gamefic 1.6.0 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +16 -0
  5. data/.solargraph.yml +5 -0
  6. data/CHANGELOG.md +6 -0
  7. data/Gemfile +7 -0
  8. data/LICENSE +20 -0
  9. data/README.md +28 -0
  10. data/Rakefile +10 -0
  11. data/gamefic.gemspec +27 -0
  12. data/lib/gamefic.rb +11 -8
  13. data/lib/gamefic/action.rb +68 -58
  14. data/lib/gamefic/active.rb +331 -0
  15. data/lib/gamefic/actor.rb +8 -0
  16. data/lib/gamefic/command.rb +9 -7
  17. data/lib/gamefic/core_ext/array.rb +27 -49
  18. data/lib/gamefic/core_ext/string.rb +25 -16
  19. data/lib/gamefic/describable.rb +37 -22
  20. data/lib/gamefic/element.rb +47 -0
  21. data/lib/gamefic/entity.rb +24 -48
  22. data/lib/gamefic/{matchable.rb → keywords.rb} +52 -50
  23. data/lib/gamefic/messaging.rb +43 -45
  24. data/lib/gamefic/node.rb +14 -5
  25. data/lib/gamefic/plot.rb +73 -85
  26. data/lib/gamefic/plot/darkroom.rb +80 -0
  27. data/lib/gamefic/plot/host.rb +42 -46
  28. data/lib/gamefic/plot/snapshot.rb +14 -214
  29. data/lib/gamefic/query.rb +15 -17
  30. data/lib/gamefic/query/base.rb +51 -42
  31. data/lib/gamefic/query/children.rb +0 -0
  32. data/lib/gamefic/query/descendants.rb +2 -2
  33. data/lib/gamefic/query/external.rb +18 -0
  34. data/lib/gamefic/query/family.rb +3 -7
  35. data/lib/gamefic/query/matches.rb +75 -67
  36. data/lib/gamefic/query/parent.rb +0 -0
  37. data/lib/gamefic/query/siblings.rb +0 -0
  38. data/lib/gamefic/query/text.rb +12 -12
  39. data/lib/gamefic/query/tree.rb +17 -0
  40. data/lib/gamefic/scene.rb +1 -5
  41. data/lib/gamefic/scene/{active.rb → activity.rb} +4 -6
  42. data/lib/gamefic/scene/base.rb +77 -13
  43. data/lib/gamefic/scene/conclusion.rb +0 -2
  44. data/lib/gamefic/scene/custom.rb +0 -2
  45. data/lib/gamefic/scene/multiple_choice.rb +18 -16
  46. data/lib/gamefic/scene/multiple_scene.rb +29 -20
  47. data/lib/gamefic/scene/pause.rb +7 -2
  48. data/lib/gamefic/scene/yes_or_no.rb +21 -9
  49. data/lib/gamefic/scriptable.rb +88 -0
  50. data/lib/gamefic/serialize.rb +223 -0
  51. data/lib/gamefic/subplot.rb +47 -51
  52. data/lib/gamefic/syntax.rb +15 -13
  53. data/lib/gamefic/version.rb +3 -3
  54. data/lib/gamefic/world.rb +18 -0
  55. data/lib/gamefic/world/callbacks.rb +135 -0
  56. data/lib/gamefic/world/commands.rb +184 -0
  57. data/lib/gamefic/world/entities.rb +98 -0
  58. data/lib/gamefic/{plot → world}/playbook.rb +245 -236
  59. data/lib/gamefic/world/players.rb +37 -0
  60. data/lib/gamefic/world/scenes.rb +226 -0
  61. metadata +40 -108
  62. data/bin/gamefic +0 -9
  63. data/lib/gamefic/character.rb +0 -232
  64. data/lib/gamefic/character/state.rb +0 -12
  65. data/lib/gamefic/engine.rb +0 -7
  66. data/lib/gamefic/engine/base.rb +0 -66
  67. data/lib/gamefic/engine/tty.rb +0 -24
  68. data/lib/gamefic/grammar.rb +0 -13
  69. data/lib/gamefic/grammar/conjugator.rb +0 -20
  70. data/lib/gamefic/grammar/gender.rb +0 -11
  71. data/lib/gamefic/grammar/person.rb +0 -10
  72. data/lib/gamefic/grammar/plural.rb +0 -13
  73. data/lib/gamefic/grammar/pronouns.rb +0 -105
  74. data/lib/gamefic/grammar/tense.rb +0 -6
  75. data/lib/gamefic/grammar/verb_set.rb +0 -43
  76. data/lib/gamefic/grammar/verbs.rb +0 -26
  77. data/lib/gamefic/grammar/word_adapter.rb +0 -49
  78. data/lib/gamefic/plot/articles.rb +0 -22
  79. data/lib/gamefic/plot/callbacks.rb +0 -127
  80. data/lib/gamefic/plot/commands.rb +0 -121
  81. data/lib/gamefic/plot/entities.rb +0 -88
  82. data/lib/gamefic/plot/players.rb +0 -15
  83. data/lib/gamefic/plot/scenes.rb +0 -149
  84. data/lib/gamefic/plot/theater.rb +0 -73
  85. data/lib/gamefic/plot/you_mount.rb +0 -22
  86. data/lib/gamefic/script.rb +0 -13
  87. data/lib/gamefic/script/base.rb +0 -42
  88. data/lib/gamefic/script/file.rb +0 -14
  89. data/lib/gamefic/script/text.rb +0 -14
  90. data/lib/gamefic/shell.rb +0 -76
  91. data/lib/gamefic/source.rb +0 -14
  92. data/lib/gamefic/source/base.rb +0 -12
  93. data/lib/gamefic/source/file.rb +0 -23
  94. data/lib/gamefic/source/text.rb +0 -16
  95. data/lib/gamefic/tester.rb +0 -19
  96. data/lib/gamefic/text.rb +0 -8
  97. data/lib/gamefic/text/ansi.rb +0 -53
  98. data/lib/gamefic/text/html.rb +0 -68
  99. data/lib/gamefic/text/html/conversions.rb +0 -250
  100. data/lib/gamefic/text/html/entities.rb +0 -9
  101. data/lib/gamefic/tty.rb +0 -10
  102. data/lib/gamefic/user.rb +0 -8
  103. data/lib/gamefic/user/base.rb +0 -15
  104. data/lib/gamefic/user/buffer.rb +0 -32
  105. data/lib/gamefic/user/tty.rb +0 -54
