Changeset View
Standalone View
binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 2,060 Lines • ▼ Show 20 Lines | "INDIVIDUAL": { | ||||
}, | }, | ||||
"GATHER": { | "GATHER": { | ||||
"APPROACHING": { | "APPROACHING": { | ||||
"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); | let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | ||||
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | ||||
var cmpMirage = Engine.QueryInterface(this.gatheringTarget, IID_Mirage); | let 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 || !cmpOwnership || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity))) | ||||
{ | { | ||||
// Save the current order's data in case we need it later | // Save the current order's data in case we need it later | ||||
var oldType = this.order.data.type; | let oldType = this.order.data.type; | ||||
var oldTarget = this.order.data.target; | let oldTarget = this.order.data.target; | ||||
var oldTemplate = this.order.data.template; | let oldTemplate = this.order.data.template; | ||||
// Try the next queued order if there is any | // Try the next queued order if there is any | ||||
if (this.FinishOrder()) | if (this.FinishOrder()) | ||||
return true; | return true; | ||||
// Try to find another nearby target of the same specific type | // Try to find another nearby target of the same specific type | ||||
// Also don't switch to a different type of huntable animal | // Also don't switch to a different type of huntable animal | ||||
var nearby = this.FindNearbyResource(function(ent, type, template) { | let nearbyResource = this.FindNearbyResource(function(ent, type, template) { | ||||
return ( | return ( | ||||
ent != oldTarget | ent != oldTarget | ||||
&& ((type.generic == "treasure" && oldType.generic == "treasure") | && ((type.generic == "treasure" && oldType.generic == "treasure") | ||||
|| (type.specific == oldType.specific | || (type.specific == oldType.specific | ||||
&& (type.specific != "meat" || oldTemplate == template))) | && (type.specific != "meat" || oldTemplate == template))) | ||||
); | ); | ||||
}, oldTarget); | }, oldTarget); | ||||
if (nearby) | |||||
Polakrity: From there. | |||||
{ | if (nearbyResource) | ||||
this.PerformGather(nearby, false, false); | this.PerformGather(nearbyResource, false, false); | ||||
return true; | |||||
} | |||||
else | else | ||||
{ | { | ||||
// It's probably better in this case, to avoid units getting stuck around a dropsite | // 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 | // in a "Target is far away, full, nearby are no good resources, return to dropsite" loop | ||||
// to order it to GatherNear the resource position. | // to order it to GatherNear the resource position. | ||||
var cmpPosition = Engine.QueryInterface(oldTarget, IID_Position); | let cmpPosition = Engine.QueryInterface(oldTarget, IID_Position); | ||||
if (cmpPosition) | if (cmpPosition) | ||||
{ | { | ||||
var pos = cmpPosition.GetPosition(); | let pos = cmpPosition.GetPosition(); | ||||
this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate); | this.GatherNearPosition(pos.x, pos.z, oldType, oldTemplate); | ||||
return true; | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
// we're kind of stuck here. Return resource. | // we're kind of stuck here. Return resource. | ||||
var nearby = this.FindNearestDropsite(oldType.generic); | let nearestDropsite = this.FindNearestDropsite(oldType.generic); | ||||
if (nearby) | if (nearestDropsite) | ||||
{ | this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); | ||||
this.PushOrderFront("ReturnResource", { "target": nearby, "force": false }); | |||||
return true; | |||||
} | |||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
// We can gather from out target, so try to move there. | // We can gather from out target, so try to move there. | ||||
if (!this.MoveTo(this.order.data, IID_ResourceGatherer)) | if (!this.MoveTo(this.order.data, IID_ResourceGatherer)) | ||||
{ | { | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return true; | return true; | ||||
} | } | ||||
this.SelectAnimation("move"); | this.SelectAnimation("move"); | ||||
return false; | |||||
}, | }, | ||||
"MoveCompleted": function(msg) { | "MoveCompleted": function(msg) { | ||||
if (msg.data.error) | if (msg.data.error) | ||||
{ | { | ||||
// We failed to reach the target | // We failed to reach the target | ||||
// remove us from the list of entities gathering from Resource. | // remove us from the list of entities gathering from Resource. | ||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | ||||
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | ||||
if (cmpSupply && cmpOwnership) | if (cmpSupply && cmpOwnership) | ||||
cmpSupply.RemoveGatherer(this.entity, cmpOwnership.GetOwner()); | cmpSupply.RemoveGatherer(this.entity, cmpOwnership.GetOwner()); | ||||
Not Done Inline ActionsWhat's the point of this if else ? Both case remove the entity no ? Stan: What's the point of this if else ? Both case remove the entity no ? | |||||
Done Inline Actionswhen you have ownership, it deletes directly from that player, if you have not, it tries to delete from every player Silier: when you have ownership, it deletes directly from that player, if you have not, it tries to… | |||||
else if (cmpSupply) | else if (cmpSupply) | ||||
cmpSupply.RemoveGatherer(this.entity); | cmpSupply.RemoveGatherer(this.entity); | ||||
// Save the current order's data in case we need it later | // Save the current order's data in case we need it later | ||||
var oldType = this.order.data.type; | let oldType = this.order.data.type; | ||||
var oldTarget = this.order.data.target; | let oldTarget = this.order.data.target; | ||||
var oldTemplate = this.order.data.template; | let oldTemplate = this.order.data.template; | ||||
// Try the next queued order if there is any | // Try the next queued order if there is any | ||||
if (this.FinishOrder()) | if (this.FinishOrder()) | ||||
return; | return false; | ||||
// Try to find another nearby target of the same specific type | // Try to find another nearby target of the same specific type | ||||
// Also don't switch to a different type of huntable animal | // Also don't switch to a different type of huntable animal | ||||
var nearby = this.FindNearbyResource(function(ent, type, template) { | let nearbyResource = this.FindNearbyResource(function(ent, type, template) { | ||||
return ( | return ( | ||||
ent != oldTarget | ent != oldTarget | ||||
&& ((type.generic == "treasure" && oldType.generic == "treasure") | && ((type.generic == "treasure" && oldType.generic == "treasure") | ||||
|| (type.specific == oldType.specific | || (type.specific == oldType.specific | ||||
&& (type.specific != "meat" || oldTemplate == template))) | && (type.specific != "meat" || oldTemplate == template))) | ||||
); | ); | ||||
}); | }); | ||||
if (nearby) | if (nearbyResource) | ||||
{ | { | ||||
this.PerformGather(nearby, false, false); | this.PerformGather(nearbyResource, false, false); | ||||
return; | return false; | ||||
} | } | ||||
// Couldn't find anything else. Just try this one again, | // Couldn't find anything else. Just try this one again, | ||||
// maybe we'll succeed next time | // maybe we'll succeed next time | ||||
this.PerformGather(oldTarget, false, false); | this.PerformGather(oldTarget, false, false); | ||||
return; | return false; | ||||
} | } | ||||
// We reached the target - start gathering from it now | // 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) | ||||
return; | return false; | ||||
// don't use ownership because this is called after a conversion/resignation | // Don't use ownership because this is called after a conversion/resignation | ||||
Not Done Inline ActionsUppercase. Polakrity: Uppercase. | |||||
// and the ownership would be invalid then. | // and the ownership would be invalid then. | ||||
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | ||||
if (cmpSupply) | if (cmpSupply) | ||||
cmpSupply.RemoveGatherer(this.entity); | cmpSupply.RemoveGatherer(this.entity); | ||||
delete this.gatheringTarget; | delete this.gatheringTarget; | ||||
}, | }, | ||||
}, | }, | ||||
// Walking to a good place to gather resources near, used by GatherNearPosition | // Walking to a good place to gather resources near, used by GatherNearPosition | ||||
"WALKING": { | "WALKING": { | ||||
"enter": function() { | "enter": function() { | ||||
if (!this.MoveTo(this.order.data)) | if (!this.MoveTo(this.order.data)) | ||||
{ | { | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return; | return true; | ||||
} | } | ||||
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; | let resourceType = this.order.data.type; | ||||
var resourceTemplate = this.order.data.template; | let resourceTemplate = this.order.data.template; | ||||
// Try to find another nearby target of the same specific type | // Try to find another nearby target of the same specific type | ||||
// Also don't switch to a different type of huntable animal | // Also don't switch to a different type of huntable animal | ||||
var nearby = this.FindNearbyResource(function(ent, type, template) { | let nearbyResource = this.FindNearbyResource(function(ent, type, template) { | ||||
return ( | return ( | ||||
(type.generic == "treasure" && resourceType.generic == "treasure") | (type.generic == "treasure" && resourceType.generic == "treasure") | ||||
|| (type.specific == resourceType.specific | || (type.specific == resourceType.specific | ||||
&& (type.specific != "meat" || resourceTemplate == template)) | && (type.specific != "meat" || resourceTemplate == template)) | ||||
); | ); | ||||
}); | }); | ||||
// If there is a nearby resource start gathering | // If there is a nearby resource start gathering | ||||
if (nearby) | if (nearbyResource) | ||||
{ | { | ||||
this.PerformGather(nearby, false, false); | this.PerformGather(nearbyResource, false, false); | ||||
return; | return false; | ||||
} | } | ||||
// Couldn't find nearby resources, so give up | // Couldn't find nearby resources, so give up | ||||
if (this.FinishOrder()) | if (this.FinishOrder()) | ||||
return; | return false; | ||||
// Nothing better to do: go back to dropsite | // Nothing better to do: go back to dropsite | ||||
var nearby = this.FindNearestDropsite(resourceType.generic); | let nearestDropsite = this.FindNearestDropsite(resourceType.generic); | ||||
if (nearby) | if (nearestDropsite) | ||||
{ | { | ||||
this.PushOrderFront("ReturnResource", { "target": nearby, "force": false }); | this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); | ||||
return; | return false; | ||||
} | } | ||||
// No dropsites, just give up | // No dropsites, just give up | ||||
Not Done Inline Actionsshoudln't we delete this.gatheringTarget like above ? Stan: shoudln't we delete this.gatheringTarget like above ? | |||||
Done Inline Actionsnot defined in WALKING branch so there is nothing to delete :) Silier: not defined in WALKING branch so there is nothing to delete :) | |||||
}, | }, | ||||
}, | }, | ||||
"GATHERING": { | "GATHERING": { | ||||
"enter": function() { | "enter": function() { | ||||
this.gatheringTarget = this.order.data.target; // deleted in "leave". | this.gatheringTarget = this.order.data.target; // deleted in "leave". | ||||
// Check if the resource is full. | // Check if the resource is full. | ||||
if (this.gatheringTarget) | if (this.gatheringTarget) | ||||
{ | { | ||||
// 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. | ||||
// 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); | ||||
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | ||||
if (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)) | if (!cmpSupply || !cmpOwnership || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)) | ||||
{ | { | ||||
this.gatheringTarget = INVALID_ENTITY; | this.gatheringTarget = INVALID_ENTITY; | ||||
this.StartTimer(0); | this.StartTimer(0); | ||||
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. | ||||
var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | ||||
var rate = cmpResourceGatherer.GetTargetGatherRate(this.gatheringTarget); | let rate = cmpResourceGatherer.GetTargetGatherRate(this.gatheringTarget); | ||||
if (!rate) | if (!rate) | ||||
{ | { | ||||
// Try to find another target if the current one stopped existing | // Try to find another target if the current one stopped existing | ||||
if (!Engine.QueryInterface(this.gatheringTarget, IID_Identity)) | if (!Engine.QueryInterface(this.gatheringTarget, IID_Identity)) | ||||
{ | { | ||||
// Let the Timer logic handle this | // Let the Timer logic handle this | ||||
this.StartTimer(0); | this.StartTimer(0); | ||||
return false; | return false; | ||||
} | } | ||||
// No rate, give up on gathering | // No rate, give up on gathering | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return true; | return true; | ||||
} | } | ||||
// Scale timing interval based on rate, and start timer | // Scale timing interval based on rate, and start timer | ||||
// The offset should be at least as long as the repeat time so we use the same value for both. | // The offset should be at least as long as the repeat time so we use the same value for both. | ||||
var offset = 1000/rate; | let offset = 1000 / rate; | ||||
Not Done Inline ActionsMaybe u can change this comment now. Polakrity: Maybe u can change this comment now. | |||||
Done Inline Actionsno, comment is still correct because parameters usage in StartTimer Silier: no, comment is still correct because parameters usage in StartTimer | |||||
var repeat = offset; | this.StartTimer(offset, offset); | ||||
Not Done Inline ActionsSpaces. Stan: Spaces. | |||||
this.StartTimer(offset, repeat); | |||||
// We want to start the gather animation as soon as possible, | // We want to start the gather animation as soon as possible, | ||||
// but only if we're actually at the target and it's still alive | // but only if we're actually at the target and it's still alive | ||||
// (else it'll look like we're chopping empty air). | // (else it'll look like we're chopping empty air). | ||||
// (If it's not alive, the Timer handler will deal with sending us | // (If it's not alive, the Timer handler will deal with sending us | ||||
// off to a different target.) | // off to a different target.) | ||||
if (this.CheckTargetRange(this.gatheringTarget, IID_ResourceGatherer)) | if (this.CheckTargetRange(this.gatheringTarget, IID_ResourceGatherer)) | ||||
{ | { | ||||
this.StopMoving(); | this.StopMoving(); | ||||
this.SetDefaultAnimationVariant(); | this.SetDefaultAnimationVariant(); | ||||
var typename = "gather_" + this.order.data.type.specific; | let typename = "gather_" + this.order.data.type.specific; | ||||
this.SelectAnimation(typename); | this.SelectAnimation(typename); | ||||
} | } | ||||
return false; | return false; | ||||
}, | }, | ||||
"leave": function() { | "leave": function() { | ||||
this.StopTimer(); | this.StopTimer(); | ||||
// don't use ownership because this is called after a conversion/resignation | // Don't use ownership because this is called after a conversion/resignation | ||||
Not Done Inline ActionsUppercase. Polakrity: Uppercase. | |||||
// and the ownership would be invalid then. | // and the ownership would be invalid then. | ||||
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | ||||
if (cmpSupply) | if (cmpSupply) | ||||
cmpSupply.RemoveGatherer(this.entity); | cmpSupply.RemoveGatherer(this.entity); | ||||
delete this.gatheringTarget; | delete this.gatheringTarget; | ||||
// Show the carried resource, if we've gathered anything. | // Show the carried resource, if we've gathered anything. | ||||
this.SetDefaultAnimationVariant(); | this.SetDefaultAnimationVariant(); | ||||
}, | }, | ||||
"Timer": function(msg) { | "Timer": function(msg) { | ||||
var resourceTemplate = this.order.data.template; | let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | ||||
var resourceType = this.order.data.type; | |||||
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | |||||
if (!cmpOwnership) | if (!cmpOwnership) | ||||
return; | return false; | ||||
var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | let resourceTemplate = this.order.data.template; | ||||
let resourceType = this.order.data.type; | |||||
let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | |||||
if (cmpSupply && cmpSupply.IsAvailable(cmpOwnership.GetOwner(), this.entity)) | if (cmpSupply && cmpSupply.IsAvailable(cmpOwnership.GetOwner(), this.entity)) | ||||
{ | { | ||||
// Check we can still reach and gather from the target | // Check we can still reach and gather from the target | ||||
if (this.CheckTargetRange(this.gatheringTarget, IID_ResourceGatherer) && this.CanGather(this.gatheringTarget)) | if (this.CanGather(this.gatheringTarget) && this.CheckTargetRange(this.gatheringTarget, IID_ResourceGatherer)) | ||||
{ | { | ||||
// Gather the resources: | // Gather the resources: | ||||
let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | |||||
var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | |||||
// Try to gather treasure | // Try to gather treasure | ||||
if (cmpResourceGatherer.TryInstantGather(this.gatheringTarget)) | if (cmpResourceGatherer.TryInstantGather(this.gatheringTarget)) | ||||
return; | return false; | ||||
// If we've already got some resources but they're the wrong type, | // If we've already got some resources but they're the wrong type, | ||||
// drop them first to ensure we're only ever carrying one type | // drop them first to ensure we're only ever carrying one type | ||||
if (cmpResourceGatherer.IsCarryingAnythingExcept(resourceType.generic)) | if (cmpResourceGatherer.IsCarryingAnythingExcept(resourceType.generic)) | ||||
cmpResourceGatherer.DropResources(); | cmpResourceGatherer.DropResources(); | ||||
// Collect from the target | // 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, | // If we've collected as many resources as possible, | ||||
// return to the nearest dropsite | // return to the nearest dropsite | ||||
if (status.filled) | if (status.filled) | ||||
{ | { | ||||
var nearby = this.FindNearestDropsite(resourceType.generic); | let nearestDropsite = this.FindNearestDropsite(resourceType.generic); | ||||
if (nearby) | if (nearestDropsite) | ||||
{ | { | ||||
// (Keep this Gather order on the stack so we'll | // (Keep this Gather order on the stack so we'll | ||||
// continue gathering after returning) | // continue gathering after returning) | ||||
this.PushOrderFront("ReturnResource", { "target": nearby, "force": false }); | this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); | ||||
return; | return false; | ||||
} | } | ||||
// Oh no, couldn't find any drop sites. Give up on gathering. | // Oh no, couldn't find any drop sites. Give up on gathering. | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return; | return false; | ||||
} | } | ||||
// We can gather more from this target, do so in the next timer | // We can gather more from this target, do so in the next timer | ||||
if (!status.exhausted) | if (!status.exhausted) | ||||
return; | return false; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
// Try to follow the target | // Try to follow the target | ||||
if (this.MoveToTargetRange(this.gatheringTarget, IID_ResourceGatherer)) | if (this.MoveToTargetRange(this.gatheringTarget, IID_ResourceGatherer)) | ||||
{ | { | ||||
this.SetNextState("APPROACHING"); | this.SetNextState("APPROACHING"); | ||||
return; | return false; | ||||
} | } | ||||
// Can't reach the target, or it doesn't exist any more | // Can't reach the target, or it doesn't exist any more | ||||
// We want to carry on gathering resources in the same area as | // We want to carry on gathering resources in the same area as | ||||
// the old one. So try to get close to the old resource's | // the old one. So try to get close to the old resource's | ||||
// last known position | // last known position | ||||
var maxRange = 8; // get close but not too close | |||||
if (this.order.data.lastPos && | if (this.order.data.lastPos && | ||||
this.MoveToPointRange(this.order.data.lastPos.x, this.order.data.lastPos.z, 0, maxRange)) | this.MoveToPointRange(this.order.data.lastPos.x, this.order.data.lastPos.z, 0, 8)) | ||||
Not Done Inline ActionsWhy 8 ? There is a range variable that's usually 4 also for some reason and should be a global. Stan: Why 8 ? There is a range variable that's usually 4 also for some reason and should be a global. | |||||
Done Inline Actionslooks like 4 represents distance of one tile, so here are 2 tiles ? you would need to ask philip Silier: looks like 4 represents distance of one tile, so here are 2 tiles ? you would need to ask philip | |||||
Not Done Inline ActionsMaybe then instead make the range/tilesize = 4 a global variable, then use it * 2 here ? Stan: Maybe then instead make the range/tilesize = 4 a global variable, then use it * 2 here ? | |||||
Not Done Inline ActionsHe is better to avoid magic number, no? Polakrity: He is better to avoid magic number, no? | |||||
Not Done Inline ActionsWell I don't know if we can get the tilesize from the engine :) Stan: Well I don't know if we can get the tilesize from the engine :) | |||||
{ | { | ||||
this.SetNextState("APPROACHING"); | this.SetNextState("APPROACHING"); | ||||
return; | return false; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// We're already in range, can't get anywhere near it or the target is exhausted. | // 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 | // 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 | // 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) && | if (cmpResourceGatherer.IsCarrying(resourceType.generic) && | ||||
this.orderQueue.length > 1 && this.orderQueue[1] !== "ReturnResource" && | this.orderQueue.length > 1 && this.orderQueue[1] !== "ReturnResource" && | ||||
(this.orderQueue[1].type !== "Gather" || this.orderQueue[1].data.type.generic !== resourceType.generic)) | (this.orderQueue[1].type !== "Gather" || this.orderQueue[1].data.type.generic !== resourceType.generic)) | ||||
{ | { | ||||
let nearby = this.FindNearestDropsite(resourceType.generic); | let nearestDropsite = this.FindNearestDropsite(resourceType.generic); | ||||
Not Done Inline ActionsnearestDropsite like above. Polakrity: nearestDropsite like above. | |||||
if (nearby) | if (nearestDropsite) | ||||
this.orderQueue.splice(1, 0, { "type": "ReturnResource", "data": { "target": nearby, "force": false } }); | this.orderQueue.splice(1, 0, { "type": "ReturnResource", "data": { "target": nearestDropsite, "force": false } }); | ||||
} | } | ||||
if (this.FinishOrder()) | if (this.FinishOrder()) | ||||
return; | return false; | ||||
// No remaining orders - pick a useful default behaviour | // No remaining orders - pick a useful default behaviour | ||||
// Try to find a new resource of the same specific type near our current position: | // 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 | // Also don't switch to a different type of huntable animal | ||||
var nearby = this.FindNearbyResource(function(ent, type, template) { | let nearbyResource = this.FindNearbyResource(function(ent, type, template) { | ||||
Not Done Inline Actionsarrow function ? Stan: arrow function ? | |||||
return ( | return ( | ||||
(type.generic == "treasure" && resourceType.generic == "treasure") | (type.generic == "treasure" && resourceType.generic == "treasure") | ||||
|| (type.specific == resourceType.specific | || (type.specific == resourceType.specific | ||||
&& (type.specific != "meat" || resourceTemplate == template)) | && (type.specific != "meat" || resourceTemplate == template)) | ||||
); | ); | ||||
}); | }); | ||||
if (nearby) | if (nearbyResource) | ||||
{ | { | ||||
this.PerformGather(nearby, false, false); | this.PerformGather(nearbyResource, false, false); | ||||
return; | return false; | ||||
} | } | ||||
// If hunting, try to go to the initial herd position to see if we are more lucky | // If hunting, try to go to the initial herd position to see if we are more lucky | ||||
if (herdPos) | if (herdPos) | ||||
{ | { | ||||
this.GatherNearPosition(herdPos.x, herdPos.z, resourceType, resourceTemplate); | this.GatherNearPosition(herdPos.x, herdPos.z, resourceType, resourceTemplate); | ||||
return; | return false; | ||||
} | } | ||||
// Nothing else to gather - if we're carrying anything then we should | // Nothing else to gather - if we're carrying anything then we should | ||||
// drop it off, and if not then we might as well head to the dropsite | // 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 | // anyway because that's a nice enough place to congregate and idle | ||||
var nearby = this.FindNearestDropsite(resourceType.generic); | let nearestDropsite = this.FindNearestDropsite(resourceType.generic); | ||||
if (nearby) | if (nearestDropsite) | ||||
{ | { | ||||
this.PushOrderFront("ReturnResource", { "target": nearby, "force": false }); | this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); | ||||
return; | return false; | ||||
} | } | ||||
// No dropsites - just give up | // No dropsites - just give up | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
"HEAL": { | "HEAL": { | ||||
▲ Show 20 Lines • Show All 2,666 Lines • ▼ Show 20 Lines | UnitAI.prototype.PerformGather = function(target, queued, force) | ||||
{ | { | ||||
this.WalkToTarget(target, queued); | this.WalkToTarget(target, queued); | ||||
return; | return; | ||||
} | } | ||||
// Save the resource type now, so if the resource gets destroyed | // Save the resource type now, so if the resource gets destroyed | ||||
// before we process the order then we still know what resource | // before we process the order then we still know what resource | ||||
// type to look for more of | // type to look for more of | ||||
var type; | let type; | ||||
var cmpResourceSupply = QueryMiragedInterface(target, IID_ResourceSupply); | let cmpResourceSupply = QueryMiragedInterface(target, IID_ResourceSupply); | ||||
if (cmpResourceSupply) | if (cmpResourceSupply) | ||||
type = cmpResourceSupply.GetType(); | type = cmpResourceSupply.GetType(); | ||||
else | else | ||||
error("CanGather allowed gathering from invalid entity"); | error("CanGather allowed gathering from invalid entity"); | ||||
// Also save the target entity's template, so that if it's an animal, | // Also save the target entity's template, so that if it's an animal, | ||||
// we won't go from hunting slow safe animals to dangerous fast ones | // we won't go from hunting slow safe animals to dangerous fast ones | ||||
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); | let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); | ||||
var template = cmpTemplateManager.GetCurrentTemplateName(target); | let template = cmpTemplateManager.GetCurrentTemplateName(target); | ||||
// Remove "resource|" prefix from template name, if present. | // Remove "resource|" prefix from template name, if present. | ||||
if (template.indexOf("resource|") != -1) | if (template.indexOf("resource|") != -1) | ||||
template = template.slice(9); | template = template.slice(9); | ||||
// Remember the position of our target, if any, in case it disappears | // Remember the position of our target, if any, in case it disappears | ||||
// later and we want to head to its last known position | // later and we want to head to its last known position | ||||
var lastPos = undefined; | let lastPos = undefined; | ||||
var cmpPosition = Engine.QueryInterface(target, IID_Position); | let cmpPosition = Engine.QueryInterface(target, IID_Position); | ||||
if (cmpPosition && cmpPosition.IsInWorld()) | if (cmpPosition && cmpPosition.IsInWorld()) | ||||
lastPos = cmpPosition.GetPosition(); | lastPos = cmpPosition.GetPosition(); | ||||
this.AddOrder("Gather", { "target": target, "type": type, "template": template, "lastPos": lastPos, "force": force }, queued); | this.AddOrder("Gather", { "target": target, "type": type, "template": template, "lastPos": lastPos, "force": force }, queued); | ||||
}; | }; | ||||
/** | /** | ||||
* Adds gather-near-position order to the queue, not forced, so it can be | * Adds gather-near-position order to the queue, not forced, so it can be | ||||
▲ Show 20 Lines • Show All 577 Lines • ▼ Show 20 Lines | UnitAI.prototype.CanGarrison = function(target) | ||||
return true; | return true; | ||||
}; | }; | ||||
UnitAI.prototype.CanGather = function(target) | UnitAI.prototype.CanGather = function(target) | ||||
{ | { | ||||
if (this.IsTurret()) | if (this.IsTurret()) | ||||
return false; | return false; | ||||
// The target must be a valid resource supply, or the mirage of one. | // The target must be a valid resource supply, or the mirage of one. | ||||
var cmpResourceSupply = QueryMiragedInterface(target, IID_ResourceSupply); | let cmpResourceSupply = QueryMiragedInterface(target, IID_ResourceSupply); | ||||
if (!cmpResourceSupply) | if (!cmpResourceSupply) | ||||
return false; | return false; | ||||
// Formation controllers should always respond to commands | // Formation controllers should always respond to commands | ||||
// (then the individual units can make up their own minds) | // (then the individual units can make up their own minds) | ||||
if (this.IsFormationController()) | if (this.IsFormationController()) | ||||
return true; | return true; | ||||
// Verify that we're able to respond to Gather commands | // Verify that we're able to respond to Gather commands | ||||
var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | ||||
if (!cmpResourceGatherer) | if (!cmpResourceGatherer) | ||||
return false; | return false; | ||||
// Verify that we can gather from this target | // Verify that we can gather from this target | ||||
if (!cmpResourceGatherer.GetTargetGatherRate(target)) | if (!cmpResourceGatherer.GetTargetGatherRate(target)) | ||||
return false; | return false; | ||||
// No need to verify ownership as we should be able to gather from | // No need to verify ownership as we should be able to gather from | ||||
▲ Show 20 Lines • Show All 279 Lines • Show Last 20 Lines |
From there.