From d0ff48bc7a4e90011e2bb818d722d1c226f22c8c Mon Sep 17 00:00:00 2001 From: wraitii Date: Sun, 2 Aug 2020 11:40:46 +0000 Subject: [PATCH] Fix gathering infinite loop when the gatherer is out of the world. Promoted units move out of the world but keep their current orders, which can trigger invalid states. As cleanup, handle this case in GATHER.FINDINGNEWTARGET A more general fix seems possible by putting the UnitAI in a default state. Reported by: psypherium Reviewed By: Angen Fixes #5788 Differential Revision: https://code.wildfiregames.com/D2920 This was SVN commit r23920. --- .../public/simulation/components/UnitAI.js | 65 +++++++++---------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js index 97b0306823..4c08d7be30 100644 --- a/binaries/data/mods/public/simulation/components/UnitAI.js +++ b/binaries/data/mods/public/simulation/components/UnitAI.js @@ -2502,47 +2502,45 @@ UnitAI.prototype.UnitFsmSpec = { // No remaining orders - pick a useful default behaviour + // Give up if we're not in the world right now. + let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); + if (!cmpPosition || !cmpPosition.IsInWorld()) + return true; + // If we have no known initial position of our target, look around our own position // as a fallback. if (!initPos) { - let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); - if (cmpPosition && cmpPosition.IsInWorld()) - { - let pos = cmpPosition.GetPosition(); - initPos = { 'x': pos.X, 'z': pos.Z }; - } + let pos = cmpPosition.GetPosition(); + initPos = { 'x': pos.X, 'z': pos.Z }; } - if (initPos) + // Try to find a new resource of the same specific type near the initial resource position: + // Also don't switch to a different type of huntable animal + let nearbyResource = this.FindNearbyResource(new Vector2D(initPos.x, initPos.z), + (ent, type, template) => { + if (previousTarget == ent) + return false; + + if (type.generic == "treasure" && resourceType.generic == "treasure") + return true; + + return type.specific == resourceType.specific && + (type.specific != "meat" || resourceTemplate == template); + }); + + if (nearbyResource) { - // Try to find a new resource of the same specific type near the initial resource position: - // Also don't switch to a different type of huntable animal - let nearbyResource = this.FindNearbyResource(new Vector2D(initPos.x, initPos.z), - (ent, type, template) => { - if (previousTarget == ent) - return false; + this.PerformGather(nearbyResource, false, false); + return true; + } - if (type.generic == "treasure" && resourceType.generic == "treasure") - return true; - - return type.specific == resourceType.specific && - (type.specific != "meat" || resourceTemplate == template); - }); - - if (nearbyResource) - { - this.PerformGather(nearbyResource, false, false); - return true; - } - - // Failing that, try to move there and se if we are more lucky: maybe there are resources in FOW. - // Only move if we are some distance away (TODO: pick the distance better?) - if (!this.CheckPointRangeExplicit(initPos.x, initPos.z, 0, 10)) - { - this.GatherNearPosition(initPos.x, initPos.z, resourceType, resourceTemplate); - return true; - } + // Failing that, try to move there and se if we are more lucky: maybe there are resources in FOW. + // Only move if we are some distance away (TODO: pick the distance better?) + if (!this.CheckPointRangeExplicit(initPos.x, initPos.z, 0, 10)) + { + this.GatherNearPosition(initPos.x, initPos.z, resourceType, resourceTemplate); + return true; } // Nothing else to gather - if we're carrying anything then we should @@ -2555,7 +2553,6 @@ UnitAI.prototype.UnitFsmSpec = { this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); return true; } - // No dropsites - just give up. return true; },