Index: ps/trunk/binaries/data/mods/public/simulation/components/Capturable.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Capturable.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Capturable.js @@ -76,7 +76,7 @@ if (numberOfEnemies == 0) return 0; - // distribute the capture points over all enemies + // Distribute the capture points over all enemies. let distributedAmount = amount / numberOfEnemies; let removedAmount = 0; while (distributedAmount > 0.0001) @@ -130,8 +130,8 @@ //// Private functions //// /** - * this has to be called whenever the capture points are changed. - * It notifies other components of the change, and switches ownership when needed + * This has to be called whenever the capture points are changed. + * It notifies other components of the change, and switches ownership when needed. */ Capturable.prototype.RegisterCapturePointsChanged = function() { @@ -145,7 +145,7 @@ if (owner == INVALID_PLAYER || this.cp[owner] > 0) return; - // if all cp has been taken from the owner, convert it to the best player + // 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]) @@ -185,8 +185,8 @@ var owner = cmpOwnership.GetOwner(); var modifiedCp = 0; - // special handle for the territory decay - // reduce cp from the owner in favour of all neighbours (also allies) + // 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); if (cmpTerritoryDecay && cmpTerritoryDecay.IsDecaying()) { @@ -214,7 +214,7 @@ if (modifiedCp) return; - // nothing changed, stop the timer + // Nothing changed, stop the timer. var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); cmpTimer.CancelTimer(this.timer); this.timer = 0; @@ -295,7 +295,7 @@ } else { - // initialise the capture points when created + // Initialise the capture points when created. let numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers(); for (let i = 0; i < numPlayers; ++i) if (i == msg.to) @@ -306,4 +306,21 @@ this.CheckTimer(); }; +/** + * When a player is defeated, reassign the cp of non-owned entities to gaia. + * Those owned by the defeated player are dealt with onOwnershipChanged. + */ +Capturable.prototype.OnPlayerDefeated = function(msg) +{ + if (!this.cp[msg.playerId]) + return; + let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); + if (cmpOwnership && cmpOwnership.GetOwner() == msg.playerId) + return; + this.cp[0] += this.cp[msg.playerId]; + this.cp[msg.playerId] = 0; + this.RegisterCapturePointsChanged(); + this.CheckTimer(); +}; + Engine.RegisterComponentType(IID_Capturable, "Capturable", Capturable); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Capturable.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Capturable.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Capturable.js @@ -14,7 +14,7 @@ "structure": 20, "playerID": 1, "regenRate": 2, - "garrisonedEntities": [30,31,32,33], + "garrisonedEntities": [30, 31, 32, 33], "garrisonRegenRate": 5, "decay": false, "decayRate": 30, @@ -66,14 +66,14 @@ }); AddMock(testData.structure, IID_StatisticsTracker, { - "LostEntity" : () => {}, + "LostEntity": () => {}, "CapturedBuilding": () => {} }); let cmpCapturable = ConstructComponent(testData.structure, "Capturable", { - "CapturePoints" : testData.maxCp, - "RegenRate" : testData.regenRate, - "GarrisonRegenRate" : testData.garrisonRegenRate + "CapturePoints": testData.maxCp, + "RegenRate": testData.regenRate, + "GarrisonRegenRate": testData.garrisonRegenRate }); AddMock(testData.structure, IID_TerritoryDecay, { @@ -90,7 +90,7 @@ // Tests initialisation of the capture points when the entity is created testCapturable(testData, cmpCapturable => { Engine.PostMessage = function(ent, iid, message) { - TS_ASSERT_UNEVAL_EQUALS(message, { "regenerating": true, "regenRate": cmpCapturable.GetRegenRate() , "territoryDecay": 0 }); + TS_ASSERT_UNEVAL_EQUALS(message, { "regenerating": true, "regenRate": cmpCapturable.GetRegenRate(), "territoryDecay": 0 }); }; cmpCapturable.OnOwnershipChanged({ "from": INVALID_PLAYER, "to": testData.playerID }); TS_ASSERT_UNEVAL_EQUALS(cmpCapturable.GetCapturePoints(), [0, 3000, 0, 0]); @@ -99,17 +99,17 @@ // Tests if the message is sent when capture points change testCapturable(testData, cmpCapturable => { cmpCapturable.SetCapturePoints([0, 2000, 0 , 1000]); - TS_ASSERT_UNEVAL_EQUALS(cmpCapturable.GetCapturePoints(), [0, 2000, 0 , 1000]); + TS_ASSERT_UNEVAL_EQUALS(cmpCapturable.GetCapturePoints(), [0, 2000, 0, 1000]); Engine.PostMessage = function(ent, iid, message) { - TS_ASSERT_UNEVAL_EQUALS(message, { "capturePoints": [0, 2000, 0 , 1000] }); + TS_ASSERT_UNEVAL_EQUALS(message, { "capturePoints": [0, 2000, 0, 1000] }); }; cmpCapturable.RegisterCapturePointsChanged(); }); // Tests reducing capture points (after a capture attack or a decay) testCapturable(testData, cmpCapturable => { - cmpCapturable.SetCapturePoints([0, 2000, 0 , 1000]); + cmpCapturable.SetCapturePoints([0, 2000, 0, 1000]); cmpCapturable.CheckTimer(); Engine.PostMessage = function(ent, iid, message) { if (iid == MT_CapturePointsChanged) @@ -123,9 +123,9 @@ // Tests reducing capture points (after a capture attack or a decay) testCapturable(testData, cmpCapturable => { - cmpCapturable.SetCapturePoints([0, 2000, 0 , 1000]); + cmpCapturable.SetCapturePoints([0, 2000, 0, 1000]); cmpCapturable.CheckTimer(); - TS_ASSERT_EQUALS(cmpCapturable.Reduce(2500, 3),2000); + TS_ASSERT_EQUALS(cmpCapturable.Reduce(2500, 3), 2000); TS_ASSERT_UNEVAL_EQUALS(cmpCapturable.GetCapturePoints(), [0, 0, 0, 3000]); }); @@ -144,7 +144,7 @@ } // With our testData, the total regen rate is 22. That should be taken from the ennemies -testRegen(testData, [12, 2950, 2 , 36], [1, 2972, 2, 25], true); +testRegen(testData, [12, 2950, 2, 36], [1, 2972, 2, 25], true); testRegen(testData, [0, 2994, 2, 4], [0, 2998, 2, 0], true); testRegen(testData, [0, 2998, 2, 0], [0, 2998, 2, 0], false); @@ -176,7 +176,7 @@ function testReduce(testData, amount, player, taken) { testCapturable(testData, cmpCapturable => { - cmpCapturable.SetCapturePoints([0, 2000, 0 , 1000]); + cmpCapturable.SetCapturePoints([0, 2000, 0, 1000]); cmpCapturable.CheckTimer(); TS_ASSERT_UNEVAL_EQUALS(cmpCapturable.Reduce(amount, player), taken); }); @@ -191,3 +191,10 @@ testReduce(testData, 1500, 3, 1500); testReduce(testData, 2000, 3, 2000); testReduce(testData, 3000, 3, 2000); + +// Test defeated player +testCapturable(testData, cmpCapturable => { + cmpCapturable.SetCapturePoints([500, 1000, 0, 250]); + cmpCapturable.OnPlayerDefeated({ "playerId": 3 }); + TS_ASSERT_UNEVAL_EQUALS(cmpCapturable.GetCapturePoints(), [750, 1000, 0, 0]); +});