[Script] [ACE] [System] Shop Upgrade 2.5

sanggameboysanggameboy Posts: 1,943Registered
[align=center][size=xx-large]Shop Upgrade 2.5[/size][/align]

[chapter]Giới thiệu[/chapter]
Cái Shop mặc định của RPG quả thật rất.... well... bad :)
Nhưng với script này, bạn sẽ thấy hệ thống Shop bây giờ rất tuyệt :)
Rất giống với các minigame khác.

[chapter]Tính năng[/chapter]
- Hình nền
- Sử dụng một windowskin khác
- Hình ảnh người bán hàng có thể thay đổi khi bạn tiến thành mua (ví dụ: khi bạn mua một món hàng, người bán hàng sẽ cười. Còn nếu bạn bán, người bán hàng sẽ cau mày ^^ nhăn mặt, cầm dao, cầm súng và vài nén hương, etc).
- Có thể hiện lời thoại của người bán hàng khi đang tiến hành mua (ví dụ: "Cảm ơn vì đã mua hàng", "bạn có cần gì khác không?", "Bây giờ đang là mùa hạ giá", "cái này tốt lắm, lại rẻ nữa, not made in chine", "mua đi mua đi", etc)
- Mọi thứ ở trên đều có thể thay đổi khi tới một cửa hàng khác. (Điều này khiến mọi shop không lặp đi lặp lại giống nhau :D, giúp game đỡ nhàm tẻ)
- Và nhiều tính năng khác...

[chapter]Screenshots[/chapter]
shop-upgrade2_zps8e9d1086.jpgshop-upgrade2_zps6a888e4b.jpg

[chapter]Hướng dẫn sử dụng[/chapter]
Bỏ Script trên script Main
Đọc hướng dẫn ở phần trên Script. Hình ảnh thì bỏ vào mục /Graphics/Pictures.

[chapter]Download[/chapter]
#------------------------------------------------------------------------------#
#  Galv's Shop Upgrade
#------------------------------------------------------------------------------#
#  For: RPGMAKER VX ACE
#  Version 2.5
#  Thanks Nicke for scrolling help
#------------------------------------------------------------------------------#
#  2013-02-12 - Version 2.5 - bug fix for changing text
#  2013-02-12 - Version 2.4 - added a stock feature to limit items in shops
#                           - added pose for trying to buy out of stock
#  2013-01-24 - Version 2.3 - fixed bug with displaying item mana gain
#  2013-01-22 - Version 2.2 - added compatability with YEA Equip Dynamic Stats
#  2013-01-16 - Version 2.1 - added changeable windowskin for shop
#  2013-01-15 - Version 2.0 - fixed a bug with talking when viewing details
#  2013-01-15 - Version 1.9 - animated actors when item is equippable
#                             added more settings for equip status window
#  2013-01-15 - Version 1.8 - added pose for trying to view details on no item
#  2013-01-15 - Version 1.7 - added pose for when details window is open
#                           - added sound effect option for open/close details
#  2013-01-15 - Version 1.6 - added state resist feature to equips
#  2013-01-15 - Version 1.5 - added 'details' to show item features + stats
#  2013-01-12 - Version 1.4 - more poses added: too many items, farewell
#  2013-01-12 - Version 1.3 - more poses added: greet, cant buy, cant sell
#  2013-01-12 - Version 1.2 - changed name to "Galv's Shop Upgrade"
#                             added variable that controls selling rate
#                             modified shop window positions
#                             changed the 'better/worse' item status display
#  2013-01-07 - Version 1.1 - added background scrolling
#  2013-01-05 - Version 1.0 - release
#------------------------------------------------------------------------------#
# This script overwrites much of the default shop.
# It adds a background and shopkeeper images, uses a variable to contol selling
# price and rearranges the shop windows.
#
# The shopkeeper can change graphic throughout the shopping process to be used
# to make them smile or anything else your imagination thinks of.
# It also adds text that displays for shopkeeper talk during this process.
#
# This script does not include graphics for you to use. You'll need to create
# your own.
#
# The script can also keep track of stock in different shops, even if you sell
# items to the shop, it will add that item to it's buy list.
#
#------------------------------------------------------------------------------#
#  INSTRUCTIONS:
#------------------------------------------------------------------------------#
#  Put script under Materials and above Main
#  Images go in /Graphics/Pictures/ folder.
#
#------------------------------------------------------------------------------#
#  SCRIPT CALLS to change images
#------------------------------------------------------------------------------#
#
# $game_system.shopkeeper = "ImageName"         # Changes shopkeeper image
#
# $game_system.shopback = "ImageName"           # Changes background image
#
# $game_system.shop_windowskin = "ImageName"    # Change windowskin for shop
#                                               # /Graphics/System/ folder
#
#------------------------------------------------------------------------------#
#  ADVANCED SCRIPT CALL to change shopkeeper talk (x is the line in settings)
#------------------------------------------------------------------------------#
#
# $game_system.shop_talk[x] = "New shopkeeper saying here" 
#
#------------------------------------------------------------------------------#
# The reason I say this is advanced is because it's used in the tiny script call
# box, you may need to use additional code. An example below:
#
#     $game_system.shop_talk[0] = "This will " +
#     "change the text for the initial welcome 
#     message."
#
# See below in SHOPKEEPER TALK each quote will be numbered to use here.
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  SCRIPT CALLS to control SHOP STOCK
#------------------------------------------------------------------------------#
#
# shop(shop_id)    # Use this script call to set the next shop processing event
#                  # to be a certain shop number. If you do not use this script
#                  # call before a shop event, the shop will not use stock.
#
# add_stock(shop_id,type,item_id,amount)     # Add a number of items to the shop
#                                            # number you specify.
#
# rem_stock(shop_id,type,item_id,amount)     # Remove a number of items from the
#                                            # shop number you specify.
#
# bulk_fill(shop_id,type,amount,[id,id,id])  # Add items to a shop in bulk.
#
# 
#   # If you do NOT add an item as stock (using the above script call) to a shop
#   # that includes that item in the shop processing event - that item will be
#   # unlimited.
#
#------------------------------------------------------------------------------#
#  EXPLANATION of the above script calls
#------------------------------------------------------------------------------#
# shop_id 
# This is a number you choose to use for a certain shop. You can use this
# number for any shop anywhere and it will keep track of what items are sold
# and bought from it. You can have as many different shop id's as you likd.
#
# type
# 0 = an item     1 = a weapon     2 = an armor
#
# item_id   or   id
# The id of the item/weapon/armor in your database.
#
# amount
# How many of the item you wish to add or remove from the chosen shop id.
#
#------------------------------------------------------------------------------#
#  EXAMPLES
#------------------------------------------------------------------------------#
#
#  add_stock(2,0,1,20)     # Will add 20 of item 1 to shop number 2
#  add_stock(6,1,10,2)     # Will add 2 of weapon 10 to shop number 6
#  rem_stock(6,1,10,2)     # Will remove 2 of weapon 10 from shop number 6
#
#  bulk_fill(1,0,20,[1,2,3,4,5,6])  # Will add 20 of each item inside square 
#                                   # brackets to shop number 1
#
#  bulk_fill(3,2,1,[12,22,13])      # Will add 1 of each armor inside square 
#                                   # brackets to shop number 3
#
#  shop(3)                 # The next shop processing will use shop number 3
#
#------------------------------------------------------------------------------#

