Jump to content

Perplexed by Papyrus


Recommended Posts

So my brain is in model building mode at the moment, so I;m having a hard time wrapping my head around one of my MCM menu function at the moment, so hopefully someone will see a simple way of making this happen, but right now I'm just not able to wrap my head around it and I'd like to get this little bug fixed for my next update,

 

I have an MCM menu which creates lists of displayed museum items and if the display item is enabled, it gets the item name from the index of items which matches the index of displays, so if display 46 is enabled, it will get the name from index 46 on the item list. This works perfectly for any item and display pair and any display + sub form of possible items pairing, but when I have more than one display for a single entry I'm a bit vexed.

 

Basically this function will look at the list and see if the item has a name and run it's normal process which is fine. If it finds that it does not have a name, it fills a property as a formlist and then deep dives that sub list to find the name of the item. The issue I am having is that I'd like to be able to cycle through the list of displays until it finds one that is enabled, fill that index as the property and then propagate that item to the MCM list (which puts a check box on or off depending on it's enabled state). If there are NONE of the items enabled on the list, I'd like to be able to pull the sublist item on index 0 and just throw it to the list as not enabled. I know this is probably not making total sense at the moment, but like I said, I'm totally in another mindset at the moment lol. Anyways, here is the script function. Thanks in advance.

 

 

 
Function ListJewelry()
   ObjectReference DISP
   Form ITM

While Index < ITMCNT
    ITM = ITMLIST.GetAt(Index) as Form
    
    if ITM.GetName() != ""    ; If the item on the list is an actual item----------------------------------
        ItemName = ITM.GetName()
        DISP = DISPLIST.GetAt(Index) as ObjectReference
            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif
    else                                  ; The item on the list is a formlist -----------------------------------------
        SubList2 = DISPLIST.GetAt(Index) as FormList
        SubList = ITMLIST.GetAt(Index) as FormList
        int Index2 = Sublist2.GetSize()
        while Index2
            Index2 -= 1
            ObjectReference OB = Sublist2.GetAt(index2) as ObjectReference
            if OB.IsEnabled()
                DISP = Sublist2.GetAt(Index2) as ObjectReference
                ITM = Sublist.GetAt(Index2) as Form
                ItemName = ITM.GetName()
                Index2 = 0
            Endif
            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif    
        EndWhile    
    Endif

    Index += 1
EndWhile

EndFunction
 

 

 

Link to comment
Share on other sites

Knock on wood... this may do it. Obviously not tested.

 

What I did was create a function which you pass in the formlist and its size. It then checks to see if the entry, as an object reference, is enabled. If it is, it returns the current index value. I then inserted the function call with a check that the value was not the default -1. If it is not, then modify the existing Index2 value to match the returned index + 1 (this is because you subtract one before doing anything else). Since the modified Index2 should be pointing directly to an enabled display, the while loop should not well loop but do what it needs to for the display & item pair.

 

Of course you may find that it needs tweaking after you do some testing...

 

 

Function ListJewelry()
   ObjectReference DISP
   Form ITM

While Index < ITMCNT
    ITM = ITMLIST.GetAt(Index) as Form
    
    if ITM.GetName() != ""    ; If the item on the list is an actual item----------------------------------
        ItemName = ITM.GetName()
        DISP = DISPLIST.GetAt(Index) as ObjectReference
            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif
    else                                  ; The item on the list is a formlist -----------------------------------------
        SubList2 = DISPLIST.GetAt(Index) as FormList
        SubList = ITMLIST.GetAt(Index) as FormList
        int Index2 = Sublist2.GetSize()

        ; INSERT BEGIN
            Int NewIdx = CheckDisplays(SubList2,Index2)
            If NewIdx != -1
                Index2 = (NewIdx + 1)
            EndIf
        ; INSERT END

        while Index2
            Index2 -= 1
            ObjectReference OB = Sublist2.GetAt(index2) as ObjectReference
            if OB.IsEnabled()
                DISP = Sublist2.GetAt(Index2) as ObjectReference
                ITM = Sublist.GetAt(Index2) as Form
                ItemName = ITM.GetName()
                Index2 = 0
            Endif
            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif    
        EndWhile    
    Endif

    Index += 1
EndWhile

EndFunction

Int Function CheckDisplays(FormList DispList, Int ListSize)
    Int Result = -1
    Idx = 0
    While Idx < ListSize
        If (DispList.GetAt(Idx) as ObjectReference).IsEnabled()
            Result = Idx
        EndIf
        If Result != -1
            Idx = ListSize  ;got value - get out of loop
        Else
            Idx += 1
        EndIf
    EndWhile
    Return Result
EndFunction 

 

 

Link to comment
Share on other sites

alright so I popped it in and had to and INT to the Idx property and change displist to displist1 in the second function's function property because displist was already being used in the script, but got it to compile.

 

Here's what it does: Open the MCM menu and it lists all items which are formlists as blank with an empty check box and lists the single item forms on the formlists properly. When I place the necromancer amulet on display, ALL of the blank slots list as the necromancer amulet and they all check off.

 

I am seeing one issue with the overall concept here in that the item display is not being listed when not on display, which is sort of what I was running into myself.

 

Here' s the slightly tweaked version:

 

 

Function ListJewelry()
   ObjectReference DISP
   Form ITM

While Index < ITMCNT
    ITM = ITMLIST.GetAt(Index) as Form
    
    if ITM.GetName() != ""    ; If the item on the list is an actual item----------------------------------
        ItemName = ITM.GetName()
        DISP = DISPLIST.GetAt(Index) as ObjectReference
            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif
    else                                  ; The item on the list is a formlist -----------------------------------------
        SubList2 = DISPLIST.GetAt(Index) as FormList
        SubList = ITMLIST.GetAt(Index) as FormList
        int Index2 = Sublist2.GetSize()

        ; INSERT BEGIN
            Int NewIdx = CheckDisplays(SubList2,Index2)
            If NewIdx != -1
                Index2 = (NewIdx + 1)
            EndIf
        ; INSERT END

        while Index2
            Index2 -= 1
            ObjectReference OB = Sublist2.GetAt(index2) as ObjectReference
            if OB.IsEnabled()
                DISP = Sublist2.GetAt(Index2) as ObjectReference
                ITM = Sublist.GetAt(Index2) as Form
                ItemName = ITM.GetName()
                Index2 = 0
            Endif
            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif    
        EndWhile    
    Endif

    Index += 1
EndWhile

EndFunction

Int Function CheckDisplays(FormList DispList1, Int ListSize)
    Int Result = -1
    int Idx = 0
    While Idx < ListSize
        If (DispList1.GetAt(Idx) as ObjectReference).IsEnabled()
            Result = Idx
        EndIf
        If Result != -1
            Idx = ListSize  ;got value - get out of loop
        Else
            Idx += 1
        EndIf
    EndWhile
    Return Result
EndFunction
Link to comment
Share on other sites

Okay, lets try this one. Pretty much the same thing. Just added some logic into the main portion that has it grab the name of the item in index 0 of the list so that the ItemName variable will have a value for the unchecked toggle option.

 

 

 

Function ListJewelry()
   ObjectReference DISP
   Form ITM

While Index < ITMCNT
    ITM = ITMLIST.GetAt(Index) as Form
    
    if ITM.GetName() != ""    ; If the item on the list is an actual item----------------------------------
        ItemName = ITM.GetName()
        DISP = DISPLIST.GetAt(Index) as ObjectReference
            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif
    else                                  ; The item on the list is a formlist -----------------------------------------
        SubList2 = DISPLIST.GetAt(Index) as FormList
        SubList = ITMLIST.GetAt(Index) as FormList
        int Index2 = Sublist2.GetSize()

        ; INSERT BEGIN
            Int NewIdx = CheckDisplays(SubList2,Index2)
            If NewIdx != -1
                Index2 = (NewIdx + 1)
            Else
                Index2 = 1
            EndIf
        ; INSERT END

        while Index2
            Index2 -= 1
            ObjectReference OB = Sublist2.GetAt(index2) as ObjectReference
            if OB.IsEnabled()
                DISP = Sublist2.GetAt(Index2) as ObjectReference
                ITM = Sublist.GetAt(Index2) as Form
                ItemName = ITM.GetName()
                Index2 = 0

        ; INSERT BEGIN
            Else
                ITM = Sublist.GetAt(Index2) as Form
                ItemName = ITM.GetName()
            Endif
        ; INSERT END

            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif    
        EndWhile    
    Endif

    Index += 1
EndWhile

EndFunction

Int Function CheckDisplays(FormList DispList1, Int ListSize)
    Int Result = -1
    int Idx = 0
    While Idx < ListSize
        If (DispList1.GetAt(Idx) as ObjectReference).IsEnabled()
            Result = Idx
        EndIf
        If Result != -1
            Idx = ListSize  ;got value - get out of loop
        Else
            Idx += 1
        EndIf
    EndWhile
    Return Result
EndFunction 

 

 

Link to comment
Share on other sites

This might work. Without seeing what is going on myself it is hard to pinpoint. What I think may be happening is that DISP variable is retaining the previous value. So when the display is not enabled, we set DISP to none at the same point as we grab the current sub list item name that matches the disabled display. The should cause the later check to fail and do the toggle option with a false value rather than true.

 

 

 

Function ListJewelry()
   ObjectReference DISP
   Form ITM

While Index < ITMCNT
    ITM = ITMLIST.GetAt(Index) as Form
    
    if ITM.GetName() != ""    ; If the item on the list is an actual item----------------------------------
        ItemName = ITM.GetName()
        DISP = DISPLIST.GetAt(Index) as ObjectReference
            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif
    else                                  ; The item on the list is a formlist -----------------------------------------
        SubList2 = DISPLIST.GetAt(Index) as FormList
        SubList = ITMLIST.GetAt(Index) as FormList
        int Index2 = Sublist2.GetSize()

        ; INSERT BEGIN
            Int NewIdx = CheckDisplays(SubList2,Index2)
            If NewIdx != -1
                Index2 = (NewIdx + 1)
            Else
                Index2 = 1
            EndIf
        ; INSERT END

        while Index2 >= 1
            Index2 -= 1
            ObjectReference OB = Sublist2.GetAt(index2) as ObjectReference
            if OB.IsEnabled()
                DISP = Sublist2.GetAt(Index2) as ObjectReference
                ITM = Sublist.GetAt(Index2) as Form
                ItemName = ITM.GetName()
                Index2 = 0

        ; INSERT BEGIN
            Else
                DISP = NONE
                ITM = Sublist.GetAt(Index2) as Form
                ItemName = ITM.GetName()
            Endif
        ; INSERT END

            if DISP.IsEnabled()
                AddToggleOption(" " + ItemName + " ", true)
            else
                AddToggleOption(" "+ ItemName +" ", False)
            endif    
        EndWhile    
    Endif

    Index += 1
EndWhile

EndFunction

Int Function CheckDisplays(FormList DispList1, Int ListSize)
    Int Result = -1
    int Idx = 0
    While Idx < ListSize
        If (DispList1.GetAt(Idx) as ObjectReference).IsEnabled()
            Result = Idx
        EndIf
        If Result != -1
            Idx = ListSize  ;got value - get out of loop
        Else
            Idx += 1
        EndIf
    EndWhile
    Return Result
EndFunction  

 

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

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