#==============================================================================
# FF7魔石系统
#==============================================================================
# Original By SephirothSpawn@rmxp.net
# Trans/edit By SailCat@66RPG
# 5.1.06
#==============================================================================

#------------------------------------------------------------------------------
# * 使用说明: 
#------------------------------------------------------------------------------
#    ~ 装备的魔石插孔数
#        - 基本用法: 武器/防具编号 # => 魔石孔数组
#          - 魔石孔数组: [成对孔数, 独立孔数]
#        ** 不能超过8个孔 (成对孔数 * 2 + 独立孔数 * 1 <= 8)
#        - 例: 1 => [2, 3] 则1号武器会拥有7个魔石孔，其中前4个孔成两对
#    ~ 魔石列表
#     * 使用自定义的魔石
#        - 基本用法: Materia.new(id, name, type, stat_effects,
#                                   elements, states, new_value, m_value,
#                                   skills, exp_levels, special_effect)  
#
#     - id : 魔石的编号
#     - name : 魔石的名字(字符串)
#     - type : 魔石的种类, 为以下字符串之一:
#           'Skill', 'Command', 'Summon', 'Support', 'Independent'
#     - stat_effects : 魔石装备后对基本数值的影响, 以百分比计算, 可以为负数
#           [ HP, SP, 力量, 灵巧, 速度, 魔力 ]
#     - elements : 魔石附带的属性数组, 由0-N个属性ID排列
#     - states : 魔石附带的状态数组, 由0-N个状态ID排列
#     - new_value : 魔石购买的价格
#     - master_value : 魔石练满后的价值
#     - Skills : 魔石可以修练出的技能列表数组, 用于Skill, Command与Summon类
#     - Exp Levels : 魔石修练升级需要的经验值数组
#           数组中的第一个值为升到2级需要的经验值, 以此类推
#     - Special Effect : 魔石拥有的特殊功能,为以下字符串之一
#           'All': 魔石会将配对的技能全体化
#           'Elemental': 魔石会给予角色配对的魔石所具备的属性攻击/防御
#           'Status': 魔石会给予角色配对的魔石所具备的状态攻击/防御
#           "Steal As Well': 魔石可以配合偷窃
#           'HP Absorb': 魔石可以吸收HP
#           'SP Absorb': 魔石可以吸收SP
#           'SP Turbo': 魔石可以加倍SP消耗来增加技能效果
#           'Exp Plus': 魔石可以增加收获的经验
#           'Gil Plus': 魔石可以增加收获的钱
#           'HP Plus': 魔石可以增加装备者的最大HP
#           'SP Plus': 魔石可以增加装备者的最大SP
#           'Str Plus': 魔石可以增加装备者的力量值
#           'Dex Plus': 魔石可以增加装备者的灵巧值
#           'Agi Plus': 魔石可以增加装备者的速度值
#           'Int Plus': 魔石可以增加装备者的魔力值
#------------------------------------------------------------------------------

#==============================================================================
# ** RPG
#==============================================================================

module RPG
  
  #============================================================================
  # ** 武器
  #============================================================================
  class Weapon
    #--------------------------------------------------------------------------
    # * 追加实例变量
    #--------------------------------------------------------------------------
    attr_accessor :paired_materia
    attr_accessor :single_materia
    #--------------------------------------------------------------------------
    # * 设置魔石孔
    #--------------------------------------------------------------------------
    def set_materia_slots(slots)
      @paired_materia, @single_materia = slots[0], slots[1]
    end
  end
  
  #============================================================================
  # ** 防具
  #============================================================================
  class Armor
    #--------------------------------------------------------------------------
    # * 追加实例变量
    #--------------------------------------------------------------------------
    attr_accessor :paired_materia
    attr_accessor :single_materia
    #--------------------------------------------------------------------------
    # * 设置魔石孔
    #--------------------------------------------------------------------------
    def set_materia_slots(slots)
      @paired_materia, @single_materia = slots[0], slots[1]
    end
  end
end

#==============================================================================
# ** 魔石
#==============================================================================

class Materia
  #--------------------------------------------------------------------------
  # * 实例变量
  #--------------------------------------------------------------------------
  attr_reader      :id
  attr_accessor   :name
  attr_accessor   :type
  attr_accessor   :stat_effects
  attr_accessor   :elements
  attr_accessor   :states
  attr_accessor   :new_value
  attr_accessor   :master_value
  attr_accessor   :skills
  attr_accessor   :exp_levels
  attr_accessor   :special_effect
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize(id, name, type, stat_effects = [], elements = [], states = [], 
    n_value = 500, m_value = 1000, skills = [], exp_levels = [], s_effect = nil)
    # Sets Parameters
    @id, @name, @type, @stat_effects, @elements, @states,
    @new_value, @master_value, @skills, @exp_levels, @special_effect = 
      id, name, type, stat_effects, elements, states, 
      n_value, m_value, skills, exp_levels, s_effect
    # Sets Exp
    @experience = 0
  end
  #--------------------------------------------------------------------------
  # * 经验
  #--------------------------------------------------------------------------
  def experience
    return @experience
  end
  #--------------------------------------------------------------------------
  # * 设置经验
  #   num: 新的经验
  #--------------------------------------------------------------------------
  def experience=(num)
    @experience = [num, @exp_levels[@exp_levels.size - 1]].min
  end
  #--------------------------------------------------------------------------
  # * 等级
  #--------------------------------------------------------------------------
  def level
    for i in 0...@exp_levels.size
      if @experience >= @exp_levels[@exp_levels.size - (1 + i)]
        return @exp_levels.size - i + 1
      end
    end
    return 1
  end
  #--------------------------------------------------------------------------
  # * 购价
  #--------------------------------------------------------------------------
  def buy_value
    return @new_value
  end
  #--------------------------------------------------------------------------
  # * 售价
  #--------------------------------------------------------------------------
  def sell_value
    return [(@master_value * (@experience / @exp_levels[@exp_levels.size - 1].to_f)).to_i, 
      @new_value / 2].max
  end
  #--------------------------------------------------------------------------
  # * 取得魔石色相
  #--------------------------------------------------------------------------
  def get_hue
    case @type
    when 'Skill'
      hue = 130
    when 'Command'
      hue = 60
    when 'Summon'
      hue = 10
    when 'Support'
      hue = 180
    when 'Independent'
      hue = 300
    end
    return hue
  end
end

#==============================================================================
# ** 魔石系统
#==============================================================================

