class Goby::Entity

Provides the ability to fight, equip/unequip weapons & armor, and carry items & gold.

Constants

NOT_EQUIPPED_ERROR

Error when the entity specifies an item not equipped.

NO_SUCH_ITEM_ERROR

Error when the entity specifies a non-existent item.

Attributes

escaped[RW]
gold[R]
inventory[RW]
name[RW]
outfit[R]

Public Class Methods

new(name: "Entity", stats: {}, inventory: [], gold: 0, outfit: {}) click to toggle source

@param [String] name the name. @param [Hash] stats hash of stats @option stats [Integer] :max_hp maximum health points. Set to be positive. @option stats [Integer] :hp current health points. Set to be nonnegative. @option stats [Integer] :attack strength in battle. Set to be positive. @option stats [Integer] :defense protection from attacks. Set to be positive. @option stats [Integer] :agility speed of commands in battle. Set to be positive. @param [[C(Item, Integer)]] inventory a list of pairs of items and their respective amounts. @param [Integer] gold the currency used for economical transactions. @param [Hash] outfit the collection of equippable items currently worn.

# File lib/goby/entity/entity.rb, line 24
def initialize(name: "Entity", stats: {}, inventory: [], gold: 0, outfit: {})
  @name = name
  set_stats(stats)
  @inventory = inventory
  set_gold(gold)

  # See its attr_accessor below.
  @outfit = {}
  outfit.each do |type,value|
    value.equip(self)
  end

  # This should only be switched to true during battle.
  @escaped = false
end

Public Instance Methods

==(rhs) click to toggle source

@param [Entity] rhs the entity on the right.

# File lib/goby/entity/entity.rb, line 284
def ==(rhs)
  @name == rhs.name
end
add_gold(gold) click to toggle source

Adds the given amount of gold.

@param [Integer] gold the amount of gold to add.

# File lib/goby/entity/entity.rb, line 43
def add_gold(gold)
  @gold += gold
  check_and_set_gold
end
add_item(item, amount = 1) click to toggle source

Adds the item and the given amount to the inventory.

@param [Item] item the item being added. @param [Integer] amount the amount of the item to add.

# File lib/goby/entity/entity.rb, line 52
def add_item(item, amount = 1)

  # Increase the amount if the item already exists in the inventory.
  @inventory.each do |couple|
    if (couple.first == item)
      couple.second += amount
      return
    end
  end

  # If not already in the inventory, push a couple.
  @inventory.push(C[item, amount])
end
add_loot(gold, treasures) click to toggle source

Adds the specified gold and treasures to the inventory.

@param [Integer] gold the amount of gold. @param [[Item]] treasures the list of treasures.

# File lib/goby/entity/entity.rb, line 70
def add_loot(gold, treasures)
  type("Loot: ")
  if ((gold.positive?) || (treasures && treasures.any?))
    print "\n"
    if gold.positive?
      type("* #{gold} gold\n")
      add_gold(gold)
    end
    if treasures && treasures.any?
      treasures.each do |treasure|
        unless treasure.nil?
          type("* #{treasure.name}\n")
          add_item(treasure)
        end
      end
    end
    print "\n"
  else
    type("nothing!\n\n")
  end
end
clear_inventory() click to toggle source

Removes all items from the entity's inventory.

# File lib/goby/entity/entity.rb, line 93
def clear_inventory
  while @inventory.size.nonzero?
    @inventory.pop
  end
end
equip_item(item) click to toggle source

Equips the specified item to the entity's outfit.

@param [Item, String] item the item (or its name) to equip.

# File lib/goby/entity/entity.rb, line 102
def equip_item(item)

  index = has_item(item)
  if index
    actual_item = inventory[index].first

    # Checks for Equippable without importing the file.
    if (defined? actual_item.equip)
      actual_item.equip(self)

      # Equipping the item will always remove it from the entity's inventory.
      remove_item(actual_item)
    else
      print "#{actual_item.name} cannot be equipped!\n\n"
    end
  else
    print NO_SUCH_ITEM_ERROR
  end
end
has_item(item) click to toggle source

Returns the index of the specified item, if it exists.

@param [Item, String] item the item (or its name). @return [Integer] the index of an existing item. Otherwise nil.

# File lib/goby/entity/entity.rb, line 126
def has_item(item)
  inventory.each_with_index do |couple, index|
    return index if couple.first.name.casecmp(item.to_s).zero?
  end
  return
