Index: ps/trunk/binaries/data/mods/public/simulation/components/ResourceGatherer.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/ResourceGatherer.js +++ ps/trunk/binaries/data/mods/public/simulation/components/ResourceGatherer.js @@ -193,7 +193,6 @@ // drop them first to ensure we're only ever carrying one type. if (this.IsCarryingAnythingExcept(resourceType.generic)) this.DropResources(); - this.AddToPlayerCounter(resourceType.generic); let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); if (cmpVisual) @@ -227,7 +226,6 @@ let cmpResourceSupply = Engine.QueryInterface(this.target, IID_ResourceSupply); if (cmpResourceSupply) cmpResourceSupply.RemoveGatherer(this.entity); - this.RemoveFromPlayerCounter(); delete this.target; @@ -426,6 +424,13 @@ Engine.PostMessage(this.entity, MT_ResourceCarryingChanged, { "to": this.GetCarryingStatus() }); }; +/** + * @return {string} - A generic resource type if we were tasked to gather. + */ +ResourceGatherer.prototype.LastGatheredType = function() +{ + return this.lastGathered; +}; /** * @param {string} type - A generic resource type. Index: ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js +++ ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js @@ -478,6 +478,16 @@ }, "Order.Gather": function(msg) { + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + if (!cmpResourceGatherer) + return this.FinishOrder(); + + // We were given the order to gather while we were still gathering. + // This is needed because we don't re-enter the GATHER-state. + let lastGatheredType = cmpResourceGatherer.LastGatheredType(); + if (lastGatheredType && msg.data.type.generic != lastGatheredType) + this.UnitFsm.SwitchToNextState(this, "INDIVIDUAL.GATHER"); + if (!this.CanGather(msg.data.target)) { this.SetNextState("INDIVIDUAL.GATHER.FINDINGNEWTARGET"); @@ -485,20 +495,9 @@ } // If the unit is full go to the nearest dropsite instead of trying to gather. - let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); - if (cmpResourceGatherer && !cmpResourceGatherer.CanCarryMore(msg.data.type.generic)) + if (!cmpResourceGatherer.CanCarryMore(msg.data.type.generic)) { - let nearestDropsite = this.FindNearestDropsite(msg.data.type.generic); - if (nearestDropsite) - this.PushOrderFront("ReturnResource", { - "target": nearestDropsite, - "force": false, - "type": msg.data.type - }); - // Players expect the unit to move, so walk to the target instead of trying to gather. - else if (!this.FinishOrder()) - this.WalkToTarget(msg.data.target, false); - + this.SetNextState("INDIVIDUAL.GATHER.RETURNINGRESOURCE"); return ACCEPT_ORDER; } @@ -2339,7 +2338,18 @@ }, "GATHER": { + "enter": function() { + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + if (cmpResourceGatherer) + cmpResourceGatherer.AddToPlayerCounter(this.order.data.type.generic); + return false; + }, + "leave": function() { + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + if (cmpResourceGatherer) + cmpResourceGatherer.RemoveFromPlayerCounter(); + // Show the carried resource, if we've gathered anything. this.SetDefaultAnimationVariant(); }, @@ -2378,9 +2388,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; }, @@ -2397,16 +2404,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; }, }, @@ -2471,12 +2473,7 @@ }, "InventoryFilled": function(msg) { - let nearestDropsite = this.FindNearestDropsite(this.order.data.type.generic); - if (nearestDropsite) - this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); - else - this.FinishOrder(); - + this.SetNextState("RETURNINGRESOURCE"); }, "OutOfRange": function(msg) { @@ -2578,6 +2575,49 @@ return true; }, }, + + "RETURNINGRESOURCE": { + "enter": function() { + let nearestDropsite = this.FindNearestDropsite(this.order.data.type.generic); + if (!nearestDropsite) + { + // The player expects the unit to move upon failure. + let formerTarget = this.order.data.target; + if (!this.FinishOrder()) + this.WalkToTarget(formerTarget); + return true; + } + this.order.data.formerTarget = this.order.data.target; + this.order.data.target = nearestDropsite; + this.SetDefaultAnimationVariant(); + this.SetNextState("APPROACHING"); + return true; + }, + + "leave": function() { + }, + + "APPROACHING": "INDIVIDUAL.RETURNRESOURCE.APPROACHING", + + "DROPPINGRESOURCES": { + "enter": function() { + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + if (this.CanReturnResource(this.order.data.target, true, cmpResourceGatherer)) + { + cmpResourceGatherer.CommitResources(this.order.data.target); + this.SetNextState("GATHER.APPROACHING"); + } + else + this.SetNextState("RETURNINGRESOURCE"); + this.order.data.target = this.order.data.formerTarget; + + return true; + }, + + "leave": function() { + }, + }, + }, }, "HEAL": {