Infer kill event teams without relying on the livedamage plugin
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
This commit is contained in:
+43
-3
@@ -167,6 +167,34 @@ class EventParser:
|
||||
team_prefix = get_team_prefix(name, self.game_state.player_tracker)
|
||||
return f"^8^5[SWITCH]^7 {team_prefix}^8{name}^0{team_msg} from {old_team_msg}{warmup}\n"
|
||||
|
||||
def _opposite_team(self, team):
|
||||
"""The other active team in a two-team mode; None when not applicable"""
|
||||
return {1: 2, 2: 1, 'RED': 'BLUE', 'BLUE': 'RED'}.get(team)
|
||||
|
||||
def _resolve_event_teams(self, data, killer, victim, killer_name, victim_name):
|
||||
"""
|
||||
Resolve (killer_team, victim_team) for a kill/death event. Event TEAM
|
||||
fields win; when a server omits them (some do during warmup), the
|
||||
missing side is derived from the counterpart player and the
|
||||
TEAMKILL/SUICIDE flags. Solo modes always resolve to FREE — every
|
||||
participant is FREE by definition. None means unknowable from this
|
||||
event (leave the tracked team untouched).
|
||||
"""
|
||||
if not self.game_state.server_info.is_team_mode():
|
||||
return ('FREE', 'FREE')
|
||||
|
||||
killer_team = killer.get('TEAM') if killer else None
|
||||
victim_team = victim.get('TEAM') if victim else None
|
||||
same_team = (bool(data.get('SUICIDE', False))
|
||||
or strip_color_codes(killer_name).strip() == strip_color_codes(victim_name).strip()
|
||||
or bool(data.get('TEAMKILL', False)))
|
||||
|
||||
if killer_team is not None and victim_team is None:
|
||||
victim_team = killer_team if same_team else self._opposite_team(killer_team)
|
||||
elif victim_team is not None and killer_team is None:
|
||||
killer_team = victim_team if same_team else self._opposite_team(victim_team)
|
||||
return (killer_team, victim_team)
|
||||
|
||||
def _handle_death(self, data):
|
||||
"""Handle PLAYER_DEATH and PLAYER_KILL events"""
|
||||
|
||||
@@ -190,6 +218,11 @@ class EventParser:
|
||||
if 'TEAM' in victim:
|
||||
self.game_state.player_tracker.update_team(victim_name, victim['TEAM'])
|
||||
self.game_state.player_tracker.add_player(victim_name)
|
||||
elif not self.game_state.server_info.is_team_mode():
|
||||
# Solo modes: every participant is FREE by definition, even when
|
||||
# the event carries no TEAM field
|
||||
self.game_state.player_tracker.update_team(victim_name, 'FREE')
|
||||
self.game_state.player_tracker.add_player(victim_name)
|
||||
|
||||
# Mark as dead
|
||||
if not data.get('WARMUP', False):
|
||||
@@ -224,10 +257,17 @@ class EventParser:
|
||||
killer = data['KILLER']
|
||||
killer_name = killer.get('NAME', 'Unknown')
|
||||
|
||||
# Update killer team
|
||||
if 'TEAM' in killer:
|
||||
self.game_state.player_tracker.update_team(killer_name, killer['TEAM'])
|
||||
# Team resolution with inference: prefer the event's TEAM fields; when
|
||||
# a server omits them (some do during warmup), derive the missing side
|
||||
# from the counterpart and the TEAMKILL/SUICIDE flags
|
||||
killer_team, victim_team = self._resolve_event_teams(
|
||||
data, killer, victim, killer_name, victim_name)
|
||||
if killer_team is not None:
|
||||
self.game_state.player_tracker.update_team(killer_name, killer_team)
|
||||
if victim_team is not None:
|
||||
self.game_state.player_tracker.update_team(victim_name, victim_team)
|
||||
self.game_state.player_tracker.add_player(killer_name)
|
||||
self.game_state.player_tracker.add_player(victim_name)
|
||||
|
||||
killer_prefix = get_team_prefix(killer_name, self.game_state.player_tracker)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user