Hi, this is my skill tree script. :) It is meant to be a simple but effective skill tree, as Diablo II's one. So features implemented are pretty much the essential ones a skill tree should have.
- Multiple Skill Trees per class: Each actor starts with the skill trees their classes determine.
- Learn/Forget Skill Trees: Actors may acquire access to a certain skill tree and lose it too.
- Skill Level Up: Skills may become stronger by being leveled up.
- Enemies may use Leveled up Skills: self explanatory :v
- Eyecandy! Smooth movement at the cursor, able to customize arrows and put some fancy icons and whatnot :p
Preview
A gif preview of the skill tree scene
How to Use
View attachment Skill Tree Demo.zip
Open the demo for in-depth instructions.
Script
Code: Comes first, before Config, before Main, after the other standard ones.
Spoiler
Spoiler
#==============================================================================# ** cockroach's SkillTree#------------------------------------------------------------------------------# Hi, this is my skill tree script. It is meant to be a simple but effective# skill tree, as Diablo II's one. So features implemented are pretty much the# basic ones a skill tree should have.## Terms of Use: Use it in any game you want, edit is as you please, in any type# of game. You can even steal the credit and post it in a chinese# underground forum as if it was yours, if you want #==============================================================================# ** SkillTree Class#------------------------------------------------------------------------------# This class contains the SkillTree object processing. Skill trees contain# their basic info and a big array of levels, each level containing an array# of skills, each skill being an array of parameters in their regard.# The class contains a number of helper functions to Skill Tree objects.#==============================================================================class SkillTree #-------------------------------------------------------------------------- # * Readable attributes in a skill tree #-------------------------------------------------------------------------- attr_reader :name # Tree's name attr_reader :description # Tree's description attr_reader :skill_tree # The skilltree's body - an array containing arrays attr_reader :level_at_col # An array telling which req. level to each column #-------------------------------------------------------------------------- # * Initialize: Sets up the basic info #-------------------------------------------------------------------------- def initialize(name, description, tree) @name = name @description = description @skill_tree = tree @level_at_col = [] count = 0 for i in @skill_tree if i != [] @level_at_col.push(count) end count += 1 end end #-------------------------------------------------------------------------- # * How Many Levels: How many different required levels are there in the # skilltree? (If theres a skill at 3, two at 9 and one at 12, there are 3 lvs # this is useful to determine how many columns will be drawn. #-------------------------------------------------------------------------- def how_many_lvs lv_count = 0 count = 0 for i in @skill_tree if i != [] lv_count += 1 end count += 1 end return lv_count end #-------------------------------------------------------------------------- # * How Many Rows: How many rows are there in the skill tree? That is, what # is the maximum pos_Y in the tree. It helps to divide the tree in rows. #-------------------------------------------------------------------------- def how_many_rows row_count = 0 #count = 0 for i in @skill_tree #print "this is i ", i if i != [] for j in i #print "this is j ", j if j[2] > row_count row_count = j[2] end end end #count += 1 end return row_count end #-------------------------------------------------------------------------- # * Is a Valid Level? : Does this level contain skills that require it? #-------------------------------------------------------------------------- def is_a_valid_level?(level) return @skill_tree[level] != [] end #-------------------------------------------------------------------------- # * Find Skill Pos: Given a skill, this method searches for it in the present # tree, returning a coordinate compatible with the command list in Window #-------------------------------------------------------------------------- def find_skill_pos(skill) # searches through all levels in the SkillTree for lv in 1...@skill_tree.size # searches through all skills in each level for sk in @skill_tree[lv] # checks if the skill is the one we're looking for if sk[0] == skill # now search for the column and the row the skill is drawn col = @level_at_col.index(lv) row = sk[2] com = (@level_at_col.size*(row-1)) + col # return a single value compatible with @commands in windows return com end end end end #-------------------------------------------------------------------------- # * Is Skill Available? : Is the skill available for the actor to be learned? # This function checks if actor has learned the pre-requisites to a certain # skill that is contained in the skill tree, and if he has enough levels #-------------------------------------------------------------------------- def is_skill_available?(actor, skill, check_level = true) level = 0 # check every level array in skill_tree for lv in @skill_tree # if there's a skill at the current level if lv != [] # check all skills in current level for sk in lv # check if skill id is the one we're looking for if sk[0] == skill # if current level is below required, return false rank = actor.skill_rank[skill] req_increment = rank * (Skill_Tree_Config::CST_REQ_INCREMENT_PER_LEVEL) req_level = level + req_increment return false if actor.level < req_level # if skill has requirements if sk[1] != [] # check all requirements for rq in sk[1] # if actor doesn't know skill required, return false if not(actor.skills.include?(rq)) return false end end end end end end level += 1 end # if no issues found, the skill is available return true end #-------------------------------------------------------------------------- # * Get Icon Opacity: How should a skill be shown? This function will check # the circumstance to know if the skill is: # - Already learned: returns total opacity # - Available to learn: returns half opacity # - Unavailable: returns little opacity #-------------------------------------------------------------------------- def get_icon_opacity(actor, skill) if actor.skills.include?(skill) return Skill_Tree_Config::CST_OPACITY_LEARNED elsif is_skill_available?(actor, skill) return Skill_Tree_Config::CST_OPACITY_AVAILABLE else return Skill_Tree_Config::CST_OPACITY_UNAVAILABLE end end #-------------------------------------------------------------------------- # * Helper Function: This function prepares a list of skill_id's or empty (0) # values to be drawn in the SkillTree_Window #-------------------------------------------------------------------------- def get_command_list col_num = how_many_lvs # a column will be drawn for each req. level row_num = how_many_rows # a row will be drawn for each row specified commands = [] will_place_empty = false for i in 1..row_num for j in @skill_tree if j != [] will_place_empty = true for l in j if l[2] == i commands.push(l[0]) will_place_empty = false end end if will_place_empty commands.push(0) end end end end return commands end #-------------------------------------------------------------------------- # * Get Requirement Links: Given a list of commands in the Window @commands # pattern, checks through all skills to return a list in order to draw the # skill req. arrows. Format: [[origin, destination], [orig, dest], etc...] #-------------------------------------------------------------------------- def get_requirement_links(commands) requirement_links = [] pos = 0 col_num = how_many_lvs for com in commands if com != nil col = pos % col_num lv = @level_at_col[col] for sk in @skill_tree[lv] if sk[0] == com for rq in sk[1] # adds a pair of [origin, destination] requirement_links.push([pos, find_skill_pos(rq)]) end end end end pos += 1 end return requirement_links end end#==============================================================================# ** cockroach's SkillTree - SkillTree_Alterations#------------------------------------------------------------------------------# This class contains the alterations necessary in the default classes, so the# mechanics are fixed to adapt to the skill tree learning system. Most of the# changes are in order to support the leveling-up of the skills.#==============================================================================#==============================================================================# ** Game_Battler:#------------------------------------------------------------------------------# An additional parameter is added to all instances of Game_Battler, which is# skill_rank[skill_id]. For each skill, it stores a level. That rank can be# changed in-game, via events, items, such as potions, quests, etc.#==============================================================================class Game_Battler attr_accessor :skill_rank #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize @battler_name = "" @battler_hue = 0 @hp = 0 @sp = 0 @states = [] @states_turn = {} @maxhp_plus = 0 @maxsp_plus = 0 @str_plus = 0 @dex_plus = 0 @agi_plus = 0 @int_plus = 0 @hidden = false @immortal = false @damage_pop = false @damage = nil @critical = false @animation_id = 0 @animation_hit = false @white_flash = false @blink = false @current_action = Game_BattleAction.new # ADDED: @skill_rank init - prepares the array with default values. @skill_rank = [] for i in $data_skills @skill_rank.push(0) end end #-------------------------------------------------------------------------- # * Apply Skill Effects: this method is changed so it checks if the rank of # the skill being used is greater than 1, in order to enhance it. #-------------------------------------------------------------------------- def skill_effect(user, skill) self.critical = false if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or ((skill.scope == 5 or skill.scope == 6) and self.hp >= 1) return false end effective = false effective |= skill.common_event_id > 0 hit = skill.hit if skill.atk_f > 0 hit *= user.hit / 100 end hit_result = (rand(100) < hit) effective |= hit < 100 # ADDED: prepares local operators that will multiply/add to the power factor = 1 addition = 0 if hit_result == true id = skill.id rank = user.skill_rank[id] # If rank is greater than 1, apply enhancements if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(id) factor = CST_SkillConfig::CST_SKILLCONFIG[id][0]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[id][1]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][0]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][1]*rank end end base_power = (skill.power * factor + addition).to_i power = base_power + user.atk * skill.atk_f / 100 if power > 0 power -= self.pdef * skill.pdef_f / 200 power -= self.mdef * skill.mdef_f / 200 power = [power, 0].max end rate = 20 rate += (user.str * skill.str_f / 100) rate += (user.dex * skill.dex_f / 100) rate += (user.agi * skill.agi_f / 100) rate += (user.int * skill.int_f / 100) self.damage = power * rate / 20 self.damage *= elements_correct(skill.element_set) self.damage /= 100 if self.damage > 0 if self.guarding? self.damage /= 2 end end if skill.variance > 0 and self.damage.abs > 0 amp = [self.damage.abs * skill.variance / 100, 1].max self.damage += rand(amp+1) + rand(amp+1) - amp end eva = 8 * self.agi / user.dex + self.eva hit = self.damage < 0 ? 100 : 100 - eva * skill.eva_f / 100 hit = self.cant_evade? ? 100 : hit hit_result = (rand(100) < hit) effective |= hit < 100 end if hit_result == true if skill.power != 0 and skill.atk_f > 0 remove_states_shock effective = true end last_hp = self.hp self.hp -= self.damage effective |= self.hp != last_hp @state_changed = false effective |= states_plus(skill.plus_state_set) effective |= states_minus(skill.minus_state_set) if skill.power == 0 self.damage = "" unless @state_changed self.damage = "Miss" end end else self.damage = "Miss" end unless $game_temp.in_battle self.damage = nil end return effective end #-------------------------------------------------------------------------- # * Skill Can Use? : Changed so it support mana cost progressive enhancements #-------------------------------------------------------------------------- def skill_can_use?(skill_id) sp_cost_base = $data_skills[skill_id].sp_cost factor = 1 addition = 0 rank = self.skill_rank[skill_id] # if rank is greater than 1, apply enhancements if rank > 1 if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(skill_id) factor = CST_SkillConfig::CST_SKILLCONFIG[skill_id][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[skill_id][3]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][3]*rank end end end sp_cost = (sp_cost_base * factor + addition).to_i if sp_cost > self.sp return false end if dead? return false end if $data_skills[skill_id].atk_f == 0 and self.restriction == 1 return false end occasion = $data_skills[skill_id].occasion if $game_temp.in_battle return (occasion == 0 or occasion == 1) else return (occasion == 0 or occasion == 2) end endend#==============================================================================# ** Game_Actor:#------------------------------------------------------------------------------# Changed so it stores the Skill_Trees learned by the actor and how much skill# points he/she has to spend on them. Also, the default learning system is# removed. Also, added three methods to handle skill tree learning:# - learn_skilltree# - forget_skilltree# - knows_skilltree?#==============================================================================class Game_Actor < Game_Battler attr_accessor :skill_trees # Skill trees available to actor attr_accessor :skill_points # Skill points remaining to be spent #-------------------------------------------------------------------------- # * Setup: Changed so it initialize attributes and don't learn skills by def #-------------------------------------------------------------------------- def setup(actor_id) actor = $data_actors[actor_id] @actor_id = actor_id @name = actor.name @character_name = actor.character_name @character_hue = actor.character_hue @battler_name = actor.battler_name @battler_hue = actor.battler_hue @class_id = actor.class_id @weapon_id = actor.weapon_id @armor1_id = actor.armor1_id @armor2_id = actor.armor2_id @armor3_id = actor.armor3_id @armor4_id = actor.armor4_id @level = actor.initial_level @exp_list = Array.new(101) make_exp_list @exp = @exp_list[@level] @skills = [] @hp = maxhp @sp = maxsp @states = [] @states_turn = {} @maxhp_plus = 0 @maxsp_plus = 0 @str_plus = 0 @dex_plus = 0 @agi_plus = 0 @int_plus = 0 # Default learning system substituted by the parameters settings @skill_trees = Skill_Tree_Config::CST_CLASS_SKILL_TREES[@class_id] @skill_points = Skill_Tree_Config::CST_SKILL_POINTS_PER_LEVEL * @level update_auto_state(nil, $data_armors[@armor1_id]) update_auto_state(nil, $data_armors[@armor2_id]) update_auto_state(nil, $data_armors[@armor3_id]) update_auto_state(nil, $data_armors[@armor4_id]) end #-------------------------------------------------------------------------- # * Exp: Changed so the actor doesn't learn skills normally by leveling up. # Instead, he is given a quantity of skill_points per level. (default is 1) #-------------------------------------------------------------------------- def exp=(exp) @exp = [[exp, 9999999].min, 0].max while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0 @level += 1 # Acquire skill_points per level @skill_points += Skill_Tree_Config::CST_SKILL_POINTS_PER_LEVEL end # Level down while @exp < @exp_list[@level] @level -= 1 end @hp = [@hp, self.maxhp].min @sp = [@sp, self.maxsp].min end #-------------------------------------------------------------------------- # * Learn Skilltree: makes an actor have access to a skilltree #-------------------------------------------------------------------------- def learn_skilltree(id) @skill_trees.push(id) if not(@skill_trees.include?(id)) end #-------------------------------------------------------------------------- # * Forget Skilltree: takes access away from the actor to a skill tree # (forgetting a skilltree doesn't forget its skills, or their ranks) #-------------------------------------------------------------------------- def forget_skilltree(id) @skill_trees.delete(id) end #-------------------------------------------------------------------------- # * Knows Skilltree? : checks if actor knows a certain skilltree #-------------------------------------------------------------------------- def knows_skilltree?(id) return @skill_trees.include?(id) endend#==============================================================================# ** Game_Enemy:#------------------------------------------------------------------------------# Changed so it stores ranks to each skill. See the config for how to set them#==============================================================================class Game_Enemy < Game_Battler def initialize(troop_id, member_index) super() @troop_id = troop_id @member_index = member_index troop = $data_troops[@troop_id] @enemy_id = troop.members[@member_index].enemy_id enemy = $data_enemies[@enemy_id] @battler_name = enemy.battler_name @battler_hue = enemy.battler_hue @hp = maxhp @sp = maxsp @hidden = troop.members[@member_index].hidden @immortal = troop.members[@member_index].immortal # Set skill ranks based on battle actions for action in $data_enemies[@enemy_id].actions lv = action.condition_level > 0 sw = action.condition_switch_id == Skill_Tree_Config::CST_ENEMY_SKILL_SWITCH sk = action.skill_id > 0 if lv and sw and sk @skill_rank[action.skill_id] = action.condition_level end end endend#==============================================================================# ** Window_Skill:#------------------------------------------------------------------------------# Changed so it shows mana cost correctly, based on level rank#==============================================================================class Window_Skill < Window_Selectable def draw_item(index) skill = @data[index] if @actor.skill_can_use?(skill.id) self.contents.font.color = normal_color else self.contents.font.color = disabled_color end x = 4 + index % 2 * (288 + 32) y = index / 2 * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) bitmap = RPG::Cache.icon(skill.icon_name) opacity = self.contents.font.color == normal_color ? 255 : 128 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0) sp_cost_base = skill.sp_cost factor = 1 addition = 0 rank = @actor.skill_rank[skill.id] if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(skill.id) factor = CST_SkillConfig::CST_SKILLCONFIG[skill.id][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[skill.id][3]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][3]*rank end end sp_cost = (sp_cost_base * factor + addition).to_i self.contents.draw_text(x + 232, y, 48, 32, sp_cost.to_s, 2) endend#==============================================================================# ** Scene_Skill:#------------------------------------------------------------------------------# Changed so it uses the mana cost and applies the effect correctly#==============================================================================class Scene_Skill #-------------------------------------------------------------------------- # * Frame Update (if skill window is active) #-------------------------------------------------------------------------- def update_skill # If B button was pressed if Input.trigger?(Input:: # Play cancel SE $game_system.se_play($data_system.cancel_se) # Switch to menu screen $scene = Scene_Menu.new(1) return end # If C button was pressed if Input.trigger?(Input::C) # Get currently selected data on the skill window @skill = @skill_window.skill # If unable to use if @skill == nil or not @actor.skill_can_use?(@skill.id) # Play buzzer SE $game_system.se_play($data_system.buzzer_se) return end # Play decision SE $game_system.se_play($data_system.decision_se) # If effect scope is ally if @skill.scope >= 3 # Activate target window @skill_window.active = false @target_window.x = (@skill_window.index + 1) % 2 * 304 @target_window.visible = true @target_window.active = true # Set cursor position to effect scope (single / all) if @skill.scope == 4 || @skill.scope == 6 @target_window.index = -1 elsif @skill.scope == 7 @target_window.index = @actor_index - 10 else @target_window.index = 0 end # If effect scope is other than ally else # If common event ID is valid if @skill.common_event_id > 0 # Common event call reservation $game_temp.common_event_id = @skill.common_event_id # Play use skill SE $game_system.se_play(@skill.menu_se) # Use up SP sp_cost_base = @skill.sp_cost factor = 1 addition = 0 rank = @actor.skill_rank[@skill.id] if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(@skill.id) factor = CST_SkillConfig::CST_SKILLCONFIG[@skill.id][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[@skill.id][3]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][3]*rank end end sp_cost = (sp_cost_base * factor + addition).to_i @actor.sp -= sp_cost # Remake each window content @status_window.refresh @skill_window.refresh @target_window.refresh # Switch to map screen $scene = Scene_Map.new return end end return end # If R button was pressed if Input.trigger?(Input::R) # Play cursor SE $game_system.se_play($data_system.cursor_se) # To next actor @actor_index += 1 @actor_index %= $game_party.actors.size # Switch to different skill screen $scene = Scene_Skill.new(@actor_index) return end # If L button was pressed if Input.trigger?(Input::L) # Play cursor SE $game_system.se_play($data_system.cursor_se) # To previous actor @actor_index += $game_party.actors.size - 1 @actor_index %= $game_party.actors.size # Switch to different skill screen $scene = Scene_Skill.new(@actor_index) return end endend#==============================================================================# ** Scene_Skill:#------------------------------------------------------------------------------# Changed so SP is spent correctly in battle when skill is ranked up#==============================================================================class Scene_Battle def make_skill_action_result # Get skill @skill = $data_skills[@active_battler.current_action.skill_id] # If not a forcing action unless @active_battler.current_action.forcing # If unable to use due to SP running out unless @active_battler.skill_can_use?(@skill.id) # Clear battler being forced into action $game_temp.forcing_battler = nil # Shift to step 1 @phase4_step = 1 return end end # Use up SP sp_cost_base = @skill.sp_cost factor = 1 addition = 0 if @active_battler.is_a? Game_Actor id = @skill.id rank = @active_battler.skill_rank[id] if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(id) factor = CST_SkillConfig::CST_SKILLCONFIG[id][0]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[id][1]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][0]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][1]*rank end end end sp_cost = (sp_cost_base * factor + addition).to_i @active_battler.sp -= sp_cost # Refresh status window @status_window.refresh # Show skill name on help window @help_window.set_text(@skill.name, 1) # Set animation ID @animation1_id = @skill.animation1_id @animation2_id = @skill.animation2_id # Set command event ID @common_event_id = @skill.common_event_id # Set target battlers set_target_battlers(@skill.scope) # Apply skill effect for target in @target_battlers target.skill_effect(@active_battler, @skill) end endend#==============================================================================# ** cockroach's SkillTree - SkillTree_Windows#------------------------------------------------------------------------------# This script creates and manages 4 Window classes - 2 normal and 2 selectable.# - Window_SkillTree_Tabs: chooses which Skill Tree to show# - Window_SkillTree: draws the skill tree itself and chooses skills# - Window_SkillTree_Description: shows the description of trees and skills# - Window_SkillTree_Actor: shows actor info and remaining skill points#==============================================================================#==============================================================================# ** Window_SkillTree_Tabs:#------------------------------------------------------------------------------# This Window_Selectable chooses which Skill Tree to show.#==============================================================================class Window_SkillTree_Tabs < Window_Selectable #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(actor) super(0, 0, 640, 64) self.contents = Bitmap.new(width - 32, height - 32) @actor = actor @skill_trees = @actor.skill_trees # How many Skill Trees will be shown? (Will depend on the actor's class) @item_max = @skill_trees.size @column_max = @item_max # Each button will have the name of the each Skill Tree @commands = [] for i in @skill_trees @commands.push($cst_skilltrees.name) end refresh self.index = 0 end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i) end end #-------------------------------------------------------------------------- # * Draw Skill Tree Names #-------------------------------------------------------------------------- def draw_item(index) x = 4 + index * (640/@item_max) self.contents.draw_text(x, 0, 608/@item_max, 32, @commands[index]) endend#==============================================================================# ** Window_SkillTree:#------------------------------------------------------------------------------# This Window_Selectable draws the skill tree and chooses which skill to learn#==============================================================================class Window_SkillTree < Window_Selectable attr_accessor :tree_id # ID of Skill Tree being shown in the window attr_accessor :arrows attr_accessor :column_max #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(actor, tree_id) super(0, 64, 640, 288) self.contents = Bitmap.new(width - 32, height - 32) # Setup base values @actor = actor @tree_id = tree_id @column_max = $cst_skilltrees[tree_id].how_many_lvs @rows = ($cst_skilltrees[tree_id].how_many_rows) @item_max = @rows*@column_max @arrows = [] # Calculates base horizontal and vertical distance between skill icons @x_step = (self.width - 32) / (@column_max + 1) @y_step = (self.height - 32) / @rows # Populates the command list with the ID of the correponding skills (or 0) @commands = $cst_skilltrees[tree_id].get_command_list refresh self.index = 0 end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear # Drawing call loop. If ID is 0, cell is empty, so no call to draw_item count = 0 for i in @commands draw_item(count) if i != 0 count += 1 end draw_arrows end #-------------------------------------------------------------------------- # * Draw Item # index : item number #-------------------------------------------------------------------------- def draw_item(index) # Setup coordinates to draw the skill x = index % @column_max * @x_step + @x_step - 12 y = index / @column_max * @y_step + @y_step/2 - 12 # Setup source info to the draw process skill_id = @commands[index] skill = $data_skills[skill_id] # Turn ID into skill object bitmap = RPG::Cache.icon(skill.icon_name) opacity = $cst_skilltrees[@tree_id].get_icon_opacity(@actor, skill_id) # Rank is the level for this skill to the current actor rank = @actor.skill_rank[skill_id] # Drawing phase self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.font.size = 16 self.contents.font.bold = true self.contents.font.color.set(0, 0, 0, 155) self.contents.draw_text(x - 2, y + 8, 32, 32, rank.to_s, 2) self.contents.font.size = 16 self.contents.font.bold = true self.contents.font.color.set(255, 255, 255, 255) self.contents.draw_text(x - 3, y + 7, 32, 32, rank.to_s, 2) end def draw_arrows dispose_arrows requirements = $cst_skilltrees[@tree_id].get_requirement_links(@commands) for rq_ar in requirements #print rq_ar[1], " is the source" #print rq_ar[0], " is the dest" draw_arrow(rq_ar[1], rq_ar[0]) end end def draw_arrow(source, dest) x_source = source % @column_max * @x_step + @x_step - 12 y_source = source / @column_max * @y_step + @y_step/2 - 12 x_dest = dest % @column_max * @x_step + @x_step - 12 y_dest = dest / @column_max * @y_step + @y_step/2 - 12 dist_x = x_dest - x_source dist_y = y_dest - y_source dist = Math.sqrt((dist_x*dist_x) + (dist_y*dist_y)) angle_r = Math.atan2(dist_x.to_f, dist_y.to_f) angle = (angle_r/Math::pI)*180.00 unit = Skill_Tree_Config::CST_ARROW_TILE_SIZE header = Skill_Tree_Config::CST_ARROW_TILE_HEADER body = Skill_Tree_Config::CST_ARROW_TILE_BODY tail = Skill_Tree_Config::CST_ARROW_TILE_TAIL ar_step_x = (Math.sin(angle_r)*unit.to_f).to_i ar_step_y = (Math.cos(angle_r)*unit.to_f).to_i ar_step_x = unit - 1 if ar_step_x >= unit ar_step_y = unit if ar_step_y > unit number_of_tiles = dist.to_i/unit refrain = 2 new_arrow_group = [] for i in 0..number_of_tiles next if i < refrain or i >= (number_of_tiles - refrain) arrow = Sprite.new case i when refrain arrow.bitmap = tail when number_of_tiles - refrain - 1 arrow.bitmap = header else arrow.bitmap = body end arrow.x = self.x + 24 + x_source + (ar_step_x*i) + ar_step_x arrow.y = self.y + 32 + y_source + (ar_step_y*i) + ar_step_y arrow.z = 9999 arrow.angle = angle arrow.opacity = Skill_Tree_Config::CST_ARROW_OPACITY arrow.visible = true new_arrow_group.push(arrow) end @arrows.push(new_arrow_group) end #-------------------------------------------------------------------------- # * Dispose Arrows #-------------------------------------------------------------------------- def dispose_arrows for i in @arrows for j in i j.dispose end end end #-------------------------------------------------------------------------- # * Update Cursor Rect - This method is changed so it fits skill icons #-------------------------------------------------------------------------- def update_cursor_rect if @index < 0 self.cursor_rect.empty return end row = @index / @column_max if row < self.top_row self.top_row = row end if row > self.top_row + (self.page_row_max - 1) self.top_row = row - (self.page_row_max - 1) end # Edit here: x and y position is set as relative to x_step and y_step x = @index % @column_max * @x_step + @x_step - 18 y = @index / @column_max * @y_step + @y_step/2 - 18 size = 36 prop = Skill_Tree_Config::CST_CURSOR_EMPTY_SPOT_PROPORTION accel = Skill_Tree_Config::CST_CURSOR_SMOOTH if @commands[@index] == 0 and prop != 1 x = @index % @column_max * @x_step + @x_step - 18 * prop y = @index / @column_max * @y_step + @y_step/2 - 18 * prop size = 36 * prop end if accel and (x != self.cursor_rect.x or y != self.cursor_rect.y or size != self.cursor_rect.width) x = (self.cursor_rect.x + x) / 2 y = (self.cursor_rect.y + y) / 2 size = (self.cursor_rect.width + size) / 2 end # And dimensions are fixed to 36 x 36 self.cursor_rect.set(x, y, size, size) end #-------------------------------------------------------------------------- # * Get Skill at Pos - This method gets which skill is at the cursor now #-------------------------------------------------------------------------- def get_skill_at_pos column = @index % @column_max row = (@index / @column_max) + 1 level = $cst_skilltrees[@tree_id].level_at_col[column] count = 0 for i in $cst_skilltrees[@tree_id].skill_tree #print "level ", count for j in i #print j[0], " is the skill / ", j[1], " is the req / row is ", j[2] if count == level and j[2] == row #print j[0], " works.." return j[0] end end count += 1 end return nil endend#==============================================================================# ** Window_SkillTree_Description:#------------------------------------------------------------------------------# This Window_Base draws skills/skill trees names, description and other info#==============================================================================class Window_SkillTree_Description < Window_Base attr_accessor :type attr_accessor :id attr_accessor :lv_rq attr_accessor :nxlv_rq attr_accessor :tree attr_accessor :rank attr_accessor :unable attr_accessor :learned #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(type, id, lv_rq = 0) super(0, 352, 450, 128) @type = type @id = id @tree = tree @lv_rq = lv_rq @unable = false @learned = false self.contents = Bitmap.new(width - 32, height - 32) refresh end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear draw_items end #-------------------------------------------------------------------------- # * Draw Items: draw info in the description window #-------------------------------------------------------------------------- def draw_items return if @id == nil x = 0 lv_str = "" nxlv_str = "" if @type == 1 str = $data_skills[@id].name str2 = $data_skills[@id].description lv_str = "Req. Level: " + @lv_rq.to_s if @learned nxlv_str = "Skill at level " + @rank.to_s + "." nxlv_appendix = " To increase hero must be Lv " + @nxlv_rq.to_s + "." nxlv_str = nxlv_str + nxlv_appendix if @unable end else str = $cst_skilltrees[id].name str2 = $cst_skilltrees[id].description end #if str2.size > 55 self.contents.draw_text(x, -6, 418, 32, str) self.contents.draw_text(x, 42, 418, 32, str2) self.contents.draw_text(x, -6, 418, 32, lv_str, 2) self.contents.draw_text(x, 66, 418, 32, nxlv_str) endend#==============================================================================# ** Window_SkillTree_Actor:#------------------------------------------------------------------------------# This Window_Base draws actor name, class, graphic and Skill Points remaining#==============================================================================class Window_SkillTree_Actor < Window_Base #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(actor) super(450, 352, 190, 128) @actor = actor self.contents = Bitmap.new(width - 32, height - 32) refresh end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear draw_item end #-------------------------------------------------------------------------- # * Draw Item # index : item number #-------------------------------------------------------------------------- def draw_item x = 0 y = 80 draw_actor_graphic(@actor, 134, y) draw_actor_name(@actor, 0, -6) draw_actor_class(@actor, 0, 18) draw_actor_level(@actor, 0, 42) skill_points = @actor.skill_points self.contents.draw_text(0, 66, 128, 32, "Skill Pts: " + skill_points.to_s) endend#==============================================================================# ** cockroach's SkillTree - Scene_SkillTree#------------------------------------------------------------------------------# This script creates and manages the Skill Tree scene, and the processes that# happen in it.#==============================================================================class Scene_SkillTree #-------------------------------------------------------------------------- # * Object Initialization # menu_index : command cursor's initial position #-------------------------------------------------------------------------- def initialize(actor) @menu_index = 0 @old_index = 0 @actor = $game_actors[actor] @tree_id = @actor.skill_trees[@menu_index] end #-------------------------------------------------------------------------- # * Main Processing #-------------------------------------------------------------------------- def main # Make tab window @skilltree_tabs_window = Window_SkillTree_Tabs.new(@actor) # Make skill tree window @skilltree_window = Window_SkillTree.new(@actor, @tree_id) @skilltree_window.active = false @skilltree_window.index = -1 # Make description window @skilltree_description_window = Window_SkillTree_Description.new(0, @tree_id) @skilltree_actor_window = Window_SkillTree_Actor.new(@actor) # Execute transition Graphics.transition # Main loop loop do # Update game screen Graphics.update # Update input information Input.update # Frame update update # Abort loop if screen is changed if $scene != self break end end # Prepare for transition Graphics.freeze # Dispose of windows @skilltree_tabs_window.dispose @skilltree_window.dispose @skilltree_description_window.dispose @skilltree_actor_window.dispose end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Update windows @skilltree_tabs_window.update @skilltree_window.update @skilltree_description_window.update @skilltree_actor_window.update # If tabs window is active, update it if @skilltree_tabs_window.active update_tabs # Check if the cursor has changed from one skill tree title to another if @old_index != @skilltree_tabs_window.index # Then the skill tree should be redrawn @skilltree_window.dispose_arrows @skilltree_window.dispose # Adjust the id and redraw the Window_SkillTree @tree_id = @actor.skill_trees[@skilltree_tabs_window.index] @skilltree_window = Window_SkillTree.new(@actor, @tree_id) @skilltree_window.active = false @skilltree_window.index = -1 # Prepare the change trigger again @old_index = @skilltree_tabs_window.index end # Check if description is showing the correct information if @skilltree_description_window.type != 0 or @skilltree_description_window.id != @tree_id # Refresh it if it isn't @skilltree_description_window.type = 0 @skilltree_description_window.id = @tree_id @skilltree_description_window.refresh end return end # Update Skill Tree if active if @skilltree_window != nil and @skilltree_window.active update_skilltree skill = @skilltree_window.get_skill_at_pos # Check if anything has changed to update description window if skill != nil and (@skilltree_description_window.type != 1 or @skilltree_description_window.id != skill) col_num = @skilltree_window.index % (@skilltree_window.column_max) level = $cst_skilltrees[@tree_id].level_at_col[col_num] rank = @actor.skill_rank[skill] req_increment = rank * (Skill_Tree_Config::CST_REQ_INCREMENT_PER_LEVEL) req_level = level + req_increment # Send attributes to the description window class @skilltree_description_window.lv_rq = level @skilltree_description_window.nxlv_rq = req_level @skilltree_description_window.rank = rank @skilltree_description_window.unable = @actor.level < req_level @skilltree_description_window.learned = rank > 0 end @skilltree_description_window.type = 1 @skilltree_description_window.id = skill # Refresh description @skilltree_description_window.refresh return end end #-------------------------------------------------------------------------- # * Frame Update (when tab window is active) #-------------------------------------------------------------------------- def update_tabs # If B button was pressed if Input.trigger?(Input:: # Play cancel SE $game_system.se_play($data_system.cancel_se) # Switch to map screen, or menu screen, depends on config @skilltree_window.dispose_arrows if Skill_Tree_Config::CST_RETURN_TO_MAP $scene = Scene_Map.new else $scene = Scene_Menu.new end return end # If C button was pressed if Input.trigger?(Input::C) $game_system.se_play($data_system.decision_se) # Switch to SkillTree window @skilltree_tabs_window.active = false @skilltree_window.active = true @skilltree_window.index = 0 return end end #-------------------------------------------------------------------------- # * Frame Update (when SkillTree window is active) #-------------------------------------------------------------------------- def update_skilltree # If B button was pressed if Input.trigger?(Input:: # Play cancel SE $game_system.se_play($data_system.cancel_se) # Make tab window active @skilltree_tabs_window.active = true @skilltree_window.active = false @skilltree_window.index = -1 return end # If C button was pressed, a skill have been chosen, or tried to if Input.trigger?(Input::C) # See which is the skill and check if it is a valid choice skill = @skilltree_window.get_skill_at_pos available = $cst_skilltrees[@tree_id].is_skill_available?(@actor, skill) # Read the maximum level to that skill, and how many skill_points spent if CST_SkillConfig::CST_SKILLCONFIG.has_key?(skill) sp_cost = CST_SkillConfig::CST_SKILLCONFIG[skill][5] max_level = CST_SkillConfig::CST_SKILLCONFIG[skill][4] else sp_cost = CST_SkillConfig::CST_SKILLCONFIG[0][5] max_level = CST_SkillConfig::CST_SKILLCONFIG[0][4] end # If all requirements are met, go ahead to learning, else play buzzer sound if @actor.skill_points > 0 and available and skill != nil and @actor.skill_rank[skill] < max_level $game_system.se_play($data_system.decision_se) @actor.skill_points -= sp_cost @skilltree_description_window.type = -1 # Provoke description to refresh # Learn the skill if actor didn't yet, and level it up @actor.learn_skill(skill) if not(@actor.skills.include?(skill)) @actor.skill_rank[skill] += 1 @skilltree_actor_window.refresh @skilltree_window.refresh else $game_system.se_play($data_system.buzzer_se) end end endend
#==============================================================================# ** cockroach's SkillTree#------------------------------------------------------------------------------# Hi, this is my skill tree script. It is meant to be a simple but effective# skill tree, as Diablo II's one. So features implemented are pretty much the# basic ones a skill tree should have.## Terms of Use: Use it in any game you want, edit is as you please, in any type# of game. You can even steal the credit and post it in a chinese# underground forum as if it was yours, if you want #==============================================================================# ** SkillTree Class#------------------------------------------------------------------------------# This class contains the SkillTree object processing. Skill trees contain# their basic info and a big array of levels, each level containing an array# of skills, each skill being an array of parameters in their regard.# The class contains a number of helper functions to Skill Tree objects.#==============================================================================class SkillTree #-------------------------------------------------------------------------- # * Readable attributes in a skill tree #-------------------------------------------------------------------------- attr_reader :name # Tree's name attr_reader :description # Tree's description attr_reader :skill_tree # The skilltree's body - an array containing arrays attr_reader :level_at_col # An array telling which req. level to each column #-------------------------------------------------------------------------- # * Initialize: Sets up the basic info #-------------------------------------------------------------------------- def initialize(name, description, tree) @name = name @description = description @skill_tree = tree @level_at_col = [] count = 0 for i in @skill_tree if i != [] @level_at_col.push(count) end count += 1 end end #-------------------------------------------------------------------------- # * How Many Levels: How many different required levels are there in the # skilltree? (If theres a skill at 3, two at 9 and one at 12, there are 3 lvs # this is useful to determine how many columns will be drawn. #-------------------------------------------------------------------------- def how_many_lvs lv_count = 0 count = 0 for i in @skill_tree if i != [] lv_count += 1 end count += 1 end return lv_count end #-------------------------------------------------------------------------- # * How Many Rows: How many rows are there in the skill tree? That is, what # is the maximum pos_Y in the tree. It helps to divide the tree in rows. #-------------------------------------------------------------------------- def how_many_rows row_count = 0 #count = 0 for i in @skill_tree #print "this is i ", i if i != [] for j in i #print "this is j ", j if j[2] > row_count row_count = j[2] end end end #count += 1 end return row_count end #-------------------------------------------------------------------------- # * Is a Valid Level? : Does this level contain skills that require it? #-------------------------------------------------------------------------- def is_a_valid_level?(level) return @skill_tree[level] != [] end #-------------------------------------------------------------------------- # * Find Skill Pos: Given a skill, this method searches for it in the present # tree, returning a coordinate compatible with the command list in Window #-------------------------------------------------------------------------- def find_skill_pos(skill) # searches through all levels in the SkillTree for lv in 1...@skill_tree.size # searches through all skills in each level for sk in @skill_tree[lv] # checks if the skill is the one we're looking for if sk[0] == skill # now search for the column and the row the skill is drawn col = @level_at_col.index(lv) row = sk[2] com = (@level_at_col.size*(row-1)) + col # return a single value compatible with @commands in windows return com end end end end #-------------------------------------------------------------------------- # * Is Skill Available? : Is the skill available for the actor to be learned? # This function checks if actor has learned the pre-requisites to a certain # skill that is contained in the skill tree, and if he has enough levels #-------------------------------------------------------------------------- def is_skill_available?(actor, skill, check_level = true) level = 0 # check every level array in skill_tree for lv in @skill_tree # if there's a skill at the current level if lv != [] # check all skills in current level for sk in lv # check if skill id is the one we're looking for if sk[0] == skill # if current level is below required, return false rank = actor.skill_rank[skill] req_increment = rank * (Skill_Tree_Config::CST_REQ_INCREMENT_PER_LEVEL) req_level = level + req_increment return false if actor.level < req_level # if skill has requirements if sk[1] != [] # check all requirements for rq in sk[1] # if actor doesn't know skill required, return false if not(actor.skills.include?(rq)) return false end end end end end end level += 1 end # if no issues found, the skill is available return true end #-------------------------------------------------------------------------- # * Get Icon Opacity: How should a skill be shown? This function will check # the circumstance to know if the skill is: # - Already learned: returns total opacity # - Available to learn: returns half opacity # - Unavailable: returns little opacity #-------------------------------------------------------------------------- def get_icon_opacity(actor, skill) if actor.skills.include?(skill) return Skill_Tree_Config::CST_OPACITY_LEARNED elsif is_skill_available?(actor, skill) return Skill_Tree_Config::CST_OPACITY_AVAILABLE else return Skill_Tree_Config::CST_OPACITY_UNAVAILABLE end end #-------------------------------------------------------------------------- # * Helper Function: This function prepares a list of skill_id's or empty (0) # values to be drawn in the SkillTree_Window #-------------------------------------------------------------------------- def get_command_list col_num = how_many_lvs # a column will be drawn for each req. level row_num = how_many_rows # a row will be drawn for each row specified commands = [] will_place_empty = false for i in 1..row_num for j in @skill_tree if j != [] will_place_empty = true for l in j if l[2] == i commands.push(l[0]) will_place_empty = false end end if will_place_empty commands.push(0) end end end end return commands end #-------------------------------------------------------------------------- # * Get Requirement Links: Given a list of commands in the Window @commands # pattern, checks through all skills to return a list in order to draw the # skill req. arrows. Format: [[origin, destination], [orig, dest], etc...] #-------------------------------------------------------------------------- def get_requirement_links(commands) requirement_links = [] pos = 0 col_num = how_many_lvs for com in commands if com != nil col = pos % col_num lv = @level_at_col[col] for sk in @skill_tree[lv] if sk[0] == com for rq in sk[1] # adds a pair of [origin, destination] requirement_links.push([pos, find_skill_pos(rq)]) end end end end pos += 1 end return requirement_links end end#==============================================================================# ** cockroach's SkillTree - SkillTree_Alterations#------------------------------------------------------------------------------# This class contains the alterations necessary in the default classes, so the# mechanics are fixed to adapt to the skill tree learning system. Most of the# changes are in order to support the leveling-up of the skills.#==============================================================================#==============================================================================# ** Game_Battler:#------------------------------------------------------------------------------# An additional parameter is added to all instances of Game_Battler, which is# skill_rank[skill_id]. For each skill, it stores a level. That rank can be# changed in-game, via events, items, such as potions, quests, etc.#==============================================================================class Game_Battler attr_accessor :skill_rank #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize @battler_name = "" @battler_hue = 0 @hp = 0 @sp = 0 @states = [] @states_turn = {} @maxhp_plus = 0 @maxsp_plus = 0 @str_plus = 0 @dex_plus = 0 @agi_plus = 0 @int_plus = 0 @hidden = false @immortal = false @damage_pop = false @damage = nil @critical = false @animation_id = 0 @animation_hit = false @white_flash = false @blink = false @current_action = Game_BattleAction.new # ADDED: @skill_rank init - prepares the array with default values. @skill_rank = [] for i in $data_skills @skill_rank.push(0) end end #-------------------------------------------------------------------------- # * Apply Skill Effects: this method is changed so it checks if the rank of # the skill being used is greater than 1, in order to enhance it. #-------------------------------------------------------------------------- def skill_effect(user, skill) self.critical = false if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or ((skill.scope == 5 or skill.scope == 6) and self.hp >= 1) return false end effective = false effective |= skill.common_event_id > 0 hit = skill.hit if skill.atk_f > 0 hit *= user.hit / 100 end hit_result = (rand(100) < hit) effective |= hit < 100 # ADDED: prepares local operators that will multiply/add to the power factor = 1 addition = 0 if hit_result == true id = skill.id rank = user.skill_rank[id] # If rank is greater than 1, apply enhancements if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(id) factor = CST_SkillConfig::CST_SKILLCONFIG[id][0]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[id][1]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][0]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][1]*rank end end base_power = (skill.power * factor + addition).to_i power = base_power + user.atk * skill.atk_f / 100 if power > 0 power -= self.pdef * skill.pdef_f / 200 power -= self.mdef * skill.mdef_f / 200 power = [power, 0].max end rate = 20 rate += (user.str * skill.str_f / 100) rate += (user.dex * skill.dex_f / 100) rate += (user.agi * skill.agi_f / 100) rate += (user.int * skill.int_f / 100) self.damage = power * rate / 20 self.damage *= elements_correct(skill.element_set) self.damage /= 100 if self.damage > 0 if self.guarding? self.damage /= 2 end end if skill.variance > 0 and self.damage.abs > 0 amp = [self.damage.abs * skill.variance / 100, 1].max self.damage += rand(amp+1) + rand(amp+1) - amp end eva = 8 * self.agi / user.dex + self.eva hit = self.damage < 0 ? 100 : 100 - eva * skill.eva_f / 100 hit = self.cant_evade? ? 100 : hit hit_result = (rand(100) < hit) effective |= hit < 100 end if hit_result == true if skill.power != 0 and skill.atk_f > 0 remove_states_shock effective = true end last_hp = self.hp self.hp -= self.damage effective |= self.hp != last_hp @state_changed = false effective |= states_plus(skill.plus_state_set) effective |= states_minus(skill.minus_state_set) if skill.power == 0 self.damage = "" unless @state_changed self.damage = "Miss" end end else self.damage = "Miss" end unless $game_temp.in_battle self.damage = nil end return effective end #-------------------------------------------------------------------------- # * Skill Can Use? : Changed so it support mana cost progressive enhancements #-------------------------------------------------------------------------- def skill_can_use?(skill_id) sp_cost_base = $data_skills[skill_id].sp_cost factor = 1 addition = 0 rank = self.skill_rank[skill_id] # if rank is greater than 1, apply enhancements if rank > 1 if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(skill_id) factor = CST_SkillConfig::CST_SKILLCONFIG[skill_id][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[skill_id][3]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][3]*rank end end end sp_cost = (sp_cost_base * factor + addition).to_i if sp_cost > self.sp return false end if dead? return false end if $data_skills[skill_id].atk_f == 0 and self.restriction == 1 return false end occasion = $data_skills[skill_id].occasion if $game_temp.in_battle return (occasion == 0 or occasion == 1) else return (occasion == 0 or occasion == 2) end endend#==============================================================================# ** Game_Actor:#------------------------------------------------------------------------------# Changed so it stores the Skill_Trees learned by the actor and how much skill# points he/she has to spend on them. Also, the default learning system is# removed. Also, added three methods to handle skill tree learning:# - learn_skilltree# - forget_skilltree# - knows_skilltree?#==============================================================================class Game_Actor < Game_Battler attr_accessor :skill_trees # Skill trees available to actor attr_accessor :skill_points # Skill points remaining to be spent #-------------------------------------------------------------------------- # * Setup: Changed so it initialize attributes and don't learn skills by def #-------------------------------------------------------------------------- def setup(actor_id) actor = $data_actors[actor_id] @actor_id = actor_id @name = actor.name @character_name = actor.character_name @character_hue = actor.character_hue @battler_name = actor.battler_name @battler_hue = actor.battler_hue @class_id = actor.class_id @weapon_id = actor.weapon_id @armor1_id = actor.armor1_id @armor2_id = actor.armor2_id @armor3_id = actor.armor3_id @armor4_id = actor.armor4_id @level = actor.initial_level @exp_list = Array.new(101) make_exp_list @exp = @exp_list[@level] @skills = [] @hp = maxhp @sp = maxsp @states = [] @states_turn = {} @maxhp_plus = 0 @maxsp_plus = 0 @str_plus = 0 @dex_plus = 0 @agi_plus = 0 @int_plus = 0 # Default learning system substituted by the parameters settings @skill_trees = Skill_Tree_Config::CST_CLASS_SKILL_TREES[@class_id] @skill_points = Skill_Tree_Config::CST_SKILL_POINTS_PER_LEVEL * @level update_auto_state(nil, $data_armors[@armor1_id]) update_auto_state(nil, $data_armors[@armor2_id]) update_auto_state(nil, $data_armors[@armor3_id]) update_auto_state(nil, $data_armors[@armor4_id]) end #-------------------------------------------------------------------------- # * Exp: Changed so the actor doesn't learn skills normally by leveling up. # Instead, he is given a quantity of skill_points per level. (default is 1) #-------------------------------------------------------------------------- def exp=(exp) @exp = [[exp, 9999999].min, 0].max while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0 @level += 1 # Acquire skill_points per level @skill_points += Skill_Tree_Config::CST_SKILL_POINTS_PER_LEVEL end # Level down while @exp < @exp_list[@level] @level -= 1 end @hp = [@hp, self.maxhp].min @sp = [@sp, self.maxsp].min end #-------------------------------------------------------------------------- # * Learn Skilltree: makes an actor have access to a skilltree #-------------------------------------------------------------------------- def learn_skilltree(id) @skill_trees.push(id) if not(@skill_trees.include?(id)) end #-------------------------------------------------------------------------- # * Forget Skilltree: takes access away from the actor to a skill tree # (forgetting a skilltree doesn't forget its skills, or their ranks) #-------------------------------------------------------------------------- def forget_skilltree(id) @skill_trees.delete(id) end #-------------------------------------------------------------------------- # * Knows Skilltree? : checks if actor knows a certain skilltree #-------------------------------------------------------------------------- def knows_skilltree?(id) return @skill_trees.include?(id) endend#==============================================================================# ** Game_Enemy:#------------------------------------------------------------------------------# Changed so it stores ranks to each skill. See the config for how to set them#==============================================================================class Game_Enemy < Game_Battler def initialize(troop_id, member_index) super() @troop_id = troop_id @member_index = member_index troop = $data_troops[@troop_id] @enemy_id = troop.members[@member_index].enemy_id enemy = $data_enemies[@enemy_id] @battler_name = enemy.battler_name @battler_hue = enemy.battler_hue @hp = maxhp @sp = maxsp @hidden = troop.members[@member_index].hidden @immortal = troop.members[@member_index].immortal # Set skill ranks based on battle actions for action in $data_enemies[@enemy_id].actions lv = action.condition_level > 0 sw = action.condition_switch_id == Skill_Tree_Config::CST_ENEMY_SKILL_SWITCH sk = action.skill_id > 0 if lv and sw and sk @skill_rank[action.skill_id] = action.condition_level end end endend#==============================================================================# ** Window_Skill:#------------------------------------------------------------------------------# Changed so it shows mana cost correctly, based on level rank#==============================================================================class Window_Skill < Window_Selectable def draw_item(index) skill = @data[index] if @actor.skill_can_use?(skill.id) self.contents.font.color = normal_color else self.contents.font.color = disabled_color end x = 4 + index % 2 * (288 + 32) y = index / 2 * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) bitmap = RPG::Cache.icon(skill.icon_name) opacity = self.contents.font.color == normal_color ? 255 : 128 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0) sp_cost_base = skill.sp_cost factor = 1 addition = 0 rank = @actor.skill_rank[skill.id] if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(skill.id) factor = CST_SkillConfig::CST_SKILLCONFIG[skill.id][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[skill.id][3]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][3]*rank end end sp_cost = (sp_cost_base * factor + addition).to_i self.contents.draw_text(x + 232, y, 48, 32, sp_cost.to_s, 2) endend#==============================================================================# ** Scene_Skill:#------------------------------------------------------------------------------# Changed so it uses the mana cost and applies the effect correctly#==============================================================================class Scene_Skill #-------------------------------------------------------------------------- # * Frame Update (if skill window is active) #-------------------------------------------------------------------------- def update_skill # If B button was pressed if Input.trigger?(Input:: # Play cancel SE $game_system.se_play($data_system.cancel_se) # Switch to menu screen $scene = Scene_Menu.new(1) return end # If C button was pressed if Input.trigger?(Input::C) # Get currently selected data on the skill window @skill = @skill_window.skill # If unable to use if @skill == nil or not @actor.skill_can_use?(@skill.id) # Play buzzer SE $game_system.se_play($data_system.buzzer_se) return end # Play decision SE $game_system.se_play($data_system.decision_se) # If effect scope is ally if @skill.scope >= 3 # Activate target window @skill_window.active = false @target_window.x = (@skill_window.index + 1) % 2 * 304 @target_window.visible = true @target_window.active = true # Set cursor position to effect scope (single / all) if @skill.scope == 4 || @skill.scope == 6 @target_window.index = -1 elsif @skill.scope == 7 @target_window.index = @actor_index - 10 else @target_window.index = 0 end # If effect scope is other than ally else # If common event ID is valid if @skill.common_event_id > 0 # Common event call reservation $game_temp.common_event_id = @skill.common_event_id # Play use skill SE $game_system.se_play(@skill.menu_se) # Use up SP sp_cost_base = @skill.sp_cost factor = 1 addition = 0 rank = @actor.skill_rank[@skill.id] if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(@skill.id) factor = CST_SkillConfig::CST_SKILLCONFIG[@skill.id][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[@skill.id][3]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][2]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][3]*rank end end sp_cost = (sp_cost_base * factor + addition).to_i @actor.sp -= sp_cost # Remake each window content @status_window.refresh @skill_window.refresh @target_window.refresh # Switch to map screen $scene = Scene_Map.new return end end return end # If R button was pressed if Input.trigger?(Input::R) # Play cursor SE $game_system.se_play($data_system.cursor_se) # To next actor @actor_index += 1 @actor_index %= $game_party.actors.size # Switch to different skill screen $scene = Scene_Skill.new(@actor_index) return end # If L button was pressed if Input.trigger?(Input::L) # Play cursor SE $game_system.se_play($data_system.cursor_se) # To previous actor @actor_index += $game_party.actors.size - 1 @actor_index %= $game_party.actors.size # Switch to different skill screen $scene = Scene_Skill.new(@actor_index) return end endend#==============================================================================# ** Scene_Skill:#------------------------------------------------------------------------------# Changed so SP is spent correctly in battle when skill is ranked up#==============================================================================class Scene_Battle def make_skill_action_result # Get skill @skill = $data_skills[@active_battler.current_action.skill_id] # If not a forcing action unless @active_battler.current_action.forcing # If unable to use due to SP running out unless @active_battler.skill_can_use?(@skill.id) # Clear battler being forced into action $game_temp.forcing_battler = nil # Shift to step 1 @phase4_step = 1 return end end # Use up SP sp_cost_base = @skill.sp_cost factor = 1 addition = 0 if @active_battler.is_a? Game_Actor id = @skill.id rank = @active_battler.skill_rank[id] if rank != nil and rank > 1 if CST_SkillConfig::CST_SKILLCONFIG.has_key?(id) factor = CST_SkillConfig::CST_SKILLCONFIG[id][0]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[id][1]*rank else factor = CST_SkillConfig::CST_SKILLCONFIG[0][0]**rank addition = CST_SkillConfig::CST_SKILLCONFIG[0][1]*rank end end end sp_cost = (sp_cost_base * factor + addition).to_i @active_battler.sp -= sp_cost # Refresh status window @status_window.refresh # Show skill name on help window @help_window.set_text(@skill.name, 1) # Set animation ID @animation1_id = @skill.animation1_id @animation2_id = @skill.animation2_id # Set command event ID @common_event_id = @skill.common_event_id # Set target battlers set_target_battlers(@skill.scope) # Apply skill effect for target in @target_battlers target.skill_effect(@active_battler, @skill) end endend#==============================================================================# ** cockroach's SkillTree - SkillTree_Windows#------------------------------------------------------------------------------# This script creates and manages 4 Window classes - 2 normal and 2 selectable.# - Window_SkillTree_Tabs: chooses which Skill Tree to show# - Window_SkillTree: draws the skill tree itself and chooses skills# - Window_SkillTree_Description: shows the description of trees and skills# - Window_SkillTree_Actor: shows actor info and remaining skill points#==============================================================================#==============================================================================# ** Window_SkillTree_Tabs:#------------------------------------------------------------------------------# This Window_Selectable chooses which Skill Tree to show.#==============================================================================class Window_SkillTree_Tabs < Window_Selectable #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(actor) super(0, 0, 640, 64) self.contents = Bitmap.new(width - 32, height - 32) @actor = actor @skill_trees = @actor.skill_trees # How many Skill Trees will be shown? (Will depend on the actor's class) @item_max = @skill_trees.size @column_max = @item_max # Each button will have the name of the each Skill Tree @commands = [] for i in @skill_trees @commands.push($cst_skilltrees.name) end refresh self.index = 0 end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i) end end #-------------------------------------------------------------------------- # * Draw Skill Tree Names #-------------------------------------------------------------------------- def draw_item(index) x = 4 + index * (640/@item_max) self.contents.draw_text(x, 0, 608/@item_max, 32, @commands[index]) endend#==============================================================================# ** Window_SkillTree:#------------------------------------------------------------------------------# This Window_Selectable draws the skill tree and chooses which skill to learn#==============================================================================class Window_SkillTree < Window_Selectable attr_accessor :tree_id # ID of Skill Tree being shown in the window attr_accessor :arrows attr_accessor :column_max #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(actor, tree_id) super(0, 64, 640, 288) self.contents = Bitmap.new(width - 32, height - 32) # Setup base values @actor = actor @tree_id = tree_id @column_max = $cst_skilltrees[tree_id].how_many_lvs @rows = ($cst_skilltrees[tree_id].how_many_rows) @item_max = @rows*@column_max @arrows = [] # Calculates base horizontal and vertical distance between skill icons @x_step = (self.width - 32) / (@column_max + 1) @y_step = (self.height - 32) / @rows # Populates the command list with the ID of the correponding skills (or 0) @commands = $cst_skilltrees[tree_id].get_command_list refresh self.index = 0 end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear # Drawing call loop. If ID is 0, cell is empty, so no call to draw_item count = 0 for i in @commands draw_item(count) if i != 0 count += 1 end draw_arrows end #-------------------------------------------------------------------------- # * Draw Item # index : item number #-------------------------------------------------------------------------- def draw_item(index) # Setup coordinates to draw the skill x = index % @column_max * @x_step + @x_step - 12 y = index / @column_max * @y_step + @y_step/2 - 12 # Setup source info to the draw process skill_id = @commands[index] skill = $data_skills[skill_id] # Turn ID into skill object bitmap = RPG::Cache.icon(skill.icon_name) opacity = $cst_skilltrees[@tree_id].get_icon_opacity(@actor, skill_id) # Rank is the level for this skill to the current actor rank = @actor.skill_rank[skill_id] # Drawing phase self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.font.size = 16 self.contents.font.bold = true self.contents.font.color.set(0, 0, 0, 155) self.contents.draw_text(x - 2, y + 8, 32, 32, rank.to_s, 2) self.contents.font.size = 16 self.contents.font.bold = true self.contents.font.color.set(255, 255, 255, 255) self.contents.draw_text(x - 3, y + 7, 32, 32, rank.to_s, 2) end def draw_arrows dispose_arrows requirements = $cst_skilltrees[@tree_id].get_requirement_links(@commands) for rq_ar in requirements #print rq_ar[1], " is the source" #print rq_ar[0], " is the dest" draw_arrow(rq_ar[1], rq_ar[0]) end end def draw_arrow(source, dest) x_source = source % @column_max * @x_step + @x_step - 12 y_source = source / @column_max * @y_step + @y_step/2 - 12 x_dest = dest % @column_max * @x_step + @x_step - 12 y_dest = dest / @column_max * @y_step + @y_step/2 - 12 dist_x = x_dest - x_source dist_y = y_dest - y_source dist = Math.sqrt((dist_x*dist_x) + (dist_y*dist_y)) angle_r = Math.atan2(dist_x.to_f, dist_y.to_f) angle = (angle_r/Math::pI)*180.00 unit = Skill_Tree_Config::CST_ARROW_TILE_SIZE header = Skill_Tree_Config::CST_ARROW_TILE_HEADER body = Skill_Tree_Config::CST_ARROW_TILE_BODY tail = Skill_Tree_Config::CST_ARROW_TILE_TAIL ar_step_x = (Math.sin(angle_r)*unit.to_f).to_i ar_step_y = (Math.cos(angle_r)*unit.to_f).to_i ar_step_x = unit - 1 if ar_step_x >= unit ar_step_y = unit if ar_step_y > unit number_of_tiles = dist.to_i/unit refrain = 2 new_arrow_group = [] for i in 0..number_of_tiles next if i < refrain or i >= (number_of_tiles - refrain) arrow = Sprite.new case i when refrain arrow.bitmap = tail when number_of_tiles - refrain - 1 arrow.bitmap = header else arrow.bitmap = body end arrow.x = self.x + 24 + x_source + (ar_step_x*i) + ar_step_x arrow.y = self.y + 32 + y_source + (ar_step_y*i) + ar_step_y arrow.z = 9999 arrow.angle = angle arrow.opacity = Skill_Tree_Config::CST_ARROW_OPACITY arrow.visible = true new_arrow_group.push(arrow) end @arrows.push(new_arrow_group) end #-------------------------------------------------------------------------- # * Dispose Arrows #-------------------------------------------------------------------------- def dispose_arrows for i in @arrows for j in i j.dispose end end end #-------------------------------------------------------------------------- # * Update Cursor Rect - This method is changed so it fits skill icons #-------------------------------------------------------------------------- def update_cursor_rect if @index < 0 self.cursor_rect.empty return end row = @index / @column_max if row < self.top_row self.top_row = row end if row > self.top_row + (self.page_row_max - 1) self.top_row = row - (self.page_row_max - 1) end # Edit here: x and y position is set as relative to x_step and y_step x = @index % @column_max * @x_step + @x_step - 18 y = @index / @column_max * @y_step + @y_step/2 - 18 size = 36 prop = Skill_Tree_Config::CST_CURSOR_EMPTY_SPOT_PROPORTION accel = Skill_Tree_Config::CST_CURSOR_SMOOTH if @commands[@index] == 0 and prop != 1 x = @index % @column_max * @x_step + @x_step - 18 * prop y = @index / @column_max * @y_step + @y_step/2 - 18 * prop size = 36 * prop end if accel and (x != self.cursor_rect.x or y != self.cursor_rect.y or size != self.cursor_rect.width) x = (self.cursor_rect.x + x) / 2 y = (self.cursor_rect.y + y) / 2 size = (self.cursor_rect.width + size) / 2 end # And dimensions are fixed to 36 x 36 self.cursor_rect.set(x, y, size, size) end #-------------------------------------------------------------------------- # * Get Skill at Pos - This method gets which skill is at the cursor now #-------------------------------------------------------------------------- def get_skill_at_pos column = @index % @column_max row = (@index / @column_max) + 1 level = $cst_skilltrees[@tree_id].level_at_col[column] count = 0 for i in $cst_skilltrees[@tree_id].skill_tree #print "level ", count for j in i #print j[0], " is the skill / ", j[1], " is the req / row is ", j[2] if count == level and j[2] == row #print j[0], " works.." return j[0] end end count += 1 end return nil endend#==============================================================================# ** Window_SkillTree_Description:#------------------------------------------------------------------------------# This Window_Base draws skills/skill trees names, description and other info#==============================================================================class Window_SkillTree_Description < Window_Base attr_accessor :type attr_accessor :id attr_accessor :lv_rq attr_accessor :nxlv_rq attr_accessor :tree attr_accessor :rank attr_accessor :unable attr_accessor :learned #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(type, id, lv_rq = 0) super(0, 352, 450, 128) @type = type @id = id @tree = tree @lv_rq = lv_rq @unable = false @learned = false self.contents = Bitmap.new(width - 32, height - 32) refresh end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear draw_items end #-------------------------------------------------------------------------- # * Draw Items: draw info in the description window #-------------------------------------------------------------------------- def draw_items return if @id == nil x = 0 lv_str = "" nxlv_str = "" if @type == 1 str = $data_skills[@id].name str2 = $data_skills[@id].description lv_str = "Req. Level: " + @lv_rq.to_s if @learned nxlv_str = "Skill at level " + @rank.to_s + "." nxlv_appendix = " To increase hero must be Lv " + @nxlv_rq.to_s + "." nxlv_str = nxlv_str + nxlv_appendix if @unable end else str = $cst_skilltrees[id].name str2 = $cst_skilltrees[id].description end #if str2.size > 55 self.contents.draw_text(x, -6, 418, 32, str) self.contents.draw_text(x, 42, 418, 32, str2) self.contents.draw_text(x, -6, 418, 32, lv_str, 2) self.contents.draw_text(x, 66, 418, 32, nxlv_str) endend#==============================================================================# ** Window_SkillTree_Actor:#------------------------------------------------------------------------------# This Window_Base draws actor name, class, graphic and Skill Points remaining#==============================================================================class Window_SkillTree_Actor < Window_Base #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(actor) super(450, 352, 190, 128) @actor = actor self.contents = Bitmap.new(width - 32, height - 32) refresh end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear draw_item end #-------------------------------------------------------------------------- # * Draw Item # index : item number #-------------------------------------------------------------------------- def draw_item x = 0 y = 80 draw_actor_graphic(@actor, 134, y) draw_actor_name(@actor, 0, -6) draw_actor_class(@actor, 0, 18) draw_actor_level(@actor, 0, 42) skill_points = @actor.skill_points self.contents.draw_text(0, 66, 128, 32, "Skill Pts: " + skill_points.to_s) endend#==============================================================================# ** cockroach's SkillTree - Scene_SkillTree#------------------------------------------------------------------------------# This script creates and manages the Skill Tree scene, and the processes that# happen in it.#==============================================================================class Scene_SkillTree #-------------------------------------------------------------------------- # * Object Initialization # menu_index : command cursor's initial position #-------------------------------------------------------------------------- def initialize(actor) @menu_index = 0 @old_index = 0 @actor = $game_actors[actor] @tree_id = @actor.skill_trees[@menu_index] end #-------------------------------------------------------------------------- # * Main Processing #-------------------------------------------------------------------------- def main # Make tab window @skilltree_tabs_window = Window_SkillTree_Tabs.new(@actor) # Make skill tree window @skilltree_window = Window_SkillTree.new(@actor, @tree_id) @skilltree_window.active = false @skilltree_window.index = -1 # Make description window @skilltree_description_window = Window_SkillTree_Description.new(0, @tree_id) @skilltree_actor_window = Window_SkillTree_Actor.new(@actor) # Execute transition Graphics.transition # Main loop loop do # Update game screen Graphics.update # Update input information Input.update # Frame update update # Abort loop if screen is changed if $scene != self break end end # Prepare for transition Graphics.freeze # Dispose of windows @skilltree_tabs_window.dispose @skilltree_window.dispose @skilltree_description_window.dispose @skilltree_actor_window.dispose end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Update windows @skilltree_tabs_window.update @skilltree_window.update @skilltree_description_window.update @skilltree_actor_window.update # If tabs window is active, update it if @skilltree_tabs_window.active update_tabs # Check if the cursor has changed from one skill tree title to another if @old_index != @skilltree_tabs_window.index # Then the skill tree should be redrawn @skilltree_window.dispose_arrows @skilltree_window.dispose # Adjust the id and redraw the Window_SkillTree @tree_id = @actor.skill_trees[@skilltree_tabs_window.index] @skilltree_window = Window_SkillTree.new(@actor, @tree_id) @skilltree_window.active = false @skilltree_window.index = -1 # Prepare the change trigger again @old_index = @skilltree_tabs_window.index end # Check if description is showing the correct information if @skilltree_description_window.type != 0 or @skilltree_description_window.id != @tree_id # Refresh it if it isn't @skilltree_description_window.type = 0 @skilltree_description_window.id = @tree_id @skilltree_description_window.refresh end return end # Update Skill Tree if active if @skilltree_window != nil and @skilltree_window.active update_skilltree skill = @skilltree_window.get_skill_at_pos # Check if anything has changed to update description window if skill != nil and (@skilltree_description_window.type != 1 or @skilltree_description_window.id != skill) col_num = @skilltree_window.index % (@skilltree_window.column_max) level = $cst_skilltrees[@tree_id].level_at_col[col_num] rank = @actor.skill_rank[skill] req_increment = rank * (Skill_Tree_Config::CST_REQ_INCREMENT_PER_LEVEL) req_level = level + req_increment # Send attributes to the description window class @skilltree_description_window.lv_rq = level @skilltree_description_window.nxlv_rq = req_level @skilltree_description_window.rank = rank @skilltree_description_window.unable = @actor.level < req_level @skilltree_description_window.learned = rank > 0 end @skilltree_description_window.type = 1 @skilltree_description_window.id = skill # Refresh description @skilltree_description_window.refresh return end end #-------------------------------------------------------------------------- # * Frame Update (when tab window is active) #-------------------------------------------------------------------------- def update_tabs # If B button was pressed if Input.trigger?(Input:: # Play cancel SE $game_system.se_play($data_system.cancel_se) # Switch to map screen, or menu screen, depends on config @skilltree_window.dispose_arrows if Skill_Tree_Config::CST_RETURN_TO_MAP $scene = Scene_Map.new else $scene = Scene_Menu.new end return end # If C button was pressed if Input.trigger?(Input::C) $game_system.se_play($data_system.decision_se) # Switch to SkillTree window @skilltree_tabs_window.active = false @skilltree_window.active = true @skilltree_window.index = 0 return end end #-------------------------------------------------------------------------- # * Frame Update (when SkillTree window is active) #-------------------------------------------------------------------------- def update_skilltree # If B button was pressed if Input.trigger?(Input:: # Play cancel SE $game_system.se_play($data_system.cancel_se) # Make tab window active @skilltree_tabs_window.active = true @skilltree_window.active = false @skilltree_window.index = -1 return end # If C button was pressed, a skill have been chosen, or tried to if Input.trigger?(Input::C) # See which is the skill and check if it is a valid choice skill = @skilltree_window.get_skill_at_pos available = $cst_skilltrees[@tree_id].is_skill_available?(@actor, skill) # Read the maximum level to that skill, and how many skill_points spent if CST_SkillConfig::CST_SKILLCONFIG.has_key?(skill) sp_cost = CST_SkillConfig::CST_SKILLCONFIG[skill][5] max_level = CST_SkillConfig::CST_SKILLCONFIG[skill][4] else sp_cost = CST_SkillConfig::CST_SKILLCONFIG[0][5] max_level = CST_SkillConfig::CST_SKILLCONFIG[0][4] end # If all requirements are met, go ahead to learning, else play buzzer sound if @actor.skill_points > 0 and available and skill != nil and @actor.skill_rank[skill] < max_level $game_system.se_play($data_system.decision_se) @actor.skill_points -= sp_cost @skilltree_description_window.type = -1 # Provoke description to refresh # Learn the skill if actor didn't yet, and level it up @actor.learn_skill(skill) if not(@actor.skills.include?(skill)) @actor.skill_rank[skill] += 1 @skilltree_actor_window.refresh @skilltree_window.refresh else $game_system.se_play($data_system.buzzer_se) end end endend
Config Script: Comes after, before Main.
Spoiler
Spoiler
Code:
#==============================================================================# ** Skill_Tree_Config#------------------------------------------------------------------------------# This is used to configure the skill trees#==============================================================================module Skill_Tree_Config############################################################################### # -----------------------------------------------------------------------------# DON'T CHANGE HERE - Global Var containing all of the SkillTree objects ------$cst_skilltrees = [] #---------------------------------------------------------# Process necessary to know how many classes need to be configured ------------$data_classes = load_data("Data/Classes.rxdata") #-----------------------------CST_CLASS_SKILL_TREES = [] #---------------------------------------------------for i in $data_classes #------------------------------------------------------- CST_CLASS_SKILL_TREES.push([]) #---------------------------------------------end #--------------------------------------------------------------------------############################################################################### #============================================================================ # GAMEPLAY CONSTANTS #---------------------------------------------------------------------------- # How many Skill Points are acquired each level? CST_SKILL_POINTS_PER_LEVEL = 1 #---------------------------------------------------------------------------- # How many extra hero levels are needed when increasing a skill level? # (use 0 if you don't want to use this level requirement parameter) CST_REQ_INCREMENT_PER_LEVEL = 1 #---------------------------------------------------------------------------- # Does the scene return to map when SkillTrees are closed? Set to false if # you want the skill tree to be part of the Menu, and return to it. CST_RETURN_TO_MAP = true #---------------------------------------------------------------------------- # When defining enemy skill levels, a dummy $game_switch shall be used, which # should be its ID? (doesn't actually affect gameplay, but should be defined) CST_ENEMY_SKILL_SWITCH = 1 #============================================================================ # AESTHETIC PARAMETERS #---------------------------------------------------------------------------- # The requirement hierarchy arrows in the SkillTree are made of small tiles of # arrows combined. Define here those tiles parameters. Their SIZE, the image # used for the HEADER of the arrow, the BODY (will be tiled many times), and # the TAIL of the arrow. Determine its OPACITY too. CST_ARROW_TILE_SIZE = 12 CST_ARROW_TILE_HEADER = RPG::Cache.picture('a_header_12.png') CST_ARROW_TILE_BODY = RPG::Cache.picture('a_body12.png') CST_ARROW_TILE_TAIL = RPG::Cache.picture('a_tail12.png') CST_ARROW_OPACITY = 105 #---------------------------------------------------------------------------- # The skill icons follow an opacity convention for being already LEARNED, # AVAILABLE to be learned, or still UNAVAILABLE. Define here its values. CST_OPACITY_LEARNED = 255 CST_OPACITY_AVAILABLE = 140 CST_OPACITY_UNAVAILABLE = 12 #---------------------------------------------------------------------------- # The cursor in the skill tree window is the glowing rectangle that selects # skills. It will pass by empty tiles sometimes. It can shrink at those moments # so it's clearer that the tile isn't selectable. Define the scale of the # cursor in that positions (or leave it 1 to not change its size). And its # movement can be SMOOTH or sudden. Choose one by setting smooth to true/false. CST_CURSOR_SMOOTH = true CST_CURSOR_EMPTY_SPOT_PROPORTION = 0.4 #============================================================================ # DATABASE PARAMETERS #---------------------------------------------------------------------------- # Class Skill Trees: set here for each class you want to define, the group of # skill trees that class will know. (Those skilltrees can be forgotten and more # can be learned, too.) CST_CLASS_SKILL_TREES[1] = [] # Fighter: none. CST_CLASS_SKILL_TREES[2] = [1] # Lancer: Water Magic CST_CLASS_SKILL_TREES[3] = [0] # Warrior: Fire Magic CST_CLASS_SKILL_TREES[4] = [2] # Thief: Energy Magic CST_CLASS_SKILL_TREES[5] = [0, 1] # Hunter: Fire/Water Magic CST_CLASS_SKILL_TREES[6] = [0, 2] # Gunner: Fire/Energy Magic CST_CLASS_SKILL_TREES[7] = [1, 2] # Cleric: Water/Energy Magic CST_CLASS_SKILL_TREES[8] = [0, 1, 2] # Mage: Fire/Water/Energy Magic #---------------------------------------------------------------------------- ############################################################################# ######################## S K I L L T R E E S ########################### ############################################################################# #============================================================================ # SKILL TREE #0 - FIRE MAGIC #---------------------------------------------------------------------------- # (Tutorial Skill Tree - too large because it has too much commenting ) #---------------------------------------------------------------------------- # Basic Info: Name, description and the highest level with a learnable skill #---------------------------------------------------------------------------- CST_SKILL_TREE_NAME = "Fire Magic" CST_SKILL_TREE_DESCRIPTION = "Use fire's might in your favour." CST_SKILL_MAX_LVL = 24 # #---------------------------------------------------------------------------- # Don't change anything here #---------------------------------------------------------------------------- CST_SKILLS = [] for i in 0..CST_SKILL_MAX_LVL CST_SKILLS.push([]) end # #---------------------------------------------------------------------------- # Skill Entry: # CST_SKILLS[L].push([S, [A, B, C], pos_Y]) # # L = Level required for the skill S = Skill ID number in database # [A, B, C] = Other skills required to learn this skill # pos_Y = vertical position in the skill tree (1, 2, 3, hardly 4) # # If no skills are required, third item is an empty list # # |Lv.1 |Lv.6 |Lv.12 |Lv. 18 |Lv.24 |Pos_Y| # [Fire] → [Greater Fire] → [Mass Fire] 1 # / # [Sharp] → [Burning Shot] 2 # \ # [Confuse] → [Weaken] → [Mass Confuse] 3 # #---------------------------------------------------------------------------- # # Level 1 CST_SKILLS[1].push([7, [], 1]) #7 - Fire CST_SKILLS[1].push([39, [], 3]) #39 - Confuse # Level 6 CST_SKILLS[6].push([53, [], 2]) #53 - Sharp # Level 12 CST_SKILLS[12].push([8, [7], 1]) #8 - Greater Fire, requires Fire to learn CST_SKILLS[12].push([45, [39, 53], 3]) #45 - Weaken, requires Sharp and Confuse # Level 18 CST_SKILLS[18].push([78, [53], 2]) #78 - Burning Shot, requires Sharp # Level 24 CST_SKILLS[24].push([9, [8, 78], 1]) #9 - Mass Fire, Rq. Grt Fire and Brn Shot CST_SKILLS[24].push([40, [45], 3]) #40 - Mass Confuse, Requires Weaken # #---------------------------------------------------------------------------- # Don't change anything here #---------------------------------------------------------------------------- $cst_skilltrees.push(SkillTree.new(CST_SKILL_TREE_NAME, CST_SKILL_TREE_DESCRIPTION, CST_SKILLS)) #============================================================================ #============================================================================ # SKILL TREE #1 - WATER MAGIC #---------------------------------------------------------------------------- CST_SKILL_TREE_NAME = "Water Magic" CST_SKILL_TREE_DESCRIPTION = "Use water's resilience in your favour." CST_SKILL_MAX_LVL = 24 #---------------------------------------------------------------------------- CST_SKILLS = [] #------------------------------------------------------------ for i in 0..CST_SKILL_MAX_LVL #---------------------------------------------- CST_SKILLS.push([]) #------------------------------------------------------ end #------------------------------------------------------------------------ #---------------------------------------------------------------------------- #---------------------------------------------------------------------------- # Skill Entry: #---------------------------------------------------------------------------- CST_SKILLS[1].push([16, [], 1]) # Water CST_SKILLS[1].push([1, [], 3]) # Heal CST_SKILLS[6].push([33, [], 2]) # Venom CST_SKILLS[12].push([17, [16], 1]) # Greater Water, requires Water CST_SKILLS[15].push([4, [1, 33], 3]) # Remedy, requires Heal and Venom CST_SKILLS[18].push([11, [17], 2]) # Greater Ice, requires Greater Water CST_SKILLS[24].push([18, [17], 1]) # Mass Water, requires Greater Water CST_SKILLS[24].push([12, [4, 11], 3]) # Mass Ice, rq. Remedy and Greater Ice #---------------------------------------------------------------------------- $cst_skilltrees.push(SkillTree.new(CST_SKILL_TREE_NAME, CST_SKILL_TREE_DESCRIPTION, CST_SKILLS)) #============================================================================ #============================================================================ # SKILL TREE #2 - ENERGY MAGIC #---------------------------------------------------------------------------- CST_SKILL_TREE_NAME = "Energy Magic" CST_SKILL_TREE_DESCRIPTION = "Use energy's versatility in your favour." CST_SKILL_MAX_LVL = 24 #---------------------------------------------------------------------------- CST_SKILLS = [] #------------------------------------------------------------ for i in 0..CST_SKILL_MAX_LVL #---------------------------------------------- CST_SKILLS.push([]) #------------------------------------------------------ end #------------------------------------------------------------------------ #---------------------------------------------------------------------------- # Skill Entry: #---------------------------------------------------------------------------- CST_SKILLS[1].push([56, [], 1]) # Blink CST_SKILLS[1].push([35, [], 3]) # Dazzle CST_SKILLS[6].push([43, [56], 2]) # Paralysis, requires Blink CST_SKILLS[6].push([71, [35], 3]) # Illusion, requires Paralysis and Dazzle CST_SKILLS[12].push([31, [13, 56], 1]) # Burst, requires Blink and Thunder CST_SKILLS[12].push([13, [43], 2]) # Thunder, requires Paralysis CST_SKILLS[24].push([32, [31], 1]) # Radiate, requires Burst CST_SKILLS[24].push([15, [13, 71], 3]) # Mass Thunder, rq. Thunder and Illusion #---------------------------------------------------------------------------- $cst_skilltrees.push(SkillTree.new(CST_SKILL_TREE_NAME, CST_SKILL_TREE_DESCRIPTION, CST_SKILLS)) #============================================================================ end#==============================================================================# ** CST_Skill_Config#------------------------------------------------------------------------------# This is used to configure how skills level up. They apply both to actor and# to enemies. To add a leveled-up skill to an enemy do the following:## - Add an action to the enemy which is the intended skill. As typical.# At this point you define the priority of the action, the circumstance# in which the skill will be used, etc etc etc.# - Add another action to the enemy being of the same skill the other one.# Now, add as requirement the dummy switch "CST_ENEMY_SKILL_SWITCH" and# as a Lv requirement, the skill level you want the enemy to have# regarding that particular skill. The action will never be performed# since the switch is a dummy, then the rate and the rest is irrelevant.# - Voilà. The enemy's rank in this skill will be set to that one upon# initialization inside its class. You can even change it from then on# via battle_events and such, calling for a script line that changes# the Game_Battler attribute @skill_rank[SKILL_ID]## (If in doubt, check the Sahagin or some other altered enemies for example)#==============================================================================module CST_SkillConfig CST_SKILLCONFIG = {} #============================================================================ # SKILL #0 - DEFAULT SKILL ADD-ON #---------------------------------------------------------------------------- POWER_FACTOR = 1.05 # How much per level is the power multiplied POWER_ADDITION = 2 # How much per level is the power added SP_COST_FACTOR = 1.02 # How much per level is the SP cost multiplied SP_COST_ADDITION = 1 # How much per level is the SP cost added MAX_LEVEL = 20 # Skill's max level. Applies only to actor skill trees SKILL_POINT_COST = 1 # Skill's cost in skill points in skill trees CST_SKILLCONFIG[0] = [POWER_FACTOR, POWER_ADDITION, SP_COST_FACTOR, SP_COST_ADDITION, MAX_LEVEL, SKILL_POINT_COST] #============================================================================ # SKILL #1 - HEAL #---------------------------------------------------------------------------- POWER_FACTOR = 1.1 POWER_ADDITION = 2 SP_COST_FACTOR = 1.01 SP_COST_ADDITION = 1 MAX_LEVEL = 20 SKILL_POINT_COST = 1 CST_SKILLCONFIG[1] = [POWER_FACTOR, POWER_ADDITION, SP_COST_FACTOR, SP_COST_ADDITION, MAX_LEVEL, SKILL_POINT_COST] #============================================================================ # SKILL #7 - FIRE #---------------------------------------------------------------------------- POWER_FACTOR = 1.05 POWER_ADDITION = 2 SP_COST_FACTOR = 1.02 SP_COST_ADDITION = 1 MAX_LEVEL = 20 SKILL_POINT_COST = 1 CST_SKILLCONFIG[7] = [POWER_FACTOR, POWER_ADDITION, SP_COST_FACTOR, SP_COST_ADDITION, MAX_LEVEL, SKILL_POINT_COST] endTerms of Use
Use it in any game you want, edit is as you please, in any type of game. You can even steal the credit and post it in a chinese underground forum as if it was yours, if you want :D