gamefic 3.3.0 → 3.5.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/CHANGELOG.md +20 -0
- data/README.md +1 -1
- data/lib/gamefic/action.rb +4 -4
- data/lib/gamefic/active/epic.rb +1 -0
- data/lib/gamefic/active.rb +4 -0
- data/lib/gamefic/callback.rb +16 -0
- data/lib/gamefic/chapter.rb +71 -0
- data/lib/gamefic/command.rb +40 -1
- data/lib/gamefic/dispatcher.rb +5 -31
- data/lib/gamefic/entity.rb +26 -0
- data/lib/gamefic/narrative.rb +30 -8
- data/lib/gamefic/plot.rb +28 -1
- data/lib/gamefic/proxy.rb +46 -0
- data/lib/gamefic/query/base.rb +28 -12
- data/lib/gamefic/query/general.rb +3 -12
- data/lib/gamefic/query/result.rb +4 -1
- data/lib/gamefic/query/scoped.rb +1 -18
- data/lib/gamefic/query/text.rb +13 -12
- data/lib/gamefic/response.rb +66 -38
- data/lib/gamefic/rulebook/calls.rb +0 -4
- data/lib/gamefic/rulebook/events.rb +10 -24
- data/lib/gamefic/rulebook/hooks.rb +10 -10
- data/lib/gamefic/rulebook.rb +8 -22
- data/lib/gamefic/scanner/base.rb +44 -0
- data/lib/gamefic/scanner/fuzzy.rb +17 -0
- data/lib/gamefic/scanner/fuzzy_nesting.rb +14 -0
- data/lib/gamefic/scanner/nesting.rb +39 -0
- data/lib/gamefic/scanner/result.rb +50 -0
- data/lib/gamefic/scanner/strict.rb +31 -0
- data/lib/gamefic/scanner.rb +33 -111
- data/lib/gamefic/scope/descendants.rb +16 -0
- data/lib/gamefic/scope/family.rb +31 -8
- data/lib/gamefic/scope.rb +1 -0
- data/lib/gamefic/scriptable/actions.rb +8 -27
- data/lib/gamefic/scriptable/entities.rb +4 -1
- data/lib/gamefic/scriptable/events.rb +13 -7
- data/lib/gamefic/scriptable/plot_proxies.rb +16 -0
- data/lib/gamefic/scriptable/proxies.rb +31 -0
- data/lib/gamefic/scriptable/queries.rb +15 -7
- data/lib/gamefic/scriptable/scenes.rb +10 -4
- data/lib/gamefic/scriptable.rb +73 -42
- data/lib/gamefic/stage.rb +2 -2
- data/lib/gamefic/subplot.rb +31 -7
- data/lib/gamefic/version.rb +1 -1
- data/lib/gamefic.rb +3 -1
- metadata +14 -4
- data/lib/gamefic/composer.rb +0 -70
- data/lib/gamefic/scriptable/proxy.rb +0 -69
data/lib/gamefic/scanner.rb
CHANGED
@@ -1,132 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'gamefic/scanner/result'
|
4
|
+
require 'gamefic/scanner/base'
|
5
|
+
require 'gamefic/scanner/strict'
|
6
|
+
require 'gamefic/scanner/fuzzy'
|
7
|
+
require 'gamefic/scanner/nesting'
|
8
|
+
require 'gamefic/scanner/fuzzy_nesting'
|
9
|
+
|
3
10
|
module Gamefic
|
4
11
|
# A module for matching objects to tokens.
|
5
12
|
#
|
6
13
|
module Scanner
|
7
|
-
|
8
|
-
|
9
|
-
# The result of an attempt to scan objects against a token in a Scanner. It
|
10
|
-
# provides an array of matching objects, the text that matched them, and the
|
11
|
-
# text that remains unmatched.
|
12
|
-
#
|
13
|
-
class Result
|
14
|
-
# The scanned objects
|
15
|
-
#
|
16
|
-
# @return [Array<Entity>, String, Regexp]
|
17
|
-
attr_reader :scanned
|
18
|
-
|
19
|
-
# The scanned token
|
20
|
-
#
|
21
|
-
# @return [String]
|
22
|
-
attr_reader :token
|
23
|
-
|
24
|
-
# The matched objects
|
25
|
-
#
|
26
|
-
# @return [Array<Entity>, String]
|
27
|
-
attr_reader :matched
|
28
|
-
|
29
|
-
# The remaining (unmatched) portion of the token
|
30
|
-
#
|
31
|
-
# @return [String]
|
32
|
-
attr_reader :remainder
|
33
|
-
|
34
|
-
def initialize scanned, token, matched, remainder
|
35
|
-
@scanned = scanned
|
36
|
-
@token = token
|
37
|
-
@matched = matched
|
38
|
-
@remainder = remainder
|
39
|
-
end
|
40
|
-
end
|
14
|
+
DEFAULT_PROCESSORS = [Nesting, Strict, FuzzyNesting, Fuzzy].freeze
|
41
15
|
|
42
16
|
# Scan entities against a token.
|
43
17
|
#
|
44
|
-
# @param selection [Array<Entity
|
18
|
+
# @param selection [Array<Entity>]
|
45
19
|
# @param token [String]
|
46
20
|
# @return [Result]
|
47
21
|
def self.scan selection, token
|
48
|
-
|
49
|
-
|
22
|
+
result = nil
|
23
|
+
processors.each do |processor|
|
24
|
+
result = processor.scan(selection, token)
|
25
|
+
break unless result.matched.empty?
|
26
|
+
end
|
27
|
+
result
|
50
28
|
end
|
51
29
|
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
30
|
+
# Select the scanner processors to use in entity queries. Each processor
|
31
|
+
# will be used in order until one of them returns matches. The default
|
32
|
+
# processor list is `DEFAULT_PROCESSORS`.
|
33
|
+
#
|
34
|
+
# Processor classes should be in order from most to least strict rules
|
35
|
+
# for matching tokens to entities.
|
36
|
+
#
|
37
|
+
# @param klasses [Array<Class<Base>>]
|
38
|
+
# @return [Array<Class<Base>>]
|
39
|
+
def self.use *klasses
|
40
|
+
processors.replace klasses.flatten
|
59
41
|
end
|
60
42
|
|
61
|
-
# @
|
62
|
-
|
63
|
-
|
64
|
-
def self.fuzzy selection, token
|
65
|
-
return scan_text(selection, token) unless selection.is_a?(Array)
|
66
|
-
|
67
|
-
scan_strict_or_fuzzy(selection, token, :select_fuzzy)
|
43
|
+
# @return [Array<Class<Base>>]
|
44
|
+
def self.processors
|
45
|
+
@processors ||= []
|
68
46
|
end
|
69
47
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def scan_strict_or_fuzzy objects, token, method
|
74
|
-
if nested?(token) && objects.all?(&:children)
|
75
|
-
denest(objects, token)
|
76
|
-
else
|
77
|
-
words = token.keywords
|
78
|
-
available = objects.clone
|
79
|
-
filtered = []
|
80
|
-
words.each_with_index do |word, idx|
|
81
|
-
tested = send(method, available, word)
|
82
|
-
return Result.new(objects, token, filtered, words[idx..].join(' ')) if tested.empty?
|
83
|
-
|
84
|
-
filtered = tested
|
85
|
-
available = filtered
|
86
|
-
end
|
87
|
-
Result.new(objects, token, filtered, '')
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def select_strict available, word
|
92
|
-
available.select { |obj| obj.keywords.include?(word) }
|
93
|
-
end
|
94
|
-
|
95
|
-
def select_fuzzy available, word
|
96
|
-
available.select { |obj| obj.keywords.any? { |wrd| wrd.start_with?(word) } }
|
97
|
-
end
|
98
|
-
|
99
|
-
def nested?(token)
|
100
|
-
token.match(NEST_REGEXP)
|
101
|
-
end
|
102
|
-
|
103
|
-
def scan_text selection, token
|
104
|
-
case selection
|
105
|
-
when Regexp
|
106
|
-
return Result.new(selection, token, token, '') if token =~ selection
|
107
|
-
else
|
108
|
-
return Result.new(selection, token, selection, token[selection.length..]) if token.start_with?(selection)
|
109
|
-
end
|
110
|
-
Result.new(selection, token, '', token)
|
111
|
-
end
|
112
|
-
|
113
|
-
def denest(objects, token)
|
114
|
-
parts = token.split(NEST_REGEXP)
|
115
|
-
current = parts.pop
|
116
|
-
last_result = scan(objects, current)
|
117
|
-
until parts.empty?
|
118
|
-
current = "#{parts.last} #{current}"
|
119
|
-
result = scan(last_result.matched, current)
|
120
|
-
break if result.matched.empty?
|
121
|
-
|
122
|
-
parts.pop
|
123
|
-
last_result = result
|
124
|
-
end
|
125
|
-
return Result.new(objects, token, [], '') if last_result.matched.empty? || last_result.matched.length > 1
|
126
|
-
return last_result if parts.empty?
|
127
|
-
|
128
|
-
denest(last_result.matched.first.children, parts.join(' '))
|
129
|
-
end
|
48
|
+
def self.strictness processor
|
49
|
+
(processors.length - (processors.find_index(processor) || processors.length)) * 100
|
130
50
|
end
|
51
|
+
|
52
|
+
use DEFAULT_PROCESSORS
|
131
53
|
end
|
132
54
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gamefic
|
4
|
+
module Scope
|
5
|
+
# The Descendants scope returns an entity's children and accessible
|
6
|
+
# descendants.
|
7
|
+
#
|
8
|
+
class Descendants < Base
|
9
|
+
def matches
|
10
|
+
context.children.flat_map do |child|
|
11
|
+
[child] + subquery_accessible(child)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/gamefic/scope/family.rb
CHANGED
@@ -2,18 +2,41 @@
|
|
2
2
|
|
3
3
|
module Gamefic
|
4
4
|
module Scope
|
5
|
-
# The Family scope returns an entity's
|
5
|
+
# The Family scope returns an entity's ascendants, descendants, siblings,
|
6
|
+
# and siblings' descendants.
|
6
7
|
#
|
7
8
|
class Family < Base
|
8
9
|
def matches
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
match_ascendants + match_descendants + match_siblings
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def match_ascendants
|
16
|
+
[].tap do |result|
|
17
|
+
here = context.parent
|
18
|
+
while here
|
19
|
+
result.push here
|
20
|
+
here = here.parent
|
21
|
+
end
|
15
22
|
end
|
16
|
-
|
23
|
+
end
|
24
|
+
|
25
|
+
def match_descendants
|
26
|
+
context.children.flat_map do |child|
|
27
|
+
[child] + subquery_accessible(child)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def match_siblings
|
32
|
+
return [] unless context.parent
|
33
|
+
|
34
|
+
context.parent
|
35
|
+
.children
|
36
|
+
.that_are_not(context)
|
37
|
+
.flat_map do |child|
|
38
|
+
[child] + subquery_accessible(child)
|
39
|
+
end
|
17
40
|
end
|
18
41
|
end
|
19
42
|
end
|
data/lib/gamefic/scope.rb
CHANGED
@@ -26,12 +26,11 @@ module Gamefic
|
|
26
26
|
# end
|
27
27
|
#
|
28
28
|
# @param verb [Symbol] An imperative verb for the command
|
29
|
-
# @param
|
29
|
+
# @param args [Array<Object>] Filters for the command's tokens
|
30
30
|
# @yieldparam [Gamefic::Actor]
|
31
31
|
# @return [Symbol]
|
32
|
-
def respond(verb, *
|
33
|
-
args
|
34
|
-
rulebook.calls.add_response Response.new(verb, rulebook.narrative, *args, &proc)
|
32
|
+
def respond(verb, *args, &proc)
|
33
|
+
rulebook.calls.add_response Response.new(verb, self, *args, &proc)
|
35
34
|
verb
|
36
35
|
end
|
37
36
|
|
@@ -47,12 +46,11 @@ module Gamefic
|
|
47
46
|
# end
|
48
47
|
#
|
49
48
|
# @param verb [Symbol] An imperative verb for the command
|
50
|
-
# @param
|
49
|
+
# @param args [Array<Object>] Filters for the command's tokens
|
51
50
|
# @yieldparam [Gamefic::Actor]
|
52
51
|
# @return [Symbol]
|
53
|
-
def meta(verb, *
|
54
|
-
args
|
55
|
-
rulebook.calls.add_response Response.new(verb, rulebook.narrative, *args, meta: true, &proc)
|
52
|
+
def meta(verb, *args, &proc)
|
53
|
+
rulebook.calls.add_response Response.new(verb, self, *args, meta: true, &proc)
|
56
54
|
verb
|
57
55
|
end
|
58
56
|
|
@@ -64,7 +62,7 @@ module Gamefic
|
|
64
62
|
# @yieldparam [Gamefic::Action]
|
65
63
|
# @return [Action::Hook]
|
66
64
|
def before_action *verbs, &block
|
67
|
-
rulebook.hooks.before_action *verbs, &block
|
65
|
+
rulebook.hooks.before_action self, *verbs, &block
|
68
66
|
end
|
69
67
|
|
70
68
|
# Add a proc to be evaluated after a character executes an action.
|
@@ -75,7 +73,7 @@ module Gamefic
|
|
75
73
|
# @yieldparam [Gamefic::Action]
|
76
74
|
# @return [Action::Hook]
|
77
75
|
def after_action *verbs, &block
|
78
|
-
rulebook.hooks.after_action *verbs, &block
|
76
|
+
rulebook.hooks.after_action self, *verbs, &block
|
79
77
|
end
|
80
78
|
|
81
79
|
# Create an alternate Syntax for a response.
|
@@ -134,23 +132,6 @@ module Gamefic
|
|
134
132
|
def syntaxes
|
135
133
|
rulebook.syntaxes
|
136
134
|
end
|
137
|
-
|
138
|
-
private
|
139
|
-
|
140
|
-
def map_response_args args
|
141
|
-
args.map do |arg|
|
142
|
-
case arg
|
143
|
-
when Entity, Class, Module, Proc, Proxy::Agent
|
144
|
-
available(arg)
|
145
|
-
when String, Regexp
|
146
|
-
plaintext(arg)
|
147
|
-
when Gamefic::Query::Base, Gamefic::Query::Text
|
148
|
-
arg
|
149
|
-
else
|
150
|
-
raise ArgumentError, "invalid argument in response: #{arg.inspect}"
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
135
|
end
|
155
136
|
end
|
156
137
|
end
|
@@ -9,7 +9,7 @@ module Gamefic
|
|
9
9
|
# #make and #destroy instead.
|
10
10
|
#
|
11
11
|
module Entities
|
12
|
-
include
|
12
|
+
include Proxies
|
13
13
|
|
14
14
|
def entity_vault
|
15
15
|
@entity_vault ||= Vault.new
|
@@ -63,6 +63,9 @@ module Gamefic
|
|
63
63
|
|
64
64
|
# Same as #pick, but raise an error if a unique match could not be found.
|
65
65
|
#
|
66
|
+
#
|
67
|
+
# @raise [RuntimeError] if a unique match was not found.
|
68
|
+
#
|
66
69
|
# @param description [String]
|
67
70
|
# @return [Gamefic::Entity, nil]
|
68
71
|
def pick! description
|
@@ -14,7 +14,7 @@ module Gamefic
|
|
14
14
|
# end
|
15
15
|
#
|
16
16
|
def on_ready &block
|
17
|
-
rulebook.events.on_ready(
|
17
|
+
rulebook.events.on_ready(Callback.new(self, block))
|
18
18
|
end
|
19
19
|
|
20
20
|
# Add a block to be executed for each player at the beginning of a turn.
|
@@ -28,37 +28,43 @@ module Gamefic
|
|
28
28
|
#
|
29
29
|
# @yieldparam [Gamefic::Actor]
|
30
30
|
def on_player_ready &block
|
31
|
-
|
31
|
+
wrapper = proc do
|
32
|
+
players.each { |player| Stage.run(self, player, &block) }
|
33
|
+
end
|
34
|
+
on_ready &wrapper
|
32
35
|
end
|
33
36
|
|
34
37
|
# Add a block to be executed after the Plot is finished updating a turn.
|
35
38
|
#
|
36
39
|
def on_update &block
|
37
|
-
rulebook.events.on_update(
|
40
|
+
rulebook.events.on_update(Callback.new(self, block))
|
38
41
|
end
|
39
42
|
|
40
43
|
# Add a block to be executed for each player at the end of a turn.
|
41
44
|
#
|
42
45
|
# @yieldparam [Gamefic::Actor]
|
43
46
|
def on_player_update &block
|
44
|
-
|
47
|
+
wrapper = proc do
|
48
|
+
players.each { |player| Stage.run(self, player, &block) }
|
49
|
+
end
|
50
|
+
on_update &wrapper
|
45
51
|
end
|
46
52
|
|
47
53
|
def on_conclude &block
|
48
|
-
rulebook.events.on_conclude(
|
54
|
+
rulebook.events.on_conclude(Callback.new(self, block))
|
49
55
|
end
|
50
56
|
|
51
57
|
# @yieldparam [Actor]
|
52
58
|
# @return [Proc]
|
53
59
|
def on_player_conclude &block
|
54
|
-
rulebook.events.on_player_conclude(
|
60
|
+
rulebook.events.on_player_conclude(Callback.new(self, block))
|
55
61
|
end
|
56
62
|
|
57
63
|
# @yieldparam [Actor]
|
58
64
|
# @yieldparam [Hash]
|
59
65
|
# @return [Proc]
|
60
66
|
def on_player_output &block
|
61
|
-
rulebook.events.on_player_output(
|
67
|
+
rulebook.events.on_player_output Callback.new(self, block)
|
62
68
|
end
|
63
69
|
end
|
64
70
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gamefic
|
4
|
+
module Scriptable
|
5
|
+
module PlotProxies
|
6
|
+
def lazy_plot key
|
7
|
+
Proxy.new(:attr, [:plot, key])
|
8
|
+
end
|
9
|
+
alias _plot lazy_plot
|
10
|
+
|
11
|
+
def attr_plot attr
|
12
|
+
define_method(attr) { plot.send(attr) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gamefic
|
4
|
+
module Scriptable
|
5
|
+
# Methods for referencing entities from proxies.
|
6
|
+
#
|
7
|
+
module Proxies
|
8
|
+
# Convert a proxy into its referenced entity.
|
9
|
+
#
|
10
|
+
# This method can receive any kind of object. If it's a proxy, its entity
|
11
|
+
# will be returned. If it's an array, each of its elements will be
|
12
|
+
# unproxied. If it's a hash, each of its values will be unproxied. Any
|
13
|
+
# other object will be returned unchanged.
|
14
|
+
#
|
15
|
+
# @param object [Object]
|
16
|
+
# @return [Object]
|
17
|
+
def unproxy object
|
18
|
+
case object
|
19
|
+
when Proxy
|
20
|
+
object.fetch self
|
21
|
+
when Array
|
22
|
+
object.map { |obj| unproxy obj }
|
23
|
+
when Hash
|
24
|
+
object.transform_values { |val| unproxy val }
|
25
|
+
else
|
26
|
+
object
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -5,14 +5,14 @@ module Gamefic
|
|
5
5
|
# Scriptable methods related to creating action queries.
|
6
6
|
#
|
7
7
|
module Queries
|
8
|
-
include
|
8
|
+
include Proxies
|
9
9
|
|
10
10
|
# Define a query that searches the entire plot's entities.
|
11
11
|
#
|
12
12
|
# @param args [Array<Object>] Query arguments
|
13
13
|
# @return [Query::General]
|
14
14
|
def anywhere *args, ambiguous: false
|
15
|
-
Query::General.new -> { entities }, *
|
15
|
+
Query::General.new -> { entities }, *args, ambiguous: ambiguous
|
16
16
|
end
|
17
17
|
|
18
18
|
# Define a query that searches an actor's family of entities. The
|
@@ -22,7 +22,7 @@ module Gamefic
|
|
22
22
|
# @param args [Array<Object>] Query arguments
|
23
23
|
# @return [Query::Scoped]
|
24
24
|
def available *args, ambiguous: false
|
25
|
-
Query::Scoped.new Scope::Family, *
|
25
|
+
Query::Scoped.new Scope::Family, *args, ambiguous: ambiguous
|
26
26
|
end
|
27
27
|
alias family available
|
28
28
|
|
@@ -31,7 +31,7 @@ module Gamefic
|
|
31
31
|
# @param args [Array<Object>] Query arguments
|
32
32
|
# @return [Query::Scoped]
|
33
33
|
def parent *args, ambiguous: false
|
34
|
-
Query::Scoped.new Scope::Parent, *
|
34
|
+
Query::Scoped.new Scope::Parent, *args, ambiguous: ambiguous
|
35
35
|
end
|
36
36
|
|
37
37
|
# Define a query that searches an actor's children.
|
@@ -39,7 +39,15 @@ module Gamefic
|
|
39
39
|
# @param args [Array<Object>] Query arguments
|
40
40
|
# @return [Query::Scoped]
|
41
41
|
def children *args, ambiguous: false
|
42
|
-
Query::Scoped.new Scope::Children, *
|
42
|
+
Query::Scoped.new Scope::Children, *args, ambiguous: ambiguous
|
43
|
+
end
|
44
|
+
|
45
|
+
# Define a query that searches an actor's descendants.
|
46
|
+
#
|
47
|
+
# @param args [Array<Object>] Query arguments
|
48
|
+
# @return [Query::Scoped]
|
49
|
+
def descendants *args, ambiguous: false
|
50
|
+
Query::Scoped.new Scope::Descendants, *args, ambiguous: ambiguous
|
43
51
|
end
|
44
52
|
|
45
53
|
# Define a query that searches an actor's siblings.
|
@@ -47,7 +55,7 @@ module Gamefic
|
|
47
55
|
# @param args [Array<Object>] Query arguments
|
48
56
|
# @return [Query::Scoped]
|
49
57
|
def siblings *args, ambiguous: false
|
50
|
-
Query::Scoped.new Scope::Siblings, *
|
58
|
+
Query::Scoped.new Scope::Siblings, *args, ambiguous: ambiguous
|
51
59
|
end
|
52
60
|
|
53
61
|
# Define a query that returns the actor itself.
|
@@ -55,7 +63,7 @@ module Gamefic
|
|
55
63
|
# @param args [Array<Object>] Query arguments
|
56
64
|
# @return [Query::Scoped]
|
57
65
|
def myself *args, ambiguous: false
|
58
|
-
Query::Scoped.new Scope::Myself, *
|
66
|
+
Query::Scoped.new Scope::Myself, *args, ambiguous: ambiguous
|
59
67
|
end
|
60
68
|
|
61
69
|
# Define a query that performs a plaintext search. It can take a String
|
@@ -33,13 +33,12 @@ module Gamefic
|
|
33
33
|
# @yieldparam [Scene]
|
34
34
|
# @return [Symbol]
|
35
35
|
def block name, klass = Scene::Default, on_start: nil, on_finish: nil, &blk
|
36
|
-
rulebook.scenes.add klass.new(name,
|
36
|
+
rulebook.scenes.add klass.new(name, self, on_start: on_start, on_finish: on_finish, &blk)
|
37
37
|
name
|
38
38
|
end
|
39
|
-
alias scene block
|
40
39
|
|
41
40
|
def preface name, klass = Scene::Activity, &start
|
42
|
-
rulebook.scenes.add klass.new(name,
|
41
|
+
rulebook.scenes.add klass.new(name, self, on_start: start)
|
43
42
|
name
|
44
43
|
end
|
45
44
|
alias precursor preface
|
@@ -60,7 +59,7 @@ module Gamefic
|
|
60
59
|
def introduction(&start)
|
61
60
|
rulebook.scenes
|
62
61
|
.introduction Scene::Default.new nil,
|
63
|
-
|
62
|
+
self,
|
64
63
|
on_start: proc { |actor, _props| Stage.run(self, actor, &start) }
|
65
64
|
end
|
66
65
|
|
@@ -160,9 +159,16 @@ module Gamefic
|
|
160
159
|
on_start: start
|
161
160
|
end
|
162
161
|
|
162
|
+
# @return [Array<Symbol>]
|
163
163
|
def scenes
|
164
164
|
rulebook.scenes.names
|
165
165
|
end
|
166
|
+
|
167
|
+
# @param name [Symbol]
|
168
|
+
# @return [Scene::Default, nil]
|
169
|
+
def scene(name)
|
170
|
+
rulebook.scenes[name]
|
171
|
+
end
|
166
172
|
end
|
167
173
|
end
|
168
174
|
end
|