Permanent
Creation

RPGツクールXP/VX用のRGSS素材です。
一部英語版対応です。 (A few materials can be used for English RPG MAKER XP/VX.)
競合率はルファーの独断と偏見なのでたまにハズレます。


スクリーンショット
↑スクリーンショット (クリックで拡大)
#==============================================================================
# ■ ダブルプレイヤーモード
#------------------------------------------------------------------------------
#  2 つのデータを読み込んで対戦するシーンクラスの定義です。
# ゲーム内で使うには、 $scene = Scene_DoublePlayersLoad.new というスクリプトを
# どこかに挿入する必要があります。
# (C) ルファー
# HP  https://tkoolerlufar.pages.dev/
#==============================================================================

=begin
  =対応RGSS
  1

  =他の素材との競合の可能性
  !!! 戦闘システム変更系素材との相性が悪い

  =導入方法
  Scene_Fileより下に新セクションを作成して、このプログラムをそこにコピーする

  =設定の変更方法。
  項目の説明を見て目的の項目を探し、
  半角の「=」の横に値を入れます。
  「整数」        と書かれている場合・・・項目ごとに指定された範囲の整数を
                       そのまま半角で入力
  「文字列」      と書かれている場合・・・半角の二重引用符("←これ)の中に
                       任意の文字列を入力
                      (ただし半角の二重引用符は入れられない)
                       二重引用符の中の文字列は全角でも良い
  「シーンクラス」と書かれている場合・・・名前が「Scene_」で始まるクラスの
                      クラス名を入力
                      「.new」は不要
  「真偽」  と書かれている場合・・・tureで真(ON)、falseで偽(OFF)
                    もちろん半角

  =項目の説明。
  バトル BGM ファイル名 (文字列)
    ・・・バトル画面で使用するBGMのファイル名を指定します。
  バトル BGM ボリューム (整数)
    ・・・バトル画面で使用するBGMのボリュームを指定します。
  バトル BGM ピッチ (整数)
    ・・・バトル画面で使用するBGMのピッチを指定します。
  戻り先の画面 (シーンクラス)
    ・・・ダブルプレイヤーモードから抜ける時に切り替わる画面のシーンクラスを
       指定します。
  MaxHP 上昇フラグ (真偽)
    ・・・真にするとMaxHPが「通常のMaxHP×(レベル+1)+99」になります。

  =更新履歴
  2010/04/13 「セーブデータのチェック」と併用時、
             ロード時に強制終了するバグを修正
  2008/04/16 分割ダウンロードの Scene_Xxxx クラスをさらに分割
             注釈の記述が誤っているのを修正
             1P側で再生される、"位置"が[画面]に設定された
             アニメーションが下にズレるバグを修正
             MaxHP上昇の有無を設定可能にした
  2008/03/27 フラグがリセットされない致命的バグ修正
             ダブルプレイヤーモード時のMaxHPが、
             「通常のMaxHP×(レベル+1)+99」になるよう仕様変更
  2008/02/28 公開

  =再定義しているメソッド
  Game_Temp#initialize (エイリアス使用)
  Game_Actor#initialize (エイリアス使用)
  Game_Actor#index (エイリアス使用)
  Game_Actor#maxhp (エイリアス使用)
  Game_Actor#skill_can_use?

  =新規定義しているメソッド
  Game_Actor#player_index (プロパティ)
=end
#----------------------------------------------------------------------------
# ◆ Lfer モジュール
#----------------------------------------------------------------------------
module Lfer
  #--------------------------------------------------------------------------
  # ● 素材ユーザーによる設定項目 (実体は定数)
  #--------------------------------------------------------------------------
  name = "004-Battle04"                   # バトル BGM ファイル名
  volume = 100                            # バトル BGM ボリューム
  pitch = 100                             # バトル BGM ピッチ
  DP_BATTLE_BGM = RPG::AudioFile.new(name, volume, pitch)
  DP_END_SCENE = Scene_Title              # 戻り先の画面
  DP_MHP = true                           # MaxHP 上昇フラグ
end
#----------------------------------------------------------------------------
# ◆ Game_Temp クラス
#----------------------------------------------------------------------------
class Game_Temp
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :doubleplayers_mode       # ダブルプレイヤーモードフラグ
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  alias lfr4_old_init initialize
  def initialize
    lfr4_old_init
    @doubleplayers_mode = false
  end
end
#----------------------------------------------------------------------------
# ◆ Game_Actor クラス
#----------------------------------------------------------------------------
class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :player_index             # プレイヤーインデックス
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     actor_id    : アクター ID
  #--------------------------------------------------------------------------
  alias lfr4_old_init initialize
  def initialize(actor_id)
    @player_index = nil
    lfr4_old_init(actor_id)
  end
  #--------------------------------------------------------------------------
  # ● インデックス取得
  #     player_index : プレイヤーインデックス
  #--------------------------------------------------------------------------
  alias lfr4_old_index index
  def index
    if @player_index != nil
      $game_doubleplayers[@player_index].actors.index(self)
    else
      lfr4_old_index
    end
  end
  #--------------------------------------------------------------------------
  # ● MaxHP の取得
  #--------------------------------------------------------------------------
  alias lfr4_old_maxhp maxhp
  def maxhp
    n = lfr4_old_maxhp
    $game_temp.doubleplayers_mode && Lfer::DP_MHP ? n * (@level + 1) + 99 : n
  end
  #--------------------------------------------------------------------------
  # ● スキルの使用可能判定
  #     skill_id : スキル ID
  #--------------------------------------------------------------------------
  def skill_can_use?(skill_id)
    if not skill_learn?(skill_id)
      return false
    end
    if $data_skills[skill_id].common_event_id > 0 and
       $game_temp.doubleplayers_mode
      return false
    end
    return super
  end
end
#----------------------------------------------------------------------------
# ◆ Game_DoublePlayers クラス
#----------------------------------------------------------------------------
class Game_DoublePlayers < Game_Party
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     game_actors  : アクターのゲームデータ
  #     game_party   : パーティのゲームデータ
  #     player_index : プレイヤーインデックス
  #--------------------------------------------------------------------------
  def initialize(game_actors, game_party, player_index)
    @game_actors = game_actors
    @actors = game_party.actors
    @player_index = player_index
    for actor in @actors
      actor.player_index = @player_index
    end
  end
  #--------------------------------------------------------------------------
  # ● パーティメンバーのリフレッシュ
  #--------------------------------------------------------------------------
  def refresh
    new_actors = []
    for i in 0...@actors.size
      if $data_actors[@actors[i].id] != nil
        new_actors.push(@game_actors[@actors[i].id])
      end
    end
    @actors = new_actors
    for actor in @actors
      actor.player_index = @player_index
    end
  end
  #--------------------------------------------------------------------------
  # ● 全滅判定
  #--------------------------------------------------------------------------
  def all_dead?
    if @actors.size == 0
      return false
    end
    for actor in @actors
      if actor.hp > 0
        return false
      end
    end
    return true
  end
end
#----------------------------------------------------------------------------
# ◆ Sprite_DoublePlayers クラス
#----------------------------------------------------------------------------
class Sprite_DoublePlayers < RPG::Sprite
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :battler                  # バトラー
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     viewport     : ビューポート
  #     player_index : プレイヤーインデックス
  #     battler      : バトラー (Game_Battler)
  #--------------------------------------------------------------------------
  def initialize(viewport, player_index, battler = nil)
    super(viewport)
    @battler = battler
    @battler_visible = false
    @player_index = player_index
  end
  #--------------------------------------------------------------------------
  # ● 解放
  #--------------------------------------------------------------------------
  def dispose
    if self.bitmap != nil
      self.bitmap.dispose
    end
    super
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  def update
    super
    if @battler == nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end
    if @battler.battler_name != @battler_name or
       @battler.battler_hue != @battler_hue
      @battler_name = @battler.battler_name
      @battler_hue = @battler.battler_hue
      self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
      @width = bitmap.width
      @height = bitmap.height
      self.ox = @width / 2
      self.oy = @height
      if @battler.dead? or @battler.hidden
        self.opacity = 0
      end
    end
    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
    if @battler.is_a?(Game_Actor) and @battler_visible
      if $game_temp.battle_main_phase
        self.opacity += 3 if self.opacity < 255
      else
        self.opacity -= 3 if self.opacity > 207
      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 or @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
        animation = $data_animations[@battler.animation_id]
        animation(animation, @battler.animation_hit)
        @battler.animation_id = 0
      end
      if @battler.damage_pop
        damage(@battler.damage, @battler.critical)
        @battler.damage = nil
        @battler.critical = 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
      end
    end
    self.x = @battler.screen_x
    self.y = @player_index == 0 ? @battler.screen_y - 160 : @battler.screen_y
    self.z = @battler.screen_z
  end
  #--------------------------------------------------------------------------
  # ● アニメーションスプライトのセット
  #--------------------------------------------------------------------------
  def animation_set_sprites(sprites, cell_data, position)
    for i in 0..15
      sprite = sprites[i]
      pattern = cell_data[i, 0]
      if sprite == nil or pattern == nil or pattern == -1
        sprite.visible = false if sprite != nil
        next
      end
      sprite.visible = true
      sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192)
      if position == 3
        if self.viewport != nil
          sprite.x = self.viewport.rect.width / 2
          sprite.y = self.viewport.rect.height - (@player_index == 0 ? 320 :
            160)
        else
          sprite.x = 320
          sprite.y = 240
        end
      else
        sprite.x = self.x - self.ox + self.src_rect.width / 2
        sprite.y = self.y - self.oy + self.src_rect.height / 2
        sprite.y -= self.src_rect.height / 4 if position == 0
        sprite.y += self.src_rect.height / 4 if position == 2
      end
      sprite.x += cell_data[i, 1]
      sprite.y += cell_data[i, 2]
      sprite.z = 2000
      sprite.ox = 96
      sprite.oy = 96
      sprite.zoom_x = cell_data[i, 3] / 100.0
      sprite.zoom_y = cell_data[i, 3] / 100.0
      sprite.angle = cell_data[i, 4]
      sprite.mirror = (cell_data[i, 5] == 1)
      sprite.opacity = cell_data[i, 6] * self.opacity / 255.0
      sprite.blend_type = cell_data[i, 7]
    end
  end
