#============================================================================== # カスタマイズポイント #============================================================================== module XRXS_MeLT # # メニューコマンド シーン/文字 # # 呼び出し方の制限を外す def self.commands commands = {"main" => ["メンバー", "コレクション", "コンフィグ", "ファイル"], "メンバー" => ["アイテム", "スキル", "装備", "ステータス"], "ファイル" => ["セーブ", "ロード", "エンド"], "アイテム" => Scene_Item, "スキル" => Scene_Skill, "装備" => Scene_Equip, "ステータス" => Scene_Status, "セーブ" => Scene_Save, "ロード" => Scene_Load, "エンド" => Scene_End} return commands end def self.captions captions = ["メンバー", "アイテム", "スキル", "装備", "ステータス", "ファイル", "セーブ", "ロード", "エンド"] return captions end def commands return XRXS_MeLT.commands end def captions return XRXS_MeLT.captions end # メニュー保存許可 SAVE_OK = true # アクター選択を用いるシーン ACTOR_INDEX_ADAPTED = [Scene_Equip, Scene_Status] class << self attr_accessor :tree end # # サイドコマンド # SIDE_KEY = nil # Input::RIGHT など キー指定で有効。nilで無効化 SIDE_SCENE = "Party" # "Party" でパーティ入れ替え, シーンも指定可 end #============================================================================== # ■ Scene_Menu #============================================================================== class Scene_Menu #-------------------------------------------------------------------------- # ● メイン処理 #-------------------------------------------------------------------------- def main # コマンドウィンドウを作成 if XRXS_MeLT.tree != nil @command_window = XRXS_MeLT.tree @command_window.slidein @command_window.active = true else @command_window = Window_MenuCommand.new(SAVE_OK) @command_window.index = @menu_index end # ステータスウィンドウを作成 @status_window = Window_MenuStatus.new # 初期化 @slideout_count= 0 @next_scene_actor_index = nil # カーソルの作成 @cursor2 = Sprite_MenuCursor.new(XRXS_MeLT::CURSOR_SKIN2) @cursor2.visible = false @cursor = Sprite_MenuCursor.new(XRXS_MeLT::CURSOR_SKIN) @sprites = [@cursor2, @cursor] # ウィンドウを作成 @windows = [] @windows.push(@command_window) @windows.push(@status_window) make_windows # トランジション実行 Graphics.transition(XRXS_MeLT::TRANS_TIME, XRXS_MeLT::TRANS_NAME) # メインループ loop do # ゲーム画面を更新 Graphics.update # 入力情報を更新 Input.update # フレーム更新 update # 画面が切り替わったらループを中断 if $scene != self break end end # トランジション準備 Graphics.freeze # ウィンドウを解放 @windows.each{|window| window.dispose } @sprites.each{|sprite| sprite.dispose } dispose_windows end #-------------------------------------------------------------------------- # ● フレーム更新 (コマンドウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_command # B ボタンが押された場合 if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) # @windows.each{|window| window.slideout! } @slideout_count = 8 @slideout_next_scene = Scene_Map $game_temp.menu_index = 0 return end # C ボタンかサイドキーが押された場合 if Input.trigger?(Input::C) or (XRXS_MeLT::SIDE_KEY != nil and Input.trigger?(XRXS_MeLT::SIDE_KEY)) # パーティ人数が 0 人で、セーブ、ゲーム終了以外のコマンドの場合 if $game_party.actors.size == 0 and @command_window.index < 4 # ブザー SE を演奏 $game_system.se_play($data_system.buzzer_se) return end # 押されたキーによってシーンを取得 if Input.trigger?(Input::C) case commands[@command_window.true_set[@command_window.index]].class when Array if @command_window.o_c[1] == "" if @command_window.tree[@command_window.true_set[@command_window.index]] == false @command_window.item_max += commands[@command_window.true_set[@command_window.index]].size @command_window.o_c = [@command_window.true_set[@command_window.index], "Open", 8] insert = @command_window.true_set.index(@command_window.o_c[0]) + 1 commands[@command_window.o_c[0]].reverse.each{|o| @command_window.true_set.insert(insert, o)} else @command_window.o_c = [@command_window.true_set[@command_window.index], "Close", 8] @command_window.true_delete(@command_window.o_c[0]) end @command_window.tree[@command_window.o_c[0]] = (@command_window.tree[@command_window.o_c[0]] == true ? false : true) end scene = nil when String eval(commands[@command_window.true_set[@command_window.index]]) scene = nil else scene = commands[@command_window.true_set[@command_window.index]] end else scene = XRXS_MeLT::SIDE_SCENE index = XRXS_MeLT.commands.index(XRXS_MeLT::SIDE_SCENE) @command_window.index = index == nil ? -1 : index end # パーティ入れ替えの場合 if scene == "Party" # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # ステータスウィンドウをアクティブにする @command_window.active = false @command_window.decide! @status_window.active = true @status_window.index = 0 return end # セーブ禁止の場合 if scene == Scene_Save and $game_system.save_disabled # ブザー SE を演奏 $game_system.se_play($data_system.buzzer_se) return end # 指定シーンへの切り替え if XRXS_MeLT::ACTOR_INDEX_ADAPTED.include?(scene) # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # ステータスウィンドウをアクティブにする @command_window.active = false @command_window.decide! @status_window.active = true @status_window.index = 0 elsif scene != nil and scene != SIDE_SCENE # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # メニューインデックスの保持 $game_temp.menu_index = @command_window.index # 画面を切り替え @windows.each{|window| window.slideout! } @slideout_count = 8 @slideout_next_scene = scene end return end end end #============================================================================== # --- XRXS. ウィンドウスライディング機構 --- #============================================================================== module XRXS_WindowSliding def initialize(x, y, w, h) super(x, y, w, h) slidein end def slidein self.contents_opacity = 0 @slidein_count = 8 @slideout_count = 0 @slide_x_speed = 8 @slide_y_speed = 0 @slide_x_limit = nil @slide_objects = [self] end end #============================================================================== # □ Window_MenuCommand #============================================================================== class Window_MenuCommand < Window_Selectable # # メニュープレート (Windowskins) # PLATE = "MenuCommandBack" # # 縁取り色 # HEMCOLOR = Color.new(64,64,0,255) # 無効化判定用 セーブ名 SAVE = "セーブ" #-------------------------------------------------------------------------- # --- インクルード --- #-------------------------------------------------------------------------- include XRXS_WindowSliding include XRXS_MeLT #-------------------------------------------------------------------------- # ○ 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :o_c # 開閉状態(この) attr_accessor :tree # 開閉状態(全部) attr_accessor :item_max # 要素数 attr_accessor :true_set # 実際の要素 #-------------------------------------------------------------------------- # ○ オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(save = true) @save = save self.cursor_height = 32 h = self.cursor_height super(-192, 0, 192, h * 10 + 32) self.x += self.width self.opacity = 0 self.contents = Bitmap.new(width - 32, h * captions.size) @plate = Sprite.new @plate.bitmap = RPG::Cache.windowskin(PLATE) @plate.x = self.x @plate.y = self.y @plate.z = self.z - 1 @plate.opacity = 0 @slide_objects.push(@plate) @item_max = commands["main"].size @s_x = self.x @s_oy = self.oy @sprites = [] @o_c =[nil, "", 0] @true_set = commands["main"] @tree = {"main" => true} commands.each{|n| if n[1].is_a?(Array) @tree[n[0]] = false end} @viewports = {"main" => Viewport_Tree.new(self.x + 16, self.y + 16, 160, self.height, self.y + self.height - 16, self.y + 16)} @viewports["main"].z = 100 tree_set("main") end #-------------------------------------------------------------------------- # ○ ツリー作成 #-------------------------------------------------------------------------- def tree_set(key, stack = 0, index = 0) commands[key].each{ |t| # コマンドを作成 s = Sprite.new(@viewports[key]) @sprites.push(s) s.x = stack * h / 2 s.y = (key == "main" ? commands[key].index(t) * h : (commands[key].index(t) - commands[key].size) * h) s.bitmap = RPG::Cache.hemtext(self.contents.text_size(t).width, h, t, 0, self.contents.color, h * 0.75, HEMCOLOR) if commands[t].is_a?(Array) @viewports[t] = Viewport_Tree.new(self.x + 16, self.y + 16 + (1 + stack + index + commands[key].index(t)) * h, 192, self.y + self.height, self.y + self.height - 16, self.y + 16) @viewports[t].rect.height -= @viewports[t].rect.y @viewports[t].z = 100 - stack # ツリーが大きすぎるとSystemStackErrorを起こしますが、そんなの作れません。 tree_set(t, stack + 1, index + commands[key].index(t)) end } end #-------------------------------------------------------------------------- # ○ フレーム更新 #-------------------------------------------------------------------------- def update super #mario sunshine # 元座標が動いた場合 if @s_x != self.x @viewports.values.each{|s| s.rect.x += (self.x - @s_x)} @s_x = self.x end if @s_oy != self.oy @viewports.values.each{|s| s.y += (@s_oy - self.oy)} @s_oy = self.oy end if @o_c[1] != "" oc_loop(@o_c[1], @o_c[0]) @o_c[2] -= 1 if @o_c[2] == 0 @o_c[1] = "" @o_c[0] = nil end end @viewports.values.each{|v| v.update} end def oc_loop(mode, parent) if commands[parent].is_a?(Array) n = next_main(parent) if mode == "Open" commands[parent].each{|c| if @tree[parent] or parent == @o_c[0] if n != nil (n...captions.size).each{|s| if @viewports[captions[s]] != nil @viewports[captions[s]].y += h / 8 end if @sprites[s].viewport == @sprites[captions.index(parent)].viewport or @sprites[s].viewport == @viewports["main"] @sprites[s].y += h / 8 end } end @sprites[captions.index(c)].y += (h / 8 * commands[parent].size) if commands[c].is_a?(Array) oc_loop(mode, c) end end } elsif mode == "Close" commands[parent].each{|c| if @tree[parent] or parent == @o_c[0] if n != nil (n...captions.size).each{|s| if @viewports[captions[s]] != nil @viewports[captions[s]].y -= h / 8 end if @sprites[s].viewport == @sprites[captions.index(parent)].viewport or @sprites[s].viewport == @viewports["main"] @sprites[s].y -= h / 8 end } end @sprites[captions.index(c)].y -= (h / 8 * commands[parent].size) if commands[c].is_a?(Array) oc_loop(mode, c) end end } end end end #-------------------------------------------------------------------------- # ○ その他メソッド #-------------------------------------------------------------------------- def next_main(main) r_end = captions.index(main) + 1 + commands[main].size for i in (captions.index(main) + 1)...captions.size return i if @sprites[i].viewport == @sprites[captions.index(main)].viewport end return (r_end != captions.size ? r_end : nil) end def true_delete(value) commands[value].each{|f| @true_set.delete(f) @item_max -= 1 if commands[f].is_a?(Array) and @tree[f] true_delete(f) end} end #-------------------------------------------------------------------------- # ○ 解放とスライド #-------------------------------------------------------------------------- def dispose if @save XRXS_MeLT.tree = self else super @plate.dispose @sprites.each{|s| s.dispose} @viewports.values.each{|s| s.dispose} end end def slidein self.contents_opacity = 0 @slidein_count = 8 @slideout_count = 0 @slide_x_speed = 24 @slide_y_speed = 0 @slide_x_limit = nil @slide_objects = [self] @slide_objects.push(@plate) if @plate != nil end def slideout! unless @save self.index = -1 end @slidein_count = 0 @slideout_count = 8 @slide_x_speed = 24 @slide_y_speed = 0 @slide_x_limit = nil @slide_objects = [self, @plate] end #-------------------------------------------------------------------------- # ○ 決定とキャンセル #-------------------------------------------------------------------------- def decide! end def cancel! end end #============================================================================== # □ Viewport_Tree #============================================================================== class Viewport_Tree < Viewport def initialize(x, yy, w, h, max = 999, min = 0) super(x, yy, w, h) @true_y = yy @true_h = h @true_oy = 0 @max = max @min = min y = y height = height end def y return @true_y end def height return @true_h end def height=(value) @true_h = value end def y=(value) @true_y = value end alias :base_oy= :oy= def oy=(value) @true_oy = value end def update self.rect.y = [@min, @true_y].max self.rect.height = [[@max - self.rect.y, @true_h].min, 1].max self.base_oy = @true_oy + [@min - @true_y, 0].max end end