Jump to content

Populating MCM AddMenuOptionST with player spells and lesser powers


Recommended Posts

IA710 wrote: "Any suggestions are welcome."

 

Maybe you remember to an older MCM posting, I wrote similiar 'use functions to separate code and reduce redundancy'.

I think the use of "HAC_PlSpellForms" does not make sense. Link to storageutil papyrus source: https://github.com/Vicyntae/SCLSE/blob/master/Data/Source/Scripts/StorageUtil.psc

 

My optimizations as follow:

    ; PapyrusUtil name: "HAC_Spells"         ; list of strings
    ; PapyrusUtil name: "HAC_SpForms"        ; list of forms

EVENT OnSpellLearned(Spell akSpell)  ; event added by Papyrus Script Extender
;===================
; add the spell to storageutil stringlist
    myF_AddTo_HAC_Spells(akSpell)

; Sort the final output spell names stringlist.
    StorageUtil.StringListSort(None, "HAC_Spells")

; Clear storageutil list of spell forms and add new forms
    myF_Strings_To_Forms()
ENDEVENT


;-------------------------------------------
FUNCTION myF_AddTo_HAC_Spells(Spell akSpell)  ; helper
;-------------------------------------------
    string s = akSpell.GetName()

; Make sure that the spell name string is mapped to the correct formid
    StorageUtil.SetFormValue(None, s, akSpell as Form)

; Remove index 0 of the final output stringlist
    StorageUtil.StringListShift(None, "HAC_Spells")

; Add the spell name to the final output stringlist with allowdupes FALSE
    StorageUtil.StringListAdd(None, "HAC_Spells", s, False)
ENDFUNCTION


;--------------------------
FUNCTION RefreshAllSpells()
;--------------------------
; Clear storageutil stringlist and add new spell strings
    myF_CreateSpellList()

; Sort the final output player spell names stringlist.
    StorageUtil.StringListSort(None, "HAC_Spells")

; Clear storageutil list of spell forms and add new forms
    myF_Strings_To_Forms()
ENDFUNCTION


;--------------------------------------------
FUNCTION myF_Update_HAC_Spells(Spell akSpell)  ; helper
;--------------------------------------------
    string s = akSpell.GetName()                                   ; get the name and use storageutil functions
    StorageUtil.SetFormValue(None, s, akSpell as Form)             ; convert formid value of the spell as string:formid map
    StorageUtil.StringListAdd(None, "HAC_Spells", s, False)        ; add spellname to stringlist
ENDFUNCTION


;-----------------------------
FUNCTION myF_CreateSpellList()  ; helper
;-----------------------------
    actor player = Game.GetPlayer()
    StorageUtil.StringlistClear(None, "HAC_Spells")                ; *** clear *** strings

; Build an array with all spells in the game
    spell[] a = PO3_SKSEFunctions.GetAllSpells()

    int i = a.Length        ; a = allSpellsInTheGame
    WHILE (i)
        i = i - 1
        spell akSpell = a[i]

        IF (akSpell) && akSpell.GetNthEffectMagicEffect(0).GetCastingType()  ; get the first MagicEffect of the spell
            ; 1 = Fire and Forget
            ; 2 = Concentration

            ; check every playable spell from master list to see if the player has it
            IF player.HasSpell(akSpell)
                myF_Update_HAC_Spells(akSpell)
            ENDIF
;;;        ELSE
            ; 0 = constant effect, we are not interested in this spell
        ENDIF
    ENDWHILE
ENDFUNCTION


;------------------------------
FUNCTION myF_Strings_To_Forms()  ; helper
;------------------------------
    int m = StorageUtil.StringListCount(none, "HAC_Spells")
    StorageUtil.FormListClear(None, "HAC_SpForms")                ; *** clear *** forms

; using the sorted string list to build the final output player spell formlist
    int i = 0
    WHILE (i < m)
        form fm = StorageUtil.GetFormValue(none, StorageUtil.StringListGet(None, "HAC_Spells", i) )
        IF ( fm )
            StorageUtil.FormListAdd(None, "HAC_SpForms", fm)
        ENDIF
        i = i + 1
    ENDWHILE