end
#----------------------------------------------------------------------------
# ◆ Spriteset_DoublePlayers クラス
#----------------------------------------------------------------------------
class Spriteset_DoublePlayers
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_reader   :viewport1                # 1P 側のビューポート
  attr_reader   :viewport2                # 2P 側のビューポート
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize
    @viewport1 = Viewport.new(0, 0, 640, 480)
    @viewport2 = Viewport.new(0, 0, 640, 480)
    @viewport1.z = @viewport2.z = 101
    @p1_sprites = [
      Sprite_DoublePlayers.new(@viewport1, 0),
      Sprite_DoublePlayers.new(@viewport1, 0),
      Sprite_DoublePlayers.new(@viewport1, 0),
      Sprite_DoublePlayers.new(@viewport1, 0)
    ]
    @p2_sprites = [
      Sprite_DoublePlayers.new(@viewport2, 1),
      Sprite_DoublePlayers.new(@viewport2, 1),
      Sprite_DoublePlayers.new(@viewport2, 1),
      Sprite_DoublePlayers.new(@viewport2, 1)
    ]
    update
  end
  #--------------------------------------------------------------------------
  # ● 解放
  #--------------------------------------------------------------------------
  def dispose
    for sprite in @p1_sprites + @p2_sprites
      sprite.dispose
    end
    @viewport1.dispose
    @viewport2.dispose
  end
  #--------------------------------------------------------------------------
  # ● エフェクト表示中判定
  #--------------------------------------------------------------------------
  def effect?
    for sprite in @p1_sprites + @p2_sprites
      return true if sprite.effect?
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  def update
    @p1_sprites[0].battler = $game_doubleplayers[0].actors[0]
    @p1_sprites[1].battler = $game_doubleplayers[0].actors[1]
    @p1_sprites[2].battler = $game_doubleplayers[0].actors[2]
    @p1_sprites[3].battler = $game_doubleplayers[0].actors[3]
    @p2_sprites[0].battler = $game_doubleplayers[1].actors[0]
    @p2_sprites[1].battler = $game_doubleplayers[1].actors[1]
    @p2_sprites[2].battler = $game_doubleplayers[1].actors[2]
    @p2_sprites[3].battler = $game_doubleplayers[1].actors[3]
    for sprite in @p1_sprites + @p2_sprites
      sprite.update
    end
    @viewport1.update
    @viewport2.update
  end
