#===============================================================================
# 
# Yanfly Engine Melody - Skill Overhaul
# Last Date Updated: 2010.06.30
# Level: Normal
# 
# This script rewrites the skill scene and adds a new currency called JP, which
# stands for Job Points. Job Points are earned through battle and used to
# purchase new skills and passives.
# 
# Note that this script does not rework the way skills function. This script
# only reworks the way the Skill Scene appears and what it can be used for.
# However, what this script does do is create a new passive item based off of
# status effects. Passives are essentially status effects that stick around
# once an actor has learned them. 
# 
#===============================================================================
# Updates
# -----------------------------------------------------------------------------
# o 2010.06.30 - Battle End Bugfix.
# o 2010.06.25 - Fixed JP level up bug.
# o 2010.06.20 - Improved applied and canceled states in data windows.
# o 2010.06.18 - Added switch enabling for both learning skills and passives.
# o 2010.06.14 - Skill Equip System Compatibility.
# o 2010.06.11 - Finished Script.
# o 2010.06.03 - Started Script.
#===============================================================================
# Instructions
# -----------------------------------------------------------------------------
# To install this script, open up your script editor and copy/paste this script
# to an open slot below ▼ Materials but above ▼ Main. Remember to save.
# 
# -----------------------------------------------------------------------------
# Skill Tags - For Skill only.
# -----------------------------------------------------------------------------
# <jp cost: x>
# This sets the JP cost of the skill to x value. This is how much JP is needed
# by the actor in the actor's current class to learn the skill.
# 
# <jp require level: x>
# This requires the actor to be at least level x before being able to acquire
# the skill through JP.
# 
# <jp require skill: x>  or  <jp require skill: x, x>
# In order for the actor to learn the skill through using JP costs, the skill
# x must also be learned. If multiple tags are used, then all of the skills
# must be learned before the skill can be acquired through JP.
# 
# <jp require passive: x>  or  <jp require passive: x, x>
# In order for the actor to learn the passive through using JP costs, the 
# passive x must also be learned. If multiple tags are used, then all of the
# passives must be learned before the passive can be acquired through JP.
# 
# <jp require switch: x>  or  <jp require switches: x, x>
# This requires switch x to be on in order for the skill to appear in the list.
# 
# <custom data>
# icon, string1, string2
# </custom data>
# This allows you to input in custom data to be displayed in the learn skill
# data window. Replace "icon" with a number to depict which icon you want
# shown in the data. Replace "string1" with the category you want shown in the
# data. Replace "string2" with the text you want shown in the data.
# 
# -----------------------------------------------------------------------------
# State Tags - For Status Effects only.
# -----------------------------------------------------------------------------
# <jp gain: x%>
# This state adjusts the JP gain for the actor by x%. Stackable.
# 
# <jp cost: x>
# This sets the JP cost of the passive to x value. This is how much JP is
# needed by the actor in the actor's current class to learn the passive.
# 
# <jp require level: x>
# This requires the actor to be at least level x before being able to acquire
# the passive through JP.
# 
# <jp require skill: x>  or  <jp require skill: x, x>
# In order for the actor to learn the passive through using JP costs, the skill
# x must also be learned. If multiple tags are used, then all of the skills
# must be learned before the passive can be acquired through JP.
# 
# <jp require passive: x>  or  <jp require passive: x, x>
# In order for the actor to learn the passive through using JP costs, the 
# passive x must also be learned. If multiple tags are used, then all of the
# passives must be learned before the passive can be acquired through JP.
# 
# <jp require switch: x>  or  <jp require switches: x, x>
# This requires switch x to be on in order for the passive to appear in list.
# 
# <custom data>
# icon, string1, string2
# </custom data>
# This allows you to input in custom data to be displayed in the learn skill
# data window. Replace "icon" with a number to depict which icon you want
# shown in the data. Replace "string1" with the category you want shown in the
# data. Replace "string2" with the text you want shown in the data.
# 
# -----------------------------------------------------------------------------
# Enemy Tags - For Enemies only.
# -----------------------------------------------------------------------------
# <jp: x>
# This is the amount of JP the enemy provides the party when it is defeated.
# If this tag is not used, then the default enemy JP value will be used instead.
# 
# -----------------------------------------------------------------------------
# Debug Shortcuts - Only during $TEST and $BTEST mode
# -----------------------------------------------------------------------------
# During testplay mode, pressing F7 or F8 at the learning skill menus will
# lower or raise the current class's JP totals. Press F6 to refresh the windows
# and press F5 to learn the selected skill. Hold down Shift and press F5 to
# forget the selected skill.
#===============================================================================

$imported = {} if $imported == nil
$imported["SkillOverhaul"] = true

module YEM
  module SKILL
    
    #===========================================================================
    # Section I. Basic Settings
    # --------------------------------------------------------------------------
    # The following below will adjust the basic settings and vocabulary that
    # will display throughout the script. Change them as you see fit.
    #===========================================================================
    
    # These switches must be on in order for the learn skill and learn passive
    # items to appear in the skill menu.
    LEARN_SKILL_SWITCH   = 41
    LEARN_PASSIVE_SWITCH = 42
    
    # This adjusts the commands used within the skill scene. The command window
    # is the window that lets you switch between various skill scene options.
    # 
    # :view_skills     View all of the available skills usable by the actor.
    # :learn_skill     Teach the actor new skills using JP.
    # :learn_passive   Teach the actor new passives using JP.
    # :equip_skill     Requires Skill Equip System.
    # 
    COMMANDS =[
      :view_skills,   # View all of the available skills usable by the actor.
      :learn_skill,   # Teach the actor new skills using JP.
      :equip_skill,   # Requires Skill Equip System.
      :learn_passive, # Teach the actor new passives using JP.
    ] # Do not remove this.
    
    # The following determines the vocabulary used for the remade skill scene.
    # Adjust it accordingly to set the way text is displayed.
    VOCAB ={
      :view_skills   => "View Skill",
      :learn_skill   => "Learn Skill",
      :learn_passive => "Passives",
    } # Do not remove this.
    
    #===========================================================================
    # Section II. JP Ruleset
    # --------------------------------------------------------------------------
    # This adjusts the rules regarding the way JP appears, is earned, and spent
    # in the game. Adjust it as you see fit. Each character's JP pool is class-
    # based, meaning that for each class, actors will have different JP values.
    # These values are stored and retained for future usage.
    #===========================================================================
    
    # This is how JP will appear in your game both visually and verbally.
    JP_TERM = "JP"   # This is the vocab used for the JP currency.
    JP_ICON = 145    # This is the icon used for JP.
    JP_SIZE = 16     # This is the font size used for JP costs.
    HIDE_JP = false  # If true, JP is hidden in the skill scene.
    
    # This sets the maximum amount of JP a character can earn per class.
    MAXIMUM_JP = 9999999
    
    # This will be the text displayed if the skill has been learned.
    LEARNED_TEXT = "Learned"
    
    # These hashes adjust what skills each class can learn. Fill in the arrays
    # with the skill ID's of learnable skills. Class 0's hash allows all classes
    # to be able to learn from it. Do not delete class 0.
    CLASS_SKILLS ={
    # ID => [Skill ID's],
       0 => [],
       1 => [121..160],
       2 => [161..200],
       3 => [201..240],
       4 => [241..280],
    } # Do not remove this.
    
    # These hashes adjust what passives each class can learn. Fill in the arrays
    # with the skill ID's of status effects. Class 0's hash allows all classes
    # to be able to learn from it. Do not delete class 0.
    CLASS_PASSIVES ={
    # ID => [State ID's],
       0 => [57..70],
       1 => [],
       2 => [],
       3 => [],
       4 => [],
    } # Do not remove this.
    
    # This is the default JP cost of each of the skills without a <jp cost: x>
    # tag placed in the skill's notebox.
    DEFAULT_JP_SKILL_COST   = 100
    DEFAULT_JP_PASSIVE_COST = 1000
    
    # Setting the following to true will have the game automatically create
    # JP costs based on what the game deems to be reasonable for each skill.
    AUTO_CREATE_JP_SKILL_COSTS = true
    JP_SKILL_COSTS ={
    # Skill Property => Factor,
      :base_damage   => 0.2000, # Additional cost per base damage point.
      :variance      => 0.5000, # Additional cost per amount of variance.
      :atk_f         => 0.5000, # Additional cost per ATK_F multiplier.
      :def_f         => 0.2500, # Additional cost per DEF_F multiplier.
      :spi_f         => 0.3333, # Additional cost per SPI_F multiplier.
      :res_f         => 0.3000, # Additional cost per RES_F multiplier.
      :dex_f         => 0.2750, # Additional cost per RES_F multiplier.
      :agi_f         => 0.2000, # Additional cost per RES_F multiplier.
      :physical      => 50.000, # Additional cost if a physical attack.
      :damage_to_mp  => 50.000, # Additional cost if deals damage to MP.
      :absorb_dmg    => 100.00, # Additional cost if it absorbs damage.
      :ignore_def    => 100.00, # Additional cost if it ignores defense.
      :element       => 25.000, # Additional cost per element.
      :status_effect => 20.000, # Additional cost per status effect.
      :multi_target  => 2.5000, # Multiply by this amount if multi-target.
    } # Do not remove this.
    
    #===========================================================================
    # Section III. Learn Data Window
    # --------------------------------------------------------------------------
    # This section adjusts the properties for the learn skill portion's data
    # window that appears in the lower right corner of the screen. This window
    # displays information regarding JP costs and various skill properties.
    #===========================================================================
    
    # This hash contains all of the information and data regarding the learn
    # data window. Adjust it accordingly.
    LEARN_DATA ={
      :fontsize   => 16,
      :require    => "Requirements",
      :properties => "Properties",
      :jp_cost    => "JP Cost",
      :skill_cost => "Skill Cost",
      :dmg_icon   => 119,
      :heal_icon  => 128,
      :base_dmg   => "Base Damage",
      :base_heal  => "Base Healing",
      :multiplier => "%s Multiplier",
      :element    => "Element",
      :add_state  => "Applies",
      :rem_state  => "Cancels",
      :stat_rate  => "%s Rate",
      :stat_set   => "%s Change",
    } # Do not remove this.
    
    # This array contains all of the elements you want displayed and in which
    # order to display them in. You can display them as individual integers or
    # as number ranges.
    SHOWN_ELEMENTS = [3, 4, 5, 6..10]
    
    # Since elements do not have icons innately, use the following hash below
    # adjust and apply icons to them.
    ELEMENT_ICONS ={
      3 => 104,  # Fire element.
      4 => 105,  # Ice element.
      5 => 106,  # Volt element.
      6 => 108,  # Earth element.
      7 => 107,  # Water element.
      8 => 109,  # Air element.
      9 => 110,  # Light element.
     10 => 111,  # Dark element.
    } # Do not remove this.
    
    #===========================================================================
    # Section IV. JP Earning Settings
    # --------------------------------------------------------------------------
    # JP can be earned through a number of ways. They can be earned through
    # regular attacks, guarding, using skills, using items, or simply leveling
    # up an actor.
    #===========================================================================
    
    # This hash adjusts the various cases of when actors earn JP and by how
    # much. JP earned can come from a set factor, a random factor, or both.
    EARN_JP ={
      :attack_set  => 10,  # Set JP earned from regular attacks.
      :attack_rand => 5,   # Random JP earned from regular attacks.
      :guard_set   => 8,   # Set JP earned from guarding.
      :guard_rand  => 4,   # Random JP earned from regular guarding.
      :skill_set   => 12,  # Set JP earned from using skills.
      :skill_rand  => 6,   # Random JP earned from using skills.
      :item_set    => 6,   # Set JP earned from using items.
      :item_rand   => 3,   # Random JP earned from using items.
      :level_set   => 500, # Set JP earned from leveling up.
      :level_rand  => 200, # Random JP earned from leveling up.
      :enemy_set   => 100, # The default JP an enemy leaves when killed.
    } # Do not remove this.
    
  end # SKILL
