gamefic 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/gamefic.rb +1 -3
  3. data/lib/gamefic/action.rb +140 -79
  4. data/lib/gamefic/character.rb +120 -53
  5. data/lib/gamefic/character/state.rb +12 -0
  6. data/lib/gamefic/core_ext/array.rb +53 -11
  7. data/lib/gamefic/core_ext/string.rb +1 -0
  8. data/lib/gamefic/describable.rb +37 -11
  9. data/lib/gamefic/engine/base.rb +17 -4
  10. data/lib/gamefic/engine/tty.rb +4 -0
  11. data/lib/gamefic/entity.rb +4 -15
  12. data/lib/gamefic/matchable.rb +50 -0
  13. data/lib/gamefic/messaging.rb +45 -0
  14. data/lib/gamefic/node.rb +16 -0
  15. data/lib/gamefic/plot.rb +27 -33
  16. data/lib/gamefic/plot/{article_mount.rb → articles.rb} +22 -22
  17. data/lib/gamefic/plot/callbacks.rb +30 -4
  18. data/lib/gamefic/plot/{command_mount.rb → commands.rb} +121 -121
  19. data/lib/gamefic/plot/entities.rb +3 -3
  20. data/lib/gamefic/plot/host.rb +3 -3
  21. data/lib/gamefic/plot/playbook.rb +74 -30
  22. data/lib/gamefic/plot/scenes.rb +149 -0
  23. data/lib/gamefic/plot/snapshot.rb +14 -39
  24. data/lib/gamefic/plot/theater.rb +73 -0
  25. data/lib/gamefic/query.rb +6 -19
  26. data/lib/gamefic/query/base.rb +127 -246
  27. data/lib/gamefic/query/children.rb +6 -7
  28. data/lib/gamefic/query/descendants.rb +15 -0
  29. data/lib/gamefic/query/family.rb +19 -7
  30. data/lib/gamefic/query/itself.rb +13 -0
  31. data/lib/gamefic/query/matches.rb +67 -11
  32. data/lib/gamefic/query/parent.rb +6 -7
  33. data/lib/gamefic/query/siblings.rb +10 -7
  34. data/lib/gamefic/query/text.rb +39 -35
  35. data/lib/gamefic/scene.rb +1 -1
  36. data/lib/gamefic/scene/active.rb +12 -6
  37. data/lib/gamefic/scene/base.rb +56 -5
  38. data/lib/gamefic/scene/conclusion.rb +3 -0
  39. data/lib/gamefic/scene/custom.rb +0 -83
  40. data/lib/gamefic/scene/multiple_choice.rb +54 -32
  41. data/lib/gamefic/scene/multiple_scene.rb +11 -6
  42. data/lib/gamefic/scene/pause.rb +3 -4
  43. data/lib/gamefic/scene/yes_or_no.rb +23 -9
  44. data/lib/gamefic/script/base.rb +4 -0
  45. data/lib/gamefic/subplot.rb +22 -19
  46. data/lib/gamefic/syntax.rb +7 -15
  47. data/lib/gamefic/user/base.rb +7 -13
  48. data/lib/gamefic/user/buffer.rb +7 -0
  49. data/lib/gamefic/user/tty.rb +13 -12
  50. data/lib/gamefic/version.rb +1 -1
  51. metadata +11 -37
  52. data/lib/gamefic/director.rb +0 -23
  53. data/lib/gamefic/director/delegate.rb +0 -126
  54. data/lib/gamefic/director/order.rb +0 -17
  55. data/lib/gamefic/director/parser.rb +0 -137
  56. data/lib/gamefic/keywords.rb +0 -67
  57. data/lib/gamefic/plot/query_mount.rb +0 -9
  58. data/lib/gamefic/plot/scene_mount.rb +0 -182
  59. data/lib/gamefic/query/ambiguous_children.rb +0 -5
  60. data/lib/gamefic/query/expression.rb +0 -47
  61. data/lib/gamefic/query/many_children.rb +0 -7
  62. data/lib/gamefic/query/plural_children.rb +0 -14
  63. data/lib/gamefic/query/self.rb +0 -10
  64. data/lib/gamefic/scene_data.rb +0 -10
  65. data/lib/gamefic/scene_data/base.rb +0 -12
  66. data/lib/gamefic/scene_data/multiple_choice.rb +0 -19
  67. data/lib/gamefic/scene_data/multiple_scene.rb +0 -21
  68. data/lib/gamefic/scene_data/yes_or_no.rb +0 -18
  69. data/lib/gamefic/serialized.rb +0 -24
  70. data/lib/gamefic/stage.rb +0 -106
