Jump to content

Recommended Posts

Subclass Manager (Version 1.3.4)

- Finished changing the way subclasses features are added to and removed from the main class.

- Flexified learn_other_skills and forget_other_skills (still produces the same end result).

- Added the ability to make your main class forget skills on class change.

 

 
Features:

  - Let your actor's subclass gain EXP!
  - Let your actor's subclass gain JP!
  - Let your actors gain bonus EXP/JP if they're single-classed!
  - Give your actors an initial subclass - and subclass level!
  - Disallow the unequipping of subclasses!
  - Cap your subclass levels individually or as a whole!
  - Make your actors forget skills from a subclass when they switch from that subclass (until they switch back)!*
  - Make your actors forget skills from a main class when they switch from that class (until they switch back)!*
  - View your subclass' JP on the main menu screen!
  - Implement your subclass' features!
  - Add PBG to your actors when their subclass levels if you have Yanfly's Parameter Bonus Growth script installed!
  - Have only your main classes maintain levels... or only your subclasses maintain levels... or both!**
  - Be totally rad!
 
... and unrelated to subclasses directly, hide classes that you can't equip from the class change screen, instead of just greying them out!
(Err... was there anything I forgot? There's quite a lot of features packed into this thing...)
 
* It may be weird to have your actors forget their skills if you have the relevant MAINTAIN set to true.
** Additional add-on required (UL Maintain) if you want to enable Class Unlock Levels and have MAINTAIN or MAINTAIN_SUB set to true. Shipping and handling fees may apply. Please see your local script dealer if you think you cannot afford this script. Haha j/k bros, it's free as always. 

 
FAQ:

  - Q: How do I add experience to my subclass?
  - A: Use $game_actors[x].gain_exp(exp_isnt_modified, 2)
 
  - Q: How do I check my actors' current subclass ID?
  - A: Use $game_actors[x].sub_id
 
  - Q: How do I change my subclass' level?
  - A: Use $game_actors[x].change_sub_level(y)
 
  - Q: How do I make my actors not be able to use skills from a different subclass?
  - A: Set REMEMBER_SUBCLASS_SKILLS to false.
 
  - Q: Why is it not letting me unequip my subclass and/or not have a subclass?
  - A: DISALLOW_NO_SUBCLASS or MAINTAIN_SUB_LEVELS is true.
 
  - Q: I set my level cap for subclass (x) to (y). Why is it capping at a different level?
  - A: There is either a custom level cap for it in MAX_SUB_LEVELS, or you have MAINTAIN_SUB_LEVELS set to true and a lower cap set in DEFAULT_MAX_SUB_LEVEL or for a different subclass in MAX_SUB_LEVELS.
 
  - Q: I have a different question!
  - A: Ask. :-)

 
Bug Fix History: none in this version, 'cuz I'm cool like that! (Or at least, none that you know about...)

  - @sub_level returned a nil value (needed to overwrite init_subclass to include initializing @sub_level, later put it in the actor setup as well)
  - more NaN issues (can't divide by zero...)
  - sub_exp returned a nil value (returns 0 if exp[@subclass_id] is nil now)
  - (re-)fixed that bug where the subclassed leveled only to the level below the cap (pasted an old version)
  - minor display issue (compatibility update: YEA - Ace Menu Engine)
  - several additional bugs found and fixed, hopefully the last of them.

 
Script:

 

 

$imported = {} if $imported.nil?
$imported["EBON-SubManager"] = true
#==============================================================================
# â–¼ YEA CLASS SYSTEM ADD-ON (EBONFLAME): SUBCLASS MANAGER v1.3.4
#==============================================================================
# â–¼ Author: Ebonflame
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#——————————————————————————
# â–¼ Updates
#——————————————————————————
#
# 2013.02.07: Initial relase, inspired by Estriole's Sub EXP Gain Script.
# 2013.02.09-2013.02.22: Bug fixes and compatibility updates; Additional
#   functions (single classes gain bonus EXP/JP, init subclass skills).
# 2013.03.06: Additional functions (gain pbg/features from subclass and
#   customizeable level caps for subclasses).
# 2013.03.14: Final items on the to-do list added (subclass JP in main menu,
#   subclass exp/exp for level on status screen), plus the option to forget
#   subclass skills when unequipping a subclass (until you equip it again).
# 2013.04.10: Additional function added (maintain_sub_levels) & compatibility
#   update (YEA::CLASS_SYSTEM::MAINTAIN_LEVELS). Note you need "EBON-ULMaintain"
#   if you have MAINTAIN_LEVELS/MAINTAIN_SUB_LEVELS set to true and you want
#   Unlock Level to work. You can find it on the main page for this script:
#   (www)rpgmakervxace.net/topic/12492-yanfly-class-system-add-ons-subclass-management/
# 2013.04.17: Added a less time-consuming method to retrieve exp values.
#   Re-wrote regexp (it still works the same way, it's just better code). Erased
#   unnecessary code. Additional functions added (change_sub_level,
#   DISALLOW_NO_SUBCLASS).
# 2013.05.22: Updated the help section. Eliminated the last nilClass error due
#   to @exp[class_id] not having a value. Re-worked setup_initial_subclass a
#   little to prevent a conflict if MAINTAIN_SUB_LEVELS is set to true. And since
#   I now actually know a little about windows, I set it so it plays the correct
#   sound when the player attempts to equip an unequippable subclass, and hid
#   the classes when neither primary nor subclass was selected within the class
#   window.
# 2013.05.29: Finished modifying subclass feature addition section. Modified
#   learn_other_skills and forget_other_skills for more flexibility. Added a
#   feature to allow the main class not to transfer skills on class change -
#   remember to set this to false if you have YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
#   set to true. (Also, sorry about not finishing the subclass feature section
#   last time.)
#
#——————————————————————————
# â–¼ Description
#——————————————————————————
#
# This is my first finished script: the Subclass Manager, inspired by the
# amazing Estriole. With this script, you can:
#
# - Let your actor's subclass gain EXP!
# - Let your actor's subclass gain JP!
# - Let your actors gain bonus EXP/JP if they're single-classed!
# - Give your actors an initial subclass - and subclass level!
# - Cap your subclass levels individually or as a whole!
# - Make your actors forget skills from a subclass when they switch from that
#   subclass (until they switch back)!*
# - View your class' and subclass' JP on the main menu screen!
# - Implement your subclass' features!
# - Add PBG to your actors when their subclass levels if you have Yanfly's
#   Parameter Bonus Growth script installed!
# - Have only your main class maintain levels... or only your subclasses maintain
#   levels... or both!**
# - Be totally rad!
#
# (Err... was there anything I forgot? There's quite a lot of features packed
# into this thing...)
#
# * It may be weird to have your actor forget their subclass' skills if
# EBON::MAINTAIN_SUB_LEVELS is set to true.
# ** Coming Soon to a webpage near you: ULMaintain! Required if you want to use
# YEA - ClassUnlockLevel in conjunction with this script and either
# MAINTAIN_LEVEL or MAINTAIN_SUB_LEVELS is set to true. Shipping and handling
# fees may apply. Additionally, it's strongly recommended that you have your
# classes set to primary only or subclass only if you have a MAINTAIN set to true.
#
# # --- # Important note: This script may conflict with other scripts that alias
# # --- # 'change_class' aside from Yanfly's Class System script. Read #1 in the
# # --- # 'Aliases & Redefinitions' section for more information.
#
# You can find updated versions of this script, as well as related scripts, at:
# (www)rpgmakervxace.net/topic/12492-yanfly-class-system-add-ons-subclass-management/
#
# You can find the original script that inspired this one at:
# (www)rpgmakervxace.net/topic/6661-yea-class-script-addon-subclass-gain-exp/
#
#——————————————————————————
# â–¼ Notetags
#——————————————————————————
#
# To initialize an actor's subclass, put the following notetag in their notes:
#
# <initial subclass: x>
# <initial subclass: x at lvl y>
#
# X and y are both numerical values. X is the subclass ID you want them to start
# with, and y is the level you want them to start at. If y is not given, level 1
# will be assumed. If y is higher than 99, 99 will be assumed.
#
#——————————————————————————
# â–¼ Script Calls
#——————————————————————————
#
# This script enables the following script calls:
#
#——————————————————————————
#
# $game_actors[x].earn_jp_alt(y)
# $game_actors[x].earn_jp_alt(y, z)
#
# This will cause actor x to earn y amount of JP. JP earned will be
# modified first by any JP Rate traits provided through notetags, then by the
# subclass JP gain rate. If z is not given, the primary class will be assumed.
#
#——————————————————————————
#
# $game_actors[x].gain_exp(y)
# $game_actors[x].gain_exp(y, z)
#
# This will cause actor x to earn y amount of EXP. Z is the value of the class
# you wish to add/subtract EXP to/from, with 1 being the main class and 2 being
# the subclass.
#
# z = nil (no class specified): Both the main class and subclass will gain the
# EXP value specified. The subclass' exp gain WILL be auto-corrected to correlate
# with the rate set in EBON::SUB_EXP_RATE. EXP gain for the main class will also
# be auto-adjusted to compensate for those with single classes if necessary.
# z = 1 (main class): only the main class will gain the EXP value specified,
# and it will NOT gain additional EXP even if EBON::SINGLE_CLASS_EXP_BONUS is
# set to true and the actor only has a main class.
# z = 2 (subclass): only the subclass will gain the EXP value specified, and it
# will NOT be auto-corrected to correlate with the rate set in EBON::SUB_EXP_RATE.
#
#——————————————————————————
#
# $game_actors[x].sub_id
# $game_actors[x].sub_level
#
# Can be used for compatibility with Yanfly's Learn Skills Engine. An example of
# how to utilize these script calls in a notetag:
#
# <learn require eval>
# @actor.sub_level > 5 &&
# [1, 2, 3].include?(@actor.sub_id)
# </learn require eval>
#
# This would make the skill show up in YEA's learn skills page if the actor's
# subclass is 1, 2, or 3 (1, 2, and 3 are the ID's of the class) and the actor's
# subclass level is greater than five. sub_id will return zero if the actor's
# subclass_id is set to nil or zero, and sub_level will return one if the actor
# does not have a subclass; otherwise it will return the actor's subclass level.
#
#——————————————————————————
#
# $game_actors[x].change_sub_level(y)
#
# This will cause actor x's subclass to become level y, performing any leveling
# operations required, such as parameter bonus growth if you have YEA - Parameter
# Bonus Growth installed, or mastery aquisitions if you have EBON - Level
# Masteries and/or EBON - Learn Masteries imported.
#
#——————————————————————————
#
# $game_actors[x].change_subclass(y)
#
# Changes the actor's subclass to <y>, where <y> is the database ID for the class
# you want to change it to. You will not be able to switch to that subclass if
# you have already exceeded the level cap for that subclass.
#
# $game_actors[x].change_subclass(0) will completely remove the actor's subclass
# (if present), including features that were added on subclass change. This will
# not work if MAINTAIN_SUB_LEVELS is set to true, since the unequipping of a
# subclass is disallowed in that case.
#
#          ~~~~~~~~~~~~~~~~~~~~~~~~———*———~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#     ===> IMPORTANT: This needs to be called if you want to change the <===
#    ===> actor's subclass_id; DO NOT just set @subclass_id to something <===
#    ===> else. THIS WILL MESS UP YOUR MAIN CLASS' FEATURES, and may <===
#          ===> prevent the subclass from leveling correctly. <===
#               ~~~~~~~~~~~~~~~~~~~———*———~~~~~~~~~~~~~~~~~~~
#
#——————————————————————————
# â–¼ Requirements
#——————————————————————————
#
# 1) Requires Yanfly's Class System scrpt.
# 2) Must be placed below YEA - Class System, YEA - Class Specifics,
# YEA - Class Unlock LV, and YEA - JP Manager (if the last three are imported).
#
#——————————————————————————
# â–¼ Compatibility
#——————————————————————————
#
# 1) YEA - JP Manager (must be below it; allows your subclass to gain JP)
# 2) YEA - Victory Aftermath (doesn't show level-up messages if you have VA
#      imported; placement doesn't matter as long as you have EBON - Subclass
#      Aftermath imported as well; shows subclass stats, gains, and level changes)
# 3) YEA - Parameter Bonus Growth (placement doesn't matter; lets your subclass
#      contribute to Parameter Bonus Growth earned)
#
#——————————————————————————
# â–¼ Aliases & Redefinitions
#——————————————————————————
#
# 1) Redefine: change_class (if keep_exp is false and the class the actor is
#      changing to is higher than your current level; to prevent PBG from
#      giving additional param_bonus_growth)
# 2) Redefine: gain_exp (to allow the subclass to gain exp)
# 3) Redefine: draw_block1, draw_exp_info, draw_actor_info (optional; to display
#      the actor's subclass information)
# 4) Alias: param_base (temporarily lowers exp in the actor's subclass if one 
#      is equipped and it's above lv 99; to prevent errors)
#
#——————————————————————————
# â–¼ Instructions
#——————————————————————————
#
# To install the script, open your script editor and paste this script into
# a new section below â–¼ Materials but above â–¼ Main.
#
#——————————————————————————
module EBON
 
  # --- # Class/Subclass Display options
 
  HIDE_UNEQUIPPABLE_CLASSES = true
  # If this is set to true, classes that cannot be equipped will be hidden from
  # the class selection screen. If set to false, the default greyed-out value
  # will be displayed.
 
  # --- # /Class/Subclass Display options
  # --- # Subclass Info Display options
 
  DISPLAY_SUB_INFO = true
  # Displays the actor's subclass information. This overwrites the following
  # core definitions: draw_block1, draw_exp_info
  # Set to false to prevent it from overwriting these definitions. Your
  # subclass' experience information will not be displayed.
 
  SUB_EXP_DISPLAY = "%s / %s"
  # <main class experience> / <subclass experience>
  # <main class exp-to-level> / <subclass exp-to-level>
 
  MAX_LV = "MAX LEVEL!"
  # When actor is at max level/max subclass level, this will be displayed
  # instead of experience points.
 
  CHANGE_LEVEL_FORMAT = true
  # Displays the actor's subclass level along with the main class level. This
  # overwrites the following definition: draw_actor_info
  # Set to false to prevent it from overwriting this definition. Your subclass'
  # level will not be displayed.
 
  SUB_LVL_FORMAT = "%s (%s)"
  # <main class level> (<subclass level>)
 
  DISPLAY_JP = true
  # Displays your actors' main class and subclass JP in the main menu.
  # Set to false if you don't want your actor's class and subclass JP shown.
 
  JP_FORMAT = "%s/%s"
  # The way jp is displayed. Default: <class jp>/<subclass jp>
 
  # --- # /Subclass Info Display options
  # --- # JP options
 
  SUB_JP_RATE = 0.50
  # JP rate. 0.50 means half JP rate for subclass.
  VICTORY_MESSAGE = "%s earned %s %s in their subclass."
  # "<actor name> earned <amount> <YEA::JP::VOCAB> in their subclass."
  # Displayed only if Victory Aftermath/subclass Aftermath is not imported.
  SUB_LEVEL_JP = 50
  # JP subclass gains from leveling up.
  SINGLE_CLASS_JP_BONUS = true
  # Allows those with single classes to be 'rewarded' with additional JP, as
  # specified by the JP subclass rate. Set to false to disable.
 
  # --- # /JP options
  # --- # EXP options
 
  SUB_EXP_RATE = 0.50
  # EXP rate. 0.50 means half EXP rate for subclass.
  SINGLE_CLASS_EXP_BONUS = true
  # Allows those with single classes to be 'rewarded' with additional EXP, as
  # specified by the subclass EXP rate. Set to false to disable.
  VOCAB_ADDITIONAL_EXP = "%s secondary exp received!"
  # "<amount of subclass/single-class bonus exp received> secondary exp received!"
  # Displayed only if Victory Aftermath/Subclass Aftermath is not imported.
  VOCAB_SUB_LV_UP = "%s reached %s %s in their subclass (%s)."
  # "<actor name> reached <Vocab::level> <level number> in their subclass
  # <subclass name>."
  # Displayed only if Victory Aftermath/Subclass Aftermath is not imported.
 
  # --- # /EXP options
  # --- # Subclass Level/Unequipping options
 
  DISALLOW_NO_SUBCLASS = false
  # Disallows the unequipping of subclasses. Automatically set to true if
  # MAINTAIN_SUB_LEVELS is true.
 
  MAINTAIN_SUB_LEVELS = false
  # Maintain the actor's @sub_level through all subclasses. This will
  # automatically set DISALLOW_NO_SUBCLASS to true and set the max level all
  # subclasses can have to the lowest entry in DEFAULT_MAX_SUB_LEVEL and
  # MAX_SUB_LEVELS combined. It is strongly recommended that you set your
  # classes to "primary only" or "subclass only" if you use either this or
  # Yanfly's MAINTAIN_LEVELS, since weird things can happen otherwise.
  #
  # If all of your classes are equippable as either primary or subclass:
  # You can set the SUB_EXP_RATE to 1.0, so that there is no conflict between
  # the potential exp values available. However, if you do not have EBON - CS
  # Additional Functions imported and CONTINUOUS_MAINTAIN set to true, and only
  # one of the MAINTAIN_LEVELS are set to true, the old level will still appear
  # in the class selection screen of whichever MAINTAIN is not set to true.
 
  DEFAULT_MAX_SUB_LEVEL = 99
  # The level cap you'd like your subclasses to stop at unless otherwise
  # specified. If YEA - Adjust Limits is not imported, the maximum cap is 99.
  # The subclass will stop leveling at the level specified here or in
  # MAX_SUB_LEVELS. The subclass does not stop leveling if your actor reaches
  # his or her level cap for their main class and the subclass cap is higher
  # than your actors' level cap.
  # If your actors' main class level cap is set to a higher level than the
  # subclass cap, and your actor equips the subclass as a main class, they
  # will not be able to re-equip that subclass if they level the subclass past
  # the level cap.
  # Note that the way this function works is by preventing your subclass from
  # leveling by not letting your subclass gain any more EXP. For example, if it
  # takes 50 EXP to get from level one to level two, and your actor's subclass
  # gains 50 or more EXP, the EXP gain will be reset to 49 and they will not
  # gain any more EXP from subsequent battles until they change subclasses (if
  # the level cap for that subclass is set to one).
 
  MAX_SUB_LEVELS = [
  # Specify any class-specific subclass level caps here.
  # If YEA - Adjust Limits is not imported, the maximum level cap is 99.
      #-------------------------------#
      # Class ID | Max Subclass Level #
      #-------------------------------#
      #[248,                       1],# Level 1 is the lowest cap possible.
      #[249,                      99],# Max if YEA - Adjust Limits isn't imported.
      #[250,                     999],# Holy crap, that's a high level cap.
      #[Class ID, Max Subclass Level],# Don't forget the brackets and commas!
      #[  ,                         ],
                   ]#Don't remove this.
                 
  # --- # /Subclass Level/Unequipping options
  # --- # Learned Skills options
                 
  REMEMBER_SUBCLASS_SKILLS = true
  # Set to true if you want your actor to remember the skills learned in their
  # subclass even if they don't have that subclass equipped. Setting this to
  # false will make your actors forget subclass skills when they don't have that
  # subclass equipped (as long as those skills aren't in the main class' skill
  # list).
 
  REMEMBER_CLASS_SKILLS = true
  # The same as REMEMBER_SUBCLASS_SKILLS, except it works on classes instead of
  # subclasses.
 
  # --- # /Learned Skills options
  # --- # Feature options
 
  # This section adds features from your subclass to your main class. Note that
  # it does so by actually putting those features into the features list of
  # the main class on the database level. It does not rewrite all of the
  # functions (definitions) that utilize those features. The script holds the
  # original class features and restores them on class or subclass change.
 
  ADDED_FEATURES = [
  # The features you want to add from the actor's equipped subclass.
  #     |-----------------------------------------------------------------|
  #     | Comment a number out if you don't want to include it. Search    |
  #     | 'Setting Features' in the help file if you're unsure what any   |
  #     | of these features mean/do.                                      |
  #     |-----------------------------------------------------------------|
  #     | [14, 42, 44]: these are features that could potentially         |
  #     | conflict with features 13, 41, and 43 (respectively) in the     |
  #     | actor's main class. If they're just included here, they will be |
  #     | added only if there is no conflict (for example, if the main    |
  #     | class has not specifically allowed the skill type "magic," but  |
  #     | the subclass does disallow use of the skill type "magic").      |
  #     |  ==> If you want them to be forcefully added even if there <==  |
  #     |    ==> is a conflict, uncomment them in FORCED_FEATURES. <==    |
  #     |-----------------------------------------------------------------|
  #     â–¼ ---===> Uncommenting these â–¼ here will have no effect. <====--- â–¼
  #     |-----------------------------------------------------------------|
  #     | [21, 41, 51, 52]: Yanfly takes care of these in his script.     |
  #     |-----------------------------------------------------------------|
  #     | [53, 54, 55]: these are features that will conflict with        |
  #     | weapons, equipment, and/or shield-wearing in the actor's main   |
  #     | class. If you would like them to be added as features anyway,   |
  #     |          ==> uncomment them in FORCED_FEATURES. <==             |
  #     |-----------------------------------------------------------------|
  #     | [62, 64]: these are features whose data ID meanings are preset. |
  #     | For 62: Use SPECL_FEATURES. For 64: Use PARTY_FEATURES.         |                                            |
  #     |   ==> Uncomment the data IDs to add in the relevant list. <==   |
  #     |-----------------------------------------------------------------|
  #-----------------------------------------------------------------------------
  # Feature Number  Feature Name           Feature Desc                   Notes
  #-----------------------------------------------------------------------------
    11,             #FEATURE_ELEMENT_RATE  (Element Rate)
    12,             #FEATURE_DEBUFF_RATE   (Debuff Rate)
    13,             #FEATURE_STATE_RATE    (State Rate)
    14,             #FEATURE_STATE_RESIST  (State Resist) <--- POSSIBLE CONFLICT
    #21,            #FEATURE_PARAM         (Parameter) <----------------- YANFLY
    22,             #FEATURE_XPARAM        (Ex-Parameter)
    23,             #FEATURE_SPARAM        (Sp-Parameter)
    31,             #FEATURE_ATK_ELEMENT   (Atk Element)
    32,             #FEATURE_ATK_STATE     (Atk State)
    33,             #FEATURE_ATK_SPEED     (Atk Speed)
    34,             #FEATURE_ATK_TIMES     (Atk Times+)
    #41,            #FEATURE_STYPE_ADD     (Add Skill Type) <------------ YANFLY
    42,             #FEATURE_STYPE_SEAL    (Disable Sk. Type) <--- POSS CONFLICT
    43,             #FEATURE_SKILL_ADD     (Add Skill)
    44,             #FEATURE_SKILL_SEAL    (Disable Skill) <-- POSSIBLE CONFLICT
    #51,            #FEATURE_EQUIP_WTYPE   (Equip Weapon) <-------------- YANFLY
    #52,            #FEATURE_EQUIP_ATYPE   (Equip Armor) <--------------- YANFLY
    #53,            #FEATURE_EQUIP_FIX     (Lock Equip) <--------- WILL CONFLICT
    #54,            #FEATURE_EQUIP_SEAL    (Seal Equip) <--------- WILL CONFLICT
    #55,            #FEATURE_SLOT_TYPE     (Slot Type) <---------- WILL CONFLICT
    61,             #FEATURE_ACTION_PLUS   (Action Times+)
    #62,            #FEATURE_SPECIAL_FLAG  (Special Flag) <-- SEE SPECL_FEATURES
    #63,            #FEATURE_COLLAPSE_TYPE (Collapse Effect) <------- IRRELEVANT
    #64             #FEATURE_PARTY_ABILITY (Party Abilities) <SEE PARTY_FEATURES
                   ]#Don't remove this.
                  
  FORCED_FEATURES = [
  # The features you want to force to override the relevant features in your
  # main class. For example, if your main class has enabled skill type 1 and
  # your subclass disables skill type 1, added features will not disable it.
  # You would have to uncomment 42 (disable skill type) in this list for it
  # to be disabled in the event of a conflict.
  #-----------------------------------------------------------------------------
  # Feature Number  Feature Name           Feature Desc        Relevant Features
  #-----------------------------------------------------------------------------
    14,             #FEATURE_STATE_RESIST  (State Resist) <------------------ 13
    #42,             #FEATURE_STYPE_SEAL    (Disable Skill Type) <----------- 41
    #44,             #FEATURE_SKILL_SEAL    (Disable Skill) <---------------- 43
    #53,             #FEATURE_EQUIP_FIX     (Lock Equip) <------------- 51/52/53
    #54,             #FEATURE_EQUIP_SEAL    (Seal Equip) <------------- 51/52/53
    #55,             #FEATURE_SLOT_TYPE     (Slot Type) <-------------------- 55
                    ]#Don't remove this
                  
  SPECL_FEATURES = [
  # These are the features listed under 'special flag' in the features tab.
  # Uncomment a feature if you want it to be added when a subclass that has that
  # feature is equipped, or comment it out if you don't want it to be added.
  #-----------------------------------------------------------------------------
  # Data ID Number  Data ID Name              Feature Desc
  #-----------------------------------------------------------------------------
    #0,              #FLAG_ID_AUTOBATTLE       (Auto Battle)
    1,              #FLAG_ID_GUARD            (Guard)
    2,              #FLAG_ID_SUBSTITUTE       (Substitute)
    3,              #FLAG_ID_PRESERVE_TP      (Preserve TP)
                   ]#Don't remove this.
                 
  PARTY_FEATURES = [
  # These are the features listed under 'party ability' in the features tab.
  # Uncomment a feature if you want it to be added when a subclass that has that
  # feature is equipped, or comment it out if you don't want it to be added.
  #-----------------------------------------------------------------------------
  # Data ID Number  Data ID Name              Feature Desc
  #-----------------------------------------------------------------------------
    0,              #ABILITY_ENCOUNTER_HALF   (Halve Encounters)
    1,              #ABILITY_ENCOUNTER_NONE   (Disable Encounters)
    2,              #ABILITY_CANCEL_SURPRISE  (Disable Surprise)
    3,              #ABILITY_RAISE_PREEMPTIVE (Increase Preemptive Strike Rate)
    4,              #ABILITY_GOLD_DOUBLE      (Double Money Earned)
    5,              #ABILITY_DROP_ITEM_DOUBLE (Double Item Acquisition Rate)
                   ]#Don't remove this.
                 
  # --- # /Feature options
 
end
 
#===============================================================================
# â–¼ As Yanfly says:
# Editting anything past this point may potentially result in causing computer
# damage, incontinence, explosion of user's head, coma, death, and/or halitosis,
# so edit at your own risk.
#===============================================================================
module EBON
  module REGEXP
  module BASEITEM
  
    # --- # Begin Subclass Compatibility (initial subclass values)
  
    SUB_INIT = /<(?:INITIAL_SUBCLASS|initial subclass):[ ](\d+|\d+\D+\d+)>/i
  
  end #BASEITEM
  end #REGEXP
end #EBON
 
#==============================================================================
# â–  DataManager
#==============================================================================
 
module DataManager
 
  #--------------------------------------------------------------------------
  # alias method: load_database
  #--------------------------------------------------------------------------
  class <<self; alias load_database_esm load_database; end
  def self.load_database
    load_database_esm
    index = $data_classes.find {|cl| !cl.nil?}
    unless !index.exp_array.nil?
      for obj in $data_classes
        obj.setup_exp_array unless obj.nil?
      end
    end
    load_notetags_esm   
  end
 
  #--------------------------------------------------------------------------
  # new method: load_notetags_esm
  #--------------------------------------------------------------------------
  def self.load_notetags_esm
    for act in $data_actors
      next if act.nil?
      act.load_notetags_esm
    end
  end
 
end # DataManager
 
    # --- # /Subclass Compatibility (initial subclass values)
 
#===============================================================================
# â–  RPG::Class
#===============================================================================
 
class RPG::Class
 
  # --- # Begin EXP Array (to reduce processing time of class_level)
 
  #--------------------------------------------------------------------------
  # new method: setup_exp_array
  # (to setup exp array; initialize is a mystery for later solving)
  #--------------------------------------------------------------------------
  def setup_exp_array
    array = []
    (1..99).each do |i|
      array.push(exp_for_level(i))
    end
    @exp_array = array
  end
 
  #--------------------------------------------------------------------------
  # new method: exp_array
  # (to retrieve exp_array)
  #--------------------------------------------------------------------------
  def exp_array
    @exp_array
  end
 
  # --- # /EXP Array (to reduce processing time of class_level)
  # --- # Subclass Compatibility (features)
  
  #--------------------------------------------------------------------------
  # new method: change_features
  # (to restore original features or add new ones)
  #--------------------------------------------------------------------------
  def change_features(features, _case = nil)
    _case ? @features += features : @features = features
  end
  
  # --- # /Subclass Compatibility (features)
  # --- # Subclass Compatibility (level 100+)
 
  #--------------------------------------------------------------------------
  # new method: above_lv99_params
  #--------------------------------------------------------------------------
  unless respond_to?("above_lv99_params")
    def above_lv99_params(param_id, level)
      return @params[param_id, level] if level <= 99
      n = @params[param_id, 99]
      multiplier = [level - 99, 1].max
      change = (@params[param_id, 99] - @params[param_id, 98]) + 1
      n += change * multiplier
      return n
    end
  end
 
  # --- # /Subclass Compatibility (level 100+)
 
end #RPG::Class
 
#===============================================================================
# â–  RPG::Actor
#===============================================================================
 
class RPG::Actor
 
    # --- # Begin Subclass Compatibility (initial subclass values)
 
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_reader :subclass_init
 
  #--------------------------------------------------------------------------
  # common cache: load_notetags_esm
  #--------------------------------------------------------------------------
  def load_notetags_esm
    @subclass_init = [0, 1]
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when EBON::REGEXP::BASEITEM::SUB_INIT
        init = $1.scan(/\d+/)
        @subclass_init[0] = $data_classes[init[0].to_i].nil? ? 0 : init[0].to_i
        @subclass_init[1] = init[1].to_i unless init[1].nil?
      #---
      end
    } # self.note.split
  end
 
end
 
    # --- # /Subclass Compatibility (initial subclass values)
 
#==============================================================================
# â–  BattleManager
#==============================================================================
 
module BattleManager
 
  # --- # Begin VA Compatibility (display_exp)
 
  #--------------------------------------------------------------------------
  # overwrite method: display_exp
  #--------------------------------------------------------------------------
  unless $imported["YEA-VictoryAftermath"]
    def self.display_exp
      if $game_troop.exp_total > 0
        fmt = Vocab::ObtainExp
        $game_message.add('\.' + sprintf(fmt, $game_troop.exp_total))
      end
      additional_exp = ($game_troop.exp_total * EBON::SUB_EXP_RATE).ceil
      if additional_exp > 0
        fmt = EBON::VOCAB_ADDITIONAL_EXP
        $game_message.add('\.' + sprintf(fmt, additional_exp.group))
      end
      gain_jp if $imported["YEA-JPManager"]
    end
  end #unless
 
  # --- # /VA Compatibility (display_exp)
  # --- # JP Compatibility (Enemy_Kill)
 
  #--------------------------------------------------------------------------
  # overwrite method: gain_jp
  #--------------------------------------------------------------------------
  def self.gain_jp
    $game_message.new_page
    amount = $game_troop.jp_total
    fmt = YEA::JP::VICTORY_MESSAGE
    for member in $game_party.members
      member.earn_jp(amount)
      if !member.subclass && EBON::SINGLE_CLASS_JP_BONUS
        member.earn_jp_alt(amount, member.class_id)
      end
      member.earn_jp_alt(amount, member.sub_id) if member.subclass
      next if $imported["YEA-VictoryAftermath"]
      value = member.battle_jp_earned.group
      $game_message.add('\.' + sprintf(fmt, member.name, value, Vocab::jp))
    end
    unless $imported["YEA-VictoryAftermath"]
      wait_for_message
      fmt = EBON::VICTORY_MESSAGE
      for member in $game_party.members
        value = (amount * member.jpr * EBON::SUB_JP_RATE +
          member.battle_sub_jp_earned).ceil.group
        $game_message.add('\.' + sprintf(fmt, member.name, value,
          Vocab::jp)) if member.subclass
      end
      wait_for_message
    end
  end
 
  # --- # /JP Compatibility (Enemy_Kill)
 
end # BattleManager
 
#==============================================================================
# â–  Game_Battler
#==============================================================================
 
class Game_Battler < Game_BattlerBase
 
  # --- # JP Compatibility (Action_JP)
 
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_reader :battle_sub_jp_earned
 
  #--------------------------------------------------------------------------
  # alias method: on_battle_start
  #--------------------------------------------------------------------------
  alias game_battler_on_battle_start_jp_yea on_battle_start
    def on_battle_start
    game_battler_on_battle_start_jp_yea
    @battle_sub_jp_earned = 0
  end
 
  #--------------------------------------------------------------------------
  # alias method: on_battle_end
  #--------------------------------------------------------------------------
  alias game_battler_on_battle_end_jp_yea on_battle_end
  def on_battle_end
    game_battler_on_battle_end_jp_yea
    @battle_sub_jp_earned = 0
  end
 
  #--------------------------------------------------------------------------
  # alias method: item_user_effect
  # (to add jp to subclass when a monster is killed)
  #--------------------------------------------------------------------------
  unless !$imported["YEA-JPManager"]
    alias game_battler_item_user_effect_jp_main item_user_effect
    def item_user_effect(user, item)
      game_battler_item_user_effect_jp_main(user, item)
      if user.actor?
        if $imported["EBON-JPGainEval"]
          unless !valid_jp_gain?(item)
            user.earn_jp_alt(item.jp_gain, user.sub_id) if user.subclass
            user.earn_jp_alt(item.jp_gain, user.class_id) if !user.subclass &&
              EBON::SINGLE_CLASS_JP_BONUS
          end
        else
          user.earn_jp_alt(item.jp_gain, user.sub_id) if user.subclass
          user.earn_jp_alt(item.jp_gain, user.class_id) if !user.subclass &&
            EBON::SINGLE_CLASS_JP_BONUS
        end
      end
    end
  end
 
  # --- # /JP Compatibility (Action_JP)
 