end
#----------------------------------------------------------------------------
# ◆ Window_DoublePlayersCommand クラス
#----------------------------------------------------------------------------
class Window_DoublePlayersCommand < Window_Selectable
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_writer   :actor                    # アクター
  attr_reader   :mode                     # モード
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     actor : アクター
  #--------------------------------------------------------------------------
  def initialize
    super(0, 64, 640, 96)
    @column_max = 2
    self.mode = 0
  end
  #--------------------------------------------------------------------------
  # ● スキルの取得
  #--------------------------------------------------------------------------
  def skill
    return @mode == 2 ? @data[self.index] : nil
  end
  #--------------------------------------------------------------------------
  # ● モードの設定
  #     mode : モード
  #--------------------------------------------------------------------------
  def mode=(mode)
    @mode = mode
    refresh
  end
  #--------------------------------------------------------------------------
  # ● リフレッシュ
  #--------------------------------------------------------------------------
  def refresh
    case @mode
    when 0
      if self.contents != nil
        self.contents.dispose
        self.contents = nil
      end
      self.contents = Bitmap.new(1, 1)
      self.index = -1
    when 1
      if self.contents != nil
        self.contents.dispose
        self.contents = nil
      end
      @item_max = 3
      self.contents = Bitmap.new(width - 32, row_max * 32)
      draw_item(nil)
    when 2
      if self.contents != nil
        self.contents.dispose
        self.contents = nil
      end
      @data = []
      for i in 0...@actor.skills.size
        skill = $data_skills[@actor.skills[i]]
        if skill != nil
          @data.push(skill)
        end
      end
      @item_max = @data.size
      if @item_max > 0
        self.contents = Bitmap.new(width - 32, row_max * 32)
        for i in 0...@item_max
          draw_item(i)
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 項目の描画
  #     index : 項目番号
  #--------------------------------------------------------------------------
  def draw_item(index)
    if index.is_a?(Integer)
      skill = @data[index]
      if @actor.skill_can_use?(skill.id)
        self.contents.font.color = normal_color
      else
        self.contents.font.color = disabled_color
      end
      x = 4 + index % 2 * (288 + 32)
      y = index / 2 * 32
      rect = Rect.new(x, y, self.width / @column_max - 32, 32)
      self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
      bitmap = RPG::Cache.icon(skill.icon_name)
      opacity = self.contents.font.color == normal_color ? 255 : 128
      self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
      self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0)
      self.contents.draw_text(x + 232, y, 48, 32, skill.sp_cost.to_s, 2)
    else
      commands = [$data_system.words.attack, $data_system.words.skill,
        $data_system.words.guard]
      for index in 0...3
        x = 4 + index % 2 * 320
        y = index / 2 * 32
        rect = Rect.new(x, y, self.width / @column_max - 32, 32)
        self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
        opacity = self.contents.font.color == normal_color ? 255 : 128
      self.contents.draw_text(x + 4, y, 204, 32, commands[index], 0)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● ヘルプテキスト更新
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_text(self.skill == nil ? "" : self.skill.description)
  end
