# )----------------------------------------------------------------------------(
# )--     AUTHOR:     Mr Trivel                                              --(
# )--     NAME:       Simple Battle Rows                                     --(
# )--     CREATED:    2014-06-15 (2014-07-10)                                --(
# )--     VERSION:    1.2                                                    --(
# )----------------------------------------------------------------------------(
# )--                         VERSION HISTORY                                --(
# )--  1.2  - Some skills can ignore battle row positions and deal full dmg. --(
# )--  1.1b - Displayed damage is fixed.                                     --(
# )--  1.1a - Enemies have rows, too.                                        --(
# )--  1.1  - Attacks while attacking from back row will deal less  damage   --(
# )--  than from front row. User can set up exceptions like ranged weapons   --(
# )--  or long reaching melee weapons.                                       --(
# )--  1.0  - Initial Script                                                 --(
# )----------------------------------------------------------------------------(
# )--                          DESCRIPTION                                   --(
# )--  This scripts adds basic Battle Row functionality. You can switch rows --(
# )--  in menu Formation command by selecting same Actor twice.              --(
# )--  Battlers in backrow will receive less damage than the ones in the front.(
# )--  Battlers in backrow will receive same damage if front row is wiped.   --(
# )--  Battlers attacking from back row will have damage penalty, unless     --(
# )--  stated in exceptions.                                                 --(
# )----------------------------------------------------------------------------(
# )--                          INSTRUCTIONS                                  --(
# )--   Use <backrow> note tag for enemies to set them in Back Row.          --(
# )--                     Plug, Custmomize, Play.                            --(
# )----------------------------------------------------------------------------(
# )--                          LICENSE INFO                                  --(
# )--  [url]http://mrtrivelvx.wordpress.com/terms-of-use/[/url]                         --(
# )----------------------------------------------------------------------------(

module MrTS
  module Formation
    # )------------------------------------------------------------------------(
    # )--  0.6 - means backrow takes 60% of the damage                       --(
    # )--  0.7 - 70%, 0.3 - only 30%, etc...                                 --(
    # )------------------------------------------------------------------------(
    DAMAGE_BACKROW_TAKEN = 0.5
    
    # )------------------------------------------------------------------------(
    # )--  0.4 - means Backrow only deals 40% of the damage, unless the      --(
    # )--  weapon type is in no_penalty_backrow_weapon_ids list.             --(
    # )------------------------------------------------------------------------(
    DAMAGE_BACKROW_DEALT = 0.4
    
    # )------------------------------------------------------------------------(
    # )--  Weapon settings. Back row: You can only attack with them in       --(
    # )--  backrow.( Front row: You can only attack with them in front row.  --(
    # )------------------------------------------------------------------------(
    BACKROW_WEAPON_IDS = [3]
    FRONTROW_WEAPON_IDS = []
    
    # )------------------------------------------------------------------------(
    # )--  Weapon type with these IDs won't receive a damage penalty while   --(
    # )--  attacking with them in the backrow. (For ranged weapons/polearms) --(
    # )------------------------------------------------------------------------(
    NO_PENALTY_BACKROW_WEAPON_IDS = [3, 4]
    
    # )------------------------------------------------------------------------(
    # )--  Skills with IDs listed in the array won't have it's damage        --(
    # )--  penalized when using from back row or on a back row battler.      --(
    # )------------------------------------------------------------------------(
    NO_PENALTY_SKILL_IDS = [12]
  end
end

$imported ||= {} ; $imported["MrTS_Simple_Battle_Rows"] = true

# )---------------------------(
# )--  Class: Game_Battler  --(
# )---------------------------(
class Game_Battler < Game_BattlerBase  
  # )---------------------------------(
  # )--  Public Instance Variables  --(
  # )---------------------------------(
  attr_reader :battle_row
  
  # )--------------------------(
  # )--  Method: initialize  --(
  # )--------------------------(
  alias mrts_initialize_b initialize
  def initialize
    mrts_initialize_b
    @battle_row = 0
  end
  
  # )------------------------------(
  # )--  New Method: switch_row  --(
  # )------------------------------(
  def switch_row
    if @battle_row == 0
      @battle_row = 1
    else
      @battle_row = 0
    end
  end
  
  # )-------------------------------------------(
  # )--  Overwrite Method: make_damage_value  --(
  # )-------------------------------------------(
  def make_damage_value(user, item)
    value = item.damage.eval(user, self, $game_variables)
    value *= item_element_rate(user, item)
    value *= pdr if item.physical?
    value *= mdr if item.magical?
    value *= rec if item.damage.recover?
    value = apply_critical(value) if @result.critical
    value = apply_variance(value, item.damage.variance)
    if item.is_a?(RPG::Skill) && !MrTS::Formation::NO_PENALTY_SKILL_IDS.include?(item.id)
      value *= MrTS::Formation::DAMAGE_BACKROW_TAKEN if self.battle_row == 1 && self.is_front_row?
      if user.is_a?(Game_Actor)
        value *= MrTS::Formation::DAMAGE_BACKROW_DEALT if user.penalty_damage?
      end
    end
    value = apply_guard(value)
    @result.make_damage(value.to_i, item)
  end
  
  # )---------------------------------(
  # )--  New Method: is_front_row?  --(
  # )---------------------------------(
  def is_front_row?
    return $game_party.get_frontrow_size > 0 if self.is_a?(Game_Actor)
    return $game_troop.get_frontrow_size > 0 if self.is_a?(Game_Enemy)
  end