end #Game_Battler
 
#==============================================================================
# â–  Game_BattlerBase
#==============================================================================
 
class Game_BattlerBase
 
  # --- # Subclass Compatibility (PBG)
 
  #--------------------------------------------------------------------------
  # new method: sub_param_bonus_growth
  #--------------------------------------------------------------------------
  def sub_param_bonus_growth(param_id)
    n = 0.0
    unless !actor? || !self.subclass || !$imported["YEA-ParamBonusGrowth"]
      n += self.subclass.param_bonus_growth[param_id]
    end
    return n
  end
 
  # --- # /Subclass Compatibility (PBG)
 
end #Game_BattlerBase
 
#==============================================================================
# â–  Game_Actor
#==============================================================================
 
class Game_Actor < Game_Battler
 
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :sub_level
  attr_accessor :subclass_id
 
  # --- # JP Compatibility (Enemy_Kill, Level_Up, Action_JP)
 
  #--------------------------------------------------------------------------
  # new method: earn_jp_alt
  # (to give JP to sub/alternate class at a specific rate and record the amount
  # of subclass JP earned in battle)
  #--------------------------------------------------------------------------
  def earn_jp_alt(jp, class_id = nil)
    class_id = @class_id if class_id.nil?
    value = (jp * jpr * EBON::SUB_JP_RATE).ceil
    if $game_party.in_battle
      @battle_sub_jp_earned = 0 if @battle_sub_jp_earned.nil?
      @battle_sub_jp_earned += value
    end
    gain_jp(value, class_id)
  end
 
  #--------------------------------------------------------------------------
  # overwrite method: gain_jp
  # (to prevent extra @battle_jp_earned if the class sent to it isn't the main
  # class)
  #--------------------------------------------------------------------------
  def gain_jp(jp, class_id = nil)
    class_id = @class_id if class_id.nil?
    init_jp if @jp.nil?
    @jp[class_id] = 0 if @jp[class_id].nil?
    @jp[class_id] += jp.to_i
    @jp[class_id] = [[@jp[class_id], YEA::JP::MAX_JP].min, 0].max
    @battle_jp_earned = 0 if @battle_jp_earned.nil? && $game_party.in_battle
    @battle_jp_earned += jp.to_i if $game_party.in_battle &&
      class_id == @class_id
  end
 
  # --- # /JP Compatibility (Enemy_Kill, Level_Up, Action_JP)
  # --- # Error Prevent Functions
 
  #--------------------------------------------------------------------------
  # alias method: setup
  # (to intialize actor's starting values at base level)
  #--------------------------------------------------------------------------
  alias game_actor_setup_cs_yea setup
  def setup(actor_id)
    game_actor_setup_cs_yea(actor_id)
    setup_initial_subclass
  end
 
  #--------------------------------------------------------------------------
  # overwrite method: init_subclass
  # (to reset subclass data to no subclass equipped)
  #--------------------------------------------------------------------------
  def init_subclass
    @subclass_id = 0
    @sub_level = 1
    @max_sub_level = 1
    @class_features = class_features
    @sub_features = []
  end
 
  #--------------------------------------------------------------------------
  # new method: setup_initial_subclass
  # (to initialize subclass from notes)
  #--------------------------------------------------------------------------
  def setup_initial_subclass
    class_id = actor.subclass_init[0] == @class_id ? 0 : actor.subclass_init[0]
    return if !class_allowed?(class_id, :subclass)
    lv = [[actor.subclass_init[1], 1].max, find_max_sub_level(class_id)].min
    @exp[class_id] = $data_classes[class_id].exp_for_level(lv)
    if EBON::MAINTAIN_SUB_LEVELS
      @sub_level = class_level(class_id, "compare")
      @max_sub_level = find_max_sub_level(class_id)
    end
    change_subclass(class_id)
    for i in 0...8 do
      @param_plus[i] += sub_param_bonus_growth(i) * (lv - 1)
    end
    recover_all
  end
 
  #--------------------------------------------------------------------------
  # overwrite method: initialize skills
  # (to initialize subclass skills as well)
  #--------------------------------------------------------------------------
  def init_skills
    @skills = []
    self.class.learnings.each do |learning|
      learn_skill(learning.skill_id) if learning.level <= @level
    end
    learn_other_skills if subclass
  end
 
  #--------------------------------------------------------------------------
  # alias method: param_base
  # (to prevent errors if the subclass level is higher than 99)
  #---------------------------------------------------------------------------
  alias yea_param_base_cs param_base
  def param_base(param_id)
    if subclass && @sub_level > 99
      cur_exp = @exp[sub_id]
      @exp[sub_id] = subclass.exp_for_level(99)
    end
    result = yea_param_base_cs(param_id)
    unless !subclass || @sub_level <= 99
      @exp[sub_id] = cur_exp
      subclass_rate = YEA::CLASS_SYSTEM::SUBCLASS_STAT_RATE
      if subclass_rate > 0
        result += ((subclass.above_lv99_params(param_id, @sub_level) *
          subclass_rate).to_i) - ((subclass.above_lv99_params(param_id, 99) *
          subclass_rate).to_i)
      end
    end
    result.to_i
  end
 
  # --- # /Error Prevent Functions
  # --- # Return Functions
 
  #--------------------------------------------------------------------------
  # new method: sub_id
  # (to set the value of subclass_id to 0 if nil and return the actor's
  # subclass ID)
  #--------------------------------------------------------------------------
  def sub_id; @subclass_id; end
 
  #--------------------------------------------------------------------------
  # new method: sub_exp
  # (to retrieve subclass experience)
  #--------------------------------------------------------------------------
  def sub_exp; @exp[sub_id] || 0; end
 
  #--------------------------------------------------------------------------
  # new method: sub_current_level_exp
  # (to retrieve subclass' exp to level up at current level)
  #--------------------------------------------------------------------------
  def sub_current_level_exp;
    !subclass ? 0 : subclass.exp_for_level(@sub_level)
  end
 
  #--------------------------------------------------------------------------
  # new method: sub_next_level_exp
  # (to retrieve subclass' exp to level up at next level)
  #--------------------------------------------------------------------------
  def sub_next_level_exp
    !subclass ? 0 : subclass.exp_for_level(@sub_level + 1)
  end
 
  #--------------------------------------------------------------------------
  # new method: max_sub_exp
  # (to return maximum subclass experience allowed)
  #--------------------------------------------------------------------------
  def max_sub_exp(class_id = nil)
    if class_id
      return 0 if $data_classes[class_id].nil?
      _class = $data_classes[class_id]
      return _class.exp_for_level([find_max_sub_level(class_id) + 1, 2].max) - 1
    end
    !subclass ? 0 : subclass.exp_for_level([max_sub_level + 1, 2].max) - 1
  end
 
  #--------------------------------------------------------------------------
  # overwrite method: class_level Edited by DisturbedInside/Ebonflame
  # (to determine level of class without relying on @level or @sub_level;
  # allows subclasses to be higher than classes and vice-versa)
  #--------------------------------------------------------------------------
 def class_level(class_id, sub = false)
   return 1 if !$data_classes[class_id]
    if sub == false
      return @level if YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
      maxi = actor.max_level
    elsif sub == true
      return @sub_level if EBON::MAINTAIN_SUB_LEVELS
      maxi = find_max_sub_level(class_id)
    elsif sub == "compare"
      maxi = [actor.max_level, find_max_sub_level(class_id)].max
    end
  
    temp_class = $data_classes[class_id]
   
    class_exp = @exp[class_id] || 0
    exp_max = [class_exp, (temp_class.exp_for_level(maxi + 1) - 1)].min
    # Note: Originally, DisturbedInside had this adjusting linearly for levels
    # above 99 (by 50744), but exp_for_level doesn't return linear values, and
    # since the rest of his code was based off exp_for_level, I changed it so
    # exp_max was non-linear as well. [~Ebonflame]
    exp_array = temp_class.exp_array
    # The exp for the most common levels are now stored in an array if you have
    # EBON - CSAdditionalFunctions or EBON - SubManager imported, for the sake of
    # a faster processing speed. If they aren't imported, change this line to:
    # exp_array = temp_class.respond_to?("exp_array") ? temp_class.exp_array : []
    index = exp_array.index(exp_array.find {|val| val > exp_max})
    return index unless index.nil?
   
    #--- DisturbedInside's code, slightly modified
    n = 100
    # if you changed the index line, you'll need to change this line also:
    # n = temp_class.respond_to?("exp_array") ? 100 : 2
    loop do
      break if temp_class.exp_for_level(n) > exp_max
      n += 1
    end
  return n
 end
 
  #--------------------------------------------------------------------------
  # overwrite method: subclass_level
  # (to return the value of the subclass' level without relying on @sub_level -
  # can evaluate classes as if they were subclasses even if they aren't
  # currently equipped as a subclass; allows subclasses to be higher than
  # classes)
  #--------------------------------------------------------------------------
  def subclass_level(class_id = nil)
    !class_id && !subclass ? 1 : class_level((class_id || sub_id), true)
  end
 
  #--------------------------------------------------------------------------
  # new method: compare_levels
  # (to return the highest level between class level and subclass level -
  # allows subclasses to be higher than classes)
  #--------------------------------------------------------------------------
  def compare_levels(class_id)
    class_level(class_id, "compare")
  end  
 
  #--------------------------------------------------------------------------
  # new method: max_sub_level
  # (to implement customizeable subclass level caps; you can still level your
  # subclass if you make it your main class. @max_sub_level needs to be updated
  # every time the current subclass is changed.)
  #--------------------------------------------------------------------------
  def max_sub_level; !subclass ? 1 : @max_sub_level; end
 
  #--------------------------------------------------------------------------
  # new method: max_sub_level?
  # (to determine if subclass has reached max level)
  #--------------------------------------------------------------------------
  def max_sub_level?; @sub_level >= max_sub_level; end
 
  #--------------------------------------------------------------------------
  # new method: find_max_sub_level
  # (so we don't have to call the find function every time we check the max
  # sub level)
  #--------------------------------------------------------------------------
  def find_max_sub_level(class_id = nil)
    class_id = sub_id if class_id.nil?
    if EBON::MAINTAIN_SUB_LEVELS    
      max_sub_level = (EBON::MAX_SUB_LEVELS.collect {|sub| sub[1]} +
        [EBON::DEFAULT_MAX_SUB_LEVEL]).min
    else
      max_sub_level = EBON::MAX_SUB_LEVELS.find {|sub| sub[0] == class_id}
      max_sub_level = !max_sub_level.nil? ? [max_sub_level[1], 1].max :
        [EBON::DEFAULT_MAX_SUB_LEVEL, 1].max
    end
    return max_sub_level if $imported["YEA-AdjustLimits"]
    [max_sub_level, 99].min
  end
 
  #--------------------------------------------------------------------------
  # new method: class_allowed?
  # (to determine if the actor is allowed to equip the class/subclass)
  #--------------------------------------------------------------------------
  def class_allowed?(class_id, symbol)
    return false if !$data_classes[class_id]
    if symbol == :primary
      return false if class_id == sub_id and EBON::MAINTAIN_SUB_LEVELS ||
        EBON::DISALLOW_NO_SUBCLASS
      return false if $imported["YEA-ClassSpecifics"] &&
        $data_classes[class_id].subclass_only
    elsif symbol == :subclass
      return false if (@exp[class_id] || 0) > max_sub_exp(class_id)
      return false if class_id == @class_id or class_id == 0 && sub_id == 0
      return false if class_id == sub_id || class_id == 0 and
        EBON::MAINTAIN_SUB_LEVELS || EBON::DISALLOW_NO_SUBCLASS
      return false if $imported["YEA-ClassSpecifics"] &&
        !subclass_requirements_met?(class_id)
    end
    check = $imported["EBON-ULMaintain"] if
      YEA::CLASS_SYSTEM::MAINTAIN_LEVELS ||
      EBON::MAINTAIN_SUB_LEVELS
    check = $imported["YEA-ClassUnlockLevel"] if check.nil?
    return false if check && !@unlocked_classes.include?(class_id) &&
      !class_unlock_level_requirements_met?($data_classes[class_id])
    return true
  end
 
  # --- # /Return Functions
  # --- # Subclass Compatibility (features)
 
  #--------------------------------------------------------------------------
  # alias method: change_class
  # (to reset class features on subclass change, correctly change subclass
  # if they're unequipping it, and prevent PBG from adding extra actor growth
  # if the new class is higher than the old class)
  #--------------------------------------------------------------------------
  alias game_actor_change_class_cs_yea change_class
  def change_class(class_id, keep_exp = false)
    return if !class_allowed?(class_id, :primary)
    self.class.change_features(@class_features) unless sub_id == 0
    forget_other_skills([@class_id], true) if !EBON::REMEMBER_CLASS_SKILLS
    init_subclass if class_id == sub_id
    new_level = class_level(class_id)
    if keep_exp || !$imported["YEA-ParameterBonusGrowth"] || new_level <= @level
      game_actor_change_class_cs_yea(class_id, keep_exp)
    else
      @class_id = class_id
      @level = class_level(@class_id)
      learn_class_skills(class_id)
      unlock_class(class_id)
      correct_subclass if $imported["YEA-ClassSpecifics"]
    end
    @class_features = class_features
    add_subclass_features if subclass
    learn_other_skills([@class_id, @level])
    refresh #release_unequippable_items
  end
 
  #--------------------------------------------------------------------------
  # overwrite method: change_subclass
  # (to reset @sub_level, @max_sub_level, skills, and class features on subclass
  # change. You need to call this in order to (permanently) change the actor's
  # subclass - don't just change @subclass_id. You've been warned.)
  #--------------------------------------------------------------------------
  def change_subclass(class_id)
    return if !class_allowed?(class_id, :subclass)
    unlock_class(class_id)
    self.class.change_features(@class_features)
    forget_other_skills if !EBON::REMEMBER_SUBCLASS_SKILLS
    if sub_id == class_id || class_id == 0
      init_subclass
    else
      if EBON::MAINTAIN_SUB_LEVELS
        @exp[class_id] = @exp[sub_id] unless sub_id == 0
        @subclass_id = class_id
      else
         @subclass_id = class_id
         @max_sub_level = find_max_sub_level(class_id)
         @sub_level = subclass_level
      end
      add_subclass_features
      learn_other_skills
    end
    refresh #release_unequippable_items
  end
 
  #--------------------------------------------------------------------------
  # new method: class_features
  # (to define original class features)
  #--------------------------------------------------------------------------
    def class_features(sub_features = nil)
      sub_features ? @class_features : self.class.features
    end
 
  #--------------------------------------------------------------------------
  # new method: add_subclass_features
  # (to judge which features should be added and add them)
  #--------------------------------------------------------------------------
  def add_subclass_features
    subclass_features = sub_id == 0 ? [] : subclass.features
    @sub_features = []
    for feature in subclass_features
      next if feature.code == 63 # Irrelevant
      next if [21, 41, 51, 52].include?(feature.code) # Yanfly
      if [14, 42, 43, 44, 53, 54, 55, 62, 64].include?(feature.code) # Special
        contents = @class_features + @sub_features
        next if contents.any? {|ft| ft.code == feature.code &&
          ft.data_id == feature.data_id} # Useless to add these features again
        if [43, 53, 54, 55, 62, 64].include?(feature.code)
          if feature.code == 43
            next if !EBON::ADDED_FEATURES.include?(feature.code)
          elsif feature.code == 62
            next if !EBON::SPECL_FEATURES.include?(feature.data_id)
          elsif feature.code == 64
            next if !EBON::PARTY_FEATURES.include?(feature.data_id)
          else
            next if !EBON::FORCED_FEATURES.include?(feature.code)
          end
        else
          code2 = feature.code - 1
          contents = @class_features.any? {|ft| ft.code == code2 &&
            ft.data_id == feature.data_id}
          next if contents && !EBON::FORCED_FEATURES.include?(feature.code)
        end
      else
        next if !EBON::ADDED_FEATURES.include?(feature.code)
      end
      @sub_features.push(feature)
    end
    self.class.change_features(@sub_features, true)
  end
 
  # --- # /Subclass Compatibility (features)
  # --- # Subclass Functionality (learned skills modification)
 
  #--------------------------------------------------------------------------
  # new method: learn_other_skills
  # (to add a group of skills learned from a specific class.)
  # Default mode: adds skills learned from the current subclass up to/including
  # the current @sub_level.
  # Use: learn_other_skills.
  # Secondary mode: adds skills learned from another class up to/including
  # a specified level (or level 1).
  # Use: learn_other_skills([class_id])
  #      learn_other_skills([class_id, level])
  #--------------------------------------------------------------------------
  def learn_other_skills(special = nil) #read the note -^
    if !special
      return if !subclass
      _class = sub_id
      level = @sub_level
    else
      return if !$data_classes[special[0]]
      _class = special[0]
      level = special[1] || 1
    end
    $data_classes[_class].learnings.each do |learning|
      learn_skill(learning.skill_id) if learning.level <= level
    end
  end
 
  #--------------------------------------------------------------------------
  # new method: forget_other_skills
  # (to remove a group of skills learned from a specific class.)
  # Default mode: removes skills learned from the current subclass from level
  # one up to/including the current @sub_level. Does not delete skills learned
  # in the main class before the actor's current @level.
  # Use: forget_other_skills.
  # Secondary mode: removes skills learned from any class beginning at/including
  # a specified level (or level 1). Does not delete skills learned in the
  # main class before the actor's current @level.
  # Use: forget_other_skills([class_id])
  #      forget_other_skills([class_id, level])
  # Tertiary mode: Same as the default or secondary mode, but removes the skills
  # even if the main class learns them.
  # Use: forget_other_skills(nil, true)
  #      forget_other_skills([class_id], true)
  #      forget_other_skills([class_id, level], true)
  #--------------------------------------------------------------------------
  def forget_other_skills(special = nil, forget_main = false) #read the note -^
    class_skills = self.class.learnings
    if special
      return if !$data_classes[special[0]]
      _class = special[0]
      level = special[1] || 1
    else
      return if !$data_classes[sub_id]
      _class = sub_id
      level = @sub_level
    end
    learnings = $data_classes[_class].learnings.sort_by {|skill| skill.level}
    dex = learnings.index(learnings.find {|learning| learning.level >= level})
    return if !dex && special
    learnings = special ? learnings[dex, learnings.length] :
      learnings[0, (dex || learnings.length)]
    for skill in learnings
      forget_skill(skill.skill_id) if forget_main || class_skills.any? {|orig|
        orig.skill_id == skill.skill_id && orig.level <= @level}
    end
  end
 
  # --- # /Subclass Functionality (learned skills modification)
  # --- # Subclass Compatibility (PBG)
 
  #--------------------------------------------------------------------------
  # new method: apply_sub_param_bonus_growth
  #--------------------------------------------------------------------------
  def apply_sub_param_bonus_growth(rate = 1)
    for i in 0...8 do @param_plus[i] += sub_param_bonus_growth(i) * rate end
  end
  # --- # /Subclass Compatibility (PBG)
  # --- # Subclass Compatibility (leveling)
 
  #--------------------------------------------------------------------------
  # new method: change_sub_level
  # (to forcefully change your actor's subclass' level)
  #--------------------------------------------------------------------------
  def change_sub_level(level, show)
    return if sub_id == 0
    level = [[level, max_sub_level].min, 1].max
    change_sub_exp(subclass.exp_for_level(level), show)
  end
 
  #--------------------------------------------------------------------------
  # overwrite method: gain_exp
  # (to allow for exp gain in subclass/main class/both classes)
  #--------------------------------------------------------------------------
  def gain_exp(exp, type = nil)
    enabled = !$imported["YEA-VictoryAftermath"] ? true :
      !SceneManager.scene_is?(Scene_Battle)
    alt_exp = (exp * EBON::SUB_EXP_RATE * final_exp_rate).ceil
    main_exp = (@exp[@class_id] || 0) + (exp * final_exp_rate).ceil
    if type == nil #both classes
      EBON::SINGLE_CLASS_EXP_BONUS == true && sub_id == 0 ?
        change_exp(main_exp + alt_exp, enabled) : change_exp(main_exp, enabled)
      change_sub_exp(sub_exp + alt_exp, enabled) if sub_id != 0
    elsif type == 1 #main class
      change_exp(main_exp, enabled)
    elsif type == 2 #subclass
      change_sub_exp(sub_exp + exp, enabled) if sub_id != 0
    end
  end
 
  #--------------------------------------------------------------------------
  # new method: change_sub_exp
  # (to add exp to subclass. Prevents your subclass from gaining exp if it's
  # at max level)
  #--------------------------------------------------------------------------
  def change_sub_exp(exp, show)
    return if sub_id == 0
    max_exp = max_sub_exp
    return if sub_exp >= max_exp
    first_level = @sub_level
    @exp[sub_id] = [exp, max_exp].min
    last_skills = skills
    sub_level_up while !max_sub_level? && sub_exp >= sub_next_level_exp
    sub_level_down while sub_exp < sub_current_level_exp
    unless $imported["YEA-VictoryAftermath"]
      display_sub_level_up(skills - last_skills) if show && @sub_level >
         first_level
    end
  end
 
  #--------------------------------------------------------------------------
  # new method: sub_level_up
  # (to trigger Param Bonus Growth Add-on)
  #--------------------------------------------------------------------------
  def sub_level_up
    @sub_level += 1
    if $imported["YEA-JPManager"]
      earn_jp_alt((EBON::SUB_LEVEL_JP / EBON::SUB_JP_RATE).ceil,
        sub_id) unless EBON::SUB_JP_RATE == 0
    end
    apply_sub_param_bonus_growth if $imported["YEA-ParameterBonusGrowth"]  
    subclass.learnings.each do |learning|
      learn_skill(learning.skill_id) if learning.level <= @sub_level
    end
  end
 
  #--------------------------------------------------------------------------
  # new method: sub_level_down
  # (to lose PBG on level down)
  #--------------------------------------------------------------------------
  def sub_level_down
   @sub_level -= 1
   apply_sub_param_bonus_growth(-1) if $imported["YEA-ParameterBonusGrowth"]
  end
 
  #--------------------------------------------------------------------------
  # new method: display_sub_level_up
  # (to display subclass leveling for default display_exp)
  #--------------------------------------------------------------------------
  def display_sub_level_up(new_skills)
    $game_message.new_page
    fmt = EBON::VOCAB_SUB_LV_UP
    $game_message.add(sprintf(fmt, @name, Vocab::level, @sub_level,
      subclass.name))
    new_skills.each do |skill|
      $game_message.add(sprintf(Vocab::ObtainSkill, skill.name))
    end
  end
 
  # --- # /Subclass Compatibility (leveling)
 
end #Game_Actor
 
#==============================================================================
# â–  Game_Troop
#==============================================================================
 
class Game_Troop < Game_Unit
 
  #--------------------------------------------------------------------------
  # new method: sub_jp_total
  #--------------------------------------------------------------------------
  def sub_jp_total
    dead_members.inject(0) {|r, enemy| r += (enemy.jp * EBON::SUB_JP_RATE).ceil}
  end
 
end # Game_Troop
 
#==============================================================================
# â–  Window_Base
#==============================================================================
 
class Window_Base < Window
 
  # --- # Begin JP Compatibility (draw subclass JP)
 
  #--------------------------------------------------------------------------
  # new method: draw_actor_jp_classes
  #--------------------------------------------------------------------------
  def draw_actor_jp_classes(actor, class_id, dx, dy, dw = 112)
    return if !$imported["YEA-JPManager"]
    if Icon.jp > 0
      dw -= 24
      draw_icon(Icon.jp, dx + dw, dy)
      dx -= 3
    end
    sub = actor.sub_id
    fmt = sub == 0 ? "%s" : EBON::JP_FORMAT
    text_total = sprintf(fmt, actor.jp(class_id).group, actor.jp(sub).group) +
      Vocab::jp
    tsize = text_size(text_total).width
    text_no_jp = sprintf(fmt, actor.jp(class_id).group, actor.jp(sub).group)
    text_no_jp_size = text_size(text_no_jp).width
    jp_size = text_size(Vocab::jp).width
    if tsize > dw
      shrink = 1 - (dw.to_f / tsize.to_f)
      if shrink > 0.4
        increase = (dw * (shrink - 0.4)).ceil
        if increase <= 12 #max spare space
          dw += increase
          dx -= increase
          jp_size = (jp_size * 0.6)
          text_no_jp_size = (text_no_jp_size * 0.6)
        else
          text_no_jp = actor.jp(class_id).group
          text_no_jp_size = text_size(text_no_jp).width
          if text_no_jp_size + jp_size > dw
            shrink = (dw.to_f / (text_no_jp_size + jp_size).to_f)
            jp_size = (jp_size * [0.6, shrink].min).ceil
            text_no_jp_size = (text_no_jp_size * [0.6, shrink].min).ceil
          end
        end
      else
        jp_size = (jp_size * (1 - shrink).abs).ceil
        text_no_jp_size = (text_no_jp_size * (1 - shrink).abs).ceil
      end
    end
    change_color(system_color)
    draw_text(dx + (dw - jp_size), dy, jp_size, line_height, Vocab::jp, 2)
    change_color(normal_color)
    draw_text(dx + (dw - text_no_jp_size) - jp_size, dy, text_no_jp_size,
      line_height, text_no_jp, 2)
  end
   
  #--------------------------------------------------------------------------
  # alias method: draw_actor_simple_status
  #--------------------------------------------------------------------------
  alias game_window_draw_actor_simple_status_cssm draw_actor_simple_status
  def draw_actor_simple_status(actor, dx, dy)
     dy -= line_height / 2 if !$imported["YEA-AceMenuEngine"]
     game_window_draw_actor_simple_status_cssm(actor, dx, dy)
     if EBON::DISPLAY_JP
       dy2 = $imported["YEA-AceMenuEngine"] ? dy - line_height / 2 : dy
       draw_actor_jp_classes(actor, actor.class_id, dx+3, dy2 +
         line_height * 3)
     end
   end
  
  # --- # /JP Compatibility (draw subclass JP)
  # --- # Subclass Compatibility (draw subclass level)
 
  #--------------------------------------------------------------------------
  # overwrite method: draw_actor_level
  #--------------------------------------------------------------------------
  alias game_window_draw_actor_level_cssm draw_actor_level
  def draw_actor_level(actor, x, y)
    if actor.sub_id == 0 || !EBON::CHANGE_LEVEL_FORMAT
      game_window_draw_actor_level_cssm(actor, x, y)
    else
      fmt = EBON::SUB_LVL_FORMAT
      text = sprintf(fmt, actor.level, actor.sub_level)
      tsize = text_size(text).width
      lvsize = text_size(Vocab::level_a).width
      change_color(system_color)
      draw_text(x, y, lvsize, line_height, Vocab::level_a)
      change_color(normal_color)
      draw_text(x + lvsize, y, [tsize, 144].min, line_height, text, 2)
    end
  end
 
  # --- # /Subclass Compatibility (draw subclass level)
 
end #Window_Base
 
#==============================================================================
# â–  Window_Status
#==============================================================================
 
class Window_Status < Window_Selectable
 
  # --- # Subclass Compatibility (larger area for class to be displayed in
  # --- # status menu)
 
  #--------------------------------------------------------------------------
  # * Draw Block 1
  #--------------------------------------------------------------------------
  alias game_window_draw_block1_cssm draw_block1
  def draw_block1(y)
    if !EBON::DISPLAY_SUB_INFO
      game_window_draw_block1_cssm(y)
    else
      dw = (contents.width/3) - standard_padding
      s1 = text_size(@actor.class).width
      s2 = text_size(@actor.nickname).width
      draw_actor_name(@actor, standard_padding, y, dw)
      draw_actor_class(@actor, ((contents.width/2) - (s1/2)), y, dw)
      draw_actor_nickname(@actor, (contents.width - s2 - standard_padding), y, dw)
    end
  end
  # --- # /Subclass Compatibility (larger area for class to be displayed in
  # --- # status menu)
  # --- # Subclass Compatibility (show subclass exp)
 
  #--------------------------------------------------------------------------
  # * Draw Experience Information
  #--------------------------------------------------------------------------
  alias game_window_draw_exp_info_cssm draw_exp_info
  def draw_exp_info(x, y)
    if !EBON::DISPLAY_SUB_INFO
      draw_exp_info_cssm(x, y)
    else
      s_next = sprintf(Vocab::ExpNext, Vocab::level)
      s_size = text_size(s_next).width
      x += (((contents.width - x)/2) - (s_size/1.5))
      dw = contents.width - x + 15
    
      s1 = @actor.max_level? ? EBON::MAX_LV : @actor.exp.group
      s2 = @actor.max_level? ? EBON::MAX_LV : (@actor.next_level_exp -
        @actor.exp).group
      s3 = @actor.max_sub_level? ? EBON::MAX_LV : @actor.sub_exp.group
      s4 = @actor.sub_id == 0 || @actor.max_sub_level? ? EBON::MAX_LV :
        (@actor.sub_next_level_exp - @actor.sub_exp).group
      fmt = @actor.subclass_id == 0 ? "%s" : EBON::SUB_EXP_DISPLAY
    
      change_color(system_color)
      draw_text(x - 15, y + line_height * 0, dw, line_height,
        Vocab::ExpTotal)
      draw_text(x - 15, y + line_height * 2, dw, line_height, s_next)
      change_color(normal_color)
      draw_text(x, y + line_height * 1, dw, line_height, sprintf(fmt, s1, s3))
      draw_text(x, y + line_height * 3, dw, line_height, sprintf(fmt, s2, s4))
    end
  end
 
  # --- # /Subclass Compatibility (show subclass exp)
 
end #Window_Status
 
#==============================================================================
# â–  Window_ClassList
#==============================================================================
 
class Window_ClassList < Window_Selectable
 
  # --- # Correction: Relative Level Display
 
  #--------------------------------------------------------------------------
  # overwrite method: draw_class_level
  # (to show the correct relative class level)
  #--------------------------------------------------------------------------
  def draw_class_level(item, rect)
    return if @actor.nil?
    if @command_window.current_symbol == :primary
      return if YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
      level = @actor.class_level(item.id)
    elsif @command_window.current_symbol == :subclass
      return if EBON::MAINTAIN_SUB_LEVELS
      level = @actor.class_level(item.id, true)
    end
    contents.font.size = YEA::CLASS_SYSTEM::LEVEL_FONT_SIZE
    text = sprintf(YEA::CLASS_SYSTEM::CLASS_LEVEL, level.group)
    draw_text(rect, text, 2)
  end
 
  # --- # /Correction: Relative Level Display
  # --- # Correction: enable?
 
  #--------------------------------------------------------------------------
  # enable?
  #--------------------------------------------------------------------------
  def enable?(item)
    return false if !@actor.class_allowed?(item.id,
      @command_window.current_symbol)
    true
  end
 
  # --- # /Correction: enable?
  # --- # Hide Unequippable Classes
 
  #--------------------------------------------------------------------------
  # include?
  #--------------------------------------------------------------------------
  if EBON::HIDE_UNEQUIPPABLE_CLASSES
    def include?(item)
      cur = @command_window.current_symbol
      return false if ![:primary, :subclass].include?(cur)
      return true if item.id == @actor.class_id && cur == :primary or
        item.id == @actor.sub_id && cur == :subclass
      unlocked = YEA::CLASS_SYSTEM::DEFAULT_UNLOCKS + @actor.unlocked_classes
      return true if unlocked.include?(item.id) &&
        @actor.class_allowed?(item.id, cur)
      false
    end
  end
 
  # --- # /Hide Unequippable Classes
 
end #Window_ClassList

 

Possible Conflicts:

 

 

  - Unconfirmed: XS Attribute System

 

 

 

 
ULMaintain (Version 1.0)
- Not needed if you don't have a MAINTAIN set to true and/or don't want to use Yanfly's Class Unlock Levels.
 

 
FAQ:

  - Q: I don't understand how this works!
  - A: Read the examples, then ask me again if you still have questions.

 
Script:


