Mercurial > skaapsteker
annotate skaapsteker/dialogue.py @ 612:a91b2e4400a5
Fallback to using simplejson if json does not exist (this appears to be all that is needed to add Python2.5 compatibility).
author | Simon Cross <hodgestar@gmail.com> |
---|---|
date | Mon, 11 Apr 2011 23:54:56 +0200 |
parents | e648501c2eea |
children | 0675f390653c |
rev | line source |
---|---|
612
a91b2e4400a5
Fallback to using simplejson if json does not exist (this appears to be all that is needed to add Python2.5 compatibility).
Simon Cross <hodgestar@gmail.com>
parents:
557
diff
changeset
|
1 try: |
a91b2e4400a5
Fallback to using simplejson if json does not exist (this appears to be all that is needed to add Python2.5 compatibility).
Simon Cross <hodgestar@gmail.com>
parents:
557
diff
changeset
|
2 import json |
a91b2e4400a5
Fallback to using simplejson if json does not exist (this appears to be all that is needed to add Python2.5 compatibility).
Simon Cross <hodgestar@gmail.com>
parents:
557
diff
changeset
|
3 except ImportError: |
a91b2e4400a5
Fallback to using simplejson if json does not exist (this appears to be all that is needed to add Python2.5 compatibility).
Simon Cross <hodgestar@gmail.com>
parents:
557
diff
changeset
|
4 import simplejson as json |
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 from . import data |
557
e648501c2eea
victory scene hacked in
Adrianna Pińska <adrianna.pinska@gmail.com>
parents:
553
diff
changeset
|
7 from .engine import OpenDialog, AddSpriteEvent, ChangeScene |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
8 |
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 class DSM(object): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
11 """Dialogue State Machine! |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
12 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
13 Parameters |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
14 ---------- |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
15 json_filename : str |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
16 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
|
17 of state machine. |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
18 world : object |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
19 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
|
20 """ |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
21 |
217
fcc5eca8eaca
Add explicit starting state to avoid it magically appearing later.
Simon Cross <hodgestar@gmail.com>
parents:
216
diff
changeset
|
22 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
|
23 self.name = name |
217
fcc5eca8eaca
Add explicit starting state to avoid it magically appearing later.
Simon Cross <hodgestar@gmail.com>
parents:
216
diff
changeset
|
24 self.state = state |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
25 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
|
26 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
|
27 self.states = AttrDict() |
483
b48c194c4af9
Some haiku and encoding fixes.
Jeremy Thurgood <firxen@gmail.com>
parents:
476
diff
changeset
|
28 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
|
29 for state, state_src in src.iteritems(): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
30 pseudo_path = [json_filename, state] |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
31 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
|
32 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
|
33 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
34 def get_state(self): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
35 return self.states[self.state] |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
36 |
251
432f6997d306
More hooking up of interacting with NPCs.
Simon Cross <hodgestar@gmail.com>
parents:
246
diff
changeset
|
37 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
|
38 self.poke() |
251
432f6997d306
More hooking up of interacting with NPCs.
Simon Cross <hodgestar@gmail.com>
parents:
246
diff
changeset
|
39 return bool(self.states[self.state].text) |
432f6997d306
More hooking up of interacting with NPCs.
Simon Cross <hodgestar@gmail.com>
parents:
246
diff
changeset
|
40 |
302
78220c989e6a
Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents:
291
diff
changeset
|
41 def _switch_dialogue_to(self, npc_name): |
78220c989e6a
Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents:
291
diff
changeset
|
42 """Switch dialogue to another npc.""" |
78220c989e6a
Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents:
291
diff
changeset
|
43 OpenDialog.post(npc_name) |
78220c989e6a
Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents:
291
diff
changeset
|
44 |
490
0eade58a71b9
Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents:
483
diff
changeset
|
45 def _drop_item(self, item, shift=(1, 0)): |
476
1c05b6c2b971
Start of drop item support.
Simon Cross <hodgestar@gmail.com>
parents:
331
diff
changeset
|
46 """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
|
47 to_level = self._me.level |
0eade58a71b9
Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents:
483
diff
changeset
|
48 to_pos = self._me.pos |
0eade58a71b9
Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents:
483
diff
changeset
|
49 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
|
50 gamestate = self.world.gamestate() |
0eade58a71b9
Support item dropping (specifically tails). Have monk drop tail.
Simon Cross <hodgestar@gmail.com>
parents:
483
diff
changeset
|
51 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
|
52 AddSpriteEvent.post(sprite) |
476
1c05b6c2b971
Start of drop item support.
Simon Cross <hodgestar@gmail.com>
parents:
331
diff
changeset
|
53 |
557
e648501c2eea
victory scene hacked in
Adrianna Pińska <adrianna.pinska@gmail.com>
parents:
553
diff
changeset
|
54 def _end_game(self): |
e648501c2eea
victory scene hacked in
Adrianna Pińska <adrianna.pinska@gmail.com>
parents:
553
diff
changeset
|
55 """End the game""" |
e648501c2eea
victory scene hacked in
Adrianna Pińska <adrianna.pinska@gmail.com>
parents:
553
diff
changeset
|
56 from .cutscene import VictoryCutScene |
e648501c2eea
victory scene hacked in
Adrianna Pińska <adrianna.pinska@gmail.com>
parents:
553
diff
changeset
|
57 ChangeScene.post(VictoryCutScene(None, None)) |
e648501c2eea
victory scene hacked in
Adrianna Pińska <adrianna.pinska@gmail.com>
parents:
553
diff
changeset
|
58 |
521
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
59 def _make_locals(self): |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
60 my_locals = { |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
61 "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
|
62 "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
|
63 "npcs": self.world.npcs, |
302
78220c989e6a
Add supporting for flicking between speaking NPCs.
Simon Cross <hodgestar@gmail.com>
parents:
291
diff
changeset
|
64 "switch_to": self._switch_dialogue_to, |
476
1c05b6c2b971
Start of drop item support.
Simon Cross <hodgestar@gmail.com>
parents:
331
diff
changeset
|
65 "drop_item": self._drop_item, |
557
e648501c2eea
victory scene hacked in
Adrianna Pińska <adrianna.pinska@gmail.com>
parents:
553
diff
changeset
|
66 "end_game": self._end_game, |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
67 } |
521
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
68 return my_locals |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
69 |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
70 def choices(self): |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
71 my_locals = self._make_locals() |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
72 state = self.states[self.state] |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
73 return state.choices(my_locals) |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
74 |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
75 def event(self, ev): |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
76 my_locals = self._make_locals() |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
77 my_locals.update(ev.items) |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
78 state = self.states[self.state] |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
79 next_state = state.event(my_locals) |
246
8dee25fd070d
Fix some npc-test and dialogue bugs.
Simon Cross <hodgestar@gmail.com>
parents:
233
diff
changeset
|
80 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
|
81 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
|
82 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
|
83 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
|
84 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
|
85 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
86 def choice(self, i): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
87 self.event(DsmEvent(choice=i)) |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
88 |
285
71f15f6e9274
Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents:
251
diff
changeset
|
89 def auto_next(self): |
71f15f6e9274
Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents:
251
diff
changeset
|
90 self.event(DsmEvent(auto_next=True)) |
71f15f6e9274
Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents:
251
diff
changeset
|
91 |
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
|
92 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
|
93 # 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
|
94 # 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
|
95 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
|
96 |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
97 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
98 class AttrDict(dict): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
99 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
100 def __getattr__(self, name): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
101 if name not in self: |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
102 raise AttributeError("No attribute %r" % (name,)) |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
103 return self[name] |
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 class DsmEvent(object): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
107 |
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
|
108 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
|
109 self.items = { |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
110 "choice": choice, |
285
71f15f6e9274
Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents:
251
diff
changeset
|
111 "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
|
112 "poke": poke, |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
113 } |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
114 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
115 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
116 class DsmState(object): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
117 """State within a DSM. |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
118 """ |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
119 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
120 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
|
121 self.name = name |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
122 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
|
123 self._choices = [] |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
124 self.triggers = [] |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
125 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
126 choices = state_src.get("choices", []) |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
127 for i, choice in enumerate(choices): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
128 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
|
129 if "if" in choice: |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
130 choice_if = compile(choice["if"], |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
131 "<%s>" % ":".join(pseudo_path + ["if"]), |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
132 "eval") |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
133 else: |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
134 choice_if = None |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
135 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
|
136 next_state_code = choice.get("next", None) |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
137 if next_state_code is not None: |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
138 self.triggers.append( |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
139 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
|
140 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
141 events = state_src.get("events", []) |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
142 for i, event in enumerate(events): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
143 pseudo_path = base_path + ["event-%d" % i] |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
144 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
|
145 pseudo_path)) |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
146 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
147 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
|
148 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
|
149 self.auto_next = False |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
150 if auto_next is not None: |
285
71f15f6e9274
Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents:
251
diff
changeset
|
151 self.auto_next = True |
521
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
152 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
|
153 pseudo_path = base_path + ["auto_next"] |
285
71f15f6e9274
Hook up auto_next dialogue events.
Simon Cross <hodgestar@gmail.com>
parents:
251
diff
changeset
|
154 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
|
155 |
216
023eea4ad4a5
Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents:
196
diff
changeset
|
156 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
|
157 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
|
158 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
|
159 "<%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
|
160 "exec") |
233
8ea658969f47
Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents:
217
diff
changeset
|
161 else: |
8ea658969f47
Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents:
217
diff
changeset
|
162 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
|
163 |
023eea4ad4a5
Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents:
196
diff
changeset
|
164 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
|
165 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
|
166 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
|
167 "<%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
|
168 "exec") |
233
8ea658969f47
Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents:
217
diff
changeset
|
169 else: |
8ea658969f47
Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents:
217
diff
changeset
|
170 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
|
171 |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
172 def __repr__(self): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
173 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
|
174 |
521
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
175 def choices(self, my_locals): |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
176 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
|
177 if choice_if is None: |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
178 yield i, text |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
179 elif eval(choice_if, {}, my_locals.copy()): |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
180 yield i, text |
5a8a7f17597d
Add support for 'if': '...' to dialogue choices.
Simon Cross <hodgestar@gmail.com>
parents:
490
diff
changeset
|
181 |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
182 def event(self, my_locals): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
183 for trigger in self.triggers: |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
184 next_state = trigger.fire(my_locals) |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
185 if next_state is not None: |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
186 return next_state |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
187 |
216
023eea4ad4a5
Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents:
196
diff
changeset
|
188 def enter(self, my_locals): |
233
8ea658969f47
Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents:
217
diff
changeset
|
189 if self.on_entry is not None: |
8ea658969f47
Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents:
217
diff
changeset
|
190 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
|
191 |
023eea4ad4a5
Add support for trigger world changes when entering and exiting dialog states.
Simon Cross <hodgestar@gmail.com>
parents:
196
diff
changeset
|
192 def leave(self, my_locals): |
233
8ea658969f47
Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents:
217
diff
changeset
|
193 if self.on_exit is not None: |
8ea658969f47
Fix on_entry and on_exit handling.
Simon Cross <hodgestar@gmail.com>
parents:
217
diff
changeset
|
194 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
|
195 |
153
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
196 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
197 class Trigger(object): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
198 """Matches DSM events and triggers state transitions. |
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 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
201 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
|
202 self._matches = compile(matches_code, |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
203 "<%s>" % ":".join(pseudo_path + ["match"]), |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
204 "eval") |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
205 self._next_state = compile(next_state_code, |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
206 "<%s>" % ":".join(pseudo_path + ["next"]), |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
207 "eval") |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
208 |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
209 def fire(self, my_locals): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
210 if eval(self._matches, {}, my_locals.copy()): |
704d23022f09
Start of dialogue tree / NPC state machine support.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
211 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
|
212 return None |