class Surume_WindowUnitCmd
  #--------------------------------------------------------------------------
  # ● コマンド挿入
  #--------------------------------------------------------------------------
  alias :srmsim_attack_set_commands :set_commands
  def set_commands
    commands = srmsim_attack_set_commands
    commands.push("攻撃")
    return commands
  end

  #--------------------------------------------------------------------------
  # ● C ボタンが押された場合
  #--------------------------------------------------------------------------
  alias :srmsim_attack_cbutton_pushed :cbutton_pushed
  def cbutton_pushed
    if srmsim_attack_cbutton_pushed == true
      return true
    end
    # コマンドウィンドウのカーソル位置で分岐
    if @commands[self.index] == "攻撃"
      # コマンドウィンドウ消去
      self.visible = false
      # 移動範囲クリア
      $game_map.move_algorythm.clear(2)
      # 選択ユニットの攻撃可能範囲計算
      selected_event = $game_map.events[$scene.pick_event_id]
      $game_map.move_algorythm.set_move_action_by_distance(selected_event.x, selected_event.y, 0, selected_event.actor.range)
      loop do
        # 敵を選択
        if $scene.select_enemy($game_map.events[$scene.pick_event_id].actor.range) == true
          enemy_id = $game_map.surume_check_event($game_player.x, $game_player.y)
          # 射程範囲内なら
          if enemy_id > 0 && $game_map.events[enemy_id].group & 7 != 0 &&
             $game_map.events[enemy_id].group & selected_event.group == 0 &&
             distance(selected_event.x, selected_event.y, $game_map.events[enemy_id].x, $game_map.events[enemy_id].y) <= selected_event.actor.range
            $game_system.se_play($data_system.decision_se)
            # 戦闘シーンに移行
            $scene.sim_battle($scene.pick_event_id, enemy_id, 0)
            return true
          end
          # 間違った選択ならエラー音を出してそのまま継続
          se = RPG::AudioFile.new("057-Wrong01")
          $game_system.se_play(se)
        # キャンセルなら
        else
          # 表示を移動範囲へ
          $game_map.move_algorythm.set_move_action_by_move(selected_event.actor.range)
          $game_map.move_algorythm.clear(0xfffd)
          # ユニットウィンドウ表示
          self.visible = true
          return false
        end
      end
    end
  end
end

#==============================================================================
# ■ Spriteset_Battle
#------------------------------------------------------------------------------
#    バトルバックスプライトを1つ追加
#==============================================================================

