#============================================================================
# Equipment Sets v1.6
# By Emerald
#----------------------------------------------------------------------------
# You're free to use the script for any game, as long as you give credits
#----------------------------------------------------------------------------
# Version History
# 1.0 -> Script fully ready for public use. Addes sets, unlimited set items,
#        set bonuses for the 8 basic stats, set bonuses requirement (how many
#        items of the set is the actor wearing?)
# 1.1 -> a. changed the set bonuses work. Instead of [parameter, bonus] you now
#        use [sort, parameter, bonus]. Also added sorts 0 and 2. Check SPECIAL
#        VALUES for their corresponding parameters.
#        b. Added sort 1: Standard Parameters (Percentage). The corresponding
#        parameters are the same as for sort 0. See SPECIAL VALUES for extra
#        notes.
# 1.2 -> Added Sort 3: Special Parameters. The values for the parameters can be
#        found in SPECIAL VALUES, just as usual. Addes Sort 4: Skills!! These
#        use a different syntax than the other bonuses, so be sure to check
#        SPECIAL VALUES if you are unfamiliar with them.
# 1.3 -> a. rewritten most of the code to remove so major bugs. Also cleaned
#        code (about 140 lines less this time, WITH 4 added Sorts). Added
#        Module Emerald (EME). Sets and Set_Bonuses move to Module EME. Added
#        MAX_ELEMENTS to Module EME. Added Sort 5 (Elemental Efficiency), Sort
#        6 (Debuff Rate), Sort 7 (State Rate), Sort 8 (State Resist) and Sort 9
#        (Attack Elements). See SPECIAL VALUES for instructions.
#        WARNING these are still in Beta Stage, so report all bugs found.  
#        b. removed many, MANY major bugs! Removed a bug where unequipping
#        resulted in an undefined array, removed some typos, fixed the bonuses
#        for almost EVERY Sort, removed some more typos, shortened code a little
#        bit, removed some more minor bugs regarding change_equip.
# 1.4 -> More bug fixes. Also added Sort 10 (Attack States), Sort 11 (Equipment
#        Types) and Sort 12 (Attack Specials). Refer to SPECIAL VALUES for
#        all needed information.
# 1.5 -> Bug fix to discard_equip(...). Added the foruth value of Sort 11
#        (Dual Wielding), added Sort 13, Sort 14, Sort 15, Sort 16 and Sort 17
#        which are Additional Skill Types, Sealed Skill Types, Sealed Skills,
#        Fixed Equip Types and Sealed Equip Types respectively. As usual, go to
#        SPECIAL VALUES for the needed instructions.
# 1.6 -> Added a compatibility patch for Fomar's Dual Wield -> Free Hands script.
#----------------------------------------------------------------------------
# Started with a Iron Sword? Pretty good. Found a Gold Sword? Awesome! Found
# the complete Bronze Set? Bad stuff...
# Unless, they give you bonuses! In other words, this script allows you to create
# bonuses for wearing multiple items of a set... Just wanted to make it sound
# more fun...
#
# Instructions:
#
# Just as always, put this script between ▼ Materials and ▼ Main. Put this script
# below any script which rewrites change_equip and above any script which aliases
# 'param' in Game_Actor (usually in Game_BattlerBase, but it only matters if it
# is rewritten/aliased in Game_Actor).
#
# Set MAX_ELEMENTS below module EME and above Sets to the maximum number of
# elements in the database. Else, the script won't recognize any above the value.
#
#
# SETS
#
# To create sets (sorry, no names yet) go to Sets in the configuration part.
# Add the set id, followed by an array containing arrays. These arrays must be
# at least two elements long, one for the type of equipment, one for the id.
# Examples:
#
# 1 => [[0, 1], [1, 2], [0, 1000]],
# 2 => [[0, 5], [0, 6], [1, 5], [1,7], [0, 1000]],
# set id => [[equipment type, equipment id], [equipment type, equipment id]]
#
# NOTE:
# The set id cannot be lower than 1. The equipment types are 0 (weapons) and 1
# (armors). When one of the arrays (either sets or arrays in a set) is not the
# last one, don't forget to add a comma.
# ALWAYS put an array with an id which doesn't exist (standard 1000+) in the
# database. Else, the final piece of equipment specified will be counted for 2.
# And that can result in some weird bonuses o_o
# Furthermore, you can have an infinite amount of equipment belonging (is that a
# word?) to a set, so don't worry about compatibility issues with Extra Equipment
# Slots scripts. Unless they rewrite change_equip, than there's a slight chance
# on problems.
# Also, you can have multiple weapons in array and the same equipment in different
# sets.
#
#
# SET BONUSES
#
# For set bonuses, go to Set_Bonuses. Use the follwing syntax to add bonuses:
#
# set id => {
#    amount of pieces required => [[sort, parameter, bonus]], [random sort, random parameter, 0]]
#           },
#
# Specifications:
# set id = the same set id as in Sets.
#
# amount of pieces required = the amount of pieces the player must be wearing in
# order to receive the bonuses. If you want to skip one, make [random... 0] the
# only element in its array. Note that this is limited to the total items the
# actor can wear.
#
# sort = type of bonus. For all sorts, see SPECIAL VALUES.
#
# parameter = the parameter which receives the bonus. For all parameters, see
# SPECIAL VALUES.
#
# bonus = the bonus to be added to parameter. Note that this is a direct bonus,
# not a percentage. If the vale is negative, the bonus will become negative. If
# the value is 0, there will be no bonus to that stat.
#
# random sort & parameter = in this case, the script DOUBLES the last bonus! So 
# make sure to always end with either a 0 bonus to a random parameter, or with a 
# halved bonus.
#
#
# SPECIAL VALUES
# Sets
# ----
# Equipment types: 0 and 1. 0 is the Weapons tab in the database, 1 is the
# Armors tab in the database.
#
# Set_Bonuses
# ---
# Sorts:
# 0  - Standard Parameter
# 1  - Standard Parameter (Percentage)
# 2  - Extra Parameter
# 3  - Special Paramater
# 4  - Skills (WARNING, DIFFERENT SYNTAX!! See Skills on how to use them)
# 5  - Elemental Efficiency
# 6  - Debuff Rate
# 7  - State Rate
# 8  - State Resistance (WARNING, VALUE HAS A DIFFERENT FUNCTION!!)
# 9  - Attack Elements (WARNING, VALUE HAS A DIFFERENT FUNCTION!!)
# 10 - Attack States
# 11 - Equipment Types (WARNING, DIFFERENT SYNTAX!! See Equipment Types on how 
#                       to use them)
# 12 - Attack Specials
# 13 - Additional Skill Types
# 14 - Sealed Skill Types
# 15 - Sealed Skills
# 16 - Fixed Equip Types
# 17 - Sealed Equip Types
#
# Standard Parameters: (Sort 0)
# 0 - MaxHp
# 1 - MaxMp
# 2 - Attack
# 3 - Defense
# 4 - Magic Attack (Spirit)
# 5 - Magic Defence (Resistance)
# 6 - Agility
# 7 - Luck
#
# Standard Parameters (Percentage): (Sort 1)
# 0 - MaxHp
# 1 - MaxMp
# 2 - Attack
# 3 - Defense
# 4 - Magic Attack (Spirit)
# 5 - Magic Defence (Resistance)
# 6 - Agility
# 7 - Luck
# Note that it stats are calculated this way:
# Basic + Equipment Bonuses + Set Bonuses (normal) + Set Bonuses (percentages,
# equal to bonus% (in [1, parameter, bonus]) * basic + equipment bonuses)
#
# Extra Parameters: (Sort 2)
# 0 - Hit Rate
# 1 - Evasion
# 2 - Critical Rate
# 3 - Critical Evasion
# 4 - Magical Evasion
# 5 - Magical Reflection
# 6 - Counter Rate
# 7 - HP Regen
# 8 - MP Regen
# 9 - TP Regen
#
# Special Parameters: (Sort 3)
# 0 - Target Rate/ Accuracy Rate(in Eng Translation Patch)/ Aggro Rate
# 1 - Guard Effect Rate
# 2 - Recovery Effect Rate
# 3 - Pharmacology/ Knowledge in Medicine(in Eng Translation Patch)
# 4 - MP Cost Rate
# 5 - TP Charge Rate
# 6 - Physical Damage Rate
# 7 - Magical Damage Rate
# 8 - Floor Damage Rate
# 9 - Experience Rate
#
# Skills: (Sort 4)
# These skills don't have parameter values. Instead, the last two elements in 
# their array have a different effect than usual:
# [sort (4), active, skill_id]
# Sort = still the same and of course 4
# Active = ALWAYSSS!!! leave this on 0. 0 means that the actor HAS NOT learned
# the skill, but once he wears the required amount of equips, THIS BECOMES 1.
# If it doesn't become 1, than the skill won't be removed when unequipping set
# items.
# Skill_Id = the id of the skill which the actor learns.
#
# Elemental Efficiency: (Sort 5)
# Values are the same as Element IDs in the database. (SO NO 0!!)
# If the bonus is negative, the actor becomes more resistant to the element.
# If the bonus is positive, the actor becomes weaker to the element.
#
# Debuff Rate: (Sort 6)
# 0 - MaxHp
# 1 - MaxMp
# 2 - Attack
# 3 - Defense
# 4 - Magic Attack (Spirit)
# 5 - Magic Defence (Resistance)
# 6 - Agility
# 7 - Luck
# If the bonus is negative, the actor becomes more resistant to debuffs regarding
# the set parameter.
# If the bonus is positive, the actor becomes weaker to debuffs regarding the set
# parameter.
# 
# State Rate: (Sort 7)
# Values are the same as the State IDs in the database (SO NO 0!!)
# If the bonus is negative, the actor becomes more resistant to the state.
# If the bonus is positive, the actor becomes weaker to the state.
#
# State Resist: (Sort 8)
# Values are the same as the State IDs in the database (SO NO 0!!)
# If the bonus is positive, the actor becomes fully resistant to the set state.
# However, if the bonus is negative, the actor LOSES full resistance to the set
# state!
#
# Attack Elements: (Sort 9)
# Values are the same as the Element IDs in the database (SO NO 0!!)
# If the bonus is positive, the element is added to the attack elements.
# However, if the bonus is negative, the element is REMOVED from the attack 
# elements!
#
# BETA STAGE - Attack States: (Sort 10)
# Values are the same as the State IDs in the database (SO NO 0!!)
# Bonus is the chance of the state to occur.
#
# BETA STAGE - Equipment Types: (Sort 11)
# 0 as parameter means that the bonus type is a Weapon Type.
# 2 as parameter means that the bonus type is an Armor Type.
# 4 as parameter allows Dual Wielding.
# Bonus is the same as the ID of the Equipment Types in the database.
#
# BETA STAGE - Attack Specials: (Sort 12)
# 0 - Attack Speed
# 1 - Additional Attacks
# Both in percentages. So for additional attacks, not 1 but 100.
#
# Additional Skill Types: (Sort 13)
# Values are the same as the Skill Types IDs in the database (SO NO 0!!)
# If the bonus is positive, the skill types is added.
# However, if the bonus is negative, the skill type is REMOVED!
#
# Sealed Skill Types: (Sort 14)
# Exact the same as above, only if the bonus is positive the type gets sealed,
# if the bonus is negative the type gets removed from the sealed types.
#
# Sealed Skills: (Sort 15)
# Again, exact the same as above. Only this time, replace the skill type id by
# the skill id.
#
# Fixed Equip Types: (Sort 16)
# Exact the same as Sealed Skill Types, only the equip types get fixed. Of course,
# replace skill type id by equip type id.
#
# Sealed Equip Types: (Sort 17)
# And yet again, exact the same only the equip types get sealed. Of course,
# replace skill type id by equip type id.
#----------------------------------------------------------------------------
# Credits to:
# Lettuce, if it wasn't for his RMVX Item Sets script, I would not have learned
# how Arrays and Hashes work.
#----------------------------------------------------------------------------
# If you have any issues with this script, contact me at
# [url]http://www.rpgmakervxace.net/index.php?/topic/1092-ees-emeralds-equipment-sets/[/url]
#============================================================================
#
# CONFIGURATION
#
#============================================================================

