gamefic 3.6.0 → 4.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/.rubocop.yml +0 -3
- data/CHANGELOG.md +19 -0
- data/Rakefile +1 -0
- data/gamefic.gemspec +1 -1
- data/lib/gamefic/action.rb +68 -54
- data/lib/gamefic/active/cue.rb +84 -6
- data/lib/gamefic/active/messaging.rb +8 -0
- data/lib/gamefic/active/narratives.rb +101 -0
- data/lib/gamefic/active.rb +80 -92
- data/lib/gamefic/binding.rb +44 -0
- data/lib/gamefic/chapter.rb +30 -46
- data/lib/gamefic/command.rb +22 -40
- data/lib/gamefic/core_ext/array.rb +7 -7
- data/lib/gamefic/core_ext/string.rb +2 -2
- data/lib/gamefic/describable.rb +13 -0
- data/lib/gamefic/dispatcher.rb +35 -55
- data/lib/gamefic/entity.rb +6 -5
- data/lib/gamefic/expression.rb +1 -11
- data/lib/gamefic/logging.rb +3 -10
- data/lib/gamefic/match.rb +23 -0
- data/lib/gamefic/messenger.rb +1 -1
- data/lib/gamefic/narrative.rb +38 -74
- data/lib/gamefic/narrator.rb +77 -0
- data/lib/gamefic/node.rb +40 -8
- data/lib/gamefic/order.rb +53 -0
- data/lib/gamefic/plot.rb +41 -59
- data/lib/gamefic/props/default.rb +5 -17
- data/lib/gamefic/props/multiple_choice.rb +5 -2
- data/lib/gamefic/props/multiple_partial.rb +16 -0
- data/lib/gamefic/props/output.rb +7 -5
- data/lib/gamefic/props/yes_or_no.rb +2 -2
- data/lib/gamefic/props.rb +1 -0
- data/lib/gamefic/proxy/attr.rb +11 -0
- data/lib/gamefic/proxy/base.rb +3 -15
- data/lib/gamefic/proxy/config.rb +2 -2
- data/lib/gamefic/proxy/pick.rb +3 -3
- data/lib/gamefic/proxy/pick_ex.rb +11 -0
- data/lib/gamefic/proxy.rb +3 -71
- data/lib/gamefic/query/ascendants.rb +16 -0
- data/lib/gamefic/query/base.rb +47 -73
- data/lib/gamefic/query/children.rb +15 -0
- data/lib/gamefic/query/descendants.rb +17 -0
- data/lib/gamefic/query/extended.rb +20 -0
- data/lib/gamefic/query/family.rb +27 -0
- data/lib/gamefic/query/global.rb +22 -0
- data/lib/gamefic/query/integer.rb +32 -0
- data/lib/gamefic/query/myself.rb +13 -0
- data/lib/gamefic/query/parent.rb +13 -0
- data/lib/gamefic/query/result.rb +1 -1
- data/lib/gamefic/query/siblings.rb +12 -0
- data/lib/gamefic/query/subqueries.rb +17 -0
- data/lib/gamefic/query/text.rb +8 -9
- data/lib/gamefic/query.rb +11 -3
- data/lib/gamefic/request.rb +60 -0
- data/lib/gamefic/response.rb +46 -72
- data/lib/gamefic/scanner/nesting.rb +6 -6
- data/lib/gamefic/scanner/result.rb +3 -0
- data/lib/gamefic/scanner/strict.rb +14 -4
- data/lib/gamefic/scanner.rb +11 -6
- data/lib/gamefic/scene/active_choice.rb +75 -0
- data/lib/gamefic/scene/activity.rb +7 -3
- data/lib/gamefic/scene/base.rb +123 -0
- data/lib/gamefic/scene/conclusion.rb +4 -1
- data/lib/gamefic/scene/multiple_choice.rb +14 -11
- data/lib/gamefic/scene/pause.rb +5 -1
- data/lib/gamefic/scene/yes_or_no.rb +9 -0
- data/lib/gamefic/scene.rb +2 -1
- data/lib/gamefic/scriptable/hooks.rb +161 -0
- data/lib/gamefic/scriptable/queries.rb +38 -29
- data/lib/gamefic/scriptable/responses.rb +70 -0
- data/lib/gamefic/scriptable/scenes.rb +88 -115
- data/lib/gamefic/scriptable/seeds.rb +69 -0
- data/lib/gamefic/scriptable/syntaxes.rb +29 -0
- data/lib/gamefic/scriptable.rb +14 -199
- data/lib/gamefic/{scriptable → scripting}/entities.rb +22 -22
- data/lib/gamefic/scripting/hooks.rb +45 -0
- data/lib/gamefic/{scriptable → scripting}/proxies.rb +5 -3
- data/lib/gamefic/scripting/responses.rb +21 -0
- data/lib/gamefic/scripting/scenes.rb +57 -0
- data/lib/gamefic/scripting/seeds.rb +10 -0
- data/lib/gamefic/scripting/syntaxes.rb +13 -0
- data/lib/gamefic/scripting.rb +43 -0
- data/lib/gamefic/subplot.rb +11 -22
- data/lib/gamefic/syntax.rb +39 -24
- data/lib/gamefic/version.rb +1 -1
- data/lib/gamefic.rb +6 -7
- metadata +38 -41
- data/lib/gamefic/active/epic.rb +0 -74
- data/lib/gamefic/active/take.rb +0 -67
- data/lib/gamefic/block.rb +0 -28
- data/lib/gamefic/callback.rb +0 -16
- data/lib/gamefic/proxy/plot_pick.rb +0 -11
- data/lib/gamefic/query/abstract.rb +0 -12
- data/lib/gamefic/query/general.rb +0 -41
- data/lib/gamefic/query/scoped.rb +0 -27
- data/lib/gamefic/rulebook/calls.rb +0 -86
- data/lib/gamefic/rulebook/events.rb +0 -65
- data/lib/gamefic/rulebook/hooks.rb +0 -57
- data/lib/gamefic/rulebook/scenes.rb +0 -68
- data/lib/gamefic/rulebook.rb +0 -125
- data/lib/gamefic/scene/default.rb +0 -88
- data/lib/gamefic/scope/base.rb +0 -44
- data/lib/gamefic/scope/children.rb +0 -16
- data/lib/gamefic/scope/descendants.rb +0 -16
- data/lib/gamefic/scope/family.rb +0 -43
- data/lib/gamefic/scope/myself.rb +0 -13
- data/lib/gamefic/scope/parent.rb +0 -13
- data/lib/gamefic/scope/siblings.rb +0 -14
- data/lib/gamefic/scope.rb +0 -9
- data/lib/gamefic/scriptable/actions.rb +0 -137
- data/lib/gamefic/scriptable/events.rb +0 -71
- data/lib/gamefic/scriptable/plot_proxies.rb +0 -29
- data/lib/gamefic/snapshot.rb +0 -44
- data/lib/gamefic/stage.rb +0 -51
- data/lib/gamefic/syntax/template.rb +0 -67
- data/lib/gamefic/vault.rb +0 -52
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ab6b04620f4d61106e3d7a3321dfc1833f0a7cce7eeb0e509ca77bdc5388d7c0
|
|
4
|
+
data.tar.gz: d8d37b580f71e20870cbe4124a8af41a953448b4bd5296e8f6f73d5e8a0e5092
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ac226d280d8e1a07ad2bc154ae1cbc49a4496a847986f4d8919aef89999386432122673b568c64e2012ef3b910652aa67a31545e59eb65633105854fd0228d4b
|
|
7
|
+
data.tar.gz: 2b271b4061e74ab43d4cd11e080261b595404f7add90ea017934e49c4d1beda47a44c3ed88b53d4ba57cc6a6602fabf5e330a18544e783b09c56129642f6f82a
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
## 4.0.0
|
|
2
|
+
- Nuanced scans
|
|
3
|
+
- Command hooks
|
|
4
|
+
- Refactored queries
|
|
5
|
+
- Cue scenes by class or name
|
|
6
|
+
- Deprecate underscore verbs
|
|
7
|
+
- Move rules to Scriptable
|
|
8
|
+
- JIT Scriptable binding
|
|
9
|
+
- Sunset Rulebook
|
|
10
|
+
- Separate Scriptable and Scripting modules
|
|
11
|
+
- ActiveChoice scenes
|
|
12
|
+
- Narrator class runs narratives
|
|
13
|
+
- Use construct for static entities
|
|
14
|
+
- Parent relations
|
|
15
|
+
- Consolidate Syntax and Template
|
|
16
|
+
- Remove Snapshot module
|
|
17
|
+
- Track command activity
|
|
18
|
+
- MultiplePartial props
|
|
19
|
+
|
|
1
20
|
## 3.6.0 - October 6, 2024
|
|
2
21
|
- Normalized arguments accept strings
|
|
3
22
|
- Smarter picks and proxies
|
data/Rakefile
CHANGED
data/gamefic.gemspec
CHANGED
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
|
24
24
|
s.add_development_dependency 'opal', '~> 1.7'
|
|
25
25
|
s.add_development_dependency 'opal-rspec', '~> 1.0'
|
|
26
26
|
s.add_development_dependency 'opal-sprockets', '~> 1.0'
|
|
27
|
-
s.add_development_dependency 'rake', '~>
|
|
27
|
+
s.add_development_dependency 'rake', '~> 13.2'
|
|
28
28
|
s.add_development_dependency 'rspec', '~> 3.5', '>= 3.5.0'
|
|
29
29
|
s.add_development_dependency 'simplecov', '~> 0.14'
|
|
30
30
|
end
|
data/lib/gamefic/action.rb
CHANGED
|
@@ -1,91 +1,105 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Gamefic
|
|
4
|
-
# The handler for executing
|
|
5
|
-
# arguments. It's also responsible for executing before_action and
|
|
6
|
-
# after_action hooks if necessary.
|
|
4
|
+
# The handler for executing a command response.
|
|
7
5
|
#
|
|
8
6
|
class Action
|
|
9
|
-
include
|
|
7
|
+
include Scriptable::Queries
|
|
10
8
|
|
|
11
|
-
#
|
|
12
|
-
# performs an action. A before action hook is capable of cancelling the
|
|
13
|
-
# action's performance.
|
|
14
|
-
#
|
|
15
|
-
class Hook
|
|
16
|
-
# @param [Array<Symbol>]
|
|
17
|
-
attr_reader :verbs
|
|
18
|
-
|
|
19
|
-
# @param [Callback]
|
|
20
|
-
attr_reader :callback
|
|
21
|
-
|
|
22
|
-
def initialize verbs, callback
|
|
23
|
-
@verbs = verbs
|
|
24
|
-
@callback = callback
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def match?(input)
|
|
28
|
-
verbs.empty? || verbs.include?(input)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# @return [Active]
|
|
9
|
+
# @return [Actor]
|
|
33
10
|
attr_reader :actor
|
|
34
11
|
|
|
35
|
-
# @return [Array]
|
|
36
|
-
attr_reader :arguments
|
|
37
|
-
|
|
38
12
|
# @return [Response]
|
|
39
13
|
attr_reader :response
|
|
40
14
|
|
|
41
|
-
# @
|
|
42
|
-
|
|
15
|
+
# @return [Array<Match>]
|
|
16
|
+
attr_reader :matches
|
|
17
|
+
|
|
18
|
+
# @return [String, nil]
|
|
19
|
+
attr_reader :input
|
|
20
|
+
|
|
21
|
+
# @param actor [Actor]
|
|
43
22
|
# @param response [Response]
|
|
44
|
-
|
|
23
|
+
# @param matches [Array<Match>]
|
|
24
|
+
# @param input [String, nil]
|
|
25
|
+
def initialize(actor, response, matches, input = nil)
|
|
45
26
|
@actor = actor
|
|
46
|
-
@arguments = arguments
|
|
47
27
|
@response = response
|
|
28
|
+
@matches = matches
|
|
29
|
+
@input = input
|
|
48
30
|
end
|
|
49
31
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
def verb
|
|
33
|
+
response.verb
|
|
34
|
+
end
|
|
53
35
|
|
|
54
|
-
|
|
55
|
-
@
|
|
56
|
-
|
|
36
|
+
def command
|
|
37
|
+
@command ||= Command.new(response.verb, matches.map(&:argument), response.meta?, input)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def queries
|
|
41
|
+
response.queries
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def arguments
|
|
45
|
+
matches.map(&:argument)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def execute
|
|
49
|
+
response.execute(actor, *arguments)
|
|
57
50
|
self
|
|
58
51
|
end
|
|
59
52
|
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
# before_action hook.
|
|
53
|
+
# The total substantiality of the action, based on how many of the
|
|
54
|
+
# arguments are concrete entities and whether the action has a verb.
|
|
63
55
|
#
|
|
64
|
-
def
|
|
65
|
-
|
|
56
|
+
def substantiality
|
|
57
|
+
arguments.that_are(Entity).length + (verb ? 1 : 0)
|
|
66
58
|
end
|
|
67
59
|
|
|
68
|
-
#
|
|
69
|
-
# prevent subsequent hooks and/or the action itself from being executed.
|
|
60
|
+
# The total strictness of all the matches.
|
|
70
61
|
#
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
# The higher the strictness, the more precisely the tokens from the user
|
|
63
|
+
# input match the arguments. For example, if the user is interacting with a
|
|
64
|
+
# pencil, the command TAKE PENCIL is stricter than TAKE PEN.
|
|
65
|
+
#
|
|
66
|
+
# @return [Integer]
|
|
67
|
+
def strictness
|
|
68
|
+
matches.sum(0, &:strictness)
|
|
73
69
|
end
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
# The precision of the response.
|
|
72
|
+
#
|
|
73
|
+
# @return [Integer]
|
|
74
|
+
def precision
|
|
75
|
+
response.precision
|
|
77
76
|
end
|
|
78
77
|
|
|
79
|
-
def
|
|
80
|
-
response.
|
|
78
|
+
def valid?
|
|
79
|
+
response.accept?(actor, command)
|
|
81
80
|
end
|
|
82
81
|
|
|
83
|
-
def
|
|
84
|
-
|
|
82
|
+
def invalid?
|
|
83
|
+
!valid?
|
|
85
84
|
end
|
|
86
85
|
|
|
87
86
|
def meta?
|
|
88
87
|
response.meta?
|
|
89
88
|
end
|
|
89
|
+
|
|
90
|
+
# Sort an array of actions in the order in which a Dispatcher should
|
|
91
|
+
# attempt to execute them.
|
|
92
|
+
#
|
|
93
|
+
# Order is determined by the actions' substantiality, strictness, and
|
|
94
|
+
# precision. In the event of a tie, the most recently defined action has
|
|
95
|
+
# higher priority.
|
|
96
|
+
#
|
|
97
|
+
# @param actions [Array<Action>]
|
|
98
|
+
# @return [Array<Action>]
|
|
99
|
+
def self.sort(actions)
|
|
100
|
+
actions.sort_by.with_index do |action, idx|
|
|
101
|
+
[-action.substantiality, -action.strictness, -action.precision, idx]
|
|
102
|
+
end
|
|
103
|
+
end
|
|
90
104
|
end
|
|
91
105
|
end
|
data/lib/gamefic/active/cue.rb
CHANGED
|
@@ -2,24 +2,102 @@
|
|
|
2
2
|
|
|
3
3
|
module Gamefic
|
|
4
4
|
module Active
|
|
5
|
-
# The
|
|
5
|
+
# The object that actors use to perform a scene.
|
|
6
6
|
#
|
|
7
7
|
class Cue
|
|
8
|
-
# @return [
|
|
9
|
-
attr_reader :
|
|
8
|
+
# @return [Actor]
|
|
9
|
+
attr_reader :actor
|
|
10
|
+
|
|
11
|
+
# @return [Class<Scene::Base>, Symbol]
|
|
12
|
+
attr_reader :key
|
|
13
|
+
|
|
14
|
+
# @return [Narrative]
|
|
15
|
+
attr_reader :narrative
|
|
10
16
|
|
|
11
17
|
# @return [Hash]
|
|
12
18
|
attr_reader :context
|
|
13
19
|
|
|
14
|
-
# @
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
# @return [Props::Default, nil]
|
|
21
|
+
attr_reader :props
|
|
22
|
+
|
|
23
|
+
# @param actor [Actor]
|
|
24
|
+
# @param key [Class<Scene::Base>, Symbol]
|
|
25
|
+
# @param narrative [Narrative]
|
|
26
|
+
def initialize actor, key, narrative, **context
|
|
27
|
+
@actor = actor
|
|
28
|
+
@key = key
|
|
29
|
+
@narrative = narrative
|
|
17
30
|
@context = context
|
|
18
31
|
end
|
|
19
32
|
|
|
33
|
+
# @return [void]
|
|
34
|
+
def start
|
|
35
|
+
@props = scene.start
|
|
36
|
+
prepare_output
|
|
37
|
+
actor.rotate_cue
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @return [void]
|
|
41
|
+
def finish
|
|
42
|
+
props&.enter(actor.queue.shift&.strip)
|
|
43
|
+
scene.finish
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [Props::Output]
|
|
47
|
+
def output
|
|
48
|
+
props&.output.clone.freeze || Props::Output::EMPTY
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @return [Cue]
|
|
52
|
+
def restart
|
|
53
|
+
Cue.new(actor, key, narrative, **context)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def type
|
|
57
|
+
scene&.type
|
|
58
|
+
end
|
|
59
|
+
|
|
20
60
|
def to_s
|
|
21
61
|
scene.to_s
|
|
22
62
|
end
|
|
63
|
+
|
|
64
|
+
# @return [void]
|
|
65
|
+
def prepare
|
|
66
|
+
props.output.merge!({
|
|
67
|
+
scene: scene.to_hash,
|
|
68
|
+
prompt: props.prompt,
|
|
69
|
+
messages: actor.messages,
|
|
70
|
+
queue: actor.queue
|
|
71
|
+
})
|
|
72
|
+
actor.narratives.player_output_blocks.each { |block| block.call actor, props.output }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @return [Scene::Base]
|
|
76
|
+
def scene
|
|
77
|
+
# @note This method always returns a new instance. Scenes identified
|
|
78
|
+
# by symbolic keys can be instances of anonymous classes that cannot
|
|
79
|
+
# be serialized, so memoizing them breaks snapshots.
|
|
80
|
+
narrative&.prepare(key, actor, props, **context) ||
|
|
81
|
+
try_unblocked_class ||
|
|
82
|
+
raise("Failed to cue #{key.inspect} in #{narrative.inspect}")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
# @return [Scene::Base]
|
|
88
|
+
def try_unblocked_class
|
|
89
|
+
return unless key.is_a?(Class) && key <= Scene::Base
|
|
90
|
+
|
|
91
|
+
Gamefic.logger.warn "Cueing scene #{key} without narrative" unless narrative
|
|
92
|
+
key.new(actor, narrative, props, **context)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @return [void]
|
|
96
|
+
def prepare_output
|
|
97
|
+
scene
|
|
98
|
+
props.output.last_input = actor.last_cue&.props&.input
|
|
99
|
+
props.output.last_prompt = actor.last_cue&.props&.prompt
|
|
100
|
+
end
|
|
23
101
|
end
|
|
24
102
|
end
|
|
25
103
|
end
|
|
@@ -30,14 +30,22 @@ module Gamefic
|
|
|
30
30
|
messenger.stream message
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
# @return [String]
|
|
33
34
|
def messages
|
|
34
35
|
messenger.messages
|
|
35
36
|
end
|
|
36
37
|
|
|
38
|
+
# Create a temporary buffer while yielding the given block and return the
|
|
39
|
+
# buffered text.
|
|
40
|
+
#
|
|
41
|
+
# @return [String]
|
|
37
42
|
def buffer &block
|
|
38
43
|
messenger.buffer(&block)
|
|
39
44
|
end
|
|
40
45
|
|
|
46
|
+
# Clear the current buffer.
|
|
47
|
+
#
|
|
48
|
+
# @return [String] The buffer's messages
|
|
41
49
|
def flush
|
|
42
50
|
messenger.flush
|
|
43
51
|
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gamefic
|
|
4
|
+
module Active
|
|
5
|
+
# A narrative container for active entities.
|
|
6
|
+
#
|
|
7
|
+
class Narratives
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
# @param narrative [Narrative]
|
|
11
|
+
# @return [self]
|
|
12
|
+
def add(narrative)
|
|
13
|
+
narrative_set.add(narrative)
|
|
14
|
+
self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @param narrative [Narrative]
|
|
18
|
+
# @return [self]
|
|
19
|
+
def delete(narrative)
|
|
20
|
+
narrative_set.delete(narrative)
|
|
21
|
+
self
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def empty?
|
|
25
|
+
narrative_set.empty?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [Integer]
|
|
29
|
+
def length
|
|
30
|
+
narrative_set.length
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def one?
|
|
34
|
+
narrative_set.one?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @return [Array<Response>]
|
|
38
|
+
def responses
|
|
39
|
+
narrative_set.flat_map(&:responses)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @return [Array<Response>]
|
|
43
|
+
def responses_for(*verbs)
|
|
44
|
+
narrative_set.flat_map { |narr| narr.responses_for(*verbs) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @return [Array<Syntax>]
|
|
48
|
+
def syntaxes
|
|
49
|
+
narrative_set.flat_map(&:syntaxes)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# True if the specified verb is understood by any of the narratives.
|
|
53
|
+
#
|
|
54
|
+
# @param verb [String, Symbol]
|
|
55
|
+
def understand?(verb)
|
|
56
|
+
verb ? narrative_set.flat_map(&:synonyms).include?(verb.to_sym) : false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @return [Array<Binding>]
|
|
60
|
+
def before_commands
|
|
61
|
+
narrative_set.flat_map(&:before_commands)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @return [Array<Binding>]
|
|
65
|
+
def after_commands
|
|
66
|
+
narrative_set.flat_map(&:after_commands)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def each(&block)
|
|
70
|
+
narrative_set.each(&block)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @return [Array<Narrative>]
|
|
74
|
+
def that_are(*args)
|
|
75
|
+
narrative_set.to_a.that_are(*args)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @return [Array<Narrative>]
|
|
79
|
+
def that_are_not(*args)
|
|
80
|
+
narrative_set.to_a.that_are_not(*args)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# @return [Array<Entity>]
|
|
84
|
+
def entities
|
|
85
|
+
narrative_set.flat_map(&:entities)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @return [Array<Binding>]
|
|
89
|
+
def player_output_blocks
|
|
90
|
+
narrative_set.flat_map(&:player_output_blocks).uniq(&:code)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
# @return [Set<Narrative>]
|
|
96
|
+
def narrative_set
|
|
97
|
+
@narrative_set ||= Set.new
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|