tomahawk6633 Posted February 2 Share Posted February 2 Hello. I'm trying to port this Fallout 4 mod called "NPC Loot bodies", which is quite effective and works all the time. I know there is this mod https://www.nexusmods.com/skyrimspecialedition/mods/33826 but i've never seen an npc to loot any bodies, even when i removed the condition for "banditfaction" so everyone can loot, but it just doesn't work. "NPC Loot bodies" works always, well as long as there is a living npc around the area. I'm struggling with this script that goes attached to the quest that controls the looting: Scriptname TEMP_S extends Quest Group Looters ReferenceAlias Property Alias_Looter Auto Const endGroup Group Corpses ReferenceAlias Property Alias_Body01 Auto Const endGroup Group Quests Quest Property TEMP_Q_for_Aliases Auto Const Quest Property TEMP_Q Auto Const endGroup Group Globals GlobalVariable Property TEMP_G_01 Auto Const GlobalVariable Property TEMP_G_PackageFinished Auto Const endGroup Group Keywords Keyword Property TEMP_K_Looted Auto Const endGroup Event OnQuestInit() StartAliasQuest() ;START the quest TEMP_Q_for_Aliases. Corpse alias fill conditions are there. The Alias_Body01 ref alias on this quest is linked to that ref alias. EndEvent Function StartAliasQuest() if TEMP_Q_for_Aliases.IsRunning() == 1 ;failsafe TEMP_Q_for_Aliases.Stop() endif Utility.Wait(0.5) ;wait for stopping... if TEMP_Q_for_Aliases.IsRunning() == 0 ;Start the alias quest TEMP_Q_for_Aliases.Start() debug.notification("Alias quest started") endif Utility.Wait(0.5) ;wait for the aliases to get filled... If Alias_Body01.GetReference() == none ;Alias has not been filled (fill conditions are not met) debug.notification("Alias is NOT filled, start loot timer") StartTimer(20, 255) ;try to start the alias quest again. (LOOP timer) Else debug.notification("Alias is filled, StartLoot()") StartLoot() EndIf EndFunction Event OnTimer(int aiTimerID) if aiTimerID == 255 ;LOOP timer StartAliasQuest() debug.notification("LOOP timer expired") EndIf If aiTimerID == 555 ;FALSE TIMER: if the actor can't loot the body in 60 seconds, abort the package End_Loot() debug.notification("aiTimerID 555 expired") Endif EndEvent Function StartLoot() TEMP_G_01.SetValueInt(1) ;for the packages (Alias_Looter.GetReference() as Actor).EvaluatePackage() StartTimer(60, 555) ;failsafe: if the looter can't path to the body, abort the package ;WAIT FOR PACKAGE STOP EndFunction Function End_loot() ;called from package "on end" fragment / falsafe timer (ID: 555) If TEMP_G_PackageFinished.GetValueInt() == 0 ;function was called from the falsafe timer debug.notification("END loot called from FALSAFE TIMER") if TEMP_Q_for_Aliases.IsRunning() == 1 TEMP_Q_for_Aliases.Stop() debug.notification("Alias quest stopped") endif TEMP_G_01.SetValueInt(0) TEMP_G_PackageFinished.SetValueInt(0) StartTimer(2, 255) ;start again LOOP timer. For the failsafe timer, no need for 20 seconds. ElseIf TEMP_G_PackageFinished.GetValueInt() == 1 ; ;function was called from the package "on end" fragment LootProcedure() MarkBodyAsLooted() debug.notification("END loot called from PACKAGE") if TEMP_Q_for_Aliases.IsRunning() == 1 TEMP_Q_for_Aliases.Stop() debug.notification("Alias quest stopped") endif TEMP_G_01.SetValueInt(0) StartTimer(10, 255) ;start again LOOP timer EndIf EndFunction Function MarkBodyAsLooted() debug.notification("MarkBodyAsLooted() running") ;AliasColl_LootedBodies.AddRef((Alias_Looter.GetReference() as Actor)) ;add looted bodies to a ref coll alias. Ref coll actors have a keyword that prevents the looter from looting them again. Remove the looted bodies one by one with a Game Timer. LootedBody_01_Actor = (Alias_Body01.GetReference() as Actor) LootedBody_01_Actor.AddKeyword(TEMP_K_Looted) StartTimerGameTime(0.5, 355) ;looted body has to have this keyword for at least two hours. (so looter won't loot this body in this period). EndFunction Actor LootedBody_01_Actor Event OnTimerGameTime(int aiTimerID) If aiTimerID == 355 RemoveLootedBody() EndIf EndEvent Function RemoveLootedBody() debug.notification("RemoveLootedBody() Timer expired") LootedBody_01_Actor.RemoveKeyword(TEMP_K_Looted) EndFunction Function LootProcedure() ;called rom package "on end" fragment. This is the actual "loot function". If (Alias_Body01.GetReference()) != none && (Alias_Looter.GetReference()) != none (Alias_Body01.GetReference() as Actor).RemoveAllItems((Alias_Looter.GetReference() as actor)) debug.notification("Looted!") ;DEBUGGING... ElseIf (Alias_Body01.GetReference()) == none && (Alias_Looter.GetReference()) != none debug.notification("Alias_Body01 is none!") ElseIf (Alias_Body01.GetReference()) != none && (Alias_Looter.GetReference()) == none debug.notification("Alias_Looter is none!") ElseIf (Alias_Body01.GetReference()) == none && (Alias_Looter.GetReference()) == none debug.notification("Alias_Body01 AND Looter are none!") EndIf EndFunction Since there are no "Timers" in Skyrim's engine, and i don't know much about coding, i feel lost. I wonder if someone knows of a way to replace the timer functions with some Skyrim equivalent to make this madness work, if it's possible. I love how it works in FO4, npcs just run and get the looting, wherever the bodies are. Makes for some quite hilarious circumstances, my favorite one is when i kill someone and put a mine in his body and just wait . Here i attach the mod in question. Remember it's a Fallout4 mod, the use i get from it is to check how the aliases get filled, the quest that makes all the magic and the package involved for the looting, plus the scripts. NPCLootBodies.zip Link to comment Share on other sites More sharing options...
Sphered Posted February 3 Share Posted February 3 (edited) Likely won't be able to "port" the mod, but rather reproduce it as feasible If I was tackling this project today, first approach I would go with, is AI ObserveDead routine where the NPC using this routine, will approach lootable bodies and perhaps perform a search animation like they will when saying "What happened?" etc. Let scripts handle the actual looting, and also have the script apply some sort of tag to prevent NPCs from trying to repeat loot, etc I was curious so played with above for a little bit. ObserveDead override pack apparently is a dud or has quirks and too many hoops to jump through to be a viable approach. Aside, I found a mod you can use as a template for the concept you want. Haven't tried it myself but it can at least get you started, if not completely do what you are wanting https://www.nexusmods.com/skyrimspecialedition/mods/4744 Edited February 5 by Sphered Link to comment Share on other sites More sharing options...
tomahawk6633 Posted February 4 Author Share Posted February 4 Thank you for the response, but i feel like the other mod i checked already try to use this method, but npcs almost never loot bodies, the other mod i checked is this by the same author of "looting bandits" https://www.nexusmods.com/skyrimspecialedition/mods/34597. I've seen several animals eating bodies with that mod, and i even changed the script so they remove all items from the corpes they eat (they are gone forever), but they have to literally step onto a body to do the looting, they won't run to eat a corpse and that's what i love from the "npc loot bodies" mod from FO4, they ran from a distance just to get the body, they are interrupted by combat so they don't go blindly and foolishly to try to loot. I even added once a bait item that when dropped spawned an invisible corpse that could attract surrounding animals, but i lost it a couple years ago. I don't know, maybe it's not possible. My question was more about if it was possible to port the mod as it is rather than change the method because as i said before other similar mods already do this but they don't work the way i hope, it's too much a hit or miss at least on my end. Link to comment Share on other sites More sharing options...
Recommended Posts