Commit bb74a0810a5fc27e8acb4c15e261e2f9c53b8556

Authored by Chris Davidson
1 parent 48821c46

Revise Defiler talents

... ... @@ -2390,14 +2390,6 @@ function _M:onTakeHit(value, src, death_note)
2390 2390 end
2391 2391 end
2392 2392
2393   - if value > 0 and self:isTalentActive(self.T_BONE_SHIELD) then
2394   - local t = self:getTalentFromId(self.T_BONE_SHIELD)
2395   - if t.absorb(self, t, self:isTalentActive(self.T_BONE_SHIELD)) then
2396   - game:delayedLogDamage(src, self, 0, ("#SLATE#(%d to bones)#LAST#"):format(value), false)
2397   - value = 0
2398   - end
2399   - end
2400   -
2401 2393 if value <=0 then return 0 end
2402 2394 if self.knowTalent and (self:knowTalent(self.T_SEETHE) or self:knowTalent(self.T_GRIM_RESOLVE)) then
2403 2395 if not self:hasEffect(self.EFF_CURSED_FORM) then
... ...
... ... @@ -61,7 +61,7 @@ newTalent{
61 61 target = function(self, t)
62 62 return {type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t), talent=t}
63 63 end,
64   - getRemoveCount = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5, "log")) end,
  64 + getRemoveCount = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5, "log")) end, -- Oh for the love of god no, fix me
