1
|
|
|
"""libtcod map attributes and field-of-view functions. |
2
|
|
|
|
3
|
|
|
Example:: |
4
|
|
|
|
5
|
|
|
>>> import tcod.map |
6
|
|
|
>>> m = tcod.map.Map(width=3, height=4) |
7
|
|
|
>>> m.walkable |
8
|
|
|
array([[False, False, False], |
9
|
|
|
[False, False, False], |
10
|
|
|
[False, False, False], |
11
|
|
|
[False, False, False]]...) |
12
|
|
|
|
13
|
|
|
# Like the rest of the tcod modules, all arrays here are |
14
|
|
|
# in row-major order and are addressed with [y,x] |
15
|
|
|
>>> m.transparent[:] = True # Sets all to True. |
16
|
|
|
>>> m.transparent[1:3,0] = False # Sets (1, 0) and (2, 0) to False. |
17
|
|
|
>>> m.transparent |
18
|
|
|
array([[ True, True, True], |
19
|
|
|
[False, True, True], |
20
|
|
|
[False, True, True], |
21
|
|
|
[ True, True, True]]...) |
22
|
|
|
|
23
|
|
|
>>> m.compute_fov(0, 0) |
24
|
|
|
>>> m.fov |
25
|
|
|
array([[ True, True, True], |
26
|
|
|
[ True, True, True], |
27
|
|
|
[False, True, True], |
28
|
|
|
[False, False, True]]...) |
29
|
|
|
>>> m.fov[3,1] |
30
|
|
|
False |
31
|
|
|
|
32
|
|
|
""" |
33
|
|
|
|
34
|
|
|
from __future__ import absolute_import |
35
|
|
|
|
36
|
|
|
import numpy as np |
|
|
|
|
37
|
|
|
|
38
|
|
|
from tcod.libtcod import lib, ffi |
39
|
|
|
import tcod._internal |
40
|
|
|
|
41
|
|
|
|
42
|
|
|
class Map(object): |
43
|
|
|
"""A map containing libtcod attributes. |
44
|
|
|
|
45
|
|
|
.. versionchanged:: 4.1 |
46
|
|
|
`transparent`, `walkable`, and `fov` are now numpy boolean arrays. |
47
|
|
|
|
48
|
|
|
.. versionchanged:: 4.3 |
49
|
|
|
Added `order` parameter. |
50
|
|
|
|
51
|
|
|
Args: |
52
|
|
|
width (int): Width of the new Map. |
53
|
|
|
height (int): Height of the new Map. |
54
|
|
|
order (str): Which numpy memory order to use. |
55
|
|
|
|
56
|
|
|
Attributes: |
57
|
|
|
width (int): Read only width of this Map. |
58
|
|
|
height (int): Read only height of this Map. |
59
|
|
|
transparent: A boolean array of transparent cells. |
60
|
|
|
walkable: A boolean array of walkable cells. |
61
|
|
|
fov: A boolean array of the cells lit by :any:'compute_fov'. |
62
|
|
|
|
63
|
|
|
""" |
64
|
|
|
|
65
|
|
|
def __init__(self, width, height, order='C'): |
66
|
|
|
assert ffi.sizeof('cell_t') == 3 # assert buffer alignment |
67
|
|
|
self.width = width |
68
|
|
|
self.height = height |
69
|
|
|
self._order = tcod._internal.verify_order(order) |
70
|
|
|
|
71
|
|
|
self.__buffer = np.zeros((height, width, 3), dtype=np.bool_) |
72
|
|
|
self.map_c = self.__as_cdata() |
73
|
|
|
|
74
|
|
|
|
75
|
|
|
def __as_cdata(self): |
|
|
|
|
76
|
|
|
return ffi.new( |
77
|
|
|
'map_t *', |
78
|
|
|
( |
79
|
|
|
self.width, |
80
|
|
|
self.height, |
81
|
|
|
self.width * self.height, |
82
|
|
|
ffi.cast('cell_t*', self.__buffer.ctypes.data), |
83
|
|
|
) |
84
|
|
|
) |
85
|
|
|
|
86
|
|
|
@property |
87
|
|
|
def transparent(self): |
|
|
|
|
88
|
|
|
buffer = self.__buffer[:,:,0] |
|
|
|
|
89
|
|
|
return buffer.T if self._order == 'F' else buffer |
90
|
|
|
|
91
|
|
|
@property |
92
|
|
|
def walkable(self): |
|
|
|
|
93
|
|
|
buffer = self.__buffer[:,:,1] |
|
|
|
|
94
|
|
|
return buffer.T if self._order == 'F' else buffer |
95
|
|
|
|
96
|
|
|
@property |
97
|
|
|
def fov(self): |
|
|
|
|
98
|
|
|
buffer = self.__buffer[:,:,2] |
|
|
|
|
99
|
|
|
return buffer.T if self._order == 'F' else buffer |
100
|
|
|
|
101
|
|
|
def compute_fov(self, x, y, radius=0, light_walls=True, |
|
|
|
|
102
|
|
|
algorithm=lib.FOV_RESTRICTIVE): |
103
|
|
|
"""Compute a field-of-view on the current instance. |
104
|
|
|
|
105
|
|
|
Args: |
106
|
|
|
x (int): Point of view, x-coordinate. |
107
|
|
|
y (int): Point of view, y-coordinate. |
108
|
|
|
radius (int): Maximum view distance from the point of view. |
109
|
|
|
|
110
|
|
|
A value of `0` will give an infinite distance. |
111
|
|
|
light_walls (bool): Light up walls, or only the floor. |
112
|
|
|
algorithm (int): Defaults to tcod.FOV_RESTRICTIVE |
113
|
|
|
""" |
114
|
|
|
lib.TCOD_map_compute_fov( |
115
|
|
|
self.map_c, x, y, radius, light_walls, algorithm) |
116
|
|
|
|
117
|
|
|
def __setstate__(self, state): |
118
|
|
|
if '_Map__buffer' not in state: # deprecated |
119
|
|
|
# remove this check on major version update |
120
|
|
|
self.__buffer = np.zeros((state['height'], state['width'], 3), |
121
|
|
|
dtype=np.bool_) |
122
|
|
|
self.__buffer[:,:,0] = state['buffer'] & 0x01 |
|
|
|
|
123
|
|
|
self.__buffer[:,:,1] = state['buffer'] & 0x02 |
|
|
|
|
124
|
|
|
self.__buffer[:,:,2] = state['buffer'] & 0x04 |
|
|
|
|
125
|
|
|
del state['buffer'] |
126
|
|
|
state['_order'] = 'F' |
127
|
|
|
if '_order' not in state: # remove this check on major version update |
128
|
|
|
raise RuntimeError( |
129
|
|
|
'This Map was saved with a bad version of tdl.') |
130
|
|
|
self.__dict__.update(state) |
131
|
|
|
self.map_c = self.__as_cdata() |
132
|
|
|
|
133
|
|
|
def __getstate__(self): |
134
|
|
|
state = self.__dict__.copy() |
135
|
|
|
del state['map_c'] |
136
|
|
|
return state |
137
|
|
|
|
This can be caused by one of the following:
1. Missing Dependencies
This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.
2. Missing __init__.py files
This error could also result from missing
__init__.py
files in your module folders. Make sure that you place one file in each sub-folder.