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 most recently started cue.
@return [Cue, nil]
The cue that will be started on the next turn.
@return [Cue, nil]
Public Instance Methods
Source
# File lib/gamefic/active.rb, line 191 def acting? @acting ||= false end
True if the actor performed a command this turn. False if the actor has not performed a command yet or has only performed meta commands.
Source
# File lib/gamefic/active.rb, line 173 def can?(verb) narratives.understand?(verb) end
True if the actor can perform the verb (i.e., an active narrative understands it).
@param verb [String, Symbol]
Source
# File lib/gamefic/active.rb, line 155 def concluding? narratives.empty? || last_cue&.type == 'Conclusion' end
True if the actor is ready to leave the game.
Source
# File lib/gamefic/active.rb, line 137 def cue scene, **context return @next_cue if @next_cue&.key == scene && @next_cue&.context == context logger.debug "Overwriting existing cue `#{@next_cue.key}` with `#{scene}`" if @next_cue @next_cue = Cue.new(self, scene, current, **context) end
Cue
a scene to start in the next turn.
@raise [ArgumentError] if the scene is not valid
@param scene [Class<Scene::Base>, Symbol] @param context [Hash] Extra data to pass to the scene’s props @return [Cue]
Source
# File lib/gamefic/active.rb, line 94 def execute(verb, *params) dispatchers.push Dispatcher.new(Order.new(self, verb, params)) dispatchers.last.execute.tap do |command| dispatchers.pop @acting = true if command&.active? end 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 arguments. 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
@param verb [Symbol] @param params [Array] @return [Command, nil]
Source
# File lib/gamefic/active.rb, line 198 def last_input output.last_input end
The input from the last finished cue.
@return [String, nil]
Source
# File lib/gamefic/active.rb, line 30 def narratives @narratives ||= Narratives.new end
The narratives in which the entity is participating.
@return [Narratives]
Source
# File lib/gamefic/active.rb, line 48 def output last_cue&.output || Props::Output::EMPTY end
Data that will be sent to the user. The output is typically sent after a scene has started and before the user is prompted for input.
The output object attached to the actor is always frozen. Authors should use on_player_output blocks to modify output to be sent to the user.
@return [Props::Output]
Source
# File lib/gamefic/active.rb, line 165 def participating? !narratives.empty? end
True if the actor is participating in any narratives.
Source
# File lib/gamefic/active.rb, line 62 def perform(input) dispatchers.push Dispatcher.new(Request.new(self, input)) dispatchers.last.execute.tap do |command| dispatchers.pop @acting = true if command&.active? end end
Perform a command.
The command’s action will be executed immediately, regardless of the entity’s state.
@example Send a command as a string
character.perform "take the key"
@param input [String] @return [Command, nil]
Source
# File lib/gamefic/active.rb, line 126 def proceed dispatchers.last&.proceed 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
@return [Action, nil]
Source
# File lib/gamefic/active.rb, line 37 def queue @queue ||= [] end
An array of commands waiting to be executed.
@return [Array<String>]
Source
# File lib/gamefic/active.rb, line 76 def quietly(input) messenger.buffer { perform input } 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 messages.
@param input [String] @return [String] The output that resulted from performing the command.
Source
# File lib/gamefic/active.rb, line 149 def recue (@next_cue = @last_cue&.restart) || warn_nil('No scene to recue') end
Restart the scene from the most recent cue.
@return [Cue, nil]
Source
# File lib/gamefic/active.rb, line 181 def rotate_cue @acting = false @last_cue = @next_cue @next_cue = nil @last_cue end
Move next_cue
into last_cue. This method is typically called by the narrator at the start of a turn. It returns the last cue.
@return [Cue, nil]
Private Instance Methods
Source
# File lib/gamefic/active.rb, line 207 def current Binding.for(self) || narratives.first end
Get the currently bound or primary narrative.
@return [Narrative, nil]
Source
# File lib/gamefic/active.rb, line 212 def dispatchers @dispatchers ||= [] end
@return [Array<Dispatcher>]
Source
# File lib/gamefic/active.rb, line 216 def warn_nil(message) logger.warn message nil end