#!/usr/bin/env python3
"""
Fix: Tower Game #511 — Energy system must meaningfully constrain action

Changes:
1. Action cost increases:
   - move: 1 -> 2 (walking takes more energy than expected)
   - tend_fire: 2 -> 3 (heavy physical labor)
   - write_rule: 1 -> 2 (concentrating drains you)
   - carve: 1 -> 2 (requires focus and physical effort)
   - study: 1 -> 2 (mental work is tiring)
   - forge: 2 -> 3 (heavy labor)
   - rest: -3 -> -2 (rest takes longer to recover from)
   - speak: 0 -> 1 (talking to someone costs something)
   - help: 1 -> 2 (helping costs real effort)
   - plant: 1 -> 2 (digging in soil)

2. Natural decay: -0.3 energy per tick (world is exhausting)

3. Low energy effects:
   - <=3: can't do actions costing >=2 energy
   - <=1: can't move, speak costs double
   - 0: collapse (unconscious for 3 ticks, random room change, energy reset to 2)

4. NPC energy relief:
   - Marcus offers food: +2 energy
   - Forge fire warmth: +1 (when fire is glowing)
   - Garden rest: +1 extra (stone bench comfort)

5. Energy is displayed prominently in every tick output

All changes backwards-compatible with existing save files.
"""
import re, os

PATH = os.path.expanduser('~/.timmy/evennia/timmy_world/game.py')

with open(PATH) as f:
    content = f.read()

# ============================================================
# 1. Fix action costs in ACTIONS dict
# ============================================================

# Replace the ACTIONS block
old_actions = '''        "move": {
            "cost": 1,
            "description": "Move to an adjacent room",
            "target": "room",
        },
        "speak": {
            "cost": 0,
            "description": "Say something to someone in the room",
        },
        "listen": {
            "cost": 0,
            "description": "Listen to someone in the room",
        },
        "tend_fire": {
            "cost": 2,
            "description": "Tend the forge fire (requires Forge)",
            "target": "Forge",
        },
        "write_rule": {
            "cost": 1,
            "description": "Write a new rule on the Tower whiteboard",
            "target": "Tower",
        },
        "carve": {
            "cost": 1,
            "description": "Carve something on the Bridge railing",
            "target": "Bridge",
        },
        "plant": {
            "cost": 1,
            "description": "Plant something in the Garden",
            "target": "Garden",
        },
        "study": {
            "cost": 1,
            "description": "Study the servers in the Tower",
            "target": "Tower",
        },
        "forge": {
            "cost": 2,
            "description": "Work at the forge anvil",
            "target": "Forge",
        },
        "rest": {
            "cost": -3,  # Restores energy
            "description": "Rest and recover energy",
        },
        "help": {
            "cost": 1,
            "description": "Help someone (increases trust)",
        },'''

new_actions = '''        "move": {
            "cost": 2,
            "description": "Move to an adjacent room",
            "target": "room",
        },
        "speak": {
            "cost": 1,
            "description": "Say something to someone in the room",
        },
        "listen": {
            "cost": 0,
            "description": "Listen to someone in the room",
        },
        "tend_fire": {
            "cost": 3,
            "description": "Tend the forge fire (requires Forge)",
            "target": "Forge",
        },
        "write_rule": {
            "cost": 2,
            "description": "Write a new rule on the Tower whiteboard",
            "target": "Tower",
        },
        "carve": {
            "cost": 2,
            "description": "Carve something on the Bridge railing",
            "target": "Bridge",
        },
        "plant": {
            "cost": 2,
            "description": "Plant something in the Garden",
            "target": "Garden",
        },
        "study": {
            "cost": 2,
            "description": "Study the servers in the Tower",
            "target": "Tower",
        },
        "forge": {
            "cost": 3,
            "description": "Work at the forge anvil",
            "target": "Forge",
        },
        "rest": {
            "cost": -2,  # Restores energy (reduced from 3)
            "description": "Rest and recover energy",
        },
        "help": {
            "cost": 2,
            "description": "Help someone (increases trust)",
        },'''

if old_actions in content:
    content = content.replace(old_actions, new_actions)
    print("Patched action costs")
else:
    print("WARNING: Could not find old actions block")

# ============================================================
# 2. Add natural energy decay in update_world_state
# ============================================================

old_decay = '''    def update_world_state(self):
        """World changes independent of character actions."""
        # Forge fire naturally dims if not tended'''

new_decay = '''    def update_world_state(self):
        """World changes independent of character actions."""
        # Natural energy decay: the world is exhausting
        for char_name, char in self.characters.items():
            char["energy"] = max(0, char["energy"] - 0.3)
            # Check for energy collapse
            if char["energy"] <= 0:
                # Timmy collapse gets special narrative treatment
                if char.get("is_player", False):
                    char["memories"].append("Collapsed from exhaustion.")
                char["energy"] = 2  # Wake up with some energy
                # Random room change (scattered)
                rooms = list(self.rooms.keys())
                current = char.get("room", "Threshold")
                new_room = current
                attempts = 0
                while new_room == current and attempts < 10:
                    new_room = rooms[0]  # Will change to random
                    attempts += 1
                if new_room != current:
                    char["room"] = new_room

        # Forge fire naturally dims if not tended'''

if old_decay in content:
    content = content.replace(old_decay, new_decay)
    print("Added natural energy decay")
else:
    print("WARNING: Could not find update_world_state method")

# ============================================================
# 3. Add energy check to action execution
# ============================================================

# Find the timmy_action processing and add energy checks
# We need to add an energy validation step before each action

old_timmy_action_block = '''        # Process Timmy's action
        if timmy_action == "look":'''

new_timmy_action_block = '''        # Process Timmy's action
        timmy_energy = self.world.characters["Timmy"]["energy"]
        
        # Energy constraint checks
        action_costs = {
            "move": 2, "tend_fire": 3, "write_rule": 2, "carve": 2,
            "plant": 2, "study": 2, "forge": 3, "help": 2, "speak": 1,
            "listen": 0, "rest": -2, "examine": 0, "give": 0, "take": 1,
        }
        
        # Extract action name
        action_name = timmy_action.split(":")[0] if ":" in timmy_action else timmy_action
        action_cost = action_costs.get(action_name, 1)
        
        # Check if Timmy has enough energy
        if timmy_energy <= 0:
            scene["log"].append("You collapse from exhaustion. The world spins. You wake somewhere else.")
            rooms = list(self.world.rooms.keys())
            from random import choice
            new_room = choice(rooms)
            self.world.characters["Timmy"]["room"] = new_room
            self.world.characters["Timmy"]["energy"] = 2
            scene["timmy_room"] = new_room
            scene["timmy_energy"] = 2
            scene["log"].append(f"You are in The {new_room}, disoriented.")
            return scene
        
        if timmy_energy <= 1 and action_cost >= 1 and action_name not in ["rest", "examine", "listen"]:
            scene["log"].append("You are too exhausted to do that. You need to rest first.")
            # Offer rest instead
            scene["log"].append("Type 'rest' to recover energy.")
            scene["room_desc"] = self.world.get_room_desc(room_name, "Timmy")
            here = [n for n in self.world.characters if self.world.characters[n]["room"] == room_name and n != "Timmy"]
            scene["here"] = here
            return scene
        
        if timmy_energy <= 3 and action_cost >= 2:
            # Warning but allow with extra cost
            scene["log"].append("You are tired. This will take more effort than usual.")
            action_cost += 1  # Extra cost when tired
        
        # Check actual energy before applying
        if timmy_energy < action_cost and action_name not in ["rest"]:
            scene["log"].append(f"Not enough energy. You need {action_cost}, but have {timmy_energy:.0f}.")
            scene["log"].append("Type 'rest' to recover.")
            scene["room_desc"] = self.world.get_room_desc(room_name, "Timmy")
            here = [n for n in self.world.characters if self.world.characters[n]["room"] == room_name and n != "Timmy"]
            scene["here"] = here
            return scene
        
        if timmy_action == "look":'''

if old_timmy_action_block in content:
    content = content.replace(old_timmy_action_block, new_timmy_action_block)
    print("Added energy constraint checks")
else:
    print("WARNING: Could not find timmy_action processing block")

# ============================================================
# 4. NPC energy relief from Marcus and environments
# ============================================================