; insert at index 0 of sorted stringlist an escape menu as backdoor
    StorageUtil.StringListInsert(None, "HAC_Spells", 0, "Back / Cancel / No Change")
ENDFUNCTION

Edited by ReDragon2013
Link to comment
Share on other sites

  • Replies 54
  • Created
  • Last Reply

Top Posters In This Topic

Sphered: The code in post #8 pretty much is the mod, conditionally auto casts some spells on a 5 second loop - I think ReDragon2013 has me going in the right direction with this issue, but if you find anything that I can improve in the "Cast_Check" function in post #8 please let me know :smile:

 

ReDragon2013: I actually had taken your advice when I first wrote this, and was trying to run it in OnConfigInit and it was in I think 2 helpers and a main function, but could never get it to run quick enough to keep it there.

 

Eventually I was trying all sorts of things to determine where the slow parts were so I knew where to put what and THATS when "HAC_PlSpellForms" came into being. At some point I decided I would never run it apart and put it all in one big function (not sure exactly why I did that, maybe to go through it all and comment it?). I was trying this in JContainers, CK Formlists, all sorts of things.

 

Your suggestions helped immensely, with some very minor additions and tweaks, the entire referencealias script as it is right now is below. The refreshallspells() is now about 25% quicker too.

 

Thank you all as usual!

 

Script:

 

 

	; PapyrusUtil name: "HAC_Spells"         ; list of strings
	; PapyrusUtil name: "HAC_SpForms"        ; list of forms


Event OnInit()

	Debug.Notification("HAC: Starting Spell Maintenance")
	RefreshAllSpells()
	Debug.Notification("HAC: Spell Maintenance Completed")
	PO3_Events_Alias.RegisterForSpellLearned(self)
EndEvent


Event OnSpellLearned(Spell akSpell)  ; event added by Papyrus Script Extender

; add the spell to storageutil stringlist
	AddTo_HAC_Spells(akSpell)
; Sort the final output spell names stringlist.
	StorageUtil.StringListSort(None, "HAC_Spells")
; Clear storageutil list of spell forms and add new forms
	Strings_To_Forms()
EndEvent


Event OnPlayerLoadGame()

	Debug.Notification("HAC: Starting Spell Maintenance")
	RefreshAllSpells()
	Debug.Notification("HAC: Spell Maintenance Completed")
EndEvent


Function RefreshAllSpells()

; Clear storageutil stringlist and add new spell strings
	CreateSpellList()
; Sort the final output player spell names stringlist.
	StorageUtil.StringListSort(None, "HAC_Spells")
; Clear storageutil list of spell forms and add new forms
	Strings_To_Forms()
EndFunction


Function AddTo_HAC_Spells(Spell akSpell)  ; helper function

	string s = akSpell.GetName()
; Make sure that the spell name string is mapped to the correct formid
	StorageUtil.SetFormValue(None, s, akSpell as Form)
; Remove index 0 of the final output stringlist
	StorageUtil.StringListShift(None, "HAC_Spells")
; Add the spell name to the final output stringlist with allowdupes FALSE
	StorageUtil.StringListAdd(None, "HAC_Spells", s, False)
EndFunction


Function Update_HAC_Spells(Spell akSpell)  ; helper function

	string s = akSpell.GetName()                                   ; get the name and use storageutil functions
	StorageUtil.SetFormValue(None, s, akSpell as Form)             ; convert formid value of the spell as string:formid map
	StorageUtil.StringListAdd(None, "HAC_Spells", s, False)        ; add spellname to stringlist
EndFunction


Function CreateSpellList()  ; helper function

	actor player = Game.GetPlayer()
	StorageUtil.StringlistClear(None, "HAC_Spells")                ; *** clear *** strings
; Build an array with all spells in the game
	spell[] a = PO3_SKSEFunctions.GetAllSpells()
	int i = a.Length        ; a = allSpellsInTheGame
	While (i)
		i = i - 1
		spell akSpell = a[i]
		If (akSpell) && akSpell.GetNthEffectMagicEffect(0).GetCastingType() > 0  ; get the first MagicEffect of the spell
			; 1 = Fire and Forget
			; 2 = Concentration
			; check every playable spell from master list to see if the player has it
			If player.HasSpell(akSpell)
				Update_HAC_Spells(akSpell)
			EndIf
		EndIf
	EndWhile
