"""Components for representing residential buildings.
"""
from __future__ import annotations
from typing import Any, Iterable
from ordered_set import OrderedSet
from neighborly.ecs import Component, GameObject, TagComponent
[docs]class ResidentialUnit(Component):
"""A Residence is a place where characters live."""
__slots__ = "_owners", "_residents", "_district", "_building"
_building: GameObject
"""The building this unit is in."""
_district: GameObject
"""The district the residence is in."""
_owners: OrderedSet[GameObject]
"""Characters that currently own the residence."""
_residents: OrderedSet[GameObject]
"""All the characters who live at the residence (including non-owners)."""
def __init__(self, building: GameObject, district: GameObject) -> None:
super().__init__()
self._building = building
self._district = district
self._owners = OrderedSet([])
self._residents = OrderedSet([])
@property
def building(self) -> GameObject:
"""Get the building the residential unit is in."""
return self._building
@property
def district(self) -> GameObject:
"""Get the district the residence is in."""
return self._district
@property
def owners(self) -> Iterable[GameObject]:
"""Get the owners of the residence."""
return self._owners
@property
def residents(self) -> Iterable[GameObject]:
"""Get all the residents of the residence."""
return self._residents
[docs] def to_dict(self) -> dict[str, Any]:
return {
"district": self.district.uid,
"owners": [entry.uid for entry in self.owners],
"residents": [entry.uid for entry in self.residents],
}
[docs] def add_owner(self, owner: GameObject) -> None:
"""Add owner to the residence.
Parameters
----------
owner
A GameObject reference to a residence owner.
"""
self._owners.add(owner)
[docs] def remove_owner(self, owner: GameObject) -> None:
"""Remove owner from residence.
Parameters
----------
owner
A GameObject reference to a residence owner.
"""
self._owners.remove(owner)
[docs] def is_owner(self, character: GameObject) -> bool:
"""Check if a GameObject owns a residence.
Parameters
----------
character
A GameObject reference to a residence owner.
"""
return character in self._owners
[docs] def add_resident(self, resident: GameObject) -> None:
"""Add a tenant to this residence.
Parameters
----------
resident
A GameObject reference to a resident.
"""
self._residents.add(resident)
[docs] def remove_resident(self, resident: GameObject) -> None:
"""Remove a tenant rom this residence.
Parameters
----------
resident
A GameObject reference to a resident.
"""
self._residents.remove(resident)
[docs] def is_resident(self, character: GameObject) -> bool:
"""Check if a GameObject is a resident.
Parameters
----------
character
A GameObject reference to a character
"""
return character in self._residents
def __repr__(self) -> str:
return f"Residence({self.to_dict()})"
def __str__(self) -> str:
return f"Residence({self.to_dict()})"
def __len__(self) -> int:
return len(self._residents)
[docs]class ResidentialBuilding(Component):
"""Tags a building as managing multiple residential units."""
__slots__ = "_residential_units", "_district"
_district: GameObject
"""The district the residence is in."""
_residential_units: list[GameObject]
"""The residential units that belong to this building."""
def __init__(self, district: GameObject) -> None:
super().__init__()
self._district = district
self._residential_units = []
@property
def district(self) -> GameObject:
"""Get the district the residential building belongs to."""
return self._district
@property
def units(self) -> Iterable[GameObject]:
"""Get the residential units within the building."""
return self._residential_units
[docs] def add_residential_unit(self, residence: GameObject) -> None:
"""Add a residential unit to the building."""
self._residential_units.append(residence)
[docs] def remove_residential_unit(self, residence: GameObject) -> None:
"""Add a residential unit to the building."""
self._residential_units.remove(residence)
[docs] def to_dict(self) -> dict[str, Any]:
return {
"district": self.district.uid,
"units": [u.uid for u in self._residential_units],
}
[docs]class Resident(Component):
"""A Component attached to characters that tracks where they live."""
__slots__ = ("residence",)
residence: GameObject
"""The GameObject ID of their residence."""
def __init__(self, residence: GameObject) -> None:
"""
Parameters
----------
residence
A GameObject reference to their residence.
"""
super().__init__()
self.residence = residence
[docs] def to_dict(self) -> dict[str, Any]:
return {**super().to_dict(), "residence": self.residence.uid}
def __repr__(self) -> str:
return f"Resident({self.to_dict()})"
def __str__(self) -> str:
return f"Resident({self.to_dict()})"
[docs]class Vacant(TagComponent):
"""Tags a residence that does not currently have anyone living there."""