end # YEM

#===============================================================================
# Editting anything past this point may potentially result in causing computer
# damage, incontinence, explosion of user's head, coma, death, and/or halitosis.
# Therefore, edit at your own risk.
#===============================================================================

module YEM
  module REGEXP
  module SKILL
    
    JP_COST  = /<(?:JP_COST|jp cost):[ ]*(\d+)>/i
    JP_REQ   = /<(?:JP_REQUIRE|jp require)[ ](.*):[ ](\d+(?:\s*,\s*\d+)*)>/i
    
    CUSTOM_DATA1 = /<(?:CUSTOM_DATA|custom data)>/i
    CUSTOM_DATA2 = /<\/(?:CUSTOM_DATA|custom data)>/i
    
  end # SKILL
  module STATE
    
    JP_COST  = /<(?:JP_COST|jp cost):[ ]*(\d+)>/i
    JP_REQ   = /<(?:JP_REQUIRE|jp require)[ ](.*):[ ](\d+(?:\s*,\s*\d+)*)>/i
    
    JP_RATE  = /<(?:JP_GAIN|jp gain):[ ]*(\d+)([%％])>/i
    
    PASSIVE_DESCRIPTION1 = /<(?:PASSIVE_DESCRIPTION|passive description)>/i
    PASSIVE_DESCRIPTION2 = /<\/(?:PASSIVE_DESCRIPTION|passive description)>/i
    CUSTOM_DATA1 = /<(?:CUSTOM_DATA|custom data)>/i
    CUSTOM_DATA2 = /<\/(?:CUSTOM_DATA|custom data)>/i
    
  end # STATE
  module ENEMY
    
    JP = /<(?:JP|jp):[ ]*(\d+)>/i
    
  end # ENEMY
  end # REGEXP
  module SKILL
    module_function
    #--------------------------------------------------------------------------
    # convert_integer_array
    #--------------------------------------------------------------------------
    def convert_integer_array(array)
      result = []
      array.each { |i|
        case i
        when Range; result |= i.to_a
        when Integer; result |= [i]
        end }
      return result
    end
    
    #--------------------------------------------------------------------------
    # full_convert_hash
    #--------------------------------------------------------------------------
    def full_convert_hash(hash)
      result = {}
      hash.each { |key|
        result[key[0]] = convert_integer_array(key[1]) }
      return result
    end
  
    #--------------------------------------------------------------------------
    # converted_contants
    #--------------------------------------------------------------------------
    CLASS_SKILLS = full_convert_hash(CLASS_SKILLS)
    CLASS_PASSIVES = full_convert_hash(CLASS_PASSIVES)
    SHOWN_ELEMENTS = convert_integer_array(SHOWN_ELEMENTS)
  end # SKILL
end # YEM

#===============================================================================
# Vocab
#===============================================================================

module Vocab
  
  #--------------------------------------------------------------------------
  # self.jp
  #--------------------------------------------------------------------------
  def self.jp; return YEM::SKILL::JP_TERM; end
  
end # Vocab

#===============================================================================
# module Icon
#===============================================================================

module Icon
  
  #--------------------------------------------------------------------------
  # self.element
  #--------------------------------------------------------------------------
  def self.element(element_id)
    icon = YEM::SKILL::ELEMENT_ICONS[element_id]
    return (icon == nil) ? 0 : icon
  end
  
  #--------------------------------------------------------------------------
  # self.jp
  #--------------------------------------------------------------------------
  def self.jp; return YEM::SKILL::JP_ICON; end
    
  #--------------------------------------------------------------------------
  # self.level
  #--------------------------------------------------------------------------
  def self.level; return YEM::SKILL::JP_ICON; end
  
  #--------------------------------------------------------------------------
  # self.base_damage
  #--------------------------------------------------------------------------
  def self.base_damage; return YEM::SKILL::LEARN_DATA[:dmg_icon]; end
  
  #--------------------------------------------------------------------------
  # self.base_healing
  #--------------------------------------------------------------------------
  def self.base_healing; return YEM::SKILL::LEARN_DATA[:heal_icon]; end
  
end # Icon
  
#===============================================================================
# RPG::Skill
#===============================================================================

