Chaos Project

RPG Maker => RPG Maker Scripts => Script Troubleshooting => Topic started by: Zephor on January 18, 2011, 05:27:42 pm

Title: Nevermind again, got a new problem!
Post by: Zephor on January 18, 2011, 05:27:42 pm
Well I have another problem now and this one might be a bit trickier to explain but here it goes. Okay, so I'm using the Stat Distribution and Job/Skill script (both by Blizzard). The problem is that in the game I'm working on, there is only one playable character. But as seen in these following images, it gives the options of next and previous. I tried just removing them but then it looks all ugly.

What I would like to do is maybe replace it with another option. For example in the first screen shot, have the next character instead bring you to skills and previous character bring me to some other screen. Get what I mean? How would I go about doing this.

(http://i54.tinypic.com/2ibhrom.png)

(http://i54.tinypic.com/voa0ew.png)

(http://i51.tinypic.com/10woc91.png)

Btw, here's the two scripts if you need them. LOOK DOWN TO MY OTHER POST FOR SECOND SCRIPT.

Spoiler: ShowHide
Quote#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# RO Job/Skill System by Blizzard
# Version: 2.01b
# Type: Ragnarok Online Job/Skill System Clone
# Date: 5.11.2007
# Date 1.0b: 4.1.2008
# Date 1.01b: 4.1.2008
# Date 1.2b: 26.1.2008
# Date 1.3b: 2.6.2008
# Date 1.4b: 8.6.2008
# Date 1.5b: 6.8.2008
# Date 1.6b: 23.11.2009
# Date 2.0b: 17.2.2010
# Date 2.01b: 4.9.2010
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#  
#  This work is protected by the following license:
# #----------------------------------------------------------------------------
# #  
# #  Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
# #  ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
# #  
# #  You are free:
# #  
# #  to Share - to copy, distribute and transmit the work
# #  to Remix -- to adapt the work
# #  
# #  Under the following conditions:
# #  
# #  Attribution. You must attribute the work in the manner specified by the
# #  author or licensor (but not in any way that suggests that they endorse you
# #  or your use of the work).
# #  
# #  Noncommercial. You may not use this work for commercial purposes.
# #  
# #  Share alike. If you alter, transform, or build upon this work, you may
# #  distribute the resulting work only under the same or similar license to
# #  this one.
# #  
# #  - For any reuse or distribution, you must make clear to others the license
# #    terms of this work. The best way to do this is with a link to this web
# #    page.
# #  
# #  - Any of the above conditions can be waived if you get permission from the
# #    copyright holder.
# #  
# #  - Nothing in this license impairs or restricts the author's moral rights.
# #  
# #----------------------------------------------------------------------------
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
#   Special Thanks for requesting this goes to Nightfox!
#
#
# new in 1.0b:
#   - fixed font problem
#   - now beta
#
# new in 1.01b:
#   - fixed a crash problem where enemies would be tested on skill levels
#
# new in 1.2b:
#   - actors can now learn Chaos Drive transformation skills through this
#     system (REQUIRES CRLS 5.0 OR HIGHER)
#   - classes/jobs now can have stat modifiers
#
# new in 1.3b:
#   - skills can now have other skills as requirements
#
# new in 1.4b:
#   - added option to hide skills that haven't met the prerequisites yet
#   - improved coding and the way data display is being refreshed
#
# new in 1.5b:
#   - fixed bug with forgetting skills
#   - added option to forget all skills from other classes when changing the
#     class
#
# new in 1.6b:
#   - now more compatible with Blizz-ABS 2.57
#
# new in 2.0b:
#   - fixed bug where HP/SP wouldn't apply when the max HP/SP were decreased
#   - fixed bug with skill usage when JOB_ONLY was not active
#   - now more compatible with Blizz-ABS 2.7
#   - improved coding
#
# new in 2.01b:
#   - fixed bug when activating JOB_ONLY
#
#  
# Compatibility:
#  
#   95% compatible with SDK v1.x, 60% compatible with SDK v2.x. Can cause
#   incompatibility issues with other exotic Skill Systems, CMS-es and CBS-es.
#   Fully compatible with Blizz-ABS, not compatible with Mr. Mo's ABS. WILL
#   corrupt old savegames.
#
#
# Explanantion:
#  
#   This script allows you to use a skill system that is very similar to the
#   skill system of the MMORPG Ragnarok Online. By gaining jobs and job levels
#   the characters get points which they can use to learn and make skills
#   stronger. Stronger skills have a higher numerical effect and lower SP cost.
#   This script also allows the usage of a job change system.
#  
#  
# Features:
#  
#   - job/class level and and change system
#   - skill level system that can be turned off as well
#   - gain Job Points for each Job Level and use them to power up your skills
#     or learn new ones
#   - increased SP cost and decreased skill power for skills that have not
#     been improved to the maximum level
#   - two fully functional scenes for class changing and skill
#     learning/improving
#   - easy setup and use
#   - compatible with Blizz-ABS and RTAB
#   - wide range of possible uses
#  
#  
# Instructions:
#  
# - How the system works:
#  
#   When a skill is learned, its power is less than 100%, its SP cost is higher
#   than 100% and its level is 1. To learn a skill only 1 JP (Job Point) is
#   needed. For every increase of the skill's level another JP is needed. When
#   the skill has reached its maximum level, the power is exactly 100% and the
#   SP cost exactly is 100%. Everything between is linearry distributed.
#  
#   Example:
#     Skill ID:       15
#     Min Lvl:         1
#     Max Lvl:        11
#     Lvl 1 Power:    20%
#     Max Power:     100%
#     Lvl 1 Cost:    150%
#     Min Cost:      100%
#   These would be the statistics of a skill at level 5:
#     Current Lvl:     5
#     Current Power:  52%
#     Current Cost:  130%
#  
# - Configuration
#  
#   INIT_JP      - initial number of Job Points
#   LVL1_POWER   - set this number to the percentage of the skill power a skill
#                  should have when having level 1
#   LVL1_COST    - set this number to the percentage of the CP cost a skill
#                  should have when having level 1
#   LVLUP_RATE   - if you have the feeling that you reach a job level to
#                  quickly increase this number or the other way around
#   EXP_RATIO    - this number determines the JOBEXP / EXP ratio in percents
#                  (i.e. if you set number to 144 and get 2000 EXP, you will
#                  get 2880 JOBEXP)
#   RESET_LVLS   - if you set this value to true, each skill that is forgotten
#                  will be completely deleted, the JP will NOT be returned, you
#                  have to do that manually
#   JOB_ONLY     - if you set this value to true, the skill level system will
#                  be turned off completely
#   USE_LEVEL    - if you set this value to true, the level required for a
#                  class change is not the current class' job level, but the
#                  real level
#   USE_ALL      - if you set this value to true, a character is not allowed to
#                  change his job as long as his JP are not zero, this creates
#                  virtually the impression that each class his its own JP
#   CLASS_SKILLS - if you set this value to true, all skills learned from one
#                  class will be removed, this option does not affect the game
#                  if the JOB_ONLY option is being used
#   HIDE_SKILLS  - if you se this to true, skills won't be displayed in the
#                  window where you can learn skills until all requirements are
#                  met
#   RO_RIGHT     - if you set this value to true, the windows in the scenes
#                  will appear at the right side
#   EVASION      - name displayed for the attribute "Evasion"
#   UP_COLOR     - color of text that displays increasing stats
#   DOWN_COLOR   - color of text that displays decreasing stats
#   CD_SKILLS    - if you are using CRLS and want actors to be able to learn CD
#                  skills through this system, you need to include all
#                  learnable IDs of CD skills so the system knows that those
#                  are not normal skills, but CD skills
#  
#   Press CTRL+F and type "START RO Skill Database" (without the double quotes)
#   and setup your skill database. The skills available for a job/class are the
#   ones you specify in your class database. The level required to be able to
#   learn a skill is now the job level. In other words, you need the given job
#   level to be able to learn that specific skill.
#  
#
# Additional Informations:
#  
#   If you wish to call the class change scene, use a "Call Script" event
#   command and type following command into the window:
#  
#     $scene = Scene_ClassChange.new
#  
#   If you wish to call the job point distribution scene, use this command:
#  
#     $scene = Scene_SkillChange.new
#  
#   If you want to manually change a skill and/or job level/EXP, simply use:
#  
#     $game_actors[ID].skill_level_change(NUMBER, S_ID)
#     $game_actors[ID].job_level_change(NUMBER, C_ID)
#     $game_actors[ID].add_job_exp(NUMBER, C_ID)
#  
#   ID     - ID of the actor in the database
#   C_ID   - ID of the class in the database
#   S_ID   - ID of the skill in the database
#   NUMBER - numeric value
#  
#   If you leave out C_ID, the current class ID will be used. Keep in mind that
#   you can CHANGE skill and job level, but you can only INCREASE Job EXP.
#   You can also manually change the value of the Job Points.
#  
#     $game_actors[ID].jp = NUMBER
#  
#   Keep in mind that increasing the job level manually will cause that JP are
#   being increased as well while decreasing the job level will NOT cause the
#   JP to decrease.
#   Here are the formulas for new effect and cost calculation for reference.
#  
#     effect = ORIGINAL * (LVL1_POWER + (skill_level - 1) *
#              (100 - LVL1_POWER) / (skill_maxlevel - 1)) / 100
#     cost   = ORIGINAL * (LVL1_COST - (skill_level - 1) *
#              (LVL1_COST - 100) / (skill_maxlevel - 1)) / 100
#  
#   This is the formula for calculation of how much EXP are needed to reach
#   the next job level.
#
#     EXP_needed_for_lvl(lvl) = LVLUP_RATE * lvl * (lvl - 1)
#  
#  
# Important note:
#  
#   If you use this system to learn CD skills, it is recommended that you leave
#   the skills' maximum level at only 1 as the consumption cost of the stats
#   cannot change in CRLS. CD skills also don't appear in the improvement
#   screen. Don't forget that you need to let the class be able to learn the CD
#   skills just like a normal skill. If you don't have CRLS installed, the
#   skill will be learned as if it was a normal skill.
#  
#  
# If you find any bugs, please report them here:
# http://forum.chaos-project.com
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

# used for compatibility
$ro_jobskill_clone = 2.01

#==============================================================================
# module BlizzCFG
#------------------------------------------------------------------------------
#  This module serves for configuration in my scripts and for consistency.
#==============================================================================

module BlizzCFG
 
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 INIT_JP = 1
 LVL1_POWER = 50
 LVL1_COST = 200
 LVLUP_RATE = 20
 EXP_RATIO = 50
 RESET_LVLS = false
 JOB_ONLY = false
 USE_LEVEL = false
 USE_ALL = false
 CLASS_SKILLS = !false
 HIDE_SKILLS = false
 RO_RIGHT = false
 EVASION = 'EVA'
 UP_COLOR = Color.new(0, 255, 0) # (R, G, B)
 DOWN_COLOR = Color.new(255, 0, 0) # (R, G, B)
 CD_SKILLS = [61]
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

 def self.roskill_maxlevel(id)
   case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START RO Skill Database
#
#   You can define the max level of each skill here. Use following template to
#   set up your configuration:
#
#     when ID then return NUMBER
#
#   ID     - the skill ID
#   NUMBER - the maximum level
#
#   Note that using values lower than 1 WILL CAUSE BUGS! Default value is 1 and
#   skills that are not defined here will have the default value automatically
#   applied.
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   when 57 then return 5
   #when 61 then return 3
   when 62 then return 5
   when 63 then return 10
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END RO Skill Database
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   end
   return 1
 end
 
 def self.roskill_reqs(id)
   case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START RO Skill Requirement Database
#
#   You have the option to make skills require not only a specific level, but
#   other skills and their levels as well. Such a skill will not appear in the
#   list of skills until all requirements are met.
#   Use following template to set up your configuration:
#
#     when ID then return [[SKILL_ID1, MIN_LEVEL1], [SKILL_ID2, MIN_LEVEL2], ...]
#
#   ID        - the skill ID
#   SKILL_ID  - ID of the required skill
#   MIN_LEVEL - minimum required level of the required skill
#
#   You can add as many requirements as you want, separate them with commas.
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   when 2 then return [[1, 2]]
   when 62 then return [[61, 1], [63, 4]]
   when 3 then return [[1, 3], [2, 2]]
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END RO Skill Requirement Database
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   end
   return []
 end
 
 def self.rojob_maxlevel(id)
   case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START RO Job Database
#
#   You can define the max level of each job here. Use following template to
#   set up your configuration:
#
#     when ID then return NUMBER
#
#   ID     - the class ID
#   NUMBER - the maximum level
#
#   Note that using values lower than 1 WILL CAUSE BUGS! Default value is 1 and
#   jobs that are not defined here will have the default value automatically
#   applied.
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   when 1 then return 50
   when 2 then return 50
   when 3 then return 50
   when 4 then return 50
   when 5 then return 50
   when 6 then return 50
   when 7 then return 50
   when 8 then return 50
   when 9 then return 50
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END RO Job Database
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   end
   return 1
 end
 
 def self.rojob_next(id)
   case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START RO Job-Connection Database
#  
#   Here you can define job change trees. When you have one job active you can
#   change to any other job that is defined here. It is possible to define
#   recursive trees where a class can be changed back as well without problems.
#   Use following template to set up your configuration:
#
#     when ID then return [[MIN_LEVEL1, NEW_ID1], [MIN_LEVEL2, NEW_ID2], ...]
#
#   ID        - the current class ID
#   MIN_LEVEL - minimum level required to be allowed to change
#   NEW_ID    - the ID of the new class
#
#   You can add as many next classes as you want, separate them with commas.
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   when 1 then return [[10, 2]]
   when 2 then return [[1, 1], [10, 3]]
   when 3 then return [[1, 2], [10, 4]]
   when 4 then return [[1, 3], [10, 5]]
   when 5 then return [[1, 4], [10, 6]]
   when 6 then return [[1, 5], [10, 7]]
   when 7 then return [[1, 6], [10, 8]]
   when 8 then return [[1, 7], [10, 9]]
   when 9 then return [[1, 8]]
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END RO Job-Connection Database
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   end
   return [[]]
 end
 
 def self.job_stat_mod(id)
   p_maxhp = p_maxsp = p_str = p_dex = p_agi = p_int = 0
   m_maxhp = m_maxsp = m_str = m_dex = m_agi = m_int = 1.0
   case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Job Stat Modifier Database
#  
#   You are able to set up modifiers for actor stats that change depending on
#   the current job. Use following template to set up your configuration:
#
#     when ID
#       p_maxhp = PLUS
#       p_maxsp = PLUS
#       p_str = PLUS
#       p_dex = PLUS
#       p_agi = PLUS
#       p_int = PLUS
#       m_maxhp = MULTI
#       m_maxsp = MULTI
#       m_str = MULTI
#       m_dex = MULTI
#       m_agi = MULTI
#       m_int = MULTI
#
#     ID    - the current class ID
#     PLUS  - an integer value (default is 0)
#     MULTI - a decimal value (default is 1.0)
#
#   The values that have p_ before that name are static modifiers. For example,
#   if you use 100, then the given stat will increase by 100 if the actor has
#   the given class. If you use -200, then it will decrease by 200 from the
#   actor's basis.
#   The values that have m_ before that name are dynamic modifiers. For
#   example, if you use 1.1, then the given stat will increase by 10% if the
#   actor has the given class. If you use 0.8, then it will decrease by 20%
#   from the actor's basis.
#  
# Note:
#  
#   It might be a good idea to create a neutral class if you are using this
#   feature. If you don't set up a class here, then the default values will be
#   applied. Keep in mind that first all static modifiers will be applied and
#   afterwards the dynamic modifiers.
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   when 1
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.0
     m_maxsp = 1.0
     m_str = 1.0
     m_dex = 1.0
     m_agi = 1.0
     m_int = 1.0
   when 2
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.1
     m_maxsp = 1.0
     m_str = 1.1
     m_dex = 1.0
     m_agi = 1.0
     m_int = 0.9
   when 3
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.2
     m_maxsp = 1.1
     m_str = 1.0
     m_dex = 0.9
     m_agi = 1.1
     m_int = 0.9
   when 4
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.0
     m_maxsp = 1.0
     m_str = 1.0
     m_dex = 1.2
     m_agi = 0.9
     m_int = 1.1
   when 5
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.0
     m_maxsp = 1.0
     m_str = 1.0
     m_dex = 1.0
     m_agi = 1.0
     m_int = 1.0
   when 6
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.0
     m_maxsp = 1.0
     m_str = 1.0
     m_dex = 1.0
     m_agi = 1.0
     m_int = 1.0
   when 7
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.0
     m_maxsp = 1.0
     m_str = 1.0
     m_dex = 1.0
     m_agi = 1.0
     m_int = 1.0
   when 8
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.0
     m_maxsp = 1.0
     m_str = 1.0
     m_dex = 1.0
     m_agi = 1.0
     m_int = 1.0
   when 9
     p_maxhp = 0
     p_maxsp = 0
     p_str = 0
     p_dex = 0
     p_agi = 0
     p_int = 0
     m_maxhp = 1.0
     m_maxsp = 1.0
     m_str = 1.0
     m_dex = 1.0
     m_agi = 1.0
     m_int = 1.0
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END RO Job Stat Modifier Database
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   end
   return [p_maxhp, m_maxhp, p_maxsp, m_maxsp, p_str, m_str, p_dex, m_dex,
       p_agi, m_agi, p_int, m_int]
 end
 
 # constants
 
 YesNo = ['Yes', 'No']
 AreYouSure = 'Are you sure?'
 Current = 'Current'
 JobPoints = 'Class Points'
 JobLevel = 'Class Level'
 JobEXP = 'Class EXP'
 EXP = 'EXP'
 Next = 'Next'
 EmptyEXP = '------'
 None = 'None'
 Lv = 'Lv'
 SkillLevel = 'Skill Level'
 MaximumLevel = 'Maximum Level'
 Cost = 'Cost'
 Power = 'Power'
 ClassCommands = ['Select', 'Next', 'Previous', 'Exit']
 ChangeClass = 'Change Class?'
 SkillCommands = ['Learn new Skill', 'Improve Skill', 'Next', 'Previous', 'Exit']
 LearnSkill = 'Learn Skill?'
 ImproveSkill = 'Improve Skill?'
 
end

#==============================================================================
# Game_Actor
#------------------------------------------------------------------------------
#  This class was enhanced with various additional variables to make this
#  system work properly. Also a number of methods were added to handle the new
#  data.
#==============================================================================

class Game_Actor
 
 # setting all accessible variables
 attr_accessor :jp
 #----------------------------------------------------------------------------
 # override setup
 #  Adds some hashes for additional data.
 #----------------------------------------------------------------------------
 alias setup_skilllevels_later setup
 def setup(id)
   @skill_level, @job_level, @job_exp, @jp = {}, {}, {}, BlizzCFG::INIT_JP
   setup_skilllevels_later(id)
   @skills = [] unless BlizzCFG::JOB_ONLY
 end
 #----------------------------------------------------------------------------
 # job_level
 #  id - class ID
 #  Safe return of any job level, current job level is default.
 #----------------------------------------------------------------------------
 def job_level(id = @class_id)
   return (@job_level[id] == nil ? 1 : @job_level[id])
 end
 #----------------------------------------------------------------------------
 # job_exp
 #  id - class ID
 #  Safe return of any job exp, current job exp are default.
 #----------------------------------------------------------------------------
 def job_exp(id = @class_id)
   return (@job_exp[id] == nil ? 0 : @job_exp[id])
 end
 #----------------------------------------------------------------------------
 # job_level_change
 #  val  - new level value
 #  id   - class ID
 #  flag - determines whether EXP should be updated or not
 #  This method processes change of a job level.
 #----------------------------------------------------------------------------
 def job_level_change(val, id = @class_id, flag = true)
   # get level
   new_level = BlizzCFG.rojob_maxlevel(id)
   # limit level value
   if new_level > val
     new_level = val
   elsif new_level < 1
     new_level = 1
   end
   # get Job Points
   jp = new_level - self.job_level(id)
   # increase Job Points
   @jp += jp if jp > 0
   # set new Job level
   @job_level[id] = new_level
   # set Job EXP if the setting flag is active
   @job_exp[id] = BlizzCFG::LVLUP_RATE * new_level * (new_level - 1) if flag
 end
 #----------------------------------------------------------------------------
 # override exp=
 #  val  - new exp value
 #  This method was modified to add job EXP each time real EXP are added.
 #----------------------------------------------------------------------------
 alias exp_is_rosys_later exp=
 def exp=(val)
   # store old EXP and skills
   old_exp, skills = @exp, @skills.clone
   exp_is_rosys_later(val)
   # no skills can be learned, remove any learned skills
   @skills = skills
   # increase Job EXP
   exp = @exp - old_exp
   add_job_exp(exp * BlizzCFG::EXP_RATIO / 100) if exp > 0
 end
 #----------------------------------------------------------------------------
 # add_job_exp
 #  val - new exp value
 #  id  - class ID
 #  This method executes job exp increasing.
 #----------------------------------------------------------------------------
 def add_job_exp(val, id = @class_id)
   max_level = BlizzCFG.rojob_maxlevel(id)
   # set new Job EXP
   exp1 = self.job_exp(id) + val
   exp2 = BlizzCFG::LVLUP_RATE * max_level * (max_level - 1)
   @job_exp[id] = (exp1 < exp2 ? exp1 : exp)
   # as long as Job level can be increased
   while self.job_level(id) < max_level && self.job_exp(id) >=
       BlizzCFG::LVLUP_RATE * self.job_level(id) * (self.job_level(id) + 1)
     # increase Job level
     job_level_change(self.job_level(id) + 1, id, false)
   end
 end
 #----------------------------------------------------------------------------
 # job_max_level?
 #  Checks if the Job's level is at the maximum.
 #----------------------------------------------------------------------------
 def job_max_level?
   return (self.job_level >= BlizzCFG.rojob_maxlevel(@class_id))
 end
 #----------------------------------------------------------------------------
 # override base_maxhp
 #  This method was changed to allow class stat modifiers.
 #----------------------------------------------------------------------------
 alias base_maxhp_rosys_later base_maxhp
 def base_maxhp
   result, mods = base_maxhp_rosys_later, BlizzCFG.job_stat_mod(@class_id)
   return ((result + mods[0]) * mods[1]).to_i
 end
 #----------------------------------------------------------------------------
 # override base_maxsp
 #  This method was changed to allow class stat modifiers.
 #----------------------------------------------------------------------------
 alias base_maxsp_rosys_later base_maxsp
 def base_maxsp
   result, mods = base_maxsp_rosys_later, BlizzCFG.job_stat_mod(@class_id)
   return ((result + mods[2]) * mods[3]).to_i
 end
 #----------------------------------------------------------------------------
 # override base_str
 #  This method was changed to allow class stat modifiers.
 #----------------------------------------------------------------------------
 alias base_str_rosys_later base_str
 def base_str
   result, mods = base_str_rosys_later, BlizzCFG.job_stat_mod(@class_id)
   return ((result + mods[4]) * mods[5]).to_i
 end
 #----------------------------------------------------------------------------
 # override base_dex
 #  This method was changed to allow class stat modifiers.
 #----------------------------------------------------------------------------
 alias base_dex_rosys_later base_dex
 def base_dex
   result, mods = base_dex_rosys_later, BlizzCFG.job_stat_mod(@class_id)
   return ((result + mods[6]) * mods[7]).to_i
 end
 #----------------------------------------------------------------------------
 # override base_agi
 #  This method was changed to allow class stat modifiers.
 #----------------------------------------------------------------------------
 alias base_agi_rosys_later base_agi
 def base_agi
   result, mods = base_agi_rosys_later, BlizzCFG.job_stat_mod(@class_id)
   return ((result + mods[8]) * mods[9]).to_i
 end
 #----------------------------------------------------------------------------
 # override base_int
 #  This method was changed to allow class stat modifiers.
 #----------------------------------------------------------------------------
 alias base_int_rosys_later base_int
 def base_int
   result, mods = base_int_rosys_later, BlizzCFG.job_stat_mod(@class_id)
   return ((result + mods[10]) * mods[11]).to_i
 end
 #----------------------------------------------------------------------------
 # get_skill_sp_cost_factor
 #  skill_id - skill ID
 #  Returns the SP cost factor of the skill for this actor.
 #----------------------------------------------------------------------------
 def get_skill_sp_cost_factor(skill_id)
   return 1 if skill_max_level?(skill_id)
   return ((BlizzCFG::LVL1_COST - (self.skill_level(skill_id) - 1) *
       (BlizzCFG::LVL1_COST - 100.0) /
       (BlizzCFG.roskill_maxlevel(skill_id) - 1)) / 100)
 end
 #----------------------------------------------------------------------------
 # get_skill_damage_factor
 #  skill_id - skill ID
 #  Returns the damage factor of the skill for this actor.
 #----------------------------------------------------------------------------
 def get_skill_damage_factor(skill_id)
   return 1 if skill_max_level?(skill_id)
   return (BlizzCFG::LVL1_POWER + (self.skill_level(skill_id) - 1) *
       (100.0 - BlizzCFG::LVL1_POWER) /
       (BlizzCFG.roskill_maxlevel(skill_id) - 1)) / 100
 end
 #----------------------------------------------------------------------------
 # skill_max_level?
 #  skill_id - skill ID
 #  Checks if a skill has reached the max level.
 #----------------------------------------------------------------------------
 def skill_max_level?(skill_id)
   return (self.skill_level(skill_id) >= BlizzCFG.roskill_maxlevel(skill_id))
 end
 # if the JOB_ONLY option is not being used, a couple of methods are being
 # parsed for skill level handling
 unless BlizzCFG::JOB_ONLY
 #----------------------------------------------------------------------------
 # skill_level
 #  id - skill ID
 #  Safe return of a skill level for this actor.
 #----------------------------------------------------------------------------
 def skill_level(id)
   return (@skill_level[id] == nil ? 1 : @skill_level[id])
 end
 #----------------------------------------------------------------------------
 # skill_level_change
 #  val - new level value
 #  id  - skill ID
 #  This method processes change of a skill level.
 #----------------------------------------------------------------------------
 def skill_level_change(val, id)
   max_level = BlizzCFG.roskill_maxlevel(id)
   if val > max_level
     @skill_level[id] = max_level
   elsif max_level < 1
     @skill_level[id] = 1
   else
     @skill_level[id] = val
   end
 end
 #----------------------------------------------------------------------------
 # override forget_skill
 #  id - skill ID
 #  This method additionally resets a level when a skill gets removed.
 #----------------------------------------------------------------------------
 alias forget_skill_rosys_later forget_skill
 def forget_skill(id)
   learned = @skills.include?(id)
   forget_skill_rosys_later(id)
   # reset skill level of forgotten skill if that option is active
   @skill_level[id] = 1 if BlizzCFG::RESET_LVLS && learned && !@skills.include?(id)
 end
 #----------------------------------------------------------------------------
 # override skill_can_use?
 #  skill_id - skill ID
 #  This method additionally takes into account the increased SP cost.
 #----------------------------------------------------------------------------
 alias skill_can_use_rosys_later? skill_can_use?
 def skill_can_use?(skill_id)
   skill = $data_skills[skill_id]
   # if not enough SP considering skill level SP cost modification
   if self.sp < (skill.sp_cost * get_skill_sp_cost_factor(skill.id)).to_i
     # skill cannot be used
     return false
   end
   return skill_can_use_rosys_later?(skill_id)
 end
 end
 
end

#==============================================================================
# Game_Battler
#------------------------------------------------------------------------------
#  This class was modified to support skill levels.
#==============================================================================

unless BlizzCFG::JOB_ONLY
class Game_Battler
 
 #----------------------------------------------------------------------------
 # override skill_effect
 #  user  - the skill performer
 #  skill - the skill
 #  This method was modified to support changed damage handling.
 #----------------------------------------------------------------------------
 alias skill_effect_rosys_later skill_effect
 def skill_effect(user, skill)
   # stores old values and executes skill
   last_hp = self.hp
   last_sr = self.sr if $crls && self.is_a?(Game_Actor)
   result = skill_effect_rosys_later(user, skill)
   # if skill was a success and effect needs to be modified
   if result && self.damage.is_a?(Numeric) && user.is_a?(Game_Actor) &&
       !user.skill_max_level?(skill.id)
     # restore values
     self.hp = last_hp
     self.sr = last_sr if $crls && self.is_a?(Game_Actor)
     # modifiy damage considering skill level
     self.damage = (self.damage * user.get_skill_damage_factor(skill.id)).to_i
     # apply skill effect on HP
     self.hp -= self.damage
   end
   return result
 end
 
end

#==============================================================================
# Window_Skill
#------------------------------------------------------------------------------
#  This class was modified to display correct SP consumption if skill levels
#  are being used.
#==============================================================================

class Window_Skill < Window_Selectable
 
 #--------------------------------------------------------------------------
 # override draw_item
 #  i - index
 #  This method was modified to print the correct SP cost.
 #--------------------------------------------------------------------------
 alias draw_item_rosys_later draw_item
 def draw_item(i)
   draw_item_rosys_later(i)
   skill = @data
   # decide color depending on the fact if currently usable
   if @actor.skill_can_use?(skill.id)
     self.contents.font.color = normal_color
   else
     self.contents.font.color = disabled_color
   end
   # remove old SP display
   self.contents.fill_rect(236 + i % 2 * 320, i / 2 * 32, 48, 32,
       Color.new(0, 0, 0, 0))
   # calculate SP cost considering skill level
   sp_cost = (skill.sp_cost * @actor.get_skill_sp_cost_factor(skill.id)).to_i
   # draw SP cost
   self.contents.draw_text(236 + i % 2 * 320, i / 2 * 32, 48, 32,
       sp_cost.to_s, 2)
 end
 
end

#==============================================================================
# Map_Battler
#------------------------------------------------------------------------------
#  This is a Blizz-ABS class.
#==============================================================================

# if Blizz-ABS is being used
if $BlizzABS && BlizzABS::VERSION >= 2.7
class Map_Battler
 
 #----------------------------------------------------------------------------
 # override skill_consumption
 #  Corrects SP consumption in Blizz-ABS.
 #----------------------------------------------------------------------------
 alias skill_consumption_rosys_later skill_consumption
 def skill_consumption(skill)
   if self.is_a?(Map_Actor) && !@battler.skill_max_level?(skill.id)
     skill = skill.clone
     skill.sp_cost = (skill.sp_cost *
         @actor.get_skill_sp_cost_factor(skill.id)).to_i
     if $tons_version != nil && $tons_version >= 7.4 && $game_system.HP_SKILL
       skill.hp_cost = (skill.hp_cost *
           @actor.get_skill_sp_cost_factor(skill.id)).to_i
     end
   end
   skill_consumption_rosys_later(skill)
 end
 
end

#==============================================================================
# Hud
#------------------------------------------------------------------------------
#  This is a Blizz-ABS class.
#==============================================================================

class Hud < Sprite
 
 def get_skills_left
   # stop if skill is not hot skill or does not exist
   return -2 if @skill == nil || @skill == 0
   # infinite usages if SP cost is zero
   return -1 if $data_skills[@skill].sp_cost == 0
   # get SP cost
   sp_cost = ($data_skills[@skill].sp_cost *
       actor.get_skill_sp_cost_factor(@skill)).to_i
   # if using SP Cost Mod Status
   if $tons_version != nil && $tons_version >= 6.54 &&
       $game_system.SP_COST_MOD
     # get modified cost
     sp_cost = BlizzCFG.get_cost_mod(actor.states, sp_cost)
   end
   # infinite usages if SP cost is zero
   return -1 if sp_cost == 0
   # calculate skills left to use
   return (@sp / sp_cost)
 end
 
end
end

#==============================================================================
# Scene_Battle
#------------------------------------------------------------------------------
#  This class was modified to support correct SP consumption if skill levels
#  are being used.
#==============================================================================

class Scene_Battle
 
 #----------------------------------------------------------------------------
 # override use_skill
 #  skill - the skill to be used
 #  Corrects SP consumption in DBS and RTAB.
 #----------------------------------------------------------------------------
 alias make_skill_action_result_rosys_later make_skill_action_result
 def make_skill_action_result(battler = nil)
   # if RTAB is being used
   if battler != nil
     # store old SP and make result
     old_sp = battler.sp
     make_skill_action_result_rosys_later(battler)
   else
     # store old SP and make result
     old_sp, battler = @active_battler.sp, @active_battler
     make_skill_action_result_rosys_later
   end
   # if skill was really used and SP consumption needs to be modified
   if battler.is_a?(Game_Actor) && @phase4_step != 1 &&
       battler.sp != @skill.sp_cost && !battler.skill_max_level?(@skill.id)
     # change SP considering skill level
     battler.sp = old_sp - (@skill.sp_cost *
       actor.get_skill_sp_cost_factor(@skill.id)).to_i
     @status_window.refresh
   end
 end
 
end
end

#==============================================================================
# Window_Base
#------------------------------------------------------------------------------
#  This class was enhanced with a few drawing utility mehods.
#==============================================================================

class Window_Base < Window
 
 #----------------------------------------------------------------------------
 # draw_actor_battler
 #  actor - the actor
 #  x     - x coordinate
 #  y     - y coordinate
 #  Draws the actor's battler graphic in a window.
 #----------------------------------------------------------------------------
 def draw_actor_battler(actor, x, y)
   # get bitmap and dimentions
   bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
   cw, ch = bitmap.width, bitmap.height
   src_rect = Rect.new(0, 0, cw, ch)
   # transfer bitmap on window
   self.contents.blt(x - cw / 2, y - ch / 2, bitmap, src_rect)
 end
 #----------------------------------------------------------------------------
 # draw_actor_job
 #  actor - the actor
 #  x     - x coordinate
 #  y     - y coordinate
 #  width - max width
 #  Draws the actor's job data.
 #----------------------------------------------------------------------------
 def draw_actor_job(actor, x, y, width)
   self.contents.font.color = system_color
   # draw all static system words
   self.contents.draw_text(x, y, width, 32, BlizzCFG::Current + ':')
   self.contents.draw_text(x, y + 32, width, 32, BlizzCFG::JobPoints + ':')
   self.contents.draw_text(x, y + 64, width, 32, BlizzCFG::JobLevel + ':')
   self.contents.draw_text(x, y + 96, width, 32, BlizzCFG::JobEXP + ':')
   self.contents.draw_text(x, y + 128, width, 32, BlizzCFG::Next + ':')
   self.contents.font.color = normal_color
   # draw all the data
   self.contents.draw_text(x, y, width, 32, actor.class_name, 2)
   self.contents.draw_text(x, y + 64, width, 32, actor.job_level.to_s, 2)
   self.contents.draw_text(x, y + 96, width, 32, actor.job_exp.to_s, 2)
   nex = BlizzCFG::LVLUP_RATE * actor.job_level * (actor.job_level + 1)
   if actor.job_max_level?
     self.contents.draw_text(x, y + 128, width, 32, BlizzCFG::EmptyEXP, 2)
   else
     self.contents.draw_text(x, y + 128, width, 32,
         (nex - actor.job_exp).to_s, 2)
   end
   # change color to red if no Job Points left
   self.contents.font.color = Color.new(255, 0, 0) if actor.jp == 0
   self.contents.draw_text(x, y + 32, width, 32, actor.jp.to_s, 2)
 end
 
end

#==============================================================================
# Window_Dialog
#------------------------------------------------------------------------------
#  Confirmation Dialog window class.
#==============================================================================

class Window_Dialog < Window_Command
 
 #----------------------------------------------------------------------------
 # Initialization
 #----------------------------------------------------------------------------
 def initialize(width, commands = BlizzCFG::YesNo,
       caption = BlizzCFG::AreYouSure)
   # add another command, serves as fix
   commands = commands + ['']
   # set caption
   @caption = caption
   @cursor_width = 32
   super(width, commands)
   # font fix
   if $fontface != nil
     self.contents.font.name = $fontface
     self.contents.font.size = $fontsize
   elsif $defaultfonttype != nil
     self.contents.font.name = $defaultfonttype
     self.contents.font.size = $defaultfontsize
   end
   # set variables
   self.x, self.y, self.z = 320 - self.width / 2, 200 - self.height / 2, 1500
   @item_max, self.opacity = commands.size - 1, 192
   commands.each {|c|
       w = self.contents.text_size(c).width
       @cursor_width = w if @cursor_width < w}
   @cursor_width += 32
   # refresh display
   refresh
   update_cursor_rect
 end
 #----------------------------------------------------------------------------
 # refresh
 #  Added caption text.
 #----------------------------------------------------------------------------
 def refresh
   super
   self.contents.font.color = system_color
   self.contents.draw_text(4, 0, self.width - 40, 32, @caption, 1)
 end
 #----------------------------------------------------------------------------
 # draw_item
 #  i     - index
 #  color - font color
 #  Changed method to draw commands one line off.
 #----------------------------------------------------------------------------
 def draw_item(index, color)
   self.contents.font.color = color
   rect = Rect.new(4, 32 * (index + 1), self.contents.width - 8, 32)
   self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
   self.contents.draw_text(rect, @commands[index], 1)
 end
 #----------------------------------------------------------------------------
 # update_cursor_rect
 #  Changed method to draw cursor one line off.
 #----------------------------------------------------------------------------
 def update_cursor_rect
   if @index < 0 || @item_max == 0
     self.cursor_rect.empty
   else
     x = (self.contents.width - @cursor_width) / 2
     self.cursor_rect.set(x, (@index + 1) * 32, @cursor_width, 32)
   end
 end
 
end

#==============================================================================
# Window_ClassStatus
#------------------------------------------------------------------------------
#  This window displays the character status and includes data about the
#  current Job like Level, EXP and Job Points along with stat change if the
#  class is being changed.
#==============================================================================

class Window_ClassStatus < Window_Base
 
 # setting all accessible variables
 attr_accessor :actor
 #----------------------------------------------------------------------------
 # Initialization
 #----------------------------------------------------------------------------
 def initialize(actor)
   super(BlizzCFG::RO_RIGHT ? 0 : 224, 0, 416, 480)
   @actor = actor
   self.contents = Bitmap.new(width - 32, height - 32)
   # font fix
   if $fontface != nil
     self.contents.font.name = $fontface
     self.contents.font.size = $fontsize
   elsif $defaultfonttype != nil
     self.contents.font.name = $defaultfonttype
     self.contents.font.size = $defaultfontsize
   end
   refresh
 end
 #----------------------------------------------------------------------------
 # refresh
 #  Processes all that is being drawn.
 #----------------------------------------------------------------------------
 def refresh(id = nil)
   self.contents.clear
   # stop if actor doesn't exist
   return if @actor == nil
   actor = @actor.clone
   actor.class_id = id if id != nil
   # draw actor data
   draw_actor_battler(actor, 200, 128, opacity = 150)
   draw_actor_name(actor, 4, 0)
   draw_actor_level(actor, 4, 32)
   draw_actor_state(actor, 4, 64)
   draw_actor_hp(actor, 4, 160, 160)
   draw_actor_sp(actor, 4, 192, 160)
   draw_actor_hp_mod(actor, 4, 160, @actor, 160)
   draw_actor_sp_mod(actor, 4, 192, @actor, 160)
   draw_actor_job(actor, 188, 288, 192)
   (0..6).each {|i|
       draw_actor_parameter(actor, 4, 224 + 32 * i, i)
       draw_actor_parameter_mod(actor, 4, 224 + 32 * i, i, @actor)}
   self.contents.font.color = system_color
   self.contents.draw_text(4, 96, 80, 32, BlizzCFG::EXP)
   self.contents.draw_text(4, 128, 80, 32, BlizzCFG::Next)
   self.contents.font.color = normal_color
   self.contents.draw_text(4, 96, 156, 32, actor.exp_s, 2)
   self.contents.draw_text(4, 128, 156, 32, actor.next_rest_exp_s, 2)
 end
 #--------------------------------------------------------------------------
 # draw_actor_hp_mod
 #  actor - the actor
 #  x     - x-coordinate
 #  y     - y-coordinate
 #  other - the actor before
 #  width - maximal allowed width
 #  This method erases the max HP value to redraw it in the right color.
 #--------------------------------------------------------------------------
 def draw_actor_hp_mod(actor, x, y, other, width = 144)
   # stop if width exceeds max
   return if width - 32 < 108
   # decide color
   if actor.maxhp > other.maxhp
     self.contents.font.color = BlizzCFG::UP_COLOR
   elsif actor.maxhp < other.maxhp
     self.contents.font.color = BlizzCFG::DOWN_COLOR
   else
     return
   end
   # delete old display
   self.contents.fill_rect(x + width - 48, y, 48, 32, Color.new(0, 0, 0, 0))
   # draw
   self.contents.draw_text(x + width - 48, y, 48, 32, actor.maxhp.to_s)
 end
 #--------------------------------------------------------------------------
 # draw_actor_sp_mod
 #  actor - the actor
 #  x     - x-coordinate
 #  y     - y-coordinate
 #  other - the actor before
 #  width - maximal allowed width
 #  This method erases the max HP value to redraw it in the right color.
 #--------------------------------------------------------------------------
 def draw_actor_sp_mod(actor, x, y, other, width = 144)
   # stop if width exceeds max
   return if width - 32 < 108
   # decide color
   if actor.maxsp > other.maxsp
     self.contents.font.color = BlizzCFG::UP_COLOR
   elsif actor.maxsp < other.maxsp
     self.contents.font.color = BlizzCFG::DOWN_COLOR
   else
     return
   end
   # delete old display
   self.contents.fill_rect(x + width - 48, y, 48, 32, Color.new(0, 0, 0, 0))
   # draw
   self.contents.draw_text(x + width - 48, y, 48, 32, actor.maxsp.to_s)
 end
 #--------------------------------------------------------------------------
 # draw_actor_parameter_mod
 #  actor - the actor
 #  x     - x-coordinate
 #  y     - y-coordinate
 #  other - the actor before
 #  type  - which stat
 #  This method erases a stat value to redraw it in the right color.
 #--------------------------------------------------------------------------
 def draw_actor_parameter_mod(actor, x, y, type, other)
   # decide parameter
   case type
   when 3 then str, v1, v2 = $data_system.words.str, actor.str, other.str
   when 4 then dex, v1, v2 = $data_system.words.dex, actor.dex, other.dex
   when 5 then agi, v1, v2 = $data_system.words.agi, actor.agi, other.agi
   when 6 then int, v1, v2 = $data_system.words.int, actor.int, other.int
   else
     return
   end
   # decide color
   if v1 > v2
     self.contents.font.color = BlizzCFG::UP_COLOR
   elsif v1 < v2
     self.contents.font.color = BlizzCFG::DOWN_COLOR
   else
     return
   end
   # delete old display
   self.contents.fill_rect(x + 120, y, 36, 32, Color.new(0, 0, 0, 0))
   # draw
   self.contents.draw_text(x + 120, y, 36, 32, v1.to_s, 2)
 end
 
end
 
#==============================================================================
# Window_Class
#------------------------------------------------------------------------------
#  This window is a slight modification of the Window_Command window to avoid
#  recoding.
#==============================================================================

class Window_Class < Window_Command
 
 #----------------------------------------------------------------------------
 # draw_item
 #  i     - index
 #  color - font color
 #  Changed to draw class/job and level requirement.
 #----------------------------------------------------------------------------
 def draw_item(i, color)
   self.contents.font.color = color
   rect = Rect.new(4, 32 * i, self.contents.width - 8, 32)
   self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
   self.contents.draw_text(rect, @commands
  • )
       self.contents.draw_text(rect, @commands[1], 2)
     end
     
    end

    #==============================================================================
    # Window_SkillLearn
    #------------------------------------------------------------------------------
    #  This window displays all skills that can be still learned.
    #==============================================================================

    class Window_SkillLearn < Window_Command
     
     # setting all accessible variables
     attr_reader :commands
     #----------------------------------------------------------------------------
     # Initialization
     #----------------------------------------------------------------------------
     def initialize(width, actor)
       @actor = actor
       super(width, refresh_skills)
       self.z, self.height, self.index = 500, 224, -1
       self.x, self.active = BlizzCFG::RO_RIGHT ? 320 : 0, false
     end
     #----------------------------------------------------------------------------
     # refresh_skills
     #  This method sets up the skill list again.
     #----------------------------------------------------------------------------
     def refresh_skills
       skills = $data_classes[@actor.class_id].learnings.clone
       # if using the option to hide skills that don't meet the requirements
       if BlizzCFG::HIDE_SKILLS
         # temporary variable
         lvl = (BlizzCFG::USE_LEVEL ? @actor.level : @actor.job_level)
         # get all learnable skills that weren't learned already
         skills = skills.find_all {|learn|
             @actor.job_level >= learn.level &&
             BlizzCFG.roskill_reqs(learn.skill_id).all? {|r|
                 @actor.skills.include?(r[0]) && @actor.skill_level(r[0]) >= r[1]}}
       end
       # filter out all skills that weren't learned already
       skills = skills.find_all {|learn| !@actor.skills.include?(learn.skill_id)}
       return (skills.size == 0 ? [nil] : skills)
     end
     #----------------------------------------------------------------------------
     # refresh
     #  This method was modifies to draw "None" is no skills are available and
     #  refreshes the skill list upon redrawing.
     #----------------------------------------------------------------------------
     def refresh
       @commands = refresh_skills
       @item_max = @commands.size
       if @commands[0] == nil
         self.contents.clear
         self.contents.font.color = disabled_color
         self.contents.draw_text(4, 0, self.contents.width - 8, 32, BlizzCFG::None)
       else
         super
       end
     end
     #----------------------------------------------------------------------------
     # draw_item
     #  i     - index
     #  color - font color
     #  Draws a specific skill and the level requirement to learn it.
     #----------------------------------------------------------------------------
     def draw_item(i, color = nil)
       lvl = (BlizzCFG::USE_LEVEL ? @actor.level : @actor.job_level)
       # decide color depending on which level is used
       if !BlizzCFG::HIDE_SKILLS && (lvl < @commands.level ||
           BlizzCFG.roskill_reqs(@commands.skill_id).any? {|r|
                !@actor.skills.include?(r[0]) || @actor.skill_level(r[0]) < r[1]})
         self.contents.font.color = disabled_color
       else
         self.contents.font.color = normal_color
       end
       # get rectangle
       rect = Rect.new(32, 32 * i, self.contents.width - 36, 32)
       # get icon bitmap
       bitmap = RPG::Cache.icon($data_skills[@commands.skill_id].icon_name)
       opacity = self.contents.font.color == normal_color ? 255 : 128
       # draw bitmap
       self.contents.blt(4, 4 + 32 * i, bitmap, Rect.new(0, 0, 24, 24), opacity)
       self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
       # draw name and requirement if not using the hiding option
       self.contents.draw_text(rect, $data_skills[@commands.skill_id].name)
       unless BlizzCFG::HIDE_SKILLS
         self.contents.draw_text(rect,
           "(#{BlizzCFG::Lv} #{@commands.level})", 2)
       end
     end
     #----------------------------------------------------------------------------
     # update_help
     #  Updates the skill status display.
     #----------------------------------------------------------------------------
     def update_help
       @help_window.set_text(@commands[index] == nil ? 0 : @commands[index].skill_id)
     end
     
    end

    #==============================================================================
    # Window_SkillImprove
    #------------------------------------------------------------------------------
    #  This window displays skills that are already learned.
    #==============================================================================

    class Window_SkillImprove < Window_Command
     
     # setting all accessible variables
     attr_accessor :commands
     #----------------------------------------------------------------------------
     # Initialization
     #----------------------------------------------------------------------------
     def initialize(width, actor)
       @actor, skills = actor, actor.skills
       skills = [nil] if skills.size == 0
       super(width, skills)
       self.z, self.height, self.index = 500, 224, -1
       self.x, self.active = BlizzCFG::RO_RIGHT ? 0 : 320, false
     end
     #----------------------------------------------------------------------------
     # set_commands
     #  commands - new commands
     #  Sets a new list of skills and updates the display.
     #----------------------------------------------------------------------------
     def set_commands(commands)
       commands = [nil] if commands.size == 0
       @commands, @item_max = commands, commands.size
       self.contents.dispose
       self.contents = Bitmap.new(width - 32, @item_max * 32)
       refresh
     end
     #----------------------------------------------------------------------------
     # refresh
     #  Changed to draw "None" if no skills are available.
     #----------------------------------------------------------------------------
     def refresh
       if @commands[0] == nil
         self.contents.clear
         self.contents.font.color = disabled_color
         self.contents.draw_text(4, 0, self.contents.width - 8, 32, BlizzCFG::None)
       else
         super
       end
     end
     #----------------------------------------------------------------------------
     # draw_item
     #  i     - index
     #  color - font color
     #  Draws a specific skill with SP cost, considering the changed SO cost due
     #  to the skill level.
     #----------------------------------------------------------------------------
     def draw_item(i, color = nil)
       skill = $data_skills[@commands]
       # decide color whether skill can still be improved
       if @actor.skill_max_level?(skill.id)
         self.contents.font.color = disabled_color
       else
         self.contents.font.color = color
       end
       # get rectangle
       rect = Rect.new(32, 32 * i, self.contents.width - 36, 32)
       self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
       # get icon bitmap
       bitmap = RPG::Cache.icon(skill.icon_name)
       opacity = self.contents.font.color == normal_color ? 255 : 128
       # draw bitmap
       self.contents.blt(4, 4 + 32 * i, bitmap, Rect.new(0, 0, 24, 24), opacity)
       self.contents.draw_text(rect, skill.name)
       # calculate SP cost considering skill level
       sp_cost = (skill.sp_cost * @actor.get_skill_sp_cost_factor(skill.id)).to_i
       # draw SP cost
       self.contents.draw_text(rect, sp_cost.to_s, 2)
     end
     #----------------------------------------------------------------------------
     # update_help
     #  Updates the skill status display.
     #----------------------------------------------------------------------------
     def update_help
       @help_window.set_text(@commands[index] == nil ? 0 : @commands[index])
     end
     
    end

    #==============================================================================
    # Window_SkillLevel
    #------------------------------------------------------------------------------
    #  This window displays the current skill's data like Level, Power Percentage,
    #  modified SP Cost, etc.
    #==============================================================================

    class Window_SkillLevel < Window_Base
     
     #----------------------------------------------------------------------------
     # Initialization
     #----------------------------------------------------------------------------
     def initialize(actor)
       super(BlizzCFG::RO_RIGHT ? 0 : 416, 0, 224, 192)
       @actor, self.contents = actor, Bitmap.new(width - 32, height - 32)
       # font fix
       if $fontface != nil
         self.contents.font.name = $fontface
         self.contents.font.size = $fontsize
       elsif $defaultfonttype != nil
         self.contents.font.name = $defaultfonttype
         self.contents.font.size = $defaultfontsize
       end
       @help_window = Window_Help.new
     end
     #----------------------------------------------------------------------------
     # refresh
     #  Helping method for easier code overview that redraws the display no matter
     #  what.
     #----------------------------------------------------------------------------
     def refresh
       return if @skill == nil
       id, @skill = @skill.id, nil
       set_text(id)
     end
     #----------------------------------------------------------------------------
     # set_text
     #  id - skill ID
     #  This method draws the currently selected skill's data and stores it so the
     #  display only gets redrawn each time it changes.
     #----------------------------------------------------------------------------
     def set_text(id)
       # stop if same skill as before
       return if @skill == $data_skills[id]
       self.contents.clear
       @skill = $data_skills[id]
       # if skill doesn't exist
       if @skill == nil
         # emtpy description window and stop
         @help_window.set_text('')
         return
       end
       # get icon bitmap and draw it
       bitmap = RPG::Cache.icon(@skill.icon_name)
       self.contents.blt(4, 4, bitmap, Rect.new(0, 0, 24, 24))
       self.contents.draw_text(32, 0, 156, 32, @skill.name)
       # calculate SP cost considering skill level
       sp_cost = (@skill.sp_cost * @actor.get_skill_sp_cost_factor(@skill.id)).to_i
       # calculate damage multiplier considering skill level
       power = (100 * @actor.get_skill_damage_factor(@skill.id)).to_i
       self.contents.font.color = system_color
       # draw all static words
       self.contents.draw_text(4, 32, 184, 32, BlizzCFG::SkillLevel + ':')
       self.contents.draw_text(4, 64, 184, 32, BlizzCFG::MaximumLevel + ':')
       self.contents.draw_text(4, 96, 184, 32, BlizzCFG::Cost + ':')
       self.contents.draw_text(4, 128, 184, 32, BlizzCFG::Power + ':')
       self.contents.draw_text(4, 64, 184, 32,
           BlizzCFG.roskill_maxlevel(@skill.id).to_s, 2)
       self.contents.font.color = normal_color
       # draw all the data
       self.contents.draw_text(4, 32, 184, 32, @actor.skill_level(@skill.id).to_s, 2)
       sp_cost = "#{sp_cost} #{$data_system.words.sp}"
       self.contents.draw_text(4, 96, 184, 32, sp_cost, 2)
       self.contents.draw_text(4, 128, 184, 32, "#{power}%", 2)
       # set help window text to skill description
       @help_window.set_text(@skill.description, 1)
     end
     #----------------------------------------------------------------------------
     # dispose
     #  This method was enhanced to dispose the skill description window.
     #----------------------------------------------------------------------------
     def dispose
       @help_window.dispose
       super
     end
     
    end

    #==============================================================================
    # Window_JobLevel
    #------------------------------------------------------------------------------
    #  This window displays job data.
    #==============================================================================

    class Window_JobLevel < Window_Base
     
     #----------------------------------------------------------------------------
     # Initialization
     #----------------------------------------------------------------------------
     def initialize(actor)
       super(BlizzCFG::RO_RIGHT ? 416 : 0, 0, 224, 192)
       @actor, self.contents = actor, Bitmap.new(width - 32, height - 32)
       # font fix
       if $fontface != nil
         self.contents.font.name = $fontface
         self.contents.font.size = $fontsize
       elsif $defaultfonttype != nil
         self.contents.font.name = $defaultfonttype
         self.contents.font.size = $defaultfontsize
       end
       refresh
     end
     #----------------------------------------------------------------------------
     # refresh
     #  This method draws the job data.
     #----------------------------------------------------------------------------
     def refresh
       self.contents.clear
       draw_actor_job(@actor, 4, 0, 184)
     end
     
    end

    #==============================================================================
    # Scene_ClassChange
    #------------------------------------------------------------------------------
    #  This scene processes the class/job change system.
    #==============================================================================

    class Scene_ClassChange
     
     #----------------------------------------------------------------------------
     # Initialization
     #----------------------------------------------------------------------------
     def initialize(index = 0, scene = Scene_Map)
       @actor, @scene = $game_party.actors[index], scene
     end
     #----------------------------------------------------------------------------
     # main
     #  Main processing method.
     #----------------------------------------------------------------------------
     def main
       # create main command window
       @command_window = Window_Command.new(224, BlizzCFG::ClassCommands)
       @command_window.x = BlizzCFG::RO_RIGHT ? 416 : 0
       # create status window
       @status_window = Window_ClassStatus.new(@actor)
       @old_index = 0
       make_class_window
       Graphics.transition
       loop do
         Graphics.update
         Input.update
         update
         break if $scene != self
       end
       Graphics.freeze
       # delete all windows
       @command_window.dispose
       @status_window.dispose
       @class_window.dispose
     end
     #----------------------------------------------------------------------------
     # make_class_window
     #  This method helps to make the code easier to overview.
     #----------------------------------------------------------------------------
     def make_class_window
       # delete old window if there is one
       @class_window.dispose unless @class_window == nil || @class_window.disposed?
       # get configuration and initialize data
       @configs = BlizzCFG.rojob_next(@actor.class_id)
       commands, lvl = [], (BlizzCFG::USE_LEVEL ? @actor.level : @actor.job_level)
       # if no configs
       if @configs[0].size == 0
         # set to "None"
         commands = [[BlizzCFG::None, '']]
       else
         # add command data
         @configs.each {|c| commands.push([$data_classes[c[1]].name,
             "(#{BlizzCFG::Lv} #{c[0]})"])}
       end
       # create window with given data
       @class_window = Window_Class.new(224, commands)
       @class_window.x, @class_window.y = BlizzCFG::RO_RIGHT ? 416 : 0, 160
       @class_window.height, @class_window.index = 320, -1
       # if no configuration
       if @configs[0].size == 0
         # set text color to disabled
         @class_window.disable_item(0)
         @command_window.disable_item(0)
       else
         # disable each new class/job that does not fulfill the requirement
         @configs.each_index {|i|
             @class_window.disable_item(i) if lvl < @configs
    • }
           @command_window.refresh
         end
       end
       #----------------------------------------------------------------------------
       # update
       #  This is the main update method which calls the appropriate method
       #  depending on which window is currently active.
       #----------------------------------------------------------------------------
       def update
         if @command_window.active
           @command_window.update
           update_command
         elsif @sure_window != nil
           @sure_window.update
           update_sure
         elsif @class_window.active
           @class_window.update
           update_classchange
         end
       end
       #----------------------------------------------------------------------------
       # update_comand
       #  This method updates the command window input.
       #----------------------------------------------------------------------------
       def update_command
         # if cancel button pressed
         if Input.trigger?(Input::B)
           # play sound and return to previous scene
           $game_system.se_play($data_system.cancel_se)
           $scene = @scene.new
         # if confirm button pressed
         elsif Input.trigger?(Input::C)
           size = $game_party.actors.size
           # depending on chosen option activate jobchange, change actor or leave
           case @command_window.index
           when 0
             if @configs[0].size == 0
               $game_system.se_play($data_system.buzzer_se)
               return
             end
             $game_system.se_play($data_system.decision_se)
             @command_window.active, @class_window.active = false, true
             @class_window.index = @old_index
             @status_window.refresh(@configs[@class_window.index][1])
           when 1 then $scene = self.class.new((@actor.index + 1) % size, @scene)
           when 2 then $scene = self.class.new((@actor.index + size - 1) % size, @scene)
           when 3 then $scene = @scene.new
           end
           $game_system.se_play($data_system.decision_se)
         end
       end
       #----------------------------------------------------------------------------
       # update_classchange
       #  This method updates the class change window input.
       #----------------------------------------------------------------------------
       def update_classchange
         # if cancel button pressed
         if Input.trigger?(Input::B)
           $game_system.se_play($data_system.cancel_se)
           @command_window.active = true
           @old_index = @class_window.index
           @class_window.active, @class_window.index = false, -1
           @status_window.refresh
         # if confirm button pressed
         elsif Input.trigger?(Input::C)
           lvl = (BlizzCFG::USE_LEVEL ? @actor.level : @actor.job_level)
           # if requirements are not fulfilled
           if lvl < @configs[@class_window.index][0]
             $game_system.se_play($data_system.buzzer_se)
           else
             $game_system.se_play($data_system.decision_se)
             # create confirmation window
             @sure_window = Window_Dialog.new(224, BlizzCFG::YesNo,
                 BlizzCFG::ChangeClass)
             @sure_window.z, @class_window.active = 500, false
           end
         # if up/down is being pressed
         elsif Input.trigger?(Input::UP) || Input.trigger?(Input::DOWN)
           # apply status window change
           @status_window.refresh(@configs[@class_window.index][1])
         end
       end
       #----------------------------------------------------------------------------
       # update_sure
       #  This method updates the confirmation window input.
       #----------------------------------------------------------------------------
       def update_sure
         # if cancel button pressed
         if Input.trigger?(Input::B)
           # play sound and remove confirmation window
           $game_system.se_play($data_system.cancel_se)
           @sure_window.dispose
           @class_window.active, @sure_window = true, nil
         # if confirm button pressed
         elsif Input.trigger?(Input::C)
           $game_system.se_play($data_system.decision_se)
           # either accept or decline and remove confirmation window
           case @sure_window.index
           when 0
             id = @actor.class_id
             @actor.class_id = @configs[@class_window.index][1]
             @actor.hp, @actor.sp = @actor.hp, @actor.sp
             @status_window.refresh
             if !BlizzCFG::JOB_ONLY && BlizzCFG::CLASS_SKILLS &&
                 @actor.class_id != id && $data_classes[id] != nil
               # remove all skills
               $data_classes[id].learnings.each {|i| @actor.forget_skill(i.skill_id)}
             end
             make_class_window
             @sure_window.dispose
             @command_window.active, @sure_window = true, nil
           when 1
             @sure_window.dispose
             @class_window.active, @sure_window = true, nil
           end
         end
       end
       
      end

      #==============================================================================
      # Scene_SkillChange
      #------------------------------------------------------------------------------
      #  This scene processes the learning and improving (leveling up) of RO skills.
      #==============================================================================

      class Scene_SkillChange
       
       #----------------------------------------------------------------------------
       # Initialization
       #----------------------------------------------------------------------------
       def initialize(index = 0, scene = Scene_Map)
         @actor, @scene = $game_party.actors[index], scene
       end
       #----------------------------------------------------------------------------
       # main
       #  This is the main processing method.
       #----------------------------------------------------------------------------
       def main
         # create main command window
         @command_window = Window_Command.new(192, BlizzCFG::SkillCommands)
         # create other windows
         @learn_window = Window_SkillLearn.new(320, @actor)
         @skill_window = Window_SkillImprove.new(320, @actor)
         @status_window = Window_SkillLevel.new(@actor)
         @job_window = Window_JobLevel.new(@actor)
         # set window positions
         @command_window.y = @status_window.y = @job_window.y = 64
         @command_window.x, @learn_window.y, @skill_window.y = 224, 256, 256
         @learn_window.x, @skill_window.x = 320, 0 if BlizzCFG::RO_RIGHT
         @learn_window.help_window = @skill_window.help_window = @status_window
         # skill status window must be clear
         @status_window.set_text(0)
         # disable command if no skills in the given category
         @command_window.disable_item(0) if @learn_window.commands[0] == nil
         @command_window.disable_item(1) if @skill_window.commands[0] == nil
         Graphics.transition
         loop do
           Graphics.update
           Input.update
           update
           break if $scene != self
         end
         Graphics.freeze
         # remove all windows
         [@command_window, @learn_window, @skill_window, @status_window,
             @job_window].each {|win|win.dispose}
       end
       #----------------------------------------------------------------------------
       # update
       #  This is the main update method which calls the appropriate method
       #  depending on which window is currently active.
       #----------------------------------------------------------------------------
       def update
         if @command_window.active
           @command_window.update
           update_command
         elsif @sure_window != nil
           @sure_window.update
           # update the correct confirmation
           @learn_window.index >= 0 ? update_sure_learn : update_sure_skill
         elsif @learn_window.active
           @learn_window.update
           update_learn
         elsif @skill_window.active
           @skill_window.update
           update_skill
         end
       end
       #----------------------------------------------------------------------------
       # update_sure
       #  This method updates the command window input.
       #----------------------------------------------------------------------------
       def update_command
         # if cancel button pressed
         if Input.trigger?(Input::B)
           $game_system.se_play($data_system.cancel_se)
           $scene = @scene.new
         # if confirm button pressed
         elsif Input.trigger?(Input::C)
           size = $game_party.actors.size
           # choose next menu, change actor or leave
           case @command_window.index
           when 0
             # if no skills in this category
             if @learn_window.commands[0] == nil
               # play sound and stop
               $game_system.se_play($data_system.buzzer_se)
               return
             end
             # play sound and activate other window
             $game_system.se_play($data_system.decision_se)
             @command_window.active, @learn_window.active = false, true
             @learn_window.index = 0
           when 1
             # if no skills in this category
             if @skill_window.commands[0] == nil
               # play sound and stop
               $game_system.se_play($data_system.buzzer_se)
               return
             end
             # play sound and activate other window
             $game_system.se_play($data_system.decision_se)
             @command_window.active, @skill_window.active = false, true
             @skill_window.index = 0
           when 2 then $scene = self.class.new((@actor.index + 1) % size, @scene)
           when 3 then $scene = self.class.new((@actor.index + size - 1) % size, @scene)
           when 4 then $scene = @scene.new
           end
           $game_system.se_play($data_system.decision_se)
         end
       end
       #----------------------------------------------------------------------------
       # update_sure
       #  This method updates the skill learn window input.
       #----------------------------------------------------------------------------
       def update_learn
         # if cancel button pressed
         if Input.trigger?(Input::B)
           # play sound and return to main command
           $game_system.se_play($data_system.cancel_se)
           @command_window.active, @learn_window.active = true, false
           @status_window.set_text(0)
           @learn_window.index = -1
         # if confirm button pressed
         elsif Input.trigger?(Input::C)
           lvl = (BlizzCFG::USE_LEVEL ? @actor.level : @actor.job_level)
           # temporary variable
           learn = @learn_window.commands[@learn_window.index]
           # if skill doesn't exist, cannot be learned, no Job Points or reqs not fulfilled
           if learn == nil || @actor.jp == 0 || lvl < learn.level ||
               BlizzCFG.roskill_reqs(learn.skill_id).any? {|r|
                   !@actor.skills.include?(r[0]) || @actor.skill_level(r[0]) < r[1]}
             # play sound
             $game_system.se_play($data_system.buzzer_se)
           else
             # play sound and create confirmation window
             $game_system.se_play($data_system.decision_se)
             @sure_window = Window_Dialog.new(224, BlizzCFG::YesNo,
                 BlizzCFG::LearnSkill)
             @learn_window.active = false
           end
         end
       end
       #----------------------------------------------------------------------------
       # update_sure
       #  This method updates the skill improve window input.
       #----------------------------------------------------------------------------
       def update_skill
         # if cancel button pressed
         if Input.trigger?(Input::B)
           # play sound and return to main command
           $game_system.se_play($data_system.cancel_se)
           @command_window.active, @skill_window.active = true, false
           @status_window.set_text(0)
           @skill_window.index = -1
         # if confirm button pressed
         elsif Input.trigger?(Input::C)
           skill = $data_skills[@skill_window.commands[@skill_window.index]]
           # if no Job Points skill or skill already maximized
           if @actor.jp == 0 || @actor.skill_max_level?(skill.id)
             # play sound
             $game_system.se_play($data_system.buzzer_se)
           else
             # play sound and create confirmation window
             $game_system.se_play($data_system.decision_se)
             @sure_window = Window_Dialog.new(224, BlizzCFG::YesNo,
                 BlizzCFG::ImproveSkill)
             @skill_window.active = false
           end
         end
       end
       #----------------------------------------------------------------------------
       # update_sure
       #  This method updates the confirmation of learning input.
       #----------------------------------------------------------------------------
       def update_sure_learn
         # if cancel button pressed
         if Input.trigger?(Input::B)
           # play sound and remove confirmation window
           $game_system.se_play($data_system.cancel_se)
           @sure_window.dispose
           @learn_window.active, @sure_window = true, nil
         # if confirm button pressed
         elsif Input.trigger?(Input::C)
           $game_system.se_play($data_system.decision_se)
           # if confirmed
           if @sure_window.index == 0
             # consume Job Point
             @actor.jp -= 1
             # temporary variable
             id = @learn_window.commands[@learn_window.index].skill_id
             # if CRLS is installed and CD skill
             if $crls != nil && BlizzCFG::CD_SKILLS.include?(id)
               # learn new CD skill
               @actor.learn_cd(id)
             else
               # learn new skill
               @actor.learn_skill(id)
             end
             # update window displays
             @learn_window.refresh
             @skill_window.set_commands(@actor.skills.clone)
             if @learn_window.commands[0] == nil
               @command_window.disable_item(0)
             else
               @command_window.draw_item(0, @command_window.normal_color)
             end
             if @skill_window.commands[0] == nil
               @command_window.disable_item(1)
             else
               @command_window.draw_item(1, @command_window.normal_color)
             end
             @job_window.refresh
           end
           # remove confirmation window
           @sure_window.dispose
           @learn_window.active, @sure_window = true, nil
         end
       end
       #----------------------------------------------------------------------------
       # update_sure
       #  This method updates the confirmation of improving input.
       #----------------------------------------------------------------------------
       def update_sure_skill
         # if cancel button pressed
         if Input.trigger?(Input::B)
           # play sound and remove confirmation window
           $game_system.se_play($data_system.cancel_se)
           @sure_window.dispose
           @skill_window.active, @sure_window = true, nil
         # if confirm button pressed
         elsif Input.trigger?(Input::C)
           $game_system.se_play($data_system.decision_se)
           if @sure_window.index == 0
             skill = $data_skills[@skill_window.commands[@skill_window.index]]
             # consume Job Point
             @actor.jp -= 1
             # improve skill
             @actor.skill_level_change(@actor.skill_level(skill.id) + 1, skill.id)
             # update window displays
             [@status_window, @skill_window, @learn_window, @job_window].each {|win|
                 win.refresh}
             (0..1).each {|i| @command_window.draw_item(i, Color.new(255, 255, 255))}
             @command_window.disable_item(0) if @learn_window.commands[0] == nil
             @command_window.disable_item(1) if @skill_window.commands[0] == nil
           end
           # remove confirmation window
           @sure_window.dispose
           @skill_window.active, @sure_window = true, nil
         end
       end
       
      end


Title: Re: Nevermind, fixed problem!
Post by: WhiteRose on January 18, 2011, 07:29:07 pm
When you come up with a solution to a problem, it's best to leave the topic as it is and add the solution in case other members later have the same problem.
Title: Re: Nevermind, fixed problem!
Post by: Zephor on January 19, 2011, 12:28:17 am
Spoiler: ShowHide
Quote
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Stat Distribution System by Blizzard
# Version: 2.01
# Type: Actor Attribute Modifier
# Date: 25.3.2007
# Date v1.1b: 6.4.2007
# Date v1.2b: 22.8.2007
# Date v1.3b: 12.9.2007
# Date v1.33b: 5.11.2007
# Date v2.0: 18.10.2009
# Date v2.01: 28.7.2010
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# Compatibility:
#
#   99% compatible with SDK v1.x. 80% compatible with SDK 2.x. WILL corrupt
#   your old savegames. Might cause problems with custom leveling up systems.
#   99% compatibility with everything else.
#
#
# Features:
#
#   - distribute points between different stats
#   - extra scene for point distribution with confirmation window at the end
#   - calls the "caller scene" automatically when finished
#   - add points by easily pressing RIGHT/LEFT
#   - hold Q to add 10 points at once
#   - hold W to add 100 points at once
#   - a Stat Distribution System that actually works like it should...
#
# new in v1.1b:
#   - added option to call the Points Scene after a fight with level ups
#   - customizable icon position and opacity
#
# new in v1.2b:
#   - improved coding and made code shorter
#   - rewritten conditions using classic syntax to avoid RGSS conditioning bug
#
# new in v1.3b:
#   - improved coding
#   - fixed bug with AUTO_CALL after battle
#   - new AUTO_MAP_CALL works on the map as well (that means it's fully
#     compatible with Blizz-ABS)
#
# new in v1.33b:
#   - improved coding
#   - improved compatibility
#   - fixed a little glitch
#
# new in v2.0:
#   - improved coding and overworked system (corrupts old savegames with older
#     version of this system!)
#   - new design
#   - new support for HP and SP
#   - now possible to configure multiple points for one stat
#
# new in v2.01:
#   - fixed bug with display of remaining DP
#
#
# Configuration:
#
#   Set up the configuration below.
#
#   STARTING_DP   - how many points should the actor have initially at level 1
#   DP_PER_LEVEL  - how many points should the actor gain per level
#   HP_DP_COST    - how many DP does 1 HP cost
#   SP_DP_COST    - how many DP does 1 SP cost
#   STR_DP_COST   - how many DP does 1 STR cost
#   DEX_DP_COST   - how many DP does 1 DEX cost
#   AGI_DP_COST   - how many DP does 1 AGI cost
#   INT_DP_COST   - how many DP does 1 INT cost
#   AUTO_CALL     - set to true to have the scene called automatically after
#                   battles if at least one character got leveled up
#   AUTO_MAP_CALL - set to true to have the scene called automatically on the
#                   map if at least one character got leveled up (this works
#                   for Blizz-ABS as well), also note that this will cause the
#                   scene to called over and over as long as not all points
#                   were distributed
#   DISPLAY_ICON  - displays an icon on the map if ANY character in the
#                   party has any points to distribute
#   OWN_ICON      - use an own icon for display, false for no or filename of
#                   your own icon (the icon has to be in the Icons folder)
#   ICON_X        - icon X coordinate
#   ICON_Y        - icon Y coordinate
#   ICON_OPACITY  - icon Y opacity
#   WINDOW_MODE   - set to true to have the command windows at the bottom, set
#                   to false to have them to at the top
#
#
#   You can always add change DP yourself by using following syntax:
#
#     $game_party.actors[POSITION].dp = VALUE
#     $game_actors[ID].dp = VALUE
#
#   POSITION - position of actor in the party (STARTS FROM ZERO!)
#   ID       - ID of actor in the database
#   VALUE    - value
#
#   You can call the Scene by using a "Call script" event command. Type into
#   the editor window this text:
#
#     $scene = Scene_Points.new
#
#
# Side Note:
#
#   Decreasing the level of an actor won't remove his gained DP. You MUST do it
#   manually.
#
#
# If you find any bugs, please report them here:
# http://www.chaosproject.co.nr
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

module BlizzCFG

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 STARTING_DP = 200
 DP_PER_LEVEL = 100
 HP_DP_COST = 1
 SP_DP_COST = 1
 STR_DP_COST = 10
 DEX_DP_COST = 10
 AGI_DP_COST = 10
 INT_DP_COST = 10
 AUTO_CALL = false
 AUTO_MAP_CALL = false
 DISPLAY_ICON = true
 OWN_ICON = false
 ICON_X = 612
 ICON_Y = 452
 ICON_OPACITY = 192
 WINDOW_MODE = true
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 # constants
 HPLimit = 9999
 SPLimit = 9999
 STRLimit = 999
 DEXLimit = 999
 AGILimit = 999
 INTLimit = 999
 DPName = 'DP'
 EvasionName = 'EVA'
 EXPText = 'EXP'
 NextText = 'next'
 EquipmentText = 'Equipment'
 AreYouSure = 'Are you sure?'
 DistroCommands = ['Distribute DP', 'Next Character', 'Previous Character', 'Finish']
 AreYouSureCommands = ['Cancel', 'Accept Changes', 'Discard Changes']
 AttrLimits = [HPLimit, SPLimit, STRLimit, DEXLimit, AGILimit, INTLimit]
 ExchangeRates = [HP_DP_COST, SP_DP_COST, STR_DP_COST,
     DEX_DP_COST, AGI_DP_COST, INT_DP_COST]
 ColorWhite = Color.new(255, 255, 255)
 ColorBlack = Color.new(0, 0, 0)
 ColorIcon = Color.new(0, 128, 255)
 ColorIncreased = Color.new(0, 255, 0)
 # ensures compatibility
 $stat_system = 2.01
 
end

#==============================================================================
# Array
#==============================================================================

class Array
 
 def sum
   result = 0
   self.each {|i| result += i if i.is_a?(Numeric)}
   return result
 end
 
end
 
#==============================================================================
# Game_Actor
#==============================================================================

class Game_Actor < Game_Battler
 
 attr_reader :dp
 
 alias setup_sds_later setup
 def setup(actor_id)
   @dp = BlizzCFG::STARTING_DP
   setup_sds_later(actor_id)
 end
 
 alias exp_sds_later exp=
 def exp=(exp)
   old_level = @level
   exp_sds_later(exp)
   value = (@level - old_level) * BlizzCFG::DP_PER_LEVEL
   self.dp += value if value > 0
 end
 
 def dp=(value)
   @dp = (value < 0 ? 0 : value)
 end
 
end

#==============================================================================
# Window_Base
#==============================================================================

class Window_Base < Window
 
 def draw_actor_battler(actor, x, y)
   bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
   cw, ch = bitmap.width, bitmap.height
   src_rect = Rect.new(0, 0, cw, ch)
   self.contents.blt(x - cw / 2, y - ch / 2, bitmap, src_rect)
 end
 
 alias draw_actor_parameter_sds_later draw_actor_parameter
 def draw_actor_parameter(actor, x, y, type)
   if type == 7
     self.contents.font.color = system_color
     self.contents.draw_text(x, y, 120, 32, BlizzCFG::EvasionName)
     self.contents.font.color = normal_color
     self.contents.draw_text(x + 120, y, 36, 32, actor.eva.to_s, 2)
   else
     draw_actor_parameter_sds_later(actor, x, y, type)
   end
 end
 
end

#==============================================================================
# Window_DistributionStatus
#==============================================================================

class Window_DistributionStatus < Window_Base
 
 attr_reader :actor
 
 def initialize(actor)
   super(0, BlizzCFG::WINDOW_MODE ? 0 : 224, 640, 256)
   @actor = actor
   self.contents = Bitmap.new(width - 32, height - 32)
   if $fontface != nil
     self.contents.font.name = $fontface
     self.contents.font.size = $fontsize
   elsif $defaultfonttype != nil
     self.contents.font.name = $defaultfonttype
     self.contents.font.size = $defaultfontsize
   end
   refresh
 end
 
 def actor=(actor)
   @actor = actor
   refresh
 end
 
 def refresh
   self.contents.clear
   unless @actor == nil
     draw_actor_battler(@actor, 256, 2, opacity = 150)
     draw_actor_name(@actor, 4, 0)
     draw_actor_class(@actor, 4, 32)
     draw_actor_level(@actor, 4, 64)
     self.contents.font.color = system_color
     self.contents.draw_text(352, 16, 96, 32, BlizzCFG::EquipmentText)
     draw_item_name($data_weapons[@actor.weapon_id], 352, 64)
     draw_item_name($data_armors[@actor.armor1_id], 352, 96)
     draw_item_name($data_armors[@actor.armor2_id], 352, 128)
     draw_item_name($data_armors[@actor.armor3_id], 352, 160)
     draw_item_name($data_armors[@actor.armor4_id], 352, 192)
     self.contents.font.color = normal_color
     draw_actor_parameter(@actor, 4, 96, 0)
     draw_actor_parameter(@actor, 4, 128, 1)
     draw_actor_parameter(@actor, 4, 160, 2)
     draw_actor_parameter(@actor, 4, 192, 7)
   end
 end
 
end
 
#==============================================================================
# Window_DistributionPoints
#==============================================================================

class Window_DistributionPoints < Window_Base
 
 attr_reader :actor
 attr_reader :dp_left
 
 def initialize(actor)
   super(0, BlizzCFG::WINDOW_MODE ? 416 : 160, 224, 64)
   self.contents = Bitmap.new(width - 32, height - 32)
   if $fontface != nil
     self.contents.font.name = $fontface
     self.contents.font.size = $fontsize
   elsif $defaultfonttype != nil
     self.contents.font.name = $defaultfonttype
     self.contents.font.size = $defaultfontsize
   end
   self.actor = actor
 end
 
 def actor=(actor)
   @actor, @dp_left = actor, actor.dp
   refresh
 end
 
 def set_dp(value)
   @dp_left = actor.dp - value
   refresh
 end
 
 def refresh
   self.contents.clear
   self.contents.font.color = system_color
   self.contents.draw_text(4, 0, 32, 32, BlizzCFG::DPName)
   self.contents.font.color = normal_color
   self.contents.draw_text(36, 0, 152, 32, "#{@dp_left} / #{@actor.dp}", 2)
 end
 
end
 
#==============================================================================
# Window_Distribution
#==============================================================================

class Window_Distribution < Window_Selectable
 
 attr_reader :actor
 attr_reader :spent
 
 def initialize(actor)
   super(224, BlizzCFG::WINDOW_MODE ? 256 : 0, 416, 224)
   self.contents = Bitmap.new(width - 32, height - 32)
   if $fontface != nil
     self.contents.font.name = $fontface
     self.contents.font.size = $fontsize
   elsif $defaultfonttype != nil
     self.contents.font.name = $defaultfonttype
     self.contents.font.size = $defaultfontsize
   end
   @words = ["Max #{$data_system.words.hp}", "Max #{$data_system.words.sp}",
       $data_system.words.str, $data_system.words.dex, $data_system.words.agi,
       $data_system.words.int]
   @item_max = @words.size
   self.actor = actor
   self.active, self.index = false, 0
 end
 
 def actor=(actor)
   @actor = actor
   @current = [@actor.maxhp, @actor.maxsp, @actor.str, @actor.dex, @actor.agi,
       @actor.int]
   @spent = [0, 0, 0, 0, 0, 0]
   refresh
 end
 
 def active=(value)
   super(value)
   update_cursor_rect
 end
 
 def apply_new_attributes
   @actor.maxhp += @spent[0] / BlizzCFG::HP_DP_COST
   @actor.maxsp += @spent[1] / BlizzCFG::SP_DP_COST
   @actor.str += @spent[2] / BlizzCFG::STR_DP_COST
   @actor.dex += @spent[3] / BlizzCFG::DEX_DP_COST
   @actor.agi += @spent[4] / BlizzCFG::AGI_DP_COST
   @actor.int += @spent[5] / BlizzCFG::INT_DP_COST
   @actor.dp -= @spent.sum
 end
 
 def refresh
   self.contents.clear
   (0...@item_max).each {|i| draw_item(i)}
 end
 
 def draw_item(i)
   y = i * 32
   self.contents.fill_rect(0, y, self.contents.width, 32, Color.new(0, 0, 0, 0))
   self.contents.font.color = system_color
   self.contents.draw_text(4, y, 80, 32, @words)
   self.contents.draw_text(344, y, 40, 32, BlizzCFG::DPName)
   self.contents.draw_text(180, y, 12, 32, '/', 1)
   self.contents.draw_text(192, y, 64, 32, @current.to_s)
   self.contents.font.color = normal_color
   self.contents.draw_text(276, y, 64, 32,
       BlizzCFG::ExchangeRates.to_s, 2)
   font, self.contents.font.name = self.contents.font.name, 'Arial'
   size, self.contents.font.size = self.contents.font.size, 32
   bold, self.contents.font.bold = self.contents.font.bold, true
   self.contents.draw_text(104, y - 2, 24, 32, '«')
   self.contents.draw_text(244, y - 2, 24, 32, '»', 2)
   self.contents.font.bold = bold
   self.contents.font.size = size
   self.contents.font.bold = bold
   self.contents.font.color = BlizzCFG::ColorIncreased if @spent > 0
   self.contents.draw_text(116, y, 64, 32,
       (@current + @spent / BlizzCFG::ExchangeRates).to_s, 2)
 end
 
 def add_points(value)
   value *= BlizzCFG::ExchangeRates[index]
   limit = @actor.dp - @spent.sum
   value = limit if value > limit
   value /= BlizzCFG::ExchangeRates[index]
   limit = BlizzCFG::AttrLimits[index] - (@current[index] + @spent[index])
   value = limit if value > limit
   if value > 0
     @spent[index] += value * BlizzCFG::ExchangeRates[index]
     return true
   end
   return false
 end
 
 def remove_points(value)
   value *= BlizzCFG::ExchangeRates[index]
   limit = spent.sum
   value = limit if value > limit
   value = @spent[index] if value > @spent[index]
   value /= BlizzCFG::ExchangeRates[index]
   if value > 0
     @spent[index] -= value * BlizzCFG::ExchangeRates[index]
     return true
   end
   return false
 end
 
 def update
   super
   return unless self.active
   if Input.press?(Input::R)
     if Input.repeat?(Input::RIGHT)
       if add_points(100)
         $game_system.se_play($data_system.cursor_se)
         draw_item(self.index)
       else
         $game_system.se_play($data_system.buzzer_se)
       end
     elsif Input.repeat?(Input::LEFT)
       if remove_points(100)
         $game_system.se_play($data_system.cursor_se)
         draw_item(self.index)
       else
         $game_system.se_play($data_system.buzzer_se)
       end
     end
   elsif Input.press?(Input::L)
     if Input.repeat?(Input::RIGHT)
       if add_points(10)
         $game_system.se_play($data_system.cursor_se)
         draw_item(self.index)
       else
         $game_system.se_play($data_system.buzzer_se)
       end
     elsif Input.repeat?(Input::LEFT)
       if remove_points(10)
         $game_system.se_play($data_system.cursor_se)
         draw_item(self.index)
       else
         $game_system.se_play($data_system.buzzer_se)
       end
     end
   elsif Input.repeat?(Input::RIGHT)
     if add_points(1)
       $game_system.se_play($data_system.cursor_se)
       draw_item(self.index)
     else
       $game_system.se_play($data_system.buzzer_se)
     end
   elsif Input.repeat?(Input::LEFT)
     if remove_points(1)
       $game_system.se_play($data_system.cursor_se)
       draw_item(self.index)
     else
       $game_system.se_play($data_system.buzzer_se)
     end
   end
 end
 
 def update_cursor_rect
   if @index < 0 || !self.active
     self.cursor_rect.empty
   else
     super
   end
 end
 
end
 
#==============================================================================
# Window_Sure
#==============================================================================

class Window_Sure < Window_Command
 
 def initialize(width, commands)
   commands = commands.clone + ['']
   super
   @item_max, self.index = commands.size - 1, 0
   self.x, self.y, self.z = 320 - self.width / 2, 240 - self.height / 2, 10000
   refresh
 end
 
 def refresh
   super
   self.contents.font.color = system_color
   self.contents.draw_text(4, 0, self.contents.width - 8, 32,
       BlizzCFG::AreYouSure, 1)
 end
 
 def draw_item(i, color)
   self.contents.font.color = color
   rect = Rect.new(4, (i + 1) * 32, self.contents.width - 8, 32)
   self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
   self.contents.draw_text(rect, @commands, 1)
 end
 
 def update_cursor_rect
   if @index < 0
     self.cursor_rect.empty
   else
     self.cursor_rect.set(32, (@index + 1) * 32, self.contents.width - 64, 32)
   end
 end
 
end
 
#==============================================================================
# Scene_Points
#==============================================================================

class Scene_Points
 
 def initialize(classe = $scene.class)
   @scene = classe
 end
 
 def main
   @command_window = Window_Command.new(224, BlizzCFG::DistroCommands)
   @command_window.y = (BlizzCFG::WINDOW_MODE ? 256 : 0)
   actor = $game_party.actors[0]
   @status_window = Window_DistributionStatus.new(actor)
   @distro_window = Window_Distribution.new(actor)
   @dp_window = Window_DistributionPoints.new(actor)
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     break if $scene != self
   end
   Graphics.freeze
   @command_window.dispose
   @status_window.dispose
   @distro_window.dispose
   @dp_window.dispose
 end
 
 def create_confirmation_window
   @sure_window = Window_Sure.new(256, BlizzCFG::AreYouSureCommands)
 end
 
 def update
   if @command_window.active
     @command_window.update
     update_main_command
   elsif @sure_window != nil
     @sure_window.update
     update_confirmation
   elsif @distro_window.active
     @distro_window.update
     update_distro
   end
 end
 
 def update_main_command
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     $scene = @scene.new
   elsif Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     if @command_window.index == 0
       @command_window.active, @distro_window.active = false, true
     elsif @distro_window.spent.sum > 0
       @command_window.active = false
       create_confirmation_window
     else
       @distro_window.index = 0
       check_command_window
     end
   end
 end
 
 def update_confirmation
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @sure_window.dispose
     @sure_window, @command_window.active = nil, true
   elsif Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     if @sure_window.index > 0
       @distro_window.apply_new_attributes if @sure_window.index == 1
       check_command_window
     end
     @sure_window.dispose
     @sure_window, @command_window.active = nil, true
   end
 end
 
 def check_command_window
   case @command_window.index
   when 1
     i = @status_window.actor.index + 1
     i %= $game_party.actors.size
     @status_window.actor = @distro_window.actor =
         @dp_window.actor = $game_party.actors
   when 2
     i = @status_window.actor.index + $game_party.actors.size - 1
     i %= $game_party.actors.size
     @status_window.actor = @distro_window.actor =
         @dp_window.actor = $game_party.actors
   when 3
     $scene = @scene.new
   end
 end
 
 def update_distro
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @command_window.active, @distro_window.active = true, false
   elsif Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     @command_window.active, @distro_window.active = true, false
   elsif Input.repeat?(Input::LEFT) || Input.repeat?(Input::RIGHT)
     @dp_window.set_dp(@distro_window.spent.sum)
   end
 end
 
end

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

class Scene_Battle
 
 alias main_sds_later main
 def main
   main_sds_later
   if BlizzCFG::AUTO_CALL &&
       $game_party.actors.any? {|actor| actor.dp > 0}
     $scene = Scene_Points.new
   end
 end
 
end

#==============================================================================
# Scene_Map
#==============================================================================

class Scene_Map
 
 alias main_sds_later main
 def main
   main_sds_later
   @notify.dispose if @notify != nil
 end
 
 alias upd_sds_later update
 def update
   check_icon if BlizzCFG::DISPLAY_ICON
   upd_sds_later
   if BlizzCFG::AUTO_MAP_CALL &&
       $game_party.actors.any? {|actor| actor.dp > 0}
     $scene = Scene_Points.new
   end
 end
 
 def check_icon
   if $game_party.actors.any? {|actor| actor.dp > 0}
     if @notify == nil
       @notify = RPG::Sprite.new
       if BlizzCFG::OWN_ICON
         @notify.bitmap = RPG::Cache.icon(BlizzCFG::OWN_ICON)
       else
         @notify.bitmap = Bitmap.new(24, 24)
         @notify.bitmap.fill_rect(0, 0, 24, 24, BlizzCFG::ColorWhite)
         @notify.bitmap.fill_rect(22, 1, 2, 23, BlizzCFG::ColorBlack)
         @notify.bitmap.fill_rect(1, 22, 23, 2, BlizzCFG::ColorBlack)
         @notify.bitmap.set_pixel(23, 0, BlizzCFG::ColorBlack)
         @notify.bitmap.set_pixel(0, 23, BlizzCFG::ColorBlack)
         @notify.bitmap.fill_rect(2, 2, 20, 20, BlizzCFG::ColorIcon)
         @notify.bitmap.fill_rect(4, 10, 16, 4, BlizzCFG::ColorWhite)
         @notify.bitmap.fill_rect(10, 4, 4, 16, BlizzCFG::ColorWhite)
         @notify.opacity = BlizzCFG::ICON_OPACITY
       end
       @notify.x, @notify.y = BlizzCFG::ICON_X, BlizzCFG::ICON_Y
       @notify.z = 5000
       @notify.blink_on
     end
     @notify.update
   elsif @notify != nil
     @notify.dispose
     @notify = nil
   end
 end
 
end