Index: binaries/data/mods/public/gui/session/messages.js
===================================================================
--- binaries/data/mods/public/gui/session/messages.js	(revision 16653)
+++ binaries/data/mods/public/gui/session/messages.js	(working copy)
@@ -119,7 +119,8 @@
 		addChatMessage({
 			"type": "attack",
 			"player": player,
-			"attacker": notification.attacker
+			"attacker": notification.attacker,
+			"targetIsDomesticAnimal": notification.targetIsDomesticAnimal
 		});
 	},
 	"dialog": function(notification, player)
@@ -511,7 +512,13 @@
 			return;
 
 		[username, playerColor] = getUsernameAndColor(msg.attacker);
-		formatted = sprintf(translate("You have been attacked by %(attacker)s!"), { attacker: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
+		// Since livestock can be attacked/gathered by allied players,
+		// we display a more specific notification in this case to not confuse the player
+		if (msg.targetIsDomesticAnimal)
+			var message = translate("Your livestock have been attacked by %(attacker)s!");
+		else
+			var message = translate("You have been attacked by %(attacker)s!");
+		formatted = sprintf(message, { attacker: "[color=\"" + playerColor + "\"]" + username + "[/color]" });
 		break;
 	case "message":
 		// May have been hidden by the 'team' command.
Index: binaries/data/mods/public/simulation/components/AttackDetection.js
===================================================================
--- binaries/data/mods/public/simulation/components/AttackDetection.js	(revision 16653)
+++ binaries/data/mods/public/simulation/components/AttackDetection.js	(working copy)
@@ -22,12 +22,22 @@
 	this.suppressedList = [];
 };
 
+AttackDetection.prototype.ActivateTimer = function(event)
+{
+	var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+	cmpTimer.SetTimeout(this.entity, IID_AttackDetection, "HandleTimeout", this.suppressionTime);
+};
+
 AttackDetection.prototype.AddSuppression = function(event)
 {
 	this.suppressedList.push(event);
+	this.ActivateTimer();
+};
 
-	var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
-	cmpTimer.SetTimeout(this.entity, IID_AttackDetection, "HandleTimeout", this.suppressionTime);
+AttackDetection.prototype.UpdateSuppressionEvent = function(index, event)
+{
+	this.suppressedList[index] = event;
+	this.ActivateTimer();
 };
 
 //// Message handlers ////
@@ -53,14 +63,30 @@
 	// Don't register attacks dealt by myself
 	if (cmpAttackerOwnership.GetOwner() == cmpPlayer.GetPlayerID())
 		return;
+		
+	// Since livestock can be attacked/gathered by allied players
+	// and generally not so valuable as other units/buildings,
+	// we have a lower priority notification for it, which can be
+	// later overriden by a regular one.
+	var cmpTargetIdentity = Engine.QueryInterface(target, IID_Identity); 
+	var targetIsDomesticAnimal = cmpTargetIdentity && cmpTargetIdentity.HasClass("Animal") && cmpTargetIdentity.HasClass("Domestic");
 
 	var cmpPosition = Engine.QueryInterface(target, IID_Position);
 	if (!cmpPosition || !cmpPosition.IsInWorld())
 		return;
 	var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
-	var event = {target: target, position: cmpPosition.GetPosition(), time: cmpTimer.GetTime()};
+	var event = {
+		"target": target,
+		"position": cmpPosition.GetPosition(),
+		"time": cmpTimer.GetTime(),
+		"targetIsDomesticAnimal": targetIsDomesticAnimal
+	};
 
-	for (var i = 0; i < this.suppressedList.length; i++)
+	// If we already have a low priority livestock event in suppressed list,
+	// and now a more important target is attacked, we want to upgrade the
+	// suppressed event and send the new notification
+	var isPriorityIncreased = false;
+	for (var i = 0; i < this.suppressedList.length; ++i)
 	{
 		var element = this.suppressedList[i];
 
@@ -69,16 +95,33 @@
 		var dist = SquaredDistance(element.position, event.position);
 		if (dist < this.suppressionRangeSquared)
 		{
-			if (dist < this.suppressionTransferRangeSquared)
-				element = event;
+			isPriorityIncreased = element.targetIsDomesticAnimal && !targetIsDomesticAnimal;
+			var isPriorityDescreased = !element.targetIsDomesticAnimal && targetIsDomesticAnimal;
+
+			if (isPriorityIncreased
+				|| (!isPriorityDescreased && dist < this.suppressionTransferRangeSquared))
+				this.UpdateSuppressionEvent(i, event);
+
+			// If priority has increased, exit the loop to send the upgraded notification below
+			if (isPriorityIncreased)
+				break;
+
 			return;
 		}
 	}
 
-	this.AddSuppression(event);
+	// If priority has increased for an existing event, then we already have it
+	// in the suppression list
+	if (!isPriorityIncreased)
+		this.AddSuppression(event);
 	Engine.PostMessage(this.entity, MT_AttackDetected, { "player": cmpPlayer.GetPlayerID(), "event": event });
 	var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
-	cmpGuiInterface.PushNotification({"type": "attack", "players": [cmpPlayer.GetPlayerID()], "attacker": cmpAttackerOwnership.GetOwner() });
+	cmpGuiInterface.PushNotification({
+		"type": "attack",
+		"players": [cmpPlayer.GetPlayerID()],
+		"attacker": cmpAttackerOwnership.GetOwner(),
+		"targetIsDomesticAnimal": targetIsDomesticAnimal
+	});
 	PlaySound("attacked", target);
 };
 
@@ -91,7 +134,7 @@
 {
 	var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
 	var now = cmpTimer.GetTime();
-	for (var i = 0; i < this.suppressedList.length; i++)
+	for (var i = 0; i < this.suppressedList.length; ++i)
 	{
 		var event = this.suppressedList[i];
 
@@ -99,7 +142,6 @@
 		if (now - event.time >= this.suppressionTime)
 		{
 			this.suppressedList.splice(i, 1);
-			i--;
 			return;
 		}
 	}