class RPG::Skill < RPG::UsableItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :custom_data
  attr_accessor :jp_cost
  attr_accessor :jp_require
  
  #--------------------------------------------------------------------------
  # common cache: yem_cache_skill_so
  #--------------------------------------------------------------------------
  def yem_cache_skill_so
    return if @cached_skill_so; @cached_skill_so = true
    create_default_jp_cost
    @custom_data = []
    enable_custom_data = false
    @jp_require = {} if @jp_require == nil
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEM::REGEXP::SKILL::JP_COST
        @jp_cost = $1.to_i
      #---
      when YEM::REGEXP::SKILL::JP_REQ
        case $1.upcase
        when "SKILL", "SKILLS"
          type = :skills
        when "PASSIVE", "PASSIVES"
          type = :passives
        when "LEVEL"
          type = :level
        when "SWITCH", "SWITCHES"
          type = :switches
        else; next
        end
        @jp_require[type] = [] if @jp_require[type] == nil
        $2.scan(/\d+/).each { |num| 
        @jp_require[type].push(num.to_i) if num.to_i > 0 }
      #---
      when YEM::REGEXP::SKILL::CUSTOM_DATA1
        enable_custom_data = true
      when YEM::REGEXP::SKILL::CUSTOM_DATA2
        enable_custom_data = false
      when /(\d+),[ ](.*),[ ](.*)/i
        next unless enable_custom_data
        array = [$1.to_i, $2.to_s, $3.to_s]
        @custom_data.push(array)
      #---
      end
    } # self.note.split
  end # yem_cache_skill_so
  
  #--------------------------------------------------------------------------
  # new method: create_default_jp_cost
  #--------------------------------------------------------------------------
  def create_default_jp_cost
    @jp_cost = YEM::SKILL::DEFAULT_JP_SKILL_COST
    return unless YEM::SKILL::AUTO_CREATE_JP_SKILL_COSTS
    if $imported["BattleEngineMelody"]
      yem_cache_baseitem_bem
      yem_cache_usableitem_bem
    end
    hash = YEM::SKILL::JP_SKILL_COSTS
    @jp_cost += (@base_damage * hash[:base_damage]).abs
    @jp_cost += @variance * hash[:variance]
    @jp_cost += @atk_f * hash[:atk_f]
    @jp_cost += @spi_f * hash[:spi_f]
    if $imported["BattleEngineMelody"]
      @jp_cost += @def_f * hash[:def_f]
      @jp_cost += @agi_f * hash[:agi_f]
      @jp_cost += @dex_f * hash[:dex_f] if $imported["DEX Stat"]
      @jp_cost += @res_f * hash[:res_f] if $imported["DEX Stat"]
    end
    @jp_cost += hash[:physical] if @physical_attack
    @jp_cost += hash[:damage_to_mp] if @damage_to_mp
    @jp_cost += hash[:absorb_dmg] if @absorb_damage
    @jp_cost += hash[:ignore_def] if @ignore_defense
    @jp_cost += @element_set.size * hash[:element]
    @jp_cost += @plus_state_set.size * hash[:status_effect]
    @jp_cost += @minus_state_set.size * hash[:status_effect]
    @jp_cost *= hash[:multi_target] if [2, 3, 5, 6, 8, 10].include?(@scope)
    @jp_cost = Integer(@jp_cost)
  end
  
end # RPG::Skill

#===============================================================================
# RPG::State
#===============================================================================

class RPG::State
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :custom_data
  attr_accessor :jp_cost
  attr_accessor :jp_rate
  attr_accessor :jp_require
  attr_accessor :passive_description
  
  #--------------------------------------------------------------------------
  # common cache: yem_cache_state_so
  #--------------------------------------------------------------------------
  def yem_cache_state_so
    return if @cached_state_so; @cached_state_so = true
    @jp_cost = YEM::SKILL::DEFAULT_JP_PASSIVE_COST
    @jp_rate = 100
    @custom_data = []
    @jp_require = {} if @jp_require == nil
    @passive_description = ""
    enable_custom_data = false
    enable_passive_description = false
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEM::REGEXP::STATE::JP_COST
        @jp_cost = $1.to_i
      when YEM::REGEXP::STATE::JP_RATE
        @jp_rate = $1.to_i
      #---
      when YEM::REGEXP::STATE::JP_REQ
        case $1.upcase
        when "SKILL", "SKILLS"
          type = :skills
        when "PASSIVE", "PASSIVES"
          type = :passives
        when "LEVEL"
          type = :level
        when "SWITCH", "SWITCHES"
          type = :switches
        else; next
        end
        @jp_require[type] = [] if @jp_require[type] == nil
        $2.scan(/\d+/).each { |num| 
        @jp_require[type].push(num.to_i) if num.to_i > 0 }
      #---
      when YEM::REGEXP::STATE::CUSTOM_DATA1
        enable_custom_data = true
      when YEM::REGEXP::STATE::CUSTOM_DATA2
        enable_custom_data = false
      when /(.*),[ ](.*),[ ](.*)/i
        next unless enable_custom_data
        array = [$1.to_i, $2.to_s, $3.to_s]
        @custom_data.push(array)
      #---
      #---
      when YEM::REGEXP::STATE::PASSIVE_DESCRIPTION1
        enable_passive_description = true
      when YEM::REGEXP::STATE::PASSIVE_DESCRIPTION2
        enable_passive_description = false
      else
        @passive_description += line.to_s if enable_passive_description
      end
    } # self.note.split
  end # yem_cache_state_so
  
end # RPG::State

#===============================================================================
# RPG::Enemy
#===============================================================================

class RPG::Enemy
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :jp
  
  #--------------------------------------------------------------------------
  # common cache: yem_cache_enemy_so
  #--------------------------------------------------------------------------
  def yem_cache_enemy_so
    return if @cached_enemy_so; @cached_enemy_so = true
    @jp = YEM::SKILL::EARN_JP[:enemy_set]
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEM::REGEXP::ENEMY::JP
        @jp = $1.to_i
      end
    } # self.note.split
  end # yem_cache_enemy_so
  
end # RPG::Enemy

#===============================================================================
# Scene_Title
#===============================================================================

class Scene_Title < Scene_Base
  
  #--------------------------------------------------------------------------
  # alias method: load_bt_database
  #--------------------------------------------------------------------------
  alias load_bt_database_so load_bt_database unless $@
  def load_bt_database
    load_bt_database_so
    load_so_cache
  end
  
  #--------------------------------------------------------------------------
  # alias method: load_database
  #--------------------------------------------------------------------------
  alias load_database_so load_database unless $@
  def load_database
    load_database_so
    load_so_cache
  end
  
  #--------------------------------------------------------------------------
  # new method: load_so_cache
  #--------------------------------------------------------------------------
  def load_so_cache
    groups = [$data_skills, $data_states, $data_enemies]
    for group in groups
      for obj in group
        next if obj == nil
        obj.yem_cache_skill_so if obj.is_a?(RPG::Skill)
        obj.yem_cache_state_so if obj.is_a?(RPG::State)
        obj.yem_cache_enemy_so if obj.is_a?(RPG::Enemy)
      end
    end
  end
  
end # Scene_Title

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

class Game_Battler
  
  #--------------------------------------------------------------------------
  # alias method: states
  #--------------------------------------------------------------------------
  alias states_so states unless $@
  def states
    result = states_so
    result |= self.passives if self.actor?
    return result
  end
  
end # Game_Battler
  
#===============================================================================
# Game_Actor
#===============================================================================

class Game_Actor < Game_Battler
  
  #--------------------------------------------------------------------------
  # alias method: level_up
  #--------------------------------------------------------------------------
  alias level_up_so level_up unless $@
  def level_up
    level_up_so
    jp = YEM::SKILL::EARN_JP[:level_set]
    random = YEM::SKILL::EARN_JP[:level_rand] 
    jp += rand(random) if random > 0
    earn_jp(jp)
  end
  
  #--------------------------------------------------------------------------
  # new method: jp
  #--------------------------------------------------------------------------
  def jp(cl_id = 0)
    @jp = {} if @jp == nil
    cl_id = @class_id if cl_id <= 0
    @jp[cl_id] = 0 if @jp[cl_id] == nil
    return @jp[cl_id]
  end
  
  #--------------------------------------------------------------------------
  # new method: earn_jp
  #--------------------------------------------------------------------------
  def earn_jp(amount = 0)
    @jp = {} if @jp == nil
    @jp[@class_id] = 0 if @jp[@class_id] == nil
    for state in states
      cases = $imported["BattleEngineMelody"] ? stack(state) : 1
      cases.times do amount *= state.jp_rate / 100.0 end
    end
    change_jp(@class_id, Integer(amount))
  end
  
  #--------------------------------------------------------------------------
  # new method: lose_jp
  #--------------------------------------------------------------------------
  def lose_jp(amount = 0)
    @jp = {} if @jp == nil
    @jp[@class_id] = 0 if @jp[@class_id] == nil
    change_jp(@class_id, -amount)
  end
  
  #--------------------------------------------------------------------------
  # new method: change_jp
  #--------------------------------------------------------------------------
  def change_jp(cl_id, amount)
    @jp = {} if @jp == nil
    @jp[cl_id] = 0 if @jp[cl_id] == nil
    @jp[cl_id] = [[@jp[cl_id] + amount, 0].max, YEM::SKILL::MAXIMUM_JP].min
  end
  
  #--------------------------------------------------------------------------
  # new method: passives
  #--------------------------------------------------------------------------
  def passives
    result = []
    @learned_passives = [] if @learned_passives == nil
    for state_id in @learned_passives
      state = $data_states[state_id]
      next if state == nil
      result.push(state)
    end
    return result
  end
  
  #--------------------------------------------------------------------------
  # new method: passive_learn?
  #--------------------------------------------------------------------------
  def passive_learn?(state)
    state = state.id if state.is_a?(RPG::State)
    @learned_passives = [] if @learned_passives == nil
    return @learned_passives.include?(state)
  end
  
  #--------------------------------------------------------------------------
  # new method: learn_passive
  #--------------------------------------------------------------------------
  def learn_passive(state_id)
    return if passive_learn?(state_id)
    @learned_passives = [] if @learned_passives == nil
    @learned_passives.push(state_id)
    @learned_passives.sort!
  end
  
  #--------------------------------------------------------------------------
  # new method: forget_passive
  #--------------------------------------------------------------------------
  def forget_passive(state_id)
    @learned_passives = [] if @learned_passives == nil
    @learned_passives.delete(state_id)
  end
  
