Jump to content

[LE] MCM states and loops...?


Kalambre

Recommended Posts

Hi, this question is for MCM experts. I need a list of toggle options to validate all armor slots (slot 30 to slot 60) in the MCM, so I'm trying to use arrays to avoid tons of states, I think I know how to do it using the old method, but I prefer to use state-based method if possible because my MCM uses states for all other options.

 

A bool value for each slot is stored in a json file, so I need to get this value, show it in MCM, change value if needed, and save changes in json file.

 

I've tried this code:

Bool[] SlotTrigger
SlotTrigger = new Bool[61]
;This is the array for slot values
 
Int SlotIndex = 30
 
String SlotsFile
;This is the json file path


        While SlotIndex < 61

            SlotTrigger[SlotIndex] = JSONUtil.GetIntValue(SlotsFile, "boolslot" + SlotIndex)

            ArmorSlot = ("Slot" + SlotIndex)

            AddToggleOptionST("ArmorSlot"+SlotIndex, "Armor Slot " + SlotIndex, SlotTrigger[SlotIndex])

            SlotIndex += 1

        EndWhile

Well, toggle options for all slot are shown in the MCM and bool values are correct, but I don't know how to connect this to OnSelectST() or OnDefaultST() events in order to change values.

 

Thanks in advance.

 

Link to comment
Share on other sites

I did something similar. I've not released it publicly yet. I should. I keep forgetting to double check that it works still and let others convert it to SSE for their personal use. At any rate, I have multiple containers with the same choices and I used a combination of global variable formlists and internal arrays to keep track of choices. I even allow for saving and restoring the selections via FISS.

 

Breaking down just one of those...

 

This is the state used just to toggle one container to be used or not.

State ToggleState0
    Event OnSelectST()
        Int index = 0
        If (cbc0 < ComponentBehave.length - 2)
            cbc0 += 1
        Else
            cbc0 = 0
        EndIf
        ComponentChoice[index] = cbc0
        SetTextOptionValueST(ComponentBehave[cbc0])
        If ComponentChoice[index] != 0
            SetOptionFlagsST(OPTION_FLAG_NONE, false, "AutoSortState"+index)
            SetOptionFlagsST(OPTION_FLAG_NONE, false, "Weightless"+index)
            SetOptionFlagsST(OPTION_FLAG_NONE, false, "MerchExcl"+index)
        Else
            AutoStoreChoice[index] = 0
            SetTextOptionValueST(AutoStoreBehave[0], false, "AutoSortState"+index)
            SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "AutoSortState"+index)

            WeightlesActive[index] = false
            SetToggleOptionValueST(WeightlesActive[index],false,"Weightless"+index)
            SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "Weightless"+index)

            MerchExclActive[index] = false
            SetToggleOptionValueST(MerchExclActive[index],false,"MerchExcl"+index)
            SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "MerchExcl"+index)

            RedoItemsActive[index] = false
            SetToggleOptionValueST(RedoItemsActive[index],false,"RedoItems"+index)
            SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "RedoItems"+index)
        EndIf
    EndEvent
    Event OnDefaultST()
        Int index = 0
        ComponentChoice[index] = 0
        SetTextOptionValueST(ComponentBehave[0])

        AutoStoreChoice[index] = 0
        SetTextOptionValueST(AutoStoreBehave[0], false, "AutoSortState"+index)
        SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "AutoSortState"+index)

        WeightlesActive[index] = false
        SetToggleOptionValueST(WeightlesActive[index],false,"Weightless"+index)
        SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "Weightless"+index)

        MerchExclActive[index] = false
        SetToggleOptionValueST(MerchExclActive[index],false,"MerchExcl"+index)
        SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "MerchExcl"+index)

        RedoItemsActive[index] = false
        SetToggleOptionValueST(RedoItemsActive[index],false,"RedoItems"+index)
        SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "RedoItems"+index)
    EndEvent
    Event OnHighlightST()
        SetInfoText("$AlchToggleInfo")
    EndEvent
EndState

This is where I save all the options in the preset:

import FISSFactory
State SavePreset
    Event OnSelectST()
        PresetSave = !PresetSave
        SetToggleOptionValueST(PresetSave)
        ShowMessage("$SavingPrest")
        FISSInterface fiss = FISSFactory.getFISS()
        If fiss
            fiss.beginSave("IMS_MCM_Preset.xml","Inventory Management System")
            Int ix = 0
            While ix < ComponentChoice.Length
                fiss.saveInt("abim_IMS_ComponentChoice"+ix,ComponentChoice[ix])
                fiss.saveInt("abim_IMS_AutoStoreChoice"+ix,AutoStoreChoice[ix])
                fiss.saveBool("abim_IMS_WeightlesActive"+ix,WeightlesActive[ix])
                fiss.saveBool("abim_IMS_MerchExclActive"+ix,MerchExclActive[ix])
                ix += 1
            EndWhile
            Int ixA = 0
            While ixA < ArrowArrayIndex.Length
                fiss.saveInt("abim_IMS_ArrowArrayIndex"+ixA,ArrowArrayIndex[ixA])
                ixA += 1
            EndWhile
            Int ixB = 0
            While ixB < BoltArrayIndex.Length
                fiss.saveInt("abim_IMS_BoltArrayIndex"+ixB,BoltArrayIndex[ixB])
                ixB += 1
            EndWhile
            String SaveResult = fiss.endSave()
            If SaveResult != ""
                ShowMessage("$Error saving file")
            Else
                ShowMessage("$Success saving file")
            EndIf
        EndIf
        PresetSave = !PresetSave
        SetToggleOptionValueST(PresetSave)
    EndEvent
    Event OnDefaultST()
        PresetSave = false
    EndEvent
    Event OnHighlightST()
        If FissActive == true
            SetInfoText("$SavePresetInfo")
        EndIf
    EndEvent