class Spriteset_SimBattle
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_reader   :viewport1                # エネミー側のビューポート
  attr_reader   :viewport2                # アクター側のビューポート
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize
    # ビューポートを作成
    @viewport1 = Viewport.new(0, 0, 640, 320)
    @viewport2 = Viewport.new(0, 0, 640, 480)
    @viewport3 = Viewport.new(0, 0, 640, 480)
    @viewport4 = Viewport.new(0, 0, 640, 480)
    #@viewport2.z = 101
    @viewport3.z = 200
    @viewport4.z = 5000
    # バトルバックスプライトを作成
    @battleback_sprite = Sprite.new(@viewport1)
    @battleback_sprite1 = Sprite.new(@viewport1)
    @battleback_sprite1.x = 320
    # 防御側スプライトを作成
    @enemy_sprites = []
    if $sim_actor[1] != $sim_actor[0]
      @enemy_sprites.push(Sprite_Battler.new(@viewport1, $sim_actor[1]))
    end
    # 攻撃側スプライトを作成
    @actor_sprites = []
    @actor_sprites.push(Sprite_Battler.new(@viewport2, $sim_actor[0]))
    # 天候を作成
    @weather = RPG::Weather.new(@viewport1)
    # ピクチャスプライトを作成
    @picture_sprites = []
    for i in 51..100
      @picture_sprites.push(Sprite_Picture.new(@viewport3,
        $game_screen.pictures[i]))
    end
    # タイマースプライトを作成
    @timer_sprite = Sprite_Timer.new
    # フレーム更新
    update
  end
  #--------------------------------------------------------------------------
  # ● 解放
  #    追加された敵用のバトルバックスプライトの解放を追加
  #--------------------------------------------------------------------------
  def dispose
    # バトルバックビットマップが存在していたら解放
    if @battleback_sprite.bitmap != nil
      @battleback_sprite.bitmap.dispose
    end
    # 攻撃側バトルバックスプライトを解放
    @battleback_sprite.dispose
    # バトルバックビットマップが存在していたら解放
    if @battleback_sprite1.bitmap != nil
      @battleback_sprite1.bitmap.dispose
    end
    # 防御側バトルバックスプライトを解放
    @battleback_sprite1.dispose
    # エネミースプライト、アクタースプライトを解放
    for sprite in @enemy_sprites + @actor_sprites
      sprite.dispose
    end
    # 天候を解放
    @weather.dispose
    # ピクチャスプライトを解放
    for sprite in @picture_sprites
      sprite.dispose
    end
    # タイマースプライトを解放
    @timer_sprite.dispose
    # ビューポートを解放
    @viewport1.dispose
    @viewport2.dispose
    @viewport3.dispose
    @viewport4.dispose
  end
  #--------------------------------------------------------------------------
  # ● エフェクト表示中判定
  #    Spriteset_SimBattleと全く同じ
  #--------------------------------------------------------------------------
  def effect?
    # エフェクトが一つでも表示中なら true を返す
    for sprite in @enemy_sprites + @actor_sprites
      return true if sprite.effect?
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #    バトルバックスプライトを分割して2枚表示
  #--------------------------------------------------------------------------
  def update
    # アクタースプライトの内容を更新 (アクターの入れ替えに対応)
    @actor_sprites[0].battler = $sim_actor[0]
    # バトルバックのファイル名が現在のものと違う場合
    if @battleback_name != $game_temp.battleback_name
      @battleback_name = $game_temp.battleback_name
      # 攻撃側バトルバックを更新
      if @battleback_sprite.bitmap != nil
        @battleback_sprite.bitmap.dispose
      end
      @battleback_sprite.bitmap = RPG::Cache.battleback(@battleback_name)
      @battleback_sprite.src_rect.set(320, 0, 320, 320)
      # 防御側バトルバックを更新
      if @battleback_sprite1.bitmap != nil
        @battleback_sprite1.bitmap.dispose
      end
      @battleback_sprite1.bitmap = RPG::Cache.battleback(@battleback_name)
      @battleback_sprite1.src_rect.set(0, 0, 320, 320)
    end
    # バトラースプライトを更新
    for sprite in @enemy_sprites + @actor_sprites
      sprite.update
    end
    # 天候グラフィックを更新
    @weather.type = $game_screen.weather_type
    @weather.max = $game_screen.weather_max
    @weather.update
    # ピクチャスプライトを更新
    for sprite in @picture_sprites
      sprite.update
    end
    # タイマースプライトを更新
    @timer_sprite.update
    # 画面の色調とシェイク位置を設定
    @viewport1.tone = $game_screen.tone
    @viewport1.ox = $game_screen.shake
    # 画面のフラッシュ色を設定
    @viewport4.color = $game_screen.flash_color
    # ビューポートを更新
    @viewport1.update
    @viewport2.update
    @viewport4.update
  end
end

#==============================================================================
# ■ Window_BattleStatus
#------------------------------------------------------------------------------
#  バトル画面でパーティメンバーのステータスを表示するウィンドウです。
#==============================================================================

