Return Gathering to A23 behaviour - Make units try to gather near the target resource's position instead of their position.
Units were incorrectly looking at resources near their position
following 7d53fb19a2
.
Fixes #5477.
Differential Revision: https://code.wildfiregames.com/D2034
This was SVN commit r22428.
This commit is contained in:
parent
5fef05d780
commit
8a38cfb7cf
@ -529,6 +529,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
}
|
||||
|
||||
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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
|
||||
"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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
},
|
||||
|
||||
"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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
|
||||
// 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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
// 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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
// 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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
}
|
||||
|
||||
// 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 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
|
||||
// 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 @@ UnitAI.prototype.MustKillGatherTarget = function(ent)
|
||||
/**
|
||||
* 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 @@ UnitAI.prototype.PerformGather = function(target, queued, force)
|
||||
};
|
||||
|
||||
this.RememberTargetPosition(order);
|
||||
order.initPos = order.lastPos;
|
||||
|
||||
this.AddOrder("Gather", order, queued);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user