Class: Gamefic::Character

Inherits:
Entity
  • Object
show all
Includes:
State
Defined in:
lib/gamefic/character.rb,
lib/gamefic/character/state.rb

Defined Under Namespace

Modules: State

Constant Summary

Constants included from Matchable

Matchable::SPLIT_REGEXP

Instance Attribute Summary collapse

Attributes inherited from Entity

#session

Attributes included from Grammar::Plural

#plural

Attributes included from Grammar::Person

#person

Attributes included from Grammar::Gender

#gender

Attributes included from Describable

#definite_article, #indefinite_article, #name, #synonyms

Instance Method Summary collapse

Methods included from State

#state

Methods inherited from Entity

#[], #[]=, #parent=, #post_initialize, #pre_initialize, #uid, #update

Methods included from Grammar::WordAdapter

#contract, #pronoun, #verb

Methods included from Grammar::Plural

#plural?

Methods included from Messaging

#flush, #messages, #output

Methods included from Describable

default_description, default_description=, #definitely, #description, #description=, #has_description?, #indefinitely, #keywords, #proper_named=, #proper_named?, #to_s

Methods included from Matchable

#keywords, #match?

Methods included from Node

#children, #flatten, #parent, #parent=

Constructor Details

#initialize(args = {}) ⇒ Character



23
24
25
26
27
28
29
# File 'lib/gamefic/character.rb', line 23

def initialize(args = {})
  super
  @queue = Array.new
  @messages = ''
  @buffer_stack = 0
  @buffer = ""
end

Instance Attribute Details

#last_actionGamefic::Action (readonly)



13
14
15
# File 'lib/gamefic/character.rb', line 13

def last_action
  @last_action
end

#last_objectEntity? (readonly)



15
16
17
# File 'lib/gamefic/character.rb', line 15

def last_object
  @last_object
end

#next_sceneObject (readonly)

Returns the value of attribute next_scene.



18
19
20
# File 'lib/gamefic/character.rb', line 18

def next_scene
  @next_scene
end

#object_of_pronounObject

Returns the value of attribute object_of_pronoun.



16
17
18
# File 'lib/gamefic/character.rb', line 16

def object_of_pronoun
  @object_of_pronoun
end

#playbookObject

Returns the value of attribute playbook.



19
20
21
# File 'lib/gamefic/character.rb', line 19

def playbook
  @playbook
end

#queueObject (readonly)

Returns the value of attribute queue.



11
12
13
# File 'lib/gamefic/character.rb', line 11

def queue
  @queue
end

#sceneObject (readonly)

Returns the value of attribute scene.



17
18
19
# File 'lib/gamefic/character.rb', line 17

def scene
  @scene
end

#userObject (readonly)

Returns the value of attribute user.



11
12
13
# File 'lib/gamefic/character.rb', line 11

def user
  @user
end

Instance Method Details

#accessible?String

Get the prompt that the user should see for the current scene.

def prompt

scene.nil? ? '>' : scene.prompt

end



213
214
215
# File 'lib/gamefic/character.rb', line 213

def accessible?
  false
end

#conclude(scene) ⇒ Object

Cue a conclusion. This method works like #cue, except it will raise a NotConclusionError if the scene is not a Scene::Conclusion.

Raises:



189
190
191
192
# File 'lib/gamefic/character.rb', line 189

def conclude scene
  raise NotConclusionError unless scene <= Scene::Conclusion
  cue scene
end

#concluded?Boolean

True if the character is in a conclusion.



197
198
199
# File 'lib/gamefic/character.rb', line 197

def concluded?
  !scene.nil? and scene.kind_of?(Scene::Conclusion)
end

#connect(user) ⇒ Object

Connect a User.



34
35
36
# File 'lib/gamefic/character.rb', line 34

def connect(user)
  @user = user
end

#cue(new_scene) ⇒ Object

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.



161
162
163
164
165
166
167
168
169
# File 'lib/gamefic/character.rb', line 161

def cue new_scene
  @next_scene = nil
  if new_scene.nil?
    @scene = nil
  else
    @scene = new_scene.new(self)
    @scene.start
  end
end

#disconnectObject

Disconnect the current User.



40
41
42
# File 'lib/gamefic/character.rb', line 40

def disconnect
  @user = nil
end

#inspectObject



217
218
219
# File 'lib/gamefic/character.rb', line 217

def inspect
  to_s
end

#perform(*command) ⇒ Object

Perform a command. The command can be specified as a String or a set of tokens. Either form 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.

Examples:

Send a command as a string

character.perform "take the key"

Send a command as a set of tokens

character.perform :take, @key


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/gamefic/character.rb', line 82

def perform(*command)
  #Director.dispatch(self, *command)

  actions = playbook.dispatch(self, *command)
  a = actions.first
  okay = true
  unless a.meta?
    playbook.validators.each { |v|
      result = v.call(self, a.verb, a.parameters)
      okay = (result != false)
      break if not okay
    }
  end
  if okay
    performance_stack.push actions
    proceed
    performance_stack.pop
  end
  a
end

#performed(order) ⇒ Object



201
202
203
204
# File 'lib/gamefic/character.rb', line 201

def performed order
  order.freeze
  @last_action = order
end

#prepare(s) ⇒ Object

Prepare a scene to be started for this character at the beginning of the next turn.



174
175
176
# File 'lib/gamefic/character.rb', line 174

def prepare s
  @next_scene = s
end

#proceed(quietly: false) ⇒ Object

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.

Examples:

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


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/gamefic/character.rb', line 138

def proceed quietly: false
  #Director::Delegate.proceed_for self

  return if performance_stack.empty?
  a = performance_stack.last.shift
  unless a.nil?
    if quietly
      if @buffer_stack == 0
        @buffer = ""
      end
      @buffer_stack += 1
    end
    a.execute
    if quietly
      @buffer_stack -= 1
      @buffer
    end
  end
end

#quietly(*command) ⇒ String

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.



107
108
109
110
111
112
113
114
115
# File 'lib/gamefic/character.rb', line 107

def quietly(*command)
  if @buffer_stack == 0
    @buffer = ""
  end
  @buffer_stack += 1
  self.perform *command
  @buffer_stack -= 1
  @buffer
end

#stream(message) ⇒ Object

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



61
62
63
64
65
66
67
# File 'lib/gamefic/character.rb', line 61

def stream(message)
  if @buffer_stack > 0
    @buffer += message
  else
    super
  end
end

#tell(message) ⇒ Object

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.



49
50
51
52
53
54
55
# File 'lib/gamefic/character.rb', line 49

def tell(message)
  if @buffer_stack > 0
    @buffer += message
  else
    super
  end
end

#will_cue?(scene) ⇒ Boolean

Return true if the character is expected to be in the specified scene on the next turn.



182
183
184
# File 'lib/gamefic/character.rb', line 182

def will_cue? scene
  (@scene.class == scene and @next_scene.nil?) or @next_scene == scene
end