end
print_inventory() click to toggle source

Prints the inventory in a nice format.

print_status() click to toggle source

Prints the status in a nice format. TODO: encapsulate print_stats and print_equipment in own functions.

remove_gold(gold) click to toggle source

Removes up to the amount of gold given in the argument. Entity's gold will not be less than zero.

@param [Integer] gold the amount of gold to remove.

# File lib/goby/entity/entity.rb, line 182
def remove_gold(gold)
  @gold -= gold
  check_and_set_gold
end
remove_item(item, amount = 1) click to toggle source

Removes the item, if it exists, and, at most, the given amount from the inventory.

@param [Item] item the item being removed. @param [Integer] amount the amount of the item to remove.

# File lib/goby/entity/entity.rb, line 191
def remove_item(item, amount = 1)

  # Decrease the amount if the item already exists in the inventory.
  @inventory.each_with_index do |couple, index|
    if (couple.first == item)
      couple.second -= amount

      # Delete the item if the amount becomes non-positive.
      @inventory.delete_at(index) if couple.second.nonpositive?

      return
    end
  end
end
set_gold(gold) click to toggle source

Sets the Entity's gold to the number in the argument. Only nonnegative numbers are accepted.

@param [Integer] gold the amount of gold to set.

# File lib/goby/entity/entity.rb, line 210
def set_gold(gold)
  @gold = gold
  check_and_set_gold
end
set_stats(passed_in_stats) click to toggle source

Sets stats

@param [Hash] passed_in_stats value pairs of stats @option passed_in_stats [Integer] :max_hp maximum health points. Set to be positive. @option passed_in_stats [Integer] :hp current health points. Set to be nonnegative. @option passed_in_stats [Integer] :attack strength in battle. Set to be positive. @option passed_in_stats [Integer] :defense protection from attacks. Set to be positive. @option passed_in_stats [Integer] :agility speed of commands in battle. Set to be positive.

# File lib/goby/entity/entity.rb, line 223
def set_stats(passed_in_stats)
  current_stats = @stats || { max_hp: 1, hp: nil, attack: 1, defense: 1, agility: 1 }
  constructed_stats = current_stats.merge(passed_in_stats)

  # Set hp to max_hp if hp not specified
  constructed_stats[:hp] = constructed_stats[:hp] || constructed_stats[:max_hp]
  # hp should not be greater than max_hp
  constructed_stats[:hp] = [constructed_stats[:hp], constructed_stats[:max_hp]].min
  #ensure hp is at least 0
  constructed_stats[:hp] = constructed_stats[:hp] > 0 ? constructed_stats[:hp] : 0
  #ensure all other stats > 0
  constructed_stats.each do |key,value|
    if [:max_hp, :attack, :defense, :agility].include?(key)
      constructed_stats[key] = value.nonpositive? ? 1 : value
    end
  end

  @stats = constructed_stats
end
stats() click to toggle source

getter for stats

@return [Object]

# File lib/goby/entity/entity.rb, line 246
def stats
  # attr_reader makes sure stats cannot be set via stats=
  # freeze makes sure that stats []= cannot be used
  @stats.freeze
end
unequip_item(item) click to toggle source

Unequips the specified item from the entity's outfit.

@param [Item, String] item the item (or its name) to unequip.

# File lib/goby/entity/entity.rb, line 255
def unequip_item(item)
  pair = @outfit.detect { |type, value| value.name.casecmp(item.to_s).zero? }
  if pair
    # On a successful find, the "detect" method always returns
    # an array of length 2; thus, the following line should not fail.
    item = pair[1]
    item.unequip(self)
    add_item(item)
  else
    print NOT_EQUIPPED_ERROR
  end
end
use_item(item, entity) click to toggle source

Uses the item, if it exists, on the specified entity.

@param [Item, String] item the item (or its name) to use. @param [Entity] entity the entity on which to use the item.

# File lib/goby/entity/entity.rb, line 272
def use_item(item, entity)
  index = has_item(item)
  if index
    actual_item = inventory[index].first
    actual_item.use(self, entity)
    remove_item(actual_item) if actual_item.consumable
  else
    print NO_SUCH_ITEM_ERROR
  end
end

Private Instance Methods

check_and_set_gold() click to toggle source

Safety function that prevents gold from decreasing below 0.

# File lib/goby/entity/entity.rb, line 295
def check_and_set_gold
  @gold = 0 if @gold.negative?
end