neonblack

Regent and Stat Formulae v1.0a

Sep 12th, 2013
330
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ##-----------------------------------------------------------------------------
  2. ## Stat Formulae and Regent Stats v1.0a
  3. ## Created by Neon Black
  4. ##
  5. ## For both commercial and non-commercial use as long as credit is given to
  6. ## Neon Black and any additional authors.  Licensed under Creative Commons
  7. ## CC BY 3.0 - http://creativecommons.org/licenses/by/3.0/.
  8. ##----------------------------------------------------------------------------##
  9.                                                                               ##
  10. ##----------------------------------------------------------------------------##
  11. ##    Revision Info:
  12. ## v1.0a - 9.12.2013
  13. ##  Added critical multiplier
  14. ## v1.0 - 9.11.2013
  15. ##  Wrote and debugged main script
  16. ##----------------------------------------------------------------------------##
  17.                                                                               ##
  18. $imported ||= {}                                                              ##
  19. $imported["RegentStatFormulae"] = 1.0                                         ##
  20.                                                                               ##
  21. ##----------------------------------------------------------------------------##
  22. ##    Instructions:
  23. ## Place this script in the script editor below "Materials" and above "Main".
  24. ## This script allows you to create formulae in certain noteboxes to change
  25. ## stats under certain conditions.  It also allows you to create your own
  26. ## custom stats known as "regent stats" which can be directly affected by
  27. ## things such as states and equips.  The tags are listed below.
  28. ##
  29. ##------
  30. ## hp formula[100]  -or-  mp formula[level * 10 + mat]  -etc-
  31. ##  - Sets a particular parameter, ex-parameter, or sp-parameter to a value
  32. ##    based on the number or value between the brackets.  This formula can be
  33. ##    anything including a script, similar to how damage formulae work for
  34. ##    skills.  Be careful not to include stats in each other's formulae since
  35. ##    it will cause an infinite loop and crash.  Valid values for stats
  36. ##    include:
  37. ##    hp, mhp, mp, mmp, atk, def, mat, mdf, agi, luk, hit, eva, cri, cev, mev,
  38. ##    mrf, cnt, hrg, mrg, trg, tgr, grd, rec, pha, mcr, tcr, pdr, mdr, fdr, exr
  39. ##    Note that hp and mhp both refer to max HP, same as mp and mmp.  Also note
  40. ##    that EX and SP parameters are assumed to be percentages with these tags.
  41. ##    This means that a final value of 50 represents 50%, etc.
  42. ##    This tag applies to actors, classes, and enemies.  Actor tags take
  43. ##    priority over class tags.
  44. ##
  45. ## crit base[3]  -or-  critcal base[1.0 + 0.01 * level]  -etc-
  46. ##  - The base multiplier for critical hit damage.  This is the number the
  47. ##    damage is multiplier by when a critical hit is struck.  This works in
  48. ##    much the same way that normal stats do.
  49. ##    This tag applies to actors, classes, and enemies.  Actor tags take
  50. ##    priority over class tags.
  51. ##
  52. ## crit damage + 1  -or-  critical damage ** level / 10 + 1  -etc-
  53. ##  - This tag works like a feature on any item with features.  This tag allows
  54. ##    a calculation to be applied to the base critical hit multiplier while the
  55. ##    feature is applied to the battler.  The formula may be applied in one of
  56. ##    6 different ways:
  57. ##     +  The formula is added to the base after it is calculated.
  58. ##     -  The formula is subtracted from the base after it is calculated.
  59. ##     *  The base is multiplied by the formula.
  60. ##     /  The base is divided by the formula.
  61. ##     ** The base is raised to the power of the formula.
  62. ##     %  The base divided by the formula and the remainder returned (modulus).
  63. ##    The features are applied in no particular order, so be aware that
  64. ##    addition could occur before multiplication.  The formula (after the first
  65. ##    operator) is always calculated before anything is done to the base value.
  66. ##
  67. ## regent value[:key] base[100]  -or-  regent[:key] base[agi + level]  -etc-
  68. ##  - Sets a base for a regent value.  Much like the stat formula tag, this tag
  69. ##    can use any formula between the brackets.  All regent values have a key
  70. ##    to identify them.  This key must start with a colon followed by a letter,
  71. ##    then may contain any combination of letters, numbers, and underscores.
  72. ##    For example, rather than :key you could use a key named :fire_power or
  73. ##    something similar.  This key can then be used to access the regent value
  74. ##    later.  If a battler does not have a regent value and one is pulled, it
  75. ##    uses the default value set in config.
  76. ##    This tag applies to actors, classes, and enemies.  Actor tags take
  77. ##    priority over class tags.
  78. ##
  79. ## regent value[:key] + 500  -or-  regent[:key] * agi + atk  -etc-
  80. ##  - Creates a feature on actors, classes, equips, enemies, or states that
  81. ##    modifies a regent stat from it's base.  The stat's base has a formula
  82. ##    applied to it in one or 6 different ways:
  83. ##     +  The formula is added to the base after it is calculated.
  84. ##     -  The formula is subtracted from the base after it is calculated.
  85. ##     *  The base is multiplied by the formula.
  86. ##     /  The base is divided by the formula.
  87. ##     ** The base is raised to the power of the formula.
  88. ##     %  The base divided by the formula and the remainder returned (modulus).
  89. ##    The features are applied in no particular order, so be aware that
  90. ##    addition could occur before multiplication.  The formula (after the first
  91. ##    operator) is always calculated before anything is done to the base value.
  92. ##
  93. ##------
  94. ## The regent stats are stored under the method "v" on a battler.  This means
  95. ## they can be quickly accessed by using .v[:key] in any kind of script call.
  96. ## For example, to use it in a damage formula, you may use a formula such as:
  97. ## a.atk + a.v[:bonus] - b.def / 2
  98. ## To get a value from actor ID 3 and store it in a variable, you could use
  99. ## a script set in variable control and use the following:
  100. ## $game_actors[3].v[:training]
  101. ## There is no real limit to how regent values can be used, so get creative.
  102. ##----------------------------------------------------------------------------##
  103.                                                                               ##
  104. module CPStatFormulae ## Do not touch this line                               ##
  105. ##----------------------------------------------------------------------------##
  106. ##    Config:
  107. ## The config options are below.  You can set these depending on the flavour of
  108. ## your game.  Each option is explained in a bit more detail above it.
  109. ##
  110. ##------
  111. # This value is the base value for regent values when a base is not defined in
  112. # a notebox.
  113. BaseRegentValue = 100
  114.  
  115. # This range affects the critical multiplier.  This is the min and max values
  116. # the critical hit damage may be multiplied by as well as the default base
  117. # value.
  118. CritMinMax = [1.5, 5]
  119. CritBase = 3
  120.  
  121. # This hash stores the min and max values for stats on ACTORS.  This allows the
  122. # default values to be broken.  Note that only normal parameters can be limited
  123. # in this way.
  124. ActorMinMax ={
  125.   :mhp => [1, 9999],
  126.   :mmp => [0, 9999],
  127.   :atk => [1, 999],
  128.   :def => [1, 999],
  129.   :mat => [1, 999],
  130.   :mdf => [1, 999],
  131.   :agi => [1, 999],
  132.   :luk => [1, 999],
  133. }
  134.  
  135. # This hash stores the min and max values for stats on ENEMIES.  This allows
  136. # the default values to be broken.  Again, this only works for parameters.
  137. EnemyMinMax ={
  138.   :mhp => [1, 999999],
  139.   :mmp => [0, 9999],
  140.   :atk => [1, 999],
  141.   :def => [1, 999],
  142.   :mat => [1, 999],
  143.   :mdf => [1, 999],
  144.   :agi => [1, 999],
  145.   :luk => [1, 999],
  146. }
  147. ##----------------------------------------------------------------------------##
  148.                                                                               ##
  149.                                                                               ##
  150. ##----------------------------------------------------------------------------##
  151. ## The following lines are the actual core code of the script.  While you are
  152. ## certainly invited to look, modifying it may result in undesirable results.
  153. ## Modify at your own risk!
  154. ###----------------------------------------------------------------------------
  155.  
  156.  
  157.   ## The basic bits used for REGEXP by certain objects.
  158.   def base_stat_formulae
  159.     set_base_stat_formulae unless @base_stat_formulae
  160.     return @base_stat_formulae
  161.   end
  162.  
  163.   def set_base_stat_formulae
  164.     @base_stat_formulae = {}
  165.     self.note.split(/[\r\n]+/).each do |line|
  166.       case line
  167.       when /(hp|mhp|mp|mmp|atk|def|mat|mdf|agi|luk) formula\[(.+)\]/i
  168.         i = $1.to_sym.downcase; i = i == :hp ? :mhp : i == :mp ? :mmp : i
  169.         @base_stat_formulae[i] = $2.to_s
  170.       when /(hit|eva|cri|cev|mev|mrf|cnt|hrg|mrg|trg) formula\[(.+)\]/i
  171.         @base_stat_formulae[$1.to_sym.downcase] = $2.to_s
  172.       when /(tgr|grd|rec|pha|mcr|tcr|pdr|mdr|fdr|exr) formula\[(.+)\]/i
  173.         @base_stat_formulae[$1.to_sym.downcase] = $2.to_s
  174.       end
  175.     end
  176.   end
  177.  
  178.   def base_crit_damage_form
  179.     set_base_regent_formulae unless @base_regent_formulae
  180.     return @base_crit_damage_val
  181.   end
  182.  
  183.   def base_regent_formulae
  184.     set_base_regent_formulae unless @base_regent_formulae
  185.     return @base_regent_formulae
  186.   end
  187.  
  188.   def set_base_regent_formulae
  189.     @base_regent_formulae = {}
  190.     self.note.split(/[\r\n]+/).each do |line|
  191.       case line
  192.       when /(?:regent value|regent)?\[:(\w+)\] base\[(.+)\]/i
  193.         @base_regent_formulae[$1.to_sym] = $2.to_s
  194.       when /crit(?:ical)? base\[(.+)\]/i
  195.         @base_crit_damage_val = $1.to_s
  196.       end
  197.     end
  198.   end
  199. end
  200.  
  201. class Game_BattlerBase
  202.   ## Sets up the regent stats object for battlers.
  203.   alias :cp_091113_init :initialize
  204.   def initialize(*args)
  205.     cp_091113_init(*args)
  206.     @value_regents = ValueRegents.new(self)
  207.   end
  208.  
  209.   def v
  210.     @value_regents
  211.   end
  212.  
  213.   ## This method allows classes that are not a superclass or subclass of a
  214.   ## battler to properly evaluate in the battler's object enviroment, including
  215.   ## a rescue value (as it almost certainly will be needed for newbies.
  216.   def evaluate_stats(formula, rescue_value = 0)
  217.     eval(formula) rescue rescue_value
  218.   end
  219. end
  220.  
  221. class Game_Battler < Game_BattlerBase
  222.   alias :cp_091113_make_damage_value :make_damage_value
  223.   def make_damage_value(user, item)
  224.     @user_for_crit_value = user
  225.     cp_091113_make_damage_value(user, item)
  226.   end
  227.  
  228.   def apply_critical(damage)
  229.     value = @user_for_crit_value.apply_crit_features
  230.     mn, mx = *CPStatFormulae::CritMinMax
  231.     damage * [mn, [mx, value].min].max
  232.   end
  233.  
  234.   def apply_crit_features
  235.     base = base_crit_damage
  236.     features(:crit_damage).each do |fet|
  237.       begin
  238.         evsect = evaluate_stats(fet.value, :error_out)
  239.         next if evsect == :error_out
  240.         base = eval("#{base} #{fet.data_id} #{evsect}")
  241.       rescue
  242.         next
  243.       end
  244.     end
  245.     return base
  246.   end
  247. end
  248.  
  249. ##------
  250. ## Overwrites parameter based methods on actors.
  251. class Game_Actor < Game_Battler
  252.   def param_min(param_id)
  253.     box = CPStatFormulae::ActorMinMax[RPG.parameter_symbol(param_id)]
  254.     return box.nil? ? super(param_id) : box[0]
  255.   end
  256.  
  257.   def param_max(param_id)
  258.     box = CPStatFormulae::ActorMinMax[RPG.parameter_symbol(param_id)]
  259.     return box.nil? ? super(param_id) : box[1]
  260.   end
  261.  
  262.   def param_base(param_id)
  263.     value = actor.base_stat_formulae[RPG.parameter_symbol(param_id)]
  264.     return self.class.param_base(param_id, self) if value.nil?
  265.     evaluate_stats(value)
  266.   end
  267.  
  268.   def xparam(xparam_id)
  269.     value = actor.base_stat_formulae[RPG.ex_parameter_symbol(xparam_id)]
  270.     value ||= self.class.xparam_base(xparam_id)
  271.     value = value.nil? ? 0 : evaluate_stats(value)
  272.     value.to_f / 100 + super(xparam_id)
  273.   end
  274.  
  275.   def sparam(sparam_id)
  276.     value = actor.base_stat_formulae[RPG.sp_parameter_symbol(sparam_id)]
  277.     value ||= self.class.sparam_base(sparam_id)
  278.     value = value.nil? ? 100 : evaluate_stats(value, 100)
  279.     value.to_f / 100 * super(sparam_id)
  280.   end
  281.  
  282.   def base_crit_damage
  283.     value = actor.base_crit_damage_form
  284.     value ||= self.class.base_crit_damage_form
  285.     base = CPStatFormulae::CritBase
  286.     return value.nil? ? base : evaluate_stats(value, base)
  287.   end
  288.  
  289.   def base_regent_value(key)
  290.     value = actor.base_regent_formulae[key]
  291.     value ||= self.class.base_regent_value(key)
  292.     rvfloor = CPStatFormulae::BaseRegentValue
  293.     value = value.nil? ? rvfloor : evaluate_stats(value, rvfloor)
  294.     return value
  295.   end
  296. end
  297.  
  298. ##------
  299. ## Overwrites parameter based methods on enemies.
  300. class Game_Enemy < Game_Battler
  301.   def param_min(param_id)
  302.     box = CPStatFormulae::EnemyMinMax[RPG.parameter_symbol(param_id)]
  303.     return box.nil? ? super(param_id) : box[0]
  304.   end
  305.  
  306.   def param_max(param_id)
  307.     box = CPStatFormulae::EnemyMinMax[RPG.parameter_symbol(param_id)]
  308.     return box.nil? ? super(param_id) : box[1]
  309.   end
  310.  
  311.   def param_base(param_id)
  312.     value = enemy.base_stat_formulae[RPG.parameter_symbol(param_id)]
  313.     return enemy.params[param_id] if value.nil?
  314.     evaluate_stats(value)
  315.   end
  316.  
  317.   def xparam(xparam_id)
  318.     value = enemy.base_stat_formulae[RPG.ex_parameter_symbol(xparam_id)]
  319.     value = value.nil? ? 0 : evaluate_stats(value)
  320.     value.to_f / 100 + super(xparam_id)
  321.   end
  322.  
  323.   def sparam(sparam_id)
  324.     value = enemy.base_stat_formulae[RPG.sp_parameter_symbol(sparam_id)]
  325.     value = value.nil? ? 100 : evaluate_stats(value, 100)
  326.     value.to_f / 100 * super(sparam_id)
  327.   end
  328.  
  329.   def base_crit_damage
  330.     value = enemy.base_crit_damage_form
  331.     base = CPStatFormulae::CritBase
  332.     return value.nil? ? base : evaluate_stats(value, base)
  333.   end
  334.  
  335.   def base_regent_value(key)
  336.     value = enemy.base_regent_formulae[key]
  337.     rvfloor = CPStatFormulae::BaseRegentValue
  338.     value = value.nil? ? rvfloor : evaluate_stats(value, rvfloor)
  339.     return value
  340.   end
  341. end
  342.  
  343. ##-----
  344. ## Allows all classes to hold regent features rather than specifying simply
  345. ## certain classes at a single time.
  346. class RPG::BaseItem
  347.   include CPStatFormulae
  348.  
  349.   alias :cp_091113_features :features
  350.   def features
  351.     add_regent_value_features
  352.     return cp_091113_features
  353.   end
  354.  
  355.   def add_regent_value_features
  356.     return if @regent_features_made; @regent_features_made = true
  357.     note.split(/[\r\n]+/).each do |line|
  358.       case line
  359.       when /(?:regent value|regent)?\[:(\w+)\] (\+|-|\*\*|\*|\/|%) (.+)/i
  360.         s = [$2.to_s, $3.to_s]
  361.         f = RPG::BaseItem::Feature.new(:regent_value, $1.to_sym, s)
  362.         @features.push(f)
  363.       when /crit(?:ical)? damage (\+|-|\*\*|\*|\/|%) (.+)/i
  364.         f = RPG::BaseItem::Feature.new(:crit_damage, $1.to_s, $2.to_s)
  365.         @features.push(f)
  366.       end
  367.     end
  368.   end
  369. end
  370.  
  371. ## Gives actors and enemies base stat tags.
  372. class RPG::Actor < RPG::BaseItem
  373.   include CPStatFormulae
  374. end
  375.  
  376. class RPG::Enemy < RPG::BaseItem
  377.   include CPStatFormulae
  378. end
  379.  
  380. ##------
  381. ## Gives classes (in game type) base tags and changes how they refer to stats.
  382. class RPG::Class < RPG::BaseItem
  383.   include CPStatFormulae
  384.  
  385.   def param_base(param_id, actor)
  386.     value = base_stat_formulae[RPG.parameter_symbol(param_id)]
  387.     return params[param_id, actor.level] if value.nil?
  388.     actor.evaluate_stats(value)
  389.   end
  390.  
  391.   def xparam_base(xparam_id)
  392.     base_stat_formulae[RPG.ex_parameter_symbol(xparam_id)]
  393.   end
  394.  
  395.   def sparam_base(sparam_id)
  396.     base_stat_formulae[RPG.sp_parameter_symbol(sparam_id)]
  397.   end
  398.  
  399.   def base_regent_value(key)
  400.     base_regent_formulae[key]
  401.   end
  402. end
  403.  
  404. ## Adds a few handlers for determining symbols from a type of number.
  405. module RPG
  406.   def self.parameter_symbol(param_id)
  407.     [:mhp, :mmp, :atk, :def, :mat, :mdf, :agi, :luk][param_id]
  408.   end
  409.  
  410.   def self.ex_parameter_symbol(xparam_id)
  411.     [:hit, :eva, :cri, :cev, :mev, :mrf, :cnt, :hrg, :mrg, :trg][xparam_id]
  412.   end
  413.  
  414.   def self.sp_parameter_symbol(sparam_id)
  415.     [:tgr, :grd, :rec, :pha, :mcr, :tcr, :pdr, :mdr, :fdr, :exr][sparam_id]
  416.   end
  417. end
  418.  
  419. ##------
  420. ## The regent value class.  This is used to add up all types of features
  421. ## together when needed and return a regent value.  This is only actually used
  422. ## when the value is called rather than holding them all at the same time.
  423. class ValueRegents
  424.   def initialize(member)
  425.     @member = member
  426.   end
  427.  
  428.   def [](key)
  429.     base = @member.base_regent_value(key)
  430.     @member.features(:regent_value).each do |fet|
  431.       next unless fet.data_id == key
  432.       begin
  433.         evsect = @member.evaluate_stats(fet.value[1], :error_out)
  434.         next if evsect == :error_out
  435.         base = eval("#{base} #{fet.value[0]} #{evsect}")
  436.       rescue
  437.         next
  438.       end
  439.     end
  440.     return base
  441.   end
  442. end
  443.  
  444.  
  445. ##-----------------------------------------------------------------------------
  446. ##  End of script.
  447. ##-----------------------------------------------------------------------------
RAW Paste Data