65 65 action = function(self, t)
66 66 local tg = self:getTalentTarget(t)
67 67 local x, y = self:getTarget(tg)
... ... @@ -111,7 +111,7 @@ newTalent{
111 111 return true
112 112 end,
113 113 info = function(self, t)
114   - return ([[Project a corrupted blast of power that deals %0.2f blight damage and removes up to %d magical or physical effect(s) from any creatures caught in the radius 3 ball.
  114 + return ([[Project a corrupted blast of power that deals %0.2f blight damage and removes up to %d magical or physical sustains or effect(s) from any creatures caught in the radius 3 ball.
115 115 For each effect, the creature has a chance to resist based on its spell save.
116 116 The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.BLIGHT, self:combatTalentSpellDamage(t, 28, 120)), t.getRemoveCount(self, t))
117 117 end,
... ...
... ... @@ -56,6 +56,7 @@ newTalent{
56 56 end,
57 57 }
58 58
  59 +-- Finish me pls
59 60 newTalent{
60 61 name = "Blood Grasp",
61 62 type = {"corruption/blood", 2},
... ... @@ -74,12 +75,25 @@ newTalent{
74 75 local tg = self:getTalentTarget(t)
75 76 local x, y = self:getTarget(tg)
76 77 if not x or not y then return nil end
77   - self:projectile(tg, x, y, DamageType.DRAINLIFE, {dam=self:spellCrit(self:combatTalentSpellDamage(t, 10, 290)), healfactor=0.5}, {type="blood"})
  78 + local dt = function(px, py)
  79 + local target = game.level.map(px, py, engine.Map.ACTOR)
  80 + if not target then return end
  81 +
  82 + local damage = DamageType:get(DamageType.BLIGHT).projector(self, target.x, target.y, DamageType.BLIGHT, self:combatTalentSpellDamage(t, 10, 190))
  83 + local heal = damage / 2
  84 + self:setEffect(self.EFF_BLOOD_GRASP, 5, {life = heal} )
  85 + self:heal(heal, self)
  86 + --local _ _, _, _, x, y = self:canProject(tg, x, y)
  87 + --{dam=self:spellCrit(self:combatTalentSpellDamage(t, 10, 290)), healfactor=0.5}
  88 + -- game.level.map:particleEmitter(self.x, self.y, 10, "bone_spear", {tx=target.x - self.x, ty=target.y - self.y})
  89 + end
  90 + self:projectile(tg, x, y, dt, nil, {type="blood"})
78 91 game:playSoundNear(self, "talents/slime")
79 92 return true
80 93 end,
81 94 info = function(self, t)
82   - return ([[Project a bolt of corrupted blood, doing %0.2f blight damage and healing you for half the damage done.
  95 + return ([[Project a bolt of corrupted blood, doing %0.2f blight damage and healing you for half the damage dealt.
  96 + Half the damage dealt will be gained as maximum life for 5 turns.
83 97 The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.BLIGHT, self:combatTalentSpellDamage(t, 10, 290)))
84 98 end,
85 99 }
... ...
... ... @@ -23,13 +23,14 @@ newTalent{
23 23 require = corrs_req1,
24 24 points = 5,
25 25 vim = 13,
26   - cooldown = 4,
  26 + cooldown = 8,
27 27 range = 10,
28 28 random_ego = "attack",
29 29 tactical = { ATTACK = {PHYSICAL = 2} },
30 30 direct_hit = true,
31 31 requires_target = true,
32   - getDamage = function(self, t) return self:combatTalentSpellDamage(t, 20, 200) end,
  32 + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 20, 250) end,
  33 + getBonus = function(self, t) return 0.3 end,
33 34 target = function(self, t)
34 35 return {type="beam", range=self:getTalentRange(t), talent=t}
35 36 end,
... ... @@ -37,18 +38,29 @@ newTalent{
37 38 local tg = self:getTalentTarget(t)
38 39 local x, y = self:getTarget(tg)
39 40 if not x or not y then return nil end
40   - self:project(tg, x, y, DamageType.PHYSICALBLEED, self:spellCrit(t.getDamage(self, t)))
  41 +
  42 + local dam = self:spellCrit(t.getDamage(self, t))
  43 +
  44 + self:project(tg, x, y, function(tx, ty)
  45 + local target = game.level.map(tx, ty, Map.ACTOR)
  46 + if not target then return end
  47 + local damage = dam * (1 + t.getBonus(self, t) * #self:effectsFilter({status="detrimental", type="magical"}, 10))
  48 +
  49 + DamageType:get(DamageType.PHYSICAL).projector(self, tx, ty, DamageType.PHYSICAL, damage)
  50 + end, dam)
41 51 local _ _, _, _, x, y = self:canProject(tg, x, y)
42 52 game.level.map:particleEmitter(self.x, self.y, tg.range, "bone_spear", {tx=x - self.x, ty=y - self.y})
43 53 game:playSoundNear(self, "talents/arcane")
  54 +
44 55 return true
45 56 end,
46 57 info = function(self, t)
47   - return ([[Conjures up a spear of bones, doing %0.2f physical damage to all targets in line, and inflicting bleeding for another %0.2f damage over 5 turns.
48   - The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)), damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)/2))
  58 + return ([[Conjures up a spear of bones, doing %0.2f physical damage to all targets in a line. Each target takes an additional %d%% damage for each magical debuff they are afflicted with.
  59 + The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)), damDesc(self, DamageType.PHYSICAL, t.getBonus(self, t)*100))
49 60 end,
50 61 }
51 62
  63 +-- Finish me pls
52 64 newTalent{
53 65 name = "Bone Grab",
54 66 type = {"corruption/bone", 2},
... ... @@ -74,7 +86,7 @@ newTalent{
74 86
75 87 target:pull(self.x, self.y, tg.range)
76 88
77   - DamageType:get(DamageType.PHYSICALBLEED).projector(self, target.x, target.y, DamageType.PHYSICALBLEED, dam)
  89 + DamageType:get(DamageType.PHYSICAL).projector(self, target.x, target.y, DamageType.PHYSICAL, dam)
78 90 if target:canBe("pin") then
79 91 target:setEffect(target.EFF_BONE_GRAB, t.getDuration(self, t), {apply_power=self:combatSpellpower()})
80 92 else
... ... @@ -86,37 +98,46 @@ newTalent{
86 98 return true
87 99 end,
88 100 info = function(self, t)
89   - return ([[Grab a target and teleport it to your side, pinning it there with a bone rising from the ground for %d turns.
90   - The bone will also deal %0.2f physical damage, inflicting bleeding for another %0.2f damage over 5 turns.
  101 + return ([[Grab a target and teleport it to your side or if adjacent to a random location away from you, pinning it there with a bone rising from the ground for %d turns.
  102 + The bone will also deal %0.2f physical damage.
91 103 The damage will increase with your Spellpower.]]):
92   - format(t.getDuration(self, t), damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)), damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)/2))
  104 + format(t.getDuration(self, t), damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)))
93 105 end,
94 106 }
95 107
96 108 newTalent{
97   - name = "Bone Nova",
  109 + name = "Bone Spike",
98 110 type = {"corruption/bone", 3},
99 111 require = corrs_req3,
  112 + image = "talents/bone_nova.png",
100 113 points = 5,
101   - vim = 25,
102   - cooldown = 12,
103   - tactical = { ATTACKAREA = {PHYSICAL = 2} },
104   - random_ego = "attack",
105   - radius = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5)) end,
106   - getDamage = function(self, t) return self:combatTalentSpellDamage(t, 8, 180) end,
  114 + mode = "passive",
  115 + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 20, 90) end,
  116 + radius = 10,
107 117 target = function(self, t)
108   - return {type="ball", radius=self:getTalentRadius(t), selffire=false, talent=t}
  118 + return {type="ball", radius=self:getTalentRadius(t), selffire=false, friendlyfire=false, talent=t}
109 119 end,
110   - action = function(self, t)
111   - local tg = self:getTalentTarget(t)
112   - self:project(tg, self.x, self.y, DamageType.PHYSICALBLEED, self:spellCrit(t.getDamage(self, t)))
113   - game.level.map:particleEmitter(self.x, self.y, tg.radius, "circle", {oversize=1.1, a=255, limit_life=8, grow=true, speed=0, img="bone_nova", radius=self:getTalentRadius(t)})
114   - game:playSoundNear(self, "talents/arcane")
115   - return true
  120 + callbackOnTalentPost = function(self, t, ab, ret, silent)
  121 + if self.turn_procs.bone_spike then return end
  122 + self.turn_procs.bone_spike = true
  123 + game:onTickEnd(function()
  124 + local tg = self:getTalentTarget(t)
  125 + local dam = self:spellCrit(t.getDamage(self, t))
  126 +
  127 + self:project(tg, self.x, self.y, function(px, py)
  128 + local target = game.level.map(px, py, engine.Map.ACTOR)
  129 + if not target then return end
  130 + local nb = #self:effectsFilter({status="detrimental", type="magical"})
  131 + if nb and nb < 3 then return end
  132 + self:project({type="beam", range=10, selffire=false, friendlyfire=false, talent=t}, target.x, target.y, DamageType.PHYSICAL, dam)
  133 + local _ _, _, _, x, y = self:canProject(tg, x, y)
  134 + game.level.map:particleEmitter(self.x, self.y, 10, "bone_spear", {tx=target.x - self.x, ty=target.y - self.y})
  135 + end)
  136 + end)
116 137 end,
117 138 info = function(self, t)
118   - return ([[Fire bone spears in all directions, hitting all foes within radius %d for %0.2f physical damage, and inflicting bleeding for another %0.2f damage over 5 turns.
119   - The damage will increase with your Spellpower.]]):format(self:getTalentRadius(t), damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)), damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)/2))
  139 + return ([[At the end of any turn you used a talent you launch a spear of bone at all enemies afflicted by 3 or more magical detrimental effects dealing %d to all enemies it passes through.
  140 + The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)) )
120 141 end,
121 142 }
122 143
... ... @@ -126,11 +147,12 @@ newTalent{
126 147 points = 5,
127 148 mode = "sustained", no_sustain_autoreset = true,
128 149 require = corrs_req4,
129   - cooldown = 30,
  150 + cooldown = 15,
130 151 sustain_vim = 50,
131 152 tactical = { DEFEND = 4 },
132 153 direct_hit = true,
133 154 getNb = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5)) end,
  155 + getThreshold = function(self, t) return math.floor(self:combatStatScale(self:combatSpellpower(), 10, 120)) end,