data/lib/gamefic/plot.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # TODO: JSON support is currently experimental.
2
2
  #require 'gamefic/entityloader'
3
- require 'gamefic/stage'
4
3
  require 'gamefic/tester'
5
4
  require 'gamefic/source'
6
5
  require 'gamefic/script'
@@ -9,39 +8,37 @@ require 'gamefic/query'
9
8
  module Gamefic
10
9
 
11
10
  class Plot
12
- autoload :SceneMount, 'gamefic/plot/scene_mount'
13
- autoload :CommandMount, 'gamefic/plot/command_mount'
14
- autoload :Entities, 'gamefic/plot/entities'
15
- autoload :ArticleMount, 'gamefic/plot/article_mount'
16
- autoload :YouMount, 'gamefic/plot/you_mount'
17
- autoload :Snapshot, 'gamefic/plot/snapshot'
18
- autoload :Host, 'gamefic/plot/host'
19
- autoload :Players, 'gamefic/plot/players'
20
- autoload :Playbook, 'gamefic/plot/playbook'
21
- autoload :Callbacks, 'gamefic/plot/callbacks'
11
+ autoload :Scenes, 'gamefic/plot/scenes'
12
+ autoload :Commands, 'gamefic/plot/commands'
13
+ autoload :Entities, 'gamefic/plot/entities'
14
+ autoload :Articles, 'gamefic/plot/articles'
15
+ autoload :YouMount, 'gamefic/plot/you_mount'
16
+ autoload :Snapshot, 'gamefic/plot/snapshot'
17
+ autoload :Host, 'gamefic/plot/host'
18
+ autoload :Players, 'gamefic/plot/players'
19
+ autoload :Playbook, 'gamefic/plot/playbook'
20
+ autoload :Callbacks, 'gamefic/plot/callbacks'
21
+ autoload :Theater, 'gamefic/plot/theater'
22
22
 
23
23
  attr_reader :commands, :imported_scripts, :source
24
24
  # TODO: Metadata could use better protection
25
25
  attr_accessor :metadata
26
- include Stage
27
- # @!parse include Gamefic, Tester, Players, SceneMount, CommandMount, Entities
28
- mount Gamefic, Tester, Players, SceneMount, CommandMount, Entities
29
- # @!parse include ArticleMount, YouMount, Snapshot, Host, Callbacks
30
- mount ArticleMount, YouMount, Snapshot, Host, Callbacks
31
- expose :script, :metadata
26
+ include Theater
27
+ include Gamefic, Tester, Players, Scenes, Commands, Entities
28
+ include Articles, YouMount, Snapshot, Host, Callbacks
32
29
 
33
- # @param [Source::Base]
30
+ # @param source [Source::Base]
34
31
  def initialize(source = nil)
35
32
  @source = source || Source::Text.new({})
36
33
  @working_scripts = []
37
34
  @imported_scripts = []
38
35
  @running = false
39
- @playbook = Playbook.new
40
36
  post_initialize
41
37
  end
42
38
 
39
+ # @return [Gamefic::Plot::Playbook]
43
40
  def playbook
44
- @playbook ||= Playbook.new
41
+ @playbook ||= Gamefic::Plot::Playbook.new
45
42
  end
46
43
 
47
44
  def running?
@@ -79,7 +76,9 @@ module Gamefic
79
76
  # Update the Plot's current turn of gameplay.
80
77
  # This method is typically called by the Engine that manages game execution.
81
78
  def update
82
- p_players.each { |p| process_input p }
79
+ entities.each { |e| e.flush }
80
+ call_before_player_update
81
+ p_players.each { |p| p.scene.update }
83
82
  p_entities.each { |e| e.update }
84
83
  call_player_update
85
84
  call_update
@@ -106,24 +105,19 @@ module Gamefic
106
105
  end
107
106
  if !@working_scripts.include?(imported_script) and !imported_scripts.include?(imported_script)
108
107
  @working_scripts.push imported_script
109
- stage imported_script.read, imported_script.absolute_path
108
+ # @hack Arguments need to be in different order if source returns proc
109
+ if imported_script.read.kind_of?(Proc)
110
+ stage &imported_script.read
111
+ else
112
+ stage imported_script.read, imported_script.absolute_path
113
+ end
110
114
  @working_scripts.pop