end
#----------------------------------------------------------------------------
# ◆ Window_DoublePlayerstatus クラス
#----------------------------------------------------------------------------
class Window_DoublePlayersStatus < Window_Base
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     player_index : プレイヤーインデックス
  #--------------------------------------------------------------------------
  def initialize(player_index)
    @party = $game_doubleplayers[player_index]
    super(0, 160 * (player_index + 1), 640, 160)
    bitmap = self.windowskin.clone
    bitmap.hue_change(120 * (player_index + 1))
    self.windowskin = bitmap
    self.contents = Bitmap.new(width - 32, height - 32)
    refresh
  end
  #--------------------------------------------------------------------------
  # ● リフレッシュ
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    @item_max = @party.actors.size
    for i in 0...@party.actors.size
      actor = @party.actors[i]
      actor_x = i * 160 + 4
      draw_actor_name(actor, actor_x, 0)
      draw_actor_hp(actor, actor_x, 32, 120)
      draw_actor_sp(actor, actor_x, 64, 120)
      draw_actor_state(actor, actor_x, 96)
    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
#----------------------------------------------------------------------------
# ◆ Arrow_DoublePlayers クラス
#----------------------------------------------------------------------------
class Arrow_DoublePlayers < Arrow_Base
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     viewport     : ビューポート
  #     player_index : プレイヤー インデックス
  #     enemy        : エネミー選択フラグ
  #--------------------------------------------------------------------------
  def initialize(viewport, player_index, enemy)
    @player_index = player_index
    @enemy = enemy
    super(viewport)
  end
  #--------------------------------------------------------------------------
  # ● カーソルが指しているアクターの取得
  #--------------------------------------------------------------------------
  def actor
    return $game_doubleplayers[@player_index].actors[@index]
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  def update
    super
    $game_doubleplayers[@player_index].actors.size.times do
      break if self.actor.exist? or not @enemy
      @index += 1
      @index %= $game_doubleplayers[@player_index].actors.size
    end
    if Input.repeat?(Input::RIGHT)
      $game_system.se_play($data_system.cursor_se)
      $game_doubleplayers[@player_index].actors.size.times do
        @index += 1
        @index %= $game_doubleplayers[@player_index].actors.size
        break if self.actor.exist? or not @enemy
      end
    end
    if Input.repeat?(Input::LEFT)
      $game_system.se_play($data_system.cursor_se)
      $game_doubleplayers[@player_index].actors.size.times do
        @index += $game_doubleplayers[@player_index].actors.size - 1
        @index %= $game_doubleplayers[@player_index].actors.size
        break if self.actor.exist? or not @enemy
      end
    end
    if self.actor != nil
      self.x = self.actor.screen_x
      self.y = @player_index == 0 ? self.actor.screen_y - 160 :
               self.actor.screen_y
    end
  end
  #--------------------------------------------------------------------------
  # ● ヘルプテキスト更新
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_actor(self.actor)
  end
