Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 2,064 Lines • ▼ Show 20 Lines | "GATHER": { | ||||
"enter": function() { | "enter": function() { | ||||
this.gatheringTarget = this.order.data.target; // temporary, deleted in "leave". | this.gatheringTarget = this.order.data.target; // temporary, deleted in "leave". | ||||
// check that we can gather from the resource we're supposed to gather from. | // check that we can gather from the resource we're supposed to gather from. | ||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | ||||
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | ||||
var cmpMirage = Engine.QueryInterface(this.gatheringTarget, IID_Mirage); | var cmpMirage = Engine.QueryInterface(this.gatheringTarget, IID_Mirage); | ||||
if ((!cmpMirage || !cmpMirage.Mirages(IID_ResourceSupply)) && | 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 | // The GATHERING timer will handle finding a valid resource. | ||||
var oldType = this.order.data.type; | this.SetNextState("GATHERING"); | ||||
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; | |||||
} | |||||
} | |||||
} | |||||
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; | return true; | ||||
} | } | ||||
this.SelectAnimation("move"); | this.SelectAnimation("move"); | ||||
return false; | return false; | ||||
}, | }, | ||||
"MoveCompleted": function(msg) { | "MoveCompleted": function(msg) { | ||||
if (msg.data.error) | // We either reached the target, or we will let the timer logic in GATHERING | ||||
{ | // handle finding a new resource. | ||||
// 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 | |||||
this.SetNextState("GATHERING"); | this.SetNextState("GATHERING"); | ||||
}, | }, | ||||
"leave": function() { | "leave": function() { | ||||
this.StopMoving(); | this.StopMoving(); | ||||
this.SetDefaultAnimationVariant(); | this.SetDefaultAnimationVariant(); | ||||
if (!this.gatheringTarget) | if (!this.gatheringTarget) | ||||
Show All 18 Lines | "GATHER": { | ||||
this.SelectAnimation("move"); | this.SelectAnimation("move"); | ||||
}, | }, | ||||
"leave": function() { | "leave": function() { | ||||
this.StopMoving(); | this.StopMoving(); | ||||
}, | }, | ||||
"MoveCompleted": function(msg) { | "MoveCompleted": function(msg) { | ||||
var resourceType = this.order.data.type; | // The GATHERING timer will handle finding a valid resource. | ||||
var resourceTemplate = this.order.data.template; | this.SetNextState("GATHERING"); | ||||
// 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 | |||||
}, | }, | ||||
}, | }, | ||||
"GATHERING": { | "GATHERING": { | ||||
"enter": function() { | "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. | // 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. | // Will only be added if we're not already in. | ||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | ||||
Stan: Could also check whether it's already INVALID_ENTITY; | |||||
Done Inline ActionsIt can be undefined here, I think it's just easier here. wraitii: It can be undefined here, I think it's just easier here. | |||||
Not Done Inline ActionsThis have to go into if (!cmpSupply || ...) and be set to INVALID_ENTITY allways Silier: This have to go into if (!cmpSupply || ...) and be set to INVALID_ENTITY allways
Idea of this… | |||||
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | let cmpSupply; | ||||
if (cmpOwnership) | |||||
cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | |||||
Not Done Inline Actionscheck for that. Stan: check for that. | |||||
if (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)) | if (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)) | ||||
{ | { | ||||
this.gatheringTarget = INVALID_ENTITY; | |||||
this.StartTimer(0); | this.StartTimer(0); | ||||
StanUnsubmitted Not Done Inline ActionsMissing a parameter. Stan: Missing a parameter. | |||||
return false; | return false; | ||||
} | } | ||||
} | |||||
// If this order was forced, the player probably gave it, but now we've reached the target | // 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) | // switch to an unforced order (can be interrupted by attacks) | ||||
this.order.data.force = false; | this.order.data.force = false; | ||||
this.order.data.autoharvest = true; | this.order.data.autoharvest = true; | ||||
// Calculate timing based on gather rates | // Calculate timing based on gather rates | ||||
// This allows the gather rate to control how often we gather, instead of how much. | // This allows the gather rate to control how often we gather, instead of how much. | ||||
▲ Show 20 Lines • Show All 3,774 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
Could also check whether it's already INVALID_ENTITY;