Index: ps/trunk/binaries/data/mods/public/simulation/components/AttackDetection.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/AttackDetection.js (revision 19153)
+++ ps/trunk/binaries/data/mods/public/simulation/components/AttackDetection.js (revision 19154)
@@ -1,160 +1,160 @@
function AttackDetection() {}
AttackDetection.prototype.Schema =
"Detects incoming attacks." +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"" +
"";
AttackDetection.prototype.Init = function()
{
this.suppressionTime = +this.template.SuppressionTime;
// Use squared distance to avoid sqrts
this.suppressionTransferRangeSquared = +this.template.SuppressionTransferRange * +this.template.SuppressionTransferRange;
this.suppressionRangeSquared = +this.template.SuppressionRange * +this.template.SuppressionRange;
this.suppressedList = [];
};
AttackDetection.prototype.ActivateTimer = function()
{
Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).SetTimeout(this.entity, IID_AttackDetection, "HandleTimeout", this.suppressionTime);
};
AttackDetection.prototype.AddSuppression = function(event)
{
this.suppressedList.push(event);
this.ActivateTimer();
};
AttackDetection.prototype.UpdateSuppressionEvent = function(index, event)
{
this.suppressedList[index] = event;
this.ActivateTimer();
};
//// Message handlers ////
AttackDetection.prototype.OnGlobalAttacked = function(msg)
{
var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
var cmpOwnership = Engine.QueryInterface(msg.target, IID_Ownership);
if (cmpOwnership.GetOwner() != cmpPlayer.GetPlayerID())
return;
Engine.PostMessage(msg.target, MT_MinimapPing);
this.AttackAlert(msg.target, msg.attacker, msg.attackerOwner);
};
//// External interface ////
AttackDetection.prototype.AttackAlert = function(target, attacker, attackerOwner)
{
let playerID = Engine.QueryInterface(this.entity, IID_Player).GetPlayerID();
// Don't register attacks dealt against other players
if (Engine.QueryInterface(target, IID_Ownership).GetOwner() != playerID)
return;
let cmpAttackerOwnership = Engine.QueryInterface(attacker, IID_Ownership);
let atkOwner = cmpAttackerOwnership && cmpAttackerOwnership.GetOwner() != -1 ? cmpAttackerOwnership.GetOwner() : attackerOwner;
// Don't register attacks dealt by myself
if (atkOwner == playerID)
return;
// Since livestock can be attacked/gathered by other players
// and generally are not so valuable as other units/buildings,
// we have a lower priority notification for it, which can be
// 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 event = {
"target": target,
"position": cmpPosition.GetPosition(),
"time": Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).GetTime(),
"targetIsDomesticAnimal": targetIsDomesticAnimal
};
// 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];
// If the new attack is within suppression distance of this element,
// then check if the element should be updated and return
- var dist = element.position.horizDistanceToSquared(event.position);
+ var dist = event.position.horizDistanceToSquared(element.position);
if (dist >= this.suppressionRangeSquared)
continue;
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;
}
// 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": playerID, "event": event });
Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface).PushNotification({
"type": "attack",
"target": target,
"players": [playerID],
"attacker": atkOwner,
"targetIsDomesticAnimal": targetIsDomesticAnimal
});
PlaySound("attacked", target);
};
AttackDetection.prototype.GetSuppressionTime = function()
{
return this.suppressionTime;
};
AttackDetection.prototype.HandleTimeout = function()
{
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
var now = cmpTimer.GetTime();
for (var i = 0; i < this.suppressedList.length; ++i)
{
var event = this.suppressedList[i];
// Check if this event has timed out
if (now - event.time >= this.suppressionTime)
{
this.suppressedList.splice(i, 1);
return;
}
}
};
AttackDetection.prototype.GetIncomingAttacks = function()
{
return this.suppressedList;
};
Engine.RegisterComponentType(IID_AttackDetection, "AttackDetection", AttackDetection);