Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Adding Attributes (Scripting Tool)

Adding Attributes Easy 1.11
By SephirothSpawn


Introduction
Ever want to give your objects attributes? Giving an actor a new stat like luck that grows as your actor does?

This script was designed to allow you to give any object (usually data structure objects) stats, either with a set stat or a stat that grows (stat is a hash, with "level" as the key and stat value as the "value") via the Curve Generator module. If you wish to use this for a object class, there must be an instance @id specified to read the stats.

Script

Copy and paste the code anywhere but it must be above any scripts that use this
Adding Attributes:
[rgss]#==============================================================================
# ** Adding Attributes Easy
#------------------------------------------------------------------------------
# SephirothSpawn
# Version 1.11
# 2009-02-02 (Year-Month-Day)
#------------------------------------------------------------------------------
# * Version History:
#
#   Version 1.0 -------------------------------------------------- (2009-01-21)
#    Version 1.1 ------------------------------------------------- (2009-02-02)
#     - Fix: Fixed add_stat default hash setup. Changed to object_to_string.
#------------------------------------------------------------------------------
# * Description:
#
#   This script was designed to allow you to give any object (usually data
#   structure objects) stats, either with a set stat or a stat that grows
#   (stat is a hash, with "level" as the key and stat value as the "value")
#   via the Curve Generator module. If you wish to use this for a object class,
#   there must be an instance @id specified to read the stats.
#------------------------------------------------------------------------------
# * Instructions:
#
#   Place the script anywhere above Main and any scripts that use it.
#------------------------------------------------------------------------------
# * Terms & Conditions:
#
#   Copyright (C) 2009 SephirothSpawn (Timothy Hoffman)
#   Free for non-commercial & commercial use.
#   Any modifications to the system are not to be re-distributed without my
#   consent.
#==============================================================================
 
#==============================================================================
# ** Module
#==============================================================================
 
class Module
  #--------------------------------------------------------------------------
  # * Add Stat
  #--------------------------------------------------------------------------
  private
  def add_stat(stat_name, hash_settings)
    # Create method
    s  = "def #{stat_name};"
    s += "  settings = #{object_to_string(hash_settings)};"
    s += "  settings.default = #{object_to_string(hash_settings.default)};"
    s += "  return settings[@id];"
    s += "end;"
    # Eval method
    module_eval (s)
  end
  #--------------------------------------------------------------------------
  # * Add Stat Curve
  #--------------------------------------------------------------------------
  private
  def add_stat_curve(stat_name, hash_settings)
    # Create method
    s  = "def #{stat_name};"
    s += '  @gen_stats = {} if @gen_stats == nil;'
    s += "  if @gen_stats['#{stat_name}'] == nil;"
    s += "    @gen_stats['#{stat_name}'] = {};"
    s += "  end;"
    s += "  if @gen_stats['#{stat_name}'].has_key?(@id);"
    s += "    return @gen_stats['#{stat_name}'][@id];"
    s += "  end;"
    s += "  settings = #{object_to_string(hash_settings)};"
    s += "  settings.default = #{object_to_string(hash_settings.default)};"
    s += "  curve = Curve_Generator.generate_curve(*settings[@id]);"
    s += "  @gen_stats['#{stat_name}'][@id] = curve;"
    s += "  return @gen_stats['#{stat_name}'][@id];"
    s += "end;"
    # Eval method
    module_eval (s)
  end
  #--------------------------------------------------------------------------
  # * Object to String
  #--------------------------------------------------------------------------
  def object_to_string(object)
    case object
    when Array
      object.collect! {|value| object_to_string(value)}
      return "[#{object.join(',')}]"
    when Hash
      s = '{'
      object.each do |key, value|
        s += "#{object_to_string(key)}=>#{object_to_string(value)},"
      end
      s += '}'
      return s
    else
      return object.to_s
    end
  end
end
[/rgss]

This script requires the Curve Generator Module (4.01)
[rgss]#==============================================================================
# ** Modules.Curve Generator Module (4.01)        By Trickster & SephirothSpawn
#------------------------------------------------------------------------------
# * Description :
#
#   This script was designed to generate a curve of numbers given certain
#   values. As of now, their are 3 formulas for you to choose from : Point-
#   slope; Early & Late; Early / Steady / Late + Curves.
#------------------------------------------------------------------------------
# * Syntax :
#
#   Generating Curve :
#    - curve = Curve_Generator.generate_curve(type, <args>)
#
#   Type : 0 - Point Slope
#          1 - Early / Late
#          2 - Early / Steady / Late + Curves
#
#   Args :
#
#    Type 0 : min_level, max_level, start value, inflation
#    Type 1 : min_level, max_level, min_value, max_value, early, late
#    Type 2 : min level, mid_level, max level, min value, mid_value,
#             max value, early, late, steady, curve 1, curve 2, integer
#
#   This will return a hash : { level => value, ... }
#==============================================================================
 
