@@ -28,7 +28,25 @@ import HashMap
2828
2929constant KEY_TRIGGER = CreateTrigger()..addAction(function onEvent)
3030constant KEY_MAP = new HashMap<int, KeyPressListener>
31-
31+
32+ // Tracks which (player, key, metaKey, onKeyDown) combos are already registered on KEY_TRIGGER, so a
33+ // second listener for the same combo does NOT register the event twice on one trigger (which fires the
34+ // trigger, and therefore every matching listener, twice per key press). Keyed by key handle id, then by
35+ // a small composite of player id + meta + up/down. Never cleared: WC3 has no per-event unregister, so
36+ // "ever registered" equals "currently registered".
37+ constant KEY_REGISTERED = new HashMap<int, HashMap<int, bool>>
38+
39+ function registerKeyOnce(player whichPlayer, oskeytype key, OSKEY_META metaKey, bool onKeyDown)
40+ let keyId = key.getHandleId()
41+ var combos = KEY_REGISTERED.get(keyId)
42+ if combos == null
43+ combos = new HashMap<int, bool>
44+ KEY_REGISTERED.put(keyId, combos)
45+ let combo = whichPlayer.getId() * 64 + metaKey.toInt() * 2 + (onKeyDown ? 1 : 0)
46+ if not combos.has(combo)
47+ combos.put(combo, true)
48+ KEY_TRIGGER.registerPlayerKeyPress(whichPlayer, key, metaKey, onKeyDown)
49+
3250
3351/* CLOSURES */
3452
@@ -42,9 +60,9 @@ public function onKeyRelease(oskeytype key, KeyPressListener listener) returns K
4260 return onKeyPress(key, OSKEY_META.NONE, false, listener)
4361
4462public function onKeyPress(oskeytype key, OSKEY_META metaKey, bool onKeyDown, KeyPressListener listener) returns KeyPressListener
45- for i = 0 to bj_MAX_PLAYERS
63+ for i = 0 to bj_MAX_PLAYERS - 1
4664 if players[i].isIngame()
47- KEY_TRIGGER.registerPlayerKeyPress (players[i], key, metaKey, onKeyDown)
65+ registerKeyOnce (players[i], key, metaKey, onKeyDown)
4866 return registerListener(listener, key, metaKey, onKeyDown)
4967
5068public function onKeyPress(player whichPlayer, oskeytype key, KeyPressListener listener) returns KeyPressListener
@@ -57,7 +75,7 @@ public function onKeyRelease(player whichPlayer, oskeytype key, KeyPressListener
5775 return onKeyPress(whichPlayer, key, OSKEY_META.NONE, false, listener)
5876
5977public function onKeyPress(player whichPlayer, oskeytype key, OSKEY_META metaKey, bool onKeyDown, KeyPressListener listener) returns KeyPressListener
60- KEY_TRIGGER.registerPlayerKeyPress (whichPlayer, key, metaKey, onKeyDown)
78+ registerKeyOnce (whichPlayer, key, metaKey, onKeyDown)
6179 return registerListener(listener, key, metaKey, onKeyDown)
6280
6381function registerListener(KeyPressListener listener, oskeytype key, OSKEY_META metaKey, bool onKeyDown) returns KeyPressListener
@@ -106,4 +124,5 @@ abstract class KeyPressListener
106124 KEY_MAP.put(id, next)
107125 else if prev != null
108126 prev.next = next
109- next.prev = prev
127+ if next != null
128+ next.prev = prev
0 commit comments