($imported ||= {})["Galvs_Shopkeepers"] = true
module Galv_Shopkeeper

#------------------------------------------------------------------------------#
#  SCRIPT SETTINGS
#------------------------------------------------------------------------------#
  #-------------------#
  # SHOPKEEPER IMAGES #
  #-------------------#
  
  SHOPKEEPER_IMAGE = "shopkeeper"
  
  # Shopkeeper will change to an image using the current shopkeeper file name
  # with the below extentions added (eg. Graphics/Pictures/shopkeeper_happy.png)
  
  GREET = "_happy"         # image extension greeting when you enter shop
  FAREWELL = "_happy"      # image extension when you leave the shop
  
  BUY = "_happy"           # image extension when you buy an item
  SELL = "_happy"          # image extension when you sell an item
  
  DONT_BUY = "_annoyed"    # image extension when you don't buy something
  DONT_SELL = "_annoyed"   # image extension when you don't sell something
  
  CANT_BUY = "_annoyed"    # image extension when you can't afford something
  CANT_SELL = "_annoyed"   # image extension when you can't sell an item
  MAX_ITEMS = "_annoyed"   # image extension when you can't hold more of an item
  SOLD_OUT = "_happy"   # image extension when can't buy sold out item
  
  SHOW_DETAILS = "_happy"  # image extension when show details window is open
  NO_DETAILS = "_annoyed"  # image extension when no item when 'd' pressed


  #-------------------#
  # BACKGROUND IMAGE  #
  #-------------------#
  
  SHOP_BACKGROUND = "shop_background"   # background image behind shopkeeper
  BACKGROUND_SCROLL_X = 0               # speed background scroll horizontally
  BACKGROUND_SCROLL_Y = 0               # speed background scroll vertically

  WINDOWSKIN = "Window"            # windowskin used by shop

  #-----------------#
  # SHOPKEEPER TALK #
  #-----------------#
  
  # These are defaults. You can change them using script calls during game.
  
  TALK = [ # don't touch
  
    "Welcome! Take a look around!",     # 0: when entering a shop
    "Thank you for your purchase!",     # 1: when purchase an item
    "I'll make good use of this.",      # 2: when sell an item
    "Do you need anything else?",       # 3: when in root menu after shopping
    "Just window shopping, huh?",       # 4: when in root menu but didn't buy
    "Are you wasting my time or what?", # 5: when in root menu but didn't sell
    "You don't have enough money!",     # 6: when try to buy too pricey item
    "I can't buy that...",              # 7: when try to sell something you cant
    "You can't carry any more of that!",# 8: when try to buy when items maxed
    "Thank you, come back again soon!", # 9: when leaving a shop
    "You can't view details of that!",  # 10: when pressing 'd' on no item.
    "We are all sold out of those!",    # 11: when item is sold out
    
  ] # don't touch
  
  
  #---------------#
  # OTHER OPTIONS #
  #---------------#
  
  ITEM_COUNT_TEXT = "In Inventory"    # Text that appears before item amount
  HOW_MANY_TEXT = "How Many?"         # Text for when determining how many
  STOCK_TEXT = "In Stock"             # Text to display how many items in stock
                                      # only displays if a limit is set.
  NO_STOCK = "Sold Out"               # Displayed if limit of 0 is reached
  STOCK_COLOR = 6                     # Color of stock text.


  
  FRAME_TIME = 75        # time that above text and images stay active before
                         # returning to default image and no talk.
                         # (60 = 1 second)
  
  SALE_VAR = 1           # variable that controls sale price as a % of item's
                         # price. Default is 50, use control variables to change
                         # this during the game. Make this 0 to not use this
                         # feature.

  DETAILS_KEY = :Z       # :Z is "D". Press "D" in the shop to show the item
                         # selected's details.

  D_IMAGE = "detail_key" # The image used to show what key to press for details
                         # This image goes in /Graphics/System/

  SE1 = ["Book2", 85, 100]  # Sound effect played when opening details
  SE2 = ["Blow1", 85, 150]  # Sound effect played when closing details
  
  ACTORS_SHOWN = 4       # Number of actors shown in the equip status window
  ACTORS_X = 15          # x position of first actor in the equip status window
  ACTORS_SPACE = 70      # space between each actor in equip status window

  # Settings to fit 6 actors here nicely are:
  # ACTORS_SHOWN = 6, ACTORS_X = 5, ACTORS_SPACE = 50
