gamefic 3.4.0 → 3.6.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +1 -1
  4. data/lib/gamefic/action.rb +1 -0
  5. data/lib/gamefic/active/epic.rb +1 -0
  6. data/lib/gamefic/active.rb +4 -0
  7. data/lib/gamefic/chapter.rb +25 -42
  8. data/lib/gamefic/command.rb +49 -1
  9. data/lib/gamefic/dispatcher.rb +8 -31
  10. data/lib/gamefic/entity.rb +26 -0
  11. data/lib/gamefic/expression.rb +3 -0
  12. data/lib/gamefic/narrative.rb +9 -5
  13. data/lib/gamefic/node.rb +3 -5
  14. data/lib/gamefic/plot.rb +5 -0
  15. data/lib/gamefic/proxy/base.rb +27 -0
  16. data/lib/gamefic/proxy/config.rb +16 -0
  17. data/lib/gamefic/proxy/pick.rb +11 -0
  18. data/lib/gamefic/proxy/plot_pick.rb +11 -0
  19. data/lib/gamefic/proxy.rb +79 -0
  20. data/lib/gamefic/query/abstract.rb +12 -0
  21. data/lib/gamefic/query/base.rb +62 -16
  22. data/lib/gamefic/query/general.rb +6 -15
  23. data/lib/gamefic/query/result.rb +4 -1
  24. data/lib/gamefic/query/scoped.rb +3 -21
  25. data/lib/gamefic/query/text.rb +17 -15
  26. data/lib/gamefic/query.rb +1 -0
  27. data/lib/gamefic/response.rb +75 -34
  28. data/lib/gamefic/scanner/base.rb +44 -0
  29. data/lib/gamefic/scanner/fuzzy.rb +17 -0
  30. data/lib/gamefic/scanner/fuzzy_nesting.rb +14 -0
  31. data/lib/gamefic/scanner/nesting.rb +39 -0
  32. data/lib/gamefic/scanner/result.rb +60 -0
  33. data/lib/gamefic/scanner/strict.rb +31 -0
  34. data/lib/gamefic/scanner.rb +33 -111
  35. data/lib/gamefic/scope/descendants.rb +16 -0
  36. data/lib/gamefic/scope/family.rb +31 -8
  37. data/lib/gamefic/scope.rb +1 -0
  38. data/lib/gamefic/scriptable/actions.rb +4 -23
  39. data/lib/gamefic/scriptable/entities.rb +32 -17
  40. data/lib/gamefic/scriptable/plot_proxies.rb +29 -0
  41. data/lib/gamefic/scriptable/proxies.rb +31 -0
  42. data/lib/gamefic/scriptable/queries.rb +27 -8
  43. data/lib/gamefic/scriptable/scenes.rb +7 -1
  44. data/lib/gamefic/scriptable.rb +78 -16
  45. data/lib/gamefic/stage.rb +2 -2
  46. data/lib/gamefic/subplot.rb +33 -1
  47. data/lib/gamefic/version.rb +1 -1
  48. data/lib/gamefic.rb +1 -1
  49. metadata +17 -4
  50. data/lib/gamefic/composer.rb +0 -70
  51. data/lib/gamefic/scriptable/proxy.rb +0 -69
@@ -7,6 +7,8 @@ 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
+
10
12
  # @return [Hash]
11
13
  attr_reader :config
12
14
 
@@ -22,7 +24,20 @@ module Gamefic
22
24
  configure
23
25
  @config.freeze
24
26
  super()
25
- [introduce].flatten.each { |pl| self.introduce pl }
27
+ @concluded = false
28
+ [introduce].flatten.each { |plyr| self.introduce plyr }
29
+ end
30
+
31
+ def self.persist!
32
+ @persistent = true
33
+ end
34
+
35
+ def self.persistent?
36
+ @persistent ||= false
37
+ end
38
+
39
+ def persistent?
40
+ self.class.persistent?
26
41
  end
27
42
 
28
43
  def included_blocks
@@ -41,6 +56,7 @@ module Gamefic
41
56
  uncast plyr
42
57
  end
43
58
  entities.each { |ent| destroy ent }
59
+ @concluded = true
44
60
  end
45
61
 
46
62
  # Make an entity that persists in the subplot's parent plot.
