Hey, sorry for being such a bum about this. I am finished, but I really haven't had time to test it and I didn't do anything to incorporate it into other scripts yet either. Sorry. Anyway, I figure that since I have no idea when I will be able to test it, I will just share it and you can test it and report back to me if something isn't working properly. Also, you can tell me what needs improvement.
Here it is - I made a small update to
LSU to version 2.0a. You will need to grab that first.
Put the LSU script above all other custom scripts that use skill noteboxes, and put this addon directly below it:
#==============================================================================
# Skill Levels
# Addon to Learn Skills By Use 2.0a
# Version: 1.0
# Author: modern algebra (rmrk.net)
# Date: October 11, 2010
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Description:
#
# This is an addon to Learn Skills By Use that permits you to create levels
# of the skill that are learnable by using the lower level version of a skill
# a set number of times.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Instructions:
#
# If using this script, then you must put the Learn Skills By Use 2.0a above
# every other custom script in the Script Editor (F11), and put this script
# directly under it. Otherwise, it will not inherit note stats from other
# scripts.
#
# Firstly, you can have an actor directly learn a level of a skill by using
# the following code in a Script call in an event:
# learn_skill_level (actor_id, skill_id, level)
# actor_id : the ID of the actor you want to learn the skill level
# skill_id : the ID of the skill
# level : the level of the skill you want the actor to learn.
#
# Now for the hard stuff: setting up levels of the skill. The most important
# part of this are the level tags (note that you can change what you use for
# tags in the MASL_REGEXP hash in the Editable Region):
#
# \L[x].../L
#
# Everything between those tags will be placed only in the note of the skill
# level x. Anything that is not between tags like that will be in the note of
# all levels of the skills (except for root_skill paths). This is useful for
# two reasons: 1. It allows you to set the generic stats for that level; and
# 2. If using a script that allows you to set stats through the notebox, then
# they will only apply to the levels you want them to.
#
# For each of the generic skill stats, you can specify a new value for that
# level between the level codes. Each generic stat has a shortcut to take less
# room than writing out its name, though you can do that as well. You can set
# what the shortcuts are in the MASL_REGEXP hash if you need to. Any of these
# may be placed within the \L[x].../L and will change the stat for that level.
# If not specified, then the stat will default to whatever it is set up in the
# database as.
# \N[x] - This will set the name of the skill to x.
# \D[x] - This will set the description of the skill to x.
# \M1[x] - This will set the first line of the use message to x.
# \M2[x] - This will set the second line of the use message to x
# \I[x] - This will set the icon used to x.
# \S[x] - This will set the scope to x. (0 => None; 1 => One Enemy;
# 2 => All Enemies; 3 => One Enemy Dual; 4 => One Random Enemy;
# 5 => 2 Random Enemies; 6 => 3 Random Enemies; 7 => One Ally;
# 8 => All Allies; 9 => One Ally (Dead); 10 => All Allies (Dead)
# 11 => The User)
# \O[x] - This will set the occasion to x. (0 => Always;
# 1 => Only in Battle; 2 => Only from the Menu; 3 => Never)
# \SPD[x] - This will set the speed to x.
# \AID[x] - This sets the ID of the animation used to x.
# \CEID[x] - This sets the ID of the common event called to x.
# \DMG[x] - This sets the base damage value to x.
# \V[x] - This sets the variance to x.
# \ATK[x] - This sets the ATK_F stat to x.
# \SPI[x] - This sets the SPI_F stat to x.
# \H[x] - This sets the hit stat to x.
# \MP[x] - This sets the MP cost to x.
# \PA - This sets the physical attack property to on.
# \!PA - This sets the physical attack property to off.
# \DMP - This sets the damage to MP property to on.
# \!DMP - This sets the damage to MP property to off.
# \AD - This sets the absorb damage property to on.
# \!AD - This sets the absorb damage property to off.
# \ID - This sets the ignore defence property to on.
# \!ID - This sets the ignore defence property to off.
# \ES[x,y,z] - This sets the element set array. Add each ID of every
# element you want the skill to have and separate by commas.
# \PSS[x,y,z] - This sets the plus state set array. Add each ID of every
# state you want the skill to add and separate by commas.
# \MSS[x,y,z] - This sets the minus state set array. Add each ID of every
# state you want the skill to remove and separate by commas.
#
# Another very important code is the \use command. Outside of level tags, the
# code is used as following:
#
# \use[x, y]
# where x is the base number of uses and y is the level growth. Put
# simply, the formula is x + (level-1)*y, and that is how many times you
# will need to use the previous skill in order to level it up.
#
# The best way to demonstrate is an example. If you have \use[10, 15], then
# you will have to use the initial skill 10 (10 + 0*15) times to get it to
# level 2. You will then have to use the level 2 skill 25 (10 + 1*15) times to
# learn level 3. You will then have to use the level 3 skill 40 (10 + 2*15)
# times to get to level 4, etc...
#
# However, you can also use the \use code within level tags and that will
# directly set how many times you need to use the previous skill to get to the
# level. In this case, the code is simply:
# \use[x]
# where x is the number of times to use the skill.
#
# The Use commands are crucial! Without them, you cannot advance to new
# levels unless you use the \root_skill (shortcutted as \RS) within the level
# tags. You will need to do this if you want to require another skill in order
# to advance to a particular level (in which case you cannot use the \use codes
# as they only deal with the previous level of the skill. If you want to use
# the \RS codes, you may. Keep in mind that the ID of a skill greater than
# level 1 is (level - 1)*1000 + id. So, if you have a skill with ID 17 in the
# database, then level 2 of the skill can be referenced by 1017, level 3 by
# 2017, level 4 by 3017, etc...
#
# Anyway, all of that probably sounds confusing, so here are some examples:
#
# Skill 1 (Fire I) Notebox:
# I am generic note\use[15, 10]
# \L[1]note that only applies to level 1/L
# \l[2]\n[Fire II]\pss[13]level 2
# note\dmg[50]/l
# \L[3]\dmg[50]\h[85]\pss[13,16]
# \n[Fire III]\ADLEVEL 3/L
#
# OK, so the first level of the skill would be exactly what you see in the
# database. Let's say it's called Fire I, does 30 damage, and has a hit rate of
# 80. The note of the level 1 skill, for the purposes of other scripts, would
# read: "I am generic note\use[15, 10] note that only applies to level 1
# Because of the \use[15,10] code, you would learn level 2 of this skill
# after 15 uses.
# As you can see within the \l[2].../l codes, there is a \n code which will
# change the name of the skill to Fire II. As well, it now adds the state with
# ID 13 (Attack Down), and does 50 damage. It's note, for the purposes of other
# scripts, will read: "I am generic note\use[15, 10] level 2 note". You would
# get to level 3 after using this skill 25 times.
# Again with level 3, the damage will be 50 (note that it needs to be repeated
# as otherwise it would inherit from level 1. The hit rate of this script is
# set to 85 by the \h code. In addition to state 13, the \pss code also adds
# state 16 (AGI Down). The \n code changes the name of the skill to Fire III
# and the \AD code now makes it so the user will absorb the damage. The note
# of level 3 will read: "I am generic note\use[15, 10] LEVEL 3"
#
# It probably seems a little complicated but I am sure you will get the hang
# of it. I will do one more little example just to show the use of \RS codes.
# I will leave out any substantive changes since the only thing I want to show
# is how you can vary the requirements for learning a new level.
#
# Skill 2 Note (ID is 2)
# \L[2]\rs[2, 15, <4>, F]
# \rs[4, 0, <2>]/L
# \L[3]\use[25]/L
# \L[4]\rs[2002, 25, <1004>, F]
# \rs[1004, 10, <2002>]/L
#
# OK, so what the above code will do is fairly simple. As I said, I didn't put
# anything that would actually change the stats of the skill - I just want to
# focus on the use of RS codes. In order to advance to level 2 of the skill,
# the \rs[2, 15, <4>, F] code means that you must use level 1 of the skill 15
# times. However, the <4> means that you also have to meet the conditions of
# \rs[4, 0, <2>] before it will advance. In that case, you don't have to use
# skill 4, you just need to have learned it before it will allow you to
# advance. The F in the first will mean that you will forget the 1st level of
# the skill when you learn level 2.
#
# Next, the level 3 codes only have a \use[25] code in it. This means you will
# just have to use the level 2 version of the skill 25 times before you learn
# level 3.
#
# Finally, in order to learn level 4, the \rs[2002, 25, <1004>, F] code means
# that you need to use the level 3 version of the skill 25 times but also need
# to meet the conditions for 1004 (level 2 of skill 4). That code is
# \rs[1004, 10, <2002>], which means that you need to use the level 2 version
# of skill 4 10 times. You then forget level 3 of skill 2.
#
# All in all, I recommend just using \use codes, but \rs will be necessary if
# you want to require other skills in order to advance levels. I note that
# while you are able to use \use[x] code within a level branch, you cannot use
# the \use[x, y] code outside or else that will establish a path where you only
# have to use the previous level of the skill.
#==============================================================================
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# EDITABLE REGION
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# MASL_FORGET_LOWER_LEVELS - a boolean. When true, then the lower levels of the
# skills are forgotten when an actor learns a new level skill. In other words,
# it will replace. If false, then the lower levels will not be erased.
MASL_FORGET_LOWER_LEVELS = true
# MASL_VOCAB_LEVELSKILL - When a skill levels, what message do you want to
# show up. %s will be replaced by the skill name, %n will be replaced by the
# actor name, and %l will be replaced by the level. %s1 will be replaced with
# the name of the first level of the skill.
MASL_VOCAB_LEVELSKILL = "%s1 has levelled up! It is now Level %l"
# MASL_REGEXP - shortcuts for setting the default attributes differently per
# level. If you edit this, remember that there must be a comma after each line
MASL_REGEXP = { # <- Do not touch this!
"level" => "L",
"name" => "N",
"description" => "D",
"message1" => "M1",
"message2" => "M2",
"icon_index" => "I",
"scope" => "S",
"occasion" => "O",
"speed" => "SPD",
"animation_id" => "AID",
"common_event_id" => "CEID",
"base_damage" => "DMG",
"variance" => "V",
"atk_f" => "ATK",
"spi_f" => "SPI",
"hit" => "H",
"mp_cost" => "MP",
"physical_attack" => "PA",
"damage_to_mp" => "DMP",
"absorb_damage" => "AD",
"ignore_defense" => "ID",
"element_set" => "ES",
"plus_state_set" => "PSS",
"minus_state_set" => "MSS",
"root_skill" => "RS"
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# END EDITABLE REGION
#//////////////////////////////////////////////////////////////////////////////
} # <- Do not touch this
#==============================================================================
# ** RPG::Skill
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new class constant - MASL_ATTR_NAMES
# new instance method - masl_setup_skill_level
#==============================================================================
class RPG::Skill
MASL_ATTR_NAMES = [["name", "description", "message1", "message2"],
["physical_attack", "damage_to_mp", "absorb_damage", "ignore_defense"],
["icon_index", "scope", "occasion", "speed", "animation_id",
"common_event_id", "base_damage", "variance", "atk_f", "spi_f", "hit",
"mp_cost"],
["element_set", "plus_state_set", "minus_state_set"]]
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Setup Skill Level
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def masl_setup_skill_level (new_id, unique_note = "")
self.id = new_id
# Get all attribute names
string_attr, boolean_attr, int_attr, ary_attr = *MASL_ATTR_NAMES
# Set any string attributes specified
string_attr.each { |attr|
unique_note.sub! (/\\(#{MASL_REGEXP[attr]}|#{attr})\[(.+?)\]/i) {
self.send (attr + "=", $2.to_s)
"" }
}
# Set any boolean attributes specified
boolean_attr.each { |attr|
unique_note.sub! (/\\(!?)(#{MASL_REGEXP[attr]}|#{attr})/i) {
self.send (attr + "=", $2.empty?)
"" }
}
# Set any integer attributes specified
int_attr.each { |attr|
unique_note.sub! (/\\(#{MASL_REGEXP[attr]}|#{attr})\[(\d+)\]/i) {
self.send (attr + "=", $2.to_i)
"" }
}
# Set any array attributes specified
ary_attr.each { |attr|
if (unique_note.sub! (/\\(#{MASL_REGEXP[attr]}|#{attr})\[(.+?)\]/i) { "" }) != nil
array = []
$2.gsub (/(\d+)/i) { |int| array.push (int.to_i) }
self.send (attr + "=", array)
end
}
unique_note.gsub! (/\\#{MASL_REGEXP["root_skill"]}\[/i) { "\\ROOT_SKILL[" }
self.note.gsub! (/\\(LEVEL|#{MASL_REGEXP["level"]})\[(\d+)\].*?\/(LEVEL|#{MASL_REGEXP["level"]})/i) { "" }
# Delete any global references to root skills since, if located
# outside level branches, it would be sufficient to teach all the
# higher levels of the skill immediately. This way, they can only
# apply to the first level of the skill.
self.note.gsub! (/\\ROOT_SKILL\[.+?\]/i) { "" }
self.note += unique_note
# Put in use requirements
f = MASL_FORGET_LOWER_LEVELS ? ", F" : ""
if unique_note[/\\USE\[(\d+)\]/i] != nil
self.note += "\\ROOT_SKILL[#{self.id - 1000}, #{$1}#{f}]"
elsif self.note[/\\USE\[(\d+)[,:;]\s*(\d+)\]/i] != nil
use = $1.to_i + (self.id / 1000)*$2.to_i
self.note += "\\ROOT_SKILL[#{self.id - 1000}, #{use}#{f}]"
end
end
end
#==============================================================================
# ** Data_Skills
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This class is a subclass of array meant to be able to handle calls for
# different skill levels
#==============================================================================
class Data_Skills < Array
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (default_array)
super (default_array.size) # Run super method
# Duplicate array
for i in 0...default_array.size
self[i] = default_array[i]
end
create_level_hash
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Create Level Hash
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def create_level_hash
@level_hash = {}
for i in 0...self.size
skill = self[i]
next if skill.nil?
# Split RPG::Skill into multiple skills for each level
skill.note.gsub! (/\\(LEVEL|#{MASL_REGEXP["level"]})\[(\d+)\](.*?)\/(LEVEL|#{MASL_REGEXP["level"]})/i) {
level = $2.to_i
l_note = $3.to_s
if level < 1
""
elsif level == 1
l_note
else
new_skill = Marshal.load (Marshal.dump (skill))
new_skill.masl_setup_skill_level (skill.id + (level - 1)*1000, l_note)
@level_hash[new_skill.id] = new_skill
""
end
}
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Reset LSU Cache
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def reset_lsu_cache
# Reset Root Skills analysis for every level
self.each { |skill|
next if skill.nil?
skill.ma_root_skills.each { |path|
path.each { |a| self[a[0]].ma_descendant_skills.delete (self.id) }
}
skill.ma_cache_lsu_skill_stats # Recache skill stats for LSU
}
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Element
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def [] (key)
if key > 1000
return @level_hash[key] unless @level_hash[key].nil?
return self[key - 1000]
end
return super (key)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Iterate
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def each (*args, &block)
return (self + @level_hash.values).each (*args, &block)
end
end
if LSU_LEARN_IMMEDIATELY
#==============================================================================
# ** Dialog_LearnSkill
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This class processes when a new skill is learned
#==============================================================================
class Dialog_LearnSkill < Dialog
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Help Text
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias malg_lsusl_hlptxt_6yn2 help_text
def help_text (*args)
if @skill.id > 1000
text = MASL_VOCAB_LEVELSKILL.gsub (/%s1/) { $data_skills[@skill.id % 1000].name }
text.gsub! (/%s/) { @skill.name }
text.gsub! (/%n/) { @actor.name }
return text.gsub (/%l/) { ((@skill.id / 1000) + 1).to_s }
else
return malg_lsusl_hlptxt_6yn2 (*args)
end
end
end
end
#==============================================================================
# ** Game_Interpreter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new method - learn_skill_level
#==============================================================================
class Game_Interpreter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Learn Skill Level
# actor_id : ID of the actor who is learning the skill
# skill_id : ID of the base skill
# level : level of the skill to teach.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def learn_skill_level (actor_id, skill_id, level = 1)
actor = $game_actors[actor_id]
# Forget all lower level instances of this skill
if MASL_FORGET_LOWER_LEVELS && level > 1
actor.skills.each { |skill|
if skill.id % 1000 == skill_id && skill.id < (level - 1)*1000
actor.forget_skill (skill_id)
end
}
end
actor.learn_skill (skill_id + (level - 1)*1000)
end
end
#==============================================================================
# ** Scene_Title
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased methods - load_database, load_bt_database
#==============================================================================
class Scene_Title
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Load Database
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias moral_sklvl_loaddb_7ol9 load_database
def load_database (*args)
moral_sklvl_loaddb_7ol9 (*args) # Run Original Method
$data_skills = Data_Skills.new ($data_skills)
$data_skills.reset_lsu_cache
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Load Database for Battle Testing
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias mnab_lvskl_btdata_6wp1 load_bt_database
def load_bt_database (*args)
mnab_lvskl_btdata_6wp1 (*args) # Run Original Method
$data_skills = Data_Skills.new ($data_skills)
$data_skills.reset_lsu_cache
end
end
Have fun and hopefully it works. Make sure you tell me if there are any bugs or if some things need improvement.