blackbirdwanderer Posted April 15, 2017 Share Posted April 15, 2017 After spending a lot of time researching and not finding an answer, I'm going to punt and ask for help. Basically, I'm writing a mod where I've got a released/rescued captive NPC in rags who searches the area looking for armor pieces and I've got an AI package that does this quite successfully. What I'm stuck on is evaluating and equipping the best of the collected armors. The BBLS mod had that option I always loved to "Wear your best armor." I was hoping to be able to trigger something like that at the end of the search. Migel (BBLS author) helped a bit, but it's been several years since he wrote it and he's now attacking the problem a different way. He suggested, and I tried, using the game's code to force equip the best items in the NPCs inventory after an UnequipAll script call, by equipping and then removing a disposable ring. This did force an equip behavior, unfortunately it forced back to the default outfit, even if it had been removed. akSpeaker.Unequipall() akSpeaker.EquipItem(SilverRing,1) akSpeaker.Removeitem(SilverRing,1) What ends up happening is the NPC equips whatever remaining items are left from their default outfit as built in the CK. If there are none, then it respawns and equips the entire default outfit. In both cases, it completely ignores all other armors in the NPC's inventory which are of a higher value. Any ideas on how to approach the problem would be appreciated. I did find a thread (https://forums.nexusmods.com/index.php?/topic/2680964-more-ck-scripting-fun-placing-outfit-items-in-inventory/?hl=%2Bequip+%2Bbest+%2Barmor&do=findComment&comment=23525594) with some related ideas about sending items to a remote chest and then pulling them back for a swimming pool undress / dress cycle. I'm not sure if I could adapt something like that for this use. Link to comment Share on other sites More sharing options...
cdcooley Posted April 16, 2017 Share Posted April 16, 2017 NPCs will only choose to wear items in their inventory if they are teammates. Everyone else always sticks with their outfit as defined in the CK. If you make an NPC a teammate then use the trick above the game will pick the best items from the current inventory based on that character's skills. (That doesn't always match what you might think is best though.) Link to comment Share on other sites More sharing options...
blackbirdwanderer Posted April 16, 2017 Author Share Posted April 16, 2017 NPCs will only choose to wear items in their inventory if they are teammates. Everyone else always sticks with their outfit as defined in the CK. If you make an NPC a teammate then use the trick above the game will pick the best items from the current inventory based on that character's skills. (That doesn't always match what you might think is best though.) Great tip! Thank you so much, this works perfectly now, at least in a limited sense. The limitation being when the teammate status is removed, the NPC reverts back to their CK defined default outfit on the next cell re-load. The CK tutorial pages say the following about teammates:NPC will sneak if the player sneaks, stop sneaking if the player stops sneaking. NPC will draw a weapon if the player draws a weapon. NPC will equip their best armor (instead of wearing their default Outfit) Crimes committed by the NPC are considered crimes the player has committed.I'm exploiting the heck out of #3. #1 and #2 don't seem to matter much since just making an NPC a teammate doesn't otherwise invoke a PlayerFollow type AI and this behavior appears to be overridden by any other AI Package active. Difficult to test #4. So is there a down-side to just leaving the freed captive NPC as a teammate? Link to comment Share on other sites More sharing options...
cdcooley Posted April 17, 2017 Share Posted April 17, 2017 If you leave them as a teammate I would advise giving the character a morality value that prevents committing a crime. It's also possible to create a "dynamic" outfit if this is a unique NPC. First create a new empty Leveled Item list. Next create a new Outfit and put the leveled item list in it. Then when you are ready to take away the teammate status add anything the character is currently wearing to the leveled item list and assign the new outfit to the NPC. You can find the currently equipped items either using SKSE inventory functions or by having a script watch for unequip events. Link to comment Share on other sites More sharing options...
blackbirdwanderer Posted April 21, 2017 Author Share Posted April 21, 2017 [solved] The main question here was a script to have an NPC equip their best equipment. The algorithm for this behavior is built into the game and seems to prioritize item value over effectiveness, so an expensive robe may be preferentially equipped over something with a better armor bonus. Also note that the command akActor.SetPlayerTeammate() is set here and left on at the end of the function. The NPC will not follow the PC, but will mimic weapon equipping and (in theory) sneaking behavior as described in the earlier post. As soon as the teammate behavior is turned off, the NPC will revert to their default outfit on the next cell load unless altered by a call to akActor.SetOutfit(). Thanks to everyone for the help (on this thread and others). I've got it working pretty well in my mod now. I've got NPCs who will go autonomously loot equipment and bodies out to a defined radius and equip the best they find, so if anyone else is trying to do something like this, here's how to make it work: Function Fragment_0(Actor akActor) akActor.SetPlayerTeammate() ; Sets teammate behavior Utility.Wait(1.0) ; pause akActor.Unequipall() ; Unequip everything from the NPC Utility.Wait(0.2) ; pause akActor.EquipItem(SilverRing,1) ; Equip a single ring worth 1 Septim Utility.Wait(0.4) ; pause akActor.Removeitem(SilverRing,1) ; Remove ring & triggers game to equip NPC with best inventory items. Utility.Wait(1.0) ; pause EndFunction Armor Property SilverRing auto ; Defines "trigger" ring used for convenience and unobtrusiveness. I made a junk silver ring with value 1 to equip/unequip to force this behavior and minimize the visual effect of the switch, plus giving the game a very small low load item to render. I added the Utility.Wait() pauses because I noticed erratic behavior. i.e., It didn't always work, and it works nearly 100% with the little pauses. Probably depends on your machine setup (I have 16GB RAM / 2GB VRAM in a laptop) and I expect a higher capability machine may not need them at all. Link to comment Share on other sites More sharing options...
cdcooley Posted April 22, 2017 Share Posted April 22, 2017 The clothing or armor they pick is controlled by their armor skills too. The gold value is a factor but if characters have a reasonably high armor skill (heavy or light) they will give preference to inexpensive armor over expensive clothing. Mages or others with with low armor skills will almost always prefer clothing and choose the most expensive. You might want to make a unique item instead of reusing the silver ring. (I had a problem when I used a gold ring because any gold ring I gave to a follower disappeared.) Just duplicate the silver ring object and fill the property with the duplicated ring which will never appear in the game anywhere else. You should be able to get away with just two pauses, one just before and just after the EquipItem call but I would make both of those 0.5. Link to comment Share on other sites More sharing options...
blackbirdwanderer Posted April 22, 2017 Author Share Posted April 22, 2017 The clothing or armor they pick is controlled by their armor skills too. The gold value is a factor but if characters have a reasonably high armor skill (heavy or light) they will give preference to inexpensive armor over expensive clothing. Mages or others with with low armor skills will almost always prefer clothing and choose the most expensive. You might want to make a unique item instead of reusing the silver ring. (I had a problem when I used a gold ring because any gold ring I gave to a follower disappeared.) Just duplicate the silver ring object and fill the property with the duplicated ring which will never appear in the game anywhere else. You should be able to get away with just two pauses, one just before and just after the EquipItem call but I would make both of those 0.5.That's good info on the armor prioritization; thanks. I knew it wasn't as straightforward as just value, but I've not seen anything beyond anecdotal info about the armor skills. I was just trying to convey the general behavior. I had already done what you suggest (I think) in that the junk ring is a unique item that appears nowhere else in the game, though not actually tagged as unique. It only exists for a fraction of a second when any NPC is called to force equip by a script. I was trying to minimize the pauses around the equipitem call since the NPC flashes naked for that time, and two 0.5 sec waits gives a very noticeable interruption. So, entirely for immersion, especially since each NPC I've got doing this searches for one weapon and then for 4 armor/clothing pieces. As they collect each one, the force equip is called so that's a lot of disappeared clothing. The first and last waits (full 1.0 sec) are mostly to make sure there's not another process competing, as well as fine tuning the NPC behavior appearances. i.e., It keeps them from changing clothes "on the run" quite so much. Link to comment Share on other sites More sharing options...
cdcooley Posted April 22, 2017 Share Posted April 22, 2017 You can also try skipping the UnequipAll call and replace it with an AddItem. Part of the timing problem might be the game is still busy unequipping things by the time you try to equip the ring and the other possibility is that just using EquipItem will also add the item if it doesn't exist but that makes it a two-step process which might also cause timing problems. I usually do "additem, equipitem, removeitem" and sometimes "additem, removeitem, evaluatepackage" to trigger an outfit change. Link to comment Share on other sites More sharing options...
blackbirdwanderer Posted April 22, 2017 Author Share Posted April 22, 2017 (edited) You can also try skipping the UnequipAll call and replace it with an AddItem. Part of the timing problem might be the game is still busy unequipping things by the time you try to equip the ring and the other possibility is that just using EquipItem will also add the item if it doesn't exist but that makes it a two-step process which might also cause timing problems. I usually do "additem, equipitem, removeitem" and sometimes "additem, removeitem, evaluatepackage" to trigger an outfit change. I haven't tried that, but I'll keep it in mind. I had been given some advice from Migel (the Bathing Beauties Luxury Suite modder) that said, "If you make an NPC naked, and then have it wear something like a ring and take the ring back off again, it will automatically put on the best stuff in its inventory. The game doesn't want your character to stay naked. It tries to dress them." I later discovered (from you!) that this only works if the NPC is a teammate. Now I'm curious how it triggers without the UnequipAll call and/or with a call to EvaluatePackage. Right now, though, I'm chasing my tail with a related part of the mod involving the Acquire package template. I used it to build both the SearchForWeapon and SearchForArmor packages for my mod. What has never seemed to work, however, is that they don't seem to auto-complete (ever) and trigger the OnChange section of the script. If you set the Acquire in SearchForArmor for 4, my NPCs dutifully go out and find 4 pieces of armor . . . and then stand there infinitely. I've built in a couple of workarounds that terminate the package another way, but it still feels like I'm missing something or not understanding how the thing is designed to work. I sort of assumed when acquire >= 1 it wouldn't OnEnd until it had all four, but some debug.notifications are telling me it hits OnEnd after each item. That's fine . . . but it still doesn't ever auto-complete. Any thoughts? [Edit] I just checked in the Procedure Tree for the Acquire behavior, and "Success Completes Package" is indeed checked, so I continue to wonder why it doesn't. Edited April 22, 2017 by blackbirdwanderer Link to comment Share on other sites More sharing options...
cdcooley Posted April 22, 2017 Share Posted April 22, 2017 Sorry. Like everything else AI packages are quirky and I don't have that much experience with them. Link to comment Share on other sites More sharing options...
Recommended Posts