diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 267f99fead623af9d87ad935d982700e5bce6cb7..3b7e39ecefbeff15a7fc6eb7ec45c28afd1ed8f9 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -611,12 +611,45 @@ function _M:actBase() self:checkStillInCombat() end +function _M:hasProc(proc) + if not self.turn_procs then return end + if self.turn_procs[proc] then + return self.turn_procs[proc] + elseif self.turn_procs.multi then + return self.turn_procs.multi[proc] + end +end + +function _M:setProc(name, val, turns) + turns = turns or 1 + val = val or true + local proc = {val = val, turns = turns} + if turns > 1 then + table.set(self, "turn_procs", "multi", name, proc) + else + self.turn_procs[name] = proc + end +end + -- General entry point for Actors to act, called by NPC:act or Player:act function _M:act() if not engine.Actor.act(self) then return end self.changed = true + + -- Store procs with more than 1 turn remaining and re-add them after we clear turn_procs + local temp = {} + if self.turn_procs.multi then + for proc, val in pairs(self.turn_procs.multi) do + if proc then + self.turn_procs.multi[proc].turns = self.turn_procs.multi[proc].turns - 1 + if self.turn_procs.multi[proc].turns > 0 then temp[proc] = val end + end + end + end + self.turn_procs = {} + if temp then self.turn_procs.multi = temp end -- Break some sustains if certain resources are too low -- Note: force_talent_ignore_ressources has no effect here diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 17e4e0fb5bdbf4816d6d69cde878a9b86aa29414..4a30dcd2b70fe5eca026ff0e3d557c8766ed8a17 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -248,13 +248,6 @@ function _M:attackTarget(target, damtype, mult, noenergy, force_unarmed) t.on_attackTarget(self, t, target) end - if self:attr("unharmed_attack_on_hit") then - local v = self:attr("unharmed_attack_on_hit") - self:attr("unharmed_attack_on_hit", -v) - if rng.percent(60) then self:attackTarget(target, nil, 1, true, true) end - self:attr("unharmed_attack_on_hit", v) - end - -- Cancel stealth! if break_stealth then self:breakStealth() end self:breakLightningSpeed() @@ -693,6 +686,15 @@ function _M:attackTargetHitProcs(target, weapon, dam, apr, armor, damtype, mult, self.__global_accuracy_damage_bonus = self.__global_accuracy_damage_bonus / self.__attacktargetwith_recursing_procs_reduce end + if self:attr("unharmed_attack_on_hit") and not (self.turn_procs.flexible_combat and (self.turn_procs.flexible_combat >= self:callTalent(self.T_FLEXIBLE_COMBAT, "getProcs")) ) then + self.turn_procs.flexible_combat = self.turn_procs.flexible_combat or 0 + self.turn_procs.flexible_combat = self.turn_procs.flexible_combat + 1 + local v = self:attr("unharmed_attack_on_hit") + self:attr("unharmed_attack_on_hit", -v) + if rng.percent(30) then self:attackTarget(target, nil, 1, true, true) end + self:attr("unharmed_attack_on_hit", v) + end + -- handle stalk targeting for hits (also handled in Actor for turn end effects) if hitted and target ~= self then local effStalker = self:hasEffect(self.EFF_STALKER) diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index cd7b301d5f043ca1bb6a7c5387be968bea99876f..07186b7fd7f4d94adf8224ca98527b5a1d94d463 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -542,10 +542,6 @@ setDefaultProjector(function(src, x, y, type, dam, state) end end - if not target.dead and dam > 0 and src.knowTalent and src:knowTalent(src.T_ENDLESS_WOES) then - src:triggerTalent(src.T_ENDLESS_WOES, nil, target, type, dam) - end - -- damage affinity healing if not target.dead and affinity_heal > 0 then target:heal(affinity_heal, src) @@ -637,15 +633,6 @@ setDefaultProjector(function(src, x, y, type, dam, state) end end - -- Use state, because we don't care if it was shrugged off. - if state.crit_power > 1 and not state.crit_elemental_surge then - if src.knowTalent and src:knowTalent(src.T_ELEMENTAL_SURGE) then - src:triggerTalent(src.T_ELEMENTAL_SURGE, nil, target, type, dam) - end - - state.crit_elemental_surge = true - end - if src.turn_procs and not src.turn_procs.dazing_damage and src.hasEffect and src:hasEffect(src.EFF_DAZING_DAMAGE) then if target:canBe("stun") then local power = math.max(src:combatSpellpower(), src:combatMindpower(), src:combatPhysicalpower()) diff --git a/game/modules/tome/data/talents/uber/cun.lua b/game/modules/tome/data/talents/uber/cun.lua index 8ec4a86da0f3218864ad088e95f5f9a9d1e8a991..f9a5d3003915daef87d75e6098c75b1a6604be34 100644 --- a/game/modules/tome/data/talents/uber/cun.lua +++ b/game/modules/tome/data/talents/uber/cun.lua @@ -20,6 +20,7 @@ uberTalent{ name = "Fast As Lightning", mode = "passive", + not_listed = true, trigger = function(self, t, ox, oy) local dx, dy = (self.x - ox), (self.y - oy) if dx ~= 0 then dx = dx / math.abs(dx) end @@ -93,36 +94,113 @@ uberTalent{ (self.damage_log[DamageType.TEMPORAL] and self.damage_log[DamageType.TEMPORAL] >= 50000) ) end} }, - cunmult = function(self) return self:combatStatScale("cun", 0.15, 1) end, - trigger = function(self, t, target, damtype, dam) - if dam < 150 then return end - if damtype == DamageType.ACID and rng.percent(20) then - target:setEffect(target.EFF_ACID_SPLASH, 5, {src=self, dam=(dam * t.cunmult(self) / 2.5) / 5, atk=self:getCun() / 2, apply_power=math.max(self:combatSpellpower(), self:combatMindpower())}) - elseif damtype == DamageType.BLIGHT and target:canBe("disease") and rng.percent(20) then - local diseases = {{self.EFF_WEAKNESS_DISEASE, "str"}, {self.EFF_ROTTING_DISEASE, "con"}, {self.EFF_DECREPITUDE_DISEASE, "dex"}} - local disease = rng.table(diseases) - target:setEffect(disease[1], 5, {src=self, dam=(dam * t.cunmult(self)/ 2.5) / 5, [disease[2]]=self:getCun() / 3, apply_power=math.max(self:combatSpellpower(), self:combatMindpower())}) - elseif damtype == DamageType.DARKNESS and target:canBe("blind") and rng.percent(20) then - target:setEffect(target.EFF_BLINDED, 5, {apply_power=math.max(self:combatSpellpower(), self:combatMindpower())}) - elseif damtype == DamageType.TEMPORAL and target:canBe("slow") and rng.percent(20) then - target:setEffect(target.EFF_SLOW, 5, {apply_power=math.max(self:combatSpellpower(), self:combatMindpower()), power=0.3}) - elseif damtype == DamageType.MIND and target:canBe("confusion") and rng.percent(20) then - target:setEffect(target.EFF_CONFUSED, 5, {apply_power=math.max(self:combatSpellpower(), self:combatMindpower()), power=20}) + getBlight = function(self, t) + return self:combatStatScale("cun", 1, 20, 0.75), self:combatStatScale("cun", 5, 30, 0.75) + end, + getDarkness = function(self, t) return self:combatStatScale("cun", 1, 30, 0.75) end, + getAcid = function(self, t) return self:combatStatScale("cun", 10, 50, 0.75) end, + getTemporal = function(self, t) return self:combatStatScale("cun", 1, 40, 0.75) end, + getMind = function(self, t) return self:combatStatScale("cun", 1, 40, 0.75) end, + range = 10, + radius = 3, + dts = {TEMPORAL=true, BLIGHT=true, ACID=true, DARKNESS=true, MIND=true,}, + getThreshold = function(self, t) return 8*self.level end, + getDamage = function(self, t) return self:combatStatScale("cun", 10, 150, 0.75) end, + doProject = function(self, t, damtype, effect, part) + local tgts = {} + -- Find everything nearby and pick one at random + local grids = core.fov.circle_grids(self.x, self.y, self:getTalentRange(t), true) + for x, yy in pairs(grids) do for y, _ in pairs(grids[x]) do + local a = game.level.map(x, y, Map.ACTOR) + if a and self:reactionToward(a) < 0 then + tgts[#tgts+1] = a + end + end end + local target = rng.table(tgts) + if not target then return end + + local eff = effect + local tg = {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, friendlyfire=false, talent=t} + game.level.map:particleEmitter(target.x, target.y, tg.radius, part, {radius=tg.radius}) + self:project(tg, target.x, target.y, function(tx, ty) + local target = game.level.map(tx, ty, Map.ACTOR) + if not target or target == self then return end + if not effect.params then return end + --local p = table.clone(effect.params) + local eff = table.clone(effect, true) + + if not effect.canbe or target:canBe(effect.canbe) then + eff.params.apply_power = math.max(self:combatSpellpower(), self:combatMindpower()) + target:setEffect(target[effect.id], 5, eff.params) + end + DamageType:get(damtype).projector(self, tx, ty, damtype, t.getDamage(self, t)) + end) + end, + callbackOnRest = function(self, t) self.endless_woes = {} end, -- No storing damage out of combat + callbackOnRun = function(self, t) self.endless_woes = {} end, + callbackOnDealDamage = function(self, t, value, target, dead, death_note) + local damtype = death_note.damtype + if not t.dts[damtype] then return end + self.endless_woes = self.endless_woes or {} + self.endless_woes[damtype] = (self.endless_woes[damtype] or 0) + value + + if self.endless_woes[damtype] > t.getThreshold(self, t) then + self.endless_woes[damtype] = 0 + if damtype == DamageType.TEMPORAL and not self:hasProc("endless_woes_temporal") then + self:setProc("endless_woes_temporal", true, 12) + game.logSeen(self, "You unleash a blast of #LIGHT_STEEL_BLUE#temporal#LAST# energy!", self.name:capitalize()) + t.doProject(self, t, damtype, {id="EFF_SLOW", dur=5, params={power=0.3}, canbe="slow"}, "ball_temporal") + elseif damtype == DamageType.BLIGHT and not self:hasProc("endless_woes_blight") then + self:setProc("endless_woes_blight", true, 12) + game.logSeen(self, "You unleash a blast of #DARK_GREEN#virulent blight!#LAST#!", self.name:capitalize()) + local dam, stat = t.getBlight(self, t) + t.doProject(self, t, damtype, {id="EFF_WOEFUL_DISEASE", dur=5, params = {src=self, dam=dam, str=stat, con=stat, dex=stat}, canbe="disease"}, "ball_blight") + elseif damtype == DamageType.ACID and not self:hasProc("endless_woes_acid") then + self:setProc("endless_woes_acid", true, 12) + local dam = t.getAcid(self, t) + game.logSeen(self, "You unleash a blast of #GREEN#acid#LAST#!", self.name:capitalize()) + t.doProject(self, t, damtype, {id="EFF_WOEFUL_CORROSION", dur=5, params={src=self, dam=dam}}, "ball_acid") + elseif damtype == DamageType.DARKNESS and not self:hasProc("endless_woes_darkness") then + self:setProc("endless_woes_darkness", true, 12) + game.logSeen(self, "You unleash a blast of numbing #GREY#darkness#LAST#!", self.name:capitalize()) + t.doProject(self, t, damtype, {id="EFF_WOEFUL_DARKNESS", dur=5, params={reduce=t.getDarkness(self, t)}}, "shadow_flash") + elseif damtype == DamageType.MIND and not self:hasProc("endless_woes_mind") then + self:setProc("endless_woes_mind", true, 12) + game.logSeen(self, "You unleash a confusing blast of #YELLOW#mental#LAST# energy!", self.name:capitalize()) + t.doProject(self, t, damtype, {id="EFF_CONFUSED", dur=5, params={power=50}, canbe="confusion"}, "starfall") + end end end, info = function(self, t) - return ([[Surround yourself with a malevolent aura. - Any acid damage you do has a 20%% chance to apply a lasting acid that deals %d%% of the initial damage for 5 turns and reduces accuracy by %d. - Any blight damage you do has a 20%% chance to cause a random disease that deals %d%% of the initial damage for 5 turns and reduces a stat by %d. - Any darkness damage you do has a 20%% chance to blind the target for 5 turns. - Any temporal damage you do has a 20%% chance to slow (30%%) the target for 5 turns. - Any mind damage you do has a 20%% chance to confuse (20%%) the target for 5 turns. - This only triggers for hits over 150 damage. - The damage values increase with your Cunning.]]) - :format(100*t.cunmult(self) / 2.5, self:getCun() / 2, 100*t.cunmult(self) / 2.5, self:getCun() / 3) + local blight_dam, blight_disease = t.getBlight(self, t) + local cooldowns = {} + local str = "" + -- Display the remaining cooldowns in the talent tooltip only if its learned + if self:knowTalent(self.T_ENDLESS_WOES) then + for dt, _ in pairs(t.dts) do + local proc = self:hasProc("endless_woes_"..dt:lower()) + if proc then cooldowns[#cooldowns+1] = (dt:lower()):capitalize()..": "..proc.turns end + end + str = "(Cooldowns)".."\n"..table.concat(cooldowns, "\n") + end + return ([[Surround yourself with a malevolent aura that stores damage you deal. + Whenever you have stored %d damage of one type you unleash a powerful blast at a random enemy dealing %d damage of that type in radius %d and applying one of the following effects: + + #GREEN#Acid:#LAST# Deals %d acid damage each turn for 5 turns. + #DARK_GREEN#Blight:#LAST# Deals %d blight damage each turn for 5 turns and reduces strength, constitution, and dexterity by %d. + #GREY#Darkness:#LAST# Reduces damage dealt by %d%% for 5 turns. + #LIGHT_STEEL_BLUE#Temporal:#LAST# Slows global action speed by %d%% for 5 turns. + #YELLOW#Mind:#LAST# Confuses (power %d%%) for 5 turns. + + Each effect has an independent 12 player turn cooldown. + The damage and effect power increase with your Cunning, the threshold with your level, and the apply power is the highest of your mind or spell power. + + %s]]) + :format(t.getThreshold(self, t), t.getDamage(self, t), self:getTalentRadius(t), t.getAcid(self, t), blight_dam, blight_disease, t.getDarkness(self, t), t.getTemporal(self, t), t.getMind(self, t), str) end, } +-- Item rarities uberTalent{ name = "Secrets of Telos", mode = "passive", @@ -161,7 +239,6 @@ uberTalent{ uberTalent{ name = "Elemental Surge", mode = "passive", - cooldown = 12, require = { special={desc="Have dealt over 50000 arcane, fire, cold, lightning, light or nature damage", fct=function(self) return self.damage_log and ( (self.damage_log[DamageType.ARCANE] and self.damage_log[DamageType.ARCANE] >= 50000) or @@ -172,45 +249,85 @@ uberTalent{ (self.damage_log[DamageType.NATURE] and self.damage_log[DamageType.NATURE] >= 50000) ) end} }, - getThreshold = function(self, t) return 4*self.level end, - getColdEffects = function(self, t) - return {physresist = 30, - armor = self:combatStatScale("cun", 20, 50, 0.75), - dam = math.max(100, self:getCun()), + dts = {PHYSICAL=true, ARCANE=true, LIGHT=true, COLD=true, LIGHTNING=true, FIRE=true, NATURE=true,}, getCold = function(self, t) + return { + armor = self:combatStatScale("cun", 10, 30, 0.75), + dam = math.max(100, self:getCun()), } end, - getShield = function(self, t) return 100 + 2*self:getCun() end, - -- triggered in default projector in mod.data.damage_types.lua - trigger = function(self, t, target, damtype, dam) - if dam < t.getThreshold(self, t) then return end - - local ok = false - if damtype == DamageType.ARCANE and rng.percent(30) then ok=true self:setEffect(self.EFF_ELEMENTAL_SURGE_ARCANE, 5, {}) - elseif damtype == DamageType.FIRE and rng.percent(30) then ok=true self:removeEffectsFilter{type="magical", status="detrimental"} self:removeEffectsFilter{type="physical", status="detrimental"} game.logSeen(self, "#CRIMSON#%s fiery attack invokes a cleansing flame!", self.name:capitalize()) - elseif damtype == DamageType.COLD and rng.percent(30) then - -- EFF_ELEMENTAL_SURGE_COLD in mod.data.timed_effect.magical.lua holds the parameters - ok=true self:setEffect(self.EFF_ELEMENTAL_SURGE_COLD, 5, t.getColdEffects(self, t)) - elseif damtype == DamageType.LIGHTNING and rng.percent(30) then ok=true self:setEffect(self.EFF_ELEMENTAL_SURGE_LIGHTNING, 5, {}) - elseif damtype == DamageType.LIGHT and rng.percent(30) and not self:hasEffect(self.EFF_DAMAGE_SHIELD) then - ok=true - self:setEffect(self.EFF_DAMAGE_SHIELD, 5, {power=t.getShield(self, t)}) - elseif damtype == DamageType.NATURE and rng.percent(30) then ok=true self:setEffect(self.EFF_ELEMENTAL_SURGE_NATURE, 5, {}) - end + getLight = function(self, t) return 20 end, + getLightning = function(self, t) return self:combatStatScale("cun", 10, 70, 0.75) end, + getFire = function(self, t) return 20 end, + getThreshold = function(self, t) return 8*self.level end, + callbackOnRest = function(self, t) self.elemental_surge = nil end, -- No storing damage out of combat + callbackOnRun = function(self, t) self.elemental_surge = nil end, + callbackOnDealDamage = function(self, t, value, target, dead, death_note) + local damtype = death_note.damtype + if not t.dts[damtype] then return end + self.elemental_surge = self.elemental_surge or {} + self.elemental_surge[damtype] = (self.elemental_surge[damtype] or 0) + value - if ok then self:startTalentCooldown(t) end + if self.elemental_surge[damtype] > t.getThreshold(self, t) then + self.elemental_surge[damtype] = 0 + if damtype == DamageType.PHYSICAL and not self:hasProc("elemental_surge_physical") then + self:setProc("elemental_surge_physical", true, 12) + game.logSeen(self, "%s surges with earthen! power!", self.name:capitalize()) + self:removeEffectsFilter({status="detrimental", type="physical", ignore_crosstier=true}, 1) + elseif damtype == DamageType.ARCANE and not self:hasProc("elemental_surge_arcane") then + self:setProc("elemental_surge_arcane", true, 12) + game.logSeen(self, "%s surges with #PURPLE#arcane#LAST# power!", self.name:capitalize()) + self:setEffect(self.EFF_ELEMENTAL_SURGE_ARCANE, 3, {}) + elseif damtype == DamageType.FIRE and not self:hasProc("elemental_surge_fire") then + self:setProc("elemental_surge_fire", true, 12) + self:setEffect(self.EFF_ELEMENTAL_SURGE_FIRE, 3, {damage = t.getFire(self, t)}) + game.logSeen(self, "%s surges with #LIGHT_RED#fiery#LAST# power!", self.name:capitalize()) + elseif damtype == DamageType.COLD and not self:hasProc("elemental_surge_cold") then + self:setProc("elemental_surge_cold", true, 12) + game.logSeen(self, "%s surges with #1133F3#icy#LAST# power!", self.name:capitalize()) + self:setEffect(self.EFF_ELEMENTAL_SURGE_COLD, 3, t.getCold(self, t) ) + elseif damtype == DamageType.LIGHTNING and not self:hasProc("elemental_surge_lightning") then + self:setProc("elemental_surge_lightning", true, 12) + game.logSeen(self, "%s surges with #ROYAL_BLUE#lightning#LAST# power!", self.name:capitalize()) + self:setEffect(self.EFF_ELEMENTAL_SURGE_LIGHTNING, 3, {move = t.getLightning(self, t)}) + elseif damtype == DamageType.LIGHT and not self:hasProc("elemental_surge_light") then + self:setProc("elemental_surge_light", true, 12) + game.logSeen(self, "%s surges with #YELLOW#light#LAST# power!", self.name:capitalize()) + self:setEffect(self.EFF_ELEMENTAL_SURGE_LIGHT, 3, {cooldown = t.getLight(self, t)}) -- Cooldown reduction + elseif damtype == DamageType.NATURE and not self:hasProc("elemental_surge_nature") then + self:setProc("elemental_surge_nature", true, 12) + game.logSeen(self, "%s surges with #LIGHT_GREEN#natural#LAST# power!", self.name:capitalize()) + self:removeEffectsFilter({status="detrimental", type="magical", ignore_crosstier=true}, 1) + end + end end, info = function(self, t) - local cold = t.getColdEffects(self, t) - return ([[Surround yourself with an elemental aura. When you deal a critical hit with an element, you have a chance to trigger a special effect. - Arcane damage has a 30%% chance to increase your spellcasting speed by 20%% for 5 turns. - Fire damage has a 30%% chance to cleanse all physical or magical detrimental effects on you. - Cold damage has a 30%% chance to turn your skin into ice for 5 turns, reducing physical damage taken by %d%%, increasing armor by %d, and dealing %d ice damage to attackers. - Lightning damage has a 30%% chance to transform you into pure lightning for 5 turns; any damage will displace you to an adjacent tile and ignore the damage (can only happen once per turn). - Light damage has a 30%% chance to create a barrier around you, absorbing %d damage for 5 turns. - Nature damage has a 30%% chance to harden your skin, preventing the application of any magical detrimental effects for 5 turns. - The Cold and Light effects scale with your Cunning. - These effects only trigger for hits over %d damage (based on your level).]]) - :format(cold.physresist, cold.armor, cold.dam, t.getShield(self, t), t.getThreshold(self, t)) + local cooldowns = {} + local str = "" + local cold = t.getCold(self, t) + -- Display the remaining cooldowns in the talent tooltip only if its learned + if self:knowTalent(self.T_ELEMENTAL_SURGE) then + for dt, _ in pairs(t.dts) do + local proc = self:hasProc("elemental_surge_"..dt:lower()) + if proc then cooldowns[#cooldowns+1] = (dt:lower()):capitalize()..": "..proc.turns end + end + str = "(Cooldowns)".."\n"..table.concat(cooldowns, "\n") + end + return ([[Surround yourself with an elemental aura. Whenever you deal elemental damage you store it, unleashing a powerful effect when %d total damage (based on level) is reached. + The charge totals are cleared out of combat. + + Physical: Cleanses 1 physical debuff. + #PURPLE#Arcane:#LAST# Increases your non-physical combat speeds by 30%% for 3 turns. + #LIGHT_RED#Fire:#LAST# Increases all damage dealt by %d%% for 3 turns. + #1133F3#Cold:#LAST# Turn your skin into ice for 3 turns increasing armor by %d and dealing %d ice damage to attackers. + #ROYAL_BLUE#Lightning:#LAST# Increases your movement speed by %d%% for 3 turns. + #YELLOW#Light:#LAST# Reduce all cooldowns by 20%% for 3 turns. + #LIGHT_GREEN#Nature:#LAST# Cleanses 1 magical debuff. + + Each cooldown is independent. + Some effects scale with your Cunning stat. + + %s]]) + :format(t.getThreshold(self, t), t.getFire(self, t), cold.armor, cold.dam, t.getLightning(self, t), str) end, } @@ -235,7 +352,8 @@ uberTalent{ name = "Eye of the Tiger", mode = "passive", trigger = function(self, t, kind) - if self.turn_procs.eye_tiger then return end + local kind_str = "eye_tiger_"..kind + if self:hasProc(kind_str) then return end local tids = {} @@ -258,13 +376,13 @@ uberTalent{ self.talents_cd[tid] = self.talents_cd[tid] - (d and d.reduce or 1) if self.talents_cd[tid] <= 0 then self.talents_cd[tid] = nil end self.changed = true - self.turn_procs.eye_tiger = true + self:setProc(kind_str) end, info = function(self, t) local list = {} for _, d in pairs(eye_of_the_tiger_data) do list[#list+1] = d.desc end return ([[%s - This can only happen once per turn, and cannot affect the talent that triggers it.]]) + This can only happen once per turn per type, and cannot affect the talent that triggers it.]]) :format(table.concat(list, "\n")) end, } @@ -302,6 +420,32 @@ uberTalent{ end, } +uberTalent{ + name = "Adept", + mode = "passive", + cant_steal = true, + info = function(self, t) + return ([[All talent types you know when you aquire this prodigy have their mastery increased by 0.3]]) + :format() + end, + on_learn = function(self, t) + for i, def in ipairs(engine.interface.ActorTalents.talents_types_def) do + if not def.hide and self:knowTalentType(def.type) then -- Do not increase mastery for NPC talents, inscriptions, prodigies, Cursed Sentry, etc + self:setTalentTypeMastery(def.type, self:getTalentTypeMastery(def.type) + 0.3) + self:updateTalentTypeMastery(def.type) + end + end + end, + on_unlearn = function(self, t) + for i, def in ipairs(engine.interface.ActorTalents.talents_types_def) do + if not def.hide and self:knowTalentType(def.type) then + self:setTalentTypeMastery(def.type, self:getTalentTypeMastery(def.type) - 0.3) + self:updateTalentTypeMastery(def.type) + end + end + end +} + uberTalent{ name = "Tricks of the Trade", mode = "passive", diff --git a/game/modules/tome/data/talents/uber/dex.lua b/game/modules/tome/data/talents/uber/dex.lua index 60409d061735389ffa733b4fd0fd0eba0dee6b93..78f83de42e7becf7af3260db52b48f8343b56d98 100644 --- a/game/modules/tome/data/talents/uber/dex.lua +++ b/game/modules/tome/data/talents/uber/dex.lua @@ -17,6 +17,24 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +uberTalent{ + name = "Flexible Combat", + mode = "passive", + on_learn = function(self, t) + self:attr("unharmed_attack_on_hit", 1) + self:attr("show_gloves_combat", 1) + end, + on_unlearn = function(self, t) + self:attr("unharmed_attack_on_hit", -1) + self:attr("show_gloves_combat", -1) + end, + getProcs = function(self, t) return math.floor(self:getDex() / 30) end, + info = function(self, t) + return ([[Each time that you make a melee attack you have a 30%% chance to execute an additional unarmed strike. This can occur once per turn for every 30 Dexterity (currently %d) you have.]]) + :format(t.getProcs(self, t)) + end, +} + uberTalent{ name = "Through The Crowd", require = { special={desc="Have had at least 6 party members at the same time", fct=function(self) @@ -149,67 +167,6 @@ uberTalent{ end, } -uberTalent{ - name = "Giant Leap", - mode = "activated", - require = { special={desc="Have dealt over 50000 damage with any weapon or unarmed", fct=function(self) return - self.damage_log and ( - (self.damage_log.weapon.twohanded and self.damage_log.weapon.twohanded >= 50000) or - (self.damage_log.weapon.shield and self.damage_log.weapon.shield >= 50000) or - (self.damage_log.weapon.dualwield and self.damage_log.weapon.dualwield >= 50000) or - (self.damage_log.weapon.other and self.damage_log.weapon.other >= 50000) - ) - end} }, - cooldown = 12, - radius = 1, - range = 10, - is_melee = true, - requires_target = true, - tactical = { CLOSEIN = 2, ATTACKAREA = { weapon = 2 }, DISABLE = { stun = 1 } }, - target = function(self, t) - return {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t)} - end, - action = function(self, t) - local tg = self:getTalentTarget(t) - local x, y, target = self:getTarget(tg) - if not x or not y then return nil end - local _ _, x, y = self:canProject(tg, x, y) - - if game.level.map(x, y, Map.ACTOR) then - x, y = util.findFreeGrid(x, y, 1, true, {[Map.ACTOR]=true}) - if not x then return end - end - - if game.level.map:checkAllEntities(x, y, "block_move") then return end - - local ox, oy = self.x, self.y - self:move(x, y, true) - if config.settings.tome.smooth_move > 0 then - self:resetMoveAnim() - self:setMoveAnim(ox, oy, 8, 5) - end - - self:removeEffectsFilter({subtype={stun=true, daze=true, pin=true, pinned=true, pinning=true}}, 50) - - self:project(tg, self.x, self.y, function(px, py, tg, self) - local target = game.level.map(px, py, Map.ACTOR) - if target and target ~= self then - local hit = self:attackTarget(target, nil, 2, true) - if hit and target:canBe("stun") then - target:setEffect(target.EFF_DAZED, 3, {}) - end - end - end) - - return true - end, - info = function(self, t) - return ([[You accurately jump to the target and deal 200%% weapon damage to all foes within radius 1 on impact as well as dazing them for 3 turns. - When you jump you free yourself from any stun, daze and pinning effects.]]) - :format() - end, -} - uberTalent{ name = "Crafty Hands", mode = "passive", diff --git a/game/modules/tome/data/talents/uber/str.lua b/game/modules/tome/data/talents/uber/str.lua index dcd9db3b0a32d3d3634c8d17dc8bef955c782d88..294bc725e28e76e7e2635e2d5964f71d9ddf326f 100644 --- a/game/modules/tome/data/talents/uber/str.lua +++ b/game/modules/tome/data/talents/uber/str.lua @@ -18,18 +18,62 @@ -- darkgod@te4.org uberTalent{ - name = "Flexible Combat", - mode = "passive", - on_learn = function(self, t) - self:attr("unharmed_attack_on_hit", 1) - self:attr("show_gloves_combat", 1) + name = "Giant Leap", + mode = "activated", + require = { special={desc="Have dealt over 50000 damage with any weapon or unarmed", fct=function(self) return + self.damage_log and ( + (self.damage_log.weapon.twohanded and self.damage_log.weapon.twohanded >= 50000) or + (self.damage_log.weapon.shield and self.damage_log.weapon.shield >= 50000) or + (self.damage_log.weapon.dualwield and self.damage_log.weapon.dualwield >= 50000) or + (self.damage_log.weapon.other and self.damage_log.weapon.other >= 50000) + ) + end} }, + cooldown = 12, + radius = 1, + range = 10, + is_melee = true, + requires_target = true, + tactical = { CLOSEIN = 2, ATTACKAREA = { weapon = 2 }, DISABLE = { stun = 1 } }, + target = function(self, t) + return {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t)} end, - on_unlearn = function(self, t) - self:attr("unharmed_attack_on_hit", -1) - self:attr("show_gloves_combat", -1) + action = function(self, t) + local tg = self:getTalentTarget(t) + local x, y, target = self:getTarget(tg) + if not x or not y then return nil end + local _ _, x, y = self:canProject(tg, x, y) + + if game.level.map(x, y, Map.ACTOR) then + x, y = util.findFreeGrid(x, y, 1, true, {[Map.ACTOR]=true}) + if not x then return end + end + + if game.level.map:checkAllEntities(x, y, "block_move") then return end + + local ox, oy = self.x, self.y + self:move(x, y, true) + if config.settings.tome.smooth_move > 0 then + self:resetMoveAnim() + self:setMoveAnim(ox, oy, 8, 5) + end + + self:removeEffectsFilter({subtype={stun=true, daze=true, pin=true, pinned=true, pinning=true}}, 50) + + self:project(tg, self.x, self.y, function(px, py, tg, self) + local target = game.level.map(px, py, Map.ACTOR) + if target and target ~= self then + local hit = self:attackTarget(target, nil, 2, true) + if hit and target:canBe("stun") then + target:setEffect(target.EFF_DAZED, 3, {}) + end + end + end) + + return true end, info = function(self, t) - return ([[Each time that you make a melee attack you have a 60%% chance to execute an additional unarmed strike.]]) + return ([[You accurately jump to the target and deal 200%% weapon damage to all foes within radius 1 on impact as well as dazing them for 3 turns. + When you jump you free yourself from any stun, daze and pinning effects.]]) :format() end, } @@ -142,12 +186,12 @@ uberTalent{ ) end} }, action = function(self, t) - self:setEffect(self.EFF_IRRESISTIBLE_SUN, 6, {dam=50 + self:getStr() * 1.7}) + self:setEffect(self.EFF_IRRESISTIBLE_SUN, 8, {dam=35 + self:getStr() * 1.3}) return true end, info = function(self, t) - local dam = (50 + self:getStr() * 1.7) / 3 - return ([[For 6 turns you gain the mass and power of a star, drawing all creatures within radius 5 toward you and dealing %0.2f fire, %0.2f light and %0.2f physical damage to all foes. + local dam = (35 + self:getStr() * 1.3) / 3 + return ([[For 8 turns you gain the mass and power of a star, drawing all creatures within radius 5 toward you and dealing %0.2f fire, %0.2f light and %0.2f physical damage to all foes and reducing their damage dealt by 30%%. Foes closer to you take up to 150%% damage. The damage will increase with your Strength.]]) :format(damDesc(self, DamageType.FIRE, dam), damDesc(self, DamageType.LIGHT, dam), damDesc(self, DamageType.PHYSICAL, dam)) diff --git a/game/modules/tome/data/talents/uber/wil.lua b/game/modules/tome/data/talents/uber/wil.lua index 82b5852e843310b6e1dcb9142d0102b053048487..f66ac24bf71ce579e54d435585329cd6277a4cb5 100644 --- a/game/modules/tome/data/talents/uber/wil.lua +++ b/game/modules/tome/data/talents/uber/wil.lua @@ -41,13 +41,23 @@ uberTalent{ name = "Meteoric Crash", mode = "passive", cooldown = 15, - getDamage = function(self, t) return math.max(100 + self:combatSpellpower() * 5, 100 + self:combatMindpower() * 5) end, + getDamage = function(self, t) return math.max(50 + self:combatSpellpower() * 5, 50 + self:combatMindpower() * 5) end, + getLava = function(self, t) return math.max(self:combatSpellpower() + 30, self:combatMindpower() + 30) end, require = { special={desc="Have witnessed a meteoric crash", fct=function(self) return game.state.birth.ignore_prodigies_special_reqs or self:attr("meteoric_crash") end} }, trigger = function(self, t, target) self:startTalentCooldown(t) local terrains = t.terrains or mod.class.Grid:loadList("/data/general/grids/lava.lua") t.terrains = terrains -- cache + local lava_dam = t.getLava(self, t) + local dam = t.getDamage(self, t) + if self:combatMindCrit() > self:combatSpellCrit() then + _dam = self:mindCrit(dam) + lava_dam = self:mindCrit(lava_dam) + else + dam = self:spellCrit(dam) + lava_dam = self:spellCrit(lava_dam) + end local meteor = function(src, x, y, dam) game.level.map:particleEmitter(x, y, 10, "meteor", {x=x, y=y}).on_remove = function(self) local x, y = self.args.x, self.args.y @@ -55,22 +65,26 @@ uberTalent{ game:playSoundNear(game.player, "talents/fireflash") local grids = {} - for i = x-1, x+1 do for j = y-1, y+1 do + for i = x-3, x+3 do for j = y-3, y+3 do local oe = game.level.map(i, j, engine.Map.TERRAIN) - if oe and not oe:attr("temporary") and - (core.fov.distance(x, y, i, j) < 1 or rng.percent(40)) and (game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "dig") or game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "grow")) then + -- Create "patchy" lava, but guarantee that the center tiles are lava + if oe and not oe:attr("temporary") and not oe.special and not game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "block_move") and (core.fov.distance(x, y, i, j) < 1 or rng.percent(40)) then local g = terrains.LAVA_FLOOR:clone() g:resolve() g:resolve(nil, true) game.zone:addEntity(game.level, g, "terrain", i, j) grids[#grids+1] = {x=i,y=j,oe=oe} end end end - for i = x-1, x+1 do for j = y-1, y+1 do + for i = x-3, x+3 do for j = y-3, y+3 do game.nicer_tiles:updateAround(game.level, i, j) end end for _, spot in ipairs(grids) do local i, j = spot.x, spot.y local g = game.level.map(i, j, engine.Map.TERRAIN) + + g.mindam = lava_dam + g.maxdam = lava_dam + g.faction = src.faction -- Don't hit self or allies g.temporary = 8 g.x = i g.y = j g.canAct = false @@ -89,9 +103,9 @@ uberTalent{ game.level:addEntity(g) end - src:project({type="ball", radius=2, selffire=false}, x, y, engine.DamageType.FIRE, dam/2) - src:project({type="ball", radius=2, selffire=false}, x, y, engine.DamageType.PHYSICAL, dam/2) - src:project({type="ball", radius=2, selffire=false}, x, y, function(px, py) + src:project({type="ball", radius=2, selffire=false, friendlyfire=false}, x, y, engine.DamageType.FIRE, dam/2) + src:project({type="ball", radius=2, selffire=false, friendlyfire=false}, x, y, engine.DamageType.PHYSICAL, dam/2) + src:project({type="ball", radius=2, selffire=false, friendlyfire=false}, x, y, function(px, py) local target = game.level.map(px, py, engine.Map.ACTOR) if target then if target:canBe("stun") then @@ -117,9 +131,11 @@ uberTalent{ info = function(self, t) local dam = t.getDamage(self, t)/2 return ([[When casting damaging spells or mind attacks, the release of your willpower can call forth a meteor to crash down near your foes. - The affected area is turned into lava for 8 turns, and the crash itself will deal %0.2f fire and %0.2f physical damage. - The meteor also stuns affected creatures for 3 turns. The damage scales with your Spellpower or Mindpower.]]) - :format(damDesc(self, DamageType.FIRE, dam), damDesc(self, DamageType.PHYSICAL, dam)) + The meteor deals %0.2f fire and %0.2f physical damage in radius 2 and stuns enemies for 3 turns. + Lava is created in radius 3 around the impact dealing %0.2f fire damage per turn for 8 turns. + You and your allies take no damage from either effect. + The damage scales with your Spellpower or Mindpower.]]) + :format(damDesc(self, DamageType.FIRE, dam), damDesc(self, DamageType.PHYSICAL, dam), damDesc(self, DamageType.FIRE, t.getLava(self, t))) end, } @@ -201,7 +217,7 @@ uberTalent{ uberTalent{ name = "Unbreakable Will", mode = "passive", - cooldown = 7, + cooldown = 5, trigger = function(self, t) self:startTalentCooldown(t) game.logSeen(self, "#LIGHT_BLUE#%s's unbreakable will shrugs off the effect!", self.name:capitalize()) @@ -209,7 +225,7 @@ uberTalent{ end, info = function(self, t) return ([[Your will is so strong that you simply ignore mental effects used against you. - Warning: this has a cooldown.]]) + This effect can only occur once every 5 turns.]]) :format() end, } diff --git a/game/modules/tome/data/timed_effects/magical.lua b/game/modules/tome/data/timed_effects/magical.lua index ff075238d0a5876e39078e751e52c08244face97..a4ff1e6a4b502f2eb31809660d0ddd04f5185b33 100644 --- a/game/modules/tome/data/timed_effects/magical.lua +++ b/game/modules/tome/data/timed_effects/magical.lua @@ -2081,6 +2081,77 @@ newEffect{ end, } +-- Endless Woes prodigy effects +newEffect{ + name = "WOEFUL_DISEASE", image = "talents/weakness_disease.png", + desc = "Woeful Disease", + long_desc = function(self, eff) return ("The target is infected by a disease, reducing its strength, constitution, dexterity by %d and doing %0.2f blight damage per turn."): + format(eff.str, eff.con, eff.dex, eff.dam) end, + type = "magical", + subtype = {disease=true, blight=true}, + status = "detrimental", + parameters = {str = 1, con = 1, dex = 1, dam = 0}, + on_gain = function(self, err) return "#Target# is afflicted by a woeful disease!" end, + on_lose = function(self, err) return "#Target# is free from the woeful disease." end, + -- Damage each turn + on_timeout = function(self, eff) + if self:attr("purify_disease") then self:heal(eff.dam, eff.src) + else if eff.dam > 0 then DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.dam, {from_disease=true}) + end end + end, + activate = function(self, eff) + self:effectTemporaryValue(eff, "inc_stats", { + [Stats.STAT_STR] = math.floor(eff.str), + [Stats.STAT_CON] = math.floor(eff.con), + [Stats.STAT_DEX] = math.floor(eff.dex), + }) + end, + deactivate = function(self, eff) + end, +} + +newEffect{ + name = "WOEFUL_DARKNESS", image = "effects/bane_blinded.png", + desc = "Woeful Darkness", + long_desc = function(self, eff) return ("The target is weakened and lost, all damage it does is reduced by %d%%."):format(eff.reduce) end, + type = "magical", + subtype = { darkness=true,}, + status = "detrimental", + parameters = {power=10, reduce=5}, + on_gain = function(self, err) return "#Target# is weakened by the darkness!", "+Woeful Darkness" end, + on_lose = function(self, err) return "#Target# looks more determined.", "-Woeful Darkness" end, + on_timeout = function(self, eff) + + end, + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("numbed", eff.reduce) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("numbed", eff.tmpid) + end, +} + +newEffect{ + name = "WOEFUL_CORROSION", image = "talents/acidic_skin.png", + desc = "Woeful Corrosion", + long_desc = function(self, eff) return ("The target has been splashed with acid, taking %0.2f acid damage per turn."):format(eff.dam) end, + type = "magical", + subtype = { acid=true,}, + status = "detrimental", + parameters = {dam = 0}, + on_gain = function(self, err) return "#Target# is covered in acid!" end, + on_lose = function(self, err) return "#Target# is free from the acid." end, + -- Damage each turn + on_timeout = function(self, eff) + DamageType:get(DamageType.ACID).projector(eff.src, self.x, self.y, DamageType.ACID, eff.dam) + end, + activate = function(self, eff) + end, + deactivate = function(self, eff) + end, +} + + newEffect{ name = "EPIDEMIC", image = "talents/epidemic.png", desc = "Epidemic", @@ -2510,47 +2581,6 @@ newEffect{ end, } -newEffect{ - name = "ELEMENTAL_SURGE_ARCANE", image = "talents/elemental_surge.png", - desc = "Elemental Surge: Arcane", - long_desc = function(self, eff) return ("Spellcasting speed increased by 20%") end, - type = "magical", - subtype = { arcane=true }, - status = "beneficial", - parameters = { }, - activate = function(self, eff) - self:effectTemporaryValue(eff, "combat_spellspeed", 0.2) - end, -} - -newEffect{ - name = "ELEMENTAL_SURGE_COLD", image = "talents/elemental_surge.png", - desc = "Elemental Surge: Cold", - long_desc = function(self, eff) return ("Icy Skin: Physical damage reduced by 30%%, armor increased by %d, and deals %d ice damage when hit in melee."):format(eff.armor, eff.dam) end, - type = "magical", - subtype = { arcane=true }, - status = "beneficial", - parameters = {physresist=30, armor=0, dam=100 }, - activate = function(self, eff) - self:effectTemporaryValue(eff, "resists", {[DamageType.PHYSICAL]=eff.physresist}) - self:effectTemporaryValue(eff, "combat_armor", eff.armor) - self:effectTemporaryValue(eff, "on_melee_hit", {[DamageType.ICE]=eff.dam}) - end, -} - -newEffect{ - name = "ELEMENTAL_SURGE_LIGHTNING", image = "talents/elemental_surge.png", - desc = "Elemental Surge: Lightning", - long_desc = function(self, eff) return ("When hit you turn into pure lightning and reappear near where you where, ignoring the blow.") end, - type = "magical", - subtype = { arcane=true }, - status = "beneficial", - parameters = { }, - activate = function(self, eff) - self:effectTemporaryValue(eff, "phase_shift", 1) - end, -} - newEffect{ name = "VULNERABILITY_POISON", image = "talents/vulnerability_poison.png", desc = "Vulnerability Poison", @@ -2615,6 +2645,7 @@ newEffect{ if self:reactionToward(target) < 0 then local dam = eff.dam * (1 + (5 - core.fov.distance(self.x, self.y, target.x, target.y)) / 8) + target:setEffect(target.EFF_WEIGHT_OF_THE_SUN, 2, {reduce = 30}) -- Quickly wears off when outside of AoE DamageType:get(DamageType.FIRE).projector(self, target.x, target.y, DamageType.FIRE, dam/3) DamageType:get(DamageType.LIGHT).projector(self, target.x, target.y, DamageType.LIGHT, dam/3) DamageType:get(DamageType.PHYSICAL).projector(self, target.x, target.y, DamageType.PHYSICAL, dam/3) @@ -2625,6 +2656,21 @@ newEffect{ end, } +newEffect{ + name = "WEIGHT_OF_THE_SUN", image = "talents/irresistible_sun.png", + desc = "Weight of the Sun", + long_desc = function(self, eff) return ("The target is struggling against immense gravity, all damage it does is reduced by %d%%."):format(eff.reduce) end, + type = "magical", + subtype = { sun=true,}, + status = "detrimental", + parameters = {reduce=5}, + on_gain = function(self, err) return "#Target# can barely stand!", "+Weight of the Sun" end, + on_lose = function(self, err) return "#Target# can move freely once more.", "-Weight of the Sun" end, + activate = function(self, eff) + self:effectTemporaryValue(eff, "numbed", eff.reduce) + end, +} + newEffect{ name = "TEMPORAL_FORM", image = "talents/temporal_form.png", desc = "Temporal Form", diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua index 9bb4d1bb66ec2c84dd72774f4d953390bcffc7bb..bb5ec91c1c2ed6c13fe2c3122c9895bcb48432a5 100644 --- a/game/modules/tome/data/timed_effects/other.lua +++ b/game/modules/tome/data/timed_effects/other.lua @@ -25,6 +25,74 @@ local Map = require "engine.Map" local Level = require "engine.Level" local Combat = require "mod.class.interface.Combat" +newEffect{ + name = "ELEMENTAL_SURGE_ARCANE", image = "talents/elemental_surge.png", + desc = "Elemental Surge: Arcane", + long_desc = function(self, eff) return ("Spell and mind speed increased by 30%") end, + type = "other", + subtype = {elemental = true }, + status = "beneficial", + parameters = { }, + activate = function(self, eff) + self:effectTemporaryValue(eff, "combat_spellspeed", 0.3) + self:effectTemporaryValue(eff, "combat_mindspeed", 0.3) + end, +} + +-- Elemental Surge effects here to avoid interaction with duration increases since so many can be up at once +newEffect{ + name = "ELEMENTAL_SURGE_FIRE", image = "talents/elemental_surge.png", + desc = "Elemental Surge: Fire", + long_desc = function(self, eff) return ("All damage increased by %d%%"):format(eff.damage) end, + type = "other", + subtype = {elemental = true }, + status = "beneficial", + parameters = {damage = 30 }, + activate = function(self, eff) + self:effectTemporaryValue(eff,"inc_damage", {all = eff.damage}) + end, +} + +newEffect{ + name = "ELEMENTAL_SURGE_COLD", image = "talents/elemental_surge.png", + desc = "Elemental Surge: Cold", + long_desc = function(self, eff) return ("Armor increased by %d, deals %d ice damage when hit in melee."):format(eff.armor, eff.dam) end, + type = "other", + subtype = {elemental = true }, + status = "beneficial", + parameters = {armor=0, dam=100 }, + activate = function(self, eff) + self:effectTemporaryValue(eff, "combat_armor", eff.armor) + self:effectTemporaryValue(eff, "on_melee_hit", {[DamageType.ICE]=eff.dam}) + end, +} + +newEffect{ + name = "ELEMENTAL_SURGE_LIGHTNING", image = "talents/elemental_surge.png", + desc = "Elemental Surge: Lightning", + long_desc = function(self, eff) return ("Movement speed increased by %d%%."):format(eff.move) end, + type = "other", + subtype = {elemental = true }, + status = "beneficial", + parameters = { move = 50}, + activate = function(self, eff) + self:effectTemporaryValue(eff, "movement_speed", eff.move/100) + end, +} + +newEffect{ + name = "ELEMENTAL_SURGE_LIGHT", image = "talents/elemental_surge.png", + desc = "Elemental Surge: Light", + long_desc = function(self, eff) return ("All talent cooldowns reduced by %d%%."):format(eff.cooldown) end, + type = "other", + subtype = {elemental = true }, + status = "beneficial", + parameters = {cooldown = 20 }, + activate = function(self, eff) + self:effectTemporaryValue(eff, "talent_cd_reduction", {allpct = eff.cooldown / 100}) + end, +} + newEffect{ name = "FLASH_SHIELD", image = "talents/flash_of_the_blade.png", desc = "Protected by the Sun", diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua index 842a4841937c30b05b0792aa920e0cdd7001c1af..0d1cea1cecf2a94ec736ccb22580f0835a459ec5 100644 --- a/game/modules/tome/data/timed_effects/physical.lua +++ b/game/modules/tome/data/timed_effects/physical.lua @@ -2570,19 +2570,6 @@ newEffect{ end, } -newEffect{ - name = "ELEMENTAL_SURGE_NATURE", image = "talents/elemental_surge.png", - desc = "Elemental Surge: Nature", - long_desc = function(self, eff) return ("Immune to physical effects.") end, - type = "physical", - subtype = { status=true }, - status = "beneficial", - parameters = { }, - activate = function(self, eff) - self:effectTemporaryValue(eff, "spell_negative_status_effect_immune", 1) - end, -} - newEffect{ name = "STEAMROLLER", image = "talents/steamroller.png", desc = "Steamroller", diff --git a/game/modules/tome/dialogs/UberTalent.lua b/game/modules/tome/dialogs/UberTalent.lua index c868a6188125f1288c0d366a8f653176dcfa3865..0002db2045d9cbff7e9d9d46c596e77294d769ae 100644 --- a/game/modules/tome/dialogs/UberTalent.lua +++ b/game/modules/tome/dialogs/UberTalent.lua @@ -75,7 +75,7 @@ function _M:generateList() local cols = {} local list = {} for tid, t in pairs(self.actor.talents_def) do - if t.uber then + if t.uber and not t.not_listed then cols[t.type[1]] = cols[t.type[1]] or {} local c = cols[t.type[1]] c[#c+1] = t