Skip to content
Snippets Groups Projects
Commit 80a20b3a authored by DarkGod's avatar DarkGod
Browse files

Merge branch 'ProjectorExclusions' into 'master'

Projector exclusions

Kinetic Surge and Telekinetic Throw will not hit the thrown target with their AOE damage.

this adds new parameters to engine.ActorProject:project allowing specific grids and actors to be excluded from the projection.
parents 82256096 7c8bb3d5
No related branches found
No related tags found
No related merge requests found
......@@ -387,6 +387,10 @@ end
-- Cone: hits everything in a cone in the direction<br/>
-- @param t.radius The radius of the ball/cone AoE
-- @param t.cone_angle The angle for the cone AoE (default 55°)
-- @param t.grid_exclude = {[x1][y1]=true,...[x2][y2]=true...} Grids to exclude - for making holes in the AOE
-- @param t.act_exclude = {[uid] = true,...} exclude grids containing actor(s) with the matching uid(s)
-- @param t.selffire = boolean or % chance to project against grids with self
-- @param t.friendlyfire = boolean or % chance to project against grids with friendly Actors (based on Actor:reactionToward(target)>0)
-- @param t.no_restrict Boolean that removes all restrictions in the t.type defined block functions.
-- @param t.stop_block Boolean that stops the target on the first tile that has an entity that blocks move.
-- @param t.range The range the target can be from the origin.
......
......@@ -34,7 +34,7 @@ end
-- @param t a type table describing the attack, passed to engine.Target:getType() for interpretation
-- @param x target coords
-- @param y target coords
-- @param damtype a damage type ID from the DamageType class
-- @param damtype a damage type ID from the DamageType class or a function to be called as damtype(px, py, t, self) on each grid
-- @param dam damage to be done
-- @param particles particles effect configuration, or nil
function _M:project(t, x, y, damtype, dam, particles)
......@@ -178,6 +178,17 @@ function _M:project(t, x, y, damtype, dam, particles)
return
end
--Remove any excluded grids
if typ.grid_exclude then
for px, ys in pairs(typ.grid_exclude) do
if grids[px] then
for py, _ in pairs(ys) do
grids[px][py]=nil
end
end
end
end
self:check("on_project_grids", grids)
-- Now project on each grid, one type
......@@ -188,9 +199,9 @@ function _M:project(t, x, y, damtype, dam, particles)
for py, _ in pairs(ys) do
-- Call the projected method of the target grid if possible
if not game.level.map:checkAllEntities(px, py, "projected", self, t, px, py, damtype, dam, particles) then
-- Check self- and friendly-fire, and if the projection "misses"
-- Check self- and friendly-fire, excluded Actors, and if the projection "misses"
local act = game.level.map(px, py, engine.Map.ACTOR)
if act and act == self and not ((type(typ.selffire) == "number" and rng.percent(typ.selffire)) or (type(typ.selffire) ~= "number" and typ.selffire)) then
if act and (typ.act_exclude and typ.act_exclude[act.uid]) or act == self and not ((type(typ.selffire) == "number" and rng.percent(typ.selffire)) or (type(typ.selffire) ~= "number" and typ.selffire)) then
elseif act and self.reactionToward and (self:reactionToward(act) >= 0) and not ((type(typ.friendlyfire) == "number" and rng.percent(typ.friendlyfire)) or (type(typ.friendlyfire) ~= "number" and typ.friendlyfire)) then
-- Otherwise hit
else
......
......@@ -680,11 +680,8 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
-- Shattering Impact
if hitted and self:attr("shattering_impact") and (not self.shattering_impact_last_turn or self.shattering_impact_last_turn < game.turn) then
local dam = dam * self.shattering_impact
local invuln = target.invulnerable
game.logSeen(target, "The shattering blow creates a shockwave!")
target.invulnerable = 1 -- Target already hit, don't damage it twice
self:project({type="ball", radius=1, selffire=false}, target.x, target.y, DamageType.PHYSICAL, dam)
target.invulnerable = invuln
self:project({type="ball", radius=1, selffire=false, act_exclude={[target.uid]=true}}, target.x, target.y, DamageType.PHYSICAL, dam) -- don't hit target with the AOE
self:incStamina(-8)
self.shattering_impact_last_turn = game.turn
end
......
......@@ -2569,22 +2569,22 @@ newTalent{
if target:canBe("knockback") or rng.percent(t.getKBResistPen(self, t)) then
self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam) --Direct Damage
local tx, ty = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
if tx and ty then
local ox, oy = target.x, target.y
target:move(tx, ty, true)
if config.settings.tome.smooth_move > 0 then
target:resetMoveAnim()
target:setMoveAnim(ox, oy, 8, 5)
local tx, ty = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
if tx and ty then
local ox, oy = target.x, target.y
target:move(tx, ty, true)
if config.settings.tome.smooth_move > 0 then
target:resetMoveAnim()
target:setMoveAnim(ox, oy, 8, 5)
end
end
tg.act_exclude = {[target.uid]=true} -- Don't hit primary target with AOE
self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage
if target:canBe("stun") then
target:setEffect(target.EFF_STUNNED, 4, {apply_power=self:combatMindpower()})
else
game.logSeen(target, "%s resists the stun!", target.name:capitalize())
end
end
self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage
if target:canBe("stun") then
target:setEffect(target.EFF_STUNNED, 4, {apply_power=self:combatMindpower()})
else
game.logSeen(target, "%s resists the stun!", target.name:capitalize())
end
else --If the target resists the knockback, do half damage to it.
target:logCombat(self, "#YELLOW##Source# resists #Target#'s throw!")
self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam/2)
......
......@@ -77,7 +77,7 @@ newTalent{
if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end
local dam = self:mindCrit(t.getDamage(self, t))
if self:reactionToward(target) < 0 then
if target ~= self then
local tg = self:getTalentTarget(t)
local x, y = self:getTarget(tg)
if not x or not y then return nil end
......@@ -94,6 +94,7 @@ newTalent{
target:setMoveAnim(ox, oy, 8, 5)
end
end
tg.act_exclude = {[target.uid]=true} -- Don't hit primary target with AOE
self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage
if target:canBe("stun") then
target:setEffect(target.EFF_STUNNED, math.floor(self:getTalentRange(t) / 2), {apply_power=self:combatMindpower()})
......@@ -109,7 +110,6 @@ newTalent{
local x, y = self:getTarget(tg)
if not x or not y then return nil end
if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end
for i = 1, math.floor(self:getTalentRange(t) / 2) do
self:project(tg, x, y, DamageType.DIG, 1)
end
......@@ -117,7 +117,6 @@ newTalent{
local _ _, x, y = self:canProject(tg, x, y)
game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y})
game:playSoundNear(self, "talents/lightning")
local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, engine.Map.TERRAIN, "block_move", self) end
local l = self:lineFOV(x, y, block_actor)
local lx, ly, is_corner_blocked = l:step()
......@@ -127,10 +126,9 @@ newTalent{
tx, ty = lx, ly
lx, ly, is_corner_blocked = l:step()
end
--self:move(tx, ty, true)
local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true})
if not fx then
if fx then
self:move(fx, fy, true)
end
return true
......
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