Index: binaries/data/mods/public/simulation/components/Capturable.js =================================================================== --- binaries/data/mods/public/simulation/components/Capturable.js +++ binaries/data/mods/public/simulation/components/Capturable.js @@ -1,19 +1,18 @@ function Capturable() {} Capturable.prototype.Schema = - "" + + "" + "" + "" + - "" + + "" + "" + "" + - "" + + "" + "" + ""; 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 @@ //// Interface functions //// /** - * Returns the current capture points array + * Returns the current capture points array. */ Capturable.prototype.GetCapturePoints = function() { @@ -41,28 +40,37 @@ }; /** - * 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 the new values. */ 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 @@ /** * 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 @@ 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 @@ }; /** - * 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.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 @@ 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 @@ 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 @@ /** * 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.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 @@ 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];