Jump to content

[LE] MCM and shrine-menu problems


Recommended Posts

  On 4/5/2019 at 6:03 PM, ReDragon2013 said:

I have doubt that next is changing the option text inside the MCM menu you like. Why?

If you end the function VampireMenu() each temp array is thrown away.

 

 

  Reveal hidden contents

 

 

everything you made with

string[] VampireText
string[] VampireMenu

keeps in this function and will never get transfer to MCM script

 

The function VampireMenu() is not suppost to make changes to the mcm.

Inside VampireMenu() i collect info from the mcm, and with that info i create fill the array VampireMenu.

 

The mcm is only there to select wich options you want to see in the menu when you activate the shrine.

After the menu is made and presented to the player, it is ok if the temp arrays get thrown away.

 

It is true that i still need to figure out a way to convert the array to a menu, but giving the array back to the mcm was never my intention.

 

So maybe i am stupid, but i don't understand your post.

Link to comment
Share on other sites

  On 4/5/2019 at 2:23 PM, ZombieNL said:

 

  On 4/5/2019 at 1:45 PM, IsharaMeradin said:

 

That is not how OnOptionHighlight works. It will only display text when an option is highlighted. If you put the mouse over any non-option area, no text will display. Unfortunately, it is working as intended.

Thnx for explaining this, but in that case i just leave it as it is now.

My mcm is easy enough to understand as it is. The InfoText was just a litle extra.

 

If the code you showed is producing the message in screenshot 7/9 from your mod-page, then i don't understand why you made it. Isn't this the way all mcm menu's work?

First you need to exit all menu's before you can notice any changes.

 

I think i prefere to explain my mcm menu in the description of my mod page. That should be enough.

 

The reason I needed to add that message box was for the following reason:

When I made that MCM script I did not know that calling certain functions within the option select would cause the MCM menu to eventually cease functioning. It is not an issue if using just my mod's MCM. But it was causing an issue when going from my mod's MCM to another mod's MCM. I have since learned that it is better to utilize the OnConfigClose event to register a single update (which even with a short duration is safely delayed until the menu system is exited) to handle starting quests, setting variables etc depending upon user selections. My Inventory Management System Rebuilt mod uses this method.

 

At any rate, however you choose to inform your users of the mod's intentions is up to you.

Link to comment
Share on other sites

  On 4/5/2019 at 11:54 AM, ZombieNL said:

 

  On 4/5/2019 at 2:50 AM, foamyesque said:

 

I'm not totally sure why there's the independent boolean variables at all. Why not the single array? Maybe another for reset-to-default information. Then you could just do

VampireVal[n] = !VampireVal[n]

The initial bools are there for when you load the mcm for the first time. The mcm should have some initial values to build the menu. I chose to make the initial values the same as the default values because i think that makes sense.

 

I don't know how to implement your suggestion into my script. I don't understand your comment enough.

 

 

You can set the initial bools in the Properties menu, since the boolean array is one. If you want a set to do the revert to default stuff, then you do need a second set of bools, but you can also make that a boolean array property and set them there.

 

So instead of a bunch of VampireValN variables for your defaults, you could use DefaultVampireVal[N] and only need to declare or manipulate one thing, just as you're doing with VampireVal[N] for your active booleans.

 

That way you can avoid hardcoding the defaults into the script and can replace the one-by-one copying into the active array in your OnInit block with a loop, which will be much more extensible should you decide to change the options in future.

 

As for the other piece:

 

Just as you can use ordinary arithmetic in an assignment (for example i = j + 1), you can use boolean arithmetic: EQUALS, NOT, AND, and OR, symbolically done as '==', '!', '&&', and '||'. Since all you're doing is flipping from one state to another you don't need an if-else-then sequence because you're always going to do the same operation: a NOT. This will turn trues into falses and falses into trues. You're doing this already with your operations ahead of the SetOptionToggle() call in your OnOptionSelect(), but you're then also doing explicit assignments of true and false to the boolean array, which you don't need to do.

 

A revision showing the implementation:

Scriptname VC_Script_MCM extends SKI_ConfigBase
{MCM menu script}

; For all code in this file i used the MCM video tutorials from DarkFox127 as starting point and started working from there.

bool bInitialized = false

string Property sVampireOptionName[] ;titles for the various options

bool Property bDefaultVampireVal[] ;fill this in the properties menu, replaces VampireValN below
;Bool VampireVal0 = True    ; Cancel button. This does not not show in mcm menu and therefore always is True.
;Bool VampireVal1 = True
;Bool VampireVal2 = False
;Bool VampireVal3 = True
;Bool VampireVal4 = False
;Bool VampireVal5 = False

int iVampireOption[] ;created & filled automatically
;int iVampire1
;int iVampire2
;int iVampire3
;int iVampire4
;int iVampire5

bool[] Property bVampireVal Auto    ; Make the array available for VC_Script_Shrine_MolagBal

