"""Collection of common components.""" from __future__ import annotations from typing import Final, Self import attrs import math import tcod.ecs.callbacks from tcod.ecs import Entity @attrs.define(frozen=True) class Position: """An entities position.""" x: int y: int def __add__(self, direction: tuple[int, int] | Position) -> Self: """Add a vector to this position.""" match direction: case Position(x, y): return self.__class__(self.x + x, self.y + y) x, y = direction return self.__class__(self.x + x, self.y + y) def __sub__(self, direction: tuple[int, int] | Position) -> Self: match direction: case Position(x, y): return self.__class__(self.x - x, self.y - y) x, y = direction return self.__class__(self.x - x, self.y - y) def mod(self, other: tuple[int,int] | Position | int) -> Self: match other: case Position(x,y): return self.__class__(self.x//x, self.y//y) case int(x): return self.__class__(self.x//x, self.y//x) x,y = other return self.__class__(self.x//x, self.y//y) def length(self): return math.sqrt(self.x**2+self.y**2) @tcod.ecs.callbacks.register_component_changed(component=Position) def on_position_changed(entity: Entity, old: Position | None, new: Position | None) -> None: """Mirror position components as a tag.""" if old == new: return if old is not None: entity.tags.discard(old) if new is not None: entity.tags.add(new) @attrs.define(frozen=True) class Graphic: """An entities icon and color.""" ch: int = ord("!") fg: tuple[int, int, int] = (255, 255, 255) Gold: Final = ("Gold", int) """Amount of gold."""