EndFunction


Function Strings_To_Forms()  ; helper function

	int m = StorageUtil.StringListCount(None, "HAC_Spells")
	StorageUtil.FormListClear(None, "HAC_SpForms")       ; *** clear *** forms
; using the sorted string list to build the final output player spell formlist
	int i = 0
	While (i < m)
		form fm = StorageUtil.GetFormValue(None, StorageUtil.StringListGet(None, "HAC_Spells", i))
		If ( fm )
			StorageUtil.FormListAdd(None, "HAC_SpForms", fm)
		EndIf
		i = i + 1
	EndWhile
; insert at index 0 of sorted stringlist an escape menu as backdoor
	StorageUtil.StringListInsert(None, "HAC_Spells", 0, "Back / Cancel / No Change")
EndFunction

 

 

 

-IA710

Link to comment
Share on other sites

(1) Keep in mind: If I rewrite the papyrus code I thought something about it. My version do the same, but is faster code.

        If (akSpell) && akSpell.GetNthEffectMagicEffect(0).GetCastingType()     ; get the first MagicEffect of the spell

your version

        If (akSpell) && akSpell.GetNthEffectMagicEffect(0).GetCastingType() > 0 ; get the first MagicEffect of the spell

(2) about event handling, try this:

 

 

;Import PO3_Events_Alias
;Import PO3_SKSEFunctions

;Import StorageUtil

    ; StorageUtil name: "HAC_Spells"         ; list of strings
    ; StorageUtil name: "HAC_SpForms"        ; list of forms


; -- EVENTs -- 4

EVENT OnInit()                      ; called first time mod will be seen on game (newgame or savegame)
    RegisterForSingleUpdate(1.0)
ENDEVENT

EVENT OnPlayerLoadGame()            ; called every time mod was loaded by savegame
    RegisterForSingleUpdate(1.0)
ENDEVENT

EVENT OnUpdate()
    Debug.Notification("HAC: Starting Spell Maintenance")
    RefreshAllSpells()
    Debug.Notification("HAC: Spell Maintenance Completed")

    PO3_Events_Alias.RegisterForSpellLearned(self)               ; register for special event
ENDEVENT


EVENT OnSpellLearned(Spell akSpell)  ; event added by Papyrus Script Extender

    AddTo_HAC_Spells(akSpell)                                    ; add the spell to storageutil stringlist
    StorageUtil.StringListSort(None, "HAC_Spells")               ; Sort the final output spell names stringlist.
    Strings_To_Forms()                                           ; Clear storageutil list of spell forms and add new forms

ENDEVENT

 


(3) Its surely faster to store only one formlist like "HAC_SpForms" and create a temporary Stringlist like "HAC_Spells" on th fly, if its recomended by MCM menu. But without to see code dependencies its a hint only.

Edited by ReDragon2013
Link to comment
Share on other sites

1) I do try to take that into consideration, but I also check for possible mistakes as everyone is human. I just assumed you had missed the > 0, and now after reviewing the code more closely I can see that the IF is already evaluating if it's over 0 (I should have trusted you and tried your code like it was, sorry for that)!

 

2) I will implement this. I have made some changes to the script already last night when testing, for some reason when adding a spell via the OnSpellLearned event I keep getting 2 entries for index 0 showing up, I put in a state to send it to "busy" while processing, didn't help, changed StorageUtil.StringListShift to StringListRemove with the "Back / Cancel / No Change" string specified and the option flagged true to remove ALL instances from the list, but that didn't seem to help. I get it when adding multiple spells quickly via script or adding just one, I even took all the code and put it into one function in the event and it's still doing it (just to make sure some function wasn't firing in parallel SOMEHOW), not sure what is going on with that. It worked properly before the changes, and I don't see that we have done anything different then what I was doing before (especially as I put it all explicitly in the event to test if somehow it was running multiple updates at once. The "busy" state should have resolved that if it was the case, even with the multiple functions, right?), so it is puzzling. The indexes between the stringlist and the formlist become 2 off of each other also, instead of one, so when I select the second "Back / Cancel / No Change" it actually loads what should be the first spell. And if I select the second spell it loads the 3rd and so on. I really can't see why this would be happening. I'm at work,

 