$imported = {} if $imported.nil?
$imported["EBON-ULMaintain"] = true
#==============================================================================
# â–¼ YEA UNLOCK LEVEL (MAINTAIN COMPATIBLE VERSION) v1.0
#==============================================================================
# â–¼ Author: Ebonflame; Credit: Yanfly (Original)/Ebonflame (Compatibility)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#——————————————————————————
# â–¼ Updates
#——————————————————————————
#
# 04.17.2013: Finished script.
#
#——————————————————————————
# â–¼ Description
#——————————————————————————
# 
# If you have this script imported because you want unlock_level to work when
# you have a MAINTAIN set to true, you can delete the original version of 
# Class Unlock Levels. If you do not want or need unlock_levels to work when 
# you have a MAINTAIN set to true, or you do not have a MAINTAIN set to true, 
# then you do not need this script.
#
# This script is designed to give Unlock Level at least minimal functionality 
# if you have YEA::CLASS_SYSTEM::MAINTAIN_LEVELS or EBON::MAINTAIN_SUB_LEVELS
# set to true. It now attempts to discern which type the class in question is 
# (primary, subclass, or both), and if the respective MAINTAIN_LEVELS is set to 
# true, compares the relevant @level/@sub_level (the actor must have a subclass
# equipped for it to compare @sub_level) to the level unlock requirements. If 
# the respective MAINTAIN_LEVELS is set to false, then it compares the level 
# of the class to the level unlock requirements.
#
# Example: Class 1 is unlocked when the actor reaches level 10 in class 4.
#
# Case 1: Class 1 is primary-only. YEA::CLASS_SYSTEM::MAINTAIN_LEVELS is false. 
# Unlock Level will compare the level of class 4 to the unlock requirements 
# (level 10) and unlock class 1 if they're met (original behavior).
#
# Case 2: Class 1 is subclass-only. EBON - SubManager is imported and 
# EBON::MAINTAIN_SUB_LEVELS is true. Unlock Level will compare the actor's 
# @sub_level to the unlock requirements (level 10) and unlock class 1 if they're
# met.
#
# Case 3: Class 1 can be equipped as either a primary or subclass. No MAINTAIN
# is true. Unlock Level will compare the level of class 4 to the unlock 
# requirements (level 10) and unlock class 1 if they're met (original behavior).
#
# Case 4: Class 1 can be equipped as either a primary or a subclass. 
# YEA::CLASS_SYSTEM::MAINTAIN_LEVELS is true, but the actor has a subclass 
# equipped and EBON - SubManager is imported. Unlock level will find the highest
# value between @level and @sub_level and compare it to the unlock requirements
# (level 10) and unlock class 1 if they're met.
#
# I know this probably sounds a little confusing, so you can contact me if you
# have any questions (rpgmakervxace.net: Ebonflame).
#
# You can find updated versions of this script at: 
# (www)rpgmakervxace.net/topic/12492-yanfly-class-system-add-ons-subclass-management/
# 
#——————————————————————————
 
 
  # --- # Begin Unlock LVL Missing Error Prevention... direct copypasta from 
  # --- # original without the 'unless maintain' part and with different aliases
 
module YEA
  module REGEXP
  module CLASS
    
    LV_UNLOCK_ON =
      /<(?:LEVEL_UNLOCK_REQUIREMENTS|level unlock requirements)>/i
    LV_UNLOCK_OFF =
      /<\/(?:LEVEL_UNLOCK_REQUIREMENTS|level unlock requirements)>/i
    LV_UNLOCK_STR = /CLASS[ ](\d+): LEVEL[ ](\d+)/i
    
  end # CLASS
  end # REGEXP
end # YEA
 
#==============================================================================
# â–  DataManager
#==============================================================================
 
module DataManager
  
  #--------------------------------------------------------------------------
  # alias method: load_database
  #--------------------------------------------------------------------------
  class <<self; alias load_database_culm load_database; end
  def self.load_database
    load_database_culm
    load_notetags_culm
  end
  
  #--------------------------------------------------------------------------
  # new method: load_notetags_culm
  #--------------------------------------------------------------------------
  def self.load_notetags_culm
    for obj in $data_classes
      obj.load_notetags_culm unless obj.nil?
    end
  end
  
end # DataManager
 
#==============================================================================
# â–  RPG::Class
#==============================================================================
 
class RPG::Class < RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :level_unlock
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_culm
  #--------------------------------------------------------------------------
  def load_notetags_culm
    @level_unlock = {}
    @level_unlock_on = false
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::CLASS::LV_UNLOCK_ON
        @level_unlock_on = true
      when YEA::REGEXP::CLASS::LV_UNLOCK_OFF
        @level_unlock_on = false
      when YEA::REGEXP::CLASS::LV_UNLOCK_STR
        next unless @level_unlock_on
        @level_unlock[$1.to_i] = $2.to_i
      end
    } # self.note.split
    #---
  end
  
end # RPG::Class
 
  # --- # /Unlock LVL Missing Error Prevention... direct copypasta from original, 
  # --- # without the 'unless maintain' part and with different aliases.
  
#==============================================================================
# â–  Game_Actor
#==============================================================================
 
class Game_Actor < Game_Battler
  
  # --- # Begin General Return Functions
  
  #--------------------------------------------------------------------------
  # new method: find_class_type
  # (to find whether the class type is primary, subclass, or either)
  #--------------------------------------------------------------------------
  if !respond_to?("find_class_type")  
    def find_class_type(class_id)
      return nil if !$imported["YEA-ClassSystem"] ||
      $data_classes[class_id].nil?
      if $imported["YEA-ClassSpecifics"]
        type = 1 if $data_classes[class_id].primary_only 
        type = 2 if $data_classes[class_id].subclass_only
      end
      type = 3 if type.nil? # both types
      return type
    end
  end
    
  #--------------------------------------------------------------------------
  # new method: find_maintain
  # (to find the maintain values)
  #--------------------------------------------------------------------------
  if !respond_to?("find_maintain")    
    def find_maintain(class_type, maintain = nil, maintain_sub = nil)
    # Note: anything that calls this needs to check and see if the class_id in 
    # question is currently equipped as the actor's class/subclass first.
      return nil if class_type.nil?
      maintain = YEA::CLASS_SYSTEM::MAINTAIN_LEVELS if maintain.nil?
      if maintain_sub.nil?
        maintain_sub = $imported["EBON-SubManager"] ? 
          EBON::MAINTAIN_SUB_LEVELS && sub_id != 0 : false
      end
      return nil unless maintain || maintain_sub
      case class_type
      #---
      when 1
        return nil if !maintain
        return 1
      when 2
        return nil if !maintain_sub
        return 2
      when 3
        if maintain && maintain_sub
          class_exp = @exp[@class_id] || 0
          subclass_exp = sub_exp
          exp = [class_exp, subclass_exp].max
          return 1 if exp == class_exp
          return 2
        elsif maintain
          return 1
        else
          return 2
        end
      #---
      end
    end
  end
  
  # --- # /General Return Functions
  # --- # Begin Unlock Level Maintain Compatibility
  
  #--------------------------------------------------------------------------
  # check_level_unlocked_classes
  #--------------------------------------------------------------------------
  def check_level_unlocked_classes
    for item in $data_classes
      next if item.nil?
      next if unlocked_classes.include?(item.id)
      next if item.level_unlock == {}
      next unless class_unlock_level_requirements_met?(item)
      unlock_class(item.id)
    end
  end
  
  #--------------------------------------------------------------------------
  # class_unlock_level_requirements_met?
  #--------------------------------------------------------------------------
  def class_unlock_level_requirements_met?(item)
    init_subclass if @subclass_id.nil?
    maintain = YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
    maintain_sub = $imported["EBON-SubManager"] ? 
      EBON::MAINTAIN_SUB_LEVELS && sub_id != 0 : 
      false
    lv = [@level, @sub_level || 1].max
    
    for key in item.level_unlock
      class_id = key[0]
      level_req = key[1]
      
      type = find_class_type(class_id)      
      case type
      #---
      when nil
        return false if class_level(class_id) < level_req
        # returns @level if MAINTAIN
      when 1
        return false if class_level(class_id) < level_req
      when 2
        return false if subclass_level < level_req
        # returns @level (YEA)/@sub_level (EBON) if MAINTAIN/MAINTAIN_SUB
      when 3
      # class can be equipped as primary or subclass
        maintain = find_maintain(type, maintain, maintain_sub)
        if maintain.nil?
          begin
            return false if compare_levels(class_id) < level_req
            # if compare_levels exists, it's possible one level cap may be higher
            # than the other; need to pick the highest cap.
          rescue
            return false if class_level(class_id) < level_req
          end
          # Just an example of a wierd way to use begin/rescue/ensure/end.
          # 'if respond_to?("compare_levels")' and/or 'if 
          # $imported["EBON-SubManager"]' would have worked as well.
        else
          return false if lv < level_req
        end
      #---
      end
    end
    return true
  end
  
  # --- # /Unlock Level Maintain Compatibility
  
end #Game_Actor
 
#==============================================================================
# â–  Window_ClassList
#==============================================================================
 
class Window_ClassList < Window_Selectable
  
   # --- # Begin Compatibility (EBON-VAUnlockedClasses)
  
  #--------------------------------------------------------------------------
  # alias method: actor=
  #--------------------------------------------------------------------------
  def actor=(actor)
    return if @actor == actor
    @actor = actor
    @last_item = nil
    actor.check_level_unlocked_classes if !$imported["EBON-VAUnlockedClasses"]
    refresh
    self.oy = 0
  end
  
  # --- # /Begin Compatibility (EBON-VAUnlockedClasses)
  
end

 

 
Subclass Aftermath (Version 1.1.5)
- Sadly, I can't use @param_plus like I originally hoped to, because there's no way to distinguish between class/other param_plus and subclass param_plus. However, I did change all the class_levels to compare_levels so it wouldn't return @level/@sub_level when determining level gain and MAINTAIN/MAINTAIN_SUB are set to true.
 

 
FAQ:

  - Q: Why is it recovering my actor's HP/MP when they level up?
  - A: RECOVERY_ON_LEVEL is set to true.

 
Script (Beta):


$imported = {} if $imported.nil?
$imported["EBON-SubAftermath"] = true
 
#==============================================================================
# â–¼ YEA VICTORY AFTERMATH ADD-ON =BETA= (EBONFLAME): SUBCLASS AFTERMATH v1.1.5
#==============================================================================
# â–¼ Author: Ebonflame
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#——————————————————————————
# â–¼ Updates
#——————————————————————————
#
# 2013.02.26: Initial release of beta version.
# 2013.03.06: Compatibility Update (Subclass Manager: PBG, subclass level caps)
# 2013.03.20: Feature Update (optional recovery of HP/MP on level-up) and
# compatibility update (had to re-write functions for changes in SubManager)
#——————————————————————————
# â–¼ To-Do
#——————————————————————————
#
# Compatibility Update: Masteries Aftermath
# Compatibility Update: Unlock Aftermath
#——————————————————————————
# â–¼ Description
#——————————————————————————
#
# This script is an add-on for the YEA Victory Aftermath script, allowing your 
# actors' subclass' EXP/JP/stat/skill change (if applicable) to be viewed
# seperately from your actor's main class' EXP/JP/stat/skill change. 
#
# Skills learned from the main class will appear on the main class' level 
# screen, while skills learned from the subclass will appear on the subclass' 
# level screen (unless the class learned them also, or the actor already has 
# them, in which case they won't appear at all).
#
# Stats shown on the subclass' level screen are not the original stats, but 
# rather the rate of influence they have on the main class. Additionally, you 
# can set the stats for the main class' level screen to include the influence
# of the subclass, or have the stats shown be the stats for the main class only.
#
# Finally, the subclass shows its own level-up text and victory quotes on its
# level-up screen (modifiable through notetags in the class notebox, like the
# Class System's quotes). To add quotes for the class when it's a subclass, put:
#
# <sub level quotes>
# "quote 1 here"
# [New Quote]
# "quote 2 here"
# </sub level quotes>
#
# and etc. in the class notebox. The quotes and formatting operate the same way 
# as the quotes for the main class.
#——————————————————————————
# â–¼ Compatibility
#——————————————————————————
#
# 1) Requires YEA – Victory Aftermath and my Subclass Manager script (found at:) 
# (www)rpgmakervxace.net/topic/12492-yanfly-class-system-add-ons-subclass-management/
# 2) Must be below YEA - Victory Aftermath.
# 3) (Should) work either above or below my Subclass Manager script.
#——————————————————————————
# â–¼ Instructions
#——————————————————————————
# To install the script, open your script editor and paste this script into
# a new section below â–¼ Materials but above â–¼ Main. This script must also
# be below YEA - Victory Aftermath.
#——————————————————————————
 
module EBON
  
  EXP_GAUGE_L = 30 # Left-hand side of subclass exp gauge.
  EXP_GAUGE_R = 31 # Right-hand side of subclass exp gauge.
  LEVEL_GAUGE_L = 25 # Left-hand side of subclass level gauge.
  LEVEL_GAUGE_R = 27 # Right-hand side of subclass level gauge.
  
  VICTORY_EXP_SUB = "+%s/%s EXP" # The way class/subclass EXP gain is displayed.
  VICTORY_JP_SUB = "+%s/%s%s" # The way class/subclass JP gain is displayed.
  
  TOP_SUB_LEVEL_UP = "%s's subclass leveled up!"
  # Text used to display subclass level up.
  
  SUB_VICTORY_QUOTES = {
    # :type   => Quotes
      #------------------------------------------------------------------------
      :sub_levels  =>  [ # Occurs as initial victory quote.
                        '"I knew studying this would come in handy."',
                        '"Hey, this subclass is pretty neat."',
                        '"Dual-classing for the win!"',
                        '"Who says I can\'t be two things at once?"'
                       ],# Do not remove this.
    } # Do not remove this.
  
  MAIN_LVL_MODIFIED_STATS = false
  # If set to true, when the actor's main class levels up, it will show the
  # stats as modified by the subclass (if applicable). If false, the stats 
  # shown will be the main class' original stats.
  
  RECOVERY_ON_LEVEL = true
  # If set to true, the actor will recover all HP/MP on level-up. If false, they
  # will not.
  
end
  
#==============================================================================
# â–¼ As Yanfly says:
# Editting anything past this point may potentially result in causing computer
# damage, incontinence, explosion of user's head, coma, death, and/or halitosis,
# so edit at your own risk.
#==============================================================================
  
  # --- # Begin VA Compatibility (subclass level quotes)
  
module YEA
  module REGEXP
  module BASEITEM
    
    SUB_LEVEL_QUOTE_ON  = /<(?:SUB_LEVEL_QUOTES|sub level quote|sub level quotes)>/i
    SUB_LEVEL_QUOTE_OFF = /<\/(?:SUB_LEVEL_QUOTES|sub level quote|sub level quotes)>/i
    
  end # BASEITEM
  end # REGEXP
end # YEA
 
#==============================================================================
# â–  RPG::BaseItem
#==============================================================================
 
class RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  # (to access subclass quotes)
  #--------------------------------------------------------------------------
  attr_accessor :sub_level_quotes
  
  #--------------------------------------------------------------------------
  # alias method: load_notetags_va
  # (to load subclass quotes from notes)
  #--------------------------------------------------------------------------
  alias load_notetags_va_yea load_notetags_va
  def load_notetags_va
    load_notetags_va_yea
    @sub_level_quotes = [""]
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::BASEITEM::SUB_LEVEL_QUOTE_ON
        @victory_quote_type = :sub_level_quote
      when YEA::REGEXP::BASEITEM::SUB_LEVEL_QUOTE_OFF
        @victory_quote_type = nil
      #---
      when YEA::REGEXP::BASEITEM::NEW_QUOTE
        case @victory_quote_type
          when nil; next
          when :sub_level_quote; @sub_level_quotes.push("")
        end
      #---
      else
        case @victory_quote_type
          when nil; next
          when :sub_level_quote; @sub_level_quotes[@sub_level_quotes.size-1
            ] += line.to_s
        end
      end
    } # self.note.split
    #---
    return unless self.is_a?(RPG::Class)
    sub_quotes = EBON::SUB_VICTORY_QUOTES
    @sub_level_quotes = sub_quotes[:sub_levels].clone if @sub_level_quotes == [""]
  end
end # RPG::BaseItem
 
 # --- # /VA Compatibility (subclass level quotes)
 
#==============================================================================
# â–  BattleManager
#==============================================================================
 
module BattleManager
  
  # --- # Begin VA Compatibility (Subclass Leveling)
 
  #--------------------------------------------------------------------------
  # overwrite method: self.gain_exp
  # (to show if the subclass levels up)
  #--------------------------------------------------------------------------
  def self.gain_exp
    $game_party.all_members.each do |actor|
      temp_actor = Marshal.load(Marshal.dump(actor))
      actor.gain_exp($game_troop.exp_total)
      next if actor.level == temp_actor.level && 
        actor.sub_level == temp_actor.sub_level
      actor.recover_all if EBON::RECOVERY_ON_LEVEL
      if actor.level > temp_actor.level
        SceneManager.scene.show_victory_level_up(actor, temp_actor)
        set_victory_text(actor, :level)
        wait_for_message
      end
      if actor.sub_level > temp_actor.sub_level
        SceneManager.scene.show_victory_level_up(actor, temp_actor, 2)
        set_victory_text(actor, :sub_levels)
        wait_for_message
      end
    end
  end
  
  # --- # /VA Compatibility (Subclass Leveling)
  
end
 
#==============================================================================
# â–  Game_Actor
#==============================================================================
  
class Game_Actor < Game_Battler
  
  # --- # Begin VA Compatibility (subclass level quotes)
  
  #--------------------------------------------------------------------------
  # overwrite method: victory_quotes
  # (to show level quotes for subclass)
  #--------------------------------------------------------------------------
  def victory_quotes(type)
    case type
    when :win
      return self.actor.win_quotes if self.actor.win_quotes != [""]
      return self.class.win_quotes
    when :level
      return self.actor.level_quotes if self.actor.level_quotes != [""]
      return self.class.level_quotes
    when :sub_levels
      return self.actor.sub_level_quotes if self.actor.sub_level_quotes != [""]
      return self.subclass.sub_level_quotes
    when :drops
      return self.actor.drops_quotes if self.actor.drops_quotes != [""]
      return self.class.drops_quotes
    else
      return ["NOTEXT"]
    end
  end
  
  # --- # /VA Compatibility (subclass level quotes)
  # --- # Begin VA debugging (multiple level JP gain)
  
  #--------------------------------------------------------------------------
  # new method: level_check
  # (to determine level difference before and after exp gain)
  #--------------------------------------------------------------------------
  def level_check(class_id, temp_exp)
    f_lvl = compare_levels(class_id)
    @exp[class_id] += temp_exp
    l_lvl = compare_levels(class_id)
    diff = l_lvl - f_lvl
    @exp[class_id] -= temp_exp
    return diff
  end
  
  # --- # /VA debugging (multiple level JP gain)
  # --- # Begin VA Compatibility (Class vs Subclass skills)
  
  #--------------------------------------------------------------------------
  # new method: skill_check
  # (to determine skill difference before and after exp gain)
  #--------------------------------------------------------------------------  
  def skill_check(_class, temp_exp, skills_to_omit = [])
    new_skills = []
    alt_exp = (temp_exp * EBON::SUB_EXP_RATE).to_i
    if _class == 1
      temp_exp += alt_exp if EBON::SINGLE_CLASS_EXP_BONUS && sub_id == 0
      @exp[@class_id] += temp_exp
      lvl = compare_levels(@class_id)
      self.class.learnings.each do |learning|
        if learning.level <= lvl && learning.level > @level
          new_skills.push(learning.skill_id)
        end     
      end
      @exp[@class_id] -= temp_exp
    elsif _class == 2
      return new_skills if sub_id == 0
      @exp[@subclass_id] += alt_exp.to_i
      lvl = compare_levels(@subclass_id)
      self.subclass.learnings.each do |learning|
        if learning.level <= lvl && learning.level > @sub_level
          new_skills.push(learning.skill_id)
        end
      end
      @exp[@subclass_id] -= alt_exp.to_i
    end
    unless skills_to_omit.empty? || new_skills.empty?
      skills_to_omit.each do |_skill|
        new_skills.delete(_skill.id) if new_skills.include?(_skill.id)
      end
    end
    skill_data = new_skills.sort.collect {|id| $data_skills[id]} 
    return skill_data
  end
  
  # --- # /VA Compatibility (Class vs Subclass skills)
  # --- # Begin SubManager Compatibility (subclass exp gain)
  
  #--------------------------------------------------------------------------
  # overwrite method: gain_exp
  # (to allow for exp gain in subclass/main class/both classes - read 'Script
  # Calls: $game_actors.gain_exp(x, y)' in Ebon-SubManager for more details)
  #--------------------------------------------------------------------------
  def gain_exp(exp, _class = nil)
    enabled = !SceneManager.scene_is?(Scene_Battle)
    alt_exp = (exp * EBON::SUB_EXP_RATE * final_exp_rate).ceil
    main_exp = (@exp[@class_id] || 0) + (exp * final_exp_rate).ceil
    if _class == nil #both classes
      EBON::SINGLE_CLASS_EXP_BONUS == true && sub_id == 0 ? 
        change_exp(main_exp + alt_exp, enabled) : change_exp(main_exp, enabled)
      change_sub_exp(sub_exp + alt_exp, enabled) if sub_id != 0
    elsif _class == 1 #main class
      change_exp(main_exp, enabled)
    elsif _class == 2 #subclass
      change_sub_exp(sub_exp + exp, enabled) if sub_id != 0
    end
  end
  
  # --- # /SubManager Compatibility (subclass exp gain)
  
end
 
#==============================================================================
# â–  Window_VictoryEXP_Back
#==============================================================================
 
class Window_VictoryEXP_Back < Window_Selectable 
  
  # --- # Begin VA Compatibility (EXP/JP Text)
  
  #--------------------------------------------------------------------------
  # alias method: draw_exp_gain
  # (to show subclass exp gain in party exp gain window)
  #--------------------------------------------------------------------------
  alias draw_exp_gain_yan draw_exp_gain
  def draw_exp_gain(actor, rect)    
    unless !$imported["EBON-SubManager"] || actor.sub_id == 0
      fmt = EBON::VICTORY_EXP_SUB
      text = sprintf(fmt, actor_exp_gain(actor).group, sub_exp_gain(actor).group)
      dw = rect.width - (rect.width - [rect.width, 96].min) / 2
      dy = rect.y + line_height * 3 + 96
      contents.font.size = YEA::VICTORY_AFTERMATH::FONTSIZE_EXP
      change_color(power_up_color)
      draw_text(rect.x, dy, dw, line_height, text, 2)
      return
    end
    draw_exp_gain_yan(actor, rect)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: draw_jp_gain
  # (to show subclass jp gain in party exp gain window)
  #--------------------------------------------------------------------------
  def draw_jp_gain(actor, rect)
    return unless $imported["YEA-JPManager"]    
    if $imported["EBON-SubManager"] && actor.sub_id != 0  
      fmt = EBON::VICTORY_JP_SUB
      actor_jp = actor_jp_gain(actor).group
      actor_sub_jp = sub_jp_gain(actor).group
      text = sprintf(fmt, actor_jp, actor_sub_jp, Vocab::jp)
    else
      fmt = YEA::JP::VICTORY_AFTERMATH
      text = sprintf(fmt, actor_jp_gain(actor).group, Vocab::jp)
    end
    dw = rect.width - (rect.width - [rect.width, 96].min) / 2
    dy = rect.y + line_height * 4 + 96
    contents.font.size = YEA::VICTORY_AFTERMATH::FONTSIZE_EXP
    change_color(power_up_color)
    draw_text(rect.x, dy, dw, line_height, text, 2)
  end
 
  #--------------------------------------------------------------------------
  # overwrite method: actor_exp_gain
  # (to show single class bonus exp)
  #--------------------------------------------------------------------------
  def actor_exp_gain(actor)
    n = @exp_total * actor.final_exp_rate
    n += sub_exp_gain(actor) if EBON::SINGLE_CLASS_EXP_BONUS && 
      actor.sub_id == 0
    return n.to_i
  end
  
  #--------------------------------------------------------------------------
  # new method: sub_exp_gain
  # (to evaluate subclass exp gain)
  #--------------------------------------------------------------------------
  def sub_exp_gain(actor)
    n = @exp_total * EBON::SUB_EXP_RATE * actor.final_exp_rate
    if actor.sub_id != 0
      max_exp = actor.max_sub_exp
      c = actor.sub_exp
      if c >= max_exp
        n = 0
      else
        m = n + c
        n -= m - max_exp if m > max_exp
      end
    end      
    return n.to_i
  end
 
  #--------------------------------------------------------------------------
  # overwrite method: actor_jp gain
  # (to display JP gain for multiple level gains at once)
  #--------------------------------------------------------------------------
  def actor_jp_gain(actor)
    n = actor.battle_jp_earned
    if actor.exp + actor_exp_gain(actor) > actor.exp_for_level(actor.level + 1)
      n += actor.level_check(actor.class_id, actor_exp_gain(actor)) * 
        YEA::JP::LEVEL_UP unless actor.max_level?
    end
    return n
  end
  
  #--------------------------------------------------------------------------
  # new method: sub_jp_gain
  # (to evaluate subclass jp gain, adjusting for multiple level gain)
  #--------------------------------------------------------------------------
  def sub_jp_gain(actor)
    n = actor.battle_sub_jp_earned    
    if actor.sub_exp + sub_exp_gain(actor) >=
      actor.sub_next_level_exp
      
      n += (actor.level_check(actor.sub_id, sub_exp_gain(actor)) * 
      EBON::SUB_LEVEL_JP) unless actor.max_sub_level?
    end
    return n
  end
  
  # --- # /VA Compatibility (Subclass EXP/JP Text)
end
 
#==============================================================================
# â–  Window_VictoryEXP_Front
#==============================================================================
 
class Window_VictoryEXP_Front < Window_VictoryEXP_Back
  
  # --- Begin VA Compatibility (Subclass EXP Bars)  
  
  #--------------------------------------------------------------------------
  # overwrite method: initialize
  #--------------------------------------------------------------------------
  def initialize
    super
    self.back_opacity = 0
    @ticks = 0
    @counter = 30
    @sub_ticks = 0
    @sub_counter = 30
    contents.font.size = YEA::VICTORY_AFTERMATH::FONTSIZE_EXP
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: update
  # (to also update sub_ticks)
  #--------------------------------------------------------------------------
  def update
    super
    update_tick
    update_sub_tick unless !$imported["EBON-SubManager"]
  end
 
  #--------------------------------------------------------------------------
  # new method: update_sub_tick
  # (to update sub_ticks)
  #--------------------------------------------------------------------------
  def update_sub_tick
    return unless self.openness >= 255
    return unless self.visible
    return if complete_sub_ticks?
    @sub_counter -= 1
    return unless @sub_counter <= 0
    return if @sub_ticks >= YEA::VICTORY_AFTERMATH::EXP_TICKS
    YEA::VICTORY_AFTERMATH::VICTORY_TICK.play
    @sub_counter = 4
    @sub_ticks += 1
    refresh
  end
  
  #--------------------------------------------------------------------------
  # new method: complete_sub_ticks?
  # (to calculate sub_ticks)
  #--------------------------------------------------------------------------
  def complete_sub_ticks?
    for actor in $game_party.battle_members
      unless actor.sub_id == 0
        total_ticks = YEA::VICTORY_AFTERMATH::EXP_TICKS
        sub_bonus_exp = sub_exp_gain(actor) * @sub_ticks / total_ticks
        sub_now_exp = actor.sub_exp - actor.sub_current_level_exp + sub_bonus_exp
        sub_next_exp = actor.sub_next_level_exp - actor.sub_current_level_exp
        rate = sub_now_exp * 1.0 / sub_next_exp
        return false if rate < 1.0 
      end
    end
    return true
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: draw_item
  # (to also draw subclass exp gain)
  #--------------------------------------------------------------------------
  def draw_item(index)
    actor = $game_party.battle_members[index]
    return if actor.nil?
    rect = item_rect(index)
    draw_actor_exp(actor, rect)
    draw_actor_sub_exp(actor, rect) unless actor.sub_id == 0 || 
      !$imported["EBON-SubManager"]
  end
    
  #--------------------------------------------------------------------------
  # exp_gauge3
  #--------------------------------------------------------------------------
  def exp_gauge3; return text_color(EBON::EXP_GAUGE_L); end
 
  #--------------------------------------------------------------------------
  # exp_gauge4
  #--------------------------------------------------------------------------
  def exp_gauge4; return text_color(EBON::EXP_GAUGE_R); end
 
  #--------------------------------------------------------------------------
  # lvl_gauge3
  #--------------------------------------------------------------------------
  def lvl_gauge3; return text_color(EBON::LEVEL_GAUGE_L); end
    
  #--------------------------------------------------------------------------
  # lvl_gauge4
  #--------------------------------------------------------------------------
  def lvl_gauge4; return text_color(EBON::LEVEL_GAUGE_R); end
    
  #--------------------------------------------------------------------------
  # overwrite method: draw_exp_gauge
  # (to allow space for the subclass gauge, if present)
  #--------------------------------------------------------------------------
  def draw_exp_gauge(actor, rect, rate)
    rate = [[rate, 1.0].min, 0.0].max
    if actor.sub_id == 0 || !$imported["EBON-SubManager"]
      dx = (rect.width - [rect.width, 96].min) / 2 + rect.x
      dw = [rect.width, 96].min
    else 
      dw = [rect.width / 2, 48].min
      dx = (rect.width - [rect.width, 98].min) / 2 + rect.x
    end
    dy = rect.y + line_height * 2 + 96
    colour1 = rate >= 1.0 ? lvl_gauge1 : exp_gauge1
    colour2 = rate >= 1.0 ? lvl_gauge2 : exp_gauge2
    draw_gauge(dx, dy, dw, rate, colour1, colour2)
    fmt = YEA::VICTORY_AFTERMATH::EXP_PERCENT
    text = sprintf(fmt, [rate * 100, 100.00].min)
    if [rate * 100, 100.00].min == 100.00
      text = actor.max_level? ? 
      text = YEA::VICTORY_AFTERMATH::MAX_LVL_TEXT : 
      text = YEA::VICTORY_AFTERMATH::LEVELUP_TEXT 
    end
    draw_text(dx, dy, dw, line_height, text, 1)
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_actor_sub_exp
  # (to calculate and draw ticks in subclass EXP guage)
  #--------------------------------------------------------------------------
  def draw_actor_sub_exp(actor, rect)
    if actor.max_sub_level?
      draw_sub_exp_gauge(actor, rect, 1.0)
      return      
    end
    ticks = @sub_ticks
    total_ticks = YEA::VICTORY_AFTERMATH::EXP_TICKS
    sub_bonus_exp = sub_exp_gain(actor) * @sub_ticks / total_ticks
    sub_now_exp = actor.sub_exp - actor.sub_current_level_exp + 
      sub_bonus_exp
    sub_next_exp = actor.sub_next_level_exp - actor.sub_current_level_exp
    rate = sub_now_exp * 1.0 / sub_next_exp
    draw_sub_exp_gauge(actor, rect, rate)
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_sub_exp_gauge
  # (to draw subclass EXP guage)
  #--------------------------------------------------------------------------
  def draw_sub_exp_gauge(actor, rect, rate)
    rate = [[rate, 1.0].min, 0.0].max if rate != 0.0
    dw = [rect.width / 2, 48].min
    dx = (rect.width - [rect.width, 94].min) / 2 + rect.x + dw
    dy = rect.y + line_height * 2 + 96
    colour1 = rate >= 1.0 ? lvl_gauge3 : exp_gauge3
    colour2 = rate >= 1.0 ? lvl_gauge4 : exp_gauge4
    draw_gauge(dx, dy, dw, rate, colour1, colour2)
    fmt = YEA::VICTORY_AFTERMATH::EXP_PERCENT
    text = sprintf(fmt, [rate * 100, 100.00].min)
    if [rate * 100, 100.00].min == 100.00
      text = actor.max_sub_level? ? 
      YEA::VICTORY_AFTERMATH::MAX_LVL_TEXT : 
      YEA::VICTORY_AFTERMATH::LEVELUP_TEXT
    end
    draw_text(dx, dy, dw, line_height, text, 1)
  end
  
  # --- # /End VA Compatibility (Subclass EXP Bars)
 
end
 
#==============================================================================
# â–  Window_VictoryLevelUp
#==============================================================================
 
