gamefic 0.2.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gamefic/action.rb +87 -56
- data/lib/gamefic/ansi.rb +55 -0
- data/lib/gamefic/character.rb +130 -76
- data/lib/gamefic/command.rb +19 -0
- data/lib/gamefic/core_ext/array.rb +51 -40
- data/lib/gamefic/core_ext/string.rb +4 -0
- data/lib/gamefic/describable.rb +108 -46
- data/lib/gamefic/direction.rb +46 -0
- data/lib/gamefic/director/delegate.rb +91 -0
- data/lib/gamefic/director/order.rb +10 -0
- data/lib/gamefic/director/parser.rb +119 -0
- data/lib/gamefic/director.rb +16 -197
- data/lib/gamefic/engine/cgi.rb +221 -0
- data/lib/gamefic/engine/tty.rb +237 -0
- data/lib/gamefic/engine.rb +88 -67
- data/lib/gamefic/entity.rb +96 -69
- data/lib/gamefic/grammar/conjugator.rb +20 -0
- data/lib/gamefic/grammar/gender.rb +11 -0
- data/lib/gamefic/grammar/person.rb +10 -0
- data/lib/gamefic/grammar/plural.rb +13 -0
- data/lib/gamefic/grammar/pronouns.rb +60 -0
- data/lib/gamefic/grammar/tense.rb +6 -0
- data/lib/gamefic/grammar/verb_set.rb +43 -0
- data/lib/gamefic/grammar/verbs.rb +25 -0
- data/lib/gamefic/grammar/word_adapter.rb +36 -0
- data/lib/gamefic/grammar.rb +13 -0
- data/lib/gamefic/html.rb +53 -0
- data/lib/gamefic/keywords.rb +51 -33
- data/lib/gamefic/node.rb +65 -58
- data/lib/gamefic/plot/article_mount.rb +22 -0
- data/lib/gamefic/plot/command_mount.rb +88 -0
- data/lib/gamefic/plot/entity_mount.rb +45 -0
- data/lib/gamefic/plot/query_mount.rb +9 -0
- data/lib/gamefic/plot/scene_mount.rb +181 -0
- data/lib/gamefic/plot/you_mount.rb +22 -0
- data/lib/gamefic/plot.rb +296 -247
- data/lib/gamefic/query/ambiguous_children.rb +5 -0
- data/lib/gamefic/query/base.rb +265 -0
- data/lib/gamefic/query/children.rb +10 -0
- data/lib/gamefic/query/expression.rb +47 -0
- data/lib/gamefic/query/family.rb +10 -0
- data/lib/gamefic/query/many_children.rb +7 -0
- data/lib/gamefic/query/matches.rb +11 -0
- data/lib/gamefic/query/parent.rb +10 -0
- data/lib/gamefic/query/plural_children.rb +14 -0
- data/lib/gamefic/query/self.rb +10 -0
- data/lib/gamefic/query/siblings.rb +10 -0
- data/lib/gamefic/query/text.rb +43 -0
- data/lib/gamefic/query.rb +19 -203
- data/lib/gamefic/rule.rb +18 -0
- data/lib/gamefic/scene/active.rb +25 -0
- data/lib/gamefic/scene/concluded.rb +22 -0
- data/lib/gamefic/scene/multiplechoice.rb +74 -0
- data/lib/gamefic/scene/paused.rb +26 -0
- data/lib/gamefic/scene/yesorno.rb +43 -0
- data/lib/gamefic/scene.rb +125 -0
- data/lib/gamefic/script/base.rb +33 -0
- data/lib/gamefic/script/file.rb +14 -0
- data/lib/gamefic/script/text.rb +14 -0
- data/lib/gamefic/script.rb +9 -0
- data/lib/gamefic/serialized.rb +24 -0
- data/lib/gamefic/shell.rb +9 -247
- data/lib/gamefic/snapshots.rb +134 -0
- data/lib/gamefic/source/base.rb +12 -0
- data/lib/gamefic/source/file.rb +23 -0
- data/lib/gamefic/source/text.rb +16 -0
- data/lib/gamefic/source.rb +9 -0
- data/lib/gamefic/stage.rb +75 -0
- data/lib/gamefic/syntax.rb +106 -124
- data/lib/gamefic/tester.rb +20 -0
- data/lib/gamefic/version.rb +3 -0
- data/lib/gamefic.rb +18 -12
- metadata +102 -70
- data/lib/gamefic/base.rb +0 -10
- data/lib/gamefic/before.rb +0 -12
- data/lib/gamefic/import/basics/actions/close.rb +0 -16
- data/lib/gamefic/import/basics/actions/commands.rb +0 -3
- data/lib/gamefic/import/basics/actions/drop-in.rb +0 -17
- data/lib/gamefic/import/basics/actions/drop-on.rb +0 -16
- data/lib/gamefic/import/basics/actions/drop.rb +0 -30
- data/lib/gamefic/import/basics/actions/enter.rb +0 -16
- data/lib/gamefic/import/basics/actions/go.rb +0 -35
- data/lib/gamefic/import/basics/actions/inventory.rb +0 -8
- data/lib/gamefic/import/basics/actions/leave.rb +0 -29
- data/lib/gamefic/import/basics/actions/look-in-at.rb +0 -27
- data/lib/gamefic/import/basics/actions/look-under.rb +0 -3
- data/lib/gamefic/import/basics/actions/look.rb +0 -71
- data/lib/gamefic/import/basics/actions/nil.rb +0 -25
- data/lib/gamefic/import/basics/actions/open.rb +0 -23
- data/lib/gamefic/import/basics/actions/quit.rb +0 -3
- data/lib/gamefic/import/basics/actions/take.rb +0 -107
- data/lib/gamefic/import/basics/entities/container.rb +0 -8
- data/lib/gamefic/import/basics/entities/entity.rb +0 -11
- data/lib/gamefic/import/basics/entities/fixture.rb +0 -5
- data/lib/gamefic/import/basics/entities/item.rb +0 -5
- data/lib/gamefic/import/basics/entities/portal.rb +0 -40
- data/lib/gamefic/import/basics/entities/room.rb +0 -30
- data/lib/gamefic/import/basics/entities/scenery.rb +0 -5
- data/lib/gamefic/import/basics/entities/supporter.rb +0 -6
- data/lib/gamefic/import/basics/entities/thing.rb +0 -16
- data/lib/gamefic/import/basics/queries/reachable.rb +0 -38
- data/lib/gamefic/import/basics/queries/room.rb +0 -8
- data/lib/gamefic/import/basics/queries/visible.rb +0 -32
- data/lib/gamefic/import/basics/rules/has-enough-light.rb +0 -14
- data/lib/gamefic/import/basics.old/actions/container.rb +0 -112
- data/lib/gamefic/import/basics.old/actions/inventory.rb +0 -50
- data/lib/gamefic/import/basics.old/actions/look.rb +0 -53
- data/lib/gamefic/import/basics.old/actions/meta.rb +0 -6
- data/lib/gamefic/import/basics.old/actions/traversal.rb +0 -35
- data/lib/gamefic/import/basics.old/actions.rb +0 -1
- data/lib/gamefic/import/basics.old/entities/container.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/fixture.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/item.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/portal.rb +0 -43
- data/lib/gamefic/import/basics.old/entities/room.rb +0 -27
- data/lib/gamefic/import/basics.old/entities/scenery.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/supporter.rb +0 -3
- data/lib/gamefic/import/basics.old/entities.rb +0 -1
- data/lib/gamefic/import/basics.old/room_modes.rb +0 -48
- data/lib/gamefic/import/basics.rb +0 -6
- data/lib/gamefic/import/room_modes.rb +0 -48
- data/lib/gamefic/import/standard.rb +0 -1
- data/lib/gamefic/meta.rb +0 -12
- data/lib/gamefic/optionset.rb +0 -114
- data/lib/gamefic/requirement.rb +0 -14
- data/lib/gamefic/story.rb +0 -14
- data/lib/gamefic/thing.rb +0 -7
data/lib/gamefic/node.rb
CHANGED
@@ -1,62 +1,69 @@
|
|
1
|
+
# Exception raised when setting a node's parent would cause
|
2
|
+
# a circular reference, e.g., A -> A or A -> B -> A
|
3
|
+
class CircularNodeReferenceError < Exception
|
4
|
+
end
|
5
|
+
|
1
6
|
module Gamefic
|
2
7
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
8
|
+
module Node
|
9
|
+
# @return [Array]
|
10
|
+
def children
|
11
|
+
@children ||= []
|
12
|
+
@children.clone
|
13
|
+
end
|
14
|
+
def flatten
|
15
|
+
array = Array.new
|
16
|
+
children.each { |child|
|
17
|
+
array = array + recurse_flatten(child)
|
18
|
+
}
|
19
|
+
return array
|
20
|
+
end
|
21
|
+
def parent
|
22
|
+
@parent
|
23
|
+
end
|
24
|
+
def parent=(node)
|
25
|
+
return if node == @parent
|
26
|
+
if node == self
|
27
|
+
raise CircularNodeReferenceError.new("Node cannot be its own parent")
|
28
|
+
end
|
29
|
+
# Do not permit circular references
|
30
|
+
if node != nil and node.parent == self
|
31
|
+
node.parent = nil
|
32
|
+
end
|
33
|
+
if node != nil and flatten.include?(node)
|
34
|
+
raise CircularNodeReferenceError.new("Node cannot be a child of a descendant")
|
35
|
+
end
|
36
|
+
if @parent != node
|
37
|
+
if @parent != nil
|
38
|
+
@parent.send(:rem_child, self)
|
39
|
+
end
|
40
|
+
@parent = node
|
41
|
+
if @parent != nil
|
42
|
+
@parent.send(:add_child, self)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
protected
|
47
|
+
def add_child(node)
|
48
|
+
children
|
49
|
+
@children.push(node)
|
50
|
+
end
|
51
|
+
def rem_child(node)
|
52
|
+
children
|
53
|
+
@children.delete(node)
|
54
|
+
end
|
55
|
+
def concat_children(children)
|
56
|
+
children.concat(children)
|
57
|
+
end
|
58
|
+
private
|
59
|
+
def recurse_flatten(node)
|
60
|
+
array = Array.new
|
61
|
+
array.push(node)
|
62
|
+
node.children.each { |child|
|
63
|
+
array = array + recurse_flatten(child)
|
64
|
+
}
|
65
|
+
return array
|
66
|
+
end
|
67
|
+
end
|
61
68
|
|
62
69
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Gamefic
|
2
|
+
module ArticleMount
|
3
|
+
def a(entity)
|
4
|
+
entity.indefinitely
|
5
|
+
end
|
6
|
+
def an(entity)
|
7
|
+
entity.indefinitely
|
8
|
+
end
|
9
|
+
def the(entity)
|
10
|
+
entity.definitely
|
11
|
+
end
|
12
|
+
def A(entity)
|
13
|
+
entity.indefinitely.cap_first
|
14
|
+
end
|
15
|
+
def An(entity)
|
16
|
+
entity.indefinitely.cap_first
|
17
|
+
end
|
18
|
+
def The(entity)
|
19
|
+
entity.definitely.cap_first
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'gamefic/action'
|
2
|
+
|
3
|
+
module Gamefic
|
4
|
+
|
5
|
+
module Plot::CommandMount
|
6
|
+
# Create a Meta Action that responds to a command.
|
7
|
+
# Meta Actions are very similar to standard Actions, except the Plot
|
8
|
+
# understands them to be commands that operate above and/or outside of the
|
9
|
+
# actual game world. Examples of Meta Actions are commands that report the
|
10
|
+
# player's current score, save and restore saved games, or list the game's
|
11
|
+
# credits.
|
12
|
+
#
|
13
|
+
# @example A simple Meta Action
|
14
|
+
# meta :credits do |actor|
|
15
|
+
# actor.tell "This game was written by John Smith."
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# @param command [Symbol] An imperative verb for the command
|
19
|
+
# @param *queries [Array<Query::Base>] Queries to filter the command's tokens
|
20
|
+
# @yieldparam [Character]
|
21
|
+
def meta(command, *queries, &proc)
|
22
|
+
act = self.action(command, *queries, &proc)
|
23
|
+
act.meta = true
|
24
|
+
act
|
25
|
+
end
|
26
|
+
def action(command, *queries, &proc)
|
27
|
+
Action.new(self, command, *queries, &proc)
|
28
|
+
end
|
29
|
+
# Create an Action that responds to a command.
|
30
|
+
# An Action uses the command argument to identify the imperative verb that
|
31
|
+
# triggers the action.
|
32
|
+
# It can also accept queries to tokenize the remainder of the input and
|
33
|
+
# filter for particular entities or properties.
|
34
|
+
# The block argument contains the code to be executed when the input
|
35
|
+
# matches all of the Action's criteria (i.e., verb and queries).
|
36
|
+
#
|
37
|
+
# @example A simple Action.
|
38
|
+
# respond :salute do |actor|
|
39
|
+
# actor.tell "Hello, sir!"
|
40
|
+
# end
|
41
|
+
# # The command "salute" will respond "Hello, sir!"
|
42
|
+
#
|
43
|
+
# @example An Action that accepts a Character
|
44
|
+
# respond :salute, Use.visible(Character) do |actor, character|
|
45
|
+
# actor.tell "#{The character} returns your salute."
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @param command [Symbol] An imperative verb for the command
|
49
|
+
# @param *queries [Array<Query::Base>] Queries to filter the command's tokens
|
50
|
+
# @yieldparam [Character]
|
51
|
+
def respond(command, *queries, &proc)
|
52
|
+
self.action(command, *queries, &proc)
|
53
|
+
end
|
54
|
+
# Create an alternate Syntax for an Action.
|
55
|
+
# The command and its translation can be parameterized.
|
56
|
+
#
|
57
|
+
# @example Create a synonym for the Inventory Action.
|
58
|
+
# interpret "catalogue", "inventory"
|
59
|
+
# # The command "catalogue" will be translated to "inventory"
|
60
|
+
#
|
61
|
+
# @example Create a parameterized synonym for the Look Action.
|
62
|
+
# interpret "scrutinize :entity", "look :entity"
|
63
|
+
# # The command "scrutinize chair" will be translated to "look chair"
|
64
|
+
#
|
65
|
+
# @param command [String] The format of the original command
|
66
|
+
# @param translation [String] The format of the translated command
|
67
|
+
# @return [Syntax] the Syntax object
|
68
|
+
def interpret command, translation
|
69
|
+
xlate command, translation
|
70
|
+
end
|
71
|
+
def syntax(*args)
|
72
|
+
xlate(*args)
|
73
|
+
end
|
74
|
+
def xlate(*args)
|
75
|
+
syn = Syntax.new(self, *args)
|
76
|
+
syn
|
77
|
+
end
|
78
|
+
def commandwords
|
79
|
+
words = Array.new
|
80
|
+
syntaxes.each { |s|
|
81
|
+
word = s.first_word
|
82
|
+
words.push(word) if !word.nil?
|
83
|
+
}
|
84
|
+
words.uniq
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Gamefic
|
2
|
+
|
3
|
+
module Plot::EntityMount
|
4
|
+
# Make a new Entity with the provided properties.
|
5
|
+
#
|
6
|
+
# @example Create an Entity
|
7
|
+
# chair = make Entity, :name => 'red chair'
|
8
|
+
# chair.name #=> 'red chair'
|
9
|
+
#
|
10
|
+
# @param cls [Class] The Class of the Entity to be created.
|
11
|
+
# @param args [Hash] The entity's properties.
|
12
|
+
# @return The Entity instance.
|
13
|
+
def make(cls, args = {}, &block)
|
14
|
+
ent = cls.new(self, args, &block)
|
15
|
+
if ent.kind_of?(Entity) == false
|
16
|
+
raise "Invalid entity class"
|
17
|
+
end
|
18
|
+
ent
|
19
|
+
end
|
20
|
+
# Pick an entity based on its description.
|
21
|
+
# The description provided must match exactly one entity; otherwise
|
22
|
+
# an error is raised.
|
23
|
+
#
|
24
|
+
# @example Select the Entity that matches the description
|
25
|
+
# red_chair = make Entity, :name => 'red chair'
|
26
|
+
# blue_chair make Entity, :name => 'blue chair'
|
27
|
+
# pick "red chair" #=> red_chair
|
28
|
+
# pick "blue chair" #=> blue_chair
|
29
|
+
# pick "chair" #=> IndexError: description is ambiguous
|
30
|
+
#
|
31
|
+
# @param @description [String] The description of the entity
|
32
|
+
# @return [Entity] The entity that matches the description
|
33
|
+
def pick(description)
|
34
|
+
query = Gamefic::Query::Base.new
|
35
|
+
result = query.match(description, entities)
|
36
|
+
if result.objects.length == 0
|
37
|
+
raise IndexError.new("Unable to find entity from '#{description}'")
|
38
|
+
elsif result.objects.length > 1
|
39
|
+
raise IndexError.new("Ambiguous entities found from '#{description}'")
|
40
|
+
end
|
41
|
+
result.objects[0]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
class NotConclusionError < Exception
|
2
|
+
end
|
3
|
+
|
4
|
+
module Gamefic
|
5
|
+
|
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
|
+
# Create a multiple-choice scene.
|
20
|
+
# The user will be required to make a valid choice to continue
|
21
|
+
#
|
22
|
+
# @yieldparam [Character]
|
23
|
+
# @yieldparam [MultipleChoiceSceneData]
|
24
|
+
def multiple_choice key, *args, &block
|
25
|
+
scene_managers[key] = MultipleChoiceSceneManager.new do |config|
|
26
|
+
config.start do |actor, data|
|
27
|
+
data.options = args
|
28
|
+
end
|
29
|
+
config.finish(&block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Create a yes-or-no scene.
|
34
|
+
# The user will be required to answer Yes or No to continue.
|
35
|
+
#
|
36
|
+
# @yieldparam [Character]
|
37
|
+
# @yieldparam [YesOrNoSceneData]
|
38
|
+
def yes_or_no key, prompt = nil, &block
|
39
|
+
manager = YesOrNoSceneManager.new do |config|
|
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
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create a scene with a prompt.
|
54
|
+
# This scene will use the provided block to process arbitrary input
|
55
|
+
# from the user.
|
56
|
+
#
|
57
|
+
# @param key [Symbol] A unique name for the scene.
|
58
|
+
# @param prompt [String] The prompt message to display to the user.
|
59
|
+
# @yieldparam [Character]
|
60
|
+
# @yieldparam [SceneData]
|
61
|
+
def prompt key, prompt, &block
|
62
|
+
scene_managers[key] = SceneManager.new do |config|
|
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"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Create a scene that pauses the game.
|
73
|
+
# This scene will execute the specified block and wait for input
|
74
|
+
# from the user (e.g., pressing Enter) to continue.
|
75
|
+
#
|
76
|
+
# @param key [Symbol] A unique name for the scene.
|
77
|
+
# @yieldparam [Character]
|
78
|
+
# @yieldparam [SceneData]
|
79
|
+
def pause key, &block
|
80
|
+
manager = PausedSceneManager.new do |config|
|
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
|
87
|
+
end
|
88
|
+
|
89
|
+
# Create a conclusion.
|
90
|
+
# The game will end after this scene is complete.
|
91
|
+
#
|
92
|
+
# @param key [Symbol] A unique name for the scene.
|
93
|
+
# @yieldparam [Character]
|
94
|
+
# @yieldparam [SceneData]
|
95
|
+
def conclusion key, &block
|
96
|
+
manager = ConcludedSceneManager.new do |config|
|
97
|
+
config.start(&block)
|
98
|
+
end
|
99
|
+
scene_managers[key] = manager
|
100
|
+
end
|
101
|
+
|
102
|
+
# Create a generic scene.
|
103
|
+
# After the scene is complete, it will automatically start the next cue.
|
104
|
+
#
|
105
|
+
# @param [Symbol] A unique name for the scene.
|
106
|
+
# @yieldparam [Character]
|
107
|
+
# @yieldparam [SceneData]
|
108
|
+
def scene key, &block
|
109
|
+
scene = SceneManager.new do |manager|
|
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
|
120
|
+
end
|
121
|
+
|
122
|
+
# Branch to a new scene based on a list of options.
|
123
|
+
# This is a specialized type of multiple-choice scene that determines
|
124
|
+
# which scene to cue based on a Hash of choices and scene keys.
|
125
|
+
#
|
126
|
+
# @example Select a scene
|
127
|
+
# branch :select_one_or_two, { "one" => :scene_one, "two" => :scene_two }
|
128
|
+
# scene :scene_one do |actor|
|
129
|
+
# actor.tell "You went to scene one"
|
130
|
+
# end
|
131
|
+
# scene :scene_two do |actor|
|
132
|
+
# actor.tell "You went to scene two"
|
133
|
+
# end
|
134
|
+
# introduction do |actor|
|
135
|
+
# cue actor, :select_one_or_two # The actor will be prompted to select "one" or "two" and get sent to the corresponding scene
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# @param key [Symbol] A unique name for the scene.
|
139
|
+
# @param options [Hash] A Hash of options and associated scene keys.
|
140
|
+
def branch key, options
|
141
|
+
multiple_choice key, *options.keys do |actor, data|
|
142
|
+
cue actor, options[data.selection]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Cue a Character's next scene
|
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
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'gamefic'
|
2
|
+
require 'gamefic/grammar'
|
3
|
+
|
4
|
+
module Gamefic
|
5
|
+
module YouMount
|
6
|
+
class YouGrammarSet
|
7
|
+
include Grammar::Gender
|
8
|
+
include Grammar::Person
|
9
|
+
include Grammar::Plural
|
10
|
+
include Grammar::WordAdapter
|
11
|
+
end
|
12
|
+
# @return [YouGrammarSet]
|
13
|
+
def you
|
14
|
+
if @you.nil?
|
15
|
+
@you = YouGrammarSet.new
|
16
|
+
@you.person = 2
|
17
|
+
end
|
18
|
+
@you
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|