end

# )--------------------------------(
# )--  Class: Window_MenuStatus  --(
# )--------------------------------(
class Window_MenuStatus < Window_Selectable
  # )-----------------------------------(
  # )--  Overwrite Method: draw_item  --(
  # )-----------------------------------(
  def draw_item(index)
    actor = $game_party.members[index]
    enabled = $game_party.battle_members.include?(actor)
    rect = item_rect(index)
    draw_item_background(index)
    draw_actor_face(actor, rect.x + 1 + 10*actor.battle_row, rect.y + 1, enabled)
    draw_actor_simple_status(actor, rect.x + 108, rect.y + line_height / 2)
  end
end

# )-------------------------(
# )--  Class: Scene_Menu  --(
# )-------------------------(
class Scene_Menu < Scene_MenuBase
  # )-------------------------------=---------(
  # )--  Overwrite Method: on_formation_ok  --(
  # )----------------------------------=------(
  def on_formation_ok
    if @status_window.pending_index >= 0
      $game_party.swap_order(@status_window.index,
                             @status_window.pending_index)
      if @status_window.pending_index == @status_window.index
        $game_party.members[@status_window.index].switch_row
        @status_window.redraw_item(@status_window.index)
      end
      @status_window.pending_index = -1
      @status_window.redraw_item(@status_window.index)
    else
      @status_window.pending_index = @status_window.index
    end
    
    @status_window.activate
  end
end

# )-------------------------(
# )--  Class: Game_Party  --(
# )-------------------------(
class Game_Unit
  # )------------------------------------(
  # )--  New Method: get_backrow_size  --(
  # )------------------------------------(
  def get_backrow_size
    size = 0
    battle_members.each do |memb|
      size += 1 if memb.alive? && memb.battle_row == 1
    end
    
    return size
  end
  
  # )-------------------------------------(
  # )--  New Method: get_frontrow_size  --(
  # )-------------------------------------(
  def get_frontrow_size
    size = 0
    alive_members.each do |memb|
      size += 1 if memb.battle_row == 0
    end
    
    return size
  end
end

# )-------------------------(
# )--  Class: Game_Actor  --(
# )----------------0--------(
class Game_Actor < Game_Battler
  # )----------------------------------------(
  # )--  New Method: get_weapon_row        --(
  # )----------------------------------------(
  def get_weapon_row
    weapons.each do |w| 
      if MrTS::Formation::BACKROW_WEAPON_IDS.include?(w.wtype_id)
        return 1
      elsif MrTS::Formation::FRONTROW_WEAPON_IDS.include?(w.wtype_id)
        return 0
      end
    end
    return 2 # both rows
  end
  
  # )----------------------------------------(
  # )--  New Method: penalty_damage?       --(
  # )----------------------------------------(
  def penalty_damage?
    weapons.each do |w| 
      if (MrTS::Formation::NO_PENALTY_BACKROW_WEAPON_IDS.include?(w.wtype_id) && @battle_row == 1) || @battle_row == 0
        return false
      end
    end
    return true
  end
end

# )-------------------------(
# )--  Class: Game_Enemy  --(
# )-------------------------(
class Game_Enemy < Game_Battler
  
  # )---------------------------------(
  # )--  Alias To: initialize       --(
  # )---------------------------------(
  alias mrts_initialize initialize
  def initialize(*args)
    mrts_initialize(*args)
    @battle_row = enemy.note =~ /<backrow>/i ? 1 : 0
  end
end

# )----------------------------------(
# )--  Class: Window_ActorCommand  --(
# )----------------------------------(
class Window_ActorCommand < Window_Command
  #--------------------------------------------------------------------------
  # * Add Attack Command to List
  #--------------------------------------------------------------------------
  def add_attack_command
    add_command(Vocab::attack, :attack, @actor.attack_usable? && [@actor.battle_row, 2].include?(@actor.get_weapon_row))
  end
end