class Window_SimBattleStatus < Window_Base
  attr_reader   :y                     # Y座標
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化(同じ)
  #--------------------------------------------------------------------------
  def initialize
    super(0, 320, 640, 160)
    self.contents = Bitmap.new(width - 32, height - 32)
    @level_up_flags = [false, false, false, false]
    refresh
  end
  #--------------------------------------------------------------------------
  # ● 解放(同じ)
  #--------------------------------------------------------------------------
  def dispose
    super
  end
  #--------------------------------------------------------------------------
  # ● レベルアップフラグの設定(同じ)
  #     actor_index : アクターインデックス
  #--------------------------------------------------------------------------
  def level_up(actor_index)
    @level_up_flags[actor_index] = true
  end
  #--------------------------------------------------------------------------
  # ● パラメータの描画
  #     actor : アクター
  #     x     : 描画先 X 座標
  #     y     : 描画先 Y 座標
  #     type  : パラメータの種類 (0〜6)
  #     パラメータの表示位置を枠に収まるよう変更
  #--------------------------------------------------------------------------
  def draw_actor_parameter(actor, x, y, type)
    case type
    when 0
      parameter_name = $data_system.words.atk
      parameter_value = actor.atk
    when 1
      parameter_name = $data_system.words.pdef
      parameter_value = actor.pdef
    when 2
      parameter_name = $data_system.words.mdef
      parameter_value = actor.mdef
    when 3
      parameter_name = $data_system.words.str
      parameter_value = actor.str
    when 4
      parameter_name = $data_system.words.dex
      parameter_value = actor.dex
    when 5
      parameter_name = $data_system.words.agi
      parameter_value = actor.agi
    when 6
      parameter_name = $data_system.words.int
      parameter_value = actor.int
    end
    self.contents.font.color = system_color
    self.contents.draw_text(x, y, 100, 32, parameter_name)
    self.contents.font.color = normal_color
    self.contents.draw_text(x + 100, y, 36, 32, parameter_value.to_s, 2)
  end
  #--------------------------------------------------------------------------
  # ● リフレッシュ
  #    攻撃側は武器名表示、防御側は鎧名表示
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    @item_max = $sim_actor.size
    for i in 0...$sim_actor.size
      actor = $sim_actor[i]
      actor_x = (1 - i) * 320 + 4
      draw_actor_name(actor, actor_x, 0)
      # 攻撃側は武器名表示
      if i == 0
        draw_item_name($data_weapons[actor.weapon_id], actor_x + 120, 0)
        draw_actor_parameter(actor, actor_x + 32 + 116, 32, 0)
      # 防御側は鎧名表示
      else
        draw_item_name($data_armors[actor.armor3_id], actor_x + 120, 0)
        draw_actor_parameter(actor, actor_x + 32 + 116, 32, 1)
      end
      draw_actor_hp(actor, actor_x, 32, 120)
      draw_actor_sp(actor, actor_x, 64, 120)
      if @level_up_flags[i]
        self.contents.font.color = normal_color
        self.contents.draw_text(actor_x, 96, 120, 32, "LEVEL UP!")
      else
        draw_actor_state(actor, actor_x, 96)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新(同じ)
  #--------------------------------------------------------------------------
  def update
    super
    # メインフェーズのときは不透明度をやや下げる
    if $game_temp.battle_main_phase
      self.contents_opacity -= 4 if self.contents_opacity > 191
    else
      self.contents_opacity += 4 if self.contents_opacity < 255
    end
  end
end

#==============================================================================
# ■ Scene_SimBattle
#------------------------------------------------------------------------------
#  バトルイベント用インタプリタ、トループ削除
#   アクターコマンドウィンドウ、パーティコマンドウィンドウ削除
#==============================================================================

