Jump to content

Recommended Posts

9 hours ago, Kharos said:

 

Basically StartBoundWaitState will place an invisible marker at the NPC, optionally put the NPC into an animation (kneeling), and set up an AI package to keep the NPC waiting at the position of the marker. The mod will also ensure that if you leave the area (NPC gets unloaded) and then return again, the animation is restored and the position fixed if necessary.

 

If you move the NPC after StartBoundWaitState , the position of the marker and of the NPC are no longer correct, which can cause issues. One issue is that if the animation is swiched to a different one (e.g. getting up) then the NPC will move back to the marker; another is that when you leave and return, the NPC will move back to the marker too.

 

I would probably have tried the approach that you mentioned above, moving the marker to the NPC. Something like:
 

api.StartBoundWaitState(myActor, ...)
myActor.MoveTo(...)
ObjectReference waitMarker = myActor.GetLinkedRef(Library.Resources.WaitMarkerLink)
waitMarker.MoveTo(myActor)


Note, I have not actually tried this, so it's possible that I made a mistake and it will not work.
 

[Edit]:
If I remember correctly the marker gets deleted in the following situations:

  • when you call StopBoundWaitState
  • when the NPC dies
  • when you free the NPC from the handcuffs

Yep, that should work, i just checked the script and you had the good idea of linking both actor and marker to each other:

Quote

akActor.SetLinkedRef(_idleMarker, Library.Resources.IdleMarkerLink)
 _idleMarker.SetLinkedRef(akActor, Library.Resources.IdleMarkerLink)

so akActor.GetLinkedRef(kw) should return the idleMarker.

Link to comment
43 minutes ago, webchef said:

hi, I read a bit in the topic, but I just can't figure out how to build the firmware dump, if the roboconnection is active it does nothing.
Both in my inventory and worn.

 

You need to have a collar (version 2 or version 3) in your inventory. With that you can create a firmware dump (it requires plastic if I remember correctly), the resulting dump will have the firmware of the same version as the collar. Do this either the chemistry workbench or if you have AWKCR in the AWKCR armor workbench.

 

Basically imagine that you copy the firmware from the collar to a new holodisk. Then later when you create a new collar, you use this holodisk to put the firmware into the new collar.

Edited by Kharos
Link to comment
On 3/3/2023 at 10:32 PM, Kharos said:

 

Devi avere un collare (versione 2 o versione 3) nel tuo inventario. Con ciò è possibile creare un dump del firmware (richiede plastica se ricordo correttamente), il dump risultante avrà il firmware della stessa versione del collare. Fallo o il banco di lavoro della chimica o se hai AWKCR nel banco di lavoro dell'armatura AWKCR.

 

Fondamentalmente immagina di copiare il firmware dal collare a un nuovo holodisk. Quindi, più tardi, quando crei un nuovo collare, usi questo holodisk per inserire il firmware nel nuovo collare.

thanks i finally get it but where do you get the higher grade collars?

Link to comment
On 3/3/2023 at 12:15 PM, Kharos said:

 

Basically StartBoundWaitState will place an invisible marker at the NPC, optionally put the NPC into an animation (kneeling), and set up an AI package to keep the NPC waiting at the position of the marker. The mod will also ensure that if you leave the area (NPC gets unloaded) and then return again, the animation is restored and the position fixed if necessary.

 

If you move the NPC after StartBoundWaitState , the position of the marker and of the NPC are no longer correct, which can cause issues. One issue is that if the animation is swiched to a different one (e.g. getting up) then the NPC will move back to the marker; another is that when you leave and return, the NPC will move back to the marker too.

 

I would probably have tried the approach that you mentioned above, moving the marker to the NPC. Something like:
 

api.StartBoundWaitState(myActor, ...)
myActor.MoveTo(...)
ObjectReference waitMarker = myActor.GetLinkedRef(Library.Resources.WaitMarkerLink)
waitMarker.MoveTo(myActor)


Note, I have not actually tried this, so it's possible that I made a mistake and it will not work.
 

