class Goby::Shop

Allows a player to buy and sell Items.

Constants

NOTHING_TO_SELL

Message for when the player has nothing to sell.

NO_ITEMS_MESSAGE

Message for when the shop has nothing to sell.

WARES_MESSAGE

Introductory greeting at the shop.

Attributes

items[RW]
name[RW]

Public Class Methods

new(name: "Shop", mode: 0, visible: true, items: []) click to toggle source

@param [String] name the name. @param [Integer] mode convenient way for a shop to have multiple actions. @param [Boolean] visible whether the shop can be seen/activated. @param [[Item]] items an array of items that the shop sells.

Calls superclass method Goby::Event::new
# File lib/goby/event/shop.rb, line 19
def initialize(name: "Shop", mode: 0, visible: true, items: [])
  super(mode: mode, visible: visible)
  @name = name
  @command = "shop"
  @items = items
end

Public Instance Methods

buy(player) click to toggle source

The chain of events for buying an item (w/ error checking).

@param [Player] player the player trying to buy an item.

# File lib/goby/event/shop.rb, line 29
def buy(player)

  print_items
  return if @items.empty?

  print "What would you like (or none)?: "
  name = player_input
  index = has_item(name)

  # The player does not want to buy an item.
  return if name.casecmp("none").zero?

  if index.nil? # non-existent item.
    print "I don't have #{name}!\n\n"
    return
  end

  # The specified item exists in the shop's inventory.
  item = @items[index]
  print "How many do you want?: "
  amount_to_buy = player_input
  total_cost = amount_to_buy.to_i * item.price

  if total_cost > player.gold # not enough gold.
    puts "You don't have enough gold!"
    print "You only have #{player.gold}, but you need #{total_cost}!\n\n"
    return
  elsif amount_to_buy.to_i < 1 # non-positive amount.
    puts "Is this some kind of joke?"
    print "You need to request a positive amount!\n\n"
    return
  end

  # The player specifies a positive amount.
  player.remove_gold(total_cost)
  player.add_item(item, amount_to_buy.to_i)
  print "Thank you for your patronage!\n\n"

end
has_item(name) click to toggle source

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

@param [String] name the item's name. @return [Integer] the index of an existing item. Otherwise nil.

# File lib/goby/event/shop.rb, line 73
def has_item(name)
  @items.each_with_index do |item, index|
    return index if item.name.casecmp(name).zero?
  end
  return
end
print_gold_and_greeting(player) click to toggle source

Displays the player's current amount of gold and a greeting. Inquires about next action.

@param [Player] player the player interacting with the shop. @return [String] the player's input.

print_items() click to toggle source

Displays a formatted list of the Shop's items or a message signaling there is nothing to sell.

purchase_price(item) click to toggle source

The amount for which the shop will purchase the item.

@param [Item] item the item in question. @return [Integer] the amount for which to purchase.

# File lib/goby/event/shop.rb, line 109
def purchase_price(item)
  item.price / 2
end
run(player) click to toggle source

The default shop experience.

@param [Player] player the player interacting with the shop.

# File lib/goby/event/shop.rb, line 116
def run(player)

  # Initial greeting.
  puts "Welcome to #{@name}."
  input = print_gold_and_greeting(player)

  while input.casecmp("exit").nonzero?
    if input.casecmp("buy").zero?
      buy(player)
    elsif input.casecmp("sell").zero?
      sell(player)
    end
    input = print_gold_and_greeting(player)
  end

  print "#{player.name} has left #{@name}.\n\n"
end
sell(player) click to toggle source

The chain of events for selling an item (w/ error checking).

@param [Player] player the player trying to sell an item.

# File lib/goby/event/shop.rb, line 137
def sell(player)

  # The player has nothing to sell.
  if player.inventory.empty?
    print NOTHING_TO_SELL
    return
  end

  player.print_inventory

  print "What would you like to sell? (or none): "
  input = player_input
  index = player.has_item(input)

  # The player does not want to sell an item.
  return if input.casecmp("none").zero?

  if index.nil? # non-existent item.
    print "You can't sell what you don't have.\n\n"
    return
  end

  item = player.inventory[index].first
  item_count = player.inventory[index].second

  unless item.disposable # non-disposable item (cannot sell/drop).
    print "You cannot sell that item.\n\n"
    return
  end

  puts "I'll buy that for #{purchase_price(item)} gold."
  print "How many do you want to sell?: "
  amount_to_sell = player_input.to_i

  if amount_to_sell > item_count # more than in the inventory.
    print "You don't have that many to sell!\n\n"
    return
  elsif amount_to_sell < 1 # non-positive amount specified.
    puts "Is this some kind of joke?"
    print "You need to sell a positive amount!\n\n"
    return
  end

  player.add_gold(purchase_price(item) * amount_to_sell)
  player.remove_item(item, amount_to_sell)
  print "Thank you for your patronage!\n\n"

end