Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #-------------------------------------------------------------------------------
- # page 1 of 12
- # Shopoholic v 2.0
- # code by cmpsr2000
- # available exclusively @ rpgrevolution.com/forums
- # Released June 25, 2008
- #
- #-------------------------------------------------------------------------------
- module Vocab
- BankAccounts = "Accounts"
- BankVault = "Vault"
- BankCancel = "Cancel"
- BankDeposit = "Deposit"
- BankWithdraw = "Withdraw"
- BankTransfer = "Transfer"
- #-----------------------------------------------------------------------------
- # The variables below probably belong in a banking module, I'll update it
- # when I'm not feeling so lazy!
- #-----------------------------------------------------------------------------
- # Icon indexes for each account type.
- #-----------------------------------------------------------------------------
- BankAccountIcons = [ #Savings Icon
- 1631,
- #Checking Icon
- 1666,
- #Loan Icon
- 1630
- ]
- #-----------------------------------------------------------------------------
- # Help window text for accounts.
- #-----------------------------------------------------------------------------
- BankDescriptions = [ #Savings Description
- "A high yield savings account.",
- #Checking Description
- "Provides credit for shopkeepers.",
- #Loan Description
- ""
- ]
- #-----------------------------------------------------------------------------
- # Account names.
- #-----------------------------------------------------------------------------
- BankAccountNames = [ #Savings
- "Savings",
- #Checking
- "Checking",
- #Loan
- "Loan"
- ]
- end
- #-------------------------------------------------------------------------------
- # Updates the Scene_title class to add in the new game objects
- #-------------------------------------------------------------------------------
- class Scene_Title < Scene_Base
- alias oldCreateGameObjectsShopoholic create_game_objects
- def create_game_objects
- oldCreateGameObjectsShopoholic
- $game_shopping = Game_Shopping.new
- $game_banking = Game_Banking.new
- end
- end
- #-------------------------------------------------------------------------------
- # updates scene file to allow persistance of the game objects accross sessions
- #-------------------------------------------------------------------------------
- class Scene_File < Scene_Base
- alias oldWriteSaveShopoholic write_save_data
- def write_save_data(file)
- oldWriteSaveShopoholic(file)
- Marshal.dump($game_shopping, file)
- Marshal.dump($game_banking, file)
- end
- alias oldReadSaveShopoholic read_save_data
- def read_save_data(file)
- oldReadSaveShopoholic(file)
- $game_shopping = Marshal.load(file)
- $game_banking = Marshal.load(file)
- end
- end
- #-------------------------------------------------------------------------------
- # The main redefinition, changes the shoping scene to include the new features
- #-------------------------------------------------------------------------------
- class Scene_Shop < Scene_Base
- def initialize(*args)
- if args.length < 1
- initBasic
- else
- @shopID = args[0]
- @discountRate = args[1] #for selling used items back to the player
- @sellRate = args[2] #For buying items from the player
- @markupRate = args[3] #For greed or generosity
- @taxRate = args[4] #tax rate
- @inflationRate = args[5] #price increase on high-demand items
- @restockRate = args[6] #minutes between restockings
- @continuousRestock = args[7] #controlls restock timer behaviour
- @rates = [@discountRate, @sellRate, @markupRate,
- @taxRate, @inflationRate]
- end
- if (timeElapsed? and @restockRate > 0) or
- $game_shopping.shopRestockTimers[@shopID] == 0
- restock
- $game_shopping.resetTimer(@shopID, @restockRate, @continuousRestock)
- end
- setMoney
- end
- def setMoney
- if $game_shopping.shopsAcceptDebit and $game_party.hasDebitItem
- @money = $game_party.netLiquidity
- else
- @money = $game_party.gold
- end
- end
- def initBasic
- @shopID = $game_shopping.currentShopID
- @discountRate = $game_shopping.currentDiscountRate
- @sellRate = $game_shopping.currentSellRate
- @markupRate = $game_shopping.currentMarkupRate
- @taxRate = $game_shopping.currentTaxRate
- @inflationRate = $game_shopping.currentInflationRate
- @restockRate = 0
- @rates = [@discountRate, @sellRate, @markupRate,
- @taxRate, @inflationRate]
- end
- def terminate
- super
- dispose_menu_background
- dispose_command_window
- @help_window.dispose
- @gold_window.dispose
- @dummy_window.dispose
- @buy_window.dispose
- @sell_window.dispose
- @number_window.dispose
- @details_window.dispose
- @message_window.dispose
- end
- def start
- super
- create_menu_background
- create_command_window
- @help_window = Window_Help.new
- @gold_window = Window_Shop_Gold.new(384, 56)
- @dummy_window = Window_Base.new(0, 112, 544, 304)
- @buy_window = Window_ShopBuy.new(0, 112, @shopID, @rates)
- @buy_window.active = false
- @buy_window.visible = false
- @buy_window.help_window = @help_window
- @sell_window = Window_ShopSell.new(0, 112, 544, 304)
- @sell_window.active = false
- @sell_window.visible = false
- @sell_window.help_window = @help_window
- @number_window = Window_ShopNumber.new(0, 112)
- @number_window.active = false
- @number_window.visible = false
- @details_window = Window_Shop_Details.new(304, 112, 240, 304,
- @rates, @shopID)
- @details_window.visible = false
- @message_window = Window_Shop_Message.new(100, 200, 400, 72)
- @message_window.active = false
- @message_window.visible = false
- end
- def update
- super
- update_menu_background
- @help_window.update
- @command_window.update
- @gold_window.update
- @dummy_window.update
- @buy_window.update
- @sell_window.update
- @number_window.update
- @details_window.update
- if @message_window.visible
- if Input.trigger?(Input::C) or Input.trigger?(Input::B)
- @message_window.visible = false
- end
- else
- if @command_window.active
- update_command_selection
- elsif @buy_window.active
- update_buy_selection
- elsif @sell_window.active
- update_sell_selection
- elsif @number_window.active
- update_number_input
- end
- end
- #check for restock if allowed
- if $game_shopping.allowRestockWhileShopping
- if timeElapsed? and @restockRate > 0
- restock
- $game_shopping.resetTimer(@shopID, @restockRate, @continuousRestock)
- @message_window.showRestockMessage
- @message_window.visible = true
- @buy_window.refreshNeeded = true
- end
- end
- end
- def update_command_selection
- if Input.trigger?(Input::B)
- Sound.play_cancel
- $scene = Scene_Map.new
- elsif Input.trigger?(Input::C)
- case @command_window.index
- when 0 # buy
- Sound.play_decision
- @command_window.active = false
- @dummy_window.visible = false
- @buy_window.active = true
- @buy_window.visible = true
- @buy_window.refresh
- @details_window.visible = true
- @details_window.buyState = true
- when 1 # sell
- if $game_temp.shop_purchase_only
- Sound.play_buzzer
- else
- Sound.play_decision
- @command_window.active = false
- @dummy_window.visible = false
- @sell_window.active = true
- @sell_window.visible = true
- @sell_window.refresh
- @details_window.buyState = false
- end
- when 2 # Quit
- Sound.play_decision
- $scene = Scene_Map.new
- end
- end
- end
- def update_buy_selection
- @details_window.item = @buy_window.item
- if Input.trigger?(Input::B)
- Sound.play_cancel
- @command_window.active = true
- @dummy_window.visible = true
- @buy_window.active = false
- @buy_window.visible = false
- @details_window.visible = false
- @details_window.item = nil
- @help_window.set_text("")
- return
- end
- if Input.trigger?(Input::C)
- @item = @buy_window.item
- if @item == nil
- Sound.play_buzzer
- return
- end
- if @item.is_a?(RPG::Skill) or @item.is_a?(RPG::Class) or
- @item.is_a?(RPG::Actor)
- number = 0
- resellNumber = $game_temp.shop_goods[@buy_window.index - 1][2]
- @price = $game_shopping.shopPrice(@item, @rates, true)
- else
- number = $game_party.item_number(@item)
- if itemIsUsed?
- resellNumber = $game_shopping.shopUsedItems[@shopID][@item]
- @price = $game_shopping.shopPrice(@item, @rates, true, true)
- else
- isInflated = false
- itemMax = $game_shopping.shopLimitedItems[@shopID][@item]
- if itemMax == nil or itemMax == false or
- itemMax == true or itemMax == -1
- resellNumber = 99
- else
- resellNumber = itemMax
- isInflated = itemMax <= $game_shopping.demandAmount
- end
- @price = $game_shopping.shopPrice(@item, @rates, true, false,
- isInflated)
- end
- end
- if @item == nil or @price > @money or number == 99
- Sound.play_buzzer
- else
- max = @price == 0 ? 99 : @money / @price
- max = [max, resellNumber, 99 - number].min
- if max == 0
- Sound.play_buzzer
- @message_window.showOutOfStockMessage(@item)
- @message_window.visible = true
- else
- Sound.play_decision
- if @item.is_a?(RPG::Skill)
- if $game_shopping.exhaustableSkills
- callNumberWindow(max)
- elsif not @item.discovered
- buyItem(1)
- else
- @message_window.showOutOfStockMessage(@item)
- @message_window.visible = true
- end
- elsif @item.is_a?(RPG::Class) or @item.is_a?(RPG::Actor)
- if not @item.discovered
- buyItem(1)
- else
- @message_window.showOutOfStockMessage(@item)
- @message_window.visible = true
- end
- else
- callNumberWindow(max)
- end
- end
- end
- end
- end
- def callNumberWindow(max)
- @buy_window.active = false
- @buy_window.visible = false
- @number_window.set(@item, max, @price)
- @number_window.active = true
- @number_window.visible = true
- end
- def update_sell_selection
- if Input.trigger?(Input::B)
- Sound.play_cancel
- @command_window.active = true
- @dummy_window.visible = true
- @sell_window.active = false
- @sell_window.visible = false
- @details_window.item = nil
- @help_window.set_text("")
- elsif Input.trigger?(Input::C)
- @item = @sell_window.item
- @details_window.item = @item
- if @item == nil or @item.price == 0
- Sound.play_buzzer
- else
- Sound.play_decision
- max = $game_party.item_number(@item)
- @price = $game_shopping.sellItemPrice(@item, @rates)
- @sell_window.active = false
- @sell_window.visible = false
- @number_window.set(@item, max, @price)
- @number_window.active = true
- @number_window.visible = true
- @details_window.visible = true
- end
- end
- end
- def cancel_number_input
- Sound.play_cancel
- @number_window.active = false
- @number_window.visible = false
- case @command_window.index
- when 0 # Buy
- @buy_window.active = true
- @buy_window.visible = true
- when 1 # Sell
- @sell_window.active = true
- @sell_window.visible = true
- @details_window.visible = false
- end
- end
- def decide_number_input
- Sound.play_shop
- @number_window.active = false
- @number_window.visible = false
- case @command_window.index
- when 0 # Buy
- buyItem(@number_window.number)
- when 1 # sell
- $game_party.gain_gold(@number_window.number * @price)
- $game_party.lose_item(@item, @number_window.number)
- itemHash = {@item => @number_window.number}
- $game_shopping.shopUsedItems[@shopID].update(itemHash)
- setMoney
- @gold_window.refresh
- @sell_window.refresh
- @sell_window.active = true
- @sell_window.visible = true
- @details_window.visible = false
- end
- end
- def buyItem(amount)
- #take gold!
- cost = amount * @price
- if cost > $game_party.gold
- cost -= $game_party.gold
- $game_party.lose_gold($game_party.gold)
- for bank in $game_banking.bankAccounts
- for account in bank
- if account.type == 1 #checking
- if cost > account.balance
- cost -= account.balance
- account.balance = 0
- else
- account.withdraw(cost)
- cost = 0
- end
- end
- end
- break if cost == 0
- end
- else
- $game_party.lose_gold(cost)
- end
- #Give item, or discover if needed
- $game_party.gain_item(@item, amount) if @item.is_a?(RPG::Item) or
- @item.is_a?(RPG::Weapon) or
- @item.is_a?(RPG::Armor)
- $data_skills [@item.id].discover if @item.is_a?(RPG::Skill)
- $data_classes [@item.id].discover if @item.is_a?(RPG::Class)
- $data_actors [@item.id].discover if @item.is_a?(RPG::Actor)
- #update actors if skill discovery occured
- if @item.is_a?(RPG::Skill)
- for x in 1..$data_actors.length - 1
- $game_actors[x].refreshSkills
- end
- end
- #update party if actor discovery occured
- if @item.is_a?(RPG::Actor)
- $game_party.add_actor(@item.id)
- end
- if @item.is_a?(RPG::Skill) and $game_shopping.exhaustableSkills
- #-------------------------------------------------------------------------
- #If you are building a game with exhaustable skills, add code here
- #to increase the specific skill by the purchased amount.
- # Note: @item is a skill object in this context!
- #
- # The next version of shopoholic may implement this if there is
- # enough desire for the feature.
- #-------------------------------------------------------------------------
- end
- itemMax = $game_shopping.shopLimitedItems[@shopID][@item]
- if itemMax != nil and itemMax != false and itemMax != true and itemMax > 0
- $game_shopping.shopLimitedItems[@shopID][@item] -= amount
- elsif itemIsUsed?
- $game_shopping.shopUsedItems[@shopID][@item] -= amount
- end
- setMoney
- @gold_window.refresh
- @buy_window.refresh
- @details_window.refreshNeeded = true
- @buy_window.active = true
- @buy_window.visible = true
- end
- def itemIsUsed?
- return true if @buy_window.index > $game_temp.shop_goods.length
- return false
- end
- def timeElapsed?
- now = Graphics.frame_count / Graphics.frame_rate
- lastRestockTime = $game_shopping.shopRestockTimers[@shopID]
- timeDif = now - lastRestockTime
- return (timeDif / 60).floor >= @restockRate
- end
- def restock
- for goods_item in $game_temp.shop_goods
- case goods_item[0]
- when 0
- item = $data_items [goods_item[1]]
- when 1
- item = $data_weapons[goods_item[1]]
- when 2
- item = $data_armors [goods_item[1]]
- when 3
- item = $data_skills [goods_item[1]]
- when 4
- item = $data_classes[goods_item[1]]
- when 5
- item = $data_actors [goods_item[1]]
- end
- if item != nil
- $game_shopping.shopLimitedItems[@shopID][item] = goods_item[2]
- end
- end
- end
- end
- #-------------------------------------------------------------------------------
- # Updates the shop window to support the new features
- #-------------------------------------------------------------------------------
- class Window_ShopBuy < Window_Selectable
- attr_accessor :refreshNeeded
- def initialize(x, y, shopID, rates)
- super(x, y, 304, 304)
- @shop_goods = $game_temp.shop_goods
- @shopID = shopID
- @rates = rates
- @refreshNeeded = false
- #---------------------------------------------------------------------------
- # Change these if you want to label the item pools differently
- #---------------------------------------------------------------------------
- @headings = ["New Items", "Used Items"]
- refresh
- self.index = 0
- end
- def setMoney
- if $game_shopping.shopsAcceptDebit and $game_party.hasDebitItem
- @money = $game_party.netLiquidity
- else
- @money = $game_party.gold
- end
- end
- def update
- super
- refresh if @refreshNeeded
- end
- def refresh
- setMoney
- @data = []
- @data.push(nil)
- for goods_item in @shop_goods
- case goods_item[0]
- when 0
- item = $data_items[goods_item[1]]
- when 1
- item = $data_weapons[goods_item[1]]
- when 2
- item = $data_armors[goods_item[1]]
- when 3
- item = $data_skills[goods_item[1]]
- when 4
- item = $data_classes[goods_item[1]]
- when 5
- item = $data_actors[goods_item[1]]
- end
- if item != nil
- @data.push(item)
- end
- end
- @labelIndexes = [0, @data.length]
- @data.push(nil)
- soldItems = $game_shopping.shopUsedItems[@shopID]
- for soldItem in soldItems.keys
- if soldItems[soldItem] > 0
- @data.push(soldItem)
- end
- end
- if @data[@data.length-1] == nil
- @item_max = @data.size - 1
- else
- @item_max = @data.size
- end
- create_contents
- for i in 0...@item_max
- if @labelIndexes.index(i) == nil
- draw_item(i)
- else
- draw_label(i) unless i > 0 and i == @item_max
- end
- end
- if self.index > @item_max - 1
- self.index = @item_max - 1
- end
- @refreshNeeded = false
- end
- def draw_item(index)
- item = @data[index]
- if index > @labelIndexes[1]
- price = $game_shopping.shopPrice(item, @rates, true, true)
- forSale = 1
- else
- itemMax = $game_shopping.shopLimitedItems[@shopID][item]
- if itemMax == nil or itemMax == false or itemMax == true
- itemMax = -1
- isInflated = false
- else
- isInflated = (itemMax > 0 and itemMax <= $game_shopping.demandAmount)
- end
- forSale = itemMax == -1 ? 100 : itemMax
- price = $game_shopping.shopPrice(item, @rates, true, false, isInflated)
- end
- if item.is_a?(RPG::Item) or item.is_a?(RPG::Weapon) or item.is_a?(RPG::Armor)
- number = $game_party.item_number(item)
- elsif item.is_a?(RPG::Skill) and $game_shopping.exhaustableSkills
- #number = the current ammount of that skill possesed.
- else
- number = 1
- end
- enabled = (price <= @money and number < 99 and forSale > 0)
- rect = item_rect(index)
- self.contents.clear_rect(rect)
- draw_item_name(item, rect.x + 24, rect.y, enabled)
- rect.width -= 4
- self.contents.draw_text(rect, price, 2)
- end
- def draw_label(index)
- label = @headings[@labelIndexes.index(index)]
- rect = item_rect(index)
- self.contents.clear_rect(rect)
- rect.width -= 4
- self.contents.draw_text(rect, label)
- end
- end
- #-------------------------------------------------------------------------------
- # Allows the Window_Item class to be used in the bank vault
- #-------------------------------------------------------------------------------
- class Window_Item < Window_Selectable
- attr_accessor :column_max
- end
- #-------------------------------------------------------------------------------
- # Updates game_actor to check for discovery of skills
- #-------------------------------------------------------------------------------
- class Game_Actor < Game_Battler
- def setup(actor_id)
- actor = $data_actors[actor_id]
- @actor_id = actor_id
- @name = actor.name
- @character_name = actor.character_name
- @character_index = actor.character_index
- @face_name = actor.face_name
- @face_index = actor.face_index
- @class_id = actor.class_id
- @weapon_id = actor.weapon_id
- @armor1_id = actor.armor1_id
- @armor2_id = actor.armor2_id
- @armor3_id = actor.armor3_id
- @armor4_id = actor.armor4_id
- @level = actor.initial_level
- @exp_list = Array.new(101)
- make_exp_list
- @exp = @exp_list[@level]
- @skills = []
- for i in self.class.learnings
- learn_skill(i.skill_id) if i.level <= @level and
- $data_skills[i.skill_id].discovered
- end
- clear_extra_values
- recover_all
- end
- def refreshSkills
- @skills = []
- for i in self.class.learnings
- learn_skill(i.skill_id) if i.level <= @level and
- $data_skills[i.skill_id].discovered
- end
- end
- end
- #-------------------------------------------------------------------------------
- # Updates game_party to allow for debit purchasing
- #-------------------------------------------------------------------------------
- class Game_Party < Game_Unit
- def netLiquidity
- checkingTotal = 0
- for bank in $game_banking.bankAccounts
- for account in bank
- if account.type == 1 #checking
- checkingTotal += account.balance
- end
- end
- end
- return @gold + checkingTotal
- end
- def hasDebitItem
- return has_item?($game_shopping.debitItem, true)
- end
- end
- #-------------------------------------------------------------------------------
- # Module for discovery of skills, classes and actors. (or anything, in general)
- #-------------------------------------------------------------------------------
- module Discovery
- attr_reader :discovered
- def discover
- @discovered = true
- end
- def hide
- @discovered = false
- end
- end
- #-------------------------------------------------------------------------------
- # Price methods, discovery and icons for skills, classes and actors.
- #-------------------------------------------------------------------------------
- module RPG
- class Skill < UsableItem
- include Discovery
- def price
- return $game_shopping.skillPrices[@id]
- end
- end
- class Class
- include Discovery
- attr_accessor :icon_index
- attr_accessor :description
- def price
- return $game_shopping.classPrices[@id]
- end
- end
- class Actor
- include Discovery
- attr_accessor :icon_index
- attr_accessor :description
- def price
- return $game_shopping.actorPrices[@id]
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement