diff --git a/game/modules/tome/ai/escort.lua b/game/modules/tome/ai/escort.lua index 2e28aa8b214c580c3f7ef460f75d99df08cca8b0..37b1416d675f9874bd6df3990962c727c9167678 100644 --- a/game/modules/tome/ai/escort.lua +++ b/game/modules/tome/ai/escort.lua @@ -43,7 +43,8 @@ newAI("escort_quest", function(self) if not self.ai_state.fleeing_msg then self.ai_state.fleeing_msg = true local enemy = self.ai_target.actor - self:doEmote(("Help! %s to the %s!"):format(string.capitalize(enemy.name), game.level.map:compassDirection(enemy.x-self.x, enemy.y-self.y) or "???")) + local dir = game.level.map:compassDirection(enemy.x-self.x, enemy.y-self.y) + self:doEmote("Help!"..(dir and (" %s to the %s!"):format(self:canSee(enemy) and string.capitalize(enemy.name) or "Something", dir) or "")) end else self:runAI("move_escort") diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index fa0282ae2ffb4a89de46ebee1b1ce8f9109e7d9e..6722137755d2e0f03da78504d8193ece413bb72b 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -315,6 +315,28 @@ function _M:getShortName(t) end end +function _M:descAccuracyBonus(desc, weapon) + local _, kind = game.player:isAccuracyEffect(weapon) + if not kind then return end + + local showpct = function(v, mult) + return ("+%0.1f%%"):format(v * mult) + end + + local m = weapon.accuracy_effect_scale or 1 + if kind == "sword" then + desc:add("Accuracy bonus: ", {"color","LIGHT_GREEN"}, showpct(0.4, m), {"color","LAST"}, " crit.pwr / acc", true) + elseif kind == "axe" then + desc:add("Accuracy bonus: ", {"color","LIGHT_GREEN"}, showpct(0.2, m), {"color","LAST"}, " crit / acc", true) + elseif kind == "mace" then + desc:add("Accuracy bonus: ", {"color","LIGHT_GREEN"}, showpct(0.1, m), {"color","LAST"}, " dam / acc", true) + elseif kind == "staff" then + desc:add("Accuracy bonus: ", {"color","LIGHT_GREEN"}, showpct(4, m), {"color","LAST"}, " procs dam / acc", true) + elseif kind == "knife" then + desc:add("Accuracy bonus: ", {"color","LIGHT_GREEN"}, showpct(0.5, m), {"color","LAST"}, " APR / acc", true) + end +end + --- Gets the full textual desc of the object without the name and requirements function _M:getTextualDesc(compare_with) compare_with = compare_with or {} @@ -496,6 +518,8 @@ function _M:getTextualDesc(compare_with) if t and t.name then desc:add("Mastery: ", {"color","GOLD"}, t.name, {"color","LAST"}, true) end end + self:descAccuracyBonus(desc, combat) + if combat.wil_attack then desc:add("Accuracy is based on willpower for this weapon.", true) end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index b971444404436fdbd3c6169cc138c52a92af2f86..d884d9be73488fafbecd7c964a6a91c75306257e 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -324,6 +324,17 @@ function _M:checkEvasion(target) return rng.percent(evasion) end +function _M:getAccuracyEffect(weapon, atk, def, scale, max) + max = max or 10000000 + scale = scale or 1 + return math.min(max, math.max(0, atk - def) * scale * (weapon.accuracy_effect_scale or 1)) +end + +function _M:isAccuracyEffect(weapon, kind) + local eff = weapon.accuracy_effect or weapon.talented + return eff == kind, eff +end + --- Attacks with one weapon function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) damtype = damtype or (weapon and weapon.damtype) or DamageType.PHYSICAL @@ -397,6 +408,13 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) dam = dam - deflected print("[ATTACK] after GESTURE_OF_GUARDING", dam) end + + if self:isAccuracyEffect(weapon, "knife") then + local bonus = 1 + self:getAccuracyEffect(weapon, atk, def, 0.005, 0.25) + print("[ATTACJ] dagger accuracy bonus", atk, def, "=", bonus, "previous", apr) + apr = apr * bonus + 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)) @@ -409,6 +427,12 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) dam = dam * mult print("[ATTACK] after mult", dam) + if self:isAccuracyEffect(weapon, "mace") then + local bonus = 1 + self:getAccuracyEffect(weapon, atk, def, 0.001, 0.1) + print("[ATTACK] mace accuracy bonus", atk, def, "=", bonus) + dam = dam * bonus + end + if target:hasEffect(target.EFF_COUNTERSTRIKE) then dam = dam * 2 local eff = target.tmp[target.EFF_COUNTERSTRIKE] @@ -493,6 +517,13 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) target:setEffect(target.EFF_OFFGUARD, tier_diff, {}, reapplied) end ]] + + if self:isAccuracyEffect(weapon, "staff") then + local bonus = 1 + self:getAccuracyEffect(weapon, atk, def, 0.04, 2) + print("[ATTACK] staff accuracy bonus", atk, def, "=", bonus) + self.__global_accuracy_damage_bonus = bonus + end + -- handle stalk targeting for hits (also handled in Actor for turn end effects) if hitted and target ~= self then if effStalker then @@ -886,6 +917,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) if hitted then game.level.map:particleEmitter(target.x, target.y, 1, "melee_attack", {color=target.blood_color}) end self.turn_procs.weapon_type = nil + self.__global_accuracy_damage_bonus = nil return self:combatSpeed(weapon), hitted end @@ -1547,6 +1579,12 @@ function _M:physicalCrit(dam, weapon, target, atk, def, add_chance, crit_power_a crit_power_add = crit_power_add + self:callTalent(self.T_SHADOWSTRIKE,"getMultiplier") end + if self:isAccuracyEffect(weapon, "axe") then + local bonus = self:getAccuracyEffect(weapon, atk, def, 0.2, 10) + print("[PHYS CRIT %] axe accuracy bonus", atk, def, "=", bonus) + chance = chance + bonus + end + chance = util.bound(chance, 0, 100) print("[PHYS CRIT %]", chance) @@ -1554,6 +1592,13 @@ function _M:physicalCrit(dam, weapon, target, atk, def, add_chance, crit_power_a if target:hasEffect(target.EFF_OFFGUARD) then crit_power_add = crit_power_add + 0.1 end + + if self:isAccuracyEffect(weapon, "sword") then + local bonus = self:getAccuracyEffect(weapon, atk, def, 0.004, 0.25) + print("[PHYS CRIT %] sword accuracy bonus", atk, def, "=", bonus) + crit_power_add = crit_power_add + bonus + end + self.turn_procs.is_crit = "physical" self.turn_procs.crit_power = (1.5 + crit_power_add + (self.combat_critical_power or 0) / 100) dam = dam * (1.5 + crit_power_add + (self.combat_critical_power or 0) / 100) diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 759c7ea7bd701d22c080228bf1687a9c33ab8718..2e428171ec3e72c9820b90bebe3efbe1d1c810ef 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -81,6 +81,11 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) end print("[PROJECTOR] after difficulty dam", dam) + if src.__global_accuracy_damage_bonus then + dam = dam * src.__global_accuracy_damage_bonus + print("[PROJECTOR] after staff accuracy damage bonus", dam) + end + -- Daze if src:attr("dazed") then dam = dam * 0.5 diff --git a/game/modules/tome/data/general/objects/2htridents.lua b/game/modules/tome/data/general/objects/2htridents.lua index 5ef2e9ef8bcb19edd19631653734ca7a87a82a8a..df7568c415e7cad04ecf71eb47cf0ce7e90f83bc 100644 --- a/game/modules/tome/data/general/objects/2htridents.lua +++ b/game/modules/tome/data/general/objects/2htridents.lua @@ -29,7 +29,7 @@ newEntity{ trident_rarity = 5, -- Special rarity field, converted to "rarity" when needed metallic = true, no_rust = true, - combat = { talented = "trident", damrange = 1.6, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} }, + combat = { talented = "trident", accuracy_effect = "mace", damrange = 1.6, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} }, desc = [[A two-handed massive trident. Tridents require the exotic weapons mastery talent to use correctly.]], twohanded = true, diff --git a/game/modules/tome/data/general/objects/bows.lua b/game/modules/tome/data/general/objects/bows.lua index dc0ef8639a8aa66cebcc2aeecf735916db6e3b96..250743db323f06700bfaa28b13bf91de0a0a8776 100644 --- a/game/modules/tome/data/general/objects/bows.lua +++ b/game/modules/tome/data/general/objects/bows.lua @@ -28,7 +28,7 @@ newEntity{ moddable_tile = resolvers.moddable_tile("bow"), encumber = 4, rarity = 7, - combat = { talented = "bow", sound = "actions/arrow", sound_miss = "actions/arrow",}, + combat = { talented = "bow", accuracy_effect = "axe", sound = "actions/arrow", sound_miss = "actions/arrow",}, require = { talent = { Talents.T_SHOOT }, }, archery_kind = "bow", archery = "bow", diff --git a/game/modules/tome/data/general/objects/slings.lua b/game/modules/tome/data/general/objects/slings.lua index d56a027a10fd7a29a96c09506ebc8b409f308ba3..876de3da8f02da31a7ff7e07bd0a77a0d3633384 100644 --- a/game/modules/tome/data/general/objects/slings.lua +++ b/game/modules/tome/data/general/objects/slings.lua @@ -27,7 +27,7 @@ newEntity{ moddable_tile = resolvers.moddable_tile("sling"), encumber = 4, rarity = 7, - combat = { talented = "sling", sound = "actions/sling", sound_miss = "actions/sling", }, + combat = { talented = "sling", accuracy_effect = "maxe", sound = "actions/sling", sound_miss = "actions/sling", }, archery_kind = "sling", archery = "sling", require = { talent = { Talents.T_SHOOT }, }, diff --git a/game/modules/tome/data/general/objects/whips.lua b/game/modules/tome/data/general/objects/whips.lua index 768b6b3e58706d3493c60ac662d5c1ef17e72147..09c2a11199494bee7dc87e6e88aa3bdcda0df660 100644 --- a/game/modules/tome/data/general/objects/whips.lua +++ b/game/modules/tome/data/general/objects/whips.lua @@ -27,7 +27,7 @@ newEntity{ encumber = 3, rarity = 5, metallic = true, - combat = { talented = "whip", damrange = 1.1, physspeed = 0.8, sound = "actions/whip_hit", sound_miss = "actions/whip_miss",}, + combat = { talented = "whip", accuracy_effect = "whip", damrange = 1.1, physspeed = 0.8, sound = "actions/whip_hit", sound_miss = "actions/whip_miss",}, desc = [[Sharp, long and deadly.]], randart_able = "/data/general/objects/random-artifacts/generic.lua", egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) },