[Edit]:
If I remember correctly the marker gets deleted in the following situations:

  • when you call StopBoundWaitState
  • when the NPC dies
  • when you free the NPC from the handcuffs

I finally tested it and i just wanted to confirm that it works as expected:

Var Library = RH_API.GetPropertyValue("Library")
If Library
	RealHandcuffs:Library LibraryScript = Library as RealHandcuffs:Library
	ObjectReference waitMarker = akTargetClone.GetLinkedRef(LibraryScript.Resources.WaitMarkerLink)
	waitMarker.SetPosition(x, y, z)
	waitMarker.SetAngle(0.0, 0.0, r)
Endif

I used setpos() because it's 100% consistent (not sure why but sometimes (seldom), moveto() messes with the pos/angle).

Edited by lee3310
Link to comment

Now there is only one thing left:
Since i applied handcuffs to both target and clone, the latter ends up with two handcuffs in his inventory. Do i have to prevent the handcuffs from being transferred or there is a way to equip them instead of calling "CreateHandcuffsEquipOnActor" again on the clone ?

Edited by lee3310
Link to comment
47 minutes ago, lee3310 said:

Now there is only one thing left:
Since i applied handcuffs to both target and clone, the latter ends up with two handcuffs in his inventory. Do i have to prevent the handcuffs from being transferred or there is a way to equip them instead of calling "CreateHandcuffsEquipOnActor" again on the clone ?

 

I don't have a full picture of what you are doing - is the problem that your armor cloning code duplicates the handcuffs, and then CreateHandcuffsEquipOnActor creates and equips a second pair? The easiest solution to that would probably be to just not clone the handcuffs, for example by checking if the armor to clone has the keyword RH_RestraintTypeHandcuffs, or by comparing the armor record (but be careful here, there are two different Armor records for regular handcuffs and for hinged handcuffs).

 

There is a function EquipRestraintUsingDefaultSettings that can be used to equip existing handcuffs instead of creating new ones, but it requires the handcuffs as an object reference, which might not be practical in your case.

 

 

Edited by Kharos
Link to comment
8 hours ago, Kharos said:

 

I don't have a full picture of what you are doing - is the problem that your armor cloning code duplicates the handcuffs, and then CreateHandcuffsEquipOnActor creates and equips a second pair? The easiest solution to that would probably be to just not clone the handcuffs, for example by checking if the armor to clone has the keyword RH_RestraintTypeHandcuffs, or by comparing the armor record (but be careful here, there are two different Armor records for regular handcuffs and for hinged handcuffs).

 

There is a function EquipRestraintUsingDefaultSettings that can be used to equip existing handcuffs instead of creating new ones, but it requires the handcuffs as an object reference, which might not be practical in your case.

 

 

I'm restraining both Actors with Handcuffs and make them take the same kneeling pose before the swap. Transfer equipment checks for equipped armors, if an armor is equipped, i add a new one to the clone if not equipped (or not an armor) i use removeitem(othercontainer).

So if i cast the "armor/Form" handcuffs as "object reference" maybe i can call "EquipRestraintUsingDefaultSettings" instead of "CreateHandcuffsEquipOnActor". (Just trying to alleviate the script by avoiding "if statements" in loops as much as possible).

Edited by lee3310
Link to comment
1 hour ago, lee3310 said:

I'm restraining both Actors with Handcuffs and make them take the same kneeling pose before the swap. Transfer equipment checks for equipped armors, if an armor is equipped, i add a new one to the clone if not equipped (or not an armor) i use removeitem(othercontainer).

So if i cast the "armor/Form" handcuffs as "object reference" maybe i can call "EquipRestraintUsingDefaultSettings" instead of "CreateHandcuffsEquipOnActor". (Just trying to alleviate the script by avoiding "if statements" in loops as much as possible).

 

You can't cast Armor to ObjectReference, these are different. Armor is like a template for the Armor; ObjectReference is the actual armor in the game world. An additional problem is that inventory items are usually Armor and not ObjectReference, even though they are game world objects. Also the whole system works badly with armor mods because they were added to the game engine for Fallout 4 (they did not exist in Skyrim). It's a mess really.

 

