changeset 359:d42752ab3231

Refactor doors and add horrible temporoary image for someone to fix later.
author Jeremy Thurgood <firxen@gmail.com>
date Fri, 06 Sep 2013 19:42:01 +0200
parents 911547a1c378
children ba7a5159a69b
files data/images/objects/locked_door.png data/levels/level1 nagslang/environment.py nagslang/game_object.py
diffstat 4 files changed, 66 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
Binary file data/images/objects/locked_door.png has changed
--- a/data/levels/level1	Fri Sep 06 19:39:59 2013 +0200
+++ b/data/levels/level1	Fri Sep 06 19:42:01 2013 +0200
@@ -59,7 +59,7 @@
   - [600, 700]
   - 0
   - door_switch
-  classname: Door
+  classname: PuzzleDoor
   name: switch_door
 lines:
 - - [750, 680]
--- a/nagslang/environment.py	Fri Sep 06 19:39:59 2013 +0200
+++ b/nagslang/environment.py	Fri Sep 06 19:42:01 2013 +0200
@@ -8,6 +8,13 @@
         raise NotImplementedError()
 
 
+class YesCondition(ProtagonistCondition):
+    """Condition that is always met.
+    """
+    def check(self, protagonist):
+        return True
+
+
 class AllConditions(ProtagonistCondition):
     """Condition that is met if all provided conditions are met.
 
--- a/nagslang/game_object.py	Fri Sep 06 19:39:59 2013 +0200
+++ b/nagslang/game_object.py	Fri Sep 06 19:42:01 2013 +0200
@@ -268,11 +268,12 @@
                 ("state_source", "puzzler")]
 
 
-class Door(GameObject):
+class BaseDoor(GameObject):
     zorder = ZORDER_FLOOR
+    is_open = True
 
     def __init__(self, space, position, destination, dest_pos, angle,
-                 key_state=None):
+                 renderer, condition):
         body = make_body(pymunk.inf, pymunk.inf, position, damping=0.5)
         self.shape = pymunk.Circle(body, 30)
         self.shape.collision_type = COLLISION_TYPE_DOOR
@@ -280,50 +281,84 @@
         self.shape.sensor = True
         self.destination = destination
         self.dest_pos = tuple(dest_pos)
-        self._key_state = key_state
+        super(BaseDoor, self).__init__(
+            SingleShapePhysicser(space, self.shape),
+            renderer,
+            puzzle.ParentAttrPuzzler('is_open'),
+            interactible=environment.Interactible(
+                environment.Action(self._post_door_event, condition)),
+        )
+
+    def _post_door_event(self, protagonist):
+        DoorEvent.post(self.destination, self.dest_pos)
+
+
+class Door(BaseDoor):
+    def __init__(self, space, position, destination, dest_pos, angle):
         super(Door, self).__init__(
-            SingleShapePhysicser(space, self.shape),
+            space, position, destination, dest_pos, angle,
+            render.ImageRenderer(resources.get_image('objects', 'door.png')),
+            environment.YesCondition(),
+        )
+
+    @classmethod
+    def requires(cls):
+        return [("name", "string"), ("position", "coordinates"),
+                ("destination", "level name"), ("dest_pos", "coordinate"),
+                ("angle", "degrees")]
+
+
+class PuzzleDoor(BaseDoor):
+    def __init__(self, space, position, destination, dest_pos, angle,
+                 key_state):
+        self._key_state = key_state
+        super(PuzzleDoor, self).__init__(
+            space, position, destination, dest_pos, angle,
             render.ImageStateRenderer({
                 True: resources.get_image('objects', 'door.png'),
-                # TODO: Locked door image.
-                False: resources.get_image('objects', 'door.png'),
+                False: resources.get_image('objects', 'locked_door.png'),
             }),
-            puzzle.ParentAttrPuzzler('is_open'),
-            interactible=environment.Interactible(
-                environment.Action(
-                    self._post_door_event,
-                    environment.FunctionCondition(lambda p: self.is_open))),
+            environment.FunctionCondition(lambda p: self.is_open),
         )
 
     @property
     def is_open(self):
         return self._stored_state['is_open']
 
-    def _post_door_event(self, protagonist):
-        DoorEvent.post(self.destination, self.dest_pos)
-
     def set_stored_state_dict(self, stored_state):
         self._stored_state = stored_state
-        if self._key_state is not None:
-            # We're lockable, so we start locked and want to save our state.
-            self._stored_state.setdefault('is_open', False)
-            return True
-        # Not lockable, so we're always open and don't bother saving state.
-        self._stored_state['is_open'] = True
-        return False
+        self._stored_state.setdefault('is_open', False)
+        return True
 
     def update(self, dt):
         if not self.is_open:
             self._stored_state['is_open'] = self.puzzler.glue.get_state_of(
                 self._key_state)
-        super(Door, self).update(dt)
+        super(PuzzleDoor, self).update(dt)
 
     @classmethod
     def requires(cls):
         return [("name", "string"), ("position", "coordinates"),
                 ("destination", "level name"), ("dest_pos", "coordinate"),
                 ("angle", "degrees"),
-                ("key_state", "puzzler (optional)")]
+                ("key_state", "puzzler")]
+
+
+class KeyedDoor(BaseDoor):
+    def __init__(self, space, position, destination, dest_pos, angle,
+                 key_item=None):
+        self._key_item = key_item
+        super(KeyedDoor, self).__init__(
+            space, position, destination, dest_pos, angle,
+            render.ImageRenderer(resources.get_image('objects', 'door.png')),
+            environment.ItemRequiredCondition(key_item),
+        )
+
+    @classmethod
+    def requires(cls):
+        return [("name", "string"), ("position", "coordinates"),
+                ("destination", "level name"), ("dest_pos", "coordinate"),
+                ("angle", "degrees"), ("key_item", "item name")]
 
 
 class Bulkhead(GameObject):