-
Notifications
You must be signed in to change notification settings - Fork 1
/
Tile.py
179 lines (145 loc) · 6.33 KB
/
Tile.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
from Item import *
from Monster import *
from TermColor import *
from Kernel import *
from Findable import *
class Tile(Findable):
dngFeatures = ['.', '}', '{', '#', '<', '>', ']', '^', '|', '-', '~', ' ']
dngItems = ['`', '0', '*', '$', '_', '[', '%', ')', '(', '/', '?', '!', '"', '=', '+', '\\']
dngMonsters = map(chr, range(ord('a'), ord('z')+1) + range(ord('A'), ord('Z')+1) + range(ord('1'), ord('5')+1)) + ['@', "'", '&', ';', ':']
walkables = {'.': 1,
'}': 1,
'{': 1,
'#': 1,
'<': 1,
'>': 1,
'^': 100,
' ': 1} #glyph: weight
def __init__(self, y, x, level):
Findable.__init__(self)
self.y = y
self.x = x
self.level = level
self.glyph = None
self.color = TermColor()
self.explored = False
self.items = []
self.monster = None
self.walkable = True
self.searches = 0
self.searched = False
self.inShop = False
self.locked = False
self.shopkeepDoor = False
def coords(self):
return (self.y, self.x)
def setTile(self, glyph, color):
self.monster = None
if glyph in Tile.dngFeatures:
self.glyph = glyph
self.color = color
self.explored = self.explored or (glyph != ' ')
if self.items:
Kernel.instance.log("Removing items on %s because I only see a dngFeature-tile" % str(self.coords()))
self.items = []
if glyph not in Tile.walkables.keys() and not self.isDoor():
Kernel.instance.log("Setting %s to unwalkable." % self)
self.walkable = False
if glyph in Tile.walkables.keys() and glyph not in [' ']:
self.walkable = True
#Kernel.instance.log("Found feature: %s, Color: %s, at (%d,%d). Tile is now: %s" % (glyph, str(color), self.y, self.x, str(self)))
elif glyph in Tile.dngItems:
it = Item(None, glyph, color)
if not self.items:
Kernel.instance.log("Added item(%s) to tile(%s)" % (str(it), str(self)))
self.items.append(it)
else:
self.items[0] = it
if glyph == '0':
self.walkable = False
else:
self.walkable = True
#Kernel.instance.log("Found item: %s, Color: %s, at (%d,%d). Tile is now: %s" % (str(it), str(color), self.y, self.x, str(self)))
elif self.coords() == Kernel.instance.Hero.coords():
self.explored = True
self.walkable = True
# Might cause some trouble
# TODO: Write comments that actually explains problems (No idea why I said the above, and no idea what the below does.. :)
if not self.isWalkable():
self.walkable = True
self.glyph = None
elif glyph in Tile.dngMonsters:
self.monster = Monster(glyph, color)
self.walkable = True
if self.glyph == ']':
if Kernel.instance.Dungeon.tile(self.y-1, self.x).glyph == '|':
self.glyph = '-'
else:
self.glyph = '|'
self.color = TermColor(33, 0, False, False)
#Kernel.instance.log("Found monster:%s, Color: %s, at (%d,%d). Tile is now: %s" % (str(self.monster), str(color), self.y, self.x, str(self)))
else:
Kernel.instance.die("Couldn't parse tile: " + glyph)
def appearance(self):
if self.monster:
return self.monster.glyph
elif self.items:
return self.items[-1].glyph
else:
return self.glyph
def isDoor(self):
return (self.glyph == '-' or self.glyph == '|') and self.color.getId() == COLOR_BROWN
def isWalkable(self): #TODO: Shops might be good to visit sometime ..:)
# if not self.adjacent({'explored': True}):
# return False
if not self.glyph:
return not self.monster and self.walkable
else:
if self.isDoor():
return not self.monster and True
return not self.monster and self.glyph in Tile.walkables.keys() and self.walkable
def walkableNeighbours(self):
ret = []
for neighbour in self.neighbours():
if neighbour.isWalkable() and not (neighbour.isDoor() or self.isDoor()):
ret.append(neighbour)
continue
if (self.isDoor() or neighbour.isDoor()) and (self.x==neighbour.x or self.y==neighbour.y) and neighbour.isWalkable():
ret.append(neighbour)
continue
return ret
def isAdjacent(self, other):
for neighbour in self.neighbours():
if neighbour == other:
return True
return False
def straight(self, find):
ret = []
for x in range(-1,2):
for y in range(-1,2):
if x*y == 0 and x!=y:
tile = self.level.tiles[(x+self.x) + (y+self.y)*WIDTH]
if tile.find(find):
ret.append(tile)
return ret
def adjacent(self, find):
return [tile for tile in self.neighbours() if tile.find(find)]
def neighbours(self):
ret = []
for x in range(-1,2):
for y in range(-1,2):
if x+self.x<0 or x+self.x>WIDTH-1 or y+self.y<0 or y+self.y>HEIGHT-4 or (x==0 and y==0):
continue
tile = self.level.tiles[x+self.x + (y+self.y)*WIDTH]
ret.append(tile)
return ret
def isHero(self):
return self.coords() == Kernel.instance.Hero.coords()
def tilesFromCurrent(self):
return (abs(Kernel.instance.Hero.x-self.x) + abs(Kernel.instance.Hero.y-self.y))
def __str__(self):
return "(%s,%s)->g:%s, c:(%s), e:%s, @:%s, m:(%s), i:(%s) w:%s(is:%s) sea:%s" % tuple(map(str, (self.y, self.x, self.glyph, self.color, self.explored, self.isHero(), self.monster, map(str, self.items), self.walkable, self.isWalkable(), self.searches)))
def __eq__(self, other):
return self.coords() == other.coords()
def __ne__(self, other):
return self.coords() != other.coords()