Sars99 Posted August 8, 2024 Share Posted August 8, 2024 This is the block of code I'm running on a script extending RefCollectionAlias of artillery pieces. int Function CheckArtyCanWorkCount() int index = GetCount() - 1 While index >= 0 if GetAt(index).CanProduceForWorkshop() == false debug.trace(self + " removing " + GetAt(index) + " - can't currently fire") RemoveRef(GetAt(index)) debug.trace(self + " New Count = " +GetCount()) Else (GetAt(index) as ArtyModule:ArtilleryDataScript).MsnAmmo = new Ammo [0] (GetAt(index) as ArtyModule:ArtilleryDataScript).bPatchLoad = bPatchLoad EndIf index -= 1 EndWhile WkspGunsGlobal.SetValue(GetCount()) GetOwningQuest().UpdateCurrentInstanceGlobal(WkspGunsGlobal) debug.trace(self + " CheckArtyCanWorkCount complete. Count = " +GetCount()) return GetCount() EndFunction In my testing example I have a Collection of 4 artillery pieces, two are not crewed. The debug code saying they are being removed runs and the GetCount() after and at the end of the function still matches the initial GetCount() call I use on OnAliasInit(). In game using the sqv console command shows the RefCollection has 4 long but with two 'none' entries. I thought that GetCount() was supposed to expand and reduce as required by AddRef() or RemoveRef()? Anyone any ideas what's going on? Link to comment Share on other sites More sharing options...
SKKmods Posted August 9, 2024 Share Posted August 9, 2024 Never had a problem with add and remove from RefCollectionAlias in hundreds of scripts, but I ALWAYS assign the object under evaluation to a variable, so try that: While index >= 0 ObjectReference thisObject = Self.GetAt(Index) If(thisObject.CanProduceForWorkshop() == false) Self.RemoveRef(thisObject) ... & etc Link to comment Share on other sites More sharing options...
Sars99 Posted August 9, 2024 Author Share Posted August 9, 2024 Thanks, I’ll give that a go and report back. I feel like that will work as one of those timing issues that tends to pop up in papyrus. I’ve used it countless (pun intended) times too with no problem, though normally not on a script that extends refcollectionalias. I have thought of a clunky workaround to capture the collection in an array and then ‘overwrite’ GetCount() and GetAt(). Mainly because I don’t want to change all the lines that reference those functions to array style functions. UPDATE::: Did as you suggested and caputred that index as a variable. No change, calling GetCount() still gives the original RefCollection size and doesn't account for the two removed references. Is there a setting in the CK that I may need to check? Link to comment Share on other sites More sharing options...
SKKmods Posted August 9, 2024 Share Posted August 9, 2024 OK so I have actually seen similar behavior back when Starfield launched and we were hacking it with early versions of xEdit to figure out the field schema. I created some corrupt (as in missing/wrong field information) ref collection aliases and had all sorts of unpredictable issues adding, enumerating and removing elements in Papyrus. So, as a quick test create a new collection, repoint the script property and see if the issue persists. Link to comment Share on other sites More sharing options...
RaidersClamoring Posted August 18, 2024 Share Posted August 18, 2024 Could it help to capture self as a variable and then reassign that reference to self inside the loop following each remove? This would essentially make it a global function or could be an actual one. It's possible that the c++ backend is then prompted to do a more thorough update before handing out the object again. RefCollectionAliases are more akin to iterators than actual container-types and those typically don't like it, or will be slow to catch up when you resize the underlying sequence mid iteration. If that's the case then a recursive loop design could also work where you create a brand new iterator each call. Link to comment Share on other sites More sharing options...
Recommended Posts