diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua index b3b90ab1ade7092654eb3b853bba8f97563d0382..8909a4ac7eab5e8bb300a2d42b7cc5383ca5e52b 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 7325cf8cdebf4bc95300a5c3cd0cf11a152dac5b..5ecd3264e935e7018b18ba82f3d6d2769865bce6 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 59dd2338e9b856d9ae9ca71ff3a83b6a0ab21b30..9d3afe944a12f9f72a28d69a10bc2f31d16a42f7 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 021c4209d6222c8f3178217298f283376fc9c78a..41b456bda903168c88c4b54d53089697fd5e3133 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 33e641c6d8e90a21760f14494327e9e9e9f941a0..cda4b8af8c872de95978cbb3bb274da0028fe8c1 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 61bd0fcec52bb18ab03486eff7fb2daa8e489cfb..adf97d41161e8406b2d530c26c1d0222fc546ccf 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