module EME
  
  MAX_ELEMENTS = 10
  

#----------------------------------------------------------------------------
# Sets syntax
#----------------------------------------------------------------------------
# Sets = {
#          set_id => [[equipment_type, equipment_id]]
#        }
#
# set_id must be bigger than 0
# equipment_type can be either 0 (weapon) or 1 (armor)
# Add a comma after a ']' if it's not the last element in the array/hash.
#
# Don't forget to add a ungettable item at the end! Else, the last item will
# count for two!
#----------------------------------------------------------------------------

Sets = {
         1 => [[0, 1], [0, 1000]],
         2 => [[1, 1], [0, 1000]],
         3 => [[1, 6], [0, 1000]]
       }

#----------------------------------------------------------------------------
# Sets syntax
#----------------------------------------------------------------------------
# Set_Bonuses = {
#       set id => {
#         amount of pieces required => [[sort, parameter, bonus]], [sort, random parameter, 0]]
#                 }
#                }
#
# set_id must correspond to set_id of Sets
# amount of pieces required indicates how many pieces of the set the actor must
# be wearing before receiving the bonus. If you want to skip one, make the only
# element in it's array [0, 0, 0].
# sort indicates which kind of parameters the bonuses change. See SPECIAL VALUES
# for all sorts.
# parameter can be a value depending on sort. See SPECIAL VALUES in the 
# instructions for their corresponding stats.
# Bonus is a direct value added to 'parameter'. If 0, no bonus is added. If
# negative, bonus becomes negative.
# Random paramter is just a random parameter to prevent the last bonus from
# being doubled. Always make the bonus of this element 0.
#
# Add a comma after a ']' or '}' if it's not the last element in the array/hash.
#
# Don't forget to add a bonus of 0 at the end! Or else, the last bonus will be
# doubled!
#----------------------------------------------------------------------------
Set_Bonuses =
{
  1 => {
    1 => [["ESPS", 4, "Ubar"], [0, 0, 0]]
       },

  2 => {
    1 => [[11, 4, 0], [0, 0, 0]],
       },
       
  3 => {
    1 => [[11, 2, 4], [0, 0, 0]],
       }
}

