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 @@ -529,6 +529,7 @@ } this.RememberTargetPosition(); + this.order.data.initPos = this.order.data.lastPos; if (this.CheckTargetRange(this.order.data.target, IID_ResourceGatherer)) this.SetNextState("INDIVIDUAL.GATHER.GATHERING"); @@ -2059,12 +2060,13 @@ this.SetNextState("GATHERING"); return true; } + this.SelectAnimation("move"); return false; }, "MovementUpdate": function(msg) { - // If we failed, the GATHERING timer will handle finding a valid resource. + // The GATHERING timer will handle finding a valid resource. this.SetNextState("GATHERING"); }, @@ -2100,7 +2102,8 @@ "MovementUpdate": function(msg) { // If we failed, the GATHERING timer will handle finding a valid resource. - this.SetNextState("GATHERING"); + if (msg.error || this.CheckRange(this.order.data)) + this.SetNextState("GATHERING"); }, }, @@ -2181,22 +2184,21 @@ }, "Timer": function(msg) { - var resourceTemplate = this.order.data.template; - var resourceType = this.order.data.type; + let resourceTemplate = this.order.data.template; + let resourceType = this.order.data.type; - var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); + let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); if (!cmpOwnership) return; - var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); + let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); if (cmpSupply && cmpSupply.IsAvailable(cmpOwnership.GetOwner(), this.entity)) - { // Check we can still reach and gather from the target if (this.CheckTargetRange(this.gatheringTarget, IID_ResourceGatherer) && this.CanGather(this.gatheringTarget)) { // Gather the resources: - var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); // Try to gather treasure if (cmpResourceGatherer.TryInstantGather(this.gatheringTarget)) @@ -2208,13 +2210,13 @@ cmpResourceGatherer.DropResources(); // Collect from the target - var status = cmpResourceGatherer.PerformGather(this.gatheringTarget); + let status = cmpResourceGatherer.PerformGather(this.gatheringTarget); // If we've collected as many resources as possible, // return to the nearest dropsite if (status.filled) { - var nearby = this.FindNearestDropsite(resourceType.generic); + let nearby = this.FindNearestDropsite(resourceType.generic); if (nearby) { // (Keep this Gather order on the stack so we'll @@ -2253,15 +2255,14 @@ return; } } - } // We're already in range, can't get anywhere near it or the target is exhausted. - var herdPos = this.order.data.initPos; + let herdPos = this.order.data.initPos; // Give up on this order and try our next queued order // but first check what is our next order and, if needed, insert a returnResource order - var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); if (cmpResourceGatherer.IsCarrying(resourceType.generic) && this.orderQueue.length > 1 && this.orderQueue[1] !== "ReturnResource" && (this.orderQueue[1].type !== "Gather" || this.orderQueue[1].data.type.generic !== resourceType.generic)) @@ -2277,13 +2278,14 @@ // Try to find a new resource of the same specific type near our current position: // Also don't switch to a different type of huntable animal - var nearby = this.FindNearbyResource(function(ent, type, template) { + let nearby = this.FindNearbyResource(function(ent, type, template) { return ( - (type.generic == "treasure" && resourceType.generic == "treasure") - || (type.specific == resourceType.specific - && (type.specific != "meat" || resourceTemplate == template)) + (type.generic == "treasure" && resourceType.generic == "treasure") || + (type.specific == resourceType.specific && + (type.specific != "meat" || resourceTemplate == template)) ); - }); + }, new Vector2D(herdPos.x, herdPos.z)); + if (nearby) { this.PerformGather(nearby, false, false); @@ -2301,7 +2303,7 @@ // drop it off, and if not then we might as well head to the dropsite // anyway because that's a nice enough place to congregate and idle - var nearby = this.FindNearestDropsite(resourceType.generic); + nearby = this.FindNearestDropsite(resourceType.generic); if (nearby) { this.PushOrderFront("ReturnResource", { "target": nearby, "force": false }); @@ -2640,16 +2642,16 @@ return; // ignore other buildings // Save the current order's data in case we need it later - var oldData = this.order.data; + let oldData = this.order.data; // Save the current state so we can continue walking if necessary // FinishOrder() below will switch to IDLE if there's no order, which sets the idle animation. // Idle animation while moving towards finished construction looks weird (ghosty). - var oldState = this.GetCurrentState(); + let oldState = this.GetCurrentState(); // Drop any resource we can if we are in range when the construction finishes - var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); - var cmpResourceDropsite = Engine.QueryInterface(msg.data.newentity, IID_ResourceDropsite); + let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + let cmpResourceDropsite = Engine.QueryInterface(msg.data.newentity, IID_ResourceDropsite); if (cmpResourceGatherer && cmpResourceDropsite && this.CheckTargetRange(msg.data.newentity, IID_Builder) && this.CanReturnResource(msg.data.newentity, true)) { @@ -2694,13 +2696,18 @@ // the build command should look for nearby resources to gather if ((oldData.force || oldData.autoharvest) && this.CanReturnResource(msg.data.newentity, false)) { - var cmpResourceDropsite = Engine.QueryInterface(msg.data.newentity, IID_ResourceDropsite); - var types = cmpResourceDropsite.GetTypes(); + let types = cmpResourceDropsite.GetTypes(); + let pos; + let cmpPosition = Engine.QueryInterface(msg.data.newentity, IID_Position); + if (cmpPosition && cmpPosition.IsInWorld()) + pos = cmpPosition.GetPosition2D(); + // TODO: Slightly undefined behavior here, we don't know what type of resource will be collected, // may cause problems for AIs (especially hunting fast animals), but avoid ugly hacks to fix that! - var nearby = this.FindNearbyResource(function(ent, type, template) { + let nearby = this.FindNearbyResource(function(ent, type, template) { return (types.indexOf(type.generic) != -1); - }, msg.data.newentity); + }, pos); + if (nearby) { this.PerformGather(nearby, true, false); @@ -2709,7 +2716,7 @@ } // Look for a nearby foundation to help with - var nearbyFoundation = this.FindNearbyFoundation(); + let nearbyFoundation = this.FindNearbyFoundation(); if (nearbyFoundation) { this.AddOrder("Repair", { "target": nearbyFoundation, "autocontinue": oldData.autocontinue, "force": false }, true); @@ -2718,10 +2725,8 @@ // Unit was approaching and there's nothing to do now, so switch to walking if (oldState === "INDIVIDUAL.REPAIR.APPROACHING") - { // We're already walking to the given point, so add this as a order. this.WalkToTarget(msg.data.newentity, true); - } }, }, @@ -3903,40 +3908,40 @@ /** * Returns the entity ID of the nearest resource supply where the given * filter returns true, or undefined if none can be found. - * if target if given, the nearest is computed versus this target position. + * if position (as a vector2D) is given, the nearest is computed versus this position. * TODO: extend this to exclude resources that already have lots of * gatherers. */ -UnitAI.prototype.FindNearbyResource = function(filter, target) +UnitAI.prototype.FindNearbyResource = function(filter, position) { - var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); + let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); if (!cmpOwnership || cmpOwnership.GetOwner() == INVALID_PLAYER) return undefined; - var owner = cmpOwnership.GetOwner(); + let owner = cmpOwnership.GetOwner(); // We accept resources owned by Gaia or any player - var players = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayers(); + let players = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayers(); - var range = 64; // TODO: what's a sensible number? + let range = 64; // TODO: what's a sensible number? - var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); - var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); - let entity = this.entity; - if (target) + let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); + let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); + let pos = position; + if (!pos) { let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); if (cmpPosition && cmpPosition.IsInWorld()) - entity = target; + pos = cmpPosition.GetPosition2D(); } - var nearby = cmpRangeManager.ExecuteQuery(entity, 0, range, players, IID_ResourceSupply); + let nearby = cmpRangeManager.ExecuteQueryAroundPos(pos, 0, range, players, IID_ResourceSupply); return nearby.find(ent => { if (!this.CanGather(ent) || !this.CheckTargetVisible(ent)) return false; - var cmpResourceSupply = Engine.QueryInterface(ent, IID_ResourceSupply); - var type = cmpResourceSupply.GetType(); - var amount = cmpResourceSupply.GetCurrentAmount(); + let cmpResourceSupply = Engine.QueryInterface(ent, IID_ResourceSupply); + let type = cmpResourceSupply.GetType(); + let amount = cmpResourceSupply.GetCurrentAmount(); - var template = cmpTemplateManager.GetCurrentTemplateName(ent); + let template = cmpTemplateManager.GetCurrentTemplateName(ent); // Remove "resource|" prefix from template names, if present. if (template.indexOf("resource|") != -1) template = template.slice(9); @@ -5031,6 +5036,7 @@ }; this.RememberTargetPosition(order); + order.initPos = order.lastPos; this.AddOrder("Gather", order, queued); };