#============================================================================== # ■ XP-RGSS-62 まとめ買いショップ [Ver.1.1.0] by Claimh #============================================================================== #============================================================================== # ■ ShopItem #============================================================================== class ShopItem BUY=0;SELL=1;EQUIP=2 NUM_MAX = 99 # 最大所持数 attr_reader :item # RPG::Item / RPG::Weapon / RPG::Armor attr_reader :num # 所持数 attr_reader :status # 取引可能状態 attr_reader :price # 価格 attr_accessor :s_num # 予約数 # オブジェクト初期化 def initialize(item, mode) @mode = mode @item = item @price = item_price reset @status = item_status(0) end # 所持数/予約数リセット def reset(s_num=0) @num = party_num @s_num = s_num end # 所持数 def party_num case @item when RPG::Item; return $game_party.item_number(@item.id) when RPG::Weapon; return $game_party.weapon_number(@item.id) when RPG::Armor; return $game_party.armor_number(@item.id) end end # 取引状態の更新 def item_status(total) case @mode when BUY return false if (total + @price) > $game_party.gold return false if (@s_num + @num) >= NUM_MAX when SELL return false if @num == @s_num return false if @item.price == 0 when EQUIP return false if @item.is_a?(RPG::Item) end return true end # 取引状態のチェック(更新) def update_status(total) n = party_num ret = (@num != n) @num = n st = item_status(total) ret |= (@status != st) @status = st return ret end # 取引可能個数のシミュレーション def item_simlate(total, n=1) case @mode when BUY return 0 if (@s_num + @num) >= NUM_MAX b_n = (($game_party.gold - total) / @price).truncate return [n, b_n, (NUM_MAX - @num - @s_num)].min when SELL return 0 if @item.price == 0 return [n, (@num - @s_num)].min end return 0 end # 売買価格(レート考慮) def item_price case @mode when BUY; return (@item.price * $game_system.shop.buy.rate_f).truncate when SELL; return (@item.price * $game_system.shop.sell.rate_f).truncate end return 0 end # 売買処理 def sale d = (@mode==BUY ? 1 : -1) case @item when RPG::Item; $game_party.gain_item(@item.id, @s_num * d) when RPG::Weapon; $game_party.gain_weapon(@item.id, @s_num * d) when RPG::Armor; $game_party.gain_armor(@item.id, @s_num * d) end end end #============================================================================== # ■ ShopItemList #============================================================================== class ShopItemList BUY=0;SELL=1;EQUIP=2 attr_reader :list # 購入/売却リスト attr_accessor :total # 支払い予定金額 # オブジェクト初期化 def initialize(mode) @mode = mode @total = 0 case @mode when BUY; @list = buy_list when SELL; @list = sell_list when EQUIP; @list = [] end end # リスト初期化 def list_reset @total = 0 @list = sell_list if @mode == SELL end # 購入リスト def buy_list list = [] for goods_item in $game_temp.shop_goods case goods_item[0] when 0; list.push(ShopItem.new($data_items[goods_item[1]], @mode)) when 1; list.push(ShopItem.new($data_weapons[goods_item[1]], @mode)) when 2; list.push(ShopItem.new($data_armors[goods_item[1]], @mode)) end end return list end # 売却リスト def sell_list list = [] for i in 1...$data_items.size list.push(ShopItem.new($data_items[i], @mode)) if $game_party.item_number(i) > 0 end for i in 1...$data_weapons.size list.push(ShopItem.new($data_weapons[i], @mode)) if $game_party.weapon_number(i) > 0 end for i in 1...$data_armors.size list.push(ShopItem.new($data_armors[i], @mode)) if $game_party.armor_number(i) > 0 end return list end # 装備リスト def equip_list(list=[]) @list = [] for item in list next if item.s_num <= 0 e_item = ShopItem.new(item.item, EQUIP) e_item.s_num = item.s_num # 買った個数を引き継ぐ @list.push(e_item) end end # 売却リストのチェック def check_sell_list new_list = sell_list # サイズが同じ場合はデータの整合性チェック if new_list.size == @list.size remake = false refresh = [] for i in 0...@list.size # 並びが違うのでremake if @list[i].item != new_list[i].item remake = true break # 売買時に予約数がある or 所持数が変わった : 部分refresh elsif @list[i].s_num > 0 or @list[i].num != new_list[i].num @list[i].reset refresh.push(i) end end unless remake return [true, refresh] end end @list = new_list return [false, []] end # アイテムの所持数・予約数初期化 def reset for item in @list item.reset end end # リストデータ参照 def [](index) return @list[index] end # リストサイズ def size return @list.size end # リスト空? def empty? return @list.empty? end end #============================================================================== # ■ Window_ShopList #------------------------------------------------------------------------------ #<設計メモ> # - アイテム数が多い状態でも軽く動作できるようにdraw_textの頻度を下げる # - 購入・売却・装備の各リストのbitmapをキャッシュしておく # - 購入・売却・装備の切り替え時にはbitmapだけを交換する # - リスト情報の変化がある場合は全てrefreshせずになるべく差分更新で済ませる #============================================================================== class Window_ShopList < Window_Selectable BUY=0;SELL=1;EQUIP=2;EXIT=3 attr_accessor :total_window #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(160, 64, 480, 288) @data = [[],[],[],[]] bit = Bitmap.new(32, 32) @bitmap = [nil, nil, bit, bit] @index_s = [-1,-1,-1,-1] @mode = BUY all_data_refresh @sprite_price = Sprite_ShopTAG.new(self.x+350, self.y+2, "価格") @sprite_num = Sprite_ShopTAG.new(self.x+410, self.y+2, "所持数") end #-------------------------------------------------------------------------- # ● オブジェクト開放 #-------------------------------------------------------------------------- def dispose super for bitmap in @bitmap unless bitmap.nil? bitmap.dispose bitmap = nil end end @sprite_price.dispose @sprite_num.dispose end #-------------------------------------------------------------------------- # ● モード変更 #-------------------------------------------------------------------------- def mode=(mode) return if mode == @mode @index_s[@mode] = @index @mode = mode self.contents = @bitmap[@mode] @item_max = @data[@mode].size self.oy = 0 self.index = @index_s[@mode] case @mode when BUY, SELL; @sprite_price.visible = @sprite_num.visible = true when EQUIP; @sprite_price.visible = false @sprite_num.visible = !ShopEx::USE_MENU_EQUIP else; @sprite_price.visible = @sprite_num.visible = false end end def init_index self.index = 0 if @index < 0 end #-------------------------------------------------------------------------- # ● リスト遷移可能か? #-------------------------------------------------------------------------- def can_select? return (@item_max != 0) end #-------------------------------------------------------------------------- # ● アイテム取得 #-------------------------------------------------------------------------- def item_list return @data end def data_i(index) return @data[@mode][index] end def item_i(index) return @data[@mode][index].item end def item return nil if @index < 0 or @index >= @data[@mode].size return @data[@mode][@index].item end #-------------------------------------------------------------------------- # ● アイテムの価格取得 #-------------------------------------------------------------------------- def item_price_i(index) return item_i(index).item_price(@mode) end #-------------------------------------------------------------------------- # ● 購入・売却アイテムの合計価格取得 #-------------------------------------------------------------------------- def total_price return (@data[BUY].total - @data[SELL].total) end #-------------------------------------------------------------------------- # ● 有効Indexか? #-------------------------------------------------------------------------- def index_active? return data_i(@index).status end #-------------------------------------------------------------------------- # ● データリフレッシュ(ALL) #-------------------------------------------------------------------------- def all_data_refresh data_refresh(BUY) data_refresh(SELL) end #-------------------------------------------------------------------------- # ● データリフレッシュ #-------------------------------------------------------------------------- def data_refresh(mode) old_size = @data[mode].size if @data[mode].is_a?(Array) @data[mode] = ShopItemList.new(mode) else @data[mode].list_reset end reameke_bitmap(old_size, mode) end #-------------------------------------------------------------------------- # ● ビットマップの再生成 #-------------------------------------------------------------------------- def reameke_bitmap(old_size, mode) size = @data[mode].size if size != old_size # サイズ違い→bitmap再生成 @bitmap[mode].dispose if @bitmap[mode] != nil @bitmap[mode] = (size == 0 ? Bitmap.new(32, 32) : Bitmap.new(width - 32, size * 32)) elsif @bitmap[mode].nil? # bitmapない→仮bitmap作成 @bitmap[mode] = Bitmap.new(32, 32) elsif size != 0 # bitmapサイズは変わらない→中身をクリア @bitmap[mode].clear end return if size == 0 # リストが空なら何もしない # bitmap再描画 tmp = @mode @mode = mode self.contents = @bitmap[mode] refresh @mode = tmp self.contents = @bitmap[@mode] @item_max = @data[@mode].size end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh(clear=false) self.contents.clear if clear @item_max = @data[@mode].size return if @item_max <= 0 for i in 0...@item_max draw_item(i) end end #-------------------------------------------------------------------------- # ● 差分リフレッシュ #-------------------------------------------------------------------------- def diff_refresh(mode, index=-1) return if @data[mode].size <= 0 tmp = @mode @mode = mode self.contents = @bitmap[mode] @item_max = @data[mode].size for i in 0...@item_max # 差分有り or カレント は再描画 if @data[mode][i].update_status(total_price) or i == index draw_item(i, true) end end @mode = tmp self.contents = @bitmap[@mode] @item_max = @data[@mode].size end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index, clear=false) x = 4 y = index * 32 if clear # 表示クリアする場合のみ rect = Rect.new(x, y, self.width - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) end item = data_i(index) self.contents.font.color = item.status ? normal_color : disabled_color draw_item_name(item.item, x, y, (item.status ? 255 : 128)) if @mode == EQUIP self.contents.draw_text(x + 340, y, 88, 32, item.s_num.to_s, 2) else if item.s_num > 0 self.contents.draw_text(x + 240, y, 32, 32, "×") self.contents.draw_text(x + 240, y, 48, 32, item.s_num.to_s, 2) end self.contents.draw_text(x + 280, y, 88, 32, item.price.to_s, 2) self.contents.draw_text(x + 340, y, 88, 32, item.num.to_s, 2) end end #-------------------------------------------------------------------------- # ● アイテム名の描画 #-------------------------------------------------------------------------- def draw_item_name(item, x, y, opacity) return if item == nil bitmap = RPG::Cache.icon(item.icon_name) self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 212, 32, item.name) end #-------------------------------------------------------------------------- # ● 個数増 #-------------------------------------------------------------------------- def up(n=1) data = data_i(@index) n = data.item_simlate(total_price, n) return false if n == 0 data.s_num += n @data[@mode].total += data.price * n updw_common return true end #-------------------------------------------------------------------------- # ● 個数減 #-------------------------------------------------------------------------- def dw(n=1) data = data_i(@index) return false if data.s_num == 0 n = [n, data.s_num].min data.s_num -= n @data[@mode].total -= data.price * n updw_common return true end #-------------------------------------------------------------------------- # ● 個数増減:共通処理 #-------------------------------------------------------------------------- def updw_common case @mode when BUY # BUY側はお金足りない部分が出るから差分を探して再描画 diff_refresh(@mode, @index) when SELL @data[SELL][@index].update_status(total_price) draw_item(@index, true) # SELL側は1項目だけ再描画 diff_refresh(BUY) # BUY側は差分を探して再描画 end @total_window.refresh(total_price) if @data[EQUIP].size > 0 @data[EQUIP] = [] @bitmap[EQUIP].dispose if @bitmap[EQUIP] != nil @bitmap[EQUIP] = Bitmap.new(32,32) @index_s[EQUIP] = -1 end end #-------------------------------------------------------------------------- # ● 売買処理 #-------------------------------------------------------------------------- def sale @index_s[@mode] = @index $game_system.shop.buy.gold += @data[BUY].total $game_system.shop.sell.gold += @data[SELL].total $game_party.lose_gold(total_price) sale_item(BUY) sale_item(SELL) make_buy_list unless ShopEx::USE_MENU_EQUIP check_buy_list check_sell_list @data[SELL].total = 0 @data[SELL].reset @total_window.refresh(total_price) self.index = @index_s[@mode] @item_max = @data[@mode].size end def sale_item(mode) return if @data[mode].total == 0 for item in @data[mode].list item.sale if item.s_num > 0 end end def make_buy_list return if @data[BUY].total == 0 @data[EQUIP] = ShopItemList.new(EQUIP) @data[EQUIP].equip_list(@data[BUY].list) reameke_bitmap(0, EQUIP) # bitmap生成&描画 end #-------------------------------------------------------------------------- # ● データチェック(BUY) #-------------------------------------------------------------------------- def check_buy_list tmp = @mode @mode = BUY self.contents = @bitmap[BUY] data = @data[BUY] for i in 0...data.size item = data[i] next if item.s_num == 0 and item.num == item.party_num item.reset item.update_status(0) draw_item(i, true) end data.total = 0 @mode = tmp self.contents = @bitmap[@mode] @index_s[BUY] = @data[BUY].size - 1 if @index_s[BUY] >= @data[BUY].size end #-------------------------------------------------------------------------- # ● データチェック(SELL) #-------------------------------------------------------------------------- def check_sell_list old_size = @data[SELL].size ret = @data[SELL].check_sell_list if !ret[0] reameke_bitmap(old_size, SELL) @index_s[SELL] = @data[SELL].size - 1 if @index_s[SELL] >= @data[SELL].size elsif !ret[1].empty? tmp = @mode @mode = SELL self.contents = @bitmap[SELL] @item_max = @data[SELL].size for i in ret[1] draw_item(i, true) end @mode = tmp self.contents = @bitmap[@mode] end end #-------------------------------------------------------------------------- # ● 装備処理 #-------------------------------------------------------------------------- def equip_item(actor_index) data = data_i(@index) case data.item when RPG::Weapon; type = 0 when RPG::Armor; type = data.item.kind + 1 else; return end $game_party.actors[actor_index].equip(type, data.item.id) data.s_num -= 1 # ret = false # Equipを再構成 if data.s_num <= 0 ret = true # 残数ゼロ @data[EQUIP].equip_list(@data[EQUIP].list.dup) reameke_bitmap(-1, EQUIP) self.index = @data[EQUIP].size - 1 if @index >= @data[EQUIP].size else draw_item(@index, true) end diff_refresh(BUY) # BUY側を再描画 check_sell_list # Sell側を再描画 return ret end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help @help_window.set_text(item == nil ? "" : item.description) end end #============================================================================== # ■ Window_ShopCommand #============================================================================== class Window_ShopCommand < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 64, 160, 4 * 32 + 32) self.contents = Bitmap.new(width - 32, height - 32) equip = ShopEx::USE_MENU_EQUIP ? "装備変更" : "購入リスト" @commands = ["購入する", "売却する", equip, "やめる"] @item_max = @commands.size refresh self.index = 0 end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i) end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) self.contents.draw_text(4, index*32, 128, 32, @commands[index]) end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help @help_window.mode = self.index 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 = Color.new(192, 224, 255, 255) self.bitmap.draw_text(0, 0, W, H, tag) end end #============================================================================== # ■ Window_ShopGold #============================================================================== class Window_ShopGold < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 224, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) @sprite = Sprite_ShopTAG.new(self.x+8, self.y+4, "所持金") refresh end def dispose super @sprite.dispose end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear cx = contents.text_size($data_system.words.gold).width self.contents.font.color = normal_color self.contents.draw_text(4, 0, 120-cx-2, 32, $game_party.gold.to_s, 2) self.contents.font.color = system_color self.contents.draw_text(124-cx, 0, cx, 32, $data_system.words.gold, 2) end end #============================================================================== # ■ Window_ShopItemsGold #============================================================================== class Window_ShopItemsGold < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 288, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) @sprite = Sprite_ShopTAG.new(self.x+8, self.y+4, "支払い金額") refresh(0) end def dispose super @sprite.dispose end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh(gold) self.contents.clear cx = contents.text_size($data_system.words.gold).width self.contents.font.color = normal_color self.contents.draw_text(4, 0, 120-cx-2, 32, gold.to_s, 2) self.contents.font.color = system_color self.contents.draw_text(124-cx, 0, cx, 32, $data_system.words.gold, 2) end end #============================================================================== # ■ Window_ShopSale #============================================================================== class Window_ShopSale < Window_Base BUY=0;SELL=1 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(210, 108, 380, 200) self.contents = Bitmap.new(width - 32, height - 32) self.back_opacity = 200 self.z = 300 self.visible = false end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh(data) self.contents.clear self.contents.font.color = system_color self.contents.draw_text(4, 0, 200, 32, "購入金額") self.contents.draw_text(4, 32, 200, 32, "売却金額") self.contents.fill_rect(Rect.new(0, 66, self.contents.width, 2), Color.new(255, 255, 255, 255)) self.contents.draw_text(4, 70, 200, 32, "支払い金額") self.contents.draw_text(4,102, 200, 32, "残金") self.contents.font.color = normal_color # 合計価格と通貨単位を描画 domination = $data_system.words.gold cx = contents.text_size(domination).width self.contents.font.color = normal_color self.contents.draw_text(4, 0, 328-cx-2, 32, data[BUY].total.to_s, 2) self.contents.draw_text(4, 32, 328-cx-2, 32, data[SELL].total.to_s, 2) self.contents.draw_text(4, 70, 328-cx-2, 32, (data[BUY].total - data[SELL].total).to_s, 2) self.contents.draw_text(4,102, 328-cx-2, 32, ($game_party.gold - (data[BUY].total - data[SELL].total)).to_s, 2) self.contents.font.color = system_color self.contents.draw_text(332-cx, 0, cx, 32, domination, 2) self.contents.draw_text(332-cx, 32, cx, 32, domination, 2) self.contents.draw_text(332-cx, 70, cx, 32, domination, 2) self.contents.draw_text(332-cx,102, cx, 32, domination, 2) end end #============================================================================== # ■ Window_ShopSaleCommand #============================================================================== class Window_ShopSaleCommand < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize # コマンドの個数からウィンドウの高さを算出 super(240, 250, 344, 64) @commands = ["支払いをする", "やめる"] @item_max = @commands.size @column_max = 2 self.contents = Bitmap.new(width - 32, height - 32) refresh self.opacity = 0 self.contents_opacity = 255 show(false) self.z = 350 end def show(f) self.active = f self.visible = f self.index = 0 end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max self.contents.draw_text(4 + i * 160, 0, 130, 32, @commands[i], 1) end end #-------------------------------------------------------------------------- # ● カーソルの矩形更新 #-------------------------------------------------------------------------- def update_cursor_rect self.cursor_rect.set(@index * 160, 0, 138, 32) end end #============================================================================== # ■ Window_ShopEquipParty #============================================================================== class Window_ShopEquipParty < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(index=0) actors = [] for actor in $game_party.actors actors.push(actor.name) end x = ShopEx::USE_MENU_EQUIP ? 100 : 320 # コマンドの個数からウィンドウの高さを算出 super(x, 128, 160, actors.size * 32 + 32) @item_max = actors.size @commands = actors self.contents = Bitmap.new(width - 32, @item_max * 32) self.z = 300 @enable = [] for i in 0...@item_max @enable.push(true) end refresh self.index = index show(false) end def show(f) self.active = f self.visible = f end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i) end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) self.contents.font.color = @enable[index] ? normal_color : disabled_color self.contents.draw_text(4, 32 * index, self.contents.width - 8, 32, @commands[index]) end #-------------------------------------------------------------------------- # ● アイテム使用・装備用の再描画 #-------------------------------------------------------------------------- def refresh_equip(item) show(true) self.contents.clear for i in 0...@item_max update_enable(i, item) draw_item(i) end end def update_enable(i, item) case item when RPG::Item @enable[i] = false # アイテムは使えない when RPG::Weapon, RPG::Armor @enable[i] = $game_party.actors[i].equippable?(item) end end def c_enable? return @enable[@index] end end #============================================================================== # ■ Window_ShopStatus #============================================================================== class Window_ShopStatus < Window_Base M_PARTY = 0 # パーティーステータス M_ACTOR = 1 # アクターステータス PATTERN = [M_PARTY, M_ACTOR] # 切り替えの並び順 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 480-128, 640, 128) self.contents = Bitmap.new(width - 32, height - 32) @item = nil @mode = PATTERN[0] @actor_idx = 0 refresh end #-------------------------------------------------------------------------- # ● アイテム名の描画 #-------------------------------------------------------------------------- def draw_item_name(item, x, y, opacity=255) return if item == nil bitmap = RPG::Cache.icon(item.icon_name) self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 212, 32, item.name) end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear return if @item == nil case @mode when M_PARTY; refresh_party when M_ACTOR; refresh_actor end end #-------------------------------------------------------------------------- # ● リフレッシュ : M_PARTY #-------------------------------------------------------------------------- def refresh_party # 装備品追加情報 for i in 0...$game_party.actors.size # アクターを取得 actor = $game_party.actors[i] x = 154*i case @item when RPG::Item draw_actor_name(actor, x, 0) draw_actor_hp(actor, x, 32) draw_actor_sp(actor, x, 64) when RPG::Weapon, RPG::Armor # 装備可能なら通常文字色に、不可能なら無効文字色に設定 able = actor.equippable?(@item) self.contents.font.color = able ? normal_color : disabled_color # アクターの名前を描画 self.contents.draw_text(x, 0, 120, 32, actor.name) next unless able if @item.is_a?(RPG::Weapon) item1 = $data_weapons[actor.weapon_id] atk1 = item1 != nil ? item1.atk : 0 atk2 = @item != nil ? @item.atk : 0 draw_item_diff(x, 32, $data_system.words.atk, (atk2 - atk1), able) elsif @item.is_a?(RPG::Armor) case @item.kind when 0; item1 = $data_armors[actor.armor1_id] when 1; item1 = $data_armors[actor.armor2_id] when 2; item1 = $data_armors[actor.armor3_id] when 3; item1 = $data_armors[actor.armor4_id] end pdef1 = item1 != nil ? item1.pdef : 0 mdef1 = item1 != nil ? item1.mdef : 0 pdef2 = @item != nil ? @item.pdef : 0 mdef2 = @item != nil ? @item.mdef : 0 draw_item_diff(x, 32, $data_system.words.pdef, (pdef2 - pdef1), able) draw_item_diff(x, 64, $data_system.words.mdef, (mdef2 - mdef1), able) end end end end def draw_item_diff(x, y, word, change, able) self.contents.font.color = able ? system_color : disabled_color self.contents.draw_text(x, y, 112, 32, word) if !able self.contents.font.color = disabled_color elsif change > 0 self.contents.font.color = crisis_color elsif change < 0 self.contents.font.color = disabled_color else self.contents.font.color = normal_color end self.contents.draw_text(x+22, y, 112, 32, sprintf("%+d", change), 2) end #-------------------------------------------------------------------------- # ● リフレッシュ : M_ACTOR #-------------------------------------------------------------------------- def refresh_actor actor = $game_party.actors[@actor_idx] able = @item.is_a?(RPG::Item) ? true : actor.equippable?(@item) type = @item.is_a?(RPG::Item) ? -1 : (@item.is_a?(RPG::Weapon) ? 0 : (@item.kind + 1) ) self.contents.font.color = able ? normal_color : disabled_color self.contents.draw_text(0, 0, 120, 32, actor.name) case @item when RPG::Item draw_actor_level(actor, 154, 0) when RPG::Weapon draw_item_name($data_weapons[actor.weapon_id], 154, 0, able ? 255 : 128) when RPG::Armor case @item.kind when 0; item1 = $data_armors[actor.armor1_id] when 1; item1 = $data_armors[actor.armor2_id] when 2; item1 = $data_armors[actor.armor3_id] when 3; item1 = $data_armors[actor.armor4_id] end draw_item_name(item1, 154, 0, able ? 255 : 128) end word = [$data_system.words.atk, $data_system.words.pdef, $data_system.words.mdef, $data_system.words.str, $data_system.words.dex, $data_system.words.agi, $data_system.words.int, ] now = [ actor.atk, actor.pdef, actor.mdef, actor.str, actor.dex, actor.agi, actor.int ] new = able ? [ actor.shop_v_equip(type, @item.id, 0), actor.shop_v_equip(type, @item.id, 1), actor.shop_v_equip(type, @item.id, 2), actor.shop_v_equip(type, @item.id, 3), actor.shop_v_equip(type, @item.id, 4), actor.shop_v_equip(type, @item.id, 5), actor.shop_v_equip(type, @item.id, 6) ] : now draw_item_diff2(0, 32, word[0], able, now[0], new[0]) draw_item_diff2(154, 32, word[1], able, now[1], new[1]) draw_item_diff2(154, 64, word[2], able, now[2], new[2]) draw_item_diff2(308, 32, word[3], able, now[3], new[3]) draw_item_diff2(308, 64, word[4], able, now[4], new[4]) draw_item_diff2(462, 32, word[5], able, now[5], new[5]) draw_item_diff2(462, 64, word[6], able, now[6], new[6]) end def draw_item_diff2(x, y, word, able, now, new) self.contents.font.color = able ? system_color : disabled_color self.contents.draw_text(x, y, 112, 32, word) if !able self.contents.font.color = disabled_color elsif now < new self.contents.font.color = crisis_color elsif now > new self.contents.font.color = disabled_color else self.contents.font.color = normal_color end self.contents.draw_text(x+22, y, 112, 32, new.to_s, 2) end #-------------------------------------------------------------------------- # ● アイテムの設定 # item : 新しいアイテム #-------------------------------------------------------------------------- def item=(item) if @item != item @item = item refresh end end #-------------------------------------------------------------------------- # ● モードチェンジ #-------------------------------------------------------------------------- def change_mode if @mode == M_ACTOR @actor_idx += 1 if @actor_idx == $game_party.actors.size @actor_idx = 0 @mode = PATTERN[0] end refresh else @mode = PATTERN[((@mode + 1) % PATTERN.size)] refresh end return true end end #============================================================================== # ■ Window_ShopItemInfo #============================================================================== class Window_ShopItemInfo < Window_Base include ShopExItemInfo #---------------------------------------------------------------------------- TEXT_H = 32 # 文字高さ ES_W = 4 # 属性・ステート間隔 SCOPE = ["なし", "敵単体", "敵全体", "味方単体", "味方全体", "味方単体蘇生", "味方全体蘇生", "使用者"] #OCCASION = ["常時使用可能", "戦闘のみ", "マップ上のみ", "使用不可"] #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(160, 64, 480, 288) self.contents = Bitmap.new(width - 32, height - 32) self.back_opacity = 200 self.visible = false self.z = 200 @data = nil end def item=(data) return if @data == data @data = data refresh(data) end #-------------------------------------------------------------------------- # ● リフレッシュ # data : RPG::Item / RPG::Weapon / RPG::Armor / RPG::Skill #-------------------------------------------------------------------------- def refresh(data) self.contents.clear return if data.nil? draw_item_name(data, indent(0), 0) #self.contents.draw_text(indent(1), TEXT_H, contents.width-indent(1), TEXT_H, data.description) #self.contents.fill_rect(0, TEXT_H*2, contents.width, 2, Color.new(255,255,255,128)) case data when RPG::Item; draw_item_info(data) when RPG::Weapon; draw_weapon_info(data) when RPG::Armor; draw_armor_info(data) end end #-------------------------------------------------------------------------- # ● Line計算 #-------------------------------------------------------------------------- def line(n) return TEXT_H * n + 4 end #-------------------------------------------------------------------------- # ● インデント #-------------------------------------------------------------------------- def indent(n) case n when 0; return 4 when 1; return 24 when 2; return 24+96 when 3; return 248 when 4; return 248+96 when 5; return 160 end return 0 end #-------------------------------------------------------------------------- # ● アイコン描画(Graphics/Icons内の画像を表示) #-------------------------------------------------------------------------- def draw_icon(x, y, file_name) return 0 if file_name.nil? or file_name == "" bit = RPG::Cache.icon(file_name) src_rect = Rect.new(0, 0, bit.width, bit.height) yy = (TEXT_H - bit.height) / 2 self.contents.blt(x, y+yy, bit, src_rect) return bit.width + ES_W end #-------------------------------------------------------------------------- # ● 属性描画 #-------------------------------------------------------------------------- def draw_elements(elements, x, y) cnt = 0 xx = 0 for id in elements next if ELE_NOT_SHOW.include?(id) break if cnt == ELE_MAX if USE_ICON xx += draw_icon(x+xx, y, ELE_ICON[id]) else rect = self.contents.text_size($data_system.elements[id]) break if (x+xx+rect.width) > contents.width self.contents.draw_text(x+xx, y, rect.width, TEXT_H, $data_system.elements[id]) xx += rect.width + ES_W end cnt += 1 end end #-------------------------------------------------------------------------- # ● ステート描画 #-------------------------------------------------------------------------- def draw_states(states, x, y) cnt = 0 xx = 0 for id in states next if STT_NOT_SHOW.include?(id) break if cnt == STT_MAX if USE_ICON xx += draw_icon(x+xx, y, STT_ICON[id]) else rect = self.contents.text_size($data_states[id].name) break if (x+xx+rect.width) > contents.width self.contents.draw_text(x+xx, y, rect.width, TEXT_H, $data_states[id].name) xx += rect.width + ES_W end cnt += 1 end end #-------------------------------------------------------------------------- # ● Item情報描画 # data : アイテム(RPG::Item) #-------------------------------------------------------------------------- def draw_item_info(data) # 消耗品 if data.consumable self.contents.font.color = system_color self.contents.draw_text(300, 0, 200, TEXT_H, "【消耗品】") end l = 1 # 行 # 範囲と命中率 if data.scope != 0 self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 200, TEXT_H, "範囲") if data.hit < 100 self.contents.draw_text(indent(3), line(l), 200, TEXT_H, "命中率") end self.contents.font.color = normal_color self.contents.draw_text(indent(2), line(l), 200, TEXT_H, SCOPE[data.scope]) if data.hit < 100 self.contents.draw_text(indent(4), line(l), 200, TEXT_H, data.hit.to_s+" %") end l += 1 end # HP/SP増減、パラメータ変化 hpspparam = false sys_l = l hp = "#{$data_system.words.hp}" sp = "#{$data_system.words.sp}" if data.recover_hp_rate != 0 hpspparam = true pm = data.recover_hp_rate >= 0 ? "回復" : "ダメージ" text = "最大#{hp}の#{data.recover_hp_rate.abs}%#{pm}" self.contents.draw_text(indent(2), line(l), 300, TEXT_H, text) l += 1 end if data.recover_hp != 0 hpspparam = true pm = data.recover_hp >= 0 ? "回復" : "ダメージ" text = "#{hp} #{data.recover_hp.abs}#{pm}" self.contents.draw_text(indent(2), line(l), 300, TEXT_H, text) l += 1 end if data.recover_sp_rate != 0 hpspparam = true pm = data.recover_sp_rate >= 0 ? "回復" : "ダメージ" text = "最大#{sp}の#{data.recover_sp_rate.abs}%#{pm}" self.contents.draw_text(indent(2), line(l), 300, TEXT_H, text) l += 1 end if data.recover_sp != 0 hpspparam = true pm = data.recover_sp >= 0 ? "回復" : "ダメージ" text = "#{sp} #{data.recover_sp.abs}#{pm}" self.contents.draw_text(indent(2), line(l), 300, TEXT_H, text) l += 1 end if data.parameter_type != 0 # パラメータ変化効果あり hpspparam = true param = ["なし", "最大#{hp}", "最大#{sp}", $data_system.words.str, $data_system.words.dex, $data_system.words.agi, $data_system.words.int][data.parameter_type] pm = data.parameter_points >= 0 ? "+" : "-" text = "#{param} #{pm}#{data.parameter_points}" self.contents.draw_text(indent(2), line(l), 300, TEXT_H, text) l += 1 end if hpspparam self.contents.font.color = system_color self.contents.draw_text(indent(1), line(sys_l), 100, TEXT_H, "効果") end # 属性 unless data.element_set.empty? self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 100, TEXT_H, "属性") self.contents.font.color = normal_color draw_elements(data.element_set, indent(2), line(l)) l += 1 end # 付与ステート unless data.plus_state_set.empty? self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 140, TEXT_H, "付与ステート") self.contents.font.color = normal_color draw_states(data.plus_state_set, indent(5), line(l)) l += 1 end # 解除ステート unless data.minus_state_set.empty? self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 140, TEXT_H, "解除ステート") self.contents.font.color = normal_color draw_states(data.minus_state_set, indent(5), line(l)) l += 1 end end #-------------------------------------------------------------------------- # ● Weapon情報描画 # data : 武器(RPG::Weapon) #-------------------------------------------------------------------------- def draw_weapon_info(data) self.contents.font.color = system_color self.contents.draw_text(300, 0, 200, TEXT_H, "【#{$data_system.words.weapon}】") self.contents.draw_text(indent(1), line(1), 200, TEXT_H, $data_system.words.atk) #self.contents.draw_text(indent(3), line(1), 200, TEXT_H, "命中率") self.contents.font.color = normal_color self.contents.draw_text(indent(2), line(1), 50, TEXT_H, data.atk.to_s, 2) #self.contents.draw_text(indent(4), line(1), 200, TEXT_H, data.hit.to_s) # 100%固定なので表示しない list = [] list.push([$data_system.words.pdef, data.pdef]) list.push([$data_system.words.mdef, data.mdef]) list.push([$data_system.words.str, data.str_plus]) list.push([$data_system.words.dex, data.dex_plus]) list.push([$data_system.words.agi, data.agi_plus]) list.push([$data_system.words.int, data.int_plus]) i = 0 l = 1 for pram in list l += 1 if i == 0 self.contents.font.color = system_color self.contents.draw_text(indent(1+i), line(l), 200, TEXT_H, pram[0]) self.contents.font.color = normal_color self.contents.draw_text(indent(2+i), line(l), 50, TEXT_H, pram[1].to_s, 2) i = (i == 2 ? 0 : 2) end l += 1 # 属性 unless data.element_set.empty? self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 100, TEXT_H, "属性") self.contents.font.color = normal_color draw_elements(data.element_set, indent(2), line(l)) l += 1 end # 付与ステート unless data.plus_state_set.empty? self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 140, TEXT_H, "付与ステート") self.contents.font.color = normal_color draw_states(data.plus_state_set, indent(5), line(l)) l += 1 end # 解除ステート unless data.minus_state_set.empty? self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 140, TEXT_H, "解除ステート") self.contents.font.color = normal_color draw_states(data.minus_state_set, indent(5), line(l)) l += 1 end end #-------------------------------------------------------------------------- # ● Armor情報描画 # data : 防具(RPG::Armor) #-------------------------------------------------------------------------- def draw_armor_info(data) self.contents.font.color = system_color kind = [$data_system.words.armor1, $data_system.words.armor2, $data_system.words.armor3, $data_system.words.armor4][data.kind] self.contents.draw_text(300, 0, 200, TEXT_H, "【#{kind}】") self.contents.draw_text(indent(1), line(1), 200, TEXT_H, $data_system.words.pdef) self.contents.draw_text(indent(3), line(1), 200, TEXT_H, $data_system.words.mdef) self.contents.font.color = normal_color self.contents.draw_text(indent(2), line(1), 50, TEXT_H, data.pdef.to_s, 2) self.contents.draw_text(indent(4), line(1), 50, TEXT_H, data.mdef.to_s, 2) l = 2 # 行 self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 200, TEXT_H, "回避修正") self.contents.font.color = normal_color self.contents.draw_text(indent(2), line(l), 50, TEXT_H, data.eva.to_s, 2) # 能力補正 i = 0 # インデント補正 list = [] list.push([$data_system.words.str, data.str_plus]) list.push([$data_system.words.dex, data.dex_plus]) list.push([$data_system.words.agi, data.agi_plus]) list.push([$data_system.words.int, data.int_plus]) for pram in list l += 1 if i == 0 self.contents.font.color = system_color self.contents.draw_text(indent(1+i), line(l), 200, TEXT_H, pram[0]) self.contents.font.color = normal_color self.contents.draw_text(indent(2+i), line(l), 50, TEXT_H, pram[1].to_s, 2) i = (i == 2 ? 0 : 2) end l += 1 # オートステート if data.auto_state_id != 0 self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 140, TEXT_H, "オートステート") self.contents.font.color = normal_color draw_states([data.auto_state_id], indent(5), line(l)) l += 1 end # 属性防御 unless data.guard_element_set.empty? self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 100, TEXT_H, "属性防御") self.contents.font.color = normal_color draw_elements(data.guard_element_set, indent(2), line(l)) l += 1 end # ステート防御 unless data.guard_state_set.empty? self.contents.font.color = system_color self.contents.draw_text(indent(1), line(l), 140, TEXT_H, "ステート防御") self.contents.font.color = normal_color draw_states(data.guard_state_set, indent(5), line(l)) l += 1 end end end