1local combat = Combat()
2combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
3combat:setParameter(COMBAT_PARAM_EFFECT, 0) -- Efeito visual do ataque
4
5-- ⚡ Configuração da animação
6local FRAME_DURATION = 100 -- Tempo entre cada frame da animação
7local ANIMATION_FRAMES = { 56, 61} -- IDs da animação
8
9-- ⚡ Configuração do efeito visual com efeito e deslocamento diferente para cada direção
10local EFFECT_BY_DIRECTION = {
11 [NORTH] = { effectId = 115, offset = {x = 0, y = 1} }, -- Efeito para o Norte
12 [EAST] = { effectId = 114, offset = {x = 1, y = 0} }, -- Efeito para o Leste
13 [SOUTH] = { effectId = 113, offset = {x = 0, y = 1} }, -- Efeito para o Sul
14 [WEST] = { effectId = 116, offset = {x = 0, y = 0} } -- Efeito para o Oeste
15}
16
17-- ⚡ Configuração da storage usada como recurso
18local STORAGE_KEY = _SYSTEM.INVENTARIO[04].UID_10 -- Storage usada como custo
19local STORAGE_COST = 1 -- Quantidade a ser consumida
20
21-- ⚡ Função para virar na direção do alvo
22local function faceTarget(creature)
23 local target = creature:getTarget()
24 if target then
25 local creaturePos = creature:getPosition()
26 local targetPos = target:getPosition()
27
28 if targetPos.x < creaturePos.x then
29 creature:setDirection(WEST)
30 elseif targetPos.x > creaturePos.x then
31 creature:setDirection(EAST)
32 elseif targetPos.y < creaturePos.y then
33 creature:setDirection(NORTH)
34 elseif targetPos.y > creaturePos.y then
35 creature:setDirection(SOUTH)
36 end
37 end
38end
39
40-- ⚡ Cálculo do dano
41function onGetFormulaValues(player, level, maglevel)
42 local min = -((level / 5) + (maglevel * 1.4) + 8)
43 local max = -((level / 5) + (maglevel * 2.2) + 14)
44 return min, max
45end
46combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")
47
48-- ⚡ Função para mudar a outfit durante a animação e restaurar a original
49local function changeOutfit(cid, originalOutfit, currentFrame)
50 local creature = Creature(cid)
51 if not creature or not creature:isPlayer() then return end
52
53 if currentFrame <= #ANIMATION_FRAMES then
54 local newOutfit = {
55 lookType = ANIMATION_FRAMES[currentFrame],
56 lookHead = originalOutfit.lookHead,
57 lookBody = originalOutfit.lookBody,
58 lookLegs = originalOutfit.lookLegs,
59 lookFeet = originalOutfit.lookFeet,
60 lookAddons = originalOutfit.lookAddons,
61 lookMount = originalOutfit.lookMount
62 }
63 creature:setOutfit(newOutfit)
64
65 addEvent(changeOutfit, FRAME_DURATION, cid, originalOutfit, currentFrame + 1)
66 else
67 -- ⚡ Restaura a outfit original corretamente ao final da animação
68 addEvent(function()
69 local c = Creature(cid)
70 if c and c:isPlayer() then
71 c:setOutfit(originalOutfit)
72 end
73 end, FRAME_DURATION)
74 end
75end
76
77-- ⚡ Função para lançar o efeito visual específico para cada direção
78local function castDirectionalEffect(creature)
79 local direction = creature:getDirection()
80 local pos = creature:getPosition()
81 local effectData = EFFECT_BY_DIRECTION[direction]
82 if effectData then
83 local effectPosition = Position(pos.x + effectData.offset.x, pos.y + effectData.offset.y, pos.z)
84 effectPosition:sendMagicEffect(effectData.effectId)
85 end
86end
87
88-- ⚡ Função para executar múltiplos hits
89local function executeMultipleHits(creature, var, hitsRemaining)
90 if hitsRemaining > 0 then
91 combat:execute(creature, var)
92 addEvent(function(cid, var, hits)
93 local c = Creature(cid)
94 if c then
95 executeMultipleHits(c, var, hits)
96 end
97 end, 150, creature:getId(), var, hitsRemaining - 1)
98 end
99end
100
101-- ⚡ Função principal da magia
102function onCastSpell(creature, var)
103 if creature:isPlayer() then
104 -- ⚠ Verifica cooldown baseado em storage
105 local cooldownKey = 0102 -- Novo storage para evitar conflito com outras magias
106 if creature:getStorageValue(cooldownKey) > os.time() then
107 local remaining = creature:getStorageValue(cooldownKey) - os.time()
108 creature:sendTextMessage(MESSAGE_STATUS_SMALL, "Aguarde " .. remaining .. " segundos para usar a magia novamente.")
109 return false
110 end
111
112 -- ⚡ Verifica se há armazenamento suficiente
113 local currentStorage = creature:getStorageValue(STORAGE_KEY)
114 if currentStorage < STORAGE_COST then
115 creature:sendTextMessage(MESSAGE_STATUS_SMALL, "Você não tem energia suficiente para usar essa magia.")
116 return false
117 end
118
119 -- ⚡ Reduz a storage ao usar a magia
120 creature:setStorageValue(STORAGE_KEY, currentStorage - STORAGE_COST)
121 creature:sendCancelMessage("@LoadAmmo " .. creature:getStorageValue(STORAGE_KEY))
122
123 -- ⚡ Define cooldown de 2 segundos para essa magia
124 creature:setStorageValue(cooldownKey, os.time() + 2)
125
126 -- ⚡ Se houver um alvo, vira na direção dele
127 faceTarget(creature)
128
129 -- ⚡ Lança o efeito visual na direção do conjurador
130 castDirectionalEffect(creature)
131
132 -- ⚡ Salva a outfit original e inicia a animação
133 local originalOutfit = creature:getOutfit()
134 changeOutfit(creature:getId(), originalOutfit, 1)
135
136 -- ⚡ Aplica múltiplos hits
137 executeMultipleHits(creature, var, 4)
138 playSound(creature, "rat_attack.ogg")
139 return false
140 else
141 return combat:execute(creature, var)
142 end
143end
144