class Window_VictoryLevelUp < Window_Base
  
  # --- # Begin VA Compatibility (Class/Subclass level-up windows)
  
  #--------------------------------------------------------------------------
  # refresh
  # (to determine which class leveled - main class or subclass)
  #--------------------------------------------------------------------------
  def refresh(actor, temp_actor, _class = 1)
    contents.clear
    reset_font_settings
    YEA::VICTORY_AFTERMATH::LEVEL_SOUND.play
    draw_actor_changes(actor, temp_actor, _class)
  end
  
  #--------------------------------------------------------------------------
  # alias method: draw_actor_changes
  # (to show differences for those with subclasses)
  #--------------------------------------------------------------------------
  alias draw_actor_changes_yea draw_actor_changes
  def draw_actor_changes(actor, temp_actor, _class = 1)
    if actor.sub_id == 0 || _class == 1
      draw_actor_changes_yea(actor, temp_actor)
    else
      dx = contents.width / 16
      draw_actor_image(actor, temp_actor, dx)
      draw_param_names_sub(actor, dx, _class)
      draw_former_stats_sub(actor, temp_actor, _class)
      draw_arrows
      draw_newer_stats_sub(actor, temp_actor, _class)
      draw_new_skills_sub(actor, temp_actor, _class)
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_actor_image_sub
  # (to draw the subclass experience)
  #--------------------------------------------------------------------------
  alias draw_actor_image_yea draw_actor_image
  def draw_actor_image(actor, temp_actor, dx)
    if actor.sub_id == 0; draw_actor_image_yea(actor, temp_actor, dx); else
      draw_text(dx, line_height, 96, line_height, actor.name, 1)
      draw_actor_face(actor, dx, line_height * 2)
      exp = (actor.exp - temp_actor.exp).to_i
      sub_exp = (actor.sub_exp - temp_actor.sub_exp).to_i
      text = sprintf(EBON::VICTORY_EXP_SUB, exp.group, sub_exp.group)
      change_color(power_up_color)
      contents.font.size = YEA::VICTORY_AFTERMATH::FONTSIZE_EXP
      draw_text(0, line_height * 2 + 96, dx + 96, line_height, text, 2)
      reset_font_settings
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_param_names_sub
  # (to show the subclass leveled)
  #--------------------------------------------------------------------------
  def draw_param_names_sub(actor, dx, _class = 1)
    dx += 108
    change_color(system_color)
    text = Vocab.level if _class == 1
    text = sprintf("Sub. %s", Vocab.level_a) if _class == 2
    draw_text(dx, 0, contents.width - dx, line_height, text)
    dy = 0
    for i in 0...8
      dy += line_height
      text = Vocab.param(i)
      draw_text(dx, dy, contents.width - dx, line_height, text)
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_former_stats_sub
  # (to show the former stats for the actor)
  #--------------------------------------------------------------------------
  def draw_former_stats_sub(actor, temp_actor, _class = 1)
    dw = contents.width / 2 - 12
    dy = 0
    change_color(normal_color)
    if _class == 1
      draw_text(0, dy, dw, line_height, temp_actor.level.group, 2)
      if !EBON::MAIN_LVL_MODIFIED_STATS && 
        YEA::CLASS_SYSTEM::SUBCLASS_STAT_RATE > 0   
        orig_class = temp_actor.sub_id
        temp_actor.subclass_id = 0      
      end
      for i in 0...8
        dy += line_height
        draw_text(0, dy, dw, line_height, temp_actor.param(i).group, 2)
      end
      temp_actor.subclass_id = orig_class if !EBON::MAIN_LVL_MODIFIED_STATS && 
        YEA::CLASS_SYSTEM::SUBCLASS_STAT_RATE > 0
    elsif _class == 2 && actor.sub_id != 0
      draw_text(0, dy, dw, line_height, temp_actor.sub_level.group, 2)
      slevel_prev = (temp_actor.sub_level - 1)
      s_rate = YEA::CLASS_SYSTEM::SUBCLASS_STAT_RATE
      for i in 0...8
        dy += line_height
        pbg_prev = (actor.sub_param_bonus_growth(i) * slevel_prev).to_i
        prev_result = (temp_actor.subclass.above_lv99_params(i, slevel_prev + 1) * 
          s_rate).to_i + pbg_prev
        draw_text(0, dy, dw, line_height, sprintf('+%s', prev_result), 2)
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_newer_stats_sub
  # (to show the newer stats for the actor)
  #--------------------------------------------------------------------------
  def draw_newer_stats_sub(actor, temp_actor, _class = 1)
    dx = contents.width / 2 + 12
    dw = contents.width - dx
    dy = 0
    if _class == 1
      change_color(param_change_color(actor.level - temp_actor.level))
      draw_text(dx, dy, dw, line_height, actor.level.group, 0)
      if !EBON::MAIN_LVL_MODIFIED_STATS && 
        YEA::CLASS_SYSTEM::SUBCLASS_STAT_RATE > 0
        orig_class = actor.sub_id
        actor.subclass_id = 0 
        temp_actor.subclass_id = 0
      end
      for i in 0...8
        dy += line_height
        change_color(param_change_color(actor.param(i) - temp_actor.param(i)))
        draw_text(dx, dy, dw, line_height, actor.param(i).group, 0)
      end
      if !EBON::MAIN_LVL_MODIFIED_STATS && 
        YEA::CLASS_SYSTEM::SUBCLASS_STAT_RATE > 0
        actor.subclass_id = orig_class
        temp_actor.subclass_id = orig_class
      end
    elsif _class == 2 && actor.sub_id != 0
      change_color(param_change_color(actor.sub_level - 
        temp_actor.sub_level))
      draw_text(dx, dy, dw, line_height, actor.sub_level.group, 0)
      slevel_cur = (actor.sub_level - 1)
      slevel_prev = (temp_actor.sub_level - 1)
      s_rate = YEA::CLASS_SYSTEM::SUBCLASS_STAT_RATE
      for i in 0...8
        dy += line_height
        growth = actor.sub_param_bonus_growth(i)
        pbg_prev = (growth * slevel_prev).to_i
        pbg_cur = (growth * slevel_cur).to_i
        # above_lv_99_params will return the correct value even if the subclass
        # level is 99 or below
        cur_result = (actor.subclass.above_lv99_params(i, slevel_cur + 1) * 
          s_rate).to_i + pbg_cur
        prev_result = (temp_actor.subclass.above_lv99_params(i, slevel_prev + 1) * 
          s_rate).to_i + pbg_prev
        change_color(param_change_color(cur_result - prev_result))
        draw_text(dx, dy, dw, line_height, sprintf('+%s', cur_result.group), 0)
      end
    end
  end
  
  # --- # /VA Compatibility (Class/Subclass level-up windows)
  # --- # Begin VA Compatibility (Class vs Subclass skills)
 
  #--------------------------------------------------------------------------
  # draw_new_skills
  # (to only display SKILLS_TEXT if the class/subclass learned something)
  #--------------------------------------------------------------------------
  def draw_new_skills_sub(actor, temp_actor, _class = 1)
    return if temp_actor.skills.size == actor.skills.size
    dw = 172 + 24
    dx = contents.width - dw
    change_color(system_color)
    text = YEA::VICTORY_AFTERMATH::SKILLS_TEXT
    exp = $game_troop.exp_total
    class_skills = temp_actor.skill_check(1, exp)
    
    if _class == 1
      draw_text(dx, 0, dw, line_height, text, 0) if !class_skills.empty?
    elsif _class == 2
      subclass_skills = temp_actor.skill_check(2, exp, class_skills + 
        temp_actor.skills)
      draw_text(dx, 0, dw, line_height, text, 0) if !subclass_skills.empty?
    end
  end
  
end # Window_VictoryLevelUp
 
#==============================================================================
# â–  Window_VictorySkills
#==============================================================================
 
class Window_VictorySkills < Window_Selectable
  
  #--------------------------------------------------------------------------
  # refresh
  # (to differentiate between class and subclass skills)
  #--------------------------------------------------------------------------
  def refresh(actor, temp_actor, _class = 1)
    contents.clear
    if actor.skills.size == temp_actor.skills.size
      unselect
      @data = []
      create_contents
      return
    end
    exp = $game_troop.exp_total
    @data = temp_actor.skill_check(1, exp * actor.final_exp_rate)
    if _class == 2
      subclass_skills = temp_actor.skill_check(2, exp * actor.final_exp_rate, 
        @data + temp_actor.skills)
      @data = subclass_skills
    end
    if @data.size > 8
      select(0)
      activate
    else
      unselect
      deactivate
    end
    create_contents
    draw_all_items
  end
 
  # --- # /VA Compatibility (Class vs Subclass skills)
  
end # Window_VictorySkills
 
#==============================================================================
# â–  Scene_Battle
#==============================================================================
 
class Scene_Battle < Scene_Base
  
  #---# Begin VA Compatibility (Class vs Subclass windows)
  
  #--------------------------------------------------------------------------
  # new method: show_victory_level_up
  # (to differentiate between main class and subclass leveling)
  #--------------------------------------------------------------------------
  def show_victory_level_up(actor, temp_actor, _class = 1)
    @victory_exp_window_back.hide
    @victory_exp_window_front.hide
    #---
    fmt = YEA::VICTORY_AFTERMATH::TOP_LEVEL_UP if _class == 1
    fmt = EBON::TOP_SUB_LEVEL_UP if _class == 2
    text = sprintf(fmt, actor.name)
    @victory_title_window.refresh(text)
    #---
    @victory_level_window.show
    @victory_level_window.refresh(actor, temp_actor, _class)
    @victory_level_skills.show
    @victory_level_skills.refresh(actor, temp_actor, _class)
  end
  
  #---# /VA Compatibility (Class vs Subclass windows)
  
end # Scene_Battle

 

 
#---------------------
 
(Almost) a parting word: the script that originally triggered my entry into the scripting world (Estriole's Subclass EXP Gain script) can be found here: http://www.rpgmakervxace.net/topic/6661-yea-class-script-addon-subclass-gain-exp/[/url] You'll find a very old version of the subclass manager script over there as well (v 1.1.4).
 
#---------------------
 
Finally, my terms of use:
- Free to use in any game, commercial or non-commercial
- Credit would be extremely welcome, but not required
- Don't repost these scripts elsewhere; come to me and I'll put 'em up if possible.
 
And that's all, folks!
Edited by Ebonflame
  • Like 3

Share this post


Link to post
Share on other sites

Nice script. I will be using this script conservatively to mold my class system. I always thought it was weird that Yanfly included the ability for the secondary class to influence your statistics gain and loss per level, but not the ability to have it gain JP or EXP as well.

 

Just want to throw this idea out there, but I think it'd be neat to have the option for a tertiary (or second subclass) class that could gain JP or EXP at a (presumably lower) different rate than the others.

 

EDIT:

If there is no subclass equipped, Victory Aftermath will result in an error. The second error I am uncertain of, but I will continue to test and find out what it is that causing it. EDIT2: Ah, the second error is with Subclass Management itself. I realized that for the testing I had forgotten to name the script.

 

 

Error #1, no subclass is equipped.

rmvxa_subclass_mgmt_error1.jpg

 

Error #2, subclass is equipped.

rmvxa_subclass_mgmt_error2.jpg

 

 

Edited by Settyness

Share this post


Link to post
Share on other sites

@ Pikalyze - thanks! :-) I thought I did a pretty decent job, myself. *grins*

 

@ Composer: Aww, you found the first bugs... ok, no problem. Let me start a new game and see if I can trigger the error, although I have a sneaking suspicion that it's the @sub_level. I've been modifying it in mine, just haven't updated the script on here yet (still tweaking the VA add-on script, and not sure what functions I'll have to add or whatnot).

Edit:

Error 1: After starting a new game in a new project with the updated version of this script (posted above, by the way), I think I've isolated the problem. Or at least, figured out that the ordering of the scripts do matter, even if I'm not sure what's causing it. If I have VA below this script, it works perfectly - no errors. However, if VA is above this script, then for some reason it gives the error. It has something to do with this line:


 





  text = "" + sprintf(YEA::VICTORY_AFTERMATH::HEADER_TEXT, actor.name)

 


