Tales of Symphonia/Phantasia skill system
#1
Tales of Symphonia/Phantasia skill system
by Jimmie
Sep 23 2005

This is a locked, single-post thread from Creation Asylum. Archived here to prevent its loss.
No support is given. If you are the owner of the thread, please contact administration.


Introduction

You know how sometimes you level up and gain new skills. This is pretty commonplace in RPGs, so you should have seen it at least once.
But what if that skills is "Omega Flare", and you never, ever, used "Flare"? (Yes, I'm ripping off names here.)
This script attempts to fix that by enforcing a minimum on the amount of times "parent" skills must be used before their more advanced version can be used.
See the bottom of this post for explanatory screenshots.

Compatability
If you have modified any of the following, there may be problems (in order of likelyhood):
Scene_Skill
Window_Skill
Scene_Battle
Game_Actor
Game_Party

Code
Why am I using double code-boxes? Because one has a scroll-bar, and the other prevents autoconversion to symbols like ©.

This is the main part of the system. Place this in a new script-slot above main.
Code:
#Tales of Symphonia/Phantasia skill system by Nitt aka jimme reashu
#Version 2.1
#This comment and comments above it must stay intact whenever the script is distributed

class Game_Party
  attr_accessor:skill_use
  attr_accessor :parents
  alias skill_setup initialize
  def initialize
    skill_setup
    @skill_use = Array.new($data_actors.size,[])
    for i in 1...$data_skills.size
      for j in 1...$data_actors.size
        @skill_use[j][i] = 0
      end
    end
  @parents = []
  #This is where you define the "parent" skill and how many times you have to have used it.
  #If "parent" is not used enough times the skill will be disabled in the menu.
  @parents[2] = {1 => 5} #Skill number one must have been used five times for number 2 to be useable
  @parents[3] = {2 => 10} #Skill number 2 must have been used 10 times for number 3 to be useable
  @parents[4] = {2 => 40, 3 => 2} #This is a special one.
  #It requires skill 2 to have been used 40 times, AND skill 3 twice in order to use skill 4.
  #You can add unlimited parents, but I wouldn't recommend using more than four.
  @parents[6] = {1 => 20, 2 => 15, 3 => 10, 4 => 10, 5 => 5}
  #@parents[7] = {6 => 3, 5 => 50}
  #And so on.
  end
end

class Game_Actor<Game_Battler
  attr_accessor:actor_id
  
  def used_enough(skill_id)
    @actor=self.actor_id

   @useflag = true
   if $game_party.parents[skill_id] != nil
     $game_party.parents[skill_id].each{|a,b|@useflag &= $game_party.skill_use[@actor][a] >= b}
   end
   @useflag
  end
end

class Scene_Skill
  def main
    @actor = $game_party.actors[@actor_index]
    @help_window = Window_Help.new
    @status_window = Window_SkillStatus.new(@actor)
    @skill_window = Window_Skill_U.new(@actor)
    @parent_window = Window_Parent.new
    @skill_window.help_window = @help_window
    @target_window = Window_Target.new
    @target_window.visible = false
    @target_window.active = false
    @use_window=Window_Use.new
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    Graphics.freeze
    @help_window.dispose
    @status_window.dispose
    @skill_window.dispose
    @target_window.dispose
    @use_window.dispose
    @parent_window.dispose
  end
  
    def update
    @help_window.update
    @status_window.update
    @skill_window.update
    @target_window.update
    @use_window.update
    @parent_window.update
    if @skill_window.active
      update_skill
      return
    end
    if @target_window.active
      update_target
      return
    end
  end
  
  def update_skill
    @use_window.refresh(@skill_window.skill,@actor)
    @parent_window.refresh(@skill_window.skill.id,@actor.actor_id)
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Menu.new(1)
      return
    end
    if Input.trigger?(Input::C)
      @skill = @skill_window.skill
      if @skill == nil or not @actor.skill_can_use?(@skill.id) or not @actor.used_enough(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      if @skill.scope >= 3
        @skill_window.active = false
        @target_window.x = (@skill_window.index + 1) % 2 * 304
        @target_window.visible = true
        @target_window.active = true
        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
      else
        if @skill.common_event_id > 0
          $game_temp.common_event_id = @skill.common_event_id
          $game_system.se_play(@skill.menu_se)
          @actor.sp -= @skill.sp_cost
          @status_window.refresh
          @skill_window.refresh
          @target_window.refresh
          $scene = Scene_Map.new
          return
        end
      end
      return
    end
    if Input.trigger?(Input::R)
      $game_system.se_play($data_system.cursor_se)
      @actor_index += 1
      @actor_index %= $game_party.actors.size
      $scene = Scene_Skill.new(@actor_index)
      return
    end
    if Input.trigger?(Input::L)
      $game_system.se_play($data_system.cursor_se)
      @actor_index += $game_party.actors.size - 1
      @actor_index %= $game_party.actors.size
      $scene = Scene_Skill.new(@actor_index)
      return
    end
  end
  def update_target
      @use_window.x = @skill_window.index % 2 == 1 ? 512 : 0
      @parent_window.x = @skill_window.index % 2 == 1 ? 0 : 128
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @skill_window.active = true
      @target_window.visible = false
      @target_window.active = false
      @use_window.x = 512
      @parent_window.x = 0
      return
    end
    if Input.trigger?(Input::C)
      unless @actor.skill_can_use?(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      unless @actor.used_enough(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      if @target_window.index == -1
        used = false
        for i in $game_party.actors
          used |= i.skill_effect(@actor, @skill)
        end
      end
      if @target_window.index <= -2
        target = $game_party.actors[@target_window.index + 10]
        used = target.skill_effect(@actor, @skill)
      end
      if @target_window.index >= 0
        target = $game_party.actors[@target_window.index]
        used = target.skill_effect(@actor, @skill)
      end
      if used
        $game_party.skill_use[@actor.actor_id][@skill.id]+=1
        $game_system.se_play(@skill.menu_se)
        @actor.sp -= @skill.sp_cost
        @status_window.refresh
        @skill_window.refresh
        @skill_window.update_help
        @target_window.refresh
        @use_window.refresh(@skill_window.skill, @actor)
        if $game_party.all_dead?
          $scene = Scene_Gameover.new
          return
        end
        if @skill.common_event_id > 0
          $game_temp.common_event_id = @skill.common_event_id
          $scene = Scene_Map.new
          return
        end
      end
      unless used
        $game_system.se_play($data_system.buzzer_se)
      end
      return
    end
  end
end

class Window_Use<Window_Base
  def initialize
    super(512,416,128,64)
    self.contents=Bitmap.new(width-32,height-32)
    self.contents.font.name=$defaultfonttype
    self.contents.font.size=$defaultfontsize
  end
  
  def refresh(skill=0, actor=0)
   self.contents.clear
   usetext = $game_party.skill_use[actor.id][skill.id] == 1 ? " use." : " uses."
  self.contents.draw_text(0,0,96,32, $game_party.skill_use[actor.id][skill.id].to_s + usetext)
  end
end

class Window_Skill
      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
    unless @actor.used_enough(skill.id)
      self.contents.font.color = text_color(1)
    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)
    self.contents.draw_text(x + 232, y, 48, 32, skill.sp_cost.to_s, 2)
  end
end

class Window_Skill_U < Window_Skill
  def initialize(actor)
    super(actor)
    self.height = 288
  end
end

class Window_Parent < Window_Base
  def initialize
    super(0,416,512,64)
    self.contents = Bitmap.new(width-32, height-32)
    self.contents.font.name = $defaultfonttype
    self.contents.font.size = $defaultfontsize
    refresh
  end
  def refresh(skill = 0, actor = 0)
    self.contents.clear
    return if skill == 0 or actor == 0
    @parents = $game_party.parents[skill]
    return if @parents == nil
    width = 0
    @parents.each{|a,b|width += contents.text_size($data_skills[a].name).width}
    widthmod = [1, 480.0/width].min
    xx = 0
    namemod = ""
    for i in @parents.keys.sort
      space = contents.text_size(namemod + $data_skills[i].name).width * widthmod
      self.contents.font.color = $game_party.skill_use[actor][i] >= @parents[i] ? normal_color : text_color(1)
      self.contents.draw_text(xx, 0, space, 32, namemod + $data_skills[i].name)
      xx += space
      namemod = ", "
    end
  end
end

This part counts skill uses in battle. Paste it UNDER your current battle system script. If you're not using a custom one, just paste it above main as usual...
It's possible (read: likely) that this will mess up any battle system other than the default that you use. If it does, let me know and send me a link to/copy of your battle system and I'll fix it up for you.
Code:
#==============================================================================
#  Scene_Battle
#==============================================================================

class Scene_Battle
  #--------------------------------------------------------------------------
  def update_phase3_skill_select
    @skill_window.visible = true
    @skill_window.update
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      end_skill_select
      return
    end
    if Input.trigger?(Input::C)
      @skill = @skill_window.skill
      if @skill == nil or not @active_battler.skill_can_use?(@skill.id) or not @active_battler.used_enough(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      @active_battler.current_action.skill_id = @skill.id
      @skill_window.visible = false
      if @skill.scope == 1
        start_enemy_select
      elsif @skill.scope == 3 or @skill.scope == 5
        start_actor_select
      else
        end_skill_select
        phase3_next_actor
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  def make_skill_action_result
    @skill = $data_skills[@active_battler.current_action.skill_id]
    unless @active_battler.current_action.forcing
      unless @active_battler.skill_can_use?(@skill.id)
        $game_temp.forcing_battler = nil
        @phase4_step = 1
        return
      end
    end
    @active_battler.sp -= @skill.sp_cost
    $game_party.skill_use[@active_battler.actor_id][@skill.id]+=1 if @active_battler.is_a?(Game_Actor)
    @status_window.refresh
    @help_window.set_text(@skill.name, 1)
    @animation1_id = @skill.animation1_id
    @animation2_id = @skill.animation2_id
    @common_event_id = @skill.common_event_id
    set_target_battlers(@skill.scope)
    for target in @target_battlers
      target.skill_effect(@active_battler, @skill)
    end
  end
end


Setup
Instructions are more or less in the script. Simply locate the line that says "@parents = []" (in versions 2 and earlier, this is actually "@parents = {}". Under that, define what skills have parents using the following syntax:
@parents[SKILL_ID] = {PARENT_ID => REQUIRED_USES, PARENT_ID => REQUIRED_USES}
As you can see, any number of parents are possible. The window which shows parents does not have place for an unlimited amount of parents, though.


Screenshot
[Image: skillsystem.png]


Have fun!
//Nitt
}


Possibly Related Threads…
Thread Author Replies Views Last Post
  A little Modification for Screenshot system Maumau 0 2,840 12-04-2008, 01:00 PM
Last Post: Maumau
  Summon/Custom Skills System! Reno-s--Joker 0 2,738 10-07-2008, 01:00 PM
Last Post: Reno-s--Joker
  Enemy Detection System GubiD 0 2,397 08-12-2007, 01:00 PM
Last Post: GubiD
  CNS (Custom Name System) Samo the thief 0 2,446 02-12-2007, 01:00 PM
Last Post: Samo the thief
  CSS (Custom Shop System) Samo the thief 0 2,789 01-29-2007, 01:00 PM
Last Post: Samo the thief
  My Saving system crystal 0 2,352 01-16-2007, 01:00 PM
Last Post: crystal
  Star Ocean Shop System Hawk-McKain 0 2,523 10-20-2006, 01:00 PM
Last Post: Hawk-McKain
  Slipknot Advance Debug System Sheol 0 2,152 12-23-2005, 01:00 PM
Last Post: Sheol



Users browsing this thread: 1 Guest(s)