Changeset View
Standalone View
binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 525 Lines • ▼ Show 20 Lines | if (this.GetStance().respondStandGround && !this.order.data.force) | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return; | return; | ||||
} | } | ||||
this.SetNextState("INDIVIDUAL.HEAL.APPROACHING"); | this.SetNextState("INDIVIDUAL.HEAL.APPROACHING"); | ||||
}, | }, | ||||
"Order.Gather": function(msg) { | "Order.Gather": function(msg) { | ||||
if (!this.CanGather(this.order.data.target)) | |||||
Freagarach: ^ | |||||
{ | |||||
this.SetNextState("INDIVIDUAL.GATHER.FINDINGNEWTARGET"); | |||||
Done Inline ActionsSpace, also add here this.CanGather(target) and you can ditch the one below? Freagarach: Space, also add here `this.CanGather(target)` and you can ditch the one below? | |||||
Done Inline ActionsI did mean by "target" "this.order.data.target". Freagarach: I did mean by "target" "this.order.data.target". | |||||
Done Inline ActionsGetGatherRate needs also a specific type, which you don't always have. Freagarach: `GetGatherRate` needs also a specific type, which you don't always have. | |||||
return; | |||||
} | |||||
// If the unit is full go to the nearest dropsite instead of trying to gather. | |||||
// Unless our target is a treasure which we cannot be full enough with (we can't carry treasures). | |||||
let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | |||||
if (msg.data.type.generic !== "treasure" && cmpResourceGatherer && !cmpResourceGatherer.CanCarryMore(msg.data.type.generic)) | |||||
{ | |||||
let nearestDropsite = this.FindNearestDropsite(msg.data.type.generic); | |||||
// Oh no, couldn't find any dropsites. Give up on gathering. | |||||
if (!nearestDropsite) | |||||
{ | |||||
this.FinishOrder(); | |||||
return; | |||||
} | |||||
Done Inline Actionsdropsites seems to be one word? Freagarach: `dropsites` seems to be one word? | |||||
this.PushOrderFront("ReturnResource", { | |||||
"target": nearestDropsite, | |||||
"force": false, | |||||
"type": msg.data.type | |||||
}); | |||||
return; | |||||
} | |||||
// If the target is still alive, we need to kill it first | // If the target is still alive, we need to kill it first | ||||
if (this.MustKillGatherTarget(this.order.data.target)) | if (this.MustKillGatherTarget(this.order.data.target)) | ||||
{ | { | ||||
// Make sure we can attack the target, else we'll get very stuck | // Make sure we can attack the target, else we'll get very stuck | ||||
if (!this.GetBestAttackAgainst(this.order.data.target, false)) | if (!this.GetBestAttackAgainst(this.order.data.target, false)) | ||||
{ | { | ||||
// Oops, we can't attack at all - give up | // Oops, we can't attack at all - give up | ||||
// TODO: should do something so the player knows why this failed | // TODO: should do something so the player knows why this failed | ||||
▲ Show 20 Lines • Show All 1,689 Lines • ▼ Show 20 Lines | "COMBAT": { | ||||
!msg.obstructed && this.CheckRange(this.order.data)) | !msg.obstructed && this.CheckRange(this.order.data)) | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
"GATHER": { | "GATHER": { | ||||
"leave": function() { | "leave": function() { | ||||
Done Inline Actions\t -> Freagarach: `\t` -> ` ` | |||||
// Show the carried resource, if we've gathered anything. | // Show the carried resource, if we've gathered anything. | ||||
Done Inline ActionsOh, and this on the previous line. Freagarach: Oh, and this on the previous line. | |||||
this.SetDefaultAnimationVariant(); | this.SetDefaultAnimationVariant(); | ||||
Done Inline ActionsProbably need the order here ^^ Freagarach: Probably need the order here ^^ | |||||
}, | }, | ||||
Done Inline ActionsEarly return? Freagarach: Early return? | |||||
"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". | ||||
Done Inline Actions(Empty line not needed.) Freagarach: (Empty line not needed.) | |||||
Done Inline ActionsComment should go below. Freagarach: Comment should go below. | |||||
// 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. | ||||
Done Inline ActionsCheck for cmpResourceGatherer? Freagarach: Check for `cmpResourceGatherer`? | |||||
Done Inline ActionsAlso return false when the resourceType == "treasure" since we cannot carry that. (Ugly hardcoding, but I plan to revisit treasures.) Freagarach: Also return false when the resourceType == "treasure" since we cannot carry that. (Ugly… | |||||
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | ||||
Done Inline ActionsYou can revert this ;) Freagarach: You can revert this ;) | |||||
let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply); | ||||
Done Inline Actionsfalse Freagarach: `false` | |||||
let 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 || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)) || | ||||
!this.MoveTo(this.order.data, IID_ResourceGatherer)) | !this.MoveTo(this.order.data, IID_ResourceGatherer)) | ||||
{ | { | ||||
// If the target's last known position is in FOW, try going there | // If the target's last known position is in FOW, try going there | ||||
// and hope that we might find it then. | // and hope that we might find it then. | ||||
Done Inline Actionstrue Freagarach: `true` | |||||
let lastPos = this.order.data.lastPos; | let lastPos = this.order.data.lastPos; | ||||
if (this.gatheringTarget != INVALID_ENTITY && | if (this.gatheringTarget != INVALID_ENTITY && | ||||
lastPos && !this.CheckPositionVisible(lastPos.x, lastPos.z)) | lastPos && !this.CheckPositionVisible(lastPos.x, lastPos.z)) | ||||
{ | { | ||||
this.PushOrderFront("Walk", { | this.PushOrderFront("Walk", { | ||||
"x": lastPos.x, "z": lastPos.z, | "x": lastPos.x, "z": lastPos.z, | ||||
"force": this.order.data.force | "force": this.order.data.force | ||||
}); | }); | ||||
return true; | return true; | ||||
} | } | ||||
Done Inline Actions+\n Freagarach: +`\n` | |||||
this.SetNextState("FINDINGNEWTARGET"); | this.SetNextState("FINDINGNEWTARGET"); | ||||
return true; | return true; | ||||
} | } | ||||
this.SetAnimationVariant("approach_" + this.order.data.type.specific); | this.SetAnimationVariant("approach_" + this.order.data.type.specific); | ||||
Done Inline ActionsThis could either be removed to restore the original behavior when there is no dropsite, or changed so the unit walks to the target instead of trying to gather from it. Stan: This could either be removed to restore the original behavior when there is no dropsite, or… | |||||
return false; | return false; | ||||
}, | }, | ||||
"MovementUpdate": function(msg) { | "MovementUpdate": function(msg) { | ||||
// The GATHERING timer will handle finding a valid resource. | // The GATHERING timer will handle finding a valid resource. | ||||
if (msg.likelyFailure) | if (msg.likelyFailure) | ||||
this.SetNextState("FINDINGNEWTARGET"); | this.SetNextState("FINDINGNEWTARGET"); | ||||
else if (this.CheckRange(this.order.data, IID_ResourceGatherer)) | else if (this.CheckRange(this.order.data, IID_ResourceGatherer)) | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | "GATHER": { | ||||
if (cmpResourceGatherer.IsCarryingAnythingExcept(resourceType.generic)) | if (cmpResourceGatherer.IsCarryingAnythingExcept(resourceType.generic)) | ||||
cmpResourceGatherer.DropResources(); | cmpResourceGatherer.DropResources(); | ||||
this.FaceTowardsTarget(this.order.data.target); | this.FaceTowardsTarget(this.order.data.target); | ||||
// Collect from the target | // Collect from the target | ||||
let status = cmpResourceGatherer.PerformGather(this.gatheringTarget); | let status = cmpResourceGatherer.PerformGather(this.gatheringTarget); | ||||
// Find a new target if the current one is exhausted. | |||||
if (status.exhausted) | |||||
{ | |||||
this.SetNextState("FINDINGNEWTARGET"); | |||||
return; | |||||
} | |||||
FreagarachUnsubmitted Done Inline ActionsThis move is not even necessary ^^' Freagarach: This move is not even necessary ^^' | |||||
// 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) | ||||
{ | { | ||||
let nearestDropsite = this.FindNearestDropsite(resourceType.generic); | let nearestDropsite = this.FindNearestDropsite(resourceType.generic); | ||||
if (nearestDropsite) | 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) | ||||
// However mark our target as invalid if it's exhausted, so we don't waste time | |||||
// trying to gather from it. | |||||
if (status.exhausted) | |||||
this.order.data.target = INVALID_ENTITY; | |||||
this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); | this.PushOrderFront("ReturnResource", { "target": nearestDropsite, "force": false }); | ||||
return; | return; | ||||
} | } | ||||
// 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; | ||||
} | } | ||||
// Find a new target if the current one is exhausted | |||||
if (status.exhausted) | |||||
this.SetNextState("FINDINGNEWTARGET"); | |||||
}, | }, | ||||
}, | }, | ||||
"FINDINGNEWTARGET": { | "FINDINGNEWTARGET": { | ||||
"enter": function() { | "enter": function() { | ||||
let previousTarget = this.order.data.target; | let previousTarget = this.order.data.target; | ||||
let resourceTemplate = this.order.data.template; | let resourceTemplate = this.order.data.template; | ||||
let resourceType = this.order.data.type; | let resourceType = this.order.data.type; | ||||
▲ Show 20 Lines • Show All 3,149 Lines • ▼ Show 20 Lines | UnitAI.prototype.SetupTradeRoute = function(target, source, route, queued) | ||||
} | } | ||||
// AI has currently no access to BackToWork | // AI has currently no access to BackToWork | ||||
let cmpPlayer = QueryOwnerInterface(this.entity); | let cmpPlayer = QueryOwnerInterface(this.entity); | ||||
if (cmpPlayer && cmpPlayer.IsAI() && !this.IsFormationController() && | if (cmpPlayer && cmpPlayer.IsAI() && !this.IsFormationController() && | ||||
this.workOrders.length && this.workOrders[0].type == "Trade") | this.workOrders.length && this.workOrders[0].type == "Trade") | ||||
{ | { | ||||
let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); | let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); | ||||
if (cmpTrader.HasBothMarkets() && | if (cmpTrader.HasBothMarkets() && | ||||
Done Inline Actions(Please revert this change when committing.) Freagarach: (Please revert this change when committing.) | |||||
(cmpTrader.GetFirstMarket() == target && cmpTrader.GetSecondMarket() == source || | (cmpTrader.GetFirstMarket() == target && cmpTrader.GetSecondMarket() == source || | ||||
cmpTrader.GetFirstMarket() == source && cmpTrader.GetSecondMarket() == target)) | cmpTrader.GetFirstMarket() == source && cmpTrader.GetSecondMarket() == target)) | ||||
{ | { | ||||
this.BackToWork(); | this.BackToWork(); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 853 Lines • Show Last 20 Lines |
^