Skip to content
Snippets Groups Projects
Commit fb8ddd1c authored by dg's avatar dg
Browse files

on_project/projected callbacks

spell reflect/absorb


git-svn-id: http://svn.net-core.org/repos/t-engine4@322 51575b47-30f0-44d4-a5cc-537603b46e54
parent 5fcb80f2
No related branches found
No related tags found
No related merge requests found
......@@ -65,6 +65,11 @@ end
-- @param dam damage to be done
-- @param particles particles effect configuration, or nil
function _M:project(t, x, y, damtype, dam, particles)
-- Call the on project of the target grid if possible
if not t.bypass and game.level.map:checkAllEntities(x, y, "on_project", self, t, x, y, damtype, dam, particles) then
return
end
if type(dam) == "number" and dam < 0 then return end
local typ = Target:getType(t)
......@@ -116,19 +121,22 @@ function _M:project(t, x, y, damtype, dam, particles)
-- Now project on each grid, one type
for px, ys in pairs(grids) do
for py, _ in pairs(ys) do
-- Friendly fire ?
if px == self.x and py == self.y then
if t.friendlyfire then
-- Call the projected method of the target grid if possible
if not game.level.map:checkAllEntities(x, y, "projected", self, t, x, y, damtype, dam, particles) then
-- Friendly fire ?
if px == self.x and py == self.y then
if t.friendlyfire then
DamageType:get(damtype).projector(self, px, py, damtype, dam)
if particles then
game.level.map:particleEmitter(px, py, 1, particles.type)
end
end
else
DamageType:get(damtype).projector(self, px, py, damtype, dam)
if particles then
game.level.map:particleEmitter(px, py, 1, particles.type)
end
end
else
DamageType:get(damtype).projector(self, px, py, damtype, dam)
if particles then
game.level.map:particleEmitter(px, py, 1, particles.type)
end
end
end
end
......
......@@ -548,3 +548,28 @@ function _M:canBe(what)
if what == "instakill" and self:attr("instakill_immune") then return false end
return true
end
--- Called when we are projected upon
-- This is used to do spell reflection, antimagic, ...
function _M:on_project(tx, ty, who, t, x, y, damtype, dam, particles)
-- Spell reflect
if self:attr("spell_reflect") and ((t.talent and t.talent.reflectable) or t.reflectable) and rng.percent(self:attr("spell_reflect")) then
game.logSeen(self, "%s reflects the spell!", self.name:capitalize())
-- Setup the bypass so it does not eternally reflect between two actors
t.bypass = true
who:project(t, x, y, damtype, dam, particles)
return true
end
-- Spell absorb
if self:attr("spell_absorb") and (t.talent and t.talent.type[1]:find("^spell/")) and rng.percent(self:attr("spell_absorb")) then
game.logSeen(self, "%s ignores the spell!", self.name:capitalize())
return true
end
return false
end
--- Called when we have been projected upon and the DamageType is about to be called
function _M:projected(tx, ty, who, t, x, y, damtype, dam, particles)
return false
end
......@@ -9,8 +9,9 @@ newTalent{
ATTACK = 10,
},
range = 20,
reflectable = true,
action = function(self, t)
local tg = {type="beam", range=self:getTalentRange(t)}
local tg = {type="beam", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.LIGHTNING, rng.avg(1, self:spellCrit(20 + self:combatSpellpower(0.8) * self:getTalentLevel(t)), 3), {type="lightning"})
......@@ -105,7 +106,7 @@ newTalent{
end end
-- Randomly take targets
local tg = {type="hit", range=self:getTalentRange(t)}
local tg = {type="hit", range=self:getTalentRange(t), talent=t}
for i = 1, math.floor(self:getTalentLevel(t)) do
if #tgts <= 0 then break end
local a, id = rng.table(tgts)
......
......@@ -9,8 +9,9 @@ newTalent{
ATTACK = 10,
},
range = 20,
reflectable = true,
action = function(self, t)
local tg = {type="bolt", range=self:getTalentRange(t)}
local tg = {type="bolt", range=self:getTalentRange(t), talent=t}
if self:getTalentLevel(t) >= 3 then tg.type = "beam" end
local x, y = self:getTarget(tg)
if not x or not y then return nil end
......
......@@ -34,8 +34,9 @@ newTalent{
points = 5,
mana = 40,
range = 20,
reflectable = true,
action = function(self, t)
local tg = {type="bolt", range=self:getTalentRange(t), nolock=true}
local tg = {type="bolt", range=self:getTalentRange(t), nolock=true, talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
for i = 1, self:getTalentLevelRaw(t) do
......@@ -59,8 +60,9 @@ newTalent{
ATTACK = 10,
},
range = 20,
reflectable = true,
action = function(self, t)
local tg = {type="bolt", range=self:getTalentRange(t)}
local tg = {type="bolt", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.SPELLKNOCKBACK, self:spellCrit(8 + self:combatSpellpower(0.15) * self:getTalentLevel(t)))
......@@ -79,10 +81,11 @@ newTalent{
cooldown = 12,
mana = 70,
range = 20,
reflectable = true,
action = function(self, t)
local x, y = self.x, self.y
if self:getTalentLevel(t) >= 4 then
local tg = {type="bolt", range=self:getTalentRange(t), nolock=true}
local tg = {type="bolt", range=self:getTalentRange(t), nolock=true, talent=t}
x, y = self:getTarget(tg)
if not x or not y then return nil end
end
......
......@@ -9,8 +9,9 @@ newTalent{
ATTACK = 10,
},
range = 20,
reflectable = true,
action = function(self, t)
local tg = {type="bolt", range=self:getTalentRange(t)}
local tg = {type="bolt", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.FIREBURN, self:spellCrit(25 + self:combatSpellpower(0.8) * self:getTalentLevel(t)), {type="flame"})
......@@ -34,7 +35,7 @@ newTalent{
},
range = 1,
action = function(self, t)
local tg = {type="cone", range=0, radius=3 + self:getTalentLevelRaw(t), friendlyfire=false}
local tg = {type="cone", range=0, radius=3 + self:getTalentLevelRaw(t), friendlyfire=false, talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.FLAMESHOCK, {dur=self:getTalentLevelRaw(t), dam=self:spellCrit(10 + self:combatSpellpower(0.2) * self:getTalentLevel(t))}, {type="flame"})
......@@ -58,7 +59,7 @@ newTalent{
},
range = 15,
action = function(self, t)
local tg = {type="ball", range=self:getTalentRange(t), radius=1 + self:getTalentLevelRaw(t)}
local tg = {type="ball", range=self:getTalentRange(t), radius=1 + self:getTalentLevelRaw(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.FIRE, self:spellCrit(28 + self:combatSpellpower(0.4) * self:getTalentLevel(t)), {type="flame"})
......
......@@ -6,7 +6,7 @@ newTalent{
mana = 5,
cooldown = 14,
action = function(self, t)
local tg = {type="ball", range=0, friendlyfire=false, radius=5 + self:getTalentLevel(t)}
local tg = {type="ball", range=0, friendlyfire=false, radius=5 + self:getTalentLevel(t), talent=t}
self:project(tg, self.x, self.y, DamageType.LIGHT, 1)
if self:getTalentLevel(t) >= 3 then
self:project(tg, self.x, self.y, DamageType.BLIND, 3 + self:getTalentLevel(t))
......
......@@ -9,8 +9,9 @@ newTalent{
DEFENSE = 10,
},
range = 20,
reflectable = true,
action = function(self, t)
local tg = {type="hit", range=self:getTalentRange(t)}
local tg = {type="hit", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.TIME_PRISON, 4 + self:combatSpellpower(0.03) * self:getTalentLevel(t), {type="manathrust"})
......@@ -32,8 +33,9 @@ newTalent{
tactical = {
BUFF = 10,
},
reflectable = true,
action = function(self, t)
local tg = {type="hit", range=self:getTalentRange(t)}
local tg = {type="hit", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.SLOW, util.bound((self:combatSpellpower(0.15) * self:getTalentLevel(t)) / 100, 0.1, 0.4), {type="manathrust"})
......
......@@ -9,8 +9,9 @@ newTalent{
ATTACK = 10,
},
range = 20,
reflectable = true,
action = function(self, t)
local tg = {type="hit", range=self:getTalentRange(t)}
local tg = {type="hit", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.COLD, self:spellCrit(12 + self:combatSpellpower(0.25) * self:getTalentLevel(t)), {type="freeze"})
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment