91 lines
2.8 KiB
Python
91 lines
2.8 KiB
Python
import json
|
|
from pathlib import Path
|
|
from typing import Any, Dict, Optional
|
|
|
|
from src.llm.models import CharacterStateUpdate
|
|
|
|
DATA_CHARS_DIR = Path("data/chars")
|
|
|
|
|
|
def ensure_chars_dir():
|
|
"""Ensures the character data directory exists."""
|
|
DATA_CHARS_DIR.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
def get_character_state(character_name: str) -> Dict[str, Any]:
|
|
"""
|
|
Reads character state from a JSON file.
|
|
If the character doesn't exist, returns a default state.
|
|
"""
|
|
ensure_chars_dir()
|
|
file_path = DATA_CHARS_DIR / f"{character_name}.json"
|
|
|
|
if not file_path.exists():
|
|
return {
|
|
"character_name": character_name,
|
|
"stats": {"hp": 0, "max_hp": 0, "ac": 0},
|
|
"status_effects": [],
|
|
"inventory": [],
|
|
}
|
|
|
|
with open(file_path, "r", encoding="utf-8") as f:
|
|
return json.load(f)
|
|
|
|
|
|
def update_character_state(update: CharacterStateUpdate):
|
|
"""
|
|
Updates character state based on a CharacterStateUpdate model.
|
|
Reads the current state, applies changes, and writes it back.
|
|
"""
|
|
ensure_chars_dir()
|
|
|
|
state = get_character_state(update.character_name)
|
|
|
|
# Update HP
|
|
if update.hp_change is not None:
|
|
current_hp = state.get("stats", {}).get("hp", 0)
|
|
state["stats"]["hp"] = current_hp + update.hp_change
|
|
|
|
# Update Status Effects
|
|
status_effects = set(state.get("status_effects", []))
|
|
for effect in update.status_effects_added:
|
|
status_effects.add(effect)
|
|
for effect in update.status_effects_removed:
|
|
status_effects.discard(effect)
|
|
state["status_effects"] = list(status_effects)
|
|
|
|
# Update Inventory
|
|
inventory = state.get("inventory", [])
|
|
for change in update.inventory_changes:
|
|
# Find if item already exists
|
|
item_exists = False
|
|
for item in inventory:
|
|
if item["item"] == change.item:
|
|
if change.action == "added":
|
|
item["quantity"] = item.get("quantity", 1) + change.quantity
|
|
elif change.action == "removed":
|
|
item["quantity"] = max(0, item.get("quantity", 1) - change.quantity)
|
|
item_exists = True
|
|
break
|
|
|
|
if not item_exists:
|
|
if change.action == "added":
|
|
inventory.append(
|
|
{
|
|
"item": change.item,
|
|
"quantity": change.quantity,
|
|
"weight": 0, # Default weight if not provided
|
|
}
|
|
)
|
|
elif change.action == "removed":
|
|
# Item not in inventory, do nothing or log
|
|
pass
|
|
|
|
state["inventory"] = inventory
|
|
|
|
file_path = DATA_CHARS_DIR / f"{update.character_name}.json"
|
|
with open(file_path, "w", encoding="utf-8") as f:
|
|
json.dump(state, f, indent=4)
|
|
|
|
return str(file_path)
|