changeset 521:5a8a7f17597d

Add support for 'if': '...' to dialogue choices.
author Simon Cross <hodgestar@gmail.com>
date Sat, 09 Apr 2011 23:36:05 +0200
parents 17987763b80f
children 4de4f94c326d
files scripts/npc-test skaapsteker/dialogue.py skaapsteker/widgets/bubble.py
diffstat 3 files changed, 29 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/npc-test	Sat Apr 09 23:33:14 2011 +0200
+++ b/scripts/npc-test	Sat Apr 09 23:36:05 2011 +0200
@@ -39,7 +39,7 @@
             text = text.encode('utf-8')
         print "%s:" % dsm.state, text
         print "--"
-        for i, choice in state.choices:
+        for i, choice in dsm.choices():
             print "%d: %s" % (i, choice)
         if state.auto_next:
             print "N: Next"
@@ -89,6 +89,7 @@
         print "  Test on_entry and on_exit for state %s" % state_name
         state.enter(my_locals)
         state.leave(my_locals)
+        list(state.choices(my_locals))
     print "ok"
 
 
--- a/skaapsteker/dialogue.py	Sat Apr 09 23:33:14 2011 +0200
+++ b/skaapsteker/dialogue.py	Sat Apr 09 23:36:05 2011 +0200
@@ -49,7 +49,7 @@
         sprite = gamestate.create_item_sprite(item, to_level=to_level, to_pos=to_pos)
         AddSpriteEvent.post(sprite)
 
-    def event(self, ev):
+    def _make_locals(self):
         my_locals = {
             "state": self.states,
             "world": self.world,
@@ -57,6 +57,15 @@
             "switch_to": self._switch_dialogue_to,
             "drop_item": self._drop_item,
         }
+        return my_locals
+
+    def choices(self):
+        my_locals = self._make_locals()
+        state = self.states[self.state]
+        return state.choices(my_locals)
+
+    def event(self, ev):
+        my_locals = self._make_locals()
         my_locals.update(ev.items)
         state = self.states[self.state]
         next_state = state.event(my_locals)
@@ -103,13 +112,19 @@
     def __init__(self, name, state_src, base_path):
         self.name = name
         self.text = state_src.get("text", None)
-        self.choices = []
+        self._choices = []
         self.triggers = []
 
         choices = state_src.get("choices", [])
         for i, choice in enumerate(choices):
             pseudo_path = base_path + ["choice-%d" % i]
-            self.choices.append((i, choice["text"]))
+            if "if" in choice:
+                choice_if = compile(choice["if"],
+                                    "<%s>" % ":".join(pseudo_path + ["if"]),
+                                    "eval")
+            else:
+                choice_if = None
+            self._choices.append((i, choice["text"], choice_if))
             next_state_code = choice.get("next", None)
             if next_state_code is not None:
                 self.triggers.append(
@@ -126,7 +141,7 @@
         self.auto_next = False
         if auto_next is not None:
             self.auto_next = True
-            assert not self.choices, "%s: auto_next and choices are not compatible" % ":".join(base_path)
+            assert not self._choices, "%s: auto_next and choices are not compatible" % ":".join(base_path)
             pseudo_path = base_path + ["auto_next"]
             self.triggers.append(Trigger("""auto_next""", auto_next, pseudo_path))
 
@@ -149,6 +164,13 @@
     def __repr__(self):
         return "<%r name=%r>" % (self.__class__.__name__, self.name)
 
+    def choices(self, my_locals):
+        for i, text, choice_if in self._choices:
+            if choice_if is None:
+                yield i, text
+            elif eval(choice_if, {}, my_locals.copy()):
+                yield i, text
+
     def event(self, my_locals):
         for trigger in self.triggers:
             next_state = trigger.fire(my_locals)
--- a/skaapsteker/widgets/bubble.py	Sat Apr 09 23:33:14 2011 +0200
+++ b/skaapsteker/widgets/bubble.py	Sat Apr 09 23:36:05 2011 +0200
@@ -58,7 +58,7 @@
             self._text = Text(state.text, pos, wrap=True)
         else:
             self._text = None
-        options = [(text, i) for (i, text) in state.choices]
+        options = [(text, i) for (i, text) in self.dsm.choices()]
         if state.auto_next:
             text = state.auto_next_text if state.auto_next_text else "Next"
             options.append((text, "N"))