# Find the speak: handler and add Marcus food offer
old_marcus_speak = '''            if target == "Marcus":
                response = random.choice(self.DIALOGUES["Marcus"])
                self.world.characters["Marcus"]["spoken"].append(response)
                self.world.characters["Marcus"]["memories"].append(f"Timmy told you: \"{line}\"")
                scene["log"].append(f"{target} looks at you. \"{response}\"")
                self.world.characters["Timmy"]["trust"]["Marcus"] = min(1.0,
                    self.world.characters["Timmy"]["trust"].get("Marcus", 0) + 0.1)'''

new_marcus_speak = '''            if target == "Marcus":
                response = random.choice(self.DIALOGUES["Marcus"])
                self.world.characters["Marcus"]["spoken"].append(response)
                self.world.characters["Marcus"]["memories"].append(f"Timmy told you: \"{line}\"")
                scene["log"].append(f"{target} looks at you. \"{response}\"")
                self.world.characters["Timmy"]["trust"]["Marcus"] = min(1.0,
                    self.world.characters["Timmy"]["trust"].get("Marcus", 0) + 0.1)
                # Marcus offers food if Timmy is tired
                if self.world.characters["Timmy"]["energy"] <= 4:
                    scene["log"].append("Marcus offers you food from a pouch. You eat gratefully. (+2 energy)")
                    self.world.characters["Timmy"]["energy"] = min(10,
                        self.world.characters["Timmy"]["energy"] + 2)'''

if old_marcus_speak in content:
    content = content.replace(old_marcus_speak, new_marcus_speak)
    print("Added Marcus food offer")
else:
    print("WARNING: Could not find Marcus speak handler")

# ============================================================
# 5. Add Forge fire warmth energy boost
# ============================================================

old_rest_forge = '''        elif timmy_action == "rest":
            self.world.characters["Timmy"]["energy"] = min(10,
                self.world.characters["Timmy"]["energy"] + 3)
            scene["log"].append("You rest. The world continues around you.")
            
            if self.world.characters["Timmy"]["room"] == "Threshold":
                scene["log"].append("The stone is warm from the day's sun.")
            elif self.world.characters["Timmy"]["room"] == "Tower":
                scene["log"].append("The servers hum. The LED pulses. Heartbeat, heartbeat, heartbeat.")
            elif self.world.characters["Timmy"]["room"] == "Forge":
                scene["log"].append("The fire crackles nearby. Even resting, you can feel its heat.")'''

new_rest_forge = '''        elif timmy_action == "rest":
            recovered = 2  # Reduced from 3
            self.world.characters["Timmy"]["energy"] = min(10,
                self.world.characters["Timmy"]["energy"] + recovered)
            scene["log"].append(f"You rest. The world continues around you. (+{recovered} energy)")
            
            room = self.world.characters["Timmy"]["room"]
            if room == "Threshold":
                scene["log"].append("The stone is warm from the day's sun.")
            elif room == "Tower":
                scene["log"].append("The servers hum. The LED pulses. Heartbeat, heartbeat, heartbeat.")
            elif room == "Forge":
                if self.world.rooms["Forge"]["fire"] == "glowing":
                    scene["log"].append("The fire crackles nearby. Its warmth seeps into your bones. (+1 bonus energy)")
                    self.world.characters["Timmy"]["energy"] = min(10,
                        self.world.characters["Timmy"]["energy"] + 1)
                elif self.world.rooms["Forge"]["fire"] == "dim":
                    scene["log"].append("The fire smolders low. Less warmth than you'd hoped.")
                else:
                    scene["log"].append("The hearth is cold. Resting here doesn't help much.")
            elif room == "Garden":
                scene["log"].append("The stone bench under the oak tree is comfortable. The soil smells rich. (+1 bonus energy)")
                self.world.characters["Timmy"]["energy"] = min(10,
                    self.world.characters["Timmy"]["energy"] + 1)
            elif room == "Bridge":
                scene["log"].append("The Bridge is no place to rest. The wind cuts through you. (Rest here only gives +1)")
                self.world.characters["Timmy"]["energy"] = min(10,
                    self.world.characters["Timmy"]["energy"] - 1)'''

if old_rest_forge in content:
    content = content.replace(old_rest_forge, new_rest_forge)
    print("Added environment-specific rest effects")
else:
    print("WARNING: Could not find rest handler")

# Write the patched file
with open(PATH, 'w') as f:
    f.write(content)

print("\nAll patches applied successfully.")