module Gamefic::Active
The Active
module gives entities the ability to perform actions and participate in scenes. The Actor
class, for example, is an Entity
subclass that includes this module.
Attributes
The input for the previous scene.
@return [String]
The prompt for the previous scene.
@return [String]
The scene class that will be cued for this entity on the next turn. Usually set with the prepare
method.
@return [Class<Gamefic::Scene::Base>]
The scene in which the entity is currently participating.
@return [Gamefic::Scene::Base]
Public Instance Methods
# File lib/gamefic/active.rb, line 243 def accessible? false end
Cue a conclusion. This method works like cue
, except it will raise a NotConclusionError
if the scene is not a Scene::Conclusion
.
@param new_scene [Class<Scene::Base>] @oaram data [Hash] Additional scene data
# File lib/gamefic/active.rb, line 231 def conclude new_scene, **data raise NotConclusionError unless new_scene <= Scene::Conclusion cue new_scene, **data end
True if the character is in a conclusion.
@return [Boolean]
# File lib/gamefic/active.rb, line 239 def concluded? !scene.nil? && scene.kind_of?(Scene::Conclusion) end
Immediately start a new scene for the character. Use prepare
if you want to declare a scene to be started at the beginning of the next turn.
@param new_scene [Class<Scene::Base>] @param data [Hash] Additional scene data
# File lib/gamefic/active.rb, line 197 def cue new_scene, **data @next_scene = nil if new_scene.nil? @scene = nil else @scene = new_scene.new(self, **data) @scene.start end end
Track the entity's performance of a scene.
# File lib/gamefic/active.rb, line 253 def entered scene klass = (scene.kind_of?(Gamefic::Scene::Base) ? scene.class : scene) entered_scenes.push klass unless entered_scenes.include?(klass) end
Determine whether the entity has performed the specified scene.
@return [Boolean]
# File lib/gamefic/active.rb, line 261 def entered? scene klass = (scene.kind_of?(Gamefic::Scene::Base) ? scene.class : scene) entered_scenes.include?(klass) end
Perform an action. This is functionally identical to the `perform` method, except the action must be declared as a verb with a list of parameters. Use `perform` if you need to parse a string as a command.
The command will be executed immediately regardless of the entity's state.
@example
character.execute :take, @key
@return [Gamefic::Action]
# File lib/gamefic/active.rb, line 145 def execute(verb, *params, quietly: false) dispatchers.push Dispatcher.dispatch_from_params(self, verb, params) proceed quietly: quietly dispatchers.pop end
# File lib/gamefic/active.rb, line 247 def inspect to_s end
# File lib/gamefic/active.rb, line 57 def output @output ||= {} end
Perform a command. The command can be specified as a String
or a verb with a list of parameters. Either form should yield the same result, but the verb/parameter form can yield better performance since it bypasses the parser.
The command will be executed immediately regardless of the entity's state.
@example Send a command as a string
character.perform "take the key"
@example Send a command as a verb with parameters
character.perform :take, @key
@todo Modify this method so it only accepts a single command.
Verbs with parameters should use Active#execute instead. It might be necessary to support command splats with a deprecation warning until version 3
@return [Gamefic::Action]
# File lib/gamefic/active.rb, line 107 def perform(*command) if command.length > 1 execute command.first, *command[1..-1] else dispatchers.push Dispatcher.dispatch(self, command.first.to_s) proceed dispatchers.pop end end
The playbooks that will be used to perform commands.
@return [Array<Gamefic::World::Playbook>]
# File lib/gamefic/active.rb, line 35 def playbooks @playbooks ||= [] end
Prepare a scene to be started for this character at the beginning of the next turn. As opposed to cue
, a prepared scene will not start until the current scene finishes.
@param new_scene [Class<Scene::Base>] @oaram data [Hash] Additional scene data
# File lib/gamefic/active.rb, line 213 def prepare new_scene, **data @next_scene = new_scene @next_options = data end
Proceed to the next Action
in the current stack. This method is typically used in Action
blocks to cascade through multiple implementations of the same verb.
@example Proceed through two implementations of a verb
introduction do |actor| actor[:has_eaten] = false # Initial value end respond :eat do |actor| actor.tell "You eat something." actor[:has_eaten] = true end respond :eat do |actor| # This version will be executed first because it was implemented last if actor[:has_eaten] actor.tell "You already ate." else actor.proceed # Execute the previous implementation end end
# File lib/gamefic/active.rb, line 174 def proceed quietly: false return if dispatchers.empty? a = dispatchers.last.next return if a.nil? if quietly if buffer_stack == 0 @buffer = "" end set_buffer_stack(buffer_stack + 1) end a.execute if quietly set_buffer_stack(buffer_stack - 1) @buffer end end
An array of actions waiting to be performed.
@return [Array<String>]
# File lib/gamefic/active.rb, line 46 def queue @queue ||= [] end
Quietly perform a command. This method executes the command exactly as perform
does, except it buffers the resulting output instead of sending it to the user.
@todo Modify this method so it only accepts a single command.
See Active#perform for more information.
@return [String] The output that resulted from performing the command.
# File lib/gamefic/active.rb, line 125 def quietly(*command) clear_buffer if buffer_stack == 0 set_buffer_stack buffer_stack + 1 self.perform *command set_buffer_stack buffer_stack - 1 buffer end
A hash of values representing the state of a performing entity.
@return [Hash{Symbol => Object}]
# File lib/gamefic/active.rb, line 53 def state @state ||= {} end
Send a message to the Character as raw text. Unlike tell
, this method will not wrap the message in HTML paragraphs.
@param message [String]
# File lib/gamefic/active.rb, line 78 def stream(message) if buffer_stack > 0 append_buffer message else super end end
# File lib/gamefic/active.rb, line 39 def syntaxes playbooks.map(&:syntaxes).flatten end
Send a message to the entity. This method will automatically wrap the message in HTML paragraphs. To send a message without paragraph formatting, use stream
instead.
@param message [String]
# File lib/gamefic/active.rb, line 66 def tell(message) if buffer_stack > 0 append_buffer format(message) else super end end
Return true if the character is expected to be in the specified scene on the next turn.
@return [Boolean]
# File lib/gamefic/active.rb, line 222 def will_cue? scene (@scene.class == scene and @next_scene.nil?) || @next_scene == scene end
Private Instance Methods
# File lib/gamefic/active.rb, line 286 def append_buffer str @buffer += str end
@return [String]
# File lib/gamefic/active.rb, line 282 def buffer @buffer ||= '' end
# File lib/gamefic/active.rb, line 273 def buffer_stack @buffer_stack ||= 0 end
# File lib/gamefic/active.rb, line 290 def clear_buffer @buffer = '' end
# File lib/gamefic/active.rb, line 294 def dispatchers @dispatchers ||= [] end
@return [Array<Gamefic::Scene::Base>]
# File lib/gamefic/active.rb, line 269 def entered_scenes @entered_scenes ||= [] end
# File lib/gamefic/active.rb, line 277 def set_buffer_stack num @buffer_stack = num end