mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-07-04 05:55:47 -07:00
fix attack-move not working for packed units
This was SVN commit r14395.
This commit is contained in:
parent
e9a269c01c
commit
0780becb8a
1 changed files with 91 additions and 29 deletions
|
|
@ -425,10 +425,8 @@ var UnitFsmSpec = {
|
|||
if (this.CanUnpack())
|
||||
{
|
||||
// Ignore unforced attacks
|
||||
// this would prevent attacks from AttackVisibleEntity or AttackEntityInZone ?
|
||||
// so we accept attacks against targets for which we have a bonus
|
||||
// TODO: use special stances instead?
|
||||
if (!this.order.data.force && this.GetAttackBonus(type, this.order.data.target) < 1.5)
|
||||
if (!this.order.data.force)
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
|
|
@ -1028,7 +1026,7 @@ var UnitFsmSpec = {
|
|||
|
||||
"Timer": function(msg) {
|
||||
// check if there are no enemies to attack
|
||||
this.FindNewTargets();
|
||||
this.FindWalkAndFightTargets();
|
||||
},
|
||||
|
||||
"leave": function(msg) {
|
||||
|
|
@ -1146,8 +1144,8 @@ var UnitFsmSpec = {
|
|||
if (this.FinishOrder())
|
||||
{
|
||||
// if WalkAndFight order, look for new target before moving again
|
||||
if (this.orderQueue.length > 0 && this.orderQueue[0].type == "WalkAndFight")
|
||||
this.FindNewTargets();
|
||||
if (this.IsWalkingAndFighting())
|
||||
this.FindWalkAndFightTargets();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1425,7 +1423,7 @@ var UnitFsmSpec = {
|
|||
},
|
||||
|
||||
"Timer": function(msg) {
|
||||
this.FindNewTargets();
|
||||
this.FindWalkAndFightTargets();
|
||||
},
|
||||
|
||||
"leave": function(msg) {
|
||||
|
|
@ -1757,8 +1755,8 @@ var UnitFsmSpec = {
|
|||
// Except if in WalkAndFight mode where we look for more ennemies around before moving again
|
||||
if (this.FinishOrder())
|
||||
{
|
||||
if (this.orderQueue.length > 0 && this.orderQueue[0].type == "WalkAndFight")
|
||||
this.FindNewTargets();
|
||||
if (this.IsWalkingAndFighting())
|
||||
this.FindWalkAndFightTargets();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3013,6 +3011,20 @@ UnitAI.prototype.IsWalking = function()
|
|||
return (state == "WALKING");
|
||||
};
|
||||
|
||||
/**
|
||||
* return true if in WalkAndFight looking for new targets
|
||||
*/
|
||||
UnitAI.prototype.IsWalkingAndFighting = function()
|
||||
{
|
||||
if (this.IsFormationMember())
|
||||
{
|
||||
var cmpUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI);
|
||||
return (cmpUnitAI && cmpUnitAI.IsWalkingAndFighting());
|
||||
}
|
||||
|
||||
return (this.orderQueue.length > 0 && this.orderQueue[0].type == "WalkAndFight");
|
||||
};
|
||||
|
||||
UnitAI.prototype.CanAttackGaia = function()
|
||||
{
|
||||
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
||||
|
|
@ -3349,12 +3361,18 @@ UnitAI.prototype.PushOrder = function(type, data)
|
|||
UnitAI.prototype.PushOrderFront = function(type, data)
|
||||
{
|
||||
var order = { "type": type, "data": data };
|
||||
// If current order is cheering then add new order after it
|
||||
// If current order is cheering then add new order after it
|
||||
// same thing if current order if packing/unpacking
|
||||
if (this.order && this.order.type == "Cheering")
|
||||
{
|
||||
var cheeringOrder = this.orderQueue.shift();
|
||||
this.orderQueue.unshift(cheeringOrder, order);
|
||||
}
|
||||
else if (this.order && this.IsPacking())
|
||||
{
|
||||
var packingOrder = this.orderQueue.shift();
|
||||
this.orderQueue.unshift = (packingOrder, order);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.orderQueue.unshift(order);
|
||||
|
|
@ -4968,25 +4986,6 @@ UnitAI.prototype.SwitchToStance = function(stance)
|
|||
*/
|
||||
UnitAI.prototype.FindNewTargets = function()
|
||||
{
|
||||
if (this.IsFormationController())
|
||||
{
|
||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
|
||||
for each (var ent in cmpFormation.members)
|
||||
{
|
||||
var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
|
||||
if (cmpUnitAI.FindNewTargets())
|
||||
{
|
||||
if (!cmpUnitAI.orderQueue[0] || cmpUnitAI.orderQueue[0].type != "Attack")
|
||||
continue;
|
||||
var data = cmpUnitAI.orderQueue[0].data;
|
||||
cmpUnitAI.FinishOrder();
|
||||
this.PushOrderFront("Attack", { "target": data.target, "force": false, "forceResponse": data.forceResponse });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.losRangeQuery)
|
||||
return false;
|
||||
|
||||
|
|
@ -5003,6 +5002,69 @@ UnitAI.prototype.FindNewTargets = function()
|
|||
return false;
|
||||
};
|
||||
|
||||
UnitAI.prototype.FindWalkAndFightTargets = function()
|
||||
{
|
||||
if (this.IsFormationController())
|
||||
{
|
||||
var cmpUnitAI;
|
||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
|
||||
for each (var ent in cmpFormation.members)
|
||||
{
|
||||
if (!(cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI)))
|
||||
continue;
|
||||
var targets = cmpUnitAI.GetTargetsFromUnit();
|
||||
for each (var targ in targets)
|
||||
{
|
||||
if (cmpUnitAI.CanAttack(targ))
|
||||
{
|
||||
this.PushOrderFront("Attack", { "target": targ, "force": true });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var targets = this.GetTargetsFromUnit();
|
||||
for each (var targ in targets)
|
||||
{
|
||||
if (this.CanAttack(targ))
|
||||
{
|
||||
this.PushOrderFront("Attack", { "target": targ, "force": true });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
UnitAI.prototype.GetTargetsFromUnit = function()
|
||||
{
|
||||
if (!this.losRangeQuery)
|
||||
return [];
|
||||
|
||||
if (!this.GetStance().targetVisibleEnemies)
|
||||
return [];
|
||||
|
||||
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
||||
if (!cmpAttack)
|
||||
return [];
|
||||
|
||||
var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||
var entities = rangeMan.ResetActiveQuery(this.losRangeQuery);
|
||||
var targets = entities.filter(function (v, i, a) { return cmpAttack.CanAttack(v); })
|
||||
.sort(function (a, b) { return cmpAttack.CompareEntitiesByPreference(a, b); });
|
||||
|
||||
if (targets.length)
|
||||
return targets;
|
||||
|
||||
// if nothing found, look for gaia targets
|
||||
var entities = rangeMan.ResetActiveQuery(this.losGaiaRangeQuery);
|
||||
var targets = entities.filter(function (v, i, a) { return cmpAttack.CanAttack(v); })
|
||||
.sort(function (a, b) { return cmpAttack.CompareEntitiesByPreference(a, b); });
|
||||
|
||||
return targets;
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets losHealRangeQuery, and if there are some targets in range that we can heal
|
||||
* then we start healing and this returns true; otherwise, returns false.
|
||||
|
|
|
|||
Loading…
Reference in a new issue