#==============================================================================
# ** Curve_Generator
#==============================================================================
 
module Curve_Generator
  #--------------------------------------------------------------------------
  # * Generate Curve
  #
  #   Type : 0 - Point Slope
  #          1 - Early / Late
  #          2 - Early / Steady / Late + Curves
  #
  #   Args :
  #
  #    Type 0 : min_level, max_level, start value, inflation
  #    Type 1 : min_level, max_level, min_value, max_value, early, late
  #    Type 2 : min level, mid_level, max level, min value, mid_value,
  #             max value, early, late, steady, curve 1, curve 2, integer
  #--------------------------------------------------------------------------
  def self.generate_curve(type, *args)
    # Collects Saved Tables
    tables = self.load_tables
    # Check for Previously Generated Table
    if tables.has_key?(type) && tables[type].has_key?(args)
      # Return Previously Generated Table
      return tables[type][args]
    end
    # Branch Point By Type
    case type
    when 0 # Point Slope
      table = Point_Slope.generate_curve(*args)
    when 1 # Early / Late
      table = Early_Late.generate_curve(*args)
    when 2 # Early / Stead / Late + Curves
      table = ESL_Curves.generate_curve(*args)
    end
    # Set 0 Defaults
    table.default = 0
    # Saves Table Information
    self.save_table(type, args, table)
    # Return Curve Information
    return table
  end
  #-------------------------------------------------------------------------
  # * Save Table
  #-------------------------------------------------------------------------
  def self.save_table(type, args, table)
    # Collects Saved Tables
    tables = self.load_tables
    # Creates Hash of Type (If non present)
    tables[type] = {} unless tables.has_key?(type)
    # Saves Table Data
    tables[type][args] = table
    # Resaves Tables to File
    save_data(tables, 'Data/Curve Generator.rxdata')    
  end
  #-------------------------------------------------------------------------
  # * Load Tables
  #-------------------------------------------------------------------------
  def self.load_tables
    # Test For Saved Table File
    unless FileTest.exist?('Data/Curve Generator.rxdata')
      # Creates Curve Generator Rxdata File
      save_data({}, 'Data/Curve Generator.rxdata')
    end
    # Returns Saved Tables
    return load_data('Data/Curve Generator.rxdata')
  end  
 
  #============================================================================
  # ** Point Slope
  #============================================================================
 
  module Point_Slope
    #------------------------------------------------------------------------
    # * Generate Curve
    #
    #   Args : min_level, max_level, start value, inflation
    #------------------------------------------------------------------------
    def self.generate_curve(min_l, max_l, start_value, inflation)
      # Creates Table
      table = {}
      # Fills Table
      for level in min_l..max_l
        table[level] = start_value + inflation * level
      end
      # Return Table
      return table
    end
  end
 
  #============================================================================
  # ** Early Late
  #============================================================================
 
  module Early_Late
    #------------------------------------------------------------------------
    # * Generate Curve
    #------------------------------------------------------------------------
    def self.generate_curve(min_l, max_l, min_v, max_v, e = 1.0, l = 1.0)
      # Creates Table
      table = {}
      # Fills Table
      for i in min_l..max_l
        # Assigns Value
        table = self.calculate_value(i, min_l.to_f, max_l.to_f,
                   min_v.to_f, max_v.to_f, e.to_f, l.to_f)
      end
      # Return Table
      return table
    end
    #------------------------------------------------------------------------
    # * Late Curve
    #------------------------------------------------------------------------
    def self.late_curve(level, min_level, max_level, min, max)
      diff = min_level - max_level
      stat = min - max
      num = stat * level ** 2 - 2 * min_level * stat * level + min_level ** 2 *
            max - 2 * min_level * max_level * min + min * min_level ** 2
      denom = diff ** 2
      return num / denom
    end
    #------------------------------------------------------------------------
    # * Early Curve
    #------------------------------------------------------------------------
    def self.early_curve(level, min_level, max_level, min, max)
      diff = max_level - min_level
      stat = max - @min
      num = -stat * level ** 2 + 2 * max_level * stat * level + min_level **
            2 * max - 2 * min_level * max_level * max + min * max_level ** 2
      denom = diff ** 2
      return num / denom    
    end
    #------------------------------------------------------------------------
    # * Steady Curve
    #------------------------------------------------------------------------
    def self.steady_curve(level, min_level, max_level, min, max)
      ch_level = max_level - min_level
      ch_stat = max - min
      base = ch_stat / ch_level * level
      mod = max * min_level - min * max_level
      base2 = mod / ch_level
      return base - base2
    end
    #------------------------------------------------------------------------
    # * Calculate Value
    #------------------------------------------------------------------------
    def self.calculate_value(level, min_level, max_level, min, max, e, l)
      return min if level < min_level
      return max if max_level < level
      if e == l
        stat = self.steady_curve(level, min_level, max_level, min, max)
      else
        early_ = self.early_curve(level, min_level, max_level, min, max)
        late_ = self.late_curve(level, min_level, max_level, min, max)
        stat = (e * early_ + l * late_) / (e + l)
      end
      stat = Integer([[stat, min].max, max].min)
      return stat
    end
  end
     
  #============================================================================
  # ** ESL_Curves
  #============================================================================
 
  module ESL_Curves
    #------------------------------------------------------------------------
    # * Generate Curve
    #------------------------------------------------------------------------
    def self.generate_curve(mn_v, md_v, mx_v, mn_l, md_l, mx_l, e = 0, l = 0,
                            s = 0, c1 = 0, c2 = 0, i = true)
      # Saves Values
      @min_value, @mid_value, @max_value = mn_v, md_v, mx_v
      @min_level, @mid_level, @max_level = mn_l, md_l, mx_l
      @early    , @late     , @steady    = e   , l   , s
      @curve1   , @curve2   , @integer   = c1  , c2  , i
      # Error Checking
      self.error_checking
      # Calculate constants
      self.calculate_constants
      # Returns Table
      return self.generate_table
    end
    #-----------------------------------------------------------------------
    # * Error Checking
    #-----------------------------------------------------------------------
    def self.error_checking
      if @late + @early + @steady + @curve1 + @curve2 == 0
        raise(StandardError, "No Influences Have Been Defined")
      elsif @min_level == @mid_level || @min_level == @max_level ||
            @mid_level == @max_level
        raise(StandardError, "Can't Use Same Level for Min, Mid, or Max Level")
      end
    end
    #-----------------------------------------------------------------------
    # * Calculate Constants
    #-----------------------------------------------------------------------
    def self.calculate_constants
      # Calculate "infi" and "inmi"
      @inmi = (@mid_value - @min_value) / (@mid_level - @min_level)
      @infi = (@max_value - @min_value) / (@max_level - @min_level)
      # Calculate "infimi"
      @infimi = (@infi - @inmi) / (@max_level - @mid_level)
    end
    #-----------------------------------------------------------------------
    # * Generate Table
    #-----------------------------------------------------------------------
    def self.generate_table
      # Create Hash table
      table = {}
      # Run Through Each Level
      self.each {|level, value| table[level] = value}
      # Return Created Table
      return table
    end
    #-----------------------------------------------------------------------
    # * Each Interator
    #-----------------------------------------------------------------------
    def self.each
      # Get Minimum level and Maximum Level
      minimum, maximum = @min_level.to_i, @max_level.to_i
      # Run Through Minimum and Maximum and Yield Level and Value
      (minimum..maximum).each {|level| yield(level, self.get_stat(level))}
    end
    #-----------------------------------------------------------------------
    # * Get Stat
    #-----------------------------------------------------------------------
    def self.get_stat(level)
      return @integer ? @min_value.to_i : @min_value if level <= @min_level
      return @integer ? @max_value.to_i : @max_value if level >= @max_level
      # Setup Total
      total = 0
      # Get Values for Every Stat if greater than 0
      total += @early  * self.early_curve(level)      if @early > 0
      total += @late   * self.late_curve(level)       if @late > 0
      total += @steady * self.steady_curve(level)     if @steady > 0
      total += @curve1 * self.early_late_curve(level) if @curve1 > 0
      total += @curve2 * self.late_early_curve(level) if @curve2 > 0
      # Get Average
      total /= @late + @early + @steady + @curve1 + @curve2
      # Limit Value
      total = level < @mid_level ?
        [total, @mid_value].min : [total, @mid_value].max
      # Further Limit Value
      total = [[total, @min_value].max, @max_value].min
      # Return Value
      return @integer ? total.to_i : total
    end
    #-----------------------------------------------------------------------
    # * Late Curve
    #-----------------------------------------------------------------------
    def self.late_curve(level)
      # Calculate "A"
      a_num = @infimi * (3 * @min_level + @mid_level) + @inmi
      a_den = (@max_level - @min_level) * (@mid_level - @min_level)
      a = - a_num / a_den
      # Return Value
      return curve(a, level)
    end
    #-----------------------------------------------------------------------
    # * Early Curve
    #-----------------------------------------------------------------------
    def self.early_curve(level)
      # Calculate "A"
      a_num = @infimi * (2 * @max_level + @min_level + @mid_level) + @inmi
      a_den = (@max_level - @mid_level) * (@max_level - @min_level)
      a = - a_num / a_den
      # Return Value
      return curve(a, level)
    end
    #-----------------------------------------------------------------------
    # * Early Late Curve
    #-----------------------------------------------------------------------
    def self.early_late_curve(level)
      # Calculate "A"
      a = @infimi / (@max_level + @min_level - 2 * @mid_level)
      # Return Value
      return curve(a, level)
    end
    #-----------------------------------------------------------------------
    # * Late Early Curve
    #-----------------------------------------------------------------------
    def self.late_early_curve(level)
      # If Less than Mid Level
      if level < @mid_level
        # Return Late Curve for level
        return late_curve(level)
      # If Greater than Mid Level
      elsif level > @mid_level
        # Return Early Curve for Level
        return early_curve(level)
      # If at Mid Level
      elsif level == @mid_level
        # Return Mid Value
        return @mid_value
      end
    end
    #-----------------------------------------------------------------------
    # * Steady Curve
    #-----------------------------------------------------------------------
    def self.steady_curve(level)
      ch_level = @max_level - @min_level
      ch_stat = @max_value - @min_value
      base = ch_stat / ch_level * level
      mod = @max_value * @min_level - @min_level * @max_level
      base2 = mod / ch_level
      return base - base2
    end
    #-----------------------------------------------------------------------
    # * Curve
    #-----------------------------------------------------------------------
    def self.curve(a, level)
      # Calculate "B"
      b = @infimi - a * (@min_level + @mid_level + @max_level)
      # Calculate "C"
      c = @inmi - a * (@mid_level ** 2 + @min_level * @mid_level +
          @min_level ** 2) - b * (@mid_level + @min_level)
      # Calculate "D"
      d = @min_value - (a * @min_level ** 3 + b * @min_level ** 2 + c *
          @min_level)
      # Calculate Stat
      stat = a * level ** 3 + b * level ** 2 + c * level + d
      # Return Stat
      return stat
    end
  end
