Hook up crawl behaviour. Make tunnel entrance even harder to find as a result
[koperkapel.git] / koperkapel / gamelib / tiles.py
1 """ Definitions for the various tile types """
2
3 import os
4 import random
5
6 from pygame.transform import rotate
7
8 from pgzero.loaders import images
9
10
11 class Tile:
12     IMG = None
13     TILESET = None
14
15     @classmethod
16     def image(cls, neighbors):
17         if cls.IMG is None or cls.TILESET is None:
18             raise NotImplementedError()
19         return images.load(os.path.join(cls.TILESET, cls.IMG))
20
21 class OrientatedTile(Tile):
22     ANGLE = None
23
24     @classmethod
25     def image(cls, neighbors):
26         if cls.IMG is None or cls.TILESET is None:
27             raise NotImplementedError()
28         img = images.load(os.path.join(cls.TILESET, cls.IMG))
29         if cls.ANGLE:
30             img = rotate(img, cls.ANGLE)
31         return img
32
33
34 class RandomizedTile(Tile):
35     IMGDIR = None
36     TILESET = None
37     ROTATE = True
38
39     @classmethod
40     def image(cls, neighbors):
41         if cls.IMGDIR is None or cls.TILESET is None:
42             raise NotImplementedError()
43
44         imgdir = os.path.join(os.path.dirname(__file__), '..', 'images',
45                 cls.TILESET, cls.IMGDIR)
46         imgpath = os.path.splitext(random.choice(os.listdir(imgdir)))[0]
47         img = images.load(os.path.join(cls.TILESET, cls.IMGDIR, imgpath))
48
49         if cls.ROTATE:
50             img = rotate(img, 90 * random.randint(0, 3))
51
52         return img
53
54 class Floor(RandomizedTile):
55     IMGDIR = "floor"
56
57 class Wall(RandomizedTile):
58     IMGDIR = "wall"
59
60 class Underground(RandomizedTile):
61     IMGDIR = "underground"
62
63 class Tunnel(OrientatedTile):
64
65     @classmethod
66     def image(cls, neighbors):
67         connections = [True if 'crawl' in x['behaviour'] else False for x in neighbors]
68         conn_count = connections.count(True)
69         # simple cases
70         cls.ANGLE = 0
71         if conn_count == 0:
72             # return single point tunnel
73             cls.IMG = os.path.join('tunnel', 'tunnel_none')
74         elif conn_count == 4:
75             # crossroads
76             cls.IMG = os.path.join('tunnel', 'tunnel_crossroads')
77         elif conn_count == 1:
78             # 1 point connector, roatated correctly
79             cls.IMG = os.path.join('tunnel', 'tunnel_1way')
80             # because of the ordering of neighbors, we use this formulation
81             for x, angle in zip(connections, (90, 270, 0, 180)):
82                 if x:
83                     cls.ANGLE = angle
84                     break
85         elif conn_count == 3:
86             # 3 point connector, rotated correctly
87             cls.IMG = os.path.join('tunnel', 'tunnel_3way')
88             # find the missing connection.
89             for x, angle in zip(connections, (0, 180, 270, 90)):
90                 if not x:
91                     cls.ANGLE = angle
92                     break
93         elif conn_count == 2:
94             # Need to distinguish pass-through or corner, and
95             # rotate correctly
96             # neighbors is left, right then up, down
97             if connections[0] == connections[1]:
98                 cls.IMG = os.path.join('tunnel', 'tunnel_passthrough')
99                 if connections[0]:
100                     cls.ANGLE = 90
101             else:
102                 cls.IMG = os.path.join('tunnel', 'tunnel_corner')
103                 if connections[0]:
104                     if connections[2]:
105                         # left, up
106                         cls.ANGLE = 90
107                     else:
108                         # left, down
109                         cls.ANGLE = 180
110                 else:
111                     if connections[2]:
112                         # right, up
113                         cls.ANGLE = 0
114                     else:
115                         # right, down
116                         cls.ANGLE = 270
117
118         return super(Tunnel, cls).image(neighbors)
119