home · contact · privacy
Make doors installable/uninstallable.
[plomrogue2] / plomrogue / things.py
index a5d38897205282e51fb29ba23333c72fded7b02a..d348e8400df1239d0105995f1193689dd132cd09 100644 (file)
@@ -1,4 +1,4 @@
-from plomrogue.errors import GameError
+from plomrogue.errors import GameError, PlayError
 from plomrogue.mapping import YX
 
 
@@ -128,17 +128,22 @@ class Thing_Door(Thing):
     symbol_hint = 'D'
     blocking = False
     portable = True
+    installable = True
 
     def open(self):
         self.blocking = False
-        self.portable = True
         del self.thing_char
 
     def close(self):
         self.blocking = True
-        self.portable = False
         self.thing_char = '#'
 
+    def install(self):
+        self.portable = False
+
+    def uninstall(self):
+        self.portable = True
+
 
 
 class Thing_Bottle(Thing):
@@ -285,26 +290,20 @@ class ThingAnimate(Thing):
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
-        self.next_tasks = []
-        self.set_task('WAIT')
+        self.next_task = [None]
+        self.task = None
         self._fov = None
 
-    def set_task(self, task_name, args=()):
-        task_class = self.game.tasks[task_name]
-        self.task = task_class(self, args)
-        self.task.check()  # will throw GameError if necessary
-
     def set_next_task(self, task_name, args=()):
         task_class = self.game.tasks[task_name]
-        self.next_tasks += [task_class(self, args)]
+        self.next_task = [task_class(self, args)]
 
     def get_next_task(self):
-        if len(self.next_tasks) > 0:
-            task = self.next_tasks.pop(0)
+        if self.next_task[0]:
+            task = self.next_task[0]
+            self.next_task = [None]
             task.check()
             return task
-        else:
-            return None
 
     def proceed(self):
         self.drunk -= 1
@@ -313,6 +312,7 @@ class ThingAnimate(Thing):
                 if self.game.sessions[c_id]['thing_id'] == self.id_:
                     self.game.io.send('DEFAULT_COLORS', c_id)
                     self.game.io.send('CHAT "You sober up."', c_id)
+                    break
             self.game.changed = True
         self._fov = None
         if self.task is None:
@@ -320,25 +320,37 @@ class ThingAnimate(Thing):
             return
         try:
             self.task.check()
-        except GameError as e:
+        except (PlayError, GameError) as e:
             self.task = None
             raise e
         self.task.todo -= 1
         if self.task.todo <= 0:
-            self._last_task_result = self.task.do()
+            self.task.do()
             self.game.changed = True
             self.task = self.get_next_task()
 
+    def prepare_multiprocessible_fov_stencil(self):
+        fov_map_class = self.game.map_geometry.fov_map_class
+        fov_radius = 3 if self.drunk > 0 else 12
+        self._fov = fov_map_class(self.game.things, self.game.maps,
+                                  self.position, fov_radius, self.game.get_map)
+
+    def multiprocessible_fov_stencil(self):
+        self._fov.init_terrain()
+
     @property
     def fov_stencil(self):
         if self._fov:
             return self._fov
-        fov_map_class = self.game.map_geometry.fov_map_class
-        fov_radius = 3 if self.drunk > 0 else 12
-        self._fov = fov_map_class(self.game.things, self.game.maps, self.position,
-                                  fov_radius, self.game.get_map)
+        # due to the pre-multiprocessing in game.send_gamestate,
+        # the following should actually never be called
+        self.prepare_multiprocessible_fov_stencil()
+        self.multiprocessible_fov_stencil()
         return self._fov
 
+    def fov_stencil_make(self):
+        self._fov.make()
+
     def fov_test(self, big_yx, little_yx):
         test_position = self.fov_stencil.target_yx(big_yx, little_yx)
         if self.fov_stencil.inside(test_position):