end
[/rgss]
Instructions

Basic Stats (That do not increase)
In your object class, add:
[rgss]class Your_Class
  hash_settings = {object_id => value, object_id => value, ...}
  hash_settings.default = default_for_non_specified_objects
  add_stat('your_stat_name', hash_settings)
end
 
 
[/rgss]

Now you will just need to call your_object.your_stat_name and it will return the value for that object.
Stat that curve
In your object class, add:
[rgss]class Your_Class
  hash_settings = {object_id => [curve_type, curve_argument, ...], object_id => [curve_type, curve_argument, ...], ...}
  hash_settings.default = [curve_type, curve_argument, ...]
  add_stat_curve('your_stat_name', hash_settings)
end
 
 
[/rgss]

Curve type and curve_arguments are listing in the curve generator module heading. If you need help, just ask.

Now you will just need to call your_object.your_stat_name and it will return a hash with your curve specified. (Key as "level" and value of stat at that level as the value)
FAQ

Examples:
[rgss]class RPG::Actor
  luck = {
    1 => [0, 1, 99, 5, 1],
    2 => [0, 1, 99, 4, 2],
    7 => [0, 1, 99, 2, 4],
    8 => [0, 1, 99, 1, 5],
  }
  luck.default = [0, 1, 99, 3, 3]
  add_stat_curve('luck', luck)
  rating = {
    1=>1,
    2=>2,
    7=>2,
    8=>1
  }
  rating.default = 3
  add_stat('rating', rating)