end # Game_Actor

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

class Game_Party < Game_Unit
  
  #--------------------------------------------------------------------------
  # alias method: setup_starting_members
  #--------------------------------------------------------------------------
  alias setup_starting_members_so setup_starting_members unless $@
  def setup_starting_members
    setup_starting_members_so
    $game_switches[YEM::SKILL::LEARN_SKILL_SWITCH] = true
    $game_switches[YEM::SKILL::LEARN_PASSIVE_SWITCH] = true
  end
  
end # Game_Party

#===============================================================================
# Game_Troop
#===============================================================================

class Game_Troop < Game_Unit
  
  #--------------------------------------------------------------------------
  # distribute_jp
  #--------------------------------------------------------------------------
  def distribute_jp
    jp = 0
    for member in dead_members
      jp += member.enemy.jp
    end
    for member in $game_party.members
      member.earn_jp(jp)
    end
  end
  
end # Game_Troop
  
#===============================================================================
# Window_Command_Centered
#===============================================================================

class Window_Command_Centered < Window_Command
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(index, enabled = true)
    rect = item_rect(index)
    rect.x += 4
    rect.width -= 8
    self.contents.clear_rect(rect)
    self.contents.font.color = normal_color
    self.contents.font.color.alpha = enabled ? 255 : 128
    self.contents.draw_text(rect, @commands[index], 1)
  end
  
end # Window_Command_Centered

#===============================================================================
# Window_Actor_Skill_Status
#===============================================================================

class Window_Actor_Skill_Status < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(actor)
    super(160, 0, Graphics.width - 160, 128)
    @actor = actor
    @class_id = actor.class_id
    refresh
  end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(new_actor)
    @actor = new_actor
    @class_id = new_actor.class_id
    refresh
  end
  
  #--------------------------------------------------------------------------
  # class_id=
  #--------------------------------------------------------------------------
  def class_id=(new_class)
    @class_id = new_class
    refresh
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    draw_actor_face(@actor, 0, 0)
    dx = 108; dy = 0
    draw_actor_name(@actor, dx, dy)
    draw_actor_class(@actor, dx + 120, dy)
    draw_actor_level(@actor, dx, dy + WLH * 1)
    draw_actor_state(@actor, dx, dy + WLH * 2)
    draw_actor_hp(@actor, dx + 120, dy + WLH * 1)
    draw_actor_mp(@actor, dx + 120, dy + WLH * 2)
    draw_actor_jp(@actor, @class_id, dx + 120, dy + WLH * 3)
  end
  
  #--------------------------------------------------------------------------
  # draw_actor_jp
  #--------------------------------------------------------------------------
  def draw_actor_jp(actor, class_id, dx, dy)
    return if YEM::SKILL::HIDE_JP
    self.contents.font.color = system_color
    self.contents.draw_text(dx, dy, 120, WLH, Vocab.jp, 0)
    draw_icon(Icon.jp, dx+96, dy)
    jp = actor.jp(class_id)
    self.contents.font.color = normal_color
    self.contents.draw_text(dx, dy, 96, WLH, jp, 2)
  end
  
end # Window_Actor_Skill_Status

#===============================================================================
# Window_Skill
#===============================================================================

class Window_Skill < Window_Selectable
  
  #--------------------------------------------------------------------------
  # new method: actor=
  #--------------------------------------------------------------------------
  def actor=(new_actor)
    @actor = new_actor
    refresh
    self.oy = 0
    self.index = 0
  end
  
end # Window_Skill

#===============================================================================
# Window_LearnSkill
#===============================================================================

class Window_LearnSkill < Window_Selectable
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(actor, help_window)
    @actor = actor
    @class_id = @actor.class_id
    @help_window = help_window
    dy = @help_window.y + @help_window.height
    super(0, dy, Graphics.width - 240, Graphics.height - dy)
    refresh
    self.active = false
    self.index = 0
  end
  
  #--------------------------------------------------------------------------
  # skill
  #--------------------------------------------------------------------------
  def skill; return @data[self.index]; end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(new_actor)
    @actor = new_actor
    @class_id = new_actor.class_id
    refresh
    self.oy = 0
    self.index = 0
  end
  
  #--------------------------------------------------------------------------
  # class_id=
  #--------------------------------------------------------------------------
  def class_id=(new_class)
    @class_id = new_class
    refresh
    self.oy = 0
    self.index = 0
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    if @cache_class != @class_id
      @cache_class = @class_id
      array = YEM::SKILL::CLASS_SKILLS[0]
      if YEM::SKILL::CLASS_SKILLS.include?(@class_id)
        array |= YEM::SKILL::CLASS_SKILLS[@class_id]
        array.sort!
      end
      @data = []
      for skill_id in array
        skill = $data_skills[skill_id]
        next unless include?(skill)
        @data.push(skill)
      end
    end
    @item_max = @data.size
    self.index = [[self.index, @item_max-1].min, 0].max
    create_contents
    for i in 0...@item_max; draw_item(i); end
  end
  
  #--------------------------------------------------------------------------
  # include?
  #--------------------------------------------------------------------------
  def include?(skill)
    return false if skill == nil
    return false if skill.name == ""
    if skill.jp_require[:switches] != nil
      for switch_id in skill.jp_require[:switches]
        return false unless $game_switches[switch_id]
      end
    end
    return true
  end
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(index)
    rect = item_rect(index)
    self.contents.clear_rect(rect)
    skill = @data[index]
    return if skill == nil
    enabled = enabled?(skill)
    draw_obj_name(skill, rect.clone, enabled)
    draw_obj_cost(skill, rect.clone, enabled)
  end
  
  #--------------------------------------------------------------------------
  # enabled?
  #--------------------------------------------------------------------------
  def enabled?(skill)
    return false if skill == nil
    return true if @actor.skill_learn?(skill)
    #---
    if skill.jp_require[:level] != nil
      return false if skill.jp_require[:level][0] > @actor.level
    end
    #---
    if skill.jp_require[:skills] != nil
      for skill_id in skill.jp_require[:skills]
        next if $data_skills[skill_id] == nil
        return false unless @actor.skill_learn?($data_skills[skill_id])
      end
    end
    #---
    if skill.jp_require[:passives] != nil
      for state_id in skill.jp_require[:passives]
        next if $data_states[state_id] == nil
        return false unless @actor.passive_learn?($data_states[state_id])
      end
    end
    #---
    return @actor.jp(@class_id) >= skill.jp_cost
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_obj_name
  #--------------------------------------------------------------------------
  def draw_obj_name(obj, rect, enabled)
    draw_icon(obj.icon_index, rect.x, rect.y, enabled)
    self.contents.font.size = Font.default_size
    self.contents.font.color = normal_color
    self.contents.font.color.alpha = enabled ? 255 : 128
    rect.width -= 96
    self.contents.draw_text(rect.x+24, rect.y, rect.width, WLH, obj.name, 0)
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_obj_cost
  #--------------------------------------------------------------------------
  def draw_obj_cost(obj, rect, enabled)
    if @actor.skill_learn?(obj)
      self.contents.font.size = YEM::SKILL::JP_SIZE
      self.contents.font.color = normal_color
      self.contents.font.color.alpha = enabled ? 255 : 128
      text = YEM::SKILL::LEARNED_TEXT
      self.contents.draw_text(rect.x, rect.y, rect.width-4, WLH, text, 2)
    else
      draw_icon(Icon.jp, rect.x + rect.width - 24, rect.y, enabled)
      self.contents.font.size = YEM::SKILL::JP_SIZE
      self.contents.font.color = normal_color
      self.contents.font.color.alpha = enabled ? 255 : 128
      cost = obj.jp_cost
      self.contents.draw_text(rect.x, rect.y, rect.width-24, WLH, cost, 2)
    end
  end
  
  #--------------------------------------------------------------------------
  # update_help
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_text(skill == nil ? "" : skill.description)
  end
  
end # Window_LearnSkill

#===============================================================================
# Window_LearnData
#===============================================================================

