DuskWulf Posted October 9, 2017 Share Posted October 9, 2017 I've been banging my head against a wall with this and I'm desperate for help. I'm puttering away at a non-lethal mod but part of it is that I need to clean up 'pacified' NPCs so that they don't behave strangely if the player goes too far from the cell and returns. I want to do Disable and MarkForDelete on the aforementioned pacified NPCs when the player is either away (or has entered a cell and isn't directly looking at them), but I have no way of really tracking them to do so. I tried adding a reference (via GetSelf and GetCrosshairRef) to a form list via AddFormToFormList, but an immediate check afterwards in the script says that the reference wasn't added. Does AddFormToFormList not handle in-game NPC references? I could use ListAddReference, but that won't persist between saves. I could use a faction, that'd be permanent, but I don't know of any way to iterate over every NPC in a faction. Every idea I have seems to come to a dead end. Any help would be vastly appreciated. TL;DR: Essentially, what I need is a permanent way to add a ref to a form list (like ListAddReference does, but permanent, as AddFormToFormList doesn't seem to add the refs), or a way to iterate over every NPC in a given faction. ---Edited Thinking I might have to do something like... Let avActorRefs := GetRefs 200, -1 ForEach Elem <- avActorRefs Let rActorRef := elem["value"] If rActorRef.GetItemCount wulfPacCleanMeUpTok >= 1 rActorRef.Disable rActorRef.MarkForDelete EndIf LoopI dunno, though... Is there a better way? Link to comment Share on other sites More sharing options...
JustChill Posted October 10, 2017 Share Posted October 10, 2017 Hey Dusk Wulf, the idea with the faction is actually the way I solved my perk mod.I am writing on V2.0 of that one to include any base record at start without having to "scan" for references around the player.Even though that function works either (but may be a bit more of a performance impact than a one-time UDF on startup). This should be preferably a quest script: scn Whatever Begin MenuMode 4 ;This will be run only in the main menu If GetGameRestarted SetBaseFactionRank 0 [YourFriendlyFaction] [base form of NPC] ;THIS IS A JIP LN function! You need that plugin for. ;[...] The only bad thing with this is that you need to add ANY base form to that faction endif End Begin GameMode ;Later if you get a perk or any condition to make NPCs friendly you can simply change the relations between the [PlayerFaction] and [YourFriendlyFaction]: if [FriendCondition = True] SetAlly [PlayerFaction] [YourFriendlyFaction] 1 1 ;Makes the factions allies. If you leave the "1 1" away, they will be friends (help you in combat). elseif [FriendCondition = False] SetEnemy [PlayerFaction] [YourFriendlyFaction] 1 1 ;This will set them to neutral (initial state). They get hostile again if the other factions in their NPC form doesn't match with the players faction. There is no need to remove the "1 1" in that case, otherwise they will be hostile FOR SURE! endif Endif Link to comment Share on other sites More sharing options...
DoctaSax Posted October 11, 2017 Share Posted October 11, 2017 (edited) AddFormToFormList should work for an actor ref, so perhaps your way of testing if it was in there wasn't correct. Then again, parking them in an array may be better. For one thing AFTFL adds items to the beginning of the list, which isn't ideal if you're gonna be looping. The best way of handling this very much depends on how large the list can get, and how often you want to check whether to remove ones that aren't around anymore. If the list grows large and you run the loop very often, there's a chance of lag. To avoid that, instead of looping through the whole thing every so often, you can systematically walk through it with each iteration of the quest script, letting that work as your loop instead. And you need to keep in mind that whenever you may need to remove something from any list while inside a loop, that loop has to be done backwards, or you'll skip elements. So here's how I'd do the handling of that: scn TrackingQstScpt ; attached to TrackingQst array_var aList int iKey ref rRef Begin GameMode if eval 1 > ar_size aList ; empty list, no point doing anything return elseif iKey < 1 ; restart the loop from the back let iKey := ar_size aList endif let iKey -= 1 let rRef := aList[iKey] ; do what you must with rRef ; if you need to remove it, do it here ar_erase aList, iKey End Ofc, aList needs to be constructed first, which is preferably done in a one-time init somewhere else, or that'd be useless code in a repeating block: scn InitQstScpt ; attached to InitQst int iInit Begin GameMode if iInit == 0 let TrackingQst.aList := ar_construct "array" startquest TrackingQst let iInit := 1 stopquest InitQst endif End And whenever/however/wherever you detect a ref to be added to the list, you add it like this: ref rRef ; could've been gotten from getself/getcrosshairref, whatever if eval 0 > ar_find rRef, TrackingQst.aList ar_append TrackingQst.aList, rRef endif Edited October 11, 2017 by DoctaSax Link to comment Share on other sites More sharing options...
Recommended Posts