Event OnConfigInit()
    ;Declare these in the property menu
    ;Pages = new string[1]
    ;Pages[0] = "Config"

    if !bInitialized
        int i = sVampireOptionName.Length
        int j = bDefaultVampireVal.Length
        iVampireOption = Utility.CreateIntArray(i)
        bVampireVal = Utility.CreateBoolArray(i)
        while i > 0
            i-=1
            if i < j ;precaution in case fewer defaults are specified than option names
                bVampireVal[i] = bDefaultVampireVal[i]
            endif
        endwhile
    endif
EndEvent

;Functionality moved to OnConfigInit()
;Event OnInit()
;    parent.OnInit()
;
;    VampireVal = new bool[6]    ; storing all bools in array
;
;    VampireVal[0] = VampireVal0
;    VampireVal[1] = VampireVal1
;    VampireVal[2] = VampireVal2
;    VampireVal[3] = VampireVal3
;    VampireVal[4] = VampireVal4
;    VampireVal[5] = VampireVal5
;EndEvent

Event OnPageReset(string page)
    If (Page == "")
        LoadCustomContent("Imaginary_Image")
        Return
    Else
        UnLoadCustomContent()
    EndIf

    If (Page == "Config")
        SetCursorFillMode(TOP_TO_BOTTOM)
        AddHeaderOption("Vampire Menu")

        int i = sVampireOptionName.Length
        while i > 1 ;because of hidden cancel button? I do not understand the purpose of that
            i-=1
            iVampireOption[i] = AddToggleOption(sVampireOptionName[i], bVampireOption[i])
        endwhile

        ;iVampire1 = AddToggleOption("Vampire Armor", VampireVal1)
        ;iVampire2 = AddToggleOption("Vampire Armor without fighting", VampireVal2)
        ;iVampire3 = AddToggleOption("Ancient Blood", VampireVal3)
        ;iVampire4 = AddToggleOption("Cure Vampirism", VampireVal4)
        ;iVampire5 = AddToggleOption("Turn into a Lycan", VampireVal5)
    EndIf
EndEvent

Event OnOptionSelect(int option)
    If (CurrentPage == "Config")

        int iIndex = iVampireOption.Find(option)
        if iIndex < 0
            return
        endif

        bVampireVal[iIndex] = !bVampireVal[iIndex]
        SetToggleOptionValue(iVampireOption[iIndex], bVampireVal[iIndex])

        ;all of the below is now redundant        
        ;If        (option == iVampire1)
        ;    VampireVal1 = !VampireVal1
        ;       SetToggleOptionValue(iVampire1, VampireVal1)
        ;       If VampireVal1 == True
        ;        VampireVal[1] = True
        ;       Else
        ;        VampireVal[1] = False
        ;    EndIf
        ;ElseIf    (option == iVampire2)
        ;    VampireVal2 = !VampireVal2
        ;    SetToggleOptionValue(iVampire2, VampireVal2)
        ;    VampireVal2 = VampireVal2
        ;    If VampireVal2 == True
        ;        VampireVal[2] = True
        ;    Else
        ;        VampireVal[2] = False
        ;    EndIf
        ;ElseIf    (option == iVampire3)
        ;    VampireVal3 = !VampireVal3
        ;    SetToggleOptionValue(iVampire3, VampireVal3)
        ;    VampireVal3 = VampireVal3
        ;    If VampireVal3 == True
        ;        VampireVal[3] = True
        ;    Else
        ;        VampireVal[3] = False
        ;    EndIf
        ;ElseIf    (option == iVampire4)
        ;    VampireVal4 = !VampireVal4
        ;    SetToggleOptionValue(iVampire4, VampireVal4)
        ;    VampireVal4 = VampireVal4
        ;    If VampireVal4 == True
        ;        VampireVal[4] = True
        ;    Else
        ;        VampireVal[4] = False
        ;    EndIf
        ;ElseIf    (option == iVampire5)
        ;    VampireVal5 = !VampireVal5
        ;    SetToggleOptionValue(iVampire5, VampireVal5)
        ;    VampireVal5 = VampireVal5
        ;    If VampireVal5 == True
        ;        VampireVal[5] = True
        ;    Else
        ;        VampireVal[5] = False
        ;    EndIf
        ;EndIf
    EndIf
EndEvent

Event OnOptionDefault(int option)

    if (CurrentPage == "Config") ;this is a needed check that was missed in original code
        int iIndex = iVampireOption.Find(option)
        if iIndex < 0
            return
        endif

        bVampireVal[iIndex] = bDefaultVampireVal[iIndex]
        SetToggleOptionValue(iVampireOption[iIndex], bVampireVal[iIndex])
    endif

    ;all of the below is now redundant
    ;If        (option == iVampire1)
    ;    VampireVal1 = True
    ;    SetToggleOptionValue(iVampire1, VampireVal1)
    ;    VampireVal[1] = True
    ;ElseIf    (option == iVampire2)
    ;    VampireVal2 = False
    ;    SetToggleOptionValue(iVampire2, VampireVal2)
    ;    VampireVal[2] = False
    ;ElseIf    (option == iVampire3)
    ;    VampireVal3 = True
    ;    SetToggleOptionValue(iVampire3, VampireVal3)
    ;    VampireVal[3] = True
    ;ElseIf    (option == iVampire4)
    ;    VampireVal4 = False
    ;    SetToggleOptionValue(iVampire4, VampireVal4)
    ;    VampireVal[4] = False
    ;ElseIf    (option == iVampire5)
    ;    VampireVal5 = False
    ;    SetToggleOptionValue(iVampire5, VampireVal5)
    ;    VampireVal[5] = False
    ;EndIf
