Fix unit-only Attack move.
attackmoveUnit is more specific than attackMove, so sinced0a42f2f00
won't fire at the same time. However the GUI code expected that, breaking it. Instead, properly check for either attackmove or attackmoveUnit. Also fix an issue withd0a42f2f00
where hotkeys would be release if switching to a more specific combination of the same hotkey. Reported by: snelius Fixes #5944 Differential Revision: https://code.wildfiregames.com/D3436 This was SVN commit r24752.
This commit is contained in:
parent
b28e6fda42
commit
8c429b9a68
@ -297,7 +297,7 @@ unload = "U" ; Unload garrisoned units when a building/mechanica
|
|||||||
move = "" ; Modifier to move to a point instead of another action (e.g. gather)
|
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)
|
attack = Ctrl ; Modifier to attack instead of another action (e.g. capture)
|
||||||
attackmove = Ctrl ; Modifier to attackmove when clicking on a point
|
attackmove = Ctrl ; Modifier to attackmove when clicking on a point
|
||||||
attackmoveUnit = "Ctrl+Q" ; Modifier to attackmove targeting only units when clicking on a point (should contain the attackmove keys)
|
attackmoveUnit = "Ctrl+Q" ; Modifier to attackmove targeting only units when clicking on a point
|
||||||
garrison = Ctrl ; Modifier to garrison when clicking on building
|
garrison = Ctrl ; Modifier to garrison when clicking on building
|
||||||
autorallypoint = Ctrl ; Modifier to set the rally point on the building itself
|
autorallypoint = Ctrl ; Modifier to set the rally point on the building itself
|
||||||
guard = "G" ; Modifier to escort/guard when clicking on unit/building
|
guard = "G" ; Modifier to escort/guard when clicking on unit/building
|
||||||
|
@ -268,6 +268,12 @@ function ownsEntity(ent)
|
|||||||
return entState && entState.player == g_ViewedPlayer;
|
return entState && entState.player == g_ViewedPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isAttackMovePressed()
|
||||||
|
{
|
||||||
|
return Engine.HotkeyIsPressed("session.attackmove") ||
|
||||||
|
Engine.HotkeyIsPressed("session.attackmoveUnit");
|
||||||
|
}
|
||||||
|
|
||||||
function isSnapToEdgesEnabled()
|
function isSnapToEdgesEnabled()
|
||||||
{
|
{
|
||||||
let config = Engine.ConfigDB_GetValue("user", "gui.session.snaptoedges");
|
let config = Engine.ConfigDB_GetValue("user", "gui.session.snaptoedges");
|
||||||
@ -1194,7 +1200,7 @@ function positionUnitsFreehandSelectionMouseUp(ev)
|
|||||||
entityDistribution.reverse();
|
entityDistribution.reverse();
|
||||||
|
|
||||||
Engine.PostNetworkCommand({
|
Engine.PostNetworkCommand({
|
||||||
"type": Engine.HotkeyIsPressed("session.attackmove") ? "attack-walk-custom" : "walk-custom",
|
"type": isAttackMovePressed() ? "attack-walk-custom" : "walk-custom",
|
||||||
"entities": selection,
|
"entities": selection,
|
||||||
"targetPositions": entityDistribution.map(pos => pos.toFixed(2)),
|
"targetPositions": entityDistribution.map(pos => pos.toFixed(2)),
|
||||||
"targetClasses": Engine.HotkeyIsPressed("session.attackmoveUnit") ? { "attack": ["Unit"] } : { "attack": ["Unit", "Structure"] },
|
"targetClasses": Engine.HotkeyIsPressed("session.attackmoveUnit") ? { "attack": ["Unit"] } : { "attack": ["Unit", "Structure"] },
|
||||||
|
@ -124,7 +124,7 @@ var g_UnitActions =
|
|||||||
},
|
},
|
||||||
"hotkeyActionCheck": function(target, selection)
|
"hotkeyActionCheck": function(target, selection)
|
||||||
{
|
{
|
||||||
return Engine.HotkeyIsPressed("session.attackmove") &&
|
return isAttackMovePressed() &&
|
||||||
this.actionCheck(target, selection);
|
this.actionCheck(target, selection);
|
||||||
},
|
},
|
||||||
"actionCheck": function(target, selection)
|
"actionCheck": function(target, selection)
|
||||||
@ -892,7 +892,7 @@ var g_UnitActions =
|
|||||||
let data = { "command": "walk" };
|
let data = { "command": "walk" };
|
||||||
let cursor = "";
|
let cursor = "";
|
||||||
|
|
||||||
if (Engine.HotkeyIsPressed("session.attackmove"))
|
if (isAttackMovePressed())
|
||||||
{
|
{
|
||||||
let targetClasses;
|
let targetClasses;
|
||||||
if (Engine.HotkeyIsPressed("session.attackmoveUnit"))
|
if (Engine.HotkeyIsPressed("session.attackmoveUnit"))
|
||||||
|
@ -310,9 +310,12 @@ InReaction HotkeyInputHandler(const SDL_Event_* ev)
|
|||||||
if ((ev->ev.type == SDL_KEYDOWN) || (ev->ev.type == SDL_MOUSEBUTTONDOWN))
|
if ((ev->ev.type == SDL_KEYDOWN) || (ev->ev.type == SDL_MOUSEBUTTONDOWN))
|
||||||
for (const SHotkeyMapping* hotkey : pressedHotkeys)
|
for (const SHotkeyMapping* hotkey : pressedHotkeys)
|
||||||
{
|
{
|
||||||
if (hotkey->requires.size() + 1 < closestMapMatch)
|
if (std::find_if(newPressedHotkeys.begin(), newPressedHotkeys.end(),
|
||||||
|
[&hotkey](const SHotkeyMapping* v){ return v->name == hotkey->name; }) != newPressedHotkeys.end())
|
||||||
|
continue;
|
||||||
|
else if (hotkey->requires.size() + 1 < closestMapMatch)
|
||||||
releasedHotkeys.push_back(hotkey->name.c_str());
|
releasedHotkeys.push_back(hotkey->name.c_str());
|
||||||
else if (std::find(newPressedHotkeys.begin(), newPressedHotkeys.end(), hotkey) == newPressedHotkeys.end())
|
else
|
||||||
{
|
{
|
||||||
// We need to check that all 'keys' are still pressed (because of mouse buttons).
|
// We need to check that all 'keys' are still pressed (because of mouse buttons).
|
||||||
if (!isPressed(hotkey->primary))
|
if (!isPressed(hotkey->primary))
|
||||||
|
@ -55,6 +55,8 @@ public:
|
|||||||
TS_ASSERT_OK(g_VFS->Mount(L"cache", DataDir()/"_testcache"));
|
TS_ASSERT_OK(g_VFS->Mount(L"cache", DataDir()/"_testcache"));
|
||||||
|
|
||||||
configDB = new CConfigDB;
|
configDB = new CConfigDB;
|
||||||
|
|
||||||
|
g_scancodes = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void tearDown()
|
void tearDown()
|
||||||
@ -70,7 +72,7 @@ public:
|
|||||||
configDB->SetValueString(CFG_SYSTEM, "hotkey.A", "A");
|
configDB->SetValueString(CFG_SYSTEM, "hotkey.A", "A");
|
||||||
configDB->SetValueString(CFG_SYSTEM, "hotkey.AB", "A+B");
|
configDB->SetValueString(CFG_SYSTEM, "hotkey.AB", "A+B");
|
||||||
configDB->SetValueString(CFG_SYSTEM, "hotkey.ABC", "A+B+C");
|
configDB->SetValueString(CFG_SYSTEM, "hotkey.ABC", "A+B+C");
|
||||||
configDB->SetValueString(CFG_SYSTEM, "hotkey.D", "D");
|
configDB->SetValueList(CFG_SYSTEM, "hotkey.D", { "D", "D+E" });
|
||||||
configDB->WriteFile(CFG_SYSTEM, "config/conf.cfg");
|
configDB->WriteFile(CFG_SYSTEM, "config/conf.cfg");
|
||||||
configDB->Reload(CFG_SYSTEM);
|
configDB->Reload(CFG_SYSTEM);
|
||||||
|
|
||||||
@ -115,6 +117,7 @@ public:
|
|||||||
|
|
||||||
fakeInput("B", true);
|
fakeInput("B", true);
|
||||||
fakeInput("A", true);
|
fakeInput("A", true);
|
||||||
|
// Activating the more precise hotkey AB untriggers "A"
|
||||||
TS_ASSERT_EQUALS(HotkeyIsPressed("A"), false);
|
TS_ASSERT_EQUALS(HotkeyIsPressed("A"), false);
|
||||||
TS_ASSERT_EQUALS(HotkeyIsPressed("AB"), true);
|
TS_ASSERT_EQUALS(HotkeyIsPressed("AB"), true);
|
||||||
TS_ASSERT_EQUALS(HotkeyIsPressed("ABC"), false);
|
TS_ASSERT_EQUALS(HotkeyIsPressed("ABC"), false);
|
||||||
@ -135,6 +138,36 @@ public:
|
|||||||
TS_ASSERT_EQUALS(HotkeyIsPressed("ABC"), false);
|
TS_ASSERT_EQUALS(HotkeyIsPressed("ABC"), false);
|
||||||
TS_ASSERT_EQUALS(HotkeyIsPressed("D"), false);
|
TS_ASSERT_EQUALS(HotkeyIsPressed("D"), false);
|
||||||
|
|
||||||
|
fakeInput("A", false);
|
||||||
|
fakeInput("D", true);
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("A"), false);
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("AB"), false);
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("ABC"), false);
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("D"), true);
|
||||||
|
|
||||||
|
fakeInput("E", true);
|
||||||
|
// Changing from one hotkey to another more specific combination of the same hotkey keeps it active
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("A"), false);
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("AB"), false);
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("ABC"), false);
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("D"), true);
|
||||||
|
fakeInput("E", false);
|
||||||
|
// Likewise going the other way.
|
||||||
|
TS_ASSERT_EQUALS(HotkeyIsPressed("D"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_quirk()
|
||||||
|
{
|
||||||
|
configDB->SetValueString(CFG_SYSTEM, "hotkey.A", "A");
|
||||||
|
configDB->SetValueString(CFG_SYSTEM, "hotkey.AB", "A+B");
|
||||||
|
configDB->SetValueString(CFG_SYSTEM, "hotkey.ABC", "A+B+C");
|
||||||
|
configDB->SetValueList(CFG_SYSTEM, "hotkey.D", { "D", "D+E" });
|
||||||
|
configDB->WriteFile(CFG_SYSTEM, "config/conf.cfg");
|
||||||
|
configDB->Reload(CFG_SYSTEM);
|
||||||
|
|
||||||
|
UnloadHotkeys();
|
||||||
|
LoadHotkeys(*configDB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quirk of the implementation: hotkeys are allowed to fire with too many keys.
|
* Quirk of the implementation: hotkeys are allowed to fire with too many keys.
|
||||||
* Further, hotkeys of the same specificity (i.e. same # of required keys)
|
* Further, hotkeys of the same specificity (i.e. same # of required keys)
|
||||||
|
Loading…
Reference in New Issue
Block a user