gamefic 2.4.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rspec.yml +41 -40
- data/.rspec-opal +2 -0
- data/.solargraph.yml +20 -3
- data/CHANGELOG.md +18 -0
- data/Rakefile +11 -1
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/gamefic.gemspec +5 -2
- data/lib/gamefic/action.rb +58 -181
- data/lib/gamefic/active/cue.rb +25 -0
- data/lib/gamefic/active/epic.rb +73 -0
- data/lib/gamefic/active/messaging.rb +43 -0
- data/lib/gamefic/active/take.rb +69 -0
- data/lib/gamefic/active.rb +111 -191
- data/lib/gamefic/actor.rb +2 -0
- data/lib/gamefic/block.rb +28 -0
- data/lib/gamefic/command.rb +6 -7
- data/lib/gamefic/composer.rb +68 -0
- data/lib/gamefic/core_ext/array.rb +4 -4
- data/lib/gamefic/core_ext/string.rb +10 -5
- data/lib/gamefic/describable.rb +39 -65
- data/lib/gamefic/dispatcher.rb +79 -41
- data/lib/gamefic/entity.rb +42 -19
- data/lib/gamefic/expression.rb +31 -0
- data/lib/gamefic/logging.rb +32 -0
- data/lib/gamefic/messenger.rb +66 -0
- data/lib/gamefic/narrative.rb +104 -0
- data/lib/gamefic/node.rb +44 -53
- data/lib/gamefic/plot.rb +60 -93
- data/lib/gamefic/props/default.rb +49 -0
- data/lib/gamefic/props/multiple_choice.rb +65 -0
- data/lib/gamefic/props/output.rb +82 -0
- data/lib/gamefic/props/pause.rb +11 -0
- data/lib/gamefic/props/yes_or_no.rb +21 -0
- data/lib/gamefic/props.rb +11 -0
- data/lib/gamefic/query/base.rb +64 -121
- data/lib/gamefic/query/general.rb +50 -0
- data/lib/gamefic/query/result.rb +20 -0
- data/lib/gamefic/query/scoped.rb +46 -0
- data/lib/gamefic/query/text.rb +43 -33
- data/lib/gamefic/query.rb +7 -15
- data/lib/gamefic/response.rb +112 -0
- data/lib/gamefic/rulebook/calls.rb +90 -0
- data/lib/gamefic/rulebook/events.rb +79 -0
- data/lib/gamefic/rulebook/hooks.rb +57 -0
- data/lib/gamefic/rulebook/scenes.rb +68 -0
- data/lib/gamefic/rulebook.rb +139 -0
- data/lib/gamefic/scanner.rb +130 -0
- data/lib/gamefic/scene/activity.rb +9 -17
- data/lib/gamefic/scene/conclusion.rb +6 -5
- data/lib/gamefic/scene/default.rb +88 -0
- data/lib/gamefic/scene/multiple_choice.rb +14 -69
- data/lib/gamefic/scene/pause.rb +9 -13
- data/lib/gamefic/scene/yes_or_no.rb +6 -46
- data/lib/gamefic/scene.rb +11 -7
- data/lib/gamefic/scope/base.rb +44 -0
- data/lib/gamefic/scope/children.rb +16 -0
- data/lib/gamefic/scope/family.rb +20 -0
- data/lib/gamefic/scope/myself.rb +13 -0
- data/lib/gamefic/scope/parent.rb +13 -0
- data/lib/gamefic/scope/siblings.rb +14 -0
- data/lib/gamefic/scope.rb +8 -0
- data/lib/gamefic/scriptable/actions.rb +156 -0
- data/lib/gamefic/scriptable/entities.rb +79 -0
- data/lib/gamefic/scriptable/events.rb +65 -0
- data/lib/gamefic/scriptable/proxy.rb +66 -0
- data/lib/gamefic/scriptable/queries.rb +73 -0
- data/lib/gamefic/scriptable/scenes.rb +162 -0
- data/lib/gamefic/scriptable.rb +167 -73
- data/lib/gamefic/snapshot.rb +44 -0
- data/lib/gamefic/stage.rb +51 -0
- data/lib/gamefic/subplot.rb +51 -79
- data/lib/gamefic/syntax/template.rb +67 -0
- data/lib/gamefic/syntax.rb +102 -83
- data/lib/gamefic/vault.rb +50 -0
- data/lib/gamefic/version.rb +1 -1
- data/lib/gamefic.rb +28 -15
- data/spec-opal/spec_helper.rb +24 -0
- metadata +94 -29
- data/lib/gamefic/element.rb +0 -46
- data/lib/gamefic/keywords.rb +0 -52
- data/lib/gamefic/messaging.rb +0 -43
- data/lib/gamefic/plot/darkroom.rb +0 -120
- data/lib/gamefic/plot/host.rb +0 -42
- data/lib/gamefic/plot/snapshot.rb +0 -27
- data/lib/gamefic/query/children.rb +0 -9
- data/lib/gamefic/query/descendants.rb +0 -15
- data/lib/gamefic/query/external.rb +0 -39
- data/lib/gamefic/query/family.rb +0 -18
- data/lib/gamefic/query/itself.rb +0 -13
- data/lib/gamefic/query/matches.rb +0 -75
- data/lib/gamefic/query/parent.rb +0 -9
- data/lib/gamefic/query/siblings.rb +0 -13
- data/lib/gamefic/query/tree.rb +0 -17
- data/lib/gamefic/scene/base.rb +0 -142
- data/lib/gamefic/scene/multiple_scene.rb +0 -29
- data/lib/gamefic/serialize.rb +0 -196
- data/lib/gamefic/world/callbacks.rb +0 -135
- data/lib/gamefic/world/commands.rb +0 -181
- data/lib/gamefic/world/entities.rb +0 -98
- data/lib/gamefic/world/playbook.rb +0 -233
- data/lib/gamefic/world/players.rb +0 -37
- data/lib/gamefic/world/scenes.rb +0 -228
- data/lib/gamefic/world.rb +0 -18
@@ -1,233 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
|
-
module Gamefic
|
4
|
-
module World
|
5
|
-
# A collection of rules for performing commands.
|
6
|
-
#
|
7
|
-
class Playbook
|
8
|
-
ActionHook = Struct.new(:verb, :block)
|
9
|
-
|
10
|
-
# An array of available syntaxes.
|
11
|
-
#
|
12
|
-
# @return [Array<Gamefic::Syntax>]
|
13
|
-
attr_reader :syntaxes
|
14
|
-
|
15
|
-
# An array of blocks to execute before actions.
|
16
|
-
#
|
17
|
-
# @return [Array<Proc>]
|
18
|
-
attr_reader :before_actions
|
19
|
-
|
20
|
-
# An array of blocks to execute after actions.
|
21
|
-
#
|
22
|
-
# @return [Array<Proc>]
|
23
|
-
attr_reader :after_actions
|
24
|
-
|
25
|
-
# @param commands [Hash]
|
26
|
-
# @param syntaxes [Array<Syntax>, Set<Syntax>]
|
27
|
-
# @param before_actions [Array]
|
28
|
-
# @param after_actions [Array]
|
29
|
-
def initialize commands: {}, syntaxes: [], before_actions: [], after_actions: []
|
30
|
-
@commands = commands
|
31
|
-
@syntax_set = syntaxes.to_set
|
32
|
-
sort_syntaxes
|
33
|
-
@before_actions = before_actions
|
34
|
-
@after_actions = after_actions
|
35
|
-
end
|
36
|
-
|
37
|
-
# An array of available actions.
|
38
|
-
#
|
39
|
-
# @return [Array<Gamefic::Action>]
|
40
|
-
def actions
|
41
|
-
@commands.values.flatten
|
42
|
-
end
|
43
|
-
|
44
|
-
# An array of recognized verbs.
|
45
|
-
#
|
46
|
-
# @return [Array<Symbol>]
|
47
|
-
def verbs
|
48
|
-
@commands.keys
|
49
|
-
end
|
50
|
-
|
51
|
-
# Add a proc to be evaluated before a character executes an action.
|
52
|
-
# When a verb is specified, the proc will only be evaluated if the
|
53
|
-
# action's verb matches it.
|
54
|
-
#
|
55
|
-
# @param verb [Symbol, nil]
|
56
|
-
# @yieldparam [Gamefic::Action]
|
57
|
-
def before_action verb = nil, &block
|
58
|
-
@before_actions.push ActionHook.new(verb, block)
|
59
|
-
end
|
60
|
-
alias validate before_action
|
61
|
-
|
62
|
-
# Add a proc to be evaluated after a character executes an action.
|
63
|
-
# When a verb is specified, the proc will only be evaluated if the
|
64
|
-
# action's verb matches it.
|
65
|
-
#
|
66
|
-
# @param verb [Symbol, nil]
|
67
|
-
# @yieldparam [Gamefic::Action]
|
68
|
-
def after_action verb = nil, &block
|
69
|
-
@after_actions.push ActionHook.new(verb, block)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Get an Array of all Actions associated with the specified verb.
|
73
|
-
#
|
74
|
-
# @param verb [Symbol] The Symbol for the verb (e.g., :go or :look)
|
75
|
-
# @return [Array<Class<Action>>] The verb's associated Actions
|
76
|
-
def actions_for verb
|
77
|
-
@commands[verb] || []
|
78
|
-
end
|
79
|
-
|
80
|
-
# Create an Action that responds to a command.
|
81
|
-
# An Action uses the command argument to identify the imperative verb that
|
82
|
-
# triggers the action.
|
83
|
-
# It can also accept queries to tokenize the remainder of the input and
|
84
|
-
# filter for particular entities or properties.
|
85
|
-
# The block argument contains the code to be executed when the input
|
86
|
-
# matches all of the Action's criteria (i.e., verb and queries).
|
87
|
-
#
|
88
|
-
# @example A simple Action.
|
89
|
-
# respond :salute do |actor|
|
90
|
-
# actor.tell "Hello, sir!"
|
91
|
-
# end
|
92
|
-
# # The command "salute" will respond "Hello, sir!"
|
93
|
-
#
|
94
|
-
# @example An Action that accepts a Character
|
95
|
-
# respond :salute, Use.visible(Character) do |actor, character|
|
96
|
-
# actor.tell "#{The character} returns your salute."
|
97
|
-
# end
|
98
|
-
#
|
99
|
-
# @param verb [Symbol] An imperative verb for the command
|
100
|
-
# @param queries [Array<Query::Base>] Filters for the command's tokens
|
101
|
-
# @yieldparam [Gamefic::Actor]
|
102
|
-
# @return [Class<Gamefic::Action>]
|
103
|
-
def respond(verb, *queries, &proc)
|
104
|
-
act = Action.subclass verb, *queries, &proc
|
105
|
-
add_action act
|
106
|
-
act
|
107
|
-
end
|
108
|
-
|
109
|
-
# Create a Meta Action that responds to a command.
|
110
|
-
# Meta Actions are very similar to standard Actions, except the Plot
|
111
|
-
# understands them to be commands that operate above and/or outside of the
|
112
|
-
# actual game world. Examples of Meta Actions are commands that report the
|
113
|
-
# player's current score, save and restore saved games, or list the game's
|
114
|
-
# credits.
|
115
|
-
#
|
116
|
-
# @example A simple Meta Action
|
117
|
-
# meta :credits do |actor|
|
118
|
-
# actor.tell "This game was written by John Smith."
|
119
|
-
# end
|
120
|
-
#
|
121
|
-
# @param verb [Symbol] An imperative verb for the command
|
122
|
-
# @param queries [Array<Query::Base>] Filters for the command's tokens
|
123
|
-
# @yieldparam [Gamefic::Actor]
|
124
|
-
# @return [Class<Gamefic::Action>]
|
125
|
-
def meta(verb, *queries, &proc)
|
126
|
-
act = Action.subclass verb, *queries, meta: true, &proc
|
127
|
-
add_action act
|
128
|
-
act
|
129
|
-
end
|
130
|
-
|
131
|
-
# Create an alternate Syntax for an Action.
|
132
|
-
# The command and its translation can be parameterized.
|
133
|
-
#
|
134
|
-
# @example Create a synonym for the Inventory Action.
|
135
|
-
# interpret "catalogue", "inventory"
|
136
|
-
# # The command "catalogue" will be translated to "inventory"
|
137
|
-
#
|
138
|
-
# @example Create a parameterized synonym for the Look Action.
|
139
|
-
# interpret "scrutinize :entity", "look :entity"
|
140
|
-
# # The command "scrutinize chair" will be translated to "look chair"
|
141
|
-
#
|
142
|
-
# @param input [String] The format of the original command
|
143
|
-
# @param translation [String] The format of the translated command
|
144
|
-
# @return [Syntax] the Syntax object
|
145
|
-
def interpret(input, translation)
|
146
|
-
syn = Syntax.new(input, translation)
|
147
|
-
add_syntax syn
|
148
|
-
syn
|
149
|
-
end
|
150
|
-
|
151
|
-
# Get a Dispatcher to select actions that can potentially be executed
|
152
|
-
# from the specified command string.
|
153
|
-
#
|
154
|
-
# @param actor [Actor]
|
155
|
-
# @param text [String]
|
156
|
-
# @return [Dispatcher]
|
157
|
-
def dispatch(actor, text)
|
158
|
-
commands = Syntax.tokenize(text, actor.syntaxes)
|
159
|
-
actions = commands.flat_map { |cmd| actions_for(cmd.verb).reject(&:hidden?) }
|
160
|
-
Dispatcher.new(actor, commands, sort_and_reduce_actions(actions))
|
161
|
-
end
|
162
|
-
|
163
|
-
# Get an array of actions, derived from the specified verb and params,
|
164
|
-
# that the actor can potentially execute.
|
165
|
-
#
|
166
|
-
# @return [Array<Gamefic::Action>]
|
167
|
-
def dispatch_from_params actor, verb, params
|
168
|
-
available = actions_for(verb)
|
169
|
-
Dispatcher.new(actor, [Command.new(verb, params)], sort_and_reduce_actions(available))
|
170
|
-
end
|
171
|
-
|
172
|
-
# Duplicate the playbook.
|
173
|
-
# This method will duplicate the commands hash and the syntax array so
|
174
|
-
# the new playbook can be modified without affecting the original.
|
175
|
-
#
|
176
|
-
# @return [Playbook]
|
177
|
-
def dup
|
178
|
-
Playbook.new commands: @commands.dup, syntaxes: @syntaxes.dup
|
179
|
-
end
|
180
|
-
|
181
|
-
def freeze
|
182
|
-
@commands.freeze
|
183
|
-
@syntaxes.freeze
|
184
|
-
end
|
185
|
-
|
186
|
-
private
|
187
|
-
|
188
|
-
def add_action(action)
|
189
|
-
@commands[action.verb] ||= []
|
190
|
-
@commands[action.verb].push action
|
191
|
-
generate_default_syntax action
|
192
|
-
end
|
193
|
-
|
194
|
-
def generate_default_syntax action
|
195
|
-
user_friendly = action.verb.to_s.gsub(/_/, ' ')
|
196
|
-
args = []
|
197
|
-
used_names = []
|
198
|
-
action.queries.each do |_c|
|
199
|
-
num = 1
|
200
|
-
new_name = ":var"
|
201
|
-
while used_names.include? new_name
|
202
|
-
num += 1
|
203
|
-
new_name = ":var#{num}"
|
204
|
-
end
|
205
|
-
used_names.push new_name
|
206
|
-
user_friendly += " #{new_name}"
|
207
|
-
args.push new_name
|
208
|
-
end
|
209
|
-
add_syntax Syntax.new(user_friendly.strip, "#{action.verb} #{args.join(' ')}") unless action.verb.to_s.start_with?('_')
|
210
|
-
end
|
211
|
-
|
212
|
-
def add_syntax syntax
|
213
|
-
raise "No actions exist for \"#{syntax.verb}\"" if @commands[syntax.verb].nil?
|
214
|
-
sort_syntaxes if @syntax_set.add?(syntax)
|
215
|
-
end
|
216
|
-
|
217
|
-
def sort_and_reduce_actions arr
|
218
|
-
arr.sort_by.with_index { |a, i| [a.rank, i] }.reverse.uniq
|
219
|
-
end
|
220
|
-
|
221
|
-
def sort_syntaxes
|
222
|
-
@syntaxes = @syntax_set.sort do |a, b|
|
223
|
-
if a.token_count == b.token_count
|
224
|
-
# For syntaxes of the same length, sort first word
|
225
|
-
b.first_word <=> a.first_word
|
226
|
-
else
|
227
|
-
b.token_count <=> a.token_count
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module Gamefic
|
2
|
-
module World
|
3
|
-
module Players
|
4
|
-
include Gamefic::World::Entities
|
5
|
-
include Gamefic::World::Commands
|
6
|
-
|
7
|
-
# An array of entities that are currently connected to users.
|
8
|
-
#
|
9
|
-
# @return [Array<Gamefic::Actor>]
|
10
|
-
def players
|
11
|
-
@players ||= []
|
12
|
-
end
|
13
|
-
|
14
|
-
def player_class cls = nil
|
15
|
-
STDERR.puts "Modifying player_class this way is deprecated. Use set_player_class instead" unless cls.nil?
|
16
|
-
@player_class = cls unless cls.nil?
|
17
|
-
@player_class ||= Gamefic::Actor
|
18
|
-
end
|
19
|
-
|
20
|
-
# @param cls [Class]
|
21
|
-
def set_player_class cls
|
22
|
-
unless cls < Gamefic::Active && cls <= Gamefic::Entity
|
23
|
-
raise ArgumentError, "Player class must be an active entity"
|
24
|
-
end
|
25
|
-
@player_class = cls
|
26
|
-
end
|
27
|
-
|
28
|
-
# Make a character that a player will control on introduction.
|
29
|
-
#
|
30
|
-
# @return [Gamefic::Actor]
|
31
|
-
def make_player_character
|
32
|
-
cast player_class, name: 'yourself', synonyms: 'self myself you me', proper_named: true
|
33
|
-
end
|
34
|
-
alias get_player_character make_player_character
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/lib/gamefic/world/scenes.rb
DELETED
@@ -1,228 +0,0 @@
|
|
1
|
-
module Gamefic
|
2
|
-
module World
|
3
|
-
module Scenes
|
4
|
-
include Commands
|
5
|
-
include Players
|
6
|
-
|
7
|
-
# @return [Class<Gamefic::Scene::Activity>]
|
8
|
-
def default_scene
|
9
|
-
@default_scene ||= Scene::Activity
|
10
|
-
end
|
11
|
-
|
12
|
-
# @return [Class<Gamefic::Scene::Conclusion>]
|
13
|
-
def default_conclusion
|
14
|
-
@default_conclusion ||= Scene::Conclusion
|
15
|
-
end
|
16
|
-
|
17
|
-
# Add a block to be executed when a player is added to the game.
|
18
|
-
# Each Plot can only have one introduction. Subsequent calls will
|
19
|
-
# overwrite the existing one.
|
20
|
-
#
|
21
|
-
# @example Welcome the player to the game
|
22
|
-
# introduction do |actor|
|
23
|
-
# actor.tell "Welcome to the game!"
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# @yieldparam [Gamefic::Actor]
|
27
|
-
def introduction(&proc)
|
28
|
-
@introduction = proc
|
29
|
-
end
|
30
|
-
|
31
|
-
# Introduce a player to the game.
|
32
|
-
# This method is typically called by the Engine that manages game execution.
|
33
|
-
#
|
34
|
-
# @param [Gamefic::Actor]
|
35
|
-
# @return [void]
|
36
|
-
def introduce(player)
|
37
|
-
player.playbooks.push playbook unless player.playbooks.include?(playbook)
|
38
|
-
player.cue default_scene
|
39
|
-
players.push player
|
40
|
-
@introduction&.call(player)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Create a multiple-choice scene.
|
44
|
-
# The user will be required to make a valid choice to continue.
|
45
|
-
#
|
46
|
-
# @example
|
47
|
-
# @scene = multiple_choice 'Go to work', 'Go to school' do |actor, scene|
|
48
|
-
# # Assuming user selected the first choice:
|
49
|
-
# scene.selection #=> 'Go to work'
|
50
|
-
# scene.index #=> 0
|
51
|
-
# scene.number #=> 1
|
52
|
-
# end
|
53
|
-
#
|
54
|
-
# @yieldparam [Gamefic::Actor]
|
55
|
-
# @yieldparam [Gamefic::Scene::MultipleChoice]
|
56
|
-
# @return [Class<Gamefic::Scene::MultipleChoice>]
|
57
|
-
def multiple_choice *choices, &block
|
58
|
-
s = Scene::MultipleChoice.subclass do |_actor, scene|
|
59
|
-
scene.options.concat choices
|
60
|
-
scene.on_finish &block
|
61
|
-
end
|
62
|
-
scene_classes.push s
|
63
|
-
s
|
64
|
-
end
|
65
|
-
|
66
|
-
# Create a yes-or-no scene.
|
67
|
-
# The user will be required to answer Yes or No to continue.
|
68
|
-
#
|
69
|
-
# @example
|
70
|
-
# @scene = yes_or_no 'What is your answer?' do |actor, scene|
|
71
|
-
# if scene.yes?
|
72
|
-
# actor.tell "You said yes."
|
73
|
-
# else
|
74
|
-
# actor.tell "You said no."
|
75
|
-
# end
|
76
|
-
# end
|
77
|
-
#
|
78
|
-
# @param prompt [String, nil]
|
79
|
-
# @yieldparam [Gamefic::Actor]
|
80
|
-
# @yieldparam [Gamefic::Scene::YesOrNo]
|
81
|
-
# @return [Class<Gamefic::Scene::YesOrNo>]
|
82
|
-
def yes_or_no prompt = nil, &block
|
83
|
-
s = Scene::YesOrNo.subclass do |_actor, scene|
|
84
|
-
scene.prompt = prompt
|
85
|
-
scene.on_finish &block
|
86
|
-
end
|
87
|
-
scene_classes.push s
|
88
|
-
s
|
89
|
-
end
|
90
|
-
|
91
|
-
# Create a scene with custom processing on user input.
|
92
|
-
#
|
93
|
-
# @example Echo the user's response
|
94
|
-
# @scene = question 'What do you say?' do |actor, scene|
|
95
|
-
# actor.tell "You said #{scene.input}"
|
96
|
-
# end
|
97
|
-
#
|
98
|
-
# @param prompt [String]
|
99
|
-
# @yieldparam [Gamefic::Actor]
|
100
|
-
# @yieldparam [Gamefic::Scene::Base]
|
101
|
-
# @return [Class<Gamefic::Scene::Base>]
|
102
|
-
def question prompt = 'What is your answer?', &block
|
103
|
-
s = Scene::Base.subclass do |_actor, scene|
|
104
|
-
scene.prompt = prompt
|
105
|
-
scene.on_finish &block
|
106
|
-
end
|
107
|
-
scene_classes.push s
|
108
|
-
s
|
109
|
-
end
|
110
|
-
|
111
|
-
# Create a scene that pauses the game.
|
112
|
-
# This scene will execute the specified block and wait for input from the
|
113
|
-
# the user (e.g., pressing Enter) to continue.
|
114
|
-
#
|
115
|
-
# @example
|
116
|
-
# @scene = pause 'Continue' do |actor|
|
117
|
-
# actor.tell "After you continue, you will be prompted for a command."
|
118
|
-
# actor.prepare default_scene
|
119
|
-
# end
|
120
|
-
#
|
121
|
-
# @param prompt [String, nil] The text to display when prompting the user to continue
|
122
|
-
# @yieldparam [Gamefic::Actor]
|
123
|
-
# @return [Class<Gamefic::Scene::Pause>]
|
124
|
-
def pause prompt = nil, &block
|
125
|
-
s = Scene::Pause.subclass do |actor, scene|
|
126
|
-
scene.prompt = prompt unless prompt.nil?
|
127
|
-
block&.call(actor, scene)
|
128
|
-
end
|
129
|
-
scene_classes.push s
|
130
|
-
s
|
131
|
-
end
|
132
|
-
|
133
|
-
# Create a conclusion.
|
134
|
-
# The game (or the character's participation in it) will end after this
|
135
|
-
# scene is complete.
|
136
|
-
#
|
137
|
-
# @example
|
138
|
-
# @scene = conclusion do |actor|
|
139
|
-
# actor.tell 'Game over'
|
140
|
-
# end
|
141
|
-
#
|
142
|
-
# @yieldparam [Gamefic::Actor]
|
143
|
-
# @return [Class<Gamefic::Scene::Conclusion>]
|
144
|
-
def conclusion &block
|
145
|
-
s = Scene::Conclusion.subclass &block
|
146
|
-
scene_classes.push s
|
147
|
-
s
|
148
|
-
end
|
149
|
-
|
150
|
-
# Create a custom scene.
|
151
|
-
#
|
152
|
-
# Custom scenes should always specify the next scene to be cued or
|
153
|
-
# prepared. If not, the scene will get repeated on the next turn.
|
154
|
-
#
|
155
|
-
# This method creates a Scene::Base by default. You can customize other
|
156
|
-
# scene types by specifying the class to create.
|
157
|
-
#
|
158
|
-
# @example Ask the user for a name
|
159
|
-
# @scene = custom do |actor, scene|
|
160
|
-
# scene.prompt = "What's your name?"
|
161
|
-
# scene.on_finish do
|
162
|
-
# actor.name = scene.input
|
163
|
-
# actor.tell "Hello, #{actor.name}!"
|
164
|
-
# actor.cue default_scene
|
165
|
-
# end
|
166
|
-
# end
|
167
|
-
#
|
168
|
-
# @param cls [Class<Scene::Base>] The class of scene to be instantiated.
|
169
|
-
# @yieldparam [Gamefic::Actor]
|
170
|
-
# @return [Class<Gamefic::Scene::Base>]
|
171
|
-
def custom cls = Scene::Base, &block
|
172
|
-
s = cls.subclass &block
|
173
|
-
scene_classes.push s
|
174
|
-
s
|
175
|
-
end
|
176
|
-
|
177
|
-
# Choose a new scene based on a list of options.
|
178
|
-
# This is a specialized type of multiple-choice scene that determines
|
179
|
-
# which scene to cue based on a Hash of choices and scene keys.
|
180
|
-
#
|
181
|
-
# @example Select a scene
|
182
|
-
# scene_one = pause do |actor|
|
183
|
-
# actor.tell "You went to scene one"
|
184
|
-
# end
|
185
|
-
#
|
186
|
-
# scene_two = pause do |actor|
|
187
|
-
# actor.tell "You went to scene two"
|
188
|
-
# end
|
189
|
-
#
|
190
|
-
# select_one_or_two = multiple_scene "One" => scene_one, "Two" => scene_two
|
191
|
-
#
|
192
|
-
# introduction do |actor|
|
193
|
-
# actor.cue select_one_or_two # The actor will be prompted to select "one" or "two" and get sent to the corresponding scene
|
194
|
-
# end
|
195
|
-
#
|
196
|
-
# @example Customize options
|
197
|
-
# scene_one = pause # do...
|
198
|
-
# scene_two = pause # do...
|
199
|
-
#
|
200
|
-
# # Some event in the game sets actor[:can_go_to_scene_two] to true
|
201
|
-
#
|
202
|
-
# select_one_or_two = multiple_scene do |actor, scene|
|
203
|
-
# scene.map "Go to scene one", scene_one
|
204
|
-
# scene.map "Go to scene two", scene_two if actor[:can_go_to_scene_two]
|
205
|
-
# end
|
206
|
-
#
|
207
|
-
# @param map [Hash] A Hash of options and associated scenes.
|
208
|
-
# @yieldparam [Gamefic::Actor]
|
209
|
-
# @yieldparam [Gamefic::Scene::MultipleScene]
|
210
|
-
# @return [Class<Gamefic::Scene::MultipleScene>]
|
211
|
-
def multiple_scene map = {}, &block
|
212
|
-
s = Scene::MultipleScene.subclass do |actor, scene|
|
213
|
-
map.each_pair do |k, v|
|
214
|
-
scene.map k, v
|
215
|
-
end
|
216
|
-
block&.call actor, scene
|
217
|
-
end
|
218
|
-
scene_classes.push s
|
219
|
-
s
|
220
|
-
end
|
221
|
-
|
222
|
-
# @return [Array<Class<Gamefic::Scene::Base>>]
|
223
|
-
def scene_classes
|
224
|
-
@scene_classes ||= []
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
data/lib/gamefic/world.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Gamefic
|
2
|
-
# A collection of classes and modules related to generating a world model.
|
3
|
-
#
|
4
|
-
module World
|
5
|
-
autoload :Playbook, 'gamefic/world/playbook'
|
6
|
-
autoload :Entities, 'gamefic/world/entities'
|
7
|
-
autoload :Commands, 'gamefic/world/commands'
|
8
|
-
autoload :Callbacks, 'gamefic/world/callbacks'
|
9
|
-
autoload :Scenes, 'gamefic/world/scenes'
|
10
|
-
autoload :Players, 'gamefic/world/players'
|
11
|
-
|
12
|
-
include Entities
|
13
|
-
include Commands
|
14
|
-
include Callbacks
|
15
|
-
include Scenes
|
16
|
-
include Players
|
17
|
-
end
|
18
|
-
end
|