Creating a new data structure, Papyrus logs "None object

Post » Tue Jun 07, 2016 6:09 pm

I'm trying to create a simple LeveledForm data structure that can contain more than 128 entries. It just keeps track of an SKSE form array and a SKSE int array, and resizes them whenever necessary.



I wrote a new script that inherits from Form, and it compiled successfully. I can now successfully compile other scripts that use a LeveledForm object. But in-game any references to LeveledForms result in Papyrus errors:





[06/04/2016 - 09:20:30AM] warning: Assigning None to a non-object variable named "::temp127"


[06/04/2016 - 09:20:30AM] Error: Cannot call AddEntry() on a None object, aborting function call


[06/04/2016 - 09:20:35AM] Error: Cannot call GetSize() on a None object, aborting function call


Here is my LeveledForm.PSC file:




Scriptname LeveledForm extends Form


;Data
Form[] form_array
Int[] level_array
;Capacity
int cap = 128
;Current number of entries
int num = 0


;===Initialization===

event OnInit()
Debug.Notification("Creating LeveledForm")

form_array = Utility.CreateFormArray(cap)
level_array = Utility.CreateIntArray(cap)
endEvent


;===Insertion===

int function AddEntry(Form new_form, int new_level)
Debug.Notification("Adding " + new_form.GetName() + ", lv." + new_level)

int i = num

; If there is no free space, double array cap
if (i >= cap)

Form[] old_formArray = form_array
Int[] old_levelArray = level_array

form_array = Utility.CreateFormArray(cap*2)
level_array = Utility.CreateIntArray(cap*2)

int j = cap
while (j > 0)
j -= 1
form_array[j] = old_FormArray[j]
level_array[j] = old_LevelArray[j]
endWhile

cap = cap*2

endif

; Save the new data
form_array[i] = new_form
level_array[i] = new_level
num = num + 1
return i

Debug.Notification("New form has been added.")
endFunction


;===Retrieval===

int function GetSize()
return num
endFunction

Form function GetAt(int i)
return form_array[i]
endFunction

int function GetLevelAt(int i)
return level_array[i]
endFunction

The calls to Debug.Notification() aren't printing anything, presumably because my LeveledForm objects are never successfully instantiated.



Any idea what I might be doing wrong?



User avatar
Jonathan Montero
 
Posts: 3487
Joined: Tue Aug 14, 2007 3:22 am

Post » Wed Jun 08, 2016 3:30 am

Since it might be relevant, here is an illustration of how I'm trying to use the data structure:



Scriptname example_script extends example_base

Form property form1 auto
Form property form2 auto

LeveledForm my_list

event OnExampleEvent()

my_list.AddEntry(form1, 1)
my_list.AddEntry(form2, 10)

endEvent

Is there maybe some kind of issue with trying to instantiate a new LeveledForm as a local variable within the script? I'm not passing it in through a property or anything.

User avatar
Shannon Marie Jones
 
Posts: 3391
Joined: Sun Nov 12, 2006 3:19 pm

Post » Tue Jun 07, 2016 10:55 pm

I think you may have already figured this out, but the answer is no. You can't create your own object type that way.



Papyrus is an object-oriented language, but the object instances are always game objects. The scripts themselves are equivalent to class definitions. The only way to instantiate a script instance by creating a game object which has that script attached. And some types like FormLists, Perks, Quests, etc. only have a single permanent instance. Only ObjectReference (and it's child types) can have multiple instances.

User avatar
ANaIs GRelot
 
Posts: 3401
Joined: Tue Dec 12, 2006 6:19 pm


Return to V - Skyrim