Skill Tree, as used in many RPG Games, Diablo, Zenonia, Inotia, Ragnarok.... Where the player can choose diferent paths according to the skills chosen.
- Skills have levels.
- Skills have requirements for improvements, actor level, skill levels.
- Easy to add/remove skill points.
- Easy to add new skills.
- Possibility of images(not necessary).
- Can add skill points by script calls.
The screens are in portuguese, but the script has been translated to english.
don´t consider the horrible design below, it is just to show that images are possible, to help improve the script graphically.
Not needed, but who prefers the download.
#=======================================================# Lune Skill Tree# Author: Raizen# Comunity: www.centrorpg.com# Classic Skill Tree, where you choose the skills and allocate# points through out the skill tree.#=======================================================module Skill_Tree#+++++++++++++++++++++++++++++++++++++++++++++ # Possible commands in Script Calls.#+++++++++++++++++++++++++++++++++++++++++++++# Add Skill points manually# Script Call: $game_actors[id].skill_tree[0]# remembering the operations += adds, -= subtracts.# Example, adding 4 points on actor with id of 5.# Script Call: $game_actors[5].skill_tree[0] += 4# Reseting skill tree# Just Script Call: reset_tree(id)# The id is the id of the actor on the database# Change a skill manually# Script Call: $game_actors[id].skill_tree[skill_id]# id = id of actor in database# skill_id = id of skill in database# Example: adding 5 points in skill id 3 in actor with id 2# Script Call: $game_actors[2].skill_tree[3] += 5# remembering the operations += adds, -= subtracts.# To activate the Skill Tree Screen manually.# Script Call: SceneManager.call(Scene_Skill_Change)#+++++++++++++++++++++++++++++++++++++++++++++# Initial Setup#+++++++++++++++++++++++++++++++++++++++++++++# Allow images? true/false# if true, the script will draw a image over the skill tree for# each character, allowing you to add details and improvements on the# design of the skill tree.# The image has to be on the folder Graphics/System with the name Actor1, Actor2...# according to the id of the actor.Images = false#---------------------------------------------# Text Setup#---------------------------------------------# remember to put texts inside" example 'text'.# Text confirming point add.Bot1 = 'Add 1 point'# cancelBot2 = 'Cancel'# Points RemainingRest = 'Points Remaining'# Total PointsTotal = 'Total Points'# Name on Menu.Menu = 'Skill Tree'#====================================================# Screen Actor configuration, read carefully to the instructions,# it is really important that you configure correctly the script.#====================================================# Don't modify. Actor = [] Sk = [] # Base for actor creation, avoid erasing this part.# any time needed use this template to create actors skill trees and# skills.=begin#Actor[id] = [Sk[0] = {'x' => 100, # icon position on x axis'y' => 32, # icon position on y axis'skill' => 5, # skill obtained'desc1' => 'Requer: Lvl 5, Bola de Fogo lvl 5', # description 1'desc2' => 'Member1', # description 2'desc3' => 'Habilidade com ataque em área', # description 3'req' => [0, 1, 5, 9, 5], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 5, # skill max level'mult' => [10, 5], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.},Sk[1] = {'x' => 100, # icon position on x axis'y' => 32, # icon position on y axis'skill' => 5, # skill obtained'desc1' => 'Requer: Lvl 5, Bola de Fogo lvl 5', # description 1'desc2' => 'Member1', # description 2'desc3' => 'Habilidade com ataque em área', # description 3'req' => [0, 1, 5, 9, 5], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 5, # skill max level'mult' => [10, 5], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.} # you can add as many skills as necessary]=end# ============================================================================# ======= Actor 1 =======================================================# ============================================================================Actor[8] = [Sk[0] = {'x' => 30, # icon position on x axis'y' => 30, # icon position on y axis'skill' => 51, # skill obtained'desc1' => 'Requires: Level 1', # description 1'desc2' => '', # description 2'desc3' => 'Fire 1', # description 3'req' => [0], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 10, # skill max level'mult' => [10, 2], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.},Sk[1] = {'x' => 90, # icon position on x axis'y' => 30, # icon position on y axis'skill' => 119, # skill obtained'desc1' => 'Requires: Level 1', # description 1'desc2' => '', # description 2'desc3' => 'Magical Reflection', # description 3'req' => [0], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 1, # skill max level'mult' => [10, 2], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.},Sk[2] = {'x' => 30, # icon position on x axis'y' => 90, # icon position on y axis'skill' => 52, # skill obtained'desc1' => 'Requires: Level 8 + 4x level', # description 1'desc2' => 'Fire 1 - Level 5', # description 2'desc3' => 'Fire 2', # description 3'req' => [8, 51, 5], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 10, # skill max level'mult' => [10, 4], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.},Sk[3] = {'x' => 30, # icon position on x axis'y' => 150, # icon position on y axis'skill' => 53, # skill obtained'desc1' => 'Requires: Lvl 15 + 4xlevel', # description 1'desc2' => 'Fire1-lvl 7, Fire2-lvl 5', # description 2'desc3' => 'Flare', # description 3'req' => [15, 51, 7, 52, 5], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 10, # skill max level'mult' => [10, 4], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.}]# ============================================================================# ======= Personagem 2 =======================================================# ============================================================================Actor[9] = [Sk[0] = {'x' => 30, # icon position on x axis'y' => 30, # icon position on y axis'skill' => 51, # skill obtained'desc1' => 'Requires: Level 1', # description 1'desc2' => '', # description 2'desc3' => 'Fire 1', # description 3'req' => [0], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 10, # skill max level'mult' => [10, 2], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.},Sk[1] = {'x' => 90, # icon position on x axis'y' => 30, # icon position on y axis'skill' => 119, # skill obtained'desc1' => 'Requires: Level 1', # description 1'desc2' => '', # description 2'desc3' => 'Magical Reflection', # description 3'req' => [0], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 1, # skill max level'mult' => [10, 2], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.},Sk[2] = {'x' => 30, # icon position on x axis'y' => 90, # icon position on y axis'skill' => 52, # skill obtained'desc1' => 'Requires: Level 8 + 4x level', # description 1'desc2' => 'Fire 1 - Level 5', # description 2'desc3' => 'Fire 2', # description 3'req' => [8, 51, 5], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 10, # skill max level'mult' => [10, 4], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.},Sk[3] = {'x' => 30, # icon position on x axis'y' => 150, # icon position on y axis'skill' => 53, # skill obtained'desc1' => 'Requires: Lvl 15 + 4xlevel', # description 1'desc2' => 'Fire1-lvl 7, Fire2-lvl 5', # description 2'desc3' => 'Flare', # description 3'req' => [15, 51, 7, 52, 5], # requeriments [necessary level,#skill id necessary, skill level, skill id, skill level.# You can add as many skills for requirements as you wish'maxlvl' => 10, # skill max level'mult' => [10, 4], # multipliers, first is multiplier of heal/damage/effect# the second is how many levels are needed to up the next skill level.}]end#==============================================================================#==============================================================================#========================= Here Starts the Script =============================#==============================================================================#==============================================================================#==============================================================================# ** Scene_Status#------------------------------------------------------------------------------# Esta classe executa o processamento da tela de atributos.#==============================================================================class Scene_Skill_Change < Scene_MenuBase #-------------------------------------------------------------------------- # * Inicialização do processo #-------------------------------------------------------------------------- def start @set = $game_party.actors # array com ids dos personagens do grupo @control_index = 0 #controle do indice de personagens @control_inindex = 0 # controle do indice de habilidades @status_window = Window_Skill_Select.new($game_party.actors[0]) # inicialização do menu de habilidades @actor_window = Window_Actor_Sk.new(0, 0) # inicialização do menu de atores @desc_window = Window_Help_Sk.new($game_party.actors[0]) # inicialização do menu de ajuda @confirm = Window_Skill_Confirm.new # inicialização do menu de confirmação @confirm.set_handler(:use_point, method(:command_use)) @confirm.set_handler(:return_window, method(:command_return)) @confirm.close @actor_window.active = true @status_window.active = false @table = Skill_Tree::Actor super end #-------------------------------------------------------------------------- # * Atualização do Processo #-------------------------------------------------------------------------- def update super # Verificação do índice do menu if @control_index != @actor_window.index @control_index = @actor_window.index @status_window.refresh(@set[@actor_window.index]) # mudança da janela de skills @desc_window.refresh(@set[@actor_window.index], @status_window.index) # mudança da janela de skills end # Verificação do índice de habilidade if @control_inindex != @status_window.index @control_inindex = @status_window.index @desc_window.refresh(@set[@actor_window.index], @status_window.index) # mudança da janela de skills end # Confirmação if Input.trigger?(:C) if @actor_window.active == true Sound.play_ok @status_window.active = true @actor_window.active = false elsif @status_window.active == true @status_window.active = false @confirm.open @confirm.activate end end # Retorno if Input.trigger?(: if @actor_window.active == true return_scene elsif @status_window.active == true @status_window.active = false @actor_window.active = true end end end #-------------------------------------------------------------------------- # * Confirmação de saída #-------------------------------------------------------------------------- def command_return @confirm.close @status_window.active = true end #-------------------------------------------------------------------------- # Confirmação de distribuição #-------------------------------------------------------------------------- def command_use @nocall = true id = $game_party.actors[@actor_window.index] # verificação dos requisitos if $game_actors[id].skill_tree[0] > 0 && $game_actors[id].skill_tree[@table[id][@status_window.index]['skill']] < @table[id][@status_window.index]['maxlvl'] for n in 1...@table[id][@status_window.index]['req'].size if n.even? @nocall = false if @table[id][@status_window.index]['req'][n] > $game_actors[id].skill_tree[@table[id][@status_window.index]['req'][n-1]] end end else @nocall = false end # verificação do multiplicador de level @nocall = false if @table[id][@status_window.index]['mult'][1]*$game_actors[id].skill_tree[@table[id][@status_window.index]['skill']] + @table[id][@status_window.index]['req'][0] >$game_actors[id].level @confirm.close @status_window.active = true unless @nocall Sound.play_buzzer return end if $game_actors[id].skill_tree[@table[id][@status_window.index]['skill']] == 0 $game_actors[id].learn_skill(@table[id][@status_window.index]['skill']) end $game_actors[id].skill_tree[@table[id][@status_window.index]['skill']] += 1 $game_actors[id].skill_mult[@table[id][@status_window.index]['skill']] += @table[id][@status_window.index]['mult'][0] $game_actors[id].skill_tree[0] -= 1 Sound.play_ok @status_window.refresh(@set[@actor_window.index]) end #-------------------------------------------------------------------------- # * Retorno ao menu principal #-------------------------------------------------------------------------- def return_scene super @status_window.dispose @actor_window.dispose @desc_window.dispose endend#==============================================================================# ** Window_Actor_Sk#------------------------------------------------------------------------------# Esta janela exibe os personagens do grupo.#==============================================================================class Window_Actor_Sk < Window_MenuStatus #-------------------------------------------------------------------------- # * Largura da janela #-------------------------------------------------------------------------- def window_width 120 end #-------------------------------------------------------------------------- # * Altura da janela #-------------------------------------------------------------------------- def window_height Graphics.height endend#==============================================================================# ** Window_Skill_Select#------------------------------------------------------------------------------# Janela Principal da Skill Tree#==============================================================================class Window_Skill_Select < Window_Baseattr_reader :index #-------------------------------------------------------------------------- # * Inicialização da Janela #-------------------------------------------------------------------------- def initialize(a) super(120, 0, window_width, Graphics.height - fitting_height(3)) refresh(a) @page = 0 @index = 0 update_cursor end #-------------------------------------------------------------------------- # * Largura da Janela #-------------------------------------------------------------------------- def window_width Graphics.width - 120 end #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- # * Aquisição do retangulo para desenhar o item(cursor) # index : índice do item #-------------------------------------------------------------------------- def item_rect(index) rect = Rect.new rect.x = @table[index]['x'] rect.y = @table[index]['y'] rect.width = 24 rect.height = 24 rect end #-------------------------------------------------------------------------- # * Atualização da janela #-------------------------------------------------------------------------- def refresh(a) contents.clear if Skill_Tree::Images if @tree_load @tree_load.bitmap.dispose @tree_load.dispose end @tree_load = Sprite.new @tree_load.bitmap = Cache.system("Actor#{+a}") @tree_load.z = 200 end @table = Skill_Tree::Actor[a] contents.font.color = text_color(1) @sum = 0 $game_actors[a].skill_tree.each {|z| @sum += z} draw_text(50, -10, 180, 50, $game_actors[a].skill_tree[0].to_s + " "+ Skill_Tree::Rest) draw_text(window_width - 200, -10, 180, 50, @sum.to_s + " "+ Skill_Tree::Total) contents.font.color = text_color(0) for i in 0...@table.size contents.font.size = 16 draw_text(@table[i]['x'], @table[i]['y']+ 26, 40, 30, $game_actors[a].skill_tree[@table[i]['skill']].to_s + " /" + @table[i]['maxlvl'].to_s) draw_icon($data_skills[@table[i]['skill']].icon_index, @table[i]['x'], @table[i]['y'], $game_actors[a].skill_learn?($data_skills[@table[i]['skill']])) end contents.font.size = Font.default_size @page = 0 @index = 0 update_cursor end #-------------------------------------------------------------------------- # * Renovação #-------------------------------------------------------------------------- def update return if active == false if Input.repeat?(:RIGHT) || Input.repeat?(:DOWN) @index += 1 @index = 0 if @index >= @table.size Sound.play_cursor elsif Input.repeat?(:LEFT) || Input.repeat?(:UP) @index -= 1 @index = (@table.size - 1) if @index < 0 Sound.play_cursor end update_cursor end #-------------------------------------------------------------------------- # * Atualização do cursor #-------------------------------------------------------------------------- def update_cursor cursor_rect.set(item_rect(@index)) end #-------------------------------------------------------------------------- # * Execução do movimento do cursor #-------------------------------------------------------------------------- def process_cursor_move last_page = @page super update_cursor Sound.play_cursor if @page != last_page end #-------------------------------------------------------------------------- # * Definição de controle de confirmação e cancelamento #-------------------------------------------------------------------------- def process_handling return unless open? && active process_jump if Input.trigger?(:A) process_back if Input.repeat?(: process_ok if Input.trigger?(:C) end #-------------------------------------------------------------------------- # * Definição de resultado ao pressionar o botão de confirmação #-------------------------------------------------------------------------- def process_ok if !character.empty? on_name_add elsif is_page_change? Sound.play_ok cursor_pagedown elsif is_ok? on_name_ok end end #-------------------------------------------------------------------------- # * Adição ao nome do personagem #-------------------------------------------------------------------------- def on_name_add if @edit_window.add(character) Sound.play_ok else Sound.play_buzzer end end #-------------------------------------------------------------------------- # * Definição do nome #-------------------------------------------------------------------------- def on_name_ok if @edit_window.name.empty? if @edit_window.restore_default Sound.play_ok else Sound.play_buzzer end else Sound.play_ok call_ok_handler end end #-------------------------------------------------------------------------- # * Descarte #-------------------------------------------------------------------------- def dispose super if @tree_load @tree_load.bitmap.dispose @tree_load.dispose end endend#==============================================================================# ** Window_Help_Sk#------------------------------------------------------------------------------# Esta janela exibe explicação de habilidades e informações sobre os requerimentos.#==============================================================================class Window_Help_Sk < Window_Base def initialize(a) super(120, Graphics.height - fitting_height(3), Graphics.width - 120, fitting_height(3)) @table = Skill_Tree::Actor[a] refresh(a, 1) end #-------------------------------------------------------------------------- # * Atualização da janela #-------------------------------------------------------------------------- def refresh(a, index) contents.clear @table = Skill_Tree::Actor[a] unless Skill_Tree::Actor[a] == nil contents.font.color = text_color(20) draw_text(0, 0, Graphics.width - 120, line_height, @table[index]['desc1']) draw_text(0, line_height, Graphics.width - 120, line_height, @table[index]['desc2']) contents.font.color = text_color(0) draw_text(0, line_height*2, Graphics.width - 120, line_height, @table[index]['desc3']) endend#==============================================================================# ** Window_MenuStatus#------------------------------------------------------------------------------# Esta janela exibe os parâmetros dos membros do grupo na tela de menu.#==============================================================================class Window_Skill_Confirm < Window_Command #-------------------------------------------------------------------------- # * Inicialização do objeto #-------------------------------------------------------------------------- def initialize super(0, 0) self.z = 9999 self.x = (Graphics.width / 2) - (window_width / 2) self.y = Graphics.height / 2 self.openness = 0 end #-------------------------------------------------------------------------- # * Aquisição da largura da janela #-------------------------------------------------------------------------- def window_width return 160 end #-------------------------------------------------------------------------- # * Criação da lista de comandos #-------------------------------------------------------------------------- def make_command_list add_main_commands end #-------------------------------------------------------------------------- # * Adição dos comandos principais #-------------------------------------------------------------------------- def add_main_commands add_command(Skill_Tree::Bot1, :use_point, true) add_command(Skill_Tree::Bot2, :return_window, true) endend#==============================================================================# ** Game_Actor#------------------------------------------------------------------------------# Esta classe gerencia os heróis. Ela é utilizada internamente pela classe# Game_Actors ($game_actors). A instância desta classe é referenciada# pela classe Game_Party ($game_party).#==============================================================================class Game_Actor < Game_Battleralias sk_tree_ini setupalias sk_tree_lvl level_upattr_accessor :skill_treeattr_accessor :skill_mult #-------------------------------------------------------------------------- # * Inicialização do objeto # actor_id : ID do herói #-------------------------------------------------------------------------- def setup(actor_id) sk_tree_ini(actor_id) @skill_tree = Array.new($data_skills.size + 1, 0) @skill_mult = Array.new($data_skills.size + 1, 0) end #-------------------------------------------------------------------------- # * Aumento de nível #-------------------------------------------------------------------------- def level_up sk_tree_lvl @skill_tree[0] += 1 endend#==============================================================================# ** Game_Party#------------------------------------------------------------------------------# Esta classe gerencia o grupo. Contém informações sobre dinheiro, itens.# A instância desta classe é referenciada por $game_party.#==============================================================================class Game_Party < Game_Unitattr_accessor :actorsend#==============================================================================# ** Game_Battler#------------------------------------------------------------------------------# Esta classe gerencia os battlers. Controla a adição de sprites e ações # dos lutadores durante o combate.# É usada como a superclasse das classes Game_Enemy e Game_Actor.#==============================================================================class Game_Battler < Game_BattlerBase #-------------------------------------------------------------------------- # * Cálculo de dano # user : usuário # item : habilidade/item #-------------------------------------------------------------------------- def make_damage_value(user, item) value = item.damage.eval(user, self, $game_variables) value *= item_element_rate(user, item) value *= pdr if item.physical? value *= mdr if item.magical? value *= rec if item.damage.recover? value = apply_critical(value) if @result.critical value = apply_variance(value, item.damage.variance) value = apply_guard(value) value += (value * $game_actors[user.id].skill_mult[item.id])/100 @result.make_damage(value.to_i, item) endend#==============================================================================# ** Game_Interpreter#------------------------------------------------------------------------------# Um interpretador para executar os comandos de evento. Esta classe é usada# internamente pelas classes Game_Map, Game_Troop e Game_Event.#==============================================================================class Game_Interpreter def reset_tree(id) @sum_sk = 0 $game_actors[id].skill_tree.each {|z| @sum_sk += z} $game_actors[id].skill_tree.fill(0) $game_actors[id].skill_tree[0] = @sum_sk endend