Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 187 Lines • ▼ Show 20 Lines | UnitAI.prototype.UnitFsmSpec = { | ||||
"TradingCanceled": function(msg) { | "TradingCanceled": function(msg) { | ||||
// ignore | // ignore | ||||
}, | }, | ||||
"GuardedAttacked": function(msg) { | "GuardedAttacked": function(msg) { | ||||
// ignore | // ignore | ||||
}, | }, | ||||
"HealingStateChanged": function(msg) { | |||||
// ignore | |||||
}, | |||||
// Formation handlers: | // Formation handlers: | ||||
"FormationLeave": function(msg) { | "FormationLeave": function(msg) { | ||||
// ignore when we're not in FORMATIONMEMBER | // ignore when we're not in FORMATIONMEMBER | ||||
}, | }, | ||||
// Called when being told to walk as part of a formation | // Called when being told to walk as part of a formation | ||||
"Order.FormationWalk": function(msg) { | "Order.FormationWalk": function(msg) { | ||||
▲ Show 20 Lines • Show All 2,310 Lines • ▼ Show 20 Lines | "HEAL": { | ||||
"HEALING": { | "HEALING": { | ||||
"enter": function() { | "enter": function() { | ||||
if (!this.CheckRange(this.order.data, IID_Heal)) | if (!this.CheckRange(this.order.data, IID_Heal)) | ||||
{ | { | ||||
this.SetNextState("APPROACHING"); | this.SetNextState("APPROACHING"); | ||||
return true; | return true; | ||||
} | } | ||||
if (!this.TargetIsAlive(this.order.data.target) || | if (!this.TargetIsAlive(this.order.data.target) || | ||||
!this.CanHeal(this.order.data.target)) | !this.CanHeal(this.order.data.target)) | ||||
Freagarach: D2403. | |||||
Done Inline ActionsWhy not IsTargetInRange from cmpHeal? Stan: Why not IsTargetInRange from cmpHeal? | |||||
Done Inline ActionsThis is more in line with the rest of unitAI code which will help make things more standard -> rather pass the component over IID_Heal perhaps, but I'd keep a common path (see also gathering, the garrisoning/turret changes, etc.) wraitii: This is more in line with the rest of unitAI code which will help make things more standard ->… | |||||
{ | { | ||||
this.SetNextState("FINDINGNEWTARGET"); | this.SetNextState("FINDINGNEWTARGET"); | ||||
return true; | return true; | ||||
} | } | ||||
let cmpHeal = Engine.QueryInterface(this.entity, IID_Heal); | let cmpHeal = Engine.QueryInterface(this.entity, IID_Heal); | ||||
this.healTimers = cmpHeal.GetTimers(); | let healTimers = cmpHeal.StartHealing(this.order.data.target); | ||||
this.StartTimer(healTimers.prepare, healTimers.repeat); | |||||
// If the repeat time since the last heal hasn't elapsed, | |||||
// delay the action to avoid healing too fast. | |||||
var prepare = this.healTimers.prepare; | |||||
if (this.lastHealed) | |||||
{ | |||||
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | |||||
var repeatLeft = this.lastHealed + this.healTimers.repeat - cmpTimer.GetTime(); | |||||
prepare = Math.max(prepare, repeatLeft); | |||||
} | |||||
this.SelectAnimation("heal"); | |||||
this.SetAnimationSync(prepare, this.healTimers.repeat); | |||||
this.StartTimer(prepare, this.healTimers.repeat); | |||||
// If using a non-default prepare time, re-sync the animation when the timer runs. | |||||
this.resyncAnimation = prepare != this.healTimers.prepare; | |||||
this.FaceTowardsTarget(this.order.data.target); | this.FaceTowardsTarget(this.order.data.target); | ||||
return false; | return false; | ||||
}, | }, | ||||
"leave": function() { | "leave": function() { | ||||
this.ResetAnimation(); | let cmpHeal = Engine.QueryInterface(this.entity, IID_Heal); | ||||
if (cmpHeal) | |||||
cmpHeal.StopHealing(); | |||||
this.StopTimer(); | this.StopTimer(); | ||||
}, | }, | ||||
"HealingStateChanged": function(msg) { | |||||
if (msg.healed) | |||||
this.SetNextState("FINDINGNEWTARGET"); | |||||
}, | |||||
"Timer": function(msg) { | "Timer": function(msg) { | ||||
let target = this.order.data.target; | let target = this.order.data.target; | ||||
// Check the target is still alive and healable | // Check the target is still alive and healable | ||||
if (!this.TargetIsAlive(target) || !this.CanHeal(target)) | if (!this.TargetIsAlive(target) || !this.CanHeal(target)) | ||||
{ | { | ||||
this.SetNextState("FINDINGNEWTARGET"); | this.SetNextState("FINDINGNEWTARGET"); | ||||
return; | return; | ||||
} | } | ||||
Show All 10 Lines | "HEAL": { | ||||
} | } | ||||
this.SetNextState("HEAL.APPROACHING"); | this.SetNextState("HEAL.APPROACHING"); | ||||
} | } | ||||
else | else | ||||
this.SetNextState("FINDINGNEWTARGET"); | this.SetNextState("FINDINGNEWTARGET"); | ||||
return; | return; | ||||
} | } | ||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | |||||
this.lastHealed = cmpTimer.GetTime() - msg.lateness; | |||||
this.FaceTowardsTarget(target); | this.FaceTowardsTarget(target); | ||||
let cmpHeal = Engine.QueryInterface(this.entity, IID_Heal); | |||||
cmpHeal.PerformHeal(target); | |||||
if (this.resyncAnimation) | |||||
{ | |||||
this.SetAnimationSync(this.healTimers.repeat, this.healTimers.repeat); | |||||
this.resyncAnimation = false; | |||||
} | |||||
}, | }, | ||||
}, | }, | ||||
Done Inline ActionsFreagarach: D2403. | |||||
"FINDINGNEWTARGET": { | "FINDINGNEWTARGET": { | ||||
"enter": function() { | "enter": function() { | ||||
// If we have another order, do that instead. | // If we have another order, do that instead. | ||||
if (this.FinishOrder()) | if (this.FinishOrder()) | ||||
return true; | return true; | ||||
// Heal another one | // Heal another one | ||||
if (this.FindNewHealTargets()) | if (this.FindNewHealTargets()) | ||||
▲ Show 20 Lines • Show All 713 Lines • ▼ Show 20 Lines | UnitAI.prototype.Init = function() | ||||
// Queue of remembered works | // Queue of remembered works | ||||
this.workOrders = []; | this.workOrders = []; | ||||
this.isGuardOf = undefined; | this.isGuardOf = undefined; | ||||
// For preventing increased action rate due to Stop orders or target death. | // For preventing increased action rate due to Stop orders or target death. | ||||
this.lastAttacked = undefined; | this.lastAttacked = undefined; | ||||
this.lastHealed = undefined; | this.lastHealed = undefined; | ||||
Done Inline ActionsDel. Freagarach: Del. | |||||
this.formationAnimationVariant = undefined; | this.formationAnimationVariant = undefined; | ||||
this.SetStance(this.template.DefaultStance); | this.SetStance(this.template.DefaultStance); | ||||
}; | }; | ||||
UnitAI.prototype.IsTurret = function() | UnitAI.prototype.IsTurret = function() | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 794 Lines • ▼ Show 20 Lines | else if (msg.tag == this.losHealRangeQuery) | ||||
this.UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg}); | this.UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg}); | ||||
}; | }; | ||||
UnitAI.prototype.OnPackFinished = function(msg) | UnitAI.prototype.OnPackFinished = function(msg) | ||||
{ | { | ||||
this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed}); | this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed}); | ||||
}; | }; | ||||
UnitAI.prototype.OnHealingStateChanged = function(msg) | |||||
{ | |||||
this.UnitFsm.ProcessMessage(this, { "type": "HealingStateChanged", "data": msg }); | |||||
}; | |||||
//// Helper functions to be called by the FSM //// | //// Helper functions to be called by the FSM //// | ||||
UnitAI.prototype.GetWalkSpeed = function() | UnitAI.prototype.GetWalkSpeed = function() | ||||
{ | { | ||||
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); | let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); | ||||
if (!cmpUnitMotion) | if (!cmpUnitMotion) | ||||
return 0; | return 0; | ||||
return cmpUnitMotion.GetWalkSpeed(); | return cmpUnitMotion.GetWalkSpeed(); | ||||
▲ Show 20 Lines • Show All 2,121 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
D2403.