class Scene_SimBattle
  #--------------------------------------------------------------------------
  # ● メイン処理
  #--------------------------------------------------------------------------
  def main
    # 戦闘用の各種一時データを初期化
    $game_temp.in_battle = true
    $game_temp.battle_turn = 0
    $game_temp.battle_event_flags.clear
    $game_temp.battle_abort = false
    $game_temp.battle_main_phase = false
    $game_temp.battleback_name = $game_map.battleback_name
    $game_temp.forcing_battler = nil

    @help_window = Window_Help.new
    @help_window.back_opacity = 160
    @help_window.visible = false
    @status_window = Window_SimBattleStatus.new
    @message_window = Window_Message.new
    # スプライトセットを作成
    @spriteset = Spriteset_SimBattle.new
    # ウェイトカウントを初期化
    @wait_count = 0
    # トランジション実行
    if $data_system.battle_transition == ""
      Graphics.transition(20)
    else
      Graphics.transition(40, "Graphics/Transitions/" +
        $data_system.battle_transition)
    end
    # バトルフェーズ4から開始
    start_phase4
    # メインループ
    loop do
      # ゲーム画面を更新
      Graphics.update
      # 入力情報を更新
      Input.update
      # フレーム更新
      update
      # 画面が切り替わったらループを中断
      if $scene != self
        break
      end
    end
    # マップをリフレッシュ
    $game_map.refresh
    # トランジション準備
    Graphics.freeze
    # ウィンドウを解放
    @help_window.dispose
    @status_window.dispose
    @message_window.dispose
    # スプライトセットを解放
    @spriteset.dispose
  end
  #--------------------------------------------------------------------------
  # ● バトル終了
  #     result : 結果 (0:勝利 1:敗北 2:逃走)
  #--------------------------------------------------------------------------
  def battle_end(result)
    # 戦闘中フラグをクリア
    $game_temp.in_battle = false
    # パーティ全員のアクションをクリア
    #$game_party.clear_actions
    # バトル用ステートを解除
    #for actor in $game_party.actors
    #  actor.remove_states_battle
    #end
    # エネミーをクリア
    #$game_troop.enemies.clear
    # バトル コールバックを呼ぶ
    if $game_temp.battle_proc != nil
      $game_temp.battle_proc.call(result)
      $game_temp.battle_proc = nil
    end
    # マップ画面に切り替え
    $scene = Scene_Map.new
  end
  #--------------------------------------------------------------------------
  # ● アフターバトルフェーズ開始
  #--------------------------------------------------------------------------
  def start_phase5
    # フェーズ 5 に移行
    @phase = 5
    # バトル終了 ME を演奏
    #$game_system.me_play($game_system.battle_end_me)
    # バトル開始前の BGM に戻す
    #$game_system.bgm_play($game_temp.map_bgm)
    # EXP、ゴールド、トレジャーを初期化
    exp = 0
    gold = 0
    treasures = []
    # EXP 獲得
    for i in 0...1
      actor = $sim_actor[i]
      if actor.cant_get_exp? == false
        last_level = actor.level
        exp = actor.add_exp
        actor.exp += actor.add_exp
        if actor.level > last_level
          @status_window.level_up(i)
        end
      end
    end
    # バトルリザルトウィンドウを作成
    @result_window = Window_BattleResult.new(exp, gold, treasures)
    # ウェイトカウントを設定
    @phase5_wait_count = -1
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (アフターバトルフェーズ)
  #--------------------------------------------------------------------------
  def update_phase5
    # ウェイトカウントが 0 より大きい場合
    if @phase5_wait_count < 0
      # リザルトウィンドウを表示
      @result_window.visible = true
      # メインフェーズフラグをクリア
      $game_temp.battle_main_phase = false
      # ステータスウィンドウをリフレッシュ
      @status_window.refresh
      @phase5_wait_count = 50
      return
    end
    # ウェイトカウントを減らす
    @phase5_wait_count -= 1
    # ウェイトカウントが 0 になった場合、または C ボタンが押された場合
    if @phase5_wait_count == 0 || Input.trigger?(Input::C)
      # リザルトウィンドウを非表示
      @result_window.visible = false
      # バトル終了
      battle_end(0)
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  def update
    # システム (タイマー)、画面を更新
    $game_system.update
    $game_screen.update
    # ウィンドウを更新
    @help_window.update
    @status_window.update
    @message_window.update
    # スプライトセットを更新
    @spriteset.update
    # トランジション処理中の場合
    if $game_temp.transition_processing
      # トランジション処理中フラグをクリア
      $game_temp.transition_processing = false
      # トランジション実行
      if $game_temp.transition_name == ""
        Graphics.transition(20)
      else
        Graphics.transition(40, "Graphics/Transitions/" +
          $game_temp.transition_name)
      end
    end
    # メッセージウィンドウ表示中の場合
    if $game_temp.message_window_showing
      return
    end
    # エフェクト表示中の場合
    if @spriteset.effect?
      return
    end
    # ウェイト中の場合
    if @wait_count > 0
      # ウェイトカウントを減らす
      @wait_count -= 1
      return
    end
    # アクションを強制されているバトラーが存在せず、
    # かつバトルイベントが実行中の場合
    if $game_temp.forcing_battler == nil and
       $game_system.battle_interpreter.running?
      return
    end
    # フェーズによって分岐
    case @phase
    when 1  # プレバトルフェーズ
      update_phase1
    when 2  # パーティコマンドフェーズ
      update_phase2
    when 3  # アクターコマンドフェーズ
      update_phase3
    when 4  # メインフェーズ
      update_phase4
    when 5  # アフターバトルフェーズ
      update_phase5
    end
  end
  #--------------------------------------------------------------------------
  # ● メインフェーズ開始
  #    ターン数削除
  #--------------------------------------------------------------------------
  def start_phase4
    # フェーズ 4 に移行
    @phase = 4

    # アクターを非選択状態に設定
    # @actor_index = -1
    @active_battler = nil
    # メインフェーズフラグをセット
    $game_temp.battle_main_phase = true
    # エネミーアクション作成(反撃入れるならここに反撃方法?)
    #for enemy in $game_troop.enemies
    #  enemy.make_action
    #end
    # 行動順序作成
    make_action_orders
    # ステップ 1 に移行
    @phase4_step = 1
  end
  #--------------------------------------------------------------------------
  # ● 行動順序作成
  #--------------------------------------------------------------------------
  def make_action_orders
    # 配列 @action_battlers を初期化
    @action_battlers = [$sim_actor[0]]
    #@action_battlers = [$sim_actor[0], $sim_actor[1]]
    end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ)(同じ)
  #--------------------------------------------------------------------------
  def update_phase4
    case @phase4_step
    when 1
      update_phase4_step1
    when 2
      update_phase4_step2
    when 3
      update_phase4_step3
    when 4
      update_phase4_step4
    when 5
      update_phase4_step5
    when 6
      update_phase4_step6
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 1 : アクション準備)
  #    アクション強制、スリップダメージなど削除
  #--------------------------------------------------------------------------
  def update_phase4_step1
    # ヘルプウィンドウを隠す
    @help_window.visible = false
    # 未行動バトラーが存在しない場合 (全員行動した)
    if @action_battlers.size == 0
      # 戦闘終了
      start_phase5
      return
    end
    # アニメーション ID およびコモンイベント ID を初期化
    @animation1_id = 0
    @animation2_id = 0
    @common_event_id = 0
    # 未行動バトラー配列の先頭からシフト
    @active_battler = @action_battlers.shift
    # すでに戦闘から外されている場合(反撃があれば必要?)
    #if @active_battler.index == nil
    #  return
    #end
    # ステータスウィンドウをリフレッシュ
    @status_window.refresh
    # ステップ 2 に移行
    @phase4_step = 2
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 2 : アクション開始)
  #    アクション強制削除
  #    事前に計算されたHPを代入
  #--------------------------------------------------------------------------
  def update_phase4_step2
    # 対象バトラーをクリア
    @target_battlers = []
    # アクションの種別で分岐
    case @active_battler.current_action.kind
    when 0  # 基本
      make_basic_action_result
    when 1  # スキル
      make_skill_action_result
    when 2  # アイテム
      make_item_action_result
    end
    # 事前に計算されたHPを代入
    $sim_actor[1].hp = $sim_actor[1].new_hp
    # ステップ 3 に移行
    if @phase4_step == 2
      @phase4_step = 3
    end
  end
  #--------------------------------------------------------------------------
  # ● 基本アクション 結果作成
  #    いろいろ削除
  #--------------------------------------------------------------------------
  def make_basic_action_result
    # 攻撃の場合
      # アニメーション ID を設定
      @animation1_id = @active_battler.animation1_id
      @animation2_id = @active_battler.animation2_id
      # 対象側バトラーの配列を設定
      @target_battlers = [$sim_actor[1]]
      return
  end
  #--------------------------------------------------------------------------
  # ● スキルアクション 結果作成
  #    強制アクション削除
  #    SP減少、スキルの効果削除(マップ画面で行っているため)
  #--------------------------------------------------------------------------
  def make_skill_action_result
    # スキルを取得
    @skill = $data_skills[@active_battler.current_action.skill_id]
    # ステータスウィンドウをリフレッシュ
    @status_window.refresh
    # ヘルプウィンドウにスキル名を表示
    @help_window.set_text(@skill.name, 1)
    # アニメーション ID を設定
    @animation1_id = @skill.animation1_id
    @animation2_id = @skill.animation2_id
    # 対象側バトラーの配列を設定
    @target_battlers = [$sim_actor[1]]
  end
  #--------------------------------------------------------------------------
  # ● アイテムアクション 結果作成
  #    アイテム減少、効果削除(マップ画面で行っているため)
  #--------------------------------------------------------------------------
  def make_item_action_result
    # アイテムを取得
    @item = $data_items[@active_battler.current_action.item_id]
    # ヘルプウィンドウにアイテム名を表示
    @help_window.set_text(@item.name, 1)
    # アニメーション ID を設定
    @animation1_id = @item.animation1_id
    @animation2_id = @item.animation2_id
    # 対象側バトラーの配列を設定
    @target_battlers = [$sim_actor[1]]
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 3 : 行動側アニメーション)(同じ)
  #--------------------------------------------------------------------------
  def update_phase4_step3
    # 行動側アニメーション (ID が 0 の場合は白フラッシュ)
    if @animation1_id == 0
      @active_battler.white_flash = true
    else
      @active_battler.animation_id = @animation1_id
      @active_battler.animation_hit = true
    end
    # ステップ 4 に移行
    @phase4_step = 4
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 4 : 対象側アニメーション)(同じ)
  #--------------------------------------------------------------------------
  def update_phase4_step4
    # 対象側アニメーション
    for target in @target_battlers
      target.animation_id = @animation2_id
      target.animation_hit = (target.damage != "Miss")
    end
    # アニメーションの長さにかかわらず、最低 8 フレーム待つ
    @wait_count = 8
    # ステップ 5 に移行
    @phase4_step = 5
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 5 : ダメージ表示)(同じ)
  #--------------------------------------------------------------------------
  def update_phase4_step5
    # ヘルプウィンドウを隠す
    @help_window.visible = false
    # ステータスウィンドウをリフレッシュ
    @status_window.refresh
    # ダメージ表示
    for target in @target_battlers
      if target.damage != nil
        target.damage_pop = true
      end
    end
    # ステップ 6 に移行
    @phase4_step = 6
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 6 : リフレッシュ)(同じ)
  #--------------------------------------------------------------------------
  def update_phase4_step6
    # アクション強制対象のバトラーをクリア
    $game_temp.forcing_battler = nil
    # コモンイベント ID が有効の場合
    if @common_event_id > 0
      # イベントをセットアップ
      common_event = $data_common_events[@common_event_id]
      $game_system.battle_interpreter.setup(common_event.list, 0)
    end
    # ステップ 1 に移行
    @phase4_step = 1
  end
