[Resource] Beyond 128: "Extended" Array Functions to

Post » Mon Nov 19, 2012 10:47 am

I have been getting annoyed with the Papyrus size limit of 128 elements on a given array, and on one of my mods, this has turned into a serious problem. So, I developed a set of functions identical in functionality to my http://www.gamesas.com/topic/1365378-exampleresourcegeneral-purpose-array-functions/ that allow you to treat multiple arrays like one large array, without having to worry about how to manage it yourself. You can just call ArrayAddFormXT, give it a form to dump in, and you can just trust that it will place the supplied form in the first element it can.

These example functions are a bit hard-coded to assume that you are using 4 individual arrays for a total of 512 elements. If you want more than that, it can easily be done, you'll just have to rewrite some parts. These might still be a little rough around the edges, so feedback is appreciated. However, they are all tested, and they all work (see test results below). All arrays in these examples store objects of type Form, but this can also be changed to your liking. The idea behind these functions and my general purpose array functions was to make arrays as easy to use as a FormList, which is what the functionality of these functions are tailored around.

Method:

The idea is that you are grouping together several arrays and referring to them in the future by an "Array ID", which is an integer. The first set of functions I defined are my "selector" functions that call the right "Do" functions based on the supplied Array ID. You will notice that the array names are baked into these function calls. I wish it could be made more generic, but since I wanted to keep the function calls short, these functions do have to have prior knowledge of the arrays you intend to use. In these examples, I use 8 arrays broken into 2 Array IDs, 1 and 2. They are: myArray1 through myArray8.

The below functions are what would actually be called by you when trying to interface with your Array IDs.

bool function ArrayAddFormXT(int ArrayID, Form myForm)
Adds a form to the first available element in the first available array associated with this ArrayID.
Spoiler
bool function ArrayAddFormXT(int ArrayID, Form myForm);-----------\	;Description \  Author: Chesko	;----------------------------------------------------------------	;Adds a form to the first available element in the first available array;associated with this ArrayID.	;-------------\	;Return Values \	;----------------------------------------------------------------	;			   false		   =			   Error (array full) OR invalid Array ID	;			   true			=			   Successif ArrayID == 1bool DoAddForm = ArrayAddFormXT_Do(myArray1, myArray2, myArray3, myArray4, myForm)return DoAddFormelseif ArrayID == 2bool DoAddForm = ArrayAddFormXT_Do(myArray5, myArray6, myArray7, myArray8, myForm)return DoAddFormelsereturn falseendifendFunction

bool function ArrayRemoveFormXT(int ArrayID, Form myForm, bool bSort = true)
Removes a form from the arrays associated with the ArrayID, and re-sorting the arrays of the Array ID by default.

Spoiler
bool function ArrayRemoveFormXT(int ArrayID, Form myForm);-----------\	;Description \  Author: Chesko	;----------------------------------------------------------------	;Removes a form from the arrays associated with the ArrayID.	;-------------\	;Return Values \	;----------------------------------------------------------------	;			   false		   =			   Error (form not found) OR invalid Array ID	;			   true			=			   Successif ArrayID == 1bool DoRemoveForm = ArrayRemoveFormXT_Do(myArray1, myArray2, myArray3, myArray4, myForm, ArrayID, bSort)return DoRemoveFormelseif ArrayID == 2bool DoRemoveForm = ArrayRemoveFormXT_Do(myArray5, myArray6, myArray7, myArray8, myForm, ArrayID, bSort)return DoRemoveFormelsereturn falseendifendFunction

bool function ArrayHasFormXT(int ArrayID, Form myForm)
Attempts to find the given form in the given Array ID, and returns true if found.

Spoiler
bool function ArrayHasFormXT(int ArrayID, Form myForm);-----------\;Description \;----------------------------------------------------------------;Attempts to find the given form in the given Array ID, and returns true if found;-------------\;Return Values \;----------------------------------------------------------------; false =  Form not found OR invalid array ID; true   = Form foundif ArrayID == 1bool DoHasForm = ArrayHasFormXT_Do(myArray1, myArray2, myArray3, myArray4, myForm)return DoHasFormelseif ArrayID == 2bool DoHasForm = ArrayHasFormXT_Do(myArray5, myArray6, myArray7, myArray8, myForm)return DoHasFormelsereturn falseendifendFunction

function ArrayClearXT(int ArrayID)
Clears all arrays associated with this array ID.

Spoiler
bool function ArrayClearXT(int ArrayID);-----------\;Description \;----------------------------------------------------------------;Clears all arrays associated with this array ID;-------------\;Return Values \;----------------------------------------------------------------; false = Invalid Array ID; true  = Complete, Valid Array IDif ArrayID == 1ArrayClearXT_Do(myArray1, myArray2, myArray3, myArray4)return trueelseif ArrayID == 2ArrayClearXT_Do(myArray5, myArray6, myArray7, myArray8)return trueelsereturn falseendifendFunction


int function ArrayCountXT(int ArrayID)
Counts the number of indicies associated with this array ID that do not have a "none" type.

Spoiler
int function ArrayCountXT(int ArrayID);-----------\;Description \;----------------------------------------------------------------;Counts the number of indicies associated with this array ID that do not have a "none" type;-------------\;Return Values \;----------------------------------------------------------------; int DoCount = number of indicies that are not "none"; -1 = Invalid Array IDif ArrayID == 1int DoCount = ArrayCountXT_Do(myArray1, myArray2, myArray3, myArray4)return DoCountelseif ArrayID == 2int DoCount = ArrayCountXT_Do(myArray5, myArray6, myArray7, myArray8)return DoCountelsereturn -1endifendFunction


