From 3837a6b541d0f78bc55eccfd9693bb0e16e3a188 Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Sat, 2 Apr 2011 21:39:21 +0000 Subject: [PATCH] Damage resistances are now stacking multiplicatively git-svn-id: http://svn.net-core.org/repos/t-engine4@3146 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engines/default/engine/Entity.lua | 32 +++++++++++++------ game/modules/tome/class/Actor.lua | 3 +- game/modules/tome/class/interface/Combat.lua | 10 +++++- .../tome/class/interface/PlayerDumpJSON.lua | 2 +- game/modules/tome/data/damage_types.lua | 4 +-- game/modules/tome/dialogs/CharacterSheet.lua | 8 ++--- 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua index b3b90ab1ad..8909a4ac7e 100644 --- a/game/engines/default/engine/Entity.lua +++ b/game/engines/default/engine/Entity.lua @@ -491,23 +491,29 @@ function _M:addTemporaryValue(prop, v, noupdate) -- The recursive enclosure local recursive - recursive = function(base, prop, v) + recursive = function(base, prop, v, method) + method = self.temporary_values_conf[prop] or method if type(v) == "number" then -- Simple addition - if self.temporary_values_conf[prop] == "mult" then + if method == "mult" then base[prop] = (base[prop] or 1) * v - elseif self.temporary_values_conf[prop] == "mult0" then + elseif method == "mult0" then base[prop] = (base[prop] or 1) * (1 + v) + elseif method == "perc_inv" then + v = v / 100 + local b = (base[prop] or 0) / 100 + b = 1 - (1 - b) * (1 - v) + base[prop] = b * 100 else base[prop] = (base[prop] or 0) + v end self:onTemporaryValueChange(prop, v, base) - print("addTmpVal", base, prop, v, " :=: ", #t, id) + print("addTmpVal", base, prop, v, " :=: ", #t, id, method) elseif type(v) == "table" then for k, e in pairs(v) do print("addTmpValTable", base[prop], k, e) base[prop] = base[prop] or {} - recursive(base[prop], k, e) + recursive(base[prop], k, e, method) end else error("unsupported temporary value type: "..type(v).." :=: "..tostring(v)) @@ -516,7 +522,7 @@ function _M:addTemporaryValue(prop, v, noupdate) -- Update the base prop if not noupdate then - recursive(initial_base, initial_prop, v) + recursive(initial_base, initial_prop, v, "add") end return id @@ -549,12 +555,18 @@ function _M:removeTemporaryValue(prop, id, noupdate) -- The recursive enclosure local recursive recursive = function(base, prop, v) + method = self.temporary_values_conf[prop] or method if type(v) == "number" then -- Simple addition - if self.temporary_values_conf[prop] == "mult" then + if method == "mult" then base[prop] = base[prop] / v - elseif self.temporary_values_conf[prop] == "mult0" then + elseif method == "mult0" then base[prop] = base[prop] / (1 + v) + elseif method == "perc_inv" then + v = v / 100 + local b = base[prop] / 100 + b = 1 - (1 - b) / (1 - v) + base[prop] = b * 100 else base[prop] = base[prop] - v end @@ -562,7 +574,7 @@ function _M:removeTemporaryValue(prop, id, noupdate) print("delTmpVal", prop, v) elseif type(v) == "table" then for k, e in pairs(v) do - recursive(base[prop], k, e) + recursive(base[prop], k, e, method) end else error("unsupported temporary value type: "..type(v).." :=: "..v) @@ -571,7 +583,7 @@ function _M:removeTemporaryValue(prop, id, noupdate) -- Update the base prop if not noupdate then - recursive(initial_base, initial_prop, oldval) + recursive(initial_base, initial_prop, oldval, "add") end end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 7325cf8cde..5ecd3264e9 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -72,6 +72,7 @@ _M.temporary_values_conf.global_speed = "mult0" _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.resists = "perc_inv" function _M:init(t, no_default) -- Define some basic combat stats @@ -696,7 +697,7 @@ function _M:tooltip(x, y, seen_by) local resists = {} for t, v in pairs(self.resists) do - if t ~= "all" then v = v + (self.resists.all or 0) end + if t ~= "all" then v = self:combatGetResist(t) end resists[#resists+1] = string.format("%d%% %s", v, t == "all" and "all" or DamageType:get(t).name) end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 59dd2338e9..9d3afe944a 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -830,6 +830,14 @@ function _M:combatMentalResist() return self.combat_mentalresist + (self:getCun() + self:getWil() + (self:getLck() - 50) * 0.5) * 0.35 + add end +--- Returns the resistance +function _M:combatGetResist(type) + local a = (self.resists.all or 0) / 100 + local b = (self.resists[type] or 0) / 100 + local r = math.min(100 * (1 - (1 - a) * (1 - b)), (self.resists_cap.all or 0) + (self.resists_cap[type] or 0)) + return r +end + --- Computes movement speed function _M:combatMovementSpeed() return (self.base_movement_speed or 1) / self.movement_speed @@ -1059,4 +1067,4 @@ function _M:startGrapple(target) game.logSeen(target, "%s resists the grapple!", target.name:capitalize()) return false end -end \ No newline at end of file +end diff --git a/game/modules/tome/class/interface/PlayerDumpJSON.lua b/game/modules/tome/class/interface/PlayerDumpJSON.lua index 021c4209d6..41b456bda9 100644 --- a/game/modules/tome/class/interface/PlayerDumpJSON.lua +++ b/game/modules/tome/class/interface/PlayerDumpJSON.lua @@ -164,7 +164,7 @@ function _M:dumpToJSON(js) if self.resists.all then d[#d+1] = { ["all resists(cap)"] = string.format("%3d%%(%3d%%)", self.resists.all, self.resists_cap.all or 0) } end for i, t in ipairs(DamageType.dam_def) do if self.resists[DamageType[t.type]] and self.resists[DamageType[t.type]] ~= 0 then - d[#d+1] = { [t.name.." resist(cap)"] = string.format("%3d%%(%3d%%)", self.resists[DamageType[t.type]] + (self.resists.all or 0), (self.resists_cap[DamageType[t.type]] or 0) + (self.resists_cap.all or 0)) } + d[#d+1] = { [t.name.." resist(cap)"] = string.format("%3d%%(%3d%%)", self:combatGetResist(DamageType[t.type]), (self.resists_cap[DamageType[t.type]] or 0) + (self.resists_cap.all or 0)) } end end immune_type = "poison_immune" immune_name = "Poison Resistance" if self:attr(immune_type) then d[#d+1] = { [immune_name] = string.format("%d%%", util.bound(self:attr(immune_type) * 100, 0, 100)) } end diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 33e641c6d8..cda4b8af8c 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -92,7 +92,7 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) if target.resists then local pen = 0 if src.resists_pen then pen = (src.resists_pen.all or 0) + (src.resists_pen[type] or 0) end - local res = math.min((target.resists.all or 0) + (target.resists[type] or 0), (target.resists_cap.all or 0) + (target.resists_cap[type] or 0)) + local res = target:combatGetResist(type) res = res * (100 - pen) / 100 print("[PROJECTOR] res", res, (100 - res) / 100, " on dam", dam) if res >= 100 then dam = 0 @@ -1382,6 +1382,6 @@ newDamageType{ else game.logSeen(target, "%s resists!", target.name:capitalize()) end - end + end end, } diff --git a/game/modules/tome/dialogs/CharacterSheet.lua b/game/modules/tome/dialogs/CharacterSheet.lua index 61bd0fcec5..adf97d4116 100644 --- a/game/modules/tome/dialogs/CharacterSheet.lua +++ b/game/modules/tome/dialogs/CharacterSheet.lua @@ -164,7 +164,7 @@ function _M:drawDialog(s) end if mean and mean.range then self:mouseTooltip(self.TOOLTIP_COMBAT_RANGE, s:drawColorStringBlended(self.font, ("Range (Main Hand): #00ff00#%3d"):format(mean.range), w, h, 255, 255, 255)) h = h + self.font_h end end - + h = h + self.font_h -- All weapons in off hands -- Offhand attacks are with a damage penalty, that can be reduced by talents @@ -185,7 +185,7 @@ function _M:drawDialog(s) if mean and mean.range then self:mouseTooltip(self.TOOLTIP_COMBAT_RANGE, s:drawColorStringBlended(self.font, ("Range (Off Hand): #00ff00#%3d"):format(mean.range), w, h, 255, 255, 255)) h = h + self.font_h end end end - + h = h + self.font_h self:mouseTooltip(self.TOOLTIP_SPELL_POWER, s:drawColorStringBlended(self.font, ("Spellpower: #00ff00#%3d"):format(player:combatSpellpower()), w, h, 255, 255, 255)) h = h + self.font_h self:mouseTooltip(self.TOOLTIP_SPELL_CRIT, s:drawColorStringBlended(self.font, ("Spell Crit: #00ff00#%3d%%"):format(player:combatSpellCrit()), w, h, 255, 255, 255)) h = h + self.font_h @@ -215,7 +215,7 @@ function _M:drawDialog(s) if player.resists.all then self:mouseTooltip(self.TOOLTIP_RESIST_ALL, s:drawColorStringBlended(self.font, ("All Resists(cap): #00ff00#%3d%%(%3d%%)"):format(player.resists.all, player.resists_cap.all or 0), w, h, 255, 255, 255)) h = h + self.font_h end for i, t in ipairs(DamageType.dam_def) do if player.resists[DamageType[t.type]] and player.resists[DamageType[t.type]] ~= 0 then - self:mouseTooltip(self.TOOLTIP_RESIST, s:drawColorStringBlended(self.font, ("%s Resist(cap): #00ff00#%3d%%(%3d%%)"):format(t.name:capitalize(), player.resists[DamageType[t.type]] + (player.resists.all or 0), (player.resists_cap[DamageType[t.type]] or 0) + (player.resists_cap.all or 0)), w, h, 255, 255, 255)) h = h + self.font_h + self:mouseTooltip(self.TOOLTIP_RESIST, s:drawColorStringBlended(self.font, ("%s Resist(cap): #00ff00#%3d%%(%3d%%)"):format(t.name:capitalize(), player:combatGetResist(DamageType[t.type]), (player.resists_cap[DamageType[t.type]] or 0) + (player.resists_cap.all or 0)), w, h, 255, 255, 255)) h = h + self.font_h end end @@ -406,7 +406,7 @@ function _M:dump() if player.resists.all then nl(("All Resists: %3d%%"):format(player.resists.all, player.resists_cap.all or 0)) end for i, t in ipairs(DamageType.dam_def) do if player.resists[DamageType[t.type]] and player.resists[DamageType[t.type]] ~= 0 then - nl(("%s Resist(cap): %3d%%(%3d%%)"):format(t.name:capitalize(), player.resists[DamageType[t.type]] + (player.resists.all or 0), (player.resists_cap[DamageType[t.type]] or 0) + (player.resists_cap.all or 0))) + nl(("%s Resist(cap): %3d%%(%3d%%)"):format(t.name:capitalize(), player:combatGetResist(DamageType[t.type]), (player.resists_cap[DamageType[t.type]] or 0) + (player.resists_cap.all or 0))) end end -- GitLab