# ▽▽▽ XRXSv2. メッセージ表示フルグレードアップVX ▽▽▽ # # publish 2010/ 3/ 2 # update - 11/ 1/10a # #============================================================================== # カスタマイズポイント #============================================================================== class Window_Message < Window_Selectable # # 基本行数 # MAX_LINE = 4 # # \p[] - キャラポップの高さ # CHARPOP_HEIGHT = 40 # # \name[] - 名前枠 X,Y座標 # NAME_WINDOW_OFFSET_X = 0 NAME_WINDOW_OFFSET_Y = -24 end #============================================================================== # 参照機能 #============================================================================== class Game_Temp attr_accessor :last_gain_material attr_accessor :last_gain_holder end #============================================================================== # フルグレードアップベース - 制御文字・基本機能 #============================================================================== class Window_Message < Window_Selectable #-------------------------------------------------------------------------- # ● 特殊文字の変換 + 準備 #-------------------------------------------------------------------------- alias xrxsv2_convert_special_characters convert_special_characters def convert_special_characters # 初期化 contents.font.size = Font.default_size contents.font.bold = Font.default_italic contents.font.italic = Font.default_bold contents.font.shadow = Font.default_shadow @type_wait = 0 @line_widths = [] @line_aligns = [] self.pop_character = nil # ウィンドウ保持指定\holdがあるか? @window_hold = (@text.gsub!(/\\hold/) { "" } != nil) # \info @info_mode = (@text.gsub!(/\\info/) { "" } != nil) # 改行削除指定\_があるか? if (/\\_(.*?)\x00/.match(@text)) != nil $game_message.choice_start -= 1 @text.gsub!(/\\_(.*?)\x00/) { $1.to_s } end # \name 判定 if @text.sub!(/\\[Nn]ame\[(.*?)\]/) { "" } name = $1 bitmap = @name_sprite.bitmap w = [bitmap.text_size(name).width, 1].max bitmap.dispose @name_sprite.bitmap = Bitmap.new(w, 32) bitmap = @name_sprite.bitmap bitmap.draw_text(0, 0, bitmap.width, bitmap.height, name) @name_window.width = w + 16 @name_window.create_contents @name_window.openness = 0 @name_window.open @name_window.visible = true @name_sprite.visible = true else @name_window.visible = false @name_sprite.visible = false @name_sprite.bitmap.dispose @name_sprite.bitmap = Bitmap.new(32,32) end # キャラボップモード if @text.gsub!(/\\[Pp]\[-1\]/) { "" } self.pop_character = -1 elsif @text.gsub!(/\\[Pp]\[([0-9]+)\]/) { "" } self.pop_character = $1.to_i elsif @text.gsub!(/\\[Pp]/) { "" } self.pop_character = 0 end # 制御文字処理 xrxsv2_convert_special_characters @text.gsub!(/\\[Ss]\[([0-9]+)\]/i) { "\x11[#{$1}]" } @text.gsub!(/\\size\[([0-9]+)\]/i) { "\x12[#{$1}]" } @text.gsub!(/\\[Oo]\[([0-9]+)\]/i) { "\x13[#{$1}]" } @text.gsub!(/\\icon\[([0-9]+)\]/i) { "\x17[#{$1}]" } @text.gsub!(/\\last_holder/i) { "\x18" } @text.gsub!(/\\last_material/i) { "\x19" } @text.gsub!(/\\B/) { "\x14" } @text.gsub!(/\\I/) { "\x15" } @text.gsub!(/\\D/) { "\x16" } @text.gsub!(/\\n/) { "\x00" } # # ライン情報の取得 rxs = ["\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08", /\[([0-9]+)\]/, "\x11","\x12","\x13","\x14", "\x15", "\x16", "\x17", "\x18","\x19"] lines = @text.split("\x00") @lines_max = lines.size for i in 0...@lines_max line = lines[i] for rx in rxs line.gsub!(rx) {""} end @line_aligns[i] = line.sub!(/\\center/) {""} ? CENTER : line.sub!(/\\right/) {""} ? RIGHT : AUTO # 行の横幅の取得と設定 cx = contents.text_size(line).width @line_widths[i] = cx end # 位置揃え制御文字の削除 @text.gsub!(/\\center/) {""} @text.gsub!(/\\right/) {""} # キャラポップ時のウィンドウリサイズ reszie_window_for_pop end #-------------------------------------------------------------------------- # ● メッセージの更新 * #-------------------------------------------------------------------------- def update_message @wait_count = @type_wait loop do c = @text.slice!(/./m) case update_message_type(c) when 1 break when 2 next end break unless @show_fast or @line_show_fast end end #-------------------------------------------------------------------------- # 一文字の描画 (返り値 1:break, 2:next) #-------------------------------------------------------------------------- def update_message_type(c) case c when nil # 描画すべき文字がない finish_message # 更新終了 return 1 when "\x00" # 改行 new_line max = MAX_LINE max = 14 if self.pop_character != nil if @line_count >= max # 行数が最大のとき unless @text.empty? # さらに続きがあるなら self.pause = true # 入力待ちを入れる return 1 end end when "\x01" # \C[n] (文字色変更) @text.sub!(/\[([0-9]+)\]/, "") contents.font.color = text_color($1.to_i) return 2 when "\x11" # \s[n] (スピード変更) @text.sub!(/\[([0-9]+)\]/, "") @type_wait = $1.to_i return 2 when "\x12" # \size @text.sub!(/\[([0-9]+)\]/, "") contents.font.size = $1.to_i return 2 when "\x13" # \O @text.sub!(/\[([0-9]+)\]/, "") contents.font.color.alpha = $1.to_i return 2 when "\x02" # \G (所持金表示) @gold_window.refresh @gold_window.open when "\x03" # \. (ウェイト 1/4 秒) @wait_count = 15 return 1 when "\x04" # \| (ウェイト 1 秒) @wait_count = 60 return 1 when "\x05" # \! (入力待ち) self.pause = true return 1 when "\x06" # \> (瞬間表示 ON) @line_show_fast = true when "\x07" # \< (瞬間表示 OFF) @line_show_fast = false when "\x08" # \^ (入力待ちなし) @pause_skip = true when "\x14" #\B contents.font.bold ^= true when "\x15" #\I contents.font.italic ^= true when "\x16" #\D contents.font.shadow ^= true when "\x17" @text.sub!(/\[([0-9]+)\]/, "") draw_icon($1.to_i, @contents_x, @contents_y) @contents_x += 24 when "\x18" name = ($game_temp.last_gain_holder.name rescue "") update_message_type_draw_at(name) when "\x19" item = ($game_temp.last_gain_material.item rescue nil) draw_item_name(item, @contents_x, @contents_y) @contents_x += 196 else # 普通の文字 update_message_type_draw_at(c) end return 0 end def update_message_type_draw_at(c) return if c.to_s.size == 0 c_width = contents.text_size(c).width c_height = contents.text_size(c).height contents.draw_text(@contents_x, @contents_y - (c_height - WLH) / 2, c_width, c_height, c) @contents_x += c_width end #-------------------------------------------------------------------------- # ● 改ページ処理 #-------------------------------------------------------------------------- alias xrxsv2_new_page new_page def new_page xrxsv2_new_page update_charpop_window end #-------------------------------------------------------------------------- # ● 改行処理 #-------------------------------------------------------------------------- alias xrxsv2_new_line new_line def new_line xrxsv2_new_line set_align end #-------------------------------------------------------------------------- # 位置揃え #-------------------------------------------------------------------------- def set_align w = @line_widths[@line_count].to_i a = @line_aligns[@line_count] case a when CENTER @contents_x = @contents_x + ((contents.width - @contents_x) - w) / 2 when RIGHT @contents_x = contents.width - w end end #-------------------------------------------------------------------------- # ● メッセージの終了 #-------------------------------------------------------------------------- alias xrxsv2_terminate_message terminate_message def terminate_message xrxsv2_terminate_message process_hold end #-------------------------------------------------------------------------- # 定数 #-------------------------------------------------------------------------- AUTO = 0 LEFT = 1 CENTER = 2 RIGHT = 3 end #============================================================================== # アクティブイベント取得 #============================================================================== class Game_Interpreter attr_reader :event_id end #============================================================================== # 各種機能の追加 - キャラポップ/ネーム/ホールド #============================================================================== class Window_Message < Window_Selectable #-------------------------------------------------------------------------- # ● カーソルの更新 * #-------------------------------------------------------------------------- def update_cursor if @index >= 0 x = ($game_message.face_name.empty? ? 0 : 112) y = ($game_message.choice_start + @index) * WLH - 1 w = contents.width - x if self.pop_character != nil x += 28 w -= 20 end self.cursor_rect.set(x, y, w, WLH) else self.cursor_rect.empty end end #-------------------------------------------------------------------------- # キャラクターの取得 # parameter : パラメータ #-------------------------------------------------------------------------- def get_character(parameter) # パラメータで分岐 case parameter when -1 # プレイヤー return $game_player when 0 # 現在アクティブなイベント id = $game_map.interpreter.event_id events = $game_map.events return events == nil ? nil : events[id] else # 特定のイベント events = $game_map.events return events == nil ? nil : events[parameter] end end #-------------------------------------------------------------------------- # (メッセージ終了時)ホールドの処理 #-------------------------------------------------------------------------- def process_hold if @window_hold @held_windows.push(Window_Copy.new(self)) @held_windows.push(Window_Copy.new(@name_window)) @held_windows.push(Sprite_Copy.new(@name_sprite)) @held_windows.push(Sprite_Copy.new(@back_sprite)) for sprite in @extra_sprites next if sprite.disposed? @held_windows.push(Sprite_Copy.new(sprite)) end @extra_sprites.clear self.openness = 0 @name_window.openness = 0 @back_sprite.visible = false else @held_windows.each {|object| object.dispose} @held_windows.clear end @name_window.close @name_sprite.visible = false end #-------------------------------------------------------------------------- # キャラポップ位置の設定と取得 #-------------------------------------------------------------------------- def pop_character=(character_id) @pop_character = character_id end def pop_character return @pop_character end #-------------------------------------------------------------------------- # キャラポップ時のウィンドウリサイズ #-------------------------------------------------------------------------- def reszie_window_for_pop if self.pop_character != nil max_x = @line_widths.max.to_i n = max_x + 32 n += $game_message.face_name.empty? ? 0 : 122 m = $game_message.face_name.empty? ? 0 : 96 w = @name_sprite.bitmap.width self.width = [n, w].max self.height = [@lines_max * WLH, m].max + 32 create_contents update_charpop_window elsif @info_mode @line_aligns[0] = CENTER self.x = - 8 self.width = Graphics.width + 16 self.height = 56 create_contents else self.x = 0 self.width = Graphics.width self.height = MAX_LINE * WLH + 32 create_contents end end #-------------------------------------------------------------------------- # ● 背景スプライトの作成 #-------------------------------------------------------------------------- alias xrxsv2_create_back_sprite create_back_sprite def create_back_sprite xrxsv2_create_back_sprite @back_sprite.zoom_x = 1.0 * Graphics.width / @back_sprite.bitmap.width @name_window = Window_Base.new(0,0,112,36) @name_window.visible = false @name_sprite = Sprite.new @name_sprite.bitmap = Bitmap.new(32,32) @name_sprite.visible = false self.x = self.x self.y = self.y self.z = self.z @held_windows = [] @extra_sprites = [] end #-------------------------------------------------------------------------- # ● 背景スプライトの解放 #-------------------------------------------------------------------------- alias xrxsv2_dispose_back_sprite dispose_back_sprite def dispose_back_sprite xrxsv2_dispose_back_sprite @name_window.dispose @name_sprite.dispose for window in @held_windows window.dispose end end #-------------------------------------------------------------------------- # ● 背景スプライトの更新 #-------------------------------------------------------------------------- alias xrxsv2_update_back_sprite update_back_sprite def update_back_sprite @name_window.update xrxsv2_update_back_sprite update_charpop_window end #-------------------------------------------------------------------------- # ウィンドウの位置と不透明度の設定 (キャラポップ) #-------------------------------------------------------------------------- def update_charpop_window if self.pop_character character = get_character(self.pop_character) return if character == nil # [X座標] n = self.width / 2 n = [n, @name_skin.width + 16].max if @current_name != nil w = @name_sprite.bitmap.width x = character.screen_x - [[n, w].max, self.width - 32].min # [Y座標] case @position when 0 y = character.screen_y - CHARPOP_HEIGHT - self.height else y = character.screen_y + 16 end x_max = Graphics.width - 4 - self.width x_min = 4 y_max = Graphics.height - self.height y_min = 4 self.x = [[x, x_max].min, x_min].max self.y = [[y, y_max].min, y_min].max end end #-------------------------------------------------------------------------- # 位置の連動 #-------------------------------------------------------------------------- def x=(n) super if @name_window @name_window.x = n + NAME_WINDOW_OFFSET_X @name_sprite.x = n + NAME_WINDOW_OFFSET_X + 8 end end def y=(n) super if @name_window @name_window.y = n + NAME_WINDOW_OFFSET_Y @name_sprite.y = n + NAME_WINDOW_OFFSET_Y + 2 end end def z=(n) super if @name_window @name_window.z = n + 1 @name_sprite.z = n + 2 end end end #============================================================================== # 伸縮対応 #============================================================================== class Window_Message < Window_Selectable #-------------------------------------------------------------------------- # ● ウィンドウの背景と位置の設定 [再定義] #-------------------------------------------------------------------------- def reset_window @background = $game_message.background @position = $game_message.position if @background == 0 # 通常ウィンドウ self.opacity = 255 else # 背景を暗くする、透明にする self.opacity = 0 end case @position when 0 # 上 self.y = 0 @gold_window.y = 360 when 1 # 中 self.y = (Graphics.height - self.height) / 2 @gold_window.y = 0 when 2 # 下 self.y = Graphics.height - self.height @gold_window.y = 0 end end end #============================================================================== # □ Window_Copy #------------------------------------------------------------------------------ # 指定のウィンドウのコピーを作成します。 #============================================================================== class Window_Copy < Window_Base #-------------------------------------------------------------------------- # ○ オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(window) super(window.x, window.y, window.width, window.height) self.contents = window.contents.dup unless window.contents.nil? self.opacity = window.opacity self.back_opacity = window.back_opacity self.z = window.z - 3 self.visible = window.visible end end #============================================================================== # □ Sprite_Copy #------------------------------------------------------------------------------ # 指定のスプライトのコピーを作成します。 #============================================================================== class Sprite_Copy < Sprite #-------------------------------------------------------------------------- # ○ オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(sprite) super() self.bitmap = sprite.bitmap.dup unless sprite.bitmap.nil? self.opacity = sprite.opacity self.x = sprite.x self.y = sprite.y self.z = sprite.z - 3 self.ox = sprite.ox self.oy = sprite.oy self.zoom_x = sprite.zoom_x self.visible = sprite.visible end end