int function ArrayCountFormXT(int ArrayID, Form myForm)
Counts the number of times myForm appears in arrays associated with this array ID.

Spoiler
int function ArrayCountFormXT(int ArrayID, Form myForm);-----------\;Description \;----------------------------------------------------------------;Counts the number of times myForm appears in arrays associated with this array ID;-------------\;Return Values \;----------------------------------------------------------------; int DoCount = number of times the form appears in the arrays associated with the Array ID; -1 = Invalid Array IDif ArrayID == 1int DoCount = ArrayCountFormXT_Do(myArray1, myArray2, myArray3, myArray4, myForm)return DoCountelseif ArrayID == 2int DoCount = ArrayCountFormXT_Do(myArray5, myArray6, myArray7, myArray8, myForm)return DoCountelsereturn -1endifendFunction


bool function ArraySortXT(int ArrayID)
Removes blank elements by shifting all elements down, moving elements to arrays "below" the current one if necessary.
Spoiler
bool function ArraySortXT(int ArrayID);-----------\;Description \;----------------------------------------------------------------;Removes blank elements by shifting all elements down, moving elements;to arrays "below" the current one if necessary.;-------------\;Return Values \;----------------------------------------------------------------; true  =  Success; false  =  Sort not necessaryif ArrayID == 1bool DoSort = ArraySortXT_Do(myArray1, myArray2, myArray3, myArray4)return DoSortelseif ArrayID == 2bool DoSort = ArraySortXT_Do(myArray5, myArray6, myArray7, myArray8)return DoSortelsereturn falseendifendFunction

So, those functions wrap up your logic of calling several different Array IDs and knowing which arrays to pass into the Do functions when called.

Here are the "Do" functions. These perform the actual work by acting on the supplied arrays provided by the functions above. These would not be called directly in your code, unless you really wanted to (though that defeats part of the purpose of abstracting this down to a single Array ID, but it's your choice).


bool function ArrayAddFormXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, Form myForm)
Adds a form to the first available element in the first available array.

Spoiler
bool function ArrayAddFormXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, Form myForm);-----------\	;Description \  Author: Chesko	;----------------------------------------------------------------	;Adds a form to the first available element in the first available array.;-------------\	;Return Values \	;----------------------------------------------------------------	;			   false		   =			   Error (array full)	;			   true			=			   Successint i = 0;notification("myArray.Length = " + myArray.Length)	while i < fArray1.Length		if fArray1[i] == none			fArray1[i] = myForm			;notification("Adding " + myForm + " to the array.")			return true		else			i += 1		endif	endWhilei = 0while i < fArray2.Length		if fArray2[i] == none			fArray2[i] = myForm			;notification("Adding " + myForm + " to the array.")			return true		else			i += 1		endif	endWhilei = 0while i < fArray3.Length		if fArray3[i] == none			fArray3[i] = myForm			;notification("Adding " + myForm + " to the array.")			return true		else			i += 1		endif	endWhilei = 0while i < fArray4.Length		if fArray4[i] == none			fArray4[i] = myForm			;notification("Adding " + myForm + " to the array.")			return true		else			i += 1		endif	endWhile	return false ;All arrays are fullendFunction

bool function ArrayRemoveFormXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, Form myForm, int ArrayID, bool bSort = false)
Removes a form from the arrays, if found.

Spoiler
bool function ArrayRemoveFormXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, Form myForm, int ArrayID, bool bSort = true);-----------\;Description \;----------------------------------------------------------------;Removes a form from the arrays, if found.;-------------\;Return Values \;----------------------------------------------------------------; false = Error (Form not found); true = Successint i = 0while i < fArray1.Lengthif fArray1[i] == myFormfArray1[i] = none;notification("Removing element " + i)if bSort == trueArraySortXT(ArrayID)endifreturn trueelsei += 1endifendWhilei = 0while i < fArray2.Lengthif fArray2[i] == myFormfArray2[i] = none;notification("Removing element " + i)if bSort == trueArraySortXT(ArrayID)endifreturn trueelsei += 1endifendWhilei = 0while i < fArray3.Lengthif fArray3[i] == myFormfArray3[i] = none;notification("Removing element " + i)if bSort == trueArraySortXT(ArrayID)endifreturn trueelsei += 1endifendWhilei = 0while i < fArray4.Lengthif fArray4[i] == myFormfArray4[i] = none;notification("Removing element " + i)if bSort == trueArraySortXT(ArrayID)endifreturn trueelsei += 1endifendWhilereturn falseendFunction

bool function ArrayHasFormXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, Form myForm)
Attempts to find the given form in the arrays, and returns true if found.

Spoiler
bool function ArrayHasFormXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, Form myForm);-----------\;Description \;----------------------------------------------------------------;Attempts to find the given form in the arrays, and returns true if found.;-------------\;Return Values \;----------------------------------------------------------------; false =  Form not found; true   = Form foundint i = 0while i < fArray1.Lengthif fArray1[i] == myFormreturn trueelsei += 1endifendWhilei = 0while i < fArray2.Lengthif fArray2[i] == myFormreturn trueelsei += 1endifendWhilei = 0while i < fArray3.Lengthif fArray3[i] == myFormreturn trueelsei += 1endifendWhilei = 0while i < fArray4.Lengthif fArray4[i] == myFormreturn trueelsei += 1endifendWhilereturn falseendFunction

function ArrayClearXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4)
Deletes the contents of arrays.