end

#==============================================================================
# ■ Game_Character
#==============================================================================

class Game_Character
  #--------------------------------------------------------------------------
  # ● 攻撃された方向へ向きなおす
  #     x : 攻撃された X 座標
  #     y : 攻撃された Y 座標
  #--------------------------------------------------------------------------
  def turn_pos(sx, sy)
    if y < @y && @y - y >= (x - @x).abs
      turn_up
    elsif y > @y && y - @y >= (x - @x).abs
      turn_down
    elsif x > @x && x - @x >= (y - @y).abs
      turn_right
    elsif x < @x && @x - x >= (y - @y).abs
      turn_left
    end
  end
end

#==============================================================================
# ■ Sprite_Battler
#------------------------------------------------------------------------------
#  敵バトラーをフェードインせず、最初から表示します。
#==============================================================================

class Sprite_Battler < RPG::Sprite
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     viewport : ビューポート
  #     battler  : バトラー (Game_Battler)
  #--------------------------------------------------------------------------
  alias :srmsim_initialize :initialize
  def initialize(viewport, battler = nil)
    srmsim_initialize(viewport, battler)
    @battler_visible = true
  end
end

#==============================================================================
# ■ Game_Actor
#------------------------------------------------------------------------------
#   新しい変数を用意
#==============================================================================

class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_reader   :exp_list                 # 必要EXP
  attr_accessor :new_hp                   # 戦闘シーン用
  attr_accessor :add_exp                  # 戦闘終了後足される経験値
  #--------------------------------------------------------------------------
  # ● インデックス取得
  #--------------------------------------------------------------------------
  def index
    return $sim_actor.index(self)
  end
  #--------------------------------------------------------------------------
  # ● バトル画面 X 座標の取得
  #--------------------------------------------------------------------------
  def screen_x
    # パーティ内の並び順から X 座標を計算して返す
    if self.index != nil
      return 480 - self.index * 320
    else
      return 0
    end
  end
  #--------------------------------------------------------------------------
  # ● バトル画面 Y 座標の取得
  #--------------------------------------------------------------------------
  def screen_y
    return 304
    #return 464
  end
  #--------------------------------------------------------------------------
  # ● バトル画面 Z 座標の取得
  #--------------------------------------------------------------------------
  def screen_z
    # パーティ内の並び順から Z 座標を計算して返す
    if self.index != nil
      return 4 - self.index
    else
      return 0
    end
  end
end

#==============================================================================
# ■ Scene_Map
#==============================================================================

class Scene_Map
  #--------------------------------------------------------------------------
  # ● 攻撃
  #--------------------------------------------------------------------------
  def sim_battle(attack_id, defence_id, skill_id)
    attack = $game_map.events[attack_id]
    defence = $game_map.events[defence_id]
    # カーソルを動かす
    $game_player.moveto(defence.x, defence.y)
    attack.turn_pos(defence.x, defence.y)
    defence.turn_pos(attack.x, attack.y)
    $sim_actor = []
    $sim_actor[0] = attack.actor
    $sim_actor[1] = defence.actor
    oldhp = defence.actor.hp
    if skill_id == 0
      # 通常攻撃
      attack.actor.current_action.kind = 0
      attack.actor.current_action.basic = 0
      defence.actor.attack_effect(attack.actor)
      if (attack.group & 1) != 0
        exp = $sim_actor[1].exp_list[$sim_actor[1].level+1] - $sim_actor[1].exp_list[$sim_actor[1].level]
        if $sim_actor[1].hp == 0
          $sim_actor[0].add_exp = exp
        else
          dmg = $sim_actor[1].damage != "Miss" ? $sim_actor[1].damage : 0
          $sim_actor[0].add_exp = dmg * exp / $sim_actor[1].maxhp
        end
      end
    elsif skill_id > 0
      # スキル
      attack.actor.current_action.kind = 1
      defence.actor.skill_effect(attack.actor, $data_skills[skill_id])
      $sim_actor[0].current_action.kind = 1
      $sim_actor[0].current_action.skill_id = skill_id
    else
      # アイテム
      attack.actor.current_action.kind = 2
      defence.actor.item_effect($data_items[-skill_id])
      $sim_actor[0].current_action.kind = 2
      $sim_actor[0].current_action.item_id = -skill_id
    end
    #$sim_actor[1].damage = oldhp - $sim_actor[1].hp
    $sim_actor[1].new_hp = $sim_actor[1].hp
    $sim_actor[1].hp = oldhp
    attack.actor.current_action.target_index = defence_id
    # トランジション準備
    Graphics.freeze
    @simstatus_window.dispose
    # スプライトセットを解放
    @spriteset.dispose
    # メッセージウィンドウを解放
    @message_window.dispose
    scene = $scene
    # バトル画面に切り替え
    $scene = Scene_SimBattle.new
    $scene.main
    $scene = scene

    @spriteset = Spriteset_Map.new
    # メッセージウィンドウを作成
    @message_window = Window_Message.new
    # ステータスウィンドウを作成
    @simstatus_window = Window_SimStatus.new
    # トランジション実行
    Graphics.transition
    # やられたユニットをマップ上から消去
    if defence.actor.hp == 0
      $game_map.events.delete defence_id
      @spriteset.dispose
      @spriteset = Spriteset_Map.new
    end
    # プレイヤーユニットを攻撃した
    if attack.trigger == 2 && defence.group & 1
      attack.start
    end
    # プレイヤーユニットに攻撃された
    if defence.trigger == 1 && attack.group & 1
      defence.start
    end
  end
end