forked from 0ad/0ad
Add repair order queueing to formations. Refs #592.
This was SVN commit r11876.
This commit is contained in:
parent
e7689342f8
commit
68d1cf167e
@ -139,7 +139,7 @@ var UnitFsmSpec = {
|
||||
"LosRangeUpdate": function(msg) {
|
||||
// ignore newly-seen units by default
|
||||
},
|
||||
|
||||
|
||||
"LosHealRangeUpdate": function(msg) {
|
||||
// ignore newly-seen injured units by default
|
||||
},
|
||||
@ -371,7 +371,7 @@ var UnitFsmSpec = {
|
||||
this.SetNextStateAlwaysEntering("INDIVIDUAL.GATHER.GATHERING");
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"Order.GatherNearPosition": function(msg) {
|
||||
// Move the unit to the position to gather from.
|
||||
this.MoveToPoint(this.order.data.x, this.order.data.z);
|
||||
@ -421,7 +421,7 @@ var UnitFsmSpec = {
|
||||
this.SetNextState("INDIVIDUAL.REPAIR.REPAIRING");
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"Order.Garrison": function(msg) {
|
||||
if (this.MoveToTarget(this.order.data.target))
|
||||
{
|
||||
@ -434,7 +434,7 @@ var UnitFsmSpec = {
|
||||
this.SetNextState("INDIVIDUAL.GARRISON.GARRISONED");
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"Order.Cheering": function(msg) {
|
||||
this.SetNextState("INDIVIDUAL.CHEERING");
|
||||
},
|
||||
@ -450,6 +450,14 @@ var UnitFsmSpec = {
|
||||
this.SetNextState("WALKING");
|
||||
},
|
||||
|
||||
// Only used by other orders to walk there in formation
|
||||
"Order.WalkToTargetRange": function(msg) {
|
||||
if(this.MoveToTargetRangeExplicit(this.order.data.target, this.order.data.min, this.order.data.max))
|
||||
this.SetNextState("WALKING");
|
||||
else
|
||||
this.FinishOrder();
|
||||
},
|
||||
|
||||
"Order.Attack": function(msg) {
|
||||
// TODO: we should move in formation towards the target,
|
||||
// then break up into individuals when close enough to it
|
||||
@ -471,10 +479,23 @@ var UnitFsmSpec = {
|
||||
},
|
||||
|
||||
"Order.Repair": function(msg) {
|
||||
// TODO: see notes in Order.Attack
|
||||
// TODO on what should we base this range?
|
||||
// Check if we are already in range, otherwise walk there
|
||||
if (!this.CheckTargetRangeExplicit(msg.data.target, 0, 10))
|
||||
{
|
||||
if (!this.TargetIsAlive(msg.data.target))
|
||||
// The building was finished or destroyed
|
||||
this.FinishOrder();
|
||||
else
|
||||
// Out of range move there in formation
|
||||
this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": 10 });
|
||||
return;
|
||||
}
|
||||
|
||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
|
||||
cmpFormation.CallMemberFunction("Repair", [msg.data.target, msg.data.autocontinue, false]);
|
||||
cmpFormation.Disband();
|
||||
|
||||
this.SetNextState("REPAIR");
|
||||
},
|
||||
|
||||
"Order.Gather": function(msg) {
|
||||
@ -483,7 +504,7 @@ var UnitFsmSpec = {
|
||||
cmpFormation.CallMemberFunction("Gather", [msg.data.target, false]);
|
||||
cmpFormation.Disband();
|
||||
},
|
||||
|
||||
|
||||
"Order.GatherNearPosition": function(msg) {
|
||||
// TODO: see notes in Order.Attack
|
||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
|
||||
@ -504,7 +525,7 @@ var UnitFsmSpec = {
|
||||
cmpFormation.CallMemberFunction("Garrison", [msg.data.target, false]);
|
||||
cmpFormation.Disband();
|
||||
},
|
||||
|
||||
|
||||
"IDLE": {
|
||||
},
|
||||
|
||||
@ -522,6 +543,19 @@ var UnitFsmSpec = {
|
||||
cmpFormation.Disband();
|
||||
},
|
||||
},
|
||||
|
||||
"REPAIR": {
|
||||
"ConstructionFinished": function(msg) {
|
||||
if (msg.data.entity != this.order.data.target)
|
||||
return;
|
||||
|
||||
if (this.FinishOrder())
|
||||
return;
|
||||
|
||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
|
||||
cmpFormation.Disband();
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@ -2375,6 +2409,12 @@ UnitAI.prototype.CheckTargetRange = function(target, iid, type)
|
||||
return cmpUnitMotion.IsInTargetRange(target, range.min, range.max);
|
||||
};
|
||||
|
||||
UnitAI.prototype.CheckTargetRangeExplicit = function(target, min, max)
|
||||
{
|
||||
var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
|
||||
return cmpUnitMotion.IsInTargetRange(target, min, max);
|
||||
};
|
||||
|
||||
UnitAI.prototype.CheckGarrisonRange = function(target)
|
||||
{
|
||||
var cmpGarrisonHolder = Engine.QueryInterface(target, IID_GarrisonHolder);
|
||||
@ -2666,13 +2706,14 @@ UnitAI.prototype.ComputeWalkingDistance = function()
|
||||
var dz = order.data.z - pos.z;
|
||||
var d = Math.sqrt(dx*dx + dz*dz);
|
||||
distance += d;
|
||||
|
||||
|
||||
// Remember this as the start position for the next order
|
||||
pos = order.data;
|
||||
|
||||
break; // and continue the loop
|
||||
|
||||
case "WalkToTarget":
|
||||
case "WalkToTargetRange": // This doesn't move to the target (just into range), but a later order will.
|
||||
case "Flee":
|
||||
case "LeaveFoundation":
|
||||
case "Attack":
|
||||
|
@ -56,7 +56,7 @@ function ProcessCommand(player, cmd)
|
||||
|
||||
case "walk":
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
|
||||
cmpUnitAI.Walk(cmd.x, cmd.z, cmd.queued);
|
||||
});
|
||||
break;
|
||||
@ -70,7 +70,7 @@ function ProcessCommand(player, cmd)
|
||||
|
||||
// See UnitAI.CanAttack for target checks
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
|
||||
cmpUnitAI.Attack(cmd.target, cmd.queued);
|
||||
});
|
||||
break;
|
||||
@ -84,7 +84,7 @@ function ProcessCommand(player, cmd)
|
||||
|
||||
// See UnitAI.CanHeal for target checks
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
|
||||
cmpUnitAI.Heal(cmd.target, cmd.queued);
|
||||
});
|
||||
break;
|
||||
@ -99,7 +99,7 @@ function ProcessCommand(player, cmd)
|
||||
|
||||
// See UnitAI.CanRepair for target checks
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
|
||||
cmpUnitAI.Repair(cmd.target, cmd.autocontinue, cmd.queued);
|
||||
});
|
||||
break;
|
||||
@ -113,14 +113,14 @@ function ProcessCommand(player, cmd)
|
||||
|
||||
// See UnitAI.CanGather for target checks
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
|
||||
cmpUnitAI.Gather(cmd.target, cmd.queued);
|
||||
});
|
||||
break;
|
||||
|
||||
case "gather-near-position":
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
|
||||
cmpUnitAI.GatherNearPosition(cmd.x, cmd.z, cmd.resourceType, cmd.queued);
|
||||
});
|
||||
break;
|
||||
@ -135,7 +135,7 @@ function ProcessCommand(player, cmd)
|
||||
|
||||
// See UnitAI.CanReturnResource for target checks
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
|
||||
cmpUnitAI.ReturnResource(cmd.target, cmd.queued);
|
||||
});
|
||||
break;
|
||||
@ -258,7 +258,7 @@ function ProcessCommand(player, cmd)
|
||||
if (CanControlUnit(cmd.target, player, controlAllUnits))
|
||||
{
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
|
||||
cmpUnitAI.Garrison(cmd.target);
|
||||
});
|
||||
}
|
||||
@ -316,7 +316,7 @@ function ProcessCommand(player, cmd)
|
||||
|
||||
case "formation":
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities, cmd.name).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, player, cmd.name).forEach(function(cmpUnitAI) {
|
||||
var cmpFormation = Engine.QueryInterface(cmpUnitAI.entity, IID_Formation);
|
||||
if (!cmpFormation)
|
||||
return;
|
||||
@ -844,7 +844,7 @@ function RemoveFromFormation(ents)
|
||||
* Returns a list of UnitAI components, each belonging either to a
|
||||
* selected unit or to a formation entity for groups of the selected units.
|
||||
*/
|
||||
function GetFormationUnitAIs(ents, formName)
|
||||
function GetFormationUnitAIs(ents, player, formName)
|
||||
{
|
||||
// If an individual was selected, remove it from any formation
|
||||
// and command it individually
|
||||
@ -922,6 +922,9 @@ function GetFormationUnitAIs(ents, formName)
|
||||
var cmpFormation = Engine.QueryInterface(formationEnt, IID_Formation);
|
||||
cmpFormation.SetMembers(formation.entities);
|
||||
|
||||
var cmpOwnership = Engine.QueryInterface(formationEnt, IID_Ownership);
|
||||
cmpOwnership.SetOwner(player);
|
||||
|
||||
// If all the selected units were previously in formations of the same shape,
|
||||
// then set this new formation to that shape too; otherwise use the default shape
|
||||
var lastFormationName = undefined;
|
||||
|
@ -6,6 +6,7 @@
|
||||
</VisualActor>
|
||||
-->
|
||||
<Formation/>
|
||||
<Ownership/>
|
||||
<Position>
|
||||
<Altitude>0</Altitude>
|
||||
<Anchor>upright</Anchor>
|
||||
|
Loading…
Reference in New Issue
Block a user