local combat = Combat() combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) combat:setParameter(COMBAT_PARAM_EFFECT, 0) -- Efeito visual do ataque -- ? Configuração da animação local FRAME_DURATION = 100 -- Tempo entre cada frame da animação local ANIMATION_FRAMES = { 51, 53} -- IDs da animação -- ? Configuração do efeito visual com efeito e deslocamento diferente para cada direção local EFFECT_BY_DIRECTION = { [NORTH] = { effectId = 120, offset = {x = 0, y = 0} }, -- Efeito para o Norte [EAST] = { effectId = 118, offset = {x = 1, y = 1} }, -- Efeito para o Leste [SOUTH] = { effectId = 112, offset = {x = 1, y = 1} }, -- Efeito para o Sul [WEST] = { effectId = 119, offset = {x = 0, y = 0} } -- Efeito para o Oeste } -- ? Configuração da storage usada como recurso local STORAGE_KEY = _SYSTEM.INVENTARIO[04].UID_10 -- Storage usada como custo local STORAGE_COST = 1 -- Quantidade a ser consumida -- ? Função para virar na direção do alvo local function faceTarget(creature) local target = creature:getTarget() if target then local creaturePos = creature:getPosition() local targetPos = target:getPosition() if targetPos.x < creaturePos.x then creature:setDirection(WEST) elseif targetPos.x > creaturePos.x then creature:setDirection(EAST) elseif targetPos.y < creaturePos.y then creature:setDirection(NORTH) elseif targetPos.y > creaturePos.y then creature:setDirection(SOUTH) end end end -- ? Cálculo do dano function onGetFormulaValues(player, level, maglevel) local min = -((level / 5) + (maglevel * 1.4) + 8) local max = -((level / 5) + (maglevel * 2.2) + 14) return min, max end combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") -- ? Função para mudar a outfit durante a animação e restaurar a original local function changeOutfit(cid, originalOutfit, currentFrame) local creature = Creature(cid) if not creature or not creature:isPlayer() then return end if currentFrame <= #ANIMATION_FRAMES then local newOutfit = { lookType = ANIMATION_FRAMES[currentFrame], lookHead = originalOutfit.lookHead, lookBody = originalOutfit.lookBody, lookLegs = originalOutfit.lookLegs, lookFeet = originalOutfit.lookFeet, lookAddons = originalOutfit.lookAddons, lookMount = originalOutfit.lookMount } creature:setOutfit(newOutfit) addEvent(changeOutfit, FRAME_DURATION, cid, originalOutfit, currentFrame + 1) else -- ? Restaura a outfit original corretamente ao final da animação addEvent(function() local c = Creature(cid) if c and c:isPlayer() then c:setOutfit(originalOutfit) end end, FRAME_DURATION) end end -- ? Função para lançar o efeito visual específico para cada direção local function castDirectionalEffect(creature) local direction = creature:getDirection() local pos = creature:getPosition() local effectData = EFFECT_BY_DIRECTION[direction] if effectData then local effectPosition = Position(pos.x + effectData.offset.x, pos.y + effectData.offset.y, pos.z) effectPosition:sendMagicEffect(effectData.effectId) end end -- ? Função para executar múltiplos hits local function executeMultipleHits(creature, var, hitsRemaining) if hitsRemaining > 0 then combat:execute(creature, var) addEvent(function(cid, var, hits) local c = Creature(cid) if c then executeMultipleHits(c, var, hits) end end, 150, creature:getId(), var, hitsRemaining - 1) end end -- ? Função principal da magia function onCastSpell(creature, var) if creature:isPlayer() then -- ? Verifica cooldown baseado em storage local cooldownKey = 0102 -- Novo storage para evitar conflito com outras magias if creature:getStorageValue(cooldownKey) > os.time() then local remaining = creature:getStorageValue(cooldownKey) - os.time() creature:sendTextMessage(MESSAGE_STATUS_SMALL, "Aguarde " .. remaining .. " segundos para usar a magia novamente.") return false end -- ? Verifica se há armazenamento suficiente local currentStorage = creature:getStorageValue(STORAGE_KEY) if currentStorage < STORAGE_COST then creature:sendTextMessage(MESSAGE_STATUS_SMALL, "Você não tem energia suficiente para usar essa magia.") return false end -- ? Reduz a storage ao usar a magia creature:setStorageValue(STORAGE_KEY, currentStorage - STORAGE_COST) creature:sendCancelMessage("@LoadAmmo " .. creature:getStorageValue(STORAGE_KEY)) -- ? Define cooldown de 2 segundos para essa magia creature:setStorageValue(cooldownKey, os.time() + 2) -- ? Se houver um alvo, vira na direção dele faceTarget(creature) -- ? Lança o efeito visual na direção do conjurador castDirectionalEffect(creature) -- ? Salva a outfit original e inicia a animação local originalOutfit = creature:getOutfit() changeOutfit(creature:getId(), originalOutfit, 1) -- ? Aplica dano apenas 1 vez (antes executava múltiplos hits) executeMultipleHits(creature, var, 1) playSound(creature, "rat_attack.ogg") return false else return combat:execute(creature, var) end end