Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 363 Lines • ▼ Show 20 Lines | "Order.PickupUnit": function(msg) { | ||||
// Check if we need to move | // Check if we need to move | ||||
// If the target can reach us and we are reasonably close, don't move. | // If the target can reach us and we are reasonably close, don't move. | ||||
// TODO: it would be slightly more optimal to check for real, not bird-flight distance. | // TODO: it would be slightly more optimal to check for real, not bird-flight distance. | ||||
let cmpPassengerMotion = Engine.QueryInterface(msg.data.target, IID_UnitMotion); | let cmpPassengerMotion = Engine.QueryInterface(msg.data.target, IID_UnitMotion); | ||||
if (cmpPassengerMotion && | if (cmpPassengerMotion && | ||||
cmpPassengerMotion.IsTargetRangeReachable(this.entity, range.min, range.max) && | cmpPassengerMotion.IsTargetRangeReachable(this.entity, range.min, range.max) && | ||||
PositionHelper.DistanceBetweenEntities(this.entity, msg.data.target) < 200) | PositionHelper.DistanceBetweenEntities(this.entity, msg.data.target) < 200) | ||||
this.SetNextState("INDIVIDUAL.PICKUP.LOADING"); | this.SetNextState("INDIVIDUAL.PICKUP.LOADING"); | ||||
else | else if (this.AbleToMove()) | ||||
this.SetNextState("INDIVIDUAL.PICKUP.APPROACHING"); | this.SetNextState("INDIVIDUAL.PICKUP.APPROACHING"); | ||||
else | |||||
return this.FinishOrder(); | |||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Guard": function(msg) { | "Order.Guard": function(msg) { | ||||
if (!this.AddGuard(msg.data.target)) | if (!this.AddGuard(msg.data.target)) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
if (!this.CheckTargetRangeExplicit(this.isGuardOf, 0, this.guardRange)) | if (this.CheckTargetRangeExplicit(this.isGuardOf, 0, this.guardRange)) | ||||
this.SetNextState("INDIVIDUAL.GUARD.GUARDING"); | |||||
else if (this.AbleToMove()) | |||||
this.SetNextState("INDIVIDUAL.GUARD.ESCORTING"); | this.SetNextState("INDIVIDUAL.GUARD.ESCORTING"); | ||||
else | else | ||||
this.SetNextState("INDIVIDUAL.GUARD.GUARDING"); | return this.FinishOrder(); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Flee": function(msg) { | "Order.Flee": function(msg) { | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.SetNextState("INDIVIDUAL.FLEEING"); | this.SetNextState("INDIVIDUAL.FLEEING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Attack": function(msg) { | "Order.Attack": function(msg) { | ||||
let type = this.GetBestAttackAgainst(msg.data.target, msg.data.allowCapture); | let type = this.GetBestAttackAgainst(msg.data.target, msg.data.allowCapture); | ||||
if (!type) | if (!type) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | "Order.Heal": function(msg) { | ||||
if (msg.data.target == this.entity) | if (msg.data.target == this.entity) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
if (this.CheckTargetRange(msg.data.target, IID_Heal)) | if (this.CheckTargetRange(msg.data.target, IID_Heal)) | ||||
{ | { | ||||
this.SetNextState("INDIVIDUAL.HEAL.HEALING"); | this.SetNextState("INDIVIDUAL.HEAL.HEALING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
} | } | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
if (this.GetStance().respondStandGround && !msg.data.force) | if (this.GetStance().respondStandGround && !msg.data.force) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
this.SetNextState("INDIVIDUAL.HEAL.APPROACHING"); | this.SetNextState("INDIVIDUAL.HEAL.APPROACHING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | "Order.Gather": function(msg) { | ||||
} | } | ||||
this.RememberTargetPosition(); | this.RememberTargetPosition(); | ||||
if (!msg.data.initPos) | if (!msg.data.initPos) | ||||
msg.data.initPos = msg.data.lastPos; | msg.data.initPos = msg.data.lastPos; | ||||
if (this.CheckTargetRange(msg.data.target, IID_ResourceGatherer)) | if (this.CheckTargetRange(msg.data.target, IID_ResourceGatherer)) | ||||
this.SetNextState("INDIVIDUAL.GATHER.GATHERING"); | this.SetNextState("INDIVIDUAL.GATHER.GATHERING"); | ||||
else | else if (this.AbleToMove()) | ||||
this.SetNextState("INDIVIDUAL.GATHER.APPROACHING"); | this.SetNextState("INDIVIDUAL.GATHER.APPROACHING"); | ||||
else | |||||
return this.FinishOrder(); | |||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.GatherNearPosition": function(msg) { | "Order.GatherNearPosition": function(msg) { | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.SetNextState("INDIVIDUAL.GATHER.WALKING"); | this.SetNextState("INDIVIDUAL.GATHER.WALKING"); | ||||
msg.data.initPos = { 'x': msg.data.x, 'z': msg.data.z }; | msg.data.initPos = { 'x': msg.data.x, 'z': msg.data.z }; | ||||
msg.data.relaxed = true; | msg.data.relaxed = true; | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.ReturnResource": function(msg) { | "Order.ReturnResource": function(msg) { | ||||
let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | ||||
if (this.CheckTargetRange(msg.data.target, IID_ResourceGatherer) && | if (this.CheckTargetRange(msg.data.target, IID_ResourceGatherer) && | ||||
this.CanReturnResource(msg.data.target, true, cmpResourceGatherer)) | this.CanReturnResource(msg.data.target, true, cmpResourceGatherer)) | ||||
{ | { | ||||
cmpResourceGatherer.CommitResources(msg.data.target); | cmpResourceGatherer.CommitResources(msg.data.target); | ||||
this.SetDefaultAnimationVariant(); | this.SetDefaultAnimationVariant(); | ||||
// Our next order should always be a Gather, | // Our next order should always be a Gather, | ||||
// so just switch back to that order. | // so just switch back to that order. | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
} | } | ||||
else | else if (this.AbleToMove()) | ||||
this.SetNextState("INDIVIDUAL.RETURNRESOURCE.APPROACHING"); | this.SetNextState("INDIVIDUAL.RETURNRESOURCE.APPROACHING"); | ||||
else | |||||
return this.FinishOrder(); | |||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Trade": function(msg) { | "Order.Trade": function(msg) { | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
// We must check if this trader has both markets in case it was a back-to-work order. | // We must check if this trader has both markets in case it was a back-to-work order. | ||||
let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); | let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); | ||||
if (!cmpTrader || !cmpTrader.HasBothMarkets()) | if (!cmpTrader || !cmpTrader.HasBothMarkets()) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
this.waypoints = []; | this.waypoints = []; | ||||
this.SetNextState("TRADE.APPROACHINGMARKET"); | this.SetNextState("TRADE.APPROACHINGMARKET"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Repair": function(msg) { | "Order.Repair": function(msg) { | ||||
if (this.CheckTargetRange(msg.data.target, IID_Builder)) | if (this.CheckTargetRange(msg.data.target, IID_Builder)) | ||||
this.SetNextState("INDIVIDUAL.REPAIR.REPAIRING"); | this.SetNextState("INDIVIDUAL.REPAIR.REPAIRING"); | ||||
else | else if (this.AbleToMove()) | ||||
this.SetNextState("INDIVIDUAL.REPAIR.APPROACHING"); | this.SetNextState("INDIVIDUAL.REPAIR.APPROACHING"); | ||||
else | |||||
return this.FinishOrder(); | |||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Garrison": function(msg) { | "Order.Garrison": function(msg) { | ||||
if (!this.AbleToMove()) | if (!this.AbleToMove()) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
// Also pack when we are in range. | // Also pack when we are in range. | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | else | ||||
this.SetNextState("COLLECTTREASURE"); | this.SetNextState("COLLECTTREASURE"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
// States for the special entity representing a group of units moving in formation: | // States for the special entity representing a group of units moving in formation: | ||||
"FORMATIONCONTROLLER": { | "FORMATIONCONTROLLER": { | ||||
"Order.Walk": function(msg) { | "Order.Walk": function(msg) { | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | ||||
this.SetNextState("WALKING"); | this.SetNextState("WALKING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.WalkAndFight": function(msg) { | "Order.WalkAndFight": function(msg) { | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | ||||
this.SetNextState("WALKINGANDFIGHTING"); | this.SetNextState("WALKINGANDFIGHTING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.MoveIntoFormation": function(msg) { | "Order.MoveIntoFormation": function(msg) { | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | ||||
this.SetNextState("FORMING"); | this.SetNextState("FORMING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
// Only used by other orders to walk there in formation. | // Only used by other orders to walk there in formation. | ||||
"Order.WalkToTargetRange": function(msg) { | "Order.WalkToTargetRange": function(msg) { | ||||
if (this.CheckRange(msg.data)) | if (this.CheckRange(msg.data)) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.SetNextState("WALKING"); | this.SetNextState("WALKING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.WalkToTarget": function(msg) { | "Order.WalkToTarget": function(msg) { | ||||
if (this.CheckRange(msg.data)) | if (this.CheckRange(msg.data)) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.SetNextState("WALKING"); | this.SetNextState("WALKING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.WalkToPointRange": function(msg) { | "Order.WalkToPointRange": function(msg) { | ||||
if (this.CheckRange(msg.data)) | if (this.CheckRange(msg.data)) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.SetNextState("WALKING"); | this.SetNextState("WALKING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Patrol": function(msg) { | "Order.Patrol": function(msg) { | ||||
if (!this.AbleToMove()) | |||||
return this.FinishOrder(); | |||||
this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | ||||
this.SetNextState("PATROL.PATROLLING"); | this.SetNextState("PATROL.PATROLLING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Guard": function(msg) { | "Order.Guard": function(msg) { | ||||
this.CallMemberFunction("Guard", [msg.data.target, false]); | this.CallMemberFunction("Guard", [msg.data.target, false]); | ||||
Engine.QueryInterface(this.entity, IID_Formation).Disband(); | Engine.QueryInterface(this.entity, IID_Formation).Disband(); | ||||
Show All 16 Lines | "Order.Attack": function(msg) { | ||||
let target = msg.data.target; | let target = msg.data.target; | ||||
let allowCapture = msg.data.allowCapture; | let allowCapture = msg.data.allowCapture; | ||||
let cmpTargetUnitAI = Engine.QueryInterface(target, IID_UnitAI); | let cmpTargetUnitAI = Engine.QueryInterface(target, IID_UnitAI); | ||||
if (cmpTargetUnitAI && cmpTargetUnitAI.IsFormationMember()) | if (cmpTargetUnitAI && cmpTargetUnitAI.IsFormationMember()) | ||||
target = cmpTargetUnitAI.GetFormationController(); | target = cmpTargetUnitAI.GetFormationController(); | ||||
if (!this.CheckFormationTargetAttackRange(target)) | if (!this.CheckFormationTargetAttackRange(target)) | ||||
{ | { | ||||
if (this.CanAttack(target) && this.CheckTargetVisible(target)) | if (this.AbleToMove() && this.CheckTargetVisible(target)) | ||||
{ | { | ||||
this.SetNextState("COMBAT.APPROACHING"); | this.SetNextState("COMBAT.APPROACHING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
} | } | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
} | } | ||||
this.CallMemberFunction("Attack", [target, allowCapture, false]); | this.CallMemberFunction("Attack", [target, allowCapture, false]); | ||||
let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); | let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); | ||||
if (cmpAttack && cmpAttack.CanAttackAsFormation()) | if (cmpAttack && cmpAttack.CanAttackAsFormation()) | ||||
this.SetNextState("COMBAT.ATTACKING"); | this.SetNextState("COMBAT.ATTACKING"); | ||||
else | else | ||||
this.SetNextState("MEMBER"); | this.SetNextState("MEMBER"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"Order.Garrison": function(msg) { | "Order.Garrison": function(msg) { | ||||
if (!Engine.QueryInterface(msg.data.target, | if (!Engine.QueryInterface(msg.data.target, | ||||
msg.data.garrison ? IID_GarrisonHolder : IID_TurretHolder)) | msg.data.garrison ? IID_GarrisonHolder : IID_TurretHolder)) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
if (this.CheckTargetRange(msg.data.target, msg.data.garrison ? IID_Garrisonable : IID_Turretable)) | if (this.CheckTargetRange(msg.data.target, msg.data.garrison ? IID_Garrisonable : IID_Turretable)) | ||||
{ | { | ||||
if (!this.CheckTargetVisible(msg.data.target)) | if (!this.AbleToMove() || !this.CheckTargetVisible(msg.data.target)) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
this.SetNextState("GARRISON.APPROACHING"); | this.SetNextState("GARRISON.APPROACHING"); | ||||
} | } | ||||
else | else | ||||
this.SetNextState("GARRISON.GARRISONING"); | this.SetNextState("GARRISON.GARRISONING"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
▲ Show 20 Lines • Show All 1,484 Lines • ▼ Show 20 Lines | "COMBAT": { | ||||
} | } | ||||
return true; | return true; | ||||
}, | }, | ||||
}, | }, | ||||
"CHASING": { | "CHASING": { | ||||
"Order.MoveToChasingPoint": function(msg) { | "Order.MoveToChasingPoint": function(msg) { | ||||
if (this.CheckPointRangeExplicit(msg.data.x, msg.data.z, 0, msg.data.max)) | if (this.CheckPointRangeExplicit(msg.data.x, msg.data.z, 0, msg.data.max) || !this.AbleToMove()) | ||||
return this.FinishOrder(); | return this.FinishOrder(); | ||||
msg.data.relaxed = true; | msg.data.relaxed = true; | ||||
this.StopTimer(); | this.StopTimer(); | ||||
this.SetNextState("MOVINGTOPOINT"); | this.SetNextState("MOVINGTOPOINT"); | ||||
return ACCEPT_ORDER; | return ACCEPT_ORDER; | ||||
}, | }, | ||||
"enter": function() { | "enter": function() { | ||||
if (!this.MoveToTargetAttackRange(this.order.data.target, this.order.data.attackType)) | if (!this.MoveToTargetAttackRange(this.order.data.target, this.order.data.attackType)) | ||||
▲ Show 20 Lines • Show All 3,080 Lines • ▼ Show 20 Lines | UnitAI.prototype.AddOrder = function(type, data, queued, pushFront) | ||||
if (this.expectedRoute) | if (this.expectedRoute) | ||||
this.expectedRoute = undefined; | this.expectedRoute = undefined; | ||||
if (pushFront) | if (pushFront) | ||||
this.PushOrderFront(type, data); | this.PushOrderFront(type, data); | ||||
else if (queued) | else if (queued) | ||||
this.PushOrder(type, data); | this.PushOrder(type, data); | ||||
else | else | ||||
{ | |||||
// May happen if an order arrives on the same turn the unit is garrisoned | |||||
// in that case, just forget the order as this will lead to an infinite loop. | |||||
// ToDo: Fix that by checking for the ability to move on orders that need that. | |||||
if (this.isGarrisoned && type != "Ungarrison") | |||||
return; | |||||
this.ReplaceOrder(type, data); | this.ReplaceOrder(type, data); | ||||
} | |||||
}; | }; | ||||
/** | /** | ||||
* Adds guard/escort order to the queue, forced by the player. | * Adds guard/escort order to the queue, forced by the player. | ||||
*/ | */ | ||||
UnitAI.prototype.Guard = function(target, queued, pushFront) | UnitAI.prototype.Guard = function(target, queued, pushFront) | ||||
{ | { | ||||
if (!this.CanGuard()) | if (!this.CanGuard()) | ||||
▲ Show 20 Lines • Show All 1,232 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator