1
0
forked from 0ad/0ad

Switch default behavior from capture to attack.

Discussed countless times on the forum.
We try this out this release.

Patch by: @marder
Differential revision: https://code.wildfiregames.com/D4697
Idea accepted by: @asterix, @wowgetoffyourcellphone, @chrstgtr
Comments by: ^ + @Stan
This was SVN commit r27399.
This commit is contained in:
Freagarach 2023-01-09 14:29:06 +00:00
parent 9044735e87
commit 82e2619ece
6 changed files with 37 additions and 44 deletions

View File

@ -332,7 +332,8 @@ unload = "U" ; Unload garrisoned units when a building/mechanica
unloadturrets = "U" ; Unload turreted units.
leaveturret = "U" ; Leave turret point.
move = "" ; Modifier to move to a point instead of another action (e.g. gather)
attack = Ctrl ; Modifier to attack instead of another action (e.g. capture)
capture = Ctrl ; Modifier to capture instead of another action (e.g. attack)
attack = "" ; Modifier to attack instead of another action (e.g. capture)
attackmove = Ctrl ; Modifier to attackmove when clicking on a point
attackmoveUnit = "Ctrl+Q" ; Modifier to attackmove targeting only units when clicking on a point
garrison = Ctrl ; Modifier to garrison when clicking on building

View File

@ -43,6 +43,10 @@
"name": "Force move",
"desc": "Modifier to move to a point instead of another action (e.g. gather)."
},
"session.capture": {
"name": "Force capture",
"desc": "Modifier to capture instead of another action (e.g. attack)."
},
"session.attack": {
"name": "Force attack",
"desc": "Modifier to attack instead of another action (e.g. capture)."

View File

@ -113,9 +113,10 @@ You may change hotkeys in [font="sans-bold-14"]Options > Hotkeys[font="sans-14"]
hotkey.selection.singleselection – Modifier to select units individually, opposed to per formation.
Right Click with a structure(s) selected – Set a rally point for units created/ungarrisoned from that structure
hotkey.session.garrison + Right Click with unit(s) selected – Garrison (If the cursor is over an own or allied structure)
hotkey.session.attack + Right Click with unit(s) selected – Attack (instead of capture or gather)
hotkey.session.attack + Right Click with unit(s) selected – Attack (instead of another action)
hotkey.session.attackmove + Right Click with unit(s) selected – Attack move (by default all enemy units and structures along the way are targeted)
hotkey.session.attackmoveUnit + Right Click with unit(s) selected – Attack move, only units along the way are targeted
hotkey.session.capture + Right Click with unit(s) selected – Capture (instead of another action)
hotkey.session.snaptoedges + Mouse Move near structures – Align the new structure with an existing nearby structure
hotkey.session.flare + Right Click – Send a flare to your allies

View File

@ -181,6 +181,11 @@ var g_UnitActions =
})
};
},
"hotkeyActionCheck": function(target, selection)
{
return Engine.HotkeyIsPressed("session.capture") &&
this.actionCheck(target, selection);
},
"actionCheck": function(target, selection)
{
let actionInfo = getActionInfo("capture", target, selection);
@ -191,7 +196,7 @@ var g_UnitActions =
"firstAbleEntity": actionInfo.entity
};
},
"specificness": 9,
"specificness": 10,
},
"attack":
@ -243,7 +248,7 @@ var g_UnitActions =
"firstAbleEntity": actionInfo.entity
};
},
"specificness": 10,
"specificness": 9,
},
"call-to-arms": {
@ -261,7 +266,7 @@ var g_UnitActions =
"targetClasses": targetClasses,
"queued": queued,
"pushFront": pushFront,
"allowCapture": true,
"allowCapture": Engine.HotkeyIsPressed("session.capture"),
"formation": g_AutoFormation.getNull()
});
return true;
@ -305,7 +310,7 @@ var g_UnitActions =
"target": action.target,
"targetClasses": { "attack": g_PatrolTargets },
"queued": queued,
"allowCapture": false,
"allowCapture": Engine.HotkeyIsPressed("session.capture"),
"formation": g_AutoFormation.getDefault()
});

View File

@ -185,6 +185,8 @@ var g_LeaveFoundationRange = 4;
UnitAI.prototype.notifyToCheerInRange = 30;
UnitAI.prototype.DEFAULT_CAPTURE = false;
// To reject an order, use 'return this.FinishOrder();'
const ACCEPT_ORDER = true;
@ -535,7 +537,7 @@ UnitAI.prototype.UnitFsmSpec = {
if (!this.AbleToMove() && !this.CheckTargetRange(msg.data.target, IID_Attack, bestAttack))
return this.FinishOrder();
this.PushOrderFront("Attack", { "target": msg.data.target, "force": !!msg.data.force, "hunting": true, "allowCapture": false });
this.PushOrderFront("Attack", { "target": msg.data.target, "force": !!msg.data.force, "hunting": true });
return ACCEPT_ORDER;
}
@ -767,7 +769,6 @@ UnitAI.prototype.UnitFsmSpec = {
"Order.Attack": function(msg) {
let target = msg.data.target;
let allowCapture = msg.data.allowCapture;
let cmpTargetUnitAI = Engine.QueryInterface(target, IID_UnitAI);
if (cmpTargetUnitAI && cmpTargetUnitAI.IsFormationMember())
target = cmpTargetUnitAI.GetFormationController();
@ -781,7 +782,7 @@ UnitAI.prototype.UnitFsmSpec = {
}
return this.FinishOrder();
}
this.CallMemberFunction("Attack", [target, allowCapture, false]);
this.CallMemberFunction("Attack", [target, msg.data.allowCapture, false]);
let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
if (cmpAttack && cmpAttack.CanAttackAsFormation())
this.SetNextState("COMBAT.ATTACKING");
@ -832,7 +833,7 @@ UnitAI.prototype.UnitFsmSpec = {
}
return ACCEPT_ORDER;
}
this.PushOrderFront("Attack", { "target": msg.data.target, "force": !!msg.data.force, "hunting": true, "allowCapture": false, "min": 0, "max": 10 });
this.PushOrderFront("Attack", { "target": msg.data.target, "force": !!msg.data.force, "hunting": true, "min": 0, "max": 10 });
return ACCEPT_ORDER;
}
@ -1300,8 +1301,7 @@ UnitAI.prototype.UnitFsmSpec = {
"ATTACKING": {
// Wait for individual members to finish
"enter": function(msg) {
let target = this.order.data.target;
let allowCapture = this.order.data.allowCapture;
const target = this.order.data.target;
if (!this.CheckFormationTargetAttackRange(target))
{
if (this.CanAttack(target) && this.CheckTargetVisible(target))
@ -1322,8 +1322,7 @@ UnitAI.prototype.UnitFsmSpec = {
},
"Timer": function(msg) {
let target = this.order.data.target;
let allowCapture = this.order.data.allowCapture;
const target = this.order.data.target;
if (!this.CheckFormationTargetAttackRange(target))
{
if (this.CanAttack(target) && this.CheckTargetVisible(target))
@ -1568,7 +1567,7 @@ UnitAI.prototype.UnitFsmSpec = {
}
if (this.CheckTargetVisible(msg.data.attacker))
this.PushOrderFront("Attack", { "target": msg.data.attacker, "force": false, "allowCapture": true });
this.PushOrderFront("Attack", { "target": msg.data.attacker, "force": false });
else
{
var cmpPosition = Engine.QueryInterface(msg.data.attacker, IID_Position);
@ -2112,9 +2111,6 @@ UnitAI.prototype.UnitFsmSpec = {
this.PushOrder("WalkAndFight", {
"x": lastPos.x, "z": lastPos.z,
"force": false,
// Force to true - otherwise structures might be attacked instead of captured,
// which is generally not expected (attacking units usually has allowCapture false).
"allowCapture": true
});
return;
}
@ -4992,12 +4988,9 @@ UnitAI.prototype.CheckTargetIsInVisionRange = function(target)
return distance < range;
};
UnitAI.prototype.GetBestAttackAgainst = function(target, allowCapture)
UnitAI.prototype.GetBestAttackAgainst = function(target, allowCapture = this.DEFAULT_CAPTURE)
{
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
if (!cmpAttack)
return undefined;
return cmpAttack.GetBestAttackAgainst(target, allowCapture);
return Engine.QueryInterface(this.entity, IID_Attack)?.GetBestAttackAgainst(target, allowCapture);
};
/**
@ -5011,7 +5004,7 @@ UnitAI.prototype.AttackVisibleEntity = function(ents)
if (!target)
return false;
this.PushOrderFront("Attack", { "target": target, "force": false, "allowCapture": true });
this.PushOrderFront("Attack", { "target": target, "force": false });
return true;
};
@ -5030,7 +5023,7 @@ UnitAI.prototype.AttackEntityInZone = function(ents)
if (!target)
return false;
this.PushOrderFront("Attack", { "target": target, "force": false, "allowCapture": true });
this.PushOrderFront("Attack", { "target": target, "force": false });
return true;
};
@ -5454,12 +5447,12 @@ UnitAI.prototype.WalkToTarget = function(target, queued, pushFront)
* to a player order, and so is forced.
* If targetClasses is given, only entities matching the targetClasses can be attacked.
*/
UnitAI.prototype.WalkAndFight = function(x, z, targetClasses, allowCapture = true, queued = false, pushFront = false)
UnitAI.prototype.WalkAndFight = function(x, z, targetClasses, allowCapture = this.DEFAULT_CAPTURE, queued = false, pushFront = false)
{
this.AddOrder("WalkAndFight", { "x": x, "z": z, "targetClasses": targetClasses, "allowCapture": allowCapture, "force": true }, queued, pushFront);
};
UnitAI.prototype.Patrol = function(x, z, targetClasses, allowCapture = true, queued = false, pushFront = false)
UnitAI.prototype.Patrol = function(x, z, targetClasses, allowCapture = this.DEFAULT_CAPTURE, queued = false, pushFront = false)
{
if (!this.CanPatrol())
{
@ -5497,7 +5490,7 @@ UnitAI.prototype.LeaveFoundation = function(target)
/**
* Adds attack order to the queue, forced by the player.
*/
UnitAI.prototype.Attack = function(target, allowCapture = true, queued = false, pushFront = false)
UnitAI.prototype.Attack = function(target, allowCapture = this.DEFAULT_CAPTURE, queued = false, pushFront = false)
{
if (!this.CanAttack(target))
{
@ -6033,7 +6026,7 @@ UnitAI.prototype.FindWalkAndFightTargets = function()
const order = {
"target": target,
"force": false,
"allowCapture": this.order?.data?.allowCapture
"allowCapture": this.order?.data?.allowCapture || this.DEFAULT_CAPTURE
};
if (this.IsFormationMember())
this.ReplaceOrder("Attack", order);

View File

@ -183,41 +183,30 @@ var g_Commands = {
"attack-walk": function(player, cmd, data)
{
let allowCapture = cmd.allowCapture || cmd.allowCapture == null;
GetFormationUnitAIs(data.entities, player, cmd, data.formation).forEach(cmpUnitAI => {
cmpUnitAI.WalkAndFight(cmd.x, cmd.z, cmd.targetClasses, allowCapture, cmd.queued, cmd.pushFront);
cmpUnitAI.WalkAndFight(cmd.x, cmd.z, cmd.targetClasses, cmd.allowCapture, cmd.queued, cmd.pushFront);
});
},
"attack-walk-custom": function(player, cmd, data)
{
let allowCapture = cmd.allowCapture || cmd.allowCapture == null;
for (let ent in data.entities)
GetFormationUnitAIs([data.entities[ent]], player, cmd, data.formation).forEach(cmpUnitAI => {
cmpUnitAI.WalkAndFight(cmd.targetPositions[ent].x, cmd.targetPositions[ent].y, cmd.targetClasses, allowCapture, cmd.queued, cmd.pushFront);
cmpUnitAI.WalkAndFight(cmd.targetPositions[ent].x, cmd.targetPositions[ent].y, cmd.targetClasses, cmd.allowCapture, cmd.queued, cmd.pushFront);
});
},
"attack": function(player, cmd, data)
{
let allowCapture = cmd.allowCapture || cmd.allowCapture == null;
if (g_DebugCommands && !allowCapture &&
!(IsOwnedByEnemyOfPlayer(player, cmd.target) || IsOwnedByNeutralOfPlayer(player, cmd.target)))
warn("Invalid command: attack target is not owned by enemy of player "+player+": "+uneval(cmd));
GetFormationUnitAIs(data.entities, player, cmd, data.formation).forEach(cmpUnitAI => {
cmpUnitAI.Attack(cmd.target, allowCapture, cmd.queued, cmd.pushFront);
cmpUnitAI.Attack(cmd.target, cmd.allowCapture, cmd.queued, cmd.pushFront);
});
},
"patrol": function(player, cmd, data)
{
let allowCapture = cmd.allowCapture || cmd.allowCapture == null;
GetFormationUnitAIs(data.entities, player, cmd, data.formation).forEach(cmpUnitAI =>
cmpUnitAI.Patrol(cmd.x, cmd.z, cmd.targetClasses, allowCapture, cmd.queued)
cmpUnitAI.Patrol(cmd.x, cmd.z, cmd.targetClasses, cmd.allowCapture, cmd.queued)
);
},