@@ -69,8 +85,24 @@ module Gamefic
69
85
  #
70
86
  def configure; end
71
87
 
88
+ def concluding?
89
+ return super unless persistent?
90
+
91
+ @concluded
92
+ end
93
+
94
+ def introduce player
95
+ @concluded ? player : super
96
+ end
97
+
72
98
  def inspect
73
99
  "#<#{self.class}>"
74
100
  end
101
+
102
+ class << self
103
+ def config
104
+ Proxy::Config.new
105
+ end
106
+ end
75
107
  end
76
108
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gamefic
4
- VERSION = '3.4.0'
4
+ VERSION = '3.6.0'
5
5
  end
data/lib/gamefic.rb CHANGED
@@ -17,6 +17,7 @@ require 'gamefic/command'
17
17
  require 'gamefic/action'
18
18
  require 'gamefic/props'
19
19
  require 'gamefic/scene'
20
+ require 'gamefic/proxy'
20
21
  require 'gamefic/scriptable'
21
22
  require 'gamefic/block'
22
23
  require 'gamefic/stage'
@@ -30,7 +31,6 @@ require 'gamefic/node'
30
31
  require 'gamefic/describable'
31
32
  require 'gamefic/messenger'
32
33
  require 'gamefic/entity'
33
- require 'gamefic/composer'
34
34
  require 'gamefic/dispatcher'
35
35
  require 'gamefic/active'
36
36
  require 'gamefic/active/cue'
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: 3.4.0
4
+ version: 3.6.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: 2024-09-10 00:00:00.000000000 Z
11
+ date: 2024-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -138,7 +138,6 @@ files:
138
138
  - lib/gamefic/callback.rb
139
139
  - lib/gamefic/chapter.rb
140
140
  - lib/gamefic/command.rb
141
- - lib/gamefic/composer.rb
142
141
  - lib/gamefic/core_ext/array.rb
143
142
  - lib/gamefic/core_ext/string.rb
144
143
  - lib/gamefic/describable.rb
@@ -156,7 +155,13 @@ files:
156
155
  - lib/gamefic/props/output.rb
157
156
  - lib/gamefic/props/pause.rb
158
157
  - lib/gamefic/props/yes_or_no.rb
158
+ - lib/gamefic/proxy.rb
159
+ - lib/gamefic/proxy/base.rb
160
+ - lib/gamefic/proxy/config.rb
161
+ - lib/gamefic/proxy/pick.rb
162
+ - lib/gamefic/proxy/plot_pick.rb
159
163
  - lib/gamefic/query.rb
164
+ - lib/gamefic/query/abstract.rb
160
165
  - lib/gamefic/query/base.rb
161
166
  - lib/gamefic/query/general.rb
162
167
  - lib/gamefic/query/result.rb
@@ -169,6 +174,12 @@ files:
169
174
  - lib/gamefic/rulebook/hooks.rb
170
175
  - lib/gamefic/rulebook/scenes.rb
171
176
  - lib/gamefic/scanner.rb
177
+ - lib/gamefic/scanner/base.rb
178
+ - lib/gamefic/scanner/fuzzy.rb
179
+ - lib/gamefic/scanner/fuzzy_nesting.rb
180
+ - lib/gamefic/scanner/nesting.rb
181
+ - lib/gamefic/scanner/result.rb
182
+ - lib/gamefic/scanner/strict.rb
172
183
  - lib/gamefic/scene.rb
173
184
  - lib/gamefic/scene/activity.rb
174
185
  - lib/gamefic/scene/conclusion.rb
@@ -179,6 +190,7 @@ files:
179
190
  - lib/gamefic/scope.rb
180
191
  - lib/gamefic/scope/base.rb
181
192
  - lib/gamefic/scope/children.rb
193
+ - lib/gamefic/scope/descendants.rb
182
194
  - lib/gamefic/scope/family.rb
183
195
  - lib/gamefic/scope/myself.rb
184
196
  - lib/gamefic/scope/parent.rb
@@ -187,7 +199,8 @@ files:
187
199
  - lib/gamefic/scriptable/actions.rb
188
200
  - lib/gamefic/scriptable/entities.rb
189
201
  - lib/gamefic/scriptable/events.rb
