1 """ Roach management scene. """
3 from pgzero.constants import keys, mouse
4 from pgzero.actor import Actor
5 from ..actors.buttons import ImageButton
6 from ..constants import WIDTH, HEIGHT
7 from ..roaches import big_roaches, roach_by_name
8 from ..serums import big_serums, roach_is_serumless, SERUMS
9 from ..vehicles.base import Vehicle
10 from .base import Scene, ChangeSceneEvent
13 TOOLBAR_LEFT_X = WIDTH * 3 // 4
15 TOOLBAR_MID_Y = HEIGHT * 1 // 2
16 VEHICLE_MID_X = WIDTH * 3 // 8
17 VEHICLE_MID_Y = HEIGHT * 1 // 2
18 BUTTON_INSET = (20, 20)
19 SERUM_OFFSET = (0, 20)
20 ROACH_PAD_OFFSET = (0, 20)
23 def inset_button(pos, d):
25 pos[0] + d[0] * BUTTON_INSET[0],
26 pos[1] + d[1] * BUTTON_INSET[1])
29 class RoachesScene(Scene):
30 """ Roach management scene. """
32 def __init__(self, level_scene=None):
34 self._level_scene = level_scene
37 self._outside_roach = None
38 self._outside_roach_pos = 0
39 self._inventory_pos = 0
40 self._inventory_item = None
41 self._roach_layer = self.actors.add_layer("roaches", level=10)
42 self._inventory_layer = self.actors.add_layer("inventory", level=10)
43 self._pad_layer = self.actors.add_layer("pads", level=5)
44 self._seat_layer = self.actors.add_layer("seats", level=5)
45 self._button_layer = self.actors.add_layer("buttons", level=6)
50 def enter(self, world):
51 self._vehicle = Vehicle.current(world)
52 self._update_calls = []
55 self._init_roaches(world)
56 self._update_inventory(world)
59 self.actors.default.clear()
60 self.actors.default.add(self._vehicle.roach_management_overlay())
62 def _init_seats(self):
63 self._seat_layer.clear()
64 for seat in self._vehicle.seats:
65 seat_actor = self._seat_layer.add(seat.actor())
67 seat.vehicle_pos[0] + VEHICLE_MID_X,
68 seat.vehicle_pos[1] + VEHICLE_MID_Y)
69 self._seat_layer[self._seat_pos].selected = True
71 def _init_roaches(self, world):
72 self._roach_actors = {}
73 for roach in world.roaches:
74 self._roach_actors[roach.name] = big_roaches.assemble(roach)
76 def _init_serums(self):
77 self._serum_actors = {
78 serum: big_serums.assemble(serum) for serum in SERUMS}
80 def _update_inventory(self, world):
81 self._inventory_layer.clear()
85 self._inventory_pos %= len(serums)
86 serum_actor = self._serum_actors[serums[self._inventory_pos]]
87 inv_pad_centre = self._inventory_pad.center
89 inv_pad_centre[0] + SERUM_OFFSET[0],
90 inv_pad_centre[1] + SERUM_OFFSET[1])
91 self._inventory_layer.add(serum_actor)
93 def _update_roaches(self, world):
94 self._roach_layer.clear()
95 seating = self._vehicle.seating(world)
96 self._outside_roaches = []
97 for roach in world.roaches:
98 seat_pos = seating.get(roach.name)
99 if seat_pos is not None:
100 roach_actor = self._roach_actors[roach.name]
101 roach_actor.pos = self._seat_layer[seat_pos].pos
102 self._roach_layer.add(roach_actor)
104 self._outside_roaches.append(roach.name)
105 if self._outside_roaches:
106 self._outside_roach_pos %= len(self._outside_roaches)
107 roach_actor = self._roach_actors[
108 self._outside_roaches[self._outside_roach_pos]]
109 roach_pad_center = self._roach_pad.center
111 roach_pad_center[0] + ROACH_PAD_OFFSET[0],
112 roach_pad_center[1] + ROACH_PAD_OFFSET[1])
113 self._roach_layer.add(roach_actor)
115 self._outside_roach_pos = 0
117 def _init_pads(self):
118 self._roach_pad = self._pad_layer.add(
119 Actor("roach_management/roach_pad", anchor=("left", "bottom")))
120 self._roach_pad.pos = (TOOLBAR_LEFT_X, TOOLBAR_MID_Y)
121 self._inventory_pad = self._pad_layer.add(
122 Actor("roach_management/inventory_pad", anchor=("left", "top")))
123 self._inventory_pad.pos = (TOOLBAR_LEFT_X, TOOLBAR_MID_Y)
125 def _add_button(self, name, anchor, inset, pos, action):
126 button = self._button_layer.add(
127 ImageButton(name, anchor=anchor, action=action))
128 button.pos = inset_button(pos, inset)
131 def _init_buttons(self):
132 self._button_layer.clear()
134 "roach_management/left_button", ("left", "bottom"), (1, -1),
135 self._roach_pad.bottomleft, self._roach_left)
138 "roach_management/right_button", ("right", "bottom"), (-1, -1),
139 self._roach_pad.bottomright, self._roach_right)
142 "roach_management/left_button", ("left", "bottom"), (1, -1),
143 self._inventory_pad.bottomleft, self._inventory_left)
146 "roach_management/right_button", ("right", "bottom"), (-1, -1),
147 self._inventory_pad.bottomright, self._inventory_right)
150 "roach_management/eject_button", ("right", "top"), (-1, 1),
151 (TOOLBAR_LEFT_X, TOOLBAR_TOP_Y), self._eject_roach)
153 def _roach_left(self):
154 self._outside_roach_pos -= 1
156 def _roach_right(self):
157 self._outside_roach_pos += 1
159 def _inventory_left(self):
160 self._inventory_pos -= 1
162 def _inventory_right(self):
163 self._inventory_pos += 1
165 def _select_seat(self, seat_pos):
166 self._seat_layer[self._seat_pos].selected = False
167 self._seat_pos = seat_pos
168 self._seat_layer[self._seat_pos].selected = True
170 def _eject_roach(self, world=None):
172 self._update_calls.append(self._eject_roach)
174 self._vehicle.seat_roach(world, None, self._seat_pos)
176 def _click_roach_pad(self, world=None):
178 self._update_calls.append(self._click_roach_pad)
180 if self._outside_roaches:
181 roach = self._outside_roaches[self._outside_roach_pos]
182 self._vehicle.seat_roach(world, roach, self._seat_pos)
184 def _click_inventory_pad(self, world=None):
186 self._update_calls.append(self._click_inventory_pad)
188 roach_name = self._vehicle.roach_at(world, self._seat_pos)
189 if roach_name is None:
191 roach = roach_by_name(world, roach_name)
194 serums = list(world.serums)
195 if self._inventory_pos >= len(serums):
197 serum = serums.pop(self._inventory_pos)
198 if roach_is_serumless(roach):
200 world.serums = serums
201 self._update_calls.append((self._update_roach_actor, roach_name))
203 def _update_roach_actor(self, world, roach_name):
204 roach = roach_by_name(world, roach_name)
205 self._roach_actors[roach_name] = big_roaches.assemble(roach)
207 def update(self, world, engine, dt):
208 update_calls, self._update_calls = self._update_calls, []
210 f, args = update_calls.pop(), ()
212 f, args = f[0], f[1:]
214 events = world.pop_events()
215 self._update_inventory(world)
216 self._update_roaches(world)
219 def on_key_down(self, key, mod, unicode):
220 if key in (keys.ESCAPE, keys.Z):
221 if self._level_scene is None:
222 from .menu import MenuScene
223 return [ChangeSceneEvent(MenuScene())]
224 return [ChangeSceneEvent(self._level_scene)]
226 def on_mouse_down(self, pos, button):
227 if button == mouse.LEFT:
228 for actor in self.actors.buttons:
229 if actor.collidepoint(pos):
230 return actor.action()
231 for i, actor in enumerate(self.actors.seats):
232 if actor.collidepoint(pos):
233 return self._select_seat(i)
234 if self._roach_pad.collidepoint(pos):
235 return self._click_roach_pad()
236 if self._inventory_pad.collidepoint(pos):
237 return self._click_inventory_pad()