#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Easy Party Switcher by Blizzard
# Version 2.51b
# Type: Party Changing System
# Date: 21.05.2006
# Date v1.1: 25.05.2006
# Date v1.2b: 27.05.2006
# Date v1.5b: 3.11.2006
# Date v1.51b: 29.11.2006
# Date v1.52b: 6.12.2006
# Date v1.7b: 23.2.2007
# Date v1.8b: 30.4.2007
# Date v2.0b: 7.8.2007
# Date v2.1b: 24.8.2007
# Date v2.11b: 24.9.2007
# Date v2.3b: 26.1.2008
# Date v2.32b: 28.1.2008
# Date v2.4b: 29.1.2008
# Date v2.41b: 6.8.2008
# Date v2.42b: 14.10.2008
# Date v2.43b: 20.10.2008
# Date v2.5b: 4.10.2012
# Date v2.51b: 22.10.2012
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#   
#  This work is protected by the following license:
# #----------------------------------------------------------------------------
# #  
# #  Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
# #  ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
# #  
# #  You are free:
# #  
# #  to Share - to copy, distribute and transmit the work
# #  to Remix - to adapt the work
# #  
# #  Under the following conditions:
# #  
# #  Attribution. You must attribute the work in the manner specified by the
# #  author or licensor (but not in any way that suggests that they endorse you
# #  or your use of the work).
# #  
# #  Noncommercial. You may not use this work for commercial purposes.
# #  
# #  Share alike. If you alter, transform, or build upon this work, you may
# #  distribute the resulting work only under the same or similar license to
# #  this one.
# #  
# #  - For any reuse or distribution, you must make clear to others the license
# #    terms of this work. The best way to do this is with a link to this web
# #    page.
# #  
# #  - Any of the above conditions can be waived if you get permission from the
# #    copyright holder.
# #  
# #  - Nothing in this license impairs or restricts the author's moral rights.
# #  
# #----------------------------------------------------------------------------
# 
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# 
# Special Thanks to:
# 
#   - Zeriab for pointing out a few glitches and shortening the code in an
#     earlier version.
#   - KK20 for finding two bugs.
# 
# 
# IMPORTANT NOTE:
# 
#   Be sure to set the MAX_PARTY to the maximum size of your party. There is
#   already a preconfiguration of 4.
# 
# 
# Compatibility:
# 
#   98% compatible with SDK v1.x. 90% compatible with SDK 2.x. Can cause
#   incompatibility issued with other Party Change Systems. Can cause problems
#   with CBS-es if you use the battle switch feature. WILL corrupt your old
#   savegames.
# 
# 
# Features:
# 
#   - set party members for "not _available" (shown transparent in the reserve)
#   - remove party members from the reserve list ("disabled_for_party")
#   - set party members, who MUST be in the party (shown transparent in the
#     current party, "must_be_in_party")
#   - set up forced positions for party members
#   - set up forced party size
#   - option either to wipe the party (for multi-party use) or only remove
#     every member (except 1) from the party.
#   - easy to use and easy to switch party members
#   - also supports small parties (2 or 3 members) and large parties (5 or
#     more)
#   - uses facesets optionally
# 
# v1.5b:
#   - better, shorter and more efficient code (less memory use, less CPU use)
#   - fixed potential bugs
# 
# v1.7b:
#   - improved coding
#   - facesets now optional
#   - no extra bitmap files needed anymore
#   - works now with Tons of Add-ons
# 
# v1.8b:
#   - added "forced position"
#   - added "forced party size"
# 
# v2.0b:
#   - fixed the bug where you could empty the party... again...
#   - fixed the bug that appeared when you pressed SHIFT
#   - added option to allow an empty party
#   - added "EXP for party members in reserve" option
#   - made the forced_size for party work more convenient
#   - improved coding
#   - slightly decreased lag
# 
# v2.1b:
#   - fixed a bug
#   - improved coding
#   - rewritten conditions using classic syntax to avoid RGSS conditioning bug
#   - now can serve as enhancement for CP Debug System
# 
# v2.11b:
#   - improved coding and performance
# 
# v2.3b:
#   - optional feature to call the Party Switcher during battle
# 
# v2.32b:
#   - fixed crash problem with SDK 2.x when using the BATTLE_SWITCH option
#   - fixed SP display glitch when using BARS from Tons of Add-ons
# 
# v2.4b:
#   - now you can activate party order change only in the party switcher
#   - add option for automatic party order change only in battle
# 
# v2.41b:
#   - fixed problem where you could put together a party where everybody is
#     dead
# 
# v2.42b:
#   - added possibility to change the BATTLE_SWITCH setting during the game
# 
# v2.43b:
#   - fixed a problem with SDK 2.x
# 
# v2.5b:
#   - fixed a problem caused by other scripts that remove the result window
# 
# v2.51b:
#   - fixed two bugs regarding actor visibility/availability
#   - improved some of the code
# 
# 
# How to use:
# 
#   To call this script, make a "Call script" command in an event.
# 
#   1. Syntax: $scene = Scene_PartySwitcher.new
#      No extra feature will be applied and you can switch the party as you
#      wish.
# 
#   2. Syntax: $scene = Scene_PartySwitcher.new(X)
#      You can replace X for 1 to remove all party members except one (either
#      one, who must be in the party or a random one), or replace X with 2, to
#      cause a party wipe. Wiping a party will disable the of the current
#      members and a NEW party of the remaining members must be formed. If you
#      replace it with 3, the current party configuration will be stored for a
#      later fast switch-back. If X is 10, all actors will be available for
#      party switching no matter if the are "not_available" or
#      "disabled_for_party". This feature is used by the CP Debug System. No
#      faceset will be used in this case for a more convenient working.
# 
#   3. Syntax: $scene = Scene_PartySwitcher.new(X, 1)
#      You can use the X as described above or just set it to 0 to disable
#      it. Also the "1" in the syntax will reset any disabled_for_party and is
#      made to be used after multi-party use.
# 
#   4. Syntax: $scene = Scene_PartySwitcher.new(X, Y, Z)
#      You can replace Z with 1 to replace the party with a stored one AND
#      store the current or replace it with 2 to replace the party with a
#      stored one, but without storing the current. USE THIS ONLY IF YOU ASSUME
#      TO HAVE A STORED PARTY READY! You can simply test if there is a store
#      party by putting this code into the conditional branch script:
# 
#      $game_system.stored_party != nil
# 
#      This syntax will not open the Party Switcher and it will override the
#      commands X and Y, so you can replace these with any number.
#   
#   5. To activate/deactivate the option of order change only, simply use the
#      event command "Call Script" with following syntax:
#      
#      $game_system.order_only = true/false
#      
#      If the setting is set to true, the switcher will allow only party order
#      change. The same goes for battle change (if you are using the
#      BATTLE_SWITCH option), but the syntax is different:
#      
#      $game_system.battle_order_only = true/false
#      
#      The BATTLE_SWITCH option can be changed during the game by using
#      following syntax:
#      
#      $game_system.battle_switch = true/false
#      
#      This option is intially set to the same setting as BATTLE_SWITCH is.
#      
#   Character faces go into the "Characters" folder and they have the same name
#   as the character spritesets have with _face added
# 
#   Example:
# 
#     sprite - Marlen.png
#     face   - Marlen_face.png
# 
#   Other syntaxes:
#     $game_actors[ID].not_available = true/false
#     $game_actors[ID].disabled_for_party = true/false
#     $game_actors[ID].must_be_in_party = true/false
#     $game_actors[ID].forced_position = nil/0/1/2/...
#   OR
#     $game_party.actors[POS].not_available = true/false
#     $game_party.actors[POS].disabled_for_party = true/false
#     $game_party.actors[POS].must_be_in_party = true/false
#     $game_party.actors[POS].forced_position = nil/0/1/2/...
# 
#   ID  - the actor's ID in the database
#   POS - the actor's position in the party (STARTS FROM 0, not 1!)
# 
#   not_available
#   - will disable the possibility of an already unlocked character to be in
#     the current party
# 
#   disabled_for_party
#   - will cause the character NOT to appear in the party switch screen at all
# 
#   must_be_in_party
#   - will cause the character to be automatically moved into the current party
#     and he also cannot be put in the reserve
# 
#   forced_position
#   - will enforce the player to be at a specific position in the party, set
#     this value to nil to disable this feature, use it in combination with
#     must_be_in_party and $game_party.forced_size or you might experience
#     bugs.
# 
#   $game_party.forced_size = nil/0/1/2/...
# 
#   Using this syntax will enforce a specific party size. The EPS won't exit
#   until this size is filled up or there are no more in the reserve. EPS will
#   automatically "correct" this number if there are not enough characters in
#   the reserve to fill up a party of forced_size. Set this value to nil to
#   disable the size requirement. Note that the actor DO NOT HAVE TO be set in
#   normal order without any empty position like in version 1.x.
# 
# 
# Additional note:
# 
#   For your own sake, do not apply the attribute "must_be_in_party" to a
#   character at the same time with "not_available" or "disabled_for_party" as
#   this WILL disrupt your party and party switch system. Use "forced_position"
#   together with "must_be_in_party" to avoid bugs. Be careful when using
#   "forced_position" with "$game_party.forced_size". Add actors at the very
#   end to be sure the player can't put others after them if the "forced_size"
#   is smaller than the maximum party size.
# 
# 
# If you find any bugs, please report them here:
# http://www.chaosproject.co.nr
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

