=begin ================================================================================ CrimsonSeas Ultimate series; Ultimate Algorithm by CrimsonSeas ================================================================================ Introduction: This script is the first one I made in the CSU series. This section deals with custom damage formulas. I made this to help people making custom damage formulas for weapons, skills, items, enemies, and unarmed actors. Note that this script still requires some scripting knowledge to use, therefore this isn't noob friendly. However, this script does help you make custom damage formulas for skills, weapons, etc by providing one section that deals with all custom damages if you had enough knowledge. -------------------------------------------------------------------------------- Features: -Write custom damage formula as a String, which will be converted into a script to calculate damage properly. As a string, you can just write off any formula that comes into mind. -Give each weapons, skills, items, enemies, and even your unarmed attacks a custom damage formula. -Preset formula, to quickly assign one formula to many skills/items/weapons. -Expands skills properties; adds Defense Factor and Agility Factor that can be set via the skills/items note field -Expands criticals; give each weapons, skills, items, enemies, and even your unarmed attack a unique critical rate and critical multiplier. This can be set via the note field(except the unarmed actor attack since actors doesn't have note field; this is configured in the script below.) ================================================================================ ================================================================================ HOW TO USE ================================================================================ -------------------------------------------------------------------------------- Note Tags -------------------------------------------------------------------------------- : assigns critical rate to skills, items, weapons, or enemies : assigns critical multiplier to skills, items, weapons,or enemies. : assigns a preset damage formula to skills, items, weapons, or enemies. : assigns a base damage value, useful if you want it to exceed 9999 (skills and items only) Can be negative. , : assigns an Attack Factor or Spirit Factor value, useful if you want it to exceed 200(skills and items only) Must be positive. , : assigns a Defense Factor or Agility Factor value, just like how atk_f and spi_f works. (skills and items only) Must be positive. : damage penetrates guard. For enemies, weapons, skills, and items. : critical will still happen even if the target is preventing criticals. For enemies, weapons, skills, and items. : Sets variance value for a weapon/enemy. Must be positive. You may configure your damage formula below. This tag also configures your default critical rates, multipliers and preset formulas. -------------------------------------------------------------------------------- How to Write Formula: -------------------------------------------------------------------------------- This is how you write your custom damage formulas. To get values to use in damage calculating from the target and the attacker, write in this format: Object.Value Object = the object that you want to get the value from(can be actors, skills, or items.) Stat = value to be read from the Object Example: attacker.atk, self.def, user.spi, obj.atk_f etc. Use this legend below to determine what to write as Object and as Stat. --------------|----------------------------------------------------------------- Object name |What this object refers to --------------|----------------------------------------------------------------- user |User of an attack or skill or item self |Target of the attack/skill/item. obj |Skill or Item to be used (only use in skill and item damage; don't |use for weapon damage.) --------------|----------------------------------------------------------------- *note that you don't use attacker as an object anymore, use user for all formulas including the attack formulas. ------------|-----------------------|------------------------------------------- Stat Name |Applies to what Object |What this Stat refers to ------------|-----------------------|------------------------------------------- atk |user, self |Attack value of the Object def |user, self |Defense value of the Object agi |user, self |Agility value of the Object spi |user, self |Spirit value of the Object hp |user, self |Remaining HP of the Object mp |user, self |Remaining MP of the Object maxhp |user, self |Max HP of the Object maxmp |user, self |Max MP of the Object hit |user, self |Hit value of the Object eva |user, self |Evasion value of the Object level |user, self |Level of the Object. Will automatically be | |treated as 1 if the Object is an enemy base_damage |obj |Base damage of the skill/item. atk_f |obj |Attack Factor of the skill/item spi_f |obj |Spirit Factor of the skill/item agi_f |obj |Agility Factor of the skill/item (Customized | |via the skill/item's note field) def_f |obj |Defense Factor of the skill/item (Customized | |via the skill/item's note field) ------------|------------------------------------------------------------------- You can also use variables stored in the event editor to calculate damage. Just write this: $game_variables[ID] to get the value stored inside that variable ID Mathematical Operators used in writng a formula: ----------------|--------------------------------------------------------------- Operator |What it does ----------------|--------------------------------------------------------------- x + y |Adds x with y x - y |Substracts y from x x * y |Multiplies x with y x / y |Divides x by y x % y |Returns the remainder of x divided by y x ** y |Returns x to the power of y Math.exp(x) |Return the exponential function of x Math.sqrt(x) |Returns the square root of x rand(x) |Returns a random value from 0 to x-1 .to_f |Changes the value into a floating point value .to_i |Changes the value into an integer value ----------------|--------------------------------------------------------------- It is suggested to change any divider into a floating point value to deliver the most accurate damage calculation. See example for details. How to write a formula: Write it as a string using the quote marks like this: "damage = user.atk - self.def" That is the default normal attack formula. Or you can make it like this: "damage = user.atk ** 2 * (999 - self.def) /(999.0 * 16)" See how I used 999.0 instead of 999? This is to make it floating point value in order to deliver the most accurate damage calculation. Another example: "damage = user.atk * (user.atk + user.atk / self.def.to_f) damage *= $game_variables[5]" Here I used .to_f to change the defense value into a floating point. This formula also multiplies damage by the value of Variable ID 5. You can even write it like this: "damage = obj.base_damage if damage > 0 damage += user.atk * 4 * obj.atk_f / 100 damage += user.spi * 2 * obj.spi_f / 100 unless obj.ignore_defense damage -= self.def * 2 * obj.atk_f / 100 damage -= self.spi * 1 * obj.spi_f / 100 end damage = 0 if damage < 0 elsif damage < 0 damage -= user.atk * 4 * obj.atk_f / 100 damage -= user.spi * 2 * obj.spi_f / 100 end" This is the default skill/item damage calculation. You can do many default programming syntax here. Remember that whatever value is stored in damage variable will be the base damage before variance, elements, critical etc comes to play. You can make it anything you like as long as it follows the rules above. ================================================================================ ================================================================================ Module Configuration ================================================================================ =end module CSU module Damage #This is the default damage formula for armed normal attack. DEFAULT_WEAPON_DAMAGE = "damage = user.atk * 4 - self.def * 2" #This is the default damage formula for unarmed attack. DEFAULT_UNARMED_DAMAGE = "damage = (user.atk + user.agi) * 2 - self.def * 1.5" #This is the default enemy damage formula DEFAULT_ENEMY_DAMAGE = "damage = user.atk * 4 - self.def * 2" #This is the default damage for formula for skills. DEFAULT_SKILL_DAMAGE = "damage = obj.base_damage if damage > 0 damage += user.atk * 4 * obj.atk_f / 100 damage += user.spi * 2 * obj.spi_f / 100 unless obj.ignore_defense damage -= self.def * 2 * obj.atk_f / 100 damage -= self.spi * 1 * obj.spi_f / 100 end damage = 0 if damage < 0 elsif damage < 0 damage -= user.atk * 4 * obj.atk_f / 100 damage -= user.spi * 2 * obj.spi_f / 100 end" #This is the default damage formula for items. DEFAULT_ITEM_DAMAGE = "damage = obj.base_damage if damage > 0 damage += user.atk * 4 * obj.atk_f / 100 damage += user.spi * 2 * obj.spi_f / 100 unless obj.ignore_defense damage -= self.def * 2 * obj.atk_f / 100 damage -= self.spi * 1 * obj.spi_f / 100 end damage = 0 if damage < 0 elsif damage < 0 damage -= user.atk * 4 * obj.atk_f / 100 damage -= user.spi * 2 * obj.spi_f / 100 end" #This part is for defining preset damage formula. You can use these formula by #writing # #in the weapon/skill/item note field, with n as a key number that returns the #desired preset formula. This part is divided into weapons preset and skill/items #preset to avoid confusion. Preset Weapons can also be used by enemies. PRESET_WEAPONS = { #<= For Weapons # n formula 1 =>"damage = (user.atk ** 2) * (999 - self.def) / 999", #don't forget the comma!! 2 =>"damage = (user.hp / user.maxhp.to_f) * user.atk * 4", 4 =>"eval(CSU::Damage::DEFAULT_WEAPON_DAMAGE) damage *= 10", 5 =>"base = user.atk + ((user.atk + user.level) / 32.0) * ((user.atk * user.level) / 32.0) damage = (((512 - self.def) * base) / (512)) damage = ((user.mp * damage * 3) / user.maxmp).to_i + 1", 3 =>"damage = (user.atk * user.level) - self.def" #No comma at the last entry. } #<=Don't delete this!! PRESET_OBJ = { #<= For Skill/Items # n formula 1 =>"damage = (user.agi * obj.agi_f) / 100", 2 =>"damage = (self.hp / 4)" #=> Gravity attack example } #<=Don't delete this!! #This part is for critical hits. Define the default multiplier for a critical hit #and the default chance for a critical hit here. Note that this completely voids #the original critical rate definition. Write all chances and multipliers in #percent. #For individual critical rates and multipliers, define it via the note field by #writing # # #in the note field. An exception is for unarmed actor attack, since actors doesn't #have note fields, you can define ti further below this config. #This is for weapons. DEFAULT_WPN_CRITICAL_RATE = 4 DEFAULT_WPN_CRITICAL_MULTIPLIER = 300 #This is for skills. DEFAULT_SKILL_CRITICAL_RATE = 10 DEFAULT_SKILL_CRITICAL_MULTIPLIER = 275 #This is for items. DEFAULT_ITEM_CRITICAL_RATE = 0 DEFAULT_ITEM_CRITICAL_MULTIPLIER = 100 #This is for unarmed actors. DEFAULT_UNARMED_CRITICAL_RATE = 4 DEFAULT_UNARMED_CRITICAL_MULTIPLIER = 200 #This is for enemies DEFAULT_ENEMY_CRITICAL_RATE = 8 DEFAULT_ENEMY_CRITICAL_MULTIPLIER = 300 #This is for seting default variance for normal attacks. DEFAULT_NORMAL_ATK_VARIANCE = 10 #=============================================================================== #Additional Damage Processing #=============================================================================== #This part may be used for additional damage processing after the basic damage #processing is done. In this script, damage processing goes through 4 phases: #1st phase: evaluating custom damage formulas #2nd phase: applying elements, critical, variance, and guard to the damage. #3rd phase: applying additional damage processing. You can set additional damage # processing code here. I believe there may be some processig code that # should be done after the 2nd phase is done, so I added this part. #4th phase: applying the calculated damage value as a true hp or mp damage #Set the default processing code for the 3rd phase here. #=============================================================================== DEFAULT_ADDITIONAL_PROCESS = "if damage < -9999 damage = -9999 elsif damage > 9999 damage = 9999 end" #This is sanity check. This piece of processing code must be done after the 2nd #phase is done, as a final check. Of course this just an example, you can use any kind of damage #processing you want here. end end #=============================================================================== #=============================================================================== #Individual Settings for Weapons, Skills, Items, etc damage formulas #=============================================================================== module RPG class Weapon #This part is for setting a formula based on a weapon's ID def damage_formula case @id when 1, 2, 3, 4 #Set many IDs with the same formula at once. return "damage = user.atk * 4 - self.def * 2" end return CSU::Damage::DEFAULT_WEAPON_DAMAGE end #This part is for setting additional damage processing. def additional_process case @id when 2 #This is how to make weapons that break the default damage limit. (If you use #sanity check as your default additional process) return "if damage < -99999 damage = -99999 elsif damage > 99999 damage = 99999 end" end return CSU::Damage::DEFAULT_ADDITIONAL_PROCESS end end class Skill #This part is for setting a formula based on a skill's ID. def damage_formula case @id when 1, 2, 3, 4 return "damage = obj.base_damage if damage > 0 damage += user.atk * 4 * obj.atk_f / 100 damage += user.spi * 2 * obj.spi_f / 100 unless obj.ignore_defense damage -= self.def * 2 * obj.atk_f / 100 damage -= self.spi * 1 * obj.spi_f / 100 end damage = 0 if damage < 0 elsif damage < 0 damage -= user.atk * 4 * obj.atk_f / 100 damage -= user.spi * 2 * obj.spi_f / 100 end" end return CSU::Damage::DEFAULT_SKILL_DAMAGE end #This part is for setting additional damage processing. def additional_process case @id when 1 #This kind of code can be used to make the skill's additional process #the same as the user's normal attack additional process. This is only #applicable to Skills and Items. return "if user.is_a?(Game_Actor) if user.weapons.compact.size >= 0 eval(user.weapons.compact[0].additional_process) else eval(user.unarmed_additional_process) end else eval(user.additional_process) end" end return CSU::Damage::DEFAULT_ADDITIONAL_PROCESS end end class Item #This part is for setting a formula based on an item's ID. def damage_formula case @id when 1, 2, 3, 4 return "damage = obj.base_damage if damage > 0 damage += user.atk * 4 * obj.atk_f / 100 damage += user.spi * 2 * obj.spi_f / 100 unless obj.ignore_defense damage -= self.def * 2 * obj.atk_f / 100 damage -= self.spi * 1 * obj.spi_f / 100 end damage = 0 if damage < 0 elsif damage < 0 damage -= user.atk * 4 * obj.atk_f / 100 damage -= user.spi * 2 * obj.spi_f / 100 end" end return CSU::Damage::DEFAULT_ITEM_DAMAGE end #This part is for setting additional damage processing. def additional_process case @id when 1 return "if user.is_a?(Game_Actor) if user.weapons.compact.size != 0 user.weapons.compact[0].additional_process else user.unarmed_additional_process end else user.additional_process end" end return CSU::Damage::DEFAULT_ADDITIONAL_PROCESS end end class Enemy #This part is for setting formula based on an enemy's ID def damage_formula case @id when 1, 2, 3, 4 return "damage = user.atk * 4 - self.def * 2" end return CSU::Damage::DEFAULT_ENEMY_DAMAGE end #This part is for setting additional damage processing. def additional_process case @id when 1 return "if damage < -99999 damage = -99999 elsif damage > 99999 damage = 99999 end" #=> The so-called break damage limit. end return CSU::Damage::DEFAULT_ADDITIONAL_PROCESS end end class Actor #This part is for setting formula for an actor's unarmed attack. def unarmed_damage_formula case @id when 1, 2, 3 return "damage = user.atk * 4 - self.def * 2" end return CSU::Damage:DEFAULT_UNARMED_DAMAGE end #This part is for setting additional damage processing. def unarmed_additional_process case @id when 1 return "if damage < -99999 damage = -99999 elsif damage > 99999 damage = 99999 end" #=> The so-called break damage limit. end return CSU::Damage::DEFAULT_ADDITIONAL_PROCESS end #This part is for setting unarmed variance def unarmed_variance case @id when 1 return 6 end return CSU::Damage::DEFAULT_NORMAL_ATK_VARIANCE end #This part is for setting actor's unarmed critical rate and multiplier, since #actors doesn't have note fields. def critical_rate case @id when 3 return 10 end return CSU::Damage::DEFAULT_UNARMED_CRITICAL_RATE end def critical_multiplier case @id when 3 return 385 end return CSU::Damage::DEFAULT_UNARMED_CRITICAL_MULTIPLIER end end end ################################################################################ #END CONFIG. Editing beyond this is highly suggested if you want to get headaches #(well, jk, it's not that complicated anyway.) ################################################################################ module CSU if defined?(SCRIPTLIST) == nil SCRIPTLIST = [] end SCRIPTLIST.push("Ultimate Algorithm") end module RPG class UsableItem attr_accessor :agi_f attr_accessor :def_f attr_accessor :critical_rate attr_accessor :critical_multiplier attr_accessor :ignore_guard attr_accessor :ignore_prev_crit def create_usableitem_cache_ultimate_algorithm #Create Base Damage cache temp = self.note[//] if temp != nil temp.sub(/[0-9-]+/) {|a| @base_damage = a.to_i} end #Create Critical Rate cache if @critical_rate == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @critical_rate = a.to_i} else @critical_rate = CSU::Damage::DEFAULT_SKILL_CRITICAL_RATE if self.is_a?(RPG::Skill) @critical_rate = CSU::Damage::DEFAULT_ITEM_CRITICAL_RATE if self.is_a?(RPG::Item) end end #Create Critical Multiplier cache if @critical_multiplier == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @critical_multiplier = a.to_i} else @critical_multiplier = CSU::Damage::DEFAULT_SKILL_CRITICAL_MULTIPLIER if self.is_a?(RPG::Skill) @critical_multiplier = CSU::Damage::DEFAULT_ITEM_CRITICAL_MULTIPLIER if self.is_a?(RPG::Item) end end #Create Attack Factor cache temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @atk_f = a.to_i} end #Create Spirit Factor cache temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @spi_f = a.to_i} end #Create Agility Factor cache if @agi_f == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @agi_f = a.to_i} else @agi_f = 0 end end #Create Defense Factor cache if @def_f == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @def_f = a.to_i} else @def_f = 0 end end #Create Ignore Guard cache if @ignore_guard == nil @ignore_guard = self.note[//] != nil end #Create Ignore Prevent Critical cache if @ignore_prev_crit == nil @ignore_prev_crit = self.note[//] != nil end end end class Skill alias damage_formula_2 damage_formula def damage_formula temp = self.note[//] if temp != nil temp.sub(/[0-9]+/){|a| return CSU::Damage::PRESET_OBJ[a.to_i] } end return damage_formula_2 end end class Item alias damage_formula_2 damage_formula def damage_formula temp = self.note[//] if temp != nil temp.sub(/[0-9]+/){|a| return CSU::Damage::PRESET_OBJ[a.to_i] } end return damage_formula_2 end end class Weapon attr_accessor :critical_rate attr_accessor :critical_multiplier attr_accessor :ignore_guard attr_accessor :ignore_prev_crit attr_accessor :variance def create_weapon_cache_ultimate_algorithm #Create Critical Rate cache if @critical_rate == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @critical_rate = a.to_i} else @critical_rate = CSU::Damage::DEFAULT_WPN_CRITICAL_RATE end end #Create Critical Multiplier cache if @critical_multiplier == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @critical_multiplier = a.to_i} else @critical_multiplier = CSU::Damage::DEFAULT_WPN_CRITICAL_MULTIPLIER end end #Create Variance cache if @variance == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @variance = a.to_i} else @variance = CSU::Damage::DEFAULT_NORMAL_ATK_VARIANCE end end #Create Ignore Guard cache if @ignore_guard == nil @ignore_guard = self.note[//] end #Create Ignore Prevent Critical cache if @ignore_prev_crit == nil @ignore_prev_crit = self.note[//] end end alias damage_formula_2 damage_formula def damage_formula temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| return CSU::Damage::PRESET_WEAPONS[a.to_i] } end return damage_formula_2 end end class Enemy attr_accessor :critical_rate attr_accessor :critical_multiplier attr_accessor :variance attr_accessor :ignore_guard attr_accessor :ignore_prev_crit def create_enemy_cache_ultimate_algorithm #Create Critical Rate cache if @critical_rate == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @critical_rate = a.to_i} else @critical_rate = CSU::Damage::DEFAULT_ENEMY_CRITICAL_RATE end end #Create Critical Multiplier cache if @critical_multiplier == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @critical_multiplier = a.to_i} else @critical_multiplier = CSU::Damage::DEFAULT_ENEMY_CRITICAL_MULTIPLIER end end #Create Variance cache if @variance == nil temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| @variance = a.to_i} else @variance = CSU::Damage::DEFAULT_NORMAL_ATK_VARIANCE end end #Create Ignore Guard cache if @ignore_guard == nil @ignore_guard = self.note[//] end #Create Ignore Prevent Critical cache if @ignore_prev_crit == nil @ignore_prev_crit = self.note[//] end end alias damage_formula_2 damage_formula def damage_formula temp = self.note[//] if temp != nil temp.sub(/[0-9]+/) {|a| return CSU::Damage::PRESET_WEAPONS[a.to_i] } end return damage_formula_2 end end end class Game_Actor def cri if weapons.compact.size == 0 return actor.critical_rate else temp = 0 for weapon in weapons.compact temp += weapon.critical_rate end return (temp / weapons.compact.size).to_i end end def unarmed_damage_formula return actor.unarmed_damage_formula end def unarmed_variance return actor.unarmed_variance end def no_variance for weapon in weapons.compact return true if weapon.no_variance end return false end def ignore_guard for weapon in weapons.compact return true if weapon.ignore_guard end return false end def ignore_prev_crit for weapon in weapons.compact return true if weapon.ignore_prev_crit end return false end def critical_multiplier if weapons.compact.size == 0 return actor.critical_multiplier else temp = 0 for weapon in weapons.compact temp += weapon.critical_multiplier end return (temp / weapons.compact.size).to_i end end def unarmed_additional_process return actor.unarmed_additional_process end end class Game_Enemy def cri return enemy.has_critical ? enemy.critical_rate.to_i : 0 end def critical_multiplier return enemy.critical_multiplier.to_i end def variance return enemy.variance end def ignore_guard return enemy.ignore_guard end def ignore_prev_crit return enemy.ignore_prev_crit end def damage_formula return enemy.damage_formula end def additional_process return enemy.additional_process end end