############################################################################ # # 装備プリセット # 作者:リック(http://mugenrick.seesaa.net) # 最終更新日:2020/3/27 # ############################################################################ # # 【説明】 # 装備欄にひとつコマンドを追加して、 # 現在の装備の組み合わせを保存、いつでも復元できるようにします。 # ボス戦や稼ぎで一時的に装備を変更したいとき等に便利です。 # # 【使用方法】 # このスクリプトを導入するだけで適用されます(ニューゲームでなくてもOK)。 # 導入位置ですが、基本的に「▼ 素材」の下、 # 「▼ メイン」の上であればどこでも構いません。 # ただし、ろかん様(http://kaisou-ryouiki.sakura.ne.jp/)の # 「新規入手アイテム強調表現」と併用するための記述を行っておりますので、 # もし当該スクリプトを導入している場合は、 # 本スクリプトをそれより下に配置してください。 # # 【注意事項】 # 不具合が無いよう確認は可能な限りとっていますが、 # 装備可能判定に誤りがあると場合によっては装備が消滅する可能性があります。 # 特に装備可不可関係のスクリプトを導入している場合は、 # 装備消滅が発生しないか確認したほうが良いでしょう。 # なるべく対応したいと思いますので、 # もし発生した際はご連絡いただけると幸いです。 # # 【更新履歴】 # 2020/ 3/27 公開 # ############################################################################# module EQ_SAVE NAME = ["保存/復元", #装備欄で表示するコマンド名称 "保存", #保存モード名称 "復元", #復元モード名称 "保存する", #保存実行選択肢名称 "復元する", #復元実行選択肢名称 "名前変更", #名前変更選択肢名称 "リセット", #リセット選択肢名称 "キャンセル"] #キャンセル選択肢名称 MODE_KEY = :X #保存/復元モード切り替えボタン SND = ["Decision2", #保存実行時に鳴らすSE "Equip1", #復元実行時に鳴らすSE "Item1"] #リセット時に鳴らすSE end $imported ||= {} $imported["装備プリセット"] = true ############################################################################# # ■ 一時システム変数 ############################################################################# class Game_Temp #-------------------------------------------------------------------------- # ■ モード取得 (true=保存 false=復元) #-------------------------------------------------------------------------- def eq_save_mode @eq_save_mode end #-------------------------------------------------------------------------- # ■ モード代入 #-------------------------------------------------------------------------- def eq_save_mode=(value) @eq_save_mode = value end #-------------------------------------------------------------------------- # ■ プリセットインデックス取得 (Scene_Nameへ移行してリセットされるため) #-------------------------------------------------------------------------- def preset_index @preset_index end #-------------------------------------------------------------------------- # ■ プリセットインデックス代入 #-------------------------------------------------------------------------- def preset_index=(index) @preset_index = index end end ############################################################################# # ■ アクターに装備プリセット保存用変数追加 ############################################################################# class Game_Actor #-------------------------------------------------------------------------- # ■ 装備プリセット取得 #-------------------------------------------------------------------------- def eq_save @eq_save end #-------------------------------------------------------------------------- # ■ 装備プリセット代入 #-------------------------------------------------------------------------- def eq_save=(list) @eq_save = list end end ############################################################################# # ■ 新規クラス 特殊計算用 ############################################################################# class R_Math #-------------------------------------------------------------------------- # ● 同一オブジェクトか (ソフトリセットでメモリが変動し判断できなくなるため) #-------------------------------------------------------------------------- def self.same_obj?(obj1, obj2) return obj1 && obj2 && (obj1.id == obj2.id) && obj1.is_a?(obj2.class) end end ############################################################################# # ■ 装備のコマンド欄に「保存/復元」コマンド追加 ############################################################################# class Window_EquipCommand < Window_HorzCommand #-------------------------------------------------------------------------- # ● 桁数の取得 #-------------------------------------------------------------------------- alias equip_save_col_max col_max def col_max equip_save_col_max + 1 end #-------------------------------------------------------------------------- # ● コマンドリストの作成 #-------------------------------------------------------------------------- alias equip_save_make_command_list make_command_list def make_command_list equip_save_make_command_list add_command(EQ_SAVE::NAME[0], :eq_save) end end ############################################################################# # ■ 新規クラス:装備プリセットウィンドウ ############################################################################# class Window_EqPreset < Window_SkillList #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, width) super(x, y, width, fitting_height(4)) create_equip_window end #-------------------------------------------------------------------------- # ● アクターの設定 #-------------------------------------------------------------------------- def actor=(actor) super @equip_window.actor = @actor end #-------------------------------------------------------------------------- # ● 装備ウィンドウの作成 #-------------------------------------------------------------------------- def create_equip_window x = self.x y = self.y + self.height width = Graphics.width - x height = Graphics.height - y @equip_window = Window_PresetEquip.new(x, y, width, height) @equip_window.actor = @actor @equip_window.index = index end #-------------------------------------------------------------------------- # ● プリセットリストの作成 #-------------------------------------------------------------------------- def make_item_list if !@actor.eq_save @actor.eq_save = [{}, {}, {}, {}, {}, {}, {}, {}] @actor.eq_save.each_with_index do |pre, i| pre[:nam] = "プリセット#{(i+1).to_s.tr('0-9', '0-9')}" pre[:equ] = [] end end @data = @actor.eq_save end #-------------------------------------------------------------------------- # ● 項目の描画 #-------------------------------------------------------------------------- def draw_item(index) item = @data[index] if item rect = item_rect(index) rect.width -= 4 draw_item_name(item, rect.x, rect.y, true) end end #-------------------------------------------------------------------------- # ● アイテム名の描画 #-------------------------------------------------------------------------- def draw_item_name(item, x, y, enabled = true, width = 150) change_color(normal_color, enabled) draw_text(x, y, width, line_height, item[:nam]) end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help if $game_temp.eq_save_mode txt = "現在は#{EQ_SAVE::NAME[1]}モードです\nモードを切り替える場合は" else txt = "現在は#{EQ_SAVE::NAME[2]}モードです\nモードを切り替える場合は" end txt += " #{EQ_SAVE::MODE_KEY.to_s} を押してください" @help_window.set_text(txt) end #-------------------------------------------------------------------------- # ● 許可状態で表示するかどうか #-------------------------------------------------------------------------- def enable?(item) true end #-------------------------------------------------------------------------- # ● 横に項目が並ぶときの空白の幅を取得 #-------------------------------------------------------------------------- def spacing return 16 end #-------------------------------------------------------------------------- # ● 項目の選択 #-------------------------------------------------------------------------- def select(index) super $game_temp.preset_index = index @equip_window.index = index @equip_window.refresh end #-------------------------------------------------------------------------- # ● リフレッシュ (装備ウィンドウも更新) #-------------------------------------------------------------------------- def refresh super @equip_window.refresh end #-------------------------------------------------------------------------- # ● 解放 (同時に装備ウィンドウも解放 名前入力移行時に残るため) #-------------------------------------------------------------------------- def dispose super @equip_window.dispose end end ############################################################################# # ■ 新規クラス 装備ウィンドウ ############################################################################# class Window_PresetEquip < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, width, height) super(x, y, width, height) refresh end #-------------------------------------------------------------------------- # ● アクターの設定 #-------------------------------------------------------------------------- def actor=(actor) @actor = actor end #-------------------------------------------------------------------------- # ● プリセットインデックスの設定 #-------------------------------------------------------------------------- def index=(index) @index = index end #-------------------------------------------------------------------------- # ● 描画 #-------------------------------------------------------------------------- def draw_all_items return if !@actor || !@index #矢印描画 x = contents.width/2 - f_size/2 y = contents.height/2 - f_size/2 txt = ($game_temp.eq_save_mode ? "カ%" : "タ%") change_color(text_color(14), true) draw_text(x, y - contents.height/4, f_size, f_size, txt) draw_text(x, y , f_size, f_size, txt) draw_text(x, y + contents.height/4, f_size, f_size, txt) #装備一覧 has_items = get_has_items [0, 1].each do |mode| x = (contents.width/2 + f_size/2) * mode #分類 txt = (mode == 0 ? "現在" : "保存") change_color(system_color, true) draw_text(x, 0, e_txt_wid, f_size, txt) x += f_size * txt.size #装備 equips = (mode == 0 ? @actor.equips : @actor.eq_save[@index][:equ]) equips.each_with_index do |e, i| next if !e enable = (mode == 0 ? @actor.equip_change_ok?(i) : (has_items[i] > 0)) change_color(normal_color, enable) draw_icon(e.icon_index, x, line_height * i, enable) draw_text(x + icon_wid, line_height * i, e_txt_wid, f_size, e.name) end end end #-------------------------------------------------------------------------- # ● フォントサイズ #-------------------------------------------------------------------------- def f_size contents.font.size end #-------------------------------------------------------------------------- # ● アイコンの幅 #-------------------------------------------------------------------------- def icon_wid 24 end #-------------------------------------------------------------------------- # ● 装備テキストの幅 #-------------------------------------------------------------------------- def e_txt_wid (contents.width-f_size)/2 - f_size*2 - icon_wid end #-------------------------------------------------------------------------- # ● 1行の高さ #-------------------------------------------------------------------------- def line_height (contents.height-f_size) / (@actor.equips.size-1) end #-------------------------------------------------------------------------- # ● 装備所持状態を配列で取得 #-------------------------------------------------------------------------- def get_has_items num_arr = [] result = [] @actor.eq_save[@index][:equ].each do |e| num = @actor.equips.count {|a_e| R_Math.same_obj?(a_e, e) } num -= num_arr.count {|a| R_Math.same_obj?(a[:equ], e) } num_arr.push({:equ => e, :num => $game_party.item_number(e) + num}) end num_arr.each do |elem| result.push(elem[:num]) end return result end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh create_contents draw_all_items end end ############################################################################# # ■ 新規クラス:ステータスウィンドウ 通常のものより横幅を縮小 ############################################################################# class Window_EqSaveStatus < Window_SkillStatus #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width Graphics.width - 330 end #-------------------------------------------------------------------------- # ● シンプルなステータスの描画 #-------------------------------------------------------------------------- def draw_actor_simple_status(actor, x, y) draw_actor_name(actor, x, y) draw_actor_hp(actor, x, y + line_height * 1, 80) draw_actor_mp(actor, x, y + line_height * 2, 80) end end ############################################################################# # ■ 新規クラス プリセット決定時選択肢 ############################################################################# class Window_PresetSelect < Window_Command #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 0) update_placement self.openness = 0 self.active = false end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width return 160 end #-------------------------------------------------------------------------- # ● ウィンドウ位置の更新 #-------------------------------------------------------------------------- def update_placement self.x = (Graphics.width - width) / 2 self.y = (Graphics.height - height) / 2 end #-------------------------------------------------------------------------- # ● コマンドリストの作成 #-------------------------------------------------------------------------- def make_command_list if $game_temp.eq_save_mode add_command(EQ_SAVE::NAME[3], :ok_save) else add_command(EQ_SAVE::NAME[4], :ok_load) end add_command(EQ_SAVE::NAME[5], :ok_name) add_command(EQ_SAVE::NAME[6], :ok_reset) add_command(EQ_SAVE::NAME[7], :cancel) end #-------------------------------------------------------------------------- # ● 決定ボタンが押されたときの処理 #-------------------------------------------------------------------------- def process_ok case @index when 0 file = "Audio/SE/#{EQ_SAVE::SND[$game_temp.eq_save_mode ? 0 : 1]}" Audio.se_play(file) when 1 Sound.play_ok when 2 Audio.se_play("Audio/SE/#{EQ_SAVE::SND[2]}") when 3 Sound.play_cancel end Input.update call_ok_handler end end ############################################################################# # ■ 装備シーン 装備保存/復元コマンド追加 ############################################################################# class Scene_Equip < Scene_MenuBase #-------------------------------------------------------------------------- # ● コマンドウィンドウの作成 #-------------------------------------------------------------------------- alias equip_save_create_command_window create_command_window def create_command_window equip_save_create_command_window @command_window.set_handler(:eq_save, method(:command_eq_save)) end #-------------------------------------------------------------------------- # ■ コマンド [装備保存/復元] #-------------------------------------------------------------------------- def command_eq_save $game_temp.eq_save_mode = false $game_temp.preset_index = 0 SceneManager.call(Scene_EqSave) end end ############################################################################# # ■ 新規クラス 装備保存/復元シーン ############################################################################# class Scene_EqSave < Scene_MenuBase #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start super create_help_window create_preset_window create_status_window create_select_window end #-------------------------------------------------------------------------- # ● 装備プリセットウィンドウの作成 #-------------------------------------------------------------------------- def create_preset_window x = @help_window.x y = @help_window.height @preset_window = Window_EqPreset.new(x, y, 330) @preset_window.actor = @actor @preset_window.help_window = @help_window @preset_window.set_handler(:ok, method(:on_preset_ok)) @preset_window.set_handler(:cancel, method(:return_scene)) @preset_window.set_handler(:pagedown, method(:next_actor)) @preset_window.set_handler(:pageup, method(:prev_actor)) @preset_window.select($game_temp.preset_index) @preset_window.refresh @preset_window.activate end #-------------------------------------------------------------------------- # ● ステータスウィンドウの作成 #-------------------------------------------------------------------------- def create_status_window y = @help_window.height @status_window = Window_EqSaveStatus.new(@preset_window.width, y) @status_window.actor = @actor end #-------------------------------------------------------------------------- # ● プリセット決定時選択肢ウィンドウの作成 #-------------------------------------------------------------------------- def create_select_window @select_window = Window_PresetSelect.new @select_window.set_handler(:ok_save, method(:on_select_save)) @select_window.set_handler(:ok_load, method(:on_select_load)) @select_window.set_handler(:ok_name, method(:on_select_name)) @select_window.set_handler(:ok_reset, method(:on_select_reset)) @select_window.set_handler(:cancel, method(:on_select_cancel)) end #-------------------------------------------------------------------------- # ● プリセット [決定] #-------------------------------------------------------------------------- def on_preset_ok @select_window.open @select_window.activate end #-------------------------------------------------------------------------- # ● プリセット決定時選択肢 [保存] #-------------------------------------------------------------------------- def on_select_save @actor.eq_save[@preset_window.index][:equ] = @actor.equips on_select_cancel end #-------------------------------------------------------------------------- # ● プリセット決定時選択肢 [復元] #-------------------------------------------------------------------------- def on_select_load 2.times { process_load } #装備効果による装備可能状態変更対応のため2回実行 @status_window.refresh on_select_cancel end #-------------------------------------------------------------------------- # ● 復元実処理 #-------------------------------------------------------------------------- def process_load save_equ = @actor.eq_save[@preset_window.index][:equ] 0.upto(@actor.equips.size - 1) do |sl| next if save_equ[sl] && !@actor.equippable?(save_equ[sl]) next if save_equ[sl] && @actor.equip_slots[sl] != save_equ[sl].etype_id @actor.change_equip(sl, save_equ[sl]) #装備が復元できず、装備変更可能なら現スロット以下から同装備を検索し交換 next if R_Math::same_obj?(@actor.equips[sl], save_equ[sl]) next if !@actor.equip_change_ok?(sl) (sl + 1).upto(@actor.equips.size - 1) do |sl2| if R_Math::same_obj?(@actor.equips[sl2], save_equ[sl]) && @actor.equip_change_ok?(sl2) tmp = @actor.equips[sl] @actor.change_equip(sl2, nil) @actor.change_equip(sl , save_equ[sl]) @actor.change_equip(sl2, tmp) end end end end #-------------------------------------------------------------------------- # ● プリセット決定時選択肢 [名前変更] #-------------------------------------------------------------------------- def on_select_name name = @actor.eq_save[@preset_window.index][:nam] SceneManager.call(Scene_PresetName) SceneManager.scene.prepare(name, 12, @actor.eq_save[@preset_window.index]) end #-------------------------------------------------------------------------- # ● プリセット決定時選択肢 [リセット] #-------------------------------------------------------------------------- def on_select_reset @actor.eq_save[@preset_window.index][:equ] = [] on_select_cancel end #-------------------------------------------------------------------------- # ● プリセット決定時選択肢 [キャンセル] #-------------------------------------------------------------------------- def on_select_cancel @select_window.select(0) @select_window.close @select_window.deactivate @preset_window.activate @preset_window.refresh end #-------------------------------------------------------------------------- # ● アクターの切り替え #-------------------------------------------------------------------------- def on_actor_change @preset_window.actor = @actor @status_window.actor = @actor @preset_window.activate @preset_window.refresh end #-------------------------------------------------------------------------- # ● フレーム更新 (モードチェンジ操作受付) #-------------------------------------------------------------------------- def update super if Input.trigger?(EQ_SAVE::MODE_KEY) && @preset_window.active change_eq_save_mode end end #-------------------------------------------------------------------------- # ● モードチェンジ #-------------------------------------------------------------------------- def change_eq_save_mode Sound.play_ok $game_temp.eq_save_mode = ($game_temp.eq_save_mode ? false : true) @preset_window.update_help @preset_window.refresh @select_window.refresh end end ############################################################################# # ■ 新規クラス プリセット名入力シーン ############################################################################# class Scene_PresetName < Scene_MenuBase #-------------------------------------------------------------------------- # ● 準備 #-------------------------------------------------------------------------- def prepare(default_name, max_char, hash) @default_name = default_name @max_char = max_char @hash = hash end #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start super @edit_window = Window_PresetNameEdit.new(@default_name, @max_char) @input_window = Window_NameInput.new(@edit_window) @input_window.set_handler(:ok, method(:on_input_ok)) end #-------------------------------------------------------------------------- # ● 入力[決定] #-------------------------------------------------------------------------- def on_input_ok @hash[:nam] = @edit_window.name return_scene end end ############################################################################# # ■ 新規クラス プリセット名入力 表示ウィンドウ(上部) ############################################################################# class Window_PresetNameEdit < Window_NameEdit #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(default_name, max_char) super($game_actors[1], max_char) @max_char = max_char @default_name = @name = default_name[0, @max_char] @index = @name.size deactivate refresh end #-------------------------------------------------------------------------- # ● 名前を描画する左端の座標を取得 #-------------------------------------------------------------------------- def left name_center = contents_width / 2 name_width = (@max_char + 1) * char_width return [name_center - name_width / 2, contents_width - name_width].min end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh contents.clear @max_char.times {|i| draw_underline(i) } @name.size.times {|i| draw_char(i) } cursor_rect.set(item_rect(@index)) end end ############################################################################# # ■ ろかんさん:新規入手アイテム強調表現併用 # 復元時に外した装備の新規入手判定防止 ############################################################################# $rsi ||= {} if $rsi["新規入手アイテム強調表現"] class Game_Party < Game_Unit #-------------------------------------------------------------------------- # ● 新規入手配列を更新するかどうか #-------------------------------------------------------------------------- alias eq_save_update_new_item? update_new_item? def update_new_item? eq_save_update_new_item? && !SceneManager.scene_is?(Scene_EqSave) end end end