#------------------------------------------------------------------------------#
#  END SCRIPT SETTINGS
#------------------------------------------------------------------------------#
end


module Shop_Stock
  def check_stock(item)
    if item.is_a?(RPG::Item); itype = 0
    elsif item.is_a?(RPG::Weapon); itype = 1
    else; itype = 2; end
    return -1 if item.nil?
    return -1 if $game_system.shop_stock[$game_system.shop_selected][[itype,item.id]].nil?
    if $game_system.shop_stock[$game_system.shop_selected][[itype,item.id]] >= 0
      return $game_system.shop_stock[$game_system.shop_selected][[itype,item.id]]
    else
      return -1
    end
  end
end


class Game_Interpreter
  def shop(shop_id)
    $game_system.shop_selected = shop_id
  end
  
  def add_stock(shop_id,type,item_id,amount)
    # type 0 = item, 1 = weapon, 2 = armor
    $game_system.shop_stock[shop_id] ||= {}
    $game_system.shop_stock[shop_id][[type,item_id]] ||= 0
    $game_system.shop_stock[shop_id][[type,item_id]] += amount
  end
  
  def rem_stock(shop_id,type,item_id,amount)
    # type 0 = item, 1 = weapon, 2 = armor
    return if $game_system.shop_stock[shop_id].nil?
    return if $game_system.shop_stock[shop_id][[type,item_id]].nil?
    $game_system.shop_stock[shop_id][[type,item_id]] -= amount
    if $game_system.shop_stock[shop_id][[type,item_id]] < 0
      $game_system.shop_stock[shop_id][[type,item_id]] = 0
    end
  end
  
  def reset_shop_settings
    $game_system.shopkeeper = Galv_Shopkeeper::SHOPKEEPER_IMAGE
    $game_system.shopback = Galv_Shopkeeper::SHOP_BACKGROUND
    $game_system.shop_windowskin = Galv_Shopkeeper::WINDOWSKIN
    $game_system.shop_talk = Galv_Shopkeeper::TALK
  end
  
  def bulk_fill(*args)
    array = [*args]
    shop_id = array[0]
    type = array[1]
    amount = array[2]
    ids = array[3]
    
    $game_system.shop_stock[shop_id] ||= {}
    ids.each do |i|
      $game_system.shop_stock[shop_id][[type,i]] ||= 0
      $game_system.shop_stock[shop_id][[type,i]] += amount
    end
  end
end # Game_Interpreter


class Game_System
  attr_accessor :shop_selected
  attr_accessor :shop_stock
  attr_accessor :shopback
  attr_accessor :shopkeeper
  attr_accessor :shop_talk
  attr_accessor :shop_spose
  attr_accessor :shop_windowskin
  
  alias galv_shopkeeper_system_initialize initialize
  def initialize
    galv_shopkeeper_system_initialize
    @shopback = Galv_Shopkeeper::SHOP_BACKGROUND
    @shopkeeper = Galv_Shopkeeper::SHOPKEEPER_IMAGE
    @shop_talk = Array.new(Galv_Shopkeeper::TALK)
    @shop_windowskin = Galv_Shopkeeper::WINDOWSKIN
    @shop_spose = nil
    @shop_selected = 0
    @shop_stock = {0=>{}}
  end
  
end # Game_System


