#◆◇◆◇◆ ダメージ表示スクリプトVXA ver 1.00 ◇◆◇◆◇ # サポート掲示板 http://www2.ezbbs.net/21/minto-aaa/ # by みんと =begin ■ 更新履歴 ○ ver 1.00(2015/03/14) 公開 ■ 説明 VXACEのバトルシステムにダメージの表示を実装します。 本スクリプトはあくまでダメージの表示を実装するだけであり それにより、特別何かができるようになるわけではありません。 実装されるダメージは以下のとおりです。 (×表示は本スクリプトで実装されないものを指します) ○通常ダメージ ○会心ダメージ ○MPダメージ ○ステートなどの付加、解除結果 ×アクターへのダメージ ×アクターの表示 ● ダメージ画像の規格 ダメージ画像はXYピクセル共にフリーサイズです。 ただし、機械的に分割しているため 数値そのものは均等に配置している必要があります。 (詳しくはサンプル画像を参照してください) 上からA列、B列とし、以下の要素で使用しています。 A 通常ダメージ B 会心ダメージ C HP回復 D MPダメージ E MP回復 F MISS表示 独自の画像を用意される際は、少なくとも6列用意する必要があります。 ※ 画像はすべてピクチャーフォルダにインポートしてください。 =end #============================================================================== # ☆ MINTO #------------------------------------------------------------------------------ # 様々なフラグを扱うメインモジュールです。 #============================================================================== module MINTO # ダメージ表示スクリプトVXAを有効化 ( true で有効 / false で無効 ) RGSS["ダメージ表示スクリプトVXA"] = true end # ダメージ表示スクリプトVXAが有効な場合に以降の処理を実行する if MINTO::RGSS["ダメージ表示スクリプトVXA"] == true then #============================================================================== # ☆ カスタマイズ #------------------------------------------------------------------------------ # 機能のカスタマイズをここで行います。 #============================================================================== module MINTO # ダメージ用ピクチャーファイル名 Damage_P = "num" # 一列に使用するYピクセルサイズ # (画像をこのサイズで割ったものが、使用するダメージの色の数です) Damage_Size = 28 # ダメージのウェーブ間隔(フレーム) Wave_Rate = 5 end #============================================================================== # ☆ Data_States #============================================================================== module Data_States #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def self.initialize(in_battle = false) if in_battle data_states = load_data("Data/BT_States.rvdata2") else data_states = load_data("Data/States.rvdata2") end @name = [""] for state in data_states next if state == nil @name.push(state.name) end end #-------------------------------------------------------------------------- # ● ステートネーム #-------------------------------------------------------------------------- def self.name return @name end end #============================================================================== # ■ Mint_Damage_System #------------------------------------------------------------------------------ #  ピクチャー数字のスプライト表示を扱うクラスです。 # このクラスは数値の高速再描写に特化したクラスとなっています。 #============================================================================== class Mint_Damage_System #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :x # X座標 attr_reader :y # Y座標 #-------------------------------------------------------------------------- # ● オブジェクト初期化 # x : X座標 # y : Y座標 # index : 求められた行数 # z : Z座標 # size : 求められた1カラーの高さ # text : 求められたピクチャー #-------------------------------------------------------------------------- def initialize(x, y, index, z, size, text, v) text ||= MINTO::Damage_P # ピクチャーデータを読み込んで代入 @number = Cache.picture(text) # 各種データを初期化 @x = x @y = y @z = z @index = index @count = [] @viewport = v # ビットマップを作成 @text_bitmap = Bitmap.new(32, 32) @text_bitmap.font.size = 30 # クリティカル表示用スプライト @critical = Sprite.new(@viewport) @critical.visible = false @critical.bitmap = Cache.picture("critical") # カラーサイズを取得(画像の高さをsizeで割った数) collar_size = @number.rect.height / size # 読み込んだ画像の幅を10で割った値が、1文字1文字の幅になる @width = @number.rect.width / 10.0 # 読み込んだ画像の高さをカラーサイズで割った数が1カラーの高さになる height = @number.rect.height / collar_size @height = height.to_i # スプライトを収納する配列を定義 @sprite = [Sprite.new(@viewport)] # スプライト生成(求められた行数分) (0...@index).each do |i| @sprite[i] = Sprite.new(@viewport) @sprite[i].x = x.to_i + (i * @width) @sprite[i].y = y.to_i @sprite[i].z = z end # ピクチャー数字用の配列生成 @picture_number = [] # X, Y, 幅, 高さ rect = Rect.new(0, 0, @width, height) # 各カラー分のピクチャーを作成 (0...collar_size).each do |collar_index| # 配列内配列を作成 @picture_number[collar_index] = [] # 0〜9までのピクチャー数字を予め作成 (0..9).each do |i| # インデックス(i)から、 # 基本幅(@width)を掛けたところにある画像を参照する rect.x = i * @width # collar_index から # 基本高さ(height)を掛けたところにある画像を参照する rect.y = collar_index * height # Bitmapを作成 bitmap = Bitmap.new(@width, height) # ピクチャー生成 bitmap.blt(0, 0, @number, rect) # 生成したピクチャーを収納 @picture_number[collar_index][i] = bitmap end end end #-------------------------------------------------------------------------- # ● インデックスの変更 # index : 求められたインデックス #-------------------------------------------------------------------------- def set_index(index) # スプライト生成(求められた行数分) (0...index).each do |i| # すでにスプライトがある場合 if @sprite[i] != nil # 次へ next end @sprite[i] = Sprite.new(@viewport) @sprite[i].x = @x.to_i + (i * @width) @sprite[i].y = @y.to_i @sprite[i].z = @z.to_i end # インデックスを更新 @index = index end #-------------------------------------------------------------------------- # ● X座標のセット # x : 基本X座標 # damage : 求められた文字 #-------------------------------------------------------------------------- def set_x(x, damage, viewport) @viewport = viewport # 求められた文字を一文字ずつ配列にする text = damage.to_s.split(//) text -= ["-"] # 文字幅を初期化 text_width = 0 # 求められた行数分繰り返す (0...@index).each do |i| # ダメージが文字列の場合 if damage.is_a?(String) # 文字の幅を取得して加算 text_width += 32 - (@text_bitmap.text_size(text[i]).width) / 2 # X座標を調整する(左寄せ) @sprite[i].x = (-32 + x) + text_width else # X座標を調整する(左寄せ) @sprite[i].x = (x + @x.to_i) + (i * (@width - 4)) end @sprite[i].viewport = viewport end @critical.x = @sprite[0].x + 16 @critical.y = @sprite[0].y - 32 end #-------------------------------------------------------------------------- # ● X座標の変更 # n : 新しいX座標 #-------------------------------------------------------------------------- def x=(n) # X座標の変更(イテレータ) (0...@index).each{|i| @sprite[i].x = n} end #-------------------------------------------------------------------------- # ● Y座標の変更 # n : 新しいY座標 #-------------------------------------------------------------------------- def y=(n) # Y座標の変更(イテレータ) (0...@index).each{|i| @sprite[i].y = n} end #-------------------------------------------------------------------------- # ● 可視状態の取得 #-------------------------------------------------------------------------- def visible # 先頭の可視状態を返す return @sprite[0].visible end #-------------------------------------------------------------------------- # ● 内容の可視状態の変更 # flag : 新しい可視状態 #-------------------------------------------------------------------------- def visible=(flag) # 可視状態の変更(イテレータ) (0...@index).each{|i| @sprite[i].visible = flag} # クリティカルを初期化 @critical.visible = flag end #-------------------------------------------------------------------------- # ● 透明度の取得 #-------------------------------------------------------------------------- def opacity # 先頭の透明度を返す return @sprite[0].opacity end #-------------------------------------------------------------------------- # ● 透明度の変更 # opacity : 新しい透明度 #-------------------------------------------------------------------------- def opacity=(opacity) # 透明度の変更(イテレータ) (0...@index).each{|i| @sprite[i].opacity = opacity} @critical.opacity = opacity end #-------------------------------------------------------------------------- # ● クリア #-------------------------------------------------------------------------- def clear # 求められた行数分のビットマップをクリア (0...@index).each do |i| @sprite[i].bitmap = nil end end #-------------------------------------------------------------------------- # ● 文字色取得 # n : 文字色番号 (0〜7) #-------------------------------------------------------------------------- def text_color(n) case n # 強化 when 0 return Color.new(0, 255, 200) # 弱体 when 1 return Color.new(255, 0, 200) # 解除 when 2 return Color.new(0, 200, 255) when 3 return Color.new(255, 255, 255) when 4 return Color.new(128, 255, 255, 255) when 5 return Color.new(255, 128, 255, 255) when 6 return Color.new(255, 255, 128, 255) when 7 return Color.new(192, 192, 192, 255) else return Color.new(255, 255, 255) end end #-------------------------------------------------------------------------- # ● 縁文字作成 # text : 求められた文字列 # bitmap : ビットマップ # color : カラーID #-------------------------------------------------------------------------- def frame_text(text, bitmap, color) bitmap.font.size = 30 bitmap.draw_text(0, 0, 40, 40, text, 1) end #-------------------------------------------------------------------------- # ● セットストリング # string : 求められた文字列 # collar : 求められたカラーインデックス # critical : クリティカルの有無 # buff : バフの種類 #-------------------------------------------------------------------------- def set_string(string, collar, critical = false, buff = nil) # クリティカルを初期化 @critical.visible = false @critical.opacity = 255 text = [string] text -= ["-"] # 求められた文字を一文字ずつ配列にする text_size = string.to_s.split(//).size # 求められた行数分繰り返す (0...@index).each do |i| # テキストが存在しない場合 if text[i] == nil # 次の処理へ next end # X座標を調整する(左寄せ) @sprite[i].x = @x.to_i + (i * 40) # ビットマップ作成 @sprite[i].bitmap = Bitmap.new(255, 40) # 文字色を設定 @sprite[i].bitmap.font.color = text_color(buff) # 文字列を描写 @sprite[i].bitmap.draw_text(0, 0, 109, 40, text[i]) # 不可視状態に設定 @sprite[i].visible = false # 透明度を初期化 @sprite[i].opacity = 255 # カウントを設定 @count[i] = 40 @count[i] += (i * MINTO::Wave_Rate) end # クリティカルの場合 if critical @critical.z = 3000 @critical.visible = true if critical == "MP" @critical.bitmap = Cache.picture("mp_dum") end end end #-------------------------------------------------------------------------- # ● セットテキスト # number : 求められた数値 # collar : 求められたカラーインデックス # critical : クリティカルの有無 #-------------------------------------------------------------------------- def set_text(number, collar = 0, critical = false) # クリティカルを初期化 @critical.visible = false # 求められた文字を一文字ずつ配列にする text = number.to_s.split(//) text -= ["-"] # クリア行数 clear_index = text.size == 1 ? 1 : 0 # X座標を調整する x_size = @index - text.size # 求められた行数分繰り返す (0...@index).each do |i| # クリア行数が0で求められた数字が0か、 # 元の数字が存在しなければなら次へ if clear_index == 0 && text[i].to_i == 0 || text[i] == nil @sprite[i].bitmap = nil next end # X座標を調整する(右寄せ) @sprite[i].x = @x.to_i + (i * (@width - 4)) + (x_size * @width) # 条件をクリアしていれば、クリア行数に1を加算 clear_index += 1 # 条件をクリアしていれば描写 @sprite[i].bitmap = @picture_number[collar][text[i].to_i] # 不可視状態に設定 @sprite[i].visible = false # 透明度を初期化 @sprite[i].opacity = 255 @critical.opacity = 255 # カウントを設定 @count[i] = 50 @count[i] += (i * MINTO::Wave_Rate) end # クリティカルの場合 if critical @critical.z = 3000 @critical.opacity = 0 @critical.visible = true if critical == "MP" @critical.bitmap = Cache.picture("mp_dum") end end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update # スプライトのループ処理 (0...@index).each do |i| # カウントが0の場合 if @count[i].to_i == 0 # 次の処理へ next end # カウントが40以下の場合 if @count[i] <= 40 # スプライトを可視状態にする @sprite[i].visible = true # クリティカルの場合 if @critical.visible @critical.opacity = 255 end # 残りカウントに応じて分岐 case @count[i] when 36..40 @sprite[i].y -= 4 when 33..37 @sprite[i].y -= 2 when 32..34 @sprite[i].y += 2 when 25..32 @sprite[i].y += 4 end end @critical.y = @sprite[0].y - (@height + 4) # カウントを減らす @count[i] -= 1 end end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def dispose # スプライトを解放 for s in @sprite + [@critical] s.dispose s = nil end # ビットマップを解放 @text_bitmap.dispose end end #============================================================================== # ■ Game_Battler #------------------------------------------------------------------------------ #  バトラーを扱うクラスです。このクラスは Game_Actor クラスと Game_Enemy クラ # スのスーパークラスとして使用されます。 #============================================================================== class Game_Battler < Game_BattlerBase #-------------------------------------------------------------------------- # ● HP の再生 #-------------------------------------------------------------------------- alias mint_ctb_regenerate_hp regenerate_hp def regenerate_hp # 元の処理を実行 mint_ctb_regenerate_hp # 再生が発生した場合 if @result.hp_damage.to_i != 0 # ダメージを表示 @result.call_damage = true @result.call_slip_damage = true end end #-------------------------------------------------------------------------- # ● スキル/アイテムの効果適用 #-------------------------------------------------------------------------- alias mint_ctb_item_apply item_apply def item_apply(user, item) # 元の処理を実行 mint_ctb_item_apply(user, item) @result.call_damage = true end #-------------------------------------------------------------------------- # ● ステートの検査 #-------------------------------------------------------------------------- def state_include?(state) if state.is_a?(String) id = Data_States.name.index(state) else id = state end # 該当するステートが付加されていれば true を返す return @states.include?($data_states[id]) end #-------------------------------------------------------------------------- # ● 画像の高さの取得 #-------------------------------------------------------------------------- def bit_height height = Cache.battler(battler_name, battler_hue).height return height end end #============================================================================== # ■ Game_ActionResult #------------------------------------------------------------------------------ #  戦闘行動の結果を扱うクラスです。このクラスは Game_Battler クラスの内部で # 使用されます。 #============================================================================== class Game_ActionResult #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :call_damage # ダメージ呼び出しフラグ attr_accessor :call_buff # バフ表示呼び出しフラグ attr_accessor :call_slip_damage # スリップダメージ呼び出しフラグ #-------------------------------------------------------------------------- # ● バフ表示呼び出しフラグの取得 #-------------------------------------------------------------------------- def call_buff @call_buff ||= [] return @call_buff end end #============================================================================== # ■ Sprite_Battler #------------------------------------------------------------------------------ #  バトラー表示用のスプライトです。Game_Battler クラスのインスタンスを監視し、 # スプライトの状態を自動的に変化させます。 #============================================================================== class Sprite_Battler < Sprite_Base #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- alias dispose_Wave_Damage dispose def dispose # 元の処理を実行 dispose_Wave_Damage # ダメージが存在する場合 if @damage != nil # ダメージを解放 dispose_damage end end #------------------------------------------------------------------------- # ● ダメージの表示 # value : ダメージ値 # critical : クリティカルの有無 # buff : バフの種類 # index : インデックス #------------------------------------------------------------------------- def damage(value, critical, buff = nil, index = nil) # 古いダメージを解放 #dispose_damage # バトラーが不可視の場合 unless @battler_visible # メソッドを返す return end # MPダメージの場合 if critical == "MP" # 0 ダメージの場合 if value.to_i == 0 # メソッドを返す return end end # バフ表示中で無い場合 unless buff center = true else center = false end # ミスの場合 unless @battler.result.hit? # スリップダメージで無い場合 unless @battler.result.call_slip_damage # バフ表示中で無い場合 unless buff # ダメージを Miss に置き換える value = "Miss" end else @battler.result.call_slip_damage = false end end # 0 ダメージの場合 if value == 0 # メソッドを返す return end # 求められた文字を一文字ずつ配列にする text = value.to_s.split(//) text -= ["-"] v = self.viewport # 初期定義(ダメージスプライトが存在しない場合) @damage ||= [] ds = MINTO::Damage_Size # ダメージスプライトを作成 @damage.unshift(Mint_Damage_System.new(0, 0, text.size, 3000, ds, nil, v)) # インデックスのセット @damage[0].set_index(text.size) # ダメージを作成 set_damage(value, critical, text.size, buff, index) # 座標を取得 if center x = (self.x - text.size * 15) + 16 else x = (self.x - self.ox / 2) end y = 14 + (self.y - self.oy / 2 + self.viewport.rect.y) # MPダメージの場合 if critical == "MP" y += 8 # 通常ダメージの場合 else y -= 8 + @damage.size % 5 * 22 end # ダメージが Miss の場合 if value == "Miss" then # ダメージの座標をセット @damage[0].set_x(x, 1233, self.viewport) else # ダメージの座標をセット @damage[0].set_x(x, value, self.viewport) end @damage[0].y = y end #------------------------------------------------------------------------- # ● ダメージ作成 # value : ダメージ値 # critical : クリティカルの有無 # size : 文字数 # buff : バフの種類 # index : インデックス #------------------------------------------------------------------------- def set_damage(value, critical, size, buff = nil, index = nil) # MPダメージの場合 if critical == "MP" critical_effect = false else critical_effect = critical end # ダメージが文字列の場合 if value.is_a?(String) # ダメージが Miss の場合 if value == "Miss" then # 数値ダメージとして表示 @damage[0].set_text(1233, 5, false) else # ダメージをセット(文字列) @damage[0].set_string(value.to_s, 0, critical_effect, buff) end else # 通常ダメージの場合 if value.to_i >= -1 # クリティカル表示の場合 if critical == true # カラーIDをセット c = 1 # ノーマルヒットの場合 else # MPダメージで無い場合 if critical != "MP" # カラーIDをセット c = 0 # MPダメージの場合 else # カラーIDをセット c = 3 end end # 回復ダメージの場合 else # MPダメージで無い場合 if critical != "MP" # カラーIDをセット c = 2 # MPダメージの場合 else # カラーIDをセット c = 4 end end # ダメージをセット(数値) @damage[0].set_text(value, c, critical_effect) end # ダメージカウントをセット @_damage_duration ||= [] @_damage_wait ||= [] # バフ表示遅延の場合 unless index.nil? # 表示を遅らせる @_damage_wait.unshift((@damage.size * 6)) else @_damage_wait.unshift(0) end @_damage_duration.unshift(50 + (size * MINTO::Wave_Rate)) # ダメージが空文字の場合 if value == "" # ダメージカウントをリセット @_damage_duration[0] = 0 end # ダメージカウントが奇数の場合 if @_damage_duration[0] % 2 == 1 # ダメージカウントを偶数にする @_damage_duration[0] += 1 end end #------------------------------------------------------------------------- # ● ダメージ解放 #------------------------------------------------------------------------- def dispose_damage(index = nil) # インデックスが指定されている場合 if index != nil @damage[index].dispose @damage[index] = nil @_damage_duration[index] = nil @_damage_wait[index] = nil @damage.compact! @_damage_duration.compact! @_damage_wait.compact! # インデックスが指定されていない場合 else # 全ダメージを解放 for i in 0...@damage.size @damage[i].dispose end @damage = [] @_damage_duration = [] @_damage_wait = [] end end #------------------------------------------------------------------------- # ● フレーム更新(ダメージ) #------------------------------------------------------------------------- def update_damage # ダメージオブジェクトが無効な場合 if @damage.nil? # メソッドを返す return end # ダメージオブジェクトの数が1以上の場合 unless @damage.empty? # ループ処理 @damage.each_with_index do |damage, i| # ウェイトカウント中の場合 if @_damage_wait[i] >= 1 # カウントを減らす @_damage_wait[i] -= 1 # 次の処理へ next else # ダメージカウントが0の場合 if @_damage_duration[i].zero? # ダメージオブジェクトを解放 dispose_damage(i) # 次の処理へ next end # ダメージカウントを進める @_damage_duration[i] -= 1 # ダメージカウントが5以下の場合 if @_damage_duration[i] <= 5 # 透明度の配列(6段階) opacity = [0, 50, 100, 150, 200, 250] # 表示中のダメージの透明度を下げる @damage[i].opacity = opacity[@_damage_duration[i]] end # ダメージオブジェクトを更新 @damage[i].update end end end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- alias mint_ctb_update update def update # バトラーが有効な場合 unless @battler.nil? # ダメージ呼び出しが行われた場合 if @battler.result.call_damage # ダメージを表示 damage(@battler.result.hp_damage, @battler.result.critical) # ダメージを表示 damage(@battler.result.mp_damage, "MP") # ダメージ呼び出しをクリア @battler.result.call_damage = false end # バフ表示の場合 unless @battler.result.call_buff.empty? # ループ処理(バフ) for i in 0...@battler.result.call_buff.size # バフの種類を取得 buff = @battler.result.call_buff[i][0] # ループ処理(変化したパラメータ) for id in @battler.result.call_buff[i][1] # idの修理に応じて分岐 case id when RPG::State # 属性が 付加 で 戦闘不能 が対象の場合 if buff == 3 and id.id == 1 # 次へ next end # バフテキストを取得 value = id.name when nil # 次へ next else # バフテキストを取得 value = Vocab::param(id) end # ダメージとして表示 damage(value, false, buff, i) end # バフ情報をクリア @battler.result.call_buff[i] = nil end # バフ情報を詰める @battler.result.call_buff.compact! end end # 元の処理を実行 mint_ctb_update # ダメージを更新 update_damage end end #============================================================================== # ■ Window_BattleLog #------------------------------------------------------------------------------ #  戦闘の進行を実況表示するウィンドウです。枠は表示しませんが、便宜上ウィンド # ウとして扱います。 #============================================================================== class Window_BattleLog < Window_Selectable #-------------------------------------------------------------------------- # ● ステート付加の表示 #-------------------------------------------------------------------------- alias mint_atb_display_added_states display_added_states def display_added_states(target) # ステートが付加された場合 unless target.result.added_state_objects.empty? # 付加したステートの表示 target.result.call_buff.push([3, target.result.added_state_objects]) end # 元の処理を実行 mint_atb_display_added_states(target) end #-------------------------------------------------------------------------- # ● ステート解除の表示 #-------------------------------------------------------------------------- alias mint_atb_display_removed_states display_removed_states def display_removed_states(target) # ステートが解除された場合 unless target.result.removed_state_objects.empty? # 解除したステートの表示 target.result.call_buff.push([2, target.result.removed_state_objects]) end # 元の処理を実行 mint_atb_display_removed_states(target) end #-------------------------------------------------------------------------- # ● 能力強化/弱体の表示 #-------------------------------------------------------------------------- alias mint_atb_display_changed_buffs display_changed_buffs def display_changed_buffs(target) # バフが付加された場合 unless target.result.added_buffs.empty? # 付加されたバフを取得 target.result.call_buff.push([0, target.result.added_buffs]) end # デバフが付加された場合 unless target.result.added_debuffs.empty? # 付加されたデバフを取得 target.result.call_buff.push([1, target.result.added_debuffs]) end # バフが解除された場合 unless target.result.removed_buffs.empty? # 解除されたバフを取得 target.result.call_buff.push([2, target.result.removed_buffs]) end # 元の処理を実行 mint_atb_display_changed_buffs(target) end end Data_States.initialize($BTEST) end