class Window_LearnData < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(actor, main_window)
    @actor = actor
    @class_id = @actor.class_id
    @main_window = main_window
    super(@main_window.width, @main_window.y, 240, @main_window.height)
    refresh
  end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(new_actor)
    @actor = new_actor
    @class_id = @actor.class_id
    refresh
  end
  
  #--------------------------------------------------------------------------
  # class_id=
  #--------------------------------------------------------------------------
  def class_id=(new_class)
    @class_id = new_class
    refresh
  end
  
  #--------------------------------------------------------------------------
  # update
  #--------------------------------------------------------------------------
  def update
    super
    refresh if @skill != @main_window.skill and !@anti_update
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    @skill = @main_window.skill
    return if @skill == nil
    draw_obj_name
    dy = WLH
    dy = draw_requirements(dy)
    dy = draw_properties(dy)
  end
  
  #--------------------------------------------------------------------------
  # draw_obj_name
  #--------------------------------------------------------------------------
  def draw_obj_name
    draw_icon(@skill.icon_index, 0, 0)
    self.contents.font.size = Font.default_size
    self.contents.font.color = normal_color
    self.contents.draw_text(24, 0, contents.width-28, WLH, @skill.name)
  end
  
  #--------------------------------------------------------------------------
  # draw_properties
  #--------------------------------------------------------------------------
  def draw_requirements(dy)
    dy = draw_requirement_title(dy)
    dy = draw_jp_cost(dy)
    dy = draw_level_req(dy)
    dy = draw_skill_req(dy)
    dy = draw_passive_req(dy)
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_requirement_title
  #--------------------------------------------------------------------------
  def draw_requirement_title(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.skill_learn?(@skill)
    self.contents.font.size = YEM::SKILL::LEARN_DATA[:fontsize]
    self.contents.font.color = system_color
    text = YEM::SKILL::LEARN_DATA[:require]
    self.contents.draw_text(4, dy, contents.width-8, WLH, text, 1); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_jp_cost
  #--------------------------------------------------------------------------
  def draw_jp_cost(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.skill_learn?(@skill)
    return dy if @skill.jp_cost <= 0
    self.contents.font.color = system_color
    draw_icon(Icon.jp, 0, dy)
    text = YEM::SKILL::LEARN_DATA[:jp_cost]
    self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
    text = @skill.jp_cost
    enabled = @actor.jp(@class_id) >= @skill.jp_cost
    self.contents.font.color = enabled ? normal_color : power_down_color
    self.contents.draw_text(4, dy, contents.width-8, WLH, text, 2); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_level_req
  #--------------------------------------------------------------------------
  def draw_level_req(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.skill_learn?(@skill)
    return dy if @skill.jp_require[:level] == nil
    self.contents.font.color = system_color
    draw_icon(Icon.level, 0, dy)
    text = Vocab.level
    self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
    text = @skill.jp_require[:level][0]
    enabled = @actor.level >= @skill.jp_require[:level][0]
    self.contents.font.color = enabled ? normal_color : power_down_color
    self.contents.draw_text(4, dy, contents.width-8, WLH, text, 2); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_skill_req
  #--------------------------------------------------------------------------
  def draw_skill_req(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.skill_learn?(@skill)
    return dy if @skill.jp_require[:skills] == nil
    for skill_id in @skill.jp_require[:skills]
      skill = $data_skills[skill_id]
      next if skill == nil
      draw_icon(skill.icon_index, 0, dy)
      enabled = @actor.skill_learn?(skill)
      self.contents.font.color = enabled ? normal_color : power_down_color
      text = skill.name
      self.contents.draw_text(24, dy, contents.width-8, WLH, text, 0)
      dy += WLH
    end
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_passive_req
  #--------------------------------------------------------------------------
  def draw_passive_req(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.skill_learn?(@skill)
    return dy if @skill.jp_require[:passives] == nil
    for state_id in @skill.jp_require[:passives]
      state = $data_states[state_id]
      next if state == nil
      draw_icon(state.icon_index, 0, dy)
      enabled = @actor.passive_learn?(state)
      self.contents.font.color = enabled ? normal_color : power_down_color
      text = state.name
      self.contents.draw_text(24, dy, contents.width-8, WLH, text, 0)
      dy += WLH
    end
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_properties
  #--------------------------------------------------------------------------
  def draw_properties(dy)
    dy = draw_properties_title(dy)
    dy = draw_skill_cost(dy)
    dy = draw_base_damage(dy)
    dy = draw_multipliers(dy)
    dy = draw_elements(dy)
    dy = draw_plus_states(dy)
    dy = draw_minus_states(dy)
    dy = draw_custom_data(dy)
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_properties_title
  #--------------------------------------------------------------------------
  def draw_properties_title(dy)
    return dy if dy + WLH > contents.height
    self.contents.font.size = YEM::SKILL::LEARN_DATA[:fontsize]
    self.contents.font.color = system_color
    text = YEM::SKILL::LEARN_DATA[:properties]
    self.contents.draw_text(4, dy, contents.width-8, WLH, text, 1); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_skill_cost
  #--------------------------------------------------------------------------
  def draw_skill_cost(dy)
    return dy if dy + WLH > contents.height
    if $imported["BattleEngineMelody"]
      return dy if @actor.custom_skill_costs(@skill, :calc_cost) <= 0
      icon = @actor.custom_skill_costs(@skill, :use_icon)
      draw_icon(icon, 0, dy)
      text = YEM::SKILL::LEARN_DATA[:skill_cost]
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      self.contents.font.color = normal_color
      text = @actor.custom_skill_costs(@skill, :text_cost)
      text = sprintf(@actor.custom_skill_costs(@skill, :suffix), text)
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
    else
      return dy if @skill.mp_cost <= 0
      icon = Icon.jp
      draw_icon(icon, 0, dy)
      text = YEM::SKILL::LEARN_DATA[:skill_cost]
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      self.contents.font.color = normal_color
      text = sprintf("%d%s", @skill.mp_cost, Vocab.mp)
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
    end
    dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_base_damage
  #--------------------------------------------------------------------------
  def draw_base_damage(dy)
    return dy if dy + WLH > contents.height
    return dy if (-5..5) === @skill.base_damage
    if @skill.base_damage > 0
      draw_icon(Icon.base_damage, 0, dy)
      text = YEM::SKILL::LEARN_DATA[:base_dmg]
    else
      draw_icon(Icon.base_healing, 0, dy)
      text = YEM::SKILL::LEARN_DATA[:base_heal]
    end
    self.contents.font.color = system_color
    self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
    self.contents.font.color = normal_color
    text = (@skill.base_damage).abs
    self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_multipliers
  #--------------------------------------------------------------------------
  def draw_multipliers(dy)
    return dy if dy + WLH > contents.height
    return dy if @skill.base_damage == 0
    icon = @skill.base_damage > 0 ? Icon.base_damage : Icon.base_healing
    #---
    if @skill.atk_f > 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:multiplier], Vocab.atk)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%s%%", @skill.atk_f)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    #---
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and @skill.def_f > 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:multiplier], Vocab.def)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%s%%", @skill.def_f)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    #---
    return dy if dy + WLH > contents.height
    #---
    if @skill.spi_f > 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:multiplier], Vocab.spi)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%s%%", @skill.spi_f)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    #---
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and $imported["RES Stat"] and
    @skill.res_f > 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:multiplier], Vocab.res)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%s%%", @skill.res_f)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    #---
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and $imported["DEX Stat"] and
    @skill.dex_f > 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:multiplier], Vocab.dex)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%s%%", @skill.dex_f)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    #---
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and @skill.agi_f > 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:multiplier], Vocab.agi)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%s%%", @skill.agi_f)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    #---
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_elements
  #--------------------------------------------------------------------------
  def draw_elements(dy)
    return dy if @skill.element_set == []
    for element_id in YEM::SKILL::SHOWN_ELEMENTS
      break if dy + WLH > contents.height
      next unless @skill.element_set.include?(element_id)
      draw_icon(Icon.element(element_id), 0, dy)
      text = YEM::SKILL::LEARN_DATA[:element]
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = $data_system.elements[element_id]
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy
  end
  
  #--------------------------------------------------------------------------
  # total_drawn_states
  #--------------------------------------------------------------------------
  def total_drawn_states(array)
    result = 0
    for state_id in array
      next if $data_states[state_id] == nil
      next if $data_states[state_id].icon_index == 0
      result += 1
    end
    return [result, 8].min
  end
  
  #--------------------------------------------------------------------------
  # draw_plus_states
  #--------------------------------------------------------------------------
  def draw_plus_states(dy)
    return dy if @skill.plus_state_set == []
    total = total_drawn_states(@skill.plus_state_set)
    if total == 1
      return dy if dy + WLH > contents.height
      state = $data_states[@skill.plus_state_set[0]]
      draw_icon(state.icon_index, 0, dy)
      text = YEM::SKILL::LEARN_DATA[:add_state]
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = state.name
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
    else
      return dy if dy + WLH*2 > contents.height
      text = YEM::SKILL::LEARN_DATA[:add_state]
      self.contents.font.color = system_color
      self.contents.draw_text(4, dy, contents.width-8, WLH, text, 1)
      dy += WLH
      dx = (contents.width - total*24)/2
      for state_id in @skill.plus_state_set
        break if dx + 24 > contents.width
        state = $data_states[state_id]
        next if state.icon_index == 0
        draw_icon(state.icon_index, dx, dy)
        dx += 24
      end
    end
    dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_minus_states
  #--------------------------------------------------------------------------
  def draw_minus_states(dy)
    return dy if @skill.minus_state_set == []
    total = total_drawn_states(@skill.minus_state_set)
    if total == 1
      return dy if dy + WLH > contents.height
      state = $data_states[@skill.minus_state_set[0]]
      draw_icon(state.icon_index, 0, dy)
      text = YEM::SKILL::LEARN_DATA[:rem_state]
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = state.name
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
    else
      return dy if dy + WLH*2 > contents.height
      text = YEM::SKILL::LEARN_DATA[:rem_state]
      self.contents.font.color = system_color
      self.contents.draw_text(4, dy, contents.width-8, WLH, text, 1)
      dy += WLH
      dx = (contents.width - total*24)/2
      for state_id in @skill.minus_state_set
        break if dx + 24 > contents.width
        state = $data_states[state_id]
        next if state.icon_index == 0
        draw_icon(state.icon_index, dx, dy)
        dx += 24
      end
    end
    dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_custom_data
  #--------------------------------------------------------------------------
  def draw_custom_data(dy)
    return dy if @skill.custom_data == []
    for array in @skill.custom_data
      break if dy + WLH > contents.height
      draw_icon(array[0], 0, dy)
      text = array[1]
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = array[2]
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy
  end
  