I think what's causing it is that VA is overwriting the original display_exp, while the subclass manager is aliasing it. I'm a bit (read: very) brain-dead from trying to chase down why the subclass exp gauge isn't going up in the VA add-on I'm writing (I didn't even catch that putting 'return if actor.nil?' right before that line canceled out of the whole exp gauge screen), so until I clear my head, my solution is to advise you to put VA below the subclass manager. Crappy solution, I know... darn ordering problems!  :huh: I should be able to fix it up by tomorrow morning, though. Maybe. Hopefully.

 

Edit 2: Okay, I think I've ferreted out the problem (here, at least). I was going unless crazy... in line 115, the one that reads: 

 

battlemanager_display_exp_jp_yea unless $imported["YEA-VictoryAftermath"]

Yeah, that unless doesn't need to be there. Apparently I was thinking it was something else. o.0


Error #2: I think copying over the updated version of the subclass manager will fix it - I wasn't able to recreate it after I copied in the updated version. I had to give @sub_level an initial value of 1, so it wouldn't return nil for those who didn't have subclasses (d'oh! haha). If it still throws the error, let me know and I'll do some more digging. :-)

And nod, I thought of that idea as well, but it could so rapidly spiral out of control, haha. "Oh, adding a second subclass? Neat! I wonder if I could add a third one, as well..." I'm still debating whether or not it would be a good idea to add that option, since just adding one subclass required so much additional code. Especially since VA overwrites the gain_exp function (hence why I called change_sub_exp from within change_exp and not gain_exp), although I could probably fix that when I release the VA patch to display subclass JP/EXP/Stat (? on Stat) gain. For now, I'm putting it on the 'huh, that'd be a neat idea' pile, haha. Edit: Nope, not gonna add an option for secondary subclasses, haha. At least, not in this script. And if I do, it'll be something along the lines of an astrology sign or such that provides permanent stat modification and can't be removed.

Edited by Ebonflame

Share this post


Link to post
Share on other sites

So my first test with the improved script, I placed it as I normally would in my skill/JP/class scripts. It functioned much better. With no subclass equipped, I had no problems whatsoever. With a subclass equipped, I got further than before. My character's face sprites showed up in Victory Aftermath, EXP ticked, and JP accumulated as normal. When I confirmed, I got this error where level up or spoils would show:


rmvxa_subclass_mgmt_error3.jpg



It was working much better. I could roll without a subclass and Victory Aftermath started to process. After that test, I decided to put Subclass Management on the top of my materials. This was above Victory Aftermath and, in theory, this should've worked better; however it did not. The game crashed instantly with the following error:



rmvxa_subclass_mgmt_error4.jpg



I would attribute this to the fact that Subclass Management was inserted before my skill/JP/class scripts. This, of course, would be another bug we may have been unaware of. Sorry, I'm not trying to player hate. I like this script and I want it to work. If I was better at Ruby, I'd help you, but this is the best I can do.

Share this post


Link to post
Share on other sites

make sure do some checking if the @subclass_id has not defined yet and @subclass_id = 0.

do whatever only if @subclass_id && @subclass_id == 0 for some part that using @subclass_id variable.

also do some checking for the returned value of that method that used above variable. if they return nil. do some escaping protocol :D.

 

your script is written based on my script which i wrote when i start scripting. it's messy and i do so many turn around way at that time.

Share this post


Link to post
Share on other sites

@ Composer - *ponders* I've tried to replicate the error, man... I really have, haha. I just can't seem to make it bug out. And the place it's freaking out doesn't make sense; line 252 should be after it goes through sub_id to see if the person even has a subclass, and after it checks the person's self.exp (which I was having problems with at one point, but seemed to be fixed when I rewrote the script to mimic the main leveling system). The new information in that line is sub_exp (which should return zero if your subclass is 0/nil, else whatever the experience is with your subclass), EBON::SUB_EXP_RATE... and possibly the final_exp_rate. 

 

Just to make sure, line 252 in your subclass manager should be:





  goal_exp = sub_exp + (goal_exp * EBON::SUB_EXP_RATE * final_exp_rate).to_i

 

 

Is this correct (is that the right line of code)? If not, could I get a copypasta of the subclass manager script you're using? I also requested this a little below.

 

Edit: Also, nod, the subclass script has to be below the class system script because it aliases init_subclass. Theoretically, it should work above the JP manager script since it only aliases existing core functions and not anything the JP manager itself created, though. (init_subclass is a definition - I sometimes refer to them as functions since the first scripting language I learned was LSL - within the class system script, so when it tries to alias it, the system says 'wtf are you doing? This function doesn't exist yet, how can we alias it?' if the subclass manager is above the class system script)

 

Also, could I get the following things from you:

 

First: have you started a new game, or is this from an existing game? How many members are in your party?

 

Second: 

- The order you normally place your scripts in (JP Manager and VA shouldn't matter in placement, but maybe...) for example, JP Manager, Victory Aftermath, Class Script, Unlock level, Specifics, Subclass Manager

- The copypasta version of the class script(s) (including subclass manager), JP Manager, and VA you're using via spoiler (don't worry about the weird "I'm not going to indent anything or insert blank lines anywhere!" bug the code function seems to have on here, I'll fix it) - maybe something got messed up in the copy/paste, or you have custom functions/etcetera.

 

Third: if questions one and two fail to yield any insights for me, maybe it has something to do with the order you're trying to equip your subclass and fight things. Are you fighting stuff without a subclass, then equipping a subclass to fight things, or vice-versa, or some other way? 

 

There's probably something I'm failing to discern that's related to one of these things, and I'm also failing to hit it in my test runs. We'll get it sorted, no worries! I'm actually really glad that you're test-running this for me and giving me feedback so I can fix the problem, thanks. :-) The more testers, the merrier! The snapshots you're posting are also good, just unfortunately not quite detailed enough. :-(

 

@ Estriole: Nod, I have sub_id checking to see if they have a subclass and returning 0 (as opposed to nil) if they don't. The code in line 252 should only run if they have a subclass equipped, which seems to fit with what Composer's saying. It's escaping correctly; I'm just not sure how or why it's messing up at when it runs.

Edited by Ebonflame

Share this post


Link to post
Share on other sites

The Subclass Management snippet is unedited from the one posted in the OP.

 

For my tests, they were all new games started in my current project which utilizes mostly Yanfly scripts. I would say my scriptbase is a typical one that this add-on would likely get plopped into. For all tests there have been one character in my party. The order of the relevant scripts in my project are as follows:

 

rmvxa_script_order.gif

 

 

The relevant scripts (that have been edited past default settings) are as follows:

 

 

Victory Aftermath

 

 

#==============================================================================
# 
# â–¼ Yanfly Engine Ace - Victory Aftermath v1.03
# -- Last Updated: 2012.01.07

# -- Level: Easy, Normal, Hard
# -- Requires: n/a
# 
#==============================================================================

$imported = {} if $imported.nil?
$imported["YEA-VictoryAftermath"] = true

#==============================================================================
# â–¼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 2012.01.07 - Compatibility Update: JP Manager
# 2012.01.01 - Bug Fixed: Quote tags were mislabeled.
# 2011.12.26 - Compatibility Update: Command Autobattle
# 2011.12.16 - Started Script and Finished.
# 
#==============================================================================
# â–¼ Introduction
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# At the end of each battle, RPG Maker VX Ace by default shows text saying that
# the party has gained so-and-so EXP while this person leveled up and your
# party happened to find these drops. This script changes that text into
# something more visual for your players to see. Active battle members will be
# seen gaining EXP, any kind of level up changes, and a list of the items
# obtained through drops.
# 
#==============================================================================
# â–¼ 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.
# 
# -----------------------------------------------------------------------------
# Actor Notetags - These notetags go in the actors notebox in the database.
# -----------------------------------------------------------------------------
# <win quotes>
#  string
#  string
# </win quotes>
# Sets the win quote for the actor. The strings are continuous and can use
# text codes. Use \n for a line break. Type in what you want the actor to say
# for the particular win quote. Use [New Quote] in between the two tags to
# start up a new quote.
# 
# <level quotes>
#  string
#  string
# </level quotes>
# Sets the level up quote for the actor. The strings are continuous and can use
# text codes. Use \n for a line break. Type in what you want the actor to say
# for the particular win quote. Use [New Quote] in between the two tags to
# start up a new quote.
# 
# <drops quotes>
#  string
#  string
# </drops quotes>
# Sets the drops quote for the actor. The strings are continuous and can use
# text codes. Use \n for a line break. Type in what you want the actor to say
# for the particular win quote. Use [New Quote] in between the two tags to
# start up a new quote.
# 
# -----------------------------------------------------------------------------
# Class Notetags - These notetags go in the class notebox in the database.
# -----------------------------------------------------------------------------
# <win quotes>
#  string
#  string
# </win quotes>
# Sets the win quote for the class. The strings are continuous and can use
# text codes. Use \n for a line break. Type in what you want the actor to say
# for the particular win quote. Use [New Quote] in between the two tags to
# start up a new quote.
# 
# <level quotes>
#  string
#  string
# </level quotes>
# Sets the level up quote for the class. The strings are continuous and can use
# text codes. Use \n for a line break. Type in what you want the actor to say
# for the particular win quote. Use [New Quote] in between the two tags to
# start up a new quote.
# 
# <drops quotes>
#  string
#  string
# </drops quotes>
# Sets the drops quote for the class. The strings are continuous and can use
# text codes. Use \n for a line break. Type in what you want the actor to say
# for the particular win quote. Use [New Quote] in between the two tags to
# start up a new quote.
# 
#==============================================================================
# â–¼ Compatibility
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# This script is made strictly for RPG Maker VX Ace. It is highly unlikely that
# it will run with RPG Maker VX without adjusting.
# 
#==============================================================================

module YEA
  module VICTORY_AFTERMATH
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - General Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # These are various settings that are used throughout the Victory Aftermath
    # portion of a battle. Adjust them as you see fit.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    VICTORY_BGM  = RPG::BGM.new("Spoils", 100, 100)    # Victory BGM
    VICTORY_TICK = RPG::SE.new("Switch1", 100, 150)  # EXP ticking SFX
    LEVEL_SOUND  = RPG::SE.new("Applause2", 80, 150)         # Level Up SFX
    SKILLS_TEXT  = "New Technique"                        # New skills text title.
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Important Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # These are some important settings so please set them up properly. This
    # section includes a switch that allows you to skip the victory aftermath
    # phase (for those back to back battles and making them seamless) and it
    # also allows you to declare a common event to run after each battle. If
    # you do not wish to use either of these features, set them to 0. The
    # common event will run regardless of win or escape.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    SKIP_AFTERMATH_SWITCH  = 0  # If switch on, skip aftermath. 0 to disable.
    SKIP_MUSIC_SWITCH      = 0  # If switch on, skip music. 0 to disable.
    AFTERMATH_COMMON_EVENT = 0  # Runs common event after battle. 0 to disable.
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Top Text Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # Here, you can adjust the various text that appears in the window that
    # appears at the top of the screen.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    TOP_TEAM         = "%s's party"           # Team name used.
    TOP_VICTORY_TEXT = "%s is victorious!"   # Text used to display victory.
    TOP_LEVEL_UP     = "%s has leveled up!"  # Text used to display level up.
    TOP_SPOILS       = "Spoils"     # Text used for spoils.
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - EXP Gauge Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # Adjust how the EXP Gauge appears for the Victory Aftermath here. This
    # includes the text display, the font size, the colour of the gauges, and
    # more. Adjust it all here.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    VICTORY_EXP  = "+%s XP"      # Text used to display EXP.
    EXP_PERCENT  = "%1.2f%%"     # The way EXP percentage will be displayed.
    LEVELUP_TEXT = "LEVEL UP!"   # Text to replace percentage when leveled.
    MAX_LVL_TEXT = "MAX LEVEL"   # Text to replace percentage when max level.
    FONTSIZE_EXP = 12            # Font size used for EXP.
    EXP_TICKS    = 10            # Ticks to full EXP
    EXP_GAUGE1   = 18            # "Window" skin text colour for gauge.
    EXP_GAUGE2   = 18            # "Window" skin text colour for gauge.
    LEVEL_GAUGE1 = 18            # "Window" skin text colour for leveling.
    LEVEL_GAUGE2 = 18            # "Window" skin text colour for leveling.
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Victory Messages -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # In the Victory Aftermath, actors can say unique things. This is the pool
    # of quotes used for actors without any custom victory quotes. Note that
    # actors with custom quotes will take priority over classes with custom
    # quotes, which will take priority over these default quotes. Use \n for
    # a line break in the quotes.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    HEADER_TEXT = "\e>\\n<%s>\e<"  # Always at start of messages.
    FOOTER_TEXT = ""                        # Always at end of messages.
    
    # Win Quotes are what the actors say when a battle is won.
    VICTORY_QUOTES ={
    # :type   => Quotes
      #------------------------------------------------------------------------
      :win    => [ # Occurs as initial victory quote.
                   '"We won! What an exciting fight!"',
                   '"I didn\'t even break a sweat."',
                   '"That wasn\'t so tough."',
                   '"Let\'s fight something harder!"',
                 ],# Do not remove this.
      #------------------------------------------------------------------------
      :level  => [ # Occurs as initial victory quote.
                   '"Yes! Level up!"',
                   '"I\'ve gotten stronger!"',
                   '"Try to keep up with me!"',
                   '"I\'ve grown again!"',
                 ],# Do not remove this.
      #------------------------------------------------------------------------
      :drops  => [ # Occurs as initial victory quote.
                   '"I\'ll be taking these."',
                   '"To the victor goes the spoils."',
                   '"The enemies dropped something!"',
                   '"Hey, what\'s this?"',
                 ],# Do not remove this.
      #------------------------------------------------------------------------
    } # Do not remove this.
    
  end # VICTORY_AFTERMATH
end # YEA

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

module YEA
  module REGEXP
  module BASEITEM
    
    NEW_QUOTE = /\[(?:NEW_QUOTE|new quote)\]/i
    
    WIN_QUOTE_ON    = /<(?:WIN_QUOTES|win quote|win quotes)>/i
    WIN_QUOTE_OFF   = /<\/(?:WIN_QUOTES|win quote|win quotes)>/i
    LEVEL_QUOTE_ON  = /<(?:LEVEL_QUOTES|level quote|level quotes)>/i
    LEVEL_QUOTE_OFF = /<\/(?:LEVEL_QUOTES|level quote|level quotes)>/i
    DROPS_QUOTE_ON  = /<(?:DROPS_QUOTES|drops quote|drops quotes)>/i
    DROPS_QUOTE_OFF = /<\/(?:DROPS_QUOTES|drops quote|drops quotes)>/i
    
  end # BASEITEM
  end # REGEXP
end # YEA

#==============================================================================
# â–  Switch
#==============================================================================

module Switch
  
  #--------------------------------------------------------------------------
  # self.skip_aftermath
  #--------------------------------------------------------------------------
  def self.skip_aftermath
    return false if YEA::VICTORY_AFTERMATH::SKIP_AFTERMATH_SWITCH <= 0
    return $game_switches[YEA::VICTORY_AFTERMATH::SKIP_AFTERMATH_SWITCH]
  end
  
  #--------------------------------------------------------------------------
  # self.skip_aftermath_music
  #--------------------------------------------------------------------------
  def self.skip_aftermath_music
    return false if YEA::VICTORY_AFTERMATH::SKIP_MUSIC_SWITCH <=0
    return $game_switches[YEA::VICTORY_AFTERMATH::SKIP_MUSIC_SWITCH]
  end
    
end # Switch

#==============================================================================
# â–  Numeric
#==============================================================================

class Numeric
  
  #--------------------------------------------------------------------------
  # new method: group_digits
  #--------------------------------------------------------------------------
  unless $imported["YEA-CoreEngine"]
  def group; return self.to_s; end
  end # $imported["YEA-CoreEngine"]
    
end # Numeric

#==============================================================================
# â–  DataManager
#==============================================================================

module DataManager
  
  #--------------------------------------------------------------------------
  # alias method: load_database
  #--------------------------------------------------------------------------
  class <<self; alias load_database_va load_database; end
  def self.load_database
    load_database_va
    load_notetags_va
  end
  
  #--------------------------------------------------------------------------
  # new method: load_notetags_va
  #--------------------------------------------------------------------------
  def self.load_notetags_va
    groups = [$data_actors, $data_classes]
    for group in groups
      for obj in group
        next if obj.nil?
        obj.load_notetags_va
      end
    end
  end
  
end # DataManager

#==============================================================================
# â–  RPG::BaseItem
#==============================================================================

class RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :win_quotes
  attr_accessor :level_quotes
  attr_accessor :drops_quotes
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_va
  #--------------------------------------------------------------------------
  def load_notetags_va
    @win_quotes = [""]
    @level_quotes = [""]
    @drops_quotes = [""]
    @victory_quote_type = nil
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::BASEITEM::WIN_QUOTE_ON
        @victory_quote_type = :win_quote
      when YEA::REGEXP::BASEITEM::WIN_QUOTE_OFF
        @victory_quote_type = nil
      when YEA::REGEXP::BASEITEM::LEVEL_QUOTE_ON
        @victory_quote_type = :level_quote
      when YEA::REGEXP::BASEITEM::LEVEL_QUOTE_OFF
        @victory_quote_type = nil
      when YEA::REGEXP::BASEITEM::DROPS_QUOTE_ON
        @victory_quote_type = :drops_quote
      when YEA::REGEXP::BASEITEM::DROPS_QUOTE_OFF
        @victory_quote_type = nil
      #---
      when YEA::REGEXP::BASEITEM::NEW_QUOTE
        case @victory_quote_type
        when nil; next
        when :win_quote;   @win_quotes.push("")
        when :level_quote; @level_quotes.push("")
        when :drops_quote; @drops_quotes.push("")
        end
      #---
      else
        case @victory_quote_type
        when nil; next
        when :win_quote;   @win_quotes[@win_quotes.size-1] += line.to_s
        when :level_quote; @level_quotes[@level_quotes.size-1] += line.to_s
        when :drops_quote; @drops_quotes[@drops_quotes.size-1] += line.to_s
        end
      end
    } # self.note.split
    #---
    return unless self.is_a?(RPG::Class)
    quotes = YEA::VICTORY_AFTERMATH::VICTORY_QUOTES
    @win_quotes = quotes[:win].clone if @win_quotes == [""]
    @level_quotes = quotes[:level].clone if @level_quotes == [""]
    @drops_quotes = quotes[:drops].clone if @drops_quotes == [""]
  end
  
end # RPG::BaseItem

#==============================================================================
# â–  BattleManager
#==============================================================================

module BattleManager
  
  #--------------------------------------------------------------------------
  # overwrite method: self.process_victory
  #--------------------------------------------------------------------------
  def self.process_victory
    if $imported["YEA-CommandAutobattle"]
      SceneManager.scene.close_disable_autobattle_window
    end
    return skip_aftermath if Switch.skip_aftermath
    play_battle_end_me
    gain_jp if $imported["YEA-JPManager"]
    display_exp
    gain_exp
    gain_gold
    gain_drop_items
    close_windows
    SceneManager.return
    replay_bgm_and_bgs
    battle_end(0)
    return true
  end
  
  #--------------------------------------------------------------------------
  # new method: self.skip_aftermath
  #--------------------------------------------------------------------------
  def self.skip_aftermath
    $game_party.all_members.each do |actor|
      actor.gain_exp($game_troop.exp_total)
    end
    $game_party.gain_gold($game_troop.gold_total)
    $game_troop.make_drop_items.each do |item|
      $game_party.gain_item(item, 1)
    end
    close_windows
    SceneManager.return
    replay_bgm_and_bgs
    battle_end(0)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: self.play_battle_end_me
  #--------------------------------------------------------------------------
  def self.play_battle_end_me
    return if Switch.skip_aftermath_music
    $game_system.battle_end_me.play
    YEA::VICTORY_AFTERMATH::VICTORY_BGM.play
  end
  
  #--------------------------------------------------------------------------
  # new method: self.set_victory_text
  #--------------------------------------------------------------------------
  def self.set_victory_text(actor, type)
    text = "" + sprintf(YEA::VICTORY_AFTERMATH::HEADER_TEXT, actor.name)
    text += actor.victory_quotes(type)[rand(actor.victory_quotes(type).size)]
    text += YEA::VICTORY_AFTERMATH::FOOTER_TEXT
    $game_message.face_name = actor.face_name
    $game_message.face_index = actor.face_index
    $game_message.add(text)
    wait_for_message
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: self.display_exp
  #--------------------------------------------------------------------------
  def self.display_exp
    SceneManager.scene.show_victory_display_exp
    actor = $game_party.random_target
    @victory_actor = actor
    set_victory_text(@victory_actor, :win)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: self.gain_exp
  #--------------------------------------------------------------------------
  def self.gain_exp
    $game_party.all_members.each do |actor|
      temp_actor = Marshal.load(Marshal.dump(actor))
      actor.gain_exp($game_troop.exp_total)
      next if actor.level == temp_actor.level
      SceneManager.scene.show_victory_level_up(actor, temp_actor)
      set_victory_text(actor, :level)
      wait_for_message
    end
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: self.gain_gold
  #--------------------------------------------------------------------------
  def self.gain_gold
    $game_party.gain_gold($game_troop.gold_total)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: self.gain_drop_items
  #--------------------------------------------------------------------------
  def self.gain_drop_items
    drops = []
    $game_troop.make_drop_items.each do |item|
      $game_party.gain_item(item, 1)
      drops.push(item)
    end
    SceneManager.scene.show_victory_spoils($game_troop.gold_total, drops)
    set_victory_text(@victory_actor, :drops)
    wait_for_message
  end
  
  #--------------------------------------------------------------------------
  # new method: self.close_windows
  #--------------------------------------------------------------------------
  def self.close_windows
    SceneManager.scene.close_victory_windows
  end
  
  #--------------------------------------------------------------------------
  # alias method: load_database
  #--------------------------------------------------------------------------
  class <<self; alias battle_end_va battle_end; end
  def self.battle_end(result)
    battle_end_va(result)
    return if result == 2
    return if YEA::VICTORY_AFTERMATH::AFTERMATH_COMMON_EVENT <= 0
    event_id = YEA::VICTORY_AFTERMATH::AFTERMATH_COMMON_EVENT
    $game_temp.reserve_common_event(event_id)
  end
  
end # BattleManager

#==============================================================================
# â–  Game_Actor
#==============================================================================

class Game_Actor < Game_Battler
  
  #--------------------------------------------------------------------------
  # overwrite method: gain_exp
  #--------------------------------------------------------------------------
  def gain_exp(exp)
    enabled = !SceneManager.scene_is?(Scene_Battle)
    change_exp(self.exp + (exp * final_exp_rate).to_i, enabled)
  end
  
  #--------------------------------------------------------------------------
  # new method: victory_quotes
  #--------------------------------------------------------------------------
  def victory_quotes(type)
    case type
    when :win
      return self.actor.win_quotes if self.actor.win_quotes != [""]
      return self.class.win_quotes
    when :level
      return self.actor.level_quotes if self.actor.level_quotes != [""]
      return self.class.level_quotes
    when :drops
      return self.actor.drops_quotes if self.actor.drops_quotes != [""]
      return self.class.drops_quotes
    else
      return ["NOTEXT"]
    end
  end
  
end # Game_Actor

#==============================================================================
# â–  Window_VictoryTitle
#==============================================================================

class Window_VictoryTitle < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize
    super(0, 0, Graphics.width, fitting_height(1))
    self.z = 200
    self.openness = 0
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh(message = "")
    contents.clear
    draw_text(0, 0, contents.width, line_height, message, 1)
  end
  
end # Window_VictoryTitle

#==============================================================================
# â–  Window_VictoryEXP_Back
#==============================================================================

class Window_VictoryEXP_Back < Window_Selectable
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize
    super(0, fitting_height(1), Graphics.width, window_height)
    self.z = 200
    self.openness = 0
  end
  
  #--------------------------------------------------------------------------
  # window_height
  #--------------------------------------------------------------------------
  def window_height
    return Graphics.height - fitting_height(4) - fitting_height(1)
  end
  
  #--------------------------------------------------------------------------
  # col_max
  #--------------------------------------------------------------------------
  def col_max; return item_max; end
  
  #--------------------------------------------------------------------------
  # spacing
  #--------------------------------------------------------------------------
  def spacing; return 8; end
  
  #--------------------------------------------------------------------------
  # item_max
  #--------------------------------------------------------------------------
  def item_max; return $game_party.battle_members.size; end
  
  #--------------------------------------------------------------------------
  # open
  #--------------------------------------------------------------------------
  def open
    @exp_total = $game_troop.exp_total
    super
  end
  
  #--------------------------------------------------------------------------
  # item_rect
  #--------------------------------------------------------------------------
  def item_rect(index)
    rect = Rect.new
    rect.width = item_width
    rect.height = contents.height
    rect.x = index % col_max * (item_width + spacing)
    rect.y = index / col_max * item_height
    return rect
  end
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(index)
    actor = $game_party.battle_members[index]
    return if actor.nil?
    rect = item_rect(index)
    reset_font_settings
    draw_actor_name(actor, rect)
    draw_exp_gain(actor, rect)
    draw_jp_gain(actor, rect)
    draw_actor_face(actor, rect)
  end
  
  #--------------------------------------------------------------------------
  # draw_actor_name
  #--------------------------------------------------------------------------
  def draw_actor_name(actor, rect)
    name = actor.name
    draw_text(rect.x, rect.y+line_height, rect.width, line_height, name, 1)
  end
  
  #--------------------------------------------------------------------------
  # draw_actor_face
  #--------------------------------------------------------------------------
  def draw_actor_face(actor, rect)
    face_name = actor.face_name
    face_index = actor.face_index
    bitmap = Cache.face(face_name)
    rw = [rect.width, 96].min
    face_rect = Rect.new(face_index % 4 * 96, face_index / 4 * 96, rw, 96)
    rx = (rect.width - rw) / 2 + rect.x
    contents.blt(rx, rect.y + line_height * 2, bitmap, face_rect, 255)
  end
  
  #--------------------------------------------------------------------------
  # draw_exp_gain
  #--------------------------------------------------------------------------
  def draw_exp_gain(actor, rect)
    dw = rect.width - (rect.width - [rect.width, 96].min) / 2
    dy = rect.y + line_height * 3 + 96
    fmt = YEA::VICTORY_AFTERMATH::VICTORY_EXP
    text = sprintf(fmt, actor_exp_gain(actor).group)
    contents.font.size = YEA::VICTORY_AFTERMATH::FONTSIZE_EXP
    change_color(power_up_color)
    draw_text(rect.x, dy, dw, line_height, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # actor_exp_gain
  #--------------------------------------------------------------------------
  def actor_exp_gain(actor)
    n = @exp_total * actor.final_exp_rate
    return n.to_i
  end
  
  #--------------------------------------------------------------------------
  # draw_jp_gain
  #--------------------------------------------------------------------------
  def draw_jp_gain(actor, rect)
    return unless $imported["YEA-JPManager"]
    dw = rect.width - (rect.width - [rect.width, 96].min) / 2
    dy = rect.y + line_height * 4 + 96
    fmt = YEA::JP::VICTORY_AFTERMATH
    text = sprintf(fmt, actor_jp_gain(actor).group, Vocab::jp)
    contents.font.size = YEA::VICTORY_AFTERMATH::FONTSIZE_EXP
    change_color(power_up_color)
    draw_text(rect.x, dy, dw, line_height, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # actor_jp_gain
  #--------------------------------------------------------------------------
  def actor_jp_gain(actor)
    n = actor.battle_jp_earned
    if actor.exp + actor_exp_gain(actor) > actor.exp_for_level(actor.level + 1)
      n += YEA::JP::LEVEL_UP unless actor.max_level?
    end
    return n
  end
  
end # Window_VictoryEXP_Back

#==============================================================================
# â–  Window_VictoryEXP_Front
#==============================================================================

class Window_VictoryEXP_Front < Window_VictoryEXP_Back
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize
    super
    self.back_opacity = 0
    @ticks = 0
    @counter = 30
    contents.font.size = YEA::VICTORY_AFTERMATH::FONTSIZE_EXP
  end
  
  #--------------------------------------------------------------------------
  # update
  #--------------------------------------------------------------------------
  def update
    super
    update_tick
  end
  
  #--------------------------------------------------------------------------
  # update_tick
  #--------------------------------------------------------------------------
  def update_tick
    return unless self.openness >= 255
    return unless self.visible
    return if complete_ticks?
    @counter -= 1
    return unless @counter <= 0
    return if @ticks >= YEA::VICTORY_AFTERMATH::EXP_TICKS
    YEA::VICTORY_AFTERMATH::VICTORY_TICK.play
    @counter = 4
    @ticks += 1
    refresh
  end
  
  #--------------------------------------------------------------------------
  # complete_ticks?
  #--------------------------------------------------------------------------
  def complete_ticks?
    for actor in $game_party.battle_members
      total_ticks = YEA::VICTORY_AFTERMATH::EXP_TICKS
      bonus_exp = actor_exp_gain(actor) * @ticks / total_ticks
      now_exp = actor.exp - actor.current_level_exp + bonus_exp
      next_exp = actor.next_level_exp - actor.current_level_exp
      rate = now_exp * 1.0 / next_exp
      return false if rate < 1.0
    end
    return true
  end
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(index)
    actor = $game_party.battle_members[index]
    return if actor.nil?
    rect = item_rect(index)
    draw_actor_exp(actor, rect)
  end
  
  #--------------------------------------------------------------------------
  # exp_gauge1
  #--------------------------------------------------------------------------
  def exp_gauge1; return text_color(YEA::VICTORY_AFTERMATH::EXP_GAUGE1); end
  
  #--------------------------------------------------------------------------
  # exp_gauge2
  #--------------------------------------------------------------------------
  def exp_gauge2; return text_color(YEA::VICTORY_AFTERMATH::EXP_GAUGE2); end
  
  #--------------------------------------------------------------------------
  # lvl_gauge1
  #--------------------------------------------------------------------------
  def lvl_gauge1; return text_color(YEA::VICTORY_AFTERMATH::LEVEL_GAUGE1); end
  
  #--------------------------------------------------------------------------
  # lvl_gauge2
  #--------------------------------------------------------------------------
  def lvl_gauge2; return text_color(YEA::VICTORY_AFTERMATH::LEVEL_GAUGE2); end
  
  #--------------------------------------------------------------------------
  # draw_actor_exp
  #--------------------------------------------------------------------------
  def draw_actor_exp(actor, rect)
    if actor.max_level?
      draw_exp_gauge(actor, rect, 1.0)
      return
    end
    total_ticks = YEA::VICTORY_AFTERMATH::EXP_TICKS
    bonus_exp = actor_exp_gain(actor) * @ticks / total_ticks
    now_exp = actor.exp - actor.current_level_exp + bonus_exp
    next_exp = actor.next_level_exp - actor.current_level_exp
    rate = now_exp * 1.0 / next_exp
    draw_exp_gauge(actor, rect, rate)
  end
  
  #--------------------------------------------------------------------------
  # draw_exp_gauge
  #--------------------------------------------------------------------------
  def draw_exp_gauge(actor, rect, rate)
    rate = [[rate, 1.0].min, 0.0].max
    dx = (rect.width - [rect.width, 96].min) / 2 + rect.x
    dy = rect.y + line_height * 2 + 96
    dw = [rect.width, 96].min
    colour1 = rate >= 1.0 ? lvl_gauge1 : exp_gauge1
    colour2 = rate >= 1.0 ? lvl_gauge2 : exp_gauge2
    draw_gauge(dx, dy, dw, rate, colour1, colour2)
    fmt = YEA::VICTORY_AFTERMATH::EXP_PERCENT
    text = sprintf(fmt, [rate * 100, 100.00].min)
    if [rate * 100, 100.00].min == 100.00
      text = YEA::VICTORY_AFTERMATH::LEVELUP_TEXT
      text = YEA::VICTORY_AFTERMATH::MAX_LVL_TEXT if actor.max_level?
    end
    draw_text(dx, dy, dw, line_height, text, 1)
  end
  
end # Window_VictoryEXP_Front

#==============================================================================
# â–  Window_VictoryLevelUp
#==============================================================================

class Window_VictoryLevelUp < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize
    super(0, fitting_height(1), Graphics.width, window_height)
    self.z = 200
    hide
  end
  
  #--------------------------------------------------------------------------
  # window_height
  #--------------------------------------------------------------------------
  def window_height
    return Graphics.height - fitting_height(4) - fitting_height(1)
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh(actor, temp_actor)
    contents.clear
    reset_font_settings
    YEA::VICTORY_AFTERMATH::LEVEL_SOUND.play
    draw_actor_changes(actor, temp_actor)
  end
  
  #--------------------------------------------------------------------------
  # draw_actor_changes
  #--------------------------------------------------------------------------
  def draw_actor_changes(actor, temp_actor)
    dx = contents.width / 16
    draw_actor_image(actor, temp_actor, dx)
    draw_param_names(actor, dx)
    draw_former_stats(temp_actor)
    draw_arrows
    draw_newer_stats(actor, temp_actor)
    draw_new_skills(actor, temp_actor)
  end
  
  #--------------------------------------------------------------------------
  # draw_actor_image
  #--------------------------------------------------------------------------
  def draw_actor_image(actor, temp_actor, dx)
    draw_text(dx, line_height, 96, line_height, actor.name, 1)
    draw_actor_face(actor, dx, line_height * 2)
    exp = actor.exp - temp_actor.exp
    text = sprintf(YEA::VICTORY_AFTERMATH::VICTORY_EXP, exp.group)
    change_color(power_up_color)
    contents.font.size = YEA::VICTORY_AFTERMATH::FONTSIZE_EXP
    draw_text(0, line_height * 2 + 96, dx + 96, line_height, text, 2)
    reset_font_settings
  end
  
  #--------------------------------------------------------------------------
  # draw_param_names
  #--------------------------------------------------------------------------
  def draw_param_names(actor, dx)
    dx += 108
    change_color(system_color)
    text = Vocab.level
    draw_text(dx, 0, contents.width - dx, line_height, text)
    dy = 0
    for i in 0...8
      dy += line_height
      text = Vocab.param(i)
      draw_text(dx, dy, contents.width - dx, line_height, text)
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_former_stats
  #--------------------------------------------------------------------------
  def draw_former_stats(actor)
    dw = contents.width / 2 - 12
    dy = 0
    change_color(normal_color)
    draw_text(0, dy, dw, line_height, actor.level.group, 2)
    for i in 0...8
      dy += line_height
      draw_text(0, dy, dw, line_height, actor.param(i).group, 2)
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_arrows
  #--------------------------------------------------------------------------
  def draw_arrows
    dx = contents.width / 2 - 12
    dy = 0
    change_color(system_color)
    for i in 0..8
      draw_text(dx, dy, 24, line_height, "→", 1)
      dy += line_height
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_newer_stats
  #--------------------------------------------------------------------------
  def draw_newer_stats(actor, temp_actor)
    dx = contents.width / 2 + 12
    dw = contents.width - dx
    dy = 0
    change_color(param_change_color(actor.level - temp_actor.level))
    draw_text(dx, dy, dw, line_height, actor.level.group, 0)
    for i in 0...8
      dy += line_height
      change_color(param_change_color(actor.param(i) - temp_actor.param(i)))
      draw_text(dx, dy, dw, line_height, actor.param(i).group, 0)
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_new_skills
  #--------------------------------------------------------------------------
  def draw_new_skills(actor, temp_actor)
    return if temp_actor.skills.size == actor.skills.size
    dw = 172 + 24
    dx = contents.width - dw
    change_color(system_color)
    text = YEA::VICTORY_AFTERMATH::SKILLS_TEXT
    draw_text(dx, 0, dw, line_height, text, 0)
  end
  
end # Window_VictoryLevelUp

#==============================================================================
# â–  Window_VictorySkills
#==============================================================================

class Window_VictorySkills < Window_Selectable
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize
    dy = fitting_height(1) + 24
    dw = 172 + 24 + 24
    dh = Graphics.height - fitting_height(4) - fitting_height(1) - 24
    super(Graphics.width - dw, dy, dw, dh)
    self.opacity = 0
    self.z = 200
    hide
  end
  
  #--------------------------------------------------------------------------
  # item_max
  #--------------------------------------------------------------------------
  def item_max; return @data.nil? ? 0 : @data.size; end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh(actor, temp_actor)
    contents.clear
    if actor.skills.size == temp_actor.skills.size
      unselect
      @data = []
      create_contents
      return
    end
    @data = actor.skills - temp_actor.skills
    if @data.size > 8
      select(0)
      activate
    else
      unselect
      deactivate
    end
    create_contents
    draw_all_items
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def draw_item(index)
    rect = item_rect(index)
    skill = @data[index]
    return if skill.nil?
    rect.width -= 4
    draw_item_name(skill, rect.x, rect.y, true)
  end
  
end # Window_VictorySkills

#==============================================================================
# â–  Window_VictorySpoils
#==============================================================================

class Window_VictorySpoils < Window_ItemList
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize
    super(0, fitting_height(1), Graphics.width, window_height)
    self.z = 200
    hide
  end
  
  #--------------------------------------------------------------------------
  # window_height
  #--------------------------------------------------------------------------
  def window_height
    return Graphics.height - fitting_height(4) - fitting_height(1)
  end
  
  #--------------------------------------------------------------------------
  # spacing
  #--------------------------------------------------------------------------
  def spacing; return 32; end
  
  #--------------------------------------------------------------------------
  # make
  #--------------------------------------------------------------------------
  def make(gold, drops)
    @gold = gold
    @drops = drops
    refresh
    select(0)
    activate
  end
  
  #--------------------------------------------------------------------------
  # make_item_list
  #--------------------------------------------------------------------------
  def make_item_list
    @data = [nil]
    items = {}
    weapons = {}
    armours = {}
    @goods = {}
    for item in @drops
      case item
      when RPG::Item
        items[item] = 0 if items[item].nil?
        items[item] += 1
      when RPG::Weapon
        weapons[item] = 0 if weapons[item].nil?
        weapons[item] += 1
      when RPG::Armor
        armours[item] = 0 if armours[item].nil?
        armours[item] += 1
      end
    end
    items = items.sort { |a,b| a[0].id <=> b[0].id }
    weapons = weapons.sort { |a,b| a[0].id <=> b[0].id }
    armours = armours.sort { |a,b| a[0].id <=> b[0].id }
    for key in items; @goods[key[0]] = key[1]; @data.push(key[0]); end
    for key in weapons; @goods[key[0]] = key[1]; @data.push(key[0]); end
    for key in armours; @goods[key[0]] = key[1]; @data.push(key[0]); end
  end
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(index)
    item = @data[index]
    rect = item_rect(index)
    reset_font_settings
    if item.nil?
      draw_gold(rect)
      return
    end
    rect.width -= 4
    draw_item_name(item, rect.x, rect.y, true, rect.width - 24)
    draw_item_number(rect, item)
  end
  
  #--------------------------------------------------------------------------
  # draw_gold
  #--------------------------------------------------------------------------
  def draw_gold(rect)
    text = Vocab.currency_unit
    draw_currency_value(@gold, text, rect.x, rect.y, rect.width)
  end
  
  #--------------------------------------------------------------------------
  # draw_item_number
  #--------------------------------------------------------------------------
  def draw_item_number(rect, item)
    number = @goods[item].group
    if $imported["YEA-AdjustLimits"]
      contents.font.size = YEA::LIMIT::ITEM_FONT
      text = sprintf(YEA::LIMIT::ITEM_PREFIX, number)
      draw_text(rect, text, 2)
    else
      draw_text(rect, sprintf("%s", number), 2)
    end
  end
  
end # Window_VictorySpoils

#==============================================================================
# â–  Scene_Battle
#==============================================================================

class Scene_Battle < Scene_Base
  
  #--------------------------------------------------------------------------
  # alias method: create_all_windows
  #--------------------------------------------------------------------------
  alias scene_battle_create_all_windows_va create_all_windows
  def create_all_windows
    scene_battle_create_all_windows_va
    create_victory_aftermath_windows
  end
  
  #--------------------------------------------------------------------------
  # new method: create_victory_aftermath_windows
  #--------------------------------------------------------------------------
  def create_victory_aftermath_windows
    @victory_title_window = Window_VictoryTitle.new
    @victory_exp_window_back = Window_VictoryEXP_Back.new
    @victory_exp_window_front = Window_VictoryEXP_Front.new
    @victory_level_window = Window_VictoryLevelUp.new
    @victory_level_skills = Window_VictorySkills.new
    @victory_spoils_window = Window_VictorySpoils.new
  end
  
  #--------------------------------------------------------------------------
  # new method: show_victory_display_exp
  #--------------------------------------------------------------------------
  def show_victory_display_exp
    @victory_title_window.open
    name = $game_party.battle_members[0].name
    fmt = YEA::VICTORY_AFTERMATH::TOP_TEAM
    name = sprintf(fmt, name) if $game_party.battle_members.size > 1
    fmt = YEA::VICTORY_AFTERMATH::TOP_VICTORY_TEXT
    text = sprintf(fmt, name)
    @victory_title_window.refresh(text)
    #---
    @victory_exp_window_back.open
    @victory_exp_window_back.refresh
    @victory_exp_window_front.open
    @victory_exp_window_front.refresh
  end
  
  #--------------------------------------------------------------------------
  # new method: show_victory_level_up
  #--------------------------------------------------------------------------
  def show_victory_level_up(actor, temp_actor)
    @victory_exp_window_back.hide
    @victory_exp_window_front.hide
    #---
    fmt = YEA::VICTORY_AFTERMATH::TOP_LEVEL_UP
    text = sprintf(fmt, actor.name)
    @victory_title_window.refresh(text)
    #---
    @victory_level_window.show
    @victory_level_window.refresh(actor, temp_actor)
    @victory_level_skills.show
    @victory_level_skills.refresh(actor, temp_actor)
  end
  
  #--------------------------------------------------------------------------
  # new method: show_victory_spoils
  #--------------------------------------------------------------------------
  def show_victory_spoils(gold, drops)
    @victory_exp_window_back.hide
    @victory_exp_window_front.hide
    @victory_level_window.hide
    @victory_level_skills.hide
    #---
    text = YEA::VICTORY_AFTERMATH::TOP_SPOILS
    @victory_title_window.refresh(text)
    #---
    @victory_spoils_window.show
    @victory_spoils_window.make(gold, drops)
  end
  
  #--------------------------------------------------------------------------
  # new method: close_victory_windows
  #--------------------------------------------------------------------------
  def close_victory_windows
    @victory_title_window.close
    @victory_exp_window_back.close
    @victory_exp_window_front.close
    @victory_level_window.close
    @victory_level_skills.close
    @victory_spoils_window.close
    wait(16)
  end
  
end # Scene_Battle

#==============================================================================
# 
# â–¼ End of File
# 
#==============================================================================

 

 

 

JP Manager

 

 

#==============================================================================
# 
# â–¼ Yanfly Engine Ace - JP Manager v1.00
# -- Last Updated: 2012.01.07
# -- Level: Normal, Hard
# -- Requires: n/a
# 
#==============================================================================

$imported = {} if $imported.nil?
$imported["YEA-JPManager"] = true

#==============================================================================
# â–¼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 2012.01.07 - Started Script and Finished.
# 
#==============================================================================
# â–¼ Introduction
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# This script provides a base for JP implementation. JP is a currency similar
# to EXP that's gained through performing actions and leveling up in addition
# to killing enemies. This script provides modifiers that adjust the gains for
# JP through rates, individual gains per skill or item, and per enemy. Though
# this script provides no usage of JP by itself, future Yanfly Engine Ace
# scripts may make use of it.
# 
#==============================================================================
# â–¼ 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.
# 
# -----------------------------------------------------------------------------
# Actor Notetags - These notetags go in the actors notebox in the database.
# -----------------------------------------------------------------------------
# <jp rate: x%>
# Changes the JP earned rate to x%. This affects JP earned and not JP directly
# gained. If this notetag isn't used, the object will default to 100%.
# 
# -----------------------------------------------------------------------------
# Class Notetags - These notetags go in the class notebox in the database.
# -----------------------------------------------------------------------------
# <jp rate: x%>
# Changes the JP earned rate to x%. This affects JP earned and not JP directly
# gained. If this notetag isn't used, the object will default to 100%.
# 
# -----------------------------------------------------------------------------
# Skill Notetags - These notetags go in the skills notebox in the database.
# -----------------------------------------------------------------------------
# <jp gain: x>
# When the actor successfully hits an target with this action, the actor will
# earn x JP. If this notetag isn't used, the amount of JP earned will equal to
# the ACTION_JP constant in the module.
# 
# -----------------------------------------------------------------------------
# Item Notetags - These notetags go in the items notebox in the database.
# -----------------------------------------------------------------------------
# <jp gain: x>
# When the actor successfully hits an target with this action, the actor will
# earn x JP. If this notetag isn't used, the amount of JP earned will equal to
# the ACTION_JP constant in the module.
# 
# -----------------------------------------------------------------------------
# Weapon Notetags - These notetags go in the weapon notebox in the database.
# -----------------------------------------------------------------------------
# <jp rate: x%>
# Changes the JP earned rate to x%. This affects JP earned and not JP directly
# gained. If this notetag isn't used, the object will default to 100%.
# 
# -----------------------------------------------------------------------------
# Armour Notetags - These notetags go in the armour notebox in the database.
# -----------------------------------------------------------------------------
# <jp rate: x%>
# Changes the JP earned rate to x%. This affects JP earned and not JP directly
# gained. If this notetag isn't used, the object will default to 100%.
# 
# -----------------------------------------------------------------------------
# Enemy Notetags - These notetags go in the enemy notebox in the database.
# -----------------------------------------------------------------------------
# <jp gain: x>
# Changes the amount of JP gained for killing the enemy to x. If this notetag
# isn't used, then the default JP gain will be equal to the amount set in the
# module through the constant ENEMY_KILL.
# 
# -----------------------------------------------------------------------------
# State Notetags - These notetags go in the states notebox in the database.
# -----------------------------------------------------------------------------
# <jp rate: x%>
# Changes the JP earned rate to x%. This affects JP earned and not JP directly
# gained. If this notetag isn't used, the object will default to 100%.
# 
# -----------------------------------------------------------------------------
# Script Calls - These commands are used with script calls.
# -----------------------------------------------------------------------------
# $game_actors[x].earn_jp(y)
# $game_actors[x].earn_jp(y, z)
# This will cause actor x to earn y amount of JP. JP earned will be modified by
# any JP Rate traits provided through notetags. If z is used, z will be the
# class the JP is earned for.
# 
# $game_actors[x].gain_jp(y)
# $game_actors[x].gain_jp(y, z)
# This will cause actor x to gain y amount of JP. JP gained this way will not
# be modified by any JP Rate traits provided through notetags. If z is used,
# z will be the class the JP is gained for.
# 
# $game_actors[x].lose_jp(y)
# $game_actors[x].lose_jp(y, z)
# This will cause actor x to lose y amount of JP. JP lost this way will not be
# modified by any JP Rate traits provided through notetags. If z is used, z
# will be the class the JP is lost from.
# 
#==============================================================================
# â–¼ Compatibility
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# This script is made strictly for RPG Maker VX Ace. It is highly unlikely that
# it will run with RPG Maker VX without adjusting.
# 
# This script is compatible with Yanfly Engine Ace - Victory Aftermath v1.03+.
# If you wish to have Victory Aftermath display JP gains, make sure the version
# is 1.03+. Script placement of these two scripts don't matter.
# 
#==============================================================================

module YEA
  module JP
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - General JP Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # This adjusts the way JP appears visually in your game. Change the icon
    # used and the vocabulary used here. Furthermore, adjust the maximum amount
    # of JP that an actor can have at a time.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    ICON   = 0           # Icon index used to represent JP.
    VOCAB  = " TP"        # What JP will be called in your game.
    MAX_JP = 99999999    # Maximum JP an actor can have.
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Default JP Gain Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # The following constants adjust how much JP is earned by default through
    # enemy kills, leveling up, and performing actions.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    ENEMY_KILL = 5     # JP earned for the whole party.
    LEVEL_UP   = 10    # JP earned when leveling up!
    ACTION_JP  = 1      # JP earned per successful hit.
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Victory Message -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # This adjusts the victory message shown for the default battle system and
    # the Yanfly Engine Ace - Victory Aftermath script (if used together).
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    VICTORY_MESSAGE   = "%s has earned %s %s!"
    VICTORY_AFTERMATH = "+%s%s"
    
  end # JP
end # YEA

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

module YEA
  module REGEXP
  module BASEITEM
    
    JP_RATE = /<(?:JP_RATE|jp rate):[ ](\d+)([%ï¼…])>/i
    
  end # BASEITEM
  module USABLEITEM
    
    JP_GAIN = /<(?:JP_GAIN|jp gain):[ ](\d+)>/i
    
  end # USABLEITEM
  module ENEMY
    
    JP_GAIN = /<(?:JP_GAIN|jp gain):[ ](\d+)>/i
    
  end # ENEMY
  end # REGEXP
end # YEA

#==============================================================================
# â–  Vocab
#==============================================================================

module Vocab
  
  #--------------------------------------------------------------------------
  # new method: self.jp
  #--------------------------------------------------------------------------
  def self.jp
    return YEA::JP::VOCAB
  end
  
end # Vocab

#==============================================================================
# â–  Icon
#==============================================================================

module Icon
  
  #--------------------------------------------------------------------------
  # self.jp
  #--------------------------------------------------------------------------
  def self.jp; return YEA::JP::ICON; end
    
end # Icon

#==============================================================================
# â–  Numeric
#==============================================================================

class Numeric
  
  #--------------------------------------------------------------------------
  # new method: group_digits
  #--------------------------------------------------------------------------
  unless $imported["YEA-CoreEngine"]
  def group; return self.to_s; end
  end # $imported["YEA-CoreEngine"]
    
end # Numeric

#==============================================================================
# â–  DataManager
#==============================================================================

module DataManager
  
  #--------------------------------------------------------------------------
  # alias method: load_database
  #--------------------------------------------------------------------------
  class <<self; alias load_database_jp load_database; end
  def self.load_database
    load_database_jp
    load_notetags_jp
  end
  
  #--------------------------------------------------------------------------
  # new method: load_notetags_jp
  #--------------------------------------------------------------------------
  def self.load_notetags_jp
    groups = [$data_actors, $data_classes, $data_weapons, $data_armors,
      $data_states, $data_enemies, $data_items, $data_skills]
    for group in groups
      for obj in group
        next if obj.nil?
        obj.load_notetags_jp
      end
    end
  end
  
end # DataManager

#==============================================================================
# â–  RPG::BaseItem
#==============================================================================

class RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :jp_rate
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_jp
  #--------------------------------------------------------------------------
  def load_notetags_jp
    @jp_rate = 1.0
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::BASEITEM::JP_RATE
        @jp_rate = $1.to_i * 0.01
      #---
      end
    } # self.note.split
    #---
  end
  
end # RPG::BaseItem

#==============================================================================
# â–  RPG::UsableItem
#==============================================================================

class RPG::UsableItem < RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :jp_gain
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_jp
  #--------------------------------------------------------------------------
  def load_notetags_jp
    @jp_gain = YEA::JP::ACTION_JP
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::USABLEITEM::JP_GAIN
        @jp_gain = $1.to_i
      #---
      end
    } # self.note.split
    #---
  end
  
end # RPG::UsableItem

#==============================================================================
# â–  RPG::Enemy
#==============================================================================

class RPG::Enemy < RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :jp_gain
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_jp
  #--------------------------------------------------------------------------
  def load_notetags_jp
    @jp_gain = YEA::JP::ENEMY_KILL
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::ENEMY::JP_GAIN
        @jp_gain = $1.to_i
      #---
      end
    } # self.note.split
    #---
  end
  
end # RPG::Enemy

#==============================================================================
# â–  BattleManager
#==============================================================================

module BattleManager
  
  #--------------------------------------------------------------------------
  # alias method: display_exp
  #--------------------------------------------------------------------------
  unless $imported["YEA-VictoryAftermath"]
  class <<self; alias battlemanager_display_exp_jp display_exp; end
  def self.display_exp
    battlemanager_display_exp_jp
    gain_jp
  end
  end # $imported["YEA-VictoryAftermath"]
  
  #--------------------------------------------------------------------------
  # new method: gain_jp
  #--------------------------------------------------------------------------
  def self.gain_jp
    amount = $game_troop.jp_total
    fmt = YEA::JP::VICTORY_MESSAGE
    for member in $game_party.members
      member.earn_jp(amount)
      next if $imported["YEA-VictoryAftermath"]
      value = member.battle_jp_earned.group
      $game_message.add('\.' + sprintf(fmt, member.name, value, Vocab::jp))
    end
    wait_for_message unless $imported["YEA-VictoryAftermath"]
  end
  
end # BattleManager

#==============================================================================
# â–  Game_BattlerBase
#==============================================================================

class Game_BattlerBase
  
  #--------------------------------------------------------------------------
  # new method: jpr
  #--------------------------------------------------------------------------
  def jpr
    n = 1.0
    if actor?
      n *= self.actor.jp_rate
      n *= self.class.jp_rate
      for equip in equips
        next if equip.nil?
        n *= equip.jp_rate
      end
    end
    for state in states
      next if state.nil?
      n *= state.jp_rate
    end
    return n
  end
  
end # Game_BattlerBase

#==============================================================================
# â–  Game_Battler
#==============================================================================

class Game_Battler < Game_BattlerBase
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :battle_jp_earned
  
  #--------------------------------------------------------------------------
  # alias method: on_battle_start
  #--------------------------------------------------------------------------
  alias game_battler_on_battle_start_jp on_battle_start
  def on_battle_start
    game_battler_on_battle_start_jp
    @battle_jp_earned = 0
  end
  
  #--------------------------------------------------------------------------
  # alias method: on_battle_end
  #--------------------------------------------------------------------------
  alias game_battler_on_battle_end_jp on_battle_end
  def on_battle_end
    game_battler_on_battle_end_jp
    @battle_jp_earned = 0
  end
  
  #--------------------------------------------------------------------------
  # alias method: item_user_effect
  #--------------------------------------------------------------------------
  alias game_battler_item_user_effect_jp item_user_effect
  def item_user_effect(user, item)
    game_battler_item_user_effect_jp(user, item)
    user.earn_jp(item.jp_gain) if user.actor?
  end
  
end # Game_Battler

#==============================================================================
# â–  Game_Actor
#==============================================================================

class Game_Actor < Game_Battler
  
  #--------------------------------------------------------------------------
  # alias method: setup
  #--------------------------------------------------------------------------
  alias game_actor_setup_jp setup
  def setup(actor_id)
    game_actor_setup_jp(actor_id)
    init_jp
  end
  
  #--------------------------------------------------------------------------
  # new method: init_jp
  #--------------------------------------------------------------------------
  def init_jp
    @jp = {}
    @jp[@class_id] = 0
  end
  
  #--------------------------------------------------------------------------
  # new method: earn_jp
  #--------------------------------------------------------------------------
  def earn_jp(jp, class_id = nil)
    gain_jp(jp * jpr, class_id)
  end
  
  #--------------------------------------------------------------------------
  # new method: gain_jp
  #--------------------------------------------------------------------------
  def gain_jp(jp, class_id = nil)
    init_jp if @jp.nil?
    class_id = @class_id if class_id.nil?
    @jp[class_id] = 0 if @jp[class_id].nil?
    @jp[class_id] += jp.to_i
    @jp[class_id] = [[@jp[class_id], YEA::JP::MAX_JP].min, 0].max
    @battle_jp_earned = 0 if @battle_jp_earned.nil? && $game_party.in_battle
    @battle_jp_earned += jp.to_i if $game_party.in_battle
  end
  
  #--------------------------------------------------------------------------
  # new method: lose_jp
  #--------------------------------------------------------------------------
  def lose_jp(jp, class_id = nil)
    gain_jp(-jp, class_id)
  end
  
  #--------------------------------------------------------------------------
  # new method: jp
  #--------------------------------------------------------------------------
  def jp(class_id = nil)
    class_id = @class_id if class_id.nil?
    @jp[class_id] = 0 if @jp[class_id].nil?
    return @jp[class_id]
  end
  
  #--------------------------------------------------------------------------
  # alias method: level_up
  #--------------------------------------------------------------------------
  alias game_actor_level_up_jp level_up
  def level_up
    game_actor_level_up_jp
    earn_jp(YEA::JP::LEVEL_UP)
  end
  
end # Game_Actor

#==============================================================================
# â–  Game_Enemy
#==============================================================================

class Game_Enemy < Game_Battler
  
  #--------------------------------------------------------------------------
  # new method: jp
  #--------------------------------------------------------------------------
  def jp
    return enemy.jp_gain
  end
  
end # Game_Enemy

#==============================================================================
# â–  Game_Troop
#==============================================================================

class Game_Troop < Game_Unit
  
  #--------------------------------------------------------------------------
  # new method: jp_total
  #--------------------------------------------------------------------------
  def jp_total
    dead_members.inject(0) {|r, enemy| r += enemy.jp }
  end
  
end # Game_Troop

#==============================================================================
# â–  Window_Base
#==============================================================================

class Window_Base < Window
  
  #--------------------------------------------------------------------------
  # new method: draw_actor_jp
  #--------------------------------------------------------------------------
  def draw_actor_jp(actor, dx, dy, dw = 112)
    draw_icon(Icon.jp, dx + dw - 24, dy) if Icon.jp > 0
    dw -= 24 if Icon.jp > 0
    change_color(system_color)
    draw_text(dx, dy, dw, line_height, Vocab::jp, 2)
    dw -= text_size(Vocab::jp).width
    change_color(normal_color)
    draw_text(dx, dy, dw, line_height, actor.jp.group, 2)
  end
  
  #--------------------------------------------------------------------------
  # new method: draw_actor_jp_class
  #--------------------------------------------------------------------------
  def draw_actor_jp_class(actor, class_id, dx, dy, dw = 112)
    draw_icon(Icon.jp, dx + dw - 24, dy) if Icon.jp > 0
    dw -= 24 if Icon.jp > 0
    change_color(system_color)
    draw_text(dx, dy, dw, line_height, Vocab::jp, 2)
    dw -= text_size(Vocab::jp).width
    change_color(normal_color)
    draw_text(dx, dy, dw, line_height, actor.jp(class_id).group, 2)
  end
  
end # Window_Base

#==============================================================================
# 
# â–¼ End of File
# 
#==============================================================================

 

 

 

Learn Skills

 

 

#==============================================================================
# 
# â–¼ Yanfly Engine Ace - Learn Skill Engine v1.00
# -- Last Updated: 2012.01.08
# -- Level: Normal, Hard
# -- Requires: n/a
# 
#==============================================================================

$imported = {} if $imported.nil?
$imported["YEA-LearnSkillEngine"] = true

#==============================================================================
# â–¼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 2012.01.08 - Started Script and Finished.
# 
#==============================================================================
# â–¼ Introduction
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# For those who want an alternative for actors to learn skills outside of
# leveling, this script allows actors to learn skills through a learn skill
# menu. The actor can use acquired JP, EXP, or Gold to learn skills. Skills can
# also be hidden until certain requirements are met.
# 
#==============================================================================
# â–¼ 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.
# 
# -----------------------------------------------------------------------------
# Class Notetags - These notetags go in the class notebox in the database.
# -----------------------------------------------------------------------------
# <learn skills: x>
# <learn skills: x, x>
# Sets the class to be able to learn skills x through the Learn Skills menu.
# Insert multiple of these tags to increase the number of skills learned.
# 
# -----------------------------------------------------------------------------
# Skill Notetags - These notetags go in the skill notebox in the database.
# -----------------------------------------------------------------------------
# <learn cost: x jp>
# <learn cost: x exp>
# <learn cost: x gold>
# Sets the learn for cost the skill to require x amounts of JP, x amounts of
# exp, or x amounts of gold. Only one type of cost can be used at a time. For
# JP costs, the Yanfly Engine Ace - JP Manager script must be installed.
# 
# <learn require level: x>
# Sets the skill to require the actor's current level to be x before the skill
# will show up in the skill learning window.
# 
# <learn require skill: x>
# <learn require skill: x, x>
# Sets the skill to require learning skill x (through any means) before the
# skill becomes visible in the skill learning window. Insert multiples of these
# tags to require more skills to be learned in order for the skill to show.
# 
# <learn require switch: x>
# <learn require switch: x, x>
# Sets the skill to require switch x to be ON in order for it to show in the
# skill learning window. Insert multiple switches to to increase the number of
# switches needed to be ON before the skill is shown.
# 
# <learn require eval>
#  string
#  string
# </learn require eval>
# For the more advanced users, replace string with lines of code to check for
# whether or not the skill will be shown in skill learning window. If multiple
# lines are used, they are all considered part of the same line.
# 
#==============================================================================
# â–¼ Compatibility
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# This script is made strictly for RPG Maker VX Ace. It is highly unlikely that
# it will run with RPG Maker VX without adjusting.
# 
# This script is compatible with Yanfly Engine Ace - JP Manager v1.00+. The
# placement of this script relative to the JP Manager script doesn't matter.
# 
#==============================================================================

module YEA
  module LEARN_SKILL
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - General Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # Adjust the general settings here for your game. These adjust how the
    # command name appears, a switch to show the Learn Command
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    COMMAND_NAME = "Learn"    # Name used for Learn Skill command.
    
    # This switch will hide the "Learn" command from view if the switch is OFF.
    # The "Learn" command will be shown if the switch is ON. Set this switch to
    # 0 to not use this effect and to always have the Learn command be shown.
    SHOW_SWITCH   = 0
    
    # This adjusts the order the Skill Types appear in for the command window.
    # Any Skill Types unlisted will not be shown. 
    STYPE_ORDER = [1,2]
    
    # For those who installed Yanfly Engine - Skill Restrictions, you can
    # choose to display warmups or cooldowns inside of the menu here.
    DRAW_WARMUP   = true        # Draw warmups for skills?
    DRAW_COOLDOWN = true        # Draw cooldowns for skills?
    
    #-------------------------------------------------------------------------
    # - Default Cost -
    #-------------------------------------------------------------------------
    # This sets the default costs for all skills. If the JP script isn't
    # installed, the type will become :exp instead.
    # 
    # Cost Type       Description
    #  :jp            - Requires YEA - JP Manager.
    #  :exp           - Makes skill cost EXP.
    #  :gold          - Makes skill cost gold.
    #-------------------------------------------------------------------------
    DEFAULT_COST = 100          # Sets the default cost of a skill.
    DEFAULT_TYPE = :jp          # Sets the default cost type.
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Learn Window Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # These settings adjust the Learn Window's visual appearance. Adjust the
    # way empty text appears, EXP cost suffixes appear, Learned text appears,
    # font sizes, and cost colours here.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    EMPTY_TEXT     = "-"        # Text if no restricts used for the skill.
    EXP_TEXT       = "XP"      # Text used for EXP costs.
    LEARNED_TEXT   = "Learned"  # Text to indicate skill has been learned.
    LEARNED_SIZE   = 12         # Font size used for learned skill text.
    COLOUR_JP      = 21         # Text colour used for JP Cost.
    COLOUR_EXP     = 21         # Text colour used for EXP Cost.
    COLOUR_GOLD    = 21         # Text colour used for Gold Cost.
    COST_SIZE      = 12         # Font size used for skill costs.
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Cost Window Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # When a skill is selected to be learned, the cost window appears. Adjust
    # the settings here to choose how your game's cost window looks. Change the
    # maximum number of rows, the gold icon used for gold costs, the gold text,
    # the learn skill text, the cancel text, and the cancel icon here.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    MAXIMUM_ROWS      = 8               # Maximum number of rows displayed.
    GOLD_ICON         = 361             # Icon used for gold costs.
    GOLD_TEXT         = "Gold Cost"     # Text used for gold costs.
    LEARN_SKILL_TEXT  = "Learn %s?"     # Text used to learn skill.
    LEARN_CANCEL_TEXT = "Cancel"        # Text used for do not learn.
    CANCEL_ICON       = 119             # Icon used for cancel.
    
  end # LEARN_SKILL
end # YEA

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

module YEA
  module LEARN_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
    #--------------------------------------------------------------------------
    # converted_contants
    #--------------------------------------------------------------------------
    STYPE_ORDER = convert_integer_array(STYPE_ORDER)
  end # LEARN_SKILL
  module REGEXP
  module CLASS
    
    LEARN_SKILLS = /<(?:LEARN_SKILLS|learn skills):[ ](\d+(?:\s*,\s*\d+)*)>/i
    
  end # CLASS
  module SKILL
    
    LEARN_COST = /<(?:LEARN_COST|learn cost):[ ](.*)>/i
    LEARN_REQUIRE_LEVEL = 
      /<(?:LEARN_REQUIRE_LEVEL|learn require level):[ ](\d+)>/i
    LEARN_REQUIRE_SKILL =
      /<(?:LEARN_REQUIRE_SKILL|learn require skill):[ ](\d+(?:\s*,\s*\d+)*)>/i
    LEARN_REQUIRE_SWITCH =
      /<(?:LEARN_REQUIRE_SWITCH|learn require switch):[ ](\d+(?:\s*,\s*\d+)*)>/i
    LEARN_REQUIRE_EVAL_ON  = /<(?:LEARN_REQUIRE_EVAL|learn require eval)>/i
    LEARN_REQUIRE_EVAL_OFF = /<\/(?:LEARN_REQUIRE_EVAL|learn require eval)>/i
    
  end # SKILL
  end # REGEXP
end # YEA

#==============================================================================
# â–  Numeric
#==============================================================================

class Numeric
  
  #--------------------------------------------------------------------------
  # new method: group_digits
  #--------------------------------------------------------------------------
  unless $imported["YEA-CoreEngine"]
  def group; return self.to_s; end
  end # $imported["YEA-CoreEngine"]
    
end # Numeric

#==============================================================================
# â–  Icon
#==============================================================================

module Icon
  
  #--------------------------------------------------------------------------
  # self.cancel
  #--------------------------------------------------------------------------
  def self.cancel
    return YEA::LEARN_SKILL::CANCEL_ICON
  end
  
  #--------------------------------------------------------------------------
  # self.learn_skill_gold
  #--------------------------------------------------------------------------
  def self.learn_skill_gold
    return YEA::LEARN_SKILL::GOLD_ICON
  end
  
end # Icon

#==============================================================================
# â–  Switch
#==============================================================================

module Switch
  
  #--------------------------------------------------------------------------
  # self.show_learn_skill
  #--------------------------------------------------------------------------
  def self.show_learn_skill
    return true if YEA::LEARN_SKILL::SHOW_SWITCH <= 0
    return $game_switches[YEA::LEARN_SKILL::SHOW_SWITCH]
  end
  
end # Switch

#==============================================================================
# â–  DataManager
#==============================================================================

module DataManager
  
  #--------------------------------------------------------------------------
  # alias method: load_database
  #--------------------------------------------------------------------------
  class <<self; alias load_database_lse load_database; end
  def self.load_database
    load_database_lse
    load_notetags_lse
  end
  
  #--------------------------------------------------------------------------
  # new method: load_notetags_lse
  #--------------------------------------------------------------------------
  def self.load_notetags_lse
    groups = [$data_classes, $data_skills]
    for group in groups
      for obj in group
        next if obj.nil?
        obj.load_notetags_lse
      end
    end
  end
  
end # DataManager

#==============================================================================
# â–  RPG::Class
#==============================================================================

class RPG::Class < RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :learn_skills
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_lse
  #--------------------------------------------------------------------------
  def load_notetags_lse
    @learn_skills = []
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::CLASS::LEARN_SKILLS
        $1.scan(/\d+/).each { |num| 
        @learn_skills.push(num.to_i) if num.to_i > 0 }
      end
    } # self.note.split
    #---
  end
  
end # RPG::Class

#==============================================================================
# â–  RPG::Skill
#==============================================================================

class RPG::Skill < RPG::UsableItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :learn_cost
  attr_accessor :learn_require_level
  attr_accessor :learn_require_skill
  attr_accessor :learn_require_switch
  attr_accessor :learn_require_eval
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_lse
  #--------------------------------------------------------------------------
  def load_notetags_lse
    @learn_cost = [YEA::LEARN_SKILL::DEFAULT_COST]
    @learn_cost.push(YEA::LEARN_SKILL::DEFAULT_TYPE)
    @learn_require_level = 0
    @learn_require_skill = []
    @learn_require_switch = []
    @learn_require_eval_on = false
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::SKILL::LEARN_COST
        case $1.upcase
        when /(\d+)[ ]JP/i
          next unless $imported["YEA-JPManager"]
          @learn_cost = [$1.to_i, :jp]
        when /(\d+)[ ]EXP/i
          @learn_cost = [$1.to_i, :exp]
        when /(\d+)[ ]GOLD/i
          @learn_cost = [$1.to_i, :gold]
        end
      #---
      when YEA::REGEXP::SKILL::LEARN_REQUIRE_LEVEL
        @learn_require_level = $1.to_i
      when YEA::REGEXP::SKILL::LEARN_REQUIRE_SKILL
        $1.scan(/\d+/).each { |num| 
        @learn_require_skill.push(num.to_i) if num.to_i > 0 }
      when YEA::REGEXP::SKILL::LEARN_REQUIRE_SWITCH
        $1.scan(/\d+/).each { |num| 
        @learn_require_switch.push(num.to_i) if num.to_i > 0 }
      #---
      when YEA::REGEXP::SKILL::LEARN_REQUIRE_EVAL_ON
        @learn_require_eval_on = true
      when YEA::REGEXP::SKILL::LEARN_REQUIRE_EVAL_OFF
        @learn_require_eval_on = false
      else
        next unless @learn_require_eval_on
        @learn_require_eval = "" if @learn_require_eval.nil?
        @learn_require_eval += line.to_s
      #---
      end
    } # self.note.split
    #---
    if !$imported["YEA-JPManager"] && @learn_cost[1] == :jp
      @learn_cost[1] = :exp
    end
  end
  
