Combat frontend rewrite: Clean architecture with structured messages, animations, and i18n

This commit is contained in:
Joan
2026-01-09 11:14:40 +01:00
parent 2875e72b20
commit f986fa18a0
8 changed files with 381 additions and 200 deletions

View File

@@ -600,7 +600,7 @@ async def npc_attack(player_id: int, combat: dict, npc_def, reduce_armor_func) -
actual_damage = max(1, npc_damage - armor_absorbed)
new_player_hp = max(0, player['hp'] - actual_damage)
message += create_combat_message("enemy_attack", npc_name=npc_def.name, damage=npc_damage, armor_absorbed=armor_absorbed)
message += create_combat_message("enemy_attack", origin="enemy", npc_name=npc_def.name, damage=npc_damage, armor_absorbed=armor_absorbed)
if armor_absorbed > 0:
message += f" (Armor absorbed {armor_absorbed})"

View File

@@ -147,7 +147,7 @@ async def initiate_combat(
await manager.send_personal_message(current_user['id'], {
"type": "combat_started",
"data": {
"message": create_combat_message("combat_start", npc_name=npc_def.name),
"message": create_combat_message("combat_start", origin="neutral", npc_name=npc_def.name),
"combat": {
"npc_id": enemy.npc_id,
"npc_name": npc_def.name,
@@ -178,7 +178,7 @@ async def initiate_combat(
return {
"success": True,
"message": create_combat_message("combat_start", npc_name=npc_def.name),
"message": create_combat_message("combat_start", origin="neutral", npc_name=npc_def.name),
"combat": {
"npc_id": enemy.npc_id,
"npc_name": npc_def.name,
@@ -283,7 +283,7 @@ async def combat_action(
else:
# Apply damage to NPC
new_npc_hp = max(0, combat['npc_hp'] - damage)
result_message = f"You attack for {damage} damage! "
result_message = create_combat_message("player_attack", origin="player", damage=damage)
# Apply weapon effects
if weapon_effects and 'bleeding' in weapon_effects:
@@ -304,7 +304,7 @@ async def combat_action(
if new_npc_hp <= 0:
# NPC defeated
result_message += create_combat_message("victory", npc_name=npc_def.name)
result_message += "\n" + create_combat_message("victory", origin="neutral", npc_name=npc_def.name)
combat_over = True
player_won = True
@@ -435,7 +435,7 @@ async def combat_action(
# Failed to flee, NPC attacks
npc_damage = random.randint(npc_def.damage_min, npc_def.damage_max)
new_player_hp = max(0, player['hp'] - npc_damage)
result_message = create_combat_message("flee_fail", npc_name=npc_def.name, damage=npc_damage)
result_message = create_combat_message("flee_fail", origin="enemy", npc_name=npc_def.name, damage=npc_damage)
if new_player_hp <= 0:
result_message += "\nYou have been defeated!"

View File

@@ -39,18 +39,20 @@ def translate_travel_message(direction: str, location_name: str, lang: str = 'en
import json
def create_combat_message(message_type: str, **data) -> str:
"""Create a structured combat message with type and data.
def create_combat_message(message_type: str, origin: str = "neutral", **data) -> str:
"""Create a structured combat message with type, origin, and data.
Args:
message_type: Type of combat message (combat_start, player_attack, etc.)
origin: Origin of the event - "player", "enemy", or "neutral"
**data: Dynamic data for the message (damage, npc_name, etc.)
Returns:
Dictionary with 'type' and 'data' fields
JSON string with 'type', 'origin', and 'data' fields
"""
return json.dumps({
"type": message_type,
"origin": origin,
"data": data
})