2024-05-19 04:30:17 +00:00
|
|
|
from typing import Any, Generator
|
|
|
|
|
2024-05-27 13:10:24 +00:00
|
|
|
from taleweave.models.entity import (
|
2024-05-27 01:32:03 +00:00
|
|
|
Character,
|
2024-05-25 20:18:40 +00:00
|
|
|
EntityReference,
|
|
|
|
Item,
|
|
|
|
Portal,
|
|
|
|
Room,
|
|
|
|
World,
|
|
|
|
WorldEntity,
|
|
|
|
)
|
2024-05-19 04:30:17 +00:00
|
|
|
|
|
|
|
from .string import normalize_name
|
2024-05-13 04:33:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
def find_room(world: World, room_name: str) -> Room | None:
|
|
|
|
for room in world.rooms:
|
2024-05-19 04:30:17 +00:00
|
|
|
if normalize_name(room.name) == normalize_name(room_name):
|
2024-05-13 04:33:47 +00:00
|
|
|
return room
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2024-05-19 19:26:51 +00:00
|
|
|
def find_portal(world: World, portal_name: str) -> Portal | None:
|
|
|
|
for room in world.rooms:
|
2024-05-29 00:55:32 +00:00
|
|
|
portal = find_portal_in_room(room, portal_name)
|
|
|
|
if portal:
|
|
|
|
return portal
|
2024-05-19 19:26:51 +00:00
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
def find_character(world: World, character_name: str) -> Character | None:
|
2024-05-13 04:33:47 +00:00
|
|
|
for room in world.rooms:
|
2024-05-27 01:32:03 +00:00
|
|
|
character = find_character_in_room(room, character_name)
|
|
|
|
if character:
|
|
|
|
return character
|
2024-05-13 04:33:47 +00:00
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
def find_character_in_room(room: Room, character_name: str) -> Character | None:
|
|
|
|
for character in room.characters:
|
|
|
|
if normalize_name(character.name) == normalize_name(character_name):
|
|
|
|
return character
|
2024-05-13 04:33:47 +00:00
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2024-05-29 00:55:32 +00:00
|
|
|
def find_portal_in_room(room: Room, portal_name: str) -> Portal | None:
|
|
|
|
for portal in room.portals:
|
|
|
|
if normalize_name(portal.name) == normalize_name(portal_name):
|
|
|
|
return portal
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2024-05-19 20:27:56 +00:00
|
|
|
# TODO: allow item or str
|
2024-05-13 04:33:47 +00:00
|
|
|
def find_item(
|
|
|
|
world: World,
|
|
|
|
item_name: str,
|
2024-05-27 01:32:03 +00:00
|
|
|
include_character_inventory=False,
|
2024-05-13 04:33:47 +00:00
|
|
|
include_item_inventory=False,
|
|
|
|
) -> Item | None:
|
|
|
|
for room in world.rooms:
|
|
|
|
item = find_item_in_room(
|
2024-05-27 01:32:03 +00:00
|
|
|
room, item_name, include_character_inventory, include_item_inventory
|
2024-05-13 04:33:47 +00:00
|
|
|
)
|
|
|
|
if item:
|
|
|
|
return item
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
def find_item_in_character(
|
|
|
|
character: Character, item_name: str, include_item_inventory=False
|
2024-05-13 04:33:47 +00:00
|
|
|
) -> Item | None:
|
2024-05-27 01:32:03 +00:00
|
|
|
return find_item_in_container(character, item_name, include_item_inventory)
|
2024-05-13 04:33:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
def find_item_in_container(
|
2024-05-27 01:32:03 +00:00
|
|
|
container: Character | Item, item_name: str, include_item_inventory=False
|
2024-05-13 04:33:47 +00:00
|
|
|
) -> Item | None:
|
|
|
|
for item in container.items:
|
2024-05-19 04:30:17 +00:00
|
|
|
if normalize_name(item.name) == normalize_name(item_name):
|
2024-05-13 04:33:47 +00:00
|
|
|
return item
|
|
|
|
|
|
|
|
if include_item_inventory:
|
|
|
|
item = find_item_in_container(item, item_name, include_item_inventory)
|
|
|
|
if item:
|
|
|
|
return item
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def find_item_in_room(
|
|
|
|
room: Room,
|
|
|
|
item_name: str,
|
2024-05-27 01:32:03 +00:00
|
|
|
include_character_inventory=False,
|
2024-05-13 04:33:47 +00:00
|
|
|
include_item_inventory=False,
|
|
|
|
) -> Item | None:
|
|
|
|
for item in room.items:
|
2024-05-19 04:30:17 +00:00
|
|
|
if normalize_name(item.name) == normalize_name(item_name):
|
2024-05-13 04:33:47 +00:00
|
|
|
return item
|
|
|
|
|
|
|
|
if include_item_inventory:
|
|
|
|
item = find_item_in_container(item, item_name, include_item_inventory)
|
|
|
|
if item:
|
|
|
|
return item
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
if include_character_inventory:
|
|
|
|
for character in room.characters:
|
|
|
|
item = find_item_in_character(character, item_name, include_item_inventory)
|
2024-05-13 04:33:47 +00:00
|
|
|
if item:
|
|
|
|
return item
|
|
|
|
|
|
|
|
return None
|
2024-05-19 04:30:17 +00:00
|
|
|
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
def find_containing_room(world: World, entity: Room | Character | Item) -> Room | None:
|
2024-05-19 18:09:52 +00:00
|
|
|
if isinstance(entity, Room):
|
|
|
|
return entity
|
|
|
|
|
|
|
|
for room in world.rooms:
|
2024-05-27 01:32:03 +00:00
|
|
|
if entity in room.characters or entity in room.items:
|
2024-05-19 18:09:52 +00:00
|
|
|
return room
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2024-05-25 20:18:40 +00:00
|
|
|
def find_entity_reference(
|
|
|
|
world: World, reference: EntityReference
|
|
|
|
) -> WorldEntity | None:
|
|
|
|
"""
|
|
|
|
Resolve an entity reference to an entity in the world.
|
|
|
|
"""
|
|
|
|
|
|
|
|
if reference.room:
|
|
|
|
return find_room(world, reference.room)
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
if reference.character:
|
|
|
|
return find_character(world, reference.character)
|
2024-05-25 20:18:40 +00:00
|
|
|
|
|
|
|
if reference.item:
|
|
|
|
return find_item(world, reference.item)
|
|
|
|
|
|
|
|
if reference.portal:
|
|
|
|
return find_portal(world, reference.portal)
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2024-05-19 04:30:17 +00:00
|
|
|
def list_rooms(world: World) -> Generator[Room, Any, None]:
|
|
|
|
for room in world.rooms:
|
|
|
|
yield room
|
|
|
|
|
|
|
|
|
|
|
|
def list_portals(world: World) -> Generator[Portal, Any, None]:
|
|
|
|
for room in world.rooms:
|
|
|
|
for portal in room.portals:
|
|
|
|
yield portal
|
|
|
|
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
def list_characters(world: World) -> Generator[Character, Any, None]:
|
2024-05-19 04:30:17 +00:00
|
|
|
for room in world.rooms:
|
2024-05-27 01:32:03 +00:00
|
|
|
for character in room.characters:
|
|
|
|
yield character
|
2024-05-19 04:30:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
def list_items(
|
2024-05-27 01:32:03 +00:00
|
|
|
world: World, include_character_inventory=True, include_item_inventory=True
|
2024-05-19 04:30:17 +00:00
|
|
|
) -> Generator[Item, Any, None]:
|
|
|
|
|
|
|
|
for room in world.rooms:
|
|
|
|
for item in room.items:
|
|
|
|
yield item
|
|
|
|
|
|
|
|
if include_item_inventory:
|
|
|
|
yield from list_items_in_container(item)
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
if include_character_inventory:
|
|
|
|
for character in room.characters:
|
|
|
|
for item in character.items:
|
2024-05-19 04:30:17 +00:00
|
|
|
yield item
|
2024-05-19 18:09:52 +00:00
|
|
|
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
def list_characters_in_room(room: Room) -> Generator[Character, Any, None]:
|
|
|
|
for character in room.characters:
|
|
|
|
yield character
|
2024-05-19 18:09:52 +00:00
|
|
|
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
def list_items_in_character(
|
|
|
|
character: Character, include_item_inventory=True
|
2024-05-19 18:09:52 +00:00
|
|
|
) -> Generator[Item, Any, None]:
|
2024-05-27 01:32:03 +00:00
|
|
|
for item in character.items:
|
2024-05-19 18:09:52 +00:00
|
|
|
yield item
|
|
|
|
|
|
|
|
if include_item_inventory:
|
|
|
|
yield from list_items_in_container(item)
|
|
|
|
|
|
|
|
|
|
|
|
def list_items_in_container(
|
|
|
|
container: Item, include_item_inventory=True
|
|
|
|
) -> Generator[Item, Any, None]:
|
|
|
|
for item in container.items:
|
|
|
|
yield item
|
|
|
|
|
|
|
|
if include_item_inventory:
|
|
|
|
yield from list_items_in_container(item)
|
|
|
|
|
|
|
|
|
|
|
|
def list_items_in_room(
|
|
|
|
room: Room,
|
2024-05-27 01:32:03 +00:00
|
|
|
include_character_inventory=True,
|
2024-05-19 18:09:52 +00:00
|
|
|
include_item_inventory=True,
|
|
|
|
) -> Generator[Item, Any, None]:
|
|
|
|
for item in room.items:
|
|
|
|
yield item
|
|
|
|
|
|
|
|
if include_item_inventory:
|
|
|
|
yield from list_items_in_container(item)
|
|
|
|
|
2024-05-27 01:32:03 +00:00
|
|
|
if include_character_inventory:
|
|
|
|
for character in room.characters:
|
|
|
|
for item in character.items:
|
2024-05-19 18:09:52 +00:00
|
|
|
yield item
|