#==============================================================================
# module BlizzCFG
#==============================================================================

module BlizzCFG

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Conficuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  # how many party members do you use
  MAX_PARTY = 4
  # set to true to use facesets instead of spritesets
  FACESETS = false
  # allows a party with 0 members
  ALLOW_EMPTY_PARTY = false
  # allows switching the party in battle
  BATTLE_SWITCH = false
  # name of the call command in the party menu in battle
  SWITCH_COMMAND = 'Switch'
  # gives all other characters EXP (specify in %)
  EXP_RESERVE = 50
  # gives "not available" characters EXP (specify in %)
  EXP_NOT_AVAILABLE = 0
  # gives "disabled for party" characters EXP (specify in %)
  EXP_DISABLED_FOR_PARTY = 0
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Conficuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

end

# recognition variable for plug-ins
$easy_party_switcher = 2.51

#==============================================================================
# Game_Actor
#==============================================================================

class Game_Actor < Game_Battler

  attr_accessor :must_be_in_party
  attr_accessor :disabled_for_party
  attr_accessor :not_available
  attr_accessor :forced_position
  
  alias setup_eps_later setup
  def setup(actor_id)
    setup_eps_later(actor_id)
    @must_be_in_party = @disabled_for_party = @not_available = false
  end
  
end

#==============================================================================
# Game_System
#==============================================================================