I'll post the code as it is later tonight when I can get on that machine.

 

3) Not sure how I would implement this suggestion - I really need two outputs the way my MCM is currently written, and their indexes have to be sorted together, Stringlist sorted index = Formlist sorted index, and then have them one index off due to the "Back" option added at the top of the stringlist.

 

I hope I am understanding your hint correctly. In the MCM I pop a Menu to select a spell, I want the list to be sorted as it is possible that someone has over 200 spells in inventory, and it's a mess to go through them if they aren't sorted.

 

I think I could maybe get away with just the StringList and the String to Formid map and then look up the formID with the string (instead of by index from the formlist based upon the two lists), but MCM returns the index of the menu option selected, so having a form array with the index one off is the way I originally have it coded. Having the strings AND formIDs stored in three places total does seem unnecessary as I talk through it here.

 

So maybe in the MCM when the menu returns the index of the string I just get the string from the stringlist index and then pass it as key to GetFormValue from the map to get the formID and cast "as spell" when I go to add it to the other array I use to store the auto cast spell and forget about the "HAC_SpForms" formlist all together?

 

ReDragon2013, thank you so much, as usual, I really respect every suggestion you make, and have learned a LOT from you (and others on this thread), but still have SO much to learn. Thank you!

 

-IA710

 

EDIT: In #2 I should have said " I keep getting 2 entries for "Back/ Cancel / No Change" showing up as indexes 0 and 1 instead of just the 1 at index zero we are inserting" instead of " I keep getting 2 entries for index 0 showing up".

Edited by ItsAlways710
Link to comment
Share on other sites

Back/Cancel/NVM can and often does equate to 0 as Int. GetAt(0) is valid as well as Whatever[0] is valid too. If what I suspect, is occurring, you need to adjust to account for 0 being a valid selection. Negative 1 is often used there aka -1. Just be aware -1 directly equals true as a bool. So be sure to do a check like If ABC > -1 to know there is something to do

Link to comment
Share on other sites

You are all awesome, I appreciate the education as usual.

 

Played with it for a while tonight and nothing was working. And then I remembered at one point I was doing the StringListInsert of the "Back" string BEFORE I built the formlist and just setting i = 1 instead of 0.

 

I had already switched to using StringListRemove instead of StringListShift, so I kept it, but moved it from the addto function to the String_to_Form function and then the addto and update functions were identical, so I removed one and updated the references.

 

I have no idea what fixed it, I'm assuming moving the StringListInsert and setting i to 1, but I moved the StringListRemove at the same time and am fine with it were it is I think - please let me know of anything anyone sees that is non-optimal:

 

 

 

;Import PO3_Events_Alias
;Import PO3_SKSEFunctions

;Import StorageUtil

	; StorageUtil name: "HAC_Spells"         ; list of strings
	; StorageUtil name: "HAC_SpForms"        ; list of forms


; -- Events -- 4

Event OnInit()                      ; called first time mod will be seen on game (newgame or savegame)
	RegisterForSingleUpdate(1.0)
ENDEvent

Event OnPlayerLoadGame()            ; called every time mod was loaded by savegame
	RegisterForSingleUpdate(1.0)
ENDEvent

Event OnUpdate()
	Debug.Notification("HAC: Starting Spell Maintenance")
	RefreshAllSpells()
	Debug.Notification("HAC: Spell Maintenance Completed")

	PO3_Events_Alias.RegisterForSpellLearned(self)               ; register for special event
ENDEvent

Event OnSpellLearned(Spell akSpell)  ; event added by Papyrus Script Extender

	Update_HAC_Spells(akSpell)                                    ; add the spell to storageutil stringlist
	StorageUtil.StringListSort(None, "HAC_Spells")               ; Sort the final output spell names stringlist.
	Strings_To_Forms()                                           ; Clear storageutil list of spell forms and add new forms

ENDEvent


Function RefreshAllSpells()

; Clear storageutil stringlist and add new spell strings
	CreateSpellList()
; Sort the final output player spell names stringlist.
	StorageUtil.StringListSort(None, "HAC_Spells")
; Clear storageutil list of spell forms and add new forms
	Strings_To_Forms()