class Scene_Shop < Scene_MenuBase
  
  alias galv_shopkeeper_scene_shop_prepare prepare
  def prepare(goods, purchase_only)
    galv_shopkeeper_scene_shop_prepare(goods, purchase_only)
    return if $game_system.shop_stock[$game_system.shop_selected].nil?
    stock_change

  end
  
  def stock_change
    temp_list = $game_system.shop_stock[$game_system.shop_selected].keys
    @goods.each do |i|
      if temp_list.include?([i[0],i[1]])
        temp_list.delete([i[0],i[1]])
      end
    end
    temp_list.each do |i|
      if $game_system.shop_stock[$game_system.shop_selected][[i[0],i[1]]] != 0
        @goods << [i[0],i[1],0,0]
      end
    end
  end
  
  alias galv_shopkeeper_scene_shop_start start
  def start
    galv_shopkeeper_scene_shop_start
    @shoptime = 0
    @has_shopped = false
    create_talk_window
    create_desc_window
    create_shop_background
    create_shopkeeper
    create_images
    @leave_shop = false
    @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::GREET) rescue Cache.picture($game_system.shopkeeper)
    @shoptime = Galv_Shopkeeper::FRAME_TIME
  end
  
  def create_desc_window
    b = @buy_window
    @desc_window = Window_ItemDesc.new(b.x, b.y, b.width, b.height)
    @desc_window.viewport = @viewport
    @desc_window.hide
  end
  
  def create_talk_window
    @talk_window = Window_Help.new
    @talk_window.viewport = @viewport
    @talk_window.set_text($game_system.shop_talk[0])
    @help_window.hide
  end
  
  def create_itemcount_window
    wy = @dummy_window.y
    ww = Graphics.width - 304
    wh = @gold_window.height
    @itemcount_window = Window_ItemCount.new(0, wy, ww, wh)
    @itemcount_window.viewport = @viewport
    @itemcount_window.hide
  end
  
  # OVERWRITE
  def create_dummy_window
    wy = @command_window.y + @command_window.height
    wh = Graphics.height - wy - @gold_window.height * 2
    @dummy_window = Window_Base.new(0, wy, Graphics.width, wh)
    @dummy_window.viewport = @viewport
  end
  
  # OVERWRITE
  def create_buy_window
    wy = @dummy_window.y
    wh = @dummy_window.height
    @buy_window = Window_ShopBuy.new(0, wy, wh, @goods)
    @buy_window.viewport = @viewport
    @buy_window.help_window = @help_window
    @buy_window.status_window = @status_window
    @buy_window.count_window = @itemcount_window
    @buy_window.desc_window = @desc_window
    @buy_window.hide
    @buy_window.set_handler(:ok,     method(:on_buy_ok))
    @buy_window.set_handler(:cancel, method(:on_buy_cancel))
    @buy_window.x = Graphics.width - @buy_window.width
  end
  
  # OVERWRITE
  def create_sell_window
    wy = @category_window.y + @category_window.height
    wh = Graphics.height - wy
    @sell_window = Window_ShopSell.new(0, wy, @buy_window.width, wh)
    @sell_window.viewport = @viewport
    @sell_window.help_window = @help_window
    @sell_window.status_window = @itemcount_window
    @sell_window.hide
    @sell_window.set_handler(:ok,     method(:on_sell_ok))
    @sell_window.set_handler(:cancel, method(:on_sell_cancel))
    @category_window.item_window = @sell_window
    @sell_window.x = Graphics.width - @buy_window.width
  end
  
  alias galv_shopkeeper_create_number_window create_number_window
  def create_number_window
    galv_shopkeeper_create_number_window
    @number_window.x = Graphics.width - @number_window.width
  end
  
  # OVERWRITE
  def create_status_window
    wx = @number_window.x
    wy = @dummy_window.y + @dummy_window.height
    ww = @number_window.width
    wh = Graphics.height - @dummy_window.height - @dummy_window.y
    @status_window = Window_ShopStatus.new(wx, wy, ww, wh)
    @status_window.viewport = @viewport
    @status_window.hide
    create_itemcount_window
  end
  
  alias galv_shopkeeper_create_dummy_window create_dummy_window
  def create_dummy_window
    galv_shopkeeper_create_dummy_window
    @dummy_window.hide
  end
  
  def create_shopkeeper
    @keeper = Sprite.new
    @keeper.bitmap = Cache.picture($game_system.shopkeeper)
    @keeper.y = Graphics.height - @keeper.bitmap.height
  end
  
  def create_images
    @dkey = Sprite.new
    @dkey.opacity = 0
    @dkey.bitmap = Cache.system(Galv_Shopkeeper::D_IMAGE) rescue Cache.system("")
    @dkey.y = Graphics.height - @dkey.bitmap.height
  end
  
  def create_shop_background
    @shopback = Plane.new
    @shopback.bitmap = Cache.picture($game_system.shopback)
  end
  
  alias galv_shopkeer_sell_on_category_ok on_category_ok
  def on_category_ok
    galv_shopkeer_sell_on_category_ok
    @dkey.opacity = 255
  end
  
  # OVERWRITE
  def on_category_cancel
    @command_window.activate
    @category_window.hide
    @sell_window.hide
    if @has_shopped == true
      @talk_window.set_text($game_system.shop_talk[3])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper)
    else
      @talk_window.set_text($game_system.shop_talk[5])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::DONT_SELL)
    end
    show_talk
    @has_shopped = false
  end
  
  # OVERWRITE
  def on_buy_cancel
    @command_window.activate
    @buy_window.hide
    @itemcount_window.hide
    @status_window.hide
    @status_window.item = nil
    @itemcount_window.item = nil
    @help_window.clear
    if @has_shopped == true
      @talk_window.set_text($game_system.shop_talk[3])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper)
    else
      @talk_window.set_text($game_system.shop_talk[4])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::DONT_BUY)
    end
    show_talk
    @has_shopped = false
    @dkey.opacity = 0
  end

  # OVERWRITE
  def on_sell_cancel
    @sell_window.unselect
    @category_window.activate
    @status_window.item = nil
    @itemcount_window.item = nil
    @itemcount_window.hide
    @help_window.clear
    @dkey.opacity = 0
  end
  
  alias galv_shopkeeper_command_buy command_buy
  def command_buy
    galv_shopkeeper_command_buy
    @keeper.bitmap = Cache.picture($game_system.shopkeeper)
    @itemcount_window.show
    hide_talk
    @dkey.opacity = 255
    @desc_window.y = @buy_window.y
    @desc_window.height = @buy_window.height
  end
  
  alias galv_shopkeeper_command_sell command_sell
  def command_sell
    galv_shopkeeper_command_sell
    @keeper.bitmap = Cache.picture($game_system.shopkeeper)
    hide_talk
    @desc_window.y = @sell_window.y
    @desc_window.height = @sell_window.height
  end
  
  alias galv_shopkeeper_do_buy do_buy
  def do_buy(number)
    @has_shopped = true
    galv_shopkeeper_do_buy(number)
    remove_stock(@item,number)
    @talk_window.set_text($game_system.shop_talk[1])
    show_talk
    @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::BUY) rescue Cache.picture($game_system.shopkeeper)
    @shoptime = Galv_Shopkeeper::FRAME_TIME
  end
  
  def remove_stock(item,number)
    return if $game_system.shop_stock[$game_system.shop_selected].nil? ||
    $game_system.shop_selected == 0
    if item.is_a?(RPG::Item); itype = 0
    elsif item.is_a?(RPG::Weapon); itype = 1
    else; itype = 2; end
    return if $game_system.shop_stock[$game_system.shop_selected][[itype,item.id]].nil?
    $game_system.shop_stock[$game_system.shop_selected][[itype,item.id]] -= number
  end

  alias galv_shopkeeper_do_sell do_sell
  def do_sell(number)
    @has_shopped = true
    galv_shopkeeper_do_sell(number)
    add_stock(@item,number)
    stock_change
    @talk_window.set_text($game_system.shop_talk[2])
    show_talk
    @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::SELL) rescue Cache.picture($game_system.shopkeeper)
    @shoptime = Galv_Shopkeeper::FRAME_TIME
  end
  
  def add_stock(item,number)
    return if $game_system.shop_selected == 0
    if item.is_a?(RPG::Item); itype = 0
    elsif item.is_a?(RPG::Weapon); itype = 1
    else; itype = 2; end
    @goods.each do |i|
      if i[0] == itype && i[1] == item.id && $game_system.shop_stock[$game_system.shop_selected][[itype,item.id]].nil?
        return
      end
    end
    $game_system.shop_stock[$game_system.shop_selected][[itype,item.id]] ||= 0
    $game_system.shop_stock[$game_system.shop_selected][[itype,item.id]] += number
  end
  

  # OVERWRITE
  def on_number_ok
    Sound.play_shop
    case @command_window.current_symbol
    when :buy
      do_buy(@number_window.number)
    when :sell
      do_sell(@number_window.number)
      @itemcount_window.hide
    end
    end_number_input
    @gold_window.refresh
    @status_window.refresh
    @itemcount_window.refresh
    @dkey.opacity = 255
  end
  
  alias galv_shopkeeper_on_number_cancel on_number_cancel
  def on_number_cancel
    galv_shopkeeper_on_number_cancel
    case @command_window.current_symbol
    when :sell
      @itemcount_window.hide
    end
    @dkey.opacity = 255
  end

  alias galv_shopkeeper_on_sell_ok on_sell_ok
  def on_sell_ok
    @number_window.trans = :sell
    galv_shopkeeper_on_sell_ok
    @itemcount_window.show
    @dkey.opacity = 0
  end
  
  alias galv_shopkeeper_on_buy_ok on_buy_ok
  def on_buy_ok
    @number_window.trans = :buy
    galv_shopkeeper_on_buy_ok
    @dkey.opacity = 0
  end
  
  
  def end_shopanim
    SceneManager.return if @leave_shop == true
    @keeper.bitmap = Cache.picture($game_system.shopkeeper)
    hide_talk unless @command_window.active
  end
  
  def show_talk
    @talk_window.show
    @help_window.hide
  end
  
  def hide_talk
    @talk_window.hide
    @help_window.show
  end

  def update
    super
    @shoptime -= 1
    end_shopanim if @shoptime == 0
    if @shoptime.odd?
      @shopback.ox += Galv_Shopkeeper::BACKGROUND_SCROLL_X
      @shopback.oy += Galv_Shopkeeper::BACKGROUND_SCROLL_Y
    end
    check_button
    other_poses if $game_system.shop_spose != nil
  end
  
  def check_button
    if @desc_window.visible
      if Input.trigger?(Galv_Shopkeeper::DETAILS_KEY) || Input.trigger?(:B)
        case @command_window.current_symbol
        when :buy
          @buy_window.show.activate
        when :sell
          @sell_window.show.activate
        end
        RPG::SE.new(Galv_Shopkeeper::SE2[0], Galv_Shopkeeper::SE2[1], Galv_Shopkeeper::SE2[2]).play
        @desc_window.hide
        @keeper.bitmap = Cache.picture($game_system.shopkeeper)
      end
    elsif @buy_window.active || @sell_window.active
      if Input.trigger?(Galv_Shopkeeper::DETAILS_KEY)
        case @command_window.current_symbol
        when :buy
          return if @buy_window.item.nil?
          @buy_window.hide.deactivate
          @desc_window.refresh(@buy_window.item,0)
        when :sell
          if @sell_window.item.nil?
            $game_system.shop_spose = 3
            return other_poses
          end
          @sell_window.hide.deactivate
          @desc_window.refresh(@sell_window.item,1)
        end
        @shoptime = 0
        RPG::SE.new(Galv_Shopkeeper::SE1[0], Galv_Shopkeeper::SE1[1], Galv_Shopkeeper::SE1[2]).play
        @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::SHOW_DETAILS) rescue Cache.picture($game_system.shopkeeper)
        hide_talk
        @desc_window.show
      end
    end
  end
  
  def other_poses
    case $game_system.shop_spose
    when 0
      @talk_window.set_text($game_system.shop_talk[6])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::CANT_BUY) rescue Cache.picture($game_system.shopkeeper)
    when 1
      @talk_window.set_text($game_system.shop_talk[7])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::CANT_SELL) rescue Cache.picture($game_system.shopkeeper)
    when 2
      @talk_window.set_text($game_system.shop_talk[8])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::MAX_ITEMS) rescue Cache.picture($game_system.shopkeeper)
    when 3
      @talk_window.set_text($game_system.shop_talk[10])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::NO_DETAILS) rescue Cache.picture($game_system.shopkeeper)
    when 4
      @talk_window.set_text($game_system.shop_talk[11])
      @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::SOLD_OUT) rescue Cache.picture($game_system.shopkeeper)
    end
    show_talk
    @shoptime = Galv_Shopkeeper::FRAME_TIME
    $game_system.shop_spose = nil
  end
  
  def return_scene
    @talk_window.set_text($game_system.shop_talk[9])
    @keeper.bitmap = Cache.picture($game_system.shopkeeper + Galv_Shopkeeper::FAREWELL) rescue Cache.picture($game_system.shopkeeper)
    show_talk
    @shoptime = Galv_Shopkeeper::FRAME_TIME
    @leave_shop = true
    $game_system.shop_selected = 0
  end
  
  def terminate
    super
    @keeper.dispose
    @keeper.bitmap.dispose
    @shopback.dispose
    @dkey.bitmap.dispose
    @dkey.dispose
  end
  
  # OVERWRITE
  def selling_price
    if $game_variables[Galv_Shopkeeper::SALE_VAR] > 0
      ((@item.price * 0.01) * $game_variables[Galv_Shopkeeper::SALE_VAR]).round
    else
      @item.price / 2
    end
  end
  