class Game_System

  attr_accessor :stored_party
  attr_accessor :order_only
  attr_accessor :battle_order_only
  attr_accessor :battle_switch
  
  alias init_eps_later initialize
  def initialize
    init_eps_later
    @order_only = @battle_order_only = false
    @battle_switch = BlizzCFG::BATTLE_SWITCH
  end
  
end

#==============================================================================
# Game_Party
#==============================================================================

class Game_Party

  attr_accessor :actors
  attr_accessor :forced_size
  
  def any_forced_position
    return (@actors.any? {|actor| actor != nil && actor.forced_position != nil})
  end
  
end

#==============================================================================
# Window_Base
#==============================================================================

class Window_Base

  alias draw_actor_graphic_eps_later draw_actor_graphic
  def draw_actor_graphic(actor, x, y)
    if actor != nil && actor.character_name != ''
      classes = [Window_Current, Window_Reserve, Window_HelpStatus]
      if BlizzCFG::FACESETS && !$all_available && classes.include?(self.class)
        draw_actor_face_eps(actor, x, y)
      else
        if classes.include?(self.class)
          bitmap = RPG::Cache.character(actor.character_name,
              actor.character_hue)
          x += bitmap.width / 8 + 24
          y += bitmap.height / 4 + 16
        end
        # this may need changing when using a custom draw_actor_graphic method
        if actor.not_available || actor.must_be_in_party
          bitmap = RPG::Cache.character(actor.character_name, actor.character_hue)
          cw = bitmap.width / 4
          ch = bitmap.height / 4
          src_rect = Rect.new(0, 0, cw, ch)
          self.contents.blt(x - cw / 2, y - ch, bitmap, src_rect, 128)
        else
          draw_actor_graphic_eps_later(actor, x, y)
        end
      end
    end
  end

  def draw_actor_face_eps(actor, x, y)
    if $tons_version == nil || $tons_version < 3.71 || !FACE_HUE
      hue = 0
    else
      hue = actor.character_hue
    end
    bitmap = RPG::Cache.character("#{actor.character_name}_face", hue)
    src_rect = Rect.new(0, 0, bitmap.width, bitmap.height)
    if actor.not_available || actor.must_be_in_party
      self.contents.blt(x, y, bitmap, src_rect, 128)
    else
      self.contents.blt(x, y, bitmap, src_rect)
    end
  end
  
