iPhone App Directory
RPG Maker VX
 
Gallery Members Search Calendar Help


Welcome Guest ( Log In | Register )

Collapse

>Announcement

The 2nd Quarter Contest has arrived! Go check it out in the Community Announcements now!
 
Reply to this topicStart new topic
> Actor / Class Attribute Swap (v2.0), Set up stat tables for classes using the Database
Rating 5 V
Mithran
post Jun 16 2009, 07:43 PM
Post #1


Scripter
Group Icon


Type: Coder
Alignment: True Neutral




Actor/Class Attribute Swap v 2.0
by Mithran


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

    
#= = = = = = = = = = = = = = = = = END SETUP = = = = = = = = = = = = = = = = = =

    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
  
  def check_equips_ActorClassSwap
    equips.each_index { |i| change_equip(i, nil) unless equippable?(equips[i]) }
  end
  
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.


--------------------
Go to the top of the page
 
+Quote Post
   
Milky
post Jun 17 2009, 03:19 PM
Post #2



Group Icon


Type: Designer




yeahh baby nice one hehe


--------------------



Go to the top of the page
 
+Quote Post
   
AlphaWhelp
post Jun 19 2009, 04:08 AM
Post #3


You can dance if you want to, you can leave your friends behind.
Group Icon


Type: Coder




Your scripts are incredible. I just don't know how anyone can make a functional VX game without using at least one of your scripts.


--------------------
My Scripts:
Spoiler:
Haste slow States for Tankentai with ATB 1.1c: http://www.rpgmakervx.net/index.php?showtopic=3781 (scroll down to about halfway through the first post and find it under add-ons.)

Old Fashioned Gameovers: http://www.rpgmakervx.net/index.php?showtopic=11819

Comic Book Scenes: http://www.rpgmakervx.net/index.php?showtopic=14072

Force Preemptive or Surprise battles: http://www.rpgmakervx.net/index.php?showtopic=15135
Go to the top of the page
 
+Quote Post
   
Kaimi
post Jul 18 2009, 11:19 AM
Post #4


RPGMakerVX.net's official Seranille lover
Group Icon


Type: Writer
Alignment: Lawful Good




Mithran, it mimics RPG Maker 2003 Class system, with abilities?


--------------------

Thanks to Kaviator for the signature


My resources
Spoiler:
Go to the top of the page
 
+Quote Post
   
Alexander Amnell
post Jun 24 2011, 09:47 PM
Post #5



Group Icon


Type: Writer
Alignment: Unaligned




This is great. Thank you so much, I have been looking for a way to tag Duel wield to an actors class for a while now. Thanks again.


--------------------
The guy who'll try to solve your script request...with an event!


My game project (dev page out, click away!)

Things that are awesome!
Spoiler:








Go to the top of the page
 
+Quote Post
   

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 23rd April 2014 - 09:40 PM

RPGMakerVX.net is an Privacy Policy, Legal.