Jump to content

Array struct property


lee3310

Recommended Posts

Here's what i'm trying to do:




Struct aStruct
Actor akActor
Int akActorValue
EndStruct


aStruct[] Property ArrayOfStructs auto


Function MyFunction()
aStruct MyStruct = new aStruct
MyStruct.akActor = anActor
MyStruct.akActorValue = anActorValue
ArrayOfStructs.add(MyStruct)
EndFunction



In the log i get this: "error: Cannot add elements to a None array"

I can properly fill the Struct property in the editor and when i click "add", a new window with "Actor" and "Int" vars opens so i can assume that the property is indeed an array but i want to fill it in the script.

Edited by lee3310
Link to comment
Share on other sites

A 'single' (jargon) Auto property needs to be populated or at least initialized in CK. Don't know if you'll be able to add to it after the fact but probably yes.

A 'full' property with getter (and setter in this case, though it isn't strictly necessary) will let you do it all in script.

 

struct aStruct
int hello
EndStruct
aStruct[] property ArrayOfStructs Hidden
aStruct[] Function Get()
if ArrayOfStructs == None
ArrayOfStructs = new aStruct[0]
endif
return ArrayOfStructs
EndFunction
Function Set(aStruct[] value) (<---- this is problematic. You will only be able to pass arrays as arguments, can't just pass structs in there)
if ArrayOfStructs == None
ArrayOfStructs = new aStruct[0]
endif
Int i = 0
While i < value.Length
ArrayOfStructs.Add(value)
i += 1
EndWhile
EndFunction
EndProperty

 

This is tedious and clunky as hell so therefor my advice is to create a variable instead if at all possible.

 

aStruct[] ArrayOfStruct ;(<----- outside of Function- or Event-scope, in a script)
;(optional return-type aStruct[])
Function Something(aStruct argument)
if ArrayOfStruct == None
ArrayOfStruct = new aStruct[0]
endif
ArrayOfStruct.Add(argument)
;(optional return ArrayOfStruct)
EndFunction

 

You will still be able to access the array from outside of your script.

YourScript s
s.ArrayOfStruct.Add(sStruct thing)
Link to comment
Share on other sites

 

A 'single' (jargon) Auto property needs to be populated or at least initialized in CK. Don't know if you'll be able to add to it after the fact but probably yes.

 

A 'full' property with getter (and setter in this case, though it isn't strictly necessary) will let you do it all in script.

 

struct aStruct
int hello
EndStruct
aStruct[] property ArrayOfStructs Hidden
aStruct[] Function Get()
if ArrayOfStructs == None
ArrayOfStructs = new aStruct[0]
endif
return ArrayOfStructs
EndFunction
Function Set(aStruct[] value) (<---- this is problematic. You will only be able to pass arrays as arguments, can't just pass structs in there)
if ArrayOfStructs == None
ArrayOfStructs = new aStruct[0]
endif
Int i = 0
While i < value.Length
ArrayOfStructs.Add(value)
i += 1
EndWhile
EndFunction
EndProperty

 

This is tedious and clunky as hell so therefor my advice is to create a variable instead if at all possible.

 

aStruct[] ArrayOfStruct ;(<----- outside of Function- or Event-scope, in a script)
;(optional return-type aStruct[])
Function Something(aStruct argument)
if ArrayOfStruct == None
ArrayOfStruct = new aStruct[0]
endif
ArrayOfStruct.Add(argument)
;(optional return ArrayOfStruct)
EndFunction

 

You will still be able to access the array from outside of your script.

 

YourScript s
s.ArrayOfStruct.Add(sStruct thing)

 

Well, to put it mildly, this is not evident. The property struct maybe clunky but it will be very useful in the future.

(<---- this is problematic. You will only be able to pass arrays as arguments, can't just pass structs in there)

So the argument has to be the same type as the struct ? (i can create an array with one entry and pass it as argumente to circumvent the limitation).

Thank you so much for the explanation and in my case, it's better to go with a simple variable instead of property.

Edited by lee3310
Link to comment
Share on other sites

 

So the argument has to be the same type as the struct ? (i can create an array with one entry and pass it as argumente to circumvent the limitation).

 

Exactly. I think I'd personally create a global convenience proxy-function that you simply pass one struct, who then wraps it in a temp 1-index array and feeds it to the ArrayOfStructs setter. Declaring, initializing and cleaning up after arrays is a bit of a chore in Papyrus.

Link to comment
Share on other sites

 

 

So the argument has to be the same type as the struct ? (i can create an array with one entry and pass it as argumente to circumvent the limitation).

 

Exactly. I think I'd personally create a global convenience proxy-function that you simply pass one struct, who then wraps it in a temp 1-index array and feeds it to the ArrayOfStructs setter. Declaring, initializing and cleaning up after arrays is a bit of a chore in Papyrus.

 

I will keep that in mind when i will use the property struct you gave me. But for now everything is working great, it's the first time i use a struct so i choose the simple route "variable" and i cleared everything in a timer "StartTimerGameTime(Time, MyActor.GetFormID())"

Event OnTimerGameTime(int aiTimerID)

While idx < ArrayOfStruct.Length

If Game.GetForm(aiTimerID) as actor == ArrayOfStruct[idx].akActor

...

ArrayOfStruct[idx].Victim = None

ArrayOfStruct.remove(idx)
Edited by lee3310
Link to comment
Share on other sites

i cleared everything in a timer "StartTimerGameTime(Time, MyActor.GetFormID())"

Event OnTimerGameTime(int aiTimerID)

While idx < ArrayOfStruct.Length

If Game.GetForm(aiTimerID) as actor == ArrayOfStruct[idx].akActor

...

ArrayOfStruct[idx].Victim = None

ArrayOfStruct.remove(idx)

 

 

That'll do it. If you are completely done with that struct instance you can clear the whole instance with None as well.

 

Btw I misread you up there -- "So the argument has to be the same type as the struct ?"

 

The argument passed to a property setter has to be the same type as the property itself, i.e. an array in this case. Or at least according to my personal wranglings passing an instance of the type the array contains will fail. If someone knows how, please speak.

Link to comment
Share on other sites

 

i cleared everything in a timer "StartTimerGameTime(Time, MyActor.GetFormID())"

Event OnTimerGameTime(int aiTimerID)

While idx < ArrayOfStruct.Length

If Game.GetForm(aiTimerID) as actor == ArrayOfStruct[idx].akActor

...

ArrayOfStruct[idx].Victim = None

ArrayOfStruct.remove(idx)

 

 

That'll do it. If you are completely done with that struct instance you can clear the whole instance with None as well.

 

Btw I misread you up there -- "So the argument has to be the same type as the struct ?"

 

The argument passed to a property setter has to be the same type as the property itself, i.e. an array in this case. Or at least according to my personal wranglings passing an instance of the type the array contains will fail. If someone knows how, please speak.

 

Yeah i meant same type as the property (struct[]) and it seems logic.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...