end # Window_LearnData

#===============================================================================
# Window_LearnPassive
#===============================================================================

class Window_LearnPassive < Window_LearnSkill
  
  #--------------------------------------------------------------------------
  # passive
  #--------------------------------------------------------------------------
  def passive; return @data[self.index]; end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    if @cache_class != @class_id
      @cache_class = @class_id
      array = YEM::SKILL::CLASS_PASSIVES[0]
      if YEM::SKILL::CLASS_PASSIVES.include?(@class_id)
        array |= YEM::SKILL::CLASS_PASSIVES[@class_id]
        array.sort!
      end
      @data = []
      for state_id in array
        state = $data_states[state_id]
        next unless include?(state)
        @data.push(state)
      end
    end
    @item_max = @data.size
    self.index = [[self.index, @item_max-1].min, 0].max
    create_contents
    for i in 0...@item_max; draw_item(i); end
  end
  
  #--------------------------------------------------------------------------
  # enabled?
  #--------------------------------------------------------------------------
  def enabled?(passive)
    return false if passive == nil
    return true if @actor.passive_learn?(passive)
    #---
    if passive.jp_require[:level] != nil
      return false if passive.jp_require[:level][0] > @actor.level
    end
    #---
    if passive.jp_require[:skills] != nil
      for skill_id in skill.jp_require[:skills]
        next if $data_skills[skill_id] == nil
        return false unless @actor.skill_learn?($data_skills[skill_id])
      end
    end
    #---
    if passive.jp_require[:passives] != nil
      for state_id in passive.jp_require[:passives]
        next if $data_states[state_id] == nil
        return false unless @actor.passive_learn?($data_states[state_id])
      end
    end
    #---
    return @actor.jp(@class_id) >= passive.jp_cost
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_obj_cost
  #--------------------------------------------------------------------------
  def draw_obj_cost(obj, rect, enabled)
    if @actor.passive_learn?(obj)
      self.contents.font.size = YEM::SKILL::JP_SIZE
      self.contents.font.color = normal_color
      self.contents.font.color.alpha = enabled ? 255 : 128
      text = YEM::SKILL::LEARNED_TEXT
      self.contents.draw_text(rect.x, rect.y, rect.width-4, WLH, text, 2)
    else
      draw_icon(Icon.jp, rect.x + rect.width - 24, rect.y, enabled)
      self.contents.font.size = YEM::SKILL::JP_SIZE
      self.contents.font.color = normal_color
      self.contents.font.color.alpha = enabled ? 255 : 128
      cost = obj.jp_cost
      self.contents.draw_text(rect.x, rect.y, rect.width-24, WLH, cost, 2)
    end
  end
  
  #--------------------------------------------------------------------------
  # update_help
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_text(passive == nil ? "" : passive.passive_description)
  end
  
end # Window_LearnPassive

#===============================================================================
# Window_PassiveData
#===============================================================================

class Window_PassiveData < Window_LearnData
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(actor, main_window)
    @anti_update = true
    super(actor, main_window)
  end
  
  #--------------------------------------------------------------------------
  # update
  #--------------------------------------------------------------------------
  def update
    super
    refresh if @passive != @main_window.passive
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    @passive = @main_window.passive
    return if @passive == nil
    draw_obj_name
    dy = WLH
    dy = draw_requirements(dy)
    dy = draw_properties(dy)
  end
  
  #--------------------------------------------------------------------------
  # draw_obj_name
  #--------------------------------------------------------------------------
  def draw_obj_name
    draw_icon(@passive.icon_index, 0, 0)
    self.contents.font.size = Font.default_size
    self.contents.font.color = normal_color
    self.contents.draw_text(24, 0, contents.width-28, WLH, @passive.name)
  end
  
  #--------------------------------------------------------------------------
  # draw_properties
  #--------------------------------------------------------------------------
  def draw_requirements(dy)
    dy = draw_requirement_title(dy)
    dy = draw_jp_cost(dy)
    dy = draw_level_req(dy)
    dy = draw_skill_req(dy)
    dy = draw_passive_req(dy)
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_requirement_title
  #--------------------------------------------------------------------------
  def draw_requirement_title(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.passive_learn?(@passive)
    self.contents.font.size = YEM::SKILL::LEARN_DATA[:fontsize]
    self.contents.font.color = system_color
    text = YEM::SKILL::LEARN_DATA[:require]
    self.contents.draw_text(4, dy, contents.width-8, WLH, text, 1); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_jp_cost
  #--------------------------------------------------------------------------
  def draw_jp_cost(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.passive_learn?(@passive)
    return dy if @passive.jp_cost <= 0
    self.contents.font.color = system_color
    draw_icon(Icon.jp, 0, dy)
    text = YEM::SKILL::LEARN_DATA[:jp_cost]
    self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
    text = @passive.jp_cost
    enabled = @actor.jp(@class_id) >= @passive.jp_cost
    self.contents.font.color = enabled ? normal_color : power_down_color
    self.contents.draw_text(4, dy, contents.width-8, WLH, text, 2); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_level_req
  #--------------------------------------------------------------------------
  def draw_level_req(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.passive_learn?(@passive)
    return dy if @passive.jp_require[:level] == nil
    self.contents.font.color = system_color
    draw_icon(Icon.level, 0, dy)
    text = Vocab.level
    self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
    text = @passive.jp_require[:level][0]
    enabled = @actor.level >= @passive.jp_require[:level][0]
    self.contents.font.color = enabled ? normal_color : power_down_color
    self.contents.draw_text(4, dy, contents.width-8, WLH, text, 2); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_skill_req
  #--------------------------------------------------------------------------
  def draw_skill_req(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.passive_learn?(@passive)
    return dy if @passive.jp_require[:skills] == nil
    for skill_id in @passive.jp_require[:skills]
      skill = $data_skills[skill_id]
      next if skill == nil
      draw_icon(skill.icon_index, 0, dy)
      enabled = @actor.skill_learn?(skill)
      self.contents.font.color = enabled ? normal_color : power_down_color
      text = skill.name
      self.contents.draw_text(24, dy, contents.width-8, WLH, text, 0)
      dy += WLH
    end
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_passive_req
  #--------------------------------------------------------------------------
  def draw_passive_req(dy)
    return dy if dy + WLH > contents.height
    return dy if @actor.passive_learn?(@passive)
    return dy if @passive.jp_require[:passives] == nil
    for state_id in @passive.jp_require[:passives]
      state = $data_states[state_id]
      next if state == nil
      draw_icon(state.icon_index, 0, dy)
      enabled = @actor.passive_learn?(state)
      self.contents.font.color = enabled ? normal_color : power_down_color
      text = state.name
      self.contents.draw_text(24, dy, contents.width-8, WLH, text, 0)
      dy += WLH
    end
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_properties
  #--------------------------------------------------------------------------
  def draw_properties(dy)
    dy = draw_properties_title(dy)
    dy = draw_parameter_rates(dy)
    dy = draw_parameter_sets(dy)
    dy = draw_jp_rate(dy)
    dy = draw_custom_data(dy)
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_properties_title
  #--------------------------------------------------------------------------
  def draw_properties_title(dy)
    return dy if dy + WLH > contents.height
    self.contents.font.size = YEM::SKILL::LEARN_DATA[:fontsize]
    self.contents.font.color = system_color
    text = YEM::SKILL::LEARN_DATA[:properties]
    self.contents.draw_text(4, dy, contents.width-8, WLH, text, 1); dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_parameter_rates
  #--------------------------------------------------------------------------
  def draw_parameter_rates(dy)
    return dy if dy + WLH > contents.height
    icon = @passive.icon_index
    #---
    if $imported["BattleEngineMelody"] and @passive.maxhp_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.hp)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.maxhp_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and @passive.maxmp_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.mp)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.maxmp_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.atk_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.atk)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.atk_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.def_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.def)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.def_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.spi_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.spi)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.spi_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["RES Stat"] and @passive.res_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.res)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.res_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["DEX Stat"] and @passive.dex_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.dex)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.dex_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.agi_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.agi)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.agi_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and @passive.hit_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.hit)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.hit_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and @passive.eva_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.eva)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.eva_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and @passive.cri_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.cri)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.cri_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["BattleEngineMelody"] and @passive.odds_rate != 100
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.odds)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.odds_rate - 100)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    #---
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_parameter_sets
  #--------------------------------------------------------------------------
  def draw_parameter_sets(dy)
    return dy unless $imported["BattleEngineMelody"]
    return dy if dy + WLH > contents.height
    icon = @passive.icon_index
    #---
    if @passive.maxhp_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.hp)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d", @passive.maxhp_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.maxmp_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.mp)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d", @passive.maxmp_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.atk_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.atk)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d", @passive.atk_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.def_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.def)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d", @passive.def_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.spi_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.spi)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d", @passive.spi_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["RES Stat"] and @passive.res_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.res)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d", @passive.res_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if $imported["DEX Stat"] and @passive.dex_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.dex)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d", @passive.dex_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.agi_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.agi)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d", @passive.agi_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.hit_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.hit)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.hit_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.eva_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.eva)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.eva_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.cri_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.cri)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.cri_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    if @passive.odds_set != 0
      draw_icon(icon, 0, dy)
      text = sprintf(YEM::SKILL::LEARN_DATA[:stat_set], Vocab.odds)
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = sprintf("%+d%%", @passive.odds_set)
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
    return dy if dy + WLH > contents.height
    #---
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_jp_rate
  #--------------------------------------------------------------------------
  def draw_jp_rate(dy)
    return dy if dy + WLH > contents.height
    return dy if @passive.jp_rate == 100
    draw_icon(Icon.jp, 0, dy)
    text = sprintf(YEM::SKILL::LEARN_DATA[:stat_rate], Vocab.jp)
    self.contents.font.color = system_color
    self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
    text = sprintf("%+d%%", @passive.jp_rate - 100)
    self.contents.font.color = normal_color
    self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
    dy += WLH
    return dy
  end
  
  #--------------------------------------------------------------------------
  # draw_custom_data
  #--------------------------------------------------------------------------
  def draw_custom_data(dy)
    return dy if @passive.custom_data == []
    for array in @passive.custom_data
      break if dy + WLH > contents.height
      draw_icon(array[0], 0, dy)
      text = array[1]
      self.contents.font.color = system_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 0)
      text = array[2]
      self.contents.font.color = normal_color
      self.contents.draw_text(24, dy, contents.width-28, WLH, text, 2)
      dy += WLH
    end
  end
  
