Saving FormLists

Post » Sun Jun 27, 2010 4:08 pm

Hm I wonder, when using FOSEs ListAddForm to add new elements to a form list, are these saved (when saving the game)? Cause to me it appears they are not (which makes me very sad), but maybe I did something wrong.
Edit: Argh, should've used the search function before, sorry for that.

Well anyway, one search result said that AddFormToFormList may cause crashes on save when removing previously added items, but I tested it and it didnt seem to happen. The post was pretty old, so has this changed now?
User avatar
Nicole M
 
Posts: 3501
Joined: Thu Jun 15, 2006 6:31 am

Post » Mon Jun 28, 2010 2:33 am

I believe that was fixed in FOSE v1.2 beta 1. See http://www.gamesas.com/index.php?showtopic=1068925 for details.

Cipscis
User avatar
GRAEME
 
Posts: 3363
Joined: Sat May 19, 2007 2:48 am

Post » Sun Jun 27, 2010 11:57 am

Hm ok, i really get CTDs on save now. Hopefully, I just did something wrong. Here's the code:
; Local Varsshort ishort sizeshort indexref currentListref inputListref elementshort found; Read & Clear Inputset inputList to HPOVListManager.inputListset element to HPOVListManager.elementset index to HPOVListManager.index set HPOVListManager.inputList to 0set HPOVListManager.element to 0set HPOVListManager.index to 0if element == 0	returnendifset i to 0set size to (listGetCount inputList)label 1set currentList to listGetNthForm inputList iif listGetFormIndex currentList element != -1	set found to 1else	set found to 0endif; Current list is the new list, and doesnt contain element -> addif i == (index - 1) && found == 0	PrintToConsole "Added to list i= %.0f" i	AddFormToFormList currentList element; Current list is not the new list but contains element -> deleteelseif i != (index -1) && found == 1	PrintToConsole "Removed from list i= %.0f" i	listRemoveForm currentList elementendifif i < size	set i to i + 1	goto 1endif


It's a stage function and it's purpose is to take a list of lists (inputList) an item (element) and a list index (1..n), and add the item to the list at the speficied index and remove it from all others (which practically means adding it for the first time, and then moving it).

The steps to reproduce the crash:
(Add an item to list 2:)
Added to list i=1
(save=>ok)

(Move the item to list 3:)
Removed from list i=1
Added to list i=2
(save=>ok)

(Move the item back to list 2:)
Removed from list i=2
Added to list i=1
(save=>crash)

Edit:
Ok, after some testing I got it working now. Assuming this is really a bug and not just a screw-up on my part, this solution may come handy for others who want to do the same thing:

My basic idea was to avoid ListRemoveForm alltogether and instead use ListReplaceNthForm. So instead of deleting a form its replaced by a dummy object NullForm (0 ref doesnt work). Then, when adding a new form, instead of adding it it's first checked if there are existing NullForms which are replaced.

In the process of testing this I saw that using AddFormToFormList to add an item to a list multiple times will not work, what will work however is adding object AddForm (another dummy) and then replacing it with NullForm. On save/load, it seems all duplicates are removed (and the list size is adjusted accordingly). This is handy, because this means it's not necessary to replace existing NullForms when adding new items, as multiple ones will automatically be purged after save/load.

Summarizing:
Add with AddFormToFormList
Delete with ListReplaceNthForm and a dummy object for an empty/deleted element
User avatar
Symone Velez
 
Posts: 3434
Joined: Thu Sep 07, 2006 12:39 am

Post » Sun Jun 27, 2010 1:28 pm

You might've run into the same thing I found, which is that removing the last item in a FormList (that contains more than 1 entry) with either ListRemoveForm or ListRemoveNthForm seems to bug the list. I don't think I did any testing with ListReplaceNthForm to see if that avoid the problem, but I found another solution that might work better for you (has been working fine for me).

In a nutshell, that method is:
- Initialize the empty formlist with a dummy object
- Only add to the head of the list (any method is fine)

The dummy will always be the last item in the list, and you can safely remove any other with either of the remove functions. Actually, it should be safe to add at any index less than the list count - 1, but unless you need to, you should add at the head (index 0) since that's more efficient.


One other thing - I don't know if your formlists contain anything other than base forms, but if they do, I've found that ListGetFormIndex will not return the index of a non-base form (it will always return -1). If you need the index in this case, you can use:

set iIndex to ListRemoveForm SomeFormList rSomeRef

...and if necessary add rSomeRef back afterward. If you're using the dummy-at-the-end method described above, you could safely add it back with:

ListAddForm SomeFormList rSomeRef iIndex ORrSomeRef.ListAddRef SomeFormList iIndex

...which will preserve the list's order.


I've already reported the apparent bugs to ianpatt, so they're on his list for things to look at.
User avatar
no_excuse
 
Posts: 3380
Joined: Sun Jul 16, 2006 3:56 am

Post » Sun Jun 27, 2010 1:53 pm

I don't think the list was longer than 1, at least judging from the debug output below. I think it was more like add single item (ok) remove single item (ok) add single item again (crash). It seems to me the replace method I described works well so far, at least I did not receive any bug reports yet :)
But thanks for the tipps, it's always good to know how these blackbox-functions actually behave (no offense @ FOSE, in the end it works! :))
User avatar
Chelsea Head
 
Posts: 3433
Joined: Thu Mar 08, 2007 6:38 am


Return to Fallout 3