-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathentity.py
150 lines (122 loc) · 4.14 KB
/
entity.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from typing import List
import math
from bearlibterminal import terminal
from components.item import Item
import tcod
from copy import deepcopy
from render_order import RenderOrder, RenderLayer
class Entity:
"""
A generic object to represent players, enemies, items, etc.
"""
# def __init__(self, x, y, char, color):
def __init__(
self,
x: int,
y: int,
char,
color,
name: str,
blocks: bool = False,
render_order=RenderOrder.CORPSE,
fighter=None,
ai=None,
item=None,
inventory=None,
stairs=None,
level=None,
equipment=None,
equippable=None,
):
self.x: int = x
self.y: int = y
self.char = char
self.color = color
self.name: str = name
self.blocks: bool = blocks
self.render_order = render_order
self.fighter = fighter
self.ai = ai
self.item = item
self.inventory = inventory
self.stairs = stairs
self.level = level
self.equipment = equipment
self.equippable = equippable
if self.fighter:
self.fighter.owner = self
if self.ai:
self.ai.owner = self
if self.item:
self.item.owner = self
if self.inventory:
self.inventory.owner = self
if self.stairs:
self.stairs.owner = self
if self.level:
self.level.owner = self
if self.equipment:
self.equipment.owner = self
if self.equippable:
self.equippable.owner = self
if not self.item:
item = Item()
self.item = item
self.item.owner = self
if self.fighter and self.equipment:
self.fighter.recalculate_hp()
def draw(self, camera, game_map):
# Draw the entity to the terminal
terminal.color(terminal.color_from_name("white"))
if game_map.fov[self.x, self.y] or (self.stairs and
game_map.explored[self.x, self.y]):
(x, y) = camera.to_camera_coordinates(self.x, self.y)
if x is not None:
terminal.put(x=x * 4, y=y * 2, c=self.char)
def move(self, dx, dy):
# Move the entity by a given amount
self.x += dx
self.y += dy
def move_towards(self, target_x, target_y, game_map, entities):
dx = target_x - self.x
dy = target_y - self.y
distance = math.sqrt(dx**2 + dy**2)
dx = int(round(dx / distance))
dy = int(round(dy / distance))
if not (game_map.is_blocked(self.x + dx, self.y + dy)
and not get_blocking_entities_at_location(
entities, self.x + dx, self.y + dy)):
self.move(dx, dy)
def distance(self, x, y):
return math.sqrt((x - self.x)**2 + (y - self.y)**2)
def distance_to(self, other):
dx = other.x - self.x
dy = other.y - self.y
return math.sqrt(dx**2 + dy**2)
def move_astar(
self,
target,
game_map,
entities,
):
map_copy = deepcopy(game_map)
for entity in entities:
if entity.blocks and entity != self and entity != target:
map_copy.walkable[entity.x][entity.y] = False
astar = tcod.path.AStar(map_copy.walkable)
new_path = astar.get_path(self.x, self.y, target.x, target.y)
if new_path and len(new_path) < 25:
x, y = new_path[0]
if x or y:
self.x = x
self.y = y
else:
self.move_towards(target.x, target.y, game_map, entities)
tcod.path_delete(new_path)
def get_blocking_entities_at_location(entities: List[Entity],
destination_x: int,
destination_y: int) -> [Entity, None]:
for entity in entities:
if entity.blocks and entity.x == destination_x and entity.y == destination_y:
return entity
return None