EndFunction


Function Update_HAC_Spells(Spell akSpell)  ; helper function

	string s = akSpell.GetName()
; Make sure that the spell name string is mapped to the correct formid
	StorageUtil.SetFormValue(None, s, akSpell as Form)
; Add the spell name to the final output stringlist with allowdupes FALSE
	StorageUtil.StringListAdd(None, "HAC_Spells", s, False)
EndFunction


Function CreateSpellList()  ; helper function

	actor player = Game.GetPlayer()
	StorageUtil.StringlistClear(None, "HAC_Spells")                ; *** clear *** strings
; Build an array with all spells in the game
	spell[] a = PO3_SKSEFunctions.GetAllSpells()
	int i = a.Length        ; a = allSpellsInTheGame
	While (i)
		i = i - 1
		spell akSpell = a[i]
		If (akSpell) && akSpell.GetNthEffectMagicEffect(0).GetCastingType()  ; get the first MagicEffect of the spell
			; 1 = Fire and Forget
			; 2 = Concentration
			; check every playable spell from master list to see if the player has it
			If player.HasSpell(akSpell)
				Update_HAC_Spells(akSpell)
			EndIf
		EndIf
	EndWhile
EndFunction


Function Strings_To_Forms()  ; helper function

; Make Absolutely sure that Back isn't in the list
	StorageUtil.StringListRemove(None, "HAC_Spells", "Back / Cancel / No Change", True)
; insert at index 0 of sorted stringlist an escape menu as back out
	StorageUtil.StringListInsert(None, "HAC_Spells", 0, "Back / Cancel / No Change")
	int m = StorageUtil.StringListCount(None, "HAC_Spells")
	StorageUtil.FormListClear(None, "HAC_SpForms")       ; *** clear *** forms
; using the sorted string list to build the final output player spell formlist
	int i = 1
	While (i < m)
		form fm = StorageUtil.GetFormValue(None, StorageUtil.StringListGet(None, "HAC_Spells", i))
		If ( fm )
			StorageUtil.FormListAdd(None, "HAC_SpForms", fm)
		EndIf
		i = i + 1
	EndWhile
EndFunction

 

 

 

As usual, thank you all for your help and kindness, I'm learning a lot!

 

-IA710

Link to comment
Share on other sites

You typed int i = 1 so.... cool, do that, but be aware that skips zero. If you want to skip zero then no worries, but otherwise you have an issue there off the bat

 

Also by the way to increase integers you can use +=

 

So like ABC += 1 to up it a notch

Link to comment
Share on other sites

as Sphered wrote:

this code

 int i
 i = i + 1

do the same as next code

 int i
 i += 1

BUT, what is better to understand? Keep in mind there is no different in papyrus executable script. wiki link: https://www.creationkit.com/index.php?title=Statement_Reference

 

version 3 for code optimization

 

;Import PO3_Events_Alias
;Import PO3_SKSEFunctions

;Import StorageUtil

    ; StorageUtil name: "HAC_Spells"         ; list of strings
    ; StorageUtil name: "HAC_SpForms"        ; list of forms
;-------------------------------------------------------------

  Bool bRefresh        ; [default=False]


; -- EVENTs -- 4

EVENT OnInit()                      ; called first time mod will be seen on game (newgame or savegame)
    RegisterForSingleUpdate(1.0)
ENDEVENT


EVENT OnPlayerLoadGame()            ; called every time a mod was loaded by savegame (player alias script only!)
    RegisterForSingleUpdate(1.0)
ENDEVENT


EVENT OnUpdate()
IF ( bRefresh )
    RETURN    ; - STOP -    Do not allow multiple threads at same time!
ENDIF
;---------------------
    bRefresh = TRUE        ; *T*

    PO3_Events_Alias.UnRegisterForSpellLearned()
    Debug.Notification("HAC: Starting Spell Maintenance")

    CreateSpellList()                                            ; Clear storageutil stringlist and add new spell strings
    StorageUtil.StringListSort(None, "HAC_Spells")               ; Sort the final output player spell names stringlist.
    Strings_To_Forms()                                           ; Clear storageutil list of spell forms and add new forms

    Debug.Notification("HAC: Spell Maintenance Completed")
    PO3_Events_Alias.RegisterForSpellLearned(self)               ; register for special event

    bRefresh = False    ; ***