Spoiler
function ArrayClearXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4);-----------\;Description \;----------------------------------------------------------------;Deletes the contents of arrays.;-------------\;Return Values \;----------------------------------------------------------------; noneint i = 0while i < fArray1.LengthfArray1[i] = nonei += 1endWhilei = 0while i < fArray2.LengthfArray2[i] = nonei += 1endWhilei = 0while i < fArray3.LengthfArray3[i] = nonei += 1endWhilei = 0while i < fArray4.LengthfArray4[i] = nonei += 1endWhileendFunction


int function ArrayCountXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4)
Counts the number of indicies in these arrays that do not have a "none" type.

Spoiler
int function ArrayCountXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4);-----------\;Description \;----------------------------------------------------------------;Counts the number of indicies associated with this array ID that do not have a "none" type.;-------------\;Return Values \;----------------------------------------------------------------; int myCount = number of indicies that are not "none"int myCount = 0int i = 0while i < fArray1.Lengthif fArray1[i] != nonemyCount += 1i += 1elsei += 1endifendWhilei = 0while i < fArray2.Lengthif fArray2[i] != nonemyCount += 1i += 1elsei += 1endifendWhilei = 0while i < fArray3.Lengthif fArray3[i] != nonemyCount += 1i += 1elsei += 1endifendWhilei = 0while i < fArray4.Lengthif fArray4[i] != nonemyCount += 1i += 1elsei += 1endifendWhile;notification("MyCount = " + myCount)return myCountendFunction

int function ArrayCountFormXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, Form myForm)
Attempts to count the number of times the given form appears in the arrays.

Spoiler
int function ArrayCountFormXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, Form myForm);-----------\;Description \;----------------------------------------------------------------;Attempts to count the number of times the given form appears in the arrays.;-------------\;Return Values \;----------------------------------------------------------------;			   0 =			   Form not found;			   int i =			   Number of times form appears in arrayint iCount = 0int i = 0while i < fArray1.Lengthif fArray1[i] == myFormiCount += 1i += 1elsei += 1endifendWhilei = 0while i < fArray2.Lengthif fArray2[i] == myFormiCount += 1i += 1elsei += 1endifendWhilei = 0while i < fArray3.Lengthif fArray3[i] == myFormiCount += 1i += 1elsei += 1endifendWhilei = 0while i < fArray4.Lengthif fArray4[i] == myFormiCount += 1i += 1elsei += 1endifendWhilereturn iCountendFunction

bool function ArraySortXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, int i = 0)
Removes blank elements by shifting all elements down, moving elements to arrays "below" the current one if necessary, optionally starting the sort at position i.

Spoiler
bool function ArraySortXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, int i = 0);-----------\;Description \  Author: Chesko;----------------------------------------------------------------;Removes blank elements by shifting all elements down, moving elements;to arrays "below" the current one if necessary, optionally starting the sort at position i.;Optionally starts sorting from element i.;-------------\;Return Values \;----------------------------------------------------------------;				 false		=		   No sorting required;				 true		 =		   Success;notification("Sort Start")bool bFirstNoneFound = falseint iFirstNoneFoundArray = 0int iFirstNonePos = 0while i < 512;Which array am I looking in?int j = 0 ;Actual array index to checkint myCurrArray ;Current arrayif i < 128myCurrArray = 1j = ielseif i < 256 && i >= 128j = i - 128myCurrArray = 2elseif i < 384 && i >= 256j = i - 256myCurrArray = 3elseif i < 512 && i >= 384j = i - 384myCurrArray = 4endifif myCurrArray == 1if fArray1[j] == noneif bFirstNoneFound == falsebFirstNoneFound = trueiFirstNoneFoundArray = myCurrArrayiFirstNonePos = ji += 1elsei += 1endifelseif bFirstNoneFound == true;check to see if it's a couple of blank entries in a rowif !(fArray1[j] == none);notification("Moving element " + i + " to index " + iFirstNonePos)if iFirstNoneFoundArray == 1fArray1[iFirstNonePos] = fArray1[j]fArray1[j] = noneelseif iFirstNoneFoundArray == 2fArray2[iFirstNonePos] = fArray1[j]fArray1[j] = noneelseif iFirstNoneFoundArray == 3fArray3[iFirstNonePos] = fArray1[j]fArray1[j] = noneelseif iFirstNoneFoundArray == 4fArray4[iFirstNonePos] = fArray1[j]fArray1[j] = noneendif;Call this function recursively until it returnsArraySortXT_Do(fArray1, fArray2, fArray3, fArray4, iFirstNonePos + 1)return trueelsei += 1endifelsei += 1endifendifelseif myCurrArray == 2if fArray2[j] == noneif bFirstNoneFound == falsebFirstNoneFound = trueiFirstNoneFoundArray = myCurrArrayiFirstNonePos = ji += 1elsei += 1endifelseif bFirstNoneFound == true;check to see if it's a couple of blank entries in a rowif !(fArray2[j] == none);notification("Moving element " + i + " to index " + iFirstNonePos)if iFirstNoneFoundArray == 1fArray1[iFirstNonePos] = fArray2[j]fArray2[j] = noneelseif iFirstNoneFoundArray == 2fArray2[iFirstNonePos] = fArray2[j]fArray2[j] = noneelseif iFirstNoneFoundArray == 3fArray3[iFirstNonePos] = fArray2[j]fArray2[j] = noneelseif iFirstNoneFoundArray == 4fArray4[iFirstNonePos] = fArray2[j]fArray2[j] = noneendif;Call this function recursively until it returnsArraySortXT_Do(fArray1, fArray2, fArray3, fArray4, iFirstNonePos + 1)return trueelsei += 1endifelsei += 1endifendifelseif myCurrArray == 3if fArray3[j] == noneif bFirstNoneFound == falsebFirstNoneFound = trueiFirstNoneFoundArray = myCurrArrayiFirstNonePos = ji += 1elsei += 1endifelseif bFirstNoneFound == true;check to see if it's a couple of blank entries in a rowif !(fArray3[j] == none);notification("Moving element " + i + " to index " + iFirstNonePos)if iFirstNoneFoundArray == 1fArray1[iFirstNonePos] = fArray3[j]fArray3[j] = noneelseif iFirstNoneFoundArray == 2fArray2[iFirstNonePos] = fArray3[j]fArray3[j] = noneelseif iFirstNoneFoundArray == 3fArray3[iFirstNonePos] = fArray3[j]fArray3[j] = noneelseif iFirstNoneFoundArray == 4fArray4[iFirstNonePos] = fArray3[j]fArray3[j] = noneendif;Call this function recursively until it returnsArraySortXT_Do(fArray1, fArray2, fArray3, fArray4, iFirstNonePos + 1)return trueelsei += 1endifelsei += 1endifendifelseif myCurrArray == 4if fArray4[j] == noneif bFirstNoneFound == falsebFirstNoneFound = trueiFirstNoneFoundArray = myCurrArrayiFirstNonePos = ji += 1elsei += 1endifelseif bFirstNoneFound == true;check to see if it's a couple of blank entries in a rowif !(fArray4[j] == none);notification("Moving element " + i + " to index " + iFirstNonePos)if iFirstNoneFoundArray == 1fArray1[iFirstNonePos] = fArray4[j]fArray4[j] = noneelseif iFirstNoneFoundArray == 2fArray2[iFirstNonePos] = fArray4[j]fArray4[j] = noneelseif iFirstNoneFoundArray == 3fArray3[iFirstNonePos] = fArray4[j]fArray4[j] = noneelseif iFirstNoneFoundArray == 4fArray4[iFirstNonePos] = fArray4[j]fArray4[j] = noneendif;Call this function recursively until it returnsArraySortXT_Do(fArray1, fArray2, fArray3, fArray4, iFirstNonePos + 1)return trueelsei += 1endifelsei += 1endifendifendifendWhilereturn falseendFunction

