annotate skaapsteker/dialogue.py @ 553:62569f486ede

Debug print cleanup.
author Jeremy Thurgood <firxen@gmail.com>
date Sun, 10 Apr 2011 01:46:10 +0200
parents 5a8a7f17597d
children e648501c2eea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
1 import json
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
2
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
3 from . import data
490
0eade58a71b9 Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents: 483
diff changeset
4 from .engine import OpenDialog, AddSpriteEvent
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
5
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
6
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
7 class DSM(object):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
8 """Dialogue State Machine!
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
9
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
10 Parameters
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
11 ----------
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
12 json_filename : str
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
13 Path to file under data/ that contains JSON description
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
14 of state machine.
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
15 world : object
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
16 Something to allow states to introspect the game state with.
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
17 """
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
18
217
fcc5eca8eaca Add explicit starting state to avoid it magically appearing later.
Simon Cross <hodgestar@gmail.com>
parents: 216
diff changeset
19 def __init__(self, name, world, json_filename, state):
331
45755c143813 Save npc state to world when a state transition occurs (fixes monk dialogue tree resetting bug).
Simon Cross <hodgestar@gmail.com>
parents: 302
diff changeset
20 self.name = name
217
fcc5eca8eaca Add explicit starting state to avoid it magically appearing later.
Simon Cross <hodgestar@gmail.com>
parents: 216
diff changeset
21 self.state = state
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
22 self.world = world
331
45755c143813 Save npc state to world when a state transition occurs (fixes monk dialogue tree resetting bug).
Simon Cross <hodgestar@gmail.com>
parents: 302
diff changeset
23 self._me = getattr(self.world.npcs, name)
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
24 self.states = AttrDict()
483
b48c194c4af9 Some haiku and encoding fixes.
Jeremy Thurgood <firxen@gmail.com>
parents: 476
diff changeset
25 src = json.loads(data.load(json_filename).read(), encoding='utf-8')
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
26 for state, state_src in src.iteritems():
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
27 pseudo_path = [json_filename, state]
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
28 self.states[state] = DsmState(state, state_src, pseudo_path)
217
fcc5eca8eaca Add explicit starting state to avoid it magically appearing later.
Simon Cross <hodgestar@gmail.com>
parents: 216
diff changeset
29 assert self.state in self.states, "DSM must have start state %r" % (self.state,)
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
30
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
31 def get_state(self):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
32 return self.states[self.state]
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
33
251
432f6997d306 More hooking up of interacting with NPCs.
Simon Cross <hodgestar@gmail.com>
parents: 246
diff changeset
34 def has_text(self):
286
0dbb50d07764 Poke the current state before checking to see if there is text in case the world has changed and it is time for the state machine to move on.
Simon Cross <hodgestar@gmail.com>
parents: 285
diff changeset
35 self.poke()
251
432f6997d306 More hooking up of interacting with NPCs.
Simon Cross <hodgestar@gmail.com>
parents: 246
diff changeset
36 return bool(self.states[self.state].text)
432f6997d306 More hooking up of interacting with NPCs.
Simon Cross <hodgestar@gmail.com>
parents: 246
diff changeset
37
302
78220c989e6a Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents: 291
diff changeset
38 def _switch_dialogue_to(self, npc_name):
78220c989e6a Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents: 291
diff changeset
39 """Switch dialogue to another npc."""
78220c989e6a Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents: 291
diff changeset
40 OpenDialog.post(npc_name)
78220c989e6a Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents: 291
diff changeset
41
490
0eade58a71b9 Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents: 483
diff changeset
42 def _drop_item(self, item, shift=(1, 0)):
476
1c05b6c2b971 Start of drop item support.
Simon Cross <hodgestar@gmail.com>
parents: 331
diff changeset
43 """Create a tail of the given type."""
490
0eade58a71b9 Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents: 483
diff changeset
44 to_level = self._me.level
0eade58a71b9 Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents: 483
diff changeset
45 to_pos = self._me.pos
0eade58a71b9 Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents: 483
diff changeset
46 to_pos = to_pos[0] + shift[0], to_pos[1] + shift[1]
0eade58a71b9 Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents: 483
diff changeset
47 gamestate = self.world.gamestate()
0eade58a71b9 Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents: 483
diff changeset
48 sprite = gamestate.create_item_sprite(item, to_level=to_level, to_pos=to_pos)
0eade58a71b9 Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents: 483
diff changeset
49 AddSpriteEvent.post(sprite)
476
1c05b6c2b971 Start of drop item support.
Simon Cross <hodgestar@gmail.com>
parents: 331
diff changeset
50
521
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
51 def _make_locals(self):
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
52 my_locals = {
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
53 "state": self.states,
193
897eec397cbb Fix state checks for hattori, ichiro, kaneda and kumiko. In the process provide easier access to other npcs.
Simon Cross <hodgestar@gmail.com>
parents: 190
diff changeset
54 "world": self.world,
897eec397cbb Fix state checks for hattori, ichiro, kaneda and kumiko. In the process provide easier access to other npcs.
Simon Cross <hodgestar@gmail.com>
parents: 190
diff changeset
55 "npcs": self.world.npcs,
302
78220c989e6a Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents: 291
diff changeset
56 "switch_to": self._switch_dialogue_to,
476
1c05b6c2b971 Start of drop item support.
Simon Cross <hodgestar@gmail.com>
parents: 331
diff changeset
57 "drop_item": self._drop_item,
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
58 }
521
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
59 return my_locals
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
60
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
61 def choices(self):
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
62 my_locals = self._make_locals()
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
63 state = self.states[self.state]
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
64 return state.choices(my_locals)
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
65
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
66 def event(self, ev):
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
67 my_locals = self._make_locals()
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
68 my_locals.update(ev.items)
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
69 state = self.states[self.state]
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
70 next_state = state.event(my_locals)
246
8dee25fd070d Fix some npc-test and dialogue bugs.
Simon Cross <hodgestar@gmail.com>
parents: 233
diff changeset
71 if next_state is not None and next_state.name in self.states:
216
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
72 self.states[self.state].leave(my_locals)
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
73 self.state = next_state.name
331
45755c143813 Save npc state to world when a state transition occurs (fixes monk dialogue tree resetting bug).
Simon Cross <hodgestar@gmail.com>
parents: 302
diff changeset
74 self._me.state = self.state
216
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
75 self.states[self.state].enter(my_locals)
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
76
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
77 def choice(self, i):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
78 self.event(DsmEvent(choice=i))
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
79
285
71f15f6e9274 Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents: 251
diff changeset
80 def auto_next(self):
71f15f6e9274 Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents: 251
diff changeset
81 self.event(DsmEvent(auto_next=True))
71f15f6e9274 Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents: 251
diff changeset
82
286
0dbb50d07764 Poke the current state before checking to see if there is text in case the world has changed and it is time for the state machine to move on.
Simon Cross <hodgestar@gmail.com>
parents: 285
diff changeset
83 def poke(self):
0dbb50d07764 Poke the current state before checking to see if there is text in case the world has changed and it is time for the state machine to move on.
Simon Cross <hodgestar@gmail.com>
parents: 285
diff changeset
84 # poke the current state to see if it feels like making
0dbb50d07764 Poke the current state before checking to see if there is text in case the world has changed and it is time for the state machine to move on.
Simon Cross <hodgestar@gmail.com>
parents: 285
diff changeset
85 # a transition.
0dbb50d07764 Poke the current state before checking to see if there is text in case the world has changed and it is time for the state machine to move on.
Simon Cross <hodgestar@gmail.com>
parents: 285
diff changeset
86 self.event(DsmEvent(poke=True))
0dbb50d07764 Poke the current state before checking to see if there is text in case the world has changed and it is time for the state machine to move on.
Simon Cross <hodgestar@gmail.com>
parents: 285
diff changeset
87
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
88
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
89 class AttrDict(dict):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
90
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
91 def __getattr__(self, name):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
92 if name not in self:
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
93 raise AttributeError("No attribute %r" % (name,))
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
94 return self[name]
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
95
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
96
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
97 class DsmEvent(object):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
98
286
0dbb50d07764 Poke the current state before checking to see if there is text in case the world has changed and it is time for the state machine to move on.
Simon Cross <hodgestar@gmail.com>
parents: 285
diff changeset
99 def __init__(self, choice=None, auto_next=False, poke=False):
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
100 self.items = {
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
101 "choice": choice,
285
71f15f6e9274 Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents: 251
diff changeset
102 "auto_next": auto_next,
286
0dbb50d07764 Poke the current state before checking to see if there is text in case the world has changed and it is time for the state machine to move on.
Simon Cross <hodgestar@gmail.com>
parents: 285
diff changeset
103 "poke": poke,
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
104 }
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
105
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
106
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
107 class DsmState(object):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
108 """State within a DSM.
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
109 """
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
110
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
111 def __init__(self, name, state_src, base_path):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
112 self.name = name
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
113 self.text = state_src.get("text", None)
521
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
114 self._choices = []
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
115 self.triggers = []
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
116
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
117 choices = state_src.get("choices", [])
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
118 for i, choice in enumerate(choices):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
119 pseudo_path = base_path + ["choice-%d" % i]
521
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
120 if "if" in choice:
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
121 choice_if = compile(choice["if"],
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
122 "<%s>" % ":".join(pseudo_path + ["if"]),
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
123 "eval")
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
124 else:
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
125 choice_if = None
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
126 self._choices.append((i, choice["text"], choice_if))
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
127 next_state_code = choice.get("next", None)
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
128 if next_state_code is not None:
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
129 self.triggers.append(
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
130 Trigger("choice == %d" % i, next_state_code, pseudo_path))
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
131
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
132 events = state_src.get("events", [])
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
133 for i, event in enumerate(events):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
134 pseudo_path = base_path + ["event-%d" % i]
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
135 self.triggers.append(Trigger(event["matches"], event["next"],
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
136 pseudo_path))
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
137
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
138 auto_next = state_src.get("auto_next", None)
291
04be4219742b Add support for auto_next_text to give the auto_next effect but with a different prompt.
Simon Cross <hodgestar@gmail.com>
parents: 286
diff changeset
139 self.auto_next_text = state_src.get("auto_next_text", None)
285
71f15f6e9274 Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents: 251
diff changeset
140 self.auto_next = False
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
141 if auto_next is not None:
285
71f15f6e9274 Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents: 251
diff changeset
142 self.auto_next = True
521
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
143 assert not self._choices, "%s: auto_next and choices are not compatible" % ":".join(base_path)
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
144 pseudo_path = base_path + ["auto_next"]
285
71f15f6e9274 Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents: 251
diff changeset
145 self.triggers.append(Trigger("""auto_next""", auto_next, pseudo_path))
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
146
216
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
147 on_entry = state_src.get("on_entry", None)
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
148 if on_entry is not None:
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
149 self.on_entry = compile(on_entry,
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
150 "<%s>" % ":".join(base_path + ["on_entry"]),
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
151 "exec")
233
8ea658969f47 Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents: 217
diff changeset
152 else:
8ea658969f47 Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents: 217
diff changeset
153 self.on_entry = None
216
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
154
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
155 on_exit = state_src.get("on_exit", None)
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
156 if on_exit is not None:
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
157 self.on_exit = compile(on_exit,
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
158 "<%s>" % ":".join(base_path + ["on_exit"]),
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
159 "exec")
233
8ea658969f47 Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents: 217
diff changeset
160 else:
8ea658969f47 Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents: 217
diff changeset
161 self.on_exit = None
216
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
162
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
163 def __repr__(self):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
164 return "<%r name=%r>" % (self.__class__.__name__, self.name)
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
165
521
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
166 def choices(self, my_locals):
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
167 for i, text, choice_if in self._choices:
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
168 if choice_if is None:
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
169 yield i, text
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
170 elif eval(choice_if, {}, my_locals.copy()):
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
171 yield i, text
5a8a7f17597d Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents: 490
diff changeset
172
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
173 def event(self, my_locals):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
174 for trigger in self.triggers:
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
175 next_state = trigger.fire(my_locals)
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
176 if next_state is not None:
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
177 return next_state
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
178
216
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
179 def enter(self, my_locals):
233
8ea658969f47 Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents: 217
diff changeset
180 if self.on_entry is not None:
8ea658969f47 Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents: 217
diff changeset
181 exec(self.on_entry, {}, my_locals.copy())
216
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
182
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
183 def leave(self, my_locals):
233
8ea658969f47 Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents: 217
diff changeset
184 if self.on_exit is not None:
8ea658969f47 Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents: 217
diff changeset
185 exec(self.on_exit, {}, my_locals.copy())
216
023eea4ad4a5 Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents: 196
diff changeset
186
153
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
187
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
188 class Trigger(object):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
189 """Matches DSM events and triggers state transitions.
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
190 """
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
191
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
192 def __init__(self, matches_code, next_state_code, pseudo_path):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
193 self._matches = compile(matches_code,
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
194 "<%s>" % ":".join(pseudo_path + ["match"]),
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
195 "eval")
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
196 self._next_state = compile(next_state_code,
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
197 "<%s>" % ":".join(pseudo_path + ["next"]),
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
198 "eval")
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
199
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
200 def fire(self, my_locals):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
201 if eval(self._matches, {}, my_locals.copy()):
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
202 return eval(self._next_state, {}, my_locals.copy())
704d23022f09 Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
203 return None