#============================================================================== # ■ VXAce-RGSS3-43 メニュー画面-改3 [Ver.1.0.2] by Claimh #------------------------------------------------------------------------------ # メニュー画面を個別Window化します #============================================================================== #============================================================================== # ■ 全般設定 #============================================================================== module MenuEx3 # 縦に並べる最大個数 HMAX = 4 # 横に並べる最大個数 WMAX = 2 # キャラクター表示を使う # true : キャラクター表示 # false : 顔グラフィック表示 CHAR = true # HP/MP描画位置調整用 PX = 20 end #============================================================================== # ■ キャラクター表示設定 #------------------------------------------------------------------------------ # ●戦闘不能時のキャラクター # ・初期値 # アクターのメモ欄にて設定 # @dead_c[ファイル名, index, キャラチップ内のindex] # 例) エリック … @dead_c[Damage3,6,0] # アーネスト … @dead_c[Damage3,7,0] # ブレンダ … @dead_c[Damage4,0,3] # ・変更時 # イベントスクリプトで変更 # set_dead_c(アクターID, "ファイル名", index, キャラチップ内のindex) #------------------------------------------------------------------------------ # ●バッドステート時のキャラクター # ・初期値 # アクターのメモ欄にて設定 # @badst_c[ファイル名, index, キャラチップ内のindex] # 例) エリック … @badst_c[Damage3,6,1] #   アーネスト … @badst_c[Damage3,7,1] # ブレンダ … @badst_c[Damage4,0,4] # ・変更時 # イベントスクリプトで変更 # set_badst_c(アクターID, "ファイル名", index, キャラチップ内のindex) # ・バッドステート判定 # ステートのメモ欄にて設定 # @badst #============================================================================== module MoveActor # キャラクター向き # 2 : 正面 # 4 : 左向き # 6 : 右向き # 8 : 背面 CHAR_DIR = 2 # キャラクター動作有り(歩行) MOVE_CHAR = true # キャラクター歩行スピード MOVE_SPD = 20 end #============================================================================== # ■ MoveCharData #============================================================================== class MoveCharData #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :enabled # 有効(戦闘メンバー) attr_reader :dead # 戦闘不能 attr_reader :badst # バッドステート attr_reader :pending # 保留状態 attr_reader :pending_color # 保留状態の背景色 attr_reader :name # グラフィック ファイル名 attr_reader :index # グラフィック インデックス attr_reader :pattern # グラフィック パターン(正常時以外で使用) #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(actor, pending=false, pending_color=Color.new(0,0,0,0)) @enabled = $game_party.battle_members.include?(actor) @pending = pending @pending_color = pending_color @dead = actor.dead? @badst = actor.badst? if @dead @name = actor.dead_character_name @index = actor.dead_character_index @pattern = actor.dead_character_pattern elsif @badst @name = actor.badst_character_name @index = actor.badst_character_index @pattern = actor.badst_character_pattern self else @name = actor.character_name @index = actor.character_index @pattern = 0 end end #-------------------------------------------------------------------------- # ● 正常? #-------------------------------------------------------------------------- def st_normal? !(@dead or @badst) end end #============================================================================== # ■ MoveCharacter #============================================================================== class MoveCharacter include MoveActor CHANGE = MOVE_SPD * 4 MAX_CNT = MOVE_SPD * 4 * 4 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(bitmap, rect, character) @rect = rect # 描画範囲 @bitmap = bitmap # 描画先ビットマップ @count = MOVE_CHAR ? 0 : MOVE_SPD set_char(character) end #-------------------------------------------------------------------------- # ● キャラクター設定 #-------------------------------------------------------------------------- def set_char(character, force=false) @character = character redraw_character(force) end #-------------------------------------------------------------------------- # ● キャラクター矩形(幅、高さ) #-------------------------------------------------------------------------- def character_rect_base b = Cache.character(@character.name) sign = @character.name[/^[\!\$]./] if sign && sign.include?('$') cw = b.width / 3 ch = b.height / 4 else cw = b.width / 12 ch = b.height / 8 end Rect.new(0, 0, cw, ch) end #-------------------------------------------------------------------------- # ● キャラクター矩形 #-------------------------------------------------------------------------- def character_rect(pattern) rect = character_rect_base if @character.dead or @character.badst rect.x = (@character.index % 4 * 3 + @character.pattern % 3) * rect.width rect.y = (@character.index / 4 * 4 + @character.pattern / 3) * rect.height else rect.x = (@character.index % 4 * 3 + pattern) * rect.width rect.y = (@character.index / 4 * 4 + (CHAR_DIR - 2) / 2) * rect.height end rect end #-------------------------------------------------------------------------- # ● 背景を描画 #-------------------------------------------------------------------------- def draw_background @bitmap.fill_rect(@rect, @character.pending_color) end #-------------------------------------------------------------------------- # ● キャラクター描画 #-------------------------------------------------------------------------- def draw_character(pattern) return if @character.name == "" pattern = 1 if pattern >= 3 src_rect = character_rect(pattern) op = @character.enabled ? 255 : 160 @bitmap.blt(@rect.x, @rect.y, Cache.character(@character.name), src_rect, op) end #-------------------------------------------------------------------------- # ● キャラクター再描画 #-------------------------------------------------------------------------- def redraw_character(force=false) return if !@character.st_normal? and !force @bitmap.clear_rect(@rect) draw_background if @character.pending draw_character((@count / MOVE_SPD) % 4) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update return unless MOVE_CHAR @count = (@count + 1) % MAX_CNT redraw_character if (@count % MOVE_SPD) == 0 end end #============================================================================== # ■ Game_Actor #============================================================================== class Game_Actor < Game_Battler #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :dead_character_name # 戦闘不能グラフィック ファイル名 attr_accessor :dead_character_index # 戦闘不能グラフィック インデックス attr_accessor :dead_character_pattern # 戦闘不能グラフィック パターン attr_accessor :badst_character_name # 戦闘不能グラフィック ファイル名 attr_accessor :badst_character_index # 戦闘不能グラフィック インデックス attr_accessor :badst_character_pattern # 戦闘不能グラフィック パターン #-------------------------------------------------------------------------- # ● セットアップ #-------------------------------------------------------------------------- alias setup_move_actor setup def setup(actor_id) setup_move_actor(actor_id) setup_dead_character(actor_id) setup_badst_character(actor_id) end #-------------------------------------------------------------------------- # ● 戦闘不能グラフィック セットアップ #-------------------------------------------------------------------------- def setup_dead_character(actor_id) result = $data_actors[actor_id].note.scan(/@dead_c\[(.*?+),(\d+),(\d+)\]/i) if result.nil? or result.empty? @dead_character_name = "" @dead_character_index = @dead_character_pattern = 0 else @dead_character_name = result[0][0].to_s @dead_character_index = result[0][1].to_i @dead_character_pattern = result[0][2].to_i end end #-------------------------------------------------------------------------- # ● バッドステートグラフィック セットアップ #-------------------------------------------------------------------------- def setup_badst_character(actor_id) result = $data_actors[actor_id].note.scan(/@badst_c\[(.*?+),(\d+),(\d+)\]/i) if result.nil? or result.empty? @badst_character_name = "" @badst_character_index = @badst_character_pattern = 0 else @badst_character_name = result[0][0].to_s @badst_character_index = result[0][1].to_i @badst_character_pattern = result[0][2].to_i end end #-------------------------------------------------------------------------- # ● バッドステート? #-------------------------------------------------------------------------- def badst? states.any? {|s| s.note.include?("@badst")} end end #============================================================================== # ■ Game_Interpreter #============================================================================== class Game_Interpreter #-------------------------------------------------------------------------- # ● 戦闘不能時のキャラクター変更 #-------------------------------------------------------------------------- def set_dead_c(actor_id, name, index, pattern) actor = $game_actors[actor_id] actor.dead_character_name = name actor.dead_character_index = index actor.dead_character_pattern = pattern end #-------------------------------------------------------------------------- # ●バッドステート時のキャラクター変更 #-------------------------------------------------------------------------- def set_badst_c(actor_id, name, index, pattern) actor = $game_actors[actor_id] actor.badst_character_name = name actor.badst_character_index = index actor.badst_character_pattern = pattern end end #============================================================================== # ■ Window_MenuOneActor #============================================================================== class Window_MenuOneActor < Window_Base #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :pending # 保留状態(並び替え用) #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y, index) @offset_x = 160 @pending = false @index = index super(x, y, window_width, window_height) create_char_object if MenuEx3::CHAR end #-------------------------------------------------------------------------- # ● キャラクターオブジェクト生成 #-------------------------------------------------------------------------- def create_char_object h = contents.height - line_height char_rect = Rect.new(12, line_height + (h - 32) / 2, 32, 32) actor = $game_party.members[@index] @char = MoveCharacter.new(contents, char_rect, MoveCharData.new(actor)) end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width (Graphics.width - @offset_x) / MenuEx3::WMAX end #-------------------------------------------------------------------------- # ● ウィンドウ高さの取得 #-------------------------------------------------------------------------- def window_height Graphics.height / MenuEx3::HMAX end #-------------------------------------------------------------------------- # ● 項目の背景を描画 #-------------------------------------------------------------------------- def draw_item_background contents.fill_rect(Rect.new(0,0,contents.width,contents.height), pending_color) if @pending end #-------------------------------------------------------------------------- # ● 顔グラフィックの描画 # enabled : 有効フラグ。false のとき半透明で描画 #-------------------------------------------------------------------------- def draw_face(face_name, face_index, x, y, enabled = true) bitmap = Cache.face(face_name) h = contents.height - line_height - 4 sy = h < 96 ? ((96 - h) / 2) : 0 h = h < 96 ? h : 96 rect = Rect.new(face_index % 4 * 96, face_index / 4 * 96 + sy, 96, h) contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha) bitmap.dispose end #-------------------------------------------------------------------------- # ● 現在値/最大値を分数形式で描画 # current : 現在値 # max : 最大値 # color1 : 現在値の色 # color2 : 最大値の色 #-------------------------------------------------------------------------- def draw_current_and_max_values(x, y, width, current, max, color1, color2) change_color(color1) xr = x + width if width < 120 # 96では4桁表示でNGなので修正 draw_text(xr - 40, y, 42, line_height, current, 2) else draw_text(xr - 92, y, 42, line_height, current, 2) change_color(color2) draw_text(xr - 52, y, 12, line_height, "/", 2) draw_text(xr - 42, y, 42, line_height, max, 2) end end #-------------------------------------------------------------------------- # ● 項目の描画 #-------------------------------------------------------------------------- def refresh contents.clear actor = $game_party.members[@index] enabled = $game_party.battle_members.include?(actor) rect = Rect.new(0, 0, contents.width, contents.height) draw_item_background draw_actor_name(actor, 4, 0, rect.width - 60) draw_actor_level(actor, rect.width - 56, 0) if MenuEx3::CHAR @char.set_char(MoveCharData.new(actor, @pending, pending_color), true) x = 12 * 2 + 32 + 4 else draw_actor_face(actor, 4, line_height, enabled) x = (rect.width - 108) > 96 ? (rect.width - 96) : 102 end if (rect.height - line_height) < (line_height * 3) ic = false h = (rect.height - line_height) / 2 else ic = true h = (rect.height - line_height - 2) / 3 end x += MenuEx3::PX w = rect.width - x - 4 draw_actor_hp(actor, x, line_height + h * 0, w) draw_actor_mp(actor, x, line_height + h * 1, w) if ic draw_actor_icons(actor, x, line_height + h * 2, w) elsif MenuEx3::CHAR # CHARモードで2行表示になる場合はステートを表示しない #draw_actor_icons(actor, 0, rect.height - line_height, 100) else draw_actor_icons(actor, 0, rect.height - line_height, 100) end end #-------------------------------------------------------------------------- # ● カーソル有効/無効化 #-------------------------------------------------------------------------- def enable_cursor cursor_rect.set(Rect.new(0, 0, contents.width, contents.height)) end def disable_cursor cursor_rect.empty end #-------------------------------------------------------------------------- # ● 保留状態の更新 #-------------------------------------------------------------------------- def pending=(flag) @pending = flag refresh end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super @char.update if MenuEx3::CHAR end end #============================================================================== # ■ Window_MenuStatusEx #============================================================================== class Window_MenuStatusEx < Window_Selectable #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :pending_index # 保留位置(並び替え用) #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y) @offset_x = 160 super(x, y, window_width, window_height) create_windows self.opacity = 0 @pending_index = -1 refresh end #-------------------------------------------------------------------------- # ● オブジェクト廃棄 #-------------------------------------------------------------------------- def dispose @windows.each {|w| w.dispose} super end #-------------------------------------------------------------------------- # ● ウィンドウの表示 #-------------------------------------------------------------------------- def show @windows.each {|w| w.show} super end #-------------------------------------------------------------------------- # ● ウィンドウの非表示 #-------------------------------------------------------------------------- def hide @windows.each {|w| w.hide} super end #-------------------------------------------------------------------------- # ● 桁数の取得 #-------------------------------------------------------------------------- def col_max MenuEx3::WMAX end #-------------------------------------------------------------------------- # ● 個別ウィンドウの生成 #-------------------------------------------------------------------------- def create_windows @windows = [] w = window_width / MenuEx3::WMAX h = window_height / MenuEx3::HMAX item_max.times do |i| x = @offset_x + w * (i % MenuEx3::WMAX) y = h * (i / MenuEx3::WMAX) @windows.push(Window_MenuOneActor.new(x, y, i)) end end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width Graphics.width - @offset_x end #-------------------------------------------------------------------------- # ● ウィンドウ高さの取得 #-------------------------------------------------------------------------- def window_height Graphics.height end #-------------------------------------------------------------------------- # ● 項目数の取得 #-------------------------------------------------------------------------- def item_max $game_party.members.size end #-------------------------------------------------------------------------- # ● 項目の高さを取得 #-------------------------------------------------------------------------- def item_height (Graphics.height - standard_padding * 2) / MenuEx3::HMAX end #-------------------------------------------------------------------------- # ● 項目の描画 #-------------------------------------------------------------------------- def draw_item(index) @windows[index].refresh end #-------------------------------------------------------------------------- # ● カーソル位置の設定 #-------------------------------------------------------------------------- def index=(index) @windows[@index].disable_cursor if @index >= 0 super(index) @windows[@index].enable_cursor if @index >= 0 end #-------------------------------------------------------------------------- # ● 決定ボタンが押されたときの処理 #-------------------------------------------------------------------------- def process_ok super $game_party.menu_actor = $game_party.members[index] end #-------------------------------------------------------------------------- # ● 前回の選択位置を復帰 #-------------------------------------------------------------------------- def select_last select($game_party.menu_actor.index || 0) end #-------------------------------------------------------------------------- # ● 保留位置(並び替え用)の更新 #-------------------------------------------------------------------------- def pending_index=(index) @windows[@pending_index].pending = false if @pending_index >= 0 @pending_index = index @windows[@pending_index].pending = true if @pending_index >= 0 end #-------------------------------------------------------------------------- # ● 先頭の行の設定 #-------------------------------------------------------------------------- def top_row=(row) super(row) h = window_height / MenuEx3::HMAX item_max.times do |i| @windows[i].y = h * (i / col_max - (top_row * col_max) / col_max) end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super @windows.each {|w| w.update} end #-------------------------------------------------------------------------- # ● カーソルの更新 #-------------------------------------------------------------------------- def update_cursor super cursor_rect.empty # カーソルは表示しない end end #============================================================================== # ■ Scene_Menu #============================================================================== class Scene_Menu < Scene_MenuBase #-------------------------------------------------------------------------- # ● ステータスウィンドウの作成 #-------------------------------------------------------------------------- def create_status_window @status_window = Window_MenuStatusEx.new(@command_window.width, 0) end end