#============================================================================== # ■ VXAce-RGSS3-30 マルチカテゴリショップ [Ver.1.0.0] by Claimh #------------------------------------------------------------------------------ # カテゴリ分類を細分化できるショップです。 #<機能概要> #・購入・売却リストをカテゴリ分類する #・武器タイプ・防具タイプで分類する #・アクターが装備可能な武器・防具で分類する #・ショップ画面からの装備変更 #・購入した装備品をすぐに装備する #・購入・売却不可のアイテムを設定できる #・購入・売却の価格レートの変更 #------------------------------------------------------------------------------ # <操作> # Cボタン : 購入/売買 # ←/→ボタン : アクター情報切り替え # ↑/↓ボタン : 購入/売却数 ±10 # L/Rボタン : カテゴリ切り替え #------------------------------------------------------------------------------ # <メモ欄設定> # ・売却不可 : #------------------------------------------------------------------------------ #<売買不可設定> # ・購入不可アイテム追加 # $game_system.shop.buy.add_ng_item(type, id) # type : 種別(0:アイテム, 1:武器, 2:防具) # id : ID # ・購入不可アイテム解除 # $game_system.shop.buy.del_ng_item(type, id) # ・売却不可アイテム追加 # $game_system.shop.sell.add_ng_item(type, id) # ・売却不可アイテム解除 # $game_system.shop.sell.del_ng_item(type, id) #------------------------------------------------------------------------------ # <全体売買レート変更> #・購入レート # $game_system.shop.buy.rate = レート(%) #・売却レート # $game_system.shop.sell.rate = レート(%) #------------------------------------------------------------------------------ # <個別売買レート変更> #※全体レートよりも個別レートが優先されます。(全体×個別というレート計算はしません) #・個別購入レート # $game_system.shop.buy.item_rate(type, id, rate) # type : 種別(0:アイテム, 1:武器, 2:防具) # id : ID # rate : レート(%) #・個別売却レート # $game_system.shop.sell.item_rate(type, id, rate) #・個別購入レート情報削除 # $game_system.shop.buy.del_item_rate(type, id) #・個別売却レート情報削除 # $game_system.shop.sell.del_item_rate(type, id) #------------------------------------------------------------------------------ # <合計金額取得> #・購入合計: $game_system.shop.buy.gold #・売却合計: $game_system.shop.sell.gold #------------------------------------------------------------------------------ # <購入不可判定について> # 以下のいずれかに当てはまる場合は購入不可 # ・お金が足りない # ・アイテムの最大数超過($game_party.item_max?) # ・購入不可アイテムの対象($game_system.shop.buy.add_ng_item) #------------------------------------------------------------------------------ # <売却不可判定について> # 以下のいずれかに当てはまる場合は売却不可 # ・データベース上の値段が0 (※レート計算で値段が0になる場合は除く) # ・メモ欄に 指定がある # ・売却不可アイテムの対象($game_system.shop.sell.add_ng_item) #------------------------------------------------------------------------------ # <アクターが装備可能な武器・防具で分類> # BUY_CTにACTORを入れた時の動作 # ・カテゴリ切り替えでACTORカテゴリに変わった時にアクターステータスも切り替え # ・アイコンはキャラクターを表示 #------------------------------------------------------------------------------ # <購入した装備品をすぐに装備する> # アクターステータスウィンドウに表示されているアクターが装備できる武器・防具を # 購入したときに装備するか否かの選択が表示されます。 #============================================================================== module ExShop ALL=0;ITEM=1;WEAPON=2;ARMOR=3;KEY=4;ACTOR=5 #---------------------------------------------------------------------------- # レート設定 #---------------------------------------------------------------------------- # 初期購入レート(%) BUY_RATE = 100.0 # 初期売却レート(%) SELL_RATE = 50.0 # 値段指定あり時も購入レートを適応する USE_P_RATE = true #---------------------------------------------------------------------------- # 分類設定 #---------------------------------------------------------------------------- # 購入分類設定 # ALL : すべて # ITEM : アイテム # WEAPON : 武器 # ARMOR : 防具 # ACTOR : アクターが装備できる武器・防具 BUY_CT = [ALL, ITEM, WEAPON, ARMOR] #BUY_CT = [ALL, ITEM, ACTOR] # アクター装備別の例 # 売却分類設定 # ALL : すべて # ITEM : アイテム # WEAPON : 武器 # ARMOR : 防具 # KEY : 大事なもの SELL_CT = [ALL, ITEM, WEAPON, ARMOR, KEY] # 武器をさらに分類する # (分類設定のWEAPONを武器タイプで分類します) USE_W_TYPE = true # 防具をさらに分類する # (分類設定のARMORを防具タイプ/防具種別で分類します) # 0 : 分類しない # 1 : 防具タイプで分類 # 2 : 装備タイプ(盾/頭/身体/装飾品)で分類 USE_A_TYPE = 2 # アイコン設定 # [ALL用, ITEM用, WEAPON用, ARMOR用, KEY用] CT_ICON = [ 125, 261, 147, 168, 259] # 武器タイプ アイコン設定 # [0, 武器タイプ1, 武器タイプ2, …] CT_W_ICON = [0, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153] # 防具タイプ アイコン設定 # [0, 防具タイプ1, 防具タイプ2, …] CT_A_ICON = [0, 168, 171, 169, 170, 160, 161] # 防具種別 アイコン設定 # [0, 盾, 頭, 身体, 装飾品] CT_E_ICON = [0, 160, 164, 169, 176] #---------------------------------------------------------------------------- # 表示設定 #---------------------------------------------------------------------------- # 購入不可アイテムの値段表示(""の時は値段を表示) V_N_BUY = "売り切れ" #---------------------------------------------------------------------------- # レイアウト設定 #---------------------------------------------------------------------------- # 所持金ウィンドウを左下に配置する # true : 左下に配置(カテゴリ多用) # false : 右上に配置(カテゴリ小用) GOLD_LD = false end module ExShop #-------------------------------------------------------------------------- # ● 購入レート変換(購入価格計算) #-------------------------------------------------------------------------- def self.buy_price(item, price, fix=false) return price if fix and !USE_P_RATE $game_system.shop.buy.price(item_type(item), item.id, price) end #-------------------------------------------------------------------------- # ● 売却レート変換(売却価格計算) #-------------------------------------------------------------------------- def self.sell_price(item, price) $game_system.shop.sell.price(item_type(item), item.id, price) end #-------------------------------------------------------------------------- # ● atype => symbol #-------------------------------------------------------------------------- def self.actor_sym $game_party.members.collect {|a| a.id.to_s.to_sym } end #-------------------------------------------------------------------------- # ● CT設定 => symbol #-------------------------------------------------------------------------- def self.ct_sym(ct) ct.inject([]) do |r, c| case c when WEAPON; r += wtype_sym when ARMOR; r += atype_sym when ACTOR; r += actor_sym else; r.push([:all, :item, :weapon, :armor, :key_item][c]) end end end #-------------------------------------------------------------------------- # ● wtype => symbol #-------------------------------------------------------------------------- def self.wtype_sym return [:weapon] unless ExShop::USE_W_TYPE $data_system.weapon_types[1, $data_system.weapon_types.size].collect {|a| a.to_sym} end #-------------------------------------------------------------------------- # ● atype => symbol #-------------------------------------------------------------------------- def self.atype_sym case ExShop::USE_A_TYPE when 1 # 防具タイプ $data_system.armor_types[1, $data_system.armor_types.size].collect {|a| a.to_sym} when 2 # 装備タイプ [:shield, :helmet, :clothes, :accessory] else [:armor] end end #-------------------------------------------------------------------------- # ● symbol => wtype or atype #-------------------------------------------------------------------------- def self.sym_type(sym) str = sym.id2name return WEAPON if $data_system.weapon_types.include?(str) return ARMOR if $data_system.armor_types.include?(str) ACTOR end #-------------------------------------------------------------------------- # ● sym => wtype #-------------------------------------------------------------------------- def self.sym_wtype(sym) $data_system.weapon_types.index(sym.id2name) end #-------------------------------------------------------------------------- # ● sym => atype #-------------------------------------------------------------------------- def self.sym_atype(sym) $data_system.armor_types.index(sym.id2name) end #-------------------------------------------------------------------------- # ● symbol => 設定 #-------------------------------------------------------------------------- def self.sym2id(sym) case sym when :all; return ALL when :item; return ITEM when :weapon; return WEAPON when :armor; return ARMOR when :key_item; return KEY when :shield, :helmet, :clothes, :accessory; return ARMOR else return sym_type(sym) end end #-------------------------------------------------------------------------- # ● symbol => アイコン #-------------------------------------------------------------------------- def self.sym2icon(sym) case sym when :all; return CT_ICON[ALL] when :none; return 0 when :item; return CT_ICON[ITEM] when :weapon; return CT_ICON[WEAPON] when :armor; return CT_ICON[ARMOR] when :key_item; return CT_ICON[KEY] when :shield; return CT_E_ICON[1] when :helmet; return CT_E_ICON[2] when :clothes; return CT_E_ICON[3] when :accessory; return CT_E_ICON[4] else case sym_type(sym) when WEAPON; return CT_W_ICON[sym_wtype(sym)] when ARMOR; return CT_A_ICON[sym_atype(sym)] when ACTOR; return 0 end end end #-------------------------------------------------------------------------- # ● symbol => Actor #-------------------------------------------------------------------------- def self.sym2actor(sym) $game_actors[sym.id2name.to_i] end #-------------------------------------------------------------------------- # ● アイテムをリストに含めるかどうか #-------------------------------------------------------------------------- def self.item_include?(sym, item) case sym when :all true when :none false when :item item.is_a?(RPG::Item) && !item.key_item? when :weapon item.is_a?(RPG::Weapon) when :armor item.is_a?(RPG::Armor) when :key_item item.is_a?(RPG::Item) && item.key_item? when :shield item.is_a?(RPG::Armor) && item.etype_id == 1 when :helmet item.is_a?(RPG::Armor) && item.etype_id == 2 when :clothes item.is_a?(RPG::Armor) && item.etype_id == 3 when :accessory item.is_a?(RPG::Armor) && item.etype_id == 4 else case sym_type(sym) when WEAPON item.is_a?(RPG::Weapon) and item.wtype_id == sym_wtype(sym) when ARMOR item.is_a?(RPG::Armor) and item.atype_id == sym_atype(sym) when ACTOR sym2actor(sym).equippable?(item) else false end end end #-------------------------------------------------------------------------- # ● アイテムタイプ #-------------------------------------------------------------------------- def self.item_type(item) case item when RPG::Item; return 0 when RPG::Weapon; return 1 when RPG::Armor; return 2 end end #-------------------------------------------------------------------------- # ● 購入可否判定 #-------------------------------------------------------------------------- def self.buy_enable?(item) not $game_system.shop.buy.ng_item?(item_type(item), item.id) end #-------------------------------------------------------------------------- # ● 売却可否判定 #-------------------------------------------------------------------------- def self.sell_enable?(item) not $game_system.shop.sell.ng_item?(item_type(item), item.id) end #-------------------------------------------------------------------------- # ● 購入不可文字 #-------------------------------------------------------------------------- def self.not_buy(item, price) return price if V_N_BUY == "" buy_enable?(item) ? price : V_N_BUY end end #============================================================================== # ■ RPG::Item #============================================================================== class RPG::Item < RPG::UsableItem #-------------------------------------------------------------------------- # ● 売却可能か? #-------------------------------------------------------------------------- def sell? @price > 0 and !@note.include?("") end end #============================================================================== # ■ RPG::EquipItem #============================================================================== class RPG::EquipItem < RPG::BaseItem #-------------------------------------------------------------------------- # ● 売却可能か? #-------------------------------------------------------------------------- def sell? @price > 0 and !@note.include?("") end end #============================================================================== # ■ ExShop::ShopStatus #============================================================================== class ExShop::ShopStatus #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :buy # 購入ステータス attr_reader :sell # 売却ステータス #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize reset end #-------------------------------------------------------------------------- # ● リセット #-------------------------------------------------------------------------- def reset @buy = Status.new(ExShop::BUY_RATE) @sell = Status.new(ExShop::SELL_RATE) end #-------------------------------------------------------------------------- # ● レートリセット #-------------------------------------------------------------------------- def rate_reset @buy.rate = ExShop::BUY_RATE @sell.rate = ExShop::SELL_RATE @buy.i_rate_reset @sell.i_rate_reset end #-------------------------------------------------------------------------- # ● 売買不可アイテム情報リセット #-------------------------------------------------------------------------- def ng_reset @buy.ng_reset @sell.ng_reset end #============================================================================ # ■ Status : 売買情報 #============================================================================ class Status attr_accessor :rate # レート attr_accessor :gold # 金額 #------------------------------------------------------------------------ # ● オブジェクト初期化 #------------------------------------------------------------------------ def initialize(rate) @rate = rate @gold = 0 i_rate_reset ng_reset end #------------------------------------------------------------------------ # ● 個別レート設定リセット #------------------------------------------------------------------------ def i_rate_reset @i_rate = [] end #------------------------------------------------------------------------ # ● 売買不可アイテムリセット #------------------------------------------------------------------------ def ng_reset @ng_items = [] end #------------------------------------------------------------------------ # ● レート: 百分率 => 浮動小数点数 #------------------------------------------------------------------------ def rate_f (@rate / 100.0) end #------------------------------------------------------------------------ # ● アイテム価格計算 #------------------------------------------------------------------------ def price(type, id, price) (price * i_rate_f(type, id)).truncate end #------------------------------------------------------------------------ # ● 対象アイテムレート取得 #------------------------------------------------------------------------ def i_rate_f(type, id) it = find_i_rate(type, id) it.nil? ? rate_f : it.rate_f end #------------------------------------------------------------------------ # ● 対象アイテムレート取得 #------------------------------------------------------------------------ def i_rate(type, id) it = find_i_rate(type, id) it.nil? ? @rate : it.rate end #------------------------------------------------------------------------ # ● 個別レート設定アイテム? #------------------------------------------------------------------------ def item_rate?(type, id) find_i_rate(type, id) != nil end #------------------------------------------------------------------------ # ● 個別レート設定アイテム情報取得 #------------------------------------------------------------------------ def find_i_rate(type, id) @i_rate.find {|a| a.include?(type, id)} end #------------------------------------------------------------------------ # ● 個別レート設定 #------------------------------------------------------------------------ def item_rate(type, id, rate) it = find_i_rate(type, id) if it.nil? @i_rate.push(Item_Rate.new(type, id, rate)) else it.rate = rate end end #------------------------------------------------------------------------ # ● 個別レート設定削除 #------------------------------------------------------------------------ def del_item_rate(type, id) @i_rate.reject! {|item| item.include?(type, id)} end #------------------------------------------------------------------------ # ● 売買不可アイテム? #------------------------------------------------------------------------ def ng_item?(type, id) @ng_items.any? {|item| item.include?(type, id)} end #------------------------------------------------------------------------ # ● 売買不可アイテム追加 #------------------------------------------------------------------------ def add_ng_item(type, id) return if ng_item?(type, id) @ng_items.push(NG_Item.new(type, id)) end #------------------------------------------------------------------------ # ● 売買不可アイテム解除 #------------------------------------------------------------------------ def del_ng_item(type, id) @ng_items.reject! {|item| item.include?(type, id)} end #========================================================================== # ■ NG_Item : 売買不可アイテム情報 #========================================================================== class NG_Item #---------------------------------------------------------------------- # ● オブジェクト初期化 # type : 種別(0..RPG:Item, 1..RPG::Weapon, 2..RPG::Armor) # id : ID #---------------------------------------------------------------------- def initialize(type, id) @type = type; @id = id end #---------------------------------------------------------------------- # ● 売買不可アイテム? #---------------------------------------------------------------------- def include?(type, id) @type == type and @id == id end end #========================================================================== # ■ Item_Rate : アイテム売買レート #========================================================================== class Item_Rate #---------------------------------------------------------------------- # ● 公開インスタンス変数 #---------------------------------------------------------------------- attr_accessor :rate # レート(%) #---------------------------------------------------------------------- # ● オブジェクト初期化 # type : 種別(0..RPG:Item, 1..RPG::Weapon, 2..RPG::Armor) # id : ID # rate : レート(%) #---------------------------------------------------------------------- def initialize(type, id, rate) @type = type; @id = id; @rate = rate end #---------------------------------------------------------------------- # ● レート: 百分率 => 浮動小数点数 #---------------------------------------------------------------------- def rate_f (@rate / 100.0) end #---------------------------------------------------------------------- # ● 売買レート対象アイテム? #---------------------------------------------------------------------- def include?(type, id) @type == type and @id == id end end end end #============================================================================== # ■ Game_System #============================================================================== class Game_System #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :shop # ショップ情報 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- alias initialize_shop_ex initialize def initialize initialize_shop_ex @shop = ExShop::ShopStatus.new end end #============================================================================== # ■ Window_ExShopCommand #------------------------------------------------------------------------------ #  ショップ画面で、購入/売却/装備を選択するウィンドウです。 #============================================================================== class Window_ExShopCommand < Window_Command #-------------------------------------------------------------------------- # ● クラス変数 #-------------------------------------------------------------------------- @@last_command_symbol = :buy #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(window_width, purchase_only) @window_width = window_width @purchase_only = purchase_only super(0, 0) select_last end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width @window_width end #-------------------------------------------------------------------------- # ● 表示行数の取得 #-------------------------------------------------------------------------- def visible_line_number 4 end #-------------------------------------------------------------------------- # ● コマンドリストの作成 #-------------------------------------------------------------------------- def make_command_list add_command(Vocab::ShopBuy, :buy) add_command(Vocab::ShopSell, :sell, !@purchase_only) add_command(Vocab.equip, :equip, $game_party.members.size > 0) add_command(Vocab::ShopCancel, :cancel) end #-------------------------------------------------------------------------- # ● 決定ボタンが押されたときの処理 #-------------------------------------------------------------------------- def process_ok @@last_command_symbol = (current_symbol == :equip ? :equip : :buy) super end #-------------------------------------------------------------------------- # ● 前回の選択位置を復帰 #-------------------------------------------------------------------------- def select_last select_symbol(@@last_command_symbol) end end #============================================================================== # ■ Window_ExShopCategory #------------------------------------------------------------------------------ #  ショップ画面で、カテゴリを選択するウィンドウです。 #============================================================================== class Window_ExShopCategory < Window_HorzCommand #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :item_window #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, w) @win_width = w super(x, y) end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width @win_width end #-------------------------------------------------------------------------- # ● 桁数の取得 #-------------------------------------------------------------------------- def col_max ExShop::GOLD_LD ? 10 : 5 end #-------------------------------------------------------------------------- # ● 先頭の桁の設定 #-------------------------------------------------------------------------- def top_col=(col) col = 0 if col < 0 # col = col_max - 1 if col > col_max - 1 self.ox = col * (item_width + spacing) end #-------------------------------------------------------------------------- # ● シンボルリスト #-------------------------------------------------------------------------- def symlist [:all, :item, :weapon, :armor, :key_item] end #-------------------------------------------------------------------------- # ● コマンドリストの作成 #-------------------------------------------------------------------------- def make_command_list symlist.each {|s| add_command(ExShop.sym2icon(s), s, true, ExShop.sym2id(s))} end #-------------------------------------------------------------------------- # ● 項目を描画する矩形の取得 #-------------------------------------------------------------------------- def item_rect(index) r = super(index) r.x += (r.width - 24) / 2 r.width = 24 r end #-------------------------------------------------------------------------- # ● 項目の描画 #-------------------------------------------------------------------------- def draw_item(index) r = item_rect(index) if @list[index][:ext] == ExShop::ACTOR draw_charicon(ExShop.sym2actor(@list[index][:symbol]), r.x, r.y, command_enabled?(index)) else draw_icon(command_name(index), r.x, r.y, command_enabled?(index)) end end #-------------------------------------------------------------------------- # ● 歩行グラフィックの描画 #-------------------------------------------------------------------------- def draw_charicon(actor, x, y, enabled) return if actor.nil? return unless actor.character_name bitmap = Cache.character(actor.character_name) sign = actor.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 = actor.character_index src_rect = Rect.new((n%4*3+1)*cw + (cw - 20) / 2, (n/4*4)*ch, 20, 20) contents.blt(x+2, y+2, bitmap, src_rect) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super @item_window.category = current_symbol if @item_window end #-------------------------------------------------------------------------- # ● アイテムウィンドウの設定 #-------------------------------------------------------------------------- def item_window=(item_window) @item_window = item_window update end end #============================================================================== # ■ Window_ExShopCategory #------------------------------------------------------------------------------ #  ショップ画面で、購入カテゴリを選択するウィンドウです。 #============================================================================== class Window_ExShopBuyCt < Window_ExShopCategory #-------------------------------------------------------------------------- # ● シンボルリスト #-------------------------------------------------------------------------- def symlist ExShop.ct_sym(ExShop::BUY_CT) end end #============================================================================== # ■ Window_ExShopCategory #------------------------------------------------------------------------------ #  ショップ画面で、売却カテゴリを選択するウィンドウです。 #============================================================================== class Window_ExShopSellCt < Window_ExShopCategory #-------------------------------------------------------------------------- # ● シンボルリスト #-------------------------------------------------------------------------- def symlist ExShop.ct_sym(ExShop::SELL_CT) end end #============================================================================== # ■ Sprite_ShopTAG #============================================================================== class Sprite_ShopTAG < Sprite W = 100 H = 14 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, tag) super(Viewport.new(x, y, W, H)) self.viewport.z = 200 self.bitmap = Bitmap.new(W, H) self.bitmap.font.size = 12 self.bitmap.font.color = system_color self.bitmap.draw_text(0, 0, W, H, tag) end #-------------------------------------------------------------------------- # ● 文字色取得 # n : 文字色番号(0..31) #-------------------------------------------------------------------------- def text_color(n) Cache.system("Window").get_pixel(64 + (n % 8) * 8, 96 + (n / 8) * 8) end #-------------------------------------------------------------------------- # ● 各種文字色の取得 #-------------------------------------------------------------------------- def normal_color; text_color(0); end; # 通常 def system_color; text_color(16); end; # システム end #============================================================================== # ■ Window_ShopBuy #============================================================================== class Window_ShopBuy < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, width, height, shop_goods) super(x, y, width, height) @shop_goods = shop_goods @money = 0 @category = :none refresh select(0) create_sprites end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def dispose super dispose_sprites end #-------------------------------------------------------------------------- # ● タグスプライト生成 #-------------------------------------------------------------------------- def create_sprites @sprite_price = Sprite_ShopTAG.new(self.x+280, self.y+2, "価格") @sprite_num = Sprite_ShopTAG.new(self.x+340, self.y+2, "所持数") end #-------------------------------------------------------------------------- # ● タグスプライト解放 #-------------------------------------------------------------------------- def dispose_sprites @sprite_price.dispose @sprite_num.dispose end #-------------------------------------------------------------------------- # ● ウィンドウの表示/非表示 #-------------------------------------------------------------------------- def visible=(flag) super(flag) @sprite_price.visible = @sprite_num.visible = flag end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width width end #-------------------------------------------------------------------------- # ● カテゴリの設定 #-------------------------------------------------------------------------- def category=(category) return if @category == category @category = category refresh self.oy = 0 end #-------------------------------------------------------------------------- # ● アイテムリストの作成 <再定義> #-------------------------------------------------------------------------- def make_item_list @data = [] @price = {} @shop_goods.each do |goods| case goods[0] when 0; item = $data_items[goods[1]] when 1; item = $data_weapons[goods[1]] when 2; item = $data_armors[goods[1]] end if item next unless include?(item) @data.push(item) i_price = goods[2] == 0 ? item.price : goods[3] @price[item] = ExShop.buy_price(item, i_price, goods[2] != 0) end end end #-------------------------------------------------------------------------- # ● アイテムをリストに含めるかどうか #-------------------------------------------------------------------------- def include?(item) item && ExShop.item_include?(@category, item) end #-------------------------------------------------------------------------- # ● 項目の描画 #-------------------------------------------------------------------------- def draw_item(index) item = @data[index] rect = item_rect(index) draw_item_name(item, rect.x, rect.y, enable?(item)) rect.width -= 64 draw_text(rect, ExShop.not_buy(item, price(item)), 2) rect.width += 60 draw_text(rect, $game_party.item_number(item), 2) end #-------------------------------------------------------------------------- # ● アイテムを許可状態で表示するかどうか #-------------------------------------------------------------------------- def enable?(item) item && price(item) <= @money && !$game_party.item_max?(item) && ExShop.buy_enable?(item) end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help @help_window.set_item(item) if @help_window if @status_window @status_window.item = item if ExShop.sym2id(@category) == ExShop::ACTOR @status_window.page_index = ExShop.sym2actor(@category).index end end end end #============================================================================== # ■ Window_ShopSell #============================================================================== class Window_ShopSell < Window_ItemList #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :status_window # ステータスウィンドウ #-------------------------------------------------------------------------- # ● 桁数の取得 #-------------------------------------------------------------------------- def col_max 1 end #-------------------------------------------------------------------------- # ● アイテムをリストに含めるかどうか #-------------------------------------------------------------------------- def include?(item) item && ExShop.item_include?(@category, item) end #-------------------------------------------------------------------------- # ● アイテムを許可状態で表示するかどうか #-------------------------------------------------------------------------- def enable?(item) item && item.sell? && ExShop.sell_enable?(item) end #-------------------------------------------------------------------------- # ● ステータスウィンドウの設定 #-------------------------------------------------------------------------- def status_window=(status_window) @status_window = status_window call_update_help end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help super @status_window.item = item if @status_window end end #============================================================================== # ■ Window_ShopNumber #============================================================================== class Window_ShopNumber < Window_Selectable #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :number # 入力された個数 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, width, height) super(x, y, width, height) @item = nil @max = 1 @price = 0 @number = 1 @currency_unit = Vocab::currency_unit end end #============================================================================== # ■ Window_ShopStatus #============================================================================== class Window_ShopStatus < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, width, height, actor) super(x, y, width, height) @item = nil @page_index = actor.index self.ox = 1 if page_max > 1 refresh end #-------------------------------------------------------------------------- # ● ウィンドウ内容の幅を計算 #-------------------------------------------------------------------------- def contents_width super + (page_max > 1 ? 2 : 0) end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh contents.clear actor = current_actor enabled = @item.is_a?(RPG::EquipItem) ? actor.equippable?(@item) : false draw_actor_face(actor, self.ox + contents_width - 96, 0, enabled) change_color(normal_color, enabled) draw_text(self.ox, 0, 112, line_height, actor.name) return unless @item.is_a?(RPG::EquipItem) draw_actor_equip_info(self.ox, line_height*2, actor, enabled) end #-------------------------------------------------------------------------- # ● 顔グラフィックの描画 #-------------------------------------------------------------------------- def draw_actor_face(actor, x, y, enabled = true) bitmap = Cache.face(actor.face_name) rect = Rect.new(actor.face_index % 4 * 96, actor.face_index / 4 * 96 + 16, 96, line_height*2) contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha) bitmap.dispose end #-------------------------------------------------------------------------- # ● アイテムの設定 #-------------------------------------------------------------------------- def item=(item) @item = item refresh end #-------------------------------------------------------------------------- # ● 表示中アクター #-------------------------------------------------------------------------- def current_actor $game_party.members[@page_index] end #-------------------------------------------------------------------------- # ● 一度に表示できるアクターの人数 #-------------------------------------------------------------------------- def page_size return 1 end #-------------------------------------------------------------------------- # ● 最大ページ数の取得 #-------------------------------------------------------------------------- def page_max $game_party.members.size end #-------------------------------------------------------------------------- # ● アクターの装備情報を描画 #-------------------------------------------------------------------------- def draw_actor_equip_info(x, y, actor, enabled) item1 = current_equipped_item(actor, @item.etype_id) prms = ExShop::GOLD_LD ? [2, 3, 4, 5] : [2, 3, 4, 5, 6, 7] prms.each do |prm| draw_actor_param_change(x, y, actor, item1, prm, enabled) y += line_height end end #-------------------------------------------------------------------------- # ● アクターの能力値変化を描画 #-------------------------------------------------------------------------- def draw_actor_param_change(x, y, actor, item1, prm_id, enabled) rect = Rect.new(x, y, contents.width - 4 - x, line_height) change = @item.params[prm_id] - (item1 ? item1.params[prm_id] : 0) change_color(system_color, enabled) draw_text(rect, $data_system.terms.params[prm_id]) if enabled change_color(param_change_color(change), enabled) draw_text(rect, sprintf("%+d", change), 2) else change_color(normal_color, enabled) draw_text(rect, "―", 2) end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super update_page end #-------------------------------------------------------------------------- # ● ページの更新 #-------------------------------------------------------------------------- def update_page if active && visible && page_max > 1 next_page if Input.trigger?(:RIGHT) prev_page if Input.trigger?(:LEFT) end end #-------------------------------------------------------------------------- # ● 指定ページへ #-------------------------------------------------------------------------- def page_index=(index) @page_index = index refresh end #-------------------------------------------------------------------------- # ● 次のページへ #-------------------------------------------------------------------------- def next_page Sound.play_cursor @page_index = (@page_index + 1) % page_max refresh end #-------------------------------------------------------------------------- # ● 前のページへ #-------------------------------------------------------------------------- def prev_page Sound.play_cursor @page_index = (@page_index - 1 + page_max) % page_max refresh end end #============================================================================== # ■ Window_ShopEquip #============================================================================== class Window_ShopEquip < Window_HorzCommand #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, width, height) @ww = width @wh = height super(x, y) end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width @ww end #-------------------------------------------------------------------------- # ● ウィンドウ高さの取得 #-------------------------------------------------------------------------- def window_height @wh end #-------------------------------------------------------------------------- # ● 桁数の取得 #-------------------------------------------------------------------------- def col_max 2 end #-------------------------------------------------------------------------- # ● ウィンドウ内容の高さを計算 #-------------------------------------------------------------------------- def contents_height height - standard_padding * 3 end #-------------------------------------------------------------------------- # ● 項目を描画する矩形の取得 #-------------------------------------------------------------------------- def item_rect(index) rect = super rect.y = 0 rect.width = 80 rect.x = 180 + index * (rect.width + spacing) rect end #-------------------------------------------------------------------------- # ● コマンドリストの作成 #-------------------------------------------------------------------------- def make_command_list add_command("はい", :equip) add_command("いいえ", :cancel) end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def set(actor=nil, item=nil) @actor = actor @item = item refresh end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh super if !@actor.nil? and !@item.nil? draw_text(0, 0, 150, line_height,"装備しますか?") draw_horz_line(line_height) draw_actor_equip(line_height * 2) end end #-------------------------------------------------------------------------- # ● 水平線の描画 #-------------------------------------------------------------------------- def draw_horz_line(y) line_y = y + line_height / 2 - 1 contents.fill_rect(0, line_y, contents_width, 2, line_color) end #-------------------------------------------------------------------------- # ● 水平線の色を取得 #-------------------------------------------------------------------------- def line_color color = normal_color color.alpha = 48 color end #-------------------------------------------------------------------------- # ● アクターの装備情報を描画 #-------------------------------------------------------------------------- def draw_actor_equip(y) draw_actor_name(@actor, 4, y) item1 = current_equipped_item draw_item_name(item1, 140, y) draw_actor_param_changes(4, y + line_height, item1) end #-------------------------------------------------------------------------- # ● 現在の装備品を取得 # 二刀流など、同じ種類の装備が複数ある場合は弱い方を返す。 #-------------------------------------------------------------------------- def current_equipped_item list = [] @actor.equip_slots.each_with_index do |slot_etype_id, i| list.push(@actor.equips[i]) if slot_etype_id == @item.etype_id end list.min_by {|item| item ? item.params[param_id] : 0 } end #-------------------------------------------------------------------------- # ● 選択中のアイテムに対応する能力値 ID の取得 # デフォルトでは武器なら攻撃力、防具なら防御力とする。 #-------------------------------------------------------------------------- def param_id @item.is_a?(RPG::Weapon) ? 2 : 3 end #-------------------------------------------------------------------------- # ● アクターの装備情報を描画 #-------------------------------------------------------------------------- def draw_actor_param_changes(x, y, item) prms = [0, 1, 2, 3, 4, 5, 6, 7] rect = Rect.new(x, y, (contents_width-8) / 2, line_height) prms.each_index do |i| draw_actor_param_change(rect, item, prms[i]) rect.y += rect.height end end #-------------------------------------------------------------------------- # ● アクターの能力値変化を描画 #-------------------------------------------------------------------------- def draw_actor_param_change(rect, item1, prm_id) change = @item.params[prm_id] - (item1 ? item1.params[prm_id] : 0) change_color(system_color) draw_text(rect, $data_system.terms.params[prm_id]) change_color(normal_color) r = Rect.new(rect.x + 70, rect.y, 80, rect.height) draw_text(r, @actor.param(prm_id), 2) return if change == 0 r.x += r.width + 4 draw_text(r, "→") change_color(param_change_color(change)) draw_text(r, @actor.param(prm_id) + change , 2) end end #============================================================================== # ■ Scene_Shop #============================================================================== class Scene_Shop < Scene_MenuBase #-------------------------------------------------------------------------- # ● 準備 #-------------------------------------------------------------------------- def prepare(goods, purchase_only) @goods = goods @purchase_only = purchase_only @actor = $game_party.members[0] end #-------------------------------------------------------------------------- # ● 準備 #-------------------------------------------------------------------------- def prepare_actor(actor) @actor = actor end #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start super create_help_window create_gold_window create_command_window create_dummy_window create_status_window create_category_window create_buy_window create_sell_window create_number_window create_equip_window end #-------------------------------------------------------------------------- # ● ゴールドウィンドウの作成 #-------------------------------------------------------------------------- def create_gold_window @gold_window = Window_Gold.new @gold_window.viewport = @viewport if ExShop::GOLD_LD @gold_window.y = Graphics.height - @gold_window.height else @gold_window.x = Graphics.width - @gold_window.width @gold_window.y = @help_window.height @gold_window.z = 200 end end #-------------------------------------------------------------------------- # ● コマンドウィンドウの作成 #-------------------------------------------------------------------------- def create_command_window @command_window = Window_ExShopCommand.new(@gold_window.width, @purchase_only) @command_window.viewport = @viewport @command_window.y = @help_window.height @command_window.set_handler(:buy, method(:command_buy)) @command_window.set_handler(:sell, method(:command_sell)) @command_window.set_handler(:equip, method(:command_equip)) @command_window.set_handler(:cancel, method(:return_scene)) end #-------------------------------------------------------------------------- # ● ダミーウィンドウの作成 #-------------------------------------------------------------------------- def create_dummy_window wx = @command_window.width wy = @help_window.height ww = Graphics.width - wx wh = Graphics.height - wy @dummy_window = Window_Base.new(wx, wy, ww, wh) @dummy_window.viewport = @viewport end #-------------------------------------------------------------------------- # ● 個数入力ウィンドウの作成 #-------------------------------------------------------------------------- def create_number_window wx = @buy_window.x wy = @buy_window.y ww = @buy_window.width wh = @buy_window.height @number_window = Window_ShopNumber.new(wx, wy, ww, wh) @number_window.viewport = @viewport @number_window.hide @number_window.set_handler(:ok, method(:on_number_ok)) @number_window.set_handler(:cancel, method(:on_number_cancel)) end #-------------------------------------------------------------------------- # ● ステータスウィンドウの作成 #-------------------------------------------------------------------------- def create_status_window wy = @command_window.y + @command_window.height ww = @command_window.width wh = Graphics.height - wy wh -= @gold_window.height if ExShop::GOLD_LD @status_window = Window_ShopStatus.new(0, wy, ww, wh, @actor) @status_window.viewport = @viewport end #-------------------------------------------------------------------------- # ● カテゴリウィンドウの作成 #-------------------------------------------------------------------------- def create_category_window wx = @command_window.width wy = @help_window.height ww = Graphics.width - wx ww -= @gold_window.width unless ExShop::GOLD_LD @buy_ct_window = Window_ExShopBuyCt.new(wx, wy, ww) @buy_ct_window.viewport = @viewport @buy_ct_window.hide.deactivate @sell_ct_window = Window_ExShopSellCt.new(wx, wy, ww) @sell_ct_window.viewport = @viewport @sell_ct_window.hide.deactivate end #-------------------------------------------------------------------------- # ● 購入ウィンドウの作成 #-------------------------------------------------------------------------- def create_buy_window wx = @dummy_window.x wy = @buy_ct_window.y + @buy_ct_window.height ww = Graphics.width - wx wh = Graphics.height - wy @buy_window = Window_ShopBuy.new(wx, wy, ww, 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)) @buy_window.set_handler(:pagedown, method(:next_buy_ct)) @buy_window.set_handler(:pageup, method(:prev_buy_ct)) @buy_ct_window.item_window = @buy_window end #-------------------------------------------------------------------------- # ● 売却ウィンドウの作成 #-------------------------------------------------------------------------- def create_sell_window wx = @command_window.width wy = @sell_ct_window.y + @sell_ct_window.height ww = Graphics.width - wx wh = Graphics.height - wy @sell_window = Window_ShopSell.new(wx, wy, ww, wh) @sell_window.viewport = @viewport @sell_window.help_window = @help_window @sell_window.status_window = @status_window @sell_window.hide @sell_window.set_handler(:ok, method(:on_sell_ok)) @sell_window.set_handler(:cancel, method(:on_sell_cancel)) @sell_window.set_handler(:pagedown, method(:next_sell_ct)) @sell_window.set_handler(:pageup, method(:prev_sell_ct)) @sell_ct_window.item_window = @sell_window end #-------------------------------------------------------------------------- # ● 装備ウィンドウの作成 #-------------------------------------------------------------------------- def create_equip_window wx = @number_window.x wy = @number_window.y ww = @number_window.width wh = @number_window.height @equip_window = Window_ShopEquip.new(wx, wy, ww, wh) @equip_window.hide.deactivate @equip_window.set_handler(:equip, method(:on_equip_ok)) @equip_window.set_handler(:cancel, method(:on_equip_cancel)) end #-------------------------------------------------------------------------- # ● コマンドウィンドウのアクティブ化 #-------------------------------------------------------------------------- def activate_cmd_window @command_window.activate @dummy_window.show @buy_ct_window.hide @buy_window.hide @sell_ct_window.hide @sell_window.hide @status_window.item = nil @help_window.clear end #-------------------------------------------------------------------------- # ● 購入ウィンドウのアクティブ化 #-------------------------------------------------------------------------- def activate_buy_window @buy_ct_window.show @buy_window.money = money @buy_window.refresh @buy_window.show.activate @status_window.activate end #-------------------------------------------------------------------------- # ● 売却ウィンドウのアクティブ化 #-------------------------------------------------------------------------- def activate_sell_window @sell_ct_window.show @sell_window.refresh @sell_window.show.activate @status_window.activate end #-------------------------------------------------------------------------- # ● 装備ウィンドウのアクティブ化 #-------------------------------------------------------------------------- def activate_equip_window @equip_window.set(@status_window.current_actor, @item) @equip_window.show.activate @equip_window.select(0) @status_window.deactivate end #-------------------------------------------------------------------------- # ● コマンド[購入する] #-------------------------------------------------------------------------- def command_buy @dummy_window.hide activate_buy_window @buy_window.select(0) end #-------------------------------------------------------------------------- # ● コマンド[売却する] #-------------------------------------------------------------------------- def command_sell @dummy_window.hide activate_sell_window @sell_window.select(0) end #-------------------------------------------------------------------------- # ● コマンド[装備] #-------------------------------------------------------------------------- def command_equip SceneManager.call(Scene_ShopEquip) SceneManager.scene.prepare(@status_window.current_actor) end #-------------------------------------------------------------------------- # ● 購入[決定] #-------------------------------------------------------------------------- def on_buy_ok @item = @buy_window.item @buy_window.hide @number_window.set(@item, max_buy, buying_price, currency_unit) @number_window.show.activate @status_window.deactivate end #-------------------------------------------------------------------------- # ● 購入[キャンセル] #-------------------------------------------------------------------------- def on_buy_cancel activate_cmd_window end #-------------------------------------------------------------------------- # ● 次の購入カテゴリに切り替え #-------------------------------------------------------------------------- def next_buy_ct @buy_ct_window.cursor_right(true) @buy_ct_window.update_cursor @buy_ct_window.update @buy_window.activate.select(0) @buy_window.update_help end #-------------------------------------------------------------------------- # ● 前の購入カテゴリに切り替え #-------------------------------------------------------------------------- def prev_buy_ct @buy_ct_window.cursor_left(true) @buy_ct_window.update_cursor @buy_ct_window.update @buy_window.activate.select(0) @buy_window.update_help end #-------------------------------------------------------------------------- # ● 売却[決定] #-------------------------------------------------------------------------- def on_sell_ok @item = @sell_window.item @sell_window.hide @number_window.set(@item, max_sell, selling_price, currency_unit) @number_window.show.activate @status_window.deactivate end #-------------------------------------------------------------------------- # ● 売却[キャンセル] #-------------------------------------------------------------------------- def on_sell_cancel activate_cmd_window end #-------------------------------------------------------------------------- # ● 次の売却カテゴリに切り替え #-------------------------------------------------------------------------- def next_sell_ct @sell_ct_window.cursor_right(true) @sell_ct_window.update_cursor @sell_ct_window.update @sell_window.activate.select(0) @sell_window.update_help end #-------------------------------------------------------------------------- # ● 前の売却カテゴリに切り替え #-------------------------------------------------------------------------- def prev_sell_ct @sell_ct_window.cursor_left(true) @sell_ct_window.update_cursor @sell_ct_window.update @sell_window.activate.select(0) @sell_window.update_help end #-------------------------------------------------------------------------- # ● 個数入力[決定] #-------------------------------------------------------------------------- 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) end end_number_input(true) @gold_window.refresh @status_window.refresh end #-------------------------------------------------------------------------- # ● 個数入力[キャンセル] #-------------------------------------------------------------------------- def on_number_cancel Sound.play_cancel end_number_input(false) end #-------------------------------------------------------------------------- # ● 購入の実行 #-------------------------------------------------------------------------- def do_buy(number) $game_party.lose_gold(number * buying_price) $game_party.gain_item(@item, number) $game_system.shop.buy.gold += number * buying_price end #-------------------------------------------------------------------------- # ● 売却の実行 #-------------------------------------------------------------------------- def do_sell(number) $game_party.gain_gold(number * selling_price) $game_party.lose_item(@item, number) $game_system.shop.sell.gold += number * selling_price end #-------------------------------------------------------------------------- # ● 個数入力の終了 #-------------------------------------------------------------------------- def end_number_input(buy=true) @number_window.hide case @command_window.current_symbol when :buy if buy && @status_window.current_actor.equippable?(@item) activate_equip_window else activate_buy_window end when :sell activate_sell_window end end #-------------------------------------------------------------------------- # ● 装備[決定] #-------------------------------------------------------------------------- def on_equip_ok Sound.play_equip @equip_window.hide actor = @status_window.current_actor actor.change_equip(actor.empty_slot(@item.etype_id), @item) activate_buy_window end #-------------------------------------------------------------------------- # ● 装備[キャンセル] #-------------------------------------------------------------------------- def on_equip_cancel @equip_window.hide activate_buy_window end #-------------------------------------------------------------------------- # ● 最大購入可能個数の取得 #-------------------------------------------------------------------------- def max_buy max = $game_party.max_item_number(@item) - $game_party.item_number(@item) buying_price == 0 ? max : [max, money / buying_price].min end #-------------------------------------------------------------------------- # ● 売値の取得 #-------------------------------------------------------------------------- def selling_price ExShop::sell_price(@item, @item.price) end end #============================================================================== # ■ Scene_ShopEquip #------------------------------------------------------------------------------ # ショップ画面から呼び出す装備画面。メニューのものとは処理を分離。 # ($game_party.menu_actorは変化させない) #============================================================================== class Scene_ShopEquip < Scene_Equip #-------------------------------------------------------------------------- # ● 準備 #-------------------------------------------------------------------------- def prepare(actor) @start_actor = actor end #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start tmp_actor = $game_party.menu_actor $game_party.menu_actor = @start_actor super $game_party.menu_actor = tmp_actor end #-------------------------------------------------------------------------- # ● 次のアクターに切り替え #-------------------------------------------------------------------------- def next_actor tmp_actor = $game_party.menu_actor @actor = $game_party.menu_actor_next $game_party.menu_actor = tmp_actor on_actor_change end #-------------------------------------------------------------------------- # ● 前のアクターに切り替え #-------------------------------------------------------------------------- def prev_actor tmp_actor = $game_party.menu_actor @actor = $game_party.menu_actor_prev $game_party.menu_actor = tmp_actor on_actor_change end #-------------------------------------------------------------------------- # ● 呼び出し元のシーンへ戻る #-------------------------------------------------------------------------- def return_scene super SceneManager.scene.prepare_actor(@actor) end end