Class: Goby::Shop

Inherits:
Event
  • Object
show all
Defined in:
lib/goby/event/shop.rb

Overview

Allows a player to buy and sell Items.

Constant Summary collapse

NO_ITEMS_MESSAGE =

Message for when the shop has nothing to sell.

"Sorry, we're out of stock right now!\n\n"
NOTHING_TO_SELL =

Message for when the player has nothing to sell.

"You have nothing to sell!\n\n"
WARES_MESSAGE =

Introductory greeting at the shop.

"Please take a look at my wares.\n\n"

Constants inherited from Event

Event::DEFAULT_RUN_TEXT

Instance Attribute Summary collapse

Attributes inherited from Event

#command, #mode, #visible

Instance Method Summary collapse

Methods inherited from Event

#==

Constructor Details

#initialize(name: "Shop", mode: 0, visible: true, items: []) ⇒ Shop

Returns a new instance of Shop.

Parameters:

  • name (String) (defaults to: "Shop")

    the name.

  • mode (Integer) (defaults to: 0)

    convenient way for a shop to have multiple actions.

  • visible (Boolean) (defaults to: true)

    whether the shop can be seen/activated.

  • items ([Item]) (defaults to: [])

    an array of items that the shop sells.



19
20
21
22
23
24
# 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

Instance Attribute Details

#itemsObject

Returns the value of attribute items.



186
187
188
# File 'lib/goby/event/shop.rb', line 186

def items
  @items
end

#nameObject

Returns the value of attribute name.



186
187
188
# File 'lib/goby/event/shop.rb', line 186

def name
  @name
end

Instance Method Details

#buy(player) ⇒ Object

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

Parameters:

  • player (Player)

    the player trying to buy an item.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# 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) ⇒ Integer

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

Parameters:

  • name (String)

    the item’s name.

Returns:

  • (Integer)

    the index of an existing item. Otherwise nil.



73
74
75
76
77
78
# 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

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

Parameters:

  • player (Player)

    the player interacting with the shop.

Returns:

  • (String)

    the player’s input.



85
86
87
88
89
90
91
# File 'lib/goby/event/shop.rb', line 85

def print_gold_and_greeting(player)
  puts "Current gold in your pouch: #{player.gold}."
  print "Would you like to buy, sell, or exit?: "
  input = player_input doublespace: false
  print "\n"
  return input
end

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



95
96
97
98
99
100
101
102
103
# File 'lib/goby/event/shop.rb', line 95

def print_items
  if @items.empty?
    print NO_ITEMS_MESSAGE
  else
    print WARES_MESSAGE
    @items.each { |item| puts "#{item.name} (#{item.price} gold)" }
    print "\n"
  end
end

#purchase_price(item) ⇒ Integer

The amount for which the shop will purchase the item.

Parameters:

  • item (Item)

    the item in question.

Returns:

  • (Integer)

    the amount for which to purchase.



109
110
111
# File 'lib/goby/event/shop.rb', line 109

def purchase_price(item)
  item.price / 2
end

#run(player) ⇒ Object

The default shop experience.

Parameters:

  • player (Player)

    the player interacting with the shop.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# 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) ⇒ Object

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

Parameters:

  • player (Player)

    the player trying to sell an item.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# 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