end
#----------------------------------------------------------------------------
# ◆ Scene_DoublePlayersLoad クラス
#----------------------------------------------------------------------------
class Scene_DoublePlayersLoad < Scene_File
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize
    super("1P のファイルを選んでください。")
  end
  #--------------------------------------------------------------------------
  # ● メイン処理
  #--------------------------------------------------------------------------
  def main
    $game_temp = Game_Temp.new
    $game_temp.doubleplayers_mode = true
    $game_temp.last_file_index = 0
    latest_time = Time.at(0)
    for i in 0..3
      filename = make_filename(i)
      if FileTest.exist?(filename)
        file = File.open(filename, "r")
        if file.mtime > latest_time
          latest_time = file.mtime
          $game_temp.last_file_index = i
        end
        file.close
      end
    end
    @player_index = 0
    @normal_windowskin = RPG::Cache.windowskin($data_system.windowskin_name)
    @decided_windowskin =
      RPG::Cache.windowskin($data_system.windowskin_name).clone
    @decided_windowskin.hue_change(180)
    $game_doubleplayers = []
    super
    @decided_windowskin.dispose
  end
  #--------------------------------------------------------------------------
  # ● 決定時の処理
  #--------------------------------------------------------------------------
  def on_decision(filename)
    unless FileTest.exist?(filename)
      $game_system.se_play($data_system.buzzer_se)
      return
    end
    if @player_index == 0 or @file_index != @p1_index
      $game_system.se_play($data_system.load_se)
      file = File.open(filename, "rb")
      read_save_data(file)
      file.close
      if @player_index == 2
        $game_system.bgm_stop
        $game_system.se_play($data_system.battle_start_se)
        $game_system.bgm_play(Lfer::DP_BATTLE_BGM)
        $scene = Scene_DoublePlayersBattle.new
      end
    else
      $game_system.se_play($data_system.decision_se)
      @player_index = 0
      $game_doubleplayers[0] = nil
      @savefile_windows[@p1_index].windowskin = @normal_windowskin
      @help_window.set_text("1P のファイルを選んでください。")
    end
  end
  #--------------------------------------------------------------------------
  # ● キャンセル時の処理
  #--------------------------------------------------------------------------
  def on_cancel
    $game_system.se_play($data_system.cancel_se)
    if @player_index > 0
      @player_index = 0
      $game_doubleplayers[0] = nil
      @savefile_windows[@p1_index].windowskin = @normal_windowskin
      @help_window.set_text("1P のファイルを選んでください。")
    else
      $game_temp.doubleplayers_mode = false
      $scene = Lfer::DP_END_SCENE.new
    end
  end
  #--------------------------------------------------------------------------
  # ● セーブデータの読み込み
  #     file : 読み込み用ファイルオブジェクト (オープン済み)
  #--------------------------------------------------------------------------
  def read_save_data(file)
    until file.eof?
      game = Marshal.load(file) rescue break
      case game
      when Game_Actors then game_actors = game
      when Game_Party  then game_party  = game
      end
    end
    $game_doubleplayers[@player_index] = Game_DoublePlayers.new(game_actors,
      game_party, @player_index)
    $game_doubleplayers[@player_index].refresh
    for actor in $game_doubleplayers[@player_index].actors
      actor.recover_all
    end
    @player_index += 1
    @help_window.set_text("2P のファイルを選んでください。")
    @savefile_windows[@p1_index = @file_index].windowskin =
      @decided_windowskin
  end
