Jump to content

Trouble with forcing equip on NPC


shadowfox999

Recommended Posts

I have some code which add armor to npc and then forcing them to wear it. The problem is that NPC has armor but refuse to equip it.

 

npc.AddItem(akBaseItem, aiItemCount, true)
npc.EquipItem(akBaseItem)
Doesn't work, but
npc.AddItem(akBaseItem, aiItemCount, true)
Utility.Wait(1)
npc.EquipItem(akBaseItem)
Works always correctly. Why? I hate using wait cause different computers have different speed of papyrus execute. What do you think?
Edit: Oh and one more important info. Sometimes in case 1 npc equip just one piece of armor. I don't know why, it seems to be totally random. I also saw few situations where NPC equip full armor and immidiatly (less then 0.1s) unequip it.
Edited by shadowfox999
Link to comment
Share on other sites

You needed to add a "wait" because if you try to equip the same item you are trying to add through additem, equipitem will return none because AddItem has not finished adding the item to the inventory for equipitem to pick up. Additem is latent. The function will not return until it finishes putting the item in the inventory. How many frames that takes isn't known to me. Maybe 2-3ms.

 

Usually a small wait like you did is necessary when using certain functions right behind each other, especially latent functions. Keep in mind though, wait itself is also latent, not returning until the passed in seconds have passed(and pausing the script).

Edited by Lisselli
Link to comment
Share on other sites

I believe you meant that additem is not latent. If it were latent, then the item would be available by the time the next function ran. Because it is not latent, equipitem starts running before additem is completed Edited by lofgren
Link to comment
Share on other sites

Well, actually, because it is latent, equipitem is running because the script got unlocked by Additem - therefor he is right in the sense of threading. Wait added 1 second to self so what appeared to have happened is equipitem jumped in front of wait, but AddItem was finished when that happened, so the code then worked as intended.

 

A way to control threading is through bools or a Spinlock. When a function doesn't share the same self(external calls) you run the risk of threading.

Edited by Lisselli
Link to comment
Share on other sites

The most likely problem is that the game's AI automatically re-evaluates what items NPCs should equip after an item is added to inventory. Without the wait the script is forcing the NPC to equip the new item then the game is re-evaluating and equipping something else. Waiting allows the auto-equip to complete first then overrides that.

 

That automatic equipping also explains why the NPCs are switching back to something else.

 

I can't get to the Wiki page right now but I think there's an optional parameter for EquipItem to help with this situation.

Link to comment
Share on other sites

 

I have some code which add armor to npc and then forcing them to wear it. The problem is that NPC has armor but refuse to equip it.

 

npc.AddItem(akBaseItem, aiItemCount, true)
npc.EquipItem(akBaseItem)
Doesn't work, but
npc.AddItem(akBaseItem, aiItemCount, true)
Utility.Wait(1)
npc.EquipItem(akBaseItem)
Works always correctly. Why? I hate using wait cause different computers have different speed of papyrus execute. What do you think?
Edit: Oh and one more important info. Sometimes in case 1 npc equip just one piece of armor. I don't know why, it seems to be totally random. I also saw few situations where NPC equip full armor and immidiatly (less then 0.1s) unequip it.

 

 

This issue is dealt with in the Mace of Molag Bal Quest.

 

They use while

npc.AddItem(akBaseItem, aiItemCount, true)

While !(npc.IsEquipped(akBaseItem))
npc.EquipItem(akBaseItem)
EndWhile
Edited by Masterofnet
Link to comment
Share on other sites

I guess I had the definition of latent backwards. I thought it meant the function would not return until it was complete.

 

Regardless I think cdcooley is correct because if you run equipitem with an item the actor does not have, it will be added automatically, at least according to the wiki. So if the additem had not finished running then equipitem would be adding a second copy and equipping thar, therefore this cannot be the source of the problem.

Edited by lofgren
Link to comment
Share on other sites

Latent functions (or any other kind) only return when they are complete, but just because the function is complete doesn't mean whatever it did can't then cause interactions with other things. AddItem is one of those problem functions because after an item is added and the function returns the game will then signal the AI system to re-evaluate which items the character should wear.

 

If you really want the NPC to wear a specific item, you should be also be setting the abPreventRemoval parameter to true on the EquipItem call.

npc.AddItem(akBaseItem, aiItemCount)
npc.EquipItem(akBaseItem, true)

That will prevent the AI from unequipping the item (at least for a while).

Link to comment
Share on other sites

  • Recently Browsing   0 members

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