134 156 getRegen = function(self, t) return math.max(math.floor(30 / t.getNb(self, t)), 3) end,
135 157 iconOverlay = function(self, t, p)
136 158 local p = self.sustain_talents[t.id]
... ... @@ -146,7 +168,7 @@ newTalent{
146 168 local p = self.sustain_talents[t.id]
147 169 p.next_regen = (p.next_regen or 1) - 1
148 170 if p.next_regen <= 0 then
149   - p.next_regen = p.between_regens or 10
  171 + p.next_regen = t.getRegen(self, t) or 10
150 172
151 173 if p.nb < t.getNb(self, t) then
152 174 p.nb = p.nb + 1
... ... @@ -159,13 +181,13 @@ newTalent{
159 181 else
160 182 p.particles[#p.particles+1] = self:addParticles(Particles.new("bone_shield", 1))
161 183 end
162   - game.logSeen(self, "A part of %s's bone shield regenerates.", self.name)
163 184 end
164 185 end
165 186 end,
166   - absorb = function(self, t, p)
  187 + callbackOnHit = function(self, t, cb, src, dt)
  188 + local p = self.sustain_talents[t.id]
167 189 if not p.nb or p.nb <= 0 then return end
168   -
  190 + if not cb.value or cb.value < t.getThreshold(self, t) then return end
169 191 p.nb = p.nb - 1
170 192 if p.adv_gfx then
171 193 if p.particles[1] and p.particles[1]._shader and p.particles[1]._shader.shad then
... ... @@ -177,8 +199,8 @@ newTalent{
177 199 local pid = table.remove(p.particles)
178 200 self:removeParticles(pid)
179 201 end
180   -
181   - game.logPlayer(self, "Your bone shield absorbs the damage!")
  202 + game:delayedLogDamage(src, self, 0, ("#SLATE#(%d to bones)#LAST#"):format(cb.value), false)
  203 + cb.value = 0
182 204 return true
183 205 end,
184 206 activate = function(self, t)
... ... @@ -201,7 +223,6 @@ newTalent{
201 223 particles = ps,
202 224 nb = nb,
203 225 next_regen = t.getRegen(self, t),
204   - between_regens = t.getRegen(self, t),
205 226 }
206 227 end,
207 228 deactivate = function(self, t, p)
... ... @@ -211,7 +232,8 @@ newTalent{
211 232 info = function(self, t)
212 233 return ([[Bone shields start circling around you. They will each fully absorb one attack.
213 234 %d shield(s) will be generated when first activated.
214   - Then every %d turns a new one will be created if not full.]]):
215   - format(t.getNb(self, t), t.getRegen(self, t))
  235 + Then every %d turns a new one will be created if not full.
  236 + This will only trigger on hits over %d damage based on Spellpower.]]):
  237 + format(t.getNb(self, t), t.getRegen(self, t), t.getThreshold(self, t))
216 238 end,
217 239 }
... ...
... ... @@ -35,14 +35,14 @@ newTalent{
35 35 self:project(tg, x, y, function(tx, ty)
36 36 local target = game.level.map(tx, ty, Map.ACTOR)
37 37 if not target then return end
38   - target:setEffect(target.EFF_CURSE_DEFENSELESSNESS, 10, {power=self:combatTalentSpellDamage(t, 30, 60), apply_power=self:combatSpellpower()})
  38 + target:setEffect(target.EFF_CURSE_DEFENSELESSNESS, 5, {power=self:combatTalentSpellDamage(t, 30, 60)})
39 39 game.level.map:particleEmitter(tx, ty, 1, "circle", {base_rot=0, oversize=0.7, a=130, limit_life=8, appear=8, speed=0, img="curse_gfx", radius=0})
40 40 end)
41 41 game:playSoundNear(self, "talents/slime")
42 42 return true
43 43 end,
44 44 info = function(self, t)
45   - return ([[Curses your target, decreasing its Defense and all saves by %d for 10 turns.
  45 + return ([[Curses your target, decreasing its Defense and all saves by %d for 5 turns. This cannot be saved against.
46 46 The effects will improve with your Spellpower.]]):format(self:combatTalentSpellDamage(t, 30, 60))
47 47 end,
48 48 }
... ...
... ... @@ -47,49 +47,7 @@ newTalent{
47 47 end,
48 48 }
49 49
50   ---[[
51   -newTalent{
52   - name = "Blood Sacrifice",
53   - type = {"corruption/sanguisuge", 2},
54   - require = corrs_req2,
55   - points = 5,
56   - vim = 0,
57   - cooldown = 30,
58   - range = 10,
59   - tactical = { VIM = 1 },
60   - action = function(self, t)
61   - local amount = self.life * 0.5
62   - if self.life <= amount + 1 then
63   - game.logPlayer(self, "Doing this would kill you.")
64   - return
65   - end
66   -
67   - local seen = false
68   - -- Check for visible monsters, only see LOS actors, so telepathy wont prevent resting
69   - core.fov.calc_circle(self.x, self.y, game.level.map.w, game.level.map.h, 20, function(_, x, y) return game.level.map:opaque(x, y) end, function(_, x, y)
70   - local actor = game.level.map(x, y, game.level.map.ACTOR)
71   - if actor and self:reactionToward(actor) < 0 and self:canSee(actor) and game.level.map.seens(x, y) then
72   - seen = {x=x,y=y,actor=actor}
73   - end
74   - end, nil)
75   - if not seen then
76   - game.logPlayer(self, "There are no foes in sight.")
77   - return
78   - end
79   -
80   - self:incVim(30 + self:combatTalentSpellDamage(t, 5, 150))
81   - self:takeHit(amount, self)
82   - game:playSoundNear(self, "talents/spell_generic2")
83   - return true
84   - end,
85   - info = function(self, t)
86   - return ([=[Sacrifices 50%% of your current life to restore %d vim.
87   - This only works if there is at least one foe in sight.
88   - The effect will increase with your Magic stat.]=]):
89   - format(30 + self:combatTalentSpellDamage(t, 5, 150))
90   - end,
91   -}
92   -]]
  50 +-- Finish me pls
93 51 newTalent{
94 52 name = "Bloodcasting",
95 53 type = {"corruption/sanguisuge", 2},
... ...
... ... @@ -28,7 +28,7 @@ newTalent{
28 28 if self.turn_procs.blood_splash_on_crit then return end
29 29 self.turn_procs.blood_splash_on_crit = true
30 30
31   - self:heal(t.heal(self, t), self)
  31 + self:heal(self:spellCrit(t.heal(self, t)), self)
32 32 if core.shader.active(4) then
33 33 self:addParticles(Particles.new("shader_shield_temp", 1, {toback=true , size_factor=1.5, y=-0.3, img="healgreen", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=2.0, circleDescendSpeed=3.5}))
34 34 self:addParticles(Particles.new("shader_shield_temp", 1, {toback=false, size_factor=1.5, y=-0.3, img="healgreen", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=1.0, circleDescendSpeed=3.5}))
... ... @@ -38,7 +38,7 @@ newTalent{
38 38 if self.turn_procs.blood_splash_on_kill then return end
39 39 self.turn_procs.blood_splash_on_kill = true
40 40
41   - self:heal(t.heal(self, t), self)
  41 + self:heal(self:spellCrit(t.heal(self, t)), self)
42 42 if core.shader.active(4) then
43 43 self:addParticles(Particles.new("shader_shield_temp", 1, {toback=true , size_factor=1.5, y=-0.3, img="healgreen", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=2.0, circleDescendSpeed=3.5}))
44 44 self:addParticles(Particles.new("shader_shield_temp", 1, {toback=false, size_factor=1.5, y=-0.3, img="healgreen", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=1.0, circleDescendSpeed=3.5}))
... ... @@ -160,7 +160,7 @@ newTalent{
160 160 vim = 18,
161 161 direct_hit = true,
162 162 requires_target = true,
163   - range = 1,
  163 + range = 4,
164 164 target = function(self, t) return {type="hit", range=self:getTalentRange(t), talent=t} end,
165 165 getNb = function(self, t) return math.floor(self:combatTalentScale(t, 2, 4, "log")) end,
166 166 getDam = function(self, t) return self:combatTalentLimit(t, 2, 10, 5) end, --Limit < 10% life/effect
... ...
... ... @@ -3422,4 +3422,31 @@ newTalent{
3422 3422 The damage improves with your Physical Power.]]):
3423 3423 format(damDesc(self, DamageType.PHYSICAL, (damage)))
3424 3424 end,
3425   -}
\ No newline at end of file
  3425 +}
  3426 +
  3427 +newTalent{
  3428 + name = "Bone Nova",
  3429 + type = {"corruption/other", 1},
  3430 + require = corrs_req3,
  3431 + points = 5,
  3432 + vim = 25,
  3433 + cooldown = 12,
  3434 + tactical = { ATTACKAREA = {PHYSICAL = 2} },
  3435 + random_ego = "attack",
  3436 + radius = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5)) end,
  3437 + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 8, 180) end,
  3438 + target = function(self, t)
  3439 + return {type="ball", radius=self:getTalentRadius(t), selffire=false, talent=t}
  3440 + end,
  3441 + action = function(self, t)
  3442 + local tg = self:getTalentTarget(t)
  3443 + self:project(tg, self.x, self.y, DamageType.PHYSICALBLEED, self:spellCrit(t.getDamage(self, t)))
  3444 + game.level.map:particleEmitter(self.x, self.y, tg.radius, "circle", {oversize=1.1, a=255, limit_life=8, grow=true, speed=0, img="bone_nova", radius=self:getTalentRadius(t)})
  3445 + game:playSoundNear(self, "talents/arcane")
  3446 + return true
  3447 + end,
  3448 + info = function(self, t)
  3449 + return ([[Fire bone spears in all directions, hitting all foes within radius %d for %0.2f physical damage, and inflicting bleeding for another %0.2f damage over 5 turns.
  3450 + The damage will increase with your Spellpower.]]):format(self:getTalentRadius(t), damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)), damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)/2))
  3451 + end,
  3452 +}
... ...
... ... @@ -2187,6 +2187,21 @@ newEffect{
2187 2187 }
2188 2188
2189 2189 newEffect{
  2190 + name = "BLOOD_GRASP", image = "talents/blood_grasp.png",
  2191 + desc = "Sanguine Infusion",
  2192 + long_desc = function(self, eff) return ("Max life increased by %d."):format(eff.life) end,
  2193 + type = "magical",
  2194 + subtype = {corruption=true},
  2195 + status = "beneficial",
  2196 + parameters = {life = 0},
  2197 + activate = function(self, eff)
  2198 + self:effectTemporaryValue(eff, "max_life", eff.life)
  2199 + end,
  2200 + deactivate = function(self, eff)
  2201 + end,
  2202 +}
  2203 +
  2204 +newEffect{
2190 2205 name = "ARCANE_SUPREMACY", image = "talents/arcane_supremacy.png",
2191 2206 desc = "Arcane Supremacy",
2192 2207 long_desc = function(self, eff) return ("The target's spellpower and spell save has been increased by %d"): format(eff.power) end,
... ...