gamefic 0.6.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/gamefic +3 -0
- data/lib/gamefic/character.rb +42 -6
- data/lib/gamefic/director/parser.rb +25 -25
- data/lib/gamefic/engine/tty.rb +14 -2
- data/lib/gamefic/engine.rb +8 -7
- data/lib/gamefic/grammar/gender.rb +1 -1
- data/lib/gamefic/grammar/pronouns.rb +53 -8
- data/lib/gamefic/grammar/verbs.rb +1 -0
- data/lib/gamefic/grammar/word_adapter.rb +31 -18
- data/lib/gamefic/html.rb +27 -13
- data/lib/gamefic/plot/article_mount.rb +1 -1
- data/lib/gamefic/plot/scene_mount.rb +27 -110
- data/lib/gamefic/{snapshots.rb → plot/snapshot.rb} +60 -29
- data/lib/gamefic/plot/you_mount.rb +1 -1
- data/lib/gamefic/plot.rb +56 -29
- data/lib/gamefic/query/base.rb +3 -1
- data/lib/gamefic/scene/active.rb +11 -18
- data/lib/gamefic/scene/base.rb +21 -0
- data/lib/gamefic/scene/conclusion.rb +11 -0
- data/lib/gamefic/scene/custom.rb +21 -0
- data/lib/gamefic/scene/multiple_choice/input.rb +11 -0
- data/lib/gamefic/scene/multiple_choice.rb +73 -0
- data/lib/gamefic/scene/passive.rb +17 -0
- data/lib/gamefic/scene/pause.rb +24 -0
- data/lib/gamefic/scene/question.rb +21 -0
- data/lib/gamefic/scene/yes_or_no.rb +30 -0
- data/lib/gamefic/scene.rb +10 -120
- data/lib/gamefic/script/base.rb +7 -2
- data/lib/gamefic/script.rb +4 -0
- data/lib/gamefic/shell/command/base.rb +38 -0
- data/lib/gamefic/shell/command/play.rb +51 -0
- data/lib/gamefic/shell/command.rb +4 -0
- data/lib/gamefic/shell/registry.rb +13 -0
- data/lib/gamefic/shell.rb +14 -71
- data/lib/gamefic/source/file.rb +1 -1
- data/lib/gamefic/source.rb +5 -0
- data/lib/gamefic/tester.rb +0 -1
- data/lib/gamefic/version.rb +1 -1
- data/lib/gamefic.rb +1 -6
- metadata +69 -61
- data/lib/gamefic/scene/concluded.rb +0 -22
- data/lib/gamefic/scene/multiplechoice.rb +0 -74
- data/lib/gamefic/scene/paused.rb +0 -26
- data/lib/gamefic/scene/yesorno.rb +0 -43
@@ -4,50 +4,25 @@ end
|
|
4
4
|
module Gamefic
|
5
5
|
|
6
6
|
module Plot::SceneMount
|
7
|
-
# Get a Hash of SceneManager objects.
|
8
|
-
#
|
9
|
-
# @return [Hash<Symbol, SceneManager>]
|
10
|
-
def scene_managers
|
11
|
-
if @scene_managers.nil?
|
12
|
-
@scene_managers ||= {}
|
13
|
-
@scene_managers[:active] = ActiveSceneManager.new
|
14
|
-
@scene_managers[:concluded] = ConcludedSceneManager.new
|
15
|
-
end
|
16
|
-
@scene_managers
|
17
|
-
end
|
18
|
-
|
19
7
|
# Create a multiple-choice scene.
|
20
8
|
# The user will be required to make a valid choice to continue
|
21
9
|
#
|
22
10
|
# @yieldparam [Character]
|
23
|
-
# @yieldparam [
|
24
|
-
def multiple_choice key,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
config.finish(&block)
|
30
|
-
end
|
11
|
+
# @yieldparam [String]
|
12
|
+
def multiple_choice key, options, &block
|
13
|
+
scenes[key] = Scene::MultipleChoice.new(
|
14
|
+
options: options,
|
15
|
+
finish: block
|
16
|
+
)
|
31
17
|
end
|
32
18
|
|
33
19
|
# Create a yes-or-no scene.
|
34
20
|
# The user will be required to answer Yes or No to continue.
|
35
21
|
#
|
36
22
|
# @yieldparam [Character]
|
37
|
-
# @yieldparam [
|
23
|
+
# @yieldparam [String] "yes" or "no"
|
38
24
|
def yes_or_no key, prompt = nil, &block
|
39
|
-
|
40
|
-
config.prompt = prompt
|
41
|
-
config.finish do |actor, data|
|
42
|
-
if data.answer.nil?
|
43
|
-
actor.tell "Please answer Yes or No."
|
44
|
-
else
|
45
|
-
data.next_cue ||= :active
|
46
|
-
block.call(actor, data)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
scene_managers[key] = manager
|
25
|
+
scenes[key] = Scene::YesOrNo.new(prompt, &block)
|
51
26
|
end
|
52
27
|
|
53
28
|
# Create a scene with a prompt.
|
@@ -55,18 +30,11 @@ module Gamefic
|
|
55
30
|
# from the user.
|
56
31
|
#
|
57
32
|
# @param key [Symbol] A unique name for the scene.
|
58
|
-
# @param prompt [String] The prompt
|
33
|
+
# @param prompt [String] The input prompt to display to the user.
|
59
34
|
# @yieldparam [Character]
|
60
|
-
# @yieldparam [
|
61
|
-
def
|
62
|
-
|
63
|
-
config.prompt = prompt
|
64
|
-
config.finish do |actor, data|
|
65
|
-
data.next_cue ||= :active
|
66
|
-
block.call actor, data
|
67
|
-
end
|
68
|
-
end
|
69
|
-
scene_managers[key].state = "Prompted"
|
35
|
+
# @yieldparam [String]
|
36
|
+
def question key, prompt, &block
|
37
|
+
scenes[key] = Scene::Question.new prompt, &block
|
70
38
|
end
|
71
39
|
|
72
40
|
# Create a scene that pauses the game.
|
@@ -75,15 +43,8 @@ module Gamefic
|
|
75
43
|
#
|
76
44
|
# @param key [Symbol] A unique name for the scene.
|
77
45
|
# @yieldparam [Character]
|
78
|
-
# @yieldparam [SceneData]
|
79
46
|
def pause key, &block
|
80
|
-
|
81
|
-
config.start do |actor, data|
|
82
|
-
data.next_cue = :active
|
83
|
-
block.call actor, data
|
84
|
-
end
|
85
|
-
end
|
86
|
-
scene_managers[key] = manager
|
47
|
+
scenes[key] = Scene::Pause.new &block
|
87
48
|
end
|
88
49
|
|
89
50
|
# Create a conclusion.
|
@@ -91,32 +52,18 @@ module Gamefic
|
|
91
52
|
#
|
92
53
|
# @param key [Symbol] A unique name for the scene.
|
93
54
|
# @yieldparam [Character]
|
94
|
-
# @yieldparam [SceneData]
|
95
55
|
def conclusion key, &block
|
96
|
-
|
97
|
-
config.start(&block)
|
98
|
-
end
|
99
|
-
scene_managers[key] = manager
|
56
|
+
scenes[key] = Scene::Conclusion.new &block
|
100
57
|
end
|
101
58
|
|
102
59
|
# Create a generic scene.
|
103
|
-
# After the scene is complete, it will automatically start the next
|
60
|
+
# After the scene is complete, it will automatically start the next
|
61
|
+
# prepared scene, or the :active scene if none is prepared.
|
104
62
|
#
|
105
63
|
# @param [Symbol] A unique name for the scene.
|
106
64
|
# @yieldparam [Character]
|
107
|
-
# @yieldparam [SceneData]
|
108
65
|
def scene key, &block
|
109
|
-
|
110
|
-
manager.start do |actor, data|
|
111
|
-
data.next_cue = :active
|
112
|
-
block.call(actor, data) if !block.nil?
|
113
|
-
cue actor, data.next_cue
|
114
|
-
actor.scene.start actor
|
115
|
-
end
|
116
|
-
# Since generic scenes always cue a new scene, there's no reason to
|
117
|
-
# define a finish block.
|
118
|
-
end
|
119
|
-
scene_managers[key] = scene
|
66
|
+
scenes[key] = Scene::Passive.new &block
|
120
67
|
end
|
121
68
|
|
122
69
|
# Branch to a new scene based on a list of options.
|
@@ -132,50 +79,20 @@ module Gamefic
|
|
132
79
|
# actor.tell "You went to scene two"
|
133
80
|
# end
|
134
81
|
# introduction do |actor|
|
135
|
-
# cue
|
82
|
+
# actor.cue, :select_one_or_two # The actor will be prompted to select "one" or "two" and get sent to the corresponding scene
|
136
83
|
# end
|
137
84
|
#
|
138
85
|
# @param key [Symbol] A unique name for the scene.
|
139
|
-
# @param
|
140
|
-
def branch key,
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
#
|
148
|
-
# @param actor [Character] The character being cued
|
149
|
-
# @param key [Symbol] The name of the scene
|
150
|
-
def cue actor, key
|
151
|
-
if !actor.scene.nil? and actor.scene.state == "Concluded"
|
152
|
-
return
|
153
|
-
end
|
154
|
-
if key.nil?
|
155
|
-
raise "Cueing scene with nil key"
|
156
|
-
end
|
157
|
-
manager = scene_managers[key]
|
158
|
-
if manager.nil?
|
159
|
-
raise "No '#{key}' scene found"
|
160
|
-
else
|
161
|
-
actor.scene = manager.prepare key
|
162
|
-
end
|
163
|
-
@scene
|
164
|
-
end
|
165
|
-
|
166
|
-
# This is functionally identical to #cue, but it also raises an
|
167
|
-
# exception if the selected scene is not a Concluded state.
|
168
|
-
#
|
169
|
-
# @param actor [Character] The character being cued
|
170
|
-
# @param key [Symbol] The name of the scene
|
171
|
-
def conclude actor, key
|
172
|
-
key = :concluded if key.nil?
|
173
|
-
manager = scene_managers[key]
|
174
|
-
if manager.state != "Concluded"
|
175
|
-
raise NotConclusionError("Cued scene '#{key}' is not a conclusion")
|
176
|
-
end
|
177
|
-
cue actor, key
|
86
|
+
# @param map [Hash] A Hash of options and associated scene keys.
|
87
|
+
def branch key, map
|
88
|
+
scenes[key] = Scene::MultipleChoice.new(
|
89
|
+
options: map.keys,
|
90
|
+
finish: proc { |actor, input|
|
91
|
+
actor.cue map[input.choice]
|
92
|
+
}
|
93
|
+
)
|
178
94
|
end
|
95
|
+
|
179
96
|
end
|
180
97
|
|
181
98
|
end
|
@@ -1,13 +1,8 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
3
|
module Gamefic
|
4
|
-
|
5
|
-
|
6
|
-
def initialize entities
|
7
|
-
@history = []
|
8
|
-
@entities = entities
|
9
|
-
end
|
10
|
-
def save entities
|
4
|
+
module Plot::Snapshot
|
5
|
+
def save
|
11
6
|
store = []
|
12
7
|
index = 0
|
13
8
|
entities.each { |e|
|
@@ -19,11 +14,11 @@ module Gamefic
|
|
19
14
|
end
|
20
15
|
if e.respond_to?(m) == true
|
21
16
|
begin
|
22
|
-
|
23
|
-
if
|
17
|
+
val = e.send(m)
|
18
|
+
if val == false
|
24
19
|
hash[con] = false
|
25
|
-
elsif
|
26
|
-
hash[con] = serialize_obj(
|
20
|
+
elsif val
|
21
|
+
hash[con] = serialize_obj(val)
|
27
22
|
else
|
28
23
|
hash[con] = nil
|
29
24
|
end
|
@@ -32,6 +27,7 @@ module Gamefic
|
|
32
27
|
end
|
33
28
|
end
|
34
29
|
}
|
30
|
+
hash[:class] = e.class.to_s
|
35
31
|
hash[:session] = {}
|
36
32
|
e.session.each_pair { |k, v|
|
37
33
|
hash[:session][k] = serialize_obj(v)
|
@@ -39,29 +35,68 @@ module Gamefic
|
|
39
35
|
store.push hash
|
40
36
|
index += 1
|
41
37
|
}
|
42
|
-
if @
|
43
|
-
@
|
38
|
+
if @initial_state.nil?
|
39
|
+
@initial_state = store
|
40
|
+
store = []
|
41
|
+
@initial_state.length.times do
|
42
|
+
store.push {}
|
43
|
+
end
|
44
|
+
else
|
45
|
+
store = reduce(store)
|
44
46
|
end
|
45
|
-
|
46
|
-
#puts json
|
47
|
-
json
|
47
|
+
store
|
48
48
|
end
|
49
49
|
def restore snapshot
|
50
|
-
|
50
|
+
internal_restore snapshot, true
|
51
|
+
end
|
52
|
+
private
|
53
|
+
def internal_restore snapshot, with_restore = true
|
54
|
+
if with_restore
|
55
|
+
@entities[@initial_state.length..-1].each { |e|
|
56
|
+
e.parent = nil
|
57
|
+
}
|
58
|
+
@entities.slice! @initial_state.length..-1
|
59
|
+
internal_restore @initial_state, false
|
60
|
+
end
|
51
61
|
index = 0
|
52
|
-
|
62
|
+
snapshot.each { |hash|
|
63
|
+
if entities[index].nil?
|
64
|
+
if with_restore
|
65
|
+
cls = Kernel.const_get(hash[:class])
|
66
|
+
entities[index] = make cls
|
67
|
+
else
|
68
|
+
break
|
69
|
+
end
|
70
|
+
end
|
53
71
|
hash.each_pair { |k, v|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
72
|
+
if k == :scene
|
73
|
+
entities[index].cue v.to_sym
|
74
|
+
else
|
75
|
+
entities[index].send("#{k}=", unserialize(v)) if k != :session and k != :class
|
76
|
+
end
|
59
77
|
}
|
78
|
+
unless hash[:session].nil?
|
79
|
+
hash[:session].each_pair { |k, v|
|
80
|
+
entities[index].session[k.to_sym] = unserialize(v)
|
81
|
+
}
|
82
|
+
end
|
60
83
|
index += 1
|
61
84
|
}
|
62
85
|
end
|
63
|
-
def
|
64
|
-
|
86
|
+
def reduce entities
|
87
|
+
reduced = []
|
88
|
+
index = 0
|
89
|
+
entities.each { |e|
|
90
|
+
r = {}
|
91
|
+
e.each_pair { |k, v|
|
92
|
+
if index >= @initial_state.length or @initial_state[index][k] != v
|
93
|
+
r[k] = v
|
94
|
+
end
|
95
|
+
}
|
96
|
+
reduced.push r
|
97
|
+
index += 1
|
98
|
+
}
|
99
|
+
reduced
|
65
100
|
end
|
66
101
|
private
|
67
102
|
def can_serialize? obj
|
@@ -98,8 +133,6 @@ module Gamefic
|
|
98
133
|
return "#<EIN_#{@entities.index(obj)}>"
|
99
134
|
elsif obj.kind_of?(Direction)
|
100
135
|
return "#<DIR_#{obj.name}>"
|
101
|
-
#elsif obj.kind_of?(Symbol)
|
102
|
-
# return "#<SYM_#{obj.to_s}>"
|
103
136
|
end
|
104
137
|
end
|
105
138
|
return obj
|
@@ -123,8 +156,6 @@ module Gamefic
|
|
123
156
|
@entities[i]
|
124
157
|
elsif obj.to_s.match(/^#<DIR_[a-z]+>$/)
|
125
158
|
Direction.find(obj[6..-2])
|
126
|
-
#elsif obj.to_s.match(/^#<SYM_[a-z]+>$/)
|
127
|
-
# Direction.find(obj[6..-2].to_sym)
|
128
159
|
else
|
129
160
|
obj
|
130
161
|
end
|
data/lib/gamefic/plot.rb
CHANGED
@@ -5,8 +5,6 @@ require 'gamefic/tester'
|
|
5
5
|
require 'gamefic/source'
|
6
6
|
require 'gamefic/script'
|
7
7
|
require 'gamefic/query'
|
8
|
-
require 'gamefic/plot/article_mount'
|
9
|
-
require 'gamefic/plot/you_mount'
|
10
8
|
|
11
9
|
module Gamefic
|
12
10
|
|
@@ -15,35 +13,52 @@ module Gamefic
|
|
15
13
|
autoload :CommandMount, 'gamefic/plot/command_mount'
|
16
14
|
autoload :EntityMount, 'gamefic/plot/entity_mount'
|
17
15
|
autoload :QueryMount, 'gamefic/plot/query_mount'
|
18
|
-
|
19
|
-
|
16
|
+
autoload :ArticleMount, 'gamefic/plot/article_mount'
|
17
|
+
autoload :YouMount, 'gamefic/plot/you_mount'
|
18
|
+
autoload :Snapshot, 'gamefic/plot/snapshot'
|
19
|
+
|
20
20
|
attr_reader :commands, :imported_scripts, :rules, :asserts, :source
|
21
|
-
|
21
|
+
# TODO Metadata could use better protection
|
22
|
+
attr_accessor :default_scene, :metadata
|
22
23
|
include Stage
|
23
24
|
# TODO This include is only here to make the module's methods visible in the IDE.
|
24
25
|
# Gamefic Studio has a PlotStageMetaMapper that handles it, but it doesn't run if
|
25
26
|
# the plugin isn't activated.
|
26
|
-
include Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount, ArticleMount, YouMount
|
27
|
-
mount Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount, ArticleMount, YouMount
|
28
|
-
expose :script, :introduction, :assert_action, :on_update, :on_player_update, :entities, :on_ready, :on_player_ready, :players
|
27
|
+
#include Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount, ArticleMount, YouMount, Snapshot
|
28
|
+
mount Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount, ArticleMount, YouMount, Snapshot
|
29
|
+
expose :script, :introduction, :assert_action, :before_player_update, :on_update, :on_player_update, :entities, :on_ready, :on_player_ready, :players, :scenes, :metadata
|
29
30
|
|
30
31
|
# @param [Source::Base]
|
31
32
|
def initialize(source = nil)
|
32
33
|
@source = source || Source::Text.new({})
|
33
|
-
@commands =
|
34
|
-
@syntaxes =
|
35
|
-
@ready_procs =
|
36
|
-
@
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
34
|
+
@commands = {}
|
35
|
+
@syntaxes = []
|
36
|
+
@ready_procs = []
|
37
|
+
@before_player_update_procs = []
|
38
|
+
@update_procs = []
|
39
|
+
@player_ready = []
|
40
|
+
@player_procs = []
|
41
|
+
@working_scripts = []
|
42
|
+
@imported_scripts = []
|
43
|
+
@entities = []
|
44
|
+
@players = []
|
45
|
+
@asserts = {}
|
44
46
|
@default_scene = :active
|
45
47
|
post_initialize
|
46
48
|
end
|
49
|
+
|
50
|
+
def scenes
|
51
|
+
if @scenes.nil?
|
52
|
+
@scenes = {}
|
53
|
+
@scenes[:active] = Scene::Active.new
|
54
|
+
@scenes[:concluded] = Scene::Conclusion.new
|
55
|
+
end
|
56
|
+
@scenes
|
57
|
+
end
|
58
|
+
|
59
|
+
def concluded?(actor)
|
60
|
+
scenes[actor.scene].kind_of?(Scene::Conclusion)
|
61
|
+
end
|
47
62
|
|
48
63
|
# Get an Array of all Actions defined in the Plot.
|
49
64
|
#
|
@@ -158,7 +173,7 @@ module Gamefic
|
|
158
173
|
# by the plot, which would be :active by default. We could
|
159
174
|
# get it like player.cue nil.
|
160
175
|
if player.scene.nil?
|
161
|
-
cue
|
176
|
+
player.cue :active
|
162
177
|
ready
|
163
178
|
update
|
164
179
|
end
|
@@ -175,7 +190,6 @@ module Gamefic
|
|
175
190
|
@player_ready.each { |block|
|
176
191
|
block.call player
|
177
192
|
}
|
178
|
-
player.scene.start player
|
179
193
|
}
|
180
194
|
end
|
181
195
|
|
@@ -184,14 +198,24 @@ module Gamefic
|
|
184
198
|
def update
|
185
199
|
# Update the plot.
|
186
200
|
@players.each { |player|
|
187
|
-
|
201
|
+
# TODO: This really doesn't belong here. We need a before_update in the plot.
|
202
|
+
@before_player_update_procs.each { |p|
|
203
|
+
p.call player
|
204
|
+
}
|
205
|
+
this_scene = player.next_scene || player.scene
|
206
|
+
player.prepare nil
|
207
|
+
if this_scene != player.scene
|
208
|
+
player.cue this_scene
|
209
|
+
player.queue.shift
|
210
|
+
else
|
211
|
+
process_input player
|
212
|
+
end
|
188
213
|
}
|
189
214
|
@entities.each { |e|
|
190
215
|
e.update
|
191
216
|
}
|
192
217
|
@players.each { |player|
|
193
218
|
update_player player
|
194
|
-
cue player, player.scene.data.next_cue if !player.scene.data.next_cue.nil?
|
195
219
|
}
|
196
220
|
@update_procs.each { |p|
|
197
221
|
p.call
|
@@ -242,22 +266,25 @@ module Gamefic
|
|
242
266
|
@player_procs.push block
|
243
267
|
end
|
244
268
|
|
269
|
+
# Add a block to be executed for each player before the turn's update is
|
270
|
+
# performed.
|
271
|
+
#
|
272
|
+
# @yieldparam [Character]
|
273
|
+
def before_player_update &block
|
274
|
+
@before_player_update_procs.push block
|
275
|
+
end
|
276
|
+
|
245
277
|
private
|
246
278
|
def process_input player
|
247
279
|
line = player.queue.shift
|
248
280
|
if !line.nil?
|
249
|
-
player.scene.finish player, line
|
250
|
-
#cue player, player.scene.data.next_cue if !player.scene.data.next_cue.nil?
|
281
|
+
scenes[player.scene].finish player, line
|
251
282
|
end
|
252
283
|
end
|
253
284
|
def update_player player
|
254
285
|
@player_procs.each { |proc|
|
255
286
|
proc.call player
|
256
287
|
}
|
257
|
-
# HACK Exception for running tests
|
258
|
-
if player[:testing] == true
|
259
|
-
cue player, :test
|
260
|
-
end
|
261
288
|
end
|
262
289
|
def rem_entity(entity)
|
263
290
|
@entities.delete(entity)
|
data/lib/gamefic/query/base.rb
CHANGED
@@ -16,6 +16,8 @@ module Gamefic::Query
|
|
16
16
|
@arguments = arguments
|
17
17
|
@match_hash = Hash.new
|
18
18
|
end
|
19
|
+
# Check whether the query allows ambiguous matches.
|
20
|
+
# If allowed, this query's
|
19
21
|
def allow_ambiguous?
|
20
22
|
false
|
21
23
|
end
|
@@ -110,7 +112,7 @@ module Gamefic::Query
|
|
110
112
|
arguments.each { |a|
|
111
113
|
if a.kind_of?(Class) or a.kind_of?(Module)
|
112
114
|
my_classes.push a
|
113
|
-
elsif a.kind_of?(Entity)
|
115
|
+
elsif a.kind_of?(Gamefic::Entity)
|
114
116
|
my_objects.push a
|
115
117
|
elsif a.kind_of?(Symbol)
|
116
118
|
if my_classes.length == 0 and my_objects.length == 0
|
data/lib/gamefic/scene/active.rb
CHANGED
@@ -1,25 +1,18 @@
|
|
1
1
|
module Gamefic
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
# Active Scenes handle the default command prompt, where input is parsed
|
4
|
+
# into an Action performed by the Character. This is the default scene in
|
5
|
+
# a Plot.
|
6
|
+
#
|
7
|
+
class Scene::Active < Scene::Base
|
8
|
+
def start actor
|
9
|
+
# TODO Anything necessary here?
|
6
10
|
end
|
7
|
-
def state
|
8
|
-
@state ||= "Active"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class ActiveScene < Scene
|
13
11
|
def finish actor, input
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# HACK Set the last_order here so inline performs don't set it
|
18
|
-
actor.send(:last_order=, last_order)
|
19
|
-
else
|
20
|
-
@finish.call actor, data
|
21
|
-
end
|
12
|
+
last_order = actor.perform input
|
13
|
+
# HACK Set the last_order here so inline performs don't set it
|
14
|
+
actor.send(:last_order=, last_order)
|
22
15
|
end
|
23
16
|
end
|
24
|
-
|
17
|
+
|
25
18
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Gamefic::Scene
|
2
|
+
|
3
|
+
# The Base Scene is not intended for instantiation. Other Scene classes
|
4
|
+
# should inherit from it.
|
5
|
+
#
|
6
|
+
class Base
|
7
|
+
def prompt
|
8
|
+
@prompt ||= '>'
|
9
|
+
end
|
10
|
+
def start actor
|
11
|
+
|
12
|
+
end
|
13
|
+
def finish actor, input
|
14
|
+
|
15
|
+
end
|
16
|
+
def state
|
17
|
+
self.class.to_s.split('::').last
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Gamefic
|
2
|
+
|
3
|
+
# A Custom Scene is a generic scene that allows for complete configuration
|
4
|
+
# of its behavior upon instantiation. It is suitable for direct instantion
|
5
|
+
# or extension by other Scene classes.
|
6
|
+
#
|
7
|
+
class Scene::Custom < Scene::Base
|
8
|
+
def initialize config = {}
|
9
|
+
@start = config[:start]
|
10
|
+
@finish = config[:finish]
|
11
|
+
@prompt = config[:prompt]
|
12
|
+
end
|
13
|
+
def start actor
|
14
|
+
@start.call(actor) unless @start.nil?
|
15
|
+
end
|
16
|
+
def finish actor, input
|
17
|
+
@finish.call(actor, input) unless @finish.nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|