diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index a04b380d491d7616a8fea23bef8af44574461910..df4f73f73a64f965c213a056e21a416c1f69d606 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -660,7 +660,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
 			self.__attacktargetwith_recursing_procs_reduce = weapon.attack_recurse_procs_reduce
 		end
 
-		if self.__attacktargetwith_recursing > 0 then
+		if self.__attacktargetwith_recursing > 0 and not self.turn_procs._no_melee_recursion then
 			local _, newhitted, newdam = self:attackTargetWith(target, weapon, damtype, mult, force_dam)
 			hitted = newhitted or hitted
 			dam = math.max(dam, newdam)
diff --git a/game/modules/tome/data/talents/techniques/battle-tactics.lua b/game/modules/tome/data/talents/techniques/battle-tactics.lua
index f5f762eaf31112d135a5f1ca8b70fab5ebf52bbc..af0ba0fbdfc20298f82a8182b8743aa2c6f8e81a 100644
--- a/game/modules/tome/data/talents/techniques/battle-tactics.lua
+++ b/game/modules/tome/data/talents/techniques/battle-tactics.lua
@@ -34,8 +34,8 @@ newTalent{
 		return true
 	end,
 	info = function(self, t)
-		return ([[Concentrate on your blows; for %d turns, each successful strike you land has a %d%% chance to trigger another, similar strike.
-		This works for all blows, even those from other talents and from shield bashes, but can happen only once each turn.
+		return ([[Concentrate on your blows; for %d turns, each strike you land on your target in melee range has a %d%% chance to trigger another, similar strike.
+		This works for all blows, even those from other talents and from shield bashes, but you can gain no more than one extra blow with each weapon during a turn.
 		The chance increases with your Dexterity.]]):format(t.getdur(self, t), t.getchance(self, t))
 	end,
 }
diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua
index dd08cd92cdf2c1177521d7d377509690891ae3a9..c52faf2b0c563fa1f055f48eb61e06bc8dd750bd 100644
--- a/game/modules/tome/data/timed_effects/physical.lua
+++ b/game/modules/tome/data/timed_effects/physical.lua
@@ -1302,16 +1302,24 @@ newEffect{
 newEffect{
 	name = "GREATER_WEAPON_FOCUS", image = "talents/greater_weapon_focus.png",
 	desc = "Greater Weapon Focus",
-	long_desc = function(self, eff) return ("Each melee blow landed has a %d%% chance to trigger an additional melee blow (up to once per turn)."):format(eff.chance) end,
+	long_desc = function(self, eff) return ("Each melee blow landed has a %d%% chance to trigger an additional melee blow (up to once per turn for each weapon)."):format(eff.chance) end,
 	type = "physical",
 	subtype = { tactic=true },
 	status = "beneficial",
 	parameters = { chance=25 },
-	-- trigger once per turn for targets
 	callbackOnMeleeAttack = function(self, eff, target, hitted, crit, weapon, damtype, mult, dam, hd)
-		if hitted and weapon and not self.turn_procs._gwf and not target.dead and rng.percent(eff.chance) then
-			self.turn_procs._gwf = true
-			self:attackTargetWith(target, weapon, damtype, mult)
+	-- trigger up to once per turn for each weapon
+	-- checks self.turn_procs._no_melee_recursion to limit possible compounded recursion or other needed special cases
+		if hitted and weapon and not (self.turn_procs._gwf_active or self.turn_procs._no_melee_recursion or target.dead) then
+			local gwf = self.turn_procs._gwf or {}
+			self.turn_procs._gwf = gwf
+			if not gwf[weapon] and rng.percent(eff.chance) then
+				gwf[weapon] = true
+				print("[ATTACK]", eff.effect_id, "callbackOnMeleeAttack triggered with weapon", weapon)
+				self.turn_procs._gwf_active = true -- safety net to prevent recursive recursion
+				self:attackTargetWith(target, weapon, damtype, mult)
+				self.turn_procs._gwf_active = nil
+			end
 		end
 	end,
 	activate = function(self, eff)