feat(combat): add damage tracking and combat events
- Add English damage taken pattern: 'You took X points of damage' - Add damage_dealt, damage_taken, evade subscriptions in main.py - Update evade pattern for 'The target Evaded your attack' and 'The attack missed you' - Show combat stats in session summary - Display real-time damage dealt/taken/evade events Combat events now tracked alongside loot for complete hunting analytics.
This commit is contained in:
parent
39d1b0d48d
commit
e3f3a595fb
|
|
@ -121,12 +121,19 @@ class LogWatcher:
|
||||||
|
|
||||||
# DAMAGE TAKEN
|
# DAMAGE TAKEN
|
||||||
# Swedish: "Du tog 31.5 poäng skada"
|
# Swedish: "Du tog 31.5 poäng skada"
|
||||||
|
# English: "You took 7.4 points of damage"
|
||||||
PATTERN_DAMAGE_TAKEN_SV = re.compile(
|
PATTERN_DAMAGE_TAKEN_SV = re.compile(
|
||||||
r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[System\]\s+'
|
r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[System\]\s+\[?\]?\s*'
|
||||||
r'Du\s+tog\s+(\d+(?:\.\d+)?)\s+poäng\s+skada',
|
r'Du\s+tog\s+(\d+(?:\.\d+)?)\s+poäng\s+skada',
|
||||||
re.IGNORECASE
|
re.IGNORECASE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
PATTERN_DAMAGE_TAKEN_EN = re.compile(
|
||||||
|
r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[System\]\s+\[?\]?\s*'
|
||||||
|
r'You\s+took\s+(\d+(?:\.\d+)?)\s+points?\s+of\s+damage',
|
||||||
|
re.IGNORECASE
|
||||||
|
)
|
||||||
|
|
||||||
# HEALING
|
# HEALING
|
||||||
# Swedish: "Du läkte dig själv 4.0 poäng"
|
# Swedish: "Du läkte dig själv 4.0 poäng"
|
||||||
PATTERN_HEAL_SV = re.compile(
|
PATTERN_HEAL_SV = re.compile(
|
||||||
|
|
@ -144,9 +151,10 @@ class LogWatcher:
|
||||||
)
|
)
|
||||||
|
|
||||||
# COMBAT EVADE/DODGE/MISS
|
# COMBAT EVADE/DODGE/MISS
|
||||||
|
# English: "You Evaded", "The target Evaded your attack", "The attack missed you"
|
||||||
PATTERN_EVADE = re.compile(
|
PATTERN_EVADE = re.compile(
|
||||||
r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[System\]\s+'
|
r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[System\]\s+\[?\]?\s*'
|
||||||
r'(You\s+Evaded|You\s+dodged|The\s+target\s+Dodged|The\s+attack\s+missed)',
|
r'(You\s+Evaded|You\s+dodged|The\s+target\s+Evaded\s+your\s+attack|The\s+target\s+Dodged|The\s+attack\s+missed\s+you)',
|
||||||
re.IGNORECASE
|
re.IGNORECASE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -184,7 +192,8 @@ class LogWatcher:
|
||||||
'damage_dealt_sv': PATTERN_DAMAGE_DEALT_SV,
|
'damage_dealt_sv': PATTERN_DAMAGE_DEALT_SV,
|
||||||
'damage_dealt_en': PATTERN_DAMAGE_DEALT_EN,
|
'damage_dealt_en': PATTERN_DAMAGE_DEALT_EN,
|
||||||
'critical_hit': PATTERN_CRITICAL_SV,
|
'critical_hit': PATTERN_CRITICAL_SV,
|
||||||
'damage_taken': PATTERN_DAMAGE_TAKEN_SV,
|
'damage_taken_sv': PATTERN_DAMAGE_TAKEN_SV,
|
||||||
|
'damage_taken_en': PATTERN_DAMAGE_TAKEN_EN,
|
||||||
'heal': PATTERN_HEAL_SV,
|
'heal': PATTERN_HEAL_SV,
|
||||||
'weapon_tier': PATTERN_WEAPON_TIER_SV,
|
'weapon_tier': PATTERN_WEAPON_TIER_SV,
|
||||||
'evade': PATTERN_EVADE,
|
'evade': PATTERN_EVADE,
|
||||||
|
|
@ -377,14 +386,24 @@ class LogWatcher:
|
||||||
data={'damage': Decimal(match.group(2))}
|
data={'damage': Decimal(match.group(2))}
|
||||||
)
|
)
|
||||||
|
|
||||||
# DAMAGE TAKEN
|
# DAMAGE TAKEN - Swedish
|
||||||
match = self.PATTERN_DAMAGE_TAKEN_SV.match(line)
|
match = self.PATTERN_DAMAGE_TAKEN_SV.match(line)
|
||||||
if match:
|
if match:
|
||||||
return LogEvent(
|
return LogEvent(
|
||||||
timestamp=self._parse_timestamp(match.group(1)),
|
timestamp=self._parse_timestamp(match.group(1)),
|
||||||
event_type='damage_taken',
|
event_type='damage_taken',
|
||||||
raw_line=line,
|
raw_line=line,
|
||||||
data={'damage': Decimal(match.group(2))}
|
data={'damage': Decimal(match.group(2)), 'language': 'swedish'}
|
||||||
|
)
|
||||||
|
|
||||||
|
# DAMAGE TAKEN - English
|
||||||
|
match = self.PATTERN_DAMAGE_TAKEN_EN.match(line)
|
||||||
|
if match:
|
||||||
|
return LogEvent(
|
||||||
|
timestamp=self._parse_timestamp(match.group(1)),
|
||||||
|
event_type='damage_taken',
|
||||||
|
raw_line=line,
|
||||||
|
data={'damage': Decimal(match.group(2)), 'language': 'english'}
|
||||||
)
|
)
|
||||||
|
|
||||||
# HEALING
|
# HEALING
|
||||||
|
|
|
||||||
20
main.py
20
main.py
|
|
@ -207,7 +207,7 @@ class LemontropiaApp:
|
||||||
logger.info(f"Using REAL log: {log_path}")
|
logger.info(f"Using REAL log: {log_path}")
|
||||||
|
|
||||||
# Stats tracking
|
# Stats tracking
|
||||||
stats = {'loot': 0, 'globals': 0, 'hofs': 0, 'skills': 0, 'total_ped': Decimal('0.0')}
|
stats = {'loot': 0, 'globals': 0, 'hofs': 0, 'skills': 0, 'damage_dealt': 0, 'damage_taken': 0, 'evades': 0, 'total_ped': Decimal('0.0')}
|
||||||
|
|
||||||
def on_event(event):
|
def on_event(event):
|
||||||
"""Handle log events."""
|
"""Handle log events."""
|
||||||
|
|
@ -235,12 +235,27 @@ class LemontropiaApp:
|
||||||
elif event.event_type == 'skill':
|
elif event.event_type == 'skill':
|
||||||
stats['skills'] += 1
|
stats['skills'] += 1
|
||||||
print(f" 📈 Skill: {event.data.get('skill_name')} +{event.data.get('gained')}")
|
print(f" 📈 Skill: {event.data.get('skill_name')} +{event.data.get('gained')}")
|
||||||
|
|
||||||
|
elif event.event_type == 'damage_dealt':
|
||||||
|
stats['damage_dealt'] += 1
|
||||||
|
print(f" 💥 Damage Dealt: {event.data.get('damage')} pts")
|
||||||
|
|
||||||
|
elif event.event_type == 'damage_taken':
|
||||||
|
stats['damage_taken'] += 1
|
||||||
|
print(f" 🛡️ Damage Taken: {event.data.get('damage')} pts")
|
||||||
|
|
||||||
|
elif event.event_type == 'evade':
|
||||||
|
stats['evades'] += 1
|
||||||
|
print(f" ✨ {event.data.get('type', 'Evade')}")
|
||||||
|
|
||||||
# Subscribe to events
|
# Subscribe to events
|
||||||
self.watcher.subscribe('loot', on_event)
|
self.watcher.subscribe('loot', on_event)
|
||||||
self.watcher.subscribe('global', on_event)
|
self.watcher.subscribe('global', on_event)
|
||||||
self.watcher.subscribe('hof', on_event)
|
self.watcher.subscribe('hof', on_event)
|
||||||
self.watcher.subscribe('skill', on_event)
|
self.watcher.subscribe('skill', on_event)
|
||||||
|
self.watcher.subscribe('damage_dealt', on_event)
|
||||||
|
self.watcher.subscribe('damage_taken', on_event)
|
||||||
|
self.watcher.subscribe('evade', on_event)
|
||||||
|
|
||||||
print("\n" + "="*50)
|
print("\n" + "="*50)
|
||||||
print("🔴 LIVE SESSION RUNNING")
|
print("🔴 LIVE SESSION RUNNING")
|
||||||
|
|
@ -271,6 +286,9 @@ class LemontropiaApp:
|
||||||
print(f" Globals: {stats['globals']}")
|
print(f" Globals: {stats['globals']}")
|
||||||
print(f" HoFs: {stats['hofs']}")
|
print(f" HoFs: {stats['hofs']}")
|
||||||
print(f" Skills: {stats['skills']}")
|
print(f" Skills: {stats['skills']}")
|
||||||
|
print(f" Damage Dealt: {stats['damage_dealt']}")
|
||||||
|
print(f" Damage Taken: {stats['damage_taken']}")
|
||||||
|
print(f" Evades/Misses: {stats['evades']}")
|
||||||
print(f" Total Value: {stats['total_ped']} PED")
|
print(f" Total Value: {stats['total_ped']} PED")
|
||||||
print(f"\n View full stats: Option 4 (Project Statistics)")
|
print(f"\n View full stats: Option 4 (Project Statistics)")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue