module RPG #============================================================================== # ■ ガードフラグに対応 #============================================================================== class Sprite < ::Sprite def damage(value, critical, guard, critical_hit = 0) dispose_damage if value.is_a?(Numeric) damage_string = value.abs.to_s else damage_string = value.to_s end bitmap = Bitmap.new(160, 60) bitmap.font.name = "Arial Black" bitmap.font.size = 32 bitmap.font.color.set(0, 0, 0) bitmap.draw_text(-1, 24-1, 160, 36, damage_string, 1) bitmap.draw_text(+1, 24-1, 160, 36, damage_string, 1) bitmap.draw_text(-1, 24+1, 160, 36, damage_string, 1) bitmap.draw_text(+1, 24+1, 160, 36, damage_string, 1) if value.is_a?(Numeric) and value < 0 bitmap.font.color.set(176, 255, 144) else bitmap.font.color.set(255, 255, 255) end bitmap.draw_text(0, 24, 160, 36, damage_string, 1) if critical bitmap.font.size = 20 bitmap.font.color.set(0, 0, 0) bitmap.draw_text(-1, 14-1, 160, 20, "WEAK", 1) bitmap.draw_text(+1, 14-1, 160, 20, "WEAK", 1) bitmap.draw_text(-1, 14+1, 160, 20, "WEAK", 1) bitmap.draw_text(+1, 14+1, 160, 20, "WEAK", 1) bitmap.font.color.set(255, 255, 255) bitmap.draw_text(0, 14, 160, 20, "WEAK", 1) end if guard bitmap.font.size = 20 bitmap.font.color.set(0, 0, 0) bitmap.draw_text(-1, 14-1, 160, 20, "GUARD", 1) bitmap.draw_text(+1, 14-1, 160, 20, "GUARD", 1) bitmap.draw_text(-1, 14+1, 160, 20, "GUARD", 1) bitmap.draw_text(+1, 14+1, 160, 20, "GUARD", 1) bitmap.font.color.set(255, 255, 255) bitmap.draw_text(0, 14, 160, 20, "GUARD", 1) end if critical or guard hosei = 0 else hosei = 14 end case critical_hit when 1 bitmap.font.size = 20 bitmap.font.color.set(0, 0, 0) bitmap.draw_text(-1, hosei-1, 160, 20, "NICE!", 1) bitmap.draw_text(+1, hosei-1, 160, 20, "NICE!", 1) bitmap.draw_text(-1, hosei+1, 160, 20, "NICE!", 1) bitmap.draw_text(+1, hosei+1, 160, 20, "NICE!", 1) bitmap.font.color.set(255, 255, 255) bitmap.draw_text(0, hosei, 160, 20, "NICE!", 1) when 2 bitmap.font.size = 20 bitmap.font.color.set(0, 0, 0) bitmap.draw_text(-1, hosei-1, 160, 20, "GREAT!", 1) bitmap.draw_text(+1, hosei-1, 160, 20, "GREAT!", 1) bitmap.draw_text(-1, hosei+1, 160, 20, "GREAT!", 1) bitmap.draw_text(+1, hosei+1, 160, 20, "GREAT!", 1) bitmap.font.color.set(255, 255, 255) bitmap.draw_text(0, hosei, 160, 20, "GREAT!", 1) when 3 bitmap.font.size = 20 bitmap.font.color.set(0, 0, 0) bitmap.draw_text(-1, hosei-1, 160, 20, "CRITICAL!", 1) bitmap.draw_text(+1, hosei-1, 160, 20, "CRITICAL!", 1) bitmap.draw_text(-1, hosei+1, 160, 20, "CRITICAL!", 1) bitmap.draw_text(+1, hosei+1, 160, 20, "CRITICAL!", 1) bitmap.font.color.set(255, 255, 255) bitmap.draw_text(0, hosei, 160, 20, "CRITICAL!", 1) end @_damage_sprite = ::Sprite.new(self.viewport) @_damage_sprite.bitmap = bitmap @_damage_sprite.ox = 80 @_damage_sprite.oy = 20 @_damage_sprite.x = self.x @_damage_sprite.y = self.y - self.oy / 2 - 24 @_damage_sprite.z = 3000 @_damage_duration = 40 end end end #============================================================================== # ■ Game_Battler #------------------------------------------------------------------------------ #  バトラーを扱うクラスです。このクラスは Game_Actor クラスと Game_Enemy クラ # スのスーパークラスとして使用されます。 #============================================================================== class Game_Battler #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :critical_hit # クリティカル段階 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- alias critical_orig_initialize initialize def initialize critical_orig_initialize @critical_hit = 0 end #-------------------------------------------------------------------------- # ● スキルの効果適用 # user : スキルの使用者 (バトラー) # skill : スキル #-------------------------------------------------------------------------- def skill_effect(user, skill, attacker_d = 0, target_d = 0) # クリティカルフラグをクリア self.critical = false # ガードフラグをクリア self.guard = false # クリティカル段階をクリア self.critical_hit = 0 # 向き効果を設定 # 全体魔法と自分自身の時は向き効果を無効化 if skill.scope == 2 or skill.scope == 4 or skill.scope == 7 d_rate = direction_effect(attacker_d, target_d, true) else d_rate = direction_effect(attacker_d, target_d) end # スキルの効果範囲が HP 1 以上の味方で、自分の HP が 0、 # またはスキルの効果範囲が HP 0 の味方で、自分の HP が 1 以上の場合 if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or ((skill.scope == 5 or skill.scope == 6) and self.hp >= 1) # メソッド終了 return false end # 有効フラグをクリア effective = false # コモンイベント ID が有効の場合は有効フラグをセット effective |= skill.common_event_id > 0 # 第一命中判定 hit = skill.hit if skill.atk_f > 0 hit *= user.hit / 100 hit -= self.eva * skill.eva_f / 100 end hit_result = (rand(100) < hit) # 不確実なスキルの場合は有効フラグをセット effective |= hit < 100 # 命中の場合 if hit_result == true # 威力を計算 power = skill.power + user.atk * skill.atk_f / 100 if power > 0 power -= self.pdef * skill.pdef_f / 200 power -= self.mdef * skill.mdef_f / 200 power = [power, 0].max end # 倍率を計算 rate = 20 rate += (user.str * skill.str_f / 100) rate += (user.dex * skill.dex_f / 100) rate += (user.agi * skill.agi_f / 100) rate += (user.int * skill.int_f / 100) # 基本ダメージを計算 self.damage = power * rate / 20 self.damage = self.damage * d_rate / 100 if self.damage > 0 self.damage = self.damage * offset(true) / 10 # クリティカル修正 if critical_user and self.damage > 0 criti = 25 * user.dex / self.agi criti = criti * skill.dex_f / 100 criti_hit = rand(100) if criti_hit < criti / 6 self.damage *= 2 self.critical_hit = 3 else if criti_hit < criti / 2 self.damage += self.damage / 2 self.critical_hit = 2 else if criti_hit < criti self.damage += self.damage / 4 self.critical_hit = 1 end end end end # 属性修正 rate = elements_correct(skill.element_set) if rate > 100 # クリティカルフラグをセット self.critical = true elsif rate < 100 # ガードフラグをセット self.guard = true end self.damage *= rate self.damage /= 100 # ダメージの符号が正の場合 if self.damage > 0 # 防御修正 if self.guarding? self.damage /= 2 end end # 分散 if skill.variance > 0 and self.damage.abs > 0 amp = [self.damage.abs * skill.variance / 100, 1].max self.damage += rand(amp+1) + rand(amp+1) - amp end # 第二命中判定 eva = 8 * self.agi / user.dex hit = self.damage < 0 ? 100 : ((100 - eva * (200 - d_rate) / 100 * skill.eva_f / 100) * offset(false)) hit = self.cant_evade? ? 100 : hit hit_result = (rand(100) < hit) # 不確実なスキルの場合は有効フラグをセット effective |= hit < 100 end # 命中の場合 if hit_result == true # 威力 0 以外の物理攻撃の場合 if skill.power != 0 and skill.atk_f > 0 # ステート衝撃解除 remove_states_shock # 有効フラグをセット effective = true end # HP からダメージを減算 last_hp = self.hp self.hp -= self.damage effective |= self.hp != last_hp # カウンター判定 counter = 0 for state_id in self.states # 存在しない時は無視 unless $data_states[state_id] == nil effect = self.states_new_effect(state_id) counter = effect[6] break if counter > 0 end end # カウンターダメージ if counter > 0 and self.damage > 0 counter_damege = self.damage * counter / 100 user.damage = 0 if user.damage == nil or user.damage == "Miss" or user.damage == "" user.damage += counter_damege end # 追加のステータスを呼び出し add_status = return_add_status(skill) # HP吸収(カウンターダメージを逆転する) hp_drain = add_status[7] if hp_drain > 0 counter_damege = self.damage * hp_drain / 100 user.damage = 0 if user.damage == nil or user.damage == "Miss" or user.damage == "" user.damage -= counter_damege end # ステート変化 @state_changed = false effective |= states_plus(skill.plus_state_set) effective |= states_minus(skill.minus_state_set) # 威力が 0 の場合 if skill.power == 0 # ダメージに空文字列を設定 self.damage = "" # ステートに変化がない場合 unless @state_changed # ダメージに "Miss" を設定 self.damage = "Miss" self.critical = false self.guard = false self.critical_hit = 0 end end # ミスの場合 else # ダメージに "Miss" を設定 self.damage = "Miss" self.critical = false self.guard = false self.critical_hit = 0 end # 戦闘中でない場合 unless $game_temp.in_battle # ダメージに nil を設定 self.damage = nil end # メソッド終了 return effective end end #============================================================================== # ■ Sprite_Character #------------------------------------------------------------------------------ #  キャラクター表示用のスプライトです。Game_Character クラスのインスタンスを # 監視し、スプライトの状態を自動的に変化させます。 # また、透過表示の機能も定義しています。 #============================================================================== class Sprite_Character < RPG::Sprite #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super # 戦闘中、かつバトラーがnilでない if $game_temp.in_battle and @battler != nil # タイル ID、ファイル名、色相のどれかが現在のものと異なる場合 if @tile_id != @character.tile_id or @character_name != @character.character_name or @character_hue != @character.character_hue or @battler_name != @battler.battler_name or @battler_hue != @battler.battler_hue or @battler_moving != @battler.moving # タイル ID とファイル名、色相を記憶 @tile_id = @character.tile_id @character_name = @character.character_name @character_hue = @character.character_hue @battler_name = @battler.battler_name @battler_hue = @battler.battler_hue @battler_moving = @battler.moving # タイル ID が有効な値の場合 if @tile_id >= 384 self.bitmap = RPG::Cache.tile($game_map.tileset_name, @tile_id, @character.character_hue) self.src_rect.set(0, 0, 32, 32) self.ox = 16 self.oy = 32 # タイル ID が無効な値の場合 else if @battler.wait_graphic and not @battler.moving self.bitmap = RPG::Cache.character(@battler.battler_name + "_w", @battler.battler_hue) else self.bitmap = RPG::Cache.character(@battler.battler_name, @battler.battler_hue) end @cw = bitmap.width / 4 @ch = bitmap.height / 4 self.ox = @cw / 2 self.oy = @ch # 戦闘不能または隠れ状態なら不透明度を 0 にする if @battler.dead? or @battler.hidden self.opacity = 0 @mini_hp_sprite.visible = false end end end else # タイル ID、ファイル名、色相のどれかが現在のものと異なる場合 if @tile_id != @character.tile_id or @character_name != @character.character_name or @character_hue != @character.character_hue # タイル ID とファイル名、色相を記憶 @tile_id = @character.tile_id @character_name = @character.character_name @character_hue = @character.character_hue # タイル ID が有効な値の場合 if @tile_id >= 384 self.bitmap = RPG::Cache.tile($game_map.tileset_name, @tile_id, @character.character_hue) self.src_rect.set(0, 0, 32, 32) self.ox = 16 self.oy = 32 # タイル ID が無効な値の場合 else self.bitmap = RPG::Cache.character(@character.character_name, @character.character_hue) @cw = bitmap.width / 4 @ch = bitmap.height / 4 self.ox = @cw / 2 self.oy = @ch end end end if $game_temp.in_battle and @battler != nil # ステートアニメーションが設定されている場合 if @battler.state_animation_id > 0 # アニメーション ID が現在のものと異なる場合 if @battler.damage == nil and @battler.state_animation_id != @state_animation_id @state_animation_id = @battler.state_animation_id loop_animation($data_animations[@state_animation_id]) end else # 詠唱中の場合 if @battler.charge_time > 0 loop_animation($data_animations[CHARGE_ANIME]) @charge_anime = true else if @charge_anime loop_animation(nil) @charge_anime = false end # アニメーション ID が現在のものと異なる場合 if @battler.damage == nil and @battler.state_animation_id != @state_animation_id @state_animation_id = @battler.state_animation_id loop_animation($data_animations[@state_animation_id]) end end end # 明滅 if @battler.blink blink_on else blink_off end # 不可視の場合 unless @battler_visible # 出現 if not @battler.hidden and not @battler.dead? and @battler.damage == nil appear @battler_visible = true @mini_hp_sprite.set_actor(@battler) @mini_hp_sprite.last_hp = @battler.hp end # 復活 if not @battler.hidden and not @battler.dead? and @battler.damage_pop appear @battler_visible = true end end # 可視の場合 if @battler_visible # 逃走 if @battler.hidden $game_system.se_play($data_system.escape_se) escape @battler_visible = false end # 白フラッシュ if @battler.white_flash whiten @battler.white_flash = false end # アニメーション if @battler.animation_id != 0 if @battler.animation_wait > 0 @battler.animation_wait -= 1 else animation = $data_animations[@battler.animation_id] animation(animation, @battler.animation_hit) @battler.animation_id = 0 end end # ダメージ if @battler.damage_pop unless @battler.damage == "" damage(@battler.damage, @battler.critical, @battler.guard, @battler.critical_hit) @mini_hp_sprite.visible = true @mini_hp_sprite.damage = @battler.damage @mini_hp_sprite.wait = 26 end @battler.damage = nil @battler.critical = false @battler.guard = false @battler.damage_pop = false end # コラプス if @battler.damage == nil and @battler.dead? if @battler.is_a?(Game_Enemy) $game_system.se_play($data_system.enemy_collapse_se) else $game_system.se_play($data_system.actor_collapse_se) end collapse @battler_visible = false @mini_hp_sprite.last_hp = 0 end # ミニHPバー更新 @mini_hp_sprite.update end else # 可視状態を設定 self.visible = (not @character.transparent) end # グラフィックがキャラクターの場合 if @tile_id == 0 # 転送元の矩形を設定 sx = @character.pattern * @cw sy = (@character.direction - 2) / 2 * @ch self.src_rect.set(sx, sy, @cw, @ch) end # スプライトの座標を設定 self.x = @character.screen_x self.y = @character.screen_y self.z = @character.screen_z(@ch) @mini_hp_sprite.x = self.x @mini_hp_sprite.y = self.y @mini_hp_sprite.z = self.z + 3000 # 不透明度、合成方法、茂み深さを設定 if $game_temp.in_battle if @battler != nil self.bush_depth = @character.bush_depth else# self.opacity = 255# self.blend_type = 0# self.visible = true# end else self.opacity = @character.opacity self.blend_type = @character.blend_type self.bush_depth = @character.bush_depth # アニメーション if @character.animation_id != 0 animation = $data_animations[@character.animation_id] animation(animation, true) @character.animation_id = 0 end end end end class Game_Actor < Game_Battler #-------------------------------------------------------------------------- # ● 補正 # クリティカルがアクターのみ発動するようにする。 #-------------------------------------------------------------------------- def critical_user return false end end class Game_Enemy < Game_Battler #-------------------------------------------------------------------------- # ● ダメージ補正 # 同上 #-------------------------------------------------------------------------- def critical_user return true end end