Jump to content

[LE] Can you loop through properties? (and/or store properties in an array?)


corrado33

Recommended Posts

Say I have this code snippit.



FormList Property RASWeapons Auto
referencealias property WeaponsChest auto
FormList Property RASTool Auto
referencealias property ToolChest auto
FormList Property RASArmor Auto
referencealias property ArmorChest auto

;What I currently have
Event onInit()
     WeaponsChest.getref().removeallitems(RASWeapons,100,true,game.getplayer())
     ToolChest.getref().removeallitems(RASTools,100,true,game.getplayer())
     ArmorChest.getref().removeallitems(RASArmor,100,true,game.getplayer())
endevent


;what I WANT

EventonInit()
     FillFormListArray(FormListArray) ;Somehow fill a form list array
     FillAliasArray(AliasArray) ;Somehow fill an alias array
     maxItems = FillAliasArray.length()
     while maxItems > 0
          FormListArray[maxItems].getref().removeallitems(ALiasArray[maxItems],100,true,game.getplayer())
          maxItems -= 1
     endwhile
endevent

Is what I want possible? Basically the questions are these:

 

Can I store a bunch of formlists in a... list? I suppose I could store them in a formlist of it's own but the harder question is... can I store a bunch of quest aliases in a list?

 

EDIT: The best way I've found to do this is to create a formlist of the formlists. Then use the "GetAlias" function and freaking PAINSTAKINGLY make sure the aliases have the correct ID numbers and are sequential and are in the same order of the formlist. I say painstakingly because everytime you delete an alias with other aliases behind it it just gets rid of that ID number.... so you have to create them correctly, the first time.

Edited by corrado33
Link to comment
Share on other sites

Yes, you can create array properties. Declare the property as usual, but with [] after the type:

 

 

Actor[] Property ActorArray auto

 

This will create an array of actors, though any type can be used, including custom ones. You would then need to fill it through the CK, in which case the size will be set to however many forms are added there, or do an explicit initialization in your script somewhere.

Link to comment
Share on other sites

Maybe zoom out a bit more - what exactly are you trying to accomplish, in broad strokes?

 

Edit: Also, your RemoveAllItems function call is incorrect.

Sorry yes, it should just be "removeItems" not "removeAllItems"

 

What I'm TRYING to do create a better sorting mod and dynamically assign chests to aliases to my master quest. This all works great. However, if I want to transfer the correct items BACK to the correct chests, I fill out formlists for EACH of these chests. To work through all of the chests, I want to put them in a loop then have a way to work through all of the formlists to get the items back to the correct chests.

 

Basically what I was thinking of doing is to have a formlist of formlists. Then loop through these formlists, use some stringutils to get the "basename" of the formlist (everything before the text "list") to match it up with the correct alias. However, the problem I' running into is that I can't seem to get a formlist of formlists to work. I don't know if you're supposed to be able to have a formlist of formlists.

 

I mean, of course, I can just NOT have a loop and just write out every line... but considering my sorting mod may have 100+ different chests.... that may result in an annoying long script.

 

And before you ask... why? Because I can and I'm OCD (not... literally, not trying to belittle OCD) about where my items are stored. The scripting isn't hard... but making it DYNAMIC IS hard. I could program this into a cell extremely easily. I want to make it work in ANY cell though.

EDIT: And for the record, I already made it work... but only if I hard program in the properties of the script. (Meaning the specific quest aliases, so the dynamic part IS working.) I'd like to make it use the "getAlias" function so the script doesn't have 100+ properties. Using getalias would allow me to just use a single editable property or variable, instead of properties for every... single.... linked quest alias.

Edited by corrado33
Link to comment
Share on other sites

You can have formlists in formlists but it starts getting tricky depending upon what is in the sub formlists as to what you can do with them at the top level. To do what you want, you may have to pull the list out and assign it to a different variable to work with.

 

Thinking out loud here...

You have aliases that point to containers

You have formlists that you fill with the contents of each container.

 

Considering that arrays are limited to 128 entries and you may have more than that, you'll need to have a formlist of your aliases and a formlist for the formlists of container contents. Make the entries between the two match up. I.e. the container content list in index 0 goes with the container alias in index 0

 

Then you can pull off the following:

 

 

FormList Property ListOfAliases Auto
FormList Property ListOfContainerContentLists Auto
Actor Property PlayerRef Auto

Function PassFromPlayerToContainers()
  Int size = ListOfAliases.GetSize()
  Int index = 0
  While index < size
    ObjectReference TheContainer = (ListOfAliases.GetAt(index) as ReferenceAlias).GetRef()
    FormList TheContents = (ListOfContainerContentLists.GetAt(index) as FormList)
    Int Quantity = PlayerRef.GetItemCount(TheContents)
    If Quantity > 0
      PlayerRef.RemoveItem(TheContents,Quantity,true,TheContainer)
    EndIf
    index += 1
  EndWhile
EndFunction

Function PassFromContainersToPlayer()
  Int size = ListOfAliases.GetSize()
  Int index = 0
  While index < size
    ObjectReference TheContainer = (ListOfAliases.GetAt(index) as ReferenceAlias).GetRef()
    FormList TheContents = (ListOfContainerContentLists.GetAt(index) as FormList)
    Int Quantity = TheContainer.GetItemCount(TheContents)
    If Quantity > 0
      TheContainer.RemoveItem(TheContents,Quantity,true,PlayerRef)
    EndIf
    index += 1
  EndWhile
