pyrogue/game/world_tools.py

83 lines
2.1 KiB
Python

"""Functions for working with worlds."""
from __future__ import annotations
from random import Random
from typing import Final
from tcod.ecs import Registry, Entity
from tcod.map import Map
import g
from game.components import Action, Gold, Graphic, Position
from game.tags import IsActor, IsItem, IsPlayer, IsDoor
world_center: Final = Position(50, 50)
def world_pos_to_map_pos(pos):
return pos+world_center
def map_pos_to_world_pos(pos):
return pos-world_center
def add_wall(world, pos, remove=False):
r_pos = world_pos_to_map_pos(pos)
map = world[None].components[Map]
map.walkable[r_pos.y][r_pos.x] = remove
map.transparent[r_pos.y][r_pos.x] = remove
def add_door(world, pos):
world.new_entity(
components={
Position: pos,
Graphic: Graphic(ord('\\')),
Action: unlock_door
},
tags=[IsDoor]
)
add_wall(world, pos)
def new_world() -> Registry:
"""Return a freshly generated world."""
world = Registry()
map = world[None].components[Map] = Map(100, 100)
map.walkable[:] = True
map.transparent[:] = True
rng = world[None].components[Random] = Random()
player_pos = Position(5,5)
world.new_entity(
components={
Position: player_pos,
Graphic: Graphic(ch=ord('@'), fg=(255, 0, 0)),
Gold: 0
},
tags=[IsActor, IsPlayer]
)
for _ in range(10):
world.new_entity(
components={
Position: Position(rng.randint(0, 20), rng.randint(0, 20)),
Graphic: Graphic(ord("$"), fg=(255, 255, 0)),
Gold: rng.randint(1, 10)
},
tags=[IsItem]
)
for i in range(20):
if i == 5 or i == 9:
add_door(world, Position(10, i))
else:
add_wall(world, Position(10, i))
cam_pos = world_pos_to_map_pos(player_pos)
map.compute_fov(cam_pos.x, cam_pos.y)
return world
def unlock_door(door: Entity):
door.components[Graphic] = Graphic(ord("/"))
door.components.pop(Action)
add_wall(g.world, door.components[Position], remove=True)