Jump to content

A few questions about arrays ...


Recommended Posts

The reason why I am asking this is because I wanted to write a script that calculates some stuff, writes the results in a large array and exports it as a JSON or CSV or TXT file.

 

 

It isn't really for any actual "in-game" purpose, but rather just to have a script that runs and does some math.

(Make up some random numbers in a certain range, do some math to them, write them in an array and do this until a certain value gets reached in one of the arrays).

 

 

I know, writing a small C++ application would be "better" for doing something like this, but I thought "why not just do it in 'papyrus'?".

(And because the IDE that I normally use for doing C or C++ stuff like that is currently not working ... Damm you CodeLite!).

 

I know that this is a bit of a weird thing to do, but I thought I'd see if this is possible, but it would appear not (because FO4 only supports small tiny arrays and I would need a few arrays with about 5000 or 6000 "entries" each ...)

 

Oh well ....

 

 

EDIT:

 

Yes, I also use that mod for FO4 and I know that it gets "baked into the savegame" ....

Edited by YouDoNotKnowMyName
Link to comment
Share on other sites

If you just need a way to see the data, you can enable logging and print the entries in the array to a user log:

 

https://www.creationkit.com/fallout4/index.php?title=TraceUser_-_Debug

 

Using the multi array technique I explained earlier, you can do something like this. This example will save 5000 random int's between 0 and 100 in a 50 X 100 multi array and print them to MyUserLog:

 

Scriptname MiscStorageItemScript extends ObjectReference 
;Script on StorageMiscItem

Int[] Property IntArray Auto

Scriptname QuestStorageScript extends Quest 

ObjectReference[] Property StorageObjects Auto 
ObjectReference Property StorageObjectRef Auto ;this is the object reference in the empty cell
MiscObject Property StorageMiscItem Auto ;The misc item with the script attached

Event OnInit()
    Utility.Wait(1)
    StorageObjects = New ObjectReference[50]
    
    Int I = -1
    While I < 49
        I += 1 
        StorageObjects[I] = StorageObjectRef.PlaceAtMe(StorageMiscItem, 1, 1, 0, 0) ;create a new persistent storage item which contains an int array 
        MiscStorageItemScript ScriptRef = StorageObjects[I] as MiscStorageItemScript ;access the storage item's script
        ScriptRef.IntArray = New Int[100] ;initialize int array on storage item with 100 entries 
        Int IA = -1 
        While IA < 99
            IA += 1
            ScriptRef.IntArray[IA] = Utility.RandomInt(0, 100) ;stores random number between 0 and 100 in array. 
        EndWhile 
    EndWhile  
    
    ;Prints all the entries in the StorageObjects multi array to MyUserLog 
    Debug.OpenUserLog("MyUserLog")
    Int MA = StorageObjects.Length - 1
    Int IA = -1
    
    While IA < MA
        IA += 1
        MiscStorageItemScript ScriptRef = StorageObjects[IA] as MiscStorageItemScript ;access the storage item's script
        
        Int MB = ScriptRef.IntArray.Length - 1
        Int IB = -1
        While IB < MB 
            IB += 1
            Debug.TraceUser("MyUserLog", ScriptRef.IntArray[IB])
        EndWhile 
    EndWhile 
    
    Debug.Notification("Done Printing")
EndEvent 

Edited by dylbill
Link to comment
Share on other sites

Thanks for that, but you know what happened?

 

My C++ IDE started working again ...

Because of course, as soon as you start asking other people for help or alternatives, you problem magically goes away and you look like a complete idiot ...

 

But thanks anyway ....

Link to comment
Share on other sites

About Question 3, import/export may be possible using an xedit script.

@DieFem would perhaps know more about that?

 

If you want to do it from the game, AAF has a JSON thing built in Flash. Not sure what exactly it can do, but AAF uses it to read config files. Perhaps you could use it, or make your own if it doesnt fit your bill.

 

@dylbill Can formlists hold object references?

Link to comment
Share on other sites

About Question 3, import/export may be possible using an xedit script.

@DieFem would perhaps know more about that?

 

Since we are talking about run-time export, xedit doesn't fit the needs. But, as dylbill suggested, Debug.TraceUser should work for this end. The problem is importing it, we have no way of importing.

In one of my mods, Repopulator, I exported data with TraceUser, formatted as papyrus script that, once compiled, the mod was able to call it and import the data.

The only way to import/export without all that hassle would be creating a F4SE plugin (dll) for such end, like the one that Transfer Settlements uses, but that's something totally out of my knowledge.

Link to comment
Share on other sites

Hey I was messing around with the Multi Array concept again, and you can actually save the script instances in an array, instead of the object references, which is faster. I also wrote some functions that treat the multi array as one big array, so you can say set up the array to have 5000 entries, save to any entry and retrieve the value from any entry. Example:

 

Scriptname MiscStorageItemScript extends ObjectReference 
;Attach this script to a MiscObject
Int[] Property IntArray Auto

Scriptname StorageQuestScript extends Quest 

MiscStorageItemScript[] Property StorageScripts auto
ObjectReference Property StorageObjectRef Auto ;this is the object reference in the empty cell
MiscObject Property StorageMiscItem Auto ;The misc item with the MiscStorageItemScript script attached

Event OnInit()
    StorageScripts = New MiscStorageItemScript[128] ;must initialize the array first
EndEvent

Event SomeEvent()
    SetUpMultiArray(StorageScripts, 5000) ;Set up the multi array with a minimum 5000 entries
    SaveToMultiArray(StorageScripts, 1222, 777) ;save the value 777 to entry 1222 in the multi array.
    Int X = GetValueFromMultiArray(StorageScripts, 1222) ;Gets value from entry 1222 in multi array. Will return 777
EndEvent 

Function SetUpMultiArray(MiscStorageItemScript[] MultiArray, Int NumbOfEntries) 
    Float A = NumbOfEntries / 128
    Int NumOfScripts = Math.Floor(A)
   
    Int I = -1 
    While I < NumOfScripts
        I += 1
        If MultiArray[I] == None
            MultiArray[I] = StorageObjectRef.PlaceAtMe(StorageMiscItem, 1, 1, 0) as MiscStorageItemScript
            MultiArray[I].IntArray = New Int[128]
        Endif      
    EndWhile           
EndFunction

Function SaveToMultiArray(MiscStorageItemScript[] MultiArray, Int akEntry, Int akValue)
    Float A = akEntry / 128
    Int ScriptIndex = Math.Floor(A)
    Float Remainder = A - ScriptIndex
    Int ArrayIndex = 128 * Remainder as int
    
    MultiArray[ScriptIndex].IntArray[ArrayIndex] = akValue
EndFunction

Int Function GetValueFromMultiArray(MiscStorageItemScript[] MultiArray, Int akEntry) 
    Float A = akEntry / 128
    Int ScriptIndex = Math.Floor(A)
    Float Remainder = A - ScriptIndex
    Int ArrayIndex = 128 * Remainder as int
    
    Return MultiArray[ScriptIndex].IntArray[ArrayIndex]
EndFunction

You can change the types to suit your needs.
Edited by dylbill
Link to comment
Share on other sites

  • Recently Browsing   0 members

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