#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# CLRS + Blizz-ABS plugin by Blizzard
# Version: 1.21b
# Requires Blizz-ABS v2.7 or higher
# Requires CRLS v6.1b or higher
# Type: Compatibility plugin
# Date: 14.7.2008
# Date v1.0b: 1.8.2008
# Date v1.01b: 23.11.2008
# Date v1.02b: 25.11.2008
# Date v1.03b: 27.11.2008
# Date v1.1b: 1.12.2008
# Date v1.2b: 13.12.2008
# Date v1.21b: 28.11.2009
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# 
# IMPORTANT NOTE:
# 
#   Special Thanks to GuardianAngelX72 for the idea for Chaos Drive.
# 
# 
# Compatibility:
# 
#   Same compatiblity as CLRS v6.1b or higher. Makes CRLS compatible with
#   Blizz-ABS. Requires at least Blizz-ABS v2.7 and CRLS v6.1b. This script
#   comes BELOW Blizz-ABS and CRLS.
# 
# 
# Features:
# 
#   - makes Soul Rage System, Soul Limit System and Chaos Drive System
#     compatible with Blizz-ABS and allows their usage on the map
#   - adds SRS, SLS and CDS skills to the hotkey assignment menu
#   - add SR bar to the HUD if using DRAW_SR
# 
# new in 1.0b:
#   - better compatibility
#   - now removes Chaos Drive if status effect disappears on the map
#   - added compatibility variable
#   - now killed Chaos Drives on the map don't cause a Game Over if other
#     actors are still alive
#   - optionally reverts Chaos Drives when not "in battle"
#   - now beta
# 
# new in 1.01b:
#   - better compatibility with Blizz-ABS v2.0
# 
# new in 1.02b:
#   - more compatibility with Blizz-ABS v2.0
# 
# new in 1.03b:
#   - even more compatibility with Blizz-ABS v2.0
# 
# new in 1.1b:
#   - now fully compatible with Blizz-ABS v2.0
# 
# new in 1.2b:
#   - fixed problems with allies using Chaos Drives
#   - now summons cannot use Chaos Drives
# 
# new in 1.21b:
#   - now fully compatible with Blizz-ABS v2.7
# 
# 
# General configuration:
# 
#   SR_ADD         - text displayed in front of SR skill names in the hotkey
#                    assignment menu
#   SL_ADD         - text displayed in front of SL skill names in the hotkey
#                    assignment menu
#   CD_ADD         - text displayed in front of CD skill names in the hotkey
#                    assignment menu
#   CD_BATTLE_ONLY - when Blizz-ABS is disabled Chaos Drives will be reverted
#                    automatically
#   CD_AUTO_REVERT - sets the Chaos Drive actor's skill to reversal upon
#                    transformation automatically
# 
# 
# Important note:
# 
#   Chaos Drives are not normal skills and should be NOT used as such. Chaos
#   Drive skills as normal skills will not make a transformation happen. Do not
#   assign two different characters the same Chaos Drive character. If you want
#   them to access the same character, make a duplicate CD character in your
#   database. Keep in mind that Blizz-ABS Summons cannot use Chaos Drive.
# 
# 
# If you find any bugs, please report them here:
# http://forum.chaos-project.com
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

if !$BlizzABS || BlizzABS::VERSION < 2.7
  raise 'Blizz-ABS v2.7 or higher not found! RMXP will now close.'
elsif $crls == nil || $crls < 6.1
  raise 'CRLS v6.1 or higher not found! RMXP will now close.'
end

module BlizzCFG
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  SR_ADD = 'SR '
  SL_ADD = 'SL '
  CD_ADD = 'CD '
  CD_BATTLE_ONLY = true
  CD_AUTO_REVERT = true
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end

# for compatibility
$crls_blizzabs = 1.21

#==============================================================================
# BlizzABS::Cache
#------------------------------------------------------------------------------
#  This class was modified to add command damage colors.
#==============================================================================

class BlizzABS::Cache
  
  DMGColors[BlizzCFG::CDS_NAME] = BlizzCFG::CHAOS_COLOR
  DMGColors[BlizzCFG::REVERT_NAME] = BlizzCFG::REVERT_COLOR
  
end

#==============================================================================
# BlizzABS::Processor
#------------------------------------------------------------------------------
#  This class was modified to allow that CD host actors gain EXP.
#==============================================================================