end # Scene_Shop < Scene_MenuBase


class Scene_Title < Scene_Base
  alias galv_shopkeeper_command_new_game command_new_game
  def command_new_game
    galv_shopkeeper_command_new_game
    $game_variables[Galv_Shopkeeper::SALE_VAR] = 50 if $game_variables[Galv_Shopkeeper::SALE_VAR] > 0
  end
end # Scene_Title < Scene_Base


class Window_ItemCount < Window_Base
  def initialize(x, y, width, height)
    super(x, y, width, height)
    @item = nil
    refresh
  end

  def refresh
    contents.clear
    draw_possession(4, 0)
  end

  def item=(item)
    @item = item
    refresh
  end

  def draw_possession(x, y)
    rect = Rect.new(x, y, contents.width - 4 - x, line_height)
    change_color(system_color)
    draw_text(rect, Galv_Shopkeeper::ITEM_COUNT_TEXT)
    change_color(normal_color)
    draw_text(rect, $game_party.item_number(@item), 2)
  end
end # Window_ItemCount < Window_Base


class Window_ShopNumber < Window_Selectable
  attr_accessor :trans

  alias galv_shopkeeper_number_initialize initialize
  def initialize(x, y, height)
    galv_shopkeeper_number_initialize(x, y, height)
    @trans = :buy
    draw_how_many
    draw_stock
  end
  
  alias galv_shopkeeper_number_refresh refresh
  def refresh
    galv_shopkeeper_number_refresh
    draw_how_many
    draw_stock
  end
  
  def draw_how_many
    change_color(system_color)
    draw_text(4, 4, contents.width, line_height, Galv_Shopkeeper::HOW_MANY_TEXT)
    change_color(normal_color)
  end
  
  def draw_stock
    return if $game_system.shop_stock[$game_system.shop_selected].nil?
    @stock = check_stock(@item)
    
    if @stock > 0
      text = @stock.to_s + " " + Galv_Shopkeeper::STOCK_TEXT
    elsif @stock == 0
      text = Galv_Shopkeeper::NO_STOCK
    elsif @stock < 0
      text = ""
    end
    change_color(text_color(Galv_Shopkeeper::STOCK_COLOR))
    draw_text(4, 4, contents.width, line_height, text + " ",2) if @trans != :sell
    change_color(normal_color)
  end
  
  def change_number(amount)
    if @stock > 0; stock = @stock
    else stock = @max
    end
    if @trans == :buy
      @number = [[@number + amount, @max, stock].min, 1].max
    elsif @trans == :sell
      @number = [[@number + amount, @max].min, 1].max
    end
  end
  
  include Shop_Stock
  