EndEvent

I'm not exactly sure what the purpose is behind the 'cancel button' because AFAICT you have no code whatsoever that implements it. Normally I'd just iterate the arrays all the way to zero, but it throws things out on actually adding the toggles, which is why that particular loop is set to stop at one instead.

 

Provided you set up the properties correctly this should have the same functionality, but be much easier to add or remove options; you just need to modify a title and, optionally, a default value. I also added a missing CurrentPage check to the OnOptionDefault() block.

Edited by foamyesque
Link to comment
Share on other sites

Your new version of the mcm script looks great, i like the idea of shrinking the wall of code, but don't forget:

    If (Page == "Config")
        SetCursorFillMode(TOP_TO_BOTTOM)
        AddHeaderOption("Vampire Menu")
        iVampire1 = AddToggleOption("Vampire Armor", VampireVal1)
        iVampire2 = AddToggleOption("Vampire Armor without fighting", VampireVal2)
        iVampire3 = AddToggleOption("Ancient Blood", VampireVal3)
        iVampire4 = AddToggleOption("Cure Vampirism", VampireVal4)
        iVampire5 = AddToggleOption("Turn into a Lycan", VampireVal5)
    EndIf

is only a part of the total mcm i want to make. I think i mentioned this inside the script for the shrine in the added comments, but i am not sure it was mentioned in one of the forum posts. If not, then sorry for that. The plan was to get the vampire part working first and then add the mortal and lycan stuff later. The total menu layout will look something like this:

    If (Page == "Config")
        SetCursorFillMode(LEFT_TO_RIGHT)
        AddHeaderOption("Vampire Menu")
        AddHeaderOption("Mortal Menu")
        iVampire1 = AddToggleOption("Vampire Armor", VampireVal1)
        AddToggleOption("Cure All Disseases", True)
        iVampire2 = AddToggleOption("Vampire Armor without fighting", VampireVal2)
        AddToggleOption("Sanguinare Vampiris", True)
        iVampire3 = AddToggleOption("Ancient Blood", VampireVal3)
        AddToggleOption("Turn into a Vampire", True)
        iVampire4 = AddToggleOption("Cure Vampirism", VampireVal4)
        AddToggleOption("Turn into a Lycan", False)
        iVampire5 = AddToggleOption("Turn into a Lycan", VampireVal5)
        AddEmptyOption()
        AddEmptyOption()
        AddEmptyOption()
        AddHeaderOption("Lycan Menu")
        AddEmptyOption()
        AddToggleOption("Lycans can't use the shrine", False)
        AddEmptyOption()
        AddToggleOption("Cure Lycantrophy", True)
        AddEmptyOption()
        AddToggleOption("Turn into a Vampire", True)        
    EndIf

As you can see i did not add any actions to the mortal and lycan options yet.
My thought was, once i get the vampire menu working, the other 2 are just more of the same and easy to add in.

Once i get the vampire stuff working and i completed the whole mcm menu, then it is a good idea to shrink the code with the code you suggested. But before i even start with the mortal and lycan stuff, i want to get the vampire stuff working first.

I see you like to add all you can to the properties-window in the CK, is that personal preference, or is there another reason for doing that?
I like to keep everything inside the script whenever possible because it's easier when you need to change/add something. If you store everything in the properties-window then you need to start CK for every change you want to make. If you keep everything inside the script, then you can just open notepad++ to edit and compile scripts. Or maybe i am doing something wrong, that is also possible.

About the cancel button:
I want to make sure the new menu always has a cancel button, this way you are not forced to choose one of the options if you activate the shrine by accident.
In the function VampireMenu() inside VC_Script_Shrine_MolagBal i check wich bools are true.
Only true bools are added to the new menu.
Because there is no option to disable the cancel button in the mcm, Bool VampireVal0 is always True.

I am sure this is not the best way to do this, but it works.
Here is the script VC_Script_Shrine_MolagBal

  Reveal hidden contents

 

 

Link to comment
Share on other sites

What I prefer to do is reduce the amount of repetition of stuff, particularly of magic numbers, and especially if there's chances I might want to change it in the future. Since I do pretty much all my coding and compiling in the CK anyway, kicking out to the property filling menus doesn't particularly impede the workflow, and the approach otherwise has a bunch of benefits in terms of flexibility, reuse, extension, and interaction with other scripts.

 

As much as I am able, I try to keep explicit constant use in my scripts limited to comparisons to zero, true, false, and none. Nearly everything else comes from a variable, property, or function in one way or another.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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