72 lines
2 KiB
Python
72 lines
2 KiB
Python
"""Collection of common components."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Final, Self, Callable
|
|
|
|
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)
|
|
case (x, y):
|
|
return self.__class__(self.x + x, self.y + y)
|
|
raise NotImplementedError
|
|
|
|
def __sub__(self, direction: tuple[int, int] | Position) -> Self:
|
|
match direction:
|
|
case Position(x, y):
|
|
return self.__class__(self.x - x, self.y - y)
|
|
case (x, y):
|
|
return self.__class__(self.x - x, self.y - y)
|
|
raise NotImplementedError
|
|
|
|
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)
|
|
case (x, y):
|
|
return self.__class__(self.x//x, self.y//y)
|
|
raise NotImplementedError
|
|
|
|
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)
|
|
|
|
Action: Final = ("Action", Callable[[tcod.ecs.Entity], None])
|
|
"""Possible action."""
|
|
|
|
Gold: Final = ("Gold", int)
|
|
"""Amount of gold."""
|