EndState

This is where I retrieve all the options in the preset

State LoadPreset
    Event OnSelectST()
        PresetLoad = !PresetLoad
        SetToggleOptionValueST(PresetLoad)
        If PresetLoad == true
            ShowMessage("$LoadingPreset")
            FISSInterface fiss = FISSFactory.getFISS()
            If fiss
                fiss.beginLoad("IMS_MCM_Preset.xml")
                Int ix = 0
                While ix < ComponentChoice.Length
                    ComponentChoice[ix] = fiss.loadInt("abim_IMS_ComponentChoice"+ix)
                    AutoStoreChoice[ix] = fiss.loadInt("abim_IMS_AutoStoreChoice"+ix)
                    WeightlesActive[ix] = fiss.loadBool("abim_IMS_WeightlesActive"+ix)
                    MerchExclActive[ix] = fiss.loadBool("abim_IMS_MerchExclActive"+ix)
                    ix += 1
                EndWhile
                Int ixA = 0
                While ixA < ArrowArrayIndex.Length
                    ArrowArrayIndex[ixA] = fiss.loadInt("abim_IMS_ArrowArrayIndex"+ixA)
                    ArrowIndex[ixA] = 0
                    If ArrowArrayIndex[ixA] >= 0
                        ArrowIndex[ixA] = ArrowArrayIndex[ixA]
                    EndIf
                    ixA += 1
                EndWhile
                Int ixB = 0
                While ixB < BoltArrayIndex.Length
                    BoltArrayIndex[ixB] = fiss.loadInt("abim_IMS_BoltArrayIndex"+ixB)
                    BoltIndex[ixB] = 0
                    If BoltArrayIndex[ixB] >= 0
                        BoltIndex[ixB] = BoltArrayIndex[ixB]
                    EndIf
                    ixB += 1
                EndWhile
                String LoadResult = fiss.endLoad()
                If LoadResult != ""
                    ShowMessage("$Error reading file")
                Else
                    ShowMessage("$Success reading file")
                    asc0 = AutoStoreChoice[0]
                    asc1 = AutoStoreChoice[1]
                    asc2 = AutoStoreChoice[2]
                    asc3 = AutoStoreChoice[3]
                    asc4 = AutoStoreChoice[4]
                    asc5 = AutoStoreChoice[5]
                    asc6 = AutoStoreChoice[6]
                    asc7 = AutoStoreChoice[7]
                    asc8 = AutoStoreChoice[8]
                    asc9 = AutoStoreChoice[9]
                    asc10 = AutoStoreChoice[10]
                    asc11 = AutoStoreChoice[11]
                    asc12 = AutoStoreChoice[12]
                    asc13 = AutoStoreChoice[13]
                    asc14 = AutoStoreChoice[14]
                    asc15 = AutoStoreChoice[15]
                    asc16 = AutoStoreChoice[16]

                    cbc0 = ComponentChoice[0]
                    cbc1 = ComponentChoice[1]
                    cbc2 = ComponentChoice[2]
                    cbc3 = ComponentChoice[3]
                    cbc4 = ComponentChoice[4]
                    cbc5 = ComponentChoice[5]
                    cbc6 = ComponentChoice[6]
                    cbc7 = ComponentChoice[7]
                    cbc8 = ComponentChoice[8]
                    cbc9 = ComponentChoice[9]
                    cbc10 = ComponentChoice[10]
                    cbc11 = ComponentChoice[11]
                    cbc12 = ComponentChoice[12]
                    cbc13 = ComponentChoice[13]
                    cbc14 = ComponentChoice[14]
                    cbc15 = ComponentChoice[15]
                    cbc16 = ComponentChoice[16]
                EndIf
            EndIf
        EndIf
        PresetLoad = !PresetLoad
        SetToggleOptionValueST(PresetLoad)
    EndEvent
    Event OnDefaultST()
        PresetLoad = false
    EndEvent
    Event OnHighlightST()
        If FissActive == true
            SetInfoText("$LoadPresetInfo")
        EndIf
    EndEvent
EndState