end

#==============================================================================
# Window_BattleResult
#==============================================================================

class Window_BattleResult
  
  attr_reader :exp
  
end

#==============================================================================
# Window_Current
#==============================================================================

class Window_Current < Window_Selectable

  def initialize
    super(0, 0, 240 + 32,
        BlizzCFG::MAX_PARTY > 4 ? 480 : BlizzCFG::MAX_PARTY * 120)
    self.contents = Bitmap.new(width - 32,
        448 + (BlizzCFG::MAX_PARTY - 4) * 120)
    @item_max = BlizzCFG::MAX_PARTY
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    self.contents.font.size = 24
    refresh
    self.active, self.index, self.z = false, -1, 5000
  end
  
  def refresh
    self.contents.clear
    $game_party.actors.each_index {|i|
        if $game_party.actors[i] != nil
          draw_actor_graphic($game_party.actors[i], 4, i * 120 + 4)
          draw_actor_name($game_party.actors[i], 152, i * 120 - 4)
          draw_actor_level($game_party.actors[i], 88, i * 120 - 4)
          draw_actor_hp($game_party.actors[i], 88, i * 120 + 24)
          draw_actor_sp($game_party.actors[i], 88, i * 120 + 52)
        end}
  end

  def setactor(index_1, index_2)
    $game_party.actors[index_2], $game_party.actors[index_1] =
        $game_party.actors[index_1], $game_party.actors[index_2]
    refresh
  end

  def getactor(index)
    return $game_party.actors[index]
  end
  
  def update_cursor_rect
    if @index < 0
      self.cursor_rect.empty
      return
    end
    row = @index / @column_max
    self.top_row = row if row < self.top_row
    if row > top_row + (page_row_max - 1)
      self.top_row = row - (page_row_max - 1)
    end
    y = (@index / @column_max) * 120 - self.oy
    self.cursor_rect.set(0, y, self.width - 32, 88)
  end

  def clone_cursor
    row = @index / @column_max
    self.top_row = row if row < self.top_row
    if row > top_row + (page_row_max - 1)
      self.top_row = row - (page_row_max - 1)
    end
    y = (@index / @column_max) * 120
    src_rect = Rect.new(0, 0, self.width, 88)
    bitmap = Bitmap.new(self.width-32, 88)
    bitmap.fill_rect(0, 0, self.width-32, 88, Color.new(255, 255, 255, 192))
    bitmap.fill_rect(2, 2, self.width-36, 84, Color.new(255, 255, 255, 80))
    self.contents.blt(0, y, bitmap, src_rect, 192)
  end
  
  def top_row
    return self.oy / 116
  end

  def top_row=(row)
    self.oy = (row % row_max) * 120
  end

  def page_row_max
    return (self.height / 120)
  end

end

#==============================================================================
# Window_Reserve
#==============================================================================

