From b301c66c33f495588bc67b4565cfba265a2cd554 Mon Sep 17 00:00:00 2001
From: DarkGod <darkgod@net-core.org>
Date: Sat, 19 Oct 2013 21:36:46 +0200
Subject: [PATCH] Swords, axes, maces, staves, daggers, whips, tridents, bows
 and slings now have special "unique" effects when hitting a foe for each
 attack you have over their defence

---
 game/modules/tome/ai/escort.lua               |  3 +-
 game/modules/tome/class/Object.lua            | 24 ++++++++++
 game/modules/tome/class/interface/Combat.lua  | 45 +++++++++++++++++++
 game/modules/tome/data/damage_types.lua       |  5 +++
 .../tome/data/general/objects/2htridents.lua  |  2 +-
 .../tome/data/general/objects/bows.lua        |  2 +-
 .../tome/data/general/objects/slings.lua      |  2 +-
 .../tome/data/general/objects/whips.lua       |  2 +-
 8 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/game/modules/tome/ai/escort.lua b/game/modules/tome/ai/escort.lua
index 2e28aa8b21..37b1416d67 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 fa0282ae2f..6722137755 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 b971444404..d884d9be73 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 759c7ea7bd..2e428171ec 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 5ef2e9ef8b..df7568c415 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 dc0ef8639a..250743db32 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 d56a027a10..876de3da8f 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 768b6b3e58..09c2a11199 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) },
-- 
GitLab