add weather and time-of-day system
This commit is contained in:
parent
a30e762498
commit
dd999a89eb
|
@ -113,7 +113,7 @@ python3 -m adventure.main \
|
|||
--discord=true \
|
||||
--server=true \
|
||||
--rooms 3 \
|
||||
--steps 30 \
|
||||
--turns 30 \
|
||||
--optional-actions=true \
|
||||
--actions adventure.sim_systems:init_actions \
|
||||
--systems adventure.sim_systems:init_logic
|
||||
|
|
|
@ -29,6 +29,7 @@ logger = getLogger(__name__)
|
|||
QUEST_SYSTEM = "quest"
|
||||
|
||||
|
||||
# region models
|
||||
@dataclass
|
||||
class QuestGoalContains:
|
||||
"""
|
||||
|
@ -82,7 +83,47 @@ class QuestData:
|
|||
completed: Dict[str, List[Quest]]
|
||||
|
||||
|
||||
# region quest completion
|
||||
# endregion
|
||||
|
||||
|
||||
# region state helpers
|
||||
def complete_quest(quests: QuestData, character: Character, quest: Quest) -> None:
|
||||
"""
|
||||
Complete the given quest for the given character.
|
||||
"""
|
||||
if quest in quests.available.get(character.name, []):
|
||||
quests.available[character.name].remove(quest)
|
||||
|
||||
if quest == quests.active.get(character.name, None):
|
||||
del quests.active[character.name]
|
||||
|
||||
if character.name not in quests.completed:
|
||||
quests.completed[character.name] = []
|
||||
|
||||
quests.completed[character.name].append(quest)
|
||||
|
||||
|
||||
def get_quests_for_character(quests: QuestData, character: Character) -> List[Quest]:
|
||||
"""
|
||||
Get all quests for the given character.
|
||||
"""
|
||||
return quests.available.get(character.name, [])
|
||||
|
||||
|
||||
def set_active_quest(quests: QuestData, character: Character, quest: Quest) -> None:
|
||||
"""
|
||||
Set the active quest for the given character.
|
||||
"""
|
||||
quests.active[character.name] = quest
|
||||
|
||||
|
||||
def get_active_quest(quests: QuestData, character: Character) -> Quest | None:
|
||||
"""
|
||||
Get the active quest for the given character.
|
||||
"""
|
||||
return quests.active.get(character.name)
|
||||
|
||||
|
||||
def is_quest_complete(world: World, quest: Quest) -> bool:
|
||||
"""
|
||||
Check if the given quest is complete.
|
||||
|
@ -121,47 +162,7 @@ def is_quest_complete(world: World, quest: Quest) -> bool:
|
|||
# endregion
|
||||
|
||||
|
||||
# region state management
|
||||
def get_quests_for_character(quests: QuestData, character: Character) -> List[Quest]:
|
||||
"""
|
||||
Get all quests for the given character.
|
||||
"""
|
||||
return quests.available.get(character.name, [])
|
||||
|
||||
|
||||
def set_active_quest(quests: QuestData, character: Character, quest: Quest) -> None:
|
||||
"""
|
||||
Set the active quest for the given character.
|
||||
"""
|
||||
quests.active[character.name] = quest
|
||||
|
||||
|
||||
def get_active_quest(quests: QuestData, character: Character) -> Quest | None:
|
||||
"""
|
||||
Get the active quest for the given character.
|
||||
"""
|
||||
return quests.active.get(character.name)
|
||||
|
||||
|
||||
def complete_quest(quests: QuestData, character: Character, quest: Quest) -> None:
|
||||
"""
|
||||
Complete the given quest for the given character.
|
||||
"""
|
||||
if quest in quests.available.get(character.name, []):
|
||||
quests.available[character.name].remove(quest)
|
||||
|
||||
if quest == quests.active.get(character.name, None):
|
||||
del quests.active[character.name]
|
||||
|
||||
if character.name not in quests.completed:
|
||||
quests.completed[character.name] = []
|
||||
|
||||
quests.completed[character.name].append(quest)
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
# region game system callbacks
|
||||
def initialize_quests(world: World) -> QuestData:
|
||||
"""
|
||||
Initialize quests for the world.
|
||||
|
@ -214,6 +215,10 @@ def simulate_quests(world: World, turn: int, data: QuestData | None = None) -> N
|
|||
complete_quest(quests, character, active_quest)
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
# region I/O
|
||||
def load_quest_data(file: str) -> QuestData:
|
||||
logger.info(f"loading quest data from {file}")
|
||||
return load_system_data(QuestData, file)
|
||||
|
@ -224,6 +229,9 @@ def save_quest_data(file: str, data: QuestData) -> None:
|
|||
return save_system_data(QuestData, file, data)
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
def init() -> List[GameSystem]:
|
||||
return [
|
||||
GameSystem(
|
||||
|
|
|
@ -3,12 +3,6 @@ from .language_actions import action_read
|
|||
from .magic_actions import action_cast
|
||||
from .movement_actions import action_climb
|
||||
|
||||
from taleweave.systems.logic import load_logic
|
||||
|
||||
LOGIC_FILES = [
|
||||
"./adventure/systems/rpg/weather_logic.yaml",
|
||||
]
|
||||
|
||||
|
||||
def init_actions():
|
||||
return [
|
||||
|
@ -24,4 +18,4 @@ def init_actions():
|
|||
|
||||
|
||||
def init_logic():
|
||||
return [load_logic(filename) for filename in LOGIC_FILES]
|
||||
return []
|
||||
|
|
|
@ -5,11 +5,11 @@ from .sleeping_actions import action_sleep
|
|||
from taleweave.systems.logic import load_logic
|
||||
|
||||
LOGIC_FILES = [
|
||||
"./adventure/systems/sim/environment_logic.yaml",
|
||||
"./adventure/systems/sim/hunger_logic.yaml",
|
||||
"./adventure/systems/sim/hygiene_logic.yaml",
|
||||
"./adventure/systems/sim/mood_logic.yaml",
|
||||
"./adventure/systems/sim/sleeping_logic.yaml",
|
||||
"./taleweave/systems/sim/environment_logic.yaml",
|
||||
"./taleweave/systems/sim/hunger_logic.yaml",
|
||||
"./taleweave/systems/sim/hygiene_logic.yaml",
|
||||
"./taleweave/systems/sim/mood_logic.yaml",
|
||||
"./taleweave/systems/sim/sleeping_logic.yaml",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
from typing import List
|
||||
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
|
||||
|
||||
LOGIC_FILES = [
|
||||
"./taleweave/systems/weather/weather_logic.yaml",
|
||||
]
|
||||
|
||||
|
||||
@dataclass
|
||||
class TimeOfDay:
|
||||
name: str
|
||||
start: int
|
||||
end: int
|
||||
|
||||
|
||||
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:
|
||||
hour = turn % TURNS_PER_DAY
|
||||
for time in TIMES_OF_DAY:
|
||||
if time.start <= hour <= time.end:
|
||||
return time
|
||||
return TIMES_OF_DAY[0]
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
def init_systems():
|
||||
return [GameSystem("weather", simulate=simulate_weather)]
|
||||
|
||||
|
||||
def init_logic():
|
||||
return [load_logic(filename) for filename in LOGIC_FILES]
|
|
@ -4,51 +4,60 @@ rules:
|
|||
match:
|
||||
type: room
|
||||
outdoor: true
|
||||
weather: sunny
|
||||
weather: clear
|
||||
chance: 0.1
|
||||
set:
|
||||
weather: cloudy
|
||||
weather: clouds
|
||||
|
||||
- group: weather
|
||||
match:
|
||||
type: room
|
||||
outdoor: true
|
||||
weather: cloudy
|
||||
weather: clouds
|
||||
chance: 0.1
|
||||
set:
|
||||
weather: rainy
|
||||
weather: rain
|
||||
|
||||
- group: weather
|
||||
match:
|
||||
type: room
|
||||
outdoor: true
|
||||
weather: rainy
|
||||
weather: rain
|
||||
chance: 0.1
|
||||
set:
|
||||
weather: sunny
|
||||
weather: clear
|
||||
|
||||
- group: weather
|
||||
match:
|
||||
type: room
|
||||
outdoor: true
|
||||
weather: cloudy
|
||||
weather: clouds
|
||||
chance: 0.1
|
||||
set:
|
||||
weather: sunny
|
||||
weather: clear
|
||||
|
||||
labels:
|
||||
- match:
|
||||
type: room
|
||||
weather: sunny
|
||||
weather: clear
|
||||
rule: |
|
||||
"time" not in attributes or attributes&.time in ["morning", "day"]
|
||||
backstory: The sun is shining brightly.
|
||||
description: The sun is shining brightly.
|
||||
- match:
|
||||
type: room
|
||||
weather: cloudy
|
||||
weather: clear
|
||||
rule: |
|
||||
"time" in attributes and attributes&.time in ["evening", "night"]
|
||||
backstory: The moon is shining brightly.
|
||||
description: The moon is shining brightly.
|
||||
- match:
|
||||
type: room
|
||||
weather: clouds
|
||||
backstory: The sky is overcast.
|
||||
description: The sky is overcast.
|
||||
- match:
|
||||
type: room
|
||||
weather: rainy
|
||||
backstory: Rain is falling from the sky.
|
||||
description: Rain is falling from the sky.
|
||||
weather: rain
|
||||
backstory: Rain is falling from the cloudy sky.
|
||||
description: Rain is falling from the cloudy sky.
|
Loading…
Reference in New Issue