class BlizzABS::Processor
  
  #----------------------------------------------------------------------------
  # override exp_result
  #----------------------------------------------------------------------------
  alias exp_result_crlsabs_later exp_result
  def exp_result(enemy)
    # gain EXP for normal actors
    exp = exp_result_crlsabs_later(enemy)
    # if party was removed
    if BlizzCFG::REMOVE_PARTY
      # each actor of the original party gains EXP
      $game_system.chaos_party.each {|actor| actor.exp += exp}
    else
      # for each actor
      $game_party.actors.each {|actor|
          # if in CD mode
          if actor.states.include?(BlizzCFG::CD_ID)
            # original actor gains exp
            BlizzCFG.find_chaos(actor.id).exp += exp
          end}
    end
  end
  
end

#==============================================================================
# BlizzABS::Utility
#------------------------------------------------------------------------------
#  This class was enhanced to support additional skill selection for Trigger
#  AI actions.
#==============================================================================

class BlizzABS::Utility
  
  #----------------------------------------------------------------------------
  # override get_actor_skills
  #----------------------------------------------------------------------------
  alias get_actor_skills_crlsabs_later get_actor_skills
  def get_actor_skills(actor)
    skills = get_actor_skills_crlsabs_later(actor) + actor.sr_skills
    skills += actor.cd_skills unless BlizzCFG::REMOVE_PARTY
    skills.push(actor.limit_id)
    skills.delete(0)
    return skills
  end
  
end

#==============================================================================
# Game_Actor
#------------------------------------------------------------------------------
#  This class was modified with extra methods for convenience.
#==============================================================================

class Game_Actor
  
  #----------------------------------------------------------------------------
  # sr_skills
  #  Returns an array of all SR skills available
  #----------------------------------------------------------------------------
  def sr_skills
    # SR skills
    ids = []
    # weapon and armor IDs
    weapons, armors = self.sr_equipment
    # get all weapon skills
    weapons.each {|id| ids += BlizzCFG.sr_database(id, true)}
    # get all armor skills
    armors.each {|id| ids += BlizzCFG.sr_database(id, false)}
    # return without duplicates and non-existant skills
    return ((ids | ids) - [0])
  end
  #----------------------------------------------------------------------------
  # override cant_get_exp?
  #----------------------------------------------------------------------------
  alias cant_get_exp_crlsabs_later? cant_get_exp?
  def cant_get_exp?
    return (@states.include?(BlizzCFG::CD_ID) || cant_get_exp_crlsabs_later?)
  end
  
end

#==============================================================================
# Map_Battler
#------------------------------------------------------------------------------
#  This class serves as superclass for characters that fight on the map and
#  can use pixel movement.
#==============================================================================

