CONTROL_MAP = {
# Movement & Basic Actions
'Up_Arrow': {'action': 'MOVE_UP', 'type': 'movement'},
'Down_Arrow': {'action': 'MOVE_DOWN', 'type': 'movement'},
'Left_Arrow': {'action': 'MOVE_LEFT', 'type': 'movement'},
'Right_Arrow': {'action': 'MOVE_RIGHT', 'type': 'movement'},
'Space': {'action': 'PRIMARY_ACTION_PASS_TACKLE', 'type': 'hold_tap'},
'Enter': {'action': 'SHOOT_POWER_SHOT', 'type': 'hold_release'},
'Backspace': {'action': 'LOB_CHIP', 'type': 'hold_release'},
# Modifiers
'LShift': {'action': 'SPRINT_MODIFIER', 'type': 'modifier'},
'LCtrl': {'action': 'SLIDE_TACKLE_MODIFIER', 'type': 'modifier'},
'LAlt': {'action': 'LOFT_MODIFIER', 'type': 'modifier'},
# Quick Passes (Contextual)
'A': {'action': 'PASS_WING_LEFT', 'type': 'quick_pass'},
'S': {'action': 'PASS_CLOSEST', 'type': 'quick_pass'},
'D': {'action': 'PASS_WING_RIGHT', 'type': 'quick_pass'},
'F': {'action': 'THROUGH_BALL', 'type': 'quick_pass'},
'Q': {'action': 'ONE_TWO_INIT', 'type': 'sequence'},
'E': {'action': 'ONE_TWO_INIT_ALT', 'type': 'sequence'},
# Numpad (Movement/Aiming) - Behavior dependent on GAME_STATE['NumLock']
'Numpad8': {'action': 'AIM_UP', 'type': 'numpad'},
'Numpad4': {'action': 'AIM_LEFT', 'type': 'numpad'},
'Numpad6': {'action': 'AIM_RIGHT', 'type': 'numpad'},
'Numpad2': {'action': 'AIM_DOWN', 'type': 'numpad'},
'Numpad5': {'action': 'HOLD_STOP', 'type': 'numpad'},
# ... Numpad 1, 3, 7, 9 for 8-way aim/set-piece zones
# Tactics & Team Commands
'F1': {'action': 'TOGGLE_DEFENSIVE_LINE', 'type': 'toggle_cycle'},
'F2': {'action': 'TOGGLE_MENTALITY', 'type': 'toggle_cycle'},
'F3': {'action': 'TOGGLE_PRESSING_MODE', 'type': 'toggle_cycle'},
# ... F4 through F12
# Navigation & UI
'Tab': {'action': 'CYCLE_TARGET_PLAYER', 'type': 'tap'},
'Home': {'action': 'SWITCH_TO_GOALKEEPER', 'type': 'tap'},
'End': {'action': 'SWITCH_TO_CAPTAIN', 'type': 'tap'},
'Insert': {'action': 'QUICK_REWIND', 'type': 'tap'},
'Esc': {'action': 'PAUSE_MENU', 'type': 'system'},
}
GAME_STATE = {
# Lock Key Toggles
'Caps_Lock': False, # Aggression Toggle (False=Calm, True=Aggressive)
'Num_Lock': False, # Precision Aiming Mode (False=Movement, True=Aiming)
'Scroll_Lock': False, # Precision Slow Mode (False=1.0x, True=0.75x Speed)
# Modifier States
'LShift_Active': False,
'LCtrl_Active': False,
'LAlt_Active': False,
# Player States
'is_charging': False,
'charge_start_time': 0.0,
'last_directional_tap': {'key': None, 'time': 0.0},
'double_tap_window': 0.3, # 300ms window
'one_two_active': False,
# Tactic States
'Defensive_Line': 'Balanced', # Deep / Balanced / High
'Mentality': 'Balanced', # Defensive / Balanced / Attacking
'Pressing_Mode': 'Medium', # Low / Medium / High
'Game_Speed_Multiplier': 1.0,
}
def handle_key_down(key, current_time):
# 1. System/Pause Key
if key == 'Esc':
execute_action('PAUSE_MENU')
return
# 2. Lock Key Toggles (OS-Level State Capture)
if key in ['Caps_Lock', 'Num_Lock', 'Scroll_Lock']:
# Assuming the input library gives us the new state of the physical lock
# Example: NumLock behavior flip
if key == 'Num_Lock':
GAME_STATE['Num_Lock'] = not GAME_STATE['Num_Lock']
# Update game speed for Scroll Lock
if key == 'Scroll_Lock':
GAME_STATE['Game_Speed_Multiplier'] = 0.75 if GAME_STATE['Scroll_Lock'] else 1.0
update_hud_toggle_state(key, GAME_STATE[key]) # Visual feedback
# 3. Modifiers (Set Active State)
if key == 'LShift':
GAME_STATE['LShift_Active'] = True
elif key == 'LCtrl':
GAME_STATE['LCtrl_Active'] = True
elif key == 'LAlt':
GAME_STATE['LAlt_Active'] = True
# 4. Hold/Charge Actions (Start Charge)
if key == 'Enter':
GAME_STATE['is_charging'] = True
GAME_STATE['charge_start_time'] = current_time
# 5. Double Tap Check (Quick Skip/Accelerate)
if key in ['Up_Arrow', 'Down_Arrow', 'Left_Arrow', 'Right_Arrow']:
if current_time - GAME_STATE['last_directional_tap']['time'] < GAME_STATE['double_tap_window'] \
and key == GAME_STATE['last_directional_tap']['key']:
execute_action('QUICK_SKIP_ACCELERATE', direction=key)
# Record press for the next potential double tap
GAME_STATE['last_directional_tap']['key'] = key
GAME_STATE['last_directional_tap']['time'] = current_time
# 6. Execute Primary Actions (based on modifiers)
if key in CONTROL_MAP:
action_data = CONTROL_MAP[key]
# Handle Quick Passes with Modifiers (Shift/Alt)
if action_data['type'] == 'quick_pass':
if GAME_STATE['LShift_Active']: # Shift + Pass = Driven
execute_action(f"DRIVEN_{action_data['action']}")
elif GAME_STATE['LAlt_Active']: # Alt + Pass = Lofted
execute_action(f"LOFTED_{action_data['action']}")
else: # Standard Pass
execute_action(action_data['action'])
# Handle Movement Keys (Arrows + Numpad based on NumLock state)
if action_data['type'] in ['movement', 'numpad']:
# Determine if input is for movement or aiming
is_aiming = GAME_STATE['Num_Lock'] and action_data['type'] == 'numpad'
is_sprinting = GAME_STATE['LShift_Active']
if is_aiming:
update_aiming_direction(action_data['action'])
else:
apply_movement(action_data['action'], is_sprinting)
# Handle One-Two Sequence
if action_data['action'].startswith('ONE_TWO_INIT'):
GAME_STATE['one_two_active'] = True
execute_action('INITIATE_WALL_PASS')
# Handle Slide Tackle (Ctrl + Tap)
if key == 'LCtrl':
execute_action('SLIDE_TACKLE_HARD_CHALLENGE', risk=True)
Note: The logic for Ctrl + Arrow Feint would be handled in a separate 'Feint' system,
triggered by LCtrl_Active + Movement Key Press.
def handle_key_up(key, current_time):
# 1. Modifiers (Release State)
if key == 'LShift':
GAME_STATE['LShift_Active'] = False
elif key == 'LCtrl':
GAME_STATE['LCtrl_Active'] = False
elif key == 'LAlt':
GAME_STATE['LAlt_Active'] = False
# 2. Hold/Charge Actions (Release Shot/Lob)
if key == 'Enter' and GAME_STATE['is_charging']:
charge_time = current_time - GAME_STATE['charge_start_time']
aim_direction = get_current_aim()
shoot_style = "POWER"
if GAME_STATE['Caps_Lock']: shoot_style = "AGGRESSIVE_POWER"
execute_action('SHOOT', power=calculate_power(charge_time), aim=aim_direction, style=shoot_style)
GAME_STATE['is_charging'] = False
elif key == 'Backspace' and GAME_STATE['is_charging']: # Same logic for Lob/Chip
# ... calculate power and execute LOB_CHIP
GAME_STATE['is_charging'] = False
# 3. Complete One-Two Sequence
if key == 'Space' and GAME_STATE['one_two_active']:
execute_action('COMPLETE_WALL_PASS')
GAME_STATE['one_two_active'] = False
def update_hud():
line1 = f"[{current_match_time()}] HOME {score_home} - {score_away} AWAY"
# Tactic Status
line2 = f"F1:{GAME_STATE['Defensive_Line'][:4]} F2:{GAME_STATE['Mentality'][:4]} F3:{GAME_STATE['Pressing_Mode'][:4]}"
# Lock Key Status - Crucial Visual
caps_status = "ON" if GAME_STATE['Caps_Lock'] else "OFF"
num_status = "ON" if GAME_STATE['Num_Lock'] else "OFF"
scroll_status = "ON" if GAME_STATE['Scroll_Lock'] else "OFF"
line3 = f"NUM:{num_status} CAPS:{caps_status} SCRL:{scroll_status}"
# ... render lines 1-3 on screen