Legacy Class Change
#1
Legacy Class Change
by legacyblade
Version: 1.20

Type: Class Change Script
Aug 26 2008

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

After awhile of searching through script databases, I was unsuccessful at finding a class changing script that did what I wanted it to do. I found one that was sort of close, but didn't work with BlizzABS, or any other ABS for that matter, and that just didn't work for me. So, I decided to make one, and I think it turned out quite well. The system is reminiscent of Final Fantasy Tactics Advanced.
Features
  • *Simple configuration*Customizable class requirements*Optional graphic changing upon class change*Descriptions for each class

Script

Code:
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
   # Legacy Class Change by Legacyblade
   # Version: 1.20
   # Type: Class Changing Script
   # Date 11-26-2008
   #
   #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
   #  
   #  This work is protected by the following license:
   # #----------------------------------------------------------------------------
   # #  
   # #  Creative Commons - Attribution-Share Alike 3.0 Unported
   # #  ( http://creativecommons.org/licenses/by-sa/3.0/ )
   # #  
   # #  You are free:
   # #  
   # #  to Share - to copy, distribute and transmit the work
   # #  to Remix - to adapt the work
   # #  
   # #  Under the following conditions:
   # #  
   # #  Attribution. You must attribute the work in the manner specified by the
   # #  author or licensor (but not in any way that suggests that they endorse you
   # #  or your use of the work).
   # #  
   # #  
   # #  Share alike. If you alter, transform, or build upon this work, you may
   # #  distribute the resulting work only under the same or similar license to
   # #  this one.
   # #  
   # #  - For any reuse or distribution, you must make clear to others the license
   # #    terms of this work. The best way to do this is with a link to this web
   # #    page.
   # #  
   # #  - Any of the above conditions can be waived if you get permission from the
   # #    copyright holder.
   # #  
   # #  - Nothing in this license impairs or restricts the author's moral rights.
   # #  
   # #----------------------------------------------------------------------------
   #
   #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
   #
   # VERY IMPORTANT NOTES:
   #
   # For every minor update or bugfix, I will increase the version by .01
   # For every new feature, I will increase the version be .1
   # For every 10 feature updates, I will update the version by 1
   #
   # Compatibility:
   #
   # The script was coded to be 100% compatible with most, if not all scripts. I can't
   # think of ANY script that wouldn't be compatible, but I will list those that I
   # tested for compatibility.
   #
   # Blizz ABS is 100% compatible, and most ABS scripts should be as well, due to how
   # the class rank is added.
   #
   # CCoa's UMS is 100% compatible.
   #
   # The SDK 2.3 seemed to be compatible. Everything worked fine even with the SDK
   # in the project.
   #
   # I'll keep testing scripts, and adding to this list
   #
   # Incompatibility:
   #
   # No known incompatibility
   #
   #
   # Known Issues:
   #
   # none ^_^
   #
   # Features:
   #
   # The Legacy Class Change system allows you to define how many levelups with a
   # certain class or classes are needed to unlock another class. Its setup in such
   # a way to fit ANY game's needs. You can also define a description for the class
   # or just set the description for each class to what type of class (long range,
   # close range, magical, popcorn wielding, ect.) It's done in such a way that you
   # can configure it to work with whatever style of RPG your making, whether it be
   # serious, joke, abs, turn based, tbs, or any other kind of RPG, the Legacy Class
   # Change will work for your game.
   #
   # Another of the newer features is the ability to have the actor's graphic (both
   # charset AND battler) change when the class is changed. This can be disabled,
   # or configured so that only certain classes will cause a graphic change, or that
   # certain classes share a graphic. I know that every game has different needs, so
   # I make my scripts as flexible as possible
   #
   # And you know what the best part is? I'm constantly working on adding new
   # features, and making Legacy Class Change work even better.
   #
   # Version History:
   #
   # v1.00b:
   #   -> Legacy Class Change released!
   #
   # v1.01b:
   #   -> Fixed a bug in class selection, that would set the actor's class_id to the
   #      index of the cursor, rather than the actual selected class_id.
   #
   # v1.02b:
   #   -> Fixed a few miscellaneous lines of code that could, under certain circumstances, cause errors
   #
   # v1.10b:
   #   -> Added the option to change an actor's graphic when the class changes.
   #
   # v1.10b:
   #   -> Fixed a bug that kept the class list from scrolling
   #
   # v.1.20:
   #   -> Left the beta stage.
   #   -> Enhanced the level handeling. Now the skills are assigned based on class
   #      level, rather than the actor's overall level.
   #
   #
   # Useless facts:
   #
   # This was the first time I've ever successfully made a script. I learned a lot
   # about everything I worked with, and can't wait to learn more about RGSS and
   # programming in general. I hope you enjoy this, because it cost an entire BOX
   # of trisquites, and a couple gallons of milk to make.
   #
   # Special Thanks:
   #
   #       - Blizzard for all his help. Without him, I couldn't have made it. Not
   #         only did he help me fix the errors, he also gave me lectures on various
   #         aspects of programming. This caused me to make LESS errors, and grow
   #         in my programming skill. Thanks blizz, this script wouldn't be here
   #         today if you hadn't been there in that MIRC room, XD
   #
   #       - GubiD for when blizzard wasn't around in MIRC to answer my questions.
   #         he helped me with a few errors that I had no idea how to fix (many of
   #         them were some of the most n00bish errors too -_-). Thanks GubiD
   #         couldn't have done it without ya!
   #
   #      - Sephirothtds for making TDS Class Change System incompatible with
   #        the Blizz-ABS. If you'd made it compatible, I would have gone with your
   #        script, and never figured out how to make one myself (a much easier to
   #        configure one at that). Your script's incompatibility sparked my urge to
   #        learn to scrip. Thanks.
   #
   #       - Juan, who offered a few pointers.
   #
   #       - To all those who put up with me in the CP chat room when I'm ranting
   #         about my newest error.
   #
   #       - To all the members of eminweb.com for nagging me enough to do my
   #         administrative duty, which eventually cured me of my infamous laziness
   #
   #       - StarrodKirby86 for requesting the class graphic system, it made this
   #         script have a feature not many class changing systems have.
   #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
  
  
   module LBConf
  
   # If this is set to true, then changing an actor's class will also change its
   # graphic.
     CLASS_GRAPHIC_CHANGE = true
    
   # Alright, so you're ambitious enough to have a different graphic for some, if
   # not ALL of your classes. Well, this will make things a tad more difficult for
   # you, but it'll make your game sure look nicer. Anyways, use the following
   # template
   # when class_id then return 'text you want appended'
   # the 'text you want appended' is how the script figures out which graphic to
   # change to. If you want class 1 to switch to the actor's default sprite with
   # _fighter on the end, then make 'text you want appended '_fighter'. If you don't
   # want the graphic to be different than the default actor graphic, then just
   # don't define anything for that class.
  
     def self.class_graphic(class_id)
       case class_id
        
         #Alright, this is where we tell the script that when the actor chooses the
         #fighter class, that it needs to look for the actor's default sprite with
         # _fighter appended to the end of it.
         when 1 then return '_fighter'
      
         #graphic suffix for lancer class
         when 2 then return '_lancer'
      
         #This is what I do when I don't have a graphic ready yet, just comment
         #the line where you define the class graphic
         #when 3 then return '_warrior'
        
         #graphic suffix for cleric class
         when 7 then return '_cleric'
      
         #graphic suffix for mage class
         when 8 then return '_mage'
        
         #You'll notice that NONE of the other classes have any configuration data
         #in most scripts, we'd get an error, but in Legacy Class Change, it just
         #passes a default blank string. This will make it used the actor's default
         #graphic. Pretty cool, eh?
          
         end
        #graphic suffix for those not defined in the above section.
       return ''
      
     end
    
   # This next section is where you define the description for each class.
   # use the following template for each class
   # when class_id then return 'class description'
   # If you don't give a class a description, don't worry. The script will provide
   # a default description. (which is configured to a blank line.
   # To change that (for whatever reason) look for return ' ' near the bottom
   # of this section
     def self.class_descriptions(class_id)
       case class_id
      
         #Description for Fighter
         when 1 then return 'Fighters wield swords, and some even wear red headbands!'
          
         #Description for Lancer
         when 2 then return 'Lancers...they fight with lances...nuff said'
          
         #Description for Warrior
         when 3 then return 'Warriors, the big slow guys we all rely to do the physical damage.'
          
         #Description for Thief
         when 4 then return 'Thieves: gotta love em...unless of course they steal YOUR hard earned gold'
          
         #Description for Hunter
         when 5 then return 'Hunters are archers. What is wrong with just calling them ARCHERS, GAH!'
          
         #Description for Gunner
         when 6 then return 'People with a guns in the same battle as people with a swords...'
          
         #Description for Cleric
         when 7 then return 'Even though they heal people, they always seem to die first...ironic'
          
         #Description for Mage
         when 8 then return 'Basic magic users. Weak as heck at low levels, but they get STRONG'
        
         #Description for Knight
         when 9 then return 'Knights, guys with shiny armor on horses...whooo...'
          
         #Description for Ranger
         when 10 then return 'Its just an Aragorn wannabe.'
        
         #Description for Assasin
         when 11 then return 'Assasins, the true bad*** (it\'s even part of their name)'
        
         #Description for Raider  
         when 12 then return 'The rudest kind of thief, they burn your town AND steal your stuff.'
        
         #Description for Sniper  
         when 13 then return 'Snipers are SO annoying in first person shooters!'
        
         #Description for Warlock
         when 14 then return 'Do they end wars? war...lock? You dont get it? *sigh*'
        
         #Description for Paladin
         when 15 then return 'Oh holy knight, your sword is brightly shining!'
        
         #Description for guardian angel  
         when 16 then return 'Paladin + knight = guardian angel...what?'
        
         #Description for Dark Knight  
         when 17 then return 'Dark Knight, that movie is kinda creepy, eh?'
        
         #Description for Shadow of Death  
         when 18 then return 'Since when does death have a shadow? Oh well.'
        
         #Description for Master of Magic  
         when 19 then return 'So boring, you\'ve probably been a mage or warlock the whole game.'
       end
       #Prevents crashes when a class description has not been defined
       return ' '
     end
  
   # This is where you set the requirement for each class. It may be a tad more
   # difficult than the class description, but you can do it! Use the following template
   # when class_id then return [0,levels in class 1, levels needed in class 2, etc]
   # Make sure to have a dummy 0 at the beginning. This is because the classes defined
   # in the database start at 1, whereas arrays start at 0. So to make things easier
   # I just left a dummy 0. If this REALLY bugs you guys, I'll remove it in the next
   # release, XD
   # Also, you should have a requirement level in the array for EACH CLASS. If you
   # want to have it unlocked by default, just set each requirement to 0, or don't
   # define it here (don't you love my crash prevention?). But make sure you have
   # a number in the array for each class (starting AFTER the dummy 0)
  
    
     def self.class_requirements(class_id)
       case class_id
      
        
         #this is one way to make a class unlocked by default. (this is Fighter, btw)
         when 1 then return [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
          
         #...or you can just leave them out of the list, its probobly easier that way
              
         #Requirement for Knight: 5 fighter, 5 lancer, 3 warrior
         when 9 then return [0,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        
         #Requirement for Ranger: 5 warrior, 5 hunter
         when 10 then return [0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        
         #Requirement for Assasin: 1 thief, 4 hunter
         when 11 then return [0,0,0,0,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        
         #Requirement for Raider 10 warrior, 3 theif
         when 12 then return [0,0,0,10,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        
         #Requirement for Sniper: 2 hunter, 4 gunner
         when 13 then return [0,0,0,0,0,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0]
  
         #Requirement for Warlock: 10 Mage (see how customizable this script is?)
         when 14 then return [0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0]
          
         #Requirement for Paladin: 5 cleric + 5 knight  
         when 15 then return [0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0]
        
         #Requirement for Gaurdian Angel: 10 Knight, 10 Paladin
         when 16 then return [0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,10,0,0,0,0]
          
         #Requirement for Dark Knight: 10 Knight + 10 Assasin
         when 17 then return [0,0,0,0,0,0,0,0,0,10,0,10,0,0,0,0,0,0,0,0]
  
         #Requirement for Shadow of Death: 10 Assasin + 10 Sniper
         when 18 then return [0,0,0,0,0,0,0,0,0,0,10,0,10,0,0,0,0,0,0]
        
         #Requirement for Master of Magic: 15 Warlock
         when 19 then return [0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0]
          
         end
        
       #Prevents crashes when a class requirement has not been defined, and also
       #makes setting the classes that start ulocked much quicker ^_^
       #just make sure there's a dummy 0, and a zero for all the classes in the
       #database
       return [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
  
     end
   end
  
  
   #This adds the class levels, and the class rank arrays to the actor class
   class Game_Actor < Game_Battler
     attr_accessor :class_levels
     attr_accessor :unlocked_class
     attr_accessor :character_name
     attr_accessor :default_charset_name
     attr_accessor :battler_name
     attr_accessor :default_battler_name
    
     alias class_rank_level_LB setup
     # Lets add the needed attributes to the Actor class
     def setup(actor_id)
       class_rank_level_LB(actor_id)
      
       @default_charset_name = @character_name
       @default_battler_name = @battler_name
      
       @prev_level = @level
       @unlocked_class = []
      
       @class_levels = Array.new($data_classes.size)
      
       @class_levels.each_index {|i|
       if i == $data_actors[actor_id].class_id
         @class_levels[i] = 1
       else
         @class_levels[i] = 0
       end}
          
       (1...$data_classes.size).each{|class_id|
       unlock_class(class_id)}
     end
     def unlock_class(class_id)
       if !@unlocked_class.include?(class_id)
         requirement = LBConf.class_requirements(class_id)
         result = true
         requirement.each_index {|i|
         if @class_levels[i] < requirement[i]
           result = false
           break
         end}
         if result
           @unlocked_class.push(class_id)
           @unlocked_class.sort!
         end
       end
     end
    
     def exp=(exp)
       @exp = [[exp, 9999999].min, 0].max
       # Level up
       while @exp >= @exp_list[@level+1] && @exp_list[@level+1] > 0
         @level += 1
         @class_levels[class_id] += 1
       #learn skills
         $data_classes[@class_id].learnings.each {|j|
           if j.level == @class_levels[@class_id]
             p 'I am learning ' + j.skill_id.to_s
             p 'just so you know, I am a level ' + @class_levels[@class_id].to_s + ' ' + $data_classes[@class_id].name
             learn_skill(j.skill_id)
           end
         }
       end
       # Level down
       while @exp < @exp_list[@level]
         @level += 1
       end
       # Correction if exceeding current max HP and max SP
       @hp = [@hp, self.maxhp].min
       @sp = [@sp, self.maxsp].min
     end
   end
  
   class Class_Change_Scene
    
     def initialize
    
       # update the unlocked_level array for each actor
       $game_party.actors.each{|actor|
       (1...$data_classes.size).each{|class_id|
       actor.unlock_class(class_id)}}
  
       #create the windows
       @actor_list = Window_Actor_List.new
       @actor_list.index = 0
       @actor_list.active = true
      
       @class_list = Window_Class_List.new
      
       @class_description = Window_Class_Description.new
      
       @last_class = 0
      
     end
    
     def main
          
       #enter the scene's loop
       Graphics.transition
       loop do
         Graphics.update
         Input.update
         update
         if $scene != self
           break
         end
       end
      
       #dispose of the windows created in the scene
       Graphics.freeze
       @actor_list.dispose
       @class_list.dispose
       @class_description.dispose
     end
      
     def update
       #update the windows
       @actor_list.update
       @class_list.update
       @class_description.update
        
       #is actor_list the window we're using?
       if @actor_list.active
          update_actor_list
         return
       end
      
       #is class_list the window we're using?
       if @class_list.active
         update_class_list
         return
       end
     end
     # Defines the method used when class_list is active
     def update_actor_list    
       if Input.trigger?(Input::B) #Did the user press the cancel button?
         $game_system.se_play($data_system.cancel_se)#play the cancel sound
         $game_player.refresh
         $scene = Scene_Map.new #Go back to the map scene!
         return
       end
       if Input.trigger?(Input::C) #Did the user press the action button?
         $game_system.se_play($data_system.decision_se) #play the decision sound
        
         #set the class_list variable of the  class_list window to the current actor's unlocked classes
         @class_list.class_list = $game_party.actors[@actor_list.index].unlocked_class
         @class_list.refresh#refresh the class_list display
         @actor_list.active = false#deactivate the actor_list window
         #set the class_window index to 0, causing the selection rectangle to appear
         @class_list.index = 0
         @class_list.active = true#activate the class_list window
         @class_list.actor = @actor_list.index#give the class_list the current actor
         @class_description.description = LBConf.class_descriptions(@class_list.index + 1)
         @class_description.refresh
       return
       end
     end
    
    
     # Defines the method used when class_list is active
     def update_class_list
       if @class_list.current_class != @last_class
         @last_class = @class_list.current_class
         @class_description.description = LBConf.class_descriptions(@class_list.current_class)
         @class_description.refresh
       end
       if Input.trigger?(Input::B) #did the user press the cancel button?
         $game_system.se_play($data_system.cancel_se) #play the cancel sound
        
         @class_list.index = -1 #make the rectangle in the class list go bye-bye
         @class_list.active = false #deactivate the class list
         @actor_list.active = true  #activate the actor list
         return
       end
       if Input.trigger?(Input::C) #Did the user press the action button?
         $game_system.se_play($data_system.decision_se) #play the decision sound
        
         #Give the selected actor the class currently selected (1 more than the index)
         $game_party.actors[@class_list.actor].class_id = @class_list.current_class
         if LBConf::CLASS_GRAPHIC_CHANGE == true
           actor_graphics_change
         end
         @actor_list.refresh #refresh the actor list's display
         @class_list.index = -1 #deactivate the rectangle in the class list
         @class_list.active = false #deactivate the class list
         @actor_list.active = true  #activate the actor list
         return
       end
     end
     def actor_graphics_change
       $game_party.actors[@class_list.actor].character_name = ($game_party.actors[@class_list.actor].default_charset_name + LBConf.class_graphic($game_party.actors[@class_list.actor].class_id))
       $game_party.actors[@class_list.actor].battler_name = ($game_party.actors[@class_list.actor].default_battler_name + LBConf.class_graphic($game_party.actors[@class_list.actor].class_id))
     end
    
   end
  
   class Window_Actor_List < Window_Selectable
     def initialize
       super(160, 0, 480, 352)
       self.contents = Bitmap.new(width - 32, height - 32)
       refresh
       self.active = false
       self.index = -1
     end
     def refresh
       self.contents.clear
       @item_max = $game_party.actors.size
       for i in 0...$game_party.actors.size
         x = 64
         y = i * 80
         actor = $game_party.actors[i]
         draw_actor_graphic(actor, x - 40, y + 55)
         draw_actor_name(actor, x, y)
         draw_actor_level(actor, x + 144, y)
         self.contents.draw_text(x, y + 32, width - 32, 32, ($data_classes[$game_party.actors[i].class_id].name + ' rank: ' + $game_party.actors[i].class_levels[$game_party.actors[i].class_id].to_s))
       end
     end
     def update_cursor_rect
       if @index < 0
         self.cursor_rect.empty
       else
         self.cursor_rect.set(0, @index * 80, self.width - 32, 70)
       end
     end
   end
  
   class Window_Class_List < Window_Selectable
  
     attr_accessor :actor
     attr_accessor :class_list
     attr_accessor :item_max
     attr_reader   :current_class
    
     def initialize
       super(0, 0, 160, 352)
       @actor = 0
       @class_list = $game_party.actors[@actor].unlocked_class
       @item_max = @class_list.length
       self.contents = Bitmap.new(width - 32, @item_max * 32)
       refresh
       @index = -1
       @active = false
       @current_class = 1
     end
    
     def refresh
       self.contents.clear
       @item_max = @class_list.size
       i = 0
       @class_list.each{|class_id|
       self.contents.draw_text(10, i, width - 32, 32, $data_classes[class_id].name)
       i += 32}
     end
    
   alias update_cursor_LB update_cursor_rect
     def update_cursor_rect
       update_cursor_LB
       if @index >= 0
         @current_class = @class_list[@index]
       end
     end
   end
  
   class Window_Class_Description < Window_Base
  
     attr_accessor :description
     def initialize
       super(0, 352, 640, 128)
       @description = ' '
       self.contents = Bitmap.new(width - 32, height - 32)
     end
    
     def refresh
       self.contents.clear
       self.contents.draw_text(0, 0, width - 32, 32, @description)
     end
   end


Instructions

Instructions are in the script


Compatibility

100% compatible with the SDK (or so it seems)

100% compatible with Ccoa's UMS

100% compatible with the BlizzABS

Should be 100% compatible with most scripts.

Credits and Thanks
  • *Blizzard for all his help. Without him, I couldn't have made it. Notonly did he help me fix the errors, he also gave me lectures on variousaspects of programming. This caused me to make LESS errors, and growin my programming skill. Thanks blizz, this script wouldn't be heretoday if you hadn't been there in that MIRC room, XD*GubiD for when blizzard wasn't around in MIRC to answer my questions.he helped me with a few errors that I had no idea how to fix (many ofthem were some of the most n00bish errors too -_-). Thanks GubiDcouldn't have done it without ya!*Sephirothtds for making TDS Class Change System incompatible withthe Blizz-ABS. If you'd made it compatible, I would have gone with yourscript, and never figured out how to make one myself (a much easier toconfigure one at that). Your script's incompatibility sparked my urge tolearn to scrip. Thanks.*Juan, who offered a few pointers.*To all those who put up with me in the CP chat room when I'm rantingabout my newest error.*To all the members of eminweb.com for nagging me enough to do myadministrative duty, which eventually cured me of my infamous laziness*StarrodKirby86 for requesting the class graphic system, it made thisscript have a feature not many class changing systems have.


Author's Notes

I'm working on adding a few more features. Please give me some suggestions!
}


Possibly Related Threads…
Thread Author Replies Views Last Post
  Unique Class Commands vinardo 0 2,877 07-17-2008, 01:00 PM
Last Post: vinardo
  Dragon Quest VII Class Changing System Sephirothtds 0 2,760 11-15-2007, 01:00 PM
Last Post: Sephirothtds
  Class Stat Bonus System Shinami 0 2,544 05-20-2007, 01:00 PM
Last Post: Shinami
  An easier WORKING party change script The Ghost 0 2,493 07-09-2006, 01:00 PM
Last Post: The Ghost
  Party & Class SephirothSpawn 0 2,583 11-30-2005, 01:00 PM
Last Post: SephirothSpawn



Users browsing this thread: 2 Guest(s)