from __future__ import annotations from typing import Iterable, List, Optional, Set, TYPE_CHECKING import numpy as np from tcod.console import Console import tile_types if TYPE_CHECKING: from engine import Engine from entity import Entity class FloorMap: engine: Engine player: Entity def __init__(self, width: int, height: int, entities: Iterable[Entity] = ()): #terrain stuff self.width, self.height = width, height self.tiles = np.full((width, height), fill_value=tile_types.wall, order="F") self.visible = np.full((width, height), fill_value=False, order="F") self.explored = np.full((width, height), fill_value=False, order="F") #contents stuff self.entities: Set[Entity] = set(entities) self.procgen_cache = {} #reserved for the procgen algorithm, otherwise ignored #set externally self.engine = None self.player = None def in_bounds(self, x: int, y: int) -> bool: return 0 <= x < self.width and 0 <= y < self.height def get_all_entities_at(self, x: int, y: int, *, unwalkable_only: bool = False, items_only: bool = False) -> List[Entity]: result: List[Entity] = [] for entity in self.entities: if entity.x == x and entity.y == y: if unwalkable_only and entity.walkable: continue if items_only and not entity.is_item(): continue result.append(entity) return result def render(self, console: Console) -> None: console.rgb[0:self.width, 0:self.height] = np.select( condlist = [self.visible, self.explored], choicelist = [self.tiles["light"], self.tiles["dark"]], default = tile_types.SHROUD ) #render the dead stuff below the alive stuff alive = (entity for entity in self.entities if entity.is_alive()) dead = (entity for entity in self.entities if not entity.is_alive()) for entity in dead: if self.visible[entity.x, entity.y]: console.print(entity.x, entity.y, entity.char, fg=entity.color) for entity in alive: if self.visible[entity.x, entity.y]: console.print(entity.x, entity.y, entity.char, fg=entity.color) #print the player above everything else for clarity if self.player: console.print(self.player.x, self.player.y, self.player.char, fg=self.player.color)