class Map_Battler
  
  #----------------------------------------------------------------------------
  # override skill_can_use?
  #----------------------------------------------------------------------------
  alias skill_can_use_crlsabs_later? skill_can_use?
  def skill_can_use?(id)
    # if actor
    if self.is_a?(Map_Actor)
      # return SL usage if it's his SL skill
      return @battler.sl_can_use? if id == @battler.limit_id
      # return SR usage if it's an SR skill
      return @battler.sr_can_use?(id) if @battler.sr_skills.include?(id)
    end
    # return normal usage
    return skill_can_use_crlsabs_later?(id)
  end
  #----------------------------------------------------------------------------
  # skill_consumption
  #  skill - the skill that was used
  #  Processes aftermath of using a skill.
  #----------------------------------------------------------------------------
  alias skill_consumption_crlsabs_later skill_consumption
  def skill_consumption(skill)
    # if not actor
    unless self.is_a?(Map_Actor)
      # normal skill consumption method
      skill_consumption_crlsabs_later(skill)
      # abort method
      return
    end
    # if this is an SR skill
    if @battler.sr_skills.include?(skill.id)
      # SR consumption
      @battler.sr -= skill.sp_cost * 10
    # if this is an SL skill
    elsif skill.id == @battler.limit_id
      # SL consumption
      @battler.use_limit
    # if this is a CD skill
    elsif @battler.cd_skills.include?(skill.id)
      # expects Chaos Drive transformation
      @pending_cd = skill.id
    else
      # normal skill consumption method
      skill_consumption_crlsabs_later(skill)
    end
  end
  #----------------------------------------------------------------------------
  # override update_states
  #----------------------------------------------------------------------------
  alias update_states_crlsabs_later update_states
  def update_states
    # stop if battler doesn't exist
    return if battler == nil
    # get CD mode
    chaos_drive = battler.states.include?(BlizzCFG::CD_ID)
    # call original method
    update_states_crlsabs_later
    # if CD mode earlier and either expired or request for reversal
    if chaos_drive && (!battler.states.include?(BlizzCFG::CD_ID) ||
        @pending_cd != nil && @pending_cd != 0 &&
        battler.states.include?(BlizzCFG::CD_ID))
      # set to reversal
      @pending_cd = 0
    end
    # if requesting CD mode change
    if @pending_cd == 0 && self.in_action <= 0 || @pending_cd != nil &&
        @pending_cd != 0
      # if not summoned
      unless $BlizzABS.summoned?(self)
        # get index in party
        index = self.battler.index
        # if requesting reversal
        if @pending_cd == 0
          # revert CD
          @battler.revert_chaos
          # recover if not using STAY_DAMAGE option
          @battler.recover_all unless BlizzCFG::STAY_DAMAGE
          # clear up garbage timers
          check_states
          # request a damage sprite
          $BlizzABS.util.request_damage_sprite(self, BlizzCFG::REVERT_NAME)
        else
          # activate CD
          @battler.use_chaos(@pending_cd)
          # if remove_party
          if BlizzCFG::REMOVE_PARTY
            # temporary variable is first actor
            actor = $game_party.actors[0]
          else
            # temporary variable is current actor
            actor = $game_party.actors[index]
          end
          # set CD character's skill to revert
          actor.skill = @pending_cd if BlizzCFG::CD_AUTO_REVERT
          # request a damage sprite
          $BlizzABS.util.request_damage_sprite(self, BlizzCFG::CDS_NAME)
        end
        # not in action if not valid anymore
        @in_action = 0 unless self.valid?
        # refresh player
        $game_player.refresh
      end
      # remove transformation flag
      @pending_cd = nil
    end
    # remove transformation flag if set on removal
    @pending_cd = nil if @pending_cd == 0 && self.in_action <= 0 
  end
  
end

#==============================================================================
# Hud
#------------------------------------------------------------------------------
#  This class was modified to display an SR bar instead of the EXP.
#==============================================================================