@@ -1,36 +1,37 @@
1
1
  require 'gamefic/plot'
2
2
 
3
3
  module Gamefic
4
+ class Subplot #< Container
5
+ include World
6
+ include Scriptable
7
+ include Gamefic::Serialize
8
+ # @!parse extend Scriptable::ClassMethods
4
9
 
5
- class Subplot
10
+ # @return [Gamefic::Plot]
6
11
  attr_reader :plot
7
- attr_writer :denied_message
8
12
 
9
- include Plot::Theater
10
- include Plot::Entities
11
- include Plot::Commands
12
- include Plot::Callbacks
13
- include Plot::Scenes
14
- include Plot::Articles
15
-
16
- class << self
17
- attr_reader :start_proc
18
-
19
- protected
20
-
21
- def on_start &block
22
- @start_proc = block
23
- end
24
- end
25
-
26
- def initialize plot, introduce: nil, next_cue: nil, busy_cue: nil
13
+ # @param plot [Gamefic::Plot]
14
+ # @param introduce [Gamefic::Actor, nil]
15
+ # @param next_cue [Class<Gamefic::Scene::Base>, nil]
16
+ # @param more [Hash]
17
+ def initialize plot, introduce: nil, next_cue: nil, **more
27
18
  @plot = plot
28
19
  @next_cue = next_cue
29
- @busy_cue = busy_cue
30
20
  @concluded = false
31
- stage &self.class.start_proc unless self.class.start_proc.nil?
21
+ @more = more
22
+ configure more
23
+ run_scripts
32
24
  playbook.freeze
33
25
  self.introduce introduce unless introduce.nil?
26
+ @static = [self] + scene_classes + entities
27
+ end
28
+
29
+ def static
30
+ plot.static
31
+ end
32
+
33
+ def players
34
+ @players ||= []
34
35
  end
35
36
 
36
37
  def subplot
@@ -46,44 +47,31 @@ module Gamefic
46
47
  end
47
48
 
48
49
  def playbook
49
- @playbook ||= plot.playbook.dup
50
- end
51
-
52
- # HACK: Always assume subplots are running for the sake of entity destruction
53
- def running?
54
- true
55
- end
56
-
57
- def denied_message
58
- @denied_message ||= 'You are already involved in another subplot.'
50
+ @playbook ||= Gamefic::Plot::Playbook.new
59
51
  end
