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

last_input[RW]

The input for the previous scene.

@return [String]

last_prompt[RW]

The prompt for the previous scene.

@return [String]

next_options[R]
next_scene[R]

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>]

scene[R]

The scene in which the entity is currently participating.

@return [Gamefic::Scene::Base]

Public Instance Methods

accessible?() click to toggle source
# File lib/gamefic/active.rb, line 243
def accessible?
  false
end
conclude(new_scene, **data) click to toggle source

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
concluded?() click to toggle source

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
cue(new_scene, **data) click to toggle source

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
entered(scene) click to toggle source

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
entered?(scene) click to toggle source

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
execute(verb, *params, quietly: false) click to toggle source

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
inspect() click to toggle source
# File lib/gamefic/active.rb, line 247
def inspect
  to_s
end
output() click to toggle source
# File lib/gamefic/active.rb, line 57
def output
  @output ||= {}
end
perform(*command) click to toggle source

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
playbooks() click to toggle source

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(new_scene, **data) click to toggle source

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(quietly: false) click to toggle source

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
queue() click to toggle source

An array of actions waiting to be performed.

@return [Array<String>]

# File lib/gamefic/active.rb, line 46
def queue
  @queue ||= []
end
quietly(*command) click to toggle source

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
state() click to toggle source

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
stream(message) click to toggle source

Send a message to the Character as raw text. Unlike tell, this method will not wrap the message in HTML paragraphs.

@param message [String]

Calls superclass method
# File lib/gamefic/active.rb, line 78
def stream(message)
  if buffer_stack > 0
    append_buffer message
  else
    super
  end
end
syntaxes() click to toggle source
# File lib/gamefic/active.rb, line 39
def syntaxes
  playbooks.map(&:syntaxes).flatten
end
tell(message) click to toggle source

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]

Calls superclass method
# File lib/gamefic/active.rb, line 66
def tell(message)
  if buffer_stack > 0
    append_buffer format(message)
  else
    super
  end
end
will_cue?(scene) click to toggle source

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

append_buffer(str) click to toggle source
# File lib/gamefic/active.rb, line 286
def append_buffer str
  @buffer += str
end
buffer() click to toggle source

@return [String]

# File lib/gamefic/active.rb, line 282
def buffer
  @buffer ||= ''
end
buffer_stack() click to toggle source
# File lib/gamefic/active.rb, line 273
def buffer_stack
  @buffer_stack ||= 0
end
clear_buffer() click to toggle source
# File lib/gamefic/active.rb, line 290
def clear_buffer
  @buffer = ''
end
dispatchers() click to toggle source
# File lib/gamefic/active.rb, line 294
def dispatchers
  @dispatchers ||= []
end
entered_scenes() click to toggle source

@return [Array<Gamefic::Scene::Base>]

# File lib/gamefic/active.rb, line 269
def entered_scenes
  @entered_scenes ||= []
end
set_buffer_stack(num) click to toggle source
# File lib/gamefic/active.rb, line 277
def set_buffer_stack num
  @buffer_stack = num
end