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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Gamefic
|
|
2
|
+
module Scripting
|
|
3
|
+
# Scripting hook methods are instance methods that return callbacks for
|
|
4
|
+
# execution in the context of a scriptable module or narrative. They
|
|
5
|
+
# collect the procs defined in Scriptable hook methods and bind them to the
|
|
6
|
+
# instance for execution.
|
|
7
|
+
#
|
|
8
|
+
module Hooks
|
|
9
|
+
# @return [Array<Binding>]
|
|
10
|
+
def before_commands
|
|
11
|
+
find_and_bind(:before_commands)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @return [Array<Binding>]
|
|
15
|
+
def after_commands
|
|
16
|
+
find_and_bind(:after_commands)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [Array<Binding>]
|
|
20
|
+
def ready_blocks
|
|
21
|
+
find_and_bind(:ready_blocks)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [Array<Binding>]
|
|
25
|
+
def update_blocks
|
|
26
|
+
find_and_bind(:update_blocks)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [Array<Binding>]
|
|
30
|
+
def player_output_blocks
|
|
31
|
+
find_and_bind(:player_output_blocks)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [Array<Binding>]
|
|
35
|
+
def conclude_blocks
|
|
36
|
+
find_and_bind(:conclude_blocks)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return [Array<Binding>]
|
|
40
|
+
def player_conclude_blocks
|
|
41
|
+
find_and_bind(:player_conclude_blocks)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Gamefic
|
|
4
|
-
module
|
|
4
|
+
module Scripting
|
|
5
5
|
# Methods for referencing entities from proxies.
|
|
6
6
|
#
|
|
7
7
|
module Proxies
|
|
@@ -14,14 +14,16 @@ module Gamefic
|
|
|
14
14
|
#
|
|
15
15
|
# @param object [Object]
|
|
16
16
|
# @return [Object]
|
|
17
|
-
def unproxy
|
|
17
|
+
def unproxy(object)
|
|
18
18
|
case object
|
|
19
|
-
when Proxy
|
|
19
|
+
when Proxy::Base
|
|
20
20
|
object.fetch self
|
|
21
21
|
when Array
|
|
22
22
|
object.map { |obj| unproxy obj }
|
|
23
23
|
when Hash
|
|
24
24
|
object.transform_values { |val| unproxy val }
|
|
25
|
+
when Response, Query::Base
|
|
26
|
+
object.bind(self)
|
|
25
27
|
else
|
|
26
28
|
object
|
|
27
29
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Gamefic
|
|
2
|
+
module Scripting
|
|
3
|
+
module Responses
|
|
4
|
+
# @return [Array<Response>]
|
|
5
|
+
def responses
|
|
6
|
+
included_scripts.flat_map(&:responses)
|
|
7
|
+
.map { |response| response.bind(self) }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# @return [Array<Response>]
|
|
11
|
+
def responses_for *verbs
|
|
12
|
+
# @todo This double reversal is odd, but Gamefic::Standard fails in
|
|
13
|
+
# Opal without it.
|
|
14
|
+
included_scripts.reverse
|
|
15
|
+
.flat_map { |script| script.responses_for(*verbs) }
|
|
16
|
+
.reverse
|
|
17
|
+
.map { |response| response.bind(self) }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Gamefic
|
|
2
|
+
module Scripting
|
|
3
|
+
module Scenes
|
|
4
|
+
# @return [Scene::Base]
|
|
5
|
+
def default_scene
|
|
6
|
+
self.class.default_scene
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# @return [Scene::Conclusion]
|
|
10
|
+
def default_conclusion
|
|
11
|
+
self.class.default_conclusion
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @return [Array<Binding>]
|
|
15
|
+
def introductions
|
|
16
|
+
included_scripts.reverse
|
|
17
|
+
.flat_map(&:introductions)
|
|
18
|
+
.map { |blk| Binding.new(self, blk) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [Hash]
|
|
22
|
+
def named_scenes
|
|
23
|
+
{}.merge(*included_scripts.flat_map(&:named_scenes))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Prepare a scene to be executed. Scenes can be accessed by their class
|
|
27
|
+
# or by a symbolic name if one has been defined in this narrative.
|
|
28
|
+
#
|
|
29
|
+
# @param name_or_class [Symbol, Class<Scene::Base>]
|
|
30
|
+
# @param actor [Actor]
|
|
31
|
+
# @param props [Props::Default]
|
|
32
|
+
# @return [Scene::Base]
|
|
33
|
+
def prepare name_or_class, actor, props, **context
|
|
34
|
+
scene_classes_map[name_or_class]&.new(actor, self, props, **context).tap do |scene|
|
|
35
|
+
scene&.rename(name_or_class.to_s) if name_or_class.is_a?(Symbol)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return [Array<Scene::Base>]
|
|
40
|
+
def scenes
|
|
41
|
+
self.class.scenes
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @param name_or_class [Symbol, Class<Scene::Base>]
|
|
45
|
+
# @return [Scene::Base]
|
|
46
|
+
def scene_class(name_or_class)
|
|
47
|
+
scene_classes_map[name_or_class]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def scene_classes_map
|
|
53
|
+
{}.merge(*included_scripts.flat_map(&:scene_classes_map))
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gamefic
|
|
4
|
+
# An instance module that enables scripting.
|
|
5
|
+
#
|
|
6
|
+
# Including `Gamefic::Scripting` also extends `Gamefic::Scriptable`.
|
|
7
|
+
#
|
|
8
|
+
module Scripting
|
|
9
|
+
require 'gamefic/scripting/proxies'
|
|
10
|
+
require 'gamefic/scripting/entities'
|
|
11
|
+
require 'gamefic/scripting/hooks'
|
|
12
|
+
require 'gamefic/scripting/responses'
|
|
13
|
+
require 'gamefic/scripting/syntaxes'
|
|
14
|
+
require 'gamefic/scripting/seeds'
|
|
15
|
+
require 'gamefic/scripting/scenes'
|
|
16
|
+
|
|
17
|
+
extend Scriptable
|
|
18
|
+
include Scriptable::Queries
|
|
19
|
+
include Entities
|
|
20
|
+
include Hooks
|
|
21
|
+
include Responses
|
|
22
|
+
include Seeds
|
|
23
|
+
include Scenes
|
|
24
|
+
include Syntaxes
|
|
25
|
+
|
|
26
|
+
# @return [Array<Module<Scriptable>>]
|
|
27
|
+
def included_scripts
|
|
28
|
+
self.class.included_scripts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param symbol [Symbol]
|
|
32
|
+
# @return [Array<Binding>]
|
|
33
|
+
def find_and_bind(symbol)
|
|
34
|
+
included_scripts.flat_map { |script| script.send(symbol) }
|
|
35
|
+
.map { |blk| Binding.new(self, blk) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.included other
|
|
39
|
+
super
|
|
40
|
+
other.extend Scriptable
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/gamefic/subplot.rb
CHANGED
|
@@ -7,8 +7,6 @@ module Gamefic
|
|
|
7
7
|
# started and concluded at any time during the parent plot's runtime.
|
|
8
8
|
#
|
|
9
9
|
class Subplot < Narrative
|
|
10
|
-
extend Scriptable::PlotProxies
|
|
11
|
-
|
|
12
10
|
# @return [Hash]
|
|
13
11
|
attr_reader :config
|
|
14
12
|
|
|
@@ -28,6 +26,10 @@ module Gamefic
|
|
|
28
26
|
[introduce].flatten.each { |plyr| self.introduce plyr }
|
|
29
27
|
end
|
|
30
28
|
|
|
29
|
+
def seeds
|
|
30
|
+
super - plot.seeds
|
|
31
|
+
end
|
|
32
|
+
|
|
31
33
|
def self.persist!
|
|
32
34
|
@persistent = true
|
|
33
35
|
end
|
|
@@ -40,33 +42,16 @@ module Gamefic
|
|
|
40
42
|
self.class.persistent?
|
|
41
43
|
end
|
|
42
44
|
|
|
43
|
-
def included_blocks
|
|
44
|
-
super - plot.included_blocks
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def ready
|
|
48
|
-
super
|
|
49
|
-
conclude if concluding?
|
|
50
|
-
end
|
|
51
|
-
|
|
52
45
|
def conclude
|
|
53
|
-
|
|
46
|
+
conclude_blocks.each(&:call)
|
|
54
47
|
players.each do |plyr|
|
|
55
|
-
|
|
48
|
+
player_conclude_blocks.each { |blk| blk[plyr] }
|
|
56
49
|
uncast plyr
|
|
57
50
|
end
|
|
58
51
|
entities.each { |ent| destroy ent }
|
|
59
52
|
@concluded = true
|
|
60
53
|
end
|
|
61
54
|
|
|
62
|
-
# Make an entity that persists in the subplot's parent plot.
|
|
63
|
-
#
|
|
64
|
-
# @see Plot#make
|
|
65
|
-
#
|
|
66
|
-
def persist klass, **args
|
|
67
|
-
plot.make klass, *args
|
|
68
|
-
end
|
|
69
|
-
|
|
70
55
|
# Start a new subplot based on the provided class.
|
|
71
56
|
#
|
|
72
57
|
# @note A subplot's host is always the base plot, regardless of whether
|
|
@@ -91,10 +76,14 @@ module Gamefic
|
|
|
91
76
|
@concluded
|
|
92
77
|
end
|
|
93
78
|
|
|
94
|
-
def introduce
|
|
79
|
+
def introduce(player)
|
|
95
80
|
@concluded ? player : super
|
|
96
81
|
end
|
|
97
82
|
|
|
83
|
+
def prepare(...)
|
|
84
|
+
super || plot.prepare(...)
|
|
85
|
+
end
|
|
86
|
+
|
|
98
87
|
def inspect
|
|
99
88
|
"#<#{self.class}>"
|
|
100
89
|
end
|
data/lib/gamefic/syntax.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'gamefic/syntax/template'
|
|
3
|
+
# require 'gamefic/syntax/template'
|
|
4
4
|
|
|
5
5
|
module Gamefic
|
|
6
6
|
# Syntaxes provide rules for matching input patterns to existing responses.
|
|
@@ -18,11 +18,14 @@ module Gamefic
|
|
|
18
18
|
# Syntax.new('search :container for :thing', 'look :thing :container')
|
|
19
19
|
#
|
|
20
20
|
class Syntax
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# @return [
|
|
21
|
+
PARAM_REGEXP = /^:[a-z0-9_]+$/i.freeze
|
|
22
|
+
|
|
23
|
+
# @return [String]
|
|
24
24
|
attr_reader :template
|
|
25
25
|
|
|
26
|
+
# @return [Array<String>]
|
|
27
|
+
attr_reader :params
|
|
28
|
+
|
|
26
29
|
# The pattern that will be used to tokenize the input into a command.
|
|
27
30
|
#
|
|
28
31
|
# @return [String]
|
|
@@ -37,10 +40,11 @@ module Gamefic
|
|
|
37
40
|
# @return [Symbol]
|
|
38
41
|
attr_reader :verb
|
|
39
42
|
|
|
40
|
-
# @param template [
|
|
43
|
+
# @param template [String]
|
|
41
44
|
# @param command [String]
|
|
42
|
-
def initialize
|
|
43
|
-
@template =
|
|
45
|
+
def initialize(template, command)
|
|
46
|
+
@template = template.normalize
|
|
47
|
+
@params = @template.keywords.select { |word| word.start_with?(':') }
|
|
44
48
|
@command = command.normalize
|
|
45
49
|
@verb = Syntax.literal_or_nil(@command.keywords[0])
|
|
46
50
|
@replace = parse_replace
|
|
@@ -55,15 +59,20 @@ module Gamefic
|
|
|
55
59
|
#
|
|
56
60
|
# @return [Symbol]
|
|
57
61
|
def synonym
|
|
58
|
-
template.
|
|
62
|
+
@synonym ||= Syntax.literal_or_nil(template.keywords.first)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @return [Regexp]
|
|
66
|
+
def regexp
|
|
67
|
+
@regexp ||= Regexp.new("^#{make_tokens.join(' ')}$", Regexp::IGNORECASE)
|
|
59
68
|
end
|
|
60
69
|
|
|
61
70
|
# Convert a String into a Command.
|
|
62
71
|
#
|
|
63
72
|
# @param text [String]
|
|
64
73
|
# @return [Expression, nil]
|
|
65
|
-
def tokenize
|
|
66
|
-
match = text&.match(
|
|
74
|
+
def tokenize(text)
|
|
75
|
+
match = text&.match(regexp)
|
|
67
76
|
return nil unless match
|
|
68
77
|
|
|
69
78
|
Expression.new(verb, match_to_args(match))
|
|
@@ -73,15 +82,15 @@ module Gamefic
|
|
|
73
82
|
#
|
|
74
83
|
# @param text [String]
|
|
75
84
|
# @return [Boolean]
|
|
76
|
-
def accept?
|
|
77
|
-
!!text.match(
|
|
85
|
+
def accept?(text)
|
|
86
|
+
!!text.match(regexp)
|
|
78
87
|
end
|
|
79
88
|
|
|
80
89
|
# Get a signature that identifies the form of the Syntax.
|
|
81
90
|
# Signatures are used to compare Syntaxes to each other.
|
|
82
91
|
#
|
|
83
92
|
def signature
|
|
84
|
-
[
|
|
93
|
+
[regexp, replace]
|
|
85
94
|
end
|
|
86
95
|
|
|
87
96
|
def ==(other)
|
|
@@ -95,22 +104,17 @@ module Gamefic
|
|
|
95
104
|
# @param text [String] The text to tokenize.
|
|
96
105
|
# @param syntaxes [Array<Syntax>] The syntaxes to use.
|
|
97
106
|
# @return [Array<Expression>] The tokenized expressions.
|
|
98
|
-
def self.tokenize
|
|
107
|
+
def self.tokenize(text, syntaxes)
|
|
99
108
|
syntaxes
|
|
100
109
|
.map { |syn| syn.tokenize(text) }
|
|
101
110
|
.compact
|
|
102
|
-
.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
# Compare two syntaxes for the purpose of ordering them in rulebooks.
|
|
106
|
-
#
|
|
107
|
-
def compare other
|
|
108
|
-
template.compare other.template
|
|
111
|
+
.uniq { |exp| [exp.verb, exp.tokens] }
|
|
112
|
+
.sort_by { |exp| [-exp.tokens.compact.length] }
|
|
109
113
|
end
|
|
110
114
|
|
|
111
115
|
# @param string [String]
|
|
112
116
|
# @return [Symbol, nil]
|
|
113
|
-
def self.literal_or_nil
|
|
117
|
+
def self.literal_or_nil(string)
|
|
114
118
|
string.start_with?(':') ? nil : string.to_sym
|
|
115
119
|
end
|
|
116
120
|
|
|
@@ -123,17 +127,28 @@ module Gamefic
|
|
|
123
127
|
command.keywords.map do |word|
|
|
124
128
|
next word unless word.start_with?(':')
|
|
125
129
|
|
|
126
|
-
index =
|
|
130
|
+
index = params.index(word) ||
|
|
127
131
|
raise(ArgumentError, "syntax command references undefined parameter `#{word}`")
|
|
128
132
|
"{$#{index + 1}}"
|
|
129
133
|
end.join(' ')
|
|
130
134
|
end
|
|
131
135
|
|
|
132
|
-
def match_to_args
|
|
136
|
+
def match_to_args(match)
|
|
133
137
|
start = replace.start_with?('{') ? 0 : 1
|
|
134
138
|
replace.keywords[start..].map do |str|
|
|
135
139
|
str.match?(/^\{\$[0-9]+\}$/) ? match[str[2..-2].to_i] : str
|
|
136
140
|
end
|
|
137
141
|
end
|
|
142
|
+
|
|
143
|
+
# @return [Array<String>]
|
|
144
|
+
def make_tokens
|
|
145
|
+
template.keywords.map.with_index do |word, idx|
|
|
146
|
+
next word unless word.match?(PARAM_REGEXP)
|
|
147
|
+
|
|
148
|
+
next nil if idx.positive? && template.keywords[idx - 1].match?(PARAM_REGEXP)
|
|
149
|
+
|
|
150
|
+
'([\w\W\s\S]*?)'
|
|
151
|
+
end.compact
|
|
152
|
+
end
|
|
138
153
|
end
|
|
139
154
|
end
|
data/lib/gamefic/version.rb
CHANGED
data/lib/gamefic.rb
CHANGED
|
@@ -7,11 +7,11 @@ require 'gamefic/core_ext/array'
|
|
|
7
7
|
require 'gamefic/core_ext/string'
|
|
8
8
|
require 'gamefic/syntax'
|
|
9
9
|
require 'gamefic/response'
|
|
10
|
-
require 'gamefic/
|
|
11
|
-
require 'gamefic/
|
|
10
|
+
require 'gamefic/match'
|
|
11
|
+
require 'gamefic/request'
|
|
12
|
+
require 'gamefic/order'
|
|
12
13
|
require 'gamefic/query'
|
|
13
14
|
require 'gamefic/scanner'
|
|
14
|
-
require 'gamefic/scope'
|
|
15
15
|
require 'gamefic/expression'
|
|
16
16
|
require 'gamefic/command'
|
|
17
17
|
require 'gamefic/action'
|
|
@@ -19,14 +19,12 @@ require 'gamefic/props'
|
|
|
19
19
|
require 'gamefic/scene'
|
|
20
20
|
require 'gamefic/proxy'
|
|
21
21
|
require 'gamefic/scriptable'
|
|
22
|
-
require 'gamefic/
|
|
23
|
-
require 'gamefic/
|
|
24
|
-
require 'gamefic/vault'
|
|
22
|
+
require 'gamefic/scripting'
|
|
23
|
+
require 'gamefic/binding'
|
|
25
24
|
require 'gamefic/narrative'
|
|
26
25
|
require 'gamefic/plot'
|
|
27
26
|
require 'gamefic/chapter'
|
|
28
27
|
require 'gamefic/subplot'
|
|
29
|
-
require 'gamefic/snapshot'
|
|
30
28
|
require 'gamefic/node'
|
|
31
29
|
require 'gamefic/describable'
|
|
32
30
|
require 'gamefic/messenger'
|
|
@@ -35,3 +33,4 @@ require 'gamefic/dispatcher'
|
|
|
35
33
|
require 'gamefic/active'
|
|
36
34
|
require 'gamefic/active/cue'
|
|
37
35
|
require 'gamefic/actor'
|
|
36
|
+
require 'gamefic/narrator'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gamefic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Fred Snyder
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2025-01-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: opal
|
|
@@ -58,20 +58,14 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
62
|
-
- - ">="
|
|
63
|
-
- !ruby/object:Gem::Version
|
|
64
|
-
version: '12.3'
|
|
61
|
+
version: '13.2'
|
|
65
62
|
type: :development
|
|
66
63
|
prerelease: false
|
|
67
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
68
65
|
requirements:
|
|
69
66
|
- - "~>"
|
|
70
67
|
- !ruby/object:Gem::Version
|
|
71
|
-
version: '
|
|
72
|
-
- - ">="
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '12.3'
|
|
68
|
+
version: '13.2'
|
|
75
69
|
- !ruby/object:Gem::Dependency
|
|
76
70
|
name: rspec
|
|
77
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -130,12 +124,10 @@ files:
|
|
|
130
124
|
- lib/gamefic/action.rb
|
|
131
125
|
- lib/gamefic/active.rb
|
|
132
126
|
- lib/gamefic/active/cue.rb
|
|
133
|
-
- lib/gamefic/active/epic.rb
|
|
134
127
|
- lib/gamefic/active/messaging.rb
|
|
135
|
-
- lib/gamefic/active/
|
|
128
|
+
- lib/gamefic/active/narratives.rb
|
|
136
129
|
- lib/gamefic/actor.rb
|
|
137
|
-
- lib/gamefic/
|
|
138
|
-
- lib/gamefic/callback.rb
|
|
130
|
+
- lib/gamefic/binding.rb
|
|
139
131
|
- lib/gamefic/chapter.rb
|
|
140
132
|
- lib/gamefic/command.rb
|
|
141
133
|
- lib/gamefic/core_ext/array.rb
|
|
@@ -145,34 +137,43 @@ files:
|
|
|
145
137
|
- lib/gamefic/entity.rb
|
|
146
138
|
- lib/gamefic/expression.rb
|
|
147
139
|
- lib/gamefic/logging.rb
|
|
140
|
+
- lib/gamefic/match.rb
|
|
148
141
|
- lib/gamefic/messenger.rb
|
|
149
142
|
- lib/gamefic/narrative.rb
|
|
143
|
+
- lib/gamefic/narrator.rb
|
|
150
144
|
- lib/gamefic/node.rb
|
|
145
|
+
- lib/gamefic/order.rb
|
|
151
146
|
- lib/gamefic/plot.rb
|
|
152
147
|
- lib/gamefic/props.rb
|
|
153
148
|
- lib/gamefic/props/default.rb
|
|
154
149
|
- lib/gamefic/props/multiple_choice.rb
|
|
150
|
+
- lib/gamefic/props/multiple_partial.rb
|
|
155
151
|
- lib/gamefic/props/output.rb
|
|
156
152
|
- lib/gamefic/props/pause.rb
|
|
157
153
|
- lib/gamefic/props/yes_or_no.rb
|
|
158
154
|
- lib/gamefic/proxy.rb
|
|
155
|
+
- lib/gamefic/proxy/attr.rb
|
|
159
156
|
- lib/gamefic/proxy/base.rb
|
|
160
157
|
- lib/gamefic/proxy/config.rb
|
|
161
158
|
- lib/gamefic/proxy/pick.rb
|
|
162
|
-
- lib/gamefic/proxy/
|
|
159
|
+
- lib/gamefic/proxy/pick_ex.rb
|
|
163
160
|
- lib/gamefic/query.rb
|
|
164
|
-
- lib/gamefic/query/
|
|
161
|
+
- lib/gamefic/query/ascendants.rb
|
|
165
162
|
- lib/gamefic/query/base.rb
|
|
166
|
-
- lib/gamefic/query/
|
|
163
|
+
- lib/gamefic/query/children.rb
|
|
164
|
+
- lib/gamefic/query/descendants.rb
|
|
165
|
+
- lib/gamefic/query/extended.rb
|
|
166
|
+
- lib/gamefic/query/family.rb
|
|
167
|
+
- lib/gamefic/query/global.rb
|
|
168
|
+
- lib/gamefic/query/integer.rb
|
|
169
|
+
- lib/gamefic/query/myself.rb
|
|
170
|
+
- lib/gamefic/query/parent.rb
|
|
167
171
|
- lib/gamefic/query/result.rb
|
|
168
|
-
- lib/gamefic/query/
|
|
172
|
+
- lib/gamefic/query/siblings.rb
|
|
173
|
+
- lib/gamefic/query/subqueries.rb
|
|
169
174
|
- lib/gamefic/query/text.rb
|
|
175
|
+
- lib/gamefic/request.rb
|
|
170
176
|
- lib/gamefic/response.rb
|
|
171
|
-
- lib/gamefic/rulebook.rb
|
|
172
|
-
- lib/gamefic/rulebook/calls.rb
|
|
173
|
-
- lib/gamefic/rulebook/events.rb
|
|
174
|
-
- lib/gamefic/rulebook/hooks.rb
|
|
175
|
-
- lib/gamefic/rulebook/scenes.rb
|
|
176
177
|
- lib/gamefic/scanner.rb
|
|
177
178
|
- lib/gamefic/scanner/base.rb
|
|
178
179
|
- lib/gamefic/scanner/fuzzy.rb
|
|
@@ -181,34 +182,30 @@ files:
|
|
|
181
182
|
- lib/gamefic/scanner/result.rb
|
|
182
183
|
- lib/gamefic/scanner/strict.rb
|
|
183
184
|
- lib/gamefic/scene.rb
|
|
185
|
+
- lib/gamefic/scene/active_choice.rb
|
|
184
186
|
- lib/gamefic/scene/activity.rb
|
|
187
|
+
- lib/gamefic/scene/base.rb
|
|
185
188
|
- lib/gamefic/scene/conclusion.rb
|
|
186
|
-
- lib/gamefic/scene/default.rb
|
|
187
189
|
- lib/gamefic/scene/multiple_choice.rb
|
|
188
190
|
- lib/gamefic/scene/pause.rb
|
|
189
191
|
- lib/gamefic/scene/yes_or_no.rb
|
|
190
|
-
- lib/gamefic/scope.rb
|
|
191
|
-
- lib/gamefic/scope/base.rb
|
|
192
|
-
- lib/gamefic/scope/children.rb
|
|
193
|
-
- lib/gamefic/scope/descendants.rb
|
|
194
|
-
- lib/gamefic/scope/family.rb
|
|
195
|
-
- lib/gamefic/scope/myself.rb
|
|
196
|
-
- lib/gamefic/scope/parent.rb
|
|
197
|
-
- lib/gamefic/scope/siblings.rb
|
|
198
192
|
- lib/gamefic/scriptable.rb
|
|
199
|
-
- lib/gamefic/scriptable/
|
|
200
|
-
- lib/gamefic/scriptable/entities.rb
|
|
201
|
-
- lib/gamefic/scriptable/events.rb
|
|
202
|
-
- lib/gamefic/scriptable/plot_proxies.rb
|
|
203
|
-
- lib/gamefic/scriptable/proxies.rb
|
|
193
|
+
- lib/gamefic/scriptable/hooks.rb
|
|
204
194
|
- lib/gamefic/scriptable/queries.rb
|
|
195
|
+
- lib/gamefic/scriptable/responses.rb
|
|
205
196
|
- lib/gamefic/scriptable/scenes.rb
|
|
206
|
-
- lib/gamefic/
|
|
207
|
-
- lib/gamefic/
|
|
197
|
+
- lib/gamefic/scriptable/seeds.rb
|
|
198
|
+
- lib/gamefic/scriptable/syntaxes.rb
|
|
199
|
+
- lib/gamefic/scripting.rb
|
|
200
|
+
- lib/gamefic/scripting/entities.rb
|
|
201
|
+
- lib/gamefic/scripting/hooks.rb
|
|
202
|
+
- lib/gamefic/scripting/proxies.rb
|
|
203
|
+
- lib/gamefic/scripting/responses.rb
|
|
204
|
+
- lib/gamefic/scripting/scenes.rb
|
|
205
|
+
- lib/gamefic/scripting/seeds.rb
|
|
206
|
+
- lib/gamefic/scripting/syntaxes.rb
|
|
208
207
|
- lib/gamefic/subplot.rb
|
|
209
208
|
- lib/gamefic/syntax.rb
|
|
210
|
-
- lib/gamefic/syntax/template.rb
|
|
211
|
-
- lib/gamefic/vault.rb
|
|
212
209
|
- lib/gamefic/version.rb
|
|
213
210
|
homepage: https://gamefic.com
|
|
214
211
|
licenses:
|