ENDEVENT


EVENT OnSpellLearned(Spell akSpell)  ; event added by Papyrus Script Extender
WHILE (bRefresh)
    Utility.Wait(0.1)    ; wait here until main refresh is finished
ENDWHILE

    Update_HAC_Spells(akSpell)                                   ; add the spell to storageutil stringlist

; remove existing escape menu from stringlist before sorting
    StorageUtil.StringListRemove(None, "HAC_Spells", "Back / Cancel / No Change", True)

    StorageUtil.StringListSort(None, "HAC_Spells")               ; Sort the stringlist of player spell names to output on screen.
    Strings_To_Forms()                                           ; Clear storageutil list of spell forms and add new forms
ENDEVENT


; -- FUNCTIONs -- 3

Function Update_HAC_Spells(Spell akSpell)  ; helper

    string s = akSpell.GetName()
    StorageUtil.SetFormValue(None, s, akSpell as Form)           ; Make sure that the spell name string is mapped to the correct formid
    StorageUtil.StringListAdd(None, "HAC_Spells", s, False)      ; Add a new spell name to stringlist with allowdupes == FALSE

EndFunction


Function CreateSpellList()  ; helper

    actor player = Game.GetPlayer()

    spell[] a = PO3_SKSEFunctions.GetAllSpells()                 ; Build a temp array with all spells in the game
    StorageUtil.StringlistClear(None, "HAC_Spells")              ; *** clear *** strings

    int i = a.Length
    WHILE (i)            ; (i != 0)
        i = i - 1

        spell akSpell = a[i]                                     ; get the first MagicEffect of valid spell and give back the casting type (0..2)
        IF (akSpell) && akSpell.GetNthEffectMagicEffect(0).GetCastingType()
            ; 1 = Fire and Forget, 2 = Concentration

            IF player.HasSpell(akSpell)                          ; check the playable spell from array to see, if the player has it
                Update_HAC_Spells(akSpell)
            ENDIF
        ENDIF

    ENDWHILE

EndFunction


Function Strings_To_Forms()  ; helper

    int m = StorageUtil.StringListCount(None, "HAC_Spells")      ; get length of stringlist
    StorageUtil.FormListClear(None, "HAC_SpForms")               ; *** clear *** forms

; use the sorted stringlist to build the store the same a formlist (without escape menu)
    int i = 0
    WHILE (i < m)
        form fm = StorageUtil.GetFormValue(None, StorageUtil.StringListGet(None, "HAC_Spells", i))
        IF ( fm )
            StorageUtil.FormListAdd(None, "HAC_SpForms", fm)
        ENDIF
        i = i + 1
    ENDWHILE

; insert at index 0 of stringlist the escape menu as way out
    StorageUtil.StringListInsert(None, "HAC_Spells", 0, "Back / Cancel / No Change")

EndFunction

 

 

version 4 for studying, it is creating the formlist first and the stringlist after

 

;Import PO3_Events_Alias
;Import PO3_SKSEFunctions
; https://www.nexusmods.com/skyrimspecialedition/mods/22854?tab=files&BH=0
; https://github.com/powerof3/PapyrusExtenderSSE/tree/master/src/Papyrus

;Import StorageUtil

    ; StorageUtil name: "HAC_Spells"         ; list of strings, will be sorted by script on every spell update
    ; StorageUtil name: "HAC_SpForms"        ; list of forms, keeps unsorted
;-------------------------------------------------------------------------------------------------------------

  Bool bRefresh        ; [default=False]


; -- EVENTs -- 4

EVENT OnInit()                      ; called first time mod will be seen on game (newgame or savegame)
;=========== 1
    RegisterForSingleUpdate(1.0)
ENDEVENT


EVENT OnPlayerLoadGame()            ; called every time a mod was loaded by savegame (player alias script only!)
;===================== 2
    RegisterForSingleUpdate(1.0)
ENDEVENT


EVENT OnUpdate()
;============= 3
IF ( bRefresh )
    RETURN    ; - STOP -    Do not allow multiple threads at same time!
