Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 1,680 Lines • ▼ Show 20 Lines | "GUARD": { | ||||
this.SetDefaultAnimationVariant(); | this.SetDefaultAnimationVariant(); | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
"FLEEING": { | "FLEEING": { | ||||
"enter": function() { | "enter": function() { | ||||
// We use the distance between the entities to account for ranged attacks | // We use the distance between the entities to account for ranged attacks | ||||
let distance = DistanceBetweenEntities(this.entity, this.order.data.target) + (+this.template.FleeDistance); | this.order.data.distanceToFlee = DistanceBetweenEntities(this.entity, this.order.data.target) + (+this.template.FleeDistance); | ||||
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); | let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); | ||||
// Use unit motion directly to ignore the visibility check. TODO: change this if we add LOS to fauna. | // Use unit motion directly to ignore the visibility check. TODO: change this if we add LOS to fauna. | ||||
if (this.CheckTargetRangeExplicit(this.order.data.target, distance, distance) || | if (this.CheckTargetRangeExplicit(this.order.data.target, this.order.data.distanceToFlee, -1) || | ||||
!cmpUnitMotion || !cmpUnitMotion.MoveToTargetRange(this.order.data.target, distance, -1)) | !cmpUnitMotion || !cmpUnitMotion.MoveToTargetRange(this.order.data.target, this.order.data.distanceToFlee, -1)) | ||||
{ | { | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return true; | return true; | ||||
} | } | ||||
this.PlaySound("panic"); | this.PlaySound("panic"); | ||||
// Run quickly | // Run quickly | ||||
this.SelectAnimation("move"); | this.SelectAnimation("move"); | ||||
this.SetSpeedMultiplier(this.GetRunMultiplier()); | this.SetSpeedMultiplier(this.GetRunMultiplier()); | ||||
}, | }, | ||||
"HealthChanged": function() { | "HealthChanged": function() { | ||||
this.SetSpeedMultiplier(this.GetRunMultiplier()); | this.SetSpeedMultiplier(this.GetRunMultiplier()); | ||||
}, | }, | ||||
"leave": function() { | "leave": function() { | ||||
this.ResetSpeedMultiplier(); | this.ResetSpeedMultiplier(); | ||||
this.StopMoving(); | this.StopMoving(); | ||||
}, | }, | ||||
"MovementUpdate": function() { | "MovementUpdate": function() { | ||||
// When we've run far enough, stop fleeing | // When we've run far enough, stop fleeing | ||||
if (this.CheckRange(this.order.data)) | if (this.CheckTargetRangeExplicit(this.order.data, this.order.data.distanceToFlee, -1)) | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
}, | }, | ||||
// TODO: what if we run into more enemies while fleeing? | // TODO: what if we run into more enemies while fleeing? | ||||
}, | }, | ||||
"COMBAT": { | "COMBAT": { | ||||
"Order.LeaveFoundation": function(msg) { | "Order.LeaveFoundation": function(msg) { | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | "COMBAT": { | ||||
// Can't reach it - try to chase after it | // Can't reach it - try to chase after it | ||||
if (this.ShouldChaseTargetedEntity(target, this.order.data.force)) | if (this.ShouldChaseTargetedEntity(target, this.order.data.force)) | ||||
{ | { | ||||
if (this.CanPack()) | if (this.CanPack()) | ||||
{ | { | ||||
this.PushOrderFront("Pack", { "force": true }); | this.PushOrderFront("Pack", { "force": true }); | ||||
return; | return; | ||||
} | } | ||||
if (this.MoveToTargetAttackRange(target, this.order.data.attackType)) | |||||
{ | |||||
this.SetNextState("COMBAT.CHASING"); | this.SetNextState("COMBAT.CHASING"); | ||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
} | |||||
this.StopMoving(); | this.StopMoving(); | ||||
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); | var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); | ||||
this.attackTimers = cmpAttack.GetTimers(this.order.data.attackType); | this.attackTimers = cmpAttack.GetTimers(this.order.data.attackType); | ||||
// If the repeat time since the last attack hasn't elapsed, | // If the repeat time since the last attack hasn't elapsed, | ||||
// delay this attack to avoid attacking too fast. | // delay this attack to avoid attacking too fast. | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | "COMBAT": { | ||||
// Can't reach it - try to chase after it | // Can't reach it - try to chase after it | ||||
if (this.ShouldChaseTargetedEntity(target, this.order.data.force)) | if (this.ShouldChaseTargetedEntity(target, this.order.data.force)) | ||||
{ | { | ||||
if (this.CanPack()) | if (this.CanPack()) | ||||
{ | { | ||||
this.PushOrderFront("Pack", { "force": true }); | this.PushOrderFront("Pack", { "force": true }); | ||||
return; | return; | ||||
} | } | ||||
if (this.MoveToTargetRange(target, IID_Attack, this.order.data.attackType)) | |||||
{ | |||||
this.SetNextState("COMBAT.CHASING"); | this.SetNextState("COMBAT.CHASING"); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
} | |||||
// if we're targetting a formation, find a new member of that formation | // if we're targetting a formation, find a new member of that formation | ||||
var cmpTargetFormation = Engine.QueryInterface(this.order.data.formationTarget || INVALID_ENTITY, IID_Formation); | var cmpTargetFormation = Engine.QueryInterface(this.order.data.formationTarget || INVALID_ENTITY, IID_Formation); | ||||
// if there is no target, it means previously searching for the target inside the target formation failed, so don't repeat the search | // if there is no target, it means previously searching for the target inside the target formation failed, so don't repeat the search | ||||
if (target && cmpTargetFormation) | if (target && cmpTargetFormation) | ||||
{ | { | ||||
this.order.data.target = this.order.data.formationTarget; | this.order.data.target = this.order.data.formationTarget; | ||||
this.TimerHandler(msg.data, msg.lateness); | this.TimerHandler(msg.data, msg.lateness); | ||||
Show All 33 Lines | "COMBAT": { | ||||
if (this.order.data.attackType == "Capture" && (this.GetStance().targetAttackersAlways || !this.order.data.force) | if (this.order.data.attackType == "Capture" && (this.GetStance().targetAttackersAlways || !this.order.data.force) | ||||
&& this.order.data.target != msg.data.attacker && this.GetBestAttackAgainst(msg.data.attacker, true) != "Capture") | && this.order.data.target != msg.data.attacker && this.GetBestAttackAgainst(msg.data.attacker, true) != "Capture") | ||||
this.RespondToTargetedEntities([msg.data.attacker]); | this.RespondToTargetedEntities([msg.data.attacker]); | ||||
}, | }, | ||||
}, | }, | ||||
"CHASING": { | "CHASING": { | ||||
"enter": function() { | "enter": function() { | ||||
if (!this.MoveTo(this.order.data)) | if (!this.MoveToTargetAttackRange(this.order.data.target, this.order.data.attackType)) | ||||
{ | { | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return true; | return true; | ||||
} | } | ||||
// Show weapons rather than carried resources. | // Show weapons rather than carried resources. | ||||
this.SetAnimationVariant("combat"); | this.SetAnimationVariant("combat"); | ||||
▲ Show 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | "GATHER": { | ||||
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; | ||||
} | } | ||||
// Can't reach the target, or it doesn't exist any more | |||||
// 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 | |||||
// last known position | |||||
var maxRange = 8; // get close but not too close | |||||
if (this.order.data.lastPos && | |||||
this.MoveToPointRange(this.order.data.lastPos.x, this.order.data.lastPos.z, 0, maxRange)) | |||||
{ | |||||
this.SetNextState("APPROACHING"); | |||||
return; | |||||
} | |||||
} | } | ||||
} | } | ||||
// 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; | var 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 | ||||
▲ Show 20 Lines • Show All 277 Lines • ▼ Show 20 Lines | "TRADE": { | ||||
if (otherMarket) | if (otherMarket) | ||||
this.WalkToTarget(otherMarket); | this.WalkToTarget(otherMarket); | ||||
}, | }, | ||||
}, | }, | ||||
"REPAIR": { | "REPAIR": { | ||||
"APPROACHING": { | "APPROACHING": { | ||||
"enter": function() { | "enter": function() { | ||||
if (!this.MoveTo(this.order.data)) | if (!this.MoveTo(this.order.data, IID_Builder)) | ||||
{ | { | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return true; | return true; | ||||
} | } | ||||
this.SelectAnimation("move"); | this.SelectAnimation("move"); | ||||
}, | }, | ||||
"leave": function() { | "leave": function() { | ||||
Show All 21 Lines | "REPAIR": { | ||||
{ | { | ||||
// Can't reach it, no longer owned by ally, or it doesn't exist any more | // Can't reach it, no longer owned by ally, or it doesn't exist any more | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return true; | return true; | ||||
} | } | ||||
if (!this.CheckTargetRange(this.repairTarget, IID_Builder)) | if (!this.CheckTargetRange(this.repairTarget, IID_Builder)) | ||||
{ | { | ||||
if (this.MoveToTargetRange(this.repairTarget, IID_Builder)) | |||||
this.SetNextState("APPROACHING"); | this.SetNextState("APPROACHING"); | ||||
else | |||||
this.FinishOrder(); | |||||
return true; | return true; | ||||
} | } | ||||
// Check if the target is still repairable | // Check if the target is still repairable | ||||
var cmpHealth = Engine.QueryInterface(this.repairTarget, IID_Health); | var cmpHealth = Engine.QueryInterface(this.repairTarget, IID_Health); | ||||
if (cmpHealth && cmpHealth.GetHitpoints() >= cmpHealth.GetMaxHitpoints()) | if (cmpHealth && cmpHealth.GetHitpoints() >= cmpHealth.GetMaxHitpoints()) | ||||
{ | { | ||||
// The building was already finished/fully repaired before we arrived; | // The building was already finished/fully repaired before we arrived; | ||||
// let the ConstructionFinished handler handle this. | // let the ConstructionFinished handler handle this. | ||||
Show All 31 Lines | "REPAIR": { | ||||
var cmpBuilder = Engine.QueryInterface(this.entity, IID_Builder); | var cmpBuilder = Engine.QueryInterface(this.entity, IID_Builder); | ||||
cmpBuilder.PerformBuilding(this.repairTarget); | cmpBuilder.PerformBuilding(this.repairTarget); | ||||
// if the building is completed, the leave() function will be called | // if the building is completed, the leave() function will be called | ||||
// by the ConstructionFinished message | // by the ConstructionFinished message | ||||
// in that case, the repairTarget is deleted, and we can just return | // in that case, the repairTarget is deleted, and we can just return | ||||
if (!this.repairTarget) | if (!this.repairTarget) | ||||
return; | return; | ||||
let inRange = this.CheckTargetRange(this.repairTarget, IID_Builder); | if (!this.CheckTargetRange(this.repairTarget, IID_Builder)) | ||||
if (!inRange && this.MoveToTargetRange(this.repairTarget, IID_Builder)) | |||||
this.SetNextState("APPROACHING"); | this.SetNextState("APPROACHING"); | ||||
else if (!inRange) | |||||
this.FinishOrder(); //can't approach and isn't in reach | |||||
}, | }, | ||||
}, | }, | ||||
"ConstructionFinished": function(msg) { | "ConstructionFinished": function(msg) { | ||||
if (msg.data.entity != this.order.data.target) | if (msg.data.entity != this.order.data.target) | ||||
return; // ignore other buildings | return; // ignore other buildings | ||||
// Save the current order's data in case we need it later | // Save the current order's data in case we need it later | ||||
▲ Show 20 Lines • Show All 3,269 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator