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:
parent
3ac1a004fa
commit
7d53fb19a2
@ -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()
|
||||
|
@ -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);
|
||||
// The GATHERING timer will handle finding a valid resource.
|
||||
this.SetNextState("GATHERING");
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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,60 +2118,26 @@ 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)
|
||||
{
|
||||
// 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);
|
||||
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))
|
||||
{
|
||||
this.gatheringTarget = INVALID_ENTITY;
|
||||
this.StartTimer(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If this order was forced, the player probably gave it, but now we've reached the target
|
||||
// switch to an unforced order (can be interrupted by attacks)
|
||||
|
Loading…
Reference in New Issue
Block a user