Again most probably the easiest way to do is a keyword check on the armor that you want to "clone" and skip it if it is handcuffs.

 

Edited by Kharos
Link to comment
1 hour ago, Kharos said:

 

You can't cast Armor to ObjectReference, these are different. Armor is like a template for the Armor; ObjectReference is the actual armor in the game world. An additional problem is that inventory items are usually Armor and not ObjectReference, even though they are game world objects. Also the whole system works badly with armor mods because they were added to the game engine for Fallout 4 (they did not exist in Skyrim). It's a mess really.

 

Again most probably the easiest way to do is a keyword check on the armor that you want to "clone" and skip it if it is handcuffs.

 

Ok, thanks for the confirmation, i will just prevent the cuffs from being transferred.
PS
Can i also check for armor handcuffs instead of KW ? since it's already listed as property in the "API" and not the keyword (i can't find "RH_RestraintTypeHandcuffs" in any script property).

 

Armor Handcuffs = RH_API.GetPropertyValue("Handcuffs") as Armor

Form[] items = sourceActor.GetInventoryItems()
If (items[index] as Armor) != Handcuffs

 

"CreateHandcuffsEquipOnActor" should only add the normal variant right ?:

Edited by lee3310
Link to comment
1 hour ago, lee3310 said:

Ok, thanks for the confirmation, i will just prevent the cuffs from being transferred.
PS
Can i also check for armor handcuffs instead of KW ? since it's already listed as property in the "API" and not the keyword (i can't find "RH_RestraintTypeHandcuffs" in any script property).

 

Armor Handcuffs = RH_API.GetPropertyValue("Handcuffs") as Armor

Form[] items = sourceActor.GetInventoryItems()
If (items[index] as Armor) != Handcuffs

 

"CreateHandcuffsEquipOnActor" should only add the normal variant right ?:

Nevermind, i will just use "Game.GetFormFromFile(0x00000965, "RealHandcuffs.esp") as Keyword"

Link to comment
18 hours ago, lee3310 said:

I used setpos() because it's 100% consistent (not sure why but sometimes (seldom), moveto() messes with the pos/angle).

 

Yes, spawning and moving of objects to other references is horribly buggy, as are the related reference orientation options. In mods I'm working on i getpos/setpos and getangle/setangle extensively because of that.

Link to comment
31 minutes ago, vaultbait said:

 

Yes, spawning and moving of objects to other references is horribly buggy, as are the related reference orientation options. In mods I'm working on i getpos/setpos and getangle/setangle extensively because of that.

So i'm not imagining things. You know what, in my testes, (with setpos/angle) i still get a little rotation offset (5-6°) sometimes and what's really weird, is that when i open consol and check the angles they are identical:
"target" getangle z = 341.1
"clone" getangle z = 341.1

I don't know how to explain this and just gave up trying to understand (caused by playIdle, different AnimArchetype...).

Link to comment
56 minutes ago, lee3310 said:

So i'm not imagining things. You know what, in my testes, (with setpos/angle) i still get a little rotation offset (5-6°) sometimes and what's really weird, is that when i open consol and check the angles they are identical:
"target" getangle z = 341.1
"clone" getangle z = 341.1

I don't know how to explain this and just gave up trying to understand (caused by playIdle, different AnimArchetype...).

 

Actors are especially... um... fluid in that regard. Their actual orientation can differ a bit from the reference orientation you give them. At least other sorts of refs tend to stay where you put them (modulo Havok physics of course).

Link to comment
37 minutes ago, vaultbait said:

 

Actors are especially... um... fluid in that regard. Their actual orientation can differ a bit from the reference orientation you give them. At least other sorts of refs tend to stay where you put them (modulo Havok physics of course).

It's not clear but you can compare the knees to the wood floor lines. (nitpicking)  

Spoiler

image.jpeg.9f6a4cb6bd06b1254fb30d4d1545afc6.jpeg

 

Edited by lee3310
Link to comment
1 hour ago, lee3310 said:

It's not clear but you can compare the knees to the wood floor lines. (nitpicking)  

