Cleanup of Capturable component
Comments By: wraitii, Stan, Freagarach Differential Revision: D2826 This was SVN commit r23875.
This commit is contained in:
1 parent
db90b7add8
commit
2769424407
1 file changed
+58
-51
@@ -1,19 +1,18 @@
|
||||
function Capturable() {}
|
||||
|
||||
Capturable.prototype.Schema =
|
||||
"<element name='CapturePoints' a:help='Maximum capture points'>" +
|
||||
"<element name='CapturePoints' a:help='Maximum capture points.'>" +
|
||||
"<ref name='positiveDecimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='RegenRate' a:help='Number of capture are regenerated per second in favour of the owner'>" +
|
||||
"<element name='RegenRate' a:help='Number of capture points that are regenerated per second in favour of the owner.'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='GarrisonRegenRate' a:help='Number of capture are regenerated per second and per garrisoned unit in favour of the owner'>" +
|
||||
"<element name='GarrisonRegenRate' a:help='Number of capture points that are regenerated per second and per garrisoned unit in favour of the owner.'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>";
|
||||
|
||||
Capturable.prototype.Init = function()
|
||||
{
|
||||
// Values affected by modifications in onOwnershipChanged
|
||||
this.maxCp = +this.template.CapturePoints;
|
||||
this.garrisonRegenRate = +this.template.GarrisonRegenRate;
|
||||
this.regenRate = +this.template.RegenRate;
|
||||
@@ -23,7 +22,7 @@ Capturable.prototype.Init = function()
|
||||
//// Interface functions ////
|
||||
|
||||
/**
|
||||
* Returns the current capture points array
|
||||
* Returns the current capture points array.
|
||||
*/
|
||||
Capturable.prototype.GetCapturePoints = function()
|
||||
{
|
||||
@@ -41,28 +40,37 @@ Capturable.prototype.GetGarrisonRegenRate = function()
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the new capture points, used for cloning entities
|
||||
* Set the new capture points, used for cloning entities.
|
||||
* The caller should assure that the sum of capture points
|
||||
* matches the max.
|
||||
* @param {number[]} - Array with for all players the new value.
|
||||
*/
|
||||
Capturable.prototype.SetCapturePoints = function(capturePointsArray)
|
||||
{
|
||||
this.cp = capturePointsArray;
|
||||
};
|
||||
|
||||
Capturable.prototype.Capture = function(effectData, attacker, attackerOwner, bonusMultiplier)
|
||||
/**
|
||||
* Compute the amount of capture points to be reduced and reduce them.
|
||||
* @param {number} effectData - Base number of capture points to be taken.
|
||||
* @param {number} captor - The entity capturing us.
|
||||
* @param {number} captorOwner - Owner of the captor.
|
||||
* @param {number} bonusMultiplier - Multiplier to be multiplied with effectData.
|
||||
* @return {Object} - Object of the form { "captureChange": number }, where number indicates the actual amount of capture points taken.
|
||||
*/
|
||||
Capturable.prototype.Capture = function(effectData, captor, captorOwner, bonusMultiplier)
|
||||
{
|
||||
let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
|
||||
|
||||
if (attackerOwner == INVALID_PLAYER || !this.CanCapture(attackerOwner) ||
|
||||
!cmpHealth || cmpHealth.GetHitpoints() == 0)
|
||||
let hitpoints = cmpHealth && cmpHealth.GetHitpoints();
|
||||
if (captorOwner == INVALID_PLAYER || !this.CanCapture(captorOwner) || !hitpoints)
|
||||
return {};
|
||||
|
||||
bonusMultiplier *= cmpHealth.GetMaxHitpoints() / (0.1 * cmpHealth.GetMaxHitpoints() + 0.9 * cmpHealth.GetHitpoints());
|
||||
bonusMultiplier /= 0.1 + 0.9 * hitpoints / cmpHealth.GetMaxHitpoints();
|
||||
|
||||
let total = Attacking.GetTotalAttackEffects({ "Capture": effectData }, "Capture") * bonusMultiplier;
|
||||
|
||||
let change = this.Reduce(total, attackerOwner);
|
||||
let change = this.Reduce(total, captorOwner);
|
||||
// TODO: implement loot
|
||||
|
||||
return { "captureChange": change };
|
||||
@@ -70,28 +78,30 @@ Capturable.prototype.Capture = function(effectData, attacker, attackerOwner, bon
|
||||
|
||||
/**
|
||||
* Reduces the amount of capture points of an entity,
|
||||
* in favour of the player of the source
|
||||
* Returns the number of capture points actually taken
|
||||
* in favour of the player of the source.
|
||||
* @param {number} amount - Number of capture points to be taken.
|
||||
* @param {number} playerID - ID of player the capture points should be awarded to.
|
||||
* @return {number} - The number of capture points actually taken.
|
||||
*/
|
||||
Capturable.prototype.Reduce = function(amount, playerID)
|
||||
{
|
||||
if (amount <= 0)
|
||||
return 0;
|
||||
|
||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
if (!cmpOwnership || cmpOwnership.GetOwner() == INVALID_PLAYER)
|
||||
return 0;
|
||||
|
||||
var cmpPlayerSource = QueryPlayerIDInterface(playerID);
|
||||
let cmpPlayerSource = QueryPlayerIDInterface(playerID);
|
||||
if (!cmpPlayerSource)
|
||||
return 0;
|
||||
|
||||
// Before changing the value, activate Fogging if necessary to hide changes
|
||||
var cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging);
|
||||
// Before changing the value, activate Fogging if necessary to hide changes.
|
||||
let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging);
|
||||
if (cmpFogging)
|
||||
cmpFogging.Activate();
|
||||
|
||||
var numberOfEnemies = this.cp.filter((v, i) => v > 0 && cmpPlayerSource.IsEnemy(i)).length;
|
||||
let numberOfEnemies = this.cp.filter((v, i) => v > 0 && cmpPlayerSource.IsEnemy(i)).length;
|
||||
|
||||
if (numberOfEnemies == 0)
|
||||
return 0;
|
||||
@@ -121,8 +131,8 @@ Capturable.prototype.Reduce = function(amount, playerID)
|
||||
distributedAmount = numberOfEnemies ? (amount - removedAmount) / numberOfEnemies : 0;
|
||||
}
|
||||
|
||||
// give all cp taken to the player
|
||||
var takenCp = this.maxCp - this.cp.reduce((a, b) => a + b);
|
||||
// Give all cp taken to the player.
|
||||
let takenCp = this.maxCp - this.cp.reduce((a, b) => a + b);
|
||||
this.cp[playerID] += takenCp;
|
||||
|
||||
this.CheckTimer();
|
||||
@@ -131,16 +141,18 @@ Capturable.prototype.Reduce = function(amount, playerID)
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the source can (re)capture points from this building
|
||||
* Check if the source can (re)capture points from this building.
|
||||
* @param {number} playerID - PlayerID of the source.
|
||||
* @return {boolean} - Whether the source can (re)capture points from this building.
|
||||
*/
|
||||
Capturable.prototype.CanCapture = function(playerID)
|
||||
{
|
||||
var cmpPlayerSource = QueryPlayerIDInterface(playerID);
|
||||
let cmpPlayerSource = QueryPlayerIDInterface(playerID);
|
||||
|
||||
if (!cmpPlayerSource)
|
||||
warn(playerID + " has no player component defined on its id");
|
||||
var cp = this.GetCapturePoints();
|
||||
var sourceEnemyCp = 0;
|
||||
warn(playerID + " has no player component defined on its id.");
|
||||
let cp = this.GetCapturePoints();
|
||||
let sourceEnemyCp = 0;
|
||||
for (let i in this.GetCapturePoints())
|
||||
if (cmpPlayerSource.IsEnemy(i))
|
||||
sourceEnemyCp += cp[i];
|
||||
@@ -155,27 +167,22 @@ Capturable.prototype.CanCapture = function(playerID)
|
||||
*/
|
||||
Capturable.prototype.RegisterCapturePointsChanged = function()
|
||||
{
|
||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
if (!cmpOwnership)
|
||||
return;
|
||||
|
||||
Engine.PostMessage(this.entity, MT_CapturePointsChanged, { "capturePoints": this.cp });
|
||||
|
||||
var owner = cmpOwnership.GetOwner();
|
||||
let owner = cmpOwnership.GetOwner();
|
||||
if (owner == INVALID_PLAYER || this.cp[owner] > 0)
|
||||
return;
|
||||
|
||||
// If all cp has been taken from the owner, convert it to the best player.
|
||||
var bestPlayer = 0;
|
||||
for (let i in this.cp)
|
||||
if (this.cp[i] >= this.cp[bestPlayer])
|
||||
bestPlayer = +i;
|
||||
|
||||
// If all cp has been taken from the owner, convert it to player with the most capture points.
|
||||
let cmpLostPlayerStatisticsTracker = QueryOwnerInterface(this.entity, IID_StatisticsTracker);
|
||||
if (cmpLostPlayerStatisticsTracker)
|
||||
cmpLostPlayerStatisticsTracker.LostEntity(this.entity);
|
||||
|
||||
cmpOwnership.SetOwner(bestPlayer);
|
||||
cmpOwnership.SetOwner(this.cp.reduce((bestPlayer, playerCp, player, cp) => playerCp > cp[bestPlayer] ? player : bestPlayer, 0));
|
||||
|
||||
let cmpCapturedPlayerStatisticsTracker = QueryOwnerInterface(this.entity, IID_StatisticsTracker);
|
||||
if (cmpCapturedPlayerStatisticsTracker)
|
||||
@@ -188,40 +195,40 @@ Capturable.prototype.GetRegenRate = function()
|
||||
if (!cmpGarrisonHolder)
|
||||
return this.regenRate;
|
||||
|
||||
let garrisonRegenRate = this.GetGarrisonRegenRate() * cmpGarrisonHolder.GetEntities().length;
|
||||
return this.regenRate + garrisonRegenRate;
|
||||
return this.regenRate + this.GetGarrisonRegenRate() * cmpGarrisonHolder.GetEntities().length;
|
||||
};
|
||||
|
||||
Capturable.prototype.TimerTick = function()
|
||||
{
|
||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
if (!cmpOwnership || cmpOwnership.GetOwner() == INVALID_PLAYER)
|
||||
return;
|
||||
|
||||
var owner = cmpOwnership.GetOwner();
|
||||
var modifiedCp = 0;
|
||||
let owner = cmpOwnership.GetOwner();
|
||||
let modifiedCp = 0;
|
||||
|
||||
// Special handle for the territory decay.
|
||||
// Reduce cp from the owner in favour of all neighbours (also allies).
|
||||
var cmpTerritoryDecay = Engine.QueryInterface(this.entity, IID_TerritoryDecay);
|
||||
let cmpTerritoryDecay = Engine.QueryInterface(this.entity, IID_TerritoryDecay);
|
||||
if (cmpTerritoryDecay && cmpTerritoryDecay.IsDecaying())
|
||||
{
|
||||
var neighbours = cmpTerritoryDecay.GetConnectedNeighbours();
|
||||
var totalNeighbours = neighbours.reduce((a, b) => a + b);
|
||||
var decay = Math.min(cmpTerritoryDecay.GetDecayRate(), this.cp[owner]);
|
||||
let neighbours = cmpTerritoryDecay.GetConnectedNeighbours();
|
||||
let totalNeighbours = neighbours.reduce((a, b) => a + b);
|
||||
let decay = Math.min(cmpTerritoryDecay.GetDecayRate(), this.cp[owner]);
|
||||
this.cp[owner] -= decay;
|
||||
|
||||
if (totalNeighbours)
|
||||
for (let p in neighbours)
|
||||
this.cp[p] += decay * neighbours[p] / totalNeighbours;
|
||||
else // decay to gaia as default
|
||||
// Decay to gaia as default.
|
||||
else
|
||||
this.cp[0] += decay;
|
||||
|
||||
modifiedCp += decay;
|
||||
this.RegisterCapturePointsChanged();
|
||||
}
|
||||
|
||||
var regenRate = this.GetRegenRate();
|
||||
let regenRate = this.GetRegenRate();
|
||||
if (regenRate < 0)
|
||||
modifiedCp += this.Reduce(-regenRate, 0);
|
||||
else if (regenRate > 0)
|
||||
@@ -231,9 +238,9 @@ Capturable.prototype.TimerTick = function()
|
||||
return;
|
||||
|
||||
// Nothing changed, stop the timer.
|
||||
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
cmpTimer.CancelTimer(this.timer);
|
||||
this.timer = 0;
|
||||
delete this.timer;
|
||||
Engine.PostMessage(this.entity, MT_CaptureRegenStateChanged, { "regenerating": false, "regenRate": 0, "territoryDecay": 0 });
|
||||
};
|
||||
|
||||
@@ -271,7 +278,7 @@ Capturable.prototype.UpdateCachedValues = function()
|
||||
/**
|
||||
* Update all chached values that could be affected by modifications.
|
||||
* Check timer and send changed messages when required.
|
||||
* @param {boolean} dontSendCpChanged - when true, caller will take care of sending that message
|
||||
* @param {boolean} dontSendCpChanged - Whether not to send a CapturePointsChanged message. When true, caller should take care of sending that message.
|
||||
*/
|
||||
Capturable.prototype.UpdateCachedValuesAndNotify = function(dontSendCpChanged = false)
|
||||
{
|
||||
@@ -321,7 +328,7 @@ Capturable.prototype.OnDiplomacyChanged = function(msg)
|
||||
Capturable.prototype.OnOwnershipChanged = function(msg)
|
||||
{
|
||||
if (msg.to == INVALID_PLAYER)
|
||||
return; // we're dead
|
||||
return;
|
||||
|
||||
// Initialise the capture points when created.
|
||||
if (!this.cp.length)
|
||||
@@ -339,8 +346,8 @@ Capturable.prototype.OnOwnershipChanged = function(msg)
|
||||
return;
|
||||
}
|
||||
|
||||
// Was already initialised, this happens on defeat or wololo
|
||||
// transfer the points of the old owner to the new one
|
||||
// When already initialised, this happens on defeat or wololo,
|
||||
// transfer the points of the old owner to the new one.
|
||||
if (this.cp[msg.from])
|
||||
{
|
||||
this.cp[msg.to] += this.cp[msg.from];
|
||||
|
||||
Reference in new issue
Block a user