1
0
forked from 0ad/0ad

Additional fixes following 0c20afdfda - units no longer return to gather nearby resources when depleting a chicken/tree/...

Reuse the timer code in the gathering sub-state to avoid broken
duplication.

Reported By: minohaka
Test By: Angen
Differential Revision: https://code.wildfiregames.com/D1956
This was SVN commit r22342.
This commit is contained in:
wraitii 2019-06-05 20:44:43 +00:00
parent 3ac1a004fa
commit 7d53fb19a2
2 changed files with 29 additions and 146 deletions

View File

@ -280,6 +280,18 @@ experiments.formation_attack = {
}
};
experiments.multiple_resources = {
"spawn": () => {
QuickSpawn(gx, gy + 80, "structures/athen_civil_centre");
let chicken = QuickSpawn(gx, gy + 50, "gaia/fauna_chicken");
QuickSpawn(gx + 3, gy + 50, "gaia/fauna_chicken");
QuickSpawn(gx - 3, gy + 50, "gaia/fauna_chicken");
Do("gather", { "target": chicken }, QuickSpawn(gx, gy, UNIT_TEMPLATE));
}
};
var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
Trigger.prototype.SetupUnits = function()

View File

@ -2070,115 +2070,20 @@ UnitAI.prototype.UnitFsmSpec = {
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
var cmpMirage = Engine.QueryInterface(this.gatheringTarget, IID_Mirage);
if ((!cmpMirage || !cmpMirage.Mirages(IID_ResourceSupply)) &&
(!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)))
(!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)) ||
!this.MoveTo(this.order.data, IID_ResourceGatherer))
{
// Save the current order's data in case we need it later
var oldType = this.order.data.type;
var oldTarget = this.order.data.target;
var oldTemplate = this.order.data.template;
// Try the next queued order if there is any
if (this.FinishOrder())
return true;
// Try to find another nearby target of the same specific type
// Also don't switch to a different type of huntable animal
var nearby = this.FindNearbyResource(function(ent, type, template) {
return (
ent != oldTarget
&& ((type.generic == "treasure" && oldType.generic == "treasure")
|| (type.specific == oldType.specific
&& (type.specific != "meat" || oldTemplate == template)))
);
}, oldTarget);
if (nearby)
{
this.PerformGather(nearby, false, false);
return true;
}
else
{
// It's probably better in this case, to avoid units getting stuck around a dropsite
// in a "Target is far away, full, nearby are no good resources, return to dropsite" loop
// to order it to GatherNear the resource position.
var cmpPosition = Engine.QueryInterface(oldTarget, IID_Position);
if (cmpPosition)
{
var pos = cmpPosition.GetPosition();
this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate);
return true;
}
else
{
// we're kind of stuck here. Return resource.
var nearby = this.FindNearestDropsite(oldType.generic);
if (nearby)
{
this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
return true;
}
}
}
// The GATHERING timer will handle finding a valid resource.
this.SetNextState("GATHERING");
return true;
}
// We can gather from out target, so try to move there.
if (!this.MoveTo(this.order.data, IID_ResourceGatherer))
{
this.FinishOrder();
return true;
}
this.SelectAnimation("move");
return false;
},
"MoveCompleted": function(msg) {
if (msg.data.error)
{
// We failed to reach the target
// remove us from the list of entities gathering from Resource.
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
if (cmpSupply && cmpOwnership)
cmpSupply.RemoveGatherer(this.entity, cmpOwnership.GetOwner());
else if (cmpSupply)
cmpSupply.RemoveGatherer(this.entity);
// Save the current order's data in case we need it later
var oldType = this.order.data.type;
var oldTarget = this.order.data.target;
var oldTemplate = this.order.data.template;
// Try the next queued order if there is any
if (this.FinishOrder())
return;
// Try to find another nearby target of the same specific type
// Also don't switch to a different type of huntable animal
var nearby = this.FindNearbyResource(function(ent, type, template) {
return (
ent != oldTarget
&& ((type.generic == "treasure" && oldType.generic == "treasure")
|| (type.specific == oldType.specific
&& (type.specific != "meat" || oldTemplate == template)))
);
});
if (nearby)
{
this.PerformGather(nearby, false, false);
return;
}
// Couldn't find anything else. Just try this one again,
// maybe we'll succeed next time
this.PerformGather(oldTarget, false, false);
return;
}
// We reached the target - start gathering from it now
// We either reached the target, or we will let the timer logic in GATHERING
// handle finding a new resource.
this.SetNextState("GATHERING");
},
@ -2213,59 +2118,25 @@ UnitAI.prototype.UnitFsmSpec = {
},
"MoveCompleted": function(msg) {
var resourceType = this.order.data.type;
var resourceTemplate = this.order.data.template;
// Try to find another nearby target of the same specific type
// Also don't switch to a different type of huntable animal
var nearby = this.FindNearbyResource(function(ent, type, template) {
return (
(type.generic == "treasure" && resourceType.generic == "treasure")
|| (type.specific == resourceType.specific
&& (type.specific != "meat" || resourceTemplate == template))
);
});
// If there is a nearby resource start gathering
if (nearby)
{
this.PerformGather(nearby, false, false);
return;
}
// Couldn't find nearby resources, so give up
if (this.FinishOrder())
return;
// Nothing better to do: go back to dropsite
var nearby = this.FindNearestDropsite(resourceType.generic);
if (nearby)
{
this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
return;
}
// No dropsites, just give up
// The GATHERING timer will handle finding a valid resource.
this.SetNextState("GATHERING");
},
},
"GATHERING": {
"enter": function() {
this.gatheringTarget = this.order.data.target; // deleted in "leave".
this.gatheringTarget = this.order.data.target || INVALID_ENTITY; // deleted in "leave".
// Check if the resource is full.
if (this.gatheringTarget)
// Will only be added if we're not already in.
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
let cmpSupply;
if (cmpOwnership)
cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
if (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity))
{
// Check that we can gather from the resource we're supposed to gather from.
// Will only be added if we're not already in.
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
if (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity))
{
this.gatheringTarget = INVALID_ENTITY;
this.StartTimer(0);
return false;
}
this.StartTimer(0);
return false;
}
// If this order was forced, the player probably gave it, but now we've reached the target