-
Notifications
You must be signed in to change notification settings - Fork 0
/
entity.py
120 lines (92 loc) · 3.68 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
import tcod as libtcod
import math
from components.item import Item
from render_functions import RenderOrder
class Entity:
'''
A generic object to represent player, enemies, items, etc.
'''
def __init__(self, x, y, char, color, name, blocks=False, render_order=RenderOrder.CORPSE,
fighter=None, ai=None, item=None, inventory=None, stairs=None, level=None, equipment=None, equippable=None):
self.x = x
self.y = y
self.char = char
self.color = color
self.name = name
self.blocks = 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
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) or
get_blocking_entities_at_location(entities, self.x + dx, self.y + dy)):
self.move(dx, dy)
def move_astar(self, target, entities, game_map):
# Create FOV map with dimensions of game map
fov = libtcod.map_new(game_map.width, game_map.height)
# Set walls as blocked
for y1 in range(game_map.height):
for x1 in range(game_map.width):
libtcod.map_set_properties(fov, x1, y1, not game_map.tiles[x1][y1].block_sight,
not game_map.tiles[x1][y1].blocked)
# Check for entities that are blocked and need to be navigated around
for entity in entities:
if entity.blocks and entity != self and entity != target:
libtcod.map_set_properties(fov, entity.x, entity.y, True, False)
# Allocate an A* path
my_path = libtcod.path_new_using_map(fov, 1.41)
libtcod.path_compute(my_path, self.x, self.y, target.x, target.y)
if not libtcod.path_is_empty(my_path) and libtcod.path_size(my_path) < 25:
x, y = libtcod.path_walk(my_path, True)
if x or y:
self.x = x
self.y = y
else:
self.move_towards(target.x, target.y, game_map, entities)
libtcod.path_delete(my_path)
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 get_blocking_entities_at_location(entities, destination_x, destination_y):
for entity in entities:
if entity.blocks and entity.x == destination_x and entity.y == destination_y:
return entity
return None