Working visibility and displaying it, still need to hide things that aren't visible
This commit is contained in:
parent
62ce2b5c71
commit
86628fdea6
|
@ -15,8 +15,15 @@ class MapDisplay(Display):
|
|||
self.pad = self.newpad(m.height, self.pack.tile_width * m.width + 1)
|
||||
|
||||
def update_pad(self) -> None:
|
||||
self.addstr(self.pad, 0, 0, self.map.draw_string(self.pack),
|
||||
self.pack.tile_fg_color, self.pack.tile_bg_color)
|
||||
for j in range(len(self.map.tiles)):
|
||||
for i in range(len(self.map.tiles[j])):
|
||||
color = self.pack.tile_fg_visible_color if \
|
||||
self.map.visibility[j][i] else self.pack.tile_fg_color
|
||||
self.addstr(self.pad, j, self.pack.tile_width * i,
|
||||
self.map.tiles[j][i].char(self.pack),
|
||||
color, self.pack.tile_bg_color)
|
||||
# self.addstr(self.pad, 0, 0, self.map.draw_string(self.pack),
|
||||
# self.pack.tile_fg_color, self.pack.tile_bg_color)
|
||||
for e in self.map.entities:
|
||||
self.addstr(self.pad, e.y, self.pack.tile_width * e.x,
|
||||
self.pack[e.name.upper()],
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import curses
|
||||
from typing import Any
|
||||
from typing import Any, Union, Tuple
|
||||
|
||||
|
||||
class TexturePack:
|
||||
|
@ -10,10 +10,11 @@ class TexturePack:
|
|||
|
||||
name: str
|
||||
tile_width: int
|
||||
tile_fg_color: int
|
||||
tile_bg_color: int
|
||||
entity_fg_color: int
|
||||
entity_bg_color: int
|
||||
tile_fg_color: Union[int, Tuple[int, int, int]]
|
||||
tile_fg_visible_color: Union[int, Tuple[int, int, int]]
|
||||
tile_bg_color: Union[int, Tuple[int, int, int]]
|
||||
entity_fg_color: Union[int, Tuple[int, int, int]]
|
||||
entity_bg_color: Union[int, Tuple[int, int, int]]
|
||||
|
||||
BODY_SNATCH_POTION: str
|
||||
BOMB: str
|
||||
|
@ -54,9 +55,10 @@ class TexturePack:
|
|||
TexturePack.ASCII_PACK = TexturePack(
|
||||
name="ascii",
|
||||
tile_width=1,
|
||||
tile_fg_visible_color=(1000, 1000, 1000),
|
||||
tile_fg_color=curses.COLOR_WHITE,
|
||||
tile_bg_color=curses.COLOR_BLACK,
|
||||
entity_fg_color=curses.COLOR_WHITE,
|
||||
entity_fg_color=(1000, 1000, 1000),
|
||||
entity_bg_color=curses.COLOR_BLACK,
|
||||
|
||||
BODY_SNATCH_POTION='S',
|
||||
|
@ -80,10 +82,11 @@ TexturePack.ASCII_PACK = TexturePack(
|
|||
TexturePack.SQUIRREL_PACK = TexturePack(
|
||||
name="squirrel",
|
||||
tile_width=2,
|
||||
tile_fg_visible_color=(1000, 1000, 1000),
|
||||
tile_fg_color=curses.COLOR_WHITE,
|
||||
tile_bg_color=curses.COLOR_BLACK,
|
||||
entity_fg_color=curses.COLOR_WHITE,
|
||||
entity_bg_color=curses.COLOR_WHITE,
|
||||
entity_fg_color=(1000, 1000, 1000),
|
||||
entity_bg_color=(1000, 1000, 1000),
|
||||
|
||||
BODY_SNATCH_POTION='🔀',
|
||||
BOMB='💣',
|
||||
|
|
|
@ -21,7 +21,7 @@ class Player(InventoryHolder, FightingEntity):
|
|||
strength: int = 5, intelligence: int = 1, charisma: int = 1,
|
||||
dexterity: int = 1, constitution: int = 1, level: int = 1,
|
||||
current_xp: int = 0, max_xp: int = 10, inventory: list = None,
|
||||
hazel: int = 42, *args, **kwargs) \
|
||||
hazel: int = 42, vision: int = 5, *args, **kwargs) \
|
||||
-> None:
|
||||
super().__init__(name=name, maxhealth=maxhealth, strength=strength,
|
||||
intelligence=intelligence, charisma=charisma,
|
||||
|
@ -32,6 +32,7 @@ class Player(InventoryHolder, FightingEntity):
|
|||
self.inventory = self.translate_inventory(inventory or [])
|
||||
self.paths = dict()
|
||||
self.hazel = hazel
|
||||
self.vision = vision
|
||||
|
||||
def move(self, y: int, x: int) -> None:
|
||||
"""
|
||||
|
@ -42,6 +43,7 @@ class Player(InventoryHolder, FightingEntity):
|
|||
self.map.currenty = y
|
||||
self.map.currentx = x
|
||||
self.recalculate_paths()
|
||||
self.map.compute_visibility(self.y, self.x, self.vision)
|
||||
|
||||
def level_up(self) -> None:
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
from enum import Enum, auto
|
||||
from math import sqrt
|
||||
from random import choice, randint
|
||||
from typing import List, Optional, Union, Tuple, Any
|
||||
from typing import List, Optional, Tuple, Any
|
||||
from math import ceil
|
||||
|
||||
from .display.texturepack import TexturePack
|
||||
from .translations import gettext as _
|
||||
|
@ -38,19 +39,25 @@ class Slope():
|
|||
self.Y = y
|
||||
self.X = x
|
||||
|
||||
def compare(self, other: Union[Tuple[int, int], "Slope"]) -> int:
|
||||
if isinstance(other, Slope):
|
||||
def compare(self, other: "Slope") -> int:
|
||||
y, x = other.Y, other.X
|
||||
else:
|
||||
y, x = other
|
||||
return self.Y * x - self.X * y
|
||||
|
||||
def __lt__(self, other: Union[Tuple[int, int], "Slope"]) -> bool:
|
||||
def __lt__(self, other: "Slope") -> bool:
|
||||
return self.compare(other) < 0
|
||||
|
||||
def __eq__(self, other: Union[Tuple[int, int], "Slope"]) -> bool:
|
||||
def __eq__(self, other: "Slope") -> bool:
|
||||
return self.compare(other) == 0
|
||||
|
||||
def __gt__(self, other: "Slope") -> bool:
|
||||
return self.compare(other) > 0
|
||||
|
||||
def __le__(self, other: "Slope") -> bool:
|
||||
return self.compare(other) <= 0
|
||||
|
||||
def __ge__(self, other: "Slope") -> bool:
|
||||
return self.compare(other) >= 0
|
||||
|
||||
|
||||
class Map:
|
||||
"""
|
||||
|
@ -194,16 +201,16 @@ class Map:
|
|||
if top.X == 1:
|
||||
top_y = x
|
||||
else:
|
||||
top_y = ((x * 2 - 1) * top.Y + top.X) / (top.X * 2)
|
||||
top_y = ceil(((x * 2 - 1) * top.Y + top.X) / (top.X * 2))
|
||||
if self.is_wall(top_y, x, octant, origin):
|
||||
if top >= (top_y * 2 + 1, x * 2) and not\
|
||||
if top >= Slope(top_y * 2 + 1, x * 2) and not\
|
||||
self.is_wall(top_y + 1, x, octant, origin):
|
||||
top_y += 1
|
||||
else:
|
||||
ax = x * 2
|
||||
if self.is_wall(top_y + 1, x + 1, octant, origin):
|
||||
ax += 1
|
||||
if top > (top_y * 2 + 1, ax):
|
||||
if top > Slope(top_y * 2 + 1, ax):
|
||||
top_y += 1
|
||||
return top_y
|
||||
|
||||
|
@ -212,9 +219,9 @@ class Map:
|
|||
if bottom.Y == 0:
|
||||
bottom_y = 0
|
||||
else:
|
||||
bottom_y = ((x * 2 + 1) * bottom.Y + bottom.X) /\
|
||||
(bottom.X * 2)
|
||||
if bottom >= (bottom_y * 2 + 1, x * 2) and\
|
||||
bottom_y = ceil(((x * 2 - 1) * bottom.Y + bottom.X)
|
||||
/ (bottom.X * 2))
|
||||
if bottom >= Slope(bottom_y * 2 + 1, x * 2) and\
|
||||
self.is_wall(bottom_y, x, octant, origin) and\
|
||||
not self.is_wall(bottom_y + 1, x, octant, origin):
|
||||
bottom_y += 1
|
||||
|
@ -223,17 +230,18 @@ class Map:
|
|||
def compute_visibility_octant(self, octant: int, origin: Tuple[int, int],
|
||||
max_range: int, distance: int, top: Slope,
|
||||
bottom: Slope) -> None:
|
||||
for x in range(distance, max_range):
|
||||
for x in range(distance, max_range + 1):
|
||||
top_y = self.crop_top_visibility(octant, origin, x, top)
|
||||
bottom_y = self.crop_bottom_visibility(octant, origin, x, bottom)
|
||||
was_opaque = -1
|
||||
for y in range(top_y, bottom_y - 1, -1):
|
||||
if sqrt(x**2 + y**2) > max_range:
|
||||
if x + y > max_range:
|
||||
continue
|
||||
is_opaque = self.is_wall(y, x, octant, origin)
|
||||
is_visible = is_opaque\
|
||||
or ((y != top_y or top > (y * 4 - 1, x * 4 - 1))
|
||||
and (y != bottom_y or bottom < (y * 4 + 1, x * 4 + 1)))
|
||||
or ((y != top_y or top > Slope(y * 4 - 1, x * 4 + 1))
|
||||
and (y != bottom_y
|
||||
or bottom < Slope(y * 4 + 1, x * 4 - 1)))
|
||||
if is_visible:
|
||||
self.set_visible(y, x, octant, origin)
|
||||
if x == max_range:
|
||||
|
@ -242,7 +250,7 @@ class Map:
|
|||
nx, ny = x * 2, y * 2 + 1
|
||||
if self.is_wall(y + 1, x, octant, origin):
|
||||
nx -= 1
|
||||
if top > (ny, nx):
|
||||
if top > Slope(ny, nx):
|
||||
if y == bottom_y:
|
||||
bottom = Slope(ny, nx)
|
||||
break
|
||||
|
@ -257,8 +265,9 @@ class Map:
|
|||
nx, ny = x * 2, y * 2 + 1
|
||||
if self.is_wall(y + 1, x + 1, octant, origin):
|
||||
nx += 1
|
||||
if bottom >= (ny, nx):
|
||||
if bottom >= Slope(ny, nx):
|
||||
return
|
||||
top = Slope(ny, nx)
|
||||
was_opaque = is_opaque
|
||||
if was_opaque != 0:
|
||||
break
|
||||
|
@ -268,30 +277,32 @@ class Map:
|
|||
origin: Tuple[int, int]) -> Tuple[int, int]:
|
||||
ny, nx = origin
|
||||
if octant == 0:
|
||||
return nx + x, ny - y
|
||||
return ny - y, nx + x
|
||||
elif octant == 1:
|
||||
return nx + y, ny - x
|
||||
return ny - x, nx + y
|
||||
elif octant == 2:
|
||||
return nx - y, ny - x
|
||||
return ny - x, nx - y
|
||||
elif octant == 3:
|
||||
return nx - x, ny - y
|
||||
return ny - y, nx - x
|
||||
elif octant == 4:
|
||||
return nx - x, ny + y
|
||||
return ny + y, nx - x
|
||||
elif octant == 5:
|
||||
return nx - y, ny + x
|
||||
return ny + x, nx - y
|
||||
elif octant == 6:
|
||||
return nx + y, ny + x
|
||||
return ny + x, nx + y
|
||||
elif octant == 7:
|
||||
return nx + x, ny + y
|
||||
return ny + y, nx + x
|
||||
|
||||
def is_wall(self, y: int, x: int, octant: int,
|
||||
origin: Tuple[int, int]) -> bool:
|
||||
y, x = self.translate_coord(y, x, octant, origin)
|
||||
return self.tiles[y][x].is_wall()
|
||||
return 0 <= y < len(self.tiles) and 0 <= x < len(self.tiles[0]) and \
|
||||
self.tiles[y][x].is_wall()
|
||||
|
||||
def set_visible(self, y: int, x: int, octant: int,
|
||||
origin: Tuple[int, int]) -> None:
|
||||
y, x = self.translate_coord(y, x, octant, origin)
|
||||
if 0 <= y < len(self.tiles) and 0 <= x < len(self.tiles[0]):
|
||||
self.visibility[y][x] = True
|
||||
|
||||
def tick(self) -> None:
|
||||
|
|
Loading…
Reference in New Issue