end # Window_PassiveData

#===============================================================================
# Scene_Battle
#===============================================================================

class Scene_Battle < Scene_Base
  
  #--------------------------------------------------------------------------
  # new method: perform_earn_jp
  #--------------------------------------------------------------------------
  def perform_earn_jp(type = :attack)
    return if @active_battler == nil
    return unless @active_battler.actor?
    eval("@jp_set = YEM::SKILL::EARN_JP[:" + type.to_s + "_set]")
    eval("@jp_rand = YEM::SKILL::EARN_JP[:" + type.to_s + "_rand]")
    @jp_set += rand(@jp_rand) if @jp_rand > 0
    @active_battler.earn_jp(@jp_set)
  end
  
  unless $imported["BattleEngineMelody"]
  #--------------------------------------------------------------------------
  # alias method: execute_action_attack
  #--------------------------------------------------------------------------
  alias execute_action_attack_so execute_action_attack unless $@
  def execute_action_attack
    execute_action_attack_so
    perform_earn_jp(:attack)
  end
  
  #--------------------------------------------------------------------------
  # alias method: execute_action_guard
  #--------------------------------------------------------------------------
  alias execute_action_guard_so execute_action_guard unless $@
  def execute_action_guard
    execute_action_guard_so
    perform_earn_jp(:guard)
  end
  
  #--------------------------------------------------------------------------
  # alias method: execute_action_skill
  #--------------------------------------------------------------------------
  alias execute_action_skill_so execute_action_skill unless $@
  def execute_action_skill
    execute_action_skill_so
    perform_earn_jp(:skill)
  end
  
  #--------------------------------------------------------------------------
  # alias method: execute_action_item
  #--------------------------------------------------------------------------
  alias execute_action_item_so execute_action_item unless $@
  def execute_action_item
    execute_action_item_so
    perform_earn_jp(:item)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: battle_end
  #--------------------------------------------------------------------------
  alias battle_end_so battle_end unless $@
  def battle_end(result)
    $game_troop.distribute_jp
    battle_end_so(result)
  end
  end # $imported["BattleEngineMelody"]
  
end # Scene_Battle

#===============================================================================
# Scene_Skill
#===============================================================================