module Materia_System
  
  #==============================================================================
  # ** 常数(数据库设定缺省值,可以修改)
  #==============================================================================

  # ~ 武器魔石孔
    WEAPON_MATERIA_SLOTS = {
      1 => [1, 1], 2 => [1, 2], 3 => [2, 2], 4 => [4, 0],
      5 => [1, 1], 6 => [1, 2], 7 => [2, 2], 8 => [4, 0],
      9 => [1, 1], 10 => [1, 2], 11 => [2, 2], 12 => [4, 0],
      13 => [1, 1], 14 => [1, 2], 15 => [2, 2], 16 => [4, 0],
      17 => [1, 1], 18 => [1, 2], 19 => [2, 2], 20 => [4, 0],
      21 => [1, 1], 22 => [1, 2], 23 => [2, 2], 24 => [4, 0], 
      25 => [1, 1], 26 => [1, 2], 27 => [2, 2], 28 => [4, 0], 
      29 => [1, 1], 30 => [1, 2], 31 => [2, 2], 32 => [4, 0]
      }
  # ~ 防具魔石孔
    ARMORS_MATERIA_SLOTS = {
      1 => [1, 1], 2 => [1, 2], 3 => [2, 2], 4 => [4, 0],
      5 => [1, 1], 6 => [1, 2], 7 => [2, 2], 8 => [4, 0],
      9 => [1, 1], 10 => [1, 2], 11 => [2, 2], 12 => [4, 0],
      13 => [1, 1], 14 => [1, 2], 15 => [2, 2], 16 => [4, 0],
      17 => [1, 1], 18 => [1, 2], 19 => [2, 2], 20 => [4, 0],
      21 => [1, 1], 22 => [1, 2], 23 => [2, 2], 24 => [4, 0], 
      25 => [1, 1], 26 => [1, 2], 27 => [2, 2], 28 => [4, 0], 
      29 => [1, 1], 30 => [1, 2], 31 => [2, 2], 32 => [4, 0]
      }
  # ~ 自带的魔石列表
    MATERIA_LIST = [nil, 
      # Skill Materia
      Materia.new(1, 'Heal', 'Skill', [ -5, 5, -3, 0, 0, 3 ], [], [], 1000, 10000, 
        [1, 2, 3, 6], [1000, 3000, 6000, 10000]), 
      Materia.new(2,'Remedy', 'Skill', [ -4, 4, -3, 0, 0, 3 ], [], [], 750, 5000,
        [4, 5], [2500, 5000]), 
      Materia.new(3, 'Fire', 'Skill', [ -3, 3, -1, 0, 0, 1 ], [1], [], 1000, 7500,
        [7, 8, 9], [1000, 3000, 7500]), 
      Materia.new(4, 'Ice', 'Skill', [ -3, 3, -1, 0, 0, 1 ], [2], [], 1000, 7500,
        [10, 11, 12], [1000, 3000, 7500]), 
      Materia.new(5, 'Electric', 'Skill', [ -3, 3, -1, 0, 0, 1 ], [3], [], 1000, 7500,
        [13, 14, 15], [1000, 3000, 7500]), 
      Materia.new(6, 'Water', 'Skill', [ -3, 3, -1, 0, 0, 1 ], [4], [], 1000, 7500,
        [16, 17, 18], [1000, 3000, 7500]), 
      Materia.new(7, 'Earth', 'Skill', [ -3, 3, -1, 0, 0, 1 ], [5], [], 1000, 7500,
        [19, 20, 21], [1000, 3000, 7500]), 
      Materia.new(8, 'Wind', 'Skill', [ -3, 3, -1, 0, 0, 1 ], [6], [], 1000, 7500,
        [22, 23, 24], [1000, 3000, 7500]), 
      Materia.new(9, 'Light', 'Skill', [ -5, 5, -3, 0, 0, 3 ], [7], [], 1000, 7500,
        [25, 26, 27], [1000, 3000, 7500]), 
      Materia.new(10, 'Dark', 'Skill', [ -5, 5, -3, 0, 0, 3 ], [8], [], 1000, 7500,
        [28, 29, 30], [1000, 3000, 7500]), 
      Materia.new(11, 'Negla', 'Skill', [ -4, 4, -2, 0, 0, 2 ], [], [], 1500, 7500,
        [31, 32], [3000, 7500]), 
      Materia.new(12, 'Poison', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [3], 750, 4500,
        [33, 34], [1500, 4500]), 
      Materia.new(13, 'Dizzy', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [4], 750, 4500,
        [35, 36], [1500, 4500]), 
      Materia.new(14, 'Mute', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [5], 750, 4500,
        [37, 38], [1500, 4500]), 
      Materia.new(15, 'Confuse', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [6], 750, 4500,
        [39, 40], [1500, 4500]), 
      Materia.new(16, 'Sleep', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [7], 750, 4500,
        [41, 42], [1500, 4500]), 
      Materia.new(17, 'Paraylze', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [8], 750, 4500,
        [43, 44], [1500, 4500]), 
      Materia.new(18, 'Weak', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [9], 750, 4500,
        [45, 46], [1500, 4500]), 
      Materia.new(19, 'Clumbsiness', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [10], 750, 4500,
        [47, 48], [1500, 4500]), 
      Materia.new(20, 'Delayed', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [11], 750, 4500,
        [49, 50], [1500, 4500]), 
      Materia.new(21, 'Enfeebled', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [12], 750, 4500,
        [51, 52], [1500, 4500]), 
      Materia.new(22, 'Sharpen', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [13], 750, 4500,
        [53], [3000]), 
      Materia.new(23, 'Barrier', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [14], 750, 4500,
        [54], [3000]), 
      Materia.new(24, 'Resist', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [15], 750, 4500,
        [55], [3000]), 
      Materia.new(25, 'Blink', 'Skill', [ -2, 2, 0, 0, 0, 0 ], [], [16], 750, 4500,
        [56], [3000]), 
      # Command Materia
      Materia.new(26, 'Fighter',  'Command', [0, 0, 5, 3, - 3, - 5], [], [], 3000, 20000,
        [57, 58, 59, 60], [2500, 5000, 9000, 14000, 2000]), 
      Materia.new(27, 'Lancer',  'Command', [0, 0, 4, 4, - 4, - 4], [], [], 3000, 20000,
        [61, 62, 63, 64], [2500, 5000, 9000, 14000, 2000]), 
      Materia.new(28, 'Warrior', 'Command', [0, 0, 7, 2, - 2, - 7], [], [], 3000, 20000,
        [65, 66, 67, 68], [2500, 5000, 9000, 14000, 2000]), 
      Materia.new(29, 'Thief', 'Command', [0, 0, 1, 8, - 8, - 1], [], [], 3000, 20000,
        [69, 70, 71, 72], [2500, 5000, 9000, 14000, 2000]), 
      Materia.new(30, 'Hunter', 'Command', [2, 2, 2, 2, 2, 2], [], [], 3000, 20000,
        [73, 74, 75, 76], [2500, 5000, 9000, 14000, 2000]), 
      Materia.new(31, 'Gunner', 'Command', [0, 4, 4, 0, 4, 0], [], [], 3000, 20000,
        [77, 78, 79, 80], [2500, 5000, 9000, 14000, 2000]), 
      # Summon Materia (Not real summons, but you would set them up the same
      Materia.new(32, 'Summon 1', 'Summon', [-10, 10, -5, -5, 0, 10], [], [], 5000, 25000,
        [60, 64], [6500, 15000, 25000]),
      Materia.new(33, 'Summon 2', 'Summon', [-10, 10, -5, -5, 0, 10], [], [], 5000, 25000,
        [68, 72], [6500, 15000, 25000]),
      Materia.new(34, 'Summon 3', 'Summon', [-10, 10, -5, -5, 0, 10], [], [], 5000, 25000,
        [76, 80], [6500, 15000, 25000]),
      # Support Materia
      Materia.new(35, 'All', 'Support', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'All'),
      Materia.new(36, 'Elemental', 'Support', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Elemental'),
      Materia.new(37, 'Status', 'Support', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Status'),
      Materia.new(38, 'Steal as well', 'Support', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Steal as well'),
      Materia.new(39, 'HP Absorb', 'Support', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'HP Absorb'),
      Materia.new(40, 'SP Absorb', 'Support', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'SP Absorb'),
      Materia.new(41, 'SP Turbo', 'Support', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'SP Turbo'),
      # Independent Mater
      Materia.new(42, 'Exp Plus', 'Independent', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Exp Plus'),
      Materia.new(43, 'Gil Plus', 'Independent', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Gil Plus'),
      Materia.new(44, 'HP Plus', 'Independent', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'HP Plus'),
      Materia.new(45, 'SP Plus', 'Independent', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'SP Plus'),
      Materia.new(46, 'Str Plus', 'Independent', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Str Plus'),
      Materia.new(47, 'Dex Plus', 'Independent', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Dex Plus'),
      Materia.new(48, 'Agi Plus', 'Independent', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Agi Plus'),
      Materia.new(49, 'Int Plus', 'Independent', [0, 0, 0, 0, 0, 0], [], [], 2000, 10000,
        [], [2000, 4000, 7000, 11000], 'Int Plus')
    ]
end

#==============================================================================
# ** Game_Battler (分割定义 3)
#==============================================================================

class Game_Battler
  alias sephiroth_sailcat_skill_effect skill_effect
  #--------------------------------------------------------------------------
  # * 应用技能效果
  #     user  : 技能的使用者(Game_Battler)
  #     skill : 技能(Skill)
  #     Sailcat译注 : 这里改用公共事件应用技能效果会在脚本冲突上好一些
  #--------------------------------------------------------------------------
  def skill_effect(user, skill)
    # Orginal Skill Effects Method
    sephiroth_sailcat_skill_effect(user, skill)
    if user.is_a?(Game_Actor)
      # Gets Paired Materia
      materia_set = user.return_paired_materia
      for paired_set in materia_set
        materia = paired_set[2]
        other_materia = paired_set[3]
        # HP Absorb
        if materia.special_effect == 'HP Absorb'
          for skill_id in other_materia.skills
            unless skill_id == 0
              m_skill = $data_skills[skill_id]
              if skill == m_skill
                hp = (user.maxhp * 0.1).to_i
                user.hp += [hp, user.maxhp - hp].min
                user.damage = - [hp, user.maxhp - hp].min
                user.damage_pop = true
              end
            end
          end
        end
        # SP Absorb
        if materia.special_effect == 'SP Absorb'
          for skill_id in other_materia.skills
            unless skill_id == 0
              m_skill = $data_skills[skill_id]
              if skill == m_skill
                sp = (user.maxsp * 0.1).to_i
                user.sp += [sp, user.maxsp - sp].min
                user.damage = - [sp, user.maxsp - sp].min
                user.damage_pop = true
              end
            end
          end
        end
        # SP Turbo
        if materia.special_effect == 'SP Turbo'
          for skill_id in other_materia.skills
            unless skill_id == 0
              m_skill = $data_skills[skill_id]
              if skill == m_skill
                unless user.sp < skill.sp_cost * 2
                  if self.damage > 0
                    self.damage *= 2
                    user.sp -= skill.sp_cost
                    user.damage = 'SP Turbo!'
                    user.damage_pop = true
                  end
                end
              end
            end
          end
        end
        # Steal As Well
        if materia.special_effect == 'Steal as well'
          for skill_id in other_materia.skills
            unless skill_id == 0
              m_skill = $data_skills[skill_id]
              if skill == m_skill
                if self.is_a?(Game_Battler)
                  if (rand(100) < self.treasure_prob)
                    unless self.item_id == 0
                      item = $data_items[self.item_id]
                    end
                    unless self.weapon_id == 0
                      item = $data_weapons[self.weapon_id]
                    end
                    unless self.armor_id == 0
                      item = $data_armors[self.armor_id]
                    end
                    unless item.nil?
                      case item
                      when RPG::Item
                        $game_party.gain_item(self.item_id, 1)
                      when RPG::Weapon
                        $game_party.gain_weapon(self.weapon_id, 1)
                      when RPG::Armor
                        $game_party.gain_armor(self.armor_id, 1)
                      end
                      user.damage = "Stole #{item.name}"
                      user.damage_pop = true
                    end
                  end
                end
              end
            end
          end
        end
      end
    end
  end
end

#==============================================================================
# ** Game_Actor
#==============================================================================

class Game_Actor
  #--------------------------------------------------------------------------
  # * 追加实例变量
  #--------------------------------------------------------------------------
  attr_accessor   :weapon_materia
  attr_accessor   :armor1_materia
  attr_accessor   :armor2_materia
  attr_accessor   :armor3_materia
  attr_accessor   :armor4_materia
  attr_accessor   :materia_skills
  alias sephiroth_sailcat_init initialize
  alias sephiroth_sailcat_setup setup
  alias sephiroth_sailcat_skills skills
  alias sephiroth_sailcat_maxhp maxhp
  alias sephiroth_sailcat_maxsp maxsp
  alias sephiroth_sailcat_str str
  alias sephiroth_sailcat_dex dex
  alias sephiroth_sailcat_agi agi
  alias sephiroth_sailcat_int int
  alias sephiroth_sailcat_equip equip
  alias sephiroth_sailcat_exp exp
  alias sephiroth_sailcat_element_rate element_rate
  alias sephiroth_sailcat_state_guard? state_guard?
  alias sephiroth_sailcat_element_set element_set
  alias sephiroth_sailcat_plus_state_set plus_state_set
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize(actor_id)
    # Sets Up Materia Slots
    @weapon_materia = Array.new
    @armor1_materia = Array.new
    @armor2_materia = Array.new
    @armor3_materia = Array.new
    @armor4_materia = Array.new
    # Orginal Initialization Method
    sephiroth_sailcat_init(actor_id)
  end
  #--------------------------------------------------------------------------
  # * 设定
  #   actor_id: 角色 ID
  #--------------------------------------------------------------------------
  def setup(actor_id)
    # Orginal Setup Method
    sephiroth_sailcat_setup(actor_id)
    # Materia Skills
    @materia_skills = []
    # Adds Weapon Materia
    sn = $data_weapons[@weapon_id].paired_materia * 2 + 
      $data_weapons[@weapon_id].single_materia unless @weapon_id == 0
    @weapon_materia = @weapon_id == 0 ? [] : Array.new(sn, nil)
    # Adds Shield Materia
    sn = $data_armors[@armor1_id].paired_materia * 2 +
      $data_armors[@armor1_id].single_materia unless @armor1_id == 0
    @armor1_materia = @armor1_id == 0 ? [] : Array.new(sn, nil)
    # Adds Head Materia
    sn = $data_armors[@armor2_id].paired_materia * 2 +
      $data_armors[@armor2_id].single_materia unless @armor2_id == 0
    @armor2_materia = @armor2_id == 0 ? [] : Array.new(sn, nil)
    # Adds Body Materia
    sn = $data_armors[@armor3_id].paired_materia * 2 +
      $data_armors[@armor3_id].single_materia unless @armor3_id == 0
    @armor3_materia = @armor3_id == 0 ? [] : Array.new(sn, nil)
    # Adds Accessory Materia
    sn = $data_armors[@armor4_id].paired_materia * 2 +
      $data_armors[@armor4_id].single_materia unless @armor4_id == 0
    @armor4_materia = @armor4_id == 0 ? [] : Array.new(sn, nil)
  end
  #--------------------------------------------------------------------------
  # * 获得技能
  #--------------------------------------------------------------------------
  def skills
    # Deletes Materia Skills
    for skill_id in @materia_skills
      self.forget_skill(skill_id)
    end
    # Original Skills Method
    skills = sephiroth_sailcat_skills
    # Adds Skills Attached to Weapon & Armors
    for materia in @weapon_materia + @armor1_materia + @armor2_materia + 
      @armor3_materia + @armor4_materia
      unless materia.nil?
        self.learn_materia_skill(materia)
      end
    end
    # Returns Skills
    return @skills
  end
  #--------------------------------------------------------------------------
  # * 学习魔石技能
  #--------------------------------------------------------------------------
  def learn_materia_skill(materia)
    # If Skill Materia
    if materia.type == 'Skill' || materia.type == 'Command' || materia.type == 'Summon'
      for i in 0...materia.level
        skill_id = materia.skills[i]
        # Learn Skill
        self.learn_skill(skill_id)
        # Adds Skills To Materia Skills
        @materia_skills << skill_id
      end
    end
  end
  #--------------------------------------------------------------------------
  # * 获得最大HP
  #--------------------------------------------------------------------------
  def maxhp
    # Orginal Max Hp Method
    n = sephiroth_sailcat_maxhp    
    # Collects HP Difference From Materia
    variance = 0
    for materia in @weapon_materia + @armor1_materia + @armor2_materia + 
        @armor3_materia + @armor4_materia
      unless materia.nil?
        variance += materia.stat_effects[0]
        if materia.special_effect == 'HP Plus'
          variance += (materia.level * 10)
        end
      end
    end
    # Takes Percentage
    n *= ((100 + variance) / 100.0)
    n = [[Integer(n), 0].max, 9999].min
    return n
  end
  #--------------------------------------------------------------------------
  # * 获得HP
  #--------------------------------------------------------------------------
  def hp
    @hp = [@hp, maxhp].min
    return @hp
  end
  #--------------------------------------------------------------------------
  # * 获得最大SP
  #--------------------------------------------------------------------------
  def maxsp
    # Orginal Max Sp Method
    n = sephiroth_sailcat_maxsp
    # Collects SP Difference From Materia
    variance = 0
    for materia in @weapon_materia + @armor1_materia + @armor2_materia + 
        @armor3_materia + @armor4_materia
      unless materia.nil?
        variance += materia.stat_effects[1]
        if materia.special_effect == 'SP Plus'
          variance += (materia.level * 10)
        end
      end
    end
    # Takes Percentage
    n *= ((100 + variance) / 100.0)
    n = [[Integer(n), 0].max, 9999].min
    return n
  end
  #--------------------------------------------------------------------------
  # * 获得SP
  #--------------------------------------------------------------------------
  def sp
    @sp = [@sp, maxsp].min
    return @sp
  end
  #--------------------------------------------------------------------------
  # * 获得力量
  #--------------------------------------------------------------------------
  def str
    # Orginal Max Str Method
    n = sephiroth_sailcat_str   
    # Collects SP Difference From Materia
    variance = 0
    for materia in @weapon_materia + @armor1_materia + @armor2_materia + 
        @armor3_materia + @armor4_materia
      unless materia.nil?
        variance += materia.stat_effects[2]
        if materia.special_effect == 'Str Plus'
          variance += (materia.level * 5)
        end
      end
    end
    # Takes Percentage
    n *= ((100 + variance) / 100.0)
    n = [[Integer(n), 1].max, 999].min
    return n
  end
  #--------------------------------------------------------------------------
  # * 获得灵巧
  #--------------------------------------------------------------------------
  def dex
    # Orginal Max Dex Method
    n = sephiroth_sailcat_dex  
    # Collects SP Difference From Materia
    variance = 0
    for materia in @weapon_materia + @armor1_materia + @armor2_materia + 
        @armor3_materia + @armor4_materia
      unless materia.nil?
        variance += materia.stat_effects[3]
        if materia.special_effect == 'Dex Plus'
          variance += (materia.level * 5)
        end
      end
    end
    # Takes Percentage
    n *= ((100 + variance) / 100.0)
    n = [[Integer(n), 1].max, 999].min
    return n
  end
  #--------------------------------------------------------------------------
  # * 获得速度
  #--------------------------------------------------------------------------
  def agi
    # Orginal Max Agi Method
    n = sephiroth_sailcat_agi  
    # Collects SP Difference From Materia
    variance = 0
    for materia in @weapon_materia + @armor1_materia + @armor2_materia + 
        @armor3_materia + @armor4_materia
      unless materia.nil?
        variance += materia.stat_effects[4]
        if materia.special_effect == 'Agi Plus'
          variance += (materia.level * 5)
        end
      end
    end
    # Takes Percentage
    n *= ((100 + variance) / 100.0)
    n = [[Integer(n), 1].max, 999].min
    return n
  end
  #--------------------------------------------------------------------------
  # * 获得魔力
  #--------------------------------------------------------------------------
  def int
    # Orginal Max Int Method
    n = sephiroth_sailcat_int  
    # Collects SP Difference From Materia
    variance = 0
    for materia in @weapon_materia + @armor1_materia + @armor2_materia + 
        @armor3_materia + @armor4_materia
      unless materia.nil?
        variance += materia.stat_effects[5]
        if materia.special_effect == 'Int Plus'
          variance += (materia.level * 5)
        end
      end
    end
    # Takes Percentage
    n *= ((100 + variance) / 100.0)
    n = [[Integer(n), 1].max, 999].min
    return n
  end
  #--------------------------------------------------------------------------
  # * 更换装备
  #     equip_type : 装备类型
  #     id    : 装备 ID (0 为解除)
  #--------------------------------------------------------------------------
  def equip(equip_type, id)
    # Removes Equipped Materia
    case equip_type
    when 0  # Weapon
      for materia in @weapon_materia
        $game_party.materia << materia unless materia.nil?
      end
    when 1  # Shield
      for materia in @armor1_materia
        $game_party.materia << materia unless materia.nil?
      end
    when 2  # Head
      for materia in @armor2_materia
        $game_party.materia << materia unless materia.nil?
      end
    when 3  # Body
      for materia in @armor3_materia
        $game_party.materia << materia unless materia.nil?
      end
    when 4  # Accessory
      for materia in @armor4_materia
        $game_party.materia << materia unless materia.nil?
      end
    end
    # Orginal Eqip Method
    sephiroth_sailcat_equip(equip_type, id)
    # Resets Materia Slots
    case equip_type
    when 0  # Weapon
      sn = $data_weapons[@weapon_id].paired_materia * 2 + 
        $data_weapons[@weapon_id].single_materia unless @weapon_id == 0
      @weapon_materia = @weapon_id == 0 ? [] : Array.new(sn, nil)
    when 1  # Shield
      sn = $data_armors[@armor1_id].paired_materia * 2 +
        $data_armors[@armor1_id].single_materia unless @armor1_id == 0
      @armor1_materia = @armor1_id == 0 ? [] : Array.new(sn, nil)
    when 2  # Head
      sn = $data_armors[@armor2_id].paired_materia * 2 +
        $data_armors[@armor2_id].single_materia unless @armor2_id == 0
      @armor2_materia = @armor2_id == 0 ? [] : Array.new(sn, nil)
    when 3  # Body
      sn = $data_armors[@armor3_id].paired_materia * 2 +
        $data_armors[@armor3_id].single_materia unless @armor3_id == 0
      @armor3_materia = @armor3_id == 0 ? [] : Array.new(sn, nil)
    when 4  # Accessory
      sn = $data_armors[@armor4_id].paired_materia * 2 +
        $data_armors[@armor4_id].single_materia unless @armor4_id == 0
      @armor4_materia = @armor4_id == 0 ? [] : Array.new(sn, nil)
    end
  end
  #--------------------------------------------------------------------------
  # * 改变EXP
  #     exp : 新的 EXP
  #--------------------------------------------------------------------------
  def exp=(exp)
    # If Gaining Exp
    if exp > @exp
      # Gets New Exp
      new_exp = exp - @exp
      # Sets Exp + % to 0
      exp_plus = 0
      for materia in @weapon_materia + @armor1_materia + @armor2_materia + 
        @armor3_materia + @armor4_materia
        unless materia.nil?
          # Gains Exp
          materia.experience += new_exp
          if materia.special_effect == 'Exp Plus'
            exp_plus += (materia.level * 10)
          end
        end
      end
      new_exp *= ((100 + exp_plus) / 100.0)
      exp = new_exp.to_i + @exp
    end
    # Orginal Exp Method
    @exp = [[exp, 9999999].min, 0].max
    # Level up
    while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
      @level += 1
      # Learn skill
      for j in $data_classes[@class_id].learnings
        if j.level == @level
          learn_skill(j.skill_id)
        end
      end
    end
    # Level down
    while @exp < @exp_list[@level]
      @level -= 1
    end
    # Correction if exceeding current max HP and max SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
  #--------------------------------------------------------------------------
  # * 获得属性有效度
  #    element_id: 属性ID
  #--------------------------------------------------------------------------
  def element_rate(element_id)
    # Gets Orginal Element Set
    result = sephiroth_sailcat_element_rate(element_id)
    # Gets Paired Materia list
    paired = return_paired_materia
    # Checks each set
    for set in paired
      # Checks Armors
      if set[0] > 0
        # Checks Support Materia
        materia = set[2]
        if materia.special_effect == 'Elemental'
          other_materia = set[3]
          if other_materia.elements.include?(element_id)
            result /= 2
          end
        end
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * 获得防御状态
  #--------------------------------------------------------------------------
  def state_guard?(state_id)
    result = sephiroth_sailcat_state_guard?(state_id)
    unless result
      # Gets Paired Materia list
      paired = return_paired_materia
      # Checks each set
      for set in paired
        # Checks Armors
        if set[0] > 0
          # Checks Support Materia
          materia = set[2]
          if materia.special_effect == 'Status'
            other_materia = set[3]
            if other_materia.states.include?(state_id)
              result = true
            end
          end
        end
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * 获得普通攻击属性
  #--------------------------------------------------------------------------
  def element_set
    # Gets Previous Element Set
    result = sephiroth_sailcat_element_set
    # Adds Materia Element Sets
    # Gets Paired Materia list
    paired = return_paired_materia
    # Checks each set
    for set in paired
      # Checks Weapon
      if set[0] == 0
        # Checks Support Materia
        materia = set[2]
        if materia.special_effect == 'Elemental'
          other_materia = set[3]
          for elem_id in other_materia.elements
            result << elem_id unless set.include?(elem_id)
          end
        end
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * 获得普通攻击状态(+)
  #--------------------------------------------------------------------------
  def plus_state_set
    # Gets Previous Status Set
    result = sephiroth_sailcat_plus_state_set
    # Gets Paired Materia list
    paired = return_paired_materia
    # Checks each set
    for set in paired
      # Checks Weapon
      if set[0] == 0
        # Checks Support Materia
        materia = set[2]
        if materia.special_effect == 'Status'
          other_materia = set[3]
          for state_id in other_materia.states
            result << state_id unless set.include?(state_id)
          end
        end
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * 装备魔石
  #     equip_type : 装备类型
  #     slot_index  : 魔石孔
  #     index : 在拥有魔石中的序号
  #--------------------------------------------------------------------------
  def equip_materia(equip_type, slot_index, index)
    # Gets Materia
    new_materia = $game_party.materia[index]
    # Unequip Materia
    materia = equip_type == 0 ? 
      @weapon_materia[slot_index] : (eval "@armor#{equip_type}_materia")[slot_index]
    unless materia.nil?
      $game_party.materia << materia
    end
    # Modifies Materia
    case equip_type
    when 0  # Weapon
      return if @weapon_materia.size == 0
      @weapon_materia[slot_index] = new_materia
    when 1  # Shield
      return if @armor1_materia.size == 0
      @armor1_materia[slot_index] = new_materia
    when 2  # Head
      return if @armor2_materia.size == 0
      @armor2_materia[slot_index] = new_materia
    when 3  # Body
      return if @armor3_materia.size == 0
      @armor3_materia[slot_index] = new_materia
    when 4  # Accessory
      return if @armor4_materia.size == 0
      @armor4_materia[slot_index] = new_materia
    end
    # Deletes Materia From Party: Materia
    $game_party.materia.delete_at(index)
  end
  #--------------------------------------------------------------------------
  # * 解除魔石
  #     equip_type : 装备类型
  #     slot_index  : 魔石孔
  #--------------------------------------------------------------------------
  def unequip_materia(equip_type, slot_index)
    materia = equip_type == 0 ? 
      @weapon_materia[slot_index] : (eval "@armor#{equip_type}_materia")[slot_index]
    unless materia.nil?
      $game_party.materia << materia
    end
    equip_type == 0 ? 
      @weapon_materia[slot_index] = nil : (eval "@armor#{equip_type}_materia")[slot_index] = nil
  end
  #--------------------------------------------------------------------------
  # * 获得双孔魔石
  #--------------------------------------------------------------------------
  def return_paired_materia
    # Creates Your Return Array
    paired = []
    # Checks Weapon
    unless @weapon_id == 0
      if $data_weapons[@weapon_id].paired_materia > 0
        for i in 0...($data_weapons[@weapon_id].paired_materia * 2)
          materia = @weapon_materia[i]
          if materia.type == 'Support'
            o_i = i + ([0, 2, 4, 6].include?(i) ? 1 : - 1)
            other_materia = @weapon_materia[o_i]
            unless other_materia.nil?
              paired << [0, [i, o_i].min, materia, other_materia]
            end
          end
        end
      end
    end
    # Checks Armors
    for a in 1..4
      unless (eval "@armor#{a}_id") == 0
        if (eval "$data_armors[@armor#{a}_id].paired_materia") > 0
          for i in 0...((eval "$data_armors[@armor#{a}_id].paired_materia") * 2)
            materia = (eval "@armor#{a}_materia")[i]
            if materia.type == 'Support'
              o_i = i + ([0, 2, 4, 6].include?(i) ? 1 : - 1)
              other_materia = (eval "@armor#{a}_materia")[o_i]
              unless other_materia.nil?
                paired << [a, [i, o_i].min, materia, other_materia]
              end
            end
          end
        end
      end
    end
    return paired
  end
end

#==============================================================================
# ** Game_Party
#==============================================================================

class Game_Party
  #--------------------------------------------------------------------------
  # * 追加实例变量
  #--------------------------------------------------------------------------
  attr_accessor   :materia
  alias sephiroth_sailcat_init initialize
  alias sephiroth_sailcat_gain_gold gain_gold
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize
    # Orginal Initialization Method
    sephiroth_sailcat_init
    # Sets Up Materia Listings
    @materia = []
  end
  #--------------------------------------------------------------------------
  # * 获得魔石
  #--------------------------------------------------------------------------
  def gain_materia(materia_index)
    # Adds Materia
    @materia << $data_materia[materia_index].dup
  end
  #--------------------------------------------------------------------------
  # * 获得金钱 (失去)
  #     n : 获得的数目
  #--------------------------------------------------------------------------
  def gain_gold(n)
    gil_plus = 0
    for actor in @actors
      for materia in actor.weapon_materia + actor.armor1_materia + 
        actor.armor2_materia + actor.armor3_materia + actor.armor4_materia
        unless materia.nil?
          if materia.special_effect == 'Gil Plus'
            gil_plus += (materia.level * 5)
          end
        end
      end
    end
    n *= (100 + gil_plus) / 100.0
    # Orginal Gain Gold Method
    sephiroth_sailcat_gain_gold(n.to_i)
  end
end

#==============================================================================
#  Window_HorizCommand
#==============================================================================
#    水平命令窗口类
#    Sailcat译注 : 这是个很有用的窗口类,我的游戏也用了类似的一个类
#==============================================================================

class Window_HorizCommand < Window_Selectable
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize(commands, width = 640, height = 64)
    super(0, 0, width, height)
    self.contents = Bitmap.new(width - 32, height - 32)
    @commands = commands
    @item_max = @commands.size
    @column_max = @commands.size
    refresh
    self.index = 0
  end
  #--------------------------------------------------------------------------
  # * 刷新
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    for i in 0...@item_max
      draw_item(i, normal_color)
    end
  end
  #--------------------------------------------------------------------------
  # * 描画命令
  #     index : 索引
  #--------------------------------------------------------------------------
  def draw_item(index, color)
    self.contents.font.color = color
    x = width / @item_max * index
    off = width / @item_max - 32
    self.contents.draw_text(x, 0, off, 32, @commands[index], 1)
  end
  #--------------------------------------------------------------------------
  # * 无效化命令
  #     index : 索引
  #--------------------------------------------------------------------------
  def disable_item(index)
    draw_item(index, disabled_color)
  end
end

#==============================================================================
# ** Window_MateriaBio
#==============================================================================

class Window_MateriaBio < Window_Base
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize
    super(240, 128, 400, 352)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.visible = false
  end
  #--------------------------------------------------------------------------
  # * 刷新
  #--------------------------------------------------------------------------
  def refresh(materia)
    self.contents.clear
    # If no Materia
    return if materia.nil?
    # Gets Icon Hue
    hue = materia.get_hue
    # Draws Materia Icon
    bitmap = RPG::Cache.icon('Materia Icon').dup
    bitmap.hue_change(hue)
    self.contents.blt(4, 0, bitmap, Rect.new(0, 0, 24, 24))
    # Draws Materia Name
    self.contents.font.size = 22
    self.contents.font.color = normal_color
    self.contents.font.bold = false
    self.contents.draw_text(32, 0, contents.width, 24, materia.name)
    # Gets Star Bitmap & Changes Hue
    bitmap = RPG::Cache.icon('Star - Icon').dup
    bitmap.hue_change(hue)
    # Gets Start of Star X Coordinate
    star_x = contents.width / 2 - 20
    # Draws Level Stars
    materia.level.times do
      self.contents.blt(star_x += 24, 0, bitmap, Rect.new(0, 0, 24, 24))
    end
    # Draws Un-Leveled Stars
    (materia.exp_levels.size + 1 - materia.level).times do
      self.contents.blt(star_x += 24, 0, bitmap, Rect.new(0, 0, 24, 24), 100)
    end
    # Draws Level
    self.contents.draw_text(contents.width / 2 + 4, 52, contents.width / 2, 24, 'Level:')
    lev = materia.level == materia.exp_levels.size + 1 ? 'Mastered' : materia.level.to_s
    self.contents.draw_text(contents.width / 2 - 4, 52, contents.width / 2, 24, lev, 2)
    # Draws Experience
    self.contents.draw_text(contents.width / 2 + 4, 76, contents.width / 2, 24, 'Experience:')
    self.contents.draw_text(contents.width / 2 - 4, 76, contents.width / 2, 24, materia.experience.to_s, 2)
    # Draws Next Level
    self.contents.draw_text(contents.width / 2 + 4, 100, contents.width / 2, 24, 'Next Level:')
    nxt = lev == 'Mastered' ? 'N/A' : materia.exp_levels[materia.level - 1] - materia.experience
    self.contents.draw_text(contents.width / 2 - 4, 100, contents.width / 2, 24, nxt.to_s, 2)
    # Draws Skills
    self.contents.draw_text(4, 28, contents.width, 24, 'Skills:')
    for i in 0...(materia.level)
      self.contents.font.color = normal_color
      unless materia.skills[i].nil?
        self.contents.draw_text(8, 52 + i * 24, contents.width / 2 - 8, 24, $data_skills[materia.skills[i]].name)
      end
    end
    for i in (materia.level)...materia.skills.size
      self.contents.font.color = disabled_color
      unless materia.skills[i].nil?
        self.contents.draw_text(8, 52 + i * 24, contents.width / 2 - 8, 24, $data_skills[materia.skills[i]].name)
      end
    end
    if materia.skills.size == 0
      self.contents.draw_text(8, 52, contents.width / 2 - 8, 24, 'Nothing')
    end
    # Draws Special Effect
    self.contents.font.color = normal_color
    se = materia.special_effect.nil? ? 'Nothing' : materia.special_effect
    self.contents.draw_text(8, 172, contents.width, 24, "Special Effect: #{se}")
    # Draw Buy Value
    self.contents.font.size = 16
    self.contents.font.bold = true
    ox = contents.width / 3
    self.contents.draw_text(4, 200, ox, 16, "Buy Value: #{materia.new_value}")
    # Draw Sell Value
    self.contents.draw_text(ox, 200, ox, 16, "Sell Value: #{materia.sell_value}", 1)
    # Draw Mater Value
    self.contents.draw_text(ox * 2 - 4, 200, ox, 16, "Master Value: #{materia.master_value}", 2)
    # Draws Stat Effects
    self.contents.font.size = 14
    self.contents.draw_text(8, 222, contents.width / 2, 14, 'Attributes Effects:')
    stat_names = ['hp', 'sp', 'str', 'dex', 'agi', 'int'].collect! {|x| eval "$data_system.words.#{x}" }
    for i in 0...materia.stat_effects.size
      self.contents.draw_text(8, 222 + (i + 1) * 14, contents.width / 2, 14, stat_names[i])
      self.contents.draw_text(- 8, 222 + (i + 1)  * 14, contents.width / 2, 14, "#{materia.stat_effects[i]} %", 2)
    end
    # Draws Element & Status Effects
    self.contents.font.size = 14
    x, y = contents.width / 2 + 4, 222
    self.contents.draw_text(x, y, contents.width / 2, 14, 'Element & Status Effects:')
    if materia.elements.size + materia.states.size == 0
      self.contents.draw_text(x + 4, y + 14, contents.width / 2, 14, 'None')
    else
      # Draws Elements
      total = 1
      for i in 0...materia.elements.size
        total += 1
        ox = 4 + total % 2 * (contents.width / 4)
        oy = total / 2 * 14
        self.contents.draw_text(x + ox, y + oy, contents.width / 2, 14, $data_system.elements[materia.elements[i]])
      end
      # Draws States
      for i in 0...materia.states.size
        total += 1
        ox = 4 + total % 2 * (contents.width / 4)
        oy = total / 2 * 14
        self.contents.draw_text(x + ox, y + oy, contents.width / 2, 14, $data_states[materia.states[i]].name)
      end
    end
  end
end

#==============================================================================
# ** Window_MateriaList
#==============================================================================

class Window_MateriaList < Window_Selectable
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize(buying, materia_list = nil, show_cost = true)
    super(0, 128, 240, 352)
    self.visible = self.active = false
    # Creates Materia List
    if buying
      @materia = []
      for index in materia_list
        @materia << $data_materia[index].dup
      end
    else
      @materia = $game_party.materia.sort! {|a, b| a.id <=> b.id}
    end
    @buying, @show_cost = buying, show_cost
    refresh
    self.index = 0
  end
  #--------------------------------------------------------------------------
  # * 获得指向的魔石
  #--------------------------------------------------------------------------
  def materia
    return @materia[self.index]
  end
  #--------------------------------------------------------------------------
  # * 刷新
  #--------------------------------------------------------------------------
  def refresh
    # Clears Contents
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    # If item count is not 0, make a bit map and draw all items
    @materia.sort! {|a, b| a.id <=> b.id}
    @item_max = @materia.size
    if @item_max > 0
      self.contents = Bitmap.new(width - 32, row_max * 32)
      for i in 0...@item_max
        draw_item(i)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * 描绘魔石
  #     index : 索引
  #--------------------------------------------------------------------------
  def draw_item(index)
    # Checks to See if Selling materia
    if @buying
      self.contents.font.color = materia.buy_value > $game_party.gold ?
        disabled_color : normal_color
    end
    # Gets Materia
    materia = @materia[index]
    # Gets Icon Hue
    hue = materia.get_hue
    # Clears Bitmap Contents
    self.contents.fill_rect(Rect.new(0, index * 32, contents.width, 32), Color.new(0, 0, 0, 0))
    # Draws Materia Icon
    bitmap = RPG::Cache.icon('Materia Icon').dup
    bitmap.hue_change(hue)
    self.contents.blt(4, index * 32 + 4, bitmap, Rect.new(0, 0, 24, 24))
    # Draws Materia Name
    self.contents.draw_text(32, index * 32, contents.width, 32, materia.name)
    # If Show Cost
    if @show_cost
      # Draws Materia Cost
      value = @buying ? materia.buy_value : materia.sell_value
      self.contents.draw_text(- 4, index * 32, contents.width, 32, ": #{value}", 2)
    end
  end
end

#==============================================================================
# ** Window_MateriaActor
#==============================================================================

class Window_MateriaActor < Window_Base
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize(actor)
    super(0, 0, 640, 152)
    self.contents = Bitmap.new(width - 32, height - 32)
    @actor = actor
    @frame = 0
    refresh
  end
  #--------------------------------------------------------------------------
  # * 刷新
  #--------------------------------------------------------------------------
  def refresh(actor = @actor)
    self.contents.clear
    # Draws Actor Sprite
    draw_actor_sprite
    # Draw Actor Information
    draw_actor_bio
    # Draws Actor Equipment  
    draw_actor_equipment
    # Draws Actor Materia
    draw_actor_materia
  end
  #--------------------------------------------------------------------------
  # * 描画角色图像
  #--------------------------------------------------------------------------
  def draw_actor_sprite
    # Clears Actor Bitmap Arena
    self.contents.fill_rect(0, 0, 80, 120, Color.new(0, 0, 0, 0))
    # Gets Actor Bitmap
    bitmap = RPG::Cache.character(@actor.character_name, @actor.character_hue)
    # Transfer Actor Frame to src_bitmap
    self.contents.stretch_blt(Rect.new(0, 0, 80, 120), bitmap,
      Rect.new(bitmap.width / 4 * @frame, 0, bitmap.width / 4, bitmap.height / 4))
  end
  #--------------------------------------------------------------------------
  # * 描画角色信息
  #--------------------------------------------------------------------------
  def draw_actor_bio
    # Clears Bio Space
    self.contents.fill_rect(92, 0, 140, 120, Color.new(0, 0, 0, 0))
    # Draws Actor name
    self.contents.font.color = normal_color
    self.contents.draw_text(92, 0, 140, 22, @actor.name)
    # Draws Level
    self.contents.draw_text(92, 22, 140, 22, "Level : #{@actor.level}")
    # Draws Actor Class
    self.contents.draw_text(92, 44, 410, 22, "Class : #{$data_classes[@actor.class_id].name}")
    # Draws HP
    self.contents.draw_text(92, 66, 140, 22, "HP : #{@actor.hp} / #{@actor.maxhp}")
    draw_slant_bar(92, 90, @actor.hp, @actor.maxhp.to_f, 136, 4)
    # Draws SP
    self.contents.draw_text(92, 92, 140, 22, "SP : #{@actor.sp} / #{@actor.maxsp}")
    draw_slant_bar(92, 116, @actor.sp, @actor.maxsp.to_f, 136, 4, 
      Color.new(0, 0, 200), Color.new(0, 170, 0))
  end
  #--------------------------------------------------------------------------
  # * 描画角色装备
  #--------------------------------------------------------------------------
  def draw_actor_equipment
    # Clears Equipment Space
    self.contents.fill_rect(240, 0, 176, 120, Color.new(0, 0, 0, 0))
    # Draws Equipment
    draw_equipment(240, 0, $data_weapons[@actor.weapon_id], 0)
    draw_equipment(240, 24, $data_armors[@actor.armor1_id], 1)
    draw_equipment(240, 48, $data_armors[@actor.armor2_id], 2)
    draw_equipment(240, 72, $data_armors[@actor.armor3_id], 3)
    draw_equipment(240, 96, $data_armors[@actor.armor4_id], 4)
  end
  #--------------------------------------------------------------------------
  # * 描画角色装备的魔石
  #--------------------------------------------------------------------------
  def draw_actor_materia
    # Clears Materia Space
    self.contents.fill_rect(416, 0, 192, 120, Color.new(0, 0, 0, 0))
    # Draws Materia Slots Background
    for i in 0..4
      self.contents.fill_rect(416, i * 24 + 2, 192, 22, Color.new(0, 0, 0, 50))
    end
    # Draws Materia Slots
    for i in 0..4
      slots_x, y = 416 - 24, i * 24
      if i == 0
        if @actor.weapon_id == 0
          p_times, s_times = 0, 0
        else
          p_times = $data_weapons[@actor.weapon_id].paired_materia
          s_times = $data_weapons[@actor.weapon_id].single_materia
        end
      else
        if (eval "@actor.armor#{i}_id") == 0
          p_times, s_times = 0, 0
        else
          p_times = eval "$data_armors[@actor.armor#{i}_id].paired_materia"
          s_times = eval "$data_armors[@actor.armor#{i}_id].single_materia"
        end
      end
      # Draws Paired Materia
      p_times.times do
        bitmap = RPG::Cache.icon('Materia Paired Left')
        self.contents.blt(slots_x += 24, y, bitmap, Rect.new(0, 0, 24, 24))
        bitmap = RPG::Cache.icon('Materia Paired Right')
        self.contents.blt(slots_x += 24, y, bitmap, Rect.new(0, 0, 24, 24))
      end
      # Draws Single Materia
      s_times.times do
        bitmap = RPG::Cache.icon('Materia Single')
        self.contents.blt(slots_x += 24, y, bitmap, Rect.new(0, 0, 24, 24))
      end
    end
    # Draws Equipped Materia
    for i in 0...@actor.weapon_materia.size
      materia = @actor.weapon_materia[i]
      unless materia.nil?
        # Gets Icon Hue
        hue = materia.get_hue
        # Draws Icon
        bitmap = RPG::Cache.icon('Materia Icon').dup
        bitmap.hue_change(hue)
        self.contents.blt(416 + i * 24, 0, bitmap, Rect.new(0, 0, 24, 24))
      end
    end
    for h in 1..4
      size = eval "@actor.armor#{h}_materia.size"
      for i in 0...size
        list = eval "@actor.armor#{h}_materia"
        materia = list[i]
        unless materia.nil?
          # Gets Icon Hue
          hue = materia.get_hue
          # Draws Icon
          bitmap = RPG::Cache.icon('Materia Icon').dup
          bitmap.hue_change(hue)
          self.contents.blt(416 + i * 24, 24 * h, bitmap, Rect.new(0, 0, 24, 24))
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * 画面更新
  #--------------------------------------------------------------------------
  def update
    super
    # Checks to Update Picture
    if Graphics.frame_count % 10 == 0
      @frame == 3 ? @frame = 0 : @frame += 1
      draw_actor_sprite
    end
  end
  #--------------------------------------------------------------------------
  # * 描画数值槽
  #--------------------------------------------------------------------------
  def draw_slant_bar(x, y, min, max, width = 152, height = 6,
      bar_color = Color.new(150, 0, 0, 255), end_color = Color.new(255, 255, 60, 255))
    # Draw Border
    for i in 0..height
      self.contents.fill_rect(x + i, y + height - i, width + 1, 1, Color.new(50, 50, 50, 255))
    end
    # Draw Background
    for i in 1..(height - 1)
      r = 100 * (height - i) / height + 0 * i / height
      g = 100 * (height - i) / height + 0 * i / height
      b = 100 * (height - i) / height + 0 * i / height
      a = 255 * (height - i) / height + 255 * i / height
      self.contents.fill_rect(x + i, y + height - i, width, 1, Color.new(r, b, g, a))
    end
    # Draws Bar
    for i in 1..( (min / max) * width - 1)
      for j in 1..(height - 1)
        r = bar_color.red * (width - i) / width + end_color.red * i / width
        g = bar_color.green * (width - i) / width + end_color.green * i / width
        b = bar_color.blue * (width - i) / width + end_color.blue * i / width
        a = bar_color.alpha * (width - i) / width + end_color.alpha * i / width
        self.contents.fill_rect(x + i + j, y + height - j, 1, 1, Color.new(r, g, b, a))
      end
    end
  end
  #--------------------------------------------------------------------------
  # * 描画装备
  #--------------------------------------------------------------------------
  def draw_equipment(x, y, item, type)
    if item.nil?
      case type
      when 0  # Weapon
        bitmap = RPG::Cache.icon("001-Weapon01")
      when 1  # Shield
        bitmap = RPG::Cache.icon("009-Shield01")
      when 2  # Helmet
        bitmap = RPG::Cache.icon("010-Head01")
      when 3  # Armor
        bitmap = RPG::Cache.icon("014-Body02")
      when 4  # Accessory
        bitmap = RPG::Cache.icon("016-Accessory01")
      end
      contents.font.color, text, opacity = disabled_color, 'Nothing', disabled_color.alpha
    else
      bitmap = RPG::Cache.icon(item.icon_name)
      contents.font.color, text, opacity = normal_color, item.name, 255
    end
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), opacity)
    self.contents.draw_text(x + 28, y, 148, 24, text, 1)
  end
end

#==============================================================================
# ** Window_MateriaEquipBio
#==============================================================================

class Window_MateriaEquipBio < Window_Base
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize
    super(0, 152, 400, 328)
    self.contents = Bitmap.new(width - 32, height - 32)
  end
  #--------------------------------------------------------------------------
  # * 刷新
  #--------------------------------------------------------------------------
  def refresh(materia)
    self.contents.clear
    # If no Materia
    return if materia.nil?
    # Gets Icon Hue
    hue = materia.get_hue
    # Draws Materia Icon
    bitmap = RPG::Cache.icon('Materia Icon').dup
    bitmap.hue_change(hue)
    self.contents.blt(0, 0, bitmap, Rect.new(0, 0, 24, 24))
    # Draws Materia Name
    self.contents.font.color = normal_color
    self.contents.font.size = 22
    self.contents.font.bold = false
    self.contents.draw_text(32, 0, contents.width, 24, materia.name)
    # Gets Star Bitmap & Changes Hue
    bitmap = RPG::Cache.icon('Star - Icon').dup
    bitmap.hue_change(hue)
    # Gets Start of Star X Coordinate
    star_x = contents.width / 2 - 20
    # Draws Level Stars
    materia.level.times do
      self.contents.blt(star_x += 24, 0, bitmap, Rect.new(0, 0, 24, 24))
    end
    # Draws Un-Leveled Stars
    (materia.exp_levels.size + 1 - materia.level).times do
      self.contents.blt(star_x += 24, 0, bitmap, Rect.new(0, 0, 24, 24), 100)
    end
    # Draws Skills
    self.contents.font.size = 16
    self.contents.font.bold = true
    self.contents.draw_text(4, 28, contents.width, 16, 'Skills:')
    for i in 0...(materia.level)
      self.contents.font.color = normal_color
      unless materia.skills[i].nil?
        self.contents.draw_text(16, 44 + i * 16, contents.width / 2 - 8, 16, $data_skills[materia.skills[i]].name)
      end
    end
    for i in (materia.level)...materia.skills.size
      self.contents.font.color = disabled_color
      unless materia.skills[i].nil?
        self.contents.draw_text(16, 44 + i * 16, contents.width / 2 - 8, 16, $data_skills[materia.skills[i]].name)
      end
    end
    # Draws Level
    self.contents.font.color = normal_color
    self.contents.draw_text(contents.width / 2 + 4, 44, contents.width / 2, 16, 'Level:')
    lev = materia.level == materia.exp_levels.size + 1 ? 'Mastered' : materia.level.to_s
    self.contents.draw_text(contents.width / 2 - 4, 44, contents.width / 2, 16, lev, 2)
    # Draws Experience
    self.contents.draw_text(contents.width / 2 + 4, 60, contents.width / 2, 16, 'Experience:')
    self.contents.draw_text(contents.width / 2 - 4, 60, contents.width / 2, 16, materia.experience.to_s, 2)
    # Draws Next Level
    self.contents.draw_text(contents.width / 2 + 4, 76, contents.width / 2, 16, 'Next Level:')
    nxt = lev == 'Mastered' ? 'N/A' : materia.exp_levels[materia.level - 1] - materia.experience
    self.contents.draw_text(contents.width / 2 - 4, 76, contents.width / 2, 16, nxt.to_s, 2)
    # Draws Special Effect
    se = materia.special_effect.nil? ? 'Nothing' : materia.special_effect
    self.contents.draw_text(8, 124, contents.width, 16, "Special Effect: #{se}")
    # Draw Buy Value
    ox = contents.width / 3
    self.contents.draw_text(4, 156, ox, 16, "Buy Value: #{materia.new_value}")
    # Draw Sell Value
    self.contents.draw_text(ox, 156, ox, 16, "Sell Value: #{materia.sell_value}", 1)
    # Draw Mater Value
    self.contents.draw_text(ox * 2 - 4, 156, ox, 16, "Master Value: #{materia.master_value}", 2)
    # Draws Stat Effects
    self.contents.draw_text(8, 188, contents.width / 2, 16, 'Attributes Effects:')
    stat_names = ['hp', 'sp', 'str', 'dex', 'agi', 'int'].collect! {|x| eval "$data_system.words.#{x}" }
    for i in 0...materia.stat_effects.size
      self.contents.draw_text(8, 188 + (i + 1) * 14, contents.width / 2, 16, stat_names[i])
      self.contents.draw_text(- 8, 188 + (i + 1)  * 14, contents.width / 2, 16, "#{materia.stat_effects[i]} %", 2)
    end
    # Draws Element & Status Effects
    x, y = contents.width / 2 + 4, 188
    self.contents.draw_text(x, y, contents.width / 2, 16, 'Element & Status Effects:')
    if materia.elements.size + materia.states.size == 0
      self.contents.draw_text(x + 4, y + 14, contents.width / 2, 16, 'None')
    else
      # Draws Elements
      total = 1
      for i in 0...materia.elements.size
        total += 1
        ox = 4 + total % 2 * (contents.width / 4)
        oy = total / 2 * 16
        self.contents.draw_text(x + ox, y + oy, contents.width / 2, 16, $data_system.elements[materia.elements[i]])
      end
      # Draws States
      for i in 0...materia.states.size
        total += 1
        ox = 4 + total % 2 * (contents.width / 4)
        oy = total / 2 * 16
        self.contents.draw_text(x + ox, y + oy, contents.width / 2, 16, $data_states[materia.states[i]].name)
      end
    end
  end
end

#==============================================================================
# ** 标题画面
#==============================================================================

class Scene_Title
  alias sephiroth_sailcat_main main
  alias sephiroth_sailcat_new_game command_new_game
  alias sephiroth_sailcat_continue command_continue
  #--------------------------------------------------------------------------
  # * 主处理
  #--------------------------------------------------------------------------
  def main
    # Orginal Main Method
    sephiroth_sailcat_main
    # Creates Materia Data List
    $data_materia = Materia_System::MATERIA_LIST
  end
  #--------------------------------------------------------------------------
  # * 命令分支: 新游戏
  #--------------------------------------------------------------------------
  def command_new_game
    # Sets Weapon Materia Slots
    for i in 1...$data_weapons.size
      $data_weapons[i].set_materia_slots(Materia_System::WEAPON_MATERIA_SLOTS[i])
    end
    # Sets Armors Materia Slots
    for i in 1...$data_armors.size
      $data_armors[i].set_materia_slots(Materia_System::ARMORS_MATERIA_SLOTS[i])
    end
    # Orginal Command: New Game Method
    sephiroth_sailcat_new_game
  end
  #--------------------------------------------------------------------------
  # * 命令分支: 继续
  #--------------------------------------------------------------------------
  def command_continue
    # Orginal Continue Method
    sephiroth_sailcat_continue
    # Sets Weapon Materia Slots
    for i in 1...$data_weapons.size
      $data_weapons[i].set_materia_slots(Materia_System::WEAPON_MATERIA_SLOTS[i])
    end
    # Sets Armors Materia Slots
    for i in 1...$data_armors.size
      $data_armors[i].set_materia_slots(Materia_System::ARMORS_MATERIA_SLOTS[i])
    end
  end
end

#==============================================================================
# ** 魔石商店
#==============================================================================

class Scene_MateriaShop
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize(materia_avialable = [])
    @materia_avialable = materia_avialable
  end
  #--------------------------------------------------------------------------
  # * 主处理
  #--------------------------------------------------------------------------
  def main
    # Help Window
    @help_window = Window_Help.new
      @help_window.set_text('What Would You like to Do?')
    # Shop Commands Window
    @shop_options_window = Window_HorizCommand.new(
      ['Buy Materia', 'Sell Materia', 'Exit'], 480)
      @shop_options_window.y = 64
    # Party Gold Window
    @gold_window = Window_Gold.new
      @gold_window.x, @gold_window.y = 480, 64
    # Dummy Window
    @dummy_window = Window_Base.new(0, 128, 640, 352)
    # Buy Materia Window
    @buy_items = Window_MateriaList.new(true, @materia_avialable)
    # Sell Materia Window
    @sell_items = Window_MateriaList.new(false)
    # Materia Bio Window
    @materia_bio = Window_MateriaBio.new
    # Scene Objects
    @objects = [@help_window, @shop_options_window, @gold_window, @buy_items,
      @sell_items, @dummy_window, @materia_bio]
    # Execute transition
    Graphics.transition
    # Main loop
    while $scene == self
      # Update game screen
      Graphics.update
      # Update input information
      Input.update
      # Update Scene Objects
      @objects.each {|x| x.update}
      # Frame update
      update
    end
    # Prepare for transition
    Graphics.freeze
    # Dispose of Scene Objects
    @objects.each {|x| x.dispose}
  end
  #--------------------------------------------------------------------------
  # * 画面更新
  #--------------------------------------------------------------------------
  def update
    # Update : Shop Commands
    if @shop_options_window.active
      update_shop_commands
    # Update : Buy Materia
    elsif @buy_items.active
      update_buy_materia
    # Update : Sell Materia
    elsif @sell_items.active
      update_sell_materia
    end
  end
  #--------------------------------------------------------------------------
  # * 更新商店命令
  #--------------------------------------------------------------------------
  def update_shop_commands
    # Sets Help Window Text
    @help_window.set_text('What Would You like to Do?')
    # If B is Pressed
    if Input.trigger?(Input::B)
      # Plays Cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Proceeds To Map
      $scene = Scene_Map.new
    end
    # If C is Pressed
    if Input.trigger?(Input::C)
      # Plays Decision SE
      $game_system.se_play($data_system.decision_se)
      # Branch Shop Commands Index
      case @shop_options_window.index
      when 0 # Buy
        # Turns Off Shop Command Window
        @shop_options_window.active = false
        # Turns On Materia Bio Window
        @materia_bio.visible = true
        # Refreshes Materia Bio Window
        @materia_bio.refresh(@buy_items.materia)
        # Turns On Buy Items Window
        @buy_items.visible = @buy_items.active = true
      when 1 # Sell
        # Turns Off Shop Command Window
        @shop_options_window.active = false
        # Turns On Materia Bio Window
        @materia_bio.visible = true
        # Refreshes Materia Bio Window
        @materia_bio.refresh(@sell_items.materia)
        # Turns On Sell Items Window
        @sell_items.visible = @sell_items.active = true
      when 2 # Exit
        $scene = Scene_Map.new
      end
    end
  end
  #--------------------------------------------------------------------------
  # * 更新魔石购买窗口
  #--------------------------------------------------------------------------
  def update_buy_materia
    # Sets Help Window Text
    @help_window.set_text('Which Materia Would You like To Purchase?')
    # If B is Pressed
    if Input.trigger?(Input::B)
      # Plays Cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Turns Off Buy Materia Window
      @buy_items.visible = @buy_items.active = false
      # Resets index
      @buy_items.index = 0
      # Turns Off Materia Bio Window
      @materia_bio.visible = false
      # Turns On Shop Commands Window
      @shop_options_window.active = true
    end
    # If C is Pressed
    if Input.trigger?(Input::C)
      # Gets materia
      materia = @buy_items.materia
      # Checks to see enought money is possesed
      if $game_party.gold < materia.buy_value
        # Play buzzer SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # Play Shop SE
      $game_system.se_play($data_system.shop_se)
      # Gains Materia
      $game_party.gain_materia(materia.id)
      # Loses the Gold
      $game_party.lose_gold(materia.buy_value)
      # Refreshes Party Gold Window
      @gold_window.refresh
      # Refreshes Buy Materia Window
      @buy_items.refresh
      # Refreshes Sell Materia Window
      @sell_items.refresh
      # Refreshes Materia Bio Window
      @materia_bio.refresh(@buy_items.materia)
    end
    # If UP or DOWN is pressed
    if Input.trigger?(Input::UP) || Input.trigger?(Input::DOWN) ||
      Input.press?(Input::UP) || Input.press?(Input::DOWN) 
      # Refreshes Materia Bio Window
      @materia_bio.refresh(@buy_items.materia)
    end
  end
  #--------------------------------------------------------------------------
  # * 更新魔石售卖窗口
  #--------------------------------------------------------------------------
  def update_sell_materia
    # Sets Help Window Text
    @help_window.set_text('Which Materia Would You like To Sell')
    # If B is Pressed
    if Input.trigger?(Input::B)
      # Plays Cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Turns Off Buy Materia Window
      @sell_items.visible = @sell_items.active = false
      # Resets index
      @sell_items.index = 0
      # Turns Off Materia Bio Window
      @materia_bio.visible = false
      # Turns On Shop Commands Window
      @shop_options_window.active = true
    end
    # If C is Pressed
    if Input.trigger?(Input::C)
      if @sell_items.materia.nil?
        # Play Buzzer SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # Play Shop SE
      $game_system.se_play($data_system.shop_se)
      # Gains the Gold
      $game_party.gain_gold(@sell_items.materia.sell_value)
      # Refreshes Party Gold Window
      @gold_window.refresh
      # Deletes Materia
      $game_party.materia.delete_at(@sell_items.index)
      # Refreshes Sell Materia Window
      @sell_items.refresh
      # Resets index
      @sell_items.index = 0
      # Refreshes Materia Bio Window
      @materia_bio.refresh(@sell_items.materia)
    end
    # If UP or DOWN is pressed
    if Input.trigger?(Input::UP) || Input.trigger?(Input::DOWN) ||
      Input.press?(Input::UP) || Input.press?(Input::DOWN) 
      # Refreshes Materia Bio Window
      @materia_bio.refresh(@sell_items.materia)
    end
  end
end

#==============================================================================
# ** 魔石装备界面
#==============================================================================

class Scene_MateriaEquip
  #--------------------------------------------------------------------------
  # * 初始化
  #     actor_index : 角色ID
  #     equip_index : 装备索引
  #--------------------------------------------------------------------------
  def initialize(actor_index = 0, equip_index = 0)
    @actor_index = actor_index
    @equip_index = equip_index
    @materia_index = 0
    @actor = $game_party.actors[@actor_index]
  end
  #--------------------------------------------------------------------------
  # * 主处理
  #--------------------------------------------------------------------------
  def main
    # Character Bio Window
    @character_bio_window = Window_MateriaActor.new(@actor)
    # Materia Bio Window
    @materia_bio_window = Window_MateriaEquipBio.new
    # Materia List
    @materia_list_window = Window_MateriaList.new(false, $game_party.materia, false)
      @materia_list_window.x, @materia_list_window.y = 400, 152
      @materia_list_window.height = 328
      @materia_list_window.visible = true
    # Materia Pointer Sprite
    @pointer_sprite = Sprite.new
      @pointer_sprite.x = 416 + (@materia_index + 1) * 24 - 28
      @pointer_sprite.y = @equip_index * 24 + 18
      @pointer_sprite.z = 9999
      @pointer_sprite.bitmap = RPG::Cache.icon('Materia Cursor')
    # Updates Materia Bio
    update_materia_bio
    # Scene Objects
    @objects = [@character_bio_window, @materia_bio_window,
      @materia_list_window, @pointer_sprite]
    # Execute transition
    Graphics.transition
    # Main loop
    while $scene == self
      # Update game screen
      Graphics.update
      # Update input information
      Input.update
      # Updates Scene Objects
      @objects.each {|x| x.update}
      # Frame update
      update
    end
    # Prepare for transition
    Graphics.freeze
    # Dispose of Scene Objects
    @objects.each {|x| x.dispose}
  end
  #--------------------------------------------------------------------------
  # * 画面更新
  #--------------------------------------------------------------------------
  def update
    # List Update
    !@materia_list_window.active ? update_weapon_select : update_materia_select
  end
  #--------------------------------------------------------------------------
  # * 画面更新 : 武器选择
  #--------------------------------------------------------------------------
  def update_weapon_select
    # Updates Pointer Cursor
    @pointer_sprite.x = 416 + (@materia_index + 1) * 24 - 28
    @pointer_sprite.y = @equip_index * 24 + 18
    # If Up is pressed
    if Input.trigger?(Input::UP)
      # Plays Cursor SE
      $game_system.se_play($data_system.cursor_se)
      # Changes Equip Index
      @equip_index = @equip_index == 0 ? @equip_index = 4 : @equip_index -= 1
      # Resets Materia Index
      @materia_index = 0
      # Updates Materia Bio Window
      update_materia_bio
    end
    # If Down is pressed
    if Input.trigger?(Input::DOWN)
      # Plays Cursor SE
      $game_system.se_play($data_system.cursor_se)
      # Changes Equip Index
      @equip_index = @equip_index == 4 ? @equip_index = 0 : @equip_index += 1
      # Resets Materia Index
      @materia_index = 0
      # Updates Materia Bio Window
      update_materia_bio
    end
    # If Right is pressed
    if Input.trigger?(Input::RIGHT)
      # Plays Cursor SE
      $game_system.se_play($data_system.cursor_se)
      # Moves Cursor Right
      case @equip_index
      when 0
        max = @actor.weapon_materia.size
      when 1
        max = @actor.armor1_materia.size
      when 2
        max = @actor.armor2_materia.size
      when 3
        max = @actor.armor3_materia.size
      when 4
        max = @actor.armor4_materia.size
      end
      return if max == 0
      @materia_index = @materia_index == max - 1 ? @materia_index = 0 : @materia_index += 1
      # Updates Materia Bio Window
      update_materia_bio
    end
    # If Left is pressed
    if Input.trigger?(Input::LEFT)
      # Plays Cursor SE
      $game_system.se_play($data_system.cursor_se)
      # Moves Cursor Left
      case @equip_index
      when 0
        max = @actor.weapon_materia.size 
      when 1
        max = @actor.armor1_materia.size
      when 2
        max = @actor.armor2_materia.size
      when 3
        max = @actor.armor3_materia.size
      when 4
        max = @actor.armor4_materia.size
      end
      return if max == 0
      @materia_index = @materia_index == 0 ? @materia_index = max - 1 : @materia_index -= 1
      # Updates Materia Bio Window
      update_materia_bio
    end
    # If L is pressed
    if Input.trigger?(Input::L)
      @actor_index = @actor_index == 0 ? 
        @actor_index = $game_party.actors.size - 1 : @actor_index -= 1
      $scene = Scene_MateriaEquip.new(@actor_index, @equip_index)
    end
    # If R is pressed
    if Input.trigger?(Input::R)
      @actor_index = @actor_index == $game_party.actors.size - 1 ? 
        @actor_index =  0: @actor_index += 1
      $scene = Scene_MateriaEquip.new(@actor_index, @equip_index)
    end
    # If A button is pressed
    if Input.trigger?(Input::A)
      # Play equip SE
      $game_system.se_play($data_system.equip_se)
      # Unequips materia
      @actor.unequip_materia(@equip_index, @materia_index)
      # Refreshes List Window
      @materia_list_window.refresh
      # Update Actor Bio Portion
      @character_bio_window.draw_actor_bio
      # Updates Actor Materia Portion
      @character_bio_window.draw_actor_materia
      # Updates Bio Window
      update_materia_bio
    end
    # If B button is pressed
    if Input.trigger?(Input::B)
      # Plays Cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Proceeds To Map
      $scene = Scene_Map.new
    end
    # If C button is pressed
    if Input.trigger?(Input::C)
      # Plays Cancel SE
      $game_system.se_play($data_system.decision_se)
      # Turns on the Materia Select Window
      @materia_list_window.active = true
      # Updates Materia Bio Window
      update_materia_bio
    end
  end
  #--------------------------------------------------------------------------
  # * 画面更新:魔石选择
  #--------------------------------------------------------------------------
  def update_materia_select
    # If B button is pressed
    if Input.trigger?(Input::B)
      # Plays Cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Turns on the Materia Select Window
      @materia_list_window.active = false
    end
    # If C button is pressed
    if Input.trigger?(Input::C)
      if @materia_list_window.materia.nil?
        # Plays Buzzer SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # Play equip SE
      $game_system.se_play($data_system.equip_se)
      # Equips Materia
      @actor.equip_materia(@equip_index, @materia_index,
        @materia_list_window.index)
      # Refreshes List Window
      @materia_list_window.refresh
      # Update Actor Bio Portion
      @character_bio_window.draw_actor_bio
      # Updates Actor Materia Portion
      @character_bio_window.draw_actor_materia
      # Turns on the Materia Select Window
      @materia_list_window.active = false
      # Updates Bio Window
      update_materia_bio
    end
    # If Index Changes
    if Input.trigger?(Input::UP) || Input.trigger?(Input::DOWN) ||
      Input.press?(Input::UP) || Input.press?(Input::DOWN)
      # Updates Materia Bio Window
      update_materia_bio
    end
  end
  #--------------------------------------------------------------------------
  # * 画面更新:人物属性
  #--------------------------------------------------------------------------
  def update_materia_bio
    # If Materia Select
    if @materia_list_window.active
      @materia_bio_window.refresh(@materia_list_window.materia)
    # If Weapon Select
    else
      case @equip_index
      when 0
        item = @actor.weapon_materia
      when 1
        item = @actor.armor1_materia
      when 2
        item = @actor.armor2_materia
      when 3
        item = @actor.armor3_materia
      when 4
        item = @actor.armor4_materia
      end
      @materia_bio_window.refresh(item[@materia_index])
    end
  end
end

#==============================================================================
# ** 战斗画面(分割定义1)
#==============================================================================

class Scene_Battle
  alias sephiroth_sailcat_init initialize
  #--------------------------------------------------------------------------
  # * 初始化
  #--------------------------------------------------------------------------
  def initialize
    # Gets Data Skills Size
    @data_skill_size = $data_skills.size
    # Orgianl Main Method
    sephiroth_sailcat_init
  end
end

#==============================================================================
# ** 战斗画面(分割定义2)
#==============================================================================

class Scene_Battle
  alias sephiroth_sailcat_start_phase2 start_phase2
  #--------------------------------------------------------------------------
  # * 开始步骤 2
  #--------------------------------------------------------------------------
  def start_phase2
    # Removes Added Skills
    ($data_skills.size - @data_skill_size).times do
      $data_skills.pop
    end
    # Orginal Method
    sephiroth_sailcat_start_phase2
  end
end

#==============================================================================
# ** 战斗画面(分割定义3)
#==============================================================================

class Scene_Battle
  alias sephiroth_sailcat_skill_select update_phase3_skill_select
  alias sephiroth_sailcat_prior_actor phase3_prior_actor
  #--------------------------------------------------------------------------
  # * 回到前一角色
  #--------------------------------------------------------------------------
  def phase3_prior_actor
    # Orginal Previous Actor Method
    sephiroth_sailcat_prior_actor
    unless @active_battler.nil?
      # Checks to See if Skill Was already selected
      if @active_battler.current_action.skill_id > @data_skill_size - 1
        # Forgets Skill
        @active_battler.forget_skill(@active_battler.current_action.skill_id)
        # Deletes Skill From $data_skills
        $data_skills.pop
        # Sets Skill Selection to nil
        @skill = nil
      end
    end
  end
  #--------------------------------------------------------------------------
  # * 更新选择特技
  #--------------------------------------------------------------------------
  def update_phase3_skill_select
    # Orignal Enemy Select Method
    sephiroth_sailcat_skill_select
    # Gets Active Battlers Paired Mater
    paired_materia_set = @active_battler.return_paired_materia
    for paired_set in paired_materia_set
      materia = paired_set[2]
      other_materia = paired_set[3]
      if materia.special_effect == 'All'
        for skill_id in other_materia.skills
          if skill_id == @skill.id
            # Duplicates Skill and Changes ID
            new_skill = @skill.dup
            new_skill.scope = 2 if @skill.scope == 1
            new_skill.scope = 4 if @skill.scope == 3 || @skill.scope == 7
            new_skill.scope = 6 if @skill.scope == 5
            new_skill.id = $data_skills.size
            $data_skills << new_skill
            @active_battler.learn_skill(new_skill.id)
            # Set action
            @active_battler.current_action.skill_id = new_skill.id
            # End skill selection
            end_skill_select
            # End enemy selection
            end_enemy_select unless @enemy_arrow.nil?
            # End actor selection
            end_actor_select unless @actor_arrow.nil?
            # Go to command input for next actor
            phase3_next_actor
          end
        end
      end
    end
    return
  end
end