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]