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.
New Element Rates, Changes the stacking of elemental values on multiple element attacks.
Introduction Personally, the default stacking on the element system is one of the base features of the game I find particularly annoying. I mean, it just takes the most effecitve element and uses that one. What kind of system is that? The original script (now called 'unique' mode) was originally requested by Hesufo. Even after creating this script, it felt like a little something was missing. I have since expanded the script to include four different ways you can stack your elements - Unique, True Average, Multiplicative, or Advanced.
Features - four modes to choose from, three which require almost no changes - all modes no longer have you RESIST (from armor or state) something that you were going to ABSORB anyway - A fourth 'advanced' mode, featuring six subsets of elements with different properties
How to Use This is a new system designed to replace the default. As such, it should be copied above main and all other custom scripts and below defaults. Detailed instructions are in the script itself.
Script
Spoiler:
CODE
#<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>< #- Element Rates v 2.0 by Mithran (last update December 14, 2008) #- "Unique" mode concept by Hesufo #- This is a complete rewrite of the default so-called element system #- that comes stock with RPG Maker VX #- #- Usage: Contains four 'modes' #- Each mode calculates element stacking differently #- Simply set change the number after SYSTEM_TYPE = #- In the customization section to use that mode #- Modes 1 through 3 require no additional work #- Explanation of the modes in the customization section #- SYSTEM_TYPE = 1 #- Mode 1 uses a unique and fairly balanced system to combine all elements #- SYSTEM_TYPE = 2 #- Mode 2 averages every element in the attack (yeah, just an average of them) #- SYSTEM_TYPE = 3 #- Mode 3 uses multiplicative stacking (every element rate is multiplied) #- More info and examples in the customization section #- #- #- Usage - Mode 4 *Advanced Mode* - Requires some setup #- Instructions are in the customization section #- #- #- #- Install: Insert above Main and all other custom scripts #<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><
module Mithran module ElementRates SYSTEM_TYPE = 4 ## Set the system type variable to use the different systems included in the #~ script ## 0 - RPGVX Standard Mode ## 1 - Unique Mode #~ Default element rate is 100 (100% damage) #~ -- #~ each element rate that is above 100 is added to the rate, then subtract #~ 100 #~ -- #~ each element rate that is below 0 (negative) is subtracted by 100 and #~ added to the calculation #~ -- #~ if the result of this calculation is negative, it cannot be bigger #~ (lower) than the value of highest negative element #~ -- #~ if the result so far is negative, it is not reduced further by mixing #~ in elements between 0 and 100 #~ -- #~ apply a weighted avarage for the rates between 0 and 100 #~ -- #~ example: Slash is 50% effective and Fire is 200% effective. #~ Using fire slash would result in 125% damage. #~ -- #~ example 2: slash is 200% effective and fire is 200% effective. #~ Using fire slash would result in 300% damage. #~ -- #~ example 3: slash is 150% effective, fire is 150% effective, #~ and wind is 0% effective. A combination of the three elements would #~ deal 133% damage (weighted average) #~ -- #~ example 4: wind and fire are both -100% rate (F). A wind/fire attack #~ would be 100% absorbed. #~ -- ## 2 - True Average Mode #~ the rate of every element is avaraged #~ example: Fire is 50% effecitve (D) and ice is 150% effective (B). #~ Using a fire/ice attack would result in 100% damage #~ -- #~ example 2: Fire is 100% effective (C) and ice is -100% effective (F). #~ Using a fire/ice attack would result in no damage #~ -- #~ example 3: Fire is 0% effective (E) and ice is -100% effective. #~ Using a fire/ice attack would result in 50% damage absorbed #~ -- ## 3 - Multiplicative Mode #~ the rate of every positive and zero element is multiplied together as a #~ percentage value #~ #~ the rate of the first negative (absorbed) element, if any, sets the #~ base negative rate #~ #~ the rate of every other every negative (absorbed) element is subtracted #~ by 100 and multiplied together, with the result set to negative #~ #~ example 1: Fire is 50% effective and ice is 150% effective. #~ Using a fire/ice attack would result in 75% damage #~ #~ example 2: Fire is 50% effective and ice is 100% absorbed. #~ Using a fire/ice attack would absorb 50% damage #~ #~ example 3: Fire is 200% effective and ice is 200% effective. #~ Using a fire/ice attack would result in 400% damage #~ #~ example 4: Fire is 200% effective, ice is 200% effective, wind is 100% #~ absorbed, earth is 100% absorbed, darkness is 100% absorbed #~ An attack with all five of these elements would do zero damage #~ ## 4 - Advanced Mode #~ See Below #==============================================================================# # * ADVANCED MODE SETTINGS* # #==============================================================================#
## Six element categories follow here. The numbers in each one coorespond ## to the element IDs in the database. To add a number, type within the ## brackes and be sure to seperate each number with a comma WEAPON_ELEMENTS = [ 1, 2, 3, 4, 5, 6 ] #~ Weapon type elements. The MOST EFFECTIVE RATE will be taken for each #~ set with the rest ignored for the final formula. PHYSICAL_ELEMENTS = [17] #~ the element for all physical attack (more than one may be defined, but #~ not necessary) #~ if more than one is assigned, they will be averaged using the true #~ average formula for the final calculation MAGICAL_ELEMENTS = [18] #~ the element for all magical attack (more than one may be defined, but #~ not necessary) #~ if more than one is assigned, they will be averaged using the true #~ average formula for the final calculation BANE_ELEMENTS = [19, 20, 21, 22] # uses the BANE system #~ Banes use their own rate definitions (see below). Bane elements are #~ intended to work with body types. #~ #~ To set a bodytype on an enemy, simply type <bodytype n> in the note #~ section, where n is the number ID of the associated bane element. #~ #~ Multiple bodytypes can be set for each enemy. Only the MOST EFFECTIVE #~ bane value will be use. #~ #~ Any state that resists a bane element will make the rate (of the bane #~ in question only) equal 100 INDIVIDUAL_ELEMENTS = [23, 24] #~ These elements are mixed using the Multiplicative Mode formula. #~ #~ They also use their own rate set (See below). As such, if you wanted #~ someone to be immune to an attack with any of these elements mixed in #~ them at all, you would set their effectivness of this value to F. #~ #~ By default are NO absorb values for indiviudal elements letter values #~ #~ If a state or equipment resists an indiviudal element, its letter value #~ is increased by 1, (A becomes B, B becomes C, etc.) rather than halving #~ its current rate like the default system #~ #~ The intended usage is for things like a "Gravity" element (for, say, #~ KGC_RateDamage) that you want bosses to be immune to. #~ #~ This allows you to mix these attacks that would otherwise be overpowered #~ with other elements. It also allows multiplicative stacking within the #~ system. #~ #~ Example: Static Field (gravity + lightning), enemy is C vs lightning #~ and F vs gravity, damage will be nullified ## ELEMENTAL_ELEMENTS (or normal elements) #~ Elemental elements set, or the normal element set, is any element not #~ already defined above. Elements in this category are combined using #~ the True Average formula for the final calculation ## THE FINAL FORMULA #~ The six element subsets are resolved as indicated above #~ Any empty subset has a value of 100 #~ If any of the subsets are negative, use the best absorbtion rate in the subsets as the final result #~ If not, the final result is a product of all six subsets as percentages
# Editing the following values is intended only for advanced users. # I figure, if you read this far, you hopefully know what you are doing, # so have at it :) ElementValues = [ # normal element definitions 0, # null value, not used in game 200, # value of A element efficency 150, # value of B element efficency 100, # value of C element efficency 50, # value of D element efficency 0, # value of E element efficency -100 ]# value of F element efficency
BaneValues = [ # "Bane" elements definitons 0, # null value, not used in game 400, # value of A element efficency 300, # value of B element efficency 250, # value of C element efficency 200, # value of D element efficency 150, # value of E element efficency 100 ] # value of F element efficency
IndividualValues = [ # 0, # null value, not used in game 200, # value of A element efficency 150, # value of B element efficency 100, # value of C element efficency 50, # value of D element efficency 25, # value of E element efficency 0 ] # value of F element efficency end end
#==============================================================================# # * End Customization * # #==============================================================================#
class RPG::BaseItem def bodytype get_item_bodytype if @bodytype == nil return @bodytype end def get_item_bodytype @bodytype = 0 self.note.gsub(/<bodytype (\d+)>/i, "") @bodytype = $1.to_i end end
class Game_Actor < Game_Battler alias element_rate_orig_mith element_rate def element_rate(element_id) case Mithran::ElementRates::SYSTEM_TYPE when 1, 2, 3 return element_rate_standard(element_id) when 4 return element_rate_advanced(element_id) else return element_rate_orig_mith(element_id) end end
def bodytypes result = [] for equip in equips.compact result.push(equip.bodytype) unless equip.bodytype == 0 end return result end
def element_rate_standard(element_id) rank = self.class.element_ranks[element_id] result = Mithran::ElementRates::ElementValues[rank] return result if result < 0 # the only difference between standard and the default method # is that states or armors that resist an element will NOT affect it if it is already negative for armor in armors.compact result /= 2 if armor.element_set.include?(element_id) end for state in states result /= 2 if state.element_set.include?(element_id) end return result end
def element_rate_advanced(element_id) case element_type(element_id) when 'bane' return element_rate_bane(element_id) when 'individual' return element_rate_individual(element_id) else return element_rate_standard(element_id) end end
def element_rate_bane(element_id) return 100 unless self.bodytypes.include?(element_id) # bane rates will only be applied if the bodytype matches rank = self.class.element_ranks[element_id] result = Mithran::ElementRates::BaneValues[rank] for armor in armors.compact return 100 if armor.element_set.include?(element_id) # resisting a bane nullifies it in the equation end for state in states.compact return 100 if state.element_set.include?(element_id) # resisting a bane nullifies it in the equation end return result end
def element_rate_individual(element_id) rank = self.class.element_ranks[element_id] for armor in armors.compact rank += 1 if armor.element_set.include?(element_id) end for state in states rank += 1 if state.element_set.include?(element_id) end rank = 6 if rank > 6 result = Mithran::ElementRates::IndividualValues[rank] end
end
class Game_Enemy < Game_Battler alias element_rate_orig_mith element_rate def element_rate(element_id) case Mithran::ElementRates::SYSTEM_TYPE when 1, 2, 3 return element_rate_standard(element_id) when 4 return element_rate_advanced(element_id) else return element_rate_orig_mith(element_id) end end
def element_rate_standard(element_id) rank = enemy.element_ranks[element_id] result = Mithran::ElementRates::ElementValues[rank] return result if result < 0 for state in states result /= 2 if state.element_set.include?(element_id) end return result end
def element_rate_advanced(element_id) case element_type(element_id) when 'bane' return element_rate_bane(element_id) when 'individual' return element_rate_individual(element_id) else return element_rate_standard(element_id) end end
def element_rate_bane(element_id) return 100 unless self.bodytypes.include?(element_id) # bane rates will only be applied if the bodytype matches rank = enemy.element_ranks[element_id] result = Mithran::ElementRates::BaneValues[rank] for state in states.compact return 100 if state.element_set.include?(element_id) # resisting a bane nullifies it in the equation end return result end
def bodytypes make_enemy_bodytypes if @bodytypes == nil return @bodytypes end
def make_enemy_bodytypes @bodytypes = [] text = enemy.note text.split(/[\r\n]+/).each { |line| if line =~ /<bodytype (\d+)>/i @bodytypes.push($1.to_i) end } end
def element_rate_individual(element_id) rank = enemy.element_ranks[element_id] for state in states rank += 1 if state.element_set.include?(element_id) end rank = 6 if rank > 6 result = Mithran::ElementRates::IndividualValues[rank] end end
class Game_Battler #-------------------------------------------------------------------------- # * Get Maximum Elemental Adjustment Amount # element_set : Elemental alignment # Returns the most effective adjustment of all elemental alignments. #-------------------------------------------------------------------------- alias elements_max_rate_orig_mith elements_max_rate def elements_max_rate(element_set) case Mithran::ElementRates::SYSTEM_TYPE when 1 return elements_max_rate_unique(element_set) when 2 return elements_max_rate_trueavg(element_set) when 3 return elements_max_rate_multiplicative(element_set) when 4 return elements_max_rate_sysadvanced(element_set) else return elements_max_rate_orig_mith(element_set) end end
def elements_max_rate_unique(element_set) return 100 if element_set.empty? current_rate = 100 element_rates = [] # array of the rate of all the elements increaser_rates = [] # array of rates which will add decreaser_rates = [] # array of rates that will divide negative_rates = [] # array of rates that will subtract element_set.each { |n| element_rates.push(element_rate(n)) # gets element rates and put them in an array } for er in element_rates if er >= 100 # if the rate is bigger than 100 or equal to 100 increaser_rates.push(er) elsif er < 100 and er > 0 # if the rate is between 0 and 100 decreaser_rates.push(er) elsif er < 0 negative_rates.push(er) # if the rate is negative end end for er in increaser_rates current_rate += er - 100 # add all the rates with values greater than 100 and # less than zero together and subtract 100 for each one. end for er in negative_rates current_rate += er - 100 current_rate = [current_rate, negative_rates.min].max # cannot absorb more # than the biggest negative rate end return current_rate if current_rate <= 0 # decreasers wont be applied if absorbing decreaser_value = 0 for er in decreaser_rates decreaser_value += er end current_rate *= increaser_rates.size current_rate += decreaser_value current_rate /= element_set.size return current_rate end
def elements_max_rate_trueavg(element_set) return 100 if element_set.empty? result = 0 element_set.each { |i| result += element_rate(i) } result /= element_set.size return result end
def elements_max_rate_multiplicative(element_set) return 100 if element_set.empty? current_rate = 100 element_rates = [] # array of the rate of all the elements positive_rates = [] # array of positive rates or zero negative_rates = [] # array of negative rates total_negative_rate = 0 element_set.each { |n| element_rates.push(element_rate(n)) # gets element rates and put them in an array } for er in element_rates negative_rates.push(er) if er < 0 positive_rates.push(er) if er >= 0 end negative_rates.each_index { |i| negative_rates[i] -= 100 } for er in negative_rates if total_negative_rate == 0 total_negative_rate = er.abs next end total_negative_rate = total_negative_rate * er / 100 total_negative_rate = total_negative_rate.abs end for er in positive_rates current_rate = current_rate * er / 100 end return (current_rate - total_negative_rate) end
def element_type(element_id) return 'weapon' if Mithran::ElementRates::WEAPON_ELEMENTS.include?(element_id) return 'physical' if Mithran::ElementRates::PHYSICAL_ELEMENTS.include?(element_id) return 'magical' if Mithran::ElementRates::MAGICAL_ELEMENTS.include?(element_id) return 'bane' if Mithran::ElementRates::BANE_ELEMENTS.include?(element_id) return 'individual' if Mithran::ElementRates::INDIVIDUAL_ELEMENTS.include?(element_id) return 'elemental' end
def get_matching_array_elements(array1, array2) result = [] for i in array1 result.push(i) if array2.include?(i) end return result end
end
FAQ Q: I don't understand the forumla! A: For the first three, its pretty much as simple as this: True Average is just an average of all the element rates. Multiplicative is basically the product of the percentage values of all the rates (unless you are stacking mutiple negatives). Unique is a bit more complicated, but it works closer to True Average but allows some upward stacking on positive elements.
Q: I still dont get it... A: Well, try it out. Modes 1 and 2 will generally yeild moderate values. Mode 3's values will vary hugely based on the element set.
Q: Whats all this about advanced modes? A: The instructions are conveniently located in the script in the customization section, along with examples of what each one does.
Q: That is far too much to read, and far far too complicated.. A: If there is something you don't get from the instructions, feel free to post or PM me and I'll try to better explain the feature. If you don't want to bother, that's why I put the alternate 'modes' in the script, which can be activated by typing a single number.
Credit and Thanks - Mithran (the script) - Hesufo (unique mode concept)
Author's Notes Feedback is welcome.
This post has been edited by Mithran: Feb 1 2011, 01:07 AM
Version 2.0 Four modes to choose from: - unique (the original posted script v 1.5b) - True Average (averages all elements in the set together) - Multiplicitive (uses multiplicative stacking) - Advanced Mode
Advanced Mode Features: - Six element subsets - weapon, elemental, physical, magical, bane, and indiviudal, each with their own rules. - Combines the best of Multiplicative and True Average modes, as well as even some of the original
Thanks to Gio and Deadlock for pointing out an error in my script. There is a point in the script where multiplicative is typoed as "multiplicitive". If you don't use multiplicative rates, it wont affect you, and you can correct it with a simple find > multiplicitive and change that one 'i' to an 'a'. The script in the original post has been fixed.