60
52
 
61
- def introduce player
62
- if plot.in_subplot?(player)
63
- if @busy_cue.nil?
64
- player.tell denied_message
65
- else
66
- player.cue @busy_cue
67
- end
68
- else
69
- super
70
- end
53
+ def cast cls, args = {}, &block
54
+ ent = super
55
+ ent.playbooks.push plot.playbook unless ent.playbooks.include?(plot.playbook)
56
+ ent
71
57
  end
72
58
 
73
59
  def exeunt player
74
- player.playbook = plot.playbook
60
+ player_conclude_procs.each { |block| block.call player }
61
+ player.playbooks.delete playbook
75
62
  player.cue (@next_cue || default_scene)
76
- p_players.delete player
63
+ players.delete player
77
64
  end
78
65
 
79
66
  def conclude
80
67
  @concluded = true
81
- entities.each { |e|
82
- destroy e
83
- }
84
- players.each { |p|
85
- exeunt p
86
- }
68
+ # Players needed to exit first in case any player_conclude procs need to
69
+ # interact with the subplot's entities.
70
+ players.each { |p| exeunt p }
71
+ # @todo I'm not sure why rejecting nils is necessary here. It's only an
72
+ # issue in Opal.
73
+ entities.reject(&:nil?).each { |e| destroy e }
74
+ # plot.static.remove(scene_classes + entities)
87
75
  end
88
76
 
89
77
  def concluded?
@@ -91,6 +79,9 @@ module Gamefic
91
79
  end
92
80
 
93
81
  def ready
82
+ # @todo We might not want to conclude subplots without players. There
83
+ # might be cases where a subplot gets created with the intention of
84
+ # introducing players in a later turn.
94
85
  conclude if players.empty?
95
86
  return if concluded?
96
87
  playbook.freeze
@@ -102,6 +93,11 @@ module Gamefic
102
93
  call_player_update
103
94
  call_update
104
95
  end
105
- end
106
96
 
97
+ # Subclasses can override this method to handle additional configuration
98
+ # options.
99
+ #
100
+ def configure more
101
+ end
102
+ end
107
103
  end
@@ -1,11 +1,9 @@
1
1
  require 'gamefic/command'
2
2
 
3
3
  module Gamefic
4
-
5
4
  class Syntax
6
5
  attr_reader :token_count, :first_word, :verb, :template, :command
7
- @@phrase = '([\w\W\s\S]*?)'
8
-
6
+
9
7
  def initialize template, command
10
8
  words = template.split_words
11
9
  @token_count = words.length
@@ -15,8 +13,8 @@ module Gamefic
15
13
  @token_count -= 1
16
14
  @first_word = ''
17
15
  else
18
- @verb = command_words[0].to_sym if !command_words[0].nil?
19
16
  @first_word = words[0].to_s
17
+ @verb = command_words[0].to_sym
20
18
  end
21
19
  @command = command_words.join(' ')
22
20
  @template = words.join(' ')
@@ -29,7 +27,7 @@ module Gamefic
29
27
  if last_token_is_reg
30
28
  next
31
29
  else
32
- tokens.push @@phrase
30
+ tokens.push '([\w\W\s\S]*?)'
33
31
  last_token_is_reg = true
34
32
  end
35
33
  else
@@ -50,11 +48,11 @@ module Gamefic
50
48
  @replace = subs.join(' ')
51
49
  @regexp = Regexp.new("^#{tokens.join(' ')}$", Regexp::IGNORECASE)
52
50
  end
53
-
51
+
54
52
  # Convert a String into a Command.
55
53
  #
56
54
  # @param text [String]
57
- # @return [Command]
55
+ # @return [Gamefic::Command]
58
56
  def tokenize text
59
57
  m = text.match(@regexp)
60
58
  return nil if m.nil?
@@ -71,7 +69,11 @@ module Gamefic
71
69
  }
72
70
  Command.new @verb, arguments
73
71
  end
74
-
72
+
73
+ # Determine if the specified text matches the syntax's expected pattern.
74
+ #
75
+ # @param text [String]
76
+ # @return [Boolean]
75
77
  def accept? text
76
78
  !text.match(@regexp).nil?
77
79
  end
@@ -82,16 +84,17 @@ module Gamefic
82
84
  def signature
83
85
  [@regexp, @replace]
