1
0
Fork 0
taleweave-ai/taleweave/systems/weather/__init__.py

102 lines
2.9 KiB
Python
Raw Normal View History

from functools import partial
2024-05-27 13:47:58 +00:00
from typing import List
from taleweave.context import get_dungeon_master
2024-05-27 13:47:58 +00:00
from taleweave.models.base import dataclass
from taleweave.models.entity import World
from taleweave.systems.logic import load_logic
from taleweave.game_system import GameSystem
from packit.agent import Agent
from taleweave.models.entity import Room, WorldEntity
from taleweave.utils.string import or_list
from packit.results import enum_result
from packit.loops import loop_retry
from logging import getLogger
logger = getLogger(__name__)
2024-05-27 13:47:58 +00:00
LOGIC_FILES = [
"./taleweave/systems/weather/weather_logic.yaml",
]
@dataclass
class TimeOfDay:
name: str
start: int
end: int
2024-05-27 14:01:10 +00:00
GAME_START_HOUR = 8
2024-05-27 13:47:58 +00:00
TURNS_PER_DAY = 24
TIMES_OF_DAY: List[TimeOfDay] = [
TimeOfDay("night", 0, 4),
TimeOfDay("morning", 5, 7),
TimeOfDay("day", 8, 18),
TimeOfDay("evening", 20, 22),
TimeOfDay("night", 23, 24),
]
def get_time_of_day(turn: int) -> TimeOfDay:
2024-05-27 14:01:10 +00:00
hour = (turn + GAME_START_HOUR) % TURNS_PER_DAY
2024-05-27 13:47:58 +00:00
for time in TIMES_OF_DAY:
if time.start <= hour <= time.end:
return time
return TIMES_OF_DAY[0]
2024-05-27 14:01:10 +00:00
def initialize_weather(world: World):
time_of_day = get_time_of_day(0)
2024-05-27 13:47:58 +00:00
for room in world.rooms:
logger.info(f"initializing weather for {room.name}")
2024-05-27 13:47:58 +00:00
room.attributes["time"] = time_of_day.name
if "environment" not in room.attributes:
dungeon_master = get_dungeon_master()
generate_room_weather(dungeon_master, world.theme, room)
def generate_room_weather(agent: Agent, theme: str, entity: Room) -> None:
environment_options = ["indoor", "outdoor"]
environment_result = partial(enum_result, enum=environment_options)
environment = loop_retry(
agent,
"Is this room indoors or outdoors?"
"Reply with a single word: {environment_list}.\n\n"
"{description}",
context={
"environment_list": or_list(environment_options),
"description": entity.description,
},
result_parser=environment_result,
)
entity.attributes["environment"] = environment
logger.info(f"generated environment for {entity.name}: {environment}")
2024-05-27 13:47:58 +00:00
def generate_weather(agent: Agent, theme: str, entity: WorldEntity) -> None:
if isinstance(entity, Room):
if "environment" not in entity.attributes:
generate_room_weather(agent, theme, entity)
2024-05-27 14:01:10 +00:00
def simulate_weather(world: World, turn: int, data: None = None):
time_of_day = get_time_of_day(turn)
for room in world.rooms:
room.attributes["time"] = time_of_day.name
2024-05-27 13:47:58 +00:00
2024-05-27 14:01:10 +00:00
def init():
logic_systems = [load_logic(filename) for filename in LOGIC_FILES]
return [
*logic_systems,
GameSystem(
"weather",
generate=generate_weather,
initialize=initialize_weather,
simulate=simulate_weather,
),
2024-05-27 14:01:10 +00:00
]