end # RPG::Skill

#==============================================================================
# â–  Game_Actor
#==============================================================================

class Game_Actor < Game_Battler
  
  #--------------------------------------------------------------------------
  # alias method: skills
  #--------------------------------------------------------------------------
  alias game_actor_skills_lse skills
  def skills
    btest_add_learn_skills
    game_actor_skills_lse
  end
  
  #--------------------------------------------------------------------------
  # new method: btest_add_learn_skills
  #--------------------------------------------------------------------------
  def btest_add_learn_skills
    return unless $BTEST
    for skill_id in self.class.learn_skills; learn_skill(skill_id); end
  end
  
  #--------------------------------------------------------------------------
  # new method: exp_class
  #--------------------------------------------------------------------------
  def exp_class(class_id)
    @exp[class_id] = 0 if @exp[class_id].nil?
    return @exp[class_id]
  end
  
  #--------------------------------------------------------------------------
  # lose_exp_class
  #--------------------------------------------------------------------------
  def lose_exp_class(value, class_id)
    exp = exp_class(class_id) - value
    change_exp_class(exp, class_id)
  end
  
  #--------------------------------------------------------------------------
  # change_exp_class
  #--------------------------------------------------------------------------
  def change_exp_class(exp, class_id)
    return change_exp(exp, false) if class_id == @class_id
    @exp[class_id] = [exp, 0].max
  end
  
end # Game_Actor

#==============================================================================
# â–  Window_SkillCommand
#==============================================================================

class Window_SkillCommand < Window_Command
  
  #--------------------------------------------------------------------------
  # alias method: make_command_list
  #--------------------------------------------------------------------------
  alias window_skillcommand_make_command_list_lse make_command_list
  def make_command_list
    window_skillcommand_make_command_list_lse
    return if @actor.nil?
    add_learn_skill_command unless $imported["YEA-SkillMenu"]
  end
  
  #--------------------------------------------------------------------------
  # new method: add_learn_skill_command
  #--------------------------------------------------------------------------
  def add_learn_skill_command
    return unless Switch.show_learn_skill
    name = YEA::LEARN_SKILL::COMMAND_NAME
    add_command(name, :learn_skill, true, @actor.added_skill_types[0])
  end
  
end # Window_SkillCommand

#==============================================================================
# â–  Window_LearnSkillCommand
#==============================================================================

class Window_LearnSkillCommand < Window_Command
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_reader   :skill_window
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(dx, dy)
    super(dx, dy)
    @actor = nil
  end
  
  #--------------------------------------------------------------------------
  # window_width
  #--------------------------------------------------------------------------
  def window_width; return 160; end
  
  #--------------------------------------------------------------------------
  # visible_line_number
  #--------------------------------------------------------------------------
  def visible_line_number; return 4; end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(actor)
    return if @actor == actor
    @actor = actor
    refresh
    select(item_max - 1) if index >= item_max
  end
  
  #--------------------------------------------------------------------------
  # make_command_list
  #--------------------------------------------------------------------------
  def make_command_list
    return if @actor.nil?
    make_unlocked_class_skill_types
    correct_unlocked_class_learned_skills
    for stype_id in YEA::LEARN_SKILL::STYPE_ORDER
      next unless include?(stype_id)
      name = $data_system.skill_types[stype_id]
      add_command(name, :skill, true, stype_id)
    end
  end
  
  #--------------------------------------------------------------------------
  # make_unlocked_class_skill_types
  #--------------------------------------------------------------------------
  def make_unlocked_class_skill_types
    return unless $imported["YEA-ClassSystem"]
    @unlocked_types = []
    unlocked_classes = @actor.unlocked_classes.clone
    unlocked_classes |= YEA::CLASS_SYSTEM::DEFAULT_UNLOCKS
    for class_id in unlocked_classes
      next if $data_classes[class_id].nil?
      for feature in $data_classes[class_id].features
        next unless feature.code == 41
        @unlocked_types.push(feature.data_id)
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # correct_unlocked_class_learned_skills
  #--------------------------------------------------------------------------
  def correct_unlocked_class_learned_skills
    return unless $imported["YEA-ClassSystem"]
    unlocked_classes = @actor.unlocked_classes.clone
    unlocked_classes |= YEA::CLASS_SYSTEM::DEFAULT_UNLOCKS
    for class_id in unlocked_classes
      @actor.learn_class_skills(class_id)
    end
  end
  
  #--------------------------------------------------------------------------
  # include?
  #--------------------------------------------------------------------------
  def include?(stype_id)
    return true if @actor.added_skill_types.include?(stype_id)
    if $imported["YEA-ClassSystem"]
      return true if @unlocked_types.include?(stype_id)
    end
    return false
  end
  
  #--------------------------------------------------------------------------
  # update
  #--------------------------------------------------------------------------
  def update
    super
    @skill_window.stype_id = current_ext if @skill_window
  end
  
  #--------------------------------------------------------------------------
  # skill_window=
  #--------------------------------------------------------------------------
  def skill_window=(skill_window)
    @skill_window = skill_window
    update
  end
  
end # Window_LearnSkillCommand

#==============================================================================
# â–  Window_LearnSkillList
#==============================================================================

class Window_LearnSkillList < Window_SkillList
  
  #--------------------------------------------------------------------------
  # col_max
  #--------------------------------------------------------------------------
  def col_max; return 1; end
  
  #--------------------------------------------------------------------------
  # select_last
  #--------------------------------------------------------------------------
  def select_last; select(0); end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(actor)
    return if @actor == actor
    super(actor)
    make_learn_skills_list
  end
  
  #--------------------------------------------------------------------------
  # make_learn_skills_list
  #--------------------------------------------------------------------------
  def make_learn_skills_list
    @learn_skills = []
    @skill_classes = {}
    return if @actor.nil?
    for skill_id in @actor.class.learn_skills
      next if $data_skills[skill_id].nil?
      next if @learn_skills.include?($data_skills[skill_id])
      skill = $data_skills[skill_id]
      @learn_skills.push(skill)
      @skill_classes[skill] = [] if @skill_classes[skill].nil?
      @skill_classes[skill].push(@actor.class.id)
    end
    make_unlocked_class_skills
  end
  
  #--------------------------------------------------------------------------
  # make_unlocked_class_skills
  #--------------------------------------------------------------------------
  def make_unlocked_class_skills
    return unless $imported["YEA-ClassSystem"]
    @unlocked_types = []
    unlocked_classes = @actor.unlocked_classes.clone
    unlocked_classes |= YEA::CLASS_SYSTEM::DEFAULT_UNLOCKS
    for class_id in unlocked_classes
      next if $data_classes[class_id].nil?
      for skill_id in $data_classes[class_id].learn_skills
        next if $data_skills[skill_id].nil?
        skill = $data_skills[skill_id]
        @learn_skills.push(skill) unless @learn_skills.include?(skill)
        @skill_classes[skill] = [] if @skill_classes[skill].nil?
        @skill_classes[skill] |= [class_id]
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # skill_classes
  #--------------------------------------------------------------------------
  def skill_classes(skill)
    return @skill_classes[skill]
  end
  
  #--------------------------------------------------------------------------
  # make_item_list
  #--------------------------------------------------------------------------
  def make_item_list
    return if @learn_skills.nil?
    @data = @learn_skills.select {|skill| include?(skill) }
  end
  
  #--------------------------------------------------------------------------
  # include?
  #--------------------------------------------------------------------------
  def include?(item)
    return false if item.nil?
    return false unless meet_requirements?(item)
    return item.stype_id == @stype_id
  end
  
  #--------------------------------------------------------------------------
  # meet_requirements?
  #--------------------------------------------------------------------------
  def meet_requirements?(item)
    return false if @actor.nil?
    return false unless meet_level_requirements?(item)
    return false unless meet_skill_requirements?(item)
    return false unless meet_switch_requirements?(item)
    return false unless meet_eval_requirements?(item)
    return true
  end
  
  #--------------------------------------------------------------------------
  # meet_level_requirements?
  #--------------------------------------------------------------------------
  def meet_level_requirements?(item)
    return @actor.level >= item.learn_require_level
  end
  
  #--------------------------------------------------------------------------
  # meet_skill_requirements?
  #--------------------------------------------------------------------------
  def meet_skill_requirements?(item)
    for skill_id in item.learn_require_skill
      next if $data_skills[skill_id].nil?
      return false unless @actor.skill_learn?($data_skills[skill_id])
    end
    return true
  end
  
  #--------------------------------------------------------------------------
  # meet_switch_requirements?
  #--------------------------------------------------------------------------
  def meet_switch_requirements?(item)
    for switch_id in item.learn_require_switch
      return false unless $game_switches[switch_id]
    end
    return true
  end
  
  #--------------------------------------------------------------------------
  # meet_eval_requirements?
  #--------------------------------------------------------------------------
  def meet_eval_requirements?(item)
    return true if item.learn_require_eval.nil?
    return eval(item.learn_require_eval)
  end
  
  #--------------------------------------------------------------------------
  # enable?
  #--------------------------------------------------------------------------
  def enable?(skill)
    return false if skill.nil?
    return false unless enabled_jp?(skill)
    return false unless enabled_exp?(skill)
    return false unless enabled_gold?(skill)
    return !@actor.skill_learn?(skill)
  end
  
  #--------------------------------------------------------------------------
  # enabled_jp?
  #--------------------------------------------------------------------------
  def enabled_jp?(skill)
    return true if skill.learn_cost[1] != :jp
    cost = skill.learn_cost[0]
    for class_id in @skill_classes[skill]
      return true if @actor.jp(class_id) >= cost
    end
    return false
  end
  
  #--------------------------------------------------------------------------
  # enabled_exp?
  #--------------------------------------------------------------------------
  def enabled_exp?(skill)
    return true if skill.learn_cost[1] != :exp
    cost = skill.learn_cost[0]
    for class_id in @skill_classes[skill]
      return true if @actor.exp_class(class_id) >= cost
    end
    return false
  end
  
  #--------------------------------------------------------------------------
  # enabled_gold?
  #--------------------------------------------------------------------------
  def enabled_gold?(skill)
    return true if skill.learn_cost[1] != :gold
    cost = skill.learn_cost[0]
    return $game_party.gold >= cost
  end
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(index)
    skill = @data[index]
    return if skill.nil?
    rect = item_rect(index)
    rect.width = (contents.width - spacing) / 2 - 4
    draw_item_name(skill, rect.x, rect.y, enable?(skill), rect.width - 24)
    draw_skill_cost(rect, skill)
    draw_restriction_info(skill, index)
    draw_learn_cost(skill, index)
  end
  
  #--------------------------------------------------------------------------
  # skill_restriction?
  #--------------------------------------------------------------------------
  def skill_restriction?(index)
    return false
  end
  
  #--------------------------------------------------------------------------
  # draw_restriction_info
  #--------------------------------------------------------------------------
  def draw_restriction_info(skill, index)
    return unless $imported["YEA-SkillRestrictions"]
    rect = item_rect(index)
    rect.x = contents.width / 2
    rect.width /= 2
    rect.width /= 3
    rect.width -= 8
    draw_skill_warmup(skill, rect)
    rect.x += rect.width + 4
    draw_skill_cooldown(skill, rect)
  end
  
  #--------------------------------------------------------------------------
  # draw_skill_warmup
  #--------------------------------------------------------------------------
  def draw_skill_warmup(skill, rect)
    return unless YEA::LEARN_SKILL::DRAW_WARMUP
    enabled = enable?(skill)
    enabled = false if skill.warmup <= 0
    change_color(warmup_colour, enabled)
    icon = Icon.warmup
    if icon > 0
      draw_icon(icon, rect.x + rect.width-24, rect.y, enable?(skill))
      rect.width -= 24
    end
    contents.font.size = YEA::SKILL_RESTRICT::WARMUP_SIZE
    value = skill.warmup > 0 ? skill.warmup.group : empty_text
    text = sprintf(YEA::SKILL_RESTRICT::WARMUP_SUFFIX, value)
    draw_text(rect, text, 2)
    reset_font_settings
  end
  
  #--------------------------------------------------------------------------
  # draw_skill_cooldown
  #--------------------------------------------------------------------------
  def draw_skill_cooldown(skill, rect)
    return unless YEA::LEARN_SKILL::DRAW_COOLDOWN
    enabled = enable?(skill)
    enabled = false if skill.cooldown <= 0
    change_color(cooldown_colour, enabled)
    icon = Icon.cooldown
    if icon > 0
      draw_icon(icon, rect.x + rect.width-24, rect.y, enable?(skill))
      rect.width -= 24
    end
    contents.font.size = YEA::SKILL_RESTRICT::COOLDOWN_SIZE
    value = skill.cooldown > 0 ? skill.cooldown.group : empty_text
    text = sprintf(YEA::SKILL_RESTRICT::COOLDOWN_SUFFIX, value)
    draw_text(rect, text, 2)
    reset_font_settings
  end
  
  #--------------------------------------------------------------------------
  # empty_text
  #--------------------------------------------------------------------------
  def empty_text
    return YEA::LEARN_SKILL::EMPTY_TEXT
  end
  
  #--------------------------------------------------------------------------
  # draw_learn_cost
  #--------------------------------------------------------------------------
  def draw_learn_cost(skill, index)
    rect = item_rect(index)
    rect.width -= 4
    if @actor.skill_learn?(skill)
      draw_learned_skill(rect)
    else
      draw_learn_skill_cost(skill, rect)
    end
    reset_font_settings
  end
  
  #--------------------------------------------------------------------------
  # draw_learned_skill
  #--------------------------------------------------------------------------
  def draw_learned_skill(rect)
    contents.font.size = YEA::LEARN_SKILL::LEARNED_SIZE
    change_color(normal_color)
    draw_text(rect, YEA::LEARN_SKILL::LEARNED_TEXT, 2)
  end
  
  #--------------------------------------------------------------------------
  # draw_learn_skill_cost
  #--------------------------------------------------------------------------
  def draw_learn_skill_cost(skill, rect)
    case skill.learn_cost[1]
    when :jp
      return unless $imported["YEA-JPManager"]
      draw_jp_cost(skill, rect)
    when :exp
      draw_exp_cost(skill, rect)
    when :gold
      draw_gold_cost(skill, rect)
    else; return
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_jp_cost
  #--------------------------------------------------------------------------
  def draw_jp_cost(skill, rect)
    enabled = enabled_jp?(skill)
    if Icon.jp > 0
      draw_icon(Icon.jp, rect.x + rect.width - 24, rect.y, enabled)
      rect.width -= 24
    end
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, Vocab::jp, 2)
    rect.width -= text_size(Vocab::jp).width
    cost = skill.learn_cost[0]
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_JP), enabled)
    draw_text(rect, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # draw_exp_cost
  #--------------------------------------------------------------------------
  def draw_exp_cost(skill, rect)
    enabled = enabled_exp?(skill)
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, YEA::LEARN_SKILL::EXP_TEXT, 2)
    rect.width -= text_size(YEA::LEARN_SKILL::EXP_TEXT).width
    cost = skill.learn_cost[0]
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_EXP), enabled)
    draw_text(rect, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # draw_gold_cost
  #--------------------------------------------------------------------------
  def draw_gold_cost(skill, rect)
    enabled = enabled_jp?(skill)
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, Vocab::currency_unit, 2)
    rect.width -= text_size(Vocab::currency_unit).width
    cost = skill.learn_cost[0]
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_GOLD), enabled)
    draw_text(rect, text, 2)
  end
  
end # Window_LearnSkillList

#==============================================================================
# â–  Window_LearnSkillCostBack
#==============================================================================

class Window_LearnSkillCostBack < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(item_window)
    dw = Graphics.width * 3 / 4
    dx = (Graphics.width - dw) / 2
    super(dx, 0, dw, fitting_height(2))
    self.openness = 0
    self.back_opacity = 255
    @front_window = nil
    @item_window = item_window
    @skill = nil
  end
  
  #--------------------------------------------------------------------------
  # reveal
  #--------------------------------------------------------------------------
  def reveal(skill, skill_classes)
    @skill = skill
    return if @skill.nil?
    case @skill.learn_cost[1]
    when :gold
      self.height = fitting_height(3)
    else
      maximum = [skill_classes.size, YEA::LEARN_SKILL::MAXIMUM_ROWS].min
      self.height = fitting_height(maximum + 2)
    end
    create_contents
    self.y = (Graphics.height - self.height) / 2
    refresh
    open
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    contents.clear
    reset_font_settings
    draw_learn_skill_text
    rect = Rect.new(0, 0, contents.width - 4, line_height)
    draw_learn_skill_cost(@skill, rect)
  end
  
  #--------------------------------------------------------------------------
  # draw_learn_skill_text
  #--------------------------------------------------------------------------
  def draw_learn_skill_text
    name = sprintf("\eI[%d]%s", @skill.icon_index, @skill.name)
    fmt = YEA::LEARN_SKILL::LEARN_SKILL_TEXT
    text = sprintf(fmt, name)
    draw_text_ex(4, 0, text)
  end
  
  #--------------------------------------------------------------------------
  # draw_learn_skill_cost
  #--------------------------------------------------------------------------
  def draw_learn_skill_cost(skill, rect)
    case skill.learn_cost[1]
    when :jp
      return unless $imported["YEA-JPManager"]
      draw_jp_cost(skill, rect)
    when :exp
      draw_exp_cost(skill, rect)
    when :gold
      draw_gold_cost(skill, rect)
    else; return
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_jp_cost
  #--------------------------------------------------------------------------
  def draw_jp_cost(skill, rect)
    enabled = true
    if Icon.jp > 0
      draw_icon(Icon.jp, rect.x + rect.width - 24, rect.y, enabled)
      rect.width -= 24
    end
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, Vocab::jp, 2)
    rect.width -= text_size(Vocab::jp).width
    cost = skill.learn_cost[0]
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_JP), enabled)
    draw_text(rect, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # draw_exp_cost
  #--------------------------------------------------------------------------
  def draw_exp_cost(skill, rect)
    enabled = true
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, YEA::LEARN_SKILL::EXP_TEXT, 2)
    rect.width -= text_size(YEA::LEARN_SKILL::EXP_TEXT).width
    cost = skill.learn_cost[0]
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_EXP), enabled)
    draw_text(rect, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # draw_gold_cost
  #--------------------------------------------------------------------------
  def draw_gold_cost(skill, rect)
    enabled = true
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, Vocab::currency_unit, 2)
    rect.width -= text_size(Vocab::currency_unit).width
    cost = skill.learn_cost[0]
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_GOLD), enabled)
    draw_text(rect, text, 2)
  end
  
end # Window_LearnSkillCostBack

#==============================================================================
# â–  Window_LearnSkillCostFront
#==============================================================================