Edit: Two more useful functions for getting rid of forms from mods that may no longer be present. http://www.gamesas.com/topic/1413790-resource-beyond-128-extended-array-functions-to-go-to-512-and-up/page__view__findpost__p__21596276.

bool function ArrayRemoveBlankFormsXT(int ArrayID)
Clears all arrays associated with this array ID of blank forms ([Form ]) and re-sorts the array ID.

Spoiler
bool function ArrayRemoveBlankFormsXT(string ArrayID);-----------\;Description \;----------------------------------------------------------------;Clears all arrays associated with this array ID of blank forms ([Form ]) and re-sorts the array ID.;-------------\;Return Values \;----------------------------------------------------------------; false = Invalid Array ID; true  = Complete, Valid Array IDif ArrayID == 1ArrayRemoveBlankFormsXT_Do(myArray1, myArray2, myArray3, myArray4, ArrayID)return trueelseif ArrayID == 2ArrayRemoveBlankFormsXT_Do(myArray5, myArray6, myArray7, myArray8, ArrayID)return trueelsereturn falseendifendFunction


bool function ArrayRemoveBlankFormsXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, int ArrayID)
Clears all arrays of blank forms ([Form ]) and re-sorts.

Spoiler
function ArrayRemoveBlankFormsXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, string ArrayID);-----------\;Description \;----------------------------------------------------------------;Clears all arrays of blank forms ([Form ]) and re-sorts.;-------------\;Return Values \;----------------------------------------------------------------; noneint i = 0while i < fArray1.Lengthif fArray1[i] == "[Form ]"fArray1[i] = noneendifi += 1endWhilei = 0while i < fArray2.Lengthif fArray2[i] == "[Form ]"fArray2[i] = noneendifi += 1endWhilei = 0while i < fArray3.Lengthif fArray3[i] == "[Form ]"fArray3[i] = noneendifi += 1endWhilei = 0while i < fArray4.Lengthif fArray4[i] == "[Form ]"fArray4[i] = noneendifi += 1endWhileArraySortXT(ArrayID)endFunction


So, that's it. With the above, you can drop your forms into a set of arrays and not worry about managing them yourself, just like it were one big array, with the ease of use of a FormList.

Examples:
ArrayAddFormXT(1, FoodCabbage)	 ;Adds the form FoodCabbage to the first available element in the arrays associated with ArrayID 1.ArrayRemoveFormXT(2, Gold001)	 ;Removes the first form matching Gold001 in the arrays associated with ArrayID 1.bool bHasPlayer = ArrayHasFormXT(1, PlayerRef)	 ;Does Array ID 1 have the form PlayerRef?

So here's the big question. Does it work? The answer, thankfully, is yes. I wrote a test script to exercise most aspects of the above function calls; each test requires the function in question to look ahead to at least the next array, if not all 4 arrays in the Array ID.