class Hud < Sprite
  
  if BlizzCFG::DRAW_SR
  #----------------------------------------------------------------------------
  # override create_positions
  #----------------------------------------------------------------------------
  alias create_positions_crlsabs_later create_positions
  def create_positions
    # call original method
    create_positions_crlsabs_later
    # set SR position taking into account other plugins
    @sr_x, @sr_y = 4, 49 + @hud_height - @original_height
    # increase other positions
    @hud_height += 16
    @hot_y += 16
    @left_y += 16
  end
  #----------------------------------------------------------------------------
  # override draw_basic
  #----------------------------------------------------------------------------
  alias draw_basic_crlsabs_later draw_basic
  def draw_basic
    # call original method
    draw_basic_crlsabs_later
    # determine color depending on HUD style
    color = case BlizzABS::Config::HUD_TYPE
    when 0 then Color.new(255, 255, 255, 192)
    when 1 then Color.new(0, 0, 0, 0)
    end
    # fill with grey rectangle if color exists
    self.bitmap.fill_rect(@sr_x+32, @sr_y+3, 116, 14, color) if color.is_a?(Color)
    # fill with grey rectangle
    self.bitmap.fill_rect(@sr_x, @sr_y, 32, 20, Color.new(0, 0, 0, 128))
    # set font color
    self.bitmap.font.color = system_color
    # draw "SR"
    self.bitmap.draw_text_full(@sr_x, @sr_y, 80, 20, BlizzCFG::SR_NAME)
    # set font color
    self.bitmap.font.color = normal_color
  end
  #----------------------------------------------------------------------------
  # override draw_empty
  #----------------------------------------------------------------------------
  alias draw_empty_crlsabs_later draw_empty
  def draw_empty
    # call original method
    draw_empty_crlsabs_later
    # draw empty bars
    self.bitmap.gradient_bar_hud(@sr_x+32, @sr_y+3, 114, 0, 'hud_red_bar')
    # set font color
    self.bitmap.font.color = disabled_color
    # draw empty SR
    self.bitmap.draw_text_full(@sr_x+54, @sr_y, 84, 20, '0,0%', 2)
    # reset flag variable
    @sr = nil
  end
  #----------------------------------------------------------------------------
  # draw_sr
  #  Draws the SR display.
  #----------------------------------------------------------------------------
  def draw_sr
    # set current variable
    @sr = actor.sr
    # set fill rate
    rate = actor.sr / 1000.0
    # draw gradient bar
    self.bitmap.gradient_bar_hud(@sr_x+32, @sr_y+3, 114, rate, 'hud_red_bar')
    # set font color
    self.bitmap.font.color = normal_color
    # draw EXP required for next level
    self.bitmap.draw_text_full(@sr_x+54, @sr_y, 84, 20, actor.sr_text, 2)
  end
  #----------------------------------------------------------------------------
  # override update
  #----------------------------------------------------------------------------
  alias upd_crlsabs_later update
  def update
    # if HUD needs refresh draw sr, otherwise test sr if actor exists
    $game_temp.hud_refresh ? draw_sr : test_sr if actor != nil
    # call original method
    upd_crlsabs_later
  end
  #----------------------------------------------------------------------------
  # test_sr
  #  Tests and draws the SR.
  #----------------------------------------------------------------------------
  def test_sr
    # draw new SR if SR or max SR have changed
    draw_sr if actor.sr != @sr
  end
  end
  #----------------------------------------------------------------------------
  # override get_skills_left
  #----------------------------------------------------------------------------
  alias get_skills_left_crls_later get_skills_left
  def get_skills_left
    # if skill hot skill exists
    if @skill != nil && @skill > 0
      # if this is a CD skill
      if actor.cd_skills.include?(@skill)
        # return 1 if already in CD mode
        return 1 if actor.states.include?(BlizzCFG::CD_ID)
        # CD usages left
        return (actor.cd_can_use? ? actor.cd_left : 1)
      # if this is an SL skill
      elsif actor.limit_id == @skill
        # SL usages left
        return (actor.sl_can_use? ? actor.sl_left : 1)
      # if this is an SR skill
      elsif actor.sr_skills.include?(@skill)
        # SR usages left
        return actor.sr_left(@skill)
      end
    end
    # normal skill number
    return get_skills_left_crls_later
  end
  
end

#==============================================================================
# Scene_Map
#------------------------------------------------------------------------------
#  This class was modified to change the party setup and revert Chaos Drives
#  so there is no Game Over.
#==============================================================================

class Scene_Map
  
  #----------------------------------------------------------------------------
  # exit_chaos
  #  dead - flag to determine whether dead or simply transforming back
  #  This method processes the data that allows actors to return to their
  #  normal form.
  #----------------------------------------------------------------------------
  def exit_chaos(dead = true)
    # reverted flag
    flag = false
    # for all actors in the party
    $game_party.actors.each {|actor|
        # if CD actor and either reverting or dead
        if actor.states.include?(BlizzCFG::CD_ID) && (dead || actor.dead?)
          # get index
          index = actor.index
          # revert action
          actor.revert_chaos
          actor.recover_all unless BlizzCFG::STAY_DAMAGE
          # set damage text
          $game_party.actors[index].damage = nil
          # at least one reversal
          flag = true
        end}
    # refresh player if reverted at least one actor
    $game_player.refresh if flag
  end
  #----------------------------------------------------------------------------
  # override test_in_battle
  #----------------------------------------------------------------------------
  alias test_in_battle_crlsabs_later test_in_battle
  def test_in_battle
    # call original method
    test_in_battle_crlsabs_later
    # if really not in battle
    if BlizzCFG::CD_BATTLE_ONLY && !$game_temp.in_battle &&
        !$game_system.map_interpreter.running? &&
        !$game_temp.message_window_showing
      # revert Chaos Drives
      exit_chaos
    end
  end
  #----------------------------------------------------------------------------
  # override judge
  #----------------------------------------------------------------------------
  alias judge_crlsabs_later judge
  def judge
    # revert Chaos Drives that need to be reverted
    exit_chaos(false)
    # return judge now
    return judge_crlsabs_later
  end
  
end

#==============================================================================
# Window_Skill_Hotkey
#------------------------------------------------------------------------------
#  This class was modified to allows special display for selection of SRS,
#  SLS and CDS skills.
#==============================================================================

