Index: binaries/data/mods/public/simulation/components/Foundation.js =================================================================== --- binaries/data/mods/public/simulation/components/Foundation.js +++ binaries/data/mods/public/simulation/components/Foundation.js @@ -75,6 +75,16 @@ return Math.floor(this.GetBuildProgress() * 100); }; +/** + * Returns the current builders. + * + * @return {number[]} - An array containing the entity IDs of assigned builders. + */ +Foundation.prototype.GetBuilders = function() +{ + return Array.from(this.builders.keys()); +}; + Foundation.prototype.GetNumBuilders = function() { return this.builders.size; @@ -117,9 +127,26 @@ }; /** - * Adds a builder to the counter. + * Adds an array of builders. + * + * @param {number[]} builders - An array containing the entity IDs of builders to assign. */ -Foundation.prototype.AddBuilder = function(builderEnt) +Foundation.prototype.AddBuilders = function(builders) +{ + for (let builder of builders) + this.AddSingleBuilder(builder); + + Engine.PostMessage(this.entity, MT_FoundationBuildersChanged, { "to": Array.from(this.builders.keys()) }); +}; + +/** + * Adds a single builder to this entity. + * Split because adding multiple builders can reuse the functionality + * but still send but one message. + * + * @param {number} builderEnt - The entity to add. + */ +Foundation.prototype.AddSingleBuilder = function(builderEnt) { if (this.builders.has(builderEnt)) return; @@ -131,7 +158,14 @@ let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); if (cmpVisual) cmpVisual.SetVariable("numbuilders", this.builders.size); +} +/** + * Adds a builder to the counter. + */ +Foundation.prototype.AddBuilder = function(builderEnt) +{ + this.AddSingleBuilder(builderEnt); Engine.PostMessage(this.entity, MT_FoundationBuildersChanged, { "to": Array.from(this.builders.keys()) }); }; Index: binaries/data/mods/public/simulation/components/Repairable.js =================================================================== --- binaries/data/mods/public/simulation/components/Repairable.js +++ binaries/data/mods/public/simulation/components/Repairable.js @@ -33,11 +33,32 @@ return hitpoints / maxHitpoints; }; +/** + * Returns the current builders. + * + * @return {number[]} - An array containing the entity IDs of assigned builders. + */ +Repairable.prototype.GetBuilders = function() +{ + return Array.from(this.builders.keys()); +}; + Repairable.prototype.GetNumBuilders = function() { return this.builders.size; }; +/** + * Adds an array of builders. + * + * @param {number[]} - An array containing the entity IDs of builders to assign. + */ +Repairable.prototype.AddBuilders = function(builders) +{ + for (let builder of builders) + this.AddBuilder(builder); +} + Repairable.prototype.AddBuilder = function(builderEnt) { if (this.builders.has(builderEnt)) Index: binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- binaries/data/mods/public/simulation/components/UnitAI.js +++ binaries/data/mods/public/simulation/components/UnitAI.js @@ -2748,11 +2748,13 @@ this.order.data.force = false; - this.repairTarget = this.order.data.target; // temporary, deleted in "leave". - // Check we can still reach and repair the target + // Needed to remove the entity from the builder list when leaving this state. + this.repairTarget = this.order.data.target; + + // Check we can still reach and repair the target. if (!this.CanRepair(this.repairTarget)) { - // Can't reach it, no longer owned by ally, or it doesn't exist any more + // Can't reach it, no longer owned by ally, or it doesn't exist any more. this.FinishOrder(); return true; } @@ -2762,8 +2764,8 @@ this.SetNextState("APPROACHING"); return true; } - // Check if the target is still repairable - var cmpHealth = Engine.QueryInterface(this.repairTarget, IID_Health); + // Check if the target is still repairable. + let cmpHealth = Engine.QueryInterface(this.repairTarget, IID_Health); if (cmpHealth && cmpHealth.GetHitpoints() >= cmpHealth.GetMaxHitpoints()) { // The building was already finished/fully repaired before we arrived; @@ -2778,7 +2780,7 @@ if (cmpBuilderList) cmpBuilderList.AddBuilder(this.entity); - this.FaceTowardsTarget(this.order.data.target); + this.FaceTowardsTarget(this.repairTarget); this.SelectAnimation("build"); this.StartTimer(1000, 1000); @@ -2795,21 +2797,21 @@ }, "Timer": function(msg) { - // Check we can still reach and repair the target + // Check we can still reach and repair the target. if (!this.CanRepair(this.repairTarget)) { - // No longer owned by ally, or it doesn't exist any more + // No longer owned by ally, or it doesn't exist any more. this.FinishOrder(); return; } - this.FaceTowardsTarget(this.order.data.target); + this.FaceTowardsTarget(this.repairTarget); let cmpBuilder = Engine.QueryInterface(this.entity, IID_Builder); cmpBuilder.PerformBuilding(this.repairTarget); - // if the building is completed, the leave() function will be called - // by the ConstructionFinished message - // in that case, the repairTarget is deleted, and we can just return + // If the building is completed, the leave() function will be called + // by the ConstructionFinished message. + // In that case, the repairTarget is deleted, and we can just return. if (!this.repairTarget) return; if (!this.CheckTargetRange(this.repairTarget, IID_Builder)) @@ -4084,6 +4086,12 @@ order.data.formationTarget = msg.newentity; } } + if (this.repairTarget && this.repairTarget == msg.entity) + { + this.repairTarget = msg.newentity; + changed = true; + } + if (changed) Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); }; Index: binaries/data/mods/public/simulation/components/tests/test_Pack.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_Pack.js +++ binaries/data/mods/public/simulation/components/tests/test_Pack.js @@ -4,12 +4,14 @@ Engine.LoadHelperScript("ValueModification.js"); Engine.LoadComponentScript("interfaces/ModifiersManager.js"); Engine.LoadComponentScript("interfaces/Capturable.js"); +Engine.LoadComponentScript("interfaces/Foundation.js"); Engine.LoadComponentScript("interfaces/GarrisonHolder.js"); Engine.LoadComponentScript("interfaces/Guard.js"); Engine.LoadComponentScript("interfaces/Health.js"); Engine.LoadComponentScript("interfaces/Pack.js"); Engine.LoadComponentScript("interfaces/Player.js"); Engine.LoadComponentScript("interfaces/Promotion.js"); +Engine.LoadComponentScript("interfaces/Repairable.js"); Engine.LoadComponentScript("interfaces/ResourceGatherer.js"); Engine.LoadComponentScript("interfaces/Timer.js"); Engine.LoadComponentScript("interfaces/UnitAI.js"); Index: binaries/data/mods/public/simulation/helpers/Transform.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Transform.js +++ binaries/data/mods/public/simulation/helpers/Transform.js @@ -53,6 +53,11 @@ cmpNewHealth.SetHitpoints(cmpNewHealth.GetMaxHitpoints() * healthLevel); } + let cmpBuilderList = QueryBuilderListInterface(oldEnt); + let cmpNewBuilderList = QueryBuilderListInterface(newEnt); + if (cmpBuilderList && cmpNewBuilderList) + cmpNewBuilderList.AddBuilders(cmpBuilderList.GetBuilders()); + var cmpUnitAI = Engine.QueryInterface(oldEnt, IID_UnitAI); var cmpNewUnitAI = Engine.QueryInterface(newEnt, IID_UnitAI); if (cmpUnitAI && cmpNewUnitAI)