Here are the test results. These tests walk all of the arrays in an Array ID (512 elements) several times to verify functionality. It also includes some performance test results, which I was pleasantly surprised and happy with. Trying to do everything that this does using FormLists would take forever, and much of the functionality of FormLists is broken anyway (which is what led me to write my http://www.gamesas.com/topic/1365378-exampleresourcegeneral-purpose-array-functions/ in the first place). Note: all of the below test results are from the same Papyrus log, but had to be broken up due to length reasons. The entire test took around 4 seconds to run.

http://pastebin.com/EZHx8jvr
http://pastebin.com/7KZc5jaA
http://pastebin.com/b7TuVr9e
http://pastebin.com/xHmzhGRN
http://pastebin.com/JSkuPQnj
http://pastebin.com/98Dc9y1V
http://pastebin.com/ZZCRKuLk
http://pastebin.com/mvSy6X8S

Highlights from the tests:
1. Everything works. Yay!
2. ArraySortXT sorted 184 elements strung across 4 arrays in 1.533998 seconds. It managed to compact everything into the first 2 arrays after sorting it.
3. ArrayAddFormXT added a new form to the 2nd array of the Array ID in 0.016998 seconds.
4. ArrayRemoveFormXT removed a form at array 2, index 56 in 0.034000 seconds.
5. ArrayHasFormXT found a Gold001 form in array 2 index 12 in 0.034000 seconds.
6. ArrayCountXT counted 184 populated array elements across 4 arrays in 0.015999 seconds.
7. ArrayCountFormXT counted all 4 instances of Gold001 in 0.016998 seconds.
8. ArrayRemoveFormXT removed a Gold001 element from the middle of Array 2 and resorted the array in 0.232998 seconds.
9. ArrayClearXT cleared all 184 array elements by setting them to "none" in 0.015999 seconds.
10. ArrayAddFormXT populated all 512 elements of the Array ID with a FoodCabbage form in 2.250000 seconds, and gracefully returned "false" when all arrays of the Array ID were full.

Enjoy, and let me know if you have any questions or suggestions.
User avatar
Jason Wolf
 
Posts: 3390
Joined: Sun Jun 17, 2007 7:30 am

Post » Mon Nov 19, 2012 5:44 am

http://skyrim.nexusmods.com/mods/24776

The Nexus page includes a download to a test mod that contains the script files used in the test cases cited at the bottom of the post. It is complete: you can install it via Nexus Mod Manager, and it will execute the test cases on game start-up. Please see your Papyrus log for test results. You can use the included source file to copy functions into your own scripts.
User avatar
Your Mum
 
Posts: 3434
Joined: Sun Jun 25, 2006 6:23 pm

Post » Mon Nov 19, 2012 6:44 am

Another example: Here is an actual implementation of ArrayAddFormXT(). This is also an example of how you could change the Array ID's to strings instead of ints, so that they might be a little easier to call and remember.

Spoiler
bool function ArrayAddFormXT(string ArrayID, Form myForm);-----------\	;Description \  Author: Chesko	;----------------------------------------------------------------	;Adds a form to the first available element in the first available array;associated with this ArrayID.	;-------------\	;Return Values \	;----------------------------------------------------------------	;			   false		   =			   Error (array full) OR invalid Array ID	;			   true			=			   Successif ArrayID == "body full"bool DoAddForm = ArrayAddFormXT_Do(_DE_ArmorBodyFull_1, _DE_ArmorBodyFull_2, _DE_ArmorBodyFull_3, _DE_ArmorBodyFull_4, myForm)return DoAddFormelseif ArrayID == "body limited"bool DoAddForm = ArrayAddFormXT_Do(_DE_ArmorBodyLimited_1, _DE_ArmorBodyLimited_2, _DE_ArmorBodyLimited_3, _DE_ArmorBodyLimited_4, myForm)return DoAddFormelseif ArrayID == "hands full"bool DoAddForm = ArrayAddFormXT_Do(_DE_ArmorHandsFull_1, _DE_ArmorHandsFull_2, _DE_ArmorHandsFull_3, _DE_ArmorHandsFull_4, myForm)return DoAddFormelseif ArrayID == "hands limited"bool DoAddForm = ArrayAddFormXT_Do(_DE_ArmorHandsLimited_1, _DE_ArmorHandsLimited_2, _DE_ArmorHandsLimited_3, _DE_ArmorHandsLimited_4, myForm)return DoAddFormelseif ArrayID == "feet full"bool DoAddForm = ArrayAddFormXT_Do(_DE_ArmorFeetFull_1, _DE_ArmorFeetFull_2, _DE_ArmorFeetFull_3, _DE_ArmorFeetFull_4, myForm)return DoAddFormelseif ArrayID == "feet limited"bool DoAddForm = ArrayAddFormXT_Do(_DE_ArmorFeetLimited_1, _DE_ArmorFeetLimited_2, _DE_ArmorFeetLimited_3, _DE_ArmorFeetLimited_4, myForm)return DoAddFormelseif ArrayID == "head full"bool DoAddForm = ArrayAddFormXT_Do(_DE_ArmorHeadFull_1, _DE_ArmorHeadFull_2, _DE_ArmorHeadFull_3, _DE_ArmorHeadFull_4, myForm)return DoAddFormelseif ArrayID == "head limited"bool DoAddForm = ArrayAddFormXT_Do(_DE_ArmorHeadLimited_1, _DE_ArmorHeadLimited_2, _DE_ArmorHeadLimited_3, _DE_ArmorHeadLimited_4, myForm)return DoAddFormelsereturn falseendifendFunction

Now all I have to do to add, say, SuperWarmGauntlets to the "full" protection set of arrays for hand equipment is:

ArrayAddFormXT("hands full", SuperWarmGauntlets)

...without having to care which actual array it goes in.
User avatar
Cedric Pearson
 
Posts: 3487
Joined: Fri Sep 28, 2007 9:39 pm

Post » Mon Nov 19, 2012 7:44 pm

Thank you very much for these!
User avatar
Silencio
 
Posts: 3442
Joined: Sun Mar 18, 2007 11:30 pm

Post » Mon Nov 19, 2012 10:31 am

Fun fact: If you populate a FormList with forms from a mod, and then remove that mod, your FormList will look like this:

Spoiler
[09/29/2012 - 03:08:17PM] <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>[09/29/2012 - 03:08:17PM] <>					   FORMLIST WALK START						<>[09/29/2012 - 03:08:17PM] <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 0: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 1: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 2: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 3: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 4: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 5: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 6: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 7: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 8: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 9: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 10: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 11: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 12: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 13: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 14: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 15: None[09/29/2012 - 03:08:17PM] ------->_DE_WinterIsComingHoods: Index 16: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 17: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 18: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 19: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 20: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 21: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 22: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 23: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 24: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 25: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 26: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 27: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 28: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 29: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 30: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 31: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 32: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 33: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 34: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 35: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 36: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 37: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 38: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 39: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 40: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 41: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 42: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 43: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 44: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 45: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 46: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 47: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 48: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 49: None[09/29/2012 - 03:08:18PM] ------->_DE_WinterIsComingHoods: Index 50: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 51: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 52: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 53: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 54: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 55: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 56: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 57: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 58: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 59: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 60: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 61: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 62: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 63: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 64: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 65: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 66: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 67: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 68: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 69: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 70: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 71: None

That FormList had 72 entries for 72 hoods, but now that the mod is missing, those forms all return None. GetSize still reports 72, it doesn't get any smaller.

When you add something to that FormList, here's what it looks like (in this example I called _DE_WinterIsComingHoods.AddForm(ArmorCuirass) ):

Spoiler
[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 0: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 1: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 2: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 3: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 4: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 5: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 6: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 7: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 8: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 9: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 10: None[09/29/2012 - 03:08:19PM] ------->_DE_WinterIsComingHoods: Index 11: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 12: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 13: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 14: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 15: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 16: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 17: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 18: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 19: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 20: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 21: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 22: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 23: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 24: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 25: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 26: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 27: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 28: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 29: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 30: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 31: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 32: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 33: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 34: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 35: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 36: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 37: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 38: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 39: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 40: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 41: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 42: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 43: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 44: None[09/29/2012 - 03:08:20PM] ------->_DE_WinterIsComingHoods: Index 45: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 46: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 47: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 48: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 49: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 50: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 51: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 52: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 53: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 54: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 55: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 56: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 57: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 58: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 59: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 60: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 61: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 62: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 63: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 64: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 65: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 66: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 67: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 68: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 69: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 70: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 71: None[09/29/2012 - 03:08:21PM] ------->_DE_WinterIsComingHoods: Index 72: [Keyword ]

Notice that the new item is now at the end of the list instead of reclaiming the space left behind by forms that are no longer present. Basically, once you populate a FormList, it's always going to be that size, and will only continue to get bigger. And since http://www.creationkit.com/Talk:RemoveAddedForm_-_FormList, FormLists should only be used if you do not intend to change the contents of the FormList at runtime, ever. For everything else, try to use an array, you have a lot more control over your data that way.

Edit: I just verified that if you re-introduce the mod back into the load order, the forms "take back" their appropriate "none" spots that they left behind in the FormList. So that's something, I guess.

With an array, under the same circumstances, those forms would have appeared as "[Form ]". If you check for that string in an array, you can actually get rid of it and revert it back to None and reclaim the space in your array. Here are a couple of functions to do that.

bool function ArrayRemoveBlankFormsXT(int ArrayID)
Clears all arrays associated with this array ID of blank forms ([Form ]) and re-sorts the array ID.

Spoiler
bool function ArrayRemoveBlankFormsXT(string ArrayID);-----------\;Description \;----------------------------------------------------------------;Clears all arrays associated with this array ID of blank forms ([Form ]) and re-sorts the array ID.;-------------\;Return Values \;----------------------------------------------------------------; false = Invalid Array ID; true  = Complete, Valid Array IDif ArrayID == 1ArrayRemoveBlankFormsXT_Do(myArray1, myArray2, myArray3, myArray4, ArrayID)return trueelseif ArrayID == 2ArrayRemoveBlankFormsXT_Do(myArray5, myArray6, myArray7, myArray8, ArrayID)return trueelsereturn falseendifendFunction


bool function ArrayRemoveBlankFormsXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, int ArrayID)
Clears all arrays of blank forms ([Form ]) and re-sorts.

Spoiler
function ArrayRemoveBlankFormsXT_Do(Form[] fArray1, Form[] fArray2, Form[] fArray3, Form[] fArray4, string ArrayID);-----------\;Description \;----------------------------------------------------------------;Clears all arrays of blank forms ([Form ]) and re-sorts.;-------------\;Return Values \;----------------------------------------------------------------; noneint i = 0while i < fArray1.Lengthif fArray1[i] == "[Form ]"fArray1[i] = noneendifi += 1endWhilei = 0while i < fArray2.Lengthif fArray2[i] == "[Form ]"fArray2[i] = noneendifi += 1endWhilei = 0while i < fArray3.Lengthif fArray3[i] == "[Form ]"fArray3[i] = noneendifi += 1endWhilei = 0while i < fArray4.Lengthif fArray4[i] == "[Form ]"fArray4[i] = noneendifi += 1endWhileArraySortXT(ArrayID)endFunction



Here's the same scenario using an array. Here we have 72 [Form ] Forms, and then legitimate forms that we want to keep.

Spoiler
[09/29/2012 - 03:31:44PM] <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>[09/29/2012 - 03:31:44PM] <>						   WALK START							 <>[09/29/2012 - 03:31:44PM] <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>[09/29/2012 - 03:31:44PM] ------->myArray1: Index 0: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 1: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 2: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 3: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 4: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 5: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 6: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 7: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 8: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 9: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 10: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 11: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 12: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 13: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 14: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 15: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 16: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 17: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 18: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 19: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 20: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 21: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 22: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 23: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 24: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 25: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 26: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 27: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 28: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 29: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 30: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 31: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 32: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 33: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 34: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 35: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 36: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 37: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 38: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 39: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 40: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 41: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 42: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 43: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 44: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 45: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 46: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 47: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 48: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 49: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 50: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 51: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 52: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 53: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 54: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 55: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 56: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 57: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 58: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 59: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 60: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 61: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 62: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 63: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 64: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 65: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 66: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 67: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 68: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 69: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 70: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 71: [Form ][09/29/2012 - 03:31:44PM] ------->myArray1: Index 72: [Form < (0F0048DF)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 73: [Form < (0F0048DE)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 74: [Form < (0F0048DD)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 75: [Form < (0F0048DC)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 76: [Form < (0F0048DB)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 77: [Form < (0F0048DA)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 78: [Form < (0F0048D9)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 79: [Form < (0F0048D8)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 80: [Form < (0F001D8F)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 81: [Form < (0F0022F5)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 82: [Form < (0F0BA99B)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 83: [Form < (0F001D8E)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 84: [Form < (0F0BA99A)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 85: [Form < (0F0022FD)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 86: [Form < (0F0022FC)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 87: [Form < (0F0BA99C)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 88: [Form < (0F001829)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 89: [Form < (0F0048E0)>]

After calling ArrayRemoveBlankFormsXT()...

Spoiler
[09/29/2012 - 03:31:44PM] <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>[09/29/2012 - 03:31:44PM] <>						   WALK START							 <>[09/29/2012 - 03:31:44PM] <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>[09/29/2012 - 03:31:44PM] ------->myArray1: Index 0: [Form < (0F0048DF)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 1: [Form < (0F0048DE)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 2: [Form < (0F0048DD)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 3: [Form < (0F0048DC)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 4: [Form < (0F0048DB)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 5: [Form < (0F0048DA)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 6: [Form < (0F0048D9)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 7: [Form < (0F0048D8)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 8: [Form < (0F001D8F)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 9: [Form < (0F0022F5)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 10: [Form < (0F0BA99B)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 11: [Form < (0F001D8E)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 12: [Form < (0F0BA99A)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 13: [Form < (0F0022FD)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 14: [Form < (0F0022FC)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 15: [Form < (0F0BA99C)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 16: [Form < (0F001829)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 17: [Form < (0F0048E0)>][09/29/2012 - 03:31:44PM] ------->myArray1: Index 18: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 19: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 20: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 21: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 22: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 23: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 24: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 25: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 26: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 27: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 28: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 29: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 30: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 31: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 32: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 33: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 34: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 35: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 36: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 37: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 38: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 39: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 40: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 41: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 42: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 43: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 44: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 45: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 46: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 47: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 48: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 49: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 50: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 51: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 52: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 53: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 54: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 55: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 56: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 57: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 58: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 59: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 60: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 61: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 62: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 63: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 64: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 65: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 66: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 67: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 68: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 69: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 70: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 71: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 72: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 73: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 74: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 75: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 76: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 77: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 78: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 79: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 80: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 81: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 82: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 83: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 84: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 85: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 86: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 87: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 88: None[09/29/2012 - 03:31:44PM] ------->myArray1: Index 89: None

Now those elements are truly set to None, and we can use that space again using our other functions.
User avatar
Nany Smith
 
Posts: 3419
Joined: Sat Mar 17, 2007 5:36 pm

Post » Mon Nov 19, 2012 4:31 pm

This looks pretty nice, I've just downloaded the test file and I'm having a look through it. One comment I thought I'd make is that, since your _Do functions don't rely on any external variables, properties, or non-global functions, it would be best to make them Global functions. The main advantage of this, of course, is that many different scripts will be able to make use of them without having to worry about threading issues caused by a single object being accessed by multiple different object simultaneously. Perfect for a library such as this.

Global functions seem to have slightly less overhead than non-global functions too, even when threading isn't a concern.

I was actually working on something similar to this just the other night, although it didn't even approach completion. After seeing this I might end up making use of what you've written instead of reinventing the wheel myself :P

P.S. It looks like the forum has wiped some of your formatting - not all of your scripts are indented in your post, although of course when I look at the original script I can tell that they should be.

Cipscis
User avatar
Pumpkin
 
Posts: 3440
Joined: Sun Jun 25, 2006 10:23 am

Post » Mon Nov 19, 2012 4:24 pm

Great idea Cipscis. I'll see about making the change.

re: formatting, yea, unfortunately it doesn't appear like I can do much about it without having to manually add spaces everywhere :/

I just wish I could decouple my "selector" functions from their dependency on local arrays, but since I can't have an array of arrays, the only way to do it would essentially just call the _Do function straight. But that makes actually calling it in the code unwieldy and long and it starts to look inelegant. Ah well.
User avatar
Melanie Steinberg
 
Posts: 3365
Joined: Fri Apr 20, 2007 11:25 pm

Post » Mon Nov 19, 2012 6:18 pm

Hrm - it appears you're not aware of the array find/rfind functionality added in 1.6: http://www.creationkit.com/Arrays_%28Papyrus%29#Searching_Arrays.

It should help speed up your code even more as you won't have to iterate through your large array in Papyrus code, but will be able to take advantage of native code speed to skips chunks of the array you don't care about.

Of course, always measure and compare, but you already know that ;)
User avatar
Nana Samboy
 
Posts: 3424
Joined: Thu Sep 14, 2006 4:29 pm

Post » Mon Nov 19, 2012 12:14 pm

Hey Viper,

No, I am fully aware of Find and rFind. However, all of the wiki examples imply that only strings can be searched for using either of these methods. Since I'm looking for objects usually of type Form, I didn't think it would work. If this does work on Forms without recasting them to a string first, perhaps the documentation needs to be edited? There is no mention what the valid input types into this method are.

Thanks for commenting!
User avatar
Juan Cerda
 
Posts: 3426
Joined: Thu Jul 12, 2007 8:49 pm

Post » Mon Nov 19, 2012 6:39 am

Ok, yeah, the wiki could probably be more clear on that, (strings are easy to use for examples, cause they have visible results) but the syntax callouts on that link do say "element type" rather then "string", so they *do* actually work for any array type Papyrus supports.

In short, you can use find and rfind for forms :smile:

(Plus the compiler is pretty good about complaining if you do something that won't ever work. For example, it will complain if you try to search an array of forms using a string, but will be just fine if you try to search an array of forms with a form)
User avatar
Samantha hulme
 
Posts: 3373
Joined: Wed Jun 21, 2006 4:22 pm

Post » Mon Nov 19, 2012 10:09 am

Ok, yeah, the wiki could probably be more clear on that, (strings are easy to use for examples, cause they have visible results) but the syntax callouts on that link do say "element type" rather then "string", so they *do* actually work for any array type Papyrus supports.

In short, you can use find and rfind for forms :smile:

Awesome, thank you. I'll make the change and do a stare-and-compare of the same performance test posted above and see what the net gain is. Thanks for the help.
User avatar
katsomaya Sanchez
 
Posts: 3368
Joined: Tue Jun 13, 2006 5:03 am

Post » Mon Nov 19, 2012 11:25 am

Just out of curiosity, how would the game react if I were to create large arrays by editing the assembly? I currently have access to the compiler and assembler, but not to Skyrim, so while I see that the assembler doesn't throw any errors for creating large arrays (although I wouldn't necessarily expect it to even if they won't work) I'm not sure if the game would reject them or if it might cause other problems.

I'm basically thinking about doing something like this:
Spoiler
  • Create a Papyrus function like this:
    Int[] Function MakeLargeIntArray()	Return new Int[128]EndFunction
    That produces assembly like this:
    .function MakeLargeIntArray  .userFlags 0  .docString ""  .return Int[]  .paramTable  .endParamTable  .localTable    .local ::temp0 int[]  .endLocalTable  .code    ARRAYCREATE ::temp0 128 ;@line 4    RETURN ::temp0 ;@line 4  .endCode.endFunction
  • I can then edit the assembly code to this:
    ARRAYCREATE ::temp0 512 ;@line 4RETURN ::temp0 ;@line 4
    That's basically equivalent to this function in Papyrus, if it could be compiled:
    Int[] Function MakeLargeIntArray()	Return new Int[512]EndFunction
The above will be assembled into a fully compiled script just fine, since it's basically bypassed the compiler's validation.Of course, I expect the validation in the compiler is there for a reason. I'm basically just wondering what sort of problems, if any, I might expect from such a function. Would it work? Would the game reject it outright? Might it cause other issues?

I notice that the assembler doesn't allow me to assembly a function returning an array of a length determined at run-time, although that seems to be a different sort of error (wrong type as opposed to argument out of range - error: Argument 2 must be an unsigned integer literal.)

Cipscis
User avatar
Riky Carrasco
 
Posts: 3429
Joined: Tue Nov 06, 2007 12:17 am

Post » Mon Nov 19, 2012 8:58 am

I say you try it and find out Cipscis :)
User avatar
Evaa
 
Posts: 3502
Joined: Mon Dec 18, 2006 9:11 am

Post » Mon Nov 19, 2012 6:05 pm

This is great. Thanks a bunch!
User avatar
Pete Schmitzer
 
Posts: 3387
Joined: Fri Sep 14, 2007 8:20 am

Post » Mon Nov 19, 2012 10:28 am

HI, All:) do you guys know of any way to make an array of objects created in one script visible or usable in another, like a formlist is?
User avatar
naomi
 
Posts: 3400
Joined: Tue Jul 11, 2006 2:58 pm

Post » Mon Nov 19, 2012 11:42 am

This looks pretty nice, I've just downloaded the test file and I'm having a look through it. One comment I thought I'd make is that, since your _Do functions don't rely on any external variables, properties, or non-global functions, it would be best to make them Global functions. The main advantage of this, of course, is that many different scripts will be able to make use of them without having to worry about threading issues caused by a single object being accessed by multiple different object simultaneously.

Won't that lead to threading issues though? Call a global function and other threads get a chance to run, which could result in some very counter intuitive behavior. You'd also get cases where more than one script might want to use the functions concurrently which could have a performance impact if I understand the threading model correctly.
User avatar
Franko AlVarado
 
Posts: 3473
Joined: Sun Nov 18, 2007 7:49 pm

Post » Mon Nov 19, 2012 5:03 am

HI, All:) do you guys know of any way to make an array of objects created in one script visible or usable in another, like a formlist is?

Form[] property myFormArray auto

Just define your arrays as properties instead of local variables. You should be able to access them externally.
User avatar
Kristina Campbell
 
Posts: 3512
Joined: Sun Oct 15, 2006 7:08 am


Return to V - Skyrim