Changeset View
Standalone View
binaries/data/mods/public/simulation/components/UnitAI.js
Show All 18 Lines | "<element name='FleeDistance'>" + | |||||||||||||||||||||||||||||||||
"<ref name='positiveDecimal'/>" + | "<ref name='positiveDecimal'/>" + | |||||||||||||||||||||||||||||||||
"</element>" + | "</element>" + | |||||||||||||||||||||||||||||||||
"<element name='CanGuard'>" + | "<element name='CanGuard'>" + | |||||||||||||||||||||||||||||||||
"<data type='boolean'/>" + | "<data type='boolean'/>" + | |||||||||||||||||||||||||||||||||
"</element>" + | "</element>" + | |||||||||||||||||||||||||||||||||
"<element name='CanPatrol'>" + | "<element name='CanPatrol'>" + | |||||||||||||||||||||||||||||||||
"<data type='boolean'/>" + | "<data type='boolean'/>" + | |||||||||||||||||||||||||||||||||
"</element>" + | "</element>" + | |||||||||||||||||||||||||||||||||
"<optional>" + | "<optional>" + | |||||||||||||||||||||||||||||||||
Freagarach: Seconds, minutes, ms? | ||||||||||||||||||||||||||||||||||
Done Inline ActionsIt's multiples of a second, I changed to an integer to enforce that. wraitii: It's multiples of a second, I changed to an integer to enforce that. | ||||||||||||||||||||||||||||||||||
Not Done Inline ActionsAny specific reason to limit it to integers? Freagarach: Any specific reason to limit it to integers? | ||||||||||||||||||||||||||||||||||
Done Inline ActionsYes, since I'm using a timer of 1000 seconds you can't really use decimals in a meaningful way. wraitii: Yes, since I'm using a timer of 1000 seconds you can't really use decimals in a meaningful way. | ||||||||||||||||||||||||||||||||||
"<interleave>" + | "<interleave>" + | |||||||||||||||||||||||||||||||||
"<element name='NaturalBehaviour' a:help='Behaviour of the unit in the absence of player commands (intended for animals)'>" + | "<element name='NaturalBehaviour' a:help='Behaviour of the unit in the absence of player commands (intended for animals)'>" + | |||||||||||||||||||||||||||||||||
"<choice>" + | "<choice>" + | |||||||||||||||||||||||||||||||||
"<value a:help='Will actively attack any unit it encounters, even if not threatened'>violent</value>" + | "<value a:help='Will actively attack any unit it encounters, even if not threatened'>violent</value>" + | |||||||||||||||||||||||||||||||||
"<value a:help='Will attack nearby units if it feels threatened (if they linger within LOS for too long)'>aggressive</value>" + | "<value a:help='Will attack nearby units if it feels threatened (if they linger within LOS for too long)'>aggressive</value>" + | |||||||||||||||||||||||||||||||||
"<value a:help='Will attack nearby units if attacked'>defensive</value>" + | "<value a:help='Will attack nearby units if attacked'>defensive</value>" + | |||||||||||||||||||||||||||||||||
"<value a:help='Will never attack units but will attempt to flee when attacked'>passive</value>" + | "<value a:help='Will never attack units but will attempt to flee when attacked'>passive</value>" + | |||||||||||||||||||||||||||||||||
"<value a:help='Will never attack units. Will typically attempt to flee for short distances when units approach'>skittish</value>" + | "<value a:help='Will never attack units. Will typically attempt to flee for short distances when units approach'>skittish</value>" + | |||||||||||||||||||||||||||||||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | var g_OrdersCancelUnpacking = new Set([ | |||||||||||||||||||||||||||||||||
"WalkToTarget", | "WalkToTarget", | |||||||||||||||||||||||||||||||||
"Patrol", | "Patrol", | |||||||||||||||||||||||||||||||||
"Garrison" | "Garrison" | |||||||||||||||||||||||||||||||||
]); | ]); | |||||||||||||||||||||||||||||||||
// When leaving a foundation, we want to be clear of it by this distance. | // When leaving a foundation, we want to be clear of it by this distance. | |||||||||||||||||||||||||||||||||
var g_LeaveFoundationRange = 4; | var g_LeaveFoundationRange = 4; | |||||||||||||||||||||||||||||||||
var GetPatrolState = () => | ||||||||||||||||||||||||||||||||||
StanUnsubmitted Not Done Inline ActionsAny reason it's not in the prototype? Stan: Any reason it's not in the prototype? | ||||||||||||||||||||||||||||||||||
wraitiiAuthorUnsubmitted Done Inline ActionsI don't need to store this, it's used to generate the FSM spec. wraitii: I don't need to store this, it's used to generate the FSM spec. | ||||||||||||||||||||||||||||||||||
StanUnsubmitted Not Done Inline ActionsI guess it could be const then also pretty sure you don't need the return ? () => {return a } == () => a ? Stan: I guess it could be const then also pretty sure you don't need the return ?
() => {return a }… | ||||||||||||||||||||||||||||||||||
bbUnsubmitted Not Done Inline ActionsDon't think this is the way to avoid duplication in the unitAI. Also formations don;t need the animation changes. I rather go in the way of D2662, but that needs further designing. For now just clutter along in the messy fsm imo bb: Don't think this is the way to avoid duplication in the unitAI. Also formations don;t need the… | ||||||||||||||||||||||||||||||||||
wraitiiAuthorUnsubmitted Done Inline ActionsIt makes it slightly easier to navigate for me since Sublime picks up on the dict better, but ay', I'll revert that change. wraitii: It makes it slightly easier to navigate for me since Sublime picks up on the dict better, but… | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||
"enter": function() { | ||||||||||||||||||||||||||||||||||
// Memorize the origin position in case that we want to go back | ||||||||||||||||||||||||||||||||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||||||||||||||||||||||||||||||||
if (!cmpPosition || !cmpPosition.IsInWorld()) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.FinishOrder(); | ||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
if (!this.patrolStartPosOrder) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder = cmpPosition.GetPosition(); | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder.targetClasses = this.order.data.targetClasses; | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder.allowCapture = this.order.data.allowCapture; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
this.SetAnimationVariant("combat"); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"leave": function() { | ||||||||||||||||||||||||||||||||||
delete this.patrolStartPosOrder; | ||||||||||||||||||||||||||||||||||
this.SetDefaultAnimationVariant(); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"PATROLLING": { | ||||||||||||||||||||||||||||||||||
"enter": function() { | ||||||||||||||||||||||||||||||||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||||||||||||||||||||||||||||||||
if (!cmpPosition || !cmpPosition.IsInWorld() || | ||||||||||||||||||||||||||||||||||
!this.MoveTo(this.order.data)) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.FinishOrder(); | ||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
this.StartTimer(0, 1000); | ||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"leave": function() { | ||||||||||||||||||||||||||||||||||
this.StopMoving(); | ||||||||||||||||||||||||||||||||||
this.StopTimer(); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"Timer": function(msg) { | ||||||||||||||||||||||||||||||||||
this.FindWalkAndFightTargets(); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"MovementUpdate": function(msg) { | ||||||||||||||||||||||||||||||||||
if (!msg.likelyFailure && !msg.likelySuccess && !this.RelaxedMaxRangeCheck(this.order.data, this.DefaultRelaxedMaxRange)) | ||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||
if (this.orderQueue.length == 1) | ||||||||||||||||||||||||||||||||||
this.PushOrder("Patrol", this.patrolStartPosOrder); | ||||||||||||||||||||||||||||||||||
this.PushOrder(this.order.type, this.order.data); | ||||||||||||||||||||||||||||||||||
this.SetNextState("CHECKINGWAYPOINT"); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"CHECKINGWAYPOINT": { | ||||||||||||||||||||||||||||||||||
"enter": function() { | ||||||||||||||||||||||||||||||||||
this.StartTimer(0, 1000); | ||||||||||||||||||||||||||||||||||
this.stopSurveying = 0; | ||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"leave": function() { | ||||||||||||||||||||||||||||||||||
this.StopTimer(); | ||||||||||||||||||||||||||||||||||
delete this.stopSurveying; | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"Timer": function(msg) { | ||||||||||||||||||||||||||||||||||
bbUnsubmitted Not Done Inline Actionsslightly out of scope, but why aren't we using a rangeQuery here and depend on timers? bb: slightly out of scope, but why aren't we using a rangeQuery here and depend on timers? | ||||||||||||||||||||||||||||||||||
wraitiiAuthorUnsubmitted Done Inline ActionsMh, what do you mean? The point is to pretend we're looking around, so I don't see how a range query would help? wraitii: Mh, what do you mean? The point is to pretend we're looking around, so I don't see how a range… | ||||||||||||||||||||||||||||||||||
bbUnsubmitted Not Done Inline ActionsSame comment applies to the (current) Patrolling state: we currently idle and check every 1000ms if there is some target near. But why we have this timer? Why not an active rangeQuery that informs us when a unit is close, so we react on that? Anyway seems out of scope for this patch though. bb: Same comment applies to the (current) Patrolling state: we currently idle and check every… | ||||||||||||||||||||||||||||||||||
wraitiiAuthorUnsubmitted Done Inline ActionsAh, yes, I see. wraitii: Ah, yes, I see.
I need a timer here anyways because the unit needs to stop "looking around"… | ||||||||||||||||||||||||||||||||||
FreagarachUnsubmitted Not Done Inline ActionsFreagarach: #5822 | ||||||||||||||||||||||||||||||||||
FreagarachUnsubmitted Not Done Inline Actions
Freagarach: > slightly out of scope, but why aren't we using a rangeQuery here and depend on timers?
| ||||||||||||||||||||||||||||||||||
if (this.stopSurveying > 2) | ||||||||||||||||||||||||||||||||||
bbUnsubmitted Not Done Inline ActionsInstead of hardcoding it, rather make it a template value. bb: Instead of hardcoding it, rather make it a template value. | ||||||||||||||||||||||||||||||||||
wraitiiAuthorUnsubmitted Done Inline Actions? wraitii: ? | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.FinishOrder(); | ||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
this.FindWalkAndFightTargets(); | ||||||||||||||||||||||||||||||||||
this.stopSurveying++; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||
// See ../helpers/FSM.js for some documentation of this FSM specification syntax | // See ../helpers/FSM.js for some documentation of this FSM specification syntax | |||||||||||||||||||||||||||||||||
UnitAI.prototype.UnitFsmSpec = { | UnitAI.prototype.UnitFsmSpec = { | |||||||||||||||||||||||||||||||||
// Default event handlers: | // Default event handlers: | |||||||||||||||||||||||||||||||||
"MovementUpdate": function(msg) { | "MovementUpdate": function(msg) { | |||||||||||||||||||||||||||||||||
// ignore spurious movement messages | // ignore spurious movement messages | |||||||||||||||||||||||||||||||||
// (these can happen when stopping moving at the same time | // (these can happen when stopping moving at the same time | |||||||||||||||||||||||||||||||||
▲ Show 20 Lines • Show All 334 Lines • ▼ Show 20 Lines | "Order.Patrol": function(msg) { | |||||||||||||||||||||||||||||||||
{ | { | |||||||||||||||||||||||||||||||||
this.PushOrderFront("Pack", { "force": true }); | this.PushOrderFront("Pack", { "force": true }); | |||||||||||||||||||||||||||||||||
return; | return; | |||||||||||||||||||||||||||||||||
} | } | |||||||||||||||||||||||||||||||||
// It's not too bad if we don't arrive at exactly the right position. | // It's not too bad if we don't arrive at exactly the right position. | |||||||||||||||||||||||||||||||||
this.order.data.relaxed = true; | this.order.data.relaxed = true; | |||||||||||||||||||||||||||||||||
this.SetNextState("INDIVIDUAL.PATROL"); | this.SetNextState("INDIVIDUAL.PATROL.PATROLLING"); | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"Order.Heal": function(msg) { | "Order.Heal": function(msg) { | |||||||||||||||||||||||||||||||||
// Check the target is alive | // Check the target is alive | |||||||||||||||||||||||||||||||||
if (!this.TargetIsAlive(this.order.data.target)) | if (!this.TargetIsAlive(this.order.data.target)) | |||||||||||||||||||||||||||||||||
{ | { | |||||||||||||||||||||||||||||||||
this.FinishOrder(); | this.FinishOrder(); | |||||||||||||||||||||||||||||||||
return; | return; | |||||||||||||||||||||||||||||||||
▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | "Order.WalkToPointRange": function(msg) { | |||||||||||||||||||||||||||||||||
if (!this.CheckRange(this.order.data)) | if (!this.CheckRange(this.order.data)) | |||||||||||||||||||||||||||||||||
this.SetNextState("WALKING"); | this.SetNextState("WALKING"); | |||||||||||||||||||||||||||||||||
else | else | |||||||||||||||||||||||||||||||||
this.FinishOrder(); | this.FinishOrder(); | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"Order.Patrol": function(msg) { | "Order.Patrol": function(msg) { | |||||||||||||||||||||||||||||||||
this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | |||||||||||||||||||||||||||||||||
this.SetNextState("PATROL"); | this.SetNextState("PATROL.PATROLLING"); | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"Order.Guard": function(msg) { | "Order.Guard": function(msg) { | |||||||||||||||||||||||||||||||||
this.CallMemberFunction("Guard", [msg.data.target, false]); | this.CallMemberFunction("Guard", [msg.data.target, false]); | |||||||||||||||||||||||||||||||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); | var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); | |||||||||||||||||||||||||||||||||
cmpFormation.Disband(); | cmpFormation.Disband(); | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
▲ Show 20 Lines • Show All 246 Lines • ▼ Show 20 Lines | "WALKINGANDFIGHTING": { | |||||||||||||||||||||||||||||||||
this.FindWalkAndFightTargets(); | this.FindWalkAndFightTargets(); | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"MovementUpdate": function(msg) { | "MovementUpdate": function(msg) { | |||||||||||||||||||||||||||||||||
if (msg.likelyFailure || this.CheckRange(this.order.data)) | if (msg.likelyFailure || this.CheckRange(this.order.data)) | |||||||||||||||||||||||||||||||||
this.FinishOrder(); | this.FinishOrder(); | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"PATROL": { | "PATROL": (() => { | |||||||||||||||||||||||||||||||||
Done Inline ActionsLinter. Freagarach: Linter. | ||||||||||||||||||||||||||||||||||
"enter": function(msg) { | let patrolState = GetPatrolState(); | |||||||||||||||||||||||||||||||||
// Memorize the origin position in case that we want to go back | let og = patrolState.PATROLLING.enter; | |||||||||||||||||||||||||||||||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | patrolState.PATROLLING.enter = function() { | |||||||||||||||||||||||||||||||||
if (!cmpPosition || !cmpPosition.IsInWorld()) | if (og.apply(this)) | |||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.FinishOrder(); | ||||||||||||||||||||||||||||||||||
return true; | return true; | |||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
if (!this.patrolStartPosOrder) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder = cmpPosition.GetPosition(); | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder.targetClasses = this.order.data.targetClasses; | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder.allowCapture = this.order.data.allowCapture; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
if (!this.MoveTo(this.order.data)) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.FinishOrder(); | ||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
this.StartTimer(0, 1000); | ||||||||||||||||||||||||||||||||||
let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); | let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); | |||||||||||||||||||||||||||||||||
cmpFormation.SetRearrange(true); | cmpFormation.SetRearrange(true); | |||||||||||||||||||||||||||||||||
cmpFormation.MoveMembersIntoFormation(true, true, "combat"); | cmpFormation.MoveMembersIntoFormation(true, true, "combat"); | |||||||||||||||||||||||||||||||||
return false; | return false; | |||||||||||||||||||||||||||||||||
}, | }; | |||||||||||||||||||||||||||||||||
return patrolState; | ||||||||||||||||||||||||||||||||||
"Timer": function(msg) { | })(), | |||||||||||||||||||||||||||||||||
// Check if there are no enemies to attack | ||||||||||||||||||||||||||||||||||
this.FindWalkAndFightTargets(); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"leave": function(msg) { | ||||||||||||||||||||||||||||||||||
this.StopTimer(); | ||||||||||||||||||||||||||||||||||
this.StopMoving(); | ||||||||||||||||||||||||||||||||||
delete this.patrolStartPosOrder; | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"MovementUpdate": function(msg) { | ||||||||||||||||||||||||||||||||||
if (!msg.likelyFailure && !this.CheckRange(this.order.data)) | ||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||
* A-B-A-B-..: | ||||||||||||||||||||||||||||||||||
* if the user only commands one patrol order, the patrol will be between | ||||||||||||||||||||||||||||||||||
* the last position and the defined waypoint | ||||||||||||||||||||||||||||||||||
* A-B-C-..-A-B-..: | ||||||||||||||||||||||||||||||||||
* otherwise, the patrol is only between the given patrol commands and the | ||||||||||||||||||||||||||||||||||
* last position is not included (last position = the position where the unit | ||||||||||||||||||||||||||||||||||
* is located at the time of the first patrol order) | ||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||
if (this.orderQueue.length == 1) | ||||||||||||||||||||||||||||||||||
this.PushOrder("Patrol", this.patrolStartPosOrder); | ||||||||||||||||||||||||||||||||||
this.PushOrder(this.order.type, this.order.data); | ||||||||||||||||||||||||||||||||||
this.FinishOrder(); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"GARRISON":{ | "GARRISON":{ | |||||||||||||||||||||||||||||||||
"APPROACHING": { | "APPROACHING": { | |||||||||||||||||||||||||||||||||
"enter": function() { | "enter": function() { | |||||||||||||||||||||||||||||||||
if (!this.MoveToGarrisonRange(this.order.data.target)) | if (!this.MoveToGarrisonRange(this.order.data.target)) | |||||||||||||||||||||||||||||||||
{ | { | |||||||||||||||||||||||||||||||||
this.FinishOrder(); | this.FinishOrder(); | |||||||||||||||||||||||||||||||||
return true; | return true; | |||||||||||||||||||||||||||||||||
} | } | |||||||||||||||||||||||||||||||||
let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); | let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); | |||||||||||||||||||||||||||||||||
cmpFormation.SetRearrange(true); | cmpFormation.SetRearrange(true); | |||||||||||||||||||||||||||||||||
cmpFormation.MoveMembersIntoFormation(true, true); | cmpFormation.MoveMembersIntoFormation(true, true); | |||||||||||||||||||||||||||||||||
// If the garrisonholder should pickup, warn it so it can take needed action. | // If the garrisonholder should pickup, warn it so it can take needed action. | |||||||||||||||||||||||||||||||||
let cmpGarrisonHolder = Engine.QueryInterface(this.order.data.target, IID_GarrisonHolder); | let cmpGarrisonHolder = Engine.QueryInterface(this.order.data.target, IID_GarrisonHolder); | |||||||||||||||||||||||||||||||||
if (cmpGarrisonHolder && cmpGarrisonHolder.CanPickup(this.entity)) | if (cmpGarrisonHolder && cmpGarrisonHolder.CanPickup(this.entity)) | |||||||||||||||||||||||||||||||||
{ | { | |||||||||||||||||||||||||||||||||
this.pickup = this.order.data.target; // temporary, deleted in "leave" | this.pickup = this.order.data.target; // temporary, deleted in "leave" | |||||||||||||||||||||||||||||||||
Engine.PostMessage(this.pickup, MT_PickupRequested, { "entity": this.entity }); | Engine.PostMessage(this.pickup, MT_PickupRequested, { "entity": this.entity }); | |||||||||||||||||||||||||||||||||
} | } | |||||||||||||||||||||||||||||||||
Not Done Inline Actions
? Freagarach: ? | ||||||||||||||||||||||||||||||||||
Done Inline ActionsHm, to be honest I'd rather not keep using that FSM feature. Id anything, I'd go back to the "call a function that returns a dict" approach for this. wraitii: Hm, to be honest I'd rather not keep using that FSM feature. Id anything, I'd go back to the… | ||||||||||||||||||||||||||||||||||
Not Done Inline ActionsWell, it is still there and greatly reduces duplication, so IMHO there is no reason for not using it? Freagarach: Well, it is still there and greatly reduces duplication, so IMHO there is no reason for not… | ||||||||||||||||||||||||||||||||||
Done Inline ActionsCore reason is I disagree that it "greatly reduces duplication" since the rest of the patrol state is also mostly duplicated, and in generation formations are duplicated. wraitii: Core reason is I disagree that it "greatly reduces duplication" since the rest of the patrol… | ||||||||||||||||||||||||||||||||||
return false; | return false; | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"leave": function() { | "leave": function() { | |||||||||||||||||||||||||||||||||
this.StopMoving(); | this.StopMoving(); | |||||||||||||||||||||||||||||||||
// If a pickup has been requested and not yet canceled, cancel it. | // If a pickup has been requested and not yet canceled, cancel it. | |||||||||||||||||||||||||||||||||
if (this.pickup) | if (this.pickup) | |||||||||||||||||||||||||||||||||
▲ Show 20 Lines • Show All 542 Lines • ▼ Show 20 Lines | "WALKINGANDFIGHTING": { | |||||||||||||||||||||||||||||||||
"MovementUpdate": function(msg) { | "MovementUpdate": function(msg) { | |||||||||||||||||||||||||||||||||
// If it looks like the path is failing, and we are close enough (3 tiles) | // If it looks like the path is failing, and we are close enough (3 tiles) | |||||||||||||||||||||||||||||||||
// stop anyways. This avoids pathing for an unreachable goal and reduces lag considerably. | // stop anyways. This avoids pathing for an unreachable goal and reduces lag considerably. | |||||||||||||||||||||||||||||||||
if (msg.likelyFailure || msg.obstructed && this.RelaxedMaxRangeCheck(this.order.data, this.DefaultRelaxedMaxRange) || | if (msg.likelyFailure || msg.obstructed && this.RelaxedMaxRangeCheck(this.order.data, this.DefaultRelaxedMaxRange) || | |||||||||||||||||||||||||||||||||
this.CheckRange(this.order.data)) | this.CheckRange(this.order.data)) | |||||||||||||||||||||||||||||||||
this.FinishOrder(); | this.FinishOrder(); | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"PATROL": { | "PATROL": GetPatrolState(), | |||||||||||||||||||||||||||||||||
Done Inline ActionsLinter. Freagarach: Linter. | ||||||||||||||||||||||||||||||||||
"enter": function() { | ||||||||||||||||||||||||||||||||||
// Memorize the origin position in case that we want to go back | ||||||||||||||||||||||||||||||||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||||||||||||||||||||||||||||||||
if (!cmpPosition || !cmpPosition.IsInWorld() || | ||||||||||||||||||||||||||||||||||
!this.MoveTo(this.order.data)) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.FinishOrder(); | ||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
if (!this.patrolStartPosOrder) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder = cmpPosition.GetPosition(); | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder.targetClasses = this.order.data.targetClasses; | ||||||||||||||||||||||||||||||||||
this.patrolStartPosOrder.allowCapture = this.order.data.allowCapture; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
this.StartTimer(0, 1000); | ||||||||||||||||||||||||||||||||||
this.SetAnimationVariant("combat"); | ||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"leave": function() { | ||||||||||||||||||||||||||||||||||
this.StopMoving(); | ||||||||||||||||||||||||||||||||||
this.StopTimer(); | ||||||||||||||||||||||||||||||||||
delete this.patrolStartPosOrder; | ||||||||||||||||||||||||||||||||||
this.SetDefaultAnimationVariant(); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"Timer": function(msg) { | ||||||||||||||||||||||||||||||||||
this.FindWalkAndFightTargets(); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"MovementUpdate": function(msg) { | ||||||||||||||||||||||||||||||||||
if (!msg.likelyFailure && !msg.likelySuccess && !this.RelaxedMaxRangeCheck(this.order.data, this.DefaultRelaxedMaxRange)) | ||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||
if (this.orderQueue.length == 1) | ||||||||||||||||||||||||||||||||||
this.PushOrder("Patrol", this.patrolStartPosOrder); | ||||||||||||||||||||||||||||||||||
this.PushOrder(this.order.type, this.order.data); | ||||||||||||||||||||||||||||||||||
this.FinishOrder(); | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
"GUARD": { | "GUARD": { | |||||||||||||||||||||||||||||||||
"RemoveGuard": function() { | "RemoveGuard": function() { | |||||||||||||||||||||||||||||||||
this.StopMoving(); | this.StopMoving(); | |||||||||||||||||||||||||||||||||
this.FinishOrder(); | this.FinishOrder(); | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"ESCORTING": { | "ESCORTING": { | |||||||||||||||||||||||||||||||||
"enter": function() { | "enter": function() { | |||||||||||||||||||||||||||||||||
if (!this.MoveToTargetRangeExplicit(this.isGuardOf, 0, this.guardRange)) | if (!this.MoveToTargetRangeExplicit(this.isGuardOf, 0, this.guardRange)) | |||||||||||||||||||||||||||||||||
{ | { | |||||||||||||||||||||||||||||||||
this.FinishOrder(); | this.FinishOrder(); | |||||||||||||||||||||||||||||||||
return true; | return true; | |||||||||||||||||||||||||||||||||
} | } | |||||||||||||||||||||||||||||||||
Not Done Inline ActionsThis makes them wait at least one second (also birds). Freagarach: This makes them wait at least one second (also birds). | ||||||||||||||||||||||||||||||||||
Done Inline ActionsChanged to >= wraitii: Changed to >= | ||||||||||||||||||||||||||||||||||
Done Inline ActionsDoes one need a conversion to number here? (+this.template.PatrolWaitTime) Freagarach: Does one need a conversion to number here? (`+this.template.PatrolWaitTime`) | ||||||||||||||||||||||||||||||||||
// Show weapons rather than carried resources. | // Show weapons rather than carried resources. | |||||||||||||||||||||||||||||||||
this.SetAnimationVariant("combat"); | this.SetAnimationVariant("combat"); | |||||||||||||||||||||||||||||||||
this.StartTimer(0, 1000); | this.StartTimer(0, 1000); | |||||||||||||||||||||||||||||||||
this.SetHeldPositionOnEntity(this.isGuardOf); | this.SetHeldPositionOnEntity(this.isGuardOf); | |||||||||||||||||||||||||||||||||
Done Inline Actions
? Freagarach: ? | ||||||||||||||||||||||||||||||||||
return false; | return false; | |||||||||||||||||||||||||||||||||
}, | }, | |||||||||||||||||||||||||||||||||
"Timer": function(msg) { | "Timer": function(msg) { | |||||||||||||||||||||||||||||||||
// Check the target is alive | // Check the target is alive | |||||||||||||||||||||||||||||||||
if (!this.TargetIsAlive(this.isGuardOf)) | if (!this.TargetIsAlive(this.isGuardOf)) | |||||||||||||||||||||||||||||||||
{ | { | |||||||||||||||||||||||||||||||||
this.FinishOrder(); | this.FinishOrder(); | |||||||||||||||||||||||||||||||||
▲ Show 20 Lines • Show All 4,796 Lines • Show Last 20 Lines |
Seconds, minutes, ms?