190
- - lib/gamefic/scriptable/proxy.rb
202
+ - lib/gamefic/scriptable/plot_proxies.rb
203
+ - lib/gamefic/scriptable/proxies.rb
191
204
  - lib/gamefic/scriptable/queries.rb
192
205
  - lib/gamefic/scriptable/scenes.rb
193
206
  - lib/gamefic/snapshot.rb
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Gamefic
4
- # A function module for creating commands from expressions.
5
- #
6
- module Composer
7
- # Create a command from the first expression that matches a response.
8
- #
9
- # @param actor [Actor]
10
- # @param expressions [Array<Expression>]
11
- # @return [Command]
12
- def self.compose actor, expressions
13
- %i[strict fuzzy].each do |method|
14
- result = match_expressions_to_response actor, expressions, method
15
- return result if result
16
- end
17
- Command.new(nil, [])
18
- end
19
-
20
- class << self
21
- private
22
-
23
- def match_expressions_to_response actor, expressions, method
24
- expressions.each do |expression|
25
- result = match_response_arguments actor, expression, method
26
- return result if result
27
- end
28
- nil
29
- end
30
-
31
- def match_response_arguments actor, expression, method
32
- actor.epic.responses_for(expression.verb).each do |response|
33
- next unless response.queries.length >= expression.tokens.length
34
-
35
- result = match_query_arguments(actor, expression, response, method)
36
- return result if result
37
- end
38
- nil
39
- end
40
-
41
- def match_query_arguments actor, expression, response, method
42
- remainder = response.verb ? '' : expression.verb.to_s
43
- arguments = []
44
- response.queries.each_with_index do |query, idx|
45
- result = Scanner.send(method, query.select(actor), "#{remainder} #{expression.tokens[idx]}".strip)
46
- break unless valid_result_from_query?(result, query)
47
-
48
- if query.ambiguous?
49
- arguments.push result.matched
50
- else
51
- arguments.push result.matched.first
52
- end
53
- remainder = result.remainder
54
- end
55
-
56
- return nil if arguments.length != response.queries.length || remainder != ''
57
-
58
- Command.new(response.verb, arguments)
59
- end
60
-
61
- # @param result [Scanner::Result]
62
- # @param query [Query::Base]
63
- def valid_result_from_query? result, query
64
- return false if result.matched.empty?
65
-
66
- result.matched.length == 1 || query.ambiguous?
67
- end
68
- end
69
- end
70
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Gamefic
4
- module Scriptable
5
- # Functions that provide proxies for referencing a narrative's entities
6
- # from class-level scripts.
7
- #
8
- module Proxy
9
- # The object that fetches a proxied entity.
10
- #
11
- class Agent
12
- attr_reader :symbol
13
-
14
- # @param symbol [Symbol, Integer]
15
- def initialize symbol
16
- @symbol = symbol
17
- end
18
-
19
- def fetch container
20
- result = safe_fetch(container)
21
- raise ArgumentError, "Unable to fetch entity from proxy agent symbol `#{symbol}`" unless result
22
-
23
- result
24
- end
25
-
26
- private
27
-
28
- def safe_fetch container
29
- if symbol.to_s =~ /^\d+$/
30
- Stage.run(container, symbol) { |sym| entities[sym] }
31
- elsif symbol.to_s.start_with?('@')
32
- Stage.run(container, symbol) { |sym| instance_variable_get(sym) }
33
- else
34
- Stage.run(container, symbol) { |sym| send(sym) }
35
- end
36
- rescue NoMethodError
37
- nil
38
- end
39
- end
40
-
41
- # Proxy a method or instance variable.
42
- #
43
- # @example
44
- # proxy(:method_name)
45
- # proxy(:@instance_variable_name)
46
- #
47
- # @param symbol [Symbol]
48
- # @return [Agent]
49
- def proxy symbol
50
- Agent.new(symbol)
51
- end
52
-
53
- # @param object [Object]
54
- # @return [Object]
55
- def unproxy object
56
- case object
57
- when Agent
58
- object.fetch self
59
- when Array
60
- object.map { |obj| unproxy obj }
61
- when Hash
62
- object.transform_values { |val| unproxy val }
63
- else
64
- object
65
- end
66
- end
67
- end
68
- end
69
- end