ENDIF
;---------------------
    bRefresh = TRUE        ; *T*

    PO3_Events_Alias.UnRegisterForSpellLearned(self)              ; unregister for special event
    Debug.Notification("HAC: Starting Spell Maintenance")         ; ### debug info ###

    CreateFormList()                                              ; Clear storageutil formlist and add all player spells
    Forms_To_Strings()                                            ; Clear storageutil stringlist and build it new

;---
; Sort the final output player spell names stringlist.
    StorageUtil.StringListSort(None, "HAC_Spells")

; insert at index 0 of stringlist the escape menu as way out
    StorageUtil.StringListInsert(None, "HAC_Spells", 0, "Back / Cancel / No Change")
;---

    Debug.Notification("HAC: Spell Maintenance Completed")        ; ### debug info ###
    PO3_Events_Alias.RegisterForSpellLearned(self)                ; register for special event

    bRefresh = False    ; ***
ENDEVENT


EVENT OnSpellLearned(Spell akSpell)  ; event added by powerofthrees Papyrus Extender
;=================== 4
WHILE (bRefresh)
    Utility.Wait(0.1)    ; wait here until main refresh is finished, just in case
ENDWHILE

    StorageUtil.FormListAdd(None, "HAC_SpForms", akSpell as Form, False)

    StorageUtil.StringListRemoveAt(None, "HAC_Spells", 0)         ; remove the escape menu from stringlist before adding a new spell
    Update_HAC_Spells(akSpell)                                    ; add this spell to storageutil stringlist

;---
; Sort the final output player spell names stringlist.
    StorageUtil.StringListSort(None, "HAC_Spells")

; insert at index 0 of stringlist the escape menu as way out
    StorageUtil.StringListInsert(None, "HAC_Spells", 0, "Back / Cancel / No Change")
;---
ENDEVENT


; -- FUNCTIONs -- 3

;----------------------------------------
Function Update_HAC_Spells(Spell akSpell)  ; helper
;----------------------------------------
    string s = akSpell.GetName()
    StorageUtil.SetFormValue(None, s, akSpell as Form)            ; Make sure that the spell name string is mapped to the correct formid
    StorageUtil.StringListAdd(None, "HAC_Spells", s, False)       ; Add a new spell name to stringlist with allowdupes == FALSE
EndFunction


;------------------------
Function CreateFormList()
;------------------------
    actor player = Game.GetPlayer()

    spell[] a = PO3_SKSEFunctions.GetAllSpells()                  ; Build a temp array with all spells in the game
    StorageUtil.FormListClear(None, "HAC_SpForms")                ; *** clear *** forms
    
    int i = a.Length                                              ; <array>.Length returns always a value greater or equal to ZERO
    WHILE (i)            ; (i) is equal to (i != 0)
        i = i - 1
        spell akSpell = a[i]                                      ; get the first MagicEffect of valid spell and give back the casting type (0..2)
        IF (akSpell) && akSpell.GetNthEffectMagicEffect(0).GetCastingType()
            ; 1 = Fire and Forget, 2 = Concentration

            IF player.HasSpell(akSpell)                           ; check the playable spell from array to see, if the player has it
                StorageUtil.FormListAdd(None, "HAC_SpForms", akSpell as Form, False)        ; do not allow duplicates in list
            ENDIF
        ENDIF
    ENDWHILE
EndFunction


;--------------------------
Function Forms_To_Strings()
;--------------------------
    int m = StorageUtil.FormListCount(None, "HAC_SpForms")        ; get length of unsorted formlist
;;;    StorageUtil.FormListClear(None, "HAC_Spells")              ; *** clear *** spells  , removed this line, because of wrong function!
   StorageUtil.StringListClear(None, "HAC_Spells")                ; *** clear *** spells

; use the formlist of spells to build a new stringlist of spellnames
    int i = 0
    WHILE (i < m)
        spell akSpell = StorageUtil.GetFormValue(None, StorageUtil.FormListGet(None, "HAC_SpForms", i)) as Spell
        IF ( akSpell )
            Update_HAC_Spells(akSpell)
            i = i + 1
        ELSE
            StorageUtil.FormListRemoveAt(None, "HAC_SpForms", i)
            m = m - 1    
        ENDIF
    ENDWHILE
EndFunction

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...