lib/gamefic/character.rb in gamefic-1.4.1 vs lib/gamefic/character.rb in gamefic-1.5.0
- old
+ new
@@ -1,19 +1,23 @@
require 'gamefic/director'
+class NotConclusionError < Exception
+end
+
module Gamefic
class Character < Entity
attr_reader :queue, :user
# @return [Gamefic::Director::Order]
attr_reader :last_order
# @return [Entity,nil]
attr_reader :last_object
attr_accessor :object_of_pronoun
-
- serialize :scene
-
- def initialize(plot, args = {})
+ attr_reader :scene
+ attr_reader :next_scene
+ attr_accessor :playbook
+
+ def initialize(args = {})
@queue = Array.new
super
@buffer_stack = 0
@buffer = ""
end
@@ -36,24 +40,18 @@
# should yield the same result, but using tokens can yield better
# performance since it bypasses the parser.
#
# The command will be executed immediately regardless of game state.
#
- # If the from_user argument is true, the command is assumed to have come
- # directly from user input. The character's last_order and last_object
- # will be updated with the result.
- #
# @example Send a command as a string
# character.perform "take the key"
#
# @example Send a command as a set of tokens
# character.perform :take, @key
#
- def perform(*command, from_user: false)
- o = Director.dispatch(self, *command)
- last_order = o if from_user
- o
+ def perform(*command)
+ Director.dispatch(self, *command)
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.
@@ -95,18 +93,10 @@
# @param message [String]
def stream(message)
user.send message.strip unless user.nil?
end
- # TODO This might not be necessary. The User#quit method was a noop anyway.
- #def destroy
- # if @user != nil
- # @user.quit
- # end
- # super
- #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
@@ -125,49 +115,45 @@
# actor.proceed # Execute the previous implementation
# end
# end
#
def proceed
- return if delegate_stack.last.nil?
- delegate_stack.last.proceed
+ Director::Delegate.proceed_for self
end
- def cue scene_name
- @scene = scene_name
+ def cue scene
@next_scene = nil
- plot.scenes[scene_name].start self
+ @scene = scene
+ @scene.start self unless @scene.nil?
end
-
- def prepare scene_name
- @next_scene = scene_name
+
+ def prepare scene
+ @next_scene = scene
end
- def conclude scene_name
- scene = plot.scenes[scene_name]
- raise "#{scene_name} is not a conclusion" unless scene.kind_of?(Scene::Conclusion)
- cue scene_name
+ def conclude scene
+ raise NotConclusionError if !scene.kind_of?(Scene::Conclusion)
+ cue scene
end
-
- # Get the name of the character's current scene
- #
- # @return [Symbol] The name of the scene
- def scene
- @scene
+
+ def concluded?
+ !scene.nil? and scene.kind_of?(Scene::Conclusion)
end
- # Alias for Character#cue key
- def scene= key
- cue key.to_sym
+ def performed order
+ @last_order = order
end
-
- def next_scene
- @next_scene
+
+ def prompt
+ scene.nil? ? '>' : scene.prompt_for(self)
end
-
+
private
+
def delegate_stack
@delegate_stack ||= []
end
+
def last_order=(order)
return if order.nil?
@last_order = order
if !order.action.meta? and !order.arguments[0].nil? and !order.arguments[0][0].nil? and order.arguments[0][0].kind_of?(Entity)
@last_object = order.arguments[0][0]