The relevant section of the OnPageReset for the container referenced above.

        AddHeaderOption("$Alchemy Supplies")
        AddTextOptionST("ToggleState"+0, "$Use Alchemy Supplies", ComponentBehave[cbc0])
        If ComponentChoice[0] == 0
            AddTextOptionST("AutoSortState"+0,"$Auto-Store", AutoStoreBehave[asc0],OPTION_FLAG_DISABLED)
            AddToggleOptionST("Weightless"+0,"$Weightless", WeightlesActive[0],OPTION_FLAG_DISABLED)
            AddToggleOptionST("MerchExcl"+0,"$MerchExcl", MerchExclActive[0],OPTION_FLAG_DISABLED)
            AddToggleOptionST("RedoItems"+0,"$RedoItems", RedoItemsActive[0],OPTION_FLAG_DISABLED)
        Else
            AddTextOptionST("AutoSortState"+0,"$Auto-Store", AutoStoreBehave[asc0],OPTION_FLAG_NONE)
            AddToggleOptionST("Weightless"+0,"$Weightless", WeightlesActive[0],OPTION_FLAG_NONE)
            AddToggleOptionST("MerchExcl"+0,"$MerchExcl", MerchExclActive[0],OPTION_FLAG_NONE)
            If AutoStoreChoice[0] != 0
                AddToggleOptionST("RedoItems"+0,"$RedoItems", RedoItemsActive[0],OPTION_FLAG_NONE)
            Else
                AddToggleOptionST("RedoItems"+0,"$RedoItems", RedoItemsActive[0],OPTION_FLAG_DISABLED)
            EndIf
        EndIf

 

I hope this helps.

Link to comment
Share on other sites

Thanks for your reply, I use a similar state to save/load settings but I need to save slots setings in a different file because I validate them at least 2 times: for player and for NPCs. So I had thought about an "array of states" that can be called repeatedly, but not sure if it's possible.

 

I've tryed using a strings array to name states:

 

State Slot[index]

EndState

 

But I get a error, seems that it only supports simple strings for StateName...

Link to comment
Share on other sites

It isn't really an array as the states have to be explicitly written out for each one but you can refer to them as if it were an array. If you look at the OnPageReset portion that I posted you'll see where a state is referenced as "ToggleState"+0 This is because the state itself is labeled "ToggleState0" It allows one to use repeating code for the states and just change the referencing number according to which option will be targeting that state.

Link to comment
Share on other sites

It isn't really an array as the states have to be explicitly written out for each one but you can refer to them as if it were an array. If you look at the OnPageReset portion that I posted you'll see where a state is referenced as "ToggleState"+0 This is because the state itself is labeled "ToggleState0" It allows one to use repeating code for the states and just change the referencing number according to which option will be targeting that state.

So, I can name a state as a string + an Int? I'll try tomorrow, if not, I'll try the old MCm way, since each option is asigned to an Int, maybe I can validate them to set each togle option.

Link to comment
Share on other sites

After trying hundreds of options using states, sometimes it worked, but i was having other issues: data not saved in files, options disappear when reloading page... Finally, I've opted for the old way, I've used one array to store optionID and other to store bool values for each toggle option, not sure if it is the most effective way but it works... Now I can set and save changes validating them in the OnOptionSelect event:

Event OnOptionSelect(Int optID)

    Int OptionIndex = 0

    While OptionIndex < 31

        If optID == OptionID[OptionIndex]

            OptionBool[OptionIndex] = !OptionBool[OptionIndex]

            SetToggleOptionValue(optID, OptionBool[OptionIndex])

            SlotNumber = OptionIndex + 30

            JSONUtil.SetIntValue(SlotsFile, "boolslot" + SlotNumber, OptionBool[OptionIndex] as Int)

            JSONUtil.Save(SlotsFile, true)

        EndIf

        OptionIndex += 1

    EndWhile

EndEvent
Link to comment
Share on other sites

There is a way to do this with the state method too and it's fairly easy.

 

You don't ever create the actual "ArmorSlot"+SlotIndex states in your script. Instead you put the OnSelectST() and OnDefaultST() events in the default script state (outside of any named state) and then use something like:

int OptionIndex = StringUtil.SubString(GetState(),9,2)) as int

to pull that numeric part of the state name when you need it. Scripts can switch to states that aren't actually defined and when they do that any event or function calls will use the code defined in the main level of the script.

 

So without testing I think your event above could be written:

Event OnSelectST()

    Int OptionIndex = StringUtil.SubString(GetState(),9,2)) as int

    OptionBool[OptionIndex] = !OptionBool[OptionIndex]

    SetToggleOptionValueST(GetState(), OptionBool[OptionIndex])

    SlotNumber = OptionIndex + 30

    JSONUtil.SetIntValue(SlotsFile, "boolslot" + SlotNumber, OptionBool[OptionIndex] as Int)

    JSONUtil.Save(SlotsFile, true)

EndEvent
Link to comment
Share on other sites

Interesting... I suppose GetState() give me current state name, true?

I'm not familiar with StrigUtil functions, and I didn't know that this kind of function was available. And probably it's fater and more efficient because don't need a "while" loop.

 

I'll try, thanks.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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