end

# WARNING!!! THIS SCRIPT ALWAYS DOUBLES THE LAST SET BONUS!!! And no worries,
# this was the last warning.
#
# Only edit things past here if you know what you're doing

$imported = {} if $imported.nil?
$imported["Emerald's Equipment Sets"] = true

#============================================================================
#
# Game_Actor
# Handles everything for this script.
#============================================================================
class RPG::Actor < RPG::BaseItem
  
  attr_accessor :active_sets
  attr_accessor :item_sets
  
  alias eme_ebs_init initialize
  def initialize
    eme_ebs_init
    @active_sets = []
    @item_sets = [0] * (EME::Sets.size + 1)
  end
  
end

class Game_Actor < Game_Battler
  
  def setup(actor_id)
    @actor_id = actor_id
    @name = actor.name
    @nickname = actor.nickname
    init_graphics
    @class_id = actor.class_id
    @level = actor.initial_level
    @exp = {}
    @equips = []
    init_exp
    init_skills
    clear_param_plus
    reset_bonuses
    @sets_wtypes = []
    @sets_atypes = []
    init_equips(actor.equips)
    recover_all
    @active_sets = []
    @item_sets = [0] * (EME::Sets.size + 1)
  end
  
  def item_sets
    @item_sets
  end
  
  def active_sets
    @active_sets
  end
  
  alias eme_ebs_change_equip change_equip
  def change_equip(slot_id, item)
    @sets_reserved_variable = 0
    unequip_set_items_check(slot_id)
    if item != nil
      for c in 1..EME::Sets.size
        for d in 0...EME::Sets[c].size
          if EME::Sets[c][d][0] == 0 and item.is_a?(RPG::Weapon)
            if EME::Sets[c][d][1] == item.id
              @item_sets[c] += 1
              unless active_sets.include?(c)
                active_sets.push(c)
              end
            end
          elsif EME::Sets[c][d][0] == 1 and item.is_a?(RPG::Armor)
            if EME::Sets[c][d][1] == item.id
              @item_sets[c] += 1
              unless active_sets.include?(c)
                active_sets.push(c)
              end
            end
          end
        end
      end
    end
    set_check
    eme_ebs_change_equip(slot_id, item)
  end
  
  def unequip_set_items_check(slot_id)
    @sets_reserved_variable = 0
    if equips[slot_id] != nil
      for a in 1..EME::Sets.size
        for b in 0...EME::Sets[a].size
          if EME::Sets[a][b][0] == 0 and equips[slot_id].is_a?(RPG::Weapon)
            if equips[slot_id].id == EME::Sets[a][b][1]
              item_sets_change(a)
              if active_sets.include?(a) and @item_sets[a] == 0
                active_sets.delete(a)
              end
              loop do
                release_unequippable_items
                if @sets_reserved_variable == 0
                  break
                end
                break
              end
            end
          elsif EME::Sets[a][b][0] == 1 and equips[slot_id].is_a?(RPG::Armor)
            if equips[slot_id].id == EME::Sets[a][b][1]
              item_sets_change(a)
              if active_sets.include?(a) and @item_sets[a] == 0
                active_sets.delete(a)
              end
              loop do
                release_unequippable_items
                if @sets_reserved_variable == 0
                  break
                end
              end
            end
          end
        end
      end
    end
  end

  def unlearn_set_skills(set_id)
    unless set_id == 0
      pieces = set_amount_wearing(set_id)
      unless pieces <= 0
        for y in 0...EME::Set_Bonuses[set_id][pieces].size
         if EME::Set_Bonuses[set_id][pieces][y][0] == 4 and EME::Set_Bonuses[set_id][pieces][y][1] == 1
            forget_skill(EME::Set_Bonuses[set_id][pieces][y][2])
            EME::Set_Bonuses[set_id][pieces][y][1] = 0
          end
        end
      end
    end
  end
  
  def item_sets_change(set_id)
    if set_id > 0 and @item_sets[set_id] > 0
      unlearn_set_skills(set_id)
      sets_unequip_types(set_id)
      @item_sets[set_id] -= 1
    end
  end
  
  def sets_unequip_types(set_id)
    pieces = @item_sets[set_id]
    unless pieces <= 0
      for y in 0...EME::Set_Bonuses[set_id][pieces].size
        if EME::Set_Bonuses[set_id][pieces][y][0] == 11 and EME::Set_Bonuses[set_id][pieces][y][1] == 1
          change_sets_additional_wtypes(EME::Set_Bonuses[set_id][pieces][y][2], false)
          EME::Set_Bonuses[set_id][pieces][y][1] = 0
        elsif EME::Set_Bonuses[set_id][pieces][y][0] == 11 and EME::Set_Bonuses[set_id][pieces][y][1] == 3
          change_sets_additional_atypes(EME::Set_Bonuses[set_id][pieces][y][2], false)
          EME::Set_Bonuses[set_id][pieces][y][1] = 2
        elsif EME::Set_Bonuses[set_id][pieces][y][0] == 11 and EME::Set_Bonuses[set_id][pieces][y][1] == 5
          @eme_ebs_two_swords_style = false
          EME::Set_Bonuses[set_id][pieces][y][1] = 4
        end
      end
    end
  end
  
  alias eme_ebs_discard_equip discard_equip
  def discard_equip(item)
    slot_id = equips.index(item)
    unequip_set_items_check(slot_id)
    eme_ebs_discard_equip(item)
  end

  def release_unequippable_items(item_gain = true)
    unless RPG::Weapon.method_defined?(:two_handed?)
      @equips.each_with_index do |item, i|
        if !equippable?(item.object) || item.object.etype_id != equip_slots[i]
          for a in 1..EME::Sets.size
            for b in 0...EME::Sets[a].size
              if EME::Sets[a][b][0] == 0 and item.object.is_a?(RPG::Weapon)
                if item.object.id == EME::Sets[a][b][1]
                  item_sets_change(a)
                  @sets_reserved_variable += 1
                  if active_sets.include?(a) and @item_sets[a] == 0
                    active_sets.delete(a)
                  end
                end
              elsif EME::Sets[a][b][0] == 1 and item.object.is_a?(RPG::Armor)
                if item.object.id == EME::Sets[a][b][1]
                  item_sets_change(a)
                  @sets_reserved_variable += 1
                  $game_variables[2] += 1
                  if active_sets.include?(a) and @item_sets[a] == 0
                    active_sets.delete(a)
                  end
                end
              end
            end
          end
          trade_item_with_party(nil, item.object) if item_gain
          item.object = nil
        end
      end
    else
      @equips.each_with_index do |item, i|
        if !equippable?(item.object,equip_slots[i]) || (item.object.etype_id != equip_slots[i] and
          not (dual_wield? and (equip_slots[i] == 1 and item.object.etype_id == 0)))
          for a in 1..EME::Sets.size
            for b in 0...EME::Sets[a].size
              if EME::Sets[a][b][0] == 0 and item.object.is_a?(RPG::Weapon)
                if item.object.id == EME::Sets[a][b][1]
                  item_sets_change(a)
                  @sets_reserved_variable += 1
                  if active_sets.include?(a) and @item_sets[a] == 0
                    active_sets.delete(a)
                  end
                end
              elsif EME::Sets[a][b][0] == 1 and item.object.is_a?(RPG::Armor)
                if item.object.id == EME::Sets[a][b][1]
                  item_sets_change(a)
                  @sets_reserved_variable += 1
                  $game_variables[2] += 1
                  if active_sets.include?(a) and @item_sets[a] == 0
                    active_sets.delete(a)
                  end
                end
              end
            end
          end
          trade_item_with_party(nil, item.object) if item_gain
          item.object = nil
        end
      end
    end
  end

  def set_amount_wearing(set_id)
    return @item_sets[set_id]
  end

  def set_check
    reset_bonuses
    for e in 0...active_sets.size
      element_id = active_sets[e]
      unless element_id == nil
        change_bonuses(element_id)
      end
    end
  end

  def change_bonuses(set_id)
    unless set_id == 0
      unless set_amount_wearing(set_id) == 0
        for f in 1..EME::Set_Bonuses[set_id].size
          if f <= set_amount_wearing(set_id)
            for g in 0...EME::Set_Bonuses[set_id][f].size
              sort = EME::Set_Bonuses[set_id][f][g][0]
              stat = EME::Set_Bonuses[set_id][f][g][1]
              stat_bonus = EME::Set_Bonuses[set_id][f][g][2]
              case EME::Set_Bonuses[set_id][f][g][0]
              when 0
                sets_param_change(stat, stat_bonus)
              when 1
                sets_per_param_change(stat, stat_bonus)
              when 2
                sets_xparam_change(stat, stat_bonus)
              when 3
                sets_sparam_change(stat, stat_bonus)
              when 4
                if stat == 0
                  learn_skill(stat_bonus)
                  EME::Set_Bonuses[set_id][f][g][1] = 1
                end
              when 5
                stat -= 1
                sets_element_rate_change(stat, stat_bonus)
              when 6
                stat -= 1
                sets_debuff_rate_change(stat, stat_bonus)
              when 7
                stat -= 1
                sets_state_rate_change(stat, stat_bonus)
              when 8
                sets_state_resist_change(stat, stat_bonus)
              when 9
                sets_atk_elements_change(stat, stat_bonus)
              when 10
                sets_atk_states_change(stat) if stat_bonus > 0
                sets_atk_states_rate_change(stat, stat_bonus)
              when 11
                if stat == 0
                  sets_additional_wtypes.push(stat_bonus)
                  EME::Set_Bonuses[set_id][f][g][1] = 1
                elsif stat == 2
                  change_sets_additional_atypes(stat_bonus)
                  EME::Set_Bonuses[set_id][f][g][1] = 3
                elsif stat == 4
                  @eme_ebs_two_swords_style = true
                  EME::Set_Bonuses[set_id][f][g][1] = 5
                end
              when 12
                sets_atk_specials_change(stat, stat_bonus)
              when 13
                add_sets_skill_types(stat, stat_bonus)
              when 14
                add_sets_sealed_skill_types(stat, stat_bonus)
              when 15
                add_sets_sealed_skills(stat, stat_bonus)
              when 16
                add_sets_fixed_equip_types(stat, stat_bonus)
              when 17
                add_sets_sealed_equip_types(stat, stat_bonus)
              end
            end
          end
        end
      end
    end
  end
  