84
86
  end
85
-
87
+
86
88
  def ==(other)
89
+ return false unless other.is_a?(Syntax)
87
90
  signature == other.signature
88
91
  end
89
-
92
+
90
93
  # Tokenize an Array of Commands from the specified text.
91
94
  #
92
95
  # @param text [String] The text to tokenize.
93
- # @param syntaxes [Array<Syntax>] The Syntaxes to use.
94
- # @return [Array<Command>] The tokenized commands.
96
+ # @param syntaxes [Array<Gamefic::Syntax>] The Syntaxes to use.
97
+ # @return [Array<Gamefic::Command>] The tokenized commands.
95
98
  def self.tokenize text, syntaxes
96
99
  matches = []
97
100
  syntaxes.each { |syntax|
@@ -108,5 +111,4 @@ module Gamefic
108
111
  matches
109
112
  end
110
113
  end
111
-
112
114
  end
@@ -1,3 +1,3 @@
1
- module Gamefic
2
- VERSION = '1.6.0'
3
- end
1
+ module Gamefic
2
+ VERSION = '2.0.3'
3
+ end
@@ -0,0 +1,18 @@
1
+ module Gamefic
2
+ # A collection of classes and modules related to generating a world model.
3
+ #
4
+ module World
5
+ autoload :Playbook, 'gamefic/world/playbook'
6
+ autoload :Entities, 'gamefic/world/entities'
7
+ autoload :Commands, 'gamefic/world/commands'
8
+ autoload :Callbacks, 'gamefic/world/callbacks'
9
+ autoload :Scenes, 'gamefic/world/scenes'
10
+ autoload :Players, 'gamefic/world/players'
11
+
12
+ include Entities
13
+ include Commands
14
+ include Callbacks
15
+ include Scenes
16
+ include Players
17
+ end
18
+ end
@@ -0,0 +1,135 @@
1
+ module Gamefic
2
+ module World
3
+ module Callbacks
4
+ # Add a block to be executed on preparation of every turn.
5
+ #
6
+ # @example Increment a turn counter
7
+ # turn = 0
8
+ # on_ready do
9
+ # turn += 1
10
+ # end
11
+ #
12
+ def on_ready &block
13
+ ready_procs.push block
14
+ end
15
+
16
+ # Add a block to be executed after the Plot is finished updating a turn.
17
+ #
18
+ def on_update &block
19
+ update_procs.push block
20
+ end
21
+
22
+ # Add a block to be executed for each player at the beginning of a turn.
23
+ #
24
+ # @example Tell the player how many turns they've played.
25
+ # on_player_ready do |player|
26
+ # player[:turns] ||= 0
27
+ # if player[:turns] > 0
28
+ # player.tell "Turn #{player[:turns]}"
29
+ # end
30
+ # player[:turns] += 1
31
+ # end
32
+ #
33
+ # @yieldparam [Gamefic::Actor]
34
+ def on_player_ready &block
35
+ player_ready_procs.push block
36
+ end
37
+
38
+ # Add a block to be executed for each player before an update.
39
+ #
40
+ # @yieldparam[Gamefic::Actor]
41
+ def before_player_update &block
42
+ before_player_update_procs.push block
43
+ end
44
+
45
+ # Add a block to be executed for each player at the end of a turn.
46
+ #
47
+ # @yieldparam [Gamefic::Actor]
48
+ def on_player_update &block
49
+ player_update_procs.push block
50
+ end
51
+
52
+ # Add a block to be executed at the conclusion of the plot.
53
+ #
54
+ # @yieldparam [Gamefic::Actor]
55
+ def on_player_conclude &block
56
+ player_conclude_procs.push block
57
+ end
58
+
59
+ def player_conclude_procs
60
+ @player_conclude_procs ||= []
61
+ end
62
+
63
+ def ready_procs
64
+ @ready_procs ||= []
65
+ end
66
+
67
+ def update_procs
68
+ @update_procs ||= []
69
+ end
70
+
71
+ def player_ready_procs
72
+ @player_ready_procs ||= []
73
+ end
74
+
75
+ def before_player_update_procs
76
+ @before_player_update_procs ||= []
77
+ end
78
+
79
+ def player_update_procs
80
+ @player_update_procs ||= []
81
+ end
82
+
83
+ private
84
+
85
+ # Execute the on_ready blocks. This method is typically called by the
86
+ # Plot while beginning a turn.
87
+ #
88
+ def call_ready
89
+ ready_procs.each { |p| p.call }
90
+ end
91
+
92
+ # Execute the on_update blocks. This method is typically called by the
93
+ # Plot while ending a turn.
94
+ #
95
+ def call_update
96
+ update_procs.each { |p| p.call }
97
+ end
98
+
99
+ # Execute the before_player_update blocks for each player. This method is
100
+ # typically called by the Plot while updating a turn, immediately before
101
+ # processing player input.
102
+ #
103
+ def call_before_player_update
104
+ players.each { |player|
105
+ player.flush
106
+ before_player_update_procs.each { |block| block.call player }
107
+ }
108
+ end
109
+
110
+ # Execute the on_player_ready blocks for each player. This method is
111
+ # typically called by the Plot while beginning a turn, immediately after
112
+ # the on_ready blocks.
113
+ #
114
+ def call_player_ready
115
+ players.each { |player|
116
+ unless player.next_scene.nil? || !player.scene.finished?
117
+ player.cue player.next_scene, **player.next_options
118
+ end
119
+ player.cue default_scene if player.scene.nil?
120
+ player_ready_procs.each { |block| block.call player }
121
+ }
122
+ end
123
+
124
+ # Execute the on_player_update blocks for each player. This method is
125
+ # typically called by the Plot while ending a turn, immediately before the
126
+ # on_ready blocks.
127
+ #
128
+ def call_player_update
129
+ players.each { |player|
130
+ player_update_procs.each { |block| block.call player }
131
+ }
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,184 @@
1
+ require 'gamefic/action'
2
+
3
+ module Gamefic
4
+ module World
5
+ module Commands
6
+ include Gamefic::World::Entities
7
+
8
+ # @return [Gamefic::World::Playbook]
9
+ def playbook
10
+ @playbook ||= Gamefic::World::Playbook.new
11
+ end
12
+
13
+ # Create an Action that responds to a command.
14
+ # An Action uses the command argument to identify the imperative verb that
15
+ # triggers the action.
16
+ # It can also accept queries to tokenize the remainder of the input and
17
+ # filter for particular entities or properties.
18
+ # The block argument contains the code to be executed when the input
19
+ # matches all of the Action's criteria (i.e., verb and queries).
20
+ #
21
+ # @example A simple Action.
22
+ # respond :salute do |actor|
23
+ # actor.tell "Hello, sir!"
24
+ # end
25
+ # # The command "salute" will respond "Hello, sir!"
26
+ #
27
+ # @example An Action that accepts a Character
28
+ # respond :salute, Use.visible(Character) do |actor, character|
29
+ # actor.tell "#{The character} returns your salute."
30
+ # end
31
+ #
32
+ # @param command [Symbol] An imperative verb for the command
33
+ # @param queries [Array<Query::Base>] Filters for the command's tokens
34
+ # @yieldparam [Gamefic::Actor]
35
+ # @return [Class] The resulting Action subclass
36
+ def respond(command, *queries, &proc)
37
+ playbook.respond(command, *map_response_args(queries), &proc)
38
+ end
39
+ alias action respond
40
+
41
+ # Parse a verb and a list of arguments into an action.
42
+ # This method serves as a shortcut to creating an action with one or more
43
+ # arguments that identify specific entities.
44
+ #
45
+ # @example
46
+ # @thing = make Entity, name: 'a thing'
47
+ # parse "use", "the thing" do |actor, thing|
48
+ # actor.tell "You use it."
49
+ # end
50
+ #
51
+ # @raise [ArgumentError] if tokens are unrecognized or ambiguous
52
+ #
53
+ # @param verb [String, Symbol] The command's verb
54
+ # @param tokens [Array<String>] The arguments passed to the action
55
+ # @return [Class] The resulting Action subclass
56
+ def parse verb, *tokens, &proc
57
+ query = Query::External.new(entities)
58
+ params = []
59
+ tokens.each do |arg|
60
+ matches = query.resolve(nil, arg)
61
+ raise ArgumentError, "Unable to resolve token '#{arg}'" if matches.objects.empty?
62
+ raise ArgumentError, "Ambiguous results for '#{arg}'" if matches.objects.length > 1
63
+ params.push Query::Family.new(matches.objects[0])
64
+ end
65
+ respond(verb.to_sym, *params, &proc)
66
+ end
67
+
68
+ # Tokenize and parse a command to create a new Action subclass.
69
+ #
70
+ # @param command [String] The command
71
+ # @yieldparam [Gamefic::Actor]
72
+ # @return [Class] the resulting Action subclass
73
+ def override(command, &proc)
74
+ cmd = Syntax.tokenize(command, playbook.syntaxes).first
75
+ raise "Unable to tokenize command '#{command}'" if cmd.nil?
76
+ parse cmd.verb, *cmd.arguments, &proc
77
+ end
78
+
79
+ # Create a Meta Action that responds to a command.
80
+ # Meta Actions are very similar to standard Actions, except the Plot
81
+ # understands them to be commands that operate above and/or outside of the
82
+ # actual game world. Examples of Meta Actions are commands that report the
83
+ # player's current score, save and restore saved games, or list the game's
84
+ # credits.
85
+ #
86
+ # @example A simple Meta Action
87
+ # meta :credits do |actor|
88
+ # actor.tell "This game was written by John Smith."
89
+ # end
90
+ #
91
+ # @param command [Symbol] An imperative verb for the command
92
+ # @param queries [Array<Query::Base>] Filters for the command's tokens
93
+ # @yieldparam [Gamefic::Actor]
94
+ def meta(command, *queries, &proc)
95
+ playbook.meta command, *queries, &proc
96
+ end
97
+
98
+ # Declare a dismabiguation response for actions.
99
+ # The disambiguator is executed when an action expects an argument to
100
+ # reference a specific entity but its query matched more than one. For
101
+ # example, "red" might refer to either a red key or a red book.
102
+ #
103
+ # If a disambiguator is not defined, the playbook will use its default
104
+ # implementation.
105
+ #
106
+ # @example Tell the player the list of ambiguous entities.
107
+ # disambiguate do |actor, entities|
108
+ # actor.tell "I don't know which you mean: #{entities.join_or}."
109
+ # end
110
+ #
111
+ # @yieldparam [Gamefic::Actor]
112
+ # @yieldparam [Array<Gamefic::Entity>]
113
+ def disambiguate &block
114
+ playbook.disambiguate &block
115
+ end
116
+
117
+ # Validate an order before a character can execute its command.
118
+ #
119
+ # @yieldparam [Gamefic::Director::Order]
120
+ def validate &block
121
+ playbook.validate &block
122
+ end
123
+
124
+ # Create an alternate Syntax for an Action.
125
+ # The command and its translation can be parameterized.
126
+ #
127
+ # @example Create a synonym for the Inventory Action.
128
+ # interpret "catalogue", "inventory"
129
+ # # The command "catalogue" will be translated to "inventory"
130
+ #
131
+ # @example Create a parameterized synonym for the Look Action.
132
+ # interpret "scrutinize :entity", "look :entity"
133
+ # # The command "scrutinize chair" will be translated to "look chair"
134
+ #
135
+ # @param command [String] The format of the original command
136
+ # @param translation [String] The format of the translated command
137
+ # @return [Syntax] the Syntax object
138
+ def interpret command, translation
139
+ playbook.interpret command, translation
140
+ end
141
+ alias xlate interpret
142
+
143
+ # Get an Array of available verbs.
144
+ #
145
+ # @return [Array<String>]
146
+ def verbs
147
+ playbook.verbs.map(&:to_s).reject { |v| v.start_with?('_') }
148
+ end
149
+
150
+ # Get an Array of all Actions defined in the Plot.
151
+ #
152
+ # @return [Array<Action>]
153
+ def actions
154
+ playbook.actions
155
+ end
156
+
157
+ def get_default_query
158
+ @default_query_class ||= Gamefic::Query::Family
159
+ end
160
+
161
+ def set_default_query cls
162
+ @default_query_class = cls
163
+ end
164
+
165
+ private
166
+
167
+ # @param queries [Array]
168
+ # @return [Array<Query::Base>]
169
+ def map_response_args queries
170
+ queries.map do |q|
171
+ if q.is_a?(Regexp)
172
+ Gamefic::Query::Text.new(q)
173
+ elsif q.is_a?(Gamefic::Query::Base)
174
+ q
175
+ elsif q.is_a?(Gamefic::Element) || (q.is_a?(Class) && q <= Gamefic::Element)
176
+ get_default_query.new(q)
177
+ else
178
+ raise ArgumentError.new("Invalid argument for response: #{q}")
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end