That is 2 different poses. On the left is alert/up, on the right is relax/down. Their knees spread on the alert/up pose. What will happen is, they will very slowly move backwards from their original location.
The only way I know of to prevent it (which ain't saying much) is by moving them back to the original location every few seconds. But you can see the move and is rather annoying.

I suppose one could add a collision plane to the furniture and then remove the furniture or switch it back to the normal furniture on NPC exit, if it's reused.

Link to comment
1 hour ago, izzyknows said:

That is 2 different poses. On the left is alert/up, on the right is relax/down. Their knees spread on the alert/up pose. What will happen is, they will very slowly move backwards from their original location.
The only way I know of to prevent it (which ain't saying much) is by moving them back to the original location every few seconds. But you can see the move and is rather annoying.

I suppose one could add a collision plane to the furniture and then remove the furniture or switch it back to the normal furniture on NPC exit, if it's reused.

Hmm, it's true and i'm suspecting "ChangeAnimArchetype()". Perhaps AnimArchtypeNervous or AnimArchtypeScared can make them agitated like that (drifting as they wiggle). If it's the case i can removing it.

PS

Nice catch by the way (telling that the poses are different from that photo ?)

Edited by lee3310
Link to comment
9 hours ago, lee3310 said:

Hmm, it's true and i'm suspecting "ChangeAnimArchetype()". Perhaps AnimArchtypeNervous or AnimArchtypeScared can make them agitated like that (drifting as they wiggle). If it's the case i can removing it.

PS

Nice catch by the way (telling that the poses are different from that photo ?)

They change animation (up/down) based on the distance of the player. I guess it was Bugthesda's way of drawing attention to a captive without dialogue At least that's my story! :P

 

Link to comment
On 3/6/2023 at 6:04 PM, lee3310 said:

 

"CreateHandcuffsEquipOnActor" should only add the normal variant right ?:

 

 

 

That depends on the flags that you are passing. Please read the extensive documentation that I put before each function in ThirdPartyApi.psc.

 

;
; Create handcuffs and equip them on an actor.
; The following flags are supported: FlagHinged, FlagUnequipConflictingRestraints, FlagAddRemoveObjectsSilently
; Returns the handcuffs on success, None on failure. Added in api version: 4
;
ObjectReference Function CreateHandcuffsEquipOnActor(Actor target, Int flags = 0)

 

And:

 

    ;
    ; A flag specifying that conflicting restraints should be unequipped to allow equipping of a restraint.
    ; Added in api version: 4
    ;
    Int Property FlagUnequipConflictingRestraints = 1 AutoReadOnly

    ;
    ; A flag specifying that objects should be added/removed silently.
    ; In other words, abSilent will be set to true when calling ObjectReference functions like AddItem, RemoveItem and Drop.
    ; Added in api version: 4
    ;
    Int Property FlagAddRemoveObjectsSilently = 2 AutoReadOnly

    ;
    ; A flag specifying that a created object reference should be disabled.
    ; In other words, abInitiallyDisabled will be set to true when calling ObjectReference.PlaceAtMe.
    ; Added in api version: 4
    ;
    Int Property FlagInitiallyDisabled = 4 AutoReadOnly

    ;
    ; A flag specifying that restraints should be of the hinged variant.
    ; Added in api version: 4
    ;
    Int Property FlagHinged = 8 AutoReadOnly

 

So, if you do

 

api.CreateHandcuffsEquipOnActor(myActor)

 

then it will create regular handcuffs. If you instead do
 

api.CreateHandcuffsEquipOnActor(myActor, 8)

 

then it will create hinged handcuffs.
 

Edited by Kharos
Link to comment
16 minutes ago, Kharos said:

 

That depends on the flags that you are passing. Please read the extensive documentation that I put before each function in ThirdPartyApi.psc.

 

;
; Create handcuffs and equip them on an actor.
; The following flags are supported: FlagHinged, FlagUnequipConflictingRestraints, FlagAddRemoveObjectsSilently
; Returns the handcuffs on success, None on failure. Added in api version: 4
;
ObjectReference Function CreateHandcuffsEquipOnActor(Actor target, Int flags = 0)

 

And:

 

    ;
    ; A flag specifying that conflicting restraints should be unequipped to allow equipping of a restraint.
    ; Added in api version: 4
    ;
    Int Property FlagUnequipConflictingRestraints = 1 AutoReadOnly

    ;
    ; A flag specifying that objects should be added/removed silently.
    ; In other words, abSilent will be set to true when calling ObjectReference functions like AddItem, RemoveItem and Drop.
    ; Added in api version: 4
    ;
    Int Property FlagAddRemoveObjectsSilently = 2 AutoReadOnly

    ;
    ; A flag specifying that a created object reference should be disabled.
    ; In other words, abInitiallyDisabled will be set to true when calling ObjectReference.PlaceAtMe.
    ; Added in api version: 4
    ;
    Int Property FlagInitiallyDisabled = 4 AutoReadOnly

    ;
    ; A flag specifying that restraints should be of the hinged variant.
    ; Added in api version: 4
    ;
    Int Property FlagHinged = 8 AutoReadOnly

 

So, if you do

 

api.CreateHandcuffsEquipOnActor(myActor)

 

then it will create regular handcuffs. If you instead do
 

api.CreateHandcuffsEquipOnActor(myActor, 8)

 

then it will create hinged handcuffs.
 

I'm using the first one (flags = 0) for both actors, but to be safe i chose the "keyword" check like i said and no more duplicated handcuffs in inventory ?. Thanks again for your help. (It is always appreciated to find an Active Modder but kind of makes you "ask" before "read"?

Link to comment

This may sound like a stupid question, but what's the difference between all the different types of collars?  I've never found any real difference between any of them (aside from whether or not you can connect them to your pip-boy for special unlock functions).

 

Namely, I refer to the RobCo Shock Collar Mk 2-3 and the Throbbing RobCo Shock Collar Mk 2-3.
From what I saw, the only difference between 2 and 3 is that you can activate them slightly differently we well?  IMO, this mod could use a better explanation of what the items it adds do in general.

Link to comment
4 hours ago, ChandraArgentis said:

This may sound like a stupid question, but what's the difference between all the different types of collars?  I've never found any real difference between any of them (aside from whether or not you can connect them to your pip-boy for special unlock functions).

 

Namely, I refer to the RobCo Shock Collar Mk 2-3 and the Throbbing RobCo Shock Collar Mk 2-3.
From what I saw, the only difference between 2 and 3 is that you can activate them slightly differently we well?  IMO, this mod could use a better explanation of what the items it adds do in general.

 

Throbbing collars are described as "more painful" in the game. Technically they cause more damage when triggered. You can test this, it requires less activations to make the victim collapse from exhaustion. If you are using it with Just Business, the training amount is higher per activation.

 

Mark 3 firmware has a bit more functions than mark 2 firmware: The pin has 4 digits instead of 3, it supports a special "punishment mode", and trigger configuration supports always/1x/2x/3x, mark 2 only goes up to 2x.

Link to comment

I'm going to apologize in advance because I cannot find a way to export my modlist from vortex even after attempting to install watchmod and it's dependency.

 

For some reason the handcuffs in this mod are being replaced with a pink rope armbinder. The "cuffs" still function properly as far as I can tell with exception to not getting a option to wear the cuffs infront of the PC and with the cuffs always being worn arms behind back (this also happens to NPCs). I suspect it's due to having Devious Devices RC8 installed but disabling that mod and going in-game to check (don't worry I didn't save) didn't change anything so I'm not sure if it is the cause or if it is, how to stop them replacing the cuffs.

 

Anyway, if anybody knows how I can properly track down the cause and fix it please let me know.

20230312170624_1.jpg

Link to comment
41 minutes ago, User55487197 said:

For some reason the handcuffs in this mod are being replaced with a pink rope armbinder.

 

At some point you installed the Replace Tape and Handcuffs mod, built the meshes in BodySlide, then uninstalled the mod but didn't delete the mesh files BodySlide created. You'll have to clean those up manually.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use