Commit 2e5be3f2ca71d84537a3bba7f29986553c732ab3

Authored by Chris Davidson
1 parent 90c99f93

Revise and bug fix Defiler talents

... ... @@ -2446,6 +2446,22 @@ newDamageType{
2446 2446 end,
2447 2447 }
2448 2448
  2449 +-- Used by Blood Grasp, heal+temporary max life based on damage
  2450 +newDamageType{
  2451 + name = "sanguine blight", type = "SANGUINE", text_color = "#DARK_GREEN#",
  2452 + projector = function(src, x, y, type, dam, state)
  2453 + state = initState(state)
  2454 + useImplicitCrit(src, state)
  2455 + if _G.type(dam) == "number" then dam = {dam=dam} end
  2456 + local target = game.level.map(x, y, Map.ACTOR) -- Get the target first to make sure we heal even on kill
  2457 + local dealt = DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam.dam, state)
  2458 + if dealt > 0 then
  2459 + src:setEffect(src.EFF_BLOOD_GRASP, 7, {life = dealt * 0.5} )
  2460 + src:heal(dealt * 0.2, src)
  2461 + end
  2462 + return dealt
  2463 + end,
  2464 +}
2449 2465 -- Drain Vim
2450 2466 newDamageType{
2451 2467 name = "vim draining blight", type = "DRAIN_VIM", text_color = "#DARK_GREEN#",
... ...
... ... @@ -29,7 +29,7 @@ newTalent{
29 29 activate = function(self, t)
30 30 game:playSoundNear(self, "talents/slime")
31 31 local ret = {
32   - per = self:addTemporaryValue("combat_critical_power", self:combatTalentSpellDamage(t, 20, 60)),
  32 + per = self:addTemporaryValue("combat_critical_power", self:combatTalentSpellDamage(t, 20, 50)),
33 33 }
34 34 if core.shader.active() then
35 35 local h1x, h1y = self:attachementSpot("head", true) if h1x then self:talentParticles(ret, {type="circle", args={toback=true, shader=true, oversize=0.7, a=225, appear=8, speed=0, img="dark_ritual_aura", base_rot=0, radius=0, x=h1x, y=h1y}}) end
... ... @@ -43,7 +43,7 @@ newTalent{
43 43 info = function(self, t)
44 44 return ([[Increases your spell critical damage multiplier by %d%%.
45 45 The multiplier will increase with your Spellpower.]]):
46   - format(self:combatTalentSpellDamage(t, 20, 60))
  46 + format(self:combatTalentSpellDamage(t, 20, 50))
47 47 end,
48 48 }
49 49
... ... @@ -125,7 +125,7 @@ newTalent{
125 125 cooldown = 12,
126 126 vim = 12,
127 127 range = 10,
128   - getResist = function(self, t) return math.ceil(self:combatTalentScale(t, 8, 35)) end,
  128 + getResist = function(self, t) return math.ceil(self:combatTalentScale(t, 3, 20)) end,
129 129 getPercent = function(self, t) return self:combatTalentSpellDamage(t, 12, 45) end, -- Scaling?
130 130 getDamage = function(self, t) return self:combatTalentSpellDamage(t, 20, 60) end,
131 131 tactical = { ATTACK = {ACID = 2}, DISABLE = 1 },
... ... @@ -158,7 +158,7 @@ newTalent{
158 158 vim = 28,
159 159 cooldown = 24,
160 160 range = 0,
161   - radius = 5,
  161 + radius = 4,
162 162 tactical = { ATTACKAREA = {BLIGHT = 3}, DISABLE = 2 },
163 163 target = function(self, t)
164 164 return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)}
... ... @@ -172,7 +172,6 @@ newTalent{
172 172 local fail = 50*power/(power + 26) -- Limit < 50% chance
173 173 return power, heal_factor, fail
174 174 end,
175   - getPoisonPenetration = function(self, t) return self:combatTalentLimit(t, 100, 15, 75) end,
176 175 getPoison = function(self,t)
177 176 if self:getTalentLevel(t) >= 6 then return 4
178 177 elseif self:getTalentLevel(t) >= 4 then return 3
... ... @@ -189,7 +188,7 @@ newTalent{
189 188 -- Add a lasting map effect
190 189 game.level.map:addEffect(self,
191 190 self.x, self.y, duration,
192   - DamageType.BLIGHT_POISON, {dam=dam, power=power, heal_factor=heal_factor, fail=fail, penetration=t.getPoisonPenetration(self,t), poison=t.getPoison(self,t), apply_power=actor:combatSpellpower()},
  191 + DamageType.BLIGHT_POISON, {dam=dam, power=power, heal_factor=heal_factor, fail=fail, penetration=0, poison=t.getPoison(self,t), apply_power=actor:combatSpellpower()},
193 192 radius,
194 193 5, nil,
195 194 MapEffect.new{
... ... @@ -209,13 +208,13 @@ newTalent{
209 208 info = function(self, t)
210 209 local dam = damDesc(self, DamageType.BLIGHT, t.getDamage(self,t))
211 210 local power, heal_factor, fail = t.getEffects(self, t)
212   - return ([[A furious storm of blighted poison rages around the caster in a radius of %d for %d turns. Each creature hit by the storm takes %0.2f blight damage and is poisoned for %0.2f blight damage over 4 turns. The blight poison is especially virulent, and has a %d%% chance to ignore poison immunity.
  211 + return ([[A furious storm of blighted poison rages around the caster in a radius of %d for %d turns. Each creature hit by the storm takes %0.2f blight damage and is poisoned for %0.2f blight damage over 4 turns.
213 212 At talent level 2 you have a chance to inflict Insidious Blight, which reduces healing by %d%%.
214 213 At talent level 4 you have a chance to inflict Numbing Blight, which reduces all damage dealt by %d%%.
215 214 At talent level 6 you have a chance to inflict Crippling Blight, which causes talents to have a %d%% chance of failure.
216 215 Each possible effect is equally likely.
217 216 The poison damage dealt is capable of a critical strike.
218 217 The damage will increase with your Spellpower.]]):
219   - format(self:getTalentRadius(t), t.getDuration(self, t), dam/4, dam, t.getPoisonPenetration(self,t), heal_factor, power, fail)
  218 + format(self:getTalentRadius(t), t.getDuration(self, t), dam/4, dam, heal_factor, power, fail)
220 219 end,
221 220 }
\ No newline at end of file
... ...
... ... @@ -56,7 +56,6 @@ newTalent{
56 56 end,
57 57 }
58 58
59   --- Finish me pls
60 59 newTalent{
61 60 name = "Blood Grasp",
62 61 type = {"corruption/blood", 2},
... ... @@ -68,33 +67,23 @@ newTalent{
68 67 proj_speed = 20,
69 68 tactical = { ATTACK = {BLIGHT = 1.75}, HEAL = {BLIGHT = 1}}, -- damage to foe heals self
70 69 requires_target = true,
  70 + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 190) end,
71 71 target = function(self, t)
72   - return {type="bolt", range=self:getTalentRange(t), talent=t, display={particle="bolt_blood"}}
  72 + return {type="bolt", range=self:getTalentRange(t), selffire=false, friendlyfire=false, talent=t, display={particle="bolt_blood"}}
73 73 end,
74 74 action = function(self, t)
75 75 local tg = self:getTalentTarget(t)
76 76 local x, y = self:getTarget(tg)
77 77 if not x or not y then return nil end
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 + local damage = self:spellCrit(t.getDamage(self, t))
  79 + self:projectile(tg, x, y, DamageType.SANGUINE, {dam=damage}, {type="blood"})
91 80 game:playSoundNear(self, "talents/slime")
92 81 return true
93 82 end,
94 83 info = function(self, t)
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.
97   - The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.BLIGHT, self:combatTalentSpellDamage(t, 10, 290)))
  84 + return ([[Project a bolt of corrupted blood, doing %0.2f blight damage and healing you for 20%% the damage dealt.
  85 + 50%% of the damage dealt will be gained as maximum life for 7 turns (before the healing).
  86 + The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.BLIGHT, t.getDamage(self, t)))
98 87 end,
99 88 }
100 89
... ... @@ -103,25 +92,44 @@ newTalent{
103 92 type = {"corruption/blood", 3},
104 93 require = corrs_req3,
105 94 points = 5,
106   - cooldown = 12,
  95 + cooldown = 8,
107 96 vim = 30,
108   - tactical = { ATTACKAREA = {BLIGHT = 2}, DISABLE = 1 },
  97 + tactical = { ATTACKAREA = {BLIGHT = 0.5} }, -- Needs a better tactical table, setting to low priority for now so it gets used later in the rotation when diseases are up
109 98 range = 0,
110   - radius = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end,
  99 + radius = function(self, t) return 10 end,
  100 + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 250) end,
  101 + getSlow = function(self, t) return self:combatTalentLimit(t, 100, 20, 70) end,
  102 + getHeal = function(self, t) return self:combatTalentSpellDamage(t, 10, 90) end,
111 103 requires_target = true,
112 104 target = function(self, t)
113   - return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t}
  105 + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, friendlyfire=false, talent=t}
114 106 end,
115 107 action = function(self, t)
116 108 local tg = self:getTalentTarget(t)
117   - self:project(tg, self.x, self.y, DamageType.BLOOD_BOIL, self:spellCrit(self:combatTalentSpellDamage(t, 28, 190)))
  109 + local x, y = self.x, self.y
  110 + local damage = self:spellCrit(t.getDamage(self, t))
  111 + local slow = t.getSlow(self, t) / 100
  112 + local heal = t.getHeal(self, t)
  113 + local amount = 0
  114 + self:project(tg, x, y, function(px, py)
  115 + local target = game.level.map(px, py, Map.ACTOR)
  116 + if not target then return end
  117 + local eff = target:removeEffectsFilter(function(e) return e.subtype.poison or e.subtype.disease or e.subtype.wound end, 1)
  118 + if eff and eff > 0 then
  119 + local dealt = DamageType:get(DamageType.BLIGHT).projector(self, target.x, target.y, DamageType.BLIGHT, damage)
  120 + target:setEffect(target.EFF_SLOW, 5, {src=self, power=slow})
  121 + amount = amount + 1
  122 + end
  123 + end)
  124 + if amount > 0 then self:heal(heal * amount, self) end
118 125 game.level.map:particleEmitter(self.x, self.y, tg.radius, "circle", {oversize=1, a=180, appear=8, limit_life=8, speed=-3, img="blood_circle", radius=tg.radius})
119 126 game:playSoundNear(self, "talents/slime")
120 127 return true
121 128 end,
122 129 info = function(self, t)
123   - return ([[Make the blood of all creatures around you in radius %d boil, doing %0.2f blight damage and slowing them by 20%%.
124   - The damage will increase with your Spellpower.]]):format(self:getTalentRadius(t), damDesc(self, DamageType.BLIGHT, self:combatTalentSpellDamage(t, 28, 190)))
  130 + return ([[Make the impure blood of all creatures around you in radius %d boil.
  131 + Each enemy afflicted by a disease, poison, or wound will have one removed at random dealing %0.2f blight damage, healing you for %d, and slowing them by %d%% for 5 turns.
  132 + The damage will increase with your Spellpower.]]):format(self:getTalentRadius(t), damDesc(self, DamageType.BLIGHT, t.getDamage(self, t)), t.getHeal(self, t), t.getSlow(self, t))
125 133 end,
126 134 }
127 135
... ...
... ... @@ -45,9 +45,8 @@ newTalent{
45 45 if not target then return end
46 46 local effs = #target:effectsFilter({status="detrimental", type="magical"})
47 47 local damage = dam * (1 + t.getBonus(self, t) * effs)
48   - game.log(tostring(damage)..", "..tostring(dam)..", "..tostring(effs))
49 48 DamageType:get(DamageType.PHYSICAL).projector(self, tx, ty, DamageType.PHYSICAL, damage)
50   - end)
  49 + end)
51 50 local _ _, _, _, x, y = self:canProject(tg, x, y)
52 51 game.level.map:particleEmitter(self.x, self.y, tg.range, "bone_spear", {tx=x - self.x, ty=y - self.y})
53 52 game:playSoundNear(self, "talents/arcane")
... ... @@ -126,7 +125,6 @@ newTalent{
126 125 end,
127 126 }
128 127
129   --- Fix breaking Movement
130 128 newTalent{
131 129 name = "Bone Spike",
132 130 type = {"corruption/bone", 3},
... ... @@ -145,13 +143,20 @@ newTalent{
145 143 self.turn_procs.bone_spike = true
146 144 game:onTickEnd(function()
147 145 local tg = self:getTalentTarget(t)
148   - local dam = self:spellCrit(t.getDamage(self, t))
149   -
  146 + local dam = t.getDamage(self, t)
  147 + local did_crit = false
150 148 self:project(tg, self.x, self.y, function(px, py)
151 149 local target = game.level.map(px, py, engine.Map.ACTOR)
152 150 if not target then return end
153 151 local nb = #target:effectsFilter({status="detrimental", type="magical"})
154 152 if nb and nb < 3 then return end
  153 +
  154 + -- Make sure crit is only calculated once, but do it here so we don't trigger a crit if there are no targets
  155 + if did_crit == false then
  156 + dam = self:spellCrit(dam)
  157 + did_crit = true
  158 + end
  159 +
155 160 self:project({type="beam", range=10, selffire=false, friendlyfire=false, talent=t}, target.x, target.y, DamageType.PHYSICAL, dam)
156 161 local _ _, _, _, x, y = self:canProject(tg, x, y)
157 162 game.level.map:particleEmitter(self.x, self.y, 10, "bone_spear", {speed=0.2, tx=target.x - self.x, ty=target.y - self.y})
... ... @@ -159,12 +164,11 @@ newTalent{
159 164 end)
160 165 end,
161 166 info = function(self, t)
162   - return ([[Whenever you use a non-instant 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.
  167 + return ([[Whenever you use a non-instant talent you launch a spear of bone at all enemies afflicted by 3 or more magical detrimental effects dealing %d physical damage to all enemies it passes through.
163 168 The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)) )
164 169 end,
165 170 }
166 171
167   --- Fix on clone bug
168 172 newTalent{
169 173 name = "Bone Shield",
170 174 type = {"corruption/bone", 4},
... ... @@ -175,8 +179,8 @@ newTalent{
175 179 sustain_vim = 50,
176 180 tactical = { DEFEND = 4 },
177 181 direct_hit = true,
178   - getRegen = function(self, t) return self:combatTalentLimit(t, 3, 20, 3.5) end,
179   - getNb = function(self, t) return math.floor(self:combatTalentScale(t, 1, 4.5)) end,
  182 + getRegen = function(self, t) return self:combatTalentLimit(t, 3, 20, 3.3) end,
  183 + getNb = function(self, t) return math.floor(self:combatTalentScale(t, 1, 3.5)) end,
180 184 getThreshold = function(self, t) return math.floor(self:combatSpellpower()) end,
181 185 iconOverlay = function(self, t, p)
182 186 local p = self.sustain_talents[t.id]
... ... @@ -199,6 +203,7 @@ newTalent{
199 203 p.nb = p.nb + 1
200 204 if p.adv_gfx then
201 205 if p.particles[1] and p.particles[1]._shader and p.particles[1]._shader.shad then
  206 + if not p.particles[1].shader then p.particles[1] = self:addParticles(Particles.new("shader_ring_rotating", 1, {toback=true, a=0.5, rotation=0, radius=1.5, img="bone_shield"}, {type="boneshield"})) end
202 207 p.particles[1]._shader.shad:resetClean()
203 208 p.particles[1]._shader:setResetUniform("chargesCount", util.bound(p.nb, 0, 10))
204 209 p.particles[1].shader.chargesCount = util.bound(p.nb, 0, 10)
... ... @@ -217,6 +222,8 @@ newTalent{
217 222 p.nb = p.nb - 1
218 223 if p.adv_gfx then
219 224 if p.particles[1] and p.particles[1]._shader and p.particles[1]._shader.shad then
  225 + -- Clones don't copy this so we need to recreate it sometimes
  226 + if not p.particles[1].shader then p.particles[1] = self:addParticles(Particles.new("shader_ring_rotating", 1, {toback=true, a=0.5, rotation=0, radius=1.5, img="bone_shield"}, {type="boneshield"})) end
220 227 p.particles[1]._shader.shad:resetClean()
221 228 p.particles[1]._shader:setResetUniform("chargesCount", util.bound(p.nb, 0, 10))
222 229 p.particles[1].shader.chargesCount = util.bound(p.nb, 0, 10)
... ... @@ -234,7 +241,6 @@ newTalent{
234 241
235 242 local adv_gfx = core.shader.allow("adv") and true or false
236 243 local ps = {}
237   - game.log("Bone Shield clone activate "..tostring(util.bound(nb, 0, 10)) or ".shader value is nil")
238 244 if adv_gfx then
239 245 ps[1] = self:addParticles(Particles.new("shader_ring_rotating", 1, {toback=true, a=0.5, rotation=0, radius=1.5, img="bone_shield"}, {type="boneshield"}))
240 246 ps[1]._shader.shad:resetClean()
... ...
... ... @@ -103,7 +103,7 @@ newTalent{
103 103 return true
104 104 end,
105 105 info = function(self, t)
106   - return ([[Curses your target, stopping any natural healing and dealing %0.2f darkness damage over 10 turns.
  106 + return ([[Curses your target, preventing normal life regeneration and dealing %0.2f darkness damage over 10 turns.
107 107 The damage will increase with your Spellpower.]]):format(damDesc(self, DamageType.DARKNESS, self:combatTalentSpellDamage(t, 10, 70)*10))
108 108 end,
109 109 }
... ...
... ... @@ -92,7 +92,7 @@ newTalent{
92 92 Virulent Disease will always try to apply a disease the target does not currently have, and also one that will have the most debilitating effect for the target.
93 93 This disease will try to prioritize being applied to an enemy with a high disease count near the target.
94 94 The effect will increase with your Spellpower.]]):
95   - format(damDesc(self, DamageType.BLIGHT, 7 + self:combatTalentSpellDamage(t, 6, 65)), self:combatTalentSpellDamage(t, 5, 35))
  95 + format(damDesc(self, DamageType.BLIGHT, 7 + self:combatTalentSpellDamage(t, 6, 45)), self:combatTalentSpellDamage(t, 5, 35))
96 96 end,
97 97 }
98 98
... ... @@ -152,7 +152,7 @@ newTalent{
152 152 end)
153 153
154 154 if diseases and #diseases > 0 then -- burst in a radius
155   - self:project({type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t)}, x, y, function(px, py)
  155 + self:project({type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t), talent=t}, x, y, function(px, py)
156 156 local target = game.level.map(px, py, engine.Map.ACTOR)
157 157 if not target or target == source or target == self or (self:reactionToward(target) >= 0) then return end
158 158
... ...
... ... @@ -30,7 +30,7 @@ newTalent{
30 30 VIM = {BLIGHT = function(self, t, target) return 2*target:getRankVimAdjust()^.5 end}
31 31 },
32 32 requires_target = true,
33   - range = function(self, t) return math.floor(self:combatTalentScale(t, 5, 9)) end,
  33 + range = function(self, t) return math.min(10, math.floor(self:combatTalentScale(t, 6, 10))) end,
34 34 action = function(self, t)
35 35 local tg = {type="hit", range=self:getTalentRange(t), talent=t, display={particle="bolt_slime"}}
36 36 local x, y = self:getTarget(tg)
... ... @@ -47,6 +47,7 @@ newTalent{
47 47 end,
48 48 }
49 49
  50 +-- Sustain?
50 51 newTalent{
51 52 name = "Bloodcasting",
52 53 type = {"corruption/sanguisuge", 2},
... ...
... ... @@ -104,6 +104,9 @@ newTalent{
104 104 end,
105 105 }
106 106
  107 +--friendlyfire
  108 +-- Note: Normally you would use die_at instead of temporary maximum life for an effect like Sanguine Infusion and not have to special case it like this
  109 +-- Unfortunately, part of the goal of SI is to encourage healing and synergize well with Bone Shield, so were stuck with ugliness
107 110 newTalent{
108 111 name = "Blood Vengeance",
109 112 type = {"corruption/torment", 4},
... ... @@ -115,25 +118,39 @@ newTalent{
115 118 sustain_vim = 22,
116 119 tactical = { BUFF = 2 },
117 120 activate = function(self, t)
118   - local l, c = t.getPower(self, t)
  121 + local ret = {}
119 122 game:playSoundNear(self, "talents/flame")
120   - local ret = {
121   - l = self:addTemporaryValue("reduce_spell_cooldown_on_hit", l),
122   - c = self:addTemporaryValue("reduce_spell_cooldown_on_hit_chance", c),
123   - }
124 123 if core.shader.active(4) then
125 124 self:effectParticles(ret, {type="shader_ring_rotating", args={rotation=0, radius=1.1, img="blood_vengeance_lightningshield"}, shader={type="lightningshield"}})
126 125 end
127 126 return ret
128 127 end,
129 128 deactivate = function(self, t, p)
130   - self:removeTemporaryValue("reduce_spell_cooldown_on_hit", p.l)
131   - self:removeTemporaryValue("reduce_spell_cooldown_on_hit_chance", p.c)
132 129 return true
133 130 end,
  131 + callbackPriorities={callbackOnHit = -1}, -- Before Bone Shield but after Rot
  132 + callbackOnHit = function(self, t, cb)
  133 + local eff = self:hasEffect(self.EFF_BLOOD_GRASP)
  134 + local life = self.max_life + (eff and eff.life or 0)
  135 + local l, c = t.getPower(self, t)
  136 + if cb.value >= self.max_life * l / 100 then
  137 +
  138 + local alt = {}
  139 + for tid, cd in pairs(self.talents_cd) do
  140 + if rng.percent(c) then alt[tid] = true end
  141 + end
  142 + for tid, cd in pairs(alt) do
  143 + self:alterTalentCoolingdown(tid, -1)
  144 + end
  145 + game.logSeen(self, "#RED#The powerful blow energizes %s reducing their cooldowns!#LAST#", self.name)
  146 + end
  147 + return cb.value
  148 +
  149 + end,
134 150 info = function(self, t)
135 151 local l, c = t.getPower(self, t)
136 152 return ([[When you are dealt a blow that reduces your life by at least %d%%, you have a %d%% chance to reduce the remaining cooldown of all your talents by 1.
  153 + Temporary life from Sanguine Infusion will not count against the damage threshold.
137 154 The chance will increase with your Spellpower.]]):
138 155 format(l, c)
139 156 end,
... ...
... ... @@ -75,11 +75,17 @@ newTalent{
75 75 if type == DamageType.FIRE then
76 76 src:setEffect(src.EFF_BURNING, 5, {src=self, apply_power=self:combatSpellpower(), power=t.getFire(self, t) / 5})
77 77 elseif type == DamageType.COLD then
78   - src:setEffect(src.EFF_FROZEN, 3, {apply_power=self:combatSpellpower(), hp=t.getCold(self, t)})
  78 + if src:canBe("stun") then
  79 + src:setEffect(src.EFF_FROZEN, 3, {apply_power=self:combatSpellpower(), hp=t.getCold(self, t)})
  80 + end
79 81 elseif type == DamageType.ACID then
80   - src:setEffect(src.EFF_BLINDED, t.getAcid(self, t), {apply_power=self:combatSpellpower()})
  82 + if src:canBe("blind") then
  83 + src:setEffect(src.EFF_BLINDED, t.getAcid(self, t), {apply_power=self:combatSpellpower()})
  84 + end
81 85 elseif type == DamageType.LIGHTNING then
82   - src:setEffect(src.EFF_DAZED, t.getLightning(self, t), {apply_power=self:combatSpellpower()})
  86 + if src:canBe("stun") then
  87 + src:setEffect(src.EFF_DAZED, t.getLightning(self, t), {apply_power=self:combatSpellpower()})
  88 + end
83 89 elseif type == DamageType.NATURE then
84 90 src:setEffect(src.EFF_SLOW, 4, {apply_power=self:combatSpellpower(), power=t.getNature(self, t) / 100})
85 91 end
... ...
... ... @@ -2209,15 +2209,24 @@ newEffect{
2209 2209 newEffect{
2210 2210 name = "BLOOD_GRASP", image = "talents/blood_grasp.png",
2211 2211 desc = "Sanguine Infusion",
2212   - long_desc = function(self, eff) return ("Max life increased by %d."):format(eff.life) end,
  2212 + long_desc = function(self, eff) return ("Maximum life increased by %d."):format(eff.life) end,
2213 2213 type = "magical",
2214 2214 subtype = {corruption=true},
2215 2215 status = "beneficial",
2216 2216 parameters = {life = 0},
  2217 + on_merge = function(self, old_eff, new_eff)
  2218 + self:removeTemporaryValue("max_life", old_eff.tmpid)
  2219 +
  2220 + old_eff.life = math.max(old_eff.life, new_eff.life)
  2221 + old_eff.tmpid = self:addTemporaryValue("max_life", old_eff.life)
  2222 + old_eff.dur = new_eff.dur
  2223 + return old_eff
  2224 + end,
2217 2225 activate = function(self, eff)
2218   - self:effectTemporaryValue(eff, "max_life", eff.life)
  2226 + eff.tmpid = self:addTemporaryValue("max_life", eff.life)
2219 2227 end,
2220 2228 deactivate = function(self, eff)
  2229 + self:removeTemporaryValue("max_life", eff.tmpid)
2221 2230 end,
2222 2231 }
2223 2232
... ...