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; 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,6 +33,16 @@ 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; 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 @@ -2687,11 +2687,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; } @@ -2701,8 +2703,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; @@ -2717,7 +2719,7 @@ if (cmpBuilderList) cmpBuilderList.AddBuilder(this.entity); - this.FaceTowardsTarget(this.order.data.target); + this.FaceTowardsTarget(this.repairTarget); this.SelectAnimation("build"); this.StartTimer(1000, 1000); @@ -2734,21 +2736,24 @@ }, "Timer": function(msg) { - // 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)) { - // 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)) 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,12 @@ cmpNewHealth.SetHitpoints(cmpNewHealth.GetMaxHitpoints() * healthLevel); } + let cmpBuilderList = QueryBuilderListInterface(oldEnt); + let cmpNewBuilderList = QueryBuilderListInterface(newEnt); + if (cmpBuilderList && cmpNewBuilderList) + for (let builder of cmpBuilderList.GetBuilders()) + cmpNewBuilderList.AddBuilder(builder); + var cmpUnitAI = Engine.QueryInterface(oldEnt, IID_UnitAI); var cmpNewUnitAI = Engine.QueryInterface(newEnt, IID_UnitAI); if (cmpUnitAI && cmpNewUnitAI)