class Window_LearnSkillCostFront < Window_Command
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(item_window, cost_window)
    super((Graphics.width - window_width) / 2, 0)
    self.openness = 0
    self.opacity = 0
    @item_window = item_window
    @cost_window = cost_window
    @skill = nil
    @actor = nil
    deactivate
  end
  
  #--------------------------------------------------------------------------
  # window_width
  #--------------------------------------------------------------------------
  def window_width; return Graphics.width * 3 / 4; end
  
  #--------------------------------------------------------------------------
  # skill_class
  #--------------------------------------------------------------------------
  def skill_class
    return @skill_classes.nil? ? nil : @skill_classes[index]
  end
  
  #--------------------------------------------------------------------------
  # reveal
  #--------------------------------------------------------------------------
  def reveal(skill, skill_classes, actor)
    @skill = skill
    @skill_classes = skill_classes.clone
    @actor = actor
    return if @skill.nil?
    case @skill.learn_cost[1]
    when :gold
      self.height = fitting_height(2)
    else
      maximum = [skill_classes.size, YEA::LEARN_SKILL::MAXIMUM_ROWS].min
      self.height = fitting_height(maximum + 1)
    end
    create_contents
    self.y = @cost_window.y + line_height
    refresh
    select(0)
    open
    activate
  end
  
  #--------------------------------------------------------------------------
  # make_command_list
  #--------------------------------------------------------------------------
  def make_command_list
    return if @skill_classes.nil?
    if @skill.learn_cost[1] == :gold
      add_command("GOLD", :gold, true)
      add_command(YEA::LEARN_SKILL::LEARN_CANCEL_TEXT, :cancel, true)
      return
    end
    for class_id in @skill_classes
      name = $data_classes[class_id].name
      add_command(name, :class, enabled?(class_id), class_id)
    end
    add_command(YEA::LEARN_SKILL::LEARN_CANCEL_TEXT, :cancel, true)
  end
  
  #--------------------------------------------------------------------------
  # enabled?
  #--------------------------------------------------------------------------
  def enabled?(class_id)
    cost = @skill.learn_cost[0]
    case @skill.learn_cost[1]
    when :jp
      return @actor.jp(class_id) >= cost
    when :exp
      return @actor.exp_class(class_id) >= cost
    end
    return true
  end
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(index)
    reset_font_settings
    rect = item_rect(index)
    rect.x += 24
    rect.width -= 28
    return draw_cancel_text(index, rect) if @list[index][:symbol] == :cancel
    draw_class_name(index, rect) if @skill.learn_cost[1] != :gold
    draw_party_gold(rect) if @skill.learn_cost[1] == :gold
    draw_learn_skill_cost(@skill, rect, index)
  end
  
  #--------------------------------------------------------------------------
  # draw_cancel_text
  #--------------------------------------------------------------------------
  def draw_cancel_text(index, rect)
    draw_icon(Icon.cancel, rect.x, rect.y)
    text = command_name(index)
    draw_text(rect.x+24, rect.y, rect.width-24, line_height, text)
  end
  
  #--------------------------------------------------------------------------
  # draw_class_name
  #--------------------------------------------------------------------------
  def draw_class_name(index, rect)
    class_id = @list[index][:ext]
    return if $data_classes[class_id].nil?
    enabled = enabled?(class_id)
    if $imported["YEA-ClassSystem"]
      draw_icon($data_classes[class_id].icon_index, rect.x, rect.y, enabled)
    end
    rect.x += 24
    rect.width -= 24
    change_color(normal_color, enabled)
    draw_text(rect, $data_classes[class_id].name)
  end
  
  #--------------------------------------------------------------------------
  # draw_class_name
  #--------------------------------------------------------------------------
  def draw_party_gold(rect)
    enabled = true
    draw_icon(Icon.learn_skill_gold, rect.x, rect.y)
    rect.x += 24
    rect.width -= 24
    change_color(normal_color, enabled)
    draw_text(rect, YEA::LEARN_SKILL::GOLD_TEXT)
  end
  
  #--------------------------------------------------------------------------
  # draw_learn_skill_cost
  #--------------------------------------------------------------------------
  def draw_learn_skill_cost(skill, rect, index)
    case skill.learn_cost[1]
    when :jp
      return unless $imported["YEA-JPManager"]
      draw_jp_cost(skill, rect, index)
    when :exp
      draw_exp_cost(skill, rect, index)
    when :gold
      draw_gold_cost(skill, rect)
    else; return
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_jp_cost
  #--------------------------------------------------------------------------
  def draw_jp_cost(skill, rect, index)
    enabled = enabled?(@list[index][:ext])
    if Icon.jp > 0
      draw_icon(Icon.jp, rect.x + rect.width - 24, rect.y, enabled)
      rect.width -= 24
    end
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, Vocab::jp, 2)
    rect.width -= text_size(Vocab::jp).width
    cost = @actor.jp(@list[index][:ext])
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_JP), enabled)
    draw_text(rect, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # draw_exp_cost
  #--------------------------------------------------------------------------
  def draw_exp_cost(skill, rect, index)
    enabled = enabled?(@list[index][:ext])
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, YEA::LEARN_SKILL::EXP_TEXT, 2)
    rect.width -= text_size(YEA::LEARN_SKILL::EXP_TEXT).width
    cost = @actor.exp_class(@list[index][:ext])
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_EXP), enabled)
    draw_text(rect, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # draw_gold_cost
  #--------------------------------------------------------------------------
  def draw_gold_cost(skill, rect)
    enabled = $game_party.gold >= skill.learn_cost[0]
    contents.font.size = YEA::LEARN_SKILL::COST_SIZE
    change_color(system_color, enabled)
    draw_text(rect, Vocab::currency_unit, 2)
    rect.width -= text_size(Vocab::currency_unit).width
    cost = $game_party.gold
    text = cost.group
    change_color(text_color(YEA::LEARN_SKILL::COLOUR_GOLD), enabled)
    draw_text(rect, text, 2)
  end
  
end # Window_LearnSkillCostFront

#==============================================================================
# â–  Scene_Skill
#==============================================================================

class Scene_Skill < Scene_ItemBase
  
  #--------------------------------------------------------------------------
  # alias method: create_command_window
  #--------------------------------------------------------------------------
  alias scene_skill_create_command_window_lse create_command_window
  def create_command_window
    scene_skill_create_command_window_lse
    @command_window.set_handler(:learn_skill, method(:command_learn_skill))
  end
  
  #--------------------------------------------------------------------------
  # new method: command_learn_skill
  #--------------------------------------------------------------------------
  def command_learn_skill
    SceneManager.call(Scene_LearnSkill)
  end
  
end # Scene_Skill

#==============================================================================
# â–  Scene_LearnSkill
#==============================================================================

class Scene_LearnSkill < Scene_Skill
  
  #--------------------------------------------------------------------------
  # start
  #--------------------------------------------------------------------------
  def start
    super
    create_cost_windows
  end
  
  #--------------------------------------------------------------------------
  # create_command_window
  #--------------------------------------------------------------------------
  def create_command_window
    wy = @help_window.height
    @command_window = Window_LearnSkillCommand.new(0, wy)
    @command_window.viewport = @viewport
    @command_window.help_window = @help_window
    @command_window.actor = @actor
    @command_window.set_handler(:skill,    method(:command_skill))
    @command_window.set_handler(:cancel,   method(:return_scene))
    @command_window.set_handler(:pagedown, method(:next_actor))
    @command_window.set_handler(:pageup,   method(:prev_actor))
  end
  
  #--------------------------------------------------------------------------
  # create_item_window
  #--------------------------------------------------------------------------
  def create_item_window
    wx = 0
    wy = @status_window.y + @status_window.height
    ww = Graphics.width
    wh = Graphics.height - wy
    @item_window = Window_LearnSkillList.new(wx, wy, ww, wh)
    @item_window.actor = @actor
    @item_window.viewport = @viewport
    @item_window.help_window = @help_window
    @item_window.set_handler(:ok,     method(:on_item_ok))
    @item_window.set_handler(:cancel, method(:on_item_cancel))
    @command_window.skill_window = @item_window
  end
  
  #--------------------------------------------------------------------------
  # create_cost_windows
  #--------------------------------------------------------------------------
  def create_cost_windows
    @cost_window = Window_LearnSkillCostBack.new(@item_window)
    @cost_front = Window_LearnSkillCostFront.new(@item_window, @cost_window)
    @cost_window.viewport = @viewport
    @cost_front.viewport = @viewport
    @cost_front.set_handler(:ok, method(:on_cost_ok))
    @cost_front.set_handler(:cancel, method(:on_cost_cancel))
  end
  
  #--------------------------------------------------------------------------
  # on_item_ok
  #--------------------------------------------------------------------------
  def on_item_ok
    skill = @item_window.item
    @cost_window.reveal(skill, @item_window.skill_classes(skill))
    @cost_front.reveal(skill, @item_window.skill_classes(skill), @actor)
  end
  
  #--------------------------------------------------------------------------
  # on_cost_ok
  #--------------------------------------------------------------------------
  def on_cost_ok
    Sound.play_use_skill
    skill = @item_window.item
    @actor.learn_skill(skill.id)
    cost = skill.learn_cost[0]
    case skill.learn_cost[1]
    when :jp
      @actor.lose_jp(cost, @cost_front.skill_class)
    when :exp
      @actor.lose_exp_class(cost, @cost_front.skill_class)
    when :gold
      $game_party.lose_gold(cost)
    end
    on_cost_cancel
    refresh_windows
  end
  
  #--------------------------------------------------------------------------
  # on_cost_cancel
  #--------------------------------------------------------------------------
  def on_cost_cancel
    @cost_front.close
    @cost_window.close
    @item_window.activate
  end
  
  #--------------------------------------------------------------------------
  # refresh_windows
  #--------------------------------------------------------------------------
  def refresh_windows
    @item_window.refresh
    @status_window.refresh
  end
  
end # Scene_LearnSkill

#==============================================================================
# 
# â–¼ End of File
# 
#==============================================================================

 

 

 

Class System

 

 

#==============================================================================
# 
# â–¼ Yanfly Engine Ace - Class System v1.10
# -- Last Updated: 2012.01.29
# -- Level: Normal, Hard
# -- Requires: n/a
# 
#==============================================================================

$imported = {} if $imported.nil?
$imported["YEA-ClassSystem"] = true

#==============================================================================
# â–¼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 2012.08.06 - Leveling issue if class level exceeds actor level.
# 2012.01.29 - Visual Bug: Disabled classes now have faded icons.
# 2012.01.08 - Compatibility Update: Learn Skill Engine
# 2012.01.05 - Bug Fixed: Equipment no longer gets duplicated.
# 2012.01.04 - Update: Autobattle will no longer use skills not available to
#              that class for specific actors.
# 2012.01.02 - Efficiency Update.
# 2011.12.26 - Added custom command functionality.
# 2011.12.23 - Compatibility Update: Class Specifics.
# 2011.12.22 - Compatibility Update: Ace Menu Engine.
# 2011.12.20 - Compatibility Update: Class Unlock Level.
# 2011.12.19 - Started Script and Finished.
# 
#==============================================================================
# â–¼ Introduction
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# This script adds the ability for your player to freely change the classes of
# actors outside of battle from a menu. When changing classes, this script
# gives the option for the developer to choose whether or not classes have
# their own levels (causing the actor's level to reset back to the class's
# level) or to maintain the current level. In addition to providing the ability
# to change classes, equipping a subclass is also doable, and the mechanics of
# having a subclass can also be defined within this 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.
# 
# -----------------------------------------------------------------------------
# Actor Notetags - These notetags go in the actors notebox in the database.
# -----------------------------------------------------------------------------
# <unlocked classes: x>
# <unlocked classes: x, x>
# This will set the default classes as unlocked for the actor. This does not
# override the default classes unlocked in the module, but instead, adds on
# to the number of unlocked classes.
# 
# -----------------------------------------------------------------------------
# Class Notetags - These notetags go in the class notebox in the database.
# -----------------------------------------------------------------------------
# <icon: x>
# Sets the icon representing the class to x.
# 
# <help description>
#  string
#  string
# </help description>
# Sets the text used for the help window in the class scene. Multiple lines in
# the notebox will be strung together. Use | for a line break.
# 
# -----------------------------------------------------------------------------
# Script Calls - These commands are used with script calls.
# -----------------------------------------------------------------------------
# $game_actors[x].unlock_class(y)
# This allows actor x to unlock class y, making it available for switching in
# and out in the Class scene.
# 
# $game_actors[x].remove_class(y)
# This causes actor x to remove class y from being able to switch to and from.
# If the actor is currently class y, the class will not be removed. If the
# actor's current subclass is y, the subclass will be unequipped.
# 
#==============================================================================
# â–¼ Compatibility
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# This script is made strictly for RPG Maker VX Ace. It is highly unlikely that
# it will run with RPG Maker VX without adjusting.
# 
#==============================================================================

module YEA
  module CLASS_SYSTEM
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - General Class Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # These are the general settings regarding the whole script. They control
    # various rules and regulations that this script undergoes. These settings
    # will also determine what a subclass can do for a player.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    CLASS_MENU_TEXT = "Orbs"  # Text that appears in the Main Menu.
    MAINTAIN_LEVELS = true    # Maintain through all classes. Default: false.
    DEFAULT_UNLOCKS = [ ]   # Classes unlocked by default.
    
    # The display between a primary class and a subclass when written in a
    # window will appear as such.
    SUBCLASS_TEXT = "%s/%s"
    
    # This adjusts the stat rate inheritance for an actor if an actor has a
    # subclass equipped. If you want to disable this, set the rate to 0.0.
    SUBCLASS_STAT_RATE = 0.0
    
    # This adds subclass skill types to the available skill types usable.
    SUBCLASS_SKILL_TYPES = true
    
    # This adds subclass weapons to equippable weapon types.
    SUBCLASS_WEAPON_TYPES = false
    
    # This adds subclass weapons to equippable armour types.
    SUBCLASS_ARMOUR_TYPES = false
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Class Scene Commands -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # These settings adjust how the class scene appears. Here, you can adjust
    # the command list and the order at which items appear. These are mostly
    # visual settings. Adjust them as you see fit.
    # 
    # -------------------------------------------------------------------------
    # :command         Description
    # -------------------------------------------------------------------------
    # :primary         Allows the player to change the primary class.
    # :subclass        Allows the player to change the subclass.
    # 
    # :learn_skill     Requires YEA - Learn Skill Engine
    # 
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    COMMANDS =[ # The order at which the menu items are shown.
    # [ :command,   "Display"],
      [ :primary,   "Primary"],
      [ :subclass,  "Secondary"],
    # [:learn_skill, "Custom"],
    # [ :custom1,   "Custom1"],
    # [ :custom2,   "Custom2"],
    ] # Do not remove this.
    
    #--------------------------------------------------------------------------
    # - Status Class Commands -
    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # For those who use scripts to that may produce unique effects for the
    # class menu, use this hash to manage the custom commands for the Class
    # Command Window. You can disable certain commands or prevent them from
    # appearing by using switches. If you don't wish to bind them to a switch,
    # set the proper switch to 0 for it to have no impact.
    #--------------------------------------------------------------------------
    CUSTOM_CLASS_COMMANDS ={
    # :command => [EnableSwitch, ShowSwitch, Handler Method,
      :custom1 => [           0,          0, :command_name1],
      :custom2 => [           0,          0, :command_name2],
    } # Do not remove this.
    
    # These settings adjust the colour displays for classes.
    CURRENT_CLASS_COLOUR = 11     # "Window" colour used for current class.
    SUBCLASS_COLOUR      = 21      # "Window" colour used for subclass.
    
    # This adjusts the display for class levels if MAINTAIN_LEVELS is false.
    CLASS_LEVEL     = "LV%s"      # Text display for level.
    LEVEL_FONT_SIZE = 12          # Font size used for level.
    
    # This array sets the order of how classes are ordered in the class listing
    # window. Any class ID's unlisted will not be shown.
    CLASS_ORDER = [41..999, 1..40]
    
    # This adjusts the font size for the Parameters window.
    PARAM_FONT_SIZE = 12
    
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - Switch Settings -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # These are the switches that govern whether or not certain menu items will
    # appear and/or will be enabled. By binding them to a Switch, you can just
    # set the Switch ON/OFF to show/hide or enable/disable a menu command. If
    # you do not wish to use this feature, set these commands to 0.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    SWITCH_SHOW_CLASS      = 0    # Switch that shows Class in Main Menu.
    SWITCH_ENABLE_CLASS    = 0    # Switch that enables Class in Main Menu.
    SWITCH_SHOW_PRIMARY    = 0    # Switch that shows Subclass in Class Menu.
    SWITCH_ENABLE_PRIMARY  = 0    # Switch that enables Subclass in Class Menu.
    SWITCH_SHOW_SUBCLASS   = 0    # Switch that shows Subclass in Class Menu.
    SWITCH_ENABLE_SUBCLASS = 0    # Switch that enables Subclass in Class Menu.
    
  end # CLASS_SYSTEM
end # YEA

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

module YEA
  module CLASS_SYSTEM
    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
    #--------------------------------------------------------------------------
    # converted_contants
    #--------------------------------------------------------------------------
    DEFAULT_UNLOCKS = convert_integer_array(DEFAULT_UNLOCKS)
    CLASS_ORDER = convert_integer_array(CLASS_ORDER)
  end # CLASS_SYSTEM
  module REGEXP
  module ACTOR
    
    UNLOCKED_CLASSES = 
      /<(?:UNLOCKED_CLASSES|unlocked classes):[ ]*(\d+(?:\s*,\s*\d+)*)>/i
    
  end # ACTOR
  module CLASS
    
    ICON_INDEX = /<(?:ICON_INDEX|icon index|icon):[ ](\d+)>/i
    HELP_DESCRIPTION_ON  = /<(?:HELP_DESCRIPTION|help description)>/i
    HELP_DESCRIPTION_OFF = /<\/(?:HELP_DESCRIPTION|help description)>/i
    
  end # CLASS
  end # REGEXP
end # YEA

#==============================================================================
# â–  Switch
#==============================================================================

module Switch
  
  #--------------------------------------------------------------------------
  # self.class_show
  #--------------------------------------------------------------------------
  def self.class_show
    return true if YEA::CLASS_SYSTEM::SWITCH_SHOW_CLASS <= 0
    return $game_switches[YEA::CLASS_SYSTEM::SWITCH_SHOW_CLASS]
  end
  
  #--------------------------------------------------------------------------
  # self.class_enable
  #--------------------------------------------------------------------------
  def self.class_enable
    return true if YEA::CLASS_SYSTEM::SWITCH_ENABLE_CLASS <= 0
    return $game_switches[YEA::CLASS_SYSTEM::SWITCH_ENABLE_CLASS]
  end
  
  #--------------------------------------------------------------------------
  # self.primary_show
  #--------------------------------------------------------------------------
  def self.primary_show
    return true if YEA::CLASS_SYSTEM::SWITCH_SHOW_PRIMARY <= 0
    return $game_switches[YEA::CLASS_SYSTEM::SWITCH_SHOW_PRIMARY]
  end
  
  #--------------------------------------------------------------------------
  # self.primary_enable
  #--------------------------------------------------------------------------
  def self.primary_enable
    return true if YEA::CLASS_SYSTEM::SWITCH_ENABLE_PRIMARY <= 0
    return $game_switches[YEA::CLASS_SYSTEM::SWITCH_ENABLE_PRIMARY]
  end
  
  #--------------------------------------------------------------------------
  # self.subclass_show
  #--------------------------------------------------------------------------
  def self.subclass_show
    return true if YEA::CLASS_SYSTEM::SWITCH_SHOW_SUBCLASS <= 0
    return $game_switches[YEA::CLASS_SYSTEM::SWITCH_SHOW_SUBCLASS]
  end
  
  #--------------------------------------------------------------------------
  # self.subclass_enable
  #--------------------------------------------------------------------------
  def self.subclass_enable
    return true if YEA::CLASS_SYSTEM::SWITCH_ENABLE_SUBCLASS <= 0
    return $game_switches[YEA::CLASS_SYSTEM::SWITCH_ENABLE_SUBCLASS]
  end
    
end # Switch

#==============================================================================
# â–  Numeric
#==============================================================================

class Numeric
  
  #--------------------------------------------------------------------------
  # new method: group_digits
  #--------------------------------------------------------------------------
  unless $imported["YEA-CoreEngine"]
  def group; return self.to_s; end
  end # $imported["YEA-CoreEngine"]
    
end # Numeric

#==============================================================================
# â–  DataManager
#==============================================================================

module DataManager
  
  #--------------------------------------------------------------------------
  # alias method: load_database
  #--------------------------------------------------------------------------
  class <<self; alias load_database_cs load_database; end
  def self.load_database
    load_database_cs
    load_notetags_cs
  end
  
  #--------------------------------------------------------------------------
  # new method: load_notetags_cs
  #--------------------------------------------------------------------------
  def self.load_notetags_cs
    groups = [$data_actors, $data_classes]
    for group in groups
      for obj in group
        next if obj.nil?
        obj.load_notetags_cs
      end
    end
  end
  
end # DataManager

#==============================================================================
# â–  RPG::Actor
#==============================================================================

class RPG::Actor < RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :unlocked_classes
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_cs
  #--------------------------------------------------------------------------
  def load_notetags_cs
    @unlocked_classes = []
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::ACTOR::UNLOCKED_CLASSES
        $1.scan(/\d+/).each { |num| 
        @unlocked_classes.push(num.to_i) if num.to_i > 0 }
      #---
      end
    } # self.note.split
    #---
  end
  
end # RPG::Actor

#==============================================================================
# â–  RPG::Class
#==============================================================================

class RPG::Class < RPG::BaseItem
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :icon_index
  
  #--------------------------------------------------------------------------
  # common cache: load_notetags_cs
  #--------------------------------------------------------------------------
  def load_notetags_cs
    @icon_index = 0
    @help_description_on = false
    #---
    self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::CLASS::ICON_INDEX
        @icon_index = $1.to_i
      #---
      when YEA::REGEXP::CLASS::HELP_DESCRIPTION_ON
        @help_description_on = true
      when YEA::REGEXP::CLASS::HELP_DESCRIPTION_OFF
        @help_description_on = false
      #---
      else
        @description += line.to_s if @help_description_on
      end
    } # self.note.split
    #---
    @description.gsub!(/[|]/i) { "\n" }
  end
  
end # RPG::Class

#==============================================================================
# â–  Game_Temp
#==============================================================================

class Game_Temp
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :scene_class_index
  attr_accessor :scene_class_oy
  
end # Game_Temp

#==============================================================================
# â–  Game_Action
#==============================================================================

class Game_Action
  
  #--------------------------------------------------------------------------
  # alias method: valid?
  #--------------------------------------------------------------------------
  alias game_action_valid_cs valid?
  def valid?
    return false if check_auto_battle_class
    return game_action_valid_cs
  end
  
  #--------------------------------------------------------------------------
  # new method: check_auto_battle_class
  #--------------------------------------------------------------------------
  def check_auto_battle_class
    return false unless subject.actor?
    return false unless subject.auto_battle?
    return false if item.nil?
    return false if subject.added_skill_types.include?(item.stype_id)
    return false if item.id == subject.attack_skill_id
    return true
  end
  
end # Game_Action

#==============================================================================
# â–  Game_BattlerBase
#==============================================================================

class Game_BattlerBase
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :temp_flag
  
  #--------------------------------------------------------------------------
  # alias method: added_skill_types
  #--------------------------------------------------------------------------
  alias game_battlerbase_added_skill_types_cs added_skill_types
  def added_skill_types
    result = game_battlerbase_added_skill_types_cs
    result |= subclass_skill_types
    return result
  end
  
  #--------------------------------------------------------------------------
  # new method: subclass_skill_types
  #--------------------------------------------------------------------------
  def subclass_skill_types; return []; end
  
  #--------------------------------------------------------------------------
  # alias method: equip_wtype_ok?
  #--------------------------------------------------------------------------
  alias game_battlerbase_equip_wtype_ok_cs equip_wtype_ok?
  def equip_wtype_ok?(wtype_id)
    return true if subclass_equip_wtype?(wtype_id)
    return game_battlerbase_equip_wtype_ok_cs(wtype_id)
  end
  
  #--------------------------------------------------------------------------
  # new method: subclass_equip_wtype?
  #--------------------------------------------------------------------------
  def subclass_equip_wtype?(wtype_id); return false; end
  
  #--------------------------------------------------------------------------
  # alias method: equip_atype_ok?
  #--------------------------------------------------------------------------
  alias game_battlerbase_equip_atype_ok_cs equip_atype_ok?
  def equip_atype_ok?(atype_id)
    return true if subclass_equip_atype?(atype_id)
    return game_battlerbase_equip_atype_ok_cs(atype_id)
  end
  
  #--------------------------------------------------------------------------
  # new method: subclass_equip_atype?
  #--------------------------------------------------------------------------
  def subclass_equip_atype?(atype_id); return false; end
  
end # Game_BattlerBase

#==============================================================================
# â–  Game_Actor
#==============================================================================

class Game_Actor < Game_Battler
  
  #--------------------------------------------------------------------------
  # alias method: setup
  #--------------------------------------------------------------------------
  alias game_actor_setup_cs setup
  def setup(actor_id)
    game_actor_setup_cs(actor_id)
    init_unlocked_classes
    init_subclass
  end
  
  #--------------------------------------------------------------------------
  # new method: init_unlocked_classes
  #--------------------------------------------------------------------------
  def init_unlocked_classes
    @unlocked_classes = actor.unlocked_classes.clone
    @unlocked_classes.push(@class_id) if !@unlocked_classes.include?(@class_id)
    @unlocked_classes.sort!
  end
  
  #--------------------------------------------------------------------------
  # new method: init_subclass
  #--------------------------------------------------------------------------
  def init_subclass
    @subclass_id = 0
  end
  
  #--------------------------------------------------------------------------
  # new method: unlocked_classes
  #--------------------------------------------------------------------------
  def unlocked_classes
    init_unlocked_classes if @unlocked_classes.nil?
    return @unlocked_classes
  end
  
  #--------------------------------------------------------------------------
  # new method: unlock_class
  #--------------------------------------------------------------------------
  def unlock_class(class_id)
    init_unlocked_classes if @unlocked_classes.nil?
    return if @unlocked_classes.include?(class_id)
    @unlocked_classes.push(class_id)
    learn_class_skills(class_id)
  end
  
  #--------------------------------------------------------------------------
  # new method: remove_class
  #--------------------------------------------------------------------------
  def remove_class(class_id)
    init_unlocked_classes if @unlocked_classes.nil?
    return if class_id == @class_id
    @unlocked_classes.delete(class_id)
    @subclass_id = 0 if class_id == @subclass_id
    refresh
  end
  
  #--------------------------------------------------------------------------
  # new method: subclass
  #--------------------------------------------------------------------------
  def subclass
    init_subclass if @subclass_id.nil?
    return $data_classes[@subclass_id]
  end
  
  #--------------------------------------------------------------------------
  # alias method: change_class
  #--------------------------------------------------------------------------
  alias game_actor_change_class_cs change_class
  def change_class(class_id, keep_exp = false)
    @subclass_id = 0 if @subclass_id == class_id
    game_actor_change_class_cs(class_id, keep_exp)
    learn_class_skills(class_id)
    unlock_class(class_id)
  end
  
  #--------------------------------------------------------------------------
  # new method: learn_class_skills
  #--------------------------------------------------------------------------
  def learn_class_skills(class_id)
    return if class_id <= 0
    return if $data_classes[class_id].nil?
    $data_classes[class_id].learnings.each do |learning|
      learn_skill(learning.skill_id) if learning.level == class_level(class_id)
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: change_subclass
  #--------------------------------------------------------------------------
  def change_subclass(class_id)
    return if class_id == @class_id
    unlock_class(class_id)
    @subclass_id = @subclass_id == class_id ? 0 : class_id
    learn_class_skills(@subclass_id)
    refresh
  end
	#————————————————————————–
	# new method: class_level Edited by DisturbedInside
	#————————————————————————–
	def class_level(class_id)
		return @level if YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
			temp_class = $data_classes[class_id]
			@exp[class_id] = 0 if @exp[class_id].nil?
			#declare a max level (using EXP)
			#If you can’t find it, go to the class database and select exp curve
			#then switch view to total at the top
			@exp[max_level] = 2547133 #This is the value to change. It declares a max level
			#You need to calculate how much exp for max level
			#Do it manually if using Yanfly-Adjusting Limits
			#To calculate max level exp if using Yanfly-adjusting limits is all math!!

			# Level 99 = 2547133
			# to calculate past there…. have to add on multiples of 50744
			# Level 110 = 3156061
			# To go from 99 -> 110 have to add on 12 multiples of 50744.
			n = 1			
			loop do
				break if temp_class.exp_for_level(n+1) > @exp[class_id]
				n += 1
				#add a restriction to “kick out†of loop if exp exceeds max level exp
				break if temp_class.exp_for_level(n+1) > @exp[max_level]
			end
		return n
	end
  
  #--------------------------------------------------------------------------
  # new method: subclass_level
  #--------------------------------------------------------------------------
  def subclass_level
    return 0 if @subclass_id == 0
    return @level if YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
    return class_level(@subclass_id)
  end
  
  #--------------------------------------------------------------------------
  # alias method: param_base
  #--------------------------------------------------------------------------
  alias game_actor_param_base_cs param_base
  def param_base(param_id)
    result = game_actor_param_base_cs(param_id)
    unless subclass.nil?
      subclass_rate = YEA::CLASS_SYSTEM::SUBCLASS_STAT_RATE
      slevel = subclass_level
      result += subclass.params[param_id, slevel] * subclass_rate
    end
    return result.to_i
  end
  
  #--------------------------------------------------------------------------
  # new method: subclass_skill_types
  #--------------------------------------------------------------------------
  def subclass_skill_types
    return [] unless YEA::CLASS_SYSTEM::SUBCLASS_SKILL_TYPES
    return [] if subclass.nil?
    array = []
    for feature in subclass.features
      next unless feature.code == FEATURE_STYPE_ADD
      next if features_set(FEATURE_STYPE_ADD).include?(feature.data_id)
      array.push(feature.data_id)
    end
    return array
  end
  
  #--------------------------------------------------------------------------
  # new method: subclass_equip_wtype?
  #--------------------------------------------------------------------------
  def subclass_equip_wtype?(wtype_id)
    return false unless YEA::CLASS_SYSTEM::SUBCLASS_WEAPON_TYPES
    return false if subclass.nil?
    for feature in subclass.features
      next unless feature.code == FEATURE_EQUIP_WTYPE
      return true if wtype_id == feature.data_id
    end
    return super
  end
  
  #--------------------------------------------------------------------------
  # new method: subclass_equip_atype?
  #--------------------------------------------------------------------------
  def subclass_equip_atype?(atype_id)
    return false unless YEA::CLASS_SYSTEM::SUBCLASS_ARMOUR_TYPES
    return false if subclass.nil?
    for feature in subclass.features
      next unless feature.code == FEATURE_EQUIP_ATYPE
      return true if atype_id == feature.data_id
    end
    return super
  end
  
  #--------------------------------------------------------------------------
  # alias method: release_unequippable_items
  #--------------------------------------------------------------------------
  alias game_actor_release_unequippable_items_cs release_unequippable_items
  def release_unequippable_items(item_gain = true)
    item_gain = false if @temp_flag
    game_actor_release_unequippable_items_cs(item_gain)
  end
  
end # Game_Actor

#==============================================================================
# â–  Game_Interpreter
#==============================================================================

class Game_Interpreter
  
  #--------------------------------------------------------------------------
  # overwrite method: command_321
  #--------------------------------------------------------------------------
  def command_321
    actor = $game_actors[@params[0]]
    if actor && $data_classes[@params[1]]
      maintain = YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
      actor.change_class(@params[1], maintain)
    end
  end
  
end # Game_Interpreter

#==============================================================================
# â–  Window_Base
#==============================================================================

class Window_Base < Window
  
  #--------------------------------------------------------------------------
  # overwrite method: draw_actor_class
  #--------------------------------------------------------------------------
  def draw_actor_class(actor, x, y, width = 112)
    change_color(normal_color)
    if actor.subclass.nil?
      text = actor.class.name
    else
      fmt = YEA::CLASS_SYSTEM::SUBCLASS_TEXT
      text = sprintf(fmt, actor.class.name, actor.subclass.name)
    end
    draw_text(x, y, width, line_height, text)
  end
  
end # Window_Base

#==============================================================================
# â–  Window_MenuCommand
#==============================================================================

class Window_MenuCommand < Window_Command
  
  #--------------------------------------------------------------------------
  # alias method: add_formation_command
  #--------------------------------------------------------------------------
  alias window_menucommand_add_formation_command_cs add_formation_command
  def add_formation_command
    add_class_command unless $imported["YEA-AceMenuEngine"]
    window_menucommand_add_formation_command_cs
  end
  
  #--------------------------------------------------------------------------
  # new method: add_class_command
  #--------------------------------------------------------------------------
  def add_class_command
    return unless Switch.class_show
    text = YEA::CLASS_SYSTEM::CLASS_MENU_TEXT
    add_command(text, :class, Switch.class_enable)
  end
  
end # Window_MenuCommand

#==============================================================================
# â–  Window_ClassCommand
#==============================================================================

class Window_ClassCommand < Window_Command
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(x, y)
    super(x, y)
    @actor = nil
  end
  
  #--------------------------------------------------------------------------
  # ◠ウィンドウ幅ã®å–å¾—
  #--------------------------------------------------------------------------
  def window_width; return 160; end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(actor)
    return if @actor == actor
    @actor = actor
    refresh
  end
  
  #--------------------------------------------------------------------------
  # item_window=
  #--------------------------------------------------------------------------
  def item_window=(window)
    @item_window = window
  end
  
  #--------------------------------------------------------------------------
  # visible_line_number
  #--------------------------------------------------------------------------
  def visible_line_number; return 4; end
  
  #--------------------------------------------------------------------------
  # make_command_list
  #--------------------------------------------------------------------------
  def make_command_list
    return if @actor.nil?
    for command in YEA::CLASS_SYSTEM::COMMANDS
      case command[0]
      when :primary
        next unless Switch.primary_show
        add_command(command[1], command[0], Switch.primary_enable)
      when :subclass
        next unless Switch.subclass_show
        add_command(command[1], command[0], Switch.subclass_enable)
      when :learn_skill
        next unless $imported["YEA-LearnSkillEngine"]
        add_learn_skill_command
      else
        process_custom_command(command)
      end
    end
    if !$game_temp.scene_class_index.nil?
      select($game_temp.scene_class_index)
      self.oy = $game_temp.scene_class_oy
    end
    $game_temp.scene_class_index = nil
    $game_temp.scene_class_oy = nil
  end
  
  #--------------------------------------------------------------------------
  # process_ok
  #--------------------------------------------------------------------------
  def process_ok
    $game_temp.scene_class_index = index
    $game_temp.scene_class_oy = self.oy
    super
  end
  
  #--------------------------------------------------------------------------
  # process_custom_command
  #--------------------------------------------------------------------------
  def process_custom_command(command)
    return unless YEA::CLASS_SYSTEM::CUSTOM_CLASS_COMMANDS.include?(command[0])
    show = YEA::CLASS_SYSTEM::CUSTOM_CLASS_COMMANDS[command[0]][1]
    continue = show <= 0 ? true : $game_switches[show]
    return unless continue
    text = command[1]
    switch = YEA::CLASS_SYSTEM::CUSTOM_CLASS_COMMANDS[command[0]][0]
    enabled = switch <= 0 ? true : $game_switches[switch]
    add_command(text, command[0], enabled)
  end
  
  #--------------------------------------------------------------------------
  # update
  #--------------------------------------------------------------------------
  def update
    super
    update_visible_windows
  end
  
  #--------------------------------------------------------------------------
  # update_visible_windows
  #--------------------------------------------------------------------------
  def update_visible_windows
    return if @current_index == current_symbol
    @current_index = current_symbol
    @item_window.refresh unless @item_window.nil?
  end
  
  #--------------------------------------------------------------------------
  # add_learn_skill_command
  #--------------------------------------------------------------------------
  def add_learn_skill_command
    return unless Switch.show_learn_skill
    name = YEA::LEARN_SKILL::COMMAND_NAME
    add_command(name, :learn_skill, true)
  end
  
end # Window_ClassCommand

#==============================================================================
# â–  Window_ClassStatus
#==============================================================================

class Window_ClassStatus < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(dx, dy)
    super(dx, dy, window_width, fitting_height(4))
    @actor = nil
  end
  
  #--------------------------------------------------------------------------
  # window_width
  #--------------------------------------------------------------------------
  def window_width; Graphics.width - 160; end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(actor)
    return if @actor == actor
    @actor = actor
    refresh
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    contents.clear
    return if @actor.nil?
    draw_actor_face(@actor, 0, 0)
    draw_actor_simple_status(@actor, 108, line_height / 2)
  end
  