end
 
class Game_Actor
  def luck
    return $data_actors[@actor_id].luck[@level]
  end
  def rating
    return $data_actors[@actor_id].rating
  end
end
[/rgss]
Compatibility

Shouldn't cause any incompatibility or issues anywhere.

Credits and Thanks

jjangjae for motivating me to finally do this.

Terms and Conditions

Free for any use or redistribution, just credit me.

Author's Notes

If anyone has any questions setting this up, please specify what you are trying to accomplish, and I can guide you through it.

As always, Enjoy :thumb:
 
Its a bit complicated I know, but its easy once you get the hand of it.

Ok. Post a stat you want to add, each actor id, and we'll start with a simple point-slope formula for each stat, so for each actor, their start value and the amount they gain each level.

I'll be back in a bit to help you set this up. I suggest taking a look at the example I provided and maybe you can figure it out.
 
actor_id: 001, 002, 003, 004, 005, 006, 007
Stats:
Strength- Determines stand-alone weapon attack power.
Vitality- Determines stand-alone weapon defense and a little bit of HP.
Dexterity- Determines accuracy and a bit of critical hit rate.
Agility- Determines speed and avoidability.
Intelligence- Determines stand-alone magical attack.
Spirit- Determines stand-alone magical defense and defense against special attacks.
Luck- Determines critical hit rate and some avoidability.

