I have attempted to create a shop, this shop is going to use a specific currency. I wanted to understand the way the shop classes, scenes, windows and such worked so I attempted to go out and create my own. I am no where near it though. Thus I need your help.
Note: This script is based of, Tsukihime, http://dl.dropboxusercontent.com/u/23043573/RPG%20Maker/RMVXA%20Scripts/Shop_Manager.txt (http://dl.dropboxusercontent.com/u/23043573/RPG%20Maker/RMVXA%20Scripts/Shop_Manager.txt)
Couple of issues:
- put @inventory.inspect will give me [[#<ClassObject>, #<ClassObject>]] instead of the items.
- when calling the scene to init the shop, I get an error on make_item_list, stating that .each doesn't exist. essentially it cant walk through an empty array.
This script composes of a series of classes that extend the parent, thus to reduce the need to re-write everything, but also allowing me to over ride, or use specific parent methods.
This script, for the time being is called as such:
## Create your items
$kc_shop.create_master_inventory(1, 1, 1, 10) #id (unique), #item_type, #item_id, #price
$kc_shop.create_master_inventory(2, 1, 2, 10) #id (unique), #item_type, #item_id, #price
## Open the shop window
GS.call_shop(GS.setup($kc_shop.get_inv)) #call the shop while passing the master inventory list to the shop window.
There are things that I am missing in the main script and some naming issues have arisen, I understand that. How ever The main issue I am trying to solve, aside from those out lined in the list above is why I am getting: undefined each for Nil:NilClass.
Its obvious to me, The inventory list is not being passed to the window, yet I assumed I took care of that in the GS.call_shop() method.
Note: This script is documented, how ever not deeply, near the end there is no documentation. I have created my own object for dealing with items called: Game_Guild_ShopObject
module GS
def self.setup(goods, purchase_only = false)
shop = Game_Guild_Shop.new(goods, purchase_only)
end
def self.call_shop(shop)
SceneManager.call(Scene_Guild_Shop)
SceneManager.scene.prepare(shop)
end
end
#==============================================================================
# ** DataManager
#------------------------------------------------------------------------------
# Create a new object called $kc_shop.
#==============================================================================
class << DataManager
#--------------------------------------------------------------------------
# * Create Game Objects
#--------------------------------------------------------------------------
alias kalacious_guild_shop_game_objects create_game_objects
def create_game_objects
kalacious_guild_shop_game_objects
$kc_shop = Game_Guild_ShopSetup.new
end
end
#==============================================================================
# ** Game_Guild_ShopSetup
#------------------------------------------------------------------------------
# Helps to set up the core shop it's self.
#==============================================================================
class Game_Guild_ShopSetup
attr_accessor :inventory_list
#--------------------------------------------------------------------------
# * Set up an empty array of inventory items
#--------------------------------------------------------------------------
def initialize
@inventory_list = []
end
#--------------------------------------------------------------------------
# * Create a master inventory list.
#--------------------------------------------------------------------------
def create_master_inventory(id, item_type, item_id, item_price)
inventory = make_inventory(id, item_type, item_id, item_price)
@inventory_list.push(inventory)
end
#--------------------------------------------------------------------------
# * Retieve the object.
#--------------------------------------------------------------------------
def get_inv
return @inventory_list
end
#--------------------------------------------------------------------------
# * Make the inventory.
#--------------------------------------------------------------------------
private
def make_inventory(id, item_type, item_id, item_price)
inventory = Game_Guild_ShopObject.new(id, item_type, item_id, item_price)
return inventory
end
end
#==============================================================================
# ** Game_Guild_ShopObject
#------------------------------------------------------------------------------
# This class is a wrapper for how the shops object stores the data about
# the items in the shop.
#==============================================================================
class Game_Guild_ShopObject
attr_reader :id
attr_reader :item_type
attr_reader :item_id
attr_reader :item_price
#--------------------------------------------------------------------------
# * Set up the objects
#--------------------------------------------------------------------------
def intialize(id, item_type, item_id, item_price)
@id = id
@item_type = item_type
@item_id = item_id
@item_price = item_price
end
#--------------------------------------------------------------------------
# * Return the $data_item, $data_weapons or $data_armor based on the id and
# the type.
#--------------------------------------------------------------------------
def guild_shop_item
return $data_items[@item_id] if @item_type == 0
return $data_weapons[@item_id] if @item_type == 1
return $data_armor[@item_id] if @item_type == 2
end
#--------------------------------------------------------------------------
# * Return the price.
#--------------------------------------------------------------------------
def get_guild_shop_price
return @price
end
end
#==============================================================================
# ** Game_Game_Shop
#------------------------------------------------------------------------------
# This class is responsible for dealing with the inventory of a guild shop.
# That is, we deal with the abillity to purchase only, the inventory, in
# regards to adding and deleting items and the abillity to, or the need for,
# the shop to be refreshed.
#==============================================================================
class Game_Guild_Shop
attr_reader :purchase_only
attr_reader :inventory
attr_accessor :refresh
#--------------------------------------------------------------------------
# * Set up the core shop.
#--------------------------------------------------------------------------
def initialize(goods, purchase_only = false)
@purchase_only = purchase_only
@inventory = goods
@refresh = false
end
#--------------------------------------------------------------------------
# * Return the inventory.
#--------------------------------------------------------------------------
def get_guild_shop_inventory
return @inventory
end
#--------------------------------------------------------------------------
# * Add a new item.
#--------------------------------------------------------------------------
def add_item(item)
@inventory.push(item) unless @inventory.include? (item)
end
#--------------------------------------------------------------------------
# * Delete an item based on id.
#--------------------------------------------------------------------------
def delete_item(item_id)
@inventory.delete_at(item_id-1)
end
end
class Window_Guild_Shop_Buy < Window_ShopBuy
def get_current_item
@inventory[item]
end
def make_item_list
@data = []
@items = {}
@price = {}
@inventory.each do |inventory|
item = inventory.item
@data.push(item)
@items[item] = inventory
@prive[item] = inventory.price
end
end
end
class Scene_Guild_Shop < Scene_Shop
def prepare(goods, purchase_only = false)
super
@inventory = goods
@purcahse_only = purchase_only
end
def create_buy_window
wy = @dummy_window.y
wh = @dummy_window.height
@buy_window = Window_Guild_Shop_Buy.new(0, wy, wh, @goods)
@buy_window.viewport = @viewport
@buy_window.help_window = @help_window
@buy_window.status_window = @status_window
@buy_window.hide
@buy_window.set_handler(:ok, method(:on_buy_ok))
@buy_window.set_handler(:cancel, method(:on_buy_cancel))
end
end
Well, without commenting on anything else in the script, you are correct that your present problem is that you never pass the inventory array you create to the window.
Part of the problem is you don't seem to name your variables consistently. For instance, Scene_Guild_Shop is:
class Scene_Guild_Shop < Scene_Shop
def prepare(goods, purchase_only = false)
super
@inventory = goods
@purcahse_only = purchase_only
end
def create_buy_window
wy = @dummy_window.y
wh = @dummy_window.height
@buy_window = Window_Guild_Shop_Buy.new(0, wy, wh, @goods)
@buy_window.viewport = @viewport
@buy_window.help_window = @help_window
@buy_window.status_window = @status_window
@buy_window.hide
@buy_window.set_handler(:ok, method(:on_buy_ok))
@buy_window.set_handler(:cancel, method(:on_buy_cancel))
end
end
You are passing to your window the @goods variable, but at no point have you ever defined an @goods variable. In your prepare method, you have a local variable named goods, but the instance variable you have named @inventory. Since @goods has never been defined, you are passing to your window a NilObject.
Even once you fix that, however, you will run into a further problem. In Window_Guild_Shop_Buy, you try to access @inventory several times, but that is also never defined. In the superclass, Window_ShopBuy, the variable you send to the initialize method will be assigned to an instance variable named @shop_goods.
As such, that is the name it in your Window_Guild_Shop_Buy class, not @inventory.
But then you have to recall that that variable is still only holding a Game_Guild_Shop object, for which no each method has been defined. As such, what you want to send to the window is not that, but is rather the inventory array. As such, in your prepare method, you might want to do:
@inventory = goods.inventory
But even then you have weird things going on in your window, like:
item = inventory.item
inventory is a Game_Guild_ShopObject, but you have never defined an item method in it. It should be guild_shop_item instead. Moreover, you later try to use the method price, when the method you have defined is get_guild_shop_price (which tries to access @price, which you've never defined and which should be @item_price - but @item_price already has a getter method since you used attr_reader, so this method is superfluous). Also, you misspell @price @prive in your block in the make_item_list method.
Anyway, I could go on, but I think you get the picture and I don't want to deprive you of the learning opportunity (rather, the massive wall of frustration you'll one day look back on as a learning opportunity). Primarily, you need to clean up your use of variable names and you need to identify them correctly when you try to retrieve them, and you need to know what each variable is holding. As it is, there's a lot of confusion, and it's very difficult to tell what object each variable is or is supposed to be. That is what is causing your errors at this point.
This entire thread can be closed I completely rebuilt the whole thing and now it works, it does what I want and everything is grand. Thanks
That's good to hear!