New threads (complete scripts) here will go into a moderation queue. You will not see your thread appear when you create it. A moderator will decide if it will be approved or denied.
Actor / Class Attribute Swap (v2.0), Set up stat tables for classes using the Database
Introduction Isn't it irritating sometimes how the parameter tables and all those nifty checkbox traits are settable only on indiviudal actors? Or how things like equipment usability or skills cant be assigned to individual actors? This script allows most attributes normally associated with an actor's class to be assicated with the actor's.. actor, and/or allows most attributes normally assignable to the actor's actor to be assigned to the class instead. Basically, all that stuff in the database you can set on the "Actors" page only can now associated with a specific class, and vice versa.
Features - Set up class attributes to be looked up from an actor's 'linked' class data - Set up actor attributes to be looked up from an actor's 'linked' actor data - Any class or actor attribute can be turned off, so the data swap no longer occurs - In addition to or instead of the above, add extra equippables or skill learnings to an actor
How to Use Install on its own script page in the materials section of the script editor above main and below default scripts. Follow the instructions in the setup section in the script.
Script
Spoiler:
CODE
# Actor / Class Attribute Swap v 2.0 # by Mithran # Last Update June 15, 2009 # Please do not redistribute without asking!
# This script allows the user to associate data normally assigned to an actor's # class to the actor's 'actor' object, and/or associate data normally assigned # to the character's actor to the character's class.
# If a class is not associated with an actor ID, or an actor is not associated # with a class ID, the default data will be used.
module Mithran module ActorClassSwap # = = = = = = = = = = = = = = = = = MAIN SETUP = = = = = = = = = = = = = = = = = DATA_ACTORS_METHODS = [ # Do not alter this line! #~ This section defines all the methods normally belonging to actors that #~ you want to put on a class instead. If you do not want a certain #~ attribute to carry over, simply comment out the line by adding a # to the #~ front #~ Delete the # at the beginning of the line to reenable it. Do NOT delete #~ the #~ at the beginning of the explanation lines #~ Each setting is encased in double quotes and followed by a comma
# "exp_basis", "exp_inflation",
#~ The exp list is built off the above two methods. Exp list is built ONLY #~ at character creation under normal circumstances. If you like, you can #~ still use exp lists with this setting. The code that builds a new exp #~ list is found in my Class Based Exp script, so I won't duplicate it here.
"parameters", #~ The actor's parameter table. This includes all parameters, such as #~ atk, agi, spi, def, maxhp, and maxmp
"two_swords_style", #~ The two swords style setting. If you link this to a class, and the class #~ change results in a weapon or shield not being able to be used, it will #~ automatically be unequipped.
#~ If the database two_swords_style does of an actor does not match #~ the two swords style of the linked class, the weapon (or shield) will be #~ automatically converted to its armor_id (or weapon_id) counterpart #~ on character creation
# "fix_equipment", #~ The fixed equipment setting, which means equipment cannot be changed.
# "auto_battle", #~ Auto battle, the character is not controllable and will automatically #~ choose actions.
"super_guard", #~ Super Guard - Guard reduces damage by 3/4 instead of 1/2.
"pharmacology", #~ Double HP and MP effects of items.
"critical_bonus", #~ A four point boost to the 'cri' attribute.
] #~ Do not delete this line!
DATA_CLASSES_METHODS = [ #~ Do not alter this line! #~ This section defines all the methods normally belonging to classes that #~ you want to associate with a class instead. If you do not want a certain #~ attribute to carry over, simply comment out the line by adding a # to the #~ front #~ Delete the # at the beginning of the line to reenable it. Do NOT delete #~ the #~ at the beginning of the explanation lines
# "position", #~ The position (front/back/rear) that determines the Class' base odds
# "weapon_set", #~ The weapons usable by the class
# "armor_set", #~ The armor usable by the class
#~ If you alter the weapon or armor set of the actors, the database will not #~ recognize them. You can use the event command #~ alter_equip(actor_id, equipment_slot, new_id) #~ where actor_id is the id of the actor you want to change #~ equipment_slot is the index of the slot the item is in #~ 0 for weapons, count up as you go down #~ and new_id is the id of the item you want to equip (must be in inventory) #~ There is no secondary check to make sure the item is going in the correct #~ slot (for compatablity with scripts such as KGC EquipExtension) #~ so be sure you have the ids correct
# "element_ranks", #~ Element Ranks, the letter values of how efficent elements are on the class
# "state_ranks", #~ State Ranks, the letter values of how efficent states are on the class
# "learnings", #~ Skill Learnings, skills learned on level up
] #~ Do not delete this line!
CLASS_TO_ACTOR_LINKS = { #~ Do not alter this line. #~ class_id => actor_id, #~ The class on the left will inherit the attributes, specificed above, of a #~ the linked actor's data. #~ Example: 2 => 1, #~ Any Warrior will use the values normaly assigned to Ralph #~ (Ralph's paramter tables and checkbox attributes will be used on any actor #~ of the warrior class) 1 => 1, 3 => 1, 4 => 1, 6 => 1, 5 => 1, 7 => 1, 8 => 1, #~ RTP Party, links all classes to Ralph! (Demonstration purposes only, this #~ is not recommended) As you can see, you do not need to put them in order #~ and more than one class can link to an actor
#~ You may change or delete the above
#~ Add more above here. } #~ Do not alter this line
ACTOR_TO_CLASS_LINKS = { #~ Do not alter this line. #~ actor_id => class_id, #~ The actor will inherit the attributes, specififed above, of the linked #~ class' data. #~ Example: 1 => 4, #~ Ralph will use the attributes normally assigned to the Magician class #~ (Magician will permanently govern Ralph's skill gains, state efficencies, #~ element efficencies, 'row', etc, if they are uncommented above) #~ You may change or delete the above
#~ Add more pairings before here } #~ Do not alter this line
CLASS_TO_ACTOR_LINKS.default = 0 # Do not change this line. ACTOR_TO_CLASS_LINKS.default = 0 # Do not change this line. #~ sets the default values to zero, so they will return a nil object on lookup
CLASS_OVERRIDE = Hash.new{ |hash, key| hash[key] = Hash.new } # Do not change this line. #~ In the following section, you can manually set any values normally #~ assigned to an actor without using links #~ These values will take precedence over the linked values above. #~ Format is #~ CLASS_OVERRIDE[class_id]["method_name"] = value #~ This only works on the 'check box' style attributes of the actor setup #~ This is an advanced setting and it is recommended that you use the links #~ provided above instead if you are unsure how to use this. #~ Example: CLASS_OVERRIDE[2]["two_swords_style"] = true #~ Warrior now has two swords style.
EXTRA_ACTOR_WEAPONS = Hash.new{ |hash, key| hash[key] = Array.new }# Do not alter this line! #~ Below here, add additional weapon ids to be used by actors in the following #~ format: #~ EXTRA_ACTOR_WEAPONS[actor_id] = [weapon_id1, weapon_id2, .. weapon_id] #~ Example: EXTRA_ACTOR_WEAPONS[4] = [3, 4] #~ Ylva can use longspear and longbow, regardless of his class. #~ Use the crossover weapons setting below to set up weapons that can only be #~ used if BOTH actor and class can use them. EXTRA_ACTOR_ARMORS = Hash.new{ |hash, key| hash[key] = Array.new } # Do not alter this line! #~ Below here, add additional weapon ids to be used by actors in the following #~ format: #~ EXTRA_ACTOR_ARMORS[actor_id] = [armor_id1, armor_id2, .. armor_id] #~ Example: EXTRA_ACTOR_ARMORS[4] = [1, 2] #~ Ylva will be able to use the Scale Shield and Leather Shield. #~ Use the crossover armors setting below to set up weapons that can only be #~ used if BOTH actor and class can use them. EXTRA_ACTOR_LEARNINGS = Hash.new{ |hash, key| hash[key] = Array.new } # Do not alter this line! #~ Below this line, add extra skill learnings to specific actors. Format is: #~ EXTRA_ACTOR_LEARNINGS[actor_id] = [ [skill_id, level], [skill_id2, level], ... ] #~ Example: EXTRA_ACTOR_LEARNINGS[4] = [ [57, 5], [58, 10] ] #~ Ylva will learn life drain at level 5 and mana drain at level 10.
REQ_BOTH_WEAPONS = [] #~ In the brackets, place the weapon ids of any weapon you want to require #~ both the actor and class to be able to use. #~ Said weapons will need to be present in the EXTRA_ACTOR_WEAPONS section #~ above to be usable by the actor, and also need to be usable by the class #~ (or the class linked to the actor data object) #~ Example: #~ REQ_BOTH_WEAPONS = [1, 2] #~ Longsword and Club will only be useable if both the parent actor and class #~ can use them. REQ_BOTH_ARMORS = [] #~ Same as REQ_BOTH_WEAPONS, but with armors.
REQ_BOTH_SKILLS = [] #~ Same as weapons and armor, but for skills. #~ Each skill id in the brackets will require both the actor and class to be #~ able to learn them in order to learn them. #~ The actor will learn the skill by whatever level is lower of the two
DATA_EVAL = " if method_defined?(:method_name) && !method_defined?(:method_name_ActorClassCrossAlias) alias :method_name_ActorClassCrossAlias :method_name def method_name(*args) data = nil paired_actor_id = 0 paired_class_id = 0 if $game_temp.acc_class_id != nil paired_actor_id = Mithran::ActorClassSwap::CLASS_TO_ACTOR_LINKS[$game_temp.acc_class_id] end if $game_temp.acc_actor_id != nil paired_class_id = Mithran::ActorClassSwap::ACTOR_TO_CLASS_LINKS[$game_temp.acc_actor_id] end paired_actor_obj = $data_actors[paired_actor_id] paired_class_obj = $data_classes[paired_class_id] if self.is_a?(RPG::Class) && paired_class_obj data = paired_class_obj.method_name_ActorClassCrossAlias(*args) elsif self.is_a?(RPG::Actor) && paired_actor_obj data = paired_actor_obj.method_name_ActorClassCrossAlias(*args) else data = method_name_ActorClassCrossAlias(*args) end if (data == true or data == false) && self.is_a?(RPG::Actor) test = Mithran::ActorClassSwap::CLASS_OVERRIDE[$game_temp.acc_class_id]['method_name'] data = test unless test.nil? end if 'method_name' == 'weapon_set' && self.is_a?(RPG::Class) old_data = data.clone test = Mithran::ActorClassSwap::EXTRA_ACTOR_WEAPONS[$game_temp.acc_actor_id] data |= test for item in Mithran::ActorClassSwap::REQ_BOTH_WEAPONS data -= [item] unless old_data.include?(item) && test.include?(item) end elsif 'method_name' == 'armor_set' && self.is_a?(RPG::Class) old_data = data.clone test = Mithran::ActorClassSwap::EXTRA_ACTOR_ARMORS[$game_temp.acc_actor_id] data |= test for item in Mithran::ActorClassSwap::REQ_BOTH_ARMORS data -= [item] unless old_data.include?(item) && test.include?(item) end elsif 'method_name' == 'learnings' && self.is_a?(RPG::Class) old_data = data.clone ary = Mithran::ActorClassSwap::EXTRA_ACTOR_LEARNINGS[$game_temp.acc_actor_id] test = [] for set in ary learning = RPG::Class::Learning.new learning.skill_id = set[0] learning.level = set[1] test.push(learning) end data |= test for learning in data.clone next unless Mithran::ActorClassSwap::REQ_BOTH_SKILLS.include?(learning.skill_id) data.delete(learning) unless old_data.has_skill_id?(learning.skill_id) && test.has_skill_id?(learning.skill_id) end end return data end end "
# Above - # A simple redirect wrapper for several methods in RPG::Actor or RPG::Class # method_name will be subsituted with the actual method name. # Uses some method-specific coding, but mostly it is a wrapper that will # work for any method.
GAME_HOOK_EVAL = " if method_defined?(:method_name) && !method_defined?(:method_name_ActorClassCrossAlias) alias :method_name_ActorClassCrossAlias :method_name def method_name(*args) if $game_temp != nil $game_temp.acc_class_id = self.class_id $game_temp.acc_actor_id = self.id end return method_name_ActorClassCrossAlias(*args) end end " # Above- # A wrapper for Game_Actor that saves on the actor and class id of the # referencing actor into an instance variable in $game_temp so it can be # read by the referenced data object, without altering the method call
GAME_HOOKS = [ "class", "actor" ] # Methods in Game_Actor that should be wrapped
module_function # Below - iterators that build the actual code to be evaluated out of the # above arrays # These are not actually evaluated until the database is loaded
def self.data_classes_methods result = [] for method_name in DATA_CLASSES_METHODS data = DATA_EVAL.clone data.gsub!("method_name", method_name.downcase) result.push(data) end return result end
def self.data_actors_methods result = [] for method_name in DATA_ACTORS_METHODS data = DATA_EVAL.clone data.gsub!("method_name", method_name.downcase) result.push(data) end return result end
def self.game_hook_methods result = [] for method_name in GAME_HOOKS data = GAME_HOOK_EVAL.clone data.gsub!("method_name", method_name.downcase) result.push(data) end return result end
end end
class Scene_Title alias load_database_ActorClassSwapAlias load_database def load_database load_database_ActorClassSwapAlias evaluate_ActorClassSwap end
alias load_bt_database_ActorClassSwapAlias load_bt_database def load_bt_database load_bt_database_ActorClassSwapAlias evaluate_ActorClassSwap end
def evaluate_ActorClassSwap # Adds the method wrappers to the methods in their respective classes for meth in Mithran::ActorClassSwap.data_actors_methods RPG::Actor.module_eval(meth) end for meth in Mithran::ActorClassSwap.data_classes_methods RPG::Class.module_eval(meth) end for meth in Mithran::ActorClassSwap.game_hook_methods Game_Actor.module_eval(meth) end end end
class Game_Temp attr_accessor (:acc_class_id, :acc_actor_id) end
class Game_Actor alias class_id_ActorClassSwap= class_id= def class_id=(new_class_id) @temp_lock_two_swords_class_swap = self.two_swords_style self.class_id_ActorClassSwap=(new_class_id) two_swords_test @temp_lock_two_swords_class_swap = nil end
def two_swords_test return unless two_swords_style_ActorClassSwap != @temp_lock_two_swords_class_swap # do nothing unless the two_swords_style parameter has changed if $imported["EquipExtension"] # If using KGC EquipExtension self.equip_type.each_index { |i| change_equip(i + 1, nil) if equip_type[i] == 0 # unequip the item if it is in a shield slot # this prevents items from being 'transformed' when two swords style changes } else change_equip(1, nil) end end
alias two_swords_style_ActorClassSwap two_swords_style def two_swords_style # cuts the method short if the temporary variable, # @temp_lock_two_swords_class_swap, is not nil, returning this instead return @temp_lock_two_swords_class_swap unless @temp_lock_two_swords_class_swap.nil? return two_swords_style_ActorClassSwap end
alias setup_ActorClassSwap setup def setup(*args) setup_ActorClassSwap(*args) # make sure items are equippable after character creation check_equips_ActorClassSwap end
module EnuAddSkillID # A module that adds an additional iterator function to 'array' that checks # the skill_id of each learning in the array, only if it is a RPG::Learning def has_skill_id?(skill_id) for obj in self next unless obj.is_a?(RPG::Class::Learning) return true if obj.skill_id == skill_id end return false end end
class Array include EnuAddSkillID unless method_defined?( :has_skill_id? ) end
class Game_Interpreter def alter_equip(actor_id, equip_slot, new_id = 0) actor = $game_actors[actor_id] return if actor.nil? actor.change_equip_by_id(equip_slot, new_id) end end
How It Works The core of this script is driven by a wrapper for all relevant methods. Each time an actor or class data object is looked up, the ids of the actor and class referencing it are passed into a global variable. If the actor has a valid class link, whenever the specificed class-specific data is looked up, it is instead pulled from the linked class. If the class has a valid actor link, whenever the specified actor-specific data is looked up, it is instead pulled from the linked class. Nothing is overwritted and very little data is altered (only for extra actor equipment, extra actor learnings, and require both), it is simply looked up from a new location.
FAQ q. Why can't I just directly assign values myself instead of all this class linking nonsense? a. I believed this way would be easier because a direct overwrite would require much more knowledge on the part of the user (you), to the point where you would pretty much be able to script what you needed yourself. I included limited functions for this in the script, but only for actor 'check box' attributes. The main intent to this script was to get parameter tables on classes using the normal database interface, which I believe is successful.
q. Nothing is transferring from my actor to class links! a. Actor to class links (putting class attributes on an actor) are disabled by default becuase I figured this would be a less used feature. You have to uncomment the lines in the setup section that deal with each specific attribute you want to swap over. The lines that should be uncommented are the ones beginning with a # all the way on the left hand side, followed by a quoted section, then a comma. Remove that #. Explanation notes underneath each commented section should NOT be uncommented.
q. Some scripter made xx attribute based off my actor, can you make it off my class instead? a. If they actually stored it on the data object, it would be a simple matter of adding the method name that needs to be swapped to the correct array, encased in "" quotes and followed by a comma. Most scripters, however, just inject the data directly into the Game_Actor object and use an if or case statement to look up the data. I built this to be expandable, so I'd be interested to know what worked and what didn't. This should be compatable with both KGC Limitbreak and Enelvon's resistance script, so long as this script is placed below both.
Credit and Thanks - Mithran
Author's Notes Please do not redistribute without asking. I'm hoping this script isn't hard to understand, so I would appreciate some feedback.