Support applying serums.
[koperkapel.git] / koperkapel / scenes / roach_management.py
index 7dc9c5eaff4952fb37e2e33f9cb57b415189ad6c..9a356ac918c9f8932b49e135b85abd0262fac4ea 100644 (file)
@@ -4,8 +4,8 @@ from pgzero.constants import keys, mouse
 from pgzero.actor import Actor
 from ..actors.buttons import ImageButton
 from ..constants import WIDTH, HEIGHT
 from pgzero.actor import Actor
 from ..actors.buttons import ImageButton
 from ..constants import WIDTH, HEIGHT
-from ..roaches import big_roaches
-from ..serums import big_serums, SERUMS
+from ..roaches import big_roaches, roach_by_name
+from ..serums import big_serums, roach_is_serumless, SERUMS
 from ..vehicles.base import Vehicle
 from .base import Scene, ChangeSceneEvent
 
 from ..vehicles.base import Vehicle
 from .base import Scene, ChangeSceneEvent
 
@@ -48,6 +48,7 @@ class RoachesScene(Scene):
 
     def enter(self, world):
         self._vehicle = Vehicle.current(world)
 
     def enter(self, world):
         self._vehicle = Vehicle.current(world)
+        self._update_calls = []
         self._init_bg()
         self._init_seats()
         self._init_roaches(world)
         self._init_bg()
         self._init_seats()
         self._init_roaches(world)
@@ -91,7 +92,7 @@ class RoachesScene(Scene):
     def _update_roaches(self, world):
         self._roach_layer.clear()
         seating = self._vehicle.seating(world)
     def _update_roaches(self, world):
         self._roach_layer.clear()
         seating = self._vehicle.seating(world)
-        outside_roaches = []
+        self._outside_roaches = []
         for roach in world.roaches:
             seat_pos = seating.get(roach.name)
             if seat_pos is not None:
         for roach in world.roaches:
             seat_pos = seating.get(roach.name)
             if seat_pos is not None:
@@ -99,16 +100,18 @@ class RoachesScene(Scene):
                 roach_actor.pos = self._seat_layer[seat_pos].pos
                 self._roach_layer.add(roach_actor)
             else:
                 roach_actor.pos = self._seat_layer[seat_pos].pos
                 self._roach_layer.add(roach_actor)
             else:
-                outside_roaches.append(roach.name)
-        self._outside_roach_pos %= len(outside_roaches)
-        if outside_roaches:
+                self._outside_roaches.append(roach.name)
+        if self._outside_roaches:
+            self._outside_roach_pos %= len(self._outside_roaches)
             roach_actor = self._roach_actors[
             roach_actor = self._roach_actors[
-                outside_roaches[self._outside_roach_pos]]
+                self._outside_roaches[self._outside_roach_pos]]
             roach_pad_center = self._roach_pad.center
             roach_actor.pos = (
                 roach_pad_center[0] + ROACH_PAD_OFFSET[0],
                 roach_pad_center[1] + ROACH_PAD_OFFSET[1])
             self._roach_layer.add(roach_actor)
             roach_pad_center = self._roach_pad.center
             roach_actor.pos = (
                 roach_pad_center[0] + ROACH_PAD_OFFSET[0],
                 roach_pad_center[1] + ROACH_PAD_OFFSET[1])
             self._roach_layer.add(roach_actor)
+        else:
+            self._outside_roach_pos = 0
 
     def _init_pads(self):
         self._roach_pad = self._pad_layer.add(
 
     def _init_pads(self):
         self._roach_pad = self._pad_layer.add(
@@ -163,12 +166,54 @@ class RoachesScene(Scene):
         self._seat_pos = seat_pos
         self._seat_layer[self._seat_pos].selected = True
 
         self._seat_pos = seat_pos
         self._seat_layer[self._seat_pos].selected = True
 
-    def _eject_roach(self):
-        print("Eject roach.")
+    def _eject_roach(self, world=None):
+        if world is None:
+            self._update_calls.append(self._eject_roach)
+            return
+        self._vehicle.seat_roach(world, None, self._seat_pos)
+
+    def _click_roach_pad(self, world=None):
+        if world is None:
+            self._update_calls.append(self._click_roach_pad)
+            return
+        if self._outside_roaches:
+            roach = self._outside_roaches[self._outside_roach_pos]
+            self._vehicle.seat_roach(world, roach, self._seat_pos)
 
 
-    def update(self, world, dt):
+    def _click_inventory_pad(self, world=None):
+        if world is None:
+            self._update_calls.append(self._click_inventory_pad)
+            return
+        roach_name = self._vehicle.roach_at(world, self._seat_pos)
+        if roach_name is None:
+            return
+        roach = roach_by_name(world, roach_name)
+        if roach is None:
+            return
+        serums = list(world.serums)
+        if self._inventory_pos >= len(serums):
+            return
+        serum = serums.pop(self._inventory_pos)
+        if roach_is_serumless(roach):
+            roach[serum] = True
+            world.serums = serums
+            self._update_calls.append((self._update_roach_actor, roach_name))
+
+    def _update_roach_actor(self, world, roach_name):
+        roach = roach_by_name(world, roach_name)
+        self._roach_actors[roach_name] = big_roaches.assemble(roach)
+
+    def update(self, world, engine, dt):
+        update_calls, self._update_calls = self._update_calls, []
+        while update_calls:
+            f, args = update_calls.pop(), ()
+            if type(f) is tuple:
+                f, args = f[0], f[1:]
+            f(world, *args)
+        events = world.pop_events()
         self._update_inventory(world)
         self._update_roaches(world)
         self._update_inventory(world)
         self._update_roaches(world)
+        return events
 
     def on_key_down(self, key, mod, unicode):
         if key == keys.ESCAPE:
 
     def on_key_down(self, key, mod, unicode):
         if key == keys.ESCAPE:
@@ -183,3 +228,7 @@ class RoachesScene(Scene):
             for i, actor in enumerate(self.actors.seats):
                 if actor.collidepoint(pos):
                     return self._select_seat(i)
             for i, actor in enumerate(self.actors.seats):
                 if actor.collidepoint(pos):
                     return self._select_seat(i)
+            if self._roach_pad.collidepoint(pos):
+                return self._click_roach_pad()
+            if self._inventory_pad.collidepoint(pos):
+                return self._click_inventory_pad()