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 @@ -2263,9 +2263,19 @@ }, "GATHER": { + "enter": function() { + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + if (cmpResourceGatherer) + cmpResourceGatherer.AddToPlayerCounter(this.order.data.type.generic); + }, + "leave": function() { // Show the carried resource, if we've gathered anything. this.SetDefaultAnimationVariant(); + + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + if (cmpResourceGatherer) + cmpResourceGatherer.RemoveFromPlayerCounter(); }, "APPROACHING": { @@ -2294,9 +2304,6 @@ return true; } this.SetAnimationVariant("approach_" + this.order.data.type.specific); - let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); - if (cmpResourceGatherer) - cmpResourceGatherer.AddToPlayerCounter(this.order.data.type.generic); return false; }, @@ -2313,16 +2320,11 @@ if (!this.gatheringTarget) return; - // don't use ownership because this is called after a conversion/resignation - // and the ownership would be invalid then. + let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); if (cmpSupply) cmpSupply.RemoveGatherer(this.entity); - let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); - if (cmpResourceGatherer) - cmpResourceGatherer.RemoveFromPlayerCounter(); - delete this.gatheringTarget; }, }, @@ -2404,7 +2406,6 @@ this.SetDefaultAnimationVariant(); this.FaceTowardsTarget(this.order.data.target); this.SelectAnimation("gather_" + this.order.data.type.specific); - cmpResourceGatherer.AddToPlayerCounter(this.order.data.type.generic); } return false; }, @@ -2418,12 +2419,7 @@ if (cmpSupply) cmpSupply.RemoveGatherer(this.entity); - let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); - if (cmpResourceGatherer) - cmpResourceGatherer.RemoveFromPlayerCounter(); - delete this.gatheringTarget; - this.ResetAnimation(); }, @@ -2485,22 +2481,9 @@ // return to the nearest dropsite if (status.filled) { - let nearestDropsite = this.FindNearestDropsite(resourceType.generic); - if (nearestDropsite) - { - // (Keep this Gather order on the stack so we'll - // continue gathering after returning) - // However mark our target as invalid if it's exhausted, so we don't waste time - // trying to gather from it. - if (status.exhausted) - this.order.data.target = INVALID_ENTITY; - this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); - return; - } - - // Oh no, couldn't find any drop sites. Give up on gathering. - this.FinishOrder(); - return; + if (status.exhausted) + this.order.data.target = INVALID_ENTITY; + this.SetNextState("RETURNINGRESOURCE"); } if (status.exhausted) @@ -2589,6 +2572,44 @@ return true; }, }, + + "RETURNINGRESOURCE": { + "enter": function() { + let nearestDropsite = this.FindNearestDropsite(this.order.data.type.generic); + if (!nearestDropsite || + !this.MoveTo({ "target": nearestDropsite }, IID_ResourceGatherer)) + { + this.FinishOrder(); + return true; + } + this.order.data.nearestDropsite = nearestDropsite; + return false; + }, + + "leave": function() { + this.StopMoving(); + }, + + "MovementUpdate": function(msg) { + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + if (this.CheckTargetRange(this.order.data.nearestDropsite, IID_ResourceGatherer) && + this.CanReturnResource(this.order.data.nearestDropsite, true, cmpResourceGatherer)) + { + cmpResourceGatherer.CommitResources(this.order.data.nearestDropsite); + + // Stop showing the carried resource animation. + this.SetDefaultAnimationVariant(); + + this.SetNextState("APPROACHING"); + return; + } + + if (msg.obstructed) + return; + + this.SetNextState("RETURNINGRESOURCE"); + }, + }, }, "HEAL": { @@ -5511,8 +5532,8 @@ // Save the resource type now, so if the resource gets destroyed // before we process the order then we still know what resource // type to look for more of - var type; - var cmpResourceSupply = QueryMiragedInterface(target, IID_ResourceSupply); + let type; + let cmpResourceSupply = QueryMiragedInterface(target, IID_ResourceSupply); if (cmpResourceSupply) type = cmpResourceSupply.GetType(); else @@ -5520,8 +5541,8 @@ // Also save the target entity's template, so that if it's an animal, // we won't go from hunting slow safe animals to dangerous fast ones - var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); - var template = cmpTemplateManager.GetCurrentTemplateName(target); + let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); + let template = cmpTemplateManager.GetCurrentTemplateName(target); if (template.indexOf("resource|") != -1) template = template.slice(9); @@ -5535,6 +5556,12 @@ this.RememberTargetPosition(order); order.initPos = order.lastPos; + // If we were already gathering but not the same type + // re-enter the gathering state. + if (this.order && this.order.type == "Gather" && + this.order.data.type.generic != type) + this.Stop(); + this.AddOrder("Gather", order, queued); };