fix(set_controls_keyo): verify the active build's skills, not a hardcoded list
SKILL_KEYS was a fixed Paladin list read via Config().char.get(). Build skills live in their own sections ([hammerdin], [blizz_sorc], [sorceress]), not [char], so that lookup returned empty for all of them and they were never checked. In practice the tool only ever verified 3 keys — teleport, battle_orders and battle_command — for every build. A hammerdin's blessed_hammer/concentration/ redemption/vigor/conviction/holy_shield went unverified, and a sorc got no build coverage at all (blizzard, ice_blast, static_field, energy_shield, telekinesis all silently skipped). Derive the list from skill_preflight.get_build_skill_checks() instead, which already resolves each build's skills out of the right config section, and keep [char]-level keys (teleport, town_portal) alongside. battle_orders/ battle_command are now gated on cta_available so a character without a Call to Arms doesn't report two permanent false "unbound" entries. Also print the build alongside the file so it is obvious what is being checked. Verified against two real .keyo files: hammerdin (fistman) — 10/10 keys ok, was reporting only 3 blizz_sorc (ding) — 7/7 keys ok, was reporting only 1 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,8 +29,40 @@ from utils.key_detector import VK_MAP
|
||||
|
||||
NAME_TO_VK = {v: k for k, v in VK_MAP.items() if k < 256}
|
||||
|
||||
SKILL_KEYS = ["blessed_hammer", "concentration", "redemption", "vigor",
|
||||
"conviction", "holy_shield", "teleport", "battle_orders", "battle_command"]
|
||||
# Keys that live in [char] for every build. battle_orders/battle_command are
|
||||
# CTA-only and are skipped unless cta_available is set, so a character without a
|
||||
# Call to Arms does not report two permanent false "unbound" entries.
|
||||
COMMON_SKILL_KEYS = ["teleport", "town_portal"]
|
||||
CTA_SKILL_KEYS = ["battle_orders", "battle_command"]
|
||||
|
||||
|
||||
def wanted_skill_keys() -> dict:
|
||||
"""Map cfg_key -> key name for every skill the ACTIVE BUILD puts on the bar.
|
||||
|
||||
Build-specific skills are taken from skill_preflight, which already resolves
|
||||
them out of the build's own config section ([hammerdin], [blizz_sorc],
|
||||
[sorceress], ...). Hardcoding a single build's skill list here meant a sorc
|
||||
was only ever checked for [char] keys, so blizzard/ice_blast/static_field
|
||||
were silently never verified.
|
||||
"""
|
||||
cfg = Config()
|
||||
wanted = {}
|
||||
try:
|
||||
from utils.skill_preflight import get_build_skill_checks
|
||||
for check in get_build_skill_checks(cfg):
|
||||
if check.hotkey:
|
||||
wanted[check.skill] = check.hotkey
|
||||
except Exception as exc:
|
||||
print(f"warning: could not load build skill list ({exc}); checking [char] keys only")
|
||||
|
||||
common = list(COMMON_SKILL_KEYS)
|
||||
if cfg.char.get("cta_available"):
|
||||
common += CTA_SKILL_KEYS
|
||||
for cfg_key in common:
|
||||
key_name = str(cfg.char.get(cfg_key, "")).strip().lower()
|
||||
if key_name:
|
||||
wanted.setdefault(cfg_key, key_name)
|
||||
return wanted
|
||||
|
||||
HEADER = 4
|
||||
ENTRY = 10
|
||||
@@ -80,13 +112,10 @@ def main():
|
||||
skill_slot_by_vk = {e[1]: e[4] for e in entries if e[2] == 1 and e[1] != UNBOUND_VK}
|
||||
free = [i for i, e in enumerate(entries) if e[2] == 1 and e[1] == UNBOUND_VK]
|
||||
|
||||
wanted = {}
|
||||
for cfg_key in SKILL_KEYS:
|
||||
key_name = str(Config().char.get(cfg_key, "")).strip().lower()
|
||||
if key_name:
|
||||
wanted[cfg_key] = key_name
|
||||
wanted = wanted_skill_keys()
|
||||
|
||||
print(f"keyo: {path}")
|
||||
print(f"build: {Config().char.get('type', '?')}")
|
||||
missing = []
|
||||
for cfg_key, key_name in wanted.items():
|
||||
vk = NAME_TO_VK.get(key_name)
|
||||
|
||||
Reference in New Issue
Block a user