#-------------------------------------------#
# LABEL FOR AUTHOR                          #
# Don't mind this ;)                        #
#-------------------------------------------#

  def reset_bonuses
    @sets_param_plus = [0] * 8
    @sets_per_param_plus = [0] * 8
    @sets_xparam_plus = [0] * 10
    @sets_sparam_plus = [0] * 10
    @sets_element_rate = [0] * (EME::MAX_ELEMENTS)
    @sets_debuff_rate = [0] * 8
    @sets_state_rate = [0] * ($data_states.size + 1)
    @sets_state_resist = []
    @sets_state_resist_remove = []
    @sets_atk_elements = []
    @sets_atk_elements_remove = []
    @sets_atk_states = []
    @sets_atk_states_rate = [0] * $data_states.size
    @sets_atk_speed_plus = 0
    @sets_atk_times_plus = 0
    @sets_skill_types = []
    @sets_skill_types_remove = []
    @sets_sealed_skill_types = []
    @sets_sealed_skill_types_remove = []
    @sets_sealed_skills = []
    @sets_sealed_skills_remove = []
    @sets_fixed_equip_types = []
    @sets_fixed_equip_types_remove = []
    @sets_sealed_equip_types = []
    @sets_sealed_equip_types_remove = []
  end

  def sets_param_plus(param_id)
    @sets_param_plus[param_id]
  end

  def add_sets_param(param_id, value)
    @sets_param_plus[param_id] += value
  end
  
  def sets_param_change(param_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_param(param_id, value)
  end
  
  def sets_per_param_plus(param_id)
    value = param_base(param_id) + param_plus(param_id)
    value *= @sets_per_param_plus[param_id] / 100
    return value
  end

  def add_sets_per_param(param_id, value)
    @sets_per_param_plus[param_id] += value
  end
  
  def sets_per_param_change(param_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_per_param(param_id, value)
  end
  
  def sets_xparam_plus(param_id)
    @sets_xparam_plus[param_id]
  end

  def add_sets_xparam(param_id, value)
    @sets_xparam_plus[param_id] += value
  end
  
  def sets_xparam_change(param_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_xparam(param_id, value)
  end

  def sets_sparam_plus(param_id)
    @sets_sparam_plus[param_id]
  end

  def add_sets_sparam(param_id, value)
    @sets_sparam_plus[param_id] += value
  end
  
  def sets_sparam_change(param_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_sparam(param_id, value)
  end
  
  def sets_element_rate(element_id)
    @sets_element_rate[element_id]
  end

  def add_sets_element_rate(element_id, value)
    @sets_element_rate[element_id] += value
  end
  
  def sets_element_rate_change(element_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_element_rate(element_id, value)
  end
  
  def sets_debuff_rate(param_id)
    @sets_debuff_rate[param_id]
  end

  def add_sets_debuff_rate(param_id, value)
    @sets_debuff_rate[param_id] += value
  end
  
  def sets_debuff_rate_change(param_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_debuff_rate(param_id, value)
  end
  
  def sets_state_rate(state_id)
    @sets_state_rate[state_id]
  end

  def add_sets_state_rate(state_id, value)
    @sets_state_rate[state_id] += value
  end
  
  def sets_state_rate_change(state_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_state_rate(state_id, value)
  end
  
  def sets_state_resist(state_id)
    @sets_state_resist[state_id]
  end
  
  def sets_state_resist_remove(state_id)
    @sets_state_resist_remove[state_id]
  end

  def add_sets_state_resist(state_id, value)
    if value > 0
      @sets_state_resist.push(state_id) unless @sets_state_resist.include?(state_id)
    elsif value < 0
      @sets_state_resist_remove.delete(state_id) unless @sets_state_resist_remove.include?(state_id)
    end
  end
  
  def sets_state_resist_change(state_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_state_resist(state_id, value)
  end
  
  def sets_atk_elements(element_id)
    @sets_atk_elements[element_id]
  end
  
  def sets_atk_elements_remove(element_id)
    @sets_atk_elements_remove[element_id]
  end

  def add_sets_atk_elements(element_id, value)
    if value > 0
      @sets_atk_elements.push(element_id) unless @sets_atk_elements.include?(element_id)
    elsif value < 0
      @sets_attack_elements_remove.delete(element_id) unless @sets_atk_elements_remove.include?(element_id)
    end
  end
  
  def sets_atk_elements_change(element_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_atk_elements(element_id, value)
  end
  
  def sets_atk_states(state_id)
    @sets_atk_states[state_id]
  end

  def add_sets_atk_states(state_id)
    @sets_atk_states.push(state_id) unless @sets_atk_states.include?(state_id)
  end
  
  def sets_atk_states_change(state_id)
    actor = $game_actors[@actor_id]
    actor.add_sets_atk_states(state_id)
  end
  
  def sets_atk_states_rate(state_id)
    @sets_atk_states_rate[state_id]
  end

  def add_sets_atk_states_rate(state_id, value)
    @sets_atk_state_rate[state_id] += value
  end
  
  def sets_atk_states_rate_change(state_id, value)
    actor = $game_actors[@actor_id]
    actor.add_sets_atk_states_rate(state_id, value)
  end
  
  def sets_atk_speed_plus
    @sets_atk_speed_plus
  end

  def add_sets_atk_speed(value)
    @sets_atk_speed_plus += value
  end

  def sets_atk_times_plus
    @sets_atk_times_plus
  end

  def add_sets_atk_times(value)
    @sets_atk_times_plus += value
  end
  
  def sets_atk_specials_change(parameter, value)
    actor = $game_actors[@actor_id]
    case parameter
    when 0
      actor.add_sets_atk_speed(value)
    when 1
      actor.add_sets_atk_times(value)
    end
  end 
    
  def sets_skill_types(skill_type_id)
    @sets_skill_types[skill_type_id]
  end
  
  def sets_skill_types_remove(skill_type_id)
    @sets_skill_types_remove[skill_type_id]
  end

  def add_sets_skill_types(skill_type_id, value)
    if value > 0
      @sets_skill_types.push(skill_type_id) unless @sets_skill_types.include?(skill_type_id)
    elsif value < 0
      @sets_skill_types_remove.delete(skill_type_id) unless @sets_skill_types_remove.include?(skill_type_id)
    end
  end
  
  def sets_sealed_skill_types(skill_type_id)
    @sets_sealed_skill_types[skill_type_id]
  end
  
  def sets_sealed_skill_types_remove(skill_type_id)
    @sets_sealed_skill_types_remove[skill_type_id]
  end

  def add_sealed_skill_types(skill_type_id, value)
    if value > 0
      @sets_sealed_skill_types.push(skill_type_id) unless @sets_sealed_skill_types.include?(skill_type_id)
    elsif value < 0
      @sets_sealed_skill_types_remove.delete(skill_type_id) unless @sets_sealed_skill_types_remove.include?(skill_type_id)
    end
  end
  
  def sets_sealed_skills(skill_id)
    @sets_sealed_skills[skill_id]
  end
  
  def sets_sealed_skills_remove(skill_id)
    @sets_sealed_skills_remove[skill_id]
  end

  def add_sets_sealed_skills(skill_id, value)
    if value > 0
      @sets_sealed_skills.push(skill_id) unless @sets_sealed_skills.include?(skill_id)
    elsif value < 0
      @sets_attack_elements_remove.delete(skill_id) unless @sets_sealed_skills_remove.include?(skill_id)
    end
  end
  
  def sets_additional_wtypes
    @sets_wtypes
  end
  
  def sets_additional_atypes
    @sets_atypes
  end
  
  def change_sets_additional_wtypes(wtype_id, positive_change = true)
    @sets_wtypes.push(wtype_id) if positive_change
    @sets_wtypes.delete(wtype_id) unless positive_change
  end
  
  def change_sets_additional_atypes(atype_id, positive_change = true)
    @sets_atypes.push(atype_id) if positive_change
    @sets_atypes.delete(atype_id) unless positive_change
  end
  
  def sets_fixed_equip_types(equip_type_id)
    @sets_fixed_equip_types[equip_type_id]
  end
  
  def sets_fixed_equip_types_remove(equip_type_id)
    @sets_fixed_equip_types_remove[equip_type_id]
  end

  def add_fixed_equip_types(equip_type_id, value)
    if value > 0
      @sets_fixed_equip_types.push(equip_type_id) unless @sets_fixed_equip_types.include?(equip_type_id)
    elsif value < 0
      @sets_fixed_equip_types_remove.delete(sequip_type_id) unless @sets_fixed_equip_types_remove.include?(equip_type_id)
    end
  end
  
  def sets_sealed_equip_types(equip_type_id)
    @sets_sealed_equip_types[equip_type_id]
  end
  
  def sets_sealed_equip_types_remove(equip_type_id)
    @sets_sealed_equip_types_remove[equip_type_id]
  end

  def add_sealed_equip_types(equip_type_id, value)
    if value > 0
      @sets_sealed_equip_types.push(equip_type_id) unless @sets_sealed_equip_types.include?(equip_type_id)
    elsif value < 0
      @sets_sealed_equip_types_remove.delete(equip_type_id) unless @sets_sealed_equip_types_remove.include?(equip_type_id)
    end
  end
  
#-------------------------------------------#
# 'NOTHER LABEL FOR AUTHOR                  #
# Don't mind this ;)                        #
#-------------------------------------------#

  def param(param_id)
    value = param_base(param_id) + param_plus(param_id) + sets_param_plus(param_id) + [sets_per_param_plus(param_id), 0].max
    value *= param_rate(param_id) * param_buff_rate(param_id)
    [[value, param_max(param_id)].min, param_min(param_id)].max.to_i
  end 
  
  alias eme_ebs_xparam xparam
  def xparam(xparam_id)
    value = eme_ebs_xparam(xparam_id) + sets_xparam_plus(xparam_id) / 100
    return value
  end
  
  alias eme_ebs_sparam sparam
  def sparam(sparam_id)
    value = eme_ebs_sparam(sparam_id) + sets_sparam_plus(sparam_id) / 100
    return value
  end
  
  alias eme_ebs_element_rate element_rate
  def element_rate(element_id)
    value = eme_ebs_element_rate(element_id) + sets_element_rate(element_id) / 100
    return value
  end
  
  alias eme_ebs_debuff_rate debuff_rate
  def debuff_rate(param_id)
    value = eme_ebs_debuff_rate(param_id) + sets_debuff_rate(param_id) / 100
    return value
  end

  alias eme_ebs_state_rate state_rate
  def state_rate(state_id)
    value = eme_ebs_state_rate(state_id) + sets_state_rate(state_id) / 100
    return value
  end

  alias eme_ebs_state_resist_set state_resist_set
  def state_resist_set
    value = eme_ebs_state_resist_set
    unless @sets_state_resist.empty?
      for i in 0...@sets_state_resist.size
        value.push(@sets_state_resist[i])
      end
    end
    unless @sets_state_resist_remove.empty?
      for i in 0...@sets_state_resist_remove.size
        value.delete(@sets_state_resist_remove[i])
      end
    end
    return value
  end
  
  alias eme_ebs_atk_elements atk_elements
  def atk_elements
    value = eme_ebs_atk_elements
    unless @sets_atk_elements.empty?
      for i in 0...@sets_atk_elements.size
        value.push(@sets_atk_elements[i])
      end
    end
    unless @sets_atk_elements_remove.empty?
      for i in 0...@sets_atk_elements_remove.size
        value.delete(@sets_atk_elements_remove[i])
      end
    end
    return value
  end
  
  alias eme_ebs_atk_states atk_states
  def atk_states
    value = eme_ebs_atk_states
    unless @sets_atk_states.empty?
      for i in 0...@sets_atk_states.size
        value.push(@sets_atk_states[i])
      end
    end
    return value
  end
  
  alias eme_ebs_atk_states_rate atk_states_rate
  def atk_states_rate(state_id)
    value = eme_ebs_atk_states_rate(state_id) + sets_atk_states_rate(state_id) / 100
    return value
  end
  
  alias eme_ebs_atk_speed atk_speed
  def atk_speed
    value = eme_ebs_atk_speed + sets_atk_speed_plus / 100
    return value
  end

  alias eme_ebs_atk_times atk_times_add
  def atk_times_add
    value = [eme_ebs_atk_times + sets_atk_times_plus / 100, 0].max
    return value
  end

  alias eme_ebs_dual_wield? dual_wield?
  def dual_wield?
    return true if @eme_ebs_two_swords_style
    eme_ebs_dual_wield?
  end
  
  alias eme_ebs_added_skill_types added_skill_types
  def added_skill_types
    value = eme_ebs_added_skill_types
    unless @sets_skill_types.empty?
      for i in 0...@sets_skill_types.size
        value.push(@sets_skill_types[i])
      end
    end
    unless @sets_skill_types_remove.empty?
      for i in 0...@sets_skill_types_remove.size
        value.delete(@sets_skill_types_remove[i])
      end
    end
    return value
  end
  
  def skill_type_sealed?(stype_id)
    value = features_set(FEATURE_STYPE_SEAL)
    unless @sets_sealed_skill_types.empty?
      for i in 0...@sets_sealed_skill_types.size
        value.push(@sets_sealed_skill_types[i])
      end
    end
    unless @sets_sealed_skill_types_remove.empty?
      for i in 0...@sets_sealed_skill_types_remove.size
        value.delete(@sets_sealed_skill_types_remove[i])
      end
    end
    return true if value.include?(stype_id)
  end

  def skill_sealed?(skill_id)
    value = features_set(FEATURE_SKILL_SEAL)
    unless @sets_sealed_skills.empty?
      for i in 0...@sets_sealed_skills.size
        value.push(@sets_sealed_skills[i])
      end
    end
    unless @sets_sealed_skills_remove.empty?
      for i in 0...@sets_sealed_skills_remove.size
        value.delete(@sets_sealed_skills_remove[i])
      end
    end
    return true if value.include?(skill_id)
  end
  
  def equip_wtype_ok?(wtype_id)
    value = features_set(FEATURE_EQUIP_WTYPE)
    for i in 0...sets_additional_wtypes.size
      value.push(sets_additional_wtypes[i])
    end
    return true if value.include?(wtype_id)
  end

  def equip_atype_ok?(atype_id)
    value = features_set(FEATURE_EQUIP_ATYPE)
    for i in 0...sets_additional_atypes.size
      value.push(sets_additional_atypes[i])
    end
    return true if value.include?(atype_id)
  end

  def equip_type_fixed?(etype_id)
    value = features_set(FEATURE_EQUIP_FIX)
    unless @sets_fixed_equip_types.empty?
      for i in 0...@sets_fixed_equip_types.size
        value.push(@sets_fixed_equip_types[i])
      end
    end
    unless @sets_fixed_equip_types_remove.empty?
      for i in 0...@sets_fixed_equip_types_remove.size
        value.delete(@sets_fixed_equip_types_remove[i])
      end
    end
    return true if value.include?(etype_id)
  end

  def equip_type_sealed?(etype_id)
    value = features_set(FEATURE_EQUIP_SEAL)
    unless @sets_sealed_equip_types.empty?
      for i in 0...@sets_sealed_equip_types.size
        value.push(@sets_sealed_equip_types[i])
      end
    end
    unless @sets_sealed_equip_types_remove.empty?
      for i in 0...@sets_sealed_equip_types_remove.size
        value.delete(@sets_sealed_equip_types_remove[i])
      end
    end
    return true if value.include?(etype_id)
  end
  
end