Add repair order queueing to formations. Refs #592.

This was SVN commit r11876.
This commit is contained in:
leper 2012-05-18 21:31:57 +00:00
parent e7689342f8
commit 68d1cf167e
3 changed files with 64 additions and 19 deletions

View File

@ -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":

View File

@ -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;

View File

@ -6,6 +6,7 @@
</VisualActor>
-->
<Formation/>
<Ownership/>
<Position>
<Altitude>0</Altitude>
<Anchor>upright</Anchor>