ItsAlways710 Posted January 13, 2022 Share Posted January 13, 2022 Hi all, I have a mod I made for myself and I fill the AddMenuOptionST() function menu options by equipping spells or weapons and entering the MCM and use GetEquippedSpell() or GetEquippedWeapon() - that's the only method I found when I was making that mod. I am making a new mod now and would love a way to populate a menu option list with all of the spells and lesser powers that a player currently has for use in the MCM AddMenuOptionST() function, but am unaware of another method that would allow for this. Is there something (papyrus extender maybe?) that allows for this without having to go in and out of the MCM? Filling a list of 30 spells can take over 20 times going in and out of the MCM (if some are master spells) and is SO tedious, I would love to save players the anguish - any help would be appreciated! -IA710 EDIT: Clarified methods used in current mod Link to comment Share on other sites More sharing options...
IsharaMeradin Posted January 14, 2022 Share Posted January 14, 2022 GetSpellCount and GetNthSpell should do the trick. Basically, get the total number of spells added to the player. Then grab the spell in each entry from 0 to one less than the count. Link to comment Share on other sites More sharing options...
ItsAlways710 Posted January 14, 2022 Author Share Posted January 14, 2022 Hi IsharaMeradin! I believe I remember playing with those when I built the other mod but it missed some spells for some reason - I'll put a function together and try it tonight. Ahhh, looking at the links you provide and it says it leaves out Race spells... I'll play with it and let you know... Thank you so much! -IA710 Link to comment Share on other sites More sharing options...
ItsAlways710 Posted January 14, 2022 Author Share Posted January 14, 2022 Hi! So I started playing with it and realized quickly why I used the method I used in the other mod - here is the function I'm playing with, my issue is how do i dynamically create a SPELL array? SKSE doesn't seem to have a function for it in Utility.pex, and evidently according to my compile errors and the creation kit wiki I can't cast an array AT ALL, anyways, this is what I have... am thinking maybe something other than SKSE allows for dynamically creating large Spell arrays? function UpdateRecentSpellsMenu() Int iIndex = playerREF.GetSpellCount() hRecentSpells = Utility.CreateFormArray(iIndex) as Spell hMenu_RecentSpells = Utility.CreateStringArray(iIndex + 1) hMenu_RecentSpells[0] = "Back / Cancel / No Change" while iIndex > 0 iIndex -= 1 hRecentSpells[iIndex] = playerREF.GetNthSpell(iIndex) hMenu_RecentSpells[iIndex + 1] = hRecentSpells[iIndex].GetName() endWhile endFunction Thank you!!! -IA710 Link to comment Share on other sites More sharing options...
IsharaMeradin Posted January 14, 2022 Share Posted January 14, 2022 In that particular instance, might want to consider using a formlist instead of an array. Yes, you'll need a property to point to it. But then you can have as many entries as you want. Link to comment Share on other sites More sharing options...
ItsAlways710 Posted January 16, 2022 Author Share Posted January 16, 2022 Hi! Using a Formlist was a good idea, as usual, thank you Ishara. Was poking around in Papyrus Extender and found a function to return all spells in the game from every mod, It has the same issue as GetNthSpell in that it returns spells associated with perks and such. I wish that there was a return cast type function for spells, this would make PO3's solution work for me. There is a mod called Spellcraft Functions SKSE64 that has a function GetSpellCastType() that should work, but it has an SKSE plugin and I don't think that the author is going to update it, although it's open source and the source is on github, I just don't know C. The Papyrus Extender function is PO3_SKSEFunctions.GetAllSpells(abIsPlayable = true) - the abisPlayable filters it to only spells that can be learned from a spell tome. I'm testing using it like this, but it's VERY slow as it's going through every spell in the game + mods. function UpdateRecentSpellsMenu() IA710_PlayerSpells.Revert() Spell[] allSpellsInTheGame = PO3_SKSEFunctions.GetAllSpells(abIsPlayable = true) Int iIndex = allSpellsInTheGame.length while iIndex > 0 iIndex -=1 if playerREF.HasSpell(allSpellsInTheGame[iIndex]) IA710_PlayerSpells.AddForm(allSpellsInTheGame[iIndex] as Form) endIf endWhile iIndex = IA710_PlayerSpells.GetSize() PlayerSpells = IA710_PlayerSpells.ToArray() hMenu_RecentSpells = Utility.CreateStringArray(iIndex + 1) hMenu_RecentSpells[0] = "Back / Cancel / No Change" while iIndex > 0 iIndex -= 1 hMenu_RecentSpells[iIndex + 1] = PlayerSpells[iIndex].GetName() endWhile endFunction Which ALMOST works right, but it leaves out spells that are added via a quest or some other method. The way I do it with Spellcraft Functions SKSE64 is: function UpdateRecentSpellsMenu() IA710_PlayerSpells.Revert() Spell[] allPlayerSpells = Spellcraft.GetAllActorSpells(playerREF) Int iIndex = allPlayerSpells.length while iIndex > 0 iIndex -=1 if Spellcraft.GetSpellCastType(allPlayerSpells[iIndex]) > 0 ;matches only if FAF or Concentration spell IA710_PlayerSpells.AddForm(allPlayerSpells[iIndex] as Form) endIf endWhile iIndex = IA710_PlayerSpells.GetSize() PlayerSpells = IA710_PlayerSpells.ToArray() hMenu_RecentSpells = Utility.CreateStringArray(iIndex + 1) hMenu_RecentSpells[0] = "Back / Cancel / No Change" while iIndex > 0 iIndex -= 1 hMenu_RecentSpells[iIndex + 1] = PlayerSpells[iIndex].GetName() endWhile endFunction This works perfectly and is SO much faster. Unfortunately I have no idea if Spellcraft Functions SKSE64 is still being updated :( Really at this point I just need a way to check the cast type of a spell (constant, concentration or Fire and Forget) because then I could ditch the constant spells and keep the rest and just use Papyrus Extender. Any ideas? I'm running out of options and haven't learned papyrus well enough to start trying to learn C on top of it LOL. Thank you Ishara! -IA710 Link to comment Share on other sites More sharing options...
IsharaMeradin Posted January 16, 2022 Share Posted January 16, 2022 You could shift the work out of the game. It would be possible to write a script for SSEEdit which would scan all active plugins for spells and assign the ones you want to a designated formlist. Just don't ask me to write such a thing. I do have a similar script (it assigns various items and workstations to formlists) for one of my mods but it was written with a lot of help. Upside is that it will make your mod faster in-game. Downside is that the user would need to run it on their own load order. I do not know C (or any variant) thus cannot help you with regards to the SKSE DLL. Link to comment Share on other sites More sharing options...
ItsAlways710 Posted January 16, 2022 Author Share Posted January 16, 2022 I have thought of that, and I'm not bad with SSEEdit, I've edited scripts successfully before. You are talking about your Inventory Management mod I'm guessing? I remember you've had me look at it before and I saw that you had a patcher with it, yours is doing a bit more than I would want but that is an option. Limits the audience a bit though. Ugh. I'm reaching out to Yeebb to see if they are interested in either updating Spellcraft Functions SKSE64 or if maybe they are willing, or know someone who is, who could hold my hand and I'll take it over, there are too many functions in that mod that put the fun back in functions to loose it - it's based on Grimy tools/plugin from oldrim. I may just have to go back to the "equip spells enter MCM" method, but after seeing how Spellcraft works I WANT it LOL. Thank you again Ishara. Maybe I won't publish this one. I have a lot of work to do on it regardless, maybe I'll make it with Spellcraft and force myself to learn C LOL. There are some Synthesis patchers I would love to write, so maybe I need to move in that direction. Hmm. The other mpd that I have been working on is below that uses the equip method, it's an auto cast mod based heavily on Smart Cast - I'd be interested in your thoughts on it if you have time to look it over (it's a bit large, at one point I had to start compiling in Notepad++, sorry): Scriptname IA710_HandyAutoCastMCMScript extends SKI_ConfigBase {Handy Auto Cast. SkyUI configuration mod pages} actor property playerREF auto Bool bCast_Check_WeaponDrawn Bool bIsHandyCastRegistered Bool bHandyDispel_ReadyToDisplayMessage Bool bHandySpellDelete Bool bParanoiaPanicStop Float fCast_Check_Health Float fCast_Check_Magicka Float fCast_Check_Stamina Float fCast_Check_TimeStamp Float fCast_Check_TimeStampExtra Float fCooldownTime Float fHandyCast_MagickaCost Float fHandyCast_ExtraMagicka Int iCast_Check_CombatState Int iCast_Check_SneakingState Int iCast_Check_Page Int iCast_Check_EndCompare Int iCast_Check_ExtraTick Int iCast_Check_iIndex Int iCast_Check_ItemTypeR Int iCast_Check_ItemTypeL Int iCurrentHandySpell Int iCurrentVersion = 0 Int iHandySpellMove Int iHCKeyMap Int iUpdateSpellDuration_iNumEffects Int iUpdateSpellDuration_iMaxDuration Int iSelectedHandySpell Int[] iAQuickCompare Int[] iAutoCastRules Int[] iAutoDispelRules Int[] iDQuickCompare Int[] iN_AQuickCompare Int[] iN_DQuickCompare Int[] iWhenToDoStuff Spell emptySpell Spell hCast_Check_SpellL Spell hCast_Check_SpellR Spell hHandyCast_Spell Spell hUpdateSpellDuration_Spell Spell[] hRecentSpells String[] hHandySpellOptions String[] hLoopOptions String[] hMenu_CombatStates String[] hMenu_Comparison String[] hMenu_RecentSpells String[] hMenu_RecentWeapons String[] hMenu_SneakStates String[] hMenu_WeaponDrawn Weapon emptyWeapon Weapon hCast_Check_WeaponL Weapon hCast_Check_WeaponR Weapon[] hRecentWeapons Bool hc_Notifications Bool hc_PanicButton Bool[] hc_Cooldown Bool[] hc_DispelOnCombat Bool[] hc_DispelWeaponSheath Bool[] hc_HandySpellEnable Bool[] hc_Maintain Float[] hc_HealthPercentage Float[] hc_LastMagickaCost Float[] hc_MagickaPercentage Float[] hc_StaminaPercentage Int[] hc_AutoCastDelay Int[] hc_CombatState Int[] hc_DispelCombatState Int[] hc_DispelDelay Int[] hc_DispelSneakingState Int[] hc_HandySpellDuration Int[] hc_HealthComparison Int[] hc_MagickaComparison Int[] hc_ReadyToCast Int[] hc_ReadyToDispel Int[] hc_SneakingState Int[] hc_StaminaComparison Int[] hc_WeaponDrawn spell[] hc_HandySpell spell[] hc_WeaponDraw_Spell Weapon[] hc_WeaponDraw_Weapon event OnUpdate() Cast_Check() endEvent event OnKeyDown(Int keycode) if (keyCode == 1) RETURN endIf gotoState("Busy") myF_Process(keycode) gotoState("") endEvent event OnVersionUpdate(Int a_version) if (a_version > iCurrentVersion) Debug.Trace(" OnVersionUpdate() - is updating the script to version " +a_version+ " -- " +self) OnConfigInit() endIf endEvent event OnConfigInit() ModName = "Handy Auto Cast" Pages = new String[12] iCurrentHandySpell = 0 Int iIndex = 11 while iIndex iIndex -= 1 Pages[iIndex] = "Spell " + iIndex as String endWhile hRecentSpells = new spell[30] hRecentWeapons = new Weapon[30] hMenu_RecentSpells = new String[31] hMenu_RecentWeapons = new String[31] iIndex = 31 while iIndex > 1 iIndex -= 1 hMenu_RecentSpells[iIndex] = "Empty " + iIndex as String hMenu_RecentWeapons[iIndex] = "Empty " + iIndex as String endWhile hMenu_RecentSpells[0] = "Back / Cancel / No Change" hMenu_RecentWeapons[0] = "Back / Cancel / No Change" hMenu_CombatStates = new String[3] hMenu_CombatStates[0] = "Ignore" hMenu_CombatStates[1] = "In Combat" hMenu_CombatStates[2] = "Out of Combat" hMenu_SneakStates = new String[3] hMenu_SneakStates[0] = "Ignore" hMenu_SneakStates[1] = "Sneaking" hMenu_SneakStates[2] = "NOT Sneaking" hMenu_WeaponDrawn = new String[17] hMenu_WeaponDrawn[0] = "Ignore" hMenu_WeaponDrawn[1] = "Any Weapon/Spell" hMenu_WeaponDrawn[2] = "Specific Spell" hMenu_WeaponDrawn[3] = "Specific Weapon" hMenu_WeaponDrawn[4] = "Bare hands" hMenu_WeaponDrawn[5] = "Any 1H sword" hMenu_WeaponDrawn[6] = "Any 1H dagger" hMenu_WeaponDrawn[7] = "Any 1H axe" hMenu_WeaponDrawn[8] = "Any 1H mace" hMenu_WeaponDrawn[9] = "Any 2H sword" hMenu_WeaponDrawn[10] = "Any 2H axe/mace" hMenu_WeaponDrawn[11] = "Any Bow" hMenu_WeaponDrawn[12] = "Any Staff" hMenu_WeaponDrawn[13] = "Any Magic spell" hMenu_WeaponDrawn[14] = "Any Shield" hMenu_WeaponDrawn[15] = "A Torch" hMenu_WeaponDrawn[16] = "Any Crossbow" hMenu_Comparison = new String[3] hMenu_Comparison[0] = "Ignore" hMenu_Comparison[1] = "Less Than" hMenu_Comparison[2] = "Greater Than" hc_HandySpell = new spell[11] hc_HandySpellDuration = new Int[11] hc_HandySpellEnable = new Bool[11] hc_CombatState = new Int[11] hc_SneakingState = new Int[11] hc_WeaponDrawn = new Int[11] hc_WeaponDraw_Weapon = new Weapon[11] hc_WeaponDraw_Spell = new spell[11] hc_HealthComparison = new Int[11] hc_HealthPercentage = new Float[11] hc_MagickaComparison = new Int[11] hc_MagickaPercentage = new Float[11] hc_StaminaComparison = new Int[11] hc_StaminaPercentage = new Float[11] hc_AutoCastDelay = new Int[11] hc_Maintain = new Bool[11] hc_DispelCombatState = new Int[11] hc_DispelSneakingState = new Int[11] hc_DispelWeaponSheath = new Bool[11] hc_DispelDelay = new Int[11] hc_DispelOnCombat = new Bool[11] hc_Cooldown = new Bool[11] hc_LastMagickaCost = new Float[11] hc_ReadyToCast = new Int[11] hc_ReadyToDispel = new Int[11] iIndex = 11 while iIndex iIndex -= 1 ResetHandySpell(iIndex) endWhile iAQuickCompare = new Int[66] iN_AQuickCompare = new Int[6] iDQuickCompare = new Int[44] iN_DQuickCompare = new Int[4] iAutoCastRules = new Int[11] iAutoDispelRules = new Int[11] iWhenToDoStuff = new Int[11] iIndex = 66 while iIndex iIndex -= 1 iAQuickCompare[iIndex] = 0 endWhile iIndex = 6 while iIndex iIndex -= 1 iN_AQuickCompare[iIndex] = 0 endWhile iIndex = 44 while iIndex iIndex -= 1 iDQuickCompare[iIndex] = 0 endWhile iIndex = 4 while iIndex iIndex -= 1 iN_DQuickCompare[iIndex] = 0 endWhile iIndex = 11 while iIndex iIndex -= 1 iAutoCastRules[iIndex] = 0 iAutoDispelRules[iIndex] = 0 endWhile bIsHandyCastRegistered = false bParanoiaPanicStop = false fCooldownTime = 0 as Float Pages[11] = "Manage Spells" hHandySpellOptions = new String[2] hHandySpellOptions[0] = "Not Selected" hHandySpellOptions[1] = "Select a Spell" hLoopOptions = new String[2] hLoopOptions[0] = "Click Here" hLoopOptions[1] = "Done" bHandySpellDelete = false iHandySpellMove = 0 hc_PanicButton = false hc_Notifications = true iHCKeyMap = -1 UnregisterForAllKeys() iCurrentVersion = GetVersion() debug.Notification("Handy Auto Cast initialized") endEvent event OnConfigOpen() {Called when the config menu is opened} UpdateRecentSpellsMenu() UpdateRecentWeaponsMenu() if IsRecentSpellsMenuEmpty() ShowMessage("The Recent Spells Menu is empty, equip spells to your character before entering this menu to fill it up", false, "$Accept", "$Cancel") endIf endEvent event OnConfigClose() {Called when the user exit the menus} UpdatePageNames() HandyCastRegistration() endEvent event OnPageReset(String a_page) {Called when a new page is selected, including the initial empty page} if a_page == "" return elseIf a_page != "" && a_page != "Manage Spells" Int iFlagMain SetCursorFillMode(TOP_TO_BOTTOM) Int iIndex = 11 while iIndex iIndex -= 1 if a_page == Pages[iIndex] iCurrentHandySpell = iIndex iIndex = 0 endIf endWhile String pageName = GetHandySpellName(iCurrentHandySpell) SetTitleText(pageName) if IsRecentSpellsMenuEmpty() || !IsHandySpellValid(iCurrentHandySpell) || !hc_HandySpellEnable[iCurrentHandySpell] iFlagMain = OPTION_FLAG_DISABLED else iFlagMain = OPTION_FLAG_NONE endIf if IsRecentSpellsMenuEmpty() || !hc_HandySpellEnable[iCurrentHandySpell] AddMenuOptionST("iMenuID_HandySpell", "Spell:", pageName, OPTION_FLAG_DISABLED) else AddMenuOptionST("iMenuID_HandySpell", "Spell:", pageName, OPTION_FLAG_NONE) endIf AddHeaderOption("AUTO CAST RULES", 0) AddTextOptionST("iMenuID_CombatState", "Combat State:", GetCombatStateString(iCurrentHandySpell), iFlagMain) AddTextOptionST("iMenuID_SneakingState", "Sneaking State:", GetSneakingStateString(iCurrentHandySpell), iFlagMain) AddMenuOptionST("iMenuID_WeaponDrawn", "Weapon Drawn:", GetWeaponDrawnStateString(iCurrentHandySpell), iFlagMain) if IsSpecificWeaponDrawn(iCurrentHandySpell) AddMenuOptionST("iMenuID_WeaponDrawn_Weapon", " Weapon:", GetWeaponDrawnString(iCurrentHandySpell), iFlagMain) else AddMenuOptionST("iMenuID_WeaponDrawn_Weapon", " Weapon:", GetWeaponDrawnString(iCurrentHandySpell), OPTION_FLAG_DISABLED) endIf AddSliderOptionST("iMenuID_AutoCastDelay", "Delay:", hc_AutoCastDelay[iCurrentHandySpell] as Float, "{0} Seconds", iFlagMain) AddEmptyOption() AddHeaderOption("AUTO DISPEL RULES", 0) if CanHandySpellBeAutoDispel(iCurrentHandySpell) AddToggleOptionST("iMenuID_Maintain", "Maintain Auto Cast Rules:", hc_Maintain[iCurrentHandySpell], iFlagMain) AddSliderOptionST("iMenuID_DispelDelay", "Delay:", hc_DispelDelay[iCurrentHandySpell] as Float, "{0} Seconds", iFlagMain) else AddToggleOptionST("iMenuID_Maintain", "Maintain Auto Cast Rules:", hc_Maintain[iCurrentHandySpell], OPTION_FLAG_DISABLED) AddSliderOptionST("iMenuID_DispelDelay", "Delay:", hc_DispelDelay[iCurrentHandySpell] as Float, "{0} Seconds", OPTION_FLAG_DISABLED) endIf SetCursorPosition(1) if IsRecentSpellsMenuEmpty() AddToggleOptionST("iMenuID_SpellEnable", "Enable:", hc_HandySpellEnable[iCurrentHandySpell], OPTION_FLAG_DISABLED) else AddToggleOptionST("iMenuID_SpellEnable", "Enable:", hc_HandySpellEnable[iCurrentHandySpell], OPTION_FLAG_NONE) endIf AddHeaderOption("", 0) AddTextOptionST("iMenuID_HealthComparison", "Health:", GetHealthComparisonString(iCurrentHandySpell), iFlagMain) if IsHealthComparisonActive(iCurrentHandySpell) AddSliderOptionST("iMenuID_HealthPercentage", "", hc_HealthPercentage[iCurrentHandySpell], "%{0}", iFlagMain) else AddSliderOptionST("iMenuID_HealthPercentage", "", hc_HealthPercentage[iCurrentHandySpell], "%{0}", OPTION_FLAG_DISABLED) endIf AddTextOptionST("iMenuID_MagickaComparison", "Magicka:", GetMagickaComparisonString(iCurrentHandySpell), iFlagMain) if IsMagickaComparisonActive(iCurrentHandySpell) AddSliderOptionST("iMenuID_MagickaPercentage", "", hc_MagickaPercentage[iCurrentHandySpell], "%{0}", iFlagMain) else AddSliderOptionST("iMenuID_MagickaPercentage", "", hc_MagickaPercentage[iCurrentHandySpell], "%{0}", OPTION_FLAG_DISABLED) endIf AddTextOptionST("iMenuID_StaminaComparison", "Stamina:", GetStaminaComparisonString(iCurrentHandySpell), iFlagMain) if IsStaminaComparisonActive(iCurrentHandySpell) AddSliderOptionST("iMenuID_StaminaPercentage", "", hc_StaminaPercentage[iCurrentHandySpell], "%{0}", iFlagMain) else AddSliderOptionST("iMenuID_StaminaPercentage", "", hc_StaminaPercentage[iCurrentHandySpell], "%{0}", OPTION_FLAG_DISABLED) endIf AddHeaderOption("", 0) if CanHandySpellBeAutoDispel(iCurrentHandySpell) && !hc_Maintain[iCurrentHandySpell] AddTextOptionST("iMenuID_DispelCombatState", "Combat State:", GetDispelCombatStateString(iCurrentHandySpell), iFlagMain) AddTextOptionST("iMenuID_DispelSneakingState", "Sneaking State:", GetDispelSneakingStateString(iCurrentHandySpell), iFlagMain) AddToggleOptionST("iMenuID_DispelWeaponSheath", "Weapon Sheath:", hc_DispelWeaponSheath[iCurrentHandySpell], iFlagMain) else AddTextOptionST("iMenuID_DispelCombatState", "Combat State:", GetDispelCombatStateString(iCurrentHandySpell), OPTION_FLAG_DISABLED) AddTextOptionST("iMenuID_DispelSneakingState", "Sneaking State:", GetDispelSneakingStateString(iCurrentHandySpell), OPTION_FLAG_DISABLED) AddToggleOptionST("iMenuID_DispelWeaponSheath", "Weapon Sheath:", hc_DispelWeaponSheath[iCurrentHandySpell], OPTION_FLAG_DISABLED) endIf elseIf a_page == "Manage Spells" SetCursorFillMode(TOP_TO_BOTTOM) SetTitleText("Manage Spells") bHandySpellDelete = false iHandySpellMove = 0 AddHeaderOption("Manager Options", 0) AddTextOptionST("iMenuID_Manager_Move", "Move Handy Spell:", hHandySpellOptions[0], 0) AddTextOptionST("iMenuID_Manager_Delete", "Delete Handy Spell:", hHandySpellOptions[0], 0) AddEmptyOption() AddToggleOptionST("iMenuID_Show_Notifications", "Show Handy Cast Notfications:", hc_Notifications, 0) AddEmptyOption() hc_PanicButton = ParanoiaPanicStopStatus() AddToggleOptionST("iMenuID_Manager_PanicButton", "Stop Handy Spell Loop:", hc_PanicButton, 0) AddTextOptionST("iMenuID_Manager_Reset", "Reset Handy Spell Loop: ", hLoopOptions[0], 0) AddKeyMapOptionST("HSKeyState", "Stop Handy Spell Loop Hotkey", iHCKeyMap) SetCursorPosition(1) AddHeaderOption("Handy Spells", 0) int iIndex = 0 while iIndex < 11 AddTextOptionST("iMenuID_Manager_HandySpell" + iIndex, "", GetHandySpellName(iIndex), OPTION_FLAG_DISABLED) iIndex += 1 endWhile endIf endEvent Bool function IsStaminaComparisonActive(Int iHandySpell) return hc_StaminaComparison[iHandySpell] != 0 endFunction Bool function ChangeHandySpellEnable(Int iHandySpell) hc_HandySpellEnable[iHandySpell] = !hc_HandySpellEnable[iHandySpell] if hc_HandySpellEnable[iHandySpell] AddPageToQuickCompare(iHandySpell) return true else RemovePageFromQuickCompare(iHandySpell) return false endIf endFunction Bool function ChangeMaintainAutoCastRules(Int iHandySpell) hc_Maintain[iHandySpell] = !hc_Maintain[iHandySpell] if hc_Maintain[iHandySpell] if hc_DispelCombatState[iHandySpell] hc_DispelCombatState[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, false, 0) SetTextOptionValueST(GetDispelCombatStateString(iHandySpell), false, "iMenuID_DispelCombatState") endIf if hc_DispelSneakingState[iHandySpell] hc_DispelSneakingState[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, false, 1) SetTextOptionValueST(GetDispelSneakingStateString(iHandySpell), false, "iMenuID_DispelSneakingState") endIf if hc_DispelWeaponSheath[iHandySpell] hc_DispelWeaponSheath[iHandySpell] = false RemoveQuickCompare(iHandySpell, false, 2) SetToggleOptionValueST(hc_DispelWeaponSheath[iHandySpell], false, "iMenuID_DispelWeaponSheath") endIf AddQuickCompare(iHandySpell, false, 3) return true else RemoveQuickCompare(iHandySpell, false, 3) return false endIf endFunction Bool function ChangeDispelWeaponSheathState(Int iHandySpell) hc_DispelWeaponSheath[iHandySpell] = !hc_DispelWeaponSheath[iHandySpell] if hc_DispelWeaponSheath[iHandySpell] AddQuickCompare(iHandySpell, false, 2) return true else RemoveQuickCompare(iHandySpell, false, 2) return false endIf endFunction function HandyCastRegistration() if bParanoiaPanicStop if bIsHandyCastRegistered bIsHandyCastRegistered = false UnregisterForUpdate() endIf else Int iIndex = 11 while iIndex iIndex -= 1 if iAutoCastRules[iIndex] if !bIsHandyCastRegistered bIsHandyCastRegistered = true RegisterForSingleUpdate(5 as Float) endIf return endIf endWhile bIsHandyCastRegistered = false UnregisterForUpdate() endIf endFunction String function GetWeaponDrawnStateString(Int iHandySpell) return hMenu_WeaponDrawn[hc_WeaponDrawn[iHandySpell]] endFunction function RemoveQuickCompare(Int iHandySpell, Bool p_AC, Int iComp) Int iQN_Page if p_AC iQN_Page = iN_AQuickCompare[iComp] else iQN_Page = iN_DQuickCompare[iComp] endIf Int iQ_PageBegin = iComp * 11 if iQN_Page Int iPosition = iQN_Page Int iIndex = iQN_Page while iIndex iIndex -= 1 if p_AC if iAQuickCompare[iQ_PageBegin + iIndex] == iHandySpell iPosition = iIndex iIndex = 0 endIf elseIf iDQuickCompare[iQ_PageBegin + iIndex] == iHandySpell iPosition = iIndex iIndex = 0 endIf endWhile if iPosition != iQN_Page if p_AC iN_AQuickCompare[iComp] = iN_AQuickCompare[iComp] - 1 iAutoCastRules[iHandySpell] = iAutoCastRules[iHandySpell] - 1 while iPosition < iN_AQuickCompare[iComp] iAQuickCompare[iQ_PageBegin + iPosition] = iAQuickCompare[iQ_PageBegin + iPosition + 1] iPosition += 1 endWhile else iN_DQuickCompare[iComp] = iN_DQuickCompare[iComp] - 1 iAutoDispelRules[iHandySpell] = iAutoDispelRules[iHandySpell] - 1 while iPosition < iN_DQuickCompare[iComp] iDQuickCompare[iQ_PageBegin + iPosition] = iDQuickCompare[iQ_PageBegin + iPosition + 1] iPosition += 1 endWhile endIf endIf endIf endFunction String function GetDispelSneakingStateString(Int iHandySpell) return hMenu_SneakStates[hc_DispelSneakingState[iHandySpell]] endFunction Int function GetVersion() return 1 endFunction String function DefaultDispelSneakingState(Int iHandySpell) hc_DispelSneakingState[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, false, 1) return GetDispelSneakingStateString(iHandySpell) endFunction String function DefaultWeaponDrawnState(Int iHandySpell) hc_WeaponDrawn[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, true, 2) return GetWeaponDrawnStateString(iHandySpell) endFunction String function ChangeCombatState(Int iHandySpell) hc_CombatState[iHandySpell] = hc_CombatState[iHandySpell] + 1 if hc_CombatState[iHandySpell] == hc_DispelCombatState[iHandySpell] hc_CombatState[iHandySpell] = hc_CombatState[iHandySpell] + 1 endIf if hc_CombatState[iHandySpell] > 2 hc_CombatState[iHandySpell] = 0 endIf if hc_CombatState[iHandySpell] AddQuickCompare(iHandySpell, true, 0) else RemoveQuickCompare(iHandySpell, true, 0) endIf return GetCombatStateString(iHandySpell) endFunction function UpdateRecentSpellsMenu() Int iIndex Bool bFlagSpell Int kIndex = 4 while kIndex Spell tmpSpell = emptySpell while kIndex as Bool && tmpSpell == emptySpell kIndex -= 1 tmpSpell = playerREF.GetEquippedSpell(kIndex) endWhile if tmpSpell != emptySpell iIndex = IsAlreadyInTheRecentSpells(tmpSpell) if iIndex < 0 MoveRecentSpellsUp(30 - 1) else MoveRecentSpellsUp(iIndex) endIf hRecentSpells[0] = tmpSpell endIf endWhile iIndex = 0 while iIndex < 30 if hRecentSpells[iIndex] != emptySpell hMenu_RecentSpells[iIndex + 1] = hRecentSpells[iIndex].GetName() iIndex += 1 else iIndex = 30 endIf endWhile endFunction String function DefaultSneakingState(Int iHandySpell) hc_SneakingState[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, true, 1) return GetSneakingStateString(iHandySpell) endFunction function RemoveDispelFeatures(Int iSpell) ResetDispelStructures(iSpell) RemoveQuickCompare(iSpell, false, 0) RemoveQuickCompare(iSpell, false, 1) RemoveQuickCompare(iSpell, false, 2) RemoveQuickCompare(iSpell, false, 3) endFunction Bool function CanHandySpellBeAutoDispel(Int iHandySpell) return iAutoCastRules[iHandySpell] as Bool && hc_HandySpellDuration[iHandySpell] > 25 endFunction String function DefaultMagickaComparison(Int iHandySpell) hc_MagickaComparison[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, true, 4) return GetMagickaComparisonString(iHandySpell) endFunction String function ChangeDispelCombatState(Int iHandySpell) hc_DispelCombatState[iHandySpell] = hc_DispelCombatState[iHandySpell] + 1 if hc_DispelCombatState[iHandySpell] == hc_CombatState[iHandySpell] hc_DispelCombatState[iHandySpell] = hc_DispelCombatState[iHandySpell] + 1 endIf if hc_DispelCombatState[iHandySpell] > 2 hc_DispelCombatState[iHandySpell] = 0 endIf if hc_DispelCombatState[iHandySpell] AddQuickCompare(iHandySpell, false, 0) else RemoveQuickCompare(iHandySpell, false, 0) endIf return GetDispelCombatStateString(iHandySpell) endFunction Bool function DefaultDispelWeaponSheathState(Int iHandySpell) hc_DispelWeaponSheath[iHandySpell] = false RemoveQuickCompare(iHandySpell, false, 2) return false endFunction Bool function IsSpecificWeaponDrawn(Int iHandySpell) return hc_WeaponDrawn[iHandySpell] == 2 || hc_WeaponDrawn[iHandySpell] == 3 && !IsRecentWeaponsMenuEmpty() endFunction Bool function DefaultHandySpellEnable(Int iHandySpell) hc_HandySpellEnable[iHandySpell] = true AddPageToQuickCompare(iHandySpell) return true endFunction function AddQuickCompare(Int iHandySpell, Bool p_AC, Int iComp) Int iQN_Page if p_AC iQN_Page = iN_AQuickCompare[iComp] else iQN_Page = iN_DQuickCompare[iComp] endIf Int iQ_PageBegin = iComp * 11 if iQN_Page Int iPosition = 0 Int iIndex = iQN_Page while iIndex iIndex -= 1 if p_AC if iAQuickCompare[iQ_PageBegin + iIndex] < iHandySpell iPosition = iIndex + 1 iIndex = 0 elseIf iAQuickCompare[iQ_PageBegin + iIndex] == iHandySpell return endIf elseIf iDQuickCompare[iQ_PageBegin + iIndex] < iHandySpell iPosition = iIndex + 1 iIndex = 0 elseIf iDQuickCompare[iQ_PageBegin + iIndex] == iHandySpell return endIf endWhile if p_AC if iPosition == iQN_Page iAQuickCompare[iQ_PageBegin + iPosition] = iHandySpell iN_AQuickCompare[iComp] = iN_AQuickCompare[iComp] + 1 iAutoCastRules[iHandySpell] = iAutoCastRules[iHandySpell] + 1 else iN_AQuickCompare[iComp] = iN_AQuickCompare[iComp] + 1 iAutoCastRules[iHandySpell] = iAutoCastRules[iHandySpell] + 1 iIndex = iN_AQuickCompare[iComp] while iIndex > iPosition + 1 iIndex -= 1 iAQuickCompare[iQ_PageBegin + iIndex] = iAQuickCompare[iQ_PageBegin + iIndex - 1] endWhile iAQuickCompare[iQ_PageBegin + iPosition] = iHandySpell endIf elseIf iPosition == iQN_Page iDQuickCompare[iQ_PageBegin + iPosition] = iHandySpell iN_DQuickCompare[iComp] = iN_DQuickCompare[iComp] + 1 iAutoDispelRules[iHandySpell] = iAutoDispelRules[iHandySpell] + 1 else iN_DQuickCompare[iComp] = iN_DQuickCompare[iComp] + 1 iAutoDispelRules[iHandySpell] = iAutoDispelRules[iHandySpell] + 1 iIndex = iN_DQuickCompare[iComp] while iIndex > iPosition + 1 iIndex -= 1 iDQuickCompare[iQ_PageBegin + iIndex] = iDQuickCompare[iQ_PageBegin + iIndex - 1] endWhile iDQuickCompare[iQ_PageBegin + iPosition] = iHandySpell endIf elseIf p_AC iAQuickCompare[iQ_PageBegin] = iHandySpell iN_AQuickCompare[iComp] = iN_AQuickCompare[iComp] + 1 iAutoCastRules[iHandySpell] = iAutoCastRules[iHandySpell] + 1 else iDQuickCompare[iQ_PageBegin] = iHandySpell iN_DQuickCompare[iComp] = iN_DQuickCompare[iComp] + 1 iAutoDispelRules[iHandySpell] = iAutoDispelRules[iHandySpell] + 1 endIf endFunction String function GetMagickaComparisonString(Int iHandySpell) return hMenu_Comparison[hc_MagickaComparison[iHandySpell]] endFunction String function ChangeHealthComparison(Int iHandySpell) if hc_HealthComparison[iHandySpell] < 2 hc_HealthComparison[iHandySpell] = hc_HealthComparison[iHandySpell] + 1 else hc_HealthComparison[iHandySpell] = 0 endIf if hc_HealthComparison[iHandySpell] AddQuickCompare(iHandySpell, true, 3) else RemoveQuickCompare(iHandySpell, true, 3) endIf return GetHealthComparisonString(iHandySpell) endFunction function ResetHandySpell(Int iSpell) hc_HandySpell[iSpell] = emptySpell hc_HandySpellDuration[iSpell] = 0 hc_HandySpellEnable[iSpell] = true hc_CombatState[iSpell] = 0 hc_SneakingState[iSpell] = 0 hc_WeaponDrawn[iSpell] = 0 hc_WeaponDraw_Weapon[iSpell] = emptyWeapon hc_WeaponDraw_Spell[iSpell] = emptySpell hc_HealthComparison[iSpell] = 0 hc_HealthPercentage[iSpell] = 50.0000 hc_MagickaComparison[iSpell] = 0 hc_MagickaPercentage[iSpell] = 50.0000 hc_StaminaComparison[iSpell] = 0 hc_StaminaPercentage[iSpell] = 50.0000 hc_AutoCastDelay[iSpell] = 0 hc_Cooldown[iSpell] = false hc_LastMagickaCost[iSpell] = 0.000000 hc_ReadyToCast[iSpell] = 0 hc_ReadyToDispel[iSpell] = 0 ResetDispelStructures(iSpell) endFunction Bool function IsHealthComparisonActive(Int iHandySpell) return hc_HealthComparison[iHandySpell] != 0 endFunction String function DefaultDispelCombatState(Int iHandySpell) hc_DispelCombatState[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, false, 0) return GetDispelCombatStateString(iHandySpell) endFunction String[] function GetMenuRecentSpells() return hMenu_RecentSpells endFunction function Cast_Check() fCast_Check_TimeStamp = utility.GetCurrentRealTime() bHandyDispel_ReadyToDisplayMessage = true if playerREF.IsInCombat() iCast_Check_CombatState = 1 else iCast_Check_CombatState = 2 endIf if playerREF.IsSneaking() iCast_Check_SneakingState = 1 else iCast_Check_SneakingState = 2 endIf bCast_Check_WeaponDrawn = playerREF.IsWeaponDrawn() iCast_Check_iIndex = 11 while iCast_Check_iIndex iCast_Check_iIndex -= 1 iWhenToDoStuff[iCast_Check_iIndex] = 0 endWhile iCast_Check_iIndex = 11 * 0 iCast_Check_EndCompare = 11 * 0 + iN_DQuickCompare[0] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iDQuickCompare[iCast_Check_iIndex] if iCast_Check_CombatState == hc_DispelCombatState[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf iCast_Check_iIndex += 1 endWhile iCast_Check_iIndex = 11 * 1 iCast_Check_EndCompare = 11 * 1 + iN_DQuickCompare[1] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iDQuickCompare[iCast_Check_iIndex] if iCast_Check_SneakingState == hc_DispelSneakingState[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf iCast_Check_iIndex += 1 endWhile iCast_Check_iIndex = 11 * 2 iCast_Check_EndCompare = 11 * 2 + iN_DQuickCompare[2] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iDQuickCompare[iCast_Check_iIndex] if !bCast_Check_WeaponDrawn iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf iCast_Check_iIndex += 1 endWhile iCast_Check_iIndex = 0 iCast_Check_EndCompare = 11 while iCast_Check_iIndex < iCast_Check_EndCompare if hc_Cooldown[iCast_Check_iIndex] if iAutoDispelRules[iCast_Check_iIndex] as Bool && iWhenToDoStuff[iCast_Check_iIndex] == iAutoDispelRules[iCast_Check_iIndex] if hc_ReadyToDispel[iCast_Check_iIndex] > 0 hc_ReadyToDispel[iCast_Check_iIndex] = hc_ReadyToDispel[iCast_Check_iIndex] - 5 else HandyDispel(iCast_Check_iIndex) endIf elseIf !hc_Maintain[iCast_Check_iIndex] hc_ReadyToDispel[iCast_Check_iIndex] = hc_DispelDelay[iCast_Check_iIndex] endIf endIf iCast_Check_iIndex += 1 endWhile iCast_Check_iIndex = 11 while iCast_Check_iIndex iCast_Check_iIndex -= 1 iWhenToDoStuff[iCast_Check_iIndex] = 0 endWhile iCast_Check_iIndex = 11 * 0 iCast_Check_EndCompare = 11 * 0 + iN_AQuickCompare[0] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iAQuickCompare[iCast_Check_iIndex] if iCast_Check_CombatState == hc_CombatState[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf iCast_Check_iIndex += 1 endWhile iCast_Check_iIndex = 11 * 1 iCast_Check_EndCompare = 11 * 1 + iN_AQuickCompare[1] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iAQuickCompare[iCast_Check_iIndex] if iCast_Check_SneakingState == hc_SneakingState[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf iCast_Check_iIndex += 1 endWhile if bCast_Check_WeaponDrawn as Bool && iN_AQuickCompare[2] as Bool iCast_Check_ItemTypeL = playerREF.GetEquippedItemType(0) + 4 iCast_Check_ItemTypeR = playerREF.GetEquippedItemType(1) + 4 hCast_Check_WeaponL = playerREF.GetEquippedWeapon(true) hCast_Check_WeaponR = playerREF.GetEquippedWeapon(false) hCast_Check_SpellL = playerREF.GetEquippedSpell(0) hCast_Check_SpellR = playerREF.GetEquippedSpell(1) iCast_Check_iIndex = 11 * 2 iCast_Check_EndCompare = 11 * 2 + iN_AQuickCompare[2] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iAQuickCompare[iCast_Check_iIndex] if hc_WeaponDrawn[iCast_Check_Page] == 1 iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 elseIf hc_WeaponDrawn[iCast_Check_Page] == iCast_Check_ItemTypeL || hc_WeaponDrawn[iCast_Check_Page] == iCast_Check_ItemTypeR iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 elseIf hc_WeaponDrawn[iCast_Check_Page] == 2 if hCast_Check_SpellL == hc_WeaponDraw_Spell[iCast_Check_Page] || hCast_Check_SpellR == hc_WeaponDraw_Spell[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf elseIf hc_WeaponDrawn[iCast_Check_Page] == 3 if hCast_Check_WeaponL == hc_WeaponDraw_Weapon[iCast_Check_Page] || hCast_Check_WeaponR == hc_WeaponDraw_Weapon[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf endIf iCast_Check_iIndex += 1 endWhile endIf if iN_AQuickCompare[3] fCast_Check_Health = playerREF.GetAVPercentage("Health") * 100 as Float iCast_Check_iIndex = 11 * 3 iCast_Check_EndCompare = 11 * 3 + iN_AQuickCompare[3] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iAQuickCompare[iCast_Check_iIndex] if hc_HealthComparison[iCast_Check_Page] == 1 if fCast_Check_Health < hc_HealthPercentage[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf elseIf fCast_Check_Health > hc_HealthPercentage[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf iCast_Check_iIndex += 1 endWhile endIf if iN_AQuickCompare[4] fCast_Check_Magicka = playerREF.GetAVPercentage("Magicka") * 100 as Float iCast_Check_iIndex = 11 * 4 iCast_Check_EndCompare = 11 * 4 + iN_AQuickCompare[4] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iAQuickCompare[iCast_Check_iIndex] if hc_MagickaComparison[iCast_Check_Page] == 1 if fCast_Check_Magicka < hc_MagickaPercentage[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf elseIf fCast_Check_Magicka > hc_MagickaPercentage[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf iCast_Check_iIndex += 1 endWhile endIf if iN_AQuickCompare[5] fCast_Check_Stamina = playerREF.GetAVPercentage("Stamina") * 100 as Float iCast_Check_iIndex = 11 * 5 iCast_Check_EndCompare = 11 * 5 + iN_AQuickCompare[5] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iAQuickCompare[iCast_Check_iIndex] if hc_StaminaComparison[iCast_Check_Page] == 1 if fCast_Check_Stamina < hc_StaminaPercentage[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf elseIf fCast_Check_Stamina > hc_StaminaPercentage[iCast_Check_Page] iWhenToDoStuff[iCast_Check_Page] = iWhenToDoStuff[iCast_Check_Page] + 1 endIf iCast_Check_iIndex += 1 endWhile endIf iCast_Check_iIndex = 11 * 3 iCast_Check_EndCompare = 11 * 3 + iN_DQuickCompare[3] while iCast_Check_iIndex < iCast_Check_EndCompare iCast_Check_Page = iDQuickCompare[iCast_Check_iIndex] if hc_Cooldown[iCast_Check_Page] && iWhenToDoStuff[iCast_Check_Page] != iAutoCastRules[iCast_Check_Page] if hc_ReadyToDispel[iCast_Check_Page] > 0 hc_ReadyToDispel[iCast_Check_Page] = hc_ReadyToDispel[iCast_Check_Page] - 5 else HandyDispel(iCast_Check_Page) endIf else hc_ReadyToDispel[iCast_Check_Page] = hc_DispelDelay[iCast_Check_Page] endIf iCast_Check_iIndex += 1 endWhile fCast_Check_TimeStampExtra = utility.GetCurrentRealTime() fCast_Check_TimeStamp = fCast_Check_TimeStampExtra - fCast_Check_TimeStamp if fCast_Check_TimeStamp > 2 as Float iCast_Check_ExtraTick = 0 else fCast_Check_TimeStamp += fCooldownTime iCast_Check_ExtraTick = math.Floor(fCast_Check_TimeStamp) fCooldownTime = fCast_Check_TimeStamp - iCast_Check_ExtraTick as Float endIf iCast_Check_iIndex = 0 iCast_Check_EndCompare = 11 while iCast_Check_iIndex < iCast_Check_EndCompare if iAutoCastRules[iCast_Check_iIndex] as Bool && iWhenToDoStuff[iCast_Check_iIndex] == iAutoCastRules[iCast_Check_iIndex] if hc_ReadyToCast[iCast_Check_iIndex] > 0 hc_ReadyToCast[iCast_Check_iIndex] = hc_ReadyToCast[iCast_Check_iIndex] - 5 - iCast_Check_ExtraTick else HandyCast(iCast_Check_iIndex) endIf elseIf hc_Cooldown[iCast_Check_iIndex] if hc_ReadyToCast[iCast_Check_iIndex] > 0 hc_ReadyToCast[iCast_Check_iIndex] = hc_ReadyToCast[iCast_Check_iIndex] - 5 - iCast_Check_ExtraTick else hc_Cooldown[iCast_Check_iIndex] = false hc_ReadyToCast[iCast_Check_iIndex] = hc_AutoCastDelay[iCast_Check_iIndex] endIf else hc_ReadyToCast[iCast_Check_iIndex] = hc_AutoCastDelay[iCast_Check_iIndex] endIf iCast_Check_iIndex += 1 endWhile RegisterForSingleUpdate(5 as Float) fCast_Check_TimeStamp = utility.GetCurrentRealTime() - fCast_Check_TimeStampExtra if fCast_Check_TimeStamp < 2 as Float fCooldownTime += fCast_Check_TimeStamp endIf endFunction String function GetStaminaComparisonString(Int iHandySpell) return hMenu_Comparison[hc_StaminaComparison[iHandySpell]] endFunction String function ChangeStaminaComparison(Int iHandySpell) if hc_StaminaComparison[iHandySpell] < 2 hc_StaminaComparison[iHandySpell] = hc_StaminaComparison[iHandySpell] + 1 else hc_StaminaComparison[iHandySpell] = 0 endIf if hc_StaminaComparison[iHandySpell] AddQuickCompare(iHandySpell, true, 5) else RemoveQuickCompare(iHandySpell, true, 5) endIf return GetStaminaComparisonString(iHandySpell) endFunction function DeleteHandySpell(Int iPage) if !IsHandySpellEmpty(iPage) CloseMCM() ResetHandySpell(iPage) RemovePageFromQuickCompare(iPage) UpdatePageNames() HandyCastRegistration() endIf endFunction String function ChangeSneakingState(Int iHandySpell) hc_SneakingState[iHandySpell] = hc_SneakingState[iHandySpell] + 1 if hc_SneakingState[iHandySpell] == hc_DispelSneakingState[iHandySpell] hc_SneakingState[iHandySpell] = hc_SneakingState[iHandySpell] + 1 endIf if hc_SneakingState[iHandySpell] > 2 hc_SneakingState[iHandySpell] = 0 endIf if hc_SneakingState[iHandySpell] AddQuickCompare(iHandySpell, true, 1) else RemoveQuickCompare(iHandySpell, true, 1) endIf return GetSneakingStateString(iHandySpell) endFunction function MoveRecentWeaponsUp(Int iSource) Int iIndex = iSource while iIndex > 0 iIndex -= 1 hRecentWeapons[iIndex + 1] = hRecentWeapons[iIndex] endWhile endFunction function AddPageToQuickCompare(Int iHandySpell) if hc_CombatState[iHandySpell] AddQuickCompare(iHandySpell, true, 0) endIf if hc_SneakingState[iHandySpell] AddQuickCompare(iHandySpell, true, 1) endIf if hc_WeaponDrawn[iHandySpell] AddQuickCompare(iHandySpell, true, 2) endIf if hc_HealthComparison[iHandySpell] AddQuickCompare(iHandySpell, true, 3) endIf if hc_MagickaComparison[iHandySpell] AddQuickCompare(iHandySpell, true, 4) endIf if hc_StaminaComparison[iHandySpell] AddQuickCompare(iHandySpell, true, 5) endIf if hc_DispelCombatState[iHandySpell] AddQuickCompare(iHandySpell, false, 0) endIf if hc_DispelSneakingState[iHandySpell] AddQuickCompare(iHandySpell, false, 1) endIf if hc_DispelWeaponSheath[iHandySpell] AddQuickCompare(iHandySpell, false, 2) endIf if hc_Maintain[iHandySpell] AddQuickCompare(iHandySpell, false, 3) endIf endFunction String function DefaultHealthComparison(Int iHandySpell) hc_HealthComparison[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, true, 3) return GetHealthComparisonString(iHandySpell) endFunction function LoopsReset() Int iIndex = 0 while iIndex < 11 if hc_Cooldown[iIndex] HandyDispel(iIndex) endIf hc_Cooldown[iIndex] = false hc_LastMagickaCost[iIndex] = 0.000000 hc_ReadyToCast[iIndex] = hc_AutoCastDelay[iIndex] hc_ReadyToDispel[iIndex] = hc_DispelDelay[iIndex] hc_DispelOnCombat[iIndex] = false iIndex += 1 endWhile HandyCastRegistration() endFunction function CloseMCM() UI.Invoke("Journal Menu", "_root.QuestJournalFader.Menu_mc.ConfigPanelClose") UI.Invoke("Journal Menu", "_root.QuestJournalFader.Menu_mc.CloseMenu") Utility.Wait(0.5) endFunction function MoveHandySpell(Int iSource, Int iTarget) ShowMessage("The MCM will close to complete the task.", false) CloseMCM() Int iIndex Spell tmp_HandySpell = hc_HandySpell[iSource] Int tmp_HandySpellDuration = hc_HandySpellDuration[iSource] Bool tmp_HandySpellEnable = hc_HandySpellEnable[iSource] Int tmp_CombatState = hc_CombatState[iSource] Int tmp_SneakingState = hc_SneakingState[iSource] Int tmp_WeaponDrawn = hc_WeaponDrawn[iSource] Weapon tmp_WeaponDraw_Weapon = hc_WeaponDraw_Weapon[iSource] Spell tmp_WeaponDraw_Spell = hc_WeaponDraw_Spell[iSource] Int tmp_HealthComparison = hc_HealthComparison[iSource] Float tmp_HealthPercentage = hc_HealthPercentage[iSource] Int tmp_MagickaComparison = hc_MagickaComparison[iSource] Float tmp_MagickaPercentage = hc_MagickaPercentage[iSource] Int tmp_StaminaComparison = hc_StaminaComparison[iSource] Float tmp_StaminaPercentage = hc_StaminaPercentage[iSource] Int tmp_AutoCastDelay = hc_AutoCastDelay[iSource] Int tmp_DispelCombatState = hc_DispelCombatState[iSource] Int tmp_DispelSneakingState = hc_DispelSneakingState[iSource] Bool tmp_DispelWeaponSheath = hc_DispelWeaponSheath[iSource] Bool tmp_Maintain = hc_Maintain[iSource] Int tmp_DispelDelay = hc_DispelDelay[iSource] Bool tmp_DispelOnCombat = hc_DispelOnCombat[iSource] Bool tmp_Cooldown = hc_Cooldown[iSource] Float tmp_LastMagickaCost = hc_LastMagickaCost[iSource] Int tmp_ReadyToCast = hc_ReadyToCast[iSource] Int tmp_ReadyToDispel = hc_ReadyToDispel[iSource] Int tmp_iAutoCastRules = iAutoCastRules[iSource] Int tmp_iAutoDispelRules = iAutoDispelRules[iSource] ChangeQuickCompareNumber(iSource, -19) if iSource < iTarget iIndex = iSource while iIndex < iTarget ProtoHandySpellMove(iIndex + 1, iIndex) iIndex += 1 endWhile else iIndex = iSource while iIndex > iTarget ProtoHandySpellMove(iIndex - 1, iIndex) iIndex -= 1 endWhile endIf ChangeQuickCompareNumber(-19, iTarget) hc_HandySpell[iTarget] = tmp_HandySpell hc_HandySpellDuration[iTarget] = tmp_HandySpellDuration hc_HandySpellEnable[iTarget] = tmp_HandySpellEnable hc_CombatState[iTarget] = tmp_CombatState hc_SneakingState[iTarget] = tmp_SneakingState hc_WeaponDrawn[iTarget] = tmp_WeaponDrawn hc_WeaponDraw_Weapon[iTarget] = tmp_WeaponDraw_Weapon hc_WeaponDraw_Spell[iTarget] = tmp_WeaponDraw_Spell hc_HealthComparison[iTarget] = tmp_HealthComparison hc_HealthPercentage[iTarget] = tmp_HealthPercentage hc_MagickaComparison[iTarget] = tmp_MagickaComparison hc_MagickaPercentage[iTarget] = tmp_MagickaPercentage hc_StaminaComparison[iTarget] = tmp_StaminaComparison hc_StaminaPercentage[iTarget] = tmp_StaminaPercentage hc_AutoCastDelay[iTarget] = tmp_AutoCastDelay hc_DispelCombatState[iTarget] = tmp_DispelCombatState hc_DispelSneakingState[iTarget] = tmp_DispelSneakingState hc_DispelWeaponSheath[iTarget] = tmp_DispelWeaponSheath hc_Maintain[iTarget] = tmp_Maintain hc_DispelDelay[iTarget] = tmp_DispelDelay hc_DispelOnCombat[iTarget] = tmp_DispelOnCombat hc_Cooldown[iTarget] = tmp_Cooldown hc_LastMagickaCost[iTarget] = tmp_LastMagickaCost hc_ReadyToCast[iTarget] = tmp_ReadyToCast hc_ReadyToDispel[iTarget] = tmp_ReadyToDispel iAutoCastRules[iTarget] = tmp_iAutoCastRules iAutoDispelRules[iTarget] = tmp_iAutoDispelRules UpdatePageNames() endFunction Int function IsAlreadyInTheRecentWeapons(Weapon p_Weapon) Int iIndex = 0 while iIndex < 30 if hRecentWeapons[iIndex] == p_Weapon return iIndex elseIf hRecentWeapons[iIndex] == emptyWeapon return -1 endIf iIndex += 1 endWhile return -1 endFunction function ChangeQuickCompareNumber(Int iSearch, Int iNewNumber) Int iQ_PageBegin Int iQN_Page Int iIndex = 0 while iIndex < 6 iQN_Page = iN_AQuickCompare[iIndex] iQ_PageBegin = iIndex * 11 while iQN_Page iQN_Page -= 1 if iAQuickCompare[iQ_PageBegin + iQN_Page] == iSearch iAQuickCompare[iQ_PageBegin + iQN_Page] = iNewNumber iQN_Page = 0 endIf endWhile iIndex += 1 endWhile iIndex = 0 while iIndex < 4 iQN_Page = iN_DQuickCompare[iIndex] iQ_PageBegin = iIndex * 11 while iQN_Page iQN_Page -= 1 if iDQuickCompare[iQ_PageBegin + iQN_Page] == iSearch iDQuickCompare[iQ_PageBegin + iQN_Page] = iNewNumber iQN_Page = 0 endIf endWhile iIndex += 1 endWhile endFunction spell[] function GetRecentSpells() return hRecentSpells endFunction function HandyDispel(Int iHandySpell) if bHandyDispel_ReadyToDisplayMessage debug.Notification("Auto Dispelling") bHandyDispel_ReadyToDisplayMessage = false endIf if iCast_Check_CombatState == 1 || hc_DispelOnCombat[iHandySpell] playerREF.RestoreAV("Magicka", hc_ReadyToCast[iHandySpell] as Float * 0.800000 / hc_HandySpellDuration[iHandySpell] as Float * hc_LastMagickaCost[iHandySpell]) endIf playerREF.DispelSpell(hc_HandySpell[iHandySpell]) hc_Cooldown[iHandySpell] = false hc_ReadyToCast[iHandySpell] = hc_AutoCastDelay[iHandySpell] endFunction Bool function DefaultMaintainAutoCastRules(Int iHandySpell) hc_Maintain[iHandySpell] = false RemoveQuickCompare(iHandySpell, false, 3) return false endFunction Bool function HandyCast(Int iHandySpell) hHandyCast_Spell = hc_HandySpell[iHandySpell] fHandyCast_MagickaCost = hHandyCast_Spell.GetEffectiveMagickaCost(playerREF) as Float if fHandyCast_MagickaCost <= playerREF.GetAV("Magicka") playerREF.DamageAV("Magicka", fHandyCast_MagickaCost) if hc_Notifications debug.Notification("Handy Cast: " + hHandyCast_Spell.GetName()) endIf hc_LastMagickaCost[iHandySpell] = fHandyCast_MagickaCost hc_Cooldown[iHandySpell] = true UpdateSpellDuration(iHandySpell) hc_ReadyToCast[iHandySpell] = hc_HandySpellDuration[iHandySpell] hc_ReadyToDispel[iHandySpell] = hc_DispelDelay[iHandySpell] hc_DispelOnCombat[iHandySpell] = iCast_Check_CombatState == 1 hHandyCast_Spell.Cast(playerREF as objectreference, none) return true else return false endIf endFunction Bool function IsHandySpellEmpty(Int iPage) return hc_HandySpell[iPage] == emptySpell endFunction String function GetDispelCombatStateString(Int iHandySpell) return hMenu_CombatStates[hc_DispelCombatState[iHandySpell]] endFunction Bool function ParanoiaPanicStopStatus() return bParanoiaPanicStop endFunction function PreventHandyCastRegistration(Bool p_ParanoiaPanicStop) bParanoiaPanicStop = p_ParanoiaPanicStop LoopsReset() endFunction String function GetHealthComparisonString(Int iHandySpell) return hMenu_Comparison[hc_HealthComparison[iHandySpell]] endFunction Bool function IsRecentSpellsMenuEmpty() return hRecentSpells[0] == emptySpell endFunction function CustomPageRefresh() Int iFlagMain if IsRecentSpellsMenuEmpty() || !IsHandySpellValid(iCurrentHandySpell) || !hc_HandySpellEnable[iCurrentHandySpell] iFlagMain = OPTION_FLAG_DISABLED else iFlagMain = OPTION_FLAG_NONE endIf if IsRecentSpellsMenuEmpty() || !hc_HandySpellEnable[iCurrentHandySpell] SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_HandySpell") else SetOptionFlagsST(OPTION_FLAG_NONE, false, "iMenuID_HandySpell") endIf SetOptionFlagsST(iFlagMain, false, "iMenuID_CombatState") SetOptionFlagsST(iFlagMain, false, "iMenuID_SneakingState") SetOptionFlagsST(iFlagMain, false, "iMenuID_WeaponDrawn") if IsSpecificWeaponDrawn(iCurrentHandySpell) SetOptionFlagsST(iFlagMain, false, "iMenuID_WeaponDrawn_Weapon") else SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_WeaponDrawn_Weapon") endIf SetOptionFlagsST(iFlagMain, false, "iMenuID_AutoCastDelay") if CanHandySpellBeAutoDispel(iCurrentHandySpell) SetOptionFlagsST(iFlagMain, false, "iMenuID_Maintain") SetOptionFlagsST(iFlagMain, false, "iMenuID_DispelDelay") else SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_Maintain") SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_DispelDelay") endIf if IsRecentSpellsMenuEmpty() SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_SpellEnable") else SetOptionFlagsST(OPTION_FLAG_NONE, false, "iMenuID_SpellEnable") endIf SetOptionFlagsST(iFlagMain, false, "iMenuID_HealthComparison") if IsHealthComparisonActive(iCurrentHandySpell) SetOptionFlagsST(iFlagMain, false, "iMenuID_HealthPercentage") else SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_HealthPercentage") endIf SetOptionFlagsST(iFlagMain, false, "iMenuID_MagickaComparison") if IsMagickaComparisonActive(iCurrentHandySpell) SetOptionFlagsST(iFlagMain, false, "iMenuID_MagickaPercentage") else SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_MagickaPercentage") endIf SetOptionFlagsST(iFlagMain, false, "iMenuID_StaminaComparison") if IsStaminaComparisonActive(iCurrentHandySpell) SetOptionFlagsST(iFlagMain, false, "iMenuID_StaminaPercentage") else SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_StaminaPercentage") endIf if CanHandySpellBeAutoDispel(iCurrentHandySpell) && !hc_Maintain[iCurrentHandySpell] SetOptionFlagsST(iFlagMain, false, "iMenuID_DispelCombatState") SetOptionFlagsST(iFlagMain, false, "iMenuID_DispelSneakingState") SetOptionFlagsST(iFlagMain, false, "iMenuID_DispelWeaponSheath") else SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_DispelCombatState") SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_DispelSneakingState") SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_DispelWeaponSheath") endIf endFunction String function DefaultStaminaComparison(Int iHandySpell) hc_StaminaComparison[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, true, 5) return GetStaminaComparisonString(iHandySpell) endFunction function UpdatePageNames() Int iIndex = 11 while iIndex iIndex -= 1 Pages[iIndex] = GetHandySpellName(iIndex) endWhile endFunction Bool function IsDuplicatedHandySpell(Spell p_Spell) Int iIndex = 11 while iIndex iIndex -= 1 if hc_HandySpell[iIndex] == p_Spell return true endIf endWhile return false endFunction String function ChangeHandyCastSpell(Int iHandySpell, Int iMenuIndex) Spell tmpSpell hc_HandySpell[iHandySpell] = hRecentSpells[iMenuIndex] SetTitleText(hMenu_RecentSpells[iMenuIndex + 1]) hc_HandySpellDuration[iHandySpell] = 0 UpdateSpellDuration(iHandySpell) hc_ReadyToCast[iHandySpell] = hc_AutoCastDelay[iHandySpell] hc_Cooldown[iHandySpell] = false if !CanHandySpellBeAutoDispel(iHandySpell) RemoveDispelFeatures(iHandySpell) endIf return hMenu_RecentSpells[iMenuIndex + 1] endFunction String function DefaultHandyCastSpell(Int iHandySpell) ResetHandySpell(iHandySpell) return GetHandySpellName(iHandySpell) endFunction Int function IsAlreadyInTheRecentSpells(Spell p_Spell) Int iIndex = 0 while iIndex < 30 if hRecentSpells[iIndex] == p_Spell return iIndex elseIf hRecentSpells[iIndex] == emptySpell return -1 endIf iIndex += 1 endWhile return -1 endFunction function ResetDispelStructures(Int iSpell) hc_Maintain[iSpell] = false hc_DispelCombatState[iSpell] = 0 hc_DispelSneakingState[iSpell] = 0 hc_DispelWeaponSheath[iSpell] = false hc_DispelDelay[iSpell] = 0 hc_DispelOnCombat[iSpell] = false endFunction String function GetHandySpellName(Int iHandySpell) if hc_HandySpell[iHandySpell] == emptySpell return "Spell " + iHandySpell as String else return hc_HandySpell[iHandySpell].GetName() endIf endFunction String function GetCombatStateString(Int iHandySpell) return hMenu_CombatStates[hc_CombatState[iHandySpell]] endFunction function UpdateSpellDuration(Int iHandySpell) iUpdateSpellDuration_iMaxDuration = -1 hUpdateSpellDuration_Spell = hc_HandySpell[iHandySpell] iUpdateSpellDuration_iNumEffects = hUpdateSpellDuration_Spell.GetNumEffects() while iUpdateSpellDuration_iNumEffects iUpdateSpellDuration_iNumEffects -= 1 if hUpdateSpellDuration_Spell.GetNthEffectDuration(iUpdateSpellDuration_iNumEffects) > iUpdateSpellDuration_iMaxDuration iUpdateSpellDuration_iMaxDuration = hUpdateSpellDuration_Spell.GetNthEffectDuration(iUpdateSpellDuration_iNumEffects) endIf endWhile if iUpdateSpellDuration_iMaxDuration <= 25 hc_HandySpellDuration[iHandySpell] = 0 else hc_HandySpellDuration[iHandySpell] = iUpdateSpellDuration_iMaxDuration - 9 endIf endFunction function RemovePageFromQuickCompare(Int iHandySpell) Int iIndex = 6 while iIndex iIndex -= 1 RemoveQuickCompare(iHandySpell, true, iIndex) endWhile iIndex = 4 while iIndex iIndex -= 1 RemoveQuickCompare(iHandySpell, false, iIndex) endWhile endFunction String function GetSneakingStateString(Int iHandySpell) return hMenu_SneakStates[hc_SneakingState[iHandySpell]] endFunction function ProtoHandySpellMove(Int iSource, Int iTarget) hc_HandySpell[iTarget] = hc_HandySpell[iSource] hc_HandySpellDuration[iTarget] = hc_HandySpellDuration[iSource] hc_HandySpellEnable[iTarget] = hc_HandySpellEnable[iSource] hc_CombatState[iTarget] = hc_CombatState[iSource] hc_SneakingState[iTarget] = hc_SneakingState[iSource] hc_WeaponDrawn[iTarget] = hc_WeaponDrawn[iSource] hc_WeaponDraw_Weapon[iTarget] = hc_WeaponDraw_Weapon[iSource] hc_WeaponDraw_Spell[iTarget] = hc_WeaponDraw_Spell[iSource] hc_HealthComparison[iTarget] = hc_HealthComparison[iSource] hc_HealthPercentage[iTarget] = hc_HealthPercentage[iSource] hc_MagickaComparison[iTarget] = hc_MagickaComparison[iSource] hc_MagickaPercentage[iTarget] = hc_MagickaPercentage[iSource] hc_StaminaComparison[iTarget] = hc_StaminaComparison[iSource] hc_StaminaPercentage[iTarget] = hc_StaminaPercentage[iSource] hc_AutoCastDelay[iTarget] = hc_AutoCastDelay[iSource] hc_DispelCombatState[iTarget] = hc_DispelCombatState[iSource] hc_DispelSneakingState[iTarget] = hc_DispelSneakingState[iSource] hc_DispelWeaponSheath[iTarget] = hc_DispelWeaponSheath[iSource] hc_Maintain[iTarget] = hc_Maintain[iSource] hc_DispelDelay[iTarget] = hc_DispelDelay[iSource] hc_DispelOnCombat[iTarget] = hc_DispelOnCombat[iSource] hc_Cooldown[iTarget] = hc_Cooldown[iSource] hc_LastMagickaCost[iTarget] = hc_LastMagickaCost[iSource] hc_ReadyToCast[iTarget] = hc_ReadyToCast[iSource] hc_ReadyToDispel[iTarget] = hc_ReadyToDispel[iSource] ChangeQuickCompareNumber(iSource, iTarget) iAutoCastRules[iTarget] = iAutoCastRules[iSource] iAutoDispelRules[iTarget] = iAutoDispelRules[iSource] endFunction Bool function IsMagickaComparisonActive(Int iHandySpell) return hc_MagickaComparison[iHandySpell] != 0 endFunction Bool function IsRecentWeaponsMenuEmpty() return hRecentWeapons[0] == emptyWeapon endFunction function MoveRecentSpellsUp(Int iSource) Int iIndex = iSource while iIndex > 0 iIndex -= 1 hRecentSpells[iIndex + 1] = hRecentSpells[iIndex] endWhile endFunction String function DefaultWeaponDrawn(Int iHandySpell) hc_WeaponDraw_Spell[iHandySpell] = emptySpell hc_WeaponDraw_Weapon[iHandySpell] = emptyWeapon return GetWeaponDrawnString(iHandySpell) endFunction String function ChangeWeaponDrawnState(Int iHandySpell, Int iMenuIndex) hc_WeaponDrawn[iHandySpell] = iMenuIndex if iMenuIndex AddQuickCompare(iHandySpell, true, 2) else RemoveQuickCompare(iHandySpell, true, 2) endIf return GetWeaponDrawnStateString(iHandySpell) endFunction function UpdateRecentWeaponsMenu() Int iIndex Bool bFlagWeapon Int kIndex = 2 while kIndex Weapon tmpWeapon = emptyWeapon while kIndex as Bool && tmpWeapon == emptyWeapon kIndex -= 1 Int iType = playerREF.GetEquippedItemType(kIndex) if iType >= 1 && iType <= 8 || iType == 12 tmpWeapon = playerREF.GetEquippedWeapon(kIndex == 0) endIf endWhile if tmpWeapon != emptyWeapon iIndex = IsAlreadyInTheRecentWeapons(tmpWeapon) if iIndex < 0 MoveRecentWeaponsUp(30 - 1) else MoveRecentWeaponsUp(iIndex) endIf hRecentWeapons[0] = tmpWeapon endIf endWhile iIndex = 0 while iIndex < 30 if hRecentWeapons[iIndex] != emptyWeapon hMenu_RecentWeapons[iIndex + 1] = hRecentWeapons[iIndex].GetName() iIndex += 1 else iIndex = 30 endIf endWhile endFunction String function DefaultCombatState(Int iHandySpell) hc_CombatState[iHandySpell] = 0 RemoveQuickCompare(iHandySpell, true, 0) return GetCombatStateString(iHandySpell) endFunction String function GetWeaponDrawnString(Int iHandySpell) if hc_WeaponDrawn[iHandySpell] == 2 && hc_WeaponDraw_Spell[iHandySpell] != emptySpell return hc_WeaponDraw_Spell[iHandySpell].GetName() elseIf hc_WeaponDrawn[iHandySpell] == 3 && hc_WeaponDraw_Weapon[iHandySpell] != emptyWeapon return hc_WeaponDraw_Weapon[iHandySpell].GetName() else return "Any" endIf endFunction String function ChangeDispelSneakingState(Int iHandySpell) hc_DispelSneakingState[iHandySpell] = hc_DispelSneakingState[iHandySpell] + 1 if hc_DispelSneakingState[iHandySpell] == hc_SneakingState[iHandySpell] hc_DispelSneakingState[iHandySpell] = hc_DispelSneakingState[iHandySpell] + 1 endIf if hc_DispelSneakingState[iHandySpell] > 2 hc_DispelSneakingState[iHandySpell] = 0 endIf if hc_DispelSneakingState[iHandySpell] AddQuickCompare(iHandySpell, false, 1) else RemoveQuickCompare(iHandySpell, false, 1) endIf return GetDispelSneakingStateString(iHandySpell) endFunction String function ChangeMagickaComparison(Int iHandySpell) if hc_MagickaComparison[iHandySpell] < 2 hc_MagickaComparison[iHandySpell] = hc_MagickaComparison[iHandySpell] + 1 else hc_MagickaComparison[iHandySpell] = 0 endIf if hc_MagickaComparison[iHandySpell] AddQuickCompare(iHandySpell, true, 4) else RemoveQuickCompare(iHandySpell, true, 4) endIf return GetMagickaComparisonString(iHandySpell) endFunction Bool function IsHandySpellValid(Int iHandySpell) return hc_HandySpell[iHandySpell] != emptySpell endFunction Bool function ChangePanicButton() hc_PanicButton = !hc_PanicButton PreventHandyCastRegistration(hc_PanicButton) return hc_PanicButton endFunction function PrepareHandyDelete() if bHandySpellDelete bHandySpellDelete = false SetTextOptionValueST(hHandySpellOptions[0], false, "iMenuID_Manager_Delete") HandySpellsSelectionGUI(bHandySpellDelete) else bHandySpellDelete = true SetTextOptionValueST(hHandySpellOptions[1], false, "iMenuID_Manager_Delete") HandySpellsSelectionGUI(bHandySpellDelete) endIf endFunction function PrepareHandyMove() if iHandySpellMove == 0 iHandySpellMove = 1 SetTextOptionValueST(hHandySpellOptions[1], false, "iMenuID_Manager_Move") HandySpellsSelectionGUI(true) else iHandySpellMove = 0 SetTextOptionValueST(hHandySpellOptions[0], false, "iMenuID_Manager_Move") HandySpellsSelectionGUI(false) endIf endFunction function HandySpellMoveProcedure(Int iSpell) if iHandySpellMove == 1 iHandySpellMove = 2 iSelectedHandySpell = iSpell SetTextOptionValueST(GetHandySpellName(iSelectedHandySpell), false, "iMenuID_Manager_Move") else MoveHandySpell(iSelectedHandySpell, iSpell) if iSelectedHandySpell < iSpell while iSelectedHandySpell <= iSpell SetTextOptionValueST(GetHandySpellName(iSelectedHandySpell), false, "iMenuID_Manager_HandySpell" + iSelectedHandySpell) iSelectedHandySpell += 1 endWhile else while iSelectedHandySpell >= iSpell SetTextOptionValueST(GetHandySpellName(iSelectedHandySpell), false, "iMenuID_Manager_HandySpell" + iSelectedHandySpell) iSelectedHandySpell -= 1 endWhile endIf PrepareHandyMove() endIf endFunction function HandySpellsSelectionGUI(Bool bActivate) Int iFlag2 Int iFlag1 if bActivate iFlag1 = OPTION_FLAG_NONE iFlag2 = OPTION_FLAG_DISABLED else iFlag1 = OPTION_FLAG_DISABLED iFlag2 = OPTION_FLAG_NONE endIf Int iIndex = 0 while iIndex < 11 if bHandySpellDelete as Bool && !IsHandySpellEmpty(iIndex) || iHandySpellMove > 0 SetOptionFlagsST(iFlag1, false, "iMenuID_Manager_HandySpell" + iIndex) else SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "iMenuID_Manager_HandySpell" + iIndex) endIf iIndex += 1 endWhile if iHandySpellMove == 0 SetOptionFlagsST(iFlag2, false, "iMenuID_Manager_Move") endIf if !bHandySpellDelete SetOptionFlagsST(iFlag2, false, "iMenuID_Manager_Delete") endIf SetOptionFlagsST(iFlag2, false, "iMenuID_Show_Notifications") SetOptionFlagsST(iFlag2, false, "iMenuID_Manager_PanicButton") SetOptionFlagsST(iFlag2, false, "iMenuID_Manager_Reset") SetOptionFlagsST(iFlag2, false, "HSKeyState") endFunction function myf_spellmovedelete(int a_option) If bHandySpellDelete as Bool || iHandySpellMove > 0 if bHandySpellDelete if ShowMessage("Are you sure you want to delete: '" + GetHandySpellName(a_option) + "'? The MCM will close to complete the task.", true, "$Accept", "$Cancel") DeleteHandySpell(a_option) SetTextOptionValueST(GetHandySpellName(a_option), false, "iMenuID_Manager_HandySpell" + a_option) PrepareHandyDelete() endIf else HandySpellMoveProcedure(a_option) endIf endIf endFunction function myf_spellhighlight() if bHandySpellDelete SetInfoText("Press to delete") elseIf iHandySpellMove == 1 SetInfoText("Choose the spell you want to move") elseIf iHandySpellMove == 2 SetInfoText("Assign the place to move the selected spell") else SetInfoText("This part of the menu assist you to delete or move Handy Spells") endIf endFunction function myF_OnOptionKeyMapChange(Int keyCode, String conflictControl, String conflictName) bool bOK = true if (keyCode != 1) && (conflictControl != "") string s = "This key is already mapped to:\n\"" + conflictControl if (conflictName == "") s = s + "\"\n\nAre you sure you want to continue?" else s = s + "\"\n(" + conflictName + ")\n\nAre you sure you want to continue?" endIf bOK = ShowMessage(s, TRUE, "$Yes", "$No") endIf if (bOK) UnregisterForKey(iHCKeyMap) if (keyCode != 1) RegisterForKey(keyCode) iHCKeyMap = keyCode endIf SetKeyMapOptionValueST(keyCode, False, "HSKeyState") endIf endFunction function myF_Process(Int keycode) int i if Utility.IsInMenuMode() i = 1 elseIf UI.IsMenuOpen("Dialogue Menu") i = 2 elseIf UI.IsMenuOpen("Console") i = 3 elseIf UI.IsMenuOpen("Crafting Menu") i = 4 elseIf UI.IsMenuOpen("MessageBoxMenu") i = 5 elseIf UI.IsMenuOpen("ContainerMenu") i = 6 elseIf UI.IsTextInputEnabled() i = 7 endIf if (i > 0) RETURN endIf if iHCKeyMap != keyCode RETURN endIf if hc_PanicButton ChangePanicButton() debug.Notification("Handy Auto Cast: Spell Loop Started") else ChangePanicButton() debug.Notification("Handy Auto Cast: Spell Loop Stopped") endIf endFunction state Busy event OnKeyDown(Int keycode) endEvent endState state iMenuID_HandySpell event OnMenuOpenST() SetMenuDialogOptions(hMenu_RecentSpells) SetMenuDialogStartIndex(0) SetMenuDialogDefaultIndex(0) endEvent event OnMenuAcceptST(Int iMenuIndex) if iMenuIndex iMenuIndex -= 1 if hRecentSpells[iMenuIndex] == emptySpell ShowMessage("Not a valid spell", false, "$Accept", "$Cancel") elseIf IsDuplicatedHandySpell(hRecentSpells[iMenuIndex]) && hRecentSpells[iMenuIndex] != hc_HandySpell[iCurrentHandySpell] ShowMessage("There is another page with the same spell name, duplication is not supported", false, "$Accept", "$Cancel") else SetMenuOptionValueST(ChangeHandyCastSpell(iCurrentHandySpell, iMenuIndex), false, "iMenuID_HandySpell") endIf endIf CustomPageRefresh() endEvent event OnDefaultST() SetMenuOptionValueST(DefaultHandyCastSpell(iCurrentHandySpell), false, "iMenuID_HandySpell") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Choose a spell from list. Default to remove assigned spell.") endEvent endState state iMenuID_CombatState event OnSelectST() SetTextOptionValueST(ChangeCombatState(iCurrentHandySpell), false, "iMenuID_CombatState") CustomPageRefresh() endEvent event OnDefaultST() SetTextOptionValueST(DefaultCombatState(iCurrentHandySpell), false, "iMenuID_CombatState") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Choose a combat state to auto cast the spell") endEvent endState state iMenuID_SneakingState event OnSelectST() SetTextOptionValueST(ChangeSneakingState(iCurrentHandySpell), false, "iMenuID_SneakingState") CustomPageRefresh() endEvent event OnDefaultST() SetTextOptionValueST(DefaultSneakingState(iCurrentHandySpell), false, "iMenuID_SneakingState") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Choose a sneaking state to auto cast the spell") endEvent endState state iMenuID_WeaponDrawn event OnMenuOpenST() SetMenuDialogOptions(hMenu_WeaponDrawn) SetMenuDialogStartIndex(0) SetMenuDialogDefaultIndex(0) endEvent event OnMenuAcceptST(Int iMenuIndex) if iMenuIndex == 3 && IsRecentWeaponsMenuEmpty() ShowMessage("The Recent Weapons Menu is empty, equip weapons to your character before entering this menu to fill it up", false, "$Accept", "$Cancel") SetMenuOptionValueST(ChangeWeaponDrawnState(iCurrentHandySpell, 1), false, "iMenuID_WeaponDrawn") else SetMenuOptionValueST(ChangeWeaponDrawnState(iCurrentHandySpell, iMenuIndex), false, "iMenuID_WeaponDrawn") endIf SetMenuOptionValueST(GetWeaponDrawnString(iCurrentHandySpell), false, "iMenuID_WeaponDrawn_Weapon") CustomPageRefresh() endEvent event OnDefaultST() SetMenuOptionValueST(DefaultWeaponDrawnState(iCurrentHandySpell), false, "iMenuID_WeaponDrawn") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Auto cast the spell if your character readies for combat") endEvent endState state iMenuID_WeaponDrawn_Weapon event OnMenuOpenST() if hc_WeaponDrawn[iCurrentHandySpell] == 2 SetMenuDialogOptions(hMenu_RecentSpells) else SetMenuDialogOptions(hMenu_RecentWeapons) endIf SetMenuDialogStartIndex(0) SetMenuDialogDefaultIndex(0) endEvent event OnMenuAcceptST(Int iMenuIndex) if hc_WeaponDrawn[iCurrentHandySpell] == 2 if iMenuIndex iMenuIndex -= 1 if hRecentSpells[iMenuIndex] == emptySpell ShowMessage("Not a valid spell", false, "$Accept", "$Cancel") else hc_WeaponDraw_Spell[iCurrentHandySpell] = hRecentSpells[iMenuIndex] hc_WeaponDraw_Weapon[iCurrentHandySpell] = emptyWeapon endIf endIf elseIf iMenuIndex iMenuIndex -= 1 if hRecentWeapons[iMenuIndex] == emptyWeapon ShowMessage("Not a valid weapon", false, "$Accept", "$Cancel") else hc_WeaponDraw_Weapon[iCurrentHandySpell] = hRecentWeapons[iMenuIndex] hc_WeaponDraw_Spell[iCurrentHandySpell] = emptySpell endIf endIf SetMenuOptionValueST(GetWeaponDrawnString(iCurrentHandySpell), false, "iMenuID_WeaponDrawn_Weapon") CustomPageRefresh() endEvent event OnDefaultST() SetMenuOptionValueST(DefaultWeaponDrawn(iCurrentHandySpell), false, "iMenuID_WeaponDrawn_Weapon") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("If you have chosen a specific weapon or spell from the previous menu, you can indicate which one with this option") endEvent endState state iMenuID_AutoCastDelay event OnSliderOpenST() SetSliderDialogStartValue(hc_AutoCastDelay[iCurrentHandySpell] as Float) SetSliderDialogDefaultValue(5.00000) SetSliderDialogRange(0.000000, 30.0000) SetSliderDialogInterval(5.00000) endEvent event OnSliderAcceptST(float value) hc_AutoCastDelay[iCurrentHandySpell] = math.Floor(value) if !hc_Cooldown[iCurrentHandySpell] hc_ReadyToCast[iCurrentHandySpell] = hc_AutoCastDelay[iCurrentHandySpell] endIf SetSliderOptionValueST(hc_AutoCastDelay[iCurrentHandySpell] as Float, "{0} Seconds", false, "iMenuID_AutoCastDelay") CustomPageRefresh() endEvent event OnDefaultST() hc_AutoCastDelay[iCurrentHandySpell] = 0 if !hc_Cooldown[iCurrentHandySpell] hc_ReadyToCast[iCurrentHandySpell] = hc_AutoCastDelay[iCurrentHandySpell] endIf SetSliderOptionValueST(hc_AutoCastDelay[iCurrentHandySpell] as Float, "{0} Seconds", false, "iMenuID_AutoCastDelay") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("The auto cast can wait a few seconds before casting the spell. The rules have to be met for the duration specified. Choose zero to auto cast as soon as the system detects the rules qualifies") endEvent endState state iMenuID_Maintain event OnSelectST() SetToggleOptionValueST(ChangeMaintainAutoCastRules(iCurrentHandySpell), false, "iMenuID_Maintain") CustomPageRefresh() endEvent event OnDefaultST() SetToggleOptionValueST(DefaultMaintainAutoCastRules(iCurrentHandySpell), false, "iMenuID_Maintain") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Auto dispel if the auto cast rules are not met") endEvent endState state iMenuID_DispelDelay event OnSliderOpenST() SetSliderDialogStartValue(hc_DispelDelay[iCurrentHandySpell] as Float) SetSliderDialogDefaultValue(5.00000) SetSliderDialogRange(0.000000, 30.0000) SetSliderDialogInterval(5.00000) endEvent event OnSliderAcceptST(float value) hc_DispelDelay[iCurrentHandySpell] = math.Floor(value) if !hc_Cooldown[iCurrentHandySpell] hc_ReadyToDispel[iCurrentHandySpell] = hc_DispelDelay[iCurrentHandySpell] endIf SetSliderOptionValueST(hc_DispelDelay[iCurrentHandySpell] as Float, "{0} Seconds", false, "iMenuID_DispelDelay") CustomPageRefresh() endEvent event OnDefaultST() hc_DispelDelay[iCurrentHandySpell] = 0 if !hc_Cooldown[iCurrentHandySpell] hc_ReadyToDispel[iCurrentHandySpell] = hc_DispelDelay[iCurrentHandySpell] endIf SetSliderOptionValueST(hc_DispelDelay[iCurrentHandySpell] as Float, "{0} Seconds", false, "iMenuID_DispelDelay") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("The auto dispel can wait a few seconds before dispelling the spell. The rules have to be met for the duration specified. Choose zero to auto dispel as soon as the system detects the rules qualifies") endEvent endState state iMenuID_SpellEnable event OnSelectST() SetToggleOptionValueST(ChangeHandySpellEnable(iCurrentHandySpell), false, "iMenuID_SpellEnable") CustomPageRefresh() endEvent event OnDefaultST() SetToggleOptionValueST(DefaultHandySpellEnable(iCurrentHandySpell), false, "iMenuID_SpellEnable") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Instead of deleting this spell to prevent its execution, you can just disable it, and enable it later") endEvent endState state iMenuID_HealthComparison event OnSelectST() SetTextOptionValueST(ChangeHealthComparison(iCurrentHandySpell), false, "iMenuID_HealthComparison") CustomPageRefresh() endEvent event OnDefaultST() SetTextOptionValueST(DefaultHealthComparison(iCurrentHandySpell), false, "iMenuID_HealthComparison") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Select the type of comparison, 'less than' or 'greater than'") endEvent endState state iMenuID_HealthPercentage event OnSliderOpenST() SetSliderDialogStartValue(hc_HealthPercentage[iCurrentHandySpell]) SetSliderDialogDefaultValue(50.0000) SetSliderDialogRange(0.000000, 100.000) SetSliderDialogInterval(5.00000) endEvent event OnSliderAcceptST(float value) hc_HealthPercentage[iCurrentHandySpell] = value SetSliderOptionValueST(value, "%{0}", false, "iMenuID_HealthPercentage") CustomPageRefresh() endEvent event OnDefaultST() hc_HealthPercentage[iCurrentHandySpell] = 50.0000 SetSliderOptionValueST(hc_HealthPercentage[iCurrentHandySpell], "%{0}", false, "iMenuID_HealthPercentage") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Threshold of the comparison to auto cast the spell") endEvent endState state iMenuID_MagickaComparison event OnSelectST() SetTextOptionValueST(ChangeMagickaComparison(iCurrentHandySpell), false ,"iMenuID_MagickaComparison") CustomPageRefresh() endEvent event OnDefaultST() SetTextOptionValueST(DefaultMagickaComparison(iCurrentHandySpell), false, "iMenuID_MagickaComparison") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Select the type of comparison, 'less than' or 'greater than'") endEvent endState state iMenuID_MagickaPercentage event OnSliderOpenST() SetSliderDialogStartValue(hc_MagickaPercentage[iCurrentHandySpell]) SetSliderDialogDefaultValue(50.0000) SetSliderDialogRange(0.000000, 100.000) SetSliderDialogInterval(5.00000) endEvent event OnSliderAcceptST(float value) hc_MagickaPercentage[iCurrentHandySpell] = value SetSliderOptionValueST(value, "%{0}", false, "iMenuID_MagickaPercentage") CustomPageRefresh() endEvent event OnDefaultST() hc_MagickaPercentage[iCurrentHandySpell] = 50.0000 SetSliderOptionValueST(hc_MagickaPercentage[iCurrentHandySpell], "%{0}", false, "iMenuID_MagickaPercentage") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Threshold of the comparison to auto cast the spell") endEvent endState state iMenuID_StaminaComparison event OnSelectST() SetTextOptionValueST(ChangeStaminaComparison(iCurrentHandySpell), false, "iMenuID_StaminaComparison") CustomPageRefresh() endEvent event OnDefaultST() SetTextOptionValueST(DefaultStaminaComparison(iCurrentHandySpell), false, "iMenuID_StaminaComparison") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Select the type of comparison, 'less than' or 'greater than'") endEvent endState state iMenuID_StaminaPercentage event OnSliderOpenST() SetSliderDialogStartValue(hc_StaminaPercentage[iCurrentHandySpell]) SetSliderDialogDefaultValue(50.0000) SetSliderDialogRange(0.000000, 100.000) SetSliderDialogInterval(5.00000) endEvent event OnSliderAcceptST(float value) hc_StaminaPercentage[iCurrentHandySpell] = value SetSliderOptionValueST(value, "%{0}", false, "iMenuID_StaminaPercentage") CustomPageRefresh() endEvent event OnDefaultST() hc_StaminaPercentage[iCurrentHandySpell] = 50.0000 SetSliderOptionValueST(hc_StaminaPercentage[iCurrentHandySpell], "%{0}", false, "iMenuID_StaminaPercentage") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Threshold of the comparison to auto cast the spell") endEvent endState state iMenuID_DispelCombatState event OnSelectST() SetTextOptionValueST(ChangeDispelCombatState(iCurrentHandySpell), false, "iMenuID_DispelCombatState") CustomPageRefresh() endEvent event OnDefaultST() SetTextOptionValueST(DefaultDispelCombatState(iCurrentHandySpell), false, "iMenuID_DispelCombatState") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Choose a combat state to auto dispel the spell") endEvent endState state iMenuID_DispelSneakingState event OnSelectST() SetTextOptionValueST(ChangeDispelSneakingState(iCurrentHandySpell), false, "iMenuID_DispelSneakingState") CustomPageRefresh() endEvent event OnDefaultST() SetTextOptionValueST(DefaultDispelSneakingState(iCurrentHandySpell), false, "iMenuID_DispelSneakingState") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Choose a sneaking state to auto dispel the spell") endEvent endState state iMenuID_DispelWeaponSheath event OnSelectST() SetToggleOptionValueST(ChangeDispelWeaponSheathState(iCurrentHandySpell), false, "iMenuID_DispelWeaponSheath") CustomPageRefresh() endEvent event OnDefaultST() SetToggleOptionValueST(DefaultDispelWeaponSheathState(iCurrentHandySpell), false, "iMenuID_DispelWeaponSheath") CustomPageRefresh() endEvent event OnHighlightST() SetInfoText("Auto dispel when you sheath your weapon/spell") endEvent endState state iMenuID_Manager_Move event OnSelectST() PrepareHandyMove() endEvent event OnHighlightST() SetInfoText("After you select this option the right part of the menu will be enabled. After that you can start the move procedure, you can cancel by pressing this option again") endEvent endState state iMenuID_Manager_Delete event OnSelectST() PrepareHandyDelete() endEvent event OnHighlightST() SetInfoText("After you select this option the right part of the menu will be enabled, then choose a spell to delete or press this option again to cancel") endEvent endState state iMenuID_Show_Notifications event OnSelectST() hc_Notifications = !hc_Notifications SetToggleOptionValueST(hc_Notifications, false, "iMenuID_Show_Notifications") endEvent event OnHighlightST() SetInfoText("Disable this option to prevent notification messages for each spell as it is cast.") endEvent endState state iMenuID_Manager_PanicButton event OnSelectST() SetToggleOptionValueST(ChangePanicButton(), false, "iMenuID_Manager_PanicButton") endEvent event OnHighlightST() SetInfoText("Enable this option to prevent your character status detection from Handy Cast") endEvent endState state iMenuID_Manager_Reset event OnSelectST() SetTextOptionValueST(hLoopOptions[1], false, "iMenuID_Manager_Reset") LoopsReset() endEvent event OnHighlightST() SetInfoText("Use it wisely") endEvent endState state HSKeyState event OnKeyMapChangeST(Int keyCode, String conflictControl, String conflictName) myF_OnOptionKeyMapChange(keycode, conflictControl, conflictName) endEvent event OnDefaultST() UnregisterForKey(iHCKeyMap) iHCKeyMap = -1 SetKeyMapOptionValueST(-1) endEvent event OnHighlightST() SetInfoText("Set a hotkey to stop/start Spell Loop") endEvent endState state iMenuID_Manager_HandySpell0 event OnSelectST() myf_spellmovedelete(0) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell1 event OnSelectST() myf_spellmovedelete(1) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell2 event OnSelectST() myf_spellmovedelete(2) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell3 event OnSelectST() myf_spellmovedelete(3) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell4 event OnSelectST() myf_spellmovedelete(4) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell5 event OnSelectST() myf_spellmovedelete(5) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell6 event OnSelectST() myf_spellmovedelete(6) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell7 event OnSelectST() myf_spellmovedelete(7) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell8 event OnSelectST() myf_spellmovedelete(8) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell9 event OnSelectST() myf_spellmovedelete(9) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState state iMenuID_Manager_HandySpell10 event OnSelectST() myf_spellmovedelete(10) endEvent event OnHighlightST() myf_spellhighlight() endEvent endState It runs very fast right now, but any optimizations that you notice would be appreciated, especially on the cast loop. Take care Ishara, and thank you! -IA710 Link to comment Share on other sites More sharing options...
ItsAlways710 Posted February 6, 2022 Author Share Posted February 6, 2022 I hate threads that end with no answer, so I've been plugging away at this. The best solution I could come up with was a referencealias script using the game reload event and the OnSpellLearned event added by Papyrus Script Extender. I did this a number of different ways, and probably re-invented the wheel, so be kind. I'm posting the one that requires SKSE, Papyrus Script Extender, and PapyrusUtil, but I did this using JContainers too, but it wasn't the fastest in my testing (but it's JMap feature was so easy to use, it typically took 50% longer than PapyrusUtil, and was faster than using formlists). Any suggestions are welcome. Event OnSpellLearned(Spell akSpell) String s = akSpell.GetName() ; Make sure that the spell name string is mapped to the correct formid StorageUtil.SetFormValue(none, s, akSpell as Form) ; Clear the final output formlist StorageUtil.FormListClear(none, "HAC_SpForms") ; 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) ; Sort the final output spell name list StorageUtil.StringListSort(none, "HAC_Spells") Int iIndex = 0 ; Build the final output formlist from the map we updated above. While iIndex < StorageUtil.StringListCount(none, "HAC_Spells") StorageUtil.FormListAdd(none, "HAC_SpForms", (StorageUtil.GetFormValue(none, (StorageUtil.StringListGet(none, "HAC_Spells", iIndex))))) iIndex += 1 EndWhile ; Insert the escape menu option into the sorted list. StorageUtil.StringListInsert(none, "HAC_Spells", 0, "Back / Cancel / No Change") EndEvent Function RefreshAllSpells() int iIndex int count = 0 ; Clear the master formid list StorageUtil.FormListClear(none, "HAC_PlSpellForms") ; Fill an array with all spells in the game Spell[] allSpellsInTheGame = PO3_SKSEFunctions.GetAllSpells() iIndex = allSpellsInTheGame.length While iIndex > 0 iIndex -= 1 ; Get the first MagicEffect of the spell MagicEffect meSpellEffect = allSpellsInTheGame[iIndex].GetNthEffectMagicEffect(0) ; If the casting type is anything other than "Constant" then add them to the master ; playable spell formlist If meSpellEffect.GetCastingType() > 0 StorageUtil.FormListAdd(none,"HAC_PlSpellForms", (allSpellsInTheGame[iIndex] as Form), false) EndIf EndWhile ; Clear the final outups StorageUtil.StringlistClear(none, "HAC_Spells") StorageUtil.FormListClear(none, "HAC_SpForms") iIndex = 0 ; Check every playable spell from master list to see if the player has it While iIndex < StorageUtil.FormListCount(none, "HAC_PlSpellForms") spell wSpell = StorageUtil.FormListGet(none,"HAC_PlSpellForms", iIndex) as spell If playerREF.HasSpell(wspell) ; If the player has the spell, get it's name, put it in storageutil as the ; key with a formid value of the spell as a string:formid map, and add the ; spell to the player spells stringlist. String s = wSpell.GetName() StorageUtil.SetFormValue(none, s, wSpell as form) StorageUtil.StringListAdd(none, "HAC_Spells", s, false) EndIf iIndex +=1 EndWhile ; Sort the final output player spell names stringlist. StorageUtil.StringListSort(none, "HAC_Spells") iIndex = 0 ; Build the final output player spell formlist using the sorted string list to ; look up the formid from the map created in the previous loop. While iIndex < StorageUtil.StringListCount(none, "HAC_Spells") StorageUtil.FormListAdd(none, "HAC_SpForms", (StorageUtil.GetFormValue(none, (StorageUtil.StringListGet(none, "HAC_Spells", iIndex))))) iIndex += 1 EndWhile ; Make index 0 of the stringlist a way to back out of the menu with no changes. StorageUtil.StringListInsert(none, "HAC_Spells", 0, "Back / Cancel / No Change") EndFunction It takes about 30 seconds for the big function to run on game reload, but the spell learned event is almost instant. Thank you all! -IA710 Link to comment Share on other sites More sharing options...
Sphered Posted February 6, 2022 Share Posted February 6, 2022 I know a few tricks to get niche things done but ADD is high so if you are stuck on something just clarify A) The point of the mod and B) The exact roadblock that is interfering with a goal With MCM mods its handy to set options with FormIDs as String. If state is interacted with, and its a spell state, you can do GetFormEx of that State as Int as Spell. Stuff like that can cut down massive swarms of script bulkage. Just depends what you are specifically aiming to accomplish Link to comment Share on other sites More sharing options...
Recommended Posts