Jeff the Green
Member
Jeff's Utilities Version: 1.1
By: Jeff the Green (Bearcat)
Introduction
This is a collection of utilities I wrote for my own use and will be necessary for most scripts I release post 2010. Until they're a part of the MACL, they'll be available as the standalone script here.
Features
The current list of methods is:
Screenshots
This is a bunch of scripting utilities, so it's hard to do a screenshot. If someone can think of one they'd like to see, I'll post it.
Script
Instructions
Put below SDK (not required) and the MACL (required), and above any of my scripts.
Method specific (included in comments, but these are more explicit instructions for less-experienced scripters):
By: Jeff the Green (Bearcat)
Introduction
This is a collection of utilities I wrote for my own use and will be necessary for most scripts I release post 2010. Until they're a part of the MACL, they'll be available as the standalone script here.
Features
The current list of methods is:
- Array.average: returns the arithmetic mean (average) of all numeric elements of the array.
- Array.geommean: returns the geometric mean of all positive numeric elements of the array.
- Array.harmmean: returns the harmonic mean of all positive numeric elements of the array.
- Array.permute: returns a random permutation of the array.
- Array.permute!: permutes self.
- Bitmap.draw_formatted_text_jeff: draws formatted text using many of the same codes as ccoa's UMS.
- Bitmap.formatted_text_height_jeff: determines the height of formatted text with a certain width.
- JeffUtilities.normal: generates a random number from a normal distribution.
- JeffUtilities.pseudorand: generates a pseudorandom number using a seed stored in $game_system.
Screenshots
This is a bunch of scripting utilities, so it's hard to do a screenshot. If someone can think of one they'd like to see, I'll post it.
Script
Ruby:
<span style="color:#000080; font-style:italic;">=begin
<span style="color:#000080; font-style:italic;">==============================================================================
<span style="color:#000080; font-style:italic;"> ●● Jeff's Utility functions
<span style="color:#000080; font-style:italic;">------------------------------------------------------------------------------
<span style="color:#000080; font-style:italic;"> Jeff the Green
<span style="color:#000080; font-style:italic;"> Version 1.1
<span style="color:#000080; font-style:italic;">
<span style="color:#000080; font-style:italic;">------------------------------------------------------------------------------
<span style="color:#000080; font-style:italic;">
<span style="color:#000080; font-style:italic;"> Version notes
<span style="color:#000080; font-style:italic;"> ----------------
<span style="color:#000080; font-style:italic;"> New methods:
<span style="color:#000080; font-style:italic;"> Array.average: returns the arithmetic mean (average) of all numeric
<span style="color:#000080; font-style:italic;"> elements of the array.
<span style="color:#000080; font-style:italic;"> Array.geommean: returns the geometric mean of all positive numeric
<span style="color:#000080; font-style:italic;"> elements of the array.
<span style="color:#000080; font-style:italic;"> Array.harmmean: returns the harmonic mean of all positive numeric
<span style="color:#000080; font-style:italic;"> elements of the array.
<span style="color:#000080; font-style:italic;"> Array.permute: returns a random permutation of the array.
<span style="color:#000080; font-style:italic;"> Array.permute!: permutes self.
<span style="color:#000080; font-style:italic;"> Bitmap.formatted_text_height_jeff: determines the height of formatted
<span style="color:#000080; font-style:italic;"> text with a certain width.
<span style="color:#000080; font-style:italic;">
<span style="color:#000080; font-style:italic;"> Deprecated methods:
<span style="color:#000080; font-style:italic;"> JeffUtilities.permutation: Replaced by Array.permute
<span style="color:#000080; font-style:italic;">
<span style="color:#000080; font-style:italic;">==============================================================================
<span style="color:#000080; font-style:italic;">=end
class JeffUtilities
#-------------------------------------------------------------------------
# * Normal distribution
# Returns a floating-point number drawn from a
# normal distribution. If no *args, uses standard distribution.
#
# mean : mean of distribution
# stdev : standard deviation of distribution
#-------------------------------------------------------------------------
def self.normal(mean = 0, stdev = 1)
w = 2
while w >= 1 # Generate standard normal distribution
x1 = 2.0 * rand() - 1.0
x2 = 2.0 * rand() - 1.0
w = x1 ** 2 + x2 ** 2
end
w = Math.sqrt((-2.0 * Math.log(w)) / w)
w = w * stdev + mean #Convert to n(mean, stdev)
return w
end
#-------------------------------------------------------------------------
# * Pseudorandom number
# Returns a random number generated using the seed stored in
# $game_system.pseudorandom_seed, updates
# $game_system.pseudorandom_seed, and re-randomizes the random seed used
# by rand.
#
# max : the maximum of the pseudorandom number. If 0 will return a
# floating point number between 0 and 1
#-------------------------------------------------------------------------
def self.pseudorand(max = 0)
srand($game_system.pseudorandom_seed) #set random seed
bigrandom = rand(4294967294) + 1 #generate random 32-bit integer
if max == 0
pseudorand = (bigrandom - 1) / 4294967294.0
else
pseudorand = bigrandom % (max + 1)
end
$game_system.pseudorandom_seed = bigrandom
srand
return pseudorand
end
#-------------------------------------------------------------------------
# * Permutation
# Returns a random permutation of an array
#
# ary : the array to be permuted
#-------------------------------------------------------------------------
def self.permutation(ary)
return ary.permute
end
end
#==============================================================================
# ** Array
#==============================================================================
class Array
#-------------------------------------------------------------------------
# * Permutation
# Returns a random permutation of self
#-------------------------------------------------------------------------
def permute
ary = self.dup
permutation = []
while ary != []
index = rand(ary.size)
permutation.push(ary[index]) # add object to permutation
ary.delete_at(index)
end
return permutation
end
#-------------------------------------------------------------------------
# * Permutation
# Permutes self as Array.permute, returns self
#-------------------------------------------------------------------------
def permute!
old_ary = self.dup
self.replace(self.permutation)
return old_ary
end
#-------------------------------------------------------------------------
# * Average
# Returns the arithmetic mean of all numeric elements;
# nil if no such elements
#-------------------------------------------------------------------------
def average
count = 0
sum = 0.0
for i in self
if i.is_a? Numeric
count += 1
sum += i
end
end
return count > 0 ? sum / count : nil
end
#-------------------------------------------------------------------------
# * Geometric Mean
# Returns the geometric mean of all positive numeric elements;
# nil if no such elements
#-------------------------------------------------------------------------
def geommean
count = 0
sum = 0.0
for i in self
if i.is_a? Numeric and i > 0
count += 1
sum += Math.log(i)
end
end
return count > 0 ? Math.exp(sum / count) : nil
end
#-------------------------------------------------------------------------
# * Harmonic Mean
# Returns the harmonic mean of all positive numeric elements;
# nil if no such elements
#-------------------------------------------------------------------------
def harmmean
count = 0
sum = 0.0
for i in self
if i.is_a? Numeric and i > 0
count += 1
sum += (i.is_a Float) ? i ** -1 : i.to_f ** -1
end
end
return count > 0 ? count / sum : nil
end
end
#==============================================================================
# ** Bitmap
#==============================================================================
class Bitmap
#--------------------------------------------------------------------------
# Name : Draw Formatted Text
# Info : Draws Formatted Wrapped Text
# Author : JeffTheGreen
# Call Info : Five Arguments
# Integer Offset_x and Offset_Y, define starting position
# Integer Width, defines the width of the text rectangle
# Integer Height, defines the height of the text drawn
# String Text, The text to be drawn
# Comment : \c[0xrrggbb] -> Change Color values are in hex
# \c[i] -> Change text color
# \b -> Turns on/off Bold
# \i -> Turns on/off Italics
# \s -> Turns on/off shadow
# \o -> Turns on/off outline
# \font[name] -> changes font
# \oa[i] -> displays armor
# \oi -> displays item
# \os -> displays skill
# \ow -> displays weapon
#-------------------------------------------------------------------------
def draw_formatted_text_jeff(x, y, width, height, text)
old_font = self.font
last_color = self.font.color
line_height = 0
# Set to Normal Color (White)
self.font.color = Color.new(255, 255, 255)
# Make Copy of Text Sent
text = text.dup
# Change "\\C" to "\001"
text.gsub!(/\\[Nn]/) { '\012' }
text.gsub!(/\\[Cc]\[0x([A-F a-f 0-9]+)\]/) {" \001[#{$1}] "}
text.gsub!(/\\[Cc]\[[Ll][Aa][Ss][Tt]\]/) {'\013'}
text.gsub!(/\\[Cc]\[([0-9])\]/) {" \002[#{$1}] "}
# armor, items, skills, and weapons
text.gsub!(/\\[Oo][Aa]\[([0-9]+)\]/) {
item = $data_armors[$1.to_i]
"\008[#{$1}]" + " " + item.name
}
text.gsub!(/\\[Oo][Ii]\[([0-9]+)\]/) {
item = $data_items[$1.to_i]
"\009[#{$1}]" + " " + item.name
}
text.gsub!(/\\[Oo][Ss]\[([0-9]+)\]/) {
item = $data_skills[$1.to_i]
"\010[#{$1}]" + " " + item.name
}
text.gsub!(/\\[Oo][Ww]\[([0-9]+)\]/) {
item = $data_weapons[$1.to_i]
"\\011[#{$1}]" + " " + item.name
}
# bold and italics
text.gsub!(/\\[Bb]/) { "\003" }
text.gsub!(/\\[Ii]/) { "\004" }
# shadow
text.gsub!(/\\[Ss]/) { "\005" }
# outline
text.gsub!(/\\[Oo]/) { "\006" }
# font
text.gsub!(/\\[Ff][Oo][Nn][Tt]\[(.*?)\]/) { "\007[#{$1}]" }
# Setup Cx and Cy
cx, cy = 0, 0
# Setup outline and shadow
outline, shadow = false, false
# Run Through each text
text.split(/\s/).each do |word|
# If String \001 is included
if word.include?("\001")
# Slice from String
word.slice!("\001")
# Change text color
word.sub!(/\[([A-F a-f 0-9]+)\]/, '')
# If matched is not nil and size of match is > 1
if $1 != nil and $1.size > 1
# Create Color
color = Color.new($1[0..1].hex, $1[2..3].hex, $1[4..5].hex)
else
# Normal Color
color = old_font.color
end
# Set Color
last_color = self.font.color.dup
self.font.color = color
# Go to next text
next
end
if word.include?("\002")
# Slice from String
word.slice!("\002")
# Change text color
word.sub!(/\[([0-9])\]/, '')
# If matched is not nil and size of match is > 1
if $1 != nil
# Create Color
color = text_color($1.to_i)
else
# old Color
color = old_font.color
end
# Set Color
last_color = self.font.color.dup
self.font.color = color
# Go to next text
next
end
# If String \003 is included
if word.include?("\003")
# Invert Bold Status
self.font.bold = !self.font.bold
# Go to next text
next
end
# If String \004 is included
if word.include?("\004")
# Invert Italic Status
self.font.italic = !self.font.italic
# Go to next text
next
end
# If String \005 is included
if word.include?("\005")
# Invert outline
self.font.shadow = !self.font.shadow
# Go to next text
next
end
# If String \006 is included
if word.include?("\006")
# Invert outline
outline = !outline
# Go to next text
next
end
if word.include?("\007")
# Slice from String
word.slice!("\001")
# Change font
word.sub!(/\[(.*?)\]/, "")
font = $1.to_s
if font == ""
self.font.name = old_font
else
self.font.name = font
end
# go to next text
next
end
if word.include?("\008")
# Slice from String
word.slice!("\007")
word.sub!(/\[([0-9]+)\]/, "")
index = $1.to_i
item = $data_armors[index]
# draw the icon
icon = RPG::Cache.icon(item.icon_name)
self.blt(cx + x + 4, cy + y + 4, icon, Rect.new(0, 0, 24, 24))
cx += 28
next
end
if word.include?("\009")
# Slice from String
word.slice!("\008")
word.sub!(/\[([0-9]+)\]/, "")
index = $1.to_i
item = $data_items[index]
# draw the icon
icon = RPG::Cache.icon(item.icon_name)
self.blt(cx + x + 4, cy + y + 4, icon, Rect.new(0, 0, 24, 24))
cx += 28
next
end
if word.include?('\010')
# Slice from String
word.slice!("\009")
word.sub!(/\[([0-9]+)\]/, "")
index = $1.to_i
item = $data_skills[index]
# draw the icon
icon = RPG::Cache.icon(item.icon_name)
self.blt(cx + x + 4, cy + y + 4, icon, Rect.new(0, 0, 24, 24))
cx += 28
next
end
if word.include?('\\011')
# Slice from String
word.slice!("\010")
word.sub!(/\[([0-9]+)\]/, "")
index = $1.to_i
item = $data_weapons[index]
# draw the icon
icon = RPG::Cache.icon(item.icon_name)
self.blt(cx + x + 4, cy + y + 4, icon, Rect.new(0, 0, 24, 24))
cx += 28
next
end
# If String \012 is included
if word.include?('\012')
# Move to new line
cy = cy + line_height
# Move to start
cx = 0
# Go to next text
next
end
if word.include?('\013')
# set color to last used
self.font.color = last_color
next
end
# Get Word Width
word_width = text_size("#{word} ").width
word_height = text_size("#{word} ").height
line_height = [line_height, word_height].max
# If can't fit on line
if (cx + word_width) > width
# Move to new line
cy = cy + line_height
# Move to start
cx = 0
end
# Get Draw X
dx = cx + x
# Get Draw Y
dy = cy + y
# Draw Text
if outline
draw_text_outline(dx, dy, word_width, 32, word)
end
draw_text(dx, dy, word_width, 32, word)
# Increase by Word Width
cx += word_width
self.font = old_font
end
end
#--------------------------------------------------------------------------
# Name : Formatted Text Size
# Info : Returns the size (height) of the formatted text at a
# given width
# Author : JeffTheGreen
# Call Info : Five Arguments
# Integer Offset_x and Offset_Y, define starting position
# Integer Width, defines the width of the text rectangle
# Integer Height, defines the height of the text drawn
# String Text, The text to be drawn
# Comment : \c[0xrrggbb] -> Change Color values are in hex
# \c[i] -> Change text color
# \b -> Turns on/off Bold
# \i -> Turns on/off Italics
# \s -> Turns on/off shadow
# \o -> Turns on/off outline
# \font[name] -> changes font
# \oa[i] -> displays armor
# \oi -> displays item
# \os -> displays skill
# \ow -> displays weapon
#-------------------------------------------------------------------------
def formatted_text_height_jeff(width, text)
old_font = self.font
last_color = self.font.color
line_height = 0
# Set to Normal Color (White)
self.font.color = Color.new(255, 255, 255)
# Make Copy of Text Sent
text = text.dup
# Change "\\C" to "\001"
text.gsub!(/\\[Nn]/) { '\012' }
text.gsub!(/\\[Cc]\[0x([A-F a-f 0-9]+)\]/) {" \001[#{$1}] "}
text.gsub!(/\\[Cc]\[[Ll][Aa][Ss][Tt]\]/) {'\013'}
text.gsub!(/\\[Cc]\[([0-9])\]/) {" \002[#{$1}] "}
# armor, items, skills, and weapons
text.gsub!(/\\[Oo][Aa]\[([0-9]+)\]/) {
item = $data_armors[$1.to_i]
"\008[#{$1}]" + " " + item.name
}
text.gsub!(/\\[Oo][Ii]\[([0-9]+)\]/) {
item = $data_items[$1.to_i]
"\009[#{$1}]" + " " + item.name
}
text.gsub!(/\\[Oo][Ss]\[([0-9]+)\]/) {
item = $data_skills[$1.to_i]
"\010[#{$1}]" + " " + item.name
}
text.gsub!(/\\[Oo][Ww]\[([0-9]+)\]/) {
item = $data_weapons[$1.to_i]
"\\011[#{$1}]" + " " + item.name
}
# bold and italics
text.gsub!(/\\[Bb]/) { "\003" }
text.gsub!(/\\[Ii]/) { "\004" }
# shadow
text.gsub!(/\\[Ss]/) { "\005" }
# outline
text.gsub!(/\\[Oo]/) { "\006" }
# font
text.gsub!(/\\[Ff][Oo][Nn][Tt]\[(.*?)\]/) { "\007[#{$1}]" }
# Setup Cx and Cy
cx, cy = 0, 0
# Setup outline and shadow
outline, shadow = false, false
# Run Through each text
text.split(/\s/).each do |word|
# If String \001 is included
if word.include?("\001")
# Slice from String
word.slice!("\001")
# Change text color
word.sub!(/\[([A-F a-f 0-9]+)\]/, '')
# If matched is not nil and size of match is > 1
if $1 != nil and $1.size > 1
# Create Color
color = Color.new($1[0..1].hex, $1[2..3].hex, $1[4..5].hex)
else
# Normal Color
color = old_font.color
end
# Set Color
last_color = self.font.color.dup
self.font.color = color
# Go to next text
next
end
if word.include?("\002")
# Slice from String
word.slice!("\002")
# Change text color
word.sub!(/\[([0-9])\]/, '')
# If matched is not nil and size of match is > 1
if $1 != nil
# Create Color
color = text_color($1.to_i)
else
# old Color
color = old_font.color
end
# Set Color
last_color = self.font.color.dup
self.font.color = color
# Go to next text
next
end
# If String \003 is included
if word.include?("\003")
# Invert Bold Status
self.font.bold = !self.font.bold
# Go to next text
next
end
# If String \004 is included
if word.include?("\004")
# Invert Italic Status
self.font.italic = !self.font.italic
# Go to next text
next
end
# If String \005 is included
if word.include?("\005")
# Invert outline
self.font.shadow = !self.font.shadow
# Go to next text
next
end
# If String \006 is included
if word.include?("\006")
# Invert outline
outline = !outline
# Go to next text
next
end
if word.include?("\007")
# Slice from String
word.slice!("\001")
# Change font
word.sub!(/\[(.*?)\]/, "")
font = $1.to_s
if font == ""
self.font.name = old_font
else
self.font.name = font
end
# go to next text
next
end
if word.include?("\008")
# Slice from String
word.slice!("\007")
word.sub!(/\[([0-9]+)\]/, "")
index = $1.to_i
item = $data_armors[index]
# draw the icon
icon = RPG::Cache.icon(item.icon_name)
self.blt(cx + 4, cy + 4, icon, Rect.new(0, 0, 24, 24))
cx += 28
next
end
if word.include?("\009")
# Slice from String
word.slice!("\008")
word.sub!(/\[([0-9]+)\]/, "")
index = $1.to_i
item = $data_items[index]
# draw the icon
icon = RPG::Cache.icon(item.icon_name)
self.blt(cx + 4, cy + 4, icon, Rect.new(0, 0, 24, 24))
cx += 28
next
end
if word.include?('\010')
# Slice from String
word.slice!("\009")
word.sub!(/\[([0-9]+)\]/, "")
index = $1.to_i
item = $data_skills[index]
# draw the icon
icon = RPG::Cache.icon(item.icon_name)
self.blt(cx + 4, cy + 4, icon, Rect.new(0, 0, 24, 24))
cx += 28
next
end
if word.include?('\\011')
# Slice from String
word.slice!("\010")
word.sub!(/\[([0-9]+)\]/, "")
index = $1.to_i
item = $data_weapons[index]
# draw the icon
icon = RPG::Cache.icon(item.icon_name)
self.blt(cx + 4, cy + 4, icon, Rect.new(0, 0, 24, 24))
cx += 28
next
end
# If String \012 is included
if word.include?('\012')
# Move to new line
cy = cy + line_height
# Move to start
cx = 0
# Go to next text
next
end
if word.include?('\013')
# set color to last used
self.font.color = last_color
next
end
# Get Word Width
word_width = text_size("#{word} ").width
word_height = text_size("#{word} ").height
line_height = [line_height, word_height].max
# If can't fit on line
if (cx + word_width) > width
# Move to new line
cy = cy + line_height
# Move to start
cx = 0
end
# Increase by Word Width
cx += word_width
self.font = old_font
end
return cy + line_height
end
#--------------------------------------------------------------------------
# * Get Text Color
# n : text color number (0-7)
#--------------------------------------------------------------------------
def text_color(n)
case n
when 0
return Color.new(255, 255, 255, 255)
when 1
return Color.new(128, 128, 255, 255)
when 2
return Color.new(255, 128, 128, 255)
when 3
return Color.new(128, 255, 128, 255)
when 4
return Color.new(128, 255, 255, 255)
when 5
return Color.new(255, 128, 255, 255)
when 6
return Color.new(255, 255, 128, 255)
when 7
return Color.new(192, 192, 192, 255)
else
normal_color
end
end
end
Instructions
Put below SDK (not required) and the MACL (required), and above any of my scripts.
Method specific (included in comments, but these are more explicit instructions for less-experienced scripters):
Call using ary.average. Returns the arithmetic mean of all numeric elements of ary.
Call using ary.geommean. Returns the geometric mean of all positive numeric elements of ary.
Call using ary.harmmean. Returns the harmonic mean of all positive numeric elements of ary.
Call using ary.permute. Returns a random permutation of ary.
Call using ary.permute. Replaces the contents of ary with a random permutation of ary and returns the non-permuted version of ary.
Call using btmp.draw_formatted_text_jeff(x, y, width, height, text). x and y are the x and y coordinates of the top left corner of the text block. width is the width of the text block (the text is wrapped, left aligned). text is the text to be drawn. You can use the following codes:
- \c[0xrrggbb] or \c[n] -> changes the color of the text to a hex value or the font color n (same colors as the [Show Text] event command)
- \c[last] -> changes the color of the text to the last color used.
- \b -> toggles bold
- \i -> toggle italics
- \s -> toggles text shadow
- \o -> toggles text outline
- \font
Call using btmp.formatted_text_height_jeff(width, text). width is the width of the text block (the text is wrapped, left aligned). text is the text to be drawn. You can use the same codes as in Bitmap.draw_formatted_text_jeff
Call using JeffUtilities.normal(mean, stdv). Returns a random number drawn from the normal distribution with mean = mean and standard deviation = stdv. Will always return a float, so script accordingly. If called without arguments, will assume a standard normal deviation (mean = 0, stdv = 1).
Call using JeffUtilities.pseudorand(max). Returns a pseudorandom number between 0 and max. If called without arguments, will return a random float between 0 and 1, inclusive. The seed is set when $game_system is initialized, updated when JeffUtilities.pseudorand() is called, and can be accessed via $game_system.pseudorandom_seed
Call using JeffUtilities.permutation(array). Returns a random permutation of array.
Compatibility
Unless you have a class named "JeffUtilities," or methods in Bitmap called "draw_formatted_text_jeff" or "formatted_text_height_jeff" (which would, quite frankly, be weird), I foresee no problems.
Credits and Thanks
The Bitmap.draw_formatted_text_jeff method is based on Trickster's draw_formatted_text in the MACL and uses codes inspired by ccoa's UMS.
Author's Notes
I'll be updating this as I come up with new or better methods; anything that requires this script will specify the version number.
Terms and Conditions
Feel free to use these scripts in games however you like, with or without attribution. If you redistribute it without significant modifications, however, please leave the starting comment (the bit between "=begin" and "=end") as is and link back to this page.">