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,30 +277,32 @@ 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) | ||||||
|  |         if 0 <= y < len(self.tiles) and 0 <= x < len(self.tiles[0]): | ||||||
|             self.visibility[y][x] = True |             self.visibility[y][x] = True | ||||||
|  |  | ||||||
|     def tick(self) -> None: |     def tick(self) -> None: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user