end # Window_ShopNumber < Window_Selectable


class Window_ShopStatus < Window_Base

  alias galv_shopkeeper_window_status_initialize initialize
  def initialize(x, y, width, height)
    @walk = 0
    @step = 0  # 0 is left, 1 is right
    @animtime = 0
    galv_shopkeeper_window_status_initialize(x, y, width, height)
  end
  
  # OVERWRITE
  def refresh
    contents.clear
    draw_equip_info(Galv_Shopkeeper::ACTORS_X + 5, 40) if @item.is_a?(RPG::EquipItem)
  end
  
  def update
    super
    @animtime += 1
    if @animtime == 10
      case @walk
      when 1; @walk -= 1
      when -1; @walk += 1
      when 0
        if @step == 1
          @walk = -1
          @step = 0
        else
          @walk = 1
          @step = 1
        end
      end
      refresh
      @animtime = 0
    end
  end

  # OVERWRITE
  def draw_equip_info(x, y)
    status_members.each_with_index do |actor, i|
      draw_actor_equip_info(x + (i * Galv_Shopkeeper::ACTORS_SPACE), y, actor)
    end
  end

  # OVERWRITE
  def page_size
    return Galv_Shopkeeper::ACTORS_SHOWN
  end

  # OVERWRITE
  def draw_actor_equip_info(x, y, actor)
    enabled = actor.equippable?(@item)
    change_color(normal_color, enabled)
    item1 = current_equipped_item(actor, @item.etype_id)
    draw_actor_param_change(x - 10, y, actor, item1) if enabled
    draw_character(actor.character_name, actor.character_index, x + 10, y, enabled)
  end

  def draw_character(character_name, character_index, x, y,enabled)
    return unless character_name
    bitmap = Cache.character(character_name)
    sign = character_name[/^[\!\$]./]
    if sign && sign.include?('$')
      cw = bitmap.width / 3
      ch = bitmap.height / 4
    else
      cw = bitmap.width / 12
      ch = bitmap.height / 8
    end
    n = character_index
    step = 0
    step = @walk if enabled
    src_rect = Rect.new((n%4*3+1+step)*cw, (n/4*4)*ch, cw, ch)
    contents.blt(x - cw / 2, y - ch, bitmap, src_rect)
  end

  # OVERWRITE
  def draw_actor_param_change(x, y, actor, item1)
    rect = Rect.new(x, y, 40, line_height)
    change = @item.params[param_id] - (item1 ? item1.params[param_id] : 0)
    change_color(param_change_color(change))
    draw_text(rect, sprintf("%+d", change), 1)
  end
end # Window_ShopStatus < Window_Base


