From 3e27dfb129d45d9e7f4159d279024a49a7f0685d Mon Sep 17 00:00:00 2001 From: Sean Sube Date: Sun, 5 May 2024 20:17:32 -0500 Subject: [PATCH] add combat and environmental systems --- adventure/sim_systems/combat_actions.py | 86 +++++++++++++++++++ adventure/sim_systems/environment_logic.yaml | 39 +++++++++ adventure/sim_systems/environment_triggers.py | 23 +++++ 3 files changed, 148 insertions(+) create mode 100644 adventure/sim_systems/combat_actions.py create mode 100644 adventure/sim_systems/environment_logic.yaml create mode 100644 adventure/sim_systems/environment_triggers.py diff --git a/adventure/sim_systems/combat_actions.py b/adventure/sim_systems/combat_actions.py new file mode 100644 index 0000000..c02c8b6 --- /dev/null +++ b/adventure/sim_systems/combat_actions.py @@ -0,0 +1,86 @@ +from adventure.context import get_dungeon_master, get_agent_for_actor, get_current_context, broadcast + + +def action_attack(target: str) -> str: + """ + Attack a character or item in the room. + + Args: + target: The name of the character or item to attack. + """ + + _, action_room, action_actor = get_current_context() + + # make sure the target is in the room + target_actor = next((actor for actor in action_room.actors if actor.name == target), None) + target_item = next((item for item in action_room.items if item.name == target), None) + + dungeon_master = get_dungeon_master() + if target_actor: + target_agent = get_agent_for_actor(target_actor) + if not target_agent: + raise ValueError(f"no agent found for actor {target_actor.name}") + + reaction = target_agent( + f"{action_actor.name} is attacking you in the {action_room.name}. How do you react?" + "Respond with 'fighting', 'fleeing', or 'surrendering'." + ) + + outcome = dungeon_master( + f"{action_actor.name} attacks {target} in the {action_room.name}. {action_room.description}." + f"{action_actor.description}. {target_actor.description}." + f"{target} reacts by {reaction}. What is the outcome of the attack? Describe the result in detail." + ) + + description = ( + f"{action_actor.name} attacks the {target} in the {action_room.name}." + f"{target} reacts by {reaction}. {outcome}" + ) + broadcast(description) + return description + elif target_item: + outcome = dungeon_master( + f"{action_actor.name} attacks {target} in the {action_room.name}. {action_room.description}." + f"{action_actor.description}. {target_item.description}." + f"What is the outcome of the attack? Describe the result in detail." + ) + + description = ( + f"{action_actor.name} attacks the {target} in the {action_room.name}. {outcome}" + ) + broadcast(description) + return description + else: + return f"{target} is not in the {action_room.name}." + + +def action_cast(target: str, spell: str) -> str: + """ + Cast a spell on a character or item in the room. + + Args: + target: The name of the character or item to cast the spell on. + spell: The name of the spell to cast. + """ + + _, action_room, action_actor = get_current_context() + + # make sure the target is in the room + target_actor = next((actor for actor in action_room.actors if actor.name == target), None) + target_item = next((item for item in action_room.items if item.name == target), None) + + if not target_actor and not target_item: + return f"{target} is not in the {action_room.name}." + + dungeon_master = get_dungeon_master() + outcome = dungeon_master( + f"{action_actor.name} casts {spell} on {target} in the {action_room.name}. {action_room.description}." + f"{action_actor.description}. {target_actor.description if target_actor else target_item.description}." + f"What is the outcome of the spell? Describe the result in detail." + ) + + description = ( + f"{action_actor.name} casts {spell} on the {target} in the {action_room.name}. {outcome}" + ) + broadcast(description) + return description diff --git a/adventure/sim_systems/environment_logic.yaml b/adventure/sim_systems/environment_logic.yaml new file mode 100644 index 0000000..56260b5 --- /dev/null +++ b/adventure/sim_systems/environment_logic.yaml @@ -0,0 +1,39 @@ +rules: + # wet/dry logic + - group: environment-moisture + match: + type: actor + wet: true + chance: 0.2 + set: + wet: false + + - group: environment-moisture + match: + type: actor + wet: true + temperature: hot + chance: 0.5 + set: + wet: false + + - group: environment-temperature + match: + type: room + temperature: hot + chance: 0.5 + trigger: adventure.sim_systems.environment_triggers:hot_room + + - group: environment-temperature + match: + type: room + temperature: cold + chance: 0.5 + trigger: adventure.sim_systems.environment_triggers:cold_room + +labels: + wet: + true: + backstory: You are soaking wet. + description: They are soaking wet and dripping water. + # false intentionally omitted \ No newline at end of file diff --git a/adventure/sim_systems/environment_triggers.py b/adventure/sim_systems/environment_triggers.py new file mode 100644 index 0000000..bb9d9f6 --- /dev/null +++ b/adventure/sim_systems/environment_triggers.py @@ -0,0 +1,23 @@ +from adventure.models import Attributes, Room + + +def hot_room(room: Room, attributes: Attributes): + """ + If the room is hot, actors should get hotter. + """ + + for actor in room.actors: + actor.attributes["hot"] = "hot" + + return attributes + + +def cold_room(room: Room, attributes: Attributes): + """ + If the room is cold, actors should get colder. + """ + + for actor in room.actors: + actor.attributes["cold"] = "cold" + + return attributes