class Window_Reserve < Window_Selectable
  
  attr_reader :actors
  
  def initialize(scene)
    super(0, 0, 368, 320)
    setup
    @column_max = 3
    rows = @item_max / @column_max
    self.contents = Bitmap.new(width - 32, rows > 3 ? rows * 96 : height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    self.contents.font.size = 24
    self.active, self.index, self.z = false, -1, 5000
    refresh
    if scene == Scene_Map && $game_system.order_only ||
        scene == Scene_Battle && $game_system.battle_order_only
      self.opacity = 128
    end
  end
  
  def setup
    @actors = []
    (1...$data_actors.size).each {|i|
        if !$game_party.actors.include?($game_actors[i]) &&
            !$game_actors[i].disabled_for_party || $all_available
          @actors.push($game_actors[i])
        end}
    @item_max = (@actors.size + $game_party.actors.size + 2) / 3 * 3
  end
  
  def refresh
    self.contents.clear
    @actors.each_index {|i|
        draw_actor_graphic(@actors[i], i % 3 * 112 + 16, i / 3 * 96 + 8)}
  end
  
  def getactor(index)
    return @actors[index]
  end
  
  def get_number
    return (@actors.find_all {|actor| actor != nil}).size if $all_available
    return (@actors.find_all {|actor| actor != nil &&
        !actor.not_available}).size
  end
  
  def setactor(index_1, index_2)
    @actors[index_1], @actors[index_2] = @actors[index_2], @actors[index_1]
    refresh
  end

  def setparty(index_1, index_2)
    @actors[index_1], $game_party.actors[index_2] =
        $game_party.actors[index_2], @actors[index_1]
    refresh
  end

  def update_cursor_rect
    if @index < 0
      self.cursor_rect.empty
      return
    end
    row = @index / @column_max
    self.top_row = row if row < self.top_row
    self.top_row = row - (page_row_max-1) if row > top_row + (page_row_max-1)
    x = (@index % @column_max) * 112 + 8
    y = (@index / @column_max) * 96 - self.oy
    self.cursor_rect.set(x, y, 96, 96)
  end

  def clone_cursor
    row = @index / @column_max
    self.top_row = row if row < self.top_row
    if row > top_row + (page_row_max - 1)
      self.top_row = row - (page_row_max - 1)
    end
    x, y = (@index % @column_max) * 112 + 8, (@index / @column_max) * 96
    src_rect = Rect.new(0, 0, 96, 96)
    bitmap = Bitmap.new(96, 96)
    bitmap.fill_rect(0, 0, 96, 96, Color.new(255, 255, 255, 192))
    bitmap.fill_rect(2, 2, 92, 92, Color.new(255, 255, 255, 80))
    self.contents.blt(x, y, bitmap, src_rect, 192)
  end
  
  def top_row
    return self.oy / 96
  end

  def top_row=(row)
    row = row % row_max
    self.oy = row * 96
  end

  def page_row_max
    return (self.height - 32) / 96
  end

end

#==============================================================================
# Window_HelpStatus
#==============================================================================

class Window_HelpStatus < Window_Base

  def initialize(gotactor, scene)
    super(0, 0, 400 - 32, 160)
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    self.contents.font.size = 24
    refresh(gotactor)
    self.active, self.z = false, 5000
    if scene == Scene_Map && $game_system.order_only ||
        scene == Scene_Battle && $game_system.battle_order_only
      self.opacity = 128
    end
  end
  
  def refresh(actor)
    self.contents.clear
    if actor != nil
      self.contents.font.color = normal_color
      if actor.not_available && !$all_available
        self.contents.draw_text(8, 0, 160, 32, 'not available', 0)
      end
      draw_actor_graphic(actor, 0, 40)
      draw_actor_name(actor, 160, 32)
      draw_actor_level(actor, 96, 32)
      draw_actor_hp(actor, 96, 64)
      draw_actor_sp(actor, 96, 96)
    end
  end

end

#==============================================================================
# Window_Warning
#==============================================================================

class Window_Warning < Window_Base

  def initialize(mode, members)
    super(0, 0, 320, 96)
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    self.contents.font.size = 24
    self.x, self.y, self.z = 320 - width/2, 240 - height/2, 9999
    self.contents.font.color = normal_color
    case mode
    when 0
      self.contents.draw_text(0, 0, 288, 32, 'You need a party', 1)
      num = members + $game_party.actors.nitems
      if $game_party.forced_size != nil && $game_party.forced_size < num
        num = $game_party.forced_size
      end
      self.contents.draw_text(0, 32, 288, 32, "of #{num} members!", 1)
    when 1
      self.contents.draw_text(0, 0, 288, 32, 'You cannot remove', 1)
      self.contents.draw_text(0, 32, 288, 32, 'the last party member!', 1)
    when 2
      self.contents.draw_text(0, 0, 288, 32, 'At least one member', 1)
      self.contents.draw_text(0, 32, 288, 32, 'has to be alive!', 1)
    end
  end

end

#==============================================================================
# Window_PartyCommand
#==============================================================================

class Window_PartyCommand
  
  alias init_eps_later initialize
  def initialize
    if $game_system.battle_switch
      if defined?(SDK) && self.is_a?(Window_HorizCommand)
        s1 = SDK::Scene_Commands::Scene_Battle::Fight
        s2 = SDK::Scene_Commands::Scene_Battle::Escape
        s3 = BlizzCFG::SWITCH_COMMAND
        super(640, [s1, s2, s3])
        disable_item(1) if !$game_temp.battle_can_escape
      else
        super(0, 0, 640, 64)
        self.contents = Bitmap.new(width - 32, height - 32)
        @commands = ['Fight', 'Escape', BlizzCFG::SWITCH_COMMAND]
        @item_max = @column_max = 3
        draw_item(0, normal_color)
        draw_item(1, $game_temp.battle_can_escape ?
            normal_color : disabled_color)
        draw_item(2, normal_color)
      end
      self.active, self.visible, self.index = false, false, 0
      self.back_opacity = 160
    else
      init_eps_later
    end
  end
  
  alias draw_item_eps_later draw_item
  def draw_item(index, color)
    if $game_system.battle_switch
      self.contents.font.color = color
      rect = Rect.new(80 + index * 160 + 4, 0, 128 - 10, 32)
      self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
      self.contents.draw_text(rect, @commands[index], 1)
    else
      draw_item_eps_later(index, color)
    end
  end
  
  alias update_cursor_rect_eps_later update_cursor_rect
  def update_cursor_rect
    if $game_system.battle_switch
      self.cursor_rect.set(80 + index * 160, 0, 128, 32)
    else
      update_cursor_rect_eps_later
    end
  end
  
  def command(index = self.index)
    return @commands[index]
  end
  
end

#==============================================================================
# Scene_PartySwitcher
#==============================================================================

class Scene_PartySwitcher
  
  def initialize(wipe_party = 0, reset = 0, store = 0)
    @wipe_party, @reset, @store = wipe_party, reset, store
    @current_window_temp = @reserve_window_temp = 0
    @scene_flag, @temp_window = false, ''
    @scene = $scene.class
  end
  
  def main
    if @store != 0
      swap_parties
      $scene = Scene_Map.new
      $game_player.refresh
      return
    end
    case @wipe_party
    when 1 then setup_forced_party
    when 2 then wipe_party
    when 3
      $game_system.stored_party = $game_party.actors
      wipe_party
    when 10 then $all_available = true
    end
    if @reset == 1
      (1...$data_actors.size).each {|i| $game_actors[i].not_available = false}
    end
    @current_window = Window_Current.new
    @current_window.index, @current_window.active = 0, true
    @reserve_window = Window_Reserve.new(@scene)
    @reserve_window.x, @reserve_window.y = 272, 160
    @help_window = Window_HelpStatus.new(@reserve_window.getactor(0), @scene)
    @help_window.x = 240 + 32
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      break if $scene != self
    end
    Graphics.freeze
    [@current_window, @reserve_window, @help_window].each {|win| win.dispose}
    $game_party.actors.compact!
    $game_player.refresh
    $all_available = false
  end
  
  def update
    check = @reserve_window.index
    if @reserve_window.active
      reserve_update
      @reserve_window.update
    end
    if check != @reserve_window.index
      if @reserve_window.active
        actor = @reserve_window.getactor(@reserve_window.index)
      elsif @current_window.active 
        actor = @reserve_window.getactor(@reserve_window_temp)
      end
      @help_window.refresh(actor) if ['', 'Current'].include?(@temp_window)
    end
    current_update if @current_window.active
    if Input.trigger?(Input::B)
      if @scene_flag
        $game_system.se_play($data_system.cancel_se)
        @scene_flag, @temp_window = false, ''
        if @reserve_window.active
          actor = @reserve_window.getactor(@reserve_window.index)
        elsif @current_window.active
          actor = @reserve_window.getactor(@reserve_window_temp)
        end
        @help_window.refresh(actor) if ['', 'Current'].include?(@temp_window)
        [@current_window, @reserve_window].each {|win| win.refresh}
        return
      end
      if $game_party.forced_size != nil &&
          ($game_party.forced_size < $game_party.actors.nitems ||
          ($game_party.forced_size > $game_party.actors.nitems &&
          @reserve_window.get_number != 0))
        $game_system.se_play($data_system.buzzer_se)
        warning(1)
        return
      end
      if $game_party.actors.all? {|actor| actor == nil ||
            actor != nil && actor.dead?}
        $game_system.se_play($data_system.buzzer_se)
        warning(2)
        return
      end
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Map.new
    elsif Input.trigger?(Input::A)
      if $game_party.any_forced_position
        $game_system.se_play($data_system.buzzer_se)
      else
        $game_system.se_play($data_system.decision_se)
        $game_party.actors.compact! 
        @current_window.refresh
      end
    end
  end
    
  def current_update
    @current_window.update
    if Input.trigger?(Input::C)
      actor = @current_window.getactor(@current_window.index)
      if actor != nil && actor.forced_position != nil
        $game_system.se_play($data_system.buzzer_se)
      else
        if @scene_flag
          switch_members
        else
          $game_system.se_play($data_system.decision_se)
          @scene_flag, @temp_window = true, 'Current'
          @temp_actor_index = @current_window.index
          @current_window.clone_cursor
        end
      end
    elsif Input.trigger?(Input::RIGHT)
      if @scene == Scene_Map && $game_system.order_only ||
          @scene == Scene_Battle && $game_system.battle_order_only
        $game_system.se_play($data_system.buzzer_se)
      else
        $game_system.se_play($data_system.cursor_se)
        @current_window.active = false
        @reserve_window.active = true
        @current_window_temp = @current_window.index
        actor = @reserve_window.getactor(@reserve_window_temp)
        @current_window.index = -1
        @reserve_window.index = @reserve_window_temp
        @help_window.refresh(actor) if !@scene_flag
      end
    end
  end
  
  def reserve_update
    if Input.trigger?(Input::C)
      if @scene_flag
        switch_members
      else
        $game_system.se_play($data_system.decision_se)
        @scene_flag, @temp_window = true, 'Reserve'
        @temp_actor_index = @reserve_window.index
        @reserve_window.clone_cursor
      end
    elsif @reserve_window.index % 3 == 0 && Input.repeat?(Input::LEFT)
      $game_system.se_play($data_system.cursor_se)
      @reserve_window.active = false
      @current_window.active = true
      @reserve_window_temp = @reserve_window.index
      @reserve_window.index = -1
      @current_window.index = @current_window_temp
    end
  end
  
  def switch_members
    if @temp_window == 'Reserve' && @reserve_window.active
      @reserve_window.setactor(@temp_actor_index, @reserve_window.index)
      actor = @reserve_window.getactor(@reserve_window.index)
      @help_window.refresh(actor)
    end
    if @temp_window == 'Current' && @current_window.active
      @current_window.setactor(@temp_actor_index, @current_window.index)
    end
    if @temp_window == 'Reserve' && @current_window.active
      actor1 = @current_window.getactor(@current_window.index)
      actor2 = @reserve_window.getactor(@temp_actor_index)
      if call_warning?(@current_window.index, actor2)
        if actor1 != nil && actor1.must_be_in_party
          $game_system.se_play($data_system.buzzer_se)
          @scene_flag, @temp_window = false, ''
          actor = @reserve_window.getactor(@reserve_window_temp)
          [@current_window, @reserve_window].each {|win| win.refresh}
          @help_window.refresh(actor)
          return
        end
        if actor2 != nil && actor2.not_available && !$all_available
          $game_system.se_play($data_system.buzzer_se)
          @scene_flag, @temp_window = false, ''
          actor = @reserve_window.getactor(@reserve_window_temp)
          [@current_window, @reserve_window].each {|win| win.refresh}
          @help_window.refresh(actor)
          return
        end
        @reserve_window.setparty(@temp_actor_index, @current_window.index)
        @current_window.refresh
        actor = @reserve_window.getactor(@reserve_window_temp)
        @help_window.refresh(actor)
      elsif $game_party.forced_size != nil
        warning(0)
      else
        warning(1)
      end
    end
    if @temp_window == 'Current' && @reserve_window.active
      actor1 = @current_window.getactor(@temp_actor_index)
      actor2 = @reserve_window.getactor(@reserve_window.index)
      if call_warning?(@temp_actor_index, actor2)
        if actor1 != nil && actor1.must_be_in_party
          $game_system.se_play($data_system.buzzer_se)
          @scene_flag, @temp_window = false, ''
          actor = @reserve_window.getactor(@reserve_window.index)
          [@current_window, @reserve_window].each {|win| win.refresh}
          @help_window.refresh(actor)
          return
        end
        if actor2 != nil && actor2.not_available && !$all_available
          $game_system.se_play($data_system.buzzer_se)
          @scene_flag, @temp_window = false, ''
          actor = @reserve_window.getactor(@reserve_window.index)
          [@current_window, @reserve_window].each {|win| win.refresh}
          @help_window.refresh(actor)
          return
        end
        @reserve_window.setparty(@reserve_window.index, @temp_actor_index)
        @current_window.refresh
        actor = @reserve_window.getactor(@reserve_window.index)
        @help_window.refresh(actor)
      elsif $game_party.forced_size != nil
        warning(0)
      else
        warning(1)
      end
    end
    $game_system.se_play($data_system.decision_se)
    @scene_flag, @temp_window = false, ''
  end
    
  def wipe_party
    $game_party.actors.each {|actor| actor.not_available = true if actor != nil}
    setup_forced_party(true)
    if $game_party.actors == []
      (1...$data_actors.size).each {|i|
          if !$game_actors[i].not_available ||
              $game_actors[i].disabled_for_party
            $game_party.actors.push($game_actors[i])
            return
          end}
    end
  end
  
  def setup_forced_party(flag = false)
    $game_party.actors, party = [], []
    (1...$data_actors.size).each {|i|
        if $game_actors[i] != nil && $game_actors[i].must_be_in_party &&
             (!$game_actors[i].disabled_for_party || flag) &&
             !$game_actors[i].not_available
          party.push($game_actors[i])
        end}
    party.clone.each {|actor|
        if actor.forced_position != nil
          $game_party.actors[actor.forced_position] = actor
          party.delete(actor)
        end}
    $game_party.actors.each_index {|i|
        $game_party.actors[i] = party.shift if $game_party.actors[i] == nil}
    $game_party.actors += party.compact
  end  
  
  def swap_parties
    $game_party.actors.compact!
    temp_actors = $game_party.actors
    temp_actors.each {|actor| actor.not_available = true}
    $game_system.stored_party.compact!
    $game_system.stored_party.each {|actor| actor.not_available = false}
    $game_party.actors = $game_system.stored_party
    $game_system.stored_party = (@store == 1 ? temp_actors : nil)
  end
  
  def call_warning?(index, actor2)
    return (BlizzCFG::ALLOW_EMPTY_PARTY || $game_party.actors[index] == nil ||
        actor2 != nil || $game_party.actors.nitems > 1)
  end
  
  def warning(type)
    $game_system.se_play($data_system.buzzer_se)
    @warning_window = Window_Warning.new(type, @reserve_window.get_number)
    loop do
      Graphics.update
      Input.update
      if Input.trigger?(Input::C)
        $game_system.se_play($data_system.decision_se) if type > 0
        [@current_window, @reserve_window].each {|win| win.refresh}
        @warning_window.dispose
        @warning_window = nil
        break
      end
    end
  end
  
end

#==============================================================================
# Scene_Battle
#==============================================================================
  
class Scene_Battle
  
  alias update_phase2_eps_later update_phase2
  def update_phase2
    update_phase2_eps_later
    if Input.trigger?(Input::C) && @party_command_window.index == 2
      $game_system.se_play($data_system.decision_se)
      @spriteset.dispose
      $scene = Scene_PartySwitcher.new
      $scene.main
      $scene = self
      @spriteset = Spriteset_Battle.new
      15.times {@spriteset.update}
      @status_window.refresh
      Graphics.transition(0)
    end
  end
  
  alias start_phase5_eps_later start_phase5
  def start_phase5
    exp = 0
    oldexp = 0
    if $game_party.actors.size > 0
      oldexp = $game_party.actors[0].exp
      start_phase5_eps_later
      exp = $game_party.actors[0].exp - oldexp if $game_party.actors.size > 0
    else
      start_phase5_eps_later
    end
    exp = @result_window.exp if exp == 0 && @result_window != nil
    exp = @exp if exp == 0 && @exp != nil
    if exp > 0
      (1...$data_actors.size).each {|i|
          if !$game_party.actors.include?($game_actors[i])
            if $game_actors[i].not_available
              addexp = exp * BlizzCFG::EXP_NOT_AVAILABLE / 100
            elsif $game_actors[i].disabled_for_party
              addexp = exp * BlizzCFG::EXP_DISABLED_FOR_PARTY / 100
            else
              addexp = exp * BlizzCFG::EXP_RESERVE / 100
            end
            $game_actors[i].exp += addexp
          end}
    end
  end
  
end