class Window_ShopBuy < Window_Selectable
  
  # OVERWRITE
  def initialize(x, y, height, shop_goods)
    super(x, y, window_width, height)
    @shop_goods = shop_goods
    @money = 0
    @max_items_reached = false
    refresh
    select(0)
  end
  
  def count_window=(count_window)
    @count_window = count_window
  end
  
  def desc_window=(desc_window)
    @desc_window = desc_window
  end

  # OVERWRITE
  def update_help
    @help_window.set_item(item) if @help_window
    @status_window.item = item if @status_window
    @count_window.item = item if @count_window
    @desc_window.item = item if @desc_window
  end
  
  # OVERWRITE
  def current_item_enabled?
    if $game_party.item_max?(item)
      @max_items_reached = true 
    else
      @max_items_reached = false
    end
    if check_stock(item) == 0
      @item_sold_out = true
    else
      @item_sold_out = false
    end
    enable?(@data[index])
  end
  
  def enable?(item)
    item && price(item) <= @money && !$game_party.item_max?(item) &&
    check_stock(item) != 0
  end
  
  # OVERWRITE
  def draw_item(index)
    item = @data[index]
    stock = check_stock(item)
    rect = item_rect(index)
    draw_item_name(item, rect.x, rect.y, enable?(item))
    rect.width -= 4
    if stock == 0
      draw_text(rect, Galv_Shopkeeper::NO_STOCK, 2)
    else
      draw_text(rect, price(item), 2)
    end
  end
  
  def process_ok
    if current_item_enabled?
      Sound.play_ok
      Input.update
      deactivate
      call_ok_handler
    else
      if @item_sold_out == true
        $game_system.shop_spose = 4
      elsif @max_items_reached == false
        $game_system.shop_spose = 0
      else
        $game_system.shop_spose = 2
      end
      Sound.play_buzzer
    end
  end
  
  include Shop_Stock
  
end # class Window_ShopBuy < Window_Selectable


class Window_ShopSell < Window_ItemList
  def col_max
    return 1
  end
  
  def process_ok
    if current_item_enabled?
      Sound.play_ok
      Input.update
      deactivate
      call_ok_handler
    else
      $game_system.shop_spose = 1
      Sound.play_buzzer
    end
  end
  
  def status_window=(status_window)
    @status_window = status_window
  end

  def update_help
    @help_window.set_item(item) if @help_window
    @status_window.item = item if @status_window
  end
end # Window_ShopSell < Window_ItemList


class Window_ItemDesc < Window_Base
  def initialize(x, y, width, height)
    super(x, y, width, height)
    @item = nil
    @shop_type = 0
  end
  
  def refresh(item,type)
    @item = item
    contents.clear
    return if item.nil?
    @shop_type = type
    draw_item_name(@item, 0, 0)
    draw_currency_value(get_price, Vocab::currency_unit, 0, 0, contents.width)
    equip_stats if @item.is_a?(RPG::EquipItem)
    item_stats if @item.is_a?(RPG::Item)
  end
  
  def get_price
    if @shop_type == 0
      return @item.price
    else
      if $game_variables[Galv_Shopkeeper::SALE_VAR] > 0
        return ((@item.price * 0.01) * $game_variables[Galv_Shopkeeper::SALE_VAR]).round
      else
        return @item.price / 2
      end
    end
  end

  def stat_col
    contents.width / 2
  end
  
  def equip_stats
    y_offset = -15
    draw_equip_stats(0, line_height * 2 + y_offset, 0)           # HP
    draw_equip_stats(stat_col, line_height * 2 + y_offset, 1)    # MP
    draw_equip_stats(0, line_height * 3 + y_offset, 2)           # ATK
    draw_equip_stats(stat_col, line_height * 3 + y_offset, 3)    # DEF
    draw_equip_stats(0, line_height * 4 + y_offset, 4)           # MAT
    draw_equip_stats(stat_col, line_height * 4 + y_offset, 5)    # MDF
    draw_equip_stats(0, line_height * 5 + y_offset, 6)           # AGI
    draw_equip_stats(stat_col, line_height * 5 + y_offset, 7)    # LUK
    draw_icons(100, line_height * 6 , width = 96)                # States
  end
  
  def item=(item)
    @item = item
    refresh
  end
  
  def draw_equip_stats(x, y, param_id)
    draw_param_name(x + 4, y, param_id)
    draw_param(x + 94, y, param_id)
  end
  
  def draw_icons(x, y, width = 96)
    icons = []  # atk
    icons2 = [] # resistances
    @item.features.each do |f|
      if f.code == 32
        icons << $data_states[f.data_id].icon_index
      elsif f.code == 14
        icons2 << $data_states[f.data_id].icon_index
      end
    end
    if icons != []
      change_color(system_color)
      draw_text(0, line_height * 6, 120, line_height, "Inflicts")
      change_color(normal_color)
      icons.each_with_index {|n, i| draw_icon(n, x + 24 * i, y) }
    elsif icons2 != []
      change_color(system_color)
      draw_text(0, line_height * 6, 120, line_height, "Resists")
      change_color(normal_color)
      icons2.each_with_index {|n, i| draw_icon(n, x + 24 * i, y) }
    end
  end

  def draw_param_name(x, y, param_id)
    change_color(system_color)
    draw_text(x, y, 80, line_height, Vocab::param(param_id))
  end
  
  def draw_param(x, y, param_id)
    if @item.params[param_id] > 0
      change_color(power_up_color)
    elsif @item.params[param_id] < 0
      change_color(power_down_color)
    else
      change_color(normal_color)
    end
    draw_text(x, y, 32, line_height, @item.params[param_id].to_s, 2)
    
  end

  def item_stats
    x = 0
    y = 0
    line = 1
    y_offset = 15
    width = contents.width
    rem_states = []
    add_states = []
    add_buffs = []
    rem_buffs = []
    
    if @item.damage.type != 0
      change_color(system_color)
      case @item.damage.type
      when 1; vocab = Vocab::hp_a + " Damage"
      when 2; vocab = Vocab::mp_a + " Damage"
      when 3; vocab = Vocab::hp_a + " Restore"
      when 4; vocab = Vocab::mp_a + " Restore"
      when 5; vocab = Vocab::hp_a + " Drain"
      when 6; vocab = Vocab::mp_a + " Drain"
      end
      draw_text(0, line_height * line + y_offset, width, line_height, vocab, 0)
      change_color(normal_color)
      draw_text(0, line_height * line + y_offset, width, line_height, @item.damage.formula.to_s, 2)
      line += 1
    end
    
    @item.effects.each do |e|
      next if line == 6
      change_color(system_color)
      case e.code
      when 11; vocab = Vocab::hp_a; vocab2 = Vocab::hp
      when 12; vocab = Vocab::mp_a; vocab2 = Vocab::mp
      when 13; vocab = Vocab::tp_a; vocab2 = Vocab::tp
      end
      
      case e.code
      when 11, 12
        draw_text(0, line_height * line + y_offset, width, line_height, vocab + " (" + vocab2 + ")", 0)
        v1 = (e.value1 * 100).to_i
        v2 = e.value2.to_i
        if e.value1 == 0
          check_color(v2)
          draw_text(0, line_height * line + y_offset, width, line_height, v2.to_s, 2)
        elsif e.value2 == 0
          check_color(v1)
          draw_text(0, line_height * line + y_offset, width, line_height, v1.to_s + "%", 2)
        else
          check_color(v1)
          draw_text(0, line_height * line + y_offset, width, line_height, v2.to_s + " + " + v1.to_s + "%", 2)
        end
        line += 1
      when 13
        draw_text(0, line_height * line + y_offset, width, line_height, vocab + " (" + vocab2 + ")", 0)
        check_color(e.value1)
        draw_text(0, line_height * line + y_offset, width, line_height, e.value1.to_i.to_s + "%", 2)
        line += 1
      when 21
        #add state
        add_states << e.data_id unless e.data_id == 0
      when 22
        #remove state
        rem_states << e.data_id unless e.data_id == 0
      when 31, 32
        #add buff/debuffs
        add_buffs << (64 + e.data_id) if e.code == 31
        add_buffs << (64 + e.data_id + 16) if e.code == 32
      when 33, 34
        rem_buffs << (64 + e.data_id) if e.code == 33
        rem_buffs << (64 + e.data_id + 16) if e.code == 34
      when 42
        #grow stat
        change_color(system_color)
        name = $data_system.terms.params[e.data_id] + " Increase"
        draw_text(0, line_height * line + y_offset, width, line_height, name, 0)
        change_color(normal_color)
        draw_text(0, line_height * line + y_offset, width, line_height, e.value1.to_i.to_s, 2)
        line += 1
      when 43
        #learn skill
        change_color(system_color)
        skill = $data_skills[e.data_id].name
        draw_text(0, line_height * line + y_offset, width, line_height, "Learn", 0)
        change_color(normal_color)
        draw_text(0, line_height * line + y_offset, width, line_height, skill, 2)
        line += 1
      end
    end
    
    if add_states != [] && line < 6 || add_buffs != [] && line < 6
      x = 90
      icons = []
      add_states.each do |s|
        icons << $data_states[s].icon_index
      end
      add_buffs.each do |b|
        icons << b
      end
      change_color(system_color)
      draw_text(0, line_height * line + y_offset, width, line_height, "Applies")
      change_color(normal_color)
      icons.each_with_index {|n, i| draw_icon(n, x + 24 * i, line_height * line + y_offset) }
      line += 1
    end
    
    if rem_states != [] && line < 6 || rem_buffs != [] && line < 6
      x = 90
      icons2 = []
      rem_states.each do |s|
        icons2 << $data_states[s].icon_index
      end
      rem_buffs.each do |b|
        icons2 << b
      end
      change_color(system_color)
      draw_text(0, line_height * line + y_offset, width, line_height, "Removes")
      change_color(normal_color)
      icons2.each_with_index {|n, i| draw_icon(n, x + 24 * i, line_height * line + y_offset) }
      line += 1
    end
  end
  
  def check_color(amount)
    if amount < 0
      change_color(power_down_color)
    else
      change_color(normal_color)
    end
  end
