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