Jump to content

Having trouble with updating a string element in an array.


Recommended Posts

The array that contains a list of string values representing item categories.

 

String[] Function CallList()
    String[] compressType = new String[9]
    compressType[0] = "All"
    compressType[1] = "Weapons"
    compressType[2] = "Armors"
    compressType[3] = "Ammo"
    compressType[4] = "Potions"
    compressType[5] = "Books"
    compressType[6] = "Notes"
    compressType[7] = "Misc"
    compressType[8] = "Soulgems"
return compressType
EndFunction

 

 

 

The main array that walks through the inventory and adds up the total weight for each form of their respective categories found, taking in account for forms that are the same type but not the same form.

 

String[] Function SetWeights()
    String[] TypeList = CallList()
    ; Types match the values of the CallList elements.
    Int[] types = new Int[8]
    types[0] = 41 ; Weapon
    types[1] = 26 ; Armor
    types[2] = 42 ; Ammo
    types[3] = 46 ; Potions
    types[4] = 27 ; Books
    types[5] = 48 ; Notes
    types[6] = 32 ; Misc
    types[7] = 52 ; Soul Gems

    Form previousItem = none
    Float previousTotalItemWeight = 0.0
    Float totalItemWeight = 0.0
    Int previousItemType = -1
    Int totalItems = PlayerRef.GetNumItems()
    Int typeFoundIndex = 0
    Int previousAmount = 0
    Int currentAmount = 0
    Float valueForString = 0.0
    String stringValue = ""
    Int i = 0
    While i < totalItems
        Form currentItem = PlayerRef.GetNthForm(i)
        typeFoundIndex = types.Find(currentItem.GetType())            ; return the index of this type
        debug.trace("Index: "+typeFoundIndex+", Type: "+TypeList[typeFoundIndex + 1])
        if typeFoundIndex > -1
            currentAmount = PlayerRef.GetItemCount(currentItem)       ; get the amount of this form found in the inventory
            totalItemWeight = currentItem.GetWeight() * currentAmount ; get the total weight from the amount of this form found in the inventory
            if currentAmount > 0
                if previousItemType == types[typeFoundIndex]           ; if the last form found was the same type as the current form
                    currentAmount += previousAmount                    ; add the amount of the previous form to the current form's amount
                    totalItemWeight += previousTotalItemWeight         ; add the total weight of the previous form to the current form's total weight
                    stringValue = TypeList[typeFoundIndex + 1] + totalItemWeight    ; Problem area.
                    TypeList[typeFoundIndex + 1] = stringValue                        ; Problem area.
                    debug.trace("Amount of type "+TypeList[typeFoundIndex + 1]+ " is "+currentAmount+ " and the total weight is "+totalItemWeight+ ", string: "+stringValue)
                endif
            endif
        endif
        previousAmount = currentAmount                                    ; set the current form as the previous form
        previousItemType = types[typeFoundIndex]                          ; set the current type of the current form as the previous type
        previousTotalItemWeight = totalItemWeight                         ; add the two weight values together
        ;debug.trace("PrevAmt: "+previousAmount+", Type: "+previousItemType+", wgt: "+previousTotalItemWeight+ " and valueForString: "+valueForString)
        i += 1                                                            ; move to the next form
    EndWhile
return TypeList
EndFunction

 

 

I've marked the areas I believe are where the problem lies since that's where the strings display the totals.

 

The end result no matter how many different ways I code that section is always like this: Armors8.0000009.00000010.000000. The string variable/array element is appending in an unexpected way. It should be overwriting the string with the new appended string value. I want the end result to be Armors 10.000000.I'll worry about the formatting later.

Edit: It works as expected if I only assign totalItemWeight to the TypeList array. That will completely overwrite the category string though and replace it with 10.000000 instead. I think maybe I don't understand how string appendage works. Papyrus seems to not like me trying to add strings together and update only a portion.

 

 

Edited by VampiricEmpress
Link to comment
Share on other sites

If I understand correctly, you're trying to get the total weight for each item type in the players inventory and then display them? If so, what you're doing now is trying to add floats at the end of a string, which won't work. Example:

 

String MyString = "Weapon "

MyString += 1.0

MyString += 2.0

 

Results in "Weapon 1.0000002.000000"

 

Instead, I would make a float array to keep track of weights, then add them to your type string array after, like so:

 