class Scene_Skill < Scene_Base
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :actor

  #--------------------------------------------------------------------------
  # overwrite method: start
  #--------------------------------------------------------------------------
  def start
    super
    create_menu_background
    @actor = $game_party.members[@actor_index]
    @class_id = @actor.class_id
    @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
    @help_window = Window_Help.new
    @help_window.viewport = @viewport
    @help_window.y = 128
    @windows = []
    @target_window = Window_MenuStatus.new(0, 0)
    @target_window.visible = false
    @target_window.active = false
    create_command_window
    @status_window = Window_Actor_Skill_Status.new(@actor)
    @status_window.viewport = @viewport
    update_windows
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: next_actor
  #--------------------------------------------------------------------------
  def next_actor
    @actor_index += 1
    @actor_index %= $game_party.members.size
    set_new_actor
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: prev_actor
  #--------------------------------------------------------------------------
  def prev_actor
    @actor_index += $game_party.members.size - 1
    @actor_index %= $game_party.members.size
    set_new_actor
  end
  
  #--------------------------------------------------------------------------
  # new method: set_new_actor
  #--------------------------------------------------------------------------
  def set_new_actor
    $game_party.last_actor_index = @actor_index
    @actor = $game_party.members[@actor_index]
    @class_id = @actor.class_id
    @status_window.actor = @actor
    for window in @windows; window.actor = @actor; end
    update_windows
  end
  
  #--------------------------------------------------------------------------
  # new method: create_command_window
  #--------------------------------------------------------------------------
  def create_command_window
    commands = []; @data = []
    for command in YEM::SKILL::COMMANDS
      case command
      when :view_skills
        dy = @help_window.y + @help_window.height
        dh = Graphics.height - dy
        @skill_window = Window_Skill.new(0, dy, Graphics.width, dh, @actor)
        @skill_window.index = 0
        @windows.push(@skill_window)
      when :learn_skill
        next unless $game_switches[YEM::SKILL::LEARN_SKILL_SWITCH]
        @learn_window = Window_LearnSkill.new(@actor, @help_window)
        @learn_data = Window_LearnData.new(@actor, @learn_window)
        @windows.push(@learn_window)
        @windows.push(@learn_data)
      when :learn_passive
        next unless $game_switches[YEM::SKILL::LEARN_PASSIVE_SWITCH]
        @passive_window = Window_LearnPassive.new(@actor, @help_window)
        @passive_data = Window_PassiveData.new(@actor, @passive_window)
        @windows.push(@passive_window)
        @windows.push(@passive_data)
      when :equip_skill
        next unless $imported["SkillEquipSystem"]
        next unless $game_switches[YEM::SKILL_EQUIP::EQUIP_SKILL_SWITCH]
        create_equip_skill_windows
        commands.push(YEM::SKILL_EQUIP::TITLE)
      else; next
      end
      @data.push(command)
      if YEM::SKILL::VOCAB[command] != nil
        commands.push(YEM::SKILL::VOCAB[command])
      end
    end
    for window in @windows
      next if window == nil?
      window.active = false
      window.viewport = @viewport
      window.help_window = @help_window if window.is_a?(Window_Selectable)
    end
    @command_window = Window_Command_Centered.new(160, commands)
    @command_window.viewport = @viewport
    @command_window.height = 128
    @command_window.active = true
  end
  
  #--------------------------------------------------------------------------
  # new method: update_windows
  #--------------------------------------------------------------------------
  def update_windows
    @last_command_index = @command_window.index
    @help_window.y = Graphics.height*8
    for window in @windows
      next if window == nil
      window.y = Graphics.height*8
    end
    #---
    case @data[@command_window.index]
    when :view_skills
      show_view_skills
    when :learn_skill
      show_learn_skill
    when :learn_passive
      show_learn_passive
    when :equip_skill
      next unless $imported["SkillEquipSystem"]
      show_equip_skill_windows
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: show_view_skills
  #--------------------------------------------------------------------------
  def show_view_skills
    @help_window.y = 128
    @skill_window.y = @help_window.y + @help_window.height
    @skill_window.update_help
  end
  
  #--------------------------------------------------------------------------
  # new method: show_learn_skill
  #--------------------------------------------------------------------------
  def show_learn_skill
    @help_window.y = 128
    @learn_window.y = @help_window.y + @help_window.height
    @learn_data.y = @learn_window.y
    @learn_window.update_help
  end
  
  #--------------------------------------------------------------------------
  # new method: show_learn_passive
  #--------------------------------------------------------------------------
  def show_learn_passive
    @help_window.y = 128
    @passive_window.y = @help_window.y + @help_window.height
    @passive_data.y = @passive_window.y
    @passive_window.update_help
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: terminate
  #--------------------------------------------------------------------------
  def terminate
    super
    dispose_menu_background
    @help_window.dispose
    for window in @windows
      next if window == nil
      next if window.disposed?
      window.dispose
    end
    @command_window.dispose
    @status_window.dispose
    @target_window.dispose
    @viewport.dispose
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: update
  #--------------------------------------------------------------------------
  def update
    super
    update_menu_background
    @viewport.update
    if @command_window.active
      update_command_selection
    elsif @skill_window != nil and @skill_window.active
      update_skill_selection
    elsif @target_window != nil and @target_window.active
      update_target_selection
    elsif @learn_window != nil and @learn_window.active
      update_learn_selection
    elsif @passive_window != nil and @passive_window.active
      update_passive_selection
    #---
    elsif @equip_skill_window != nil and @equip_skill_window.active
      update_skill_equip_selection
    elsif @equip_skill_replace != nil and @equip_skill_replace.active
      update_skill_equip_replacement
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: update_command_selection
  #--------------------------------------------------------------------------
  def update_command_selection
    @command_window.update
    update_windows if @last_command_index != @command_window.index
    if Input.trigger?(Input::B)
      Sound.play_cancel
      return_scene
    elsif Input.repeat?(Input::RIGHT)
      Sound.play_cursor
      next_actor
    elsif Input.repeat?(Input::LEFT)
      Sound.play_cursor
      prev_actor
    #--- Debug Commands ---
    elsif $TEST and Input.trigger?(Input::F5)
      Sound.play_recovery
      @actor.mp = @actor.maxhp
      @status_window.refresh
      @skill_window.refresh if @skill_window != nil
    #--- Debug Commands ---
    elsif Input.trigger?(Input::C)
      Sound.play_decision
      case @data[@command_window.index]
      when :view_skills
        @command_window.active = false
        @skill_window.active = true
      when :learn_skill
        @command_window.active = false
        @learn_window.active = true
      when :learn_passive
        @command_window.active = false
        @passive_window.active = true
      when :equip_skill
        next unless $imported["SkillEquipSystem"]
        @command_window.active = false
        @equip_skill_window.active = true
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: update_skill_selection
  #--------------------------------------------------------------------------
  def update_skill_selection
    @skill_window.update
    if Input.trigger?(Input::B)
      Sound.play_cancel
      @command_window.active = true
      @skill_window.active = false
    elsif Input.trigger?(Input::C)
      @skill = @skill_window.skill
      if @skill != nil
        @actor.last_skill_id = @skill.id
      end
      if @actor.skill_can_use?(@skill)
        Sound.play_decision
        determine_skill
      else
        Sound.play_buzzer
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # alias method: update_target_selection
  #--------------------------------------------------------------------------
  alias update_target_selection_so update_target_selection unless $@
  def update_target_selection
    @target_window.update
    update_target_selection_so
  end
  
  #--------------------------------------------------------------------------
  # new method: update_learn_selection
  #--------------------------------------------------------------------------
  def update_learn_selection
    @learn_window.update
    @learn_data.update
    if Input.trigger?(Input::B)
      Sound.play_cancel
      @command_window.active = true
      @learn_window.active = false
      @skill_window.refresh if @skill_window != nil
      @passive_window.refresh if @passive_window != nil
    elsif Input.repeat?(Input::RIGHT)
      Sound.play_cursor
      next_actor
      @learn_window.index = 0
    elsif Input.repeat?(Input::LEFT)
      Sound.play_cursor
      prev_actor
      @learn_window.index = 0
    #--- Debug Commands ---
    elsif $TEST and Input.repeat?(Input::F8) # Increase JP
      Sound.play_equip
      var = YEM::SKILL::MAXIMUM_JP / 10
      jp = Input.press?(Input::SHIFT) ? rand(var) + var : rand(100) +100
      @actor.change_jp(@class_id, jp)
      @status_window.refresh
    elsif $TEST and Input.repeat?(Input::F7) # Decrease JP
      Sound.play_equip
      var = YEM::SKILL::MAXIMUM_JP / 10
      jp = Input.press?(Input::SHIFT) ? rand(var) + var : rand(100) +100
      @actor.change_jp(@class_id, -jp)
      @status_window.refresh
    elsif $TEST and Input.trigger?(Input::F6) # Refresh Windows
      Sound.play_load
      @status_window.refresh
      @learn_window.refresh
      @learn_data.refresh
    elsif $TEST and Input.trigger?(Input::F5) # Learn/Forget Skill
      skill = @learn_window.skill
      learn_skill(skill, Input.press?(Input::SHIFT))
    #--- Debug Commands ---
    elsif Input.trigger?(Input::C)
      skill = @learn_window.skill
      if @learn_window.enabled?(skill) and !@actor.skill_learn?(skill)
        learn_skill(skill)
      else
        Sound.play_buzzer
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: learn_skill
  #--------------------------------------------------------------------------
  def learn_skill(skill, forget = false)
    Sound.play_shop
    @actor.learn_skill(skill.id) unless forget
    @actor.forget_skill(skill.id) if forget
    @actor.change_jp(@class_id, -skill.jp_cost)
    @learn_window.refresh
    @learn_data.refresh
    @status_window.refresh
    @equip_skill_window.refresh if @equip_skill_window != nil
  end
  
  #--------------------------------------------------------------------------
  # new method: update_passive_selection
  #--------------------------------------------------------------------------
  def update_passive_selection
    @passive_window.update
    @passive_data.update
    if Input.trigger?(Input::B)
      Sound.play_cancel
      @command_window.active = true
      @passive_window.active = false
      @skill_window.refresh if @skill_window != nil
      @learn_window.refresh if @learn_window != nil
    elsif Input.repeat?(Input::RIGHT)
      Sound.play_cursor
      next_actor
      @passive_window.index = 0
    elsif Input.repeat?(Input::LEFT)
      Sound.play_cursor
      prev_actor
      @passive_window.index = 0
    #--- Debug Commands ---
    elsif $TEST and Input.repeat?(Input::F8) # Increase JP
      Sound.play_equip
      var = YEM::SKILL::MAXIMUM_JP / 10
      jp = Input.press?(Input::SHIFT) ? rand(var) + var : rand(100) +100
      @actor.change_jp(@class_id, jp)
      @status_window.refresh
    elsif $TEST and Input.repeat?(Input::F7) # Decrease JP
      Sound.play_equip
      var = YEM::SKILL::MAXIMUM_JP / 10
      jp = Input.press?(Input::SHIFT) ? rand(var) + var : rand(100) +100
      @actor.change_jp(@class_id, -jp)
      @status_window.refresh
    elsif $TEST and Input.trigger?(Input::F6) # Refresh Windows
      Sound.play_load
      @status_window.refresh
      @passive_window.refresh
      @passive_data.refresh
    elsif $TEST and Input.trigger?(Input::F5) # Learn/Forget Passive
      passive = @passive_window.passive
      learn_passive(passive, Input.press?(Input::SHIFT))
    #--- Debug Commands ---
    elsif Input.trigger?(Input::C)
      passive = @passive_window.passive
      if @passive_window.enabled?(passive) and !@actor.passive_learn?(passive)
        learn_passive(passive)
      else
        Sound.play_buzzer
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: learn_passive
  #--------------------------------------------------------------------------
  def learn_passive(passive, forget = false)
    Sound.play_shop
    @actor.learn_passive(passive.id) unless forget
    @actor.forget_passive(passive.id) if forget
    @actor.change_jp(@class_id, -passive.jp_cost)
    @passive_window.refresh
    @passive_data.refresh
    @status_window.refresh
  end
  
end # Scene_Skill

#===============================================================================
# 
# END OF FILE
# 
#===============================================================================