"""POV template engine for combat messages.""" import re from typing import Any def render_pov( template: str, viewer: Any | None, attacker: Any | None, defender: Any | None, ) -> str: """Render a combat message template from a specific viewer's POV. Args: template: Message template with {attacker}, {defender}, and contextual tags like {s}, {es}, {y|ies}, {his}, {him} viewer: Entity viewing the message (determines "You" vs name) attacker: Attacking entity defender: Defending entity Returns: Rendered message with appropriate perspective substitutions Contextual tags apply to the most recently mentioned entity: - {s} → "" for 2nd person, "s"/"es" for 3rd (smart conjugation) - {es} → "" for 2nd person, "es" for 3rd person - {y|ies} → left form for 2nd person, right form for 3rd person - {his} → "your" for 2nd person, "his" for 3rd person - {him} → "you" for 2nd person, "him" for 3rd person """ if not template: return template # Track whether the last entity mentioned was "You" (2nd person) last_was_you = False # Pattern to match all tags tag_pattern = re.compile(r"\{(attacker|defender|s|es|his|him|[^}]*\|[^}]*)\}") # Process template character by character, building result result = [] pos = 0 for match in tag_pattern.finditer(template): # Add text before this tag result.append(template[pos : match.start()]) tag = match.group(0) tag_name = match.group(1) # Entity tags if tag_name in ("attacker", "defender"): entity = attacker if tag_name == "attacker" else defender if entity is viewer: last_was_you = True result.append("You") else: last_was_you = False result.append(entity.name if entity else "") # Contextual verb conjugation tags elif tag == "{s}": if last_was_you: result.append("") else: # Check previous character for smart conjugation prev_text = "".join(result) if prev_text and ( prev_text[-1:] in "sxz" or (len(prev_text) >= 2 and prev_text[-2:] in ("ch", "sh")) ): result.append("es") else: result.append("s") elif tag == "{es}": result.append("" if last_was_you else "es") elif tag == "{his}": result.append("your" if last_was_you else "his") elif tag == "{him}": # Check if "self" follows to form reflexive pronoun remaining = template[match.end() :] if remaining.startswith("self"): result.append("your" if last_was_you else "him") else: result.append("you" if last_was_you else "him") elif "|" in tag: # Handle {a|b} pattern content = tag[1:-1] # Strip { and } left, right = content.split("|", 1) result.append(left if last_was_you else right) else: result.append(tag) pos = match.end() # Add remaining text after last tag result.append(template[pos:]) return "".join(result)