111
115
  imported_scripts.push imported_script
112
116
  true
113
117
  else
114
118
  false
115
119
  end
116
- end
117
-
118
- private
119
-
120
- def process_input player
121
- line = player.queue.shift
122
- if !line.nil?
123
- player.scene.finish player, line
124
- end
125
- end
126
-
120
+ end
127
121
  end
128
122
 
129
123
  end
@@ -1,22 +1,22 @@
1
- module Gamefic
2
- module Plot::ArticleMount
3
- def a(entity)
4
- entity.indefinitely
5
- end
6
- def an(entity)
7
- entity.indefinitely
8
- end
9
- def the(entity)
10
- entity.definitely
11
- end
12
- def A(entity)
13
- entity.indefinitely.cap_first
14
- end
15
- def An(entity)
16
- entity.indefinitely.cap_first
17
- end
18
- def The(entity)
19
- entity.definitely.cap_first
20
- end
21
- end
22
- end
1
+ module Gamefic
2
+ module Plot::Articles
3
+ def a(entity)
4
+ entity.indefinitely
5
+ end
6
+ def an(entity)
7
+ entity.indefinitely
8
+ end
9
+ def the(entity)
10
+ entity.definitely
11
+ end
12
+ def A(entity)
13
+ entity.indefinitely.cap_first
14
+ end
15
+ def An(entity)
16
+ entity.indefinitely.cap_first
17
+ end
18
+ def The(entity)
19
+ entity.definitely.cap_first
20
+ end
21
+ end
22
+ end
@@ -1,6 +1,6 @@
1
1
  module Gamefic
2
2
 
3
- module Plot::Callbacks
3
+ module Plot::Callbacks
4
4
  # Add a block to be executed on preparation of every turn.
5
5
  #
6
6
  # @example Increment a turn counter
@@ -35,6 +35,13 @@ module Gamefic
35
35
  p_player_ready_procs.push block
36
36
  end
37
37
 
38
+ # Add a block to be executed for each player before an update.
39
+ #
40
+ # @yieldparam[Character]
41
+ def before_player_update &block
42
+ p_before_player_update_procs.push block
43
+ end
44
+
38
45
  # Add a block to be executed for each player at the end of a turn.
39
46
  #
40
47
  # @yieldparam [Character]
@@ -58,15 +65,29 @@ module Gamefic
58
65
  p_update_procs.each { |p| p.call }
59
66
  end
60
67
 
68
+ # Execute the before_player_update blocks for each player. This method is
69
+ # typically called by the Plot while updating a turn, immediately before
70
+ # processing player input.
71
+ #
72
+ def call_before_player_update
73
+ p_players.each { |player|
74
+ player.flush
75
+ p_before_player_update_procs.each { |block| block.call player }
76
+ }
77
+ end
78
+
61
79
  # Execute the on_player_ready blocks for each player. This method is
62
80
  # typically called by the Plot while beginning a turn, immediately after
63
81
  # the on_ready blocks.
64
82
  #
65
83
  def call_player_ready
66
84
  p_players.each { |player|
67
- this_scene = player.next_scene || player.scene
68
- player.prepare nil
69
- player.cue this_scene unless player.scene == this_scene
85
+ unless player.next_scene.nil?
86
+ player.cue player.next_scene
87
+ end
88
+ player.cue default_scene if player.scene.nil?
89
+ #player.prepare nil
90
+ #player.cue this_scene #unless player.scene.class == this_scene
70
91
  p_player_ready_procs.each { |block| block.call player }
71
92
  }
72
93
  end
@@ -77,6 +98,7 @@ module Gamefic
77
98
  #
78
99
  def call_player_update
79
100
  p_players.each { |player|
101
+ #player.performed nil
80
102
  p_player_update_procs.each { |block| block.call player }
81
103
  }
82
104
  end
@@ -89,6 +111,10 @@ module Gamefic
89
111
  @p_update_procs ||= []
90
112
  end
91
113
 
114
+ def p_before_player_update_procs
115
+ @p_before_player_update_procs ||= []
116
+ end
117
+
92
118
  def p_player_ready_procs
93
119
  @p_player_ready_procs ||= []
94
120
  end
