Bug in FormList.HasForm() and disabled mods

Post » Mon Nov 19, 2012 10:08 am

Here's the setup. I talk about Dawnguard but I assume it applies to any mod.

My mod has a FormList, and it adds some entries to it if Dawnguard is present. Now, I was trying to be clever, and handle the case where the user enables Dawnguard, plays for a while, disables Dawnguard, plays for a while, enables Dawnguard again. So, I have an OnPlayerLoadGame() event in my script, where I look to see whether Dawnguard has been loaded or not, via Game.GetFormFromFile(...). If Dawnguard is loaded, then I look to see whether my FormList has the new entries in it, or not, via FormList.HasForm(). So, the code looks something like this, minus error handling, comments, and a loop:

	Form dawnguardProbe = Game.GetFormFromFile(0x000034dc, "Dawnguard.esm")	bool dawnguardLoaded = (dawnguardProbe != None)	if dawnguardLoaded		; Does booklist include Dawnguard books?		if !UBGAllBooksGlowList.HasForm(dawnguardProbe)			UBGAllBooksGlowList.AddForm(dawnguardProbe)

Now, I was assuming that if the user disabled Dawnguard and continued playing, the Dawnguard forms that I added to the FormList would just be cleared out of the FormList. That was apparently wrong. The entries seem stay in the list, but in some "zombie" fashion I haven't totally figured out. If the user re-enables Dawnguard, and the code above runs for the second time, HasForm(X) returns _false_ instead of _true_, even though GetSize() shows that the "old" X added by the first run of this code has not been removed from the list. So, basically, every time this sequence of events happens (which admittedly should be rare), the formlist will grow in size and gain some more "zombie" entries. Which is no doubt bad.

So, has anyone seen behavior like this, or have any comments? I'm now investigating FormList.Revert() as a workaround. Hopefully that isn't buggy as well.
User avatar
~Amy~
 
Posts: 3478
Joined: Sat Aug 12, 2006 5:38 am

Post » Mon Nov 19, 2012 6:12 pm

Chesko posted some relevant comments and links in http://www.gamesas.com/topic/1413790-resource-beyond-128-extended-array-functions-to-go-to-512-and-up/ earlier today that you'll probably want to check out.

Cipscis
User avatar
Irmacuba
 
Posts: 3531
Joined: Sat Mar 31, 2007 2:54 am

Post » Mon Nov 19, 2012 12:15 pm

I'd use the dawnguardLoaded var to check for Dawnguard instead of checking the FLST for dawnguardProbe. While a property is set with that item, it'll be persistent which might have to do with why it's not purged. Try the example function out, but you'll need to set up the arrays unless stripping it down.

Spoiler
Bool[] Property bDLCIsLoaded Auto ; Element 0 is bDawnguard, etc.Int[] Property iKnownFormID Auto ; Element 0 is 2048 for Dawnguard DLC1AurielsBow "Auriels Bow" [WEAP:02000800], etc.String[] Property sDLCName Auto ; Element 0 is Dawnguard.ESM, etc.FormList Property UBGAllBooksGlowList AutoFunction CheckForDLC()	Int iIndex = sDLCName.Length	While iIndex > 0		iIndex -= 1		If bDLCIsLoaded[iIndex] != Game.GetFormFromFile(iKnownFormID[iIndex], sDLCName[iIndex])			bDLCIsLoaded[iIndex] = !bDLCIsLoaded[iIndex]			If bDLCIsLoaded[iIndex]				Debug.Trace(sDLCName[iIndex] + " is loaded")				If iIndex == 0 ; Dawnguard					UBGAllBooksGlowList.AddForm(Game.GetFormFromFile(0x000034DC, sDLCName[iIndex])				ElseIf iIndex == 1 ; Hearthfire					; Make any changes needed for Hearthfire				ElseIf iIndex == 2 ; KillerBees					; Make any changes needed for KillerBees				EndIf			Else				Debug.Trace(sDLCName[iIndex] + " was loaded, but is no longer")				If iIndex == 0 ; Dawnguard					UBGAllBooksGlowList.Revert()				ElseIf iIndex == 1 ; Hearthfire					; Revert any changes previously made for Hearthfire				ElseIf iIndex == 2 ; KillerBees					; Revert any changes previously made for KillerBees				EndIf			EndIf		EndIf	EndWhileEndFunction
User avatar
Andrew Tarango
 
Posts: 3454
Joined: Wed Oct 17, 2007 10:07 am


Return to V - Skyrim