LastHeldMagicButton = -1 LastCastMagicID = -1 -- Getters function GetSelectedEquipMagicData() local selectedIndex = GetPointerValue(CHR_INS_BASE.PLAYER_GAME_DATA.EQUIP_GAME_DATA.EQUIP_MAGIC_DATA.SELECTED_MAGIC_SLOT_INDEX) local magicId = GetPointerValue(CHR_INS_BASE.PLAYER_GAME_DATA.EQUIP_GAME_DATA.EQUIP_MAGIC_DATA.MAGIC_SLOT(selectedIndex)) return selectedIndex, magicId end -- Logic function TriggerBeforeSpellcast() CultSpellStack_ApplyLib() end function IsCastingSpell() return LastHeldMagicButton ~= -1 and IsNodeActive("Magic_Upper_SM") == TRUE end function FindSpellEquipIndex(spellId) for i = 0, 13, 1 do local magicId = GetPointerValue(CHR_INS_BASE.PLAYER_GAME_DATA.EQUIP_GAME_DATA.EQUIP_MAGIC_DATA.MAGIC_SLOT(i)) if magicId == spellId then return i elseif magicId == -1 then -- Empty slot, no need to continue searching return -1 end end return -1 end -- Spell Losses local __buffSpells = {} local __isBuffSpellInitialized = false function DisableSpellsOnStatLoss() if not __isBuffSpellInitialized then for _, classSpells in pairs(__allSpells) do for spellId, spellData in pairs(classSpells) do if spellData.SpEffects ~= nil then __buffSpells[spellId] = spellData end end end __isBuffSpellInitialized = true end for spellId, spellData in pairs(__buffSpells) do if not IsJewelGrantedSpell(spellId) then for _, spEffect in pairs(spellData.SpEffects) do if env(GetSpEffectID, spEffect) == TRUE then local reqInt = GetParamValue(PARAM.Magic.REQUIREMENT_INT, spellId) local reqFth = GetParamValue(PARAM.Magic.REQUIREMENT_FTH, spellId) local reqArc = GetParamValue(PARAM.Magic.REQUIREMENT_ARC, spellId) if reqInt > GetPointerValue(CHR_INS_BASE.PLAYER_GAME_DATA.INTELLIGENCE) or reqFth > GetPointerValue(CHR_INS_BASE.PLAYER_GAME_DATA.FAITH) or reqArc > GetPointerValue(CHR_INS_BASE.PLAYER_GAME_DATA.ARCANE) then act(ClearSpEffect, spEffect) Log("Cleared Spell", spellId, "due to stat loss SpEffect", spEffect) end end end end end end function DisableSpellsOnMeleeAbility() if env(GetSpEffectID, 197) == FALSE then return end act(ClearSpEffect, 197) for spellId, spellData in pairs(__buffSpells) do ClearSpEffectArray(spellData.SpEffects) end end local __infiniteSpells = {} local __infiniteSpellsInitialized = false function DisableSpellOnUnequip() if not __infiniteSpellsInitialized then for classIndex = 1, #__allSpells, 1 do for spellId, spellData in pairs(__allSpells[classIndex]) do if spellData.SpEffects ~= nil then for _, spEffect in pairs(spellData.SpEffects) do local spEffectCategory = GetParamValue(PARAM.SpEffectParam.EFFECT_CATEGORY, spEffect) if spEffectCategory == 155 -- 155 = Legendary Enchantment or spEffectCategory == 165 then -- 165 = Perpetual Enchantment __infiniteSpells[spellId] = spellData break end end end end end __infiniteSpellsInitialized = true end for spellId, spellData in pairs(__infiniteSpells) do if not IsJewelGrantedSpell(spellId) then for _, spEffect in pairs(spellData.SpEffects) do if env(GetSpEffectID, spEffect) == TRUE then if FindSpellEquipIndex(spellId) == -1 then act(ClearSpEffect, spEffect) end end end end end end local jewelGrantedSpells = { [7413] = 392400, -- Spirit Link + Jewel of the Ancestors [5080] = 391300, -- Accursed Binding + Jewel of the Prince } function IsJewelGrantedSpell(spellId) local jewelSpEffect = jewelGrantedSpells[spellId] return jewelSpEffect ~= nil and env(GetSpEffectID, jewelSpEffect) == TRUE end -- Specific Spells local __toggleSpells = {} local __toggledSpells = {} local __toggleSpellsInitialized = false local fpCost = PARAM.Magic.FP_CONSUMPTION function ToggleSpellFPCostManager() if not __toggleSpellsInitialized then for classIndex = 1, #__allSpells, 1 do for spellId, spellData in pairs(__allSpells[classIndex]) do if spellData.RestoreFpCost ~= nil then __toggleSpells[spellId] = spellData end end end __toggleSpellsInitialized = true end for spellId, spellData in pairs(__toggleSpells) do local isSpellActive = false for _, spEffect in pairs(spellData.SpEffects) do if env(GetSpEffectID, spEffect) == TRUE then isSpellActive = true break end end -- Set FP cost to 0 if spell is active if isSpellActive then if __toggledSpells[spellId] == nil then __toggledSpells[spellId] = spellData.RestoreFpCost SetParamValue(fpCost, spellId, 0) end -- Restore original FP cost if spell is inactive elseif __toggledSpells[spellId] ~= nil then SetParamValue(fpCost, spellId, __toggledSpells[spellId]) __toggledSpells[spellId] = nil end end end -- Other function CastingToolAshes(wep_hand, weaponID, neededSpEffect, grantedSpEffect) if GetWeaponID(wep_hand) ~= tostring(weaponID) then return end if wep_hand == HAND_RIGHT then neededSpEffect = neededSpEffect + 1 grantedSpEffect = grantedSpEffect + 1 end if env(GetSpEffectID, neededSpEffect) == TRUE then act(AddSpEffect, grantedSpEffect) end end hasLanded = false function IsCasterAsh() if c_SwordArtsID == 109 and c_SwordArtsHand == HAND_RIGHT then act(UpdateMagicIdToActive) return TRUE end return FALSE end function SetMagicParam(originalMagicParam, newMagicParam) if originalMagicParam == nil or newMagicParam == nil or originalMagicParam == newMagicParam then return end local currentSlot, currentMagicId = GetSelectedEquipMagicData() if currentMagicId == originalMagicParam then SetPointerValue(CHR_INS_BASE.PLAYER_GAME_DATA.EQUIP_GAME_DATA.EQUIP_MAGIC_DATA.MAGIC_SLOT(currentSlot), newMagicParam) return end local originalIndex = FindSpellEquipIndex(originalMagicParam) if originalIndex ~= -1 then SetPointerValue(CHR_INS_BASE.PLAYER_GAME_DATA.EQUIP_GAME_DATA.EQUIP_MAGIC_DATA.MAGIC_SLOT(originalIndex), newMagicParam) end end -- Dictionary -- ORDER MATTERS: The index of the spell list in __allSpells must match the ordering of the classes for spellBan logic to work correctly __allSpells = { __glintSpells, __gravitySpells, __dragonkinSpells, __magmaSpells, __stormSpells, __nightSpells, __necroSpells, __frostSpells, __aberrantSpells, __giantsflameSpells, __fundiSpells, __bestialSpells, __cultSpells, __godskinSpells, __frenzySpells, __bloodflameSpells, __rotSpells, __mysticSpells, }