From 97d23b0b9569e1db3bf52affec2a1074057a2fd2 Mon Sep 17 00:00:00 2001 From: DarkGod <darkgod@net-core.org> Date: Thu, 18 Jul 2013 01:36:50 +0200 Subject: [PATCH] Applied infinite scaling to afflicted --- game/modules/tome/class/Actor.lua | 1 + game/modules/tome/class/interface/Combat.lua | 17 +- .../tome/data/talents/cursed/cursed-aura.lua | 93 ++++++---- .../tome/data/talents/cursed/cursed-form.lua | 47 ++--- .../data/talents/cursed/dark-sustenance.lua | 7 +- .../tome/data/talents/cursed/darkness.lua | 15 +- .../tome/data/talents/cursed/endless-hunt.lua | 6 +- .../data/talents/cursed/force-of-will.lua | 72 +++----- .../tome/data/talents/cursed/gestures.lua | 81 ++++++--- .../tome/data/talents/cursed/gloom.lua | 34 ++-- .../tome/data/talents/cursed/predator.lua | 43 ++--- .../tome/data/talents/cursed/punishments.lua | 10 +- .../tome/data/talents/cursed/rampage.lua | 20 +- .../tome/data/talents/cursed/shadows.lua | 40 ++-- .../tome/data/talents/cursed/slaughter.lua | 28 +-- .../tome/data/talents/cursed/strife.lua | 15 +- .../tome/data/timed_effects/mental.lua | 29 +++ .../modules/tome/data/timed_effects/other.lua | 171 +++++++++--------- .../tome/data/timed_effects/physical.lua | 3 + 19 files changed, 380 insertions(+), 352 deletions(-) diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 4e7b2576b6..b4cc2da576 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -462,6 +462,7 @@ function _M:actBase() end end + if self:knowTalent(self.T_GESTURE_OF_GUARDING) then self:setEffect(self.EFF_GESTURE_OF_GUARDING,1,{}) end if self:knowTalent(self.T_DUAL_WEAPON_DEFENSE) then self:setEffect(self.EFF_DUAL_WEAPON_DEFENSE,1,{}) end if self:knowTalent(self.T_COUNTER_ATTACK) then self:setEffect(self.EFF_COUNTER_ATTACKING,1,{}) end if self:knowTalent(self.T_DEFENSIVE_THROW) then self:setEffect(self.EFF_DEFENSIVE_GRAPPLING,1,{}) end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 455bfd1d9b..68455a0ad3 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -359,11 +359,6 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) end end - if target.knowTalent and target:knowTalent(target.T_GESTURE_OF_GUARDING) then - local t = target:getTalentFromId(target.T_GESTURE_OF_GUARDING) - mult = mult * (100 + t.getDamageChange(target, t)) / 100 - end - -- track weakness for hate bonus before the target removes it local effGloomWeakness = target:hasEffect(target.EFF_GLOOM_WEAKNESS) @@ -396,6 +391,12 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) print("[ATTACK] after DUAL_WEAPON_DEFENSE", dam) end end + if target.knowTalent and target:hasEffect(target.EFF_GESTURE_OF_GUARDING) then + local deflected = math.min(dam, target:callTalent(target.T_GESTURE_OF_GUARDING, "doGuard")) + game.logSeen(target, "%s dismisses %d damage from %s's attack with a sweeping gesture.", target.name:capitalize(), deflected, self.name:capitalize()) + dam = dam - deflected + print("[ATTACK] after GESTURE_OF_GUARDING", dam) + end print("[ATTACK] raw dam", dam, "versus", armor, pres, "with APR", apr) armor = math.max(0, armor - apr) dam = math.max(dam * pres - armor, 0) + (dam * (1 - pres)) @@ -771,7 +772,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) end -- Gesture of Guarding counterattack - if hitted and not target.dead and not target:attr("stunned") and not target:attr("dazed") and not target:attr("stoned") and target:knowTalent(target.T_GESTURE_OF_GUARDING) then + if hitted and not target.dead and not target:attr("stunned") and not target:attr("dazed") and not target:attr("stoned") and target:hasEffect(target.EFF_GESTURE_OF_GUARDING) then local t = target:getTalentFromId(target.T_GESTURE_OF_GUARDING) t.on_hit(target, t, self) end @@ -1859,7 +1860,7 @@ end function _M:combatSeeStealth() local bonus = 0 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 + 5 + self:getTalentLevel(self.T_PRETERNATURAL_SENSES) * self:getWil(15, true) 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 end @@ -1868,7 +1869,7 @@ end function _M:combatSeeInvisible() local bonus = 0 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 + 5 + self:getTalentLevel(self.T_PRETERNATURAL_SENSES) * self:getWil(15, true) end + if self:knowTalent(self.T_PRETERNATURAL_SENSES) then bonus = bonus + self:callTalent(self.T_PRETERNATURAL_SENSES, "sensePower") end return (self:attr("see_invisible") or 0) + bonus end diff --git a/game/modules/tome/data/talents/cursed/cursed-aura.lua b/game/modules/tome/data/talents/cursed/cursed-aura.lua index 79220afae0..f24f4a5dd0 100644 --- a/game/modules/tome/data/talents/cursed/cursed-aura.lua +++ b/game/modules/tome/data/talents/cursed/cursed-aura.lua @@ -37,6 +37,9 @@ newTalent{ getCurses = function(self, t) return { self.EFF_CURSE_OF_CORPSES, self.EFF_CURSE_OF_MADNESS, self.EFF_CURSE_OF_MISFORTUNE, self.EFF_CURSE_OF_NIGHTMARES, self.EFF_CURSE_OF_SHROUDS } end, + cursePenalty = function(self, t) + return self:combatTalentLimit(math.max(1, self:getTalentLevel(t)-9), 0, 1, 0.50) + end, -- tests whether or not an item can be cursed (takes into account current talent level unless ignoreLevel = true) canCurseItem = function(self, t, item, level) if not item:wornInven() then return false end @@ -55,6 +58,11 @@ newTalent{ if level >= 2 and item.type == "armor" and (item.slot == "BODY" or item.slot == "CLOAK") then return true end if level >= 3 and item.type == "armor" and (item.slot == "HEAD" or item.slot == "OFFHAND") then return true end if level >= 4 and item.type == "armor" and (item.slot == "HANDS" or item.slot == "FEET" or item.slot == "BELT") then return true end + if level >=6 and item.type == "jewelry" and item.slot == "FINGER" then return true end + if level >=7 and item.type == "jewelry" and item.slot == "NECK" then return true end + if level >=8 and item.type == "lite" and item.slot == "LITE" then return true end + if level >=9 and (item.type == "charm" or item.type == "tool") and item.slot == "TOOL" then return true end + if level >=10 and item.slot == "QUIVER" and (item.type == "alchemist-gem" or item.type == "ammo") then return true end return false end, @@ -198,11 +206,12 @@ newTalent{ local tDarkGifts = self:getTalentFromId(self.T_DARK_GIFTS) for i, curse in ipairs(curses) do local eff = self:hasEffect(curse) - local level = itemCounts[curse] or 0 + local level = itemCounts[curse] and (itemCounts[curse] + self:callTalent(self.T_DARK_GIFTS, "curseBonusLevel")) or 0 + local penalty = t.cursePenalty(self, t) local currentLevel = eff and eff.level or 0 - + local currentPenalty = eff and eff.Penalty or 1 --print("* curse:", self.tempeffect_def[curse].desc, currentLevel, "->", level, eff) - if currentLevel ~= level or forceUpdateEffects then + if currentLevel ~= level or currentPenalty ~= penalty or forceUpdateEffects then if eff then self:removeEffect(curse, false, true) end @@ -212,9 +221,10 @@ newTalent{ if not eff then eff = { def = self.tempeffect_def[curse] } end - eff.level = math.min(5, level) + eff.level = level + eff.Penalty = penalty + eff.BonusPower = BonusPower eff.unlockLevel = math.min(5, tDarkGifts and self:getTalentLevelRaw(tDarkGifts) or 0) - self:setEffect(curse, 1, eff) end @@ -240,12 +250,21 @@ newTalent{ game:registerDialog(cursedAuraSelect) end, info = function(self, t) - return ([[Your defiling touch permeates everything around you, imparting a random curse on each item you find. When you equip a cursed item, you gain the effects of that curse. Multiple items with the same curse increase the power of those effects up to a maximum level of 5. Initially curses are harmful, but powerful benefits can be unlocked with multiple items and the Dark Gifts. - At level 1 you gain the ability to curse weapons. - At level 2 you gain the ability to curse body armor and cloaks. - At level 3 you gain the ability to curse shields and helmets. - At level 4 you gain the ability to curse gloves, boots and belts. - At level 5 you can activate this talent to surround yourself with an aura that adds 2 levels to a curse of your choosing. (Currently %s)]]):format(t.getCursedAuraName(self, t)) + return ([[Your defiling touch permeates everything around you, permanently imparting a random curse on each item you find. When you equip a cursed item, you gain the effects of that curse (shown as a beneficial effect). Each item with the same curse that is equipped increases the curse's power. Initially curses are harmful, but powerful benefits accumulate as the power of the curse increases. + The Dark Gifts talent unlocks higher level curse effects and increases their power. + Your aura permeates your equipment more thoroughly with talent level and can affect items as follows: + Level 1 -- weapons + Level 2 -- body armor and cloaks + Level 3 -- shields and helmets + Level 4 -- gloves, boots and belts + Level 6 -- rings + Level 7 -- amulets/necklaces + Level 8 -- lites + Level 9 -- tools/totems/torques/wands + level 10 -- ammunition + At level 5, you can activate this talent to surround yourself with an aura that adds 2 levels to a curse of your choosing. (%s chosen) + Talent levels higher than 10 reduce the negative effects of your curses (currently %d%% reduction).]]): + format(t.getCursedAuraName(self, t), (1-t.cursePenalty(self, t))*100) end, } @@ -256,6 +275,9 @@ newTalent{ require = cursed_lev_req2, no_unlearn_last = true, points = 5, + curseBonusLevel = function(self, t) + return self:combatTalentScale(math.max(0,self:getTalentLevel(t)-5), 1, 2.5) + end, on_learn = function(self, t) local tDefilingTouch = self:getTalentFromId(self.T_DEFILING_TOUCH) tDefilingTouch.updateCurses(self, tDefilingTouch, true) @@ -266,7 +288,10 @@ newTalent{ end, info = function(self, t) local level = math.min(4, self:getTalentLevelRaw(t)) - return ([[Your curses bring you dark gifts. Unlocks bonus level %d effects on all of your curses, allowing you to gain that effect when the power level of your curse reaches that level. At talent level 5, the luck penalty of cursed effects is reduced to 1.]]):format(level) + local xs = t.curseBonusLevel(self,t) + return ([[Your curses bring you dark gifts. Unlocks bonus level %d effects on all of your curses, allowing you to gain that effect when the power level of your curse reaches that level. At talent level 5, the luck penalty of cursed effects is reduced to 1. + Talent levels above 5 add bonus power levels to your curses, increasing their effects (currently %0.1f).]]): + format(level, xs) end, } @@ -325,12 +350,8 @@ newTalent{ cooldown = 40, range = 5, no_npc_use = true, - getDuration = function(self, t) - return math.floor(6 + self:getTalentLevel(t) * 2) - end, - getAttackSpeed = function(self, t) - return math.min(1.6, 0.4 + self:getTalentLevel(t)/5) - end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 8, 16)) end, + getAttackSpeed = function(self, t) return self:combatTalentScale(t, 0.6, 1.4) end, action = function(self, t) local inven = self:getInven("INVEN") local found = false @@ -377,24 +398,31 @@ newTalent{ local sentry = NPC.new { type = "construct", subtype = "weapon", display = o.display, color=o.color, image = o.image, blood_color = colors.GREY, - name = "animated "..o.name, faction = self.faction, + name = "animated "..o:getName(), -- bug fix + faction = self.faction, desc = "A weapon imbued with a living curse. It seems to be searching for its next victim.", faction = self.faction, body = { INVEN = 10, MAINHAND=1, QUIVER=1 }, rank = 2, size_category = 1, - autolevel = "warrior", + autolevel = o.combat.wil_attack and "summoner" or "warrior", ai = "summoned", ai_real = "tactical", ai_state = { talent_in=1, }, - max_life = 50, life_rating = 3, - stats = { str=20, dex=20, mag=10, con=10 }, + max_life = 50 + self.max_life*self:combatTalentLimit(t, 1, 0.04, 0.17), -- Add % of summoner's life < 100% + life_rating = 3, + stats = o.combat.wil_attack and {wil= 20, cun = 20, mag=10, con=10} or {str=20, dex=20, mag=10, con=10}, combat = { dam=1, atk=1, apr=1 }, - combat_armor = 100, combat_def = 50, + combat_armor = math.max(100,50 + self.level), + combat_armor_hardiness = math.min(70,5*self:getTalentLevel(t)), + combat_def = math.max(50,self.level), + inc_damage = table.clone(self.inc_damage or {}, true), + resists_pen = table.clone(self.resists_pen or {}, true), + combat_physspeed = t.getAttackSpeed(self, t), infravision = 10, - resists = { all = 75, }, + resists = { all = self:combatTalentLimit(t, 100, 71, 75), }, cut_immune = 1, blind_immune = 1, fear_immune = 1, @@ -408,16 +436,17 @@ newTalent{ no_drops = true, -- remove to drop the weapon resolvers.talents{ - [Talents.T_WEAPON_COMBAT]={base=1, every=10, max=5}, - [Talents.T_WEAPONS_MASTERY]={base=1, every=10, max=5}, - [Talents.T_KNIFE_MASTERY]={base=1, every=10, max=5}, - [Talents.T_EXOTIC_WEAPONS_MASTERY]={base=1, every=10, max=5}, - [Talents.T_STAFF_MASTERY]={base=1, every=10, max=5}, - [Talents.T_BOW_MASTERY]={base=1, every=10, max=5}, - [Talents.T_SLING_MASTERY]={base=1, every=10, max=5}, + [Talents.T_WEAPON_COMBAT]={base=1, every=10}, + [Talents.T_WEAPONS_MASTERY]={base=1, every=10}, + [Talents.T_KNIFE_MASTERY]={base=1, every=10}, + [Talents.T_EXOTIC_WEAPONS_MASTERY]={base=1, every=10}, + [Talents.T_STAFF_MASTERY]={base=1, every=10}, + [Talents.T_BOW_MASTERY]={base=1, every=10}, + [Talents.T_SLING_MASTERY]={base=1, every=10}, + [Talents.T_PSIBLADES]=o.combat.wil_attack and {base=1, every=10}, [Talents.T_SHOOT]=1, }, - + o.combat.wil_attack and resolvers.sustains_at_birth(), summoner = self, summoner_gain_exp=true, summon_time = t.getDuration(self, t), diff --git a/game/modules/tome/data/talents/cursed/cursed-form.lua b/game/modules/tome/data/talents/cursed/cursed-form.lua index 93304d9580..9f1b93b635 100644 --- a/game/modules/tome/data/talents/cursed/cursed-form.lua +++ b/game/modules/tome/data/talents/cursed/cursed-form.lua @@ -31,18 +31,16 @@ newTalent{ getHealPerKill = function(self, t) return combatTalentDamage(self, t, 15, 50) end, - getMaxUnnaturalBodyHeal = function(self, t) - return t.getHealPerKill(self, t) * 2 - end, - getRegenRate = function(self, t) - return 3 + math.sqrt(self:getTalentLevel(t) * 2) * math.min(1000, self.max_life) * 0.006 + getMaxUnnaturalBodyHeal = function(self, t) -- Add up to 50% max life to pool + return t.getHealPerKill(self, t) * 2 + self:combatTalentLimit(t, .5, 0.01, 0.03) * self.max_life end, + getRegenRate = function(self, t) return 3 + combatTalentDamage(self, t, 15, 25) end, updateHealingFactor = function(self, t) local change = -0.5 + math.min(100, self:getHate()) * .005 self.healing_factor = (self.healing_factor or 1) - (self.unnatural_body_healing_factor or 0) + change self.unnatural_body_healing_factor = change end, - do_regenLife = function(self, t) + do_regenLife = function(self, t) -- called by _M:actBase in mod.class.Actor.lua -- update healing factor t.updateHealingFactor(self, t) @@ -58,9 +56,9 @@ newTalent{ self.unnatural_body_heal = math.max(0, (self.unnatural_body_heal or 0) - heal) end end, - on_kill = function(self, t, target) + on_kill = function(self, t, target) -- called by _M:die in mod.class.Actor.lua if target and target.max_life then - heal = math.min(t.getHealPerKill(self, t), target.max_life) + local heal = math.min(t.getHealPerKill(self, t), target.max_life) if heal > 0 then self.unnatural_body_heal = math.min(self.life, (self.unnatural_body_heal or 0) + heal) self.unnatural_body_heal = math.min(self.unnatural_body_heal, t.getMaxUnnaturalBodyHeal(self, t)) @@ -72,7 +70,7 @@ newTalent{ local maxUnnaturalBodyHeal = t.getMaxUnnaturalBodyHeal(self, t) local regenRate = t.getRegenRate(self, t) - return ([[Your body's strength is fed by your hatred. This causes most forms of healing to be between 50%% effective (at 0 Hate) to 100%% effective (at 100+ Hate). In addition, after each kill, you regenerate %d life (up to a maximum of %d) at a rate of %0.1f life per turn. This healing cannot be reduced by your hatred levels. + return ([[Your body's strength is fed by your hatred. This causes most forms of healing to be between 50%% effective (at 0 Hate) to 100%% effective (at 100+ Hate). In addition, after each kill, you store the waning life force to invigorate yourself, restoring %d life (limited by the foe's maximum life, up to a maximum of %d at any time). You can heal no more than %0.1f life per turn this way, and it is not affected by your hatred level or other effects. Healing from kills improves with your Willpower.]]):format(healPerKill, maxUnnaturalBodyHeal, regenRate) end, } @@ -83,22 +81,15 @@ newTalent{ mode = "passive", require = cursed_wil_req2, points = 5, - on_learn = function(self, t) - self:attr("fear_immune", 0.15) - self:attr("confusion_immune", 0.15) - self:attr("knockback_immune", 0.15) - self:attr("stun_immune", 0.15) - return true - end, - on_unlearn = function(self, t) - self:attr("fear_immune", -0.15) - self:attr("confusion_immune", -0.15) - self:attr("knockback_immune", -0.15) - self:attr("stun_immune", -0.15) - return true + getImmune = function(self, t) return self:combatTalentLimit(t, 1, 0.15, 0.5) end, -- Limit < 100% + passives = function(self, t, p) + self:talentTemporaryValue(p, "fear_immune", t.getImmune(self, t)) + self:talentTemporaryValue(p, "confusion_immune", t.getImmune(self, t)) + self:talentTemporaryValue(p, "knockback_immune", t.getImmune(self, t)) + self:talentTemporaryValue(p, "stun_immune", t.getImmune(self, t)) end, info = function(self, t) - return ([[Your thirst for blood drives your movements. (+%d%% confusion, fear, knockback and stun immunity)]]):format(self:getTalentLevelRaw(t) * 15) + return ([[Your thirst for blood drives your movements. You gain +%d%% confusion, fear, knockback and stun immunity.]]):format(t.getImmune(self, t)*100) end, } @@ -109,7 +100,7 @@ newTalent{ require = cursed_wil_req3, points = 5, getIncDamageChange = function(self, t, increase) - return math.min(30, math.floor(math.sqrt(self:getTalentLevel(t)) * 2 * increase)) + return self:combatTalentLimit(t, 60, 2, 2*2.24) * increase --I5 Limit < 60% end, info = function(self, t) local incDamageChangeMax = t.getIncDamageChange(self, t, 5) @@ -123,12 +114,8 @@ newTalent{ require = cursed_wil_req4, mode = "passive", points = 5, - getStatChange = function(self, t, increase) - return math.min(18, math.floor(math.sqrt(self:getTalentLevel(t) * 1) * increase)) - end, - getNeutralizeChance = function(self, t) - return math.min(30, math.floor(math.sqrt(self:getTalentLevel(t)) * 10)) - end, + getStatChange = function(self, t, increase) return math.floor(self:combatTalentScale(t, 1, 2.24) * increase) end, + getNeutralizeChance = function(self, t) return self:combatTalentLimit(t, 60, 10, 23.4) end, -- Limit < 60% info = function(self, t) local statChangeMax = t.getStatChange(self, t, 5) local neutralizeChance = t.getNeutralizeChance(self, t) diff --git a/game/modules/tome/data/talents/cursed/dark-sustenance.lua b/game/modules/tome/data/talents/cursed/dark-sustenance.lua index ebc4f3c185..4b4c8b142f 100644 --- a/game/modules/tome/data/talents/cursed/dark-sustenance.lua +++ b/game/modules/tome/data/talents/cursed/dark-sustenance.lua @@ -167,7 +167,7 @@ newTalent{ require = cursed_wil_req3, points = 5, getDamageGain = function(self, t) - return math.sqrt(self:getTalentLevel(t)) * 5 + self:combatMindpower() * 0.05 + return self:combatLimit(self:getTalentLevel(t)^0.5 * 5 + self:combatMindpower() * 0.05, 100, 0, 0, 14, 14) -- Limit < 100% end, info = function(self, t) local damageGain = t.getDamageGain(self, t) @@ -183,10 +183,7 @@ newTalent{ require = cursed_wil_req4, points = 5, getResistGain = function(self, t) - return math.sqrt(self:getTalentLevel(t)) * 14 + self:combatMindpower() * 0.15 - end, - getExtension = function(self, t) - return math.floor(self:getTalentLevel(t) - 1) + return self:combatLimit(self:getTalentLevel(t)^0.5 * 14 + self:combatMindpower() * 0.15, 100, 0, 0, 40, 40) -- Limit < 100% end, info = function(self, t) local resistGain = t.getResistGain(self, t) diff --git a/game/modules/tome/data/talents/cursed/darkness.lua b/game/modules/tome/data/talents/cursed/darkness.lua index 847c423e28..514873f5ca 100644 --- a/game/modules/tome/data/talents/cursed/darkness.lua +++ b/game/modules/tome/data/talents/cursed/darkness.lua @@ -146,7 +146,8 @@ local function getDamageIncrease(self) t = self:getTalentFromId(self.T_DARK_TENDRILS) if t then total = total + self:getTalentLevelRaw(t) end - return total * 2 + return self:combatScale(total, 5, 1, 40, 20) --I5 +--I5 return total * 2 end newTalent{ @@ -287,7 +288,8 @@ newTalent{ end, getDarkCount = function(self, t) - return 1 + math.floor(self:getTalentLevel(t)) +--I5 return 1 + math.floor(self:getTalentLevel(t)) + return math.floor(self:combatTalentScale(t, 2, 6, "log")) --I5 end, getDamage = function(self, t) return self:combatTalentMindDamage(t, 0, 60) @@ -351,10 +353,12 @@ newTalent{ mode = "passive", random_ego = "attack", range = function(self, t) - return 1 + self:getTalentLevelRaw(t) +--I5 return 1 + self:getTalentLevelRaw(t) + return math.floor(self:combatTalentScale(t, 2, 6)) --I5 end, getMovementSpeedChange = function(self, t) - return self:getTalentLevel(t) * 0.5 +--I5 return self:getTalentLevel(t) * 0.5 + return self:combatTalentScale(t, 0.75, 2.5, 0.75) --I5 end, info = function(self, t) local range = self:getTalentRange(t) @@ -436,7 +440,8 @@ newTalent{ direct_hit = true, requires_target = true, getPinDuration = function(self, t) - return 2 + math.floor(self:getTalentLevel(t) / 2) +--I5 return 2 + math.floor(self:getTalentLevel(t) / 2) + return math.floor(self:combatTalentScale(t, 2.5, 4.5)) --I5 end, getDamage = function(self, t) return self:combatTalentMindDamage(t, 0, 80) diff --git a/game/modules/tome/data/talents/cursed/endless-hunt.lua b/game/modules/tome/data/talents/cursed/endless-hunt.lua index 71daa4db81..82e4f5535c 100644 --- a/game/modules/tome/data/talents/cursed/endless-hunt.lua +++ b/game/modules/tome/data/talents/cursed/endless-hunt.lua @@ -146,14 +146,12 @@ newTalent{ cooldown = 6, hate = 5, tactical = { ATTACK = { PHYSICAL = 3 } }, - getCooldownDuration = function(self, t) - return 3 + math.floor(self:getTalentLevel(t) * 0.75) - end, + getCooldownDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3.75, 6.75, "log", 0, 1)) end, getDamageMultiplier = function(self, t, hate) return getHateMultiplier(self, 0.35, 0.67, false, hate) end, getTargetDamageChange = function(self, t) - return -self:combatTalentStatDamage(t, "wil", 0.7, 0.9) + return -self:combatLimit(self:combatTalentStatDamage(t, "wil", 0.7, 0.9), 1, 0, 0, 0.75, 0.87) -- Limit < 100% end, getDuration = function(self, t) return 2 diff --git a/game/modules/tome/data/talents/cursed/force-of-will.lua b/game/modules/tome/data/talents/cursed/force-of-will.lua index e7bc61d40c..b8d31a3f6e 100644 --- a/game/modules/tome/data/talents/cursed/force-of-will.lua +++ b/game/modules/tome/data/talents/cursed/force-of-will.lua @@ -117,6 +117,7 @@ newTalent{ getKnockback = function(self, t) return 2 end, + critpower = function(self, t) return self:combatTalentScale(t, 4, 15) end, action = function(self, t) local range = self:getTalentRange(t) @@ -131,18 +132,15 @@ newTalent{ forceHit(self, t, target, self.x, self.y, damage, knockback, 7, power, 10) return true end, - on_learn = function(self, t) - self.combat_critical_power = (self.combat_critical_power or 0) + 3 - end, - on_unlearn = function(self, t) - self.combat_critical_power = (self.combat_critical_power or 0) - 3 + passives = function(self, t, p) + self:talentTemporaryValue(p, "combat_critical_power", t.critpower(self, t)) end, info = function(self, t) local damage = t.getDamage(self, t) local knockback = t.getKnockback(self, t) return ([[Focusing your hate, you strike your foe with unseen force for %d damage and %d knockback. - In addition, your ability to channel force increases all critical damage by 3%% per point (current: %d%%) - Damage increases with your Mindpower.]]):format(damDesc(self, DamageType.PHYSICAL, damage), knockback, self.combat_critical_power or 0) + In addition, your ability to channel force with this talent increases all critical damage by %d%% (currently: %d%%) + Damage increases with your Mindpower.]]):format(damDesc(self, DamageType.PHYSICAL, damage), knockback, t.critpower(self, t), self.combat_critical_power or 0) end, } @@ -163,6 +161,7 @@ newTalent{ getDisplayName = function(self, t, p) return ("Deflection (%d)"):format(p.value) end, + critpower = function(self, t) return self:combatTalentScale(t, 4, 15) end, activate = function(self, t) game:playSoundNear(self, "talents/spell_generic2") return { @@ -209,17 +208,14 @@ newTalent{ p.power = power end end, - on_learn = function(self, t) - self.combat_critical_power = (self.combat_critical_power or 0) + 3 - end, - on_unlearn = function(self, t) - self.combat_critical_power = (self.combat_critical_power or 0) - 3 + passives = function(self, t, p) + self:talentTemporaryValue(p, "combat_critical_power", t.critpower(self, t)) end, info = function(self, t) local maxDamage = t.getMaxDamage(self, t) return ([[Create a barrier that siphons hate from you at the rate of 0.2 a turn. The barrier will deflect 50%% of incoming damage with the force of your will, up to %d damage. The barrier charges at a rate of 1/35th of its maximum charge per turn. - In addition, your ability to channel force increases all critical damage by 3%% per point (current: %d%%) - The maximum damage the barrier can deflect increases with your Mindpower.]]):format(maxDamage, self.combat_critical_power or 0) + In addition, your ability to channel force with this talent increases all critical damage by %d%% (currently: %d%%) + The maximum damage deflected increases with your Mindpower.]]):format(maxDamage, t.critpower(self, t),self.combat_critical_power or 0) end, } @@ -234,9 +230,7 @@ newTalent{ requires_target = true, hate = 12, range = 4, - radius = function(self, t) - return math.floor(2 + self:getTalentLevel(t) / 3) - end, + radius = function(self, t) return math.floor(self:combatTalentScale(t, 2.3, 3.7)) end, getDamage = function(self, t) return self:combatTalentMindDamage(t, 0, 300) end, @@ -249,6 +243,7 @@ newTalent{ getDazeDuration = function(self, t) return 3 end, + critpower = function(self, t) return self:combatTalentScale(t, 4, 15) end, action = function(self, t) --NOTE TO DG, SINCE I CAN'T UNDERSTAND A WORD OF BENLI'S CODE: EDIT SO THAT KNOCKBACK OCCURS AFTER DAMAGE, AND SEPARATELY, TO PREVENT ENEMIES BEING SHOVED INTO A NEW SPACE AND HIT AGAIN. local range = self:getTalentRange(t) local radius = self:getTalentRadius(t) @@ -283,11 +278,8 @@ newTalent{ return true end, - on_learn = function(self, t) - self.combat_critical_power = (self.combat_critical_power or 0) + 3 - end, - on_unlearn = function(self, t) - self.combat_critical_power = (self.combat_critical_power or 0) - 3 + passives = function(self, t, p) + self:talentTemporaryValue(p, "combat_critical_power", t.critpower(self, t)) end, info = function(self, t) local radius = self:getTalentRadius(t) @@ -295,8 +287,8 @@ newTalent{ local knockback = t.getKnockback(self, t) local dazeDuration = t.getDazeDuration(self, t) return ([[You rage coalesces at a single point, and then explodes outward, blasting enemies within a radius of %d in all directions. The blast causes %d damage and %d knockback at the center, that decreases with distance. Anyone caught in the explosion will also be dazed for 3 turns. - In addition, your ability to channel force increases all critical damage by 3%% per point (current: %d%%) - Damage increases with your Mindpower.]]):format(radius, damDesc(self, DamageType.PHYSICAL, damage), knockback, self.combat_critical_power or 0) + In addition, your ability to channel force with this talent increases all critical damage by %d%% (currently: %d%%) + Damage increases with your Mindpower.]]):format(radius, damDesc(self, DamageType.PHYSICAL, damage), knockback, t.critpower(self, t), self.combat_critical_power or 0) end, } @@ -309,21 +301,14 @@ newTalent{ cooldown = 30, tactical = { ATTACKAREA = { PHYSICAL = 2 } }, range = 4, - getDuration = function(self, t) - return 5 + math.floor(self:getTalentLevel(t)) - end, + getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 6, 10)) end, getDamage = function(self, t) return self:combatTalentMindDamage(t, 0, 140) end, getKnockback = function(self, t) return 2 end, - getSecondHitChance = function(self, t) - local level = self:getTalentLevel(t) - if level < 4 then return 0 end - - return 5 + (level - 4) * 10 - end, + getSecondHitChance = function(self, t) return self:combatTalentScale(self:getTalentLevel(t)-4, 15, 35) end, action = function(self, t) game.logSeen(self, "An unseen force begin to swirl around %s!", self.name) local duration = t.getDuration(self, t) @@ -348,8 +333,9 @@ newTalent{ local damage = t.getDamage(self, t) local knockback = t.getKnockback(self, t) - local hitCount = 1 - if rng.percent(t.getSecondHitChance(self, t)) then hitCount = hitCount + 1 end + local xtrahits = t.getSecondHitChance(self,t)/100 + local hitCount = 1 + math.floor(xtrahits) + if rng.percent(xtrahits - math.floor(xtrahits)*100) then hitCount = hitCount + 1 end -- Randomly take targets for i = 1, hitCount do @@ -365,20 +351,20 @@ newTalent{ game.logSeen(self, "The unseen force around %s subsides.", self.name) end end, - on_learn = function(self, t) - self.combat_critical_power = (self.combat_critical_power or 0) + 3 - end, - on_unlearn = function(self, t) - self.combat_critical_power = (self.combat_critical_power or 0) - 3 + critpower = function(self, t) return self:combatTalentScale(t, 4, 15) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "combat_critical_power", t.critpower(self, t)) end, info = function(self, t) local duration = t.getDuration(self, t) local damage = t.getDamage(self, t) local knockback = t.getKnockback(self, t) local secondHitChance = t.getSecondHitChance(self, t) - return ([[Your fury becomes an unseen force, that randomly lashes out at the foes around you. For %d turns, you strike one nearby target doing %d damage and %d knockback. At higher levels, there is a %d%% chance of a second, random strike. - In addition, your ability to channel force increases all critical damage by 3%% per point (current: %d%%) - Damage increases with your Mindpower.]]):format(duration, damDesc(self, DamageType.PHYSICAL, damage), knockback, secondHitChance, self.combat_critical_power or 0) + local hits = 1 + math.floor(secondHitChance/100) + local chance = secondHitChance - math.floor(secondHitChance/100)*100 + return ([[Your fury becomes an unseen force that randomly lashes out at foes around you. For %d turns you strike %d (%d%% chance for %d) nearby target(s) within range 5 doing %d damage and %d knockback. The number of extra strikes increases at higher talent levels. + In addition, your ability to channel force with this talent increases all critical damage by %d%% (currently: %d%%) + Damage increases with your Mindpower.]]):format(duration, hits, chance, hits+1, damDesc(self, DamageType.PHYSICAL, damage), knockback, t.critpower(self, t), self.combat_critical_power or 0) end, } diff --git a/game/modules/tome/data/talents/cursed/gestures.lua b/game/modules/tome/data/talents/cursed/gestures.lua index 1eaae3c2e6..fa5fa98cda 100644 --- a/game/modules/tome/data/talents/cursed/gestures.lua +++ b/game/modules/tome/data/talents/cursed/gestures.lua @@ -18,18 +18,25 @@ -- darkgod@te4.org local function canUseGestures(self) - local nb = 0 - if self:getInven("MAINHAND") then - local weapon = self:getInven("MAINHAND")[1] - if not weapon or weapon.subtype == "mindstar" then nb = nb + 1 end - end - + local dam, nb = 0, 0 + local weapon + if self:getInven("OFFHAND") then - local weapon = self:getInven("OFFHAND")[1] - if not weapon or weapon.subtype == "mindstar" then nb = nb + 1 end + weapon = self:getInven("OFFHAND")[1] + if not weapon or weapon.subtype == "mindstar" then + nb = nb + 1 + dam = self:combatDamage(weapon and weapon.combat) + end end - return nb == 2 and true or false + if self:getInven("MAINHAND") then + weapon = self:getInven("MAINHAND")[1] + if not weapon or weapon.subtype == "mindstar" then + nb = nb + 1 + dam = math.max(dam,self:combatDamage(weapon and weapon.combat)) + end + end + return nb >= 2 and true or false, dam -- return damage for use with Gesture of Guarding end newTalent{ @@ -69,9 +76,7 @@ newTalent{ return bonus end, - getStunChance = function(self, t) - return math.max(10, self:getTalentLevelRaw(t) * 2) - end, + 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.") @@ -125,9 +130,9 @@ newTalent{ local stunChance = t.getStunChance(self, t) local bonusDamage = t.getBonusDamage(self, t) local bonusCritical = t.getBonusCritical(self, t) - return ([[Use a gesture of pain in place of an normal attack to strike into the minds of your enemies, inflicting between %0.1f and %0.1f mind damage. If you strike your target, there is a %d%% chance to stun your opponent for 3 turns. - This strike replaces your melee physical and checks Mindpower versus Mental Save, and is thus not affected by your Accuracy or the enemy's Defense. It also does not trigger any physical on-hit effects. However, the base damage and the critical chance of Mindstars equipped is added in when this attack is performed. - 25%% chance of cross tier effects. Requires two free or mindstar-equipped hands. Can cause critical hits with cross tier effects. The damage will increase with your Mindpower. Mindstars bonuses from damage and physical criticals: (+%d damage, +%d critical chance)]]):format(damDesc(self, DamageType.MIND, baseDamage * 0.5), damDesc(self, DamageType.MIND, baseDamage), stunChance, bonusDamage, bonusCritical) + return ([[Use a gesture of pain in place of a normal attack to assault the minds of your enemies, inflicting between %0.1f and %0.1f mind damage. If the attack succeeds, there is a %d%% chance to stun your opponent for 3 turns. + This strike replaces your melee physical and checks your Mindpower against your opponent's Mental Save, and is thus not affected by your Accuracy or the enemy's Defense. It also does not trigger any physical on-hit effects. However, the base damage and the critical chance of any Mindstars equipped are added in when this attack is performed. + This talent requires two free or mindstar-equipped hands and has a 25%% chance to inflict cross tier effects which can be critical hits. The damage will increase with your Mindpower. Mindstars bonuses from damage and physical criticals: (+%d damage, +%d critical chance)]]):format(damDesc(self, DamageType.MIND, baseDamage * 0.5), damDesc(self, DamageType.MIND, baseDamage), stunChance, bonusDamage, bonusCritical) end, } @@ -182,15 +187,33 @@ newTalent{ mode = "passive", cooldown = 10, points = 5, - getDamageChange = function(self, t) - if not canUseGestures(self) then return 0 end - - return -math.pow(self:getTalentLevel(t), 0.5) * 14 - end, - getCounterAttackChance = function(self, t) - if not canUseGestures(self) then return 0 end - return math.sqrt(self:getTalentLevel(t)) * 4 + getGuardPercent = function(self, t) return self:combatTalentLimit(t, 100, 14, 31) end, --Limit < 100% + -- Damage reduction handled in _M:attackTargetWith function in mod.class.interface.Combat.lua + getDamageChange = function(self, t, fake) + local test, dam = canUseGestures(self) + if not test and not fake then return 0 end + return t.getGuardPercent(self, t) * dam/100 + end, + getCounterAttackChance = function(self, t, fake) + if (not canUseGestures(self) or not self:isTalentActive(self.T_GESTURE_OF_PAIN)) and not fake then return 0 end + return self:combatTalentLimit(t, 50, 4, 8.9) -- Limit < 50% + end, + -- Mental effect "GESTURE_OF_GUARDING" handles the deflect count, refreshed in mod.class.Actor.lua _M:actBase + getDeflects = function(self, t, fake) + if not canUseGestures(self) and not fake then return 0 end + return self:combatStatScale("cun", 0, 2.25) + end, + doGuard = function(self, t) + local deflected, ef = 0, self:hasEffect(self.EFF_GESTURE_OF_GUARDING) + if ef and ef.deflects > 0 then + deflected = t.getDamageChange(self, t) + if ef.deflects < 1 then deflected = deflected * ef.deflects end -- Partial deflection + ef.deflects = ef.deflects -1 + if ef.deflects <=0 then self:removeEffect(self.EFF_GESTURE_OF_GUARDING) end + end + return deflected end, + -- Counterattack handled in _M:attackTargetWith function in mod.class.interface.Combat.lua (requires EFF_GESTURE_OF_GUARDING) on_hit = function(self, t, who) if rng.percent(t.getCounterAttackChance(self, t)) and self:isTalentActive(self.T_GESTURE_OF_PAIN) and canUseGestures(self) then game.logSeen(self, "#F53CBE#%s lashes back at %s!", self.name:capitalize(), who.name) @@ -198,10 +221,14 @@ newTalent{ tGestureOfPain.attack(self, tGestureOfPain, who) end end, + on_unlearn = function(self, t) + self:removeEffect(self.EFF_GESTURE_OF_GUARDING) + end, info = function(self, t) - local damageChange = t.getDamageChange(self, t) - local counterAttackChance = t.getCounterAttackChance(self, t) - return ([[You guard against melee damage with a sweep of you hand. All damage from melee attacks is reduced by %d%%. There is also a %d%% chance of counterattacking while Gesture of Pain is active. - Requires two free or mindstar-equipped hands; does not require Gesture of Pain to be sustained.]]):format(-damageChange, counterAttackChance) + local damageChange = t.getDamageChange(self, t, true) + local counterAttackChance = t.getCounterAttackChance(self, t, true) + return ([[You guard against melee damage with a sweep of your hand. So long as you can use Gestures (Requires two free or mindstar-equipped hands), you deflect up to %d damage (%0.1f%% of your best free hand melee damage) from up to %0.1f melee attack(s) each turn (based on your cunning). + If Gesture of Pain is active, you also have a %0.1f%% chance to counterattack.]]): + format(damageChange, t.getGuardPercent(self, t), t.getDeflects(self, t, true), counterAttackChance) end, } diff --git a/game/modules/tome/data/talents/cursed/gloom.lua b/game/modules/tome/data/talents/cursed/gloom.lua index 57179d0d66..1ff2036ed7 100644 --- a/game/modules/tome/data/talents/cursed/gloom.lua +++ b/game/modules/tome/data/talents/cursed/gloom.lua @@ -25,6 +25,11 @@ local function getWillFailureEffectiveness(self, minChance, maxChance, attackStr return attackStrength * self:getWil() * 0.05 * (minChance + (maxChance - minChance) / 2) end +-- mindpower bonus for gloom talents +local function gloomTalentsMindpower(self) + return self:combatScale(self:getTalentLevel(self.T_GLOOM) + self:getTalentLevel(self.T_WEAKNESS) + self:getTalentLevel(self.T_DISMAY) + self:getTalentLevel(self.T_SANCTUARY), 1, 1, 20, 20, 0.75) +end + newTalent{ name = "Gloom", type = {"cursed/gloom", 1}, @@ -35,9 +40,7 @@ newTalent{ range = 3, no_energy = true, tactical = { BUFF = 5 }, - getChance = function(self, t) - return math.sqrt(self:getTalentLevel(t)) * 7 - end, + getChance = function(self, t) return self:combatLimit(self:getTalentLevel(t)^.5, 100, 7, 1, 15.65, 2.23) end, -- Limit < 100% getDuration = function(self, t) return 3 end, @@ -58,12 +61,11 @@ newTalent{ -- all gloom effects are handled here local tWeakness = self:getTalentFromId(self.T_WEAKNESS) local tDismay = self:getTalentFromId(self.T_DISMAY) - local tSanctuary = self:getTalentFromId(self.T_SANCTUARY) + --local tSanctuary = self:getTalentFromId(self.T_SANCTUARY) --local tLifeLeech = self:getTalentFromId(self.T_LIFE_LEECH) --local lifeLeeched = 0 - --local mindpower = self:combatMindpower(1, self:getTalentLevelRaw(tGloom) + self:getTalentLevelRaw(tWeakness) + self:getTalentLevelRaw(tDismayed) + self:getTalentLevelRaw(tLifeLeech)) - local mindpower = self:combatMindpower(1, self:getTalentLevelRaw(tGloom) + self:getTalentLevelRaw(tWeakness) + self:getTalentLevelRaw(tDismayed) + self:getTalentLevelRaw(tSanctuary)) + local mindpower = self:combatMindpower(1, gloomTalentsMindpower(self)) local grids = core.fov.circle_grids(self.x, self.y, self:getTalentRange(tGloom), true) for x, yy in pairs(grids) do @@ -141,7 +143,7 @@ newTalent{ info = function(self, t) local chance = t.getChance(self, t) local duration = t.getDuration(self, t) - local mindpowerChange = self:getTalentLevelRaw(self.T_GLOOM) + self:getTalentLevelRaw(self.T_WEAKNESS) + self:getTalentLevelRaw(self.T_DISMAY) + self:getTalentLevelRaw(self.T_SANCTUARY) + local mindpowerChange = gloomTalentsMindpower(self) return ([[A terrible gloom surrounds you, affecting all those who approach to within radius 3. Each turn, those caught in your gloom must save against your Mindpower, or have an %d%% chance to suffer from slowness, stun or confusion for %d turns. This ability is innate, and carries no cost to activate or deactivate. Each point in Gloom increases the mindpower of all gloom effects (current: %+d).]]):format(chance, duration, mindpowerChange) end, @@ -153,15 +155,11 @@ newTalent{ mode = "passive", require = cursed_wil_req2, points = 5, - getChance = function(self, t) - return math.sqrt(self:getTalentLevel(t)) * 7 - end, + getChance = function(self, t) return self:combatLimit(self:getTalentLevel(t)^.5, 100, 7, 1, 15.65, 2.23) end, -- Limit < 100% getDuration = function(self, t) return 3 end, - getIncDamageChange = function(self, t) - return -math.sqrt(self:getTalentLevel(t)) * 12 - end, + getIncDamageChange = function(self, t) return self:combatLimit(self:getTalentLevel(t)^.5, 65, 12, 1, 26.8, 2.23) end, -- Limit to <65% getHateBonus = function(self, t) return 2 end, @@ -170,7 +168,7 @@ newTalent{ local duration = t.getDuration(self, t) local incDamageChange = t.getIncDamageChange(self, t) local hateBonus = t.getHateBonus(self, t) - local mindpowerChange = self:getTalentLevelRaw(self.T_GLOOM) + self:getTalentLevelRaw(self.T_WEAKNESS) + self:getTalentLevelRaw(self.T_DISMAY) + self:getTalentLevelRaw(self.T_SANCTUARY) + local mindpowerChange = gloomTalentsMindpower(self) return ([[Each turn, those caught in your gloom must save against your Mindpower, or have an %d%% chance to be crippled by fear for %d turns, reducing damage they inflict by %d%%. The first time you melee strike a foe after they have been weakened will give you %d hate. Each point in Weakness increases the Mindpower of all gloom effects (current: %+d).]]):format(chance, duration, -incDamageChange, hateBonus, mindpowerChange) end, @@ -182,16 +180,14 @@ newTalent{ mode = "passive", require = cursed_wil_req3, points = 5, - getChance = function(self, t) - return math.sqrt(self:getTalentLevel(t)) * 3.5 - end, + getChance = function(self, t) return self:combatLimit(self:getTalentLevel(t)^.5, 100, 3.5, 1, 7.83, 2.23) end, -- Limit < 100% getDuration = function(self, t) return 3 end, info = function(self, t) local chance = t.getChance(self, t) local duration = t.getDuration(self, t) - local mindpowerChange = self:getTalentLevelRaw(self.T_GLOOM) + self:getTalentLevelRaw(self.T_WEAKNESS) + self:getTalentLevelRaw(self.T_DISMAY) + self:getTalentLevelRaw(self.T_SANCTUARY) + local mindpowerChange = gloomTalentsMindpower(self) return ([[Each turn, those caught in your gloom must save against your Mindpower or have an %0.1f%% chance of becoming dismayed for %d turns. When dismayed, the first melee attack against the foe will result in a critical hit. Each point in Dismay increases the Mindpower of all gloom effects (current: %+d).]]):format(chance, duration, mindpowerChange) end, @@ -229,7 +225,7 @@ newTalent{ end, info = function(self, t) local damageChange = t.getDamageChange(self, t) - local mindpowerChange = self:getTalentLevelRaw(self.T_GLOOM) + self:getTalentLevelRaw(self.T_WEAKNESS) + self:getTalentLevelRaw(self.T_DISMAY) + self:getTalentLevelRaw(self.T_SANCTUARY) + local mindpowerChange = gloomTalentsMindpower(self) return ([[Your gloom has become a sanctuary from the outside world. Damage from any attack that originates beyond the boundary of your gloom is reduced by %d%%. Each point in Sanctuary increases the Mindpower of all gloom effects (current: %+d).]]):format(-damageChange, mindpowerChange) end, diff --git a/game/modules/tome/data/talents/cursed/predator.lua b/game/modules/tome/data/talents/cursed/predator.lua index b0312609fd..71000dafd0 100644 --- a/game/modules/tome/data/talents/cursed/predator.lua +++ b/game/modules/tome/data/talents/cursed/predator.lua @@ -37,7 +37,7 @@ newTalent{ local t = self:getTalentFromId(self.T_MIMIC) if t then total = total + self:getTalentLevelRaw(t) end - return 20 - (total * 0.5) + return self:combatLimit(total, 0, 19.5, 1, 10, 20) -- Limit > 0 end, getSubtypeDamageChange = function(self, t) return math.pow(self:getTalentLevel(t), 0.5) * 0.15 @@ -45,9 +45,7 @@ newTalent{ getTypeDamageChange = function(self, t) return math.pow(self:getTalentLevel(t), 0.5) * 0.065 end, - getHateBonus = function(self, t) - return self:getTalentLevelRaw(t) * 2 - end, + getHateBonus = function(self, t) return self:combatTalentScale(t, 3, 10, "log") end, target = function(self, t) return {type="hit", range=self:getTalentRange(t), talent=t} end, action = function(self, t) local tg = self:getTalentTarget(t) @@ -64,7 +62,14 @@ newTalent{ return true end, - + on_unlearn = function(self, t) + if not self:knowTalent(t) then + local ef = self.tempeffect_def.EFF_PREDATOR + ef.no_remove = false + self:removeEffect(self.EFF_PREDATOR) + ef.no_remove = true + end + end, info = function(self, t) local maxKillExperience = t.getMaxKillExperience(self, t) local subtypeDamageChange = t.getSubtypeDamageChange(self, t) @@ -85,15 +90,9 @@ newTalent{ mode = "passive", require = cursed_lev_req2, points = 5, - getSubtypeAttackChange = function(self, t) - return math.pow(self:getTalentLevel(t), 0.7) * 5 - end, - getTypeAttackChange = function(self, t) - return math.pow(self:getTalentLevel(t), 0.7) * 2 - end, - getSubtypeStunChance = function(self, t) - return math.pow(self:getTalentLevel(t), 0.5) * 3.1 - end, + getSubtypeAttackChange = function(self, t) return self:combatTalentScale(t, 5, 15.4, 0.75) end, + getTypeAttackChange = function(self, t) return self:combatTalentScale(t, 2, 6.2, 0.75) end, + getSubtypeStunChance = function(self, t) return self:combatLimit(self:getTalentLevel(t)^0.5, 100, 3.1, 1, 6.93, 2.23) end, -- Limit < 100% on_learn = function(self, t) local eff = self:hasEffect(self.EFF_PREDATOR) if eff then @@ -128,15 +127,9 @@ newTalent{ end, on_unlearn = function(self, t) end, - getSubtypeChance = function(self, t) - return math.sqrt(self:getTalentLevel(t)) * 10 - end, - getTypeChance = function(self, t) - return math.sqrt(self:getTalentLevel(t)) * 4 - end, - getPhysicalResistChange = function(self, t) - return -math.sqrt(self:getTalentLevel(t)) * 8 - end, + getSubtypeChance = function(self, t) return self:combatLimit(self:getTalentLevel(t)^0.5, 100, 10, 1, 22.3, 2.23) end, -- Limit <100% + getTypeChance = function(self, t) return self:combatLimit(self:getTalentLevel(t)^0.5, 100, 4, 1, 8.94, 2.23) end, -- Limit <100% + getPhysicalResistChange = function(self, t) return -self:combatLimit(self:getTalentLevel(t)^0.5, 100, 8, 1, 17.9, 2.23) end, -- Limit <100% getStatReduction = function(self, t) return math.floor(math.sqrt(self:getTalentLevel(t)) * 4.3) end, @@ -169,9 +162,7 @@ newTalent{ mode = "passive", require = cursed_lev_req4, points = 5, - getMaxIncrease = function(self, t) - return math.min(35, math.pow(self:getTalentLevel(t), 0.7) * 7) - end, + getMaxIncrease = function(self, t) return self:combatTalentScale(t, 7, 21.6, 0.75) end, on_learn = function(self, t) self:removeEffect(self.EFF_MIMIC, true, true) end, diff --git a/game/modules/tome/data/talents/cursed/punishments.lua b/game/modules/tome/data/talents/cursed/punishments.lua index ff51a01da6..dc3bd2b6b9 100644 --- a/game/modules/tome/data/talents/cursed/punishments.lua +++ b/game/modules/tome/data/talents/cursed/punishments.lua @@ -311,12 +311,8 @@ newTalent{ mode = "passive", require = cursed_cun_req4, points = 5, - getChance = function(self, t) - return math.sqrt(self:getTalentLevel(t)) * 8 - end, - getMindResistChange = function(self, t) - return -math.min(5, self:getTalentLevelRaw(t)) * 10 - end, + getChance = function(self, t) return self:combatLimit(self:getTalentLevel(t)^0.5, 100, 8, 1, 17.9, 2.23) end, -- Limit < 100% + getMindResistChange = function(self, t) return -self:combatTalentLimit(t, 50, 15, 35) end, -- Limit < 50% doMadness = function(target, t, src) local chance = t.getChance(src, t) if target and src and target:reactionToward(src) < 0 and src:checkHit(src:combatMindpower(), target:combatMentalResist(), 0, chance, 5) then @@ -325,7 +321,7 @@ newTalent{ if effect == 1 then -- confusion if target:canBe("confusion") and not target:hasEffect(target.EFF_MADNESS_CONFUSED) then - target:setEffect(target.EFF_MADNESS_CONFUSED, 3, {power=70, mindResistChange=mindResistChange}) + target:setEffect(target.EFF_MADNESS_CONFUSED, 3, {power=50, mindResistChange=mindResistChange}) -- Consistent with other confusion hit = true end elseif effect == 2 then diff --git a/game/modules/tome/data/talents/cursed/rampage.lua b/game/modules/tome/data/talents/cursed/rampage.lua index ade7164d0b..c49b6a6777 100644 --- a/game/modules/tome/data/talents/cursed/rampage.lua +++ b/game/modules/tome/data/talents/cursed/rampage.lua @@ -32,12 +32,8 @@ newTalent{ getMaxDuration = function(self, t) return 8 end, - getMovementSpeedChange = function(self, t) - return math.pow(self:getTalentLevel(t), 0.5) * 1.4 - end, - getCombatPhysSpeedChange = function(self, t) - return math.pow(self:getTalentLevel(t), 0.5) * 0.224 - end, + getMovementSpeedChange = function(self, t) return self:combatTalentScale(t, 1.4, 3.13, 0.75) end, --Nerf this? + getCombatPhysSpeedChange = function(self, t) return self:combatTalentScale(t, 0.224, 0.5, 0.75) end, on_pre_use = function(self, t, silent) if self:hasEffect(self.EFF_RAMPAGE) then if not silent then game.logPlayer(self, "You are already rampaging!") end @@ -106,15 +102,9 @@ newTalent{ end, on_unlearn = function(self, t) end, - getPhysicalDamageChange = function(self, t) - return math.pow(self:getTalentLevel(t), 0.7) * 12 - end, - getCombatPhysResistChange = function(self, t) - return math.pow(self:getTalentLevel(t), 0.7) * 6 - end, - getCombatMentalResistChange = function(self, t) - return math.pow(self:getTalentLevel(t), 0.7) * 6 - end, + getPhysicalDamageChange = function(self, t) return self:combatTalentScale(t, 12, 37) end, + getCombatPhysResistChange = function(self, t) return self:combatTalentScale(t, 6, 18.5, 0.75) end, + getCombatMentalResistChange = function(self, t) return self:combatTalentScale(t, 6, 18.5, 0.75) end, info = function(self, t) local physicalDamageChange = t.getPhysicalDamageChange(self, t) local combatPhysResistChange = t.getCombatPhysResistChange(self, t) diff --git a/game/modules/tome/data/talents/cursed/shadows.lua b/game/modules/tome/data/talents/cursed/shadows.lua index f46ba20cf1..f5a7139760 100644 --- a/game/modules/tome/data/talents/cursed/shadows.lua +++ b/game/modules/tome/data/talents/cursed/shadows.lua @@ -196,17 +196,17 @@ local function createShadow(self, level, tCallShadows, tShadowWarriors, tShadowM avoid_traps = 1, max_life = resolvers.rngavg(3,12), life_rating = 5, - stats = { - str=5 + math.floor(level), - dex=10 + math.floor(level * 1.5), - mag=10 + math.floor(level * 1.5), - wil=5 + math.floor(level), - cun=5 + math.floor(level * 0.7), - con=5 + math.floor(level * 0.7), + stats = { -- affected by stat limits + str=math.floor(self:combatScale(level, 5, 0, 55, 50, 0.75)), + dex=math.floor(self:combatScale(level, 10, 0, 85, 50, 0.75)), + mag=math.floor(self:combatScale(level, 10, 0, 85, 50, 0.75)), + wil=math.floor(self:combatScale(level, 5, 0, 55, 50, 0.75)), + cun=math.floor(self:combatScale(level, 5, 0, 40, 50, 0.75)), + con=math.floor(self:combatScale(level, 5, 0, 40, 50, 0.75)), }, combat_armor = 0, combat_def = 3, combat = { - dam=math.floor(level * 1.5), + dam=math.floor(self:combatScale(level, 1.5, 1, 75, 50, 0.75)), atk=10 + level, apr=8, dammod={str=0.5, dex=0.5} @@ -331,9 +331,7 @@ newTalent{ cooldown = 10, hate = 0, tactical = { BUFF = 5 }, - getLevel = function(self, t) - return math.min(self.level, 50) - end, + getLevel = function(self, t) return self.level end, getMaxShadows = function(self, t) return math.min(4, math.max(1, math.floor(self:getTalentLevel(t) * 0.55))) end, @@ -390,7 +388,7 @@ newTalent{ -- use hate if self.hate < 6 then -- not enough hate..just wait for another try - game.logPlayer(self, "You hate is too low to call another shadow!", deflectDamage) + game.logPlayer(self, "Your hate is too low to call another shadow!", deflectDamage) return false end self:incHate(-6) @@ -451,7 +449,7 @@ newTalent{ end, getDominateChance = function(self, t) if self:getTalentLevelRaw(t) > 0 then - return math.min(100, math.sqrt(self:getTalentLevel(t)) * 7) + return self:combatLimit(self:getTalentLevel(t)^.5, 100, 7, 1, 15.65, 2.23) -- Limit < 100% else return 0 end @@ -496,14 +494,14 @@ newTalent{ points = 5, getCloseAttackSpellChance = function(self, t) if math.floor(self:getTalentLevel(t)) > 0 then - return math.min(100, math.sqrt(self:getTalentLevel(t)) * 7) + return self:combatLimit(self:getTalentLevel(t)^.5, 100, 7, 1, 15.65, 2.23) -- Limit < 100% else return 0 end end, getFarAttackSpellChance = function(self, t) if math.floor(self:getTalentLevel(t)) >= 3 then - return math.min(100, math.sqrt(self:getTalentLevel(t)) * 7) + return self:combatLimit(self:getTalentLevel(t)^.5, 100, 7, 1, 15.65, 2.23) -- Limit < 100% else return 0 end @@ -528,9 +526,7 @@ newTalent{ canReform = function(self, t) return t.getReformLevel(self, t) > 0 end, - getSpellpowerChange = function(self, t) - return math.floor(self:getTalentLevel(t) * 3) - end, + getSpellpowerChange = function(self, t) return math.floor(self:combatTalentScale(t, 3, 15, 0.75)) end, on_learn = function(self, t) if game and game.level and game.level.entities then for _, e in pairs(game.level.entities) do @@ -577,12 +573,8 @@ newTalent{ range = 6, requires_target = true, tactical = { ATTACK = 2 }, - getDefenseDuration = function(self, t) - return 3 + math.floor(self:getTalentLevel(t) * 1.5) - end, - getBlindsideChance = function(self, t) - return math.min(100, 30 + self:getTalentLevel(t) * 10) - end, + getDefenseDuration = function(self, t) return math.floor(self:combatTalentScale(t, 4.4, 10.1)) end, + getBlindsideChance = function(self, t) return self:combatTalentLimit(t, 100, 40, 80) end, -- Limit < 100% action = function(self, t) local range = self:getTalentRange(t) local target = { type="hit", range=range, nowarning=true } diff --git a/game/modules/tome/data/talents/cursed/slaughter.lua b/game/modules/tome/data/talents/cursed/slaughter.lua index 3e1d9b1c8e..3b09aa9f4f 100644 --- a/game/modules/tome/data/talents/cursed/slaughter.lua +++ b/game/modules/tome/data/talents/cursed/slaughter.lua @@ -29,12 +29,13 @@ newTalent{ hate = 2, tactical = { ATTACK = { PHYSICAL = 2 } }, requires_target = true, + -- note that EFF_CURSED_WOUND in mod.data.timed_effects.physical.lua has a cap of -75% healing per application getDamageMultiplier = function(self, t, hate) return 1 + self:combatTalentIntervalDamage(t, "str", 0.3, 1.5, 0.4) * getHateMultiplier(self, 0.3, 1, false, hate) end, getHealFactorChange = function(self, t) local level = math.max(3 * self:getTalentTypeMastery(t.type[1]), self:getTalentLevel(t)) - return -math.sqrt(level - 2) * 0.15 + return -self:combatLimit(math.max(0,(level-2)^0.5), 1, 0, 0, 0.26, 1.73) -- Limit < -100% end, getWoundDuration = function(self, t) return 15 @@ -82,7 +83,7 @@ newTalent{ end, getAttackChange = function(self, t) local level = math.max(3 * self:getTalentTypeMastery(t.type[1]) - 2, self:getTalentLevel(t) - 2) - return -self:rescaleDamage((math.sqrt(level) - 0.5) * 15 * ((100 + self:getStat("str")) / 200)) + return -self:combatScale(math.max(0,level^0.5 - 0.5) * 15 * (100 + self:getStr()), 0, 0, 20.77, 3696, 0.67) end, range = 0, radius = 1, @@ -138,16 +139,14 @@ newTalent{ random_ego = "attack", cooldown = 15, hate = 5, - range = function(self, t) return 3 + self:getTalentLevelRaw(t) end, + range = function(self, t) return math.floor(self:combatTalentScale(t, 4, 8)) end, tactical = { CLOSEIN = 2 }, requires_target = true, getDamageMultiplier = function(self, t, hate) return 0.7 * getHateMultiplier(self, 0.5, 1, false, hate) --return self:combatTalentIntervalDamage(t, "str", 0.8, 1.7, 0.4) * getHateMultiplier(self, 0.5, 1, false, hate) end, - getMaxAttackCount = function(self, t) - return 1 + self:getTalentLevelRaw(t) - end, + getMaxAttackCount = function(self, t) return math.floor(self:combatTalentScale(t, 2, 6, "log")) end, action = function(self, t) local targeting = {type="bolt", range=self:getTalentRange(t), nolock=true} local targetX, targetY, actualTarget = self:getTarget(targeting) @@ -286,15 +285,14 @@ newTalent{ points = 5, cooldown = 10, no_energy = true, - getChance = function(self, t) + getChance = function(self, t, has2h) local chance = self:combatTalentIntervalDamage(t, "str", 10, 38, 0.4) - if self:hasTwoHandedWeapon() then - chance = chance + 15 - end + if (not has2h and self:hasTwoHandedWeapon()) or (has2h and has2h > 0) then chance = chance + 15 end + chance = self:combatLimit(chance, 100, 0, 0, 25.18, 25.18) -- Limit < 100% return chance end, getDamageMultiplier = function(self, t, hate) - local damageMultiplier = self:combatTalentIntervalDamage(t, "str", 0.3, 0.9, 0.4) * getHateMultiplier(self, 0.5, 1.0, false, hate) + local damageMultiplier = self:combatLimit(self:getTalentLevel(t) * self:getStr()*getHateMultiplier(self, 0.5, 1.0, false, hate), 1, 0, 0, 0.79, 500) -- Limit < 100% if self:hasTwoHandedWeapon() then damageMultiplier = damageMultiplier + 0.25 end @@ -353,10 +351,12 @@ newTalent{ inCleave = false end, info = function(self, t) - local chance = t.getChance(self, t) - return ([[While active, every swing of your weapon has a %d%% chance of striking a second nearby target for %d%% (at 0 Hate) to %d%% (at 100+ Hate) damage. The recklessness of your attacks brings you bad luck (luck -3). + local chance = t.getChance(self, t, 0) + local chance2h = t.getChance(self, t, 1) + return ([[While active, every swing of your weapon has a %d%% (if one-handed) or %d%% (if two-handed) chance of striking a second nearby target for %d%% (at 0 Hate) to %d%% (at 100+ Hate) damage (+25%% for two-handed weapons). The recklessness of your attacks brings you bad luck (luck -3). Cleave, Repel and Surge cannot be active simultaneously, and activating one will place the others in cooldown. - The Cleave chance and damage increase with your Strength, and when wielding a two-handed weapon (+15%% chance, +25%% damage).]]):format(chance, t.getDamageMultiplier(self, t, 0) * 100, t.getDamageMultiplier(self, t, 100) * 100) + The Cleave chance and damage increase with your Strength.]]): + format(chance, chance2h, t.getDamageMultiplier(self, t, 0) * 100, t.getDamageMultiplier(self, t, 100) * 100) end, } diff --git a/game/modules/tome/data/talents/cursed/strife.lua b/game/modules/tome/data/talents/cursed/strife.lua index c5dc23a2ce..df35abc17f 100644 --- a/game/modules/tome/data/talents/cursed/strife.lua +++ b/game/modules/tome/data/talents/cursed/strife.lua @@ -41,9 +41,7 @@ newTalent{ getDefenseChange = function(self, t) return -self:combatTalentStatDamage(t, "wil", 6, 45) end, - getResistPenetration = function(self, t) - return self:combatTalentStatDamage(t, "wil", 30, 80) - end, + getResistPenetration = function(self, t) return self:combatLimit(self:combatTalentStatDamage(t, "wil", 30, 80), 100, 0, 0, 55, 55) end, -- Limit < 100% action = function(self, t) local range = self:getTalentRange(t) local tg = {type="hit", range=self:getTalentRange(t)} @@ -81,15 +79,16 @@ newTalent{ mode = "passive", require = cursed_str_req2, points = 5, - range = function(self, t) - return math.floor(2 + 6 * (self:getTalentLevel(t) / 6.5)) - end, + range = function(self, t) return math.floor(self:combatTalentScale(t, 2.5, 6.6)) end, + -- _M:combatSeeStealth and _M:combatSeeInvisible functions updated in mod.class.interface.Combat.lua + sensePower = function(self, t) return self:combatScale(self:getTalentLevel(t) * self:getWil(15, true), 5, 0, 80, 75) end, info = function(self, t) local range = self:getTalentRange(t) + local sense = t.sensePower(self, t) return ([[Your preternatural senses aid you in your hunt for the next victim. You sense foes in a radius of %0.1f. You will always sense a stalked victim in a radius of 10. Also increases stealth detection by %d and invisibility detection by %d. Sealth and invisibility detection improves with your Willpower]]): - format(range, 5 + self:getTalentLevel(t) * self:getWil(15, true), 5 + self:getTalentLevel(t) * self:getWil(15, true)) + format(range, sense, sense) end, } @@ -368,7 +367,7 @@ newTalent{ cooldown = 10, no_energy = true, getChance = function(self, t) - local chance = self:combatTalentStatDamage(t, "str", 12, 36) + local chance = self:combatLimit(self:combatTalentStatDamage(t, "str", 12, 36), 50, 0, 0, 26.45, 26.45) -- Limit <50% (56% with shield) if self:hasShield() then chance = chance + 6 end diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua index 7b2ae11d44..9f42e7e020 100644 --- a/game/modules/tome/data/timed_effects/mental.lua +++ b/game/modules/tome/data/timed_effects/mental.lua @@ -1872,6 +1872,35 @@ newEffect{ end, } +newEffect{ + name = "GESTURE_OF_GUARDING", image = "talents/gesture_of_guarding.png", + desc = "Guarded", + long_desc = function(self, eff) + local xs = "" + local dam, deflects = eff.dam, eff.deflects + if deflects < 1 then -- Partial deflect has reduced effectiveness + dam = dam*math.max(0,deflects) + deflects = 1 + end + if self:isTalentActive(self.T_GESTURE_OF_PAIN) then xs = (" with a %d%% chance to counterattack"):format(self:callTalent(self.T_GESTURE_OF_GUARDING,"getCounterAttackChance")) end + return ("Guarding against melee damage: Will dismiss up to %d damage from the next %0.1f attack(s)%s."):format(dam, deflects, xs) + end, + charges = function(self, eff) return "#LIGHT_GREEN#"..math.ceil(eff.deflects) end, + type = "mental", + subtype = { curse=true }, + status = "beneficial", + decrease = 0, + no_stop_enter_worlmap = true, no_stop_resting = true, + parameters = {dam = 1, deflects = 1}, + activate = function(self, eff) + eff.dam = self:callTalent(self.T_GESTURE_OF_GUARDING,"getDamageChange") + eff.deflects = self:callTalent(self.T_GESTURE_OF_GUARDING,"getDeflects") + if eff.dam <= 0 or eff.deflects <= 0 then eff.dur = 0 end + end, + deactivate = function(self, eff) + end, +} + newEffect{ name = "RAMPAGE", image = "talents/rampage.png", desc = "Rampaging", diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua index 7eb62797c6..8fa2b894cc 100644 --- a/game/modules/tome/data/timed_effects/other.lua +++ b/game/modules/tome/data/timed_effects/other.lua @@ -23,6 +23,7 @@ local Entity = require "engine.Entity" local Chat = require "engine.Chat" local Map = require "engine.Map" local Level = require "engine.Level" +local Combat = require "mod.class.interface.Combat" newEffect{ name = "INFUSION_COOLDOWN", image = "effects/infusion_cooldown.png", @@ -650,8 +651,8 @@ newEffect{ decrease = 0, no_remove = true, cancel_on_level_change = true, - parameters = {}, - getResistsUndead = function(level) return -2 * level end, + parameters = {Penalty = 1}, + getResistsUndead = function(eff, level) return -2 * level * (eff.Penalty or 1) end, getIncDamageUndead = function(level) return 2 + level * 2 end, getLckChange = function(eff, level) if eff.unlockLevel >= 5 or level <= 2 then return -1 end @@ -659,22 +660,18 @@ newEffect{ end, getStrChange = function(level) return level end, getMagChange = function(level) return level end, - getCorpselightRadius = function(level) return level + 1 end, - getReprieveChance = function(level) return 35 + (level - 4) * 15 end, - display_desc = function(self, eff) - return ([[Curse of Corpses %d]]):format(eff.level) - end, + getCorpselightRadius = function(level) return math.floor(level + 1) end, + getReprieveChance = function(level) return Combat:combatLimit(level-4, 100, 35, 0, 50, 5) end, -- Limit < 100% + display_desc = function(self, eff) return ([[Curse of Corpses (power %0.1f)]]):format(eff.level) end, long_desc = function(self, eff) local def, level, bonusLevel = self.tempeffect_def[self.EFF_CURSE_OF_CORPSES], eff.level, math.min(eff.unlockLevel, eff.level) - - return ([[An aura of death surrounds you. #LIGHT_BLUE#Level %d%s#WHITE# -#CRIMSON#Penalty: #WHITE#Fear of Death: %+d%% resistance against damage from the undead. -#CRIMSON#Level 1: %sPower over Death: %+d%% damage against the undead. -#CRIMSON#Level 2: %s%+d Luck, %+d Strength, %+d Magic -#CRIMSON#Level 3: %sCorpselight: Each death you cause leaves behind a trace of itself, an eerie light of radius %d. -#CRIMSON#Level 4: %sReprieve from Death: Humanoids you slay have a %d%% chance to rise to fight beside you as ghouls for 6 turns.]]):format( - level, self.cursed_aura == self.EFF_CURSE_OF_CORPSES and ", Cursed Aura" or "", - def.getResistsUndead(level), + return ([[An aura of death surrounds you. +#CRIMSON#Penalty : #WHITE#Fear of Death: %+d%% resistance against damage from the undead. +#CRIMSON#Power 1+: %sPower over Death: %+d%% damage against the undead. +#CRIMSON#Power 2+: %s%+d Luck, %+d Strength, %+d Magic +#CRIMSON#Power 3+: %sCorpselight: Each death you cause leaves behind a trace of itself, an eerie light of radius %d. +#CRIMSON#Power 4+: %sReprieve from Death: Humanoids you slay have a %d%% chance to rise to fight beside you as ghouls for 6 turns.]]):format( + def.getResistsUndead(eff, level), bonusLevel >= 1 and "#WHITE#" or "#GREY#", def.getIncDamageUndead(math.max(level, 1)), bonusLevel >= 2 and "#WHITE#" or "#GREY#", def.getLckChange(eff, math.max(level, 2)), def.getStrChange(math.max(level, 2)), def.getMagChange(math.max(level, 2)), bonusLevel >= 3 and "#WHITE#" or "#GREY#", def.getCorpselightRadius(math.max(level, 3)), @@ -684,7 +681,7 @@ newEffect{ local def, level, bonusLevel = self.tempeffect_def[self.EFF_CURSE_OF_CORPSES], eff.level, math.min(eff.unlockLevel, eff.level) -- penalty: Fear of Death - eff.resistsUndeadId = self:addTemporaryValue("resists_actor_type", { ["undead"] = def.getResistsUndead(level) }) + eff.resistsUndeadId = self:addTemporaryValue("resists_actor_type", { ["undead"] = def.getResistsUndead(eff,level) }) -- level 1: Power over Death if bonusLevel < 1 then return end @@ -788,31 +785,30 @@ newEffect{ decrease = 0, no_remove = true, cancel_on_level_change = true, - parameters = {}, - getMindResistChange = function(level) return -level * 3 end, - getConfusionImmuneChange = function(level) return -level * 0.04 end, + parameters = {Penalty = 1}, + getMindResistChange = function(eff, level) return -level * 3 * (eff.Penalty or 1) end, + getConfusionImmuneChange = function(eff, level) return -level * 0.04 * (eff.Penalty or 1) end, getCombatCriticalPowerChange = function(level) return level * 3 end, - getOffHandMultChange = function(level) return level * 4 end, + -- called by _M:getOffHandMult in mod.class.interface.Combat.lua + getOffHandMultChange = function(level) return Combat:combatTalentLimit(level, 50, 4, 20) end, -- Limit < 50% getLckChange = function(eff, level) if eff.unlockLevel >= 5 or level <= 2 then return -1 end if level <= 3 then return -2 else return -3 end end, getDexChange = function(level) return -1 + level * 2 end, - getManiaDamagePercent = function(level) return 16 - (level - 4) * 3 end, - display_desc = function(self, eff) - return ([[Curse of Madness %d]]):format(eff.level) + getManiaDamagePercent = function(level) + return Combat:combatLimit(level - 4, 5, 13, 1, 8, 5) -- Limit > 5% end, + display_desc = function(self, eff) return ([[Curse of Madness (power %0.1f)]]):format(eff.level) end, long_desc = function(self, eff) local def, level, bonusLevel = self.tempeffect_def[self.EFF_CURSE_OF_MADNESS], eff.level, math.min(eff.unlockLevel, eff.level) - - return ([[You feel your grip on reality slipping. #LIGHT_BLUE#Level %d%s#WHITE# -#CRIMSON#Penalty: #WHITE#Fractured Sanity: %+d%% Mind Resistance, %+d%% Confusion Immunity -#CRIMSON#Level 1: %sUnleashed: %+d%% critical damage, %+d%% off-hand weapon damage -#CRIMSON#Level 2: %s%+d Luck, %+d Dexterity -#CRIMSON#Level 3: %sConspirator: When you are confused, any foe that hits you or that you hit in melee becomes confused. -#CRIMSON#Level 4: %sMania: Any time you take more than %d%% damage during a single turn, the remaining cooldown of one of your talents is reduced by 1.]]):format( - level, self.cursed_aura == self.EFF_CURSE_OF_MADNESS and ", Cursed Aura" or "", - def.getMindResistChange(level), def.getConfusionImmuneChange(level) * 100, + return ([[You feel your grip on reality slipping. +#CRIMSON#Penalty : #WHITE#Fractured Sanity: %+d%% Mind Resistance, %+d%% Confusion Immunity +#CRIMSON#Power 1+: %sUnleashed: %+d%% critical damage, %+d%% off-hand weapon damage +#CRIMSON#Power 2+: %s%+d Luck, %+d Dexterity +#CRIMSON#Power 3+: %sConspirator: When you are confused, any foe that hits you or that you hit in melee becomes confused. +#CRIMSON#Power 4+: %sMania: Any time you lose more than %0.1f%% of your life over a single turn, the remaining cooldown of one of your talents is reduced by 1.]]):format( + def.getMindResistChange(eff, level), def.getConfusionImmuneChange(eff, level) * 100, bonusLevel >= 1 and "#WHITE#" or "#GREY#", def.getCombatCriticalPowerChange(math.max(level, 1)), def.getOffHandMultChange(math.max(level, 1)), bonusLevel >= 2 and "#WHITE#" or "#GREY#", def.getLckChange(eff, math.max(level, 2)), def.getDexChange(math.max(level, 2)), bonusLevel >= 3 and "#WHITE#" or "#GREY#", @@ -825,8 +821,8 @@ newEffect{ eff.last_life = self.life -- penalty: Fractured Sanity - eff.mindResistId = self:addTemporaryValue("resists", { [DamageType.MIND] = def.getMindResistChange(level) }) - eff.confusionImmuneId = self:addTemporaryValue("confusion_immune", def.getConfusionImmuneChange(level) ) + eff.mindResistId = self:addTemporaryValue("resists", { [DamageType.MIND] = def.getMindResistChange(eff, level) }) + eff.confusionImmuneId = self:addTemporaryValue("confusion_immune", def.getConfusionImmuneChange(eff, level) ) -- level 1: Twisted Mind if bonusLevel < 1 then return end @@ -880,12 +876,13 @@ newEffect{ on_merge = function(self, old_eff, new_eff) return old_eff end, doConspirator = function(self, eff, target) if math.min(eff.unlockLevel, eff.level) >= 3 and self:attr("confused") and target:canBe("confusion") then - target:setEffect(target.EFF_CONFUSED, 3, {power=60}) + target:setEffect(target.EFF_CONFUSED, 3, {power=50}) -- Make consistent game.logSeen(self, "#F53CBE#%s spreads confusion to %s.", self.name:capitalize(), target.name) end end, } + newEffect{ name = "CURSE_OF_SHROUDS", desc = "Curse of Shrouds", @@ -897,10 +894,10 @@ newEffect{ decrease = 0, no_remove = true, cancel_on_level_change = true, - parameters = {}, - getShroudIncDamageChange = function(level) return -(4 + level * 2) end, + parameters = {Penalty = 1}, + getShroudIncDamageChange = function(eff, level) return -(4 + level * 2) * (eff.Penalty or 1) end, getResistsDarknessChange = function(level) return level * 4 end, - getResistsCapDarknessChange = function(level) return level * 4 end, + getResistsCapDarknessChange = function(level) return Combat:combatTalentLimit(level, 30, 4, 12) end, -- Limit < 30% getSeeInvisible = function(level) return 2 + level * 2 end, getLckChange = function(eff, level) if eff.unlockLevel >= 5 or level <= 2 then return -1 end @@ -908,20 +905,16 @@ newEffect{ end, getConChange = function(level) return -1 + level * 2 end, getShroudResistsAllChange = function(level) return (level - 1) * 5 end, - display_desc = function(self, eff) - return ([[Curse of Shrouds %d]]):format(eff.level) - end, + display_desc = function(self, eff) return ([[Curse of Shrouds (power %0.1f)]]):format(eff.level) end, long_desc = function(self, eff) local def, level, bonusLevel = self.tempeffect_def[self.EFF_CURSE_OF_SHROUDS], eff.level, math.min(eff.unlockLevel, eff.level) - - return ([[A shroud of darkness seems to fall across your path. #LIGHT_BLUE#Level %d%s#WHITE# -#CRIMSON#Penalty: #WHITE#Shroud of Weakness: Small chance of becoming enveloped in a Shroud of Weakness (reduces damage dealt by %d%%) for 4 turns. -#CRIMSON#Level 1: %sNightwalker: %+d Darkness Resistance, %+d%% Max Darkness Resistance, %+d See Invisible -#CRIMSON#Level 2: %s%+d Luck, %+d Constitution -#CRIMSON#Level 3: %sShroud of Passing: Your form seems to fade as you move, reducing all damage taken by %d%% for 1 turn after movement. -#CRIMSON#Level 4: %sShroud of Death: The power of every kill seems to envelop you like a shroud, reducing all damage taken by %d%% for 3 turns.]]):format( - level, self.cursed_aura == self.EFF_CURSE_OF_SHROUDS and ", Cursed Aura" or "", - -def.getShroudIncDamageChange(level), + return ([[A shroud of darkness seems to fall across your path. +#CRIMSON#Penalty : #WHITE#Shroud of Weakness: Small chance of becoming enveloped in a Shroud of Weakness (reduces damage dealt by %d%%) for 4 turns. +#CRIMSON#Power 1+: %sNightwalker: %+d Darkness Resistance, %+d%% Max Darkness Resistance, %+d See Invisible +#CRIMSON#Power 2+: %s%+d Luck, %+d Constitution +#CRIMSON#Power 3+: %sShroud of Passing: Your form seems to fade as you move, reducing all damage taken by %d%% for 1 turn after movement. +#CRIMSON#Power 4+: %sShroud of Death: The power of every kill seems to envelop you like a shroud, reducing all damage taken by %d%% for 3 turns.]]):format( + -def.getShroudIncDamageChange(eff, level), bonusLevel >= 1 and "#WHITE#" or "#GREY#", def.getResistsDarknessChange(math.max(level, 1)), def.getResistsCapDarknessChange(math.max(level, 1)), def.getSeeInvisible(math.max(level, 1)), bonusLevel >= 2 and "#WHITE#" or "#GREY#", def.getLckChange(eff, math.max(level, 2)), def.getConChange(math.max(level, 2)), bonusLevel >= 3 and "#WHITE#" or "#GREY#", def.getShroudResistsAllChange(math.max(level, 3)), @@ -963,7 +956,7 @@ newEffect{ -- Shroud of Weakness if rng.chance(100) then local def = self.tempeffect_def[self.EFF_CURSE_OF_SHROUDS] - self:setEffect(self.EFF_SHROUD_OF_WEAKNESS, 4, { power=def.getShroudIncDamageChange(eff.level) }) + self:setEffect(self.EFF_SHROUD_OF_WEAKNESS, 4, { power=def.getShroudIncDamageChange(eff, eff.level) }) end end, doShroudOfPassing = function(self, eff) @@ -1046,37 +1039,39 @@ newEffect{ decrease = 0, no_remove = true, cancel_on_level_change = true, - parameters = {}, - getVisionsReduction = function(level) return 5 + level * 4 end, + parameters = {Penalty = 1}, + -- called by _M:combatMentalResist in mod.class.interface.Combat.lua + getVisionsReduction = function(eff, level) + return Combat:combatTalentLimit(level, 100, 9, 25) * (eff.Penalty or 1) -- Limit < 100% + end, getResistsPhysicalChange = function(level) return 1 + level end, - getResistsCapPhysicalChange = function(level) return 1 + level end, + getResistsCapPhysicalChange = function(level) return Combat:combatTalentLimit(level, 30, 1, 5) end, -- Limit < 30% getLckChange = function(eff, level) if eff.unlockLevel >= 5 or level <= 2 then return -1 end if level <= 3 then return -2 else return -3 end end, getWilChange = function(level) return -1 + level * 2 end, - getBaseSuffocateAirChange = function(level) return 10 + (level - 3) * 3 end, - getSuffocateAirChange = function(level) return 3 + (level - 3) * 2 end, - getNightmareChance = function(level) return 0.1 + (level -4) * 0.05 end, + getBaseSuffocateAirChange = function(level) return Combat:combatTalentLimit(level, 50, 4, 16) end, -- Limit < 50 to take >2 hits to kill most monsters + getSuffocateAirChange = function(level) return Combat:combatTalentLimit(level, 10, 0, 7) end, -- Limit < 10 + getNightmareChance = function(level) return Combat:combatTalentLimit(math.max(0, level-4), 25, 3, 10) end, -- Limit < 25% getNightmareRadius = function(level) return 5 + (level - 4) * 2 end, display_desc = function(self, eff) if math.min(eff.unlockLevel, eff.level) >= 4 then - return ([[Curse of Nightmares %d: %d%%]]):format(eff.level, eff.nightmareChance or 0) + return ([[Curse of Nightmares (power %0.1f): %d%%]]):format(eff.level, eff.nightmareChance or 0) else - return ([[Curse of Nightmares %d]]):format(eff.level) + return ([[Curse of Nightmares (power %0.1f)]]):format(eff.level) end end, long_desc = function(self, eff) local def, level, bonusLevel = self.tempeffect_def[self.EFF_CURSE_OF_NIGHTMARES], eff.level, math.min(eff.unlockLevel, eff.level) - return ([[Horrible visions fill your mind. #LIGHT_BLUE#Level %d%s#WHITE# -#CRIMSON#Penalty: #WHITE#Plagued by Visions: Your mental save has a 20%% chance to be reduced by %d%% when tested. -#CRIMSON#Level 1: %sRemoved from Reality: %+d Physical Resistance, %+d Maximum Physical Resistance -#CRIMSON#Level 2: %s%+d Luck, %+d Willpower -#CRIMSON#Level 3: %sSuffocate: Your touch instills a horror that suffocates any weak, non-elite foe that hits you or that you hit in melee. At 3 levels below yours they lose %d air and an additional %d air for each level below that. -#CRIMSON#Level 4: %sNightmare: Each time you are damaged by a foe there is %d%% chance of triggering a radius %d nightmare (slow effects, hateful whispers, and summoned Terrors) for 8 turns. This chance grows each time you are struck.]]):format( - level, self.cursed_aura == self.EFF_CURSE_OF_NIGHTMARES and ", Cursed Aura" or "", - def.getVisionsReduction(level), + return ([[Horrible visions fill your mind. +#CRIMSON#Penalty : #WHITE#Plagued by Visions: Your mental save has a 20%% chance to be reduced by %d%% when tested. +#CRIMSON#Power 1+: %sRemoved from Reality: %+d Physical Resistance, %+d Maximum Physical Resistance +#CRIMSON#Power 2+: %s%+d Luck, %+d Willpower +#CRIMSON#Power 3+: %sSuffocate: Your touch instills a horror that suffocates any weak, non-elite foe that hits you or that you hit in melee. At 3 levels below yours they lose %d air and an additional %d air for each level below that. +#CRIMSON#Power 4+: %sNightmare: Each time you are damaged by a foe there is a chance (currently %d%%) of triggering a radius %d nightmare (slow effects, hateful whispers, and summoned Terrors) for 8 turns. This chance grows each time you are struck but fades over time.]]):format( + def.getVisionsReduction(eff, level), bonusLevel >= 1 and "#WHITE#" or "#GREY#", def.getResistsPhysicalChange(math.max(level, 1)), def.getResistsCapPhysicalChange(math.max(level, 1)), bonusLevel >= 2 and "#WHITE#" or "#GREY#", def.getLckChange(eff, math.max(level, 2)), def.getWilChange(math.max(level, 2)), bonusLevel >= 3 and "#WHITE#" or "#GREY#", def.getBaseSuffocateAirChange(math.max(level, 3)), def.getSuffocateAirChange(math.max(level, 3)), @@ -1112,7 +1107,7 @@ newEffect{ if math.min(eff.unlockLevel, eff.level) >= 3 then if target and target.rank <= 2 and target.level <= self.level - 3 and not target:attr("no_breath") and not target:attr("invulnerable") then local def = self.tempeffect_def[self.EFF_CURSE_OF_NIGHTMARES] - local airLoss = def.getBaseSuffocateAirChange(eff.level) + (self.level - target.level - 3) * def.getSuffocateAirChange(eff.level) + local airLoss = def.getBaseSuffocateAirChange(eff.level) + Combat:combatTalentScale(self.level - target.level - 3, 1, 5) * def.getSuffocateAirChange(eff.level) game.logSeen(self, "#F53CBE#%s begins to choke from a suffocating curse. (-%d air)", target.name, airLoss) target:suffocate(airLoss, self, "suffocated from a curse") end @@ -1147,6 +1142,10 @@ newEffect{ resolvers.talents{ }, }, + on_timeout = function(self, eff) -- Chance for nightmare fades over time + if eff.nightmareChance then eff.nightmareChance = math.max(0, eff.nightmareChance-1) end + end, + -- called by _M:onTakeHit function in in mod.class.Actor.lua doNightmare = function(self, eff) if math.min(eff.unlockLevel, eff.level) >= 4 then -- build chance for a nightmare @@ -1219,6 +1218,7 @@ newEffect{ end, } + newEffect{ name = "CURSE_OF_MISFORTUNE", desc = "Curse of Misfortune", @@ -1230,7 +1230,9 @@ newEffect{ decrease = 0, no_remove = true, cancel_on_level_change = true, - parameters = {}, + parameters = {Penalty = 1}, + getMoneyMult = function(eff, level) return Combat:combatTalentLimit(level, 1, 0.15, 0.35) * (eff.Penalty or 1)end, -- Limit < 1 bug fix + getCombatDefChange = function(level) return level * 2 end, getCombatDefRangedChange = function(level) return level end, getLckChange = function(eff, level) @@ -1238,22 +1240,19 @@ newEffect{ if level <= 3 then return -2 else return -3 end end, getCunChange = function(level) return -1 + level * 2 end, - getDeviousMindChange = function(level) return 20 + 15 * (level - 3) end, - getUnfortunateEndChance = function(level) return 30 + (level - 4) * 10 end, - getUnfortunateEndIncrease = function(level) return 40 + (level - 4) * 20 end, - display_desc = function(self, eff) - return ([[Curse of Misfortune %d]]):format(eff.level) - end, + getDeviousMindChange = function(level) return Combat:combatTalentLimit(math.max(1,level-3), 100, 35, 55) end, -- Limit < 100% + getUnfortunateEndChance = function(level) return Combat:combatTalentLimit(math.max(1, level-3), 100, 30, 40) end, -- Limit < 50% + getUnfortunateEndIncrease = function(level) return Combat:combatTalentLimit(math.max(1, level-3), 50, 30, 40) end, -- Limit < 50% + display_desc = function(self, eff) return ([[Curse of Misfortune (power %0.1f)]]):format(eff.level) end, long_desc = function(self, eff) local def, level, bonusLevel = self.tempeffect_def[self.EFF_CURSE_OF_MISFORTUNE], eff.level, math.min(eff.unlockLevel, eff.level) - return ([[Mayhem and destruction seem to follow you. #LIGHT_BLUE#Level %d%s#WHITE# -#CRIMSON#Penalty: #WHITE#Lost Fortune: You seem to find less gold in your journeys. -#CRIMSON#Level 1: %sMissed Opportunities: %+d Defense, +%d Ranged Defense -#CRIMSON#Level 2: %s%+d Luck, %+d Cunning -#CRIMSON#Level 3: %sDevious Mind: You have an affinity for seeing the devious plans of others (+%d%% chance to avoid traps). -#CRIMSON#Level 4: %sUnfortunate End: There is a %d%% chance that the damage you deal will increase by %d%% if it is enough to kill your opponent.]]):format( - level, self.cursed_aura == self.EFF_CURSE_OF_MISFORTUNE and ", Cursed Aura" or "", + return ([[Mayhem and destruction seem to follow you. +#CRIMSON#Penalty : #WHITE#Lost Fortune: You seem to find less gold in your journeys. +#CRIMSON#Power 1+: %sMissed Opportunities: %+d Defense, +%d Ranged Defense +#CRIMSON#Power 2+: %s%+d Luck, %+d Cunning +#CRIMSON#Power 3+: %sDevious Mind: You have an affinity for seeing the devious plans of others (+%d%% chance to avoid traps). +#CRIMSON#Power 4+: %sUnfortunate End: There is a %d%% chance that the damage you deal will increase by %d%% if the increase would be enough to kill your opponent.]]):format( bonusLevel >= 1 and "#WHITE#" or "#GREY#", def.getCombatDefChange(math.max(level, 1)), def.getCombatDefRangedChange(math.max(level, 1)), bonusLevel >= 2 and "#WHITE#" or "#GREY#", def.getLckChange(eff, math.max(level, 2)), def.getCunChange(math.max(level, 2)), bonusLevel >= 3 and "#WHITE#" or "#GREY#", def.getDeviousMindChange(math.max(level, 3)), @@ -1263,7 +1262,7 @@ newEffect{ local def, level, bonusLevel = self.tempeffect_def[self.EFF_CURSE_OF_MISFORTUNE], eff.level, math.min(eff.unlockLevel, eff.level) -- penalty: Lost Fortune - eff.moneyValueMultiplierId = self:addTemporaryValue("money_value_multiplier", 0.5 - level * 0.05) + eff.moneyValueMultiplierId = self:addTemporaryValue("money_value_multiplier", -def.getMoneyMult(eff, level)) -- level 1: Missed Shot if bonusLevel < 1 then return end @@ -1279,7 +1278,7 @@ newEffect{ -- level 3: Devious Mind if bonusLevel < 3 then return end - eff.trapAvoidanceId = self:addTemporaryValue("trap_avoidance", 50) + eff.trapAvoidanceId = self:addTemporaryValue("trap_avoidance", def.getDeviousMindChange(level)) -- level 4: Unfortunate End end, @@ -1291,6 +1290,8 @@ newEffect{ if eff.trapAvoidanceId then self:removeTemporaryValue("trap_avoidance", eff.trapAvoidanceId) end end, on_merge = function(self, old_eff, new_eff) return old_eff end, + + -- called by default projector in mod.data.damage_types.lua doUnfortunateEnd = function(self, eff, target, dam) if math.min(eff.unlockLevel, eff.level) >=4 then local def = self.tempeffect_def[self.EFF_CURSE_OF_MISFORTUNE] diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua index ee3c3dedb8..4f3c504f1e 100644 --- a/game/modules/tome/data/timed_effects/physical.lua +++ b/game/modules/tome/data/timed_effects/physical.lua @@ -1726,6 +1726,7 @@ newEffect{ -- Note: This effect is cancelled by EFF_DISARMED long_desc = function(self, eff) return ("Parrying melee attacks: Has a %d%% chance to deflect up to %d damage from the next %0.1f attack(s)."):format(self.tempeffect_def.EFF_DUAL_WEAPON_DEFENSE.deflectchance(self, eff),eff.dam, math.max(eff.deflects,1)) end, + charges = function(self, eff) return math.ceil(eff.deflects) end, type = "physical", subtype = {tactic=true}, status = "beneficial", @@ -1803,6 +1804,7 @@ newEffect{ long_desc = function(self, eff) return ("Countering melee attacks: Has a %d%% chance to get an automatic counter attack when avoiding a melee attack. (%0.1f counters remaining)"):format(self.tempeffect_def.EFF_COUNTER_ATTACKING.counterchance(self, eff), math.max(eff.counterattacks,1)) end, + charges = function(self, eff) return math.ceil(eff.counterattacks) end, type = "physical", subtype = {tactic=true}, status = "beneficial", @@ -1829,6 +1831,7 @@ newEffect{ long_desc = function(self, eff) return ("Has a %d%% chance to counter attack with a defensive throw when avoiding a melee attack, possibly throwing the target to the ground and stunning it. (%0.1f throws remaining)"):format(self.tempeffect_def.EFF_DEFENSIVE_GRAPPLING.throwchance(self, eff), math.max(eff.throws,1)) end, + charges = function(self, eff) return math.ceil(eff.throws) end, type = "physical", subtype = {tactic=true}, status = "beneficial", -- GitLab