#==============================================================================
# ** Modules.Curve Generator Module (4.0) 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, ... }
#==============================================================================
MACL::Loaded << 'Modules.Curve_Generator'
#==============================================================================
# ** 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_level, 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 level in min_l..max_l
# Assigns Value
table[i] = 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