EndFunction

 

 

 

Link to comment
Share on other sites

You can have formlists in formlists but it starts getting tricky depending upon what is in the sub formlists as to what you can do with them at the top level. To do what you want, you may have to pull the list out and assign it to a different variable to work with.

 

Thinking out loud here...

You have aliases that point to containers

You have formlists that you fill with the contents of each container.

 

Considering that arrays are limited to 128 entries and you may have more than that, you'll need to have a formlist of your aliases and a formlist for the formlists of container contents. Make the entries between the two match up. I.e. the container content list in index 0 goes with the container alias in index 0

 

Then you can pull off the following:

 

 

FormList Property ListOfAliases Auto
FormList Property ListOfContainerContentLists Auto
Actor Property PlayerRef Auto

Function PassFromPlayerToContainers()
  Int size = ListOfAliases.GetSize()
  Int index = 0
  While index < size
    ObjectReference TheContainer = (ListOfAliases.GetAt(index) as ReferenceAlias).GetRef()
    FormList TheContents = (ListOfContainerContentLists.GetAt(index) as FormList)
    Int Quantity = PlayerRef.GetItemCount(TheContents)
    If Quantity > 0
      PlayerRef.RemoveItem(TheContents,Quantity,true,TheContainer)
    EndIf
    index += 1
  EndWhile
EndFunction

Function PassFromContainersToPlayer()
  Int size = ListOfAliases.GetSize()
  Int index = 0
  While index < size
    ObjectReference TheContainer = (ListOfAliases.GetAt(index) as ReferenceAlias).GetRef()
    FormList TheContents = (ListOfContainerContentLists.GetAt(index) as FormList)
    Int Quantity = TheContainer.GetItemCount(TheContents)
    If Quantity > 0
      TheContainer.RemoveItem(TheContents,Quantity,true,PlayerRef)
    EndIf
    index += 1
  EndWhile
EndFunction

 

 

 

I thought about exactly what you're suggesting, but I can't seem to make a formlist of quest aliases. (That was my first idea to complete what I wanted to do, just make the indices match.) Unless there is another way to fill formlists, I cannot drag quest aliases into a formlist like you can anything else in the game.

 

For now, I've completed my replication of the "Dynamic auto sorting mod." I've made 26 (for now, more to come) different "unique objects" (right now just every different type of "vendor Item") that assign any chest in the game to a specific type of item. Then I have a spell that selects the nearest 10 crafting stations (in the cell that's loaded) and whenever you activate any of those crafting stations, every single item in each of those 26 chests are transferred to you. And when you exit, every single item is transferred back to the chest it came from. AND IT WORKS! (Mainly thanks to your help :wink: ) It's not... super complicated. For every new type of "sorting" chest, you need A. a new unique item, B: a new formlist, C: a new quest alias in the master quest. And you need to attach the correct scripts to each of those things (except the formlist) and make sure the properties are filled out correctly. There are a few other things you have to do, but they're not complicated (like adding the new unique item to the "unique items" formist so that it doesn't get transferred to you when you activate the crafting station.)There are 4 or 5 scripts total, but there is only 1 complicated one. The rest are simple "On item added, add form to formlist, on item removed blah blah." The only thing that runs constantly is a quest to detect if you've casted the "Find new crafting stations" spell.

 

The only thing I have to do now is to... well... write the special "sorting" if statement, which is just going to be one freaking huge massive if statement. If item.haskeyword(blah) then move to blah chest, elseif item.haskeyword blah blah blah.

 

I plan on making it differently than the dynamic auto sorting mod. I'm starting with the most specific keywords, like WeapTypeDagger, but if that chest doesn't exist, then check for WeapMaterialElven, and if that doesn't exist then check for WeaponOneHanded, and if that doesn't exist then check for VendorItemWeapon or whatever the specific keywords are. So you can pick and choose HOW specific you want the sorting to be.

Edited by corrado33
Link to comment
Share on other sites

If you can make an array of quest aliases, the same thing will work. Just match the indexes between the array and the formlist of formlists. Just know that you'll be limited to 128 entries at max in the array. There is a funky way of extending an array by using additional arrays but I never understood all that.

Link to comment
Share on other sites

If you can make an array of quest aliases, the same thing will work. Just match the indexes between the array and the formlist of formlists. Just know that you'll be limited to 128 entries at max in the array. There is a funky way of extending an array by using additional arrays but I never understood all that.

 

It isn't especially difficult, but honestly the easy answer is to use SKSE. Anybody who doesn't use SkyUI and SKSE isn't worth making mods for anyway :p

Link to comment
Share on other sites

If you have a set of aliases to containers why are you looping through them to match them up to some set of form lists? You should be putting a script on each alias that has a formlist property. The script on each alias should be handling the contents of its own container individually. The only array you might want is something to cycle through the aliases to signal that they should all run a particular function. If you're using SKSE then you can even use a ModEvent to signal each of the alias scripts and get all of them working at the same time for maximum performance.

 

P.S. Arrays can be of any length as long as you fill them in the CK instead of creating them in Papyrus even without SKSE.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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