Is this what you need?
 
Ok. You will have to take care of algorithms and such, but this is how you could set it up. We'll use the early/late formula of the curve generator module.

[rgss]class RPG::Actor
   str = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   str.default = [1, 1, 99, min_value, max_value, early, late]
 
   vit = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   vit.default = [1, 1, 99, min_value, max_value, early, late]
 
   dex = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   dex.default = [1, 1, 99, min_value, max_value, early, late] 
 
   agi = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   agi.default = [1, 1, 99, min_value, max_value, early, late]
 
   int = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   int.default = [1, 1, 99, min_value, max_value, early, late]
 
   spr = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   spr.default = [1, 1, 99, min_value, max_value, early, late]
 
   luck = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   luck.default = [1, 1, 99, min_value, max_value, early, late]
 
   add_stat_curve('str', str)
   add_stat_curve('vit', vit)
   add_stat_curve('dex', dex)
   add_stat_curve('agi', agi)
   add_stat_curve('int', int)
   add_stat_curve('spr', spr)
   add_stat_curve(luck', luck)
end
 
class Game_Actor
 def str
   return $data_actors[@actor_id].str[@level]
 end
 def vit
   return $data_actors[@actor_id].vit[@level]
 end
 def dex
   return $data_actors[@actor_id].dex[@level]
 end
 def agi
   return $data_actors[@actor_id].agi[@level]
 end
 def int
   return $data_actors[@actor_id].int[@level]
 end
 def spr
   return $data_actors[@actor_id].spr[@level]
 end
 def luck
   return $data_actors[@actor_id].luck[@level]
 end
end
<span style="color:#996600;"
[/rgss]

Now you will have to modify the min_value, max_value, early, late values for each stat, for each character. So:
Code:
   luck = {

     1 => [1, 1, 99, min_value, max_value, early, late],
For actor 1, this is there luck stat setup. min_value is the value at level 1 (or whatever the 1 value is before the 99), max_value is the stat value at level 99 (or whatever the value is where 99 is). Early and late numbers I would test first. With the early and late values, I would try numbers between 0.5 and 1.5 (I believe, but you might have to tinker with this).

You will have to do that for each stat, for each actor. I would instead recommend using 4 of he default stats and just do this for 3 stats instead of redoing all seven.

If you want to see your values at each level, you can check with:
Code:
p $data_actors[actor_id].stat

Replace actor_id with 1-7, whichever actor you are checking and stat with str, vit, dex, agi, int, spr, or luck.

Hopefully that helped a little. I might make a system that shows a graph of values, so you can see them so you can choose the best setup.
 
Hey whoa, a script below 1000 lines of scripting from you... watch your health there, seems dangerous to me ;)

Either way, interesting thing, I can definately imagine a bunch of things doable with that addition.

As always, keep up the good work ^^
 
It was a quick 20 minute script, but something I probably should have done... 2-3 years ago.

I'w working on the table generator graph. Just some math and some window layout manipulation. Should have it done in a bit, depending if I go to bed like I should.
 
Wow. This is quite unlike you, Seph. I mean, posting an incorrect version of an already well established script? That's getting a little sloppy, if you ask me. If you aren't sure what I'm talking about, look at line 156 of the curve generator module, where it uses an undeclared variable. I'm not sure about the rest of the script, there may be other errors as well. Anyway, this is a vey interesting looking script. BTW, do you know how to get the curve generator module to work as though it were the actual RMXP curve generator? I figured out how to mimic the straight line, as well as the fastest curve, but it doesn't mimic anything else. (By fastest, I mean the default curve with the bar all the way to the left on the "fast" to "slow" scale)
 
Dumb question, but...

I'm assuming these "new" stats will require additional Scripts (below this one) in order to do things like display the "new" stats in the Menu>Status page. This just makes the new stats in the "background" and sets their progression, but it doesn't change any in-game displays or really do anything with the stats.

Right? Or am I dumb?

Because, the next logical question for me anyway, is how would you get any new stats to display properly in the Menu>Status page?
 
@Glitch: Yeah I noticed it. I just got back home and had next to little time to test this out. I pulled the module from an older project where I thought I fixed that, but apparently I didn't fix it in that project (so many damn project folders).

I am working on adding a few new curve generators, 1 being the exp growth and 2 being the base stat curves. I honestly haven't even looked at that module since Trickster and I developed it nearly two years ago.

@Nearly Infinite: Your right. This script simply adds a method that creates and reads curves, vs. doing it.

It depends on how you plan on using these attributes. For things like new stats for actors, you will have to add the stat in the RPG::Actor class, make a method to read the stat (usually depending on level, as shown in luck example from above and finally, reading that method and drawing it on the window. Using the example from the main post, you would go into Window_Status, and somewhere like under draw_actor_parameter(@actor, 96, 400, 6), you would have to add:
[rgss]    self.contents.font.color = system_color
    self.contents.draw_text(96, 432, 120, 32, 'Luck')
    self.contents.font.color = normal_color
    self.contents.draw_text(96 + 120, 432, 36, 32, @actor.luck.to_s, 2)
[/rgss]

Because of the number of things this can be used for, it couldn't really auto-draw newly added stats, because you could add these stats to basically any object. This method is really just an over-complicated attr_reader type method.
 
Nearly Infinite":225zv633 said:
Dumb question, but...

I'm assuming these "new" stats will require additional Scripts (below this one) in order to do things like display the "new" stats in the Menu>Status page. This just makes the new stats in the "background" and sets their progression, but it doesn't change any in-game displays or really do anything with the stats.

Right? Or am I dumb?

Because, the next logical question for me anyway, is how would you get any new stats to display properly in the Menu>Status page?

Well, you are right. To get them to display in the stats page, you'll have to edit that script. That requires changing some coordinates to make room (or font sizes), then inserting similar code to show the new stats.

Edit: it looks like Sephy beat me to the punch. You do that a lot when I'm not really paying attention.
 
SephirothSpawn":1v3a033i said:
Ok. You will have to take care of algorithms and such, but this is how you could set it up. We'll use the early/late formula of the curve generator module.

[rgss]class RPG::Actor
   str = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   str.default = [1, 1, 99, min_value, max_value, early, late]
 
   vit = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   vit.default = [1, 1, 99, min_value, max_value, early, late]
 
   dex = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   dex.default = [1, 1, 99, min_value, max_value, early, late] 
 
   agi = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   agi.default = [1, 1, 99, min_value, max_value, early, late]
 
   int = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   int.default = [1, 1, 99, min_value, max_value, early, late]
 
   spr = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   spr.default = [1, 1, 99, min_value, max_value, early, late]
 
   luck = {
     1 => [1, 1, 99, min_value, max_value, early, late],
     2 => [1, 1, 99, min_value, max_value, early, late],
     3 => [1, 1, 99, min_value, max_value, early, late],
     4 => [1, 1, 99, min_value, max_value, early, late],
     5 => [1, 1, 99, min_value, max_value, early, late],
     6 => [1, 1, 99, min_value, max_value, early, late],
     7 => [1, 1, 99, min_value, max_value, early, late]
   }
   luck.default = [1, 1, 99, min_value, max_value, early, late]
 
   add_stat_curve('str', str)
   add_stat_curve('vit', vit)
   add_stat_curve('dex', dex)
   add_stat_curve('agi', agi)
   add_stat_curve('int', int)
   add_stat_curve('spr', spr)
   add_stat_curve(luck', luck)
end
 
class Game_Actor
 def str
   return $data_actors[@actor_id].str[@level]
 end
 def vit
   return $data_actors[@actor_id].vit[@level]
 end
 def dex
   return $data_actors[@actor_id].dex[@level]
 end
 def agi
   return $data_actors[@actor_id].agi[@level]
 end
 def int
   return $data_actors[@actor_id].int[@level]
 end
 def spr
   return $data_actors[@actor_id].spr[@level]
 end
 def luck
   return $data_actors[@actor_id].luck[@level]
 end
end
 
<span style="color:#996600;"
[/rgss]

Now you will have to modify the min_value, max_value, early, late values for each stat, for each character. So:
Code:
   luck = {

     1 => [1, 1, 99, min_value, max_value, early, late],
For actor 1, this is there luck stat setup. min_value is the value at level 1 (or whatever the 1 value is before the 99), max_value is the stat value at level 99 (or whatever the value is where 99 is). Early and late numbers I would test first. With the early and late values, I would try numbers between 0.5 and 1.5 (I believe, but you might have to tinker with this).

You will have to do that for each stat, for each actor. I would instead recommend using 4 of he default stats and just do this for 3 stats instead of redoing all seven.

If you want to see your values at each level, you can check with:
Code:
p $data_actors[actor_id].stat

Replace actor_id with 1-7, whichever actor you are checking and stat with str, vit, dex, agi, int, spr, or luck.

Hopefully that helped a little. I might make a system that shows a graph of values, so you can see them so you can choose the best setup.

So let's say I modify luck. If I edit the code this way for explanation purposes:
x => [1, 1, 99, min_value, max_value, early, late]
2 => [1, 1, 99, min_value, max_value, early, late]

The 'x' would be the level of the character? And inside the brackets, the first number represents min_value, the second max_value, and the third what? I think if I knew what those represent I would understand it more clearly.
By the way, I'm not sure I see it in the script, but each attribute affects things like attack power, speed, defense, and so forth, correct?
 
x would be the actor id.

The numbers between the [] are all curve generators parameters. First number being the type, and the trailing numbers being specific algorithm parameters. You can see from the script heading:
Code:
# #   Type : 0 - Point Slope

#          1 - Early / Late

#          2 - Early / Steady / Late + Curves

#

#   Args :

#

#    Type 0 : min_level, max_level, start value, inflation

#    Type 1 : min_level, max_level, min_value, max_value, early, late

#    Type 2 : min level, mid_level, max level, min value, mid_value,

#             max value, early, late, steady, curve 1, curve 2, integer

The first number (1) represents which curve generator algorithm you will be using (0- Point-Slope, 1-Early Late, 2-Early, Mid, Late)

So, if you are using 0, your [] will look like:
Code:
x => [0, min_level, max_level, start value, inflation]

If you are using 1, your [] will look like:

[code]x => [1, min_level, max_level, min_value, max_value, early, late]

If you are using 2, your [] will look like:
Code:
x => [2, min level, mid_level, max level, min value, mid_value, max value, early, late, steady, curve 1, curve 2, integer]

I suggest you just use type 0 or 1, as those will be better suited for you.

I am going to add the exp and stat base algorithms as soon as I can.
 

Dko

Member

Hemm I wanted to try out this script by using the luck example. But for some reason I get the error when I have an event on my map that calls $game_actors[1].stam ( I'm using the method print). The error being "undefined local variable or method 'hash_settings' for #<RPG::Actor:0x1505198>

This is my script thats right bellow the Curve Generator and Attribute Modifier scripts.
[ruby] 
class RPG::Actor
  stam = {
    1 => [0, 1, 99, 5, 1],
    2 => [0, 1, 99, 4, 2],
    7 => [0, 1, 99, 2, 4],
    8 => [0, 1, 99, 1, 5],
  }
  stam.default = [0, 1, 99, 3, 3]
  add_stat_curve('stam', stam)
end
 
 
class Game_Actor
  def stam
    return $data_actors[@actor_id].stam[@level]
  end  
end
 
[/ruby]

Did I put something in the wrong order? I can't figure out what could be causing the problem in the least. (Doesn't help I'm not the most experienced in Ruby)

EDIT: Here is an image of some info my companion in this endeavor printed that he says might shed some light on things.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top