gamefic 1.5.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gamefic.rb +1 -3
- data/lib/gamefic/action.rb +140 -79
- data/lib/gamefic/character.rb +120 -53
- data/lib/gamefic/character/state.rb +12 -0
- data/lib/gamefic/core_ext/array.rb +53 -11
- data/lib/gamefic/core_ext/string.rb +1 -0
- data/lib/gamefic/describable.rb +37 -11
- data/lib/gamefic/engine/base.rb +17 -4
- data/lib/gamefic/engine/tty.rb +4 -0
- data/lib/gamefic/entity.rb +4 -15
- data/lib/gamefic/matchable.rb +50 -0
- data/lib/gamefic/messaging.rb +45 -0
- data/lib/gamefic/node.rb +16 -0
- data/lib/gamefic/plot.rb +27 -33
- data/lib/gamefic/plot/{article_mount.rb → articles.rb} +22 -22
- data/lib/gamefic/plot/callbacks.rb +30 -4
- data/lib/gamefic/plot/{command_mount.rb → commands.rb} +121 -121
- data/lib/gamefic/plot/entities.rb +3 -3
- data/lib/gamefic/plot/host.rb +3 -3
- data/lib/gamefic/plot/playbook.rb +74 -30
- data/lib/gamefic/plot/scenes.rb +149 -0
- data/lib/gamefic/plot/snapshot.rb +14 -39
- data/lib/gamefic/plot/theater.rb +73 -0
- data/lib/gamefic/query.rb +6 -19
- data/lib/gamefic/query/base.rb +127 -246
- data/lib/gamefic/query/children.rb +6 -7
- data/lib/gamefic/query/descendants.rb +15 -0
- data/lib/gamefic/query/family.rb +19 -7
- data/lib/gamefic/query/itself.rb +13 -0
- data/lib/gamefic/query/matches.rb +67 -11
- data/lib/gamefic/query/parent.rb +6 -7
- data/lib/gamefic/query/siblings.rb +10 -7
- data/lib/gamefic/query/text.rb +39 -35
- data/lib/gamefic/scene.rb +1 -1
- data/lib/gamefic/scene/active.rb +12 -6
- data/lib/gamefic/scene/base.rb +56 -5
- data/lib/gamefic/scene/conclusion.rb +3 -0
- data/lib/gamefic/scene/custom.rb +0 -83
- data/lib/gamefic/scene/multiple_choice.rb +54 -32
- data/lib/gamefic/scene/multiple_scene.rb +11 -6
- data/lib/gamefic/scene/pause.rb +3 -4
- data/lib/gamefic/scene/yes_or_no.rb +23 -9
- data/lib/gamefic/script/base.rb +4 -0
- data/lib/gamefic/subplot.rb +22 -19
- data/lib/gamefic/syntax.rb +7 -15
- data/lib/gamefic/user/base.rb +7 -13
- data/lib/gamefic/user/buffer.rb +7 -0
- data/lib/gamefic/user/tty.rb +13 -12
- data/lib/gamefic/version.rb +1 -1
- metadata +11 -37
- data/lib/gamefic/director.rb +0 -23
- data/lib/gamefic/director/delegate.rb +0 -126
- data/lib/gamefic/director/order.rb +0 -17
- data/lib/gamefic/director/parser.rb +0 -137
- data/lib/gamefic/keywords.rb +0 -67
- data/lib/gamefic/plot/query_mount.rb +0 -9
- data/lib/gamefic/plot/scene_mount.rb +0 -182
- data/lib/gamefic/query/ambiguous_children.rb +0 -5
- data/lib/gamefic/query/expression.rb +0 -47
- data/lib/gamefic/query/many_children.rb +0 -7
- data/lib/gamefic/query/plural_children.rb +0 -14
- data/lib/gamefic/query/self.rb +0 -10
- data/lib/gamefic/scene_data.rb +0 -10
- data/lib/gamefic/scene_data/base.rb +0 -12
- data/lib/gamefic/scene_data/multiple_choice.rb +0 -19
- data/lib/gamefic/scene_data/multiple_scene.rb +0 -21
- data/lib/gamefic/scene_data/yes_or_no.rb +0 -18
- data/lib/gamefic/serialized.rb +0 -24
- 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 :
|
13
|
-
autoload :
|
14
|
-
autoload :Entities,
|
15
|
-
autoload :
|
16
|
-
autoload :YouMount,
|
17
|
-
autoload :Snapshot,
|
18
|
-
autoload :Host,
|
19
|
-
autoload :Players,
|
20
|
-
autoload :Playbook,
|
21
|
-
autoload :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
|
27
|
-
|
28
|
-
|
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
|
-
|
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
|
-
|
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::
|
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
|
-
|
68
|
-
|
69
|
-
|
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::
|
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
|
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
|
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
|