Index: binaries/data/mods/public/simulation/components/GarrisonHolder.js =================================================================== --- binaries/data/mods/public/simulation/components/GarrisonHolder.js +++ binaries/data/mods/public/simulation/components/GarrisonHolder.js @@ -505,7 +505,9 @@ GarrisonHolder.prototype.HasEnoughHealth = function() { let cmpHealth = Engine.QueryInterface(this.entity, IID_Health); - return cmpHealth.GetHitpoints() > Math.floor(+this.template.EjectHealth * cmpHealth.GetMaxHitpoints()); + if (cmpHealth) + return cmpHealth.GetHitpoints() > Math.floor(+this.template.EjectHealth * cmpHealth.GetMaxHitpoints()); + return true; }; /** Index: binaries/data/mods/public/simulation/components/ResourceSupply.js =================================================================== --- binaries/data/mods/public/simulation/components/ResourceSupply.js +++ binaries/data/mods/public/simulation/components/ResourceSupply.js @@ -25,6 +25,11 @@ "" + "" + "" + + "" + + "" + + "" + + "" + + "" + ""; ResourceSupply.prototype.Init = function() @@ -42,6 +47,15 @@ this.cachedType = { "generic": type, "specific": subtype }; }; +ResourceSupply.prototype.IsMine = function() +{ + let cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); + if (!cmpGarrisonHolder) + return false; + + return this.template.Mine && this.template.Mine == "true"; +}; + ResourceSupply.prototype.IsInfinite = function() { return !isFinite(+this.template.Amount); 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 @@ -2216,6 +2216,17 @@ { this.StopMoving(); this.SetDefaultAnimationVariant(); + + if (cmpSupply.IsMine()) + { + let cmpGarrisonHolder = Engine.QueryInterface(this.gatheringTarget, IID_GarrisonHolder); + if (!cmpGarrisonHolder || !cmpGarrisonHolder.Garrison(this.entity)) + { + this.FinishOrder(); + return true; + } + this.isGarrisoned = true; + } this.FaceTowardsTarget(this.order.data.target); this.SelectAnimation("gather_" + this.order.data.type.specific); } @@ -2259,7 +2270,7 @@ return; } - if (!this.CheckTargetRange(this.gatheringTarget, IID_ResourceGatherer)) + if (!this.CheckTargetRange(this.gatheringTarget, IID_ResourceGatherer) && !cmpSupply.IsMine()) { // Try to follow the target if (this.MoveToTargetRange(this.gatheringTarget, IID_ResourceGatherer)) @@ -2299,6 +2310,12 @@ // return to the nearest dropsite if (status.filled) { + if (cmpSupply.IsMine()) + { + let cmpGarrisonHolder = Engine.QueryInterface(this.gatheringTarget, IID_GarrisonHolder); + if (cmpGarrisonHolder && !cmpGarrisonHolder.Unload(this.entity)) + return; + } let nearby = this.FindNearestDropsite(resourceType.generic); if (nearby) { @@ -2319,7 +2336,15 @@ // Find a new target if the current one is exhausted if (status.exhausted) + { + if (cmpSupply.IsMine()) + { + let cmpGarrisonHolder = Engine.QueryInterface(this.gatheringTarget, IID_GarrisonHolder); + if (cmpGarrisonHolder && !cmpGarrisonHolder.Unload(this.entity)) + return; + } this.SetNextState("FINDINGNEWTARGET"); + } }, }, @@ -5781,8 +5806,6 @@ UnitAI.prototype.CanGather = function(target) { - if (this.IsTurret()) - return false; // The target must be a valid resource supply, or the mirage of one. var cmpResourceSupply = QueryMiragedInterface(target, IID_ResourceSupply); if (!cmpResourceSupply) Index: binaries/data/mods/public/simulation/templates/template_gaia_geo_rock.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_gaia_geo_rock.xml +++ binaries/data/mods/public/simulation/templates/template_gaia_geo_rock.xml @@ -1,5 +1,18 @@ + + 12 + 0 + Unit + Worker + 0 + 1 + + + 011.50 + + + Stone Quarry Quarry rock for stone. @@ -14,6 +27,7 @@ 1000 stone.rock 12 + true