diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 3aa6cad65e49533b94a7096d1c4586aaf61cb584..857c528cd5099b2763227379802f6684cdeb8203 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -1372,33 +1372,35 @@ end
 -- Note: There can be up to a 1 tick delay in displaying log information
 function _M:displayDelayedLogDamage()
 	if not self.uiset or not self.uiset.logdisplay then return end
-	for src, tgts in pairs(self.delayed_log_damage) do
-		for target, dams in pairs(tgts) do
-			if #dams.descs > 1 then
-				game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Source# hits #Target# for %s (%0.0f total damage)%s.", table.concat(dams.descs, ", "), dams.total, dams.healing<0 and (" #LIGHT_GREEN#[%0.0f healing]#LAST#"):format(-dams.healing) or ""))
-			else
-				if dams.healing >= 0 then
-					game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Source# hits #Target# for %s damage.", table.concat(dams.descs, ", ")))
-				elseif src == target then
-					game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Source# receives %s.", table.concat(dams.descs, ", ")))
+	for real_src, psrcs in pairs(self.delayed_log_damage) do
+		for src, tgts in pairs(psrcs) do
+			for target, dams in pairs(tgts) do
+				if #dams.descs > 1 then
+					game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Source# hits #Target# for %s (%0.0f total damage)%s.", table.concat(dams.descs, ", "), dams.total, dams.healing<0 and (" #LIGHT_GREEN#[%0.0f healing]#LAST#"):format(-dams.healing) or ""))
 				else
-					game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Target# receives %s from #Source#.", table.concat(dams.descs, ", ")))
-				end
-			end
-			local rsrc = src.resolveSource and src:resolveSource() or src
-			local rtarget = target.resolveSource and target:resolveSource() or target
-			local x, y = target.x or -1, target.y or -1
-			local sx, sy = self.level.map:getTileToScreen(x, y)
-			if target.dead then
-				if dams.tgtSeen and (rsrc == self.player or rtarget == self.player or self.party:hasMember(rsrc) or self.party:hasMember(rtarget)) then
-					self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, rng.float(-2.5, -1.5), ("Kill (%d)!"):format(dams.total), {255,0,255}, true)
-					self:delayedLogMessage(target, nil,  "death", self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#{bold}##Source# killed #Target#!#{normal}#"))
+					if dams.healing >= 0 then
+						game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Source# hits #Target# for %s damage.", table.concat(dams.descs, ", ")))
+					elseif src == target then
+						game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Source# receives %s.", table.concat(dams.descs, ", ")))
+					else
+						game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Target# receives %s from #Source#.", table.concat(dams.descs, ", ")))
+					end
 				end
-			elseif dams.total > 0 or dams.healing == 0 then
-				if dams.tgtSeen and (rsrc == self.player or self.party:hasMember(rsrc)) then
-					self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, rng.float(-3, -2), tostring(-math.ceil(dams.total)), {0,255,dams.is_crit and 200 or 0}, dams.is_crit)
-				elseif dams.tgtSeen and (rtarget == self.player or self.party:hasMember(rtarget)) then
-					self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -rng.float(-3, -2), tostring(-math.ceil(dams.total)), {255,dams.is_crit and 200 or 0,0}, dams.is_crit)
+				local rsrc = real_src.resolveSource and real_src:resolveSource() or real_src
+				local rtarget = target.resolveSource and target:resolveSource() or target
+				local x, y = target.x or -1, target.y or -1
+				local sx, sy = self.level.map:getTileToScreen(x, y)
+				if target.dead then
+					if dams.tgtSeen and (rsrc == self.player or rtarget == self.player or self.party:hasMember(rsrc) or self.party:hasMember(rtarget)) then
+						self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, rng.float(-2.5, -1.5), ("Kill (%d)!"):format(dams.total), {255,0,255}, true)
+						self:delayedLogMessage(target, nil,  "death", self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#{bold}##Source# killed #Target#!#{normal}#"))
+					end
+				elseif dams.total > 0 or dams.healing == 0 then
+					if dams.tgtSeen and (rsrc == self.player or self.party:hasMember(rsrc)) then
+						self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, rng.float(-3, -2), tostring(-math.ceil(dams.total)), {0,255,dams.is_crit and 200 or 0}, dams.is_crit)
+					elseif dams.tgtSeen and (rtarget == self.player or self.party:hasMember(rtarget)) then
+						self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -rng.float(-3, -2), tostring(-math.ceil(dams.total)), {255,dams.is_crit and 200 or 0,0}, dams.is_crit)
+					end
 				end
 			end
 		end
@@ -1411,12 +1413,11 @@ end
 -- log and collate combat damage for later display with displayDelayedLogDamage
 function _M:delayedLogDamage(src, target, dam, desc, crit)
 	if not target or not src then return end
-	src = src.__project_source or src -- assign message to indirect damage source if available
+	local psrc = src.__project_source or src -- assign message to indirect damage source if available
 	local visible, srcSeen, tgtSeen = self:logVisible(src, target)
 	if visible then -- only log damage the player is aware of
-		self.delayed_log_damage[src] = self.delayed_log_damage[src] or {}
-		self.delayed_log_damage[src][target] = self.delayed_log_damage[src][target] or {total=0, healing=0, descs={}}
-		local t = self.delayed_log_damage[src][target]
+		local t = table.getTable(self.delayed_log_damage, src, psrc, target)
+		table.update(t, {total=0, healing=0, descs={}})
 		t.descs[#t.descs+1] = desc
 		if dam>=0 then
 			t.total = t.total + dam
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index 5b8366eac07c6a6c1b56a293dda9bfce4da13c71..14b2abb51f9285095e0e949c86cfa6a141c82119 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -445,11 +445,10 @@ setDefaultProjector(function(src, x, y, type, dam, state)
 		if not DamageType:get(type).hideMessage then
 			local visible, srcSeen, tgtSeen = game:logVisible(src, target)
 			if visible then -- don't log damage that the player doesn't know about
-				local source = src.__project_source or src
 				if crit_power > 1 then
-					game:delayedLogDamage(source, target, dam, ("#{bold}#%s%d %s#{normal}##LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", dam, DamageType:get(type).name), true)
+					game:delayedLogDamage(src, target, dam, ("#{bold}#%s%d %s#{normal}##LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", dam, DamageType:get(type).name), true)
 				else
-					game:delayedLogDamage(source, target, dam, ("%s%d %s#LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", dam, DamageType:get(type).name), false)
+					game:delayedLogDamage(src, target, dam, ("%s%d %s#LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", dam, DamageType:get(type).name), false)
 				end
 			end
 		end