end
#----------------------------------------------------------------------------
# ◆ Scene_DoublePlayersBattle クラス
#----------------------------------------------------------------------------
class Scene_DoublePlayersBattle
  #--------------------------------------------------------------------------
  # ● メイン処理
  #--------------------------------------------------------------------------
  def main
    $game_temp.in_battle = true
    $game_temp.battle_turn = 0
    $game_temp.battle_main_phase = false
    @help_window = Window_Help.new
    @p1_status_window = Window_DoublePlayersStatus.new(0)
    @p2_status_window = Window_DoublePlayersStatus.new(1)
    @command_window = Window_DoublePlayersCommand.new
    @spriteset = Spriteset_DoublePlayers.new
    @wait_count = 0
    if $data_system.battle_transition == ""
      Graphics.transition(20)
    else
      Graphics.transition(40, "Graphics/Transitions/" +
        $data_system.battle_transition)
    end
    start_phase1
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    Graphics.freeze
    @help_window.dispose
    @p1_status_window.dispose
    @p2_status_window.dispose
    @command_window.dispose
    @spriteset.dispose
  end
  #--------------------------------------------------------------------------
  # ● 勝敗判定
  #--------------------------------------------------------------------------
  def judge
    if $game_doubleplayers[0].all_dead? ||
       $game_doubleplayers[0].actors.size == 0 and
       $game_doubleplayers[1].all_dead? ||
       $game_doubleplayers[1].actors.size == 0
      @winner = -1
      start_phase4
      return true
    end
    if $game_doubleplayers[1].all_dead? or
       $game_doubleplayers[1].actors.size == 0
      @winner = 0
      start_phase4
      return true
    end
    if $game_doubleplayers[0].all_dead? or
       $game_doubleplayers[0].actors.size == 0
      @winner = 1
      start_phase4
      return true
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ● バトル終了
  #--------------------------------------------------------------------------
  def battle_end
    for i in 0..1
      $game_doubleplayers[i].clear_actions
    end
    $game_temp.doubleplayers_mode = false
    $scene = Lfer::DP_END_SCENE.new
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  def update
    @help_window.update
    @p1_status_window.update
    @p2_status_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 @spriteset.effect?
      return
    end
    if @wait_count > 0
      @wait_count -= 1
      return
    end
    case @phase
    when 1
      update_phase1
    when 2
      update_phase2
    when 3
      update_phase3
    when 4
      update_phase4
    end
  end
  #--------------------------------------------------------------------------
  # ● プレバトルフェーズ開始
  #--------------------------------------------------------------------------
  def start_phase1
    @phase = 1
    for i in 0..1
      $game_doubleplayers[i].clear_actions
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (プレバトルフェーズ)
  #--------------------------------------------------------------------------
  def update_phase1
   start_phase2 unless judge
  end
  #--------------------------------------------------------------------------
  # ● アフターバトルフェーズ開始
  #--------------------------------------------------------------------------
  def start_phase4
    @phase = 4
    Audio.bgm_stop
    if @winner == -1
      $game_system.me_play($data_system.gameover_me)
      @help_window.set_text("引き分けになりました。")
      @help_window.pause = true
    else
      $game_system.me_play($game_system.battle_end_me)
      @help_window.set_text(sprintf("%dP が勝利しました!",
          @winner + 1, $game_doubleplayers[@winner].actors[0].name))
      @help_window.pause = true
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (アフターバトルフェーズ)
  #--------------------------------------------------------------------------
  def update_phase4
    if Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      battle_end
    end
  end
  #--------------------------------------------------------------------------
  # ● コマンドフェーズ開始
  #--------------------------------------------------------------------------
  def start_phase2
    @phase = 2
    @player_index = 0
    @actor_index = -1
    @active_battler = nil
    phase2_next_actor
  end
  #--------------------------------------------------------------------------
  # ● 次のアクターのコマンド入力へ
  #--------------------------------------------------------------------------
  def phase2_next_actor
    begin
      if @active_battler != nil
        @active_battler.blink = false
      end
      if @actor_index == $game_doubleplayers[@player_index].actors.size - 1
        if @player_index == 0
          @player_index = 1
          @actor_index = -1
        else
          start_phase3
          return
        end
      end
      @actor_index += 1
      @active_battler =
        $game_doubleplayers[@player_index].actors[@actor_index]
      @active_battler.blink = true
    end until @active_battler.inputable?
    phase2_setup_command_window
  end
  #--------------------------------------------------------------------------
  # ● 前のアクターのコマンド入力へ
  #--------------------------------------------------------------------------
  def phase2_prior_actor
    before_actor_index = @actor_index
    begin
      if @active_battler != nil
        @active_battler.blink = false
        if @actor_index == 0
          @actor_index = before_actor_index
          @active_battler =
            $game_doubleplayers[@player_index].actors[@actor_index]
          @active_battler.blink = true
          return
        end
      end
      @actor_index -= 1
      @active_battler =
        $game_doubleplayers[@player_index].actors[@actor_index]
      @active_battler.blink = true
    end until @active_battler.inputable?
    $game_system.se_play($data_system.cancel_se)
    phase2_setup_command_window
  end
  #--------------------------------------------------------------------------
  # ● コマンドウィンドウのセットアップ
  #--------------------------------------------------------------------------
  def phase2_setup_command_window
    @command_window.mode = 1
    @command_window.help_window = @help_window
    @command_window.index = 0
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (コマンドフェーズ)
  #--------------------------------------------------------------------------
  def update_phase2
    if @enemy_arrow != nil
      update_phase2_enemy_select
    elsif @actor_arrow != nil
      update_phase2_actor_select
    elsif @command_window.mode == 1
      update_phase2_basic_command
    elsif @command_window.mode == 2
      update_phase2_skill_select
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (コマンドフェーズ : 基本コマンド)
  #--------------------------------------------------------------------------
  def update_phase2_basic_command
    @command_window.update
    if Input.trigger?(Input::B)
      phase2_prior_actor
      return
    end
    if Input.trigger?(Input::C)
      case @command_window.index
      when 0
        $game_system.se_play($data_system.decision_se)
        @active_battler.current_action.kind = 0
        @active_battler.current_action.basic = 0
        @selected_attack = true
        start_enemy_select
      when 1
        $game_system.se_play($data_system.decision_se)
        @active_battler.current_action.kind = 1
        start_skill_select
        @selected_attack = false
      when 2
        $game_system.se_play($data_system.decision_se)
        @active_battler.current_action.kind = 0
        @active_battler.current_action.basic = 1
        phase2_next_actor
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (コマンドフェーズ : スキル選択)
  #--------------------------------------------------------------------------
  def update_phase2_skill_select
    @command_window.update
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      end_skill_select
      return
    end
    if Input.trigger?(Input::C)
      @skill = @command_window.skill
      if @skill == nil or not @active_battler.skill_can_use?(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      @active_battler.current_action.skill_id = @skill.id
      if @skill.scope == 1
        start_enemy_select
      elsif @skill.scope == 3 or @skill.scope == 5
        start_actor_select
      else
        end_skill_select
        phase2_next_actor
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (コマンドフェーズ : エネミー選択)
  #--------------------------------------------------------------------------
  def update_phase2_enemy_select
    @enemy_arrow.update
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      end_enemy_select
      return
    end
    if Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      @active_battler.current_action.target_index = @enemy_arrow.index
      end_enemy_select
      if @skill_window != nil
        end_skill_select
      end
      if @item_window != nil
        end_item_select
      end
      phase2_next_actor
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (コマンドフェーズ : アクター選択)
  #--------------------------------------------------------------------------
  def update_phase2_actor_select
    @actor_arrow.update
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      end_actor_select
      return
    end
    if Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      @active_battler.current_action.target_index = @actor_arrow.index
      end_actor_select
      if @skill_window != nil
        end_skill_select
      end
      if @item_window != nil
        end_item_select
      end
      phase2_next_actor
    end
  end
  #--------------------------------------------------------------------------
  # ● エネミー選択開始
  #--------------------------------------------------------------------------
  def start_enemy_select
    if @player_index == 0
      @enemy_arrow = Arrow_DoublePlayers.new(@spriteset.viewport2, 1, true)
    else
      @enemy_arrow = Arrow_DoublePlayers.new(@spriteset.viewport1, 0, true)
    end
    @enemy_arrow.help_window = @help_window
  end
  #--------------------------------------------------------------------------
  # ● エネミー選択終了
  #--------------------------------------------------------------------------
  def end_enemy_select
    @enemy_arrow.dispose
    @enemy_arrow = nil
  end
  #--------------------------------------------------------------------------
  # ● アクター選択開始
  #--------------------------------------------------------------------------
  def start_actor_select
    if @player_index == 0
      @actor_arrow = Arrow_DoublePlayers.new(@spriteset.viewport1, 0, false)
    else
      @actor_arrow = Arrow_DoublePlayers.new(@spriteset.viewport2, 1, false)
    end
    @actor_arrow.index = @actor_index
    @actor_arrow.help_window = @help_window
  end
  #--------------------------------------------------------------------------
  # ● アクター選択終了
  #--------------------------------------------------------------------------
  def end_actor_select
    @actor_arrow.dispose
    @actor_arrow = nil
  end
  #--------------------------------------------------------------------------
  # ● スキル選択開始
  #--------------------------------------------------------------------------
  def start_skill_select
    @command_window.actor = @active_battler
    @command_window.mode = 2
    @command_window.index = 0
  end
  #--------------------------------------------------------------------------
  # ● スキル選択終了
  #--------------------------------------------------------------------------
  def end_skill_select
    @command_window.mode = 1
    @command_window.index = 1
  end
  #--------------------------------------------------------------------------
  # ● メインフェーズ開始
  #--------------------------------------------------------------------------
  def start_phase3
    @phase = 3
    $game_temp.battle_turn += 1
    @actor_index = -1
    @active_battler = nil
    @command_window.mode = 0
    @command_window.help_window = nil
    $game_temp.battle_main_phase = true
    make_action_orders
    @phase3_step = 1
  end
  #--------------------------------------------------------------------------
  # ● 行動順序作成
  #--------------------------------------------------------------------------
  def make_action_orders
    @action_battlers = []
    for i in 0..1
      for battler in $game_doubleplayers[i].actors
        @action_battlers.push(battler)
      end
    end
    for battler in @action_battlers
      battler.make_action_speed
    end
    @action_battlers.sort! {|a,b|
      b.current_action.speed - a.current_action.speed }
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ)
  #--------------------------------------------------------------------------
  def update_phase3
    case @phase3_step
    when 1
      update_phase3_step1
    when 2
      update_phase3_step2
    when 3
      update_phase3_step3
    when 4
      update_phase3_step4
    when 5
      update_phase3_step5
    when 6
      update_phase3_step6
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 1 : アクション準備)
  #--------------------------------------------------------------------------
  def update_phase3_step1
    @help_window.set_text("")
    if judge
      return
    end
    if @action_battlers.size == 0
      start_phase2
      return
    end
    @animation1_id = 0
    @animation2_id = 0
    @active_battler = @action_battlers.shift
    if @active_battler.index == nil
      return
    end
    @allies_player_index = @active_battler.player_index
    @enemies_player_index = @active_battler.player_index ^ 1
    if @active_battler.hp > 0 and @active_battler.slip_damage?
      @active_battler.slip_damage_effect
      @active_battler.damage_pop = true
    end
    @active_battler.remove_states_auto
    @p1_status_window.refresh
    @p2_status_window.refresh
    @phase3_step = 2
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 2 : アクション開始)
  #--------------------------------------------------------------------------
  def update_phase3_step2
    if @active_battler.restriction == 2 or @active_battler.restriction == 3
      @active_battler.current_action.kind = 0
      @active_battler.current_action.basic = 0
    end
    if @active_battler.restriction == 4
      $game_temp.forcing_battler = nil
      @phase3_step = 1
      return
    end
    @target_battlers = []
    if @active_battler.current_action.kind == 0
      make_basic_action_result
    else
      make_skill_action_result
    end
    if @phase3_step == 2
      @phase3_step = 3
    end
  end
  #--------------------------------------------------------------------------
  # ● 基本アクション 結果作成
  #--------------------------------------------------------------------------
  def make_basic_action_result
    if @active_battler.current_action.basic == 0
      @animation1_id = @active_battler.animation1_id
      @animation2_id = @active_battler.animation2_id
      if @active_battler.restriction == 3
        target =
          $game_doubleplayers[@allies_player_index].random_target_actor
      elsif @active_battler.restriction == 2
        target =
          $game_doubleplayers[@enemies_player_index].random_target_actor
      else
        target =
          $game_doubleplayers[@enemies_player_index].smooth_target_actor(
            @active_battler.current_action.target_index)
      end
      @target_battlers = [target]
      for target in @target_battlers
        target.attack_effect(@active_battler)
      end
      return
    end
    if @active_battler.current_action.basic == 1
      @help_window.set_text($data_system.words.guard, 1)
      return
    end
    if @active_battler.current_action.basic == 3
      $game_temp.forcing_battler = nil
      @phase3_step = 1
      return
    end
  end
  #--------------------------------------------------------------------------
  # ● スキルの対象側バトラー設定
  #     scope : スキルの効果範囲
  #--------------------------------------------------------------------------
  def set_target_battlers(scope)
    case scope
    when 1
      index = @active_battler.current_action.target_index
      @target_battlers.push(
        $game_doubleplayers[@enemies_player_index].smooth_target_actor(
          index))
    when 2
      for actor in $game_doubleplayers[@enemies_player_index].actors
        @target_battlers.push(actor) if actor.exist?
      end
    when 3
      index = @active_battler.current_action.target_index
      @target_battlers.push(
        $game_doubleplayers[@allies_player_index].smooth_target_actor(index))
    when 4
      for actor in $game_doubleplayers[@allies_player_index].actors
        @target_battlers.push(actor) if actor.exist?
      end
    when 5
      index = @active_battler.current_action.target_index
      actor = $game_doubleplayers[@allies_player_index].actors[index]
      @target_battlers.push(actor) if actor != nil and actor.hp0?
    when 6
      for actor in $game_doubleplayers[@allies_player_index].actors
        @target_battlers.push(actor) if actor != nil and actor.hp0?
      end
    when 7
      @target_battlers.push(@active_battler)
    end
  end
  #--------------------------------------------------------------------------
  # ● スキルアクション 結果作成
  #--------------------------------------------------------------------------
  def make_skill_action_result
    @skill = $data_skills[@active_battler.current_action.skill_id]
    unless @active_battler.skill_can_use?(@skill.id)
      $game_temp.forcing_battler = nil
      @phase3_step = 1
      return
    end
    @active_battler.sp -= @skill.sp_cost
    @p1_status_window.refresh
    @p2_status_window.refresh
    @help_window.set_text(@skill.name, 1)
    @animation1_id = @skill.animation1_id
    @animation2_id = @skill.animation2_id
    @common_event_id = @skill.common_event_id
    set_target_battlers(@skill.scope)
    for target in @target_battlers
      target.skill_effect(@active_battler, @skill)
    end
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 3 : 行動側アニメーション)
  #--------------------------------------------------------------------------
  def update_phase3_step3
    if @animation1_id == 0
      @active_battler.white_flash = true
    else
      @active_battler.animation_id = @animation1_id
      @active_battler.animation_hit = true
    end
    @phase3_step = 4
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 4 : 対象側アニメーション)
  #--------------------------------------------------------------------------
  def update_phase3_step4
    for target in @target_battlers
      target.animation_id = @animation2_id
      target.animation_hit = target.damage != "Miss"
    end
    @wait_count = 8
    @phase3_step = 5
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 5 : ダメージ表示)
  #--------------------------------------------------------------------------
  def update_phase3_step5
    @help_window.set_text("")
    @p1_status_window.refresh
    @p2_status_window.refresh
    for target in @target_battlers
      target.damage_pop = true if target.damage != nil
    end
    @phase3_step = 6
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 6 : リフレッシュ)
  #--------------------------------------------------------------------------
  def update_phase3_step6
    $game_temp.forcing_battler = nil
    @phase3_step = 1
  end
end

戻る