diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 8fa6c1a617d6bc0129d6e3745863eeec5f9c271c..d82da5f86e6434236fb3f37b5efceacd7cb6ab66 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -73,10 +73,10 @@ _M.stats_per_level = 3 -- Speeds are multiplicative, not additive _M.temporary_values_conf.global_speed_add = "newest" -_M.temporary_values_conf.movement_speed = "mult0" -_M.temporary_values_conf.combat_physspeed = "mult0" -_M.temporary_values_conf.combat_spellspeed = "mult0" -_M.temporary_values_conf.combat_mindspeed = "mult0" +_M.temporary_values_conf.movement_speed = "add" -- Prevent excessive movement speed compounding +_M.temporary_values_conf.combat_physspeed = "add" -- Prevent excessive attack speed compounding +_M.temporary_values_conf.combat_spellspeed = "add" -- Prevent excessive spell speed compounding +_M.temporary_values_conf.combat_mindspeed = "add" -- Prevent excessive mind speed compounding -- Damage cap takes the lowest _M.temporary_values_conf.flat_damage_cap = "lowest" @@ -1042,7 +1042,7 @@ function _M:move(x, y, force) -- Try to detect traps if self:knowTalent(self.T_HEIGHTENED_SENSES) then - local power = self:getTalentLevel(self.T_HEIGHTENED_SENSES) * self:getCun(25, true) + local power = self:callTalent(self.T_HEIGHTENED_SENSES,"trapPower") local grids = core.fov.circle_grids(self.x, self.y, 1, true) for x, yy in pairs(grids) do for y, _ in pairs(yy) do local trap = game.level.map(x, y, Map.TRAP) @@ -1388,8 +1388,8 @@ function _M:colorStats(stat) return "#0080FF#"..score elseif score <= 99 then return "#8d55ff#"..score - elseif score == 100 then - return "#8d55ff#**" + elseif score >= 100 then + return "#8d55ff#"..score -- Enable longer numbers end end @@ -2052,7 +2052,7 @@ function _M:onTakeHit(value, src) -- Second Life if self:isTalentActive(self.T_SECOND_LIFE) and value >= self.life then - local sl = self.max_life * (0.05 + self:getTalentLevelRaw(self.T_SECOND_LIFE)/25) + local sl = self:callTalent(self.T_SECOND_LIFE,"getLife") value = 0 self.life = sl game.logSeen(self, "%s has been saved by a blast of positive energy!", self.name:capitalize()) @@ -2094,7 +2094,7 @@ function _M:onTakeHit(value, src) if self:knowTalent(self.T_DUCK_AND_DODGE) then local t = self:getTalentFromId(self.T_DUCK_AND_DODGE) if value >= self.max_life * t.getThreshold(self, t) then - self:setEffect(self.EFF_EVASION, t.getDuration(self, t), {chance=t.getEvasionChance(self, t)}) + self:setEffect(self.EFF_EVASION, t.getDuration(self, t), {chance=t.getEvasionChance(self, t), defense = t.getDefense(self)}) end end @@ -2533,8 +2533,7 @@ function _M:resolveLevelTalents() if not self.start_level or not self._levelup_talents then return end local maxfact = 1 -- Balancing parameter for levels > 50: maxtalent level = actorlevel/50*maxfact * normal max talent level - --I5 remove the following statement once all talent scaling is in: - --if game.zone.short_name == "infinite-dungeon" then maxfact=math.max(maxfact,self.level/50) end + maxfact=math.max(maxfact,self.level/50) for tid, info in pairs(self._levelup_talents) do if not info.max or (self.talents[tid] or 0) < math.floor(info.max*maxfact) then @@ -2557,8 +2556,8 @@ function _M:levelup() self.unused_generics = self.unused_generics + 1 if self.level % 5 == 0 then self.unused_talents = self.unused_talents + 1 end if self.level % 5 == 0 then self.unused_generics = self.unused_generics - 1 end - -- At levels 10, 20 and 36 we gain a new talent type - if self.level == 10 or self.level == 20 or self.level == 36 then + -- At levels 10, 20 and 36 and then every 30 levels, we gain a new talent type + if self.level == 10 or self.level == 20 or self.level == 36 or (self.level > 50 and (self.level - 6) % 30 == 0) then self.unused_talents_types = self.unused_talents_types + 1 end if self.level == 30 or self.level == 42 then @@ -2638,7 +2637,10 @@ function _M:levelup() end -- Force levelup of the golem - if self.alchemy_golem then self.alchemy_golem:forceLevelup(self.level) end + if self.alchemy_golem then + self.alchemy_golem.max_level = self.max_level -- make sure golem can level up with master + self.alchemy_golem:forceLevelup(self.level) + end -- Notify party levelups if self.x and self.y and game.party:hasMember(self) and not self.silent_levelup then @@ -2703,8 +2705,8 @@ function _M:onStatChange(stat, v) end function _M:recomputeGlobalSpeed() - if self.global_speed_add > 0 then self.global_speed = self.global_speed_base + self.global_speed_add - else self.global_speed = self.global_speed_base * math.exp(self.global_speed_add) + if self.global_speed_add >= 0 then self.global_speed = self.global_speed_base + self.global_speed_add + else self.global_speed = self.global_speed_base / (1 + math.abs(self.global_speed_add)) -- Symmetric scaling end self.global_speed = math.max(self.global_speed, 0.1) end @@ -4576,7 +4578,7 @@ function _M:on_set_temporary_effect(eff_id, e, p) end if e.status == "detrimental" and self:knowTalent(self.T_RESILIENT_BONES) then - p.dur = math.ceil(p.dur * (1 - util.bound(self:getTalentLevel(self.T_RESILIENT_BONES) / 12, 0, 1))) + p.dur = math.ceil(p.dur * (1 - self:callTalent(self.T_RESILIENT_BONES,"durresist"))) end if e.status == "detrimental" and e.type ~= "other" and self:attr("reduce_detrimental_status_effects_time") then local power = util.bound(self.reduce_detrimental_status_effects_time, 0, 100) diff --git a/game/modules/tome/class/Store.lua b/game/modules/tome/class/Store.lua index 5c79f27576e1cdc6e976e5b167ce08555015ef5f..96a979cb4d25adb8c01fc97f85bf05c6670b85af 100644 --- a/game/modules/tome/class/Store.lua +++ b/game/modules/tome/class/Store.lua @@ -31,7 +31,9 @@ end function _M:init(t, no_default) t.store.buy_percent = t.store.buy_percent or function(self, o) if o.type == "gem" then return 40 else return 5 end end - t.store.sell_percent = t.store.sell_percent or function(self, o) return 120 + 3 * (o.__store_level or 0) end -- Stores prices goes up with item level + t.store.sell_percent = t.store.sell_percent or function(self, o) -- Store prices goes up with item level + return mod.class.interface.Combat:combatTalentScale(math.max(1, o.__store_level or 1), 123, 135, "log") + end t.store.nb_fill = t.store.nb_fill or 10 t.store.purse = t.store.purse or 20 Store.init(self, t, no_default) diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 68455a0ad3d546455598101bf4032ead00b9891b..4b046bf574c2951b96d4ef18c71d5683edc92e69 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -384,7 +384,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) elseif self:checkHit(atk, def) and (self:canSee(target) or self:attr("blind_fight") or rng.chance(3)) then local pres = util.bound(target:combatArmorHardiness() / 100, 0, 1) if target.knowTalent and target:hasEffect(target.EFF_DUAL_WEAPON_DEFENSE) then - local deflect = target:callTalent(target.T_DUAL_WEAPON_DEFENSE, "doDeflect") + local deflect = math.max(dam, target:callTalent(target.T_DUAL_WEAPON_DEFENSE, "doDeflect")) if deflect > 0 then game.logSeen(target, "%s parries %d damage from %s's attack.", target.name:capitalize(), deflect, self.name:capitalize()) dam = math.max(dam - deflect,0) @@ -1121,11 +1121,11 @@ function _M:combatCrit(weapon) weapon = weapon or self.combat or {} local addcrit = 0 if weapon.talented and self:knowTalent(Talents.T_LETHALITY) then - addcrit = 1 + self:getTalentLevel(Talents.T_LETHALITY) * 1.3 + addcrit = 1 + self:callTalent(Talents.T_LETHALITY, "getCriticalChance") end local crit = self.combat_physcrit + (self:getCun() - 10) * 0.3 + (self:getLck() - 50) * 0.30 + (weapon.physcrit or 1) + addcrit - return util.bound(crit, 0, 100) + return math.max(crit, 0) -- note: crit > 100% may be offset by crit reduction elsewhere end --- Gets the damage range @@ -1352,7 +1352,7 @@ function _M:combatPhysicalpower(mod, weapon, add) mod = mod or 1 add = add or 0 if self:knowTalent(Talents.T_ARCANE_DESTRUCTION) then - add = add + self:combatSpellpower() * self:getTalentLevel(Talents.T_ARCANE_DESTRUCTION) / 7 + add = add + self:combatSpellpower() * self:callTalent(Talents.T_ARCANE_DESTRUCTION, "getSPMult") end if self:isTalentActive(Talents.T_BLOOD_FRENZY) then add = add + self.blood_frenzy @@ -1372,7 +1372,7 @@ function _M:combatPhysicalpower(mod, weapon, add) add = add + 10 * self:combatCheckTraining(weapon) - local d = (self.combat_dam > 0 and self.combat_dam or 0) + add + self:getStr() + local d = math.max(0, self.combat_dam + add) + self:getStr() -- allows strong debuffs to offset strength if self:attr("dazed") then d = d / 2 end return self:rescaleCombatStats(d) * mod end @@ -1396,7 +1396,7 @@ function _M:combatSpellpower(mod, add) add = add + self:callTalent(self.T_SHADOW_CUNNING,"getSpellpower") * self:getCun() / 100 end if self:hasEffect(self.EFF_BLOODLUST) then - add = add + self:hasEffect(self.EFF_BLOODLUST).dur + add = add + self:hasEffect(self.EFF_BLOODLUST).power end local am = 1 @@ -1542,9 +1542,9 @@ function _M:physicalCrit(dam, weapon, target, atk, def, add_chance, crit_power_a chance = chance - target:callTalent(target.T_SCOUNDREL,"getCritPenalty") end - if self:isTalentActive(self.T_STEALTH) and self:knowTalent(self.T_SHADOWSTRIKE) then + if self:attr("stealth") and self:knowTalent(self.T_SHADOWSTRIKE) and not target:canSee(self) then -- bug fix chance = 100 - crit_power_add = crit_power_add + self:getTalentLevel(self.T_SHADOWSTRIKE) / 7 + crit_power_add = crit_power_add + self:callTalent(self.T_SHADOWSTRIKE,"getMultiplier") end chance = util.bound(chance, 0, 100) @@ -1572,9 +1572,9 @@ function _M:spellCrit(dam, add_chance, crit_power_add) local chance = self:combatSpellCrit() + (add_chance or 0) local crit = false - if self:isTalentActive(self.T_STEALTH) and self:knowTalent(self.T_SHADOWSTRIKE) then + if self:attr("stealth") and self:knowTalent(self.T_SHADOWSTRIKE) and not target:canSee(self) then -- bug fix chance = 100 - crit_power_add = crit_power_add + self:getTalentLevel(self.T_SHADOWSTRIKE) / 7 + crit_power_add = crit_power_add + self:callTalent(self.T_SHADOWSTRIKE,"getMultiplier") end print("[SPELL CRIT %]", chance) @@ -1619,9 +1619,9 @@ function _M:mindCrit(dam, add_chance, crit_power_add) local chance = self:combatMindCrit() + (add_chance or 0) local crit = false - if self:isTalentActive(self.T_STEALTH) and self:knowTalent(self.T_SHADOWSTRIKE) then + if self:attr("stealth") and self:knowTalent(self.T_SHADOWSTRIKE) and not target:canSee(self) then -- bug fix chance = 100 - crit_power_add = crit_power_add + self:getTalentLevel(self.T_SHADOWSTRIKE) / 7 + crit_power_add = crit_power_add + self:callTalent(self.T_SHADOWSTRIKE,"getMultiplier") end print("[MIND CRIT %]", chance) @@ -1721,7 +1721,7 @@ function _M:combatPhysicalResist(fake) add = add + self:getCon() / 3 end if self:knowTalent(self.T_POWER_IS_MONEY) then - add = add + util.bound(self.money / (90 - self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 5), 0, self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 7) + add = add + self:callTalent(self.T_POWER_IS_MONEY, "getSaves") end -- To return later @@ -1749,7 +1749,7 @@ function _M:combatSpellResist(fake) add = add + self:getCon() / 3 end if self:knowTalent(self.T_POWER_IS_MONEY) then - add = add + util.bound(self.money / (90 - self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 5), 0, self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 7) + add = add + self:callTalent(self.T_POWER_IS_MONEY, "getSaves") end -- To return later @@ -1781,11 +1781,16 @@ function _M:combatMentalResist(fake) add = add + t.getMental(self, t) end if self:knowTalent(self.T_POWER_IS_MONEY) then - add = add + util.bound(self.money / (90 - self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 5), 0, self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 7) + add = add + self:callTalent(self.T_POWER_IS_MONEY, "getSaves") end local d = self.combat_mentalresist + (self:getCun() + self:getWil() + (self:getLck() - 50) * 0.5) * 0.35 + add if self:attr("dazed") then d = d / 2 end + + local nm = self:hasEffect(self.EFF_CURSE_OF_NIGHTMARES) + if nm and rng.percent(20) then + d = d * (1-self.tempeffect_def.EFF_CURSE_OF_NIGHTMARES.getVisionsReduction(nm, nm.level)/100) + end return self:rescaleCombatStats(d) end @@ -1808,8 +1813,8 @@ function _M:combatGetResist(type) power = self.force_use_resist_percent or 100 end - local a = (self.resists.all or 0) / 100 - local b = (self.resists[type] or 0) / 100 + local a = math.min((self.resists.all or 0) / 100,1) -- Prevent large numbers from inverting the resist formulas + local b = math.min((self.resists[type] or 0) / 100,1) local r = math.min(100 * (1 - (1 - a) * (1 - b)), (self.resists_cap.all or 0) + (self.resists_cap[type] or 0)) return r * power / 100 end @@ -1862,7 +1867,7 @@ function _M:combatSeeStealth() if self:knowTalent(self.T_PIERCING_SIGHT) then bonus = bonus + self:callTalent(self.T_PIERCING_SIGHT,"seePower") end if self:knowTalent(self.T_PRETERNATURAL_SENSES) then bonus = bonus + self:callTalent(self.T_PRETERNATURAL_SENSES, "sensePower") end -- level 50 with 100 cun ==> 50 - return self:combatScale(self.level/2 + self:getCun(25, true) + (self:attr("see_stealth") or 0), 0, 0, 50, 50) + bonus -- Note bonus scaled separately from talents + return self:combatScale(self.level/2 + self:getCun()/4 + (self:attr("see_stealth") or 0), 0, 0, 50, 50) + bonus -- Note bonus scaled separately from talents end --- Computes see invisible diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 9539ee7131bcf96b1b58047d64284beb389fcf71..2e558872e0a2a5469c3d6a2cebaa8ff26645984f 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -1639,9 +1639,8 @@ newDamageType{ if target and (target:attr("undead") or target.retch_heal) then target:heal(dam * 1.5) - if src.getTalentLevel then - local tl = src:getTalentLevel(src.T_RETCH) - if rng.percent(tl * 5) then + if src.callTalent then + if rng.percent(src:callTalent(src.T_RETCH, "getPurgeChance")) then local effs = {} local status = "detrimental" for eff_id, p in pairs(target.tmp) do @@ -1659,9 +1658,8 @@ newDamageType{ elseif target then DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam) - if src.getTalentLevel then - local tl = src:getTalentLevel(src.T_RETCH) - if rng.percent(tl * 5) then + if src.callTalent then + if rng.percent(src:callTalent(src.T_RETCH, "getPurgeChance")) then local effs = {} local status = "beneficial" for eff_id, p in pairs(target.tmp) do diff --git a/game/modules/tome/data/maps/vaults/paladin-vs-vampire.lua b/game/modules/tome/data/maps/vaults/paladin-vs-vampire.lua index 19cef2f6867606667b65d0602b24f4a7ccda6f1b..83f0f47c15a93de96c70722f791acb84019117dd 100644 --- a/game/modules/tome/data/maps/vaults/paladin-vs-vampire.lua +++ b/game/modules/tome/data/maps/vaults/paladin-vs-vampire.lua @@ -49,7 +49,7 @@ defineTile('S', "FLOOR", nil, mod.class.NPC.new{ faction = "sunwall", hard_faction = "sunwall", body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, desc = [[A Human in shining plate armour.]], - level_range = {10, 50}, exp_worth = 1, + level_range = {10, nil}, exp_worth = 1, rank = 2, size_category = 3, autolevel = "warriormage", @@ -64,14 +64,14 @@ defineTile('S', "FLOOR", nil, mod.class.NPC.new{ {type="armor", subtype="massive", autoreq=true}, }, resolvers.talents{ - [Talents.T_ARMOUR_TRAINING]=3, - [Talents.T_CHANT_OF_FORTRESS]=3, - [Talents.T_SEARING_LIGHT]=2, - [Talents.T_MARTYRDOM]=2, - [Talents.T_WEAPON_OF_LIGHT]=2, - [Talents.T_FIREBEAM]=2, - [Talents.T_WEAPON_COMBAT]=4, - [Talents.T_HEALING_LIGHT]=2, + [Talents.T_ARMOUR_TRAINING]={base = 3, every = 4, max = 10}, + [Talents.T_CHANT_OF_FORTRESS]={base = 1, every = 6, max = 5}, + [Talents.T_SEARING_LIGHT]={base = 1, every = 5, max = 5}, + [Talents.T_MARTYRDOM]={base=2, every= 7, max = 5}, + [Talents.T_WEAPON_OF_LIGHT]={base = 1, every = 5, max = 5}, + [Talents.T_FIREBEAM]={base = 5, every = 7, max = 5}, + [Talents.T_WEAPON_COMBAT]={base = 4, every = 7, max = 5}, + [Talents.T_HEALING_LIGHT]={base = 2, every = 7, max = 5}, }, on_added = function(self) self.energy.value = game.energy_to_act self:useTalent(self.T_WEAPON_OF_LIGHT) diff --git a/game/modules/tome/data/talents/cunning/lethality.lua b/game/modules/tome/data/talents/cunning/lethality.lua index 33a30ff20fc6a844b69639b777a24737b6723019..d442e5678f407fee8f5bae167b0700305dd81f53 100644 --- a/game/modules/tome/data/talents/cunning/lethality.lua +++ b/game/modules/tome/data/talents/cunning/lethality.lua @@ -24,6 +24,7 @@ newTalent{ points = 5, require = cuns_req1, critpower = function(self, t) return self:combatTalentScale(t, 7.5, 25, 0.75) end, + -- called by _M:combatCrit in mod.class.interface.Combat.lua getCriticalChance = function(self, t) return self:combatTalentScale(t, 2.3, 7.5, 0.75) end, passives = function(self, t, p) self:talentTemporaryValue(p, "combat_critical_power", t.critpower(self, t)) diff --git a/game/modules/tome/data/talents/cursed/gestures.lua b/game/modules/tome/data/talents/cursed/gestures.lua index fa5fa98cdabaa59c29a2b118915e3576fc59cdda..d36fe3fe0fa725a34d9a73705b5b9521635a2811 100644 --- a/game/modules/tome/data/talents/cursed/gestures.lua +++ b/game/modules/tome/data/talents/cursed/gestures.lua @@ -79,7 +79,7 @@ newTalent{ getStunChance = function(self, t) return self:combatTalentLimit(t, 50, 12, 20) end, -- Limit < 50% preAttack = function(self, t, target) if not canUseGestures(self) then - game.logPlayer(self, "You do not have a free or mindstar-equipped hand to use Gesture of Pain.") + game.logPlayer(self, "You require two free or mindstar-equipped hands to use Gesture of Pain.") return false end @@ -87,7 +87,6 @@ newTalent{ end, attack = function(self, t, target) local hit = false - local mindpower = self:combatMindpower() local baseDamage = t.getBaseDamage(self, t) local bonusDamage = t.getBonusDamage(self, t) diff --git a/game/modules/tome/data/talents/misc/horrors.lua b/game/modules/tome/data/talents/misc/horrors.lua index 03bbc1894ae086e7bd0acfefa1e1c9420110754b..44d945f5baa87a6cdd26edc40ba95e78b274c41b 100644 --- a/game/modules/tome/data/talents/misc/horrors.lua +++ b/game/modules/tome/data/talents/misc/horrors.lua @@ -41,7 +41,7 @@ newTalent{ on_pre_use = function(self, t, silent) if not self:hasEffect(self.EFF_FRENZY) then return false end return true end, getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1, 1.7) end, getBleedDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.5, 3) end, - getHealingPenalty = function(self, t) return self:getTalentLevel(t) * 10 end, + getHealingPenalty = function(self, t) return self:combatTalentLimit(t, 100, 15, 50) end, -- Limit to <100% action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -73,7 +73,7 @@ newTalent{ tactical = { CLOSEIN = 3 }, direct_hit = true, message = "@Source@ leaps forward in a frenzy!", - range = function(self, t) return math.floor(2 + self:getTalentLevel(t)) end, + range = function(self, t) return math.floor(self:combatTalentScale(t, 2.4, 10)) end, requires_target = true, on_pre_use = function(self, t, silent) if not self:hasEffect(self.EFF_FRENZY) or self:attr("encased_in_ice") or self:attr("never_move") then return false end return true end, action = function(self, t) @@ -119,7 +119,9 @@ newTalent{ tactical = { ATTACK = { PHYSICAL = 2 } }, getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.5, 1) end, getBleedDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.8, 1.5) end, - getPower = function(self, t) return self:combatTalentStatDamage(t, "con", 10, 50) end, + -- Limit crit, speed increase, -health to <100% + getPower = function(self, t) return self:combatLimit(self:combatTalentStatDamage(t, "con", 10, 50), 1, 0, 0, 0.357, 35.7) end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, do_devourer_frenzy = function(self, target, t) game.logSeen(self, "The scent of blood sends the %ss into a frenzy!", self.name:capitalize()) -- frenzy devourerers @@ -140,7 +142,7 @@ newTalent{ reapplied = true end end - target:setEffect(target.EFF_FRENZY, math.floor(2 + self:getTalentLevel(t)), {crit = t.getPower(self, t), power=t.getPower(self, t)/50, dieat=t.getPower(self, t)/50}, reapplied) + target:setEffect(target.EFF_FRENZY, t.getDuration(self, t), {crit = t.getPower(self, t)*100, power=t.getPower(self, t), dieat=t.getPower(self, t)}, reapplied) end end end) @@ -164,8 +166,11 @@ newTalent{ info = function(self, t) local damage = t.getDamage(self, t) * 100 local bleed = t.getBleedDamage(self, t) * 100 + local power = t.getPower(self, t) *100 return ([[Bites the target for %d%% weapon damage, potentially causing it to bleed for %d%% weapon damage over five turns. - If the target is affected by the bleed it will send the devourer into a frenzy (which in turn will frenzy nearby devourers).]]):format(damage, bleed) + If the target is affected by the bleed it will send the devourer into a frenzy for %d turns (which in turn will frenzy other nearby devourers). + The frenzy will increase global speed by %d%%, physical crit chance by %d%%, and prevent death until -%d%% life.]]): + format(damage, bleed, t.getDuration(self, t), power, power, power) end, } @@ -187,8 +192,8 @@ newTalent{ end, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 15, 40) end, getDarknessPower = function(self, t) return self:combatTalentSpellDamage(t, 15, 40) end, - getLiteReduction = function(self, t) return self:getTalentLevelRaw(t) end, - getDuration = function(self, t) return 4 + math.ceil(self:getTalentLevel(t)) end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 5, 9)) end, + getLiteReduction = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5)) end, action = function(self, t) local tg = self:getTalentTarget(t) local x, y = self:getTarget(tg) @@ -270,7 +275,7 @@ newTalent{ is_summon = true, getDamage = function(self, t) return self:combatTalentMindDamage(t, 5, 50) end, getExplosion = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end, - getSummonTime = function(self, t) return 6 + math.ceil(self:getTalentLevel(t)) end, + getSummonTime = function(self, t) return math.floor(self:combatTalentScale(t, 7, 11)) end, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local tx, ty, target = self:getTarget(tg) @@ -356,7 +361,7 @@ newTalent{ tactical = { ATTACK = { ACID = 1, BLIGHT = 1 }, DISABLE = 4 }, getBurstDamage = function(self, t) return self:combatTalentSpellDamage(t, 30, 300) end, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 5, 50) end, - getDuration = function(self, t) return 4 + math.ceil(self:getTalentLevel(t)) end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 5, 9)) end, proj_speed = 6, spawn_carrion_worm = function (self, target, t) local x, y = util.findFreeGrid(target.x, target.y, 10, true, {[Map.ACTOR]=true}) @@ -419,7 +424,9 @@ newTalent{ return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false} end, getDamage = function(self, t) return self:combatTalentMindDamage(t, 5, 85) end, - getDuration = function(self, t) return 3 + self:combatMindpower(0.05) + self:getTalentLevel(t)/2 end, + getDuration = function(self, t) return + math.floor(self:combatScale(self:combatMindpower(0.05) + self:getTalentLevel(t)/2, 3, 0, 8.33, 5.33)) + end, action = function(self, t) -- Add a lasting map effect game.level.map:addEffect(self, @@ -441,7 +448,7 @@ newTalent{ info = function(self, t) local damage = t.getDamage(self, t) local duration = t.getDuration(self, t) - return ([[Summon a storm of swirling blades to slice your foes, inflicting physical damage and bleeding to anyone who approaches. + return ([[Summon a storm of swirling blades to slice your foes, inflicting %d physical damage and bleeding to anyone who approaches for %d turns. The damage and duration will increase with your Mindpower.]]):format(damDesc(self, DamageType.PHYSICAL, damage), duration) end, } @@ -567,7 +574,7 @@ newTalent{ tactical = { DISABLE = 1, CLOSEIN = 3 }, requires_target = true, getDamage = function(self, t) return self:mindCrit(self:combatTalentMindDamage(t, 5, 50)) end, - getDuration = function(self, t) return 2 + math.ceil(self:getTalentLevel(t)) end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) local tg = {type="bolt", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) @@ -640,9 +647,7 @@ newTalent{ cooldown = 20, tactical = { CLOSEIN = 2 }, requires_target = true, - range = function(self, t) - return 5 + self:getTalentLevel(t) - end, + range = function(self, t) return math.floor(self:combatTalentScale(t, 6, 10)) end, radius = function(self, t) return 1-- util.bound(4 - self:getTalentLevel(t) / 2, 1, 4) end, diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua index cd3834446e65f901985694fc4f038fa16e632f57..0c10a3d2c657c31f7a9f18fac1bc73298f8fdaab 100644 --- a/game/modules/tome/data/talents/misc/npcs.lua +++ b/game/modules/tome/data/talents/misc/npcs.lua @@ -82,18 +82,20 @@ newTalent{ range = 1, requires_target = true, tactical = { ATTACK = { NATURE = 1, poison = 1} }, + getMult = function(self, t) return self:combatTalentScale(t, 3, 7, "log") end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) if not x or not y or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end self.combat_apr = self.combat_apr + 1000 - self:attackTarget(target, DamageType.POISON, 2 + self:getTalentLevel(t), true) + self:attackTarget(target, DamageType.POISON, t.getMult(self, t), true) self.combat_apr = self.combat_apr - 1000 return true end, info = function(self, t) - return ([[Crawl onto the target, covering it in poison.]]) + return ([[Crawl onto the target, doing %d%% damage and covering it in poison.]]): + format(100*t.getMult(self, t)) end, } @@ -132,6 +134,7 @@ newTalent{ range = 1, tactical = { DISABLE = { blind = 2 } }, requires_target = true, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 6, 10)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -139,10 +142,10 @@ newTalent{ if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end local hit = self:attackTarget(target, DamageType.LIGHT, self:combatTalentWeaponDamage(t, 1, 1.8), true) - -- Try to stun ! + -- Try to blind ! if hit then if target:canBe("blind") then - target:setEffect(target.EFF_BLINDED, math.ceil(5 + self:getTalentLevel(t)), {apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_BLINDED, t.getDuration(self, t), {apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the blindness blow!", target.name:capitalize()) end @@ -151,7 +154,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Releases blinding spores at the target.]]) + return ([[Releases stinging spores at the target, blinding it for %d turns.]]): + format(t.getDuration(self, t)) end, } @@ -165,18 +169,20 @@ newTalent{ range = 1, tactical = { ATTACK = { NATURE = 1, poison = 1} }, requires_target = true, + getMult = function(self, t) return self:combatTalentScale(t, 3, 7, "log") end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) if not x or not y or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end self.combat_apr = self.combat_apr + 1000 - self:attackTarget(target, DamageType.POISON, 2 + self:getTalentLevel(t), true) + self:attackTarget(target, DamageType.POISON, t.getMult(self, t), true) self.combat_apr = self.combat_apr - 1000 return true end, info = function(self, t) - return ([[Releases poisonous spores at the target.]]) + return ([[Releases poisonous spores at the target, doing %d%% damage and poisoning it.]]): + format(100 * t.getMult(self, t)) end, } @@ -189,6 +195,7 @@ newTalent{ require = { stat = { str=12 }, }, tactical = { ATTACK = { PHYSICAL = 1 }, DISABLE = { stun = 2 } }, requires_target = true, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -199,7 +206,7 @@ newTalent{ -- Try to stun ! if hit then if target:canBe("stun") then - target:setEffect(target.EFF_STUNNED, 2 + self:getTalentLevel(t), {apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_STUNNED, t.getDuration(self, t), {apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the stunning blow!", target.name:capitalize()) end @@ -208,7 +215,9 @@ newTalent{ return true end, info = function(self, t) - return ([[Hits the target doing %d%% damage. If the attack hits, the target is stunned. The chance to stun improves with your Physical Power.]]):format(100 * self:combatTalentWeaponDamage(t, 0.5, 1)) + return ([[Hits the target doing %d%% damage. If the attack hits, the target is stunned for %d turns. + The chance to stun improves with your Physical Power.]]): + format(100 * self:combatTalentWeaponDamage(t, 0.5, 1), t.getDuration(self, t)) end, } @@ -221,6 +230,7 @@ newTalent{ require = { stat = { str=12 }, }, requires_target = true, tactical = { ATTACK = { PHYSICAL = 1 }, DISABLE = { disarm = 2 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -229,7 +239,7 @@ newTalent{ local hit = self:attackTarget(target, nil, self:combatTalentWeaponDamage(t, 0.5, 1), true) if hit and target:canBe("disarm") then - target:setEffect(target.EFF_DISARMED, 2 + self:getTalentLevel(t), {apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_DISARMED, t.getDuration(self, t), {apply_power=self:combatPhysicalpower()}) target:crossTierEffect(target.EFF_DISARMED, self:combatPhysicalpower()) else game.logSeen(target, "%s resists the blow!", target.name:capitalize()) @@ -238,7 +248,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Hits the target doing %d%% damage and trying to disarm the target. The chance improves with your Physical Power.]]):format(100 * self:combatTalentWeaponDamage(t, 0.5, 1)) + return ([[Hits the target doing %d%% damage and trying to disarm the target for %d turns. The chance improves with your Physical Power.]]): + format(100 * self:combatTalentWeaponDamage(t, 0.5, 1), t.getDuration(self, t)) end, } @@ -251,6 +262,7 @@ newTalent{ require = { stat = { str=12 }, }, requires_target = true, tactical = { ATTACK = { PHYSICAL = 2 }, DISABLE = { stun = 1 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 15, 52)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -258,10 +270,10 @@ newTalent{ if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end local hit = self:attackTarget(target, nil, self:combatTalentWeaponDamage(t, 0.5, 1), true) - -- Try to stun ! + -- Try to constrict ! if hit then if target:canBe("pin") then - target:setEffect(target.EFF_CONSTRICTED, (2 + self:getTalentLevel(t)) * 10, {src=self, power=1.5 * self:getTalentLevel(t), apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_CONSTRICTED, t.getDuration(self, t), {src=self, power=1.5 * self:getTalentLevel(t), apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the constriction!", target.name:capitalize()) end @@ -270,7 +282,9 @@ newTalent{ return true end, info = function(self, t) - return ([[Hits the target doing %d%% damage. If the attack hits, the target is constricted. The constriction power improves with your Physical Power.]]):format(100 * self:combatTalentWeaponDamage(t, 0.5, 1)) + return ([[Hits the target doing %d%% damage. If the attack hits, the target is constricted for %d turns. + The constriction power improves with your Physical Power.]]): + format(100 * self:combatTalentWeaponDamage(t, 0.5, 1), t.getDuration(self, t)) end, } @@ -317,16 +331,17 @@ newTalent{ range = 1, tactical = { ATTACK = { NATURE = 1, poison = 1} }, requires_target = true, + getMult = function(self, t) return self:combatTalentScale(t, 3, 7, "log") end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) if not x or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end - self:attackTarget(target, DamageType.POISON, 2 + self:getTalentLevel(t), true) + self:attackTarget(target, DamageType.POISON, t.getMult(self, t), true) return true end, info = function(self, t) - return ([[Bites the target, infecting it with poison.]]) + return ([[Bites the target, doing %d%% damage and injecting it with poison.]]):format(100 * t.getMult(self, t)) end, } @@ -401,6 +416,7 @@ newTalent{ message = "@Source@ diseases @target@.", requires_target = true, tactical = { ATTACK = { BLIGHT = 2 }, DISABLE = { disease = 1 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 13, 25)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -411,7 +427,7 @@ newTalent{ -- Try to rot ! if hit then if target:canBe("disease") then - target:setEffect(target.EFF_ROTTING_DISEASE, 10 + self:getTalentLevel(t) * 3, {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, con=math.floor(4 + target:getCon() * 0.1), apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_ROTTING_DISEASE, t.getDuration(self, t), {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, con=math.floor(4 + target:getCon() * 0.1), apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the disease!", target.name:capitalize()) end @@ -420,7 +436,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Hits the target doing %d%% damage. If the attack hits, the target is diseased.]]):format(100 * self:combatTalentWeaponDamage(t, 0.5, 1)) + return ([[Hits the target doing %d%% damage. If the attack hits, the target is afflicted with a disease, inflicting %d blight damage per turn for %d turns and reducing constitution.]]): + format(100 * self:combatTalentWeaponDamage(t, 0.5, 1),damDesc(self, DamageType.BLIGHT,self:getStr() / 3 + self:getTalentLevel(t) * 2),t.getDuration(self, t)) end, } @@ -432,6 +449,7 @@ newTalent{ message = "@Source@ diseases @target@.", tactical = { ATTACK = { BLIGHT = 2 }, DISABLE = { disease = 1 } }, requires_target = true, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 13, 25)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -442,7 +460,7 @@ newTalent{ -- Try to rot ! if hit then if target:canBe("disease") then - target:setEffect(target.EFF_DECREPITUDE_DISEASE, 10 + self:getTalentLevel(t) * 3, {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, dex=math.floor(4 + target:getDex() * 0.1), apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_DECREPITUDE_DISEASE, t.getDuration(self, t), {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, dex=math.floor(4 + target:getDex() * 0.1), apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the disease!", target.name:capitalize()) end @@ -451,7 +469,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Hits the target doing %d%% damage. If the attack hits, the target is diseased.]]):format(100 * self:combatTalentWeaponDamage(t, 0.5, 1)) + return ([[Hits the target doing %d%% damage. If the attack hits, the target is afflicted with a disease, inflicting %d blight damage per turn for %d turns and reducing dexterity.]]): + format(100 * self:combatTalentWeaponDamage(t, 0.5, 1),damDesc(self, DamageType.BLIGHT,self:getStr() / 3 + self:getTalentLevel(t) * 2),t.getDuration(self, t)) end, } @@ -463,6 +482,7 @@ newTalent{ message = "@Source@ diseases @target@.", requires_target = true, tactical = { ATTACK = { BLIGHT = 2 }, DISABLE = { disease = 1 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 13, 25)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -473,7 +493,7 @@ newTalent{ -- Try to rot ! if hit then if target:canBe("disease") then - target:setEffect(target.EFF_WEAKNESS_DISEASE, 10 + self:getTalentLevel(t) * 3, {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, str=math.floor(4 + target:getStr() * 0.1), apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_WEAKNESS_DISEASE, t.getDuration(self, t), {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, str=math.floor(4 + target:getStr() * 0.1), apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the disease!", target.name:capitalize()) end @@ -482,7 +502,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Hits the target doing %d%% damage. If the attack hits, the target is diseased.]]):format(100 * self:combatTalentWeaponDamage(t, 0.5, 1)) + return ([[Hits the target doing %d%% damage. If the attack hits, the target is afflicted with a disease, inflicting %d blight damage per turn for %d turns and reducing strength.]]): + format(100 * self:combatTalentWeaponDamage(t, 0.5, 1),damDesc(self, DamageType.BLIGHT,self:getStr() / 3 + self:getTalentLevel(t) * 2),t.getDuration(self, t)) end, } @@ -496,15 +517,16 @@ newTalent{ direct_hit = true, requires_target = true, tactical = { DISABLE = { confusion = 3 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.CONFUSION, {dur=2+self:getTalentLevel(t), dam=50+self:getTalentLevelRaw(t)*10}, {type="manathrust"}) + self:project(tg, x, y, DamageType.CONFUSION, {dur=t.getDuration(self, t), dam=50+self:getTalentLevelRaw(t)*10}, {type="manathrust"}) return true end, info = function(self, t) - return ([[Try to confuse the target's mind for a while.]]) + return ([[Try to confuse the target's mind for %d turns.]]):format(t.getDuration(self, t)) end, } @@ -518,17 +540,19 @@ newTalent{ reflectable = true, tactical = { ATTACK = { COLD = 1 } }, requires_target = true, + getDamage = function(self, t) return self:combatScale(self:combatSpellpower() * self:getTalentLevel(t), 12, 0, 78.25, 265, 0.67) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.COLD, self:spellCrit(12 + self:combatSpellpower(0.25) * self:getTalentLevel(t)), {type="freeze"}) + self:project(tg, x, y, DamageType.COLD, self:spellCrit(t.getDamage(self, t)), {type="freeze"}) game:playSoundNear(self, "talents/ice") return true end, info = function(self, t) - return ([[Condenses ambient water on a target, damaging it for %0.2f. - The damage will increase with your Spellpower.]]):format(12 + self:combatSpellpower(0.25) * self:getTalentLevel(t)) + return ([[Condenses ambient water on a target, inflicting %0.1f cold damage. + The damage will increase with your Spellpower.]]): + format(damDesc(self, DamageType.COLD,t.getDamage(self, t))) end, } @@ -543,17 +567,19 @@ newTalent{ reflectable = true, requires_target = true, tactical = { DISABLE = { stun = 2 }, ATTACK = { COLD = 1 } }, + getDamage = function(self, t) return self:combatScale(self:combatSpellpower() * self:getTalentLevel(t), 12, 0, 65, 265, 0.67) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.COLDSTUN, self:spellCrit(12 + self:combatSpellpower(0.20) * self:getTalentLevel(t)), {type="freeze"}) + self:project(tg, x, y, DamageType.COLDSTUN, self:spellCrit(t.getDamage(self, t)), {type="freeze"}) game:playSoundNear(self, "talents/ice") return true end, info = function(self, t) - return ([[Condenses ambient water on a target, damaging it for %0.2f and stunning it for 4 turns. - The damage will increase with your Spellpower]]):format(12 + self:combatSpellpower(0.20) * self:getTalentLevel(t)) + return ([[Condenses ambient water on a target, inflicting %0.1f cold damage and stunning it for 4 turns. + The damage will increase with your Spellpower]]): + format(damDesc(self, DamageType.COLD,t.getDamage(self, t))) end, } @@ -597,7 +623,7 @@ newTalent{ end return nb end }, - getCureCount = function(self, t) return math.floor(self:getTalentLevel(t)) end, + getCureCount = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5, "log")) end, action = function(self, t) local target = self local effs = {} @@ -660,6 +686,7 @@ newTalent{ require = { stat = { str=12 }, }, requires_target = true, tactical = { DISABLE = { pin = 2 }, ATTACK = { PHYSICAL = 1 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 2, 6)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -667,10 +694,10 @@ newTalent{ if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end local hit = self:attackTarget(target, nil, self:combatTalentWeaponDamage(t, 0.8, 1.4), true) - -- Try to stun ! + -- Try to pin ! if hit then if target:canBe("pin") then - target:setEffect(target.EFF_PINNED, 1 + self:getTalentLevel(t), {apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_PINNED, t.getDuration(self, t), {apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the grab!", target.name:capitalize()) end @@ -679,7 +706,7 @@ newTalent{ return true end, info = function(self, t) - return ([[Hits the target doing %d%% damage; if the attack hits, the target is pinned to the ground.]]):format(100 * self:combatTalentWeaponDamage(t, 0.8, 1.4)) + return ([[Hits the target doing %d%% damage; if the attack hits, the target is pinned to the ground for %d turns.]]):format(100 * self:combatTalentWeaponDamage(t, 0.8, 1.4), t.getDuration(self, t)) end, } @@ -691,17 +718,13 @@ newTalent{ cooldown = 12, message = "@Source@ projects ink!", range = 0, - radius = function(self, t) - return 4 + self:getTalentLevelRaw(t) - end, + radius = function(self, t) return math.floor(self:combatTalentScale(t, 5, 9)) end, direct_hit = true, requires_target = true, target = function(self, t) return {type="cone", range=self:getTalentRadius(t), radius=self:getTalentRadius(t), selffire=false, talent=t} end, - getDuration = function(self, t) - return 2 + self:getTalentLevelRaw(t) - end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, tactical = { DISABLE = { blind = 2 } }, action = function(self, t) local tg = self:getTalentTarget(t) @@ -727,19 +750,22 @@ newTalent{ range = 10, requires_target = true, tactical = { ATTACK = { NATURE = 1, poison = 1} }, + getDamage = function(self, t) + return self:combatScale(math.max(self:getStr(), self:getDex())*self:getTalentLevel(t), 20, 0, 420, 500) + end, action = function(self, t) local tg = {type="bolt", range=self:getTalentRange(t)} local x, y = self:getTarget(tg) if not x or not y then return nil end local s = math.max(self:getDex(), self:getStr()) - self:project(tg, x, y, DamageType.POISON, 20 + (s * self:getTalentLevel(t)) * 0.8, {type="slime"}) + self:project(tg, x, y, DamageType.POISON, t.getDamage(self,t), {type="slime"}) game:playSoundNear(self, "talents/slime") return true end, info = function(self, t) - local s = math.max(self:getDex(), self:getStr()) return ([[Spit poison at your target, doing %0.2f poison damage over six turns. - The damage will increase with your Strength or Dexterity (whichever is higher).]]):format(20 + (s * self:getTalentLevel(t)) * 0.8) + The damage will increase with your Strength or Dexterity (whichever is higher).]]): + format(damDesc(self, DamageType.POISON, t.getDamage(self,t))) end, } @@ -752,17 +778,20 @@ newTalent{ range = 10, requires_target = true, tactical = { ATTACK = { BLIGHT = 2 } }, + getDamage = function(self, t) + return self:combatScale(self:getMag()*self:getTalentLevel(t), 20, 0, 420, 500) + end, action = function(self, t) local tg = {type="bolt", range=self:getTalentRange(t)} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.BLIGHT, 20 + (self:getMag() * self:getTalentLevel(t)) * 0.8, {type="slime"}) + self:project(tg, x, y, DamageType.BLIGHT, t.getDamage(self,t), {type="slime"}) game:playSoundNear(self, "talents/slime") return true end, info = function(self, t) return ([[Spit blight at your target doing %0.2f blight damage. - The damage will increase with your Magic.]]):format(20 + (self:getMag() * self:getTalentLevel(t)) * 0.8) + The damage will increase with your Magic.]]):format(t.getDamage(self,t)) end, } @@ -775,7 +804,7 @@ newTalent{ cooldown = 15, tactical = { DISABLE = 2, CLOSEIN = 3 }, requires_target = true, - range = function(self, t) return math.floor(5 + self:getTalentLevelRaw(t)) end, + range = function(self, t) return math.floor(self:combatTalentScale(t, 6, 10)) end, action = function(self, t) if self:attr("never_move") then game.logPlayer(self, "You cannot do that currently.") return end @@ -827,17 +856,19 @@ newTalent{ return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)} end, tactical = { ATTACK = { PHYSICAL = 2 } }, + getDamage = function(self, t) return self:combatScale(self:getStr()*self:getTalentLevel(t), 20, 0, 420, 500) end, action = function(self, t) local tg = self:getTalentTarget(t) local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.BLEED, 20 + (self:getStr() * self:getTalentLevel(t)) * 0.8, {type="archery"}) + self:project(tg, x, y, DamageType.BLEED, t.getDamage(self, t), {type="archery"}) game:playSoundNear(self, "talents/earth") return true end, info = function(self, t) return ([[Throws a pack of bones at your target doing %0.2f physical damage as bleeding. - The damage will increase with the Strength stat]]):format(20 + (self:getStr() * self:getTalentLevel(t)) * 0.8) + The damage will increase with the Strength stat]]): + format(damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t))) end, } @@ -851,16 +882,19 @@ newTalent{ range = 10, requires_target = true, tactical = { DISABLE = { stun = 1, pin = 1 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) local dur = 2 + self:getTalentLevel(t) local trap = mod.class.Trap.new{ type = "web", subtype="web", id_by_type=true, unided_name = "sticky web", display = '^', color=colors.YELLOW, image = "trap/trap_spiderweb_01_64.png", name = "sticky web", auto_id = true, - detect_power = 6 * self:getTalentLevel(t), disarm_power = 10 * self:getTalentLevel(t), + detect_power = 6 * self:getTalentLevel(t), disarm_power = 10 * self:getTalentLevel(t), --Trap Params level_range = {self.level, self.level}, message = "@Target@ is caught in a web!", pin_dur = dur, + temporary = dur * 5, + summoner = self, faction = false, canTrigger = function(self, x, y, who) if who.type == "spiderkin" then return false end @@ -879,7 +913,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Lay an invisible web under you, trapping all non-spiderkin that pass.]]):format() + return ([[Lay an invisible web under you, pinning all non-spiderkin that pass for %d turns.]]): + format(t.getDuration(self, t)) end, } @@ -890,21 +925,20 @@ newTalent{ equilibrium = 4, cooldown = 6, range = 0, - radius = function(self, t) - return 2 + self:getTalentLevelRaw(t) / 1.5 - end, + radius = function(self, t) return math.floor(self:combatTalentScale(t, 2.7, 5,3)) end, direct_hit = true, tactical = { DISABLE = 3 }, requires_target = true, target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), talent=t} end, + darkPower = function(self, t) return self:combatTalentScale(t, 10, 50) end, action = function(self, t) local tg = self:getTalentTarget(t) local x, y = self:getTarget(tg) if not x or not y then return nil end self:project(tg, x, y, function(px, py) - local g = engine.Entity.new{name="darkness", show_tooltip=true, block_sight=true, always_remember=false, unlit=self:getTalentLevel(t) * 10} + local g = engine.Entity.new{name="darkness", show_tooltip=true, block_sight=true, always_remember=false, unlit=t.darkPower(self, t)} game.level.map(px, py, Map.TERRAIN+1, g) game.level.map.remembers(px, py, false) game.level.map.lites(px, py, false) @@ -914,8 +948,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Weave darkness, blocking all light but the most powerful and teleporting you a short range. - The damage will increase with the Dexterity stat]]):format(20 + (self:getDex() * self:getTalentLevel(t)) * 0.3) + return ([[Weave darkness (power %d) in a radius of %d, blocking all light but the most powerful and teleporting you a short range.]]): + format(t.darkPower(self, t), self:getTalentRadius(t)) end, } @@ -933,17 +967,19 @@ newTalent{ target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), talent=t} end, + getDam = function(self, t) return self:combatScale(self:getStr() * self:getTalentLevel(t), 12, 0, 262, 500) end, + getDist = function(self, t) return math.floor(self:combatTalentScale(t, 4, 8)) end, action = function(self, t) local tg = self:getTalentTarget(t) local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.PHYSKNOCKBACK, {dist=3+self:getTalentLevelRaw(t), dam=self:mindCrit(12 + self:getStr(50, true) * self:getTalentLevel(t))}, {type="archery"}) + self:project(tg, x, y, DamageType.PHYSKNOCKBACK, {dist=t.getDist(self, t), dam=self:mindCrit(t.getDam(self, t))}, {type="archery"}) game:playSoundNear(self, "talents/ice") return true end, info = function(self, t) - return ([[Throws a huge boulder at a target, damaging it for %0.2f and knocking it back. - The damage will increase with your Strength.]]):format(12 + self:getStr(50, true) * self:getTalentLevel(t)) + return ([[Throws a huge boulder at a target, damaging it for %0.2f and knocking it back %d tiles. + The damage will increase with your Strength.]]):format(damDesc(self, DamageType.PHYSICAL, t.getDam(self, t)), t.getDist(self, t)) end, } @@ -957,8 +993,9 @@ newTalent{ range = 10, tactical = { ATTACK = 3 }, direct_hit = true, + radius = function(self, t) return math.floor(self:combatTalentScale(t, 6, 10)) end, action = function(self, t) - local rad = self:getTalentLevel(t) + 5 + local rad = self:getTalentRadius(t) for i = self.x - rad, self.x + rad do for j = self.y - rad, self.y + rad do if game.level.map:isBound(i, j) then local actor = game.level.map(i, j, game.level.map.ACTOR) if actor and not actor.player then @@ -975,7 +1012,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Howl to call your hunting pack.]]) + return ([[Howl (radius %d) to call your hunting pack.]]): + format(self:getTalentRadius(t)) end, } @@ -989,8 +1027,9 @@ newTalent{ range = 10, direct_hit = true, tactical = { ATTACK = 3 }, + radius = function(self, t) return math.floor(self:combatTalentScale(t, 6, 10)) end, action = function(self, t) - local rad = self:getTalentLevel(t) + 5 + local rad = self:getTalentRadius(t) for i = self.x - rad, self.x + rad do for j = self.y - rad, self.y + rad do if game.level.map:isBound(i, j) then local actor = game.level.map(i, j, game.level.map.ACTOR) if actor and not actor.player then @@ -1007,7 +1046,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Shriek to call your allies.]]) + return ([[Shriek (radius %d) to call your allies.]]): + format(self:getTalentRadius(t)) end, } @@ -1020,6 +1060,7 @@ newTalent{ stamina = 12, requires_target = true, tactical = { ATTACK = { PHYSICAL = 1 }, DISABLE = { stun = 2 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) local weapon = self:hasTwoHandedWeapon() if not weapon then @@ -1033,10 +1074,10 @@ newTalent{ if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end local speed, hit = self:attackTargetWith(target, weapon.combat, nil, self:combatTalentWeaponDamage(t, 1, 1.4)) - -- Try to stun ! + -- Try to pin ! if hit then if target:canBe("pin") then - target:setEffect(target.EFF_PINNED, 2 + self:getTalentLevel(t), {apply_power=self:combatPhysicalpower()}) + target:setEffect(target.EFF_PINNED, t.getDuration(self, t), {apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the crushing!", target.name:capitalize()) end @@ -1045,7 +1086,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Hits the target with a mighty blow to the legs doing %d%% weapon damage. If the attack hits, the target is unable to move for %d turns.]]):format(100 * self:combatTalentWeaponDamage(t, 1, 1.4), 2+self:getTalentLevel(t)) + return ([[Hits the target with a mighty blow to the legs doing %d%% weapon damage. If the attack hits, the target is unable to move for %d turns.]]): + format(100 * self:combatTalentWeaponDamage(t, 1, 1.4), t.getDuration(self, t)) end, } @@ -1059,16 +1101,17 @@ newTalent{ direct_hit = true, requires_target = true, tactical = { DISABLE = { silence = 3 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 5, 9)) end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.SILENCE, {dur=math.floor(4 + self:getTalentLevel(t))}, {type="mind"}) - game:playSoundNear(self, "talents/spell_generic") + self:project(tg, x, y, DamageType.SILENCE, {dur=t.getDuration(self, t)}, {type="mind"}) return true end, info = function(self, t) - return ([[Sends a telepathic attack, silencing the target for %d turns.]]):format(math.floor(4 + self:getTalentLevel(t))) + return ([[Sends a telepathic attack, silencing the target for %d turns.]]): + format(t.getDuration(self, t)) end, } @@ -1113,8 +1156,9 @@ newTalent{ return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)} end, tactical = { ATTACKAREA = { BLIGHT = 2 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) - local duration = self:getTalentLevel(t) + 2 + local duration = t.getDuration(self, t) local dam = self:combatTalentSpellDamage(t, 4, 65) local tg = self:getTalentTarget(t) local x, y = self:getTarget(tg) @@ -1133,8 +1177,9 @@ newTalent{ return true end, info = function(self, t) - return ([[Corrupted vapour rises at the target location doing %0.2f blight damage every turn for %d turns. - The damage will increase with Magic stat.]]):format(self:combatTalentSpellDamage(t, 5, 65), self:getTalentLevel(t) + 2) + return ([[Corrupted vapour rises at the target location (radius 4) doing %0.2f blight damage every turn for %d turns. + The damage will increase with Magic stat.]]): + format(damDesc(self, engine.DamageType.BLIGHT, self:combatTalentSpellDamage(t, 5, 65)), t.getDuration(self, t)) end, } @@ -1195,19 +1240,21 @@ newTalent{ range = 1, requires_target = true, tactical = { ATTACK = { LIGHT = 1 } }, + getDamage = function(self, t) return self:combatScale(self:combatSpellpower() * self:getTalentLevel(t), 0, 0, 66.25 , 265, 0.67) end, action = function(self, t) local tg = {type="bolt", range=1} local x, y, target = self:getTarget(tg) if not x or not y then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end - self:project(tg, x, y, DamageType.LIGHT, math.floor(self:combatSpellpower(0.25) * self:getTalentLevel(t)), {type="light"}) + self:project(tg, x, y, DamageType.LIGHT, t.getDamage(self, t), {type="light"}) game.level.map:particleEmitter(self.x, self.y, 1, "ball_fire", {radius = 1, r = 1, g = 0, b = 0}) self:die(self) game:playSoundNear(self, "talents/arcane") return true end, info = function(self, t) - return ([[Explodes in a blinding light.]]) + return ([[Causes the user to explode (killing it) in a blinding light burst for %d damage.]]): + format(damDesc(self, DamageType.LIGHT, t.getDamage(self, t))) end, } @@ -1247,6 +1294,7 @@ newTalent{ proj_speed = 2, requires_target = true, tactical = { ATTACK = 2 }, + getDamage = function(self, t) return self:combatScale(self:getMag() * self:getTalentLevel(t), 0, 0, 450, 500) end, action = function(self, t) local tg = {type = "bolt", range = 20, talent = t} local x, y = self:getTarget(tg) @@ -1262,13 +1310,14 @@ newTalent{ {DamageType.ARCANE, "manathrust"}, {DamageType.DARKNESS, "dark"}, } - tg.display={particle="bolt_elemental", trail="generictrail"} - self:projectile(tg, x, y, elem[1], math.floor(self:getMag(90, true) * self:getTalentLevel(t)), {type=elem[2]}) + tg.display={particle="bolt_elemental", trail="generictrail"} + self:projectile(tg, x, y, elem[1], t.getDamage(self, t), {type=elem[2]}) game:playSoundNear(self, "talents/arcane") return true end, info = function(self, t) - return ([[Fire a slow bolt of a random element. Damage raises with magic stat.]]) + return ([[Fire a slow bolt of a random element for %d damage. Damage increases with the magic stat.]]): + format(t.getDamage(self, t)) end, } @@ -1283,6 +1332,9 @@ newTalent{ proj_speed = 2, requires_target = true, tactical = { ATTACK = { FIRE = 1, PHYSICAL = 1 } }, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 5, 9)) end, + nbProj = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5, "log")) end, + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 15, 80) end, action = function(self, t) local tg = {type="bolt", range=self:getTalentRange(t), nolock=true, talent=t} local x, y = self:getTarget(tg) @@ -1299,11 +1351,11 @@ newTalent{ name = "raging volcano", image = oe.image, add_mos = {{image = "terrain/lava/volcano_01.png"}}, display = '&', color=colors.LIGHT_RED, back_color=colors.RED, always_remember = true, - temporary = 4 + self:getTalentLevel(t), + temporary = t.getDuration(self, t), x = x, y = y, canAct = false, - nb_projs = math.floor(self:getTalentLevel(self.T_VOLCANO)), - dam = self:combatTalentSpellDamage(self.T_VOLCANO, 15, 80), + nb_projs = t.nbProj(self, t), + dam = t.getDamage(self, t), act = function(self) local tgts = {} local grids = core.fov.circle_grids(self.x, self.y, 5, true) @@ -1342,9 +1394,10 @@ newTalent{ return true end, info = function(self, t) - return ([[Summons a small raging volcano for %d turns. Every turn, it will fire %d molten boulders toward your foes, dealing %0.2f fire and %0.2f physical damage. + local dam = t.getDamage(self, t) + return ([[Summons a small raging volcano for %d turns. Every turn, it will fire a molten boulder towards up to %d of your foes, dealing %0.2f fire and %0.2f physical damage. The damage will scale with your Spellpower.]]): - format(4 + self:getTalentLevel(t), math.floor(self:getTalentLevel(self.T_VOLCANO)), damDesc(self, DamageType.FIRE, self:combatTalentSpellDamage(self.T_VOLCANO, 15, 80) / 2), damDesc(self, DamageType.PHYSICAL, self:combatTalentSpellDamage(self.T_VOLCANO, 15, 80) / 2)) + format(t.getDuration(self, t), t.nbProj(self, t), damDesc(self, DamageType.FIRE, dam/2), damDesc(self, DamageType.PHYSICAL, dam/2)) end, } @@ -1395,11 +1448,12 @@ newTalent{ }, direct_hit = true, range = 0, - radius = function(self, t) return 1 + self:getTalentLevelRaw(t) end, + radius = function(self, t) return math.floor(self:combatTalentScale(t, 2, 6)) end, target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=true, talent=t} end, - getPower = function(self, t) return self:combatTalentSpellDamage(t, 10, 50) end, + getPower = function(self, t) return self:combatLimit(self:combatTalentSpellDamage(t, 10, 50), 1, 0, 0, 0.329, 32.9) end, -- Limit < 100 + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5)) end, action = function(self, t) local tg = self:getTalentTarget(t) self:project(tg, self.x, self.y, function(px, py) @@ -1418,7 +1472,7 @@ newTalent{ reapplied = true end end - target:setEffect(target.EFF_FRENZY, self:getTalentLevel(t), {crit = t.getPower(self, t)/10, power=t.getPower(self, t)/100, dieat=t.getPower(self, t)/100}, reapplied) + target:setEffect(target.EFF_FRENZY, t.getDuration(self, t), {crit = t.getPower(self, t)*100, power=t.getPower(self, t), dieat=t.getPower(self, t)}, reapplied) end end end) @@ -1429,8 +1483,11 @@ newTalent{ return true end, info = function(self, t) - return ([[Speeds up nearby Dredges. - ]]):format() + local range = t.radius(self,t) + local power = t.getPower(self,t) * 100 + return ([[Sends Dredges in a radius of %d into a frenzy for %d turns. + The frenzy will increase global speed by %d%%, physical crit chance by %d%%, and prevent death until -%d%% life.]]): + format(range, t.getDuration(self, t), power, power, power) end, } @@ -1590,7 +1647,7 @@ newTalent{ return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)} end, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 4, 50) end, - getDuration = function(self, t) return self:getTalentLevel(t) + 2 end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) local tg = self:getTalentTarget(t) local x, y = self:getTarget(tg) @@ -1645,9 +1702,7 @@ newTalent{ cooldown = 20, tactical = { ATTACK = { FIRE = 1 }, HEAL = 1, }, range = 0, - radius = function(self, t) - return 3 + self:getTalentLevelRaw(t) - end, + radius = function(self, t) return math.floor(self:combatTalentScale(t, 4, 8)) end, requires_target = true, target = function(self, t) return {type="cone", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t} @@ -1717,7 +1772,7 @@ newTalent{ mana = 70, tactical = { ATTACKAREA = { FIRE=2, PHYSICAL=2 } }, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 15, 250) end, - getNb = function(self, t) return 3 + math.floor(self:getTalentLevel(t) / 3) end, + getNb = function(self, t) return math.floor(self:combatTalentScale(t, 3.3, 4.8, "log")) end, radius = 2, range = 5, target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t} end, @@ -1962,6 +2017,7 @@ newTalent{ range = 10, tactical = { DISABLE = 1, CLOSEIN = 3 }, requires_target = true, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 4, 8)) end, action = function(self, t) local tg = {type="bolt", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) @@ -1976,16 +2032,16 @@ newTalent{ target:pull(self.x, self.y, tg.range) DamageType:get(DamageType.COLD).projector(self, target.x, target.y, DamageType.COLD, dam) - target:setEffect(target.EFF_SLOW_MOVE, math.floor(3 + self:getTalentLevel(t)), {apply_power=self:combatSpellpower(), power=0.5}) + target:setEffect(target.EFF_SLOW_MOVE, t.getDuration(self, t), {apply_power=self:combatSpellpower(), power=0.5}) end) game:playSoundNear(self, "talents/arcane") return true end, info = function(self, t) - return ([[Grab a target and teleport it to your side, covering it with frost, reducing its movement speed by 50%% for %d turns. + return ([[Grab a target and transport it next to you, covering it with frost, reducing its movement speed by 50%% for %d turns. The ice will also deal %0.2f cold damage. The damage will increase with your Spellpower.]]): - format(math.floor(3 + self:getTalentLevel(t)), damDesc(self, DamageType.COLD, self:combatTalentSpellDamage(t, 5, 140))) + format(t.getDuration(self, t), damDesc(self, DamageType.COLD, self:combatTalentSpellDamage(t, 5, 140))) end, } diff --git a/game/modules/tome/data/talents/misc/objects.lua b/game/modules/tome/data/talents/misc/objects.lua index dbd0e9b4b4a9cbc0574b6749f1d951e52ab2db2f..71e876962dfaa30b44f7364ec6e6879cad5c8951 100644 --- a/game/modules/tome/data/talents/misc/objects.lua +++ b/game/modules/tome/data/talents/misc/objects.lua @@ -299,13 +299,17 @@ newTalent{ target = function(self, t) return {type="hit", range=1, talent=t} end, + getpower = function(self, t) return 8 end, + maxpower = function(self, t) return self:combatTalentLimit(t, 100, 45, 70) end, -- Limit spell failure < 100% action = function(self, t) self:getTalentLevel(t) local tg = self:getTalentTarget(t) local x, y, target = self:getTarget(tg) if not x or not y then return nil end + dispower = t.getpower(self,t) + dismax = t.maxpower(self, t) self:project(tg, x, y, function(px, py) - target:setEffect(target.EFF_SPELL_DISRUPTION, 8, {src=self, power = 8, max = 45+self:getTalentLevel(t)*5, apply_power=self:combatMindpower()}) + target:setEffect(target.EFF_SPELL_DISRUPTION, 8, {src=self, power = dispower, max = dismax, apply_power=self:combatMindpower()}) if rng.percent(30) and self:getTalentLevel(t)>2 then local effs = {} @@ -335,18 +339,18 @@ newTalent{ end end end - if self:getTalentLevel(t)>4 then - if target.undead or target.construct then - self:project({type="hit"}, target.x, target.y, engine.DamageType.ARCANE, 40+self:combatMindpower()) - if target:canBe("stun") then target:setEffect(target.EFF_STUNNED, 5, {apply_power=self:combatMindpower()}) end - game.logSeen(self, "%s's animating magic is disrupted!", target.name:capitalize()) - end + if self:getTalentLevel(t)>=5 then + if target.undead or target.construct then + self:project({type="hit"}, target.x, target.y, engine.DamageType.ARCANE, 40+self:combatMindpower()) + if target:canBe("stun") then target:setEffect(target.EFF_STUNNED, 5, {apply_power=self:combatMindpower()}) end + game.logSeen(self, "%s's animating magic is disrupted!", target.name:capitalize()) end + end end, nil, {type="slime"}) return true end, info = function(self, t) - return ([[Inflict various status effects on the target, depending on the level.]]):format(7 + self:getWil() * 0.5) + return ([[The target has a %d%% chance (stacking to a maximum of %d%%) to fail to cast any spell. At level 2 magical effects may be disrupted, at level 3 magical sustains may be disrupted, and at level 5 magical constructs and undead may be stunned.]]):format(t.getpower(self, t),t.maxpower(self,t)) end, } diff --git a/game/modules/tome/data/talents/misc/races.lua b/game/modules/tome/data/talents/misc/races.lua index ff99deca2a2781a160d026861ced8a9a8e806562..e97c39f47acdbc251eb4a117706f2b3e60be91bc 100644 --- a/game/modules/tome/data/talents/misc/races.lua +++ b/game/modules/tome/data/talents/misc/races.lua @@ -43,7 +43,7 @@ newTalent{ require = racial_req1, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 10, 45, 25)) end, -- Limit >10 tactical = { HEAL = 2 }, on_pre_use = function(self, t) return not self:hasEffect(self.EFF_REGENERATION) end, action = function(self, t) @@ -62,23 +62,20 @@ newTalent{ require = racial_req2, points = 5, mode = "passive", - on_learn = function(self, t) - self:attr("blind_immune", 0.08) - self.sight = self.sight + 1 - self.heightened_senses = (self.heightened_senses or 0) + 1 - self.infravision = (self.infravision or 0) + 1 - end, - on_unlearn = function(self, t) - self.sight = self.sight - 1 - self.heightened_senses = (self.heightened_senses or 0) - 1 - self.infravision = (self.infravision or 0) - 1 - self:attr("blind_immune", -0.08) + getSight = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5, "log")) end, + getESight = function(self, t) return math.ceil(self:combatTalentScale(t, 0.3, 2.3, "log", 0, 2)) end, + getImmune = function(self, t) return self:combatTalentLimit(t, 1, 0.1, 0.4) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "blind_immune", t.getImmune(self, t)) + self:talentTemporaryValue(p, "sight", t.getSight(self, t)) + self:talentTemporaryValue(p, "infravision", t.getESight(self, t)) + self:talentTemporaryValue(p, "heightened_senses", t.getESight(self, t)) end, info = function(self, t) return ([[While Highers are not meant to rule other humans - and show no particular will to do so - they are frequently called to higher duties. Their nature grants them better senses than other humans. Increase blindness immunity by %d%%, maximum sight range by %d, and increases existing infravision, and heightened senses range by %d.]]): - format(self:getTalentLevelRaw(t) * 8, self:getTalentLevelRaw(t), math.ceil(self:getTalentLevelRaw(t)/2)) + format(t.getImmune(self, t) * 100, t.getSight(self, t), t.getESight(self, t)) end, } @@ -88,24 +85,23 @@ newTalent{ require = racial_req3, points = 5, mode = "passive", - cooldown = function(self, t) return 22 - 3 * self:getTalentLevelRaw(t) end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 0, 19, 7)) end, -- Limit > 0 + getSave = function(self, t) return self:combatTalentScale(t, 5, 25, 0.75) end, + power = function(self, t) return self:combatTalentScale(t, 7, 25) end, trigger = function(self, t, damtype) self:startTalentCooldown(t) self:setEffect(self.EFF_BORN_INTO_MAGIC, 5, {damtype=damtype}) end, - on_learn = function(self, t) - self.combat_spellresist = self.combat_spellresist + 5 - self.resists[DamageType.ARCANE] = (self.resists[DamageType.ARCANE] or 0) + 5 - end, - on_unlearn = function(self, t) - self.combat_spellresist = self.combat_spellresist - 5 - self.resists[DamageType.ARCANE] = (self.resists[DamageType.ARCANE] or 0) - 5 + passives = function(self, t, p) + self:talentTemporaryValue(p, "combat_spellresist", t.getSave(self, t)) + self:talentTemporaryValue(p, "resists",{[DamageType.ARCANE]=t.power(self, t)}) end, info = function(self, t) + local netpower = t.power(self, t) return ([[Highers were originally created during the Age of Allure by the human Conclave. They are imbued with magic at the very core of their being. Increase spell save by +%d and arcane resistance by %d%%. - Also when you cast a spell dealing damage, you gain a 15%% bonus to the damage type for 5 turns (this effect has a cooldown)]]): - format(self:getTalentLevelRaw(t) * 5, self:getTalentLevelRaw(t) * 5, self:getTalentLevelRaw(t) * 5) + Also when you cast a spell dealing damage, you gain a 15%% bonus to the damage type for 5 turns. (This effect has a cooldown.)]]): + format(t.getSave(self, t), netpower) end, } @@ -115,9 +111,9 @@ newTalent{ require = racial_req4, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 3 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 20, 47, 35)) end, -- Limit >20 tactical = { MANA = 2, VIM = 2, EQUILIBRIUM = 2, STAMINA = 2, POSITIVE = 2, NEGATIVE = 2, PARADOX = 2, PSI = 2 }, - getDuration = function(self, t) return 1 + self:getTalentLevelRaw(t) end, + getDuration = function(self, t) return math.floor(self:combatTalentLimit(t, 10, 2, 6.1)) end, -- Limit to < 10 action = function(self, t) self:setEffect(self.EFF_HIGHBORN_S_BLOOM, t.getDuration(self, t), {}) return true @@ -141,16 +137,17 @@ newTalent{ require = racial_req1, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 4 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 10, 46, 30)) end, -- Limit to >10 turns + getSpeed = function(self, t) return self:combatStatScale(math.max(self:getDex(), self:getMag()), 0.1, 0.476, 0.75) end, tactical = { DEFEND = 1 }, action = function(self, t) - local power = 0.1 + math.max(self:getDex(), self:getMag()) / 210 - self:setEffect(self.EFF_SPEED, 8, {power=power}) + self:setEffect(self.EFF_SPEED, 8, {power=t.getSpeed(self, t)}) return true end, info = function(self, t) return ([[Call upon the grace of the Eternals to increase your general speed by %d%% for 8 turns. - The speed bonus will increase with your Dexterity or Magic (whichever is higher).]]):format((0.1 + math.max(self:getDex(), self:getMag()) / 210) * 100) + The speed bonus will increase with your Dexterity or Magic (whichever is higher).]]): + format(t.getSpeed(self, t) * 100) end, } @@ -160,21 +157,18 @@ newTalent{ require = racial_req2, points = 5, mode = "passive", - on_learn = function(self, t) - self.combat_physcrit = self.combat_physcrit + 2 - self.combat_spellcrit = self.combat_spellcrit + 2 - self.combat_mindcrit = self.combat_mindcrit + 2 - self.combat_critical_power = (self.combat_critical_power or 0) + 5 - end, - on_unlearn = function(self, t) - self.combat_physcrit = self.combat_physcrit - 2 - self.combat_spellcrit = self.combat_spellcrit - 2 - self.combat_mindcrit = self.combat_mindcrit - 2 - self.combat_critical_power = (self.combat_critical_power or 0) - 5 + critChance = function(self, t) return self:combatTalentScale(t, 3, 10, 0.75) end, + critPower = function(self, t) return self:combatTalentScale(t, 6, 25, 0.75) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "combat_physcrit", t.critChance(self, t)) + self:talentTemporaryValue(p, "combat_spellcrit", t.critChance(self, t)) + self:talentTemporaryValue(p, "combat_mindcrit", t.critChance(self, t)) + self:talentTemporaryValue(p, "combat_critical_power", t.critPower(self, t)) end, info = function(self, t) return ([[Reality bends slightly in the presence of a Shaloren, due to their inherent magical nature. - Increases critical chance by %d%% and critical strike power by %d%%.]]):format(self:getTalentLevelRaw(t) * 2, self:getTalentLevelRaw(t) * 5) + Increases critical chance by %d%% and critical strike power by %d%%.]]): + format(t.critChance(self, t), t.critPower(self, t)) end, } @@ -183,15 +177,17 @@ newTalent{ type = {"race/shalore", 3}, require = racial_req3, points = 5, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 3 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 47, 35)) end, -- Limit > 5 + getChance = function(self, t) return self:combatTalentLimit(t, 100, 21, 45) end, -- Limit < 100% + getInvis = function(self, t) return self:combatStatScale("mag" , 7, 25) end, mode = "sustained", no_energy = true, activate = function(self, t) self.invis_on_hit_disable = self.invis_on_hit_disable or {} game:playSoundNear(self, "talents/spell_generic2") local ret = { - invis = self:addTemporaryValue("invis_on_hit", 15 + self:getTalentLevelRaw(t) * 6), - power = self:addTemporaryValue("invis_on_hit_power", 5 + self:getMag(20, true)), + invis = self:addTemporaryValue("invis_on_hit", t.getChance(self, t)), + power = self:addTemporaryValue("invis_on_hit_power", t.getInvis(self, t)), talent = self:addTemporaryValue("invis_on_hit_disable", {[t.id]=1}), } return ret @@ -205,7 +201,7 @@ newTalent{ info = function(self, t) return ([[As the only immortal race of Eyal, Shaloren have learnt, over the long years, to use their innate inner magic to protect themselves. %d%% chance to become invisible (power %d) for 5 turns, when hit by a blow doing at least 10%% of their total life.]]): - format(15 + self:getTalentLevelRaw(t) * 6, 5 + self:getMag(20, true)) + format(t.getChance(self, t), t.getInvis(self, t)) end, } @@ -215,7 +211,9 @@ newTalent{ require = racial_req4, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 3 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 20, 47, 35)) end, -- Limit to >20 + getEffectGood = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5, "log")) end, + getEffectBad = function(self, t) return math.floor(self:combatTalentScale(t, 2.9, 10.01, "log")) end, tactical = { BUFF = function(self, t, target) local nb = 0 @@ -241,9 +239,9 @@ newTalent{ local e = target.tempeffect_def[eff_id] if e.type ~= "other" then if e.status == "beneficial" then - p.dur = p.dur + self:getTalentLevelRaw(t) + p.dur = math.min(p.dur*2, p.dur + t.getEffectGood(self, t)) elseif e.status == "detrimental" then - p.dur = p.dur - self:getTalentLevelRaw(t) * 2 + p.dur = p.dur - t.getEffectBad(self, t) if p.dur <= 0 then todel[#todel+1] = eff_id end end end @@ -260,7 +258,7 @@ newTalent{ while #tids > 0 do local tt = rng.tableRemove(tids) if not tt then break end - self.talents_cd[tt.id] = self.talents_cd[tt.id] - self:getTalentLevelRaw(t) + self.talents_cd[tt.id] = self.talents_cd[tt.id] - t.getEffectGood(self, t) if self.talents_cd[tt.id] <= 0 then self.talents_cd[tt.id] = nil end end @@ -269,8 +267,8 @@ newTalent{ end, info = function(self, t) return ([[The world grows old as you stand through the ages. To you, time is different. - Reduces the time remaining on detrimental effects by %d, cooling down talents by %d, and increases the time remaining on beneficial effects by %d.]]): - format(self:getTalentLevelRaw(t) * 2, self:getTalentLevelRaw(t), self:getTalentLevelRaw(t)) + Reduces the time remaining on detrimental effects by %d, cooling down talents by %d, and increases the time remaining on beneficial effects by %d (up to 2 times the current duration).]]): + format(t.getEffectBad(self, t), t.getEffectGood(self, t), t.getEffectGood(self, t)) end, } @@ -285,15 +283,17 @@ newTalent{ require = racial_req1, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 45, 25)) end, -- Limit > 5 + getPower = function(self, t) return self:combatStatScale("wil", 11, 20) end, tactical = { ATTACK = 1, DEFEND = 1 }, action = function(self, t) - self:setEffect(self.EFF_ETERNAL_WRATH, 5, {power=10 + self:getWil(10, true)}) + self:setEffect(self.EFF_ETERNAL_WRATH, 5, {power=t.getPower(self, t)}) return true end, info = function(self, t) return ([[Call upon the power of the Eternals, increasing all damage by %d%% and reducing all damage taken by %d%% for 5 turns. - The bonus will increase with your Willpower.]]):format(10 + self:getWil(10, true), 10 + self:getWil(10, true)) + The bonus will increase with your Willpower.]]): + format(t.getPower(self, t), t.getPower(self, t)) end, } @@ -303,17 +303,15 @@ newTalent{ require = racial_req2, points = 5, mode = "passive", - on_learn = function(self, t) - self.combat_physresist = self.combat_physresist + 5 - self.combat_mentalresist = self.combat_mentalresist + 5 - end, - on_unlearn = function(self, t) - self.combat_physresist = self.combat_physresist - 5 - self.combat_mentalresist = self.combat_mentalresist - 5 + getSave = function(self, t) return self:combatTalentScale(t, 6, 25, 0.75) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "combat_physresist", t.getSave(self, t)) + self:talentTemporaryValue(p, "combat_mentalresist", t.getSave(self, t)) end, info = function(self, t) return ([[Thaloren have always been a free people, living in their beloved forest and never caring much about the world outside. - Increase Physical and Mental Save by +%d.]]):format(self:getTalentLevelRaw(t) * 5) + Increase Physical and Mental Save by +%d.]]): + format(t.getSave(self, t)) end, } @@ -323,19 +321,18 @@ newTalent{ require = racial_req3, points = 5, mode = "passive", - on_learn = function(self, t) - self:attr("disease_immune", 0.2) - self.resists[DamageType.BLIGHT] = (self.resists[DamageType.BLIGHT] or 0) + 2 - self.resists.all = (self.resists.all or 0) + 1.3 - end, - on_unlearn = function(self, t) - self:attr("disease_immune", -0.2) - self.resists[DamageType.BLIGHT] = (self.resists[DamageType.BLIGHT] or 0) - 2 - self.resists.all = (self.resists.all or 0) - 1.3 + getDiseaseImmune = function(self, t) return self:combatTalentLimit(t, 1, 0.2, 0.75) end, -- Limit < 100% + getBResist = function(self, t) return self:combatTalentScale(t, 3, 10) end, + getAllResist = function(self, t) return self:combatTalentScale(t, 2, 6.5) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "disease_immune", t.getDiseaseImmune(self, t)) + self:talentTemporaryValue(p, "resists",{[DamageType.BLIGHT]=t.getBResist(self, t)}) + self:talentTemporaryValue(p, "resists",{all=t.getAllResist(self, t)}) end, info = function(self, t) return ([[You are part of the wood; it shields you from corruption. - Increase disease immunity by %d%%, blight resistance by %d%%, and all resistances by %d%%.]]):format(self:getTalentLevelRaw(t) * 20, self:getTalentLevelRaw(t) * 2, self:getTalentLevelRaw(t) * 1.3) + Increase disease immunity by %d%%, blight resistance by %0.1f%%, and all resistances by %0.1f%%.]]): + format(t.getDiseaseImmune(self, t)*100, t.getBResist(self, t), t.getAllResist(self, t)) end, } @@ -345,7 +342,7 @@ newTalent{ require = racial_req4, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 4 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 8, 46, 34)) end, -- limit >8 tactical = { ATTACK = { PHYSICAL = 2 }, DISABLE = { stun = 1, knockback = 1 } }, range = 4, action = function(self, t) @@ -383,8 +380,11 @@ newTalent{ ai = "summoned", ai_real = "tactical", ai_state = { talent_in=2, }, stats = {str=0, dex=0, con=0, cun=0, wil=0, mag=0}, combat = { dam=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), atk=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.6), dammod={str=1.1} }, - inc_stats = { str=25 + self:getWil() * self:getTalentLevel(t) / 5, dex=18, con=10 + self:getTalentLevel(t) * 2, }, - + inc_stats = { + str=25 + self:combatScale(self:getWil() * self:getTalentLevel(t), 0, 0, 100, 500, 0.75), + dex=18, + con=10 + self:combatTalentScale(t, 3, 10, 0.75), + }, level_range = {1, nil}, exp_worth = 0, silent_levelup = true, @@ -424,19 +424,24 @@ newTalent{ require = racial_req1, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 8, 45, 25)) end, -- Limit >8 + getParams = function(self, t) + return { + armor = self:combatStatScale("con", 7, 25), + physical = self:combatStatScale("con", 12, 30, 0.75), + spell = self:combatStatScale("con", 12, 30, 0.75), + } + end, tactical = { DEFEND = 2 }, action = function(self, t) - self:setEffect(self.EFF_DWARVEN_RESILIENCE, 8, { - armor=5 + self:getCon() / 5, - physical=10 + self:getCon() / 5, - spell=10 + self:getCon() / 5, - }) + self:setEffect(self.EFF_DWARVEN_RESILIENCE, 8, t.getParams(self, t)) return true end, info = function(self, t) + local params = t.getParams(self, t) return ([[Call upon the legendary resilience of the Dwarven race to increase your Armor (+%d), Spell (+%d) and Physical (+%d) saves for 8 turns. - The bonus will increase with your Constitution.]]):format(5 + self:getCon() / 5, 10 + self:getCon() / 5, 10 + self:getCon() / 5) + The bonus will increase with your Constitution.]]): + format(params.armor, params.physical, params.spell) end, } @@ -446,15 +451,14 @@ newTalent{ require = racial_req2, points = 5, mode = "passive", - on_learn = function(self, t) - self:attr("auto_stoneskin", 6) - end, - on_unlearn = function(self, t) - self:attr("auto_stoneskin", -6) + armor = function(self, t) return self:combatTalentScale(t, 6, 30) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "auto_stoneskin", t.armor(self, t)) end, info = function(self, t) return ([[Dwarf skin is a complex structure, it can automatically react to physical blows to harden itself. - 15%% chance when hit in melee to increase Armour total by %d for 5 turns.]]):format(self:getTalentLevelRaw(t) * 6) + When you are hit in melee, you have a 15%% chance to increase your Armour total by %d for 5 turns.]]): + format(t.armor(self, t)) end, } @@ -464,10 +468,17 @@ newTalent{ require = racial_req3, points = 5, mode = "passive", + getMaxSaves = function(self, t) return self:combatTalentScale(t, 8, 35) end, + getGold = function(self, t) return self:combatTalentLimit(t, 40, 85, 65) end, -- Limit > 40 + -- called by _M:combatPhysicalResist, _M:combatSpellResist, _M:combatMentalResist in mod.class.interface.Combat.lua + getSaves = function(self, t) + return util.bound(self.money / t.getGold(self, t), 0, t.getMaxSaves(self, t)) + end, info = function(self, t) return ([[Money is the heart of the Dwarven Empire; it rules over all other considerations. Increases Physical, Mental and Spell Saves based on the amount of gold you possess. - +1 save every %d gold, up to +%d.]]):format(90 - self:getTalentLevelRaw(t) * 5, self:getTalentLevelRaw(t) * 7) + +1 save every %d gold, up to +%d. (currently +%d)]]): + format(t.getGold(self, t), t.getMaxSaves(self, t), t.getSaves(self, t)) end, } @@ -476,10 +487,12 @@ newTalent{ type = {"race/dwarf", 4}, require = racial_req4, points = 5, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 45, 25)) end, -- Limit >5 range = 1, no_npc_use = true, - getRange = function(self, t) return math.floor(1 + self:getCon(4, true) + self:getTalentLevel(t)) end, + getRange = function(self, t) + return math.max(1, math.floor(self:combatScale(0.04*self:getCon() + self:getTalentLevel(t), 2.4, 1.4, 10, 9))) + end, action = function(self, t) local tg = {type="bolt", range=self:getTalentRange(t), nolock=true, talent=t} local x, y = self:getTarget(tg) @@ -509,19 +522,24 @@ newTalent{ require = racial_req1, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 45, 25)) end, -- Limit >5 + getParams = function(self, t) + return { + physical = self:combatStatScale("cun", 15, 60, 0.75), + spell = self:combatStatScale("cun", 15, 60, 0.75), + mind = self:combatStatScale("cun", 15, 60, 0.75), + } + end, tactical = { ATTACK = 2 }, action = function(self, t) - self:setEffect(self.EFF_HALFLING_LUCK, 5, { - physical=10 + self:getCun() / 2, - spell=10 + self:getCun() / 2, - mind=10 + self:getCun() / 2, - }) + self:setEffect(self.EFF_HALFLING_LUCK, 5, t.getParams(self, t)) return true end, info = function(self, t) - return ([[Call upon the luck and cunning of the Little Folk to increase your physical, mental, and spell critical strike chance by %d%% and saves by %d for 5 turns. - The bonus will increase with your Cunning.]]):format(10 + self:getCun() / 2, 10 + self:getCun() / 2) + local params = t.getParams(self, t) + return ([[Call upon the luck and cunning of the Little Folk to increase your physical, mental, and spell critical strike chance by %d%% and your saves by %d for 5 turns. + The bonus will increase with your Cunning.]]): + format(params.mind, params.mind) end, } @@ -532,15 +550,20 @@ newTalent{ points = 5, mode = "passive", getThreshold = function(self, t) return math.max(10, (15 - self:getTalentLevelRaw(t))) / 100 end, - getEvasionChance = function(self, t) return self:getStat("lck") end, - getDuration = function(self, t) return 1 + math.ceil(self:getTalentLevel(t)/2) end, + getEvasionChance = function(self, t) return 50 end, + getDuration = function(self, t) return math.ceil(self:combatTalentScale(t, 1.3, 3.3)) end, + -- called by _M:onTakeHit function in mod.class.Actor.lua for trigger + getDefense = function(self) + local oldevasion = self:hasEffect(self.EFF_EVASION) + return self:getStat("lck")/200*(self:combatDefenseBase() - (oldevasion and oldevasion.defense or 0)) -- Prevent stacking + end, info = function(self, t) local threshold = t.getThreshold(self, t) local evasion = t.getEvasionChance(self, t) local duration = t.getDuration(self, t) return ([[Your incredible luck kicks in at just the right moment to save your skin. - Whenever you take %d%% or more of your life from a single attack, you gain Evasion equal to your luck stat (currently %d%%) for the next %d turns.]]): - format(threshold * 100, evasion, duration) + Whenever you take %d%% or more of your life from a single attack, you gain Evasion (%d%%) and %d additional defense (based on your luck and other defensive stats) for the next %d turns.]]): + format(threshold * 100, evasion, t.getDefense(self), duration) end, } @@ -563,10 +586,10 @@ newTalent{ require = racial_req4, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 10, 45, 25)) end, -- limit >10 tactical = { DEFEND = 1, CURE = 1 }, - getRemoveCount = function(self, t) return 1 + self:getTalentLevel(t) end, - getDuration = function(self, t) return 1 + self:getTalentLevel(t) end, + getRemoveCount = function(self, t) return math.floor(self:combatTalentScale(t, 2, 6, "log")) end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 2, 6)) end, action = function(self, t) local effs = {} @@ -593,7 +616,7 @@ newTalent{ info = function(self, t) local duration = t.getDuration(self, t) local count = t.getRemoveCount(self, t) - return ([[Halflings are one of the more powerful military force of the known world; they have been at war with most other races for thousand of years. + return ([[Halflings have one of the most powerful military forces in the known world and they have been at war with most other races for thousand of years. Removes %d stun, daze, or pin effects, and makes you immune to stuns, dazes and pins for %d turns. This talent takes no time to use.]]):format(duration, count) end, @@ -610,15 +633,17 @@ newTalent{ require = racial_req1, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 4 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 46, 30)) end, -- Limit to >5 turns + getPower = function(self, t) return self:combatStatScale("wil", 12, 30) end, tactical = { ATTACK = 2 }, action = function(self, t) - self:setEffect(self.EFF_ORC_FURY, 5, {power=10 + self:getWil(20, true)}) + self:setEffect(self.EFF_ORC_FURY, 5, {power=t.getPower(self, t)}) return true end, info = function(self, t) - return ([[Summons your lust for blood and destruction, increasing all damage dealt by %d%% for 5 turns. - The bonus will increase with your Willpower.]]):format(10 + self:getWil(20, true)) + return ([[Summons your lust for blood and destruction, increasing all damage you deal by %d%% for 5 turns. + The bonus will increase with your Willpower.]]): + format(t.getPower(self, t)) end, } @@ -628,17 +653,15 @@ newTalent{ require = racial_req2, points = 5, mode = "passive", - on_learn = function(self, t) - self.combat_physresist = self.combat_physresist + 5 - self.combat_mentalresist = self.combat_mentalresist + 5 - end, - on_unlearn = function(self, t) - self.combat_physresist = self.combat_physresist - 5 - self.combat_mentalresist = self.combat_mentalresist - 5 + getSaves = function(self, t) return self:combatTalentScale(t, 6, 25, 0.75) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "combat_physresist", t.getSaves(self, t)) + self:talentTemporaryValue(p, "combat_mentalresist", t.getSaves(self, t)) end, info = function(self, t) - return ([[Orcs have been the prey of the other races for thousands of years, with or without reasons. They have learnt to withstand things that would break weaker races. - Increase physical and mental save by +%d.]]):format(self:getTalentLevelRaw(t) * 5) + return ([[Orcs have been the prey of the other races for thousands of years, with or without justification. They have learnt to withstand things that would break weaker races. + Increase physical and mental save by +%d.]]): + format(t.getSaves(self, t)) end, } @@ -648,15 +671,14 @@ newTalent{ require = racial_req3, points = 5, mode = "passive", - on_learn = function(self, t) - self.resists_pen.all = (self.resists_pen.all or 0) + 5 - end, - on_unlearn = function(self, t) - self.resists_pen.all = (self.resists_pen.all or 0) - 5 + getPen = function(self, t) return self:combatTalentLimit(t, 50, 7, 25) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "resists_pen", {all = t.getPen(self, t)}) end, info = function(self, t) return ([[Orcs have seen countless battles, and won many of them. - Increase all damage penetration by %d%%.]]):format(self:getTalentLevelRaw(t) * 5) + Increase all damage penetration by %d%%.]]): + format(t.getPen(self, t)) end, } @@ -666,7 +688,9 @@ newTalent{ require = racial_req4, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 4 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 10, 46, 30)) end, -- Limit to >10 + remcount = function(self,t) return math.ceil(self:combatTalentScale(t, 0.5, 3, "log", 0, 3)) end, + heal = function(self, t) return 25 + 2.3* self:getCon() + self:combatTalentLimit(t, 0.1, 0.01, 0.05)*self.max_life end, is_heal = true, tactical = { DEFEND = 1, HEAL = 2, CURE = function(self, t, target) local nb = 0 @@ -690,7 +714,7 @@ newTalent{ end end - for i = 1, math.ceil(self:getTalentLevel(t) * 3 / 5) do + for i = 1, t.remcount(self,t) do if #effs == 0 then break end local eff = rng.tableRemove(effs) @@ -699,14 +723,15 @@ newTalent{ end end self:attr("allow_on_heal", 1) - self:heal(25 + self:getCon() * 2.3) + self:heal(t.heal(self, t)) self:attr("allow_on_heal", -1) return true end, info = function(self, t) - return ([[Call upon the will of all the Orc Prides to survive this battle. - Heals you for %d life, and removes up to %d detrimental effects. - The bonus will increase with your Constitution.]]):format(25 + self:getCon() * 2.3, math.ceil(self:getTalentLevel(t) * 3 / 5)) + return ([[Call upon the will of all of the Orc Prides to survive this battle. + You heal for %d life, and remove up to %d detrimental effects. + The healing will increase with your Constitution.]]): + format(t.heal(self, t), t.remcount(self,t)) end, } @@ -721,7 +746,8 @@ newTalent{ require = racial_req1, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 3 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 10, 47, 35)) end, -- Limit >10 + getduration = function(self) return math.floor(self:combatStatScale("wil", 5, 14)) end, range = 4, no_npc_use = true, requires_target = true, @@ -741,15 +767,15 @@ newTalent{ target:takeHit(1, self) target:takeHit(1, self) target:takeHit(1, self) - target:setEffect(target.EFF_DOMINANT_WILL, 4 + self:getWil(10), {src=self}) + target:setEffect(target.EFF_DOMINANT_WILL, t.getduration(self), {src=self}) end) return true end, info = function(self, t) return ([[Shatters the mind of your victim, giving you full control over its actions for %s turns. When the effect ends, you pull out your mind and the victim's body collapses, dead. - This effect does not work on rares, bosses or undeads. - The duration will increase with your Willpower.]]):format(4 + self:getWil(10)) + This effect does not work on rares, bosses, or undeads. + The duration will increase with your Willpower.]]):format(t.getduration(self)) end, } @@ -759,19 +785,17 @@ newTalent{ require = racial_req2, points = 5, mode = "passive", - on_learn = function(self, t) - self:attr("confusion_immune", 0.12) - self:attr("silence_immune", 0.12) - self.combat_mentalresist = self.combat_mentalresist + 4 - end, - on_unlearn = function(self, t) - self:attr("confusion_immune", -0.12) - self:attr("silence_immune", -0.12) - self.combat_mentalresist = self.combat_mentalresist - 4 + getImmune = function(self, t) return self:combatTalentLimit(t, 1, 0.17, 0.6) end, -- Limit < 100% + getSave = function(self, t) return self:combatTalentScale(t, 5, 20, 0.75) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "confusion_immune", t.getImmune(self, t)) + self:talentTemporaryValue(p, "silence_immune", t.getImmune(self, t)) + self:talentTemporaryValue(p, "combat_mentalresist", t.getSave(self, t)) end, info = function(self, t) return ([[Your mind becomes more attuned to the Way, and is shielded from outside effects. - Increase confusion and silence immunities by %d%%, and your Mental Save by +%d.]]):format(self:getTalentLevelRaw(t) * 12, self:getTalentLevelRaw(t) * 4) + Increase confusion and silence immunities by %d%%, and your Mental Save by +%d.]]): + format(100*t.getImmune(self, t), t.getSave(self, t)) end, } @@ -781,17 +805,14 @@ newTalent{ require = racial_req3, points = 5, mode = "passive", - on_learn = function(self, t) - self.global_speed_base = self.global_speed_base + 0.03 - self:recomputeGlobalSpeed() - end, - on_unlearn = function(self, t) - self.global_speed_base = self.global_speed_base - 0.03 + speedup = function(self, t) return self:combatTalentScale(t, 0.04, 0.15, 0.75) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "global_speed_base", t.speedup(self, t)) self:recomputeGlobalSpeed() end, info = function(self, t) return ([[Yeeks live fast, think fast, and sacrifice fast for the Way. - Increase global speed by %d%%.]]):format(self:getTalentLevelRaw(t) * 3) + Increase global speed by %0.1f%%.]]):format(100*t.speedup(self, t)) end, } @@ -801,7 +822,7 @@ newTalent{ require = racial_req4, points = 5, no_energy = true, - cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 3 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 6, 47, 35)) end, -- Limit >6 range = 4, no_npc_use = true, action = function(self, t) @@ -838,8 +859,14 @@ newTalent{ autolevel = "none", ai = "summoned", ai_real = "tactical", ai_state = { talent_in=2, }, stats = {str=0, dex=0, con=0, cun=0, wil=0, mag=0}, - inc_stats = { str=25 + self:getWil() * self:getTalentLevel(t) / 5, mag=10, cun=25 + self:getWil() * self:getTalentLevel(t) / 5, wil=25 + self:getWil() * self:getTalentLevel(t) / 5, dex=18, con=10 + self:getTalentLevel(t) * 2, }, - + inc_stats = { + str=self:combatScale(self:getWil() * self:getTalentLevel(t), 25, 0, 125, 500, 0.75), + mag=10, + cun=self:combatScale(self:getWil() * self:getTalentLevel(t), 25, 0, 125, 500, 0.75), + wil=self:combatScale(self:getWil() * self:getTalentLevel(t), 25, 0, 125, 500, 0.75), + dex=18, + con=10 + self:combatTalentScale(t, 2, 10, 0.75), + }, resolvers.equip{ {type="weapon", subtype="longsword", autoreq=true}, {type="weapon", subtype="dagger", autoreq=true}, @@ -869,7 +896,7 @@ newTalent{ end, info = function(self, t) return ([[Reach through the collective psionic gestalt of the yeeks, the Way, to call for immediate help. - Summons up to 3 yeek mindslayers to your side.]]) + Summons up to 3 yeek mindslayers to your side for 6 turns.]]) end, } diff --git a/game/modules/tome/data/talents/undeads/ghoul.lua b/game/modules/tome/data/talents/undeads/ghoul.lua index da73b6f20c110fcb1a0ed4d3a5fbdef2179d7d98..7fe1ce48ae04d96f063d105ac9af27dec899e545 100644 --- a/game/modules/tome/data/talents/undeads/ghoul.lua +++ b/game/modules/tome/data/talents/undeads/ghoul.lua @@ -23,26 +23,17 @@ newTalent{ mode = "passive", require = undeads_req1, points = 5, - on_learn = function(self, t) - self.inc_stats[self.STAT_STR] = self.inc_stats[self.STAT_STR] + 2 - self:onStatChange(self.STAT_STR, 2) - self.inc_stats[self.STAT_CON] = self.inc_stats[self.STAT_CON] + 2 - self:onStatChange(self.STAT_CON, 2) - end, - on_unlearn = function(self, t) - self.inc_stats[self.STAT_STR] = self.inc_stats[self.STAT_STR] - 2 - self:onStatChange(self.STAT_STR, -2) - self.inc_stats[self.STAT_CON] = self.inc_stats[self.STAT_CON] - 2 - self:onStatChange(self.STAT_CON, -2) - end, + statBonus = function(self, t) return self:combatTalentScale(t, 2, 10, 0.75) end, getMaxDamage = function(self, t) return math.max(50, 100 - self:getTalentLevelRaw(t) * 10) end, passives = function(self, t, p) + self:talentTemporaryValue(p, "inc_stats", {[self.STAT_STR]=t.statBonus(self, t)}) + self:talentTemporaryValue(p, "inc_stats", {[self.STAT_CON]=t.statBonus(self, t)}) self:talentTemporaryValue(p, "flat_damage_cap", {all=t.getMaxDamage(self, t)}) end, info = function(self, t) return ([[Improves your ghoulish body, increasing Strength and Constitution by %d. Your body also becomes incredibly resilient to damage, you can never take a blow that deals more than %d%% of your maximum life.]]) - :format(2 * self:getTalentLevelRaw(t), t.getMaxDamage(self, t)) + :format(t.statBonus(self, t), t.getMaxDamage(self, t)) end, } @@ -54,7 +45,7 @@ newTalent{ tactical = { CLOSEIN = 3 }, direct_hit = true, cooldown = function(self, t) return math.max(10, 22 - self:getTalentLevelRaw(t) * 2) end, - range = function(self, t) return math.floor(4 + self:getTalentLevel(t) * 1.2) end, + range = function(self, t) return math.floor(self:combatTalentScale(t, 5, 10, 0.5, 0, 1)) end, requires_target = true, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} @@ -96,8 +87,11 @@ newTalent{ tactical = { ATTACK = { BLIGHT = 1 }, HEAL = 1 }, range=1, requires_target = true, + getduration = function(self, t) return self:combatTalentScale(t, 7, 15, 0.5) end, + getPurgeChance = function(self, t) return self:combatTalentLimit(t, 100, 5, 25) end, -- Limit < 100% + -- status effect removal handled in mod.data.damage_types (type = "RETCH") action = function(self, t) - local duration = self:getTalentLevelRaw(t) * 2 + 5 + local duration = t.getduration(self, t) local radius = 3 local dam = 10 + self:combatTalentStatDamage(t, "con", 10, 60) local tg = {type="ball", range=self:getTalentRange(t), radius=radius} @@ -118,7 +112,7 @@ newTalent{ return ([[Vomit on the ground around you, healing any undead in the area and damaging anyone else. Lasts %d turns, and deals %d blight damage or heals %d life. Creatures standing in the retch also have %d%% chance to loose a physical effect each turn. - Undeads will be stripped from a detrimental effect while others will be stripped from a beneficial effect.]]):format(self:getTalentLevelRaw(t) * 2 + 5, damDesc(self, DamageType.BLIGHT, dam), dam * 1.5, self:getTalentLevel(t) * 5) + Undeads will be stripped from a detrimental effect while others will be stripped from a beneficial effect.]]):format(t.getduration(self, t), damDesc(self, DamageType.BLIGHT, dam), dam * 1.5, t.getPurgeChance(self, t)) end, } @@ -131,8 +125,8 @@ newTalent{ tactical = { ATTACK = {BLIGHT = 2} }, range = 1, requires_target = true, - getDamage = function(self, t) return 0.2 + self:getTalentLevel(t) / 12 end, - getDuration = function(self, t) return 3 + math.ceil(self:getTalentLevel(t)) end, + getDamage = function(self, t) return self:combatTalentScale(t, 0.28, 0.62) end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 4, 8)) end, getDiseaseDamage = function(self, t) return self:combatTalentStatDamage(t, "con", 5, 50) end, getStatDamage = function(self, t) return self:combatTalentStatDamage(t, "con", 5, 20) end, spawn_ghoul = function (self, target, t) @@ -185,7 +179,7 @@ newTalent{ if target.dead and ghoulify > 0 then t.spawn_ghoul(self, target, t) end - target:setEffect(target.EFF_GHOUL_ROT, 3 + math.ceil(self:getTalentLevel(t)), {src=self, apply_power=self:combatPhysicalpower(), dam=t.getDiseaseDamage(self, t), str=str_damage, con=con_damage, dex=dex_damage, make_ghoul=ghoulify}) + target:setEffect(target.EFF_GHOUL_ROT, t.getDuration(self,t), {src=self, apply_power=self:combatPhysicalpower(), dam=t.getDiseaseDamage(self, t), str=str_damage, con=con_damage, dex=dex_damage, make_ghoul=ghoulify}) else game.logSeen(target, "%s resists the disease!", target.name:capitalize()) end diff --git a/game/modules/tome/data/talents/undeads/skeleton.lua b/game/modules/tome/data/talents/undeads/skeleton.lua index b077665143c3cdd8232e85703a6541d96cbca4e3..0148f9bf53954c7ca7c45890a3c2162dda51931a 100644 --- a/game/modules/tome/data/talents/undeads/skeleton.lua +++ b/game/modules/tome/data/talents/undeads/skeleton.lua @@ -23,20 +23,14 @@ newTalent{ mode = "passive", require = undeads_req1, points = 5, - on_learn = function(self, t) - self.inc_stats[self.STAT_STR] = self.inc_stats[self.STAT_STR] + 2 - self:onStatChange(self.STAT_STR, 2) - self.inc_stats[self.STAT_DEX] = self.inc_stats[self.STAT_DEX] + 2 - self:onStatChange(self.STAT_DEX, 2) - end, - on_unlearn = function(self, t) - self.inc_stats[self.STAT_STR] = self.inc_stats[self.STAT_STR] - 2 - self:onStatChange(self.STAT_STR, -2) - self.inc_stats[self.STAT_DEX] = self.inc_stats[self.STAT_DEX] - 2 - self:onStatChange(self.STAT_DEX, -2) + statBonus = function(self, t) return self:combatTalentScale(t, 2, 10, 0.75) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "inc_stats", {[self.STAT_STR]=t.statBonus(self, t)}) + self:talentTemporaryValue(p, "inc_stats", {[self.STAT_DEX]=t.statBonus(self, t)}) end, info = function(self, t) - return ([[Improves your skeletal condition, increasing Strength and Dexterity by %d.]]):format(2 * self:getTalentLevelRaw(t)) + return ([[Improves your skeletal condition, increasing Strength and Dexterity by %d.]]): + format(t.statBonus(self, t)) end, } @@ -47,14 +41,18 @@ newTalent{ points = 5, cooldown = 30, tactical = { DEFEND = 2 }, + getShield = function(self, t) + return 3.5*self:getDex()+self:combatTalentScale(t, 120, 400) + self:combatTalentLimit(t, 0.1, 0.01, 0.05)*self.max_life + end, + action = function(self, t) - self:setEffect(self.EFF_DAMAGE_SHIELD, 10, {power=50 + 70 * self:getTalentLevel(t) + self:getDex(350, true)}) + self:setEffect(self.EFF_DAMAGE_SHIELD, 10, {power=t.getShield(self, t)}) return true end, info = function(self, t) return ([[Creates a shield of bones, absorbing %d damage. Lasts for 10 turns. The total damage the shield can absorb increases with your Dexterity.]]): - format(50 + 70 * self:getTalentLevel(t) + self:getDex(350, true)) + format(t.getShield(self, t)) end, } @@ -65,9 +63,11 @@ newTalent{ points = 5, mode = "passive", range = 1, + -- called by _M:on_set_temporary_effect function in mod.class.Actor.lua + durresist = function(self, t) return self:combatTalentLimit(t, 1, 0.1, 5/12) end, -- Limit < 100% info = function(self, t) - return ([[Your undead bones are very resilient, reducing the duration of all detrimental effects on you by %d%%.]]): - format(100 * (self:getTalentLevel(self.T_RESILIENT_BONES) / 12)) + return ([[Your undead bones are very resilient, reducing the duration of all detrimental effects on you by up to %d%%.]]): + format(100 * t.durresist(self, t)) end, } @@ -76,7 +76,10 @@ newTalent{ short_name = "SKELETON_REASSEMBLE", type = {"undead/skeleton",4}, require = undeads_req4, points = 5, - cooldown = function(self, t) return 45 - self:getTalentLevelRaw(t) * 4 end, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 10, 41, 25)) end, -- Limit cooldown >10 + getHeal = function(self, t) + return self:combatTalentScale(t, 100, 500) + self:combatTalentLimit(t, 0.1, 0.01, 0.05)*self.max_life + end, tactical = { HEAL = 2 }, is_heal = true, on_learn = function(self, t) @@ -91,7 +94,7 @@ newTalent{ short_name = "SKELETON_REASSEMBLE", end, action = function(self, t) self:attr("allow_on_heal", 1) - self:heal(100 * self:getTalentLevel(t), self) + self:heal(t.getHeal(self, t), self) self:attr("allow_on_heal", -1) game:playSoundNear(self, "talents/heal") return true @@ -99,6 +102,6 @@ newTalent{ short_name = "SKELETON_REASSEMBLE", info = function(self, t) return ([[Re-position some of your bones, healing yourself for %d. At level 5, you will gain the ability to completely re-assemble your body should it be destroyed (can only be used once)]]): - format(100 * self:getTalentLevel(t)) + format(t.getHeal(self, t)) end, } diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua index 9f42e7e020b95564af67238b5205c812ebadbd9f..33809ed499cbbfcb4740e1ff779890fc719f3c57 100644 --- a/game/modules/tome/data/timed_effects/mental.lua +++ b/game/modules/tome/data/timed_effects/mental.lua @@ -1773,6 +1773,9 @@ newEffect{ on_gain = function(self, err) return nil, "+Bloodbath" end, on_lose = function(self, err) return nil, "-Bloodbath" end, on_merge = function(self, old_eff, new_eff) + + if old_eff.cur_regen + new_eff.regen < new_eff.max then game.logSeen(self, "%s's blood frenzy intensifies!", self.name:capitalize()) end + new_eff.templife_id = old_eff.templife_id self:removeTemporaryValue("max_life", old_eff.life_id) self:removeTemporaryValue("life_regen", old_eff.life_regen_id) self:removeTemporaryValue("stamina_regen", old_eff.stamina_regen_id) @@ -1788,15 +1791,19 @@ newEffect{ activate = function(self, eff) local v = eff.hp * self.max_life / 100 eff.life_id = self:addTemporaryValue("max_life", v) - self:heal(v) + eff.templife_id = self:addTemporaryValue("life",v) -- Prevent healing_factor affecting activation eff.cur_regen = eff.regen eff.life_regen_id = self:addTemporaryValue("life_regen", eff.regen) eff.stamina_regen_id = self:addTemporaryValue("stamina_regen", eff.regen /5) + game.logSeen(self, "%s revels in the spilt blood and grows stronger!",self.name:capitalize()) end, deactivate = function(self, eff) self:removeTemporaryValue("max_life", eff.life_id) self:removeTemporaryValue("life_regen", eff.life_regen_id) self:removeTemporaryValue("stamina_regen", eff.stamina_regen_id) + + self:removeTemporaryValue("life",eff.templife_id) -- remove extra hps to prevent excessive heals at high level + game.logSeen(self, "%s no longer revels in blood quite so much.",self.name:capitalize()) end, } diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua index 0e4a205d81554d3b48dfff7be41a6d19aea77075..dc58dd0526a5338c7291f9fd76374f2a3db68471 100644 --- a/game/modules/tome/data/timed_effects/other.lua +++ b/game/modules/tome/data/timed_effects/other.lua @@ -992,6 +992,7 @@ newEffect{ type = "other", subtype = { time=true }, status = "detrimental", + no_stop_enter_worlmap = true, no_stop_resting = true, parameters = { power=10 }, activate = function(self, eff) diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua index c4de85efb48507cfaf3027f1162cbca5ba775185..11eaa88ff3fd7007fb1f7f40244405f01545b058 100644 --- a/game/modules/tome/data/timed_effects/physical.lua +++ b/game/modules/tome/data/timed_effects/physical.lua @@ -417,9 +417,11 @@ newEffect{ on_lose = function(self, err) return "#Target# is no longer evading attacks.", "-Evasion" end, activate = function(self, eff) eff.tmpid = self:addTemporaryValue("evasion", eff.chance) + eff.defid = self:addTemporaryValue("combat_def", eff.defense) end, deactivate = function(self, eff) self:removeTemporaryValue("evasion", eff.tmpid) + self:removeTemporaryValue("combat_def", eff.defid) end, }