String[] Function SetWeights()

    String[] TypeList = CallList()
    ; Types match the values of the CallList elements.
    Int[] types = new Int[8]
    types[0] = 41 ; Weapon
    types[1] = 26 ; Armor
    types[2] = 42 ; Ammo
    types[3] = 46 ; Potions
    types[4] = 27 ; Books
    types[5] = 48 ; Notes
    types[6] = 32 ; Misc
    types[7] = 52 ; Soul Gems

    Float[] TypeWeights = New Float[8]
    
    Form previousItem = none
    Int totalItems = PlayerRef.GetNumItems()
    Int typeFoundIndex = 0
    Int i = 0
    While i < totalItems
        Form currentItem = PlayerRef.GetNthForm(i)
        typeFoundIndex = types.Find(currentItem.GetType())            ; return the index of this type
        debug.trace("Index: "+typeFoundIndex+", Type: "+TypeList[typeFoundIndex + 1])
        if typeFoundIndex > -1
            Float currentAmount   = PlayerRef.GetItemCount(currentItem) as float     ; get the amount of this form found in the inventory (as float so multiplication in next step is accurate.
            Float totalItemWeight = currentItem.GetWeight() * currentAmount ; get the total weight from the amount of this form found in the inventory
            if currentAmount > 0
                TypeWeights[typeFoundIndex] = TypeWeights[typeFoundIndex] + totalItemWeight ;add total weight of item to weight type
            endif
        endif
        i += 1                                                            ; move to the next form
    EndWhile
    
    i = 0 
    While i < 8
        TypeList[i] = TypeList[i] + " " + TypeWeights[i] ;add weight to type string 
        i += 1
    EndWhile
    
return TypeList
EndFunction
Link to comment
Share on other sites

@Sphered - I forgot about SKSE's string functions.
@dylbill: Yeah that is what I'm trying to do and that is what is happening on screen. That solved the issue, thank you kindly sir. I spent 10+ hrs trying to solve it. All those previousItem/count etc in my earlier post was me trying to get around the issue. I had to adjust the code a bit to shift elements down. There's a reason the TypeList is 9 elements instead of 8. The "All" element has to be there.

 

Here's the result:

Bhz9Mxl.jpg



This is not through SkyUI, so the place value stripping was done manually;

String Function StripDecimals(Float value)
    ; Strips Skyrims max place value displayed from millionths(0.000000) to tenths(0.0).
    
    ; Determine if the value is a decimal but 0 is in the tenths place.
    Float difference = value - value as int
    if difference > 0.0

        ; Turn the tenths place value into a true whole number.
        int wholeNum = (difference * 10) as int

        ; append the whole number to the tenths place value string and return it.
        ; Basically splitting the 2 values of the decimal on both sides of the decimal point
        ; and appending those values to opposite sides of the string deciamal point.
        return value as int + "."+wholeNum
    else
        return value as int +".0"
    endif
        
EndFunction
Edited by VampiricEmpress
Link to comment
Share on other sites

You might consider the SKSE function GetContainerForms() and just read/sift through valid types on demand and fetch whatever

 

I've used this before to create a fake second inventory. Pretty handy and at least for me didnt seem to cause performance issues

Link to comment
Share on other sites

Another thing you can try is to use threading. Basically, make new scripts and attach them to different forms in the ck. Then use either update, or mod events that get and save the item weights. So for example if the player has 20 items in inventory, thread 1 will do items 1 through 10 and thread 2 will do items 11 through 20. If you use events you can make the threads run simultaneously. I had to do something similar for my mod Customize Weapon Speed, as by default it set's speeds for all weapons in game when you load a save. Without threading it took around 2 minutes. Using 5 threads I got it down to 20 seconds. Source code is provided.

Link to comment
Share on other sites

I was looking through Papyrus Extender and I found this function:

Form[] Function AddItemsOfTypeToArray(ObjectReference akRef, int aiFormType, bool abNoEquipped = true, bool abNoFavorited = false, bool abNoQuestItem = false) global native
Using this I think would speed things up considerably, as you wouldn't have to use GetType on every item.
Link to comment
Share on other sites

I've downloaded you mod to check out how you did it.

 

Seems like a lot of stuff is possible with his extender and even commonlib has exposed some stuff I can mess around with.

 

Except I don't know C++ and studying now means I wont be able to do anything meaningful, Skyrim wise, for at least a year or more.

 

In any case, I can also fake my own getType by casting the forms to their types and check what they are like that.

 

::rambles more::

 

Point: I want to keep dependencies down so I'll use alternatives to PO3's extensions.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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