class Window_Skill_Hotkey < Window_Skill
  
  #----------------------------------------------------------------------------
  # override setup_skills
  #----------------------------------------------------------------------------
  alias setup_skills_crlsabs_later setup_skills
  def setup_skills
    # call original method
    setup_skills_crlsabs_later
    # all data arrays
    @sr_skills, @cd_skills, @sl_skills = [], [], []
    # if this actor can use SRS
    if BlizzCFG::SR_USERS.include?(@actor.id)
      # add all SR skills
      @actor.sr_skills.each {|id| @sr_skills.push($data_skills[id])}
    end
    # if this actor can use SLS
    if BlizzCFG::SL_USERS.include?(@actor.id) && @actor.limit_id != 0
      # add all SL skills
      @sl_skills.push($data_skills[@actor.limit_id])
    end
    # if this actor can use CDS
    if BlizzCFG::CD_USERS.include?(@actor.id)
      # add all CD skills
      @actor.cd_skills.each {|id| @cd_skills.push($data_skills[id])}
    end
    # increase skill count
    @item_max += @sr_skills.size + @sl_skills.size + @cd_skills.size
  end
  #----------------------------------------------------------------------------
  # override draw_skills
  #----------------------------------------------------------------------------
  alias draw_skills_crlsabs_later draw_skills
  def draw_skills
    # decrease skill count
    @item_max -= @sr_skills.size + @cd_skills.size + @sl_skills.size + 1
    # call original method
    draw_skills_crlsabs_later
    # remove nil from end
    @data.pop
    # modify data
    @data += @sr_skills + @sl_skills + @cd_skills + [nil]
    # get size boundries
    size_sr = @item_max + @sr_skills.size
    size_sl = size_sr + @sl_skills.size
    size_cd = size_sl + @cd_skills.size
    # draw each SR skill
    (@item_max...size_sr).each {|i| draw_sr(i)}
    # draw each SL skill
    (size_sr...size_sl).each {|i| draw_sl(i)}
    # draw each CD skill
    (size_sl...size_cd).each {|i| draw_cd(i)}
    # increase skill count again
    @item_max = size_cd + 1
    # draw remove text
    draw_item(size_cd)
  end
  #----------------------------------------------------------------------------
  # draw_item
  #  i - skill index
  #  Draws one complete skill.
  #----------------------------------------------------------------------------
  def draw_sr(i)
    # if skill can be used
    if @actor.sr_can_use?(@data[i].id)
      # set font color
      self.contents.font.color = normal_color
    else
      # set font color
      self.contents.font.color = disabled_color
    end
    # draw skill data
    draw_data(i, BlizzCFG::SR_ADD)
    # draw skill SR cost
    self.contents.draw_text(236, i*32, 48, 32, "#{@data[i].sp_cost}%", 2)
  end
  #----------------------------------------------------------------------------
  # draw_sl
  #  i - skill index
  #  Draws one complete SL skill.
  #----------------------------------------------------------------------------
  def draw_sl(i)
    # if skill can be used
    if @actor.sl_can_use?
      # set font color
      self.contents.font.color = normal_color
    else
      # set font color
      self.contents.font.color = disabled_color
    end
    # draw skill data
    draw_data(i, BlizzCFG::SL_ADD)
  end
  #----------------------------------------------------------------------------
  # draw_cd
  #  i - skill index
  #  Draws one complete CD skill.
  #----------------------------------------------------------------------------
  def draw_cd(i)
    # if skill can be used
    if @actor.cd_can_use?
      # set font color
      self.contents.font.color = normal_color
    else
      # set font color
      self.contents.font.color = disabled_color
    end
    # draw skill data
    draw_data(i, BlizzCFG::CD_ADD)
  end
  #----------------------------------------------------------------------------
  # draw_data
  #  i   - skill index
  #  add - text added to name
  #  Draws common parts of any skill.
  #----------------------------------------------------------------------------
  def draw_data(i, add)
    # clean this display
    self.contents.fill_rect(Rect.new(4, i*32, 288, 32), Color.new(0, 0, 0, 0))
    # get icon bitmap
    bitmap = RPG::Cache.icon(@data[i].icon_name)
    # get opacity
    opacity = self.contents.font.color == normal_color ? 255 : 128
    # draw icon bitmap
    self.contents.blt(4, 4+i*32, bitmap, Rect.new(0, 0, 24, 24), opacity)
    # draw text with name
    self.contents.draw_text(32, i*32, 204, 32, add + @data[i].name)
  end
  
end