end # Window_ClassStatus

#==============================================================================
# â–  Window_ClassParam
#==============================================================================

class Window_ClassParam < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(dx, dy)
    super(dx, dy, window_width, Graphics.height - dy)
    @actor = nil
    @temp_actor = nil
    refresh
  end
  
  #--------------------------------------------------------------------------
  # window_width
  #--------------------------------------------------------------------------
  def window_width; return Graphics.width * 2 / 5; end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(actor)
    return if @actor == actor
    @actor = actor
    refresh
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    contents.clear
    8.times {|i| draw_item(0, line_height * i, i) }
  end
  
  #--------------------------------------------------------------------------
  # set_temp_actor
  #--------------------------------------------------------------------------
  def set_temp_actor(temp_actor)
    return if @temp_actor == temp_actor
    @temp_actor = temp_actor
    refresh
  end
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(dx, dy, param_id)
    draw_background_colour(dx, dy)
    draw_param_name(dx + 4, dy, param_id)
    draw_current_param(dx + 4, dy, param_id) if @actor
    drx = (contents.width + 22) / 2
    draw_right_arrow(drx, dy)
    draw_new_param(drx + 22, dy, param_id) if @temp_actor
    reset_font_settings
  end
  
  #--------------------------------------------------------------------------
  # draw_background_colour
  #--------------------------------------------------------------------------
  def draw_background_colour(dx, dy)
    colour = Color.new(0, 0, 0, translucent_alpha/2)
    rect = Rect.new(dx+1, dy+1, contents.width - 2, line_height - 2)
    contents.fill_rect(rect, colour)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: draw_param_name
  #--------------------------------------------------------------------------
  def draw_param_name(dx, dy, param_id)
    contents.font.size = YEA::CLASS_SYSTEM::PARAM_FONT_SIZE
    change_color(system_color)
    draw_text(dx, dy, contents.width, line_height, Vocab::param(param_id))
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: draw_current_param
  #--------------------------------------------------------------------------
  def draw_current_param(dx, dy, param_id)
    change_color(normal_color)
    dw = (contents.width + 22) / 2
    draw_text(0, dy, dw, line_height, @actor.param(param_id).group, 2)
    reset_font_settings
  end
  
  #--------------------------------------------------------------------------
  # draw_right_arrow
  #--------------------------------------------------------------------------
  def draw_right_arrow(x, y)
    change_color(system_color)
    draw_text(x, y, 22, line_height, "-", 1)
  end
  
  #--------------------------------------------------------------------------
  # draw_new_param
  #--------------------------------------------------------------------------
  def draw_new_param(dx, dy, param_id)
    contents.font.size = YEA::CLASS_SYSTEM::PARAM_FONT_SIZE
    new_value = @temp_actor.param(param_id)
    change_color(param_change_color(new_value - @actor.param(param_id)))
    draw_text(0, dy, contents.width-4, line_height, new_value.group, 2)
    reset_font_settings
  end
  
end # Window_ClassParam

#==============================================================================
# â–  Window_ClassList
#==============================================================================

class Window_ClassList < Window_Selectable
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(dx, dy)
    dw = Graphics.width - (Graphics.width * 2 / 5)
    dh = Graphics.height - dy
    super(dx, dy, dw, dh)
    @actor = nil
    @command_window = nil
    @status_window
    @data = []
  end
  
  #--------------------------------------------------------------------------
  # actor=
  #--------------------------------------------------------------------------
  def actor=(actor)
    return if @actor == actor
    @actor = actor
    @last_item = nil
    refresh
    self.oy = 0
  end
  
  #--------------------------------------------------------------------------
  # command_window=
  #--------------------------------------------------------------------------
  def command_window=(command_window)
    @command_window = command_window
  end
  
  #--------------------------------------------------------------------------
  # status_window=
  #--------------------------------------------------------------------------
  def status_window=(status_window)
    @status_window = status_window
  end
  
  #--------------------------------------------------------------------------
  # item_max
  #--------------------------------------------------------------------------
  def item_max; return @data ? @data.size : 1; end
  
  #--------------------------------------------------------------------------
  # item
  #--------------------------------------------------------------------------
  def item; return @data && index >= 0 ? @data[index] : nil; end
  
  #--------------------------------------------------------------------------
  # current_item_enabled?
  #--------------------------------------------------------------------------
  def current_item_enabled?; return enable?(@data[index]); end
  
  #--------------------------------------------------------------------------
  # include?
  #--------------------------------------------------------------------------
  def include?(item)
    return true if YEA::CLASS_SYSTEM::DEFAULT_UNLOCKS.include?(item.id)
    return @actor.unlocked_classes.include?(item.id)
  end
  
  #--------------------------------------------------------------------------
  # enable?
  #--------------------------------------------------------------------------
  def enable?(item)
    return false if item == @actor.class
    return true
  end
  
  #--------------------------------------------------------------------------
  # make_item_list
  #--------------------------------------------------------------------------
  def make_item_list
    @data = []
    for class_id in YEA::CLASS_SYSTEM::CLASS_ORDER
      next if $data_classes[class_id].nil?
      item = $data_classes[class_id]
      @data.push(item) if include?(item)
    end
  end
  
  #--------------------------------------------------------------------------
  # select_last
  #--------------------------------------------------------------------------
  def select_last
    case @command_window.current_symbol
    when :primary
      select(@data.index(@actor.class))
    when :subclass
      select(0) if @actor.subclass.nil?
      select(@data.index(@actor.subclass)) unless @actor.subclass.nil?
    else
      select(0)
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_item
  #--------------------------------------------------------------------------
  def draw_item(index)
    item = @data[index]
    return if item.nil?
    rect = item_rect(index)
    rect.width -= 4
    reset_font_settings
    set_item_colour(item)
    draw_class_icon(item, rect)
    draw_class_name(item, rect)
    draw_class_level(item, rect)
  end
  
  #--------------------------------------------------------------------------
  # set_item_colour
  #--------------------------------------------------------------------------
  def set_item_colour(item)
    if item == @actor.class
      change_color(text_color(YEA::CLASS_SYSTEM::CURRENT_CLASS_COLOUR))
    elsif item == @actor.subclass
      change_color(text_color(YEA::CLASS_SYSTEM::SUBCLASS_COLOUR))
    else
      change_color(normal_color, enable?(item))
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_class_icon
  #--------------------------------------------------------------------------
  def draw_class_icon(item, rect)
    icon = item.icon_index
    draw_icon(icon, rect.x, rect.y, enable?(item))
  end
  
  #--------------------------------------------------------------------------
  # draw_class_name
  #--------------------------------------------------------------------------
  def draw_class_name(item, rect)
    text = item.name
    draw_text(24, rect.y, rect.width-24, line_height, text)
  end
  
  #--------------------------------------------------------------------------
  # draw_class_level
  #--------------------------------------------------------------------------
  def draw_class_level(item, rect)
    return if YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
    return if @actor.nil?
    level = @actor.class_level(item.id)
    contents.font.size = YEA::CLASS_SYSTEM::LEVEL_FONT_SIZE
    text = sprintf(YEA::CLASS_SYSTEM::CLASS_LEVEL, level.group)
    draw_text(rect, text, 2)
  end
  
  #--------------------------------------------------------------------------
  # update_help
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_item(item)
    return if @actor.nil?
    return if @status_window.nil?
    update_param_window
  end
  
  #--------------------------------------------------------------------------
  # update_param_window
  #--------------------------------------------------------------------------
  def update_param_window
    return if @last_item == item
    @last_item = item
    class_id = item.nil? ? @actor.class_id : item.id
    temp_actor = Marshal.load(Marshal.dump(@actor))
    temp_actor.temp_flag = true
    case @command_window.current_symbol
    when :primary
      temp_actor.change_class(class_id, YEA::CLASS_SYSTEM::MAINTAIN_LEVELS)
    when :subclass
      temp_actor.change_subclass(class_id)
    end
    @status_window.set_temp_actor(temp_actor)
  end
  
  #--------------------------------------------------------------------------
  # update_class
  #--------------------------------------------------------------------------
  def update_class
    @last_item = nil
    update_help
    refresh
    activate
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    make_item_list
    create_contents
    draw_all_items
  end
  
end # Window_ClassList

#==============================================================================
# â–  Scene_Menu
#==============================================================================

class Scene_Menu < Scene_MenuBase
  
  #--------------------------------------------------------------------------
  # alias method: create_command_window
  #--------------------------------------------------------------------------
  alias scene_menu_create_command_window_cs create_command_window
  def create_command_window
    scene_menu_create_command_window_cs
    @command_window.set_handler(:class, method(:command_personal))
  end
  
  #--------------------------------------------------------------------------
  # alias method: on_personal_ok
  #--------------------------------------------------------------------------
  alias scene_menu_on_personal_ok_cs on_personal_ok
  def on_personal_ok
    case @command_window.current_symbol
    when :class
      SceneManager.call(Scene_Class)
    else
      scene_menu_on_personal_ok_cs
    end
  end
  
end # Scene_Menu

#==============================================================================
# â–  Scene_Class
#==============================================================================

class Scene_Class < Scene_MenuBase
  
  #--------------------------------------------------------------------------
  # start
  #--------------------------------------------------------------------------
  def start
    super
    create_help_window
    create_command_window
    create_status_window
    create_param_window
    create_item_window
    relocate_windows
  end
  
  #--------------------------------------------------------------------------
  # create_command_window
  #--------------------------------------------------------------------------
  def create_command_window
    wy = @help_window.height
    @command_window = Window_ClassCommand.new(0, wy)
    @command_window.viewport = @viewport
    @command_window.help_window = @help_window
    @command_window.actor = @actor
    @command_window.set_handler(:cancel,   method(:return_scene))
    @command_window.set_handler(:primary,  method(:command_class_change))
    @command_window.set_handler(:subclass, method(:command_class_change))
    process_custom_class_commands
    return if $game_party.in_battle
    @command_window.set_handler(:pagedown, method(:next_actor))
    @command_window.set_handler(:pageup,   method(:prev_actor))
    @command_window.set_handler(:learn_skill, method(:command_learn_skill))
  end
  
  #--------------------------------------------------------------------------
  # process_custom_class_commands
  #--------------------------------------------------------------------------
  def process_custom_class_commands
    for command in YEA::CLASS_SYSTEM::COMMANDS
      next unless YEA::CLASS_SYSTEM::CUSTOM_CLASS_COMMANDS.include?(command[0])
      called_method = YEA::CLASS_SYSTEM::CUSTOM_CLASS_COMMANDS[command[0]][2]
      @command_window.set_handler(command[0], method(called_method))
    end
  end
  
  #--------------------------------------------------------------------------
  # create_status_window
  #--------------------------------------------------------------------------
  def create_status_window
    wy = @help_window.height
    @status_window = Window_ClassStatus.new(@command_window.width, wy)
    @status_window.viewport = @viewport
    @status_window.actor = @actor
  end
  
  #--------------------------------------------------------------------------
  # create_param_window
  #--------------------------------------------------------------------------
  def create_param_window
    dx = Graphics.width - (Graphics.width * 2 / 5)
    dy = @status_window.y + @status_window.height
    @param_window = Window_ClassParam.new(dx, dy)
    @param_window.viewport = @viewport
    @param_window.actor = @actor
  end
  
  #--------------------------------------------------------------------------
  # create_item_window
  #--------------------------------------------------------------------------
  def create_item_window
    dy = @status_window.y + @status_window.height
    @item_window = Window_ClassList.new(0, dy)
    @item_window.help_window = @help_window
    @item_window.command_window = @command_window
    @item_window.status_window = @param_window
    @item_window.viewport = @viewport
    @item_window.actor = @actor
    @command_window.item_window = @item_window
    @item_window.set_handler(:ok,     method(:on_class_ok))
    @item_window.set_handler(:cancel, method(:on_class_cancel))
  end
  
  #--------------------------------------------------------------------------
  # relocate_windows
  #--------------------------------------------------------------------------
  def relocate_windows
    return unless $imported["YEA-AceMenuEngine"]
    case Menu.help_window_location
    when 0 # Top
      @help_window.y = 0
      @command_window.y = @help_window.height
      @param_window.y = @command_window.y + @command_window.height
    when 1 # Middle
      @command_window.y = 0
      @help_window.y = @command_window.height
      @param_window.y = @help_window.y + @help_window.height
    else # Bottom
      @command_window.y = 0
      @param_window.y = @command_window.height
      @help_window.y = @param_window.y + @param_window.height
    end
    @status_window.y = @command_window.y
    @item_window.y = @param_window.y
  end
  
  #--------------------------------------------------------------------------
  # on_actor_change
  #--------------------------------------------------------------------------
  def on_actor_change
    @command_window.actor = @actor
    @status_window.actor = @actor
    @param_window.actor = @actor
    @item_window.actor = @actor
    @command_window.activate
  end
  
  #--------------------------------------------------------------------------
  # command_class_change
  #--------------------------------------------------------------------------
  def command_class_change
    @item_window.activate
    @item_window.select_last
  end
  
  #--------------------------------------------------------------------------
  # on_class_cancel
  #--------------------------------------------------------------------------
  def on_class_cancel
    @item_window.unselect
    @command_window.activate
    @param_window.set_temp_actor(nil)
  end
  
  #--------------------------------------------------------------------------
  # on_class_ok
  #--------------------------------------------------------------------------
  def on_class_ok
    Sound.play_equip
    class_id = @item_window.item.id
    maintain = YEA::CLASS_SYSTEM::MAINTAIN_LEVELS
    hp = @actor.hp * 1.0 / @actor.mhp
    mp = @actor.mp * 1.0 / [@actor.mmp, 1].max
    case @command_window.current_symbol
    when :primary
      @actor.change_class(class_id, maintain)
    when :subclass
      @actor.change_subclass(class_id)
    else
      @item_window.activate
      return
    end
    @actor.hp = (@actor.mhp * hp).to_i
    @actor.mp = (@actor.mmp * mp).to_i
    @status_window.refresh
    @item_window.update_class
  end
  
  #--------------------------------------------------------------------------
  # new method: command_learn_skill
  #--------------------------------------------------------------------------
  def command_learn_skill
    return unless $imported["YEA-LearnSkillEngine"]
    SceneManager.call(Scene_LearnSkill)
  end
  
  #--------------------------------------------------------------------------
  # command_name1
  #--------------------------------------------------------------------------
  def command_name1
    # Do nothing.
  end
  
  #--------------------------------------------------------------------------
  # command_name2
  #--------------------------------------------------------------------------
  def command_name2
    # Do nothing.
  end
  
end # Scene_Class

#==============================================================================
# 
# â–¼ End of File
# 
#==============================================================================

 

 

 

 

 

I tried to make all my tests as uninfluenced as possible. They were all new games and I only did what was needed to make the appropriate tests. When I equipped subclasses, I did only that and ran a test battle to see the results. Each of these tests were new games. I even started a new project with the only materials being (in this order):

 

-Ace Core Engine
-Class System
-JP Manager
-Learn Skills
-Victory Aftermath
-Subclass Management

 

Eric is a Soldier by default, but I equipped Monk as his subclass. The battletest went by and completed unhindered by error. When I opened the menu to check my classes again, everything seemed fine. I even switched the subclass out for a new one (Sage), but then I selected my Primary and as soon as I hit confirm over the Primary, I got this error:

 

 

rmvxa_subclass_mgmt_error5.jpg

 

Edited by Settyness

Share this post


Link to post
Share on other sites

Oh, the NaN. Yay. I ran into that a few times already, apparently you can't divide by zero - who knew? *wry grin*  I also apparently forgot to re-enable it when I fixed it, since it's commented out. 

 

Line 251,

  goal_exp = (goal_exp / final_exp_rate) unless self.exp == 0 #|| final_exp_rate == 0

 

That should be: 

  goal_exp = (goal_exp / final_exp_rate) unless goal_exp == 0 || final_exp_rate == 0

 

Thanks a bunch for providing the scripts. Sorry, I was hoping maybe the problem was that there was a function somebody made as an add-in to it and it was somehow miraculously conflicting with the subclass manager script. It seems my hopes were in vain (and that I need to use something besides Opera on this site, since Opera is the one eating all my spacing when I paste into it or something, since you had no issues with it). I ran the same test with the fixed line of code, as well as another fixed line of code that had the same potential divide by zero problem, and the minimalist test you mentioned, and it ran completely through - it allowed me to change subclass and class, and gave me EXP/JP for each. (The script will be updated shortly.) I'll start importing the other scripts to see if I can find the bug and let you know when I hit on it.

Share this post


Link to post
Share on other sites

@Composer, Kimodengaged:

 

I added a section to the actor_setup definition that automatically sets an actor's @subclass_id and @sub_level to 0 and 1, respectively. I've also redefined 'init_subclass' instead of just aliasing it, and fine-tuned the language a little. This should (hopefully) clear up the nil subclass error. Note that you'll have to start a new game as well as check the 'initialize' button when you first introduce the actor to your party if adding them through the default GUI, in order for the @subclass_id and @sub_level fix to take effect. I'm still at a loss as to why it's sending nil instead of 0, since sub_id should automatically set @subclass_id to 0. I'm also at a loss as to why I can test run okay and not get the error message. Additionally, I I've fixed the bug where the default display_exp gives the wrong JP earned for the subclass.

 

Let me know if you still have any problems, and thanks for your patience. I don't have as much free time as I'd like to work on my scripts - work, college, and my son tends to take up most of it.

Edited by Ebonflame

Share this post


Link to post
Share on other sites

The error is still popping up. However, after i took out my XS Attribute System script everything works fine and my subclass is earning exp and jp well. No errors whatsoever.

Share this post


Link to post
Share on other sites

@ Composer, Klmodengaged: After many hours of staring blankly at it, I think I found the rather obvious problem... I think sub_exp was the one returning nil, so I added '|| @exp[@subclass_id].nil?' into the return 0 portion of sub_exp. I'm crossing my fingers that that's the problem - if it's not, I'm going to have to take it to the scripting help board to see if they can puzzle it out. I also put in checks to see if self.exp was nil and corrected if it was, since you could have the same problem there (I think). Also, I did a test run with the (four!?) scripts required to run XS' Attribute System, and it seemed to work okay after that. I didn't test extensively, though, so there might still be some conflict I missed. If any pop up, I'll check them out.

 

(please dear god let that be the problem... LOL)

Edited by Ebonflame

Share this post


Link to post
Share on other sites

Added PBG and subclass feature abilities, as well as level cap for subclasses. Updated Subclass Aftermath to reflect changes. I've done a lot more testing since then and haven't had that NilClass bug pop up. Is it working okay for you two?

Edited by Ebonflame

Share this post


Link to post
Share on other sites

Hi Ebonflame,

 

First of all, two thumbs up for you! For delivering the features you said you would as well as making these great scripts!

 

So far it is working very well without any problems. 

 

The subclass max level addition is a nice touch :)

 

I was just wondering if you ever plan on adding a feature of:

 

1. Default/from the start of the game subclass for each actor

 

2. Hide primary classes from subclass scene and vise versa (instead of the default graying out of each class).

 

3. Show/draw subclass JP on status menu/within the area of exp, hp, mp, tp etc. (like the draw_actor_jp but for subclasses)

 

And lastly, a clarification: what are your terms of use for your scripts? :D

Share this post


Link to post
Share on other sites

ravrax,

 

Thanks! :-) I'm glad it's working well - I hate those random bugs that pop up because I forget something really basic, haha. And nod, I saw someone post a request for it elsewhere and thought it'd be an easy, useful function to include.

 

1 - Probably. I was contemplating it, but haven't really decided either way (calling $game_actors[x].change_subclass(y) through the event editor when you first add an actor is pretty easy to do, but then again, automated is usually better)

 

2 - Wouldn't even know where to start with that one. Maybe, depending on how complicated it is. It's pretty iffy, though.

 

3 - Briefly looked at the functions already included for drawing the actors' class JP, got dizzy, and had to lie down. o.0 Kidding! I did look at it, but I could never get the actors' main class JP to show up in my status window/main window through the default options anyway. I see the spot where it would probably go, but it doesn't appear on mine and I must be overlooking the option to make it show up. If I could figure out what I'm doing wrong (maybe I have to write the code to make it appear, but why would he include draw_actor_jp if there wasn't a way to make it show up also included?), I'd figure out how to include it in the status window... but I don't like working blind, haha. If I can't see it, I can't figure out what's wrong with it - I'm not foolish enough to believe I'm all so great that I don't need to test things. *grins*

 

Err, sorry - I rambled a bit. o.0 Main point for 3: It's a slightly-less-iffy 'maybe, if I can manage to make the main class' JP appear in the status window (or main menu, even) to start with.' Probably something simple I'm overlooking, but meh.

 

As for clarification on my terms: yeah, should have included that in the main post, come to think of it. Haha oh well.

 

- Free to use in any game, commercial or non-commercial

- Credit would be extremely welcome, but not required

- No reposting these scripts elsewhere; come to me if you want them posted and I'll put 'em up for you if possible

Edited by Ebonflame

Share this post


Link to post
Share on other sites

Let's see..where to start :P

 

1. Cool. I agree that automated is easier but I'm not going to be too picky about it haha...I'm content with the event call that you pointed out on.

 

2. No worries about that, I just thought of it just a while ago after some testing that the hide option is not really that much needed. It was purely for vanity reasons. 

 

3. That's sure some good ol' rambling :D I'm not sure if this helps but I was able to draw the main class actor JP to the main menu by adding this line under the "draw_actor_simple_status" area:

 

Line code:

 

draw_actor_jp(actor, x, y, w)

 

Hope it helps with the retrieval of the elusive subclass JP.

Share this post


Link to post
Share on other sites

ravrax,

 

I'm working on it, the weekends are just pretty hectic for me. I've decided to go ahead and include the initial subclass and subclass level in the notetags also, since changing the actor's subclass level is slightly more tricky than just changing the subclass - you'd have to use something like $game_actors[x].gain_exp($game_actors[x].subclass.exp_for_level(y), 2). I'm not sure what the exact format would be off the top of my head, but it's still a tad more complicated and could probably cause a nilClass error if the actor doesn't have a subclass. Also, there's currently a couple of bugs I'm fixing - they're pretty elusive, but there nontheless. I'll have it done within the next couple of days. And yeah, it does help - thanks! :-). I hadn't touched the window area of scripting yet, haha. After fiddling with it for a bit, I think I've mostly got the hang of it.

Share this post


Link to post
Share on other sites

Sounds good! This script just keeps getting better and better with each new added functionality! I'm glad I was able to help out. Keep in touch :D

Share this post


Link to post
Share on other sites

*pant, pant* Ooookay, now that I've mastered the ancient art of math-ese... Seriously. Geesh. Did I mention I failed Algebra? But I think I finally got all of the math squared away (along with that horrible regex), so feel free to test out the awesome new features!

 

- You can now view your subclass' JP in the main menu

- Your actors can now have an initial subclass and subclass level (put the following notetag in your actor's notes box: <initial subclass: x at lvl y>, where x is the class ID and y is the level to start out with). There's also a couple of different ways you could format it... x @ y, x at y, x at lvl y, and x at lv y will all work.

- I tweaked gain_exp a bit; if you specify class/subclass, it will add the exp value sent, with no modifiers (no bonus for single class, and no reduced exp for subclass). Seemed slightly more useful to me that way.

- As a bonus, you can now make your actor forget subclass skills learned in that subclass if they switch from that subclass, until they switch back to that subclass. I added a constant to allow you to do so automatically, but the two nifty little functions I had to add in there can also add/remove class skills from another class to/from your actor's available skills list. They'll add skills learned in the other class up to a certain level or make the actor forget any skills the other class learned above a certain level, depending on which is called. Kind of complicated to explain, though, so I left it out of the script calls info... lol. If you want to use the functions in another way than adding/removing skills from the actor's subclass on subclass change, let me know and I'll see if I can't explain them a little better.

 

I really wanted to include JP in the status menu, but... well, there's just no room for it as the status menu currently stands. :-/ So instead I tweaked the draw_actor_simple_status you mentioned, and now it draws it on the main menu. One good thing, though - it also draws it in the skills and class screen, so you can see how much JP your main class and subclass has at a glance. Should be good enough, yeah?

 

Oh, but try to keep the numbers your actors gain kind of low. Anything higher than eight numbers (four in each class) looks tremendously ugly. It also starts creeping toward your actor's face graphic, and the script will eventually give up and just display the actor's main class' JP if it runs out of extra room (as in, giving it more would spill over onto the face graphic) and the text just can't be squeezed any smaller.

 

Let me know what you think, ravrax. :-)

Edited by Ebonflame

Share this post


Link to post
Share on other sites

I am flabbergasted in a very good way. (pardon my urge to use some weird underrated words)

 

Heyyy Ebonflame! This is a great update! I'd give you a glass of water to help relieve you of your suffering/panting if I could haha :D

 

As of this moment, I might just have tried every single aspect of the new features except for the forget subclass skills(I'll save some for later :P) So moving along, I have news on each feature for you!

 

 

1. After plugging in the script, I encountered a Syntax Error on Line 1406:

 

Error:

 

unexpected ')', expecting ']'

 

Then I changed

 

Line 1406:

 

!class_unlock_level_requirements_met?($data_classes[class_id)]

 

to

 

!class_unlock_level_requirements_met?[$data_classes(class_id)]

 

Then the error did not show up again after that.

 

2. Initial subclass - There seems to be a little bug crawling around. Whenever I put the <initial subclass: x at level y> in an actor's notebox, this error pops up when I test the game:

 

Script 'YEA- Class Unlock Level' line 159: NoMethodError Occurred  

 

Correct me if I'm wrong but I have a feeling that the change I made to Line 1406 has a connection with this error?

 

3. Subclass JP in main menu - High Ten!

 

4. JP on status menu - You're right, the JP showing up on the skills and class screen is enough. However, for some reason it does not show up on my skills and class status window. I might be missing something here. Any clue?

 

5. JP amount - No worries I dabbled a bit with the JP aesthetics so that it would fit my menu nicely. :D

 

 

Let you know what I think?

 

I think if I were to make a game exclusively of only one script, I'd pick yours.

Share this post


Link to post
Share on other sites

*Smiles* you totally just made all that hard work worth it. ;-) Haha but seriously, thanks. Your appreciation is much appreciated. ^^

 

1) Oops, darn brackets and parenthesis got me again.

 

!class_unlock_level_requirements_met?($data_classes[class_id)]

 the last parenthesis should be outside the bracket, not inside ---^

 

It should say !class_unlock_level_requirements_met?($data_classes[class_id]). I switched the last parenthesis with the last bracket by accident. I might've done it with the other one too, I'll take a look just to make sure.

 

2) Yep, changing the beginning parenthesis to a bracket is what messed it up. I also didn't put 'at level' in the regexp, just 'at lvl' and 'at lv.' I'll go add it :-) (Wish I truly understood how the regexp worked, though - my regexp is looking rather unnecessarily complicated, and I know there's a way to record the second number with it and call it back using $2 instead of $1 or something. The way I'm doing it works, but I know it's not the most efficient. All those slashes and quantifiers scare the bejebus outtta me.)

 

3) Sweeeeet! That was undoubtedly the hardest part of the entire thing, haha. Glad no bugs popped up there.

 

4) H'mmm... my first instinct is to say there's something not calling draw_actor_simple_status, since that's what I've aliased to call draw_actor_jp_classes. It could also be something redefining draw_actor_simple_status, but then draw_actor_jp_classes shouldn't appear at all, as opposed to only disappearing in the class and skills windows. The problem scripts aren't Learn Skills Engine or Parameter Growth, since those both work above or below the class system script and its add-ons. Where's your Yanfly Menu System (if you have it installed)? Above the Class System scripts?

 

Nod, my best guess is something is not calling draw_actor_simple_status somewhere. It shows up in the core classes 'Window_Base' (the original definition), 'Window_MenuBase' (called in 'draw_item'),  and 'Window_SkillStatus' (called in 'refresh'). You could do ctrl+shift+f and search for 'Window_Base,' 'Window_MenuBase,' and 'Window_SkillStatus,' then scroll through the custom scripts you have that modify the relative functions/definitions within those classes (draw_actor_simple_status, draw_item, and refresh, respectively) if you want. If something is modifying any of those, you could add the following lines into the definition to force it to call draw_actor_jp_classes:

 

    if $imported["EBON-SubManager"]
      dy -= line_height / 2 if $imported["YEA-AceMenuEngine"]
      draw_actor_jp_classes(actor, actor.class_id, dx+3, dy + line_height * 3) if

        EBON::DISPLAY_JP
    end

 

If nothing pops up when you search, I'll take a closer look at my script list and we can start comparing. My script list is pretty basic; there's only ~25 or so scripts that I'm using/specifically making the SubManager compatible with as needed.

 

5 - Cool, that was something I was pretty worried about. When I did the test runs, I'd gain about 4k JP in each class for leveling, and had the icon drawn so I had the minimum amount of space possible. Things got pretty gnarly-looking, haha! "What is this...? I can barely read the stupid JP... oi... well, I mean, I could put it up under the TP guage too I guess, but there's probably a reason that third line over there is empty..." And so on. I even dabbled with the idea of extending the width of the JP and drawing a gauge or something under it so that it wouldn't look too horrible when it extended onto the actor's face graphic, XD.

 

Aww... I could just hop through this wifi and kiss you right now. ;-) No offense intended. *grins* Seriously, though, thanks for being so patient. :-)

 

PS: I just noticed a pretty significant bug in the Class System script, which I also have in mine: when you switch classes/subclasses, it doesn't unequip weapons/armor that you can no longer wear/wield! I wonder why that wasn't built into the change_class function? Oh well, just something else I'll have to fix, haha.

 

Edit: *frowns* Hey, have you noticed it in your Class System script, or is it just a fluke? Even if I disable my subclass manager script, I still get it when I change classes. And I'm having a hard time tracing it. :-/

Edited by Ebonflame

Share this post


Link to post
Share on other sites

*Smiles back*

 

 

1. Those DARN brackets and parenthesis always get me too! :D

 

2. That's good news! Now the problem is quickly fixed with the domino effect.

 

3. DARN bugs.

 

4. Great! That's all I needed to fix it.

 

5. I believe the show JP function you made is good enough because it not only gave the right amount of core information but also it provided a spacious room for customization.

 

6. Significant bug in the class system script - Really? Hmm..that's quite strange because I just tried it with your subclass manager script and when I switched my class/subclass, my character's equipment were automatically unequipped. Maybe it has something to do with one of the other ~25 scripts you have there?

 

 

No offense taken AT ALL..but honey ain't this going a little bit too fast, I don't even know your name yet. :P

Share this post


Link to post
Share on other sites

1 - Hahaha, glad I'm not the only one who gets tripped up by those brackets/parenthesis.

 

2 - Cool, glad it was easily resolved.

 

3 - Nod, I know, right?

 

4 - Awesome! Wasn't sure what the problem was if that wasn't it, haha.

Edit: I had to modify draw_simple_status because there's nowhere to put the JP if you have the default menu. So now it corrects the line_height irregardless of whether or not you have YEA - Ace Menu Engine installed. Sorry! I'll update the original script shortly.

 

*** New draw_actor_simple_status:

 

  def draw_actor_simple_status(actor, dx, dy)
    dy -= line_height / 2 if !$imported["YEA-AceMenuEngine"] #<-- this is what changed
    game_window_draw_actor_simple_status_cs(actor, dx, dy)
    if EBON::DISPLAY_JP
      dy2 = $imported["YEA-AceMenuEngine"] ? dy - line_height / 2 : dy #<-- this also changed
      draw_actor_jp_classes(actor, actor.class_id, dx+3, dy2 + #<-- and this too (dy2 vs dy)
        line_height * 3) if EBON::DISPLAY_JP
    end
  end

 

*** New function to add to your thingy:

 

  if $imported["EBON-SubManager"]
      dy2 = $imported["YEA-AceMenuEngine"] ? dy - line_height / 2 : dy  #<-- this changed, needs to have the draw_actor_simple_status above

      draw_actor_jp_classes(actor, actor.class_id, dx+3, dy2 +

        line_height * 3) if EBON::DISPLAY_JP
  end

 

5 - Whew, good. To be honest, I'm pretty tired of working on that function. The math, man, the math! D-:< *winks*

 

6 - H'mm, nod. It's quite possible... I'll start up a fresh project and see what happens.

Edit: Yeah, it's got something to do with another script. Or I messed up the core scripts with all my fiddling... either way, it works in a fresh project. Now to figure out what, exactly, the problem is in the original project. I've had to restart this project about three times already, lol, not doing it again. But I did discover that bug that would have creeped out from under the wood at some later point anyway, so that's a good thing.

 

 What? No name? Bah, humbug... excuses, excuses... my name is right up here, see? Ebonflame. ;-) And you're ravrax... now we have enough for an e-kiss, yes? *laughs* Just playin' with ya, totally understandable. *grins*

Edited by Ebonflame

Share this post


Link to post
Share on other sites

I have some minor bad news..I found a new bug with Yanfly's JP Manager. 

 

Whenever I use a healing item of any sort through the item menu, this error pops up:

 

Popup:

 

No method error occurred undefined method `+' for nil:NilClass

 

Then I changed Line 1281

 

From

 

Line 1281:

 

@battle_sub_jp_earned += value if jp == YEA::JP::ACTION_JP

 

To 

 

 

@battle_sub_jp_earned = value if jp == YEA::JP::ACTION_JP
 
After that it was working, however, it seems that whenever I use a healing item on a character through the item menu, its JP also increases in relation to the amount of JP earned per action as set in the JP Manager's script settings. Is there a way to stop the JP from increasing when healing items are used through the item menu?
 
This is the first time I've ever heard of the word humbug..interesting. "e-kiss" haha You do know that you're making me more curious of what your real name is now do ya? :D

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
Top ArrowTop Arrow Highlighted