@@ -1,121 +1,121 @@
1
- require 'gamefic/action'
2
-
3
- module Gamefic
4
-
5
- module Plot::CommandMount
6
- # Create an Action that responds to a command.
7
- # An Action uses the command argument to identify the imperative verb that
8
- # triggers the action.
9
- # It can also accept queries to tokenize the remainder of the input and
10
- # filter for particular entities or properties.
11
- # The block argument contains the code to be executed when the input
12
- # matches all of the Action's criteria (i.e., verb and queries).
13
- #
14
- # @example A simple Action.
15
- # respond :salute do |actor|
16
- # actor.tell "Hello, sir!"
17
- # end
18
- # # The command "salute" will respond "Hello, sir!"
19
- #
20
- # @example An Action that accepts a Character
21
- # respond :salute, Use.visible(Character) do |actor, character|
22
- # actor.tell "#{The character} returns your salute."
23
- # end
24
- #
25
- # @param command [Symbol] An imperative verb for the command
26
- # @param *queries [Array<Query::Base>] Queries to filter the command's tokens
27
- # @yieldparam [Character]
28
- def respond(command, *queries, &proc)
29
- playbook.respond(command, *queries, &proc)
30
- end
31
-
32
- # Create a Meta Action that responds to a command.
33
- # Meta Actions are very similar to standard Actions, except the Plot
34
- # understands them to be commands that operate above and/or outside of the
35
- # actual game world. Examples of Meta Actions are commands that report the
36
- # player's current score, save and restore saved games, or list the game's
37
- # credits.
38
- #
39
- # @example A simple Meta Action
40
- # meta :credits do |actor|
41
- # actor.tell "This game was written by John Smith."
42
- # end
43
- #
44
- # @param command [Symbol] An imperative verb for the command
45
- # @param *queries [Array<Query::Base>] Queries to filter the command's tokens
46
- # @yieldparam [Character]
47
- def meta(command, *queries, &proc)
48
- playbook.meta command, *queries, &proc
49
- end
50
-
51
- # @deprecated
52
- def action(command, *queries, &proc)
53
- respond command, *queries, &proc
54
- end
55
-
56
- # Declare a dismabiguation response for actions.
57
- # The disambigurator is executed when an action expects an argument to
58
- # reference a specific entity but its query matched more than one. For
59
- # example, "red" might refer to either a red key or a red book.
60
- #
61
- # If a disambiguator is not defined, the playbook will use its default
62
- # implementation.
63
- #
64
- # @example Tell the player the list of ambiguous entities.
65
- # disambiguate do |actor, entities|
66
- # actor.tell "I don't know which you mean: #{entities.join_or}."
67
- # end
68
- #
69
- # @yieldparam [Gamefic::Character]
70
- # @yieldparam [Array<Gamefic::Entity>]
71
- def disambiguate &block
72
- playbook.disambiguate &block
73
- end
74
-
75
- # Validate an order before a character can execute its command.
76
- #
77
- # @yieldparam [Gamefic::Director::Order]
78
- def validate &block
79
- playbook.validate &block
80
- end
81
-
82
- # Create an alternate Syntax for an Action.
83
- # The command and its translation can be parameterized.
84
- #
85
- # @example Create a synonym for the Inventory Action.
86
- # interpret "catalogue", "inventory"
87
- # # The command "catalogue" will be translated to "inventory"
88
- #
89
- # @example Create a parameterized synonym for the Look Action.
90
- # interpret "scrutinize :entity", "look :entity"
91
- # # The command "scrutinize chair" will be translated to "look chair"
92
- #
93
- # @param command [String] The format of the original command
94
- # @param translation [String] The format of the translated command
95
- # @return [Syntax] the Syntax object
96
- def interpret command, translation
97
- playbook.interpret command, translation
98
- end
99
-
100
- # @deprecated
101
- def xlate command, translation
102
- interpret command, translation
103
- end
104
-
105
- # Get an Array of available verbs.
106
- # If the to_s parameter is true, convert Symbols to Strings.
107
- #
108
- # @return [Array<Symbol|String>]
109
- def verbs to_s: false
110
- to_s ? playbook.verbs.map { |v| v.to_s } : playbook.verbs
111
- end
112
-
113
- # Get an Array of all Actions defined in the Plot.
114
- #
115
- # @return [Array<Action>]
116
- def actions
117
- playbook.actions
118
- end
119
- end
120
-
121
- end
1
+ require 'gamefic/action'
2
+
3
+ module Gamefic
4
+
5
+ module Plot::Commands
6
+ # Create an Action that responds to a command.
7
+ # An Action uses the command argument to identify the imperative verb that
8
+ # triggers the action.
9
+ # It can also accept queries to tokenize the remainder of the input and
10
+ # filter for particular entities or properties.
11
+ # The block argument contains the code to be executed when the input
12
+ # matches all of the Action's criteria (i.e., verb and queries).
13
+ #
14
+ # @example A simple Action.
15
+ # respond :salute do |actor|
16
+ # actor.tell "Hello, sir!"
17
+ # end
18
+ # # The command "salute" will respond "Hello, sir!"
19
+ #
20
+ # @example An Action that accepts a Character
21
+ # respond :salute, Use.visible(Character) do |actor, character|
22
+ # actor.tell "#{The character} returns your salute."
23
+ # end
24
+ #
25
+ # @param command [Symbol] An imperative verb for the command
26
+ # @param queries [Array<Query::Base>] Filters for the command's tokens
27
+ # @yieldparam [Character]
28
+ def respond(command, *queries, &proc)
29
+ playbook.respond(command, *queries, &proc)
30
+ end
31
+
32
+ # Create a Meta Action that responds to a command.
33
+ # Meta Actions are very similar to standard Actions, except the Plot
34
+ # understands them to be commands that operate above and/or outside of the
35
+ # actual game world. Examples of Meta Actions are commands that report the
36
+ # player's current score, save and restore saved games, or list the game's
37
+ # credits.
38
+ #
39
+ # @example A simple Meta Action
40
+ # meta :credits do |actor|
41
+ # actor.tell "This game was written by John Smith."
42
+ # end
43
+ #
44
+ # @param command [Symbol] An imperative verb for the command
45
+ # @param queries [Array<Query::Base>] Filters for the command's tokens
46
+ # @yieldparam [Character]
47
+ def meta(command, *queries, &proc)
48
+ playbook.meta command, *queries, &proc
49
+ end
50
+
51
+ # @deprecated
52
+ def action(command, *queries, &proc)
53
+ respond command, *queries, &proc
54
+ end
55
+
56
+ # Declare a dismabiguation response for actions.
57
+ # The disambigurator is executed when an action expects an argument to
58
+ # reference a specific entity but its query matched more than one. For
59
+ # example, "red" might refer to either a red key or a red book.
60
+ #
61
+ # If a disambiguator is not defined, the playbook will use its default
62
+ # implementation.
63
+ #
64
+ # @example Tell the player the list of ambiguous entities.
65
+ # disambiguate do |actor, entities|
66
+ # actor.tell "I don't know which you mean: #{entities.join_or}."
67
+ # end
68
+ #
69
+ # @yieldparam [Gamefic::Character]
70
+ # @yieldparam [Array<Gamefic::Entity>]
71
+ def disambiguate &block
72
+ playbook.disambiguate &block
73
+ end
74
+
75
+ # Validate an order before a character can execute its command.
76
+ #
77
+ # @yieldparam [Gamefic::Director::Order]
78
+ def validate &block
79
+ playbook.validate &block
80
+ end
81
+
82
+ # Create an alternate Syntax for an Action.
83
+ # The command and its translation can be parameterized.
84
+ #
85
+ # @example Create a synonym for the Inventory Action.
86
+ # interpret "catalogue", "inventory"
87
+ # # The command "catalogue" will be translated to "inventory"
88
+ #
89
+ # @example Create a parameterized synonym for the Look Action.
90
+ # interpret "scrutinize :entity", "look :entity"
91
+ # # The command "scrutinize chair" will be translated to "look chair"
92
+ #
93
+ # @param command [String] The format of the original command
94
+ # @param translation [String] The format of the translated command
95
+ # @return [Syntax] the Syntax object
96
+ def interpret command, translation
97
+ playbook.interpret command, translation
98
+ end
99
+
100
+ # @deprecated
101
+ def xlate command, translation
102
+ interpret command, translation
103
+ end
104
+
105
+ # Get an Array of available verbs.
106
+ # If the to_s parameter is true, convert Symbols to Strings.
107
+ #
108
+ # @return [Array<Symbol|String>]
109
+ def verbs to_s: false
110
+ to_s ? playbook.verbs.map { |v| v.to_s } : playbook.verbs
111
+ end
112
+
113
+ # Get an Array of all Actions defined in the Plot.
114
+ #
115
+ # @return [Array<Action>]
116
+ def actions
117
+ playbook.actions
118
+ end
119
+ end
120
+
121
+ end