end # Window_ItemDesc < Window_Base


class Window_Base < Window
  alias galv_shopkeeper_windowbase_initialize initialize
  def initialize(x, y, width, height)
    galv_shopkeeper_windowbase_initialize(x, y, width, height)
    if SceneManager.scene_is?(Scene_Shop)
      self.windowskin = Cache.system($game_system.shop_windowskin)
    end
  end
end # Window_Base < Window


#------------------------------------------------------------------------------#
#  COMPATABILITY PATCH FOR YANFLY'S EQUIP DYNAMIC STATS SCRIPT
#------------------------------------------------------------------------------#
#  If you don't use this script from Yanfly, you can remove this.              #
#------------------------------------------------------------------------------#

if $imported["YEA-EquipDynamicStats"]
  class Window_ShopStatus < Window_Base
    def draw_actor_param_change(x, y, actor, item1)
      rect = Rect.new(x, y, 40, line_height)
      change = actor_param_change_value(actor, item1)
      change_color(param_change_color(change))
      text = change.group
      text = "+" + text if change >= 0
      draw_text(rect, sprintf("%+d", change), 1)
    end
  end # Window_ShopStatus

  class Window_ItemDesc < Window_Base
    def draw_equip_stats(x, y, param_id)
      draw_param_name(x + 4, y, param_id)
      draw_param(x + 30, y, param_id)
    end
    
    def draw_param(x, y, param_id)
      a = @item.params[param_id] + $game_variables[@item.var_params[param_id]]
      b = @item.per_params[param_id]
      if a > 0 || b > 0; change_color(power_up_color)
      elsif a < 0 || b < 0; change_color(power_down_color)
      else; change_color(normal_color); end
      a != 0 && b != 0 ? plus = "+" : plus = ""
      if b != 0; perc = "%"; b = (b *= 100).to_i.to_s; else; perc = ""; b = ""; end
      if b == "" && a == 0; a = 0; elsif b != "" && a == 0; a = ""; end
      draw_text(x, y, 100, line_height, a.to_s + plus + b.to_s + perc, 2)
    end
  end # Window_ItemDesc < Window_Base
end
Download Demo (bản 2.4)

[chapter]Credit[/chapter]
Galv
Script được làm theo yêu cầu của Nee Millon
Nicke cho chức năng scoll background

[chapter]Điều khoản khi sử dụng[/chapter]
Miễn phí

Comments

Sign In or Register to comment.