#==============================================================================
# MOONPEARL'S COMMON STUFF
#==============================================================================
#------------------------------------------------------------------------------
# Overview
#------------------------------------------------------------------------------
# This script contains custom functions I use quite often, so instead of
# making copies for each script I write, I put them all here. Everything is
# needed to make this or that script of mine work - and is pretty useful for
# scripters anyway. If you're experiencing compatibility problems, or are not
# sure about a particular feature, please refer to its description.
# If you use any of those as a basis for your own script, consider it a
# giveaway. Express credit is not required, but is appreciated. Otherwise, a
# warm-hearted thank you will do.
# Cheers,
# Moonpearl (moonpearl12@gmail.com)
# http://moonpearl-gm.blogspot.com/
#------------------------------------------------------------------------------
# Table of Contents
#------------------------------------------------------------------------------
# NOTES -
# - Tweaks are completely safe since they do not modify any existing code
# - Classes are safe too because they are new to Ruby and RGSS code
# - Mods are relatively safe but might possibly cause issues - refer to the
# entry's description for more information.
#------------------------------------------------------------------------------
# 050 - Buffer (tweak)
# 085 - Message Expression Evaluator (Window_Message mod)
# 207 - Automatic Windowskins (Window_Base mod)
# 240 - Automatic Transitions (Scene_Base mod)
# 289 - Variables & Switches Commands (Interpreter mod)
# 325 - Bitmask (class)
# 426 - Ruby Expansion (tweak)
# 536 - Dialog Boxes (tweak)
#------------------------------------------------------------------------------
#==============================================================================
#==============================================================================
# BUFFERS
#------------------------------------------------------------------------------
# This sets variables and switches to serve as buffers and hold temporary
# information.
#==============================================================================
# Index of the temporary buffer variable
VAR_TEMP = 1
# Index of the temporary buffer switch
SW_TEMP = 1
# Retrieve the buffer variable
def temp
return $game_variables[VAR_TEMP]
end
# Set the buffer variable
def set_temp(v)
$game_variables[VAR_TEMP] = v
return $game_variables[VAR_TEMP]
end
# Retrieve the buffer switch
def sw_temp
return $game_switches[SW_TEMP]
end
# Set the buffer switch
def set_sw_temp(v)
$game_switches[SW_TEMP] = v
return $game_switches[SW_TEMP]
end
#==============================================================================
# MESSAGE EXPRESSION EVALUATOR
#------------------------------------------------------------------------------
# This edit allows to display the result of Ruby expressions written directly
# in Show Message event commands using \f[<expression>].
#------------------------------------------------------------------------------
# > EXAMPLE: "Three plus two is \f[3+2]." will be displayed as "Three plus
# two is 5."
#------------------------------------------------------------------------------
# Most likely incompatible with any custom message systems. Simply remove this
# section if you have no use for it, or copy the outlined command to your
# custom Window_Message class.
#==============================================================================
class Window_Message < Window_Selectable
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
self.contents.font.color = normal_color
x = y = 0
@cursor_width = 0
# Indent if choice
if $game_temp.choice_start == 0
x = 8
end
# If waiting for a message to be displayed
if $game_temp.message_text != nil
text = $game_temp.message_text
# Control text processing
begin
last_text = text.clone
text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
end until text == last_text
text.gsub!(/\\[Nn]\[([0-9]+)\]/) do
$game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
end
#--------------------------------------------------------------------------
text.gsub!(/\\[Ff]\[([ \w\=\+\-\*\/\$\(\)\!\.\,\'\:\%\@]+)\]/) { eval $1 }
#--------------------------------------------------------------------------
# Change "\\\\" to "\000" for convenience
text.gsub!(/\\\\/) { "\000" }
# Change "\\C" to "\001" and "\\G" to "\002"
text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
text.gsub!(/\\[Gg]/) { "\002" }
# Get 1 text character in c (loop until unable to get text)
while ((c = text.slice!(/./m)) != nil)
# If \\
if c == "\000"
# Return to original text
c = "\\"
end
# If \C[n]
if c == "\001"
# Change text color
text.sub!(/\[([0-9]+)\]/, "")
color = $1.to_i
if color >= 0 and color <= 7
self.contents.font.color = text_color(color)
end
# go to next text
next
end
# If \G
if c == "\002"
# Make gold window
if @gold_window == nil
@gold_window = Window_Gold.new
@gold_window.x = 560 - @gold_window.width
if $game_temp.in_battle
@gold_window.y = 192
else
@gold_window.y = self.y >= 128 ? 32 : 384
end
@gold_window.opacity = self.opacity
@gold_window.back_opacity = self.back_opacity
end
# go to next text
next
end
# If new line text
if c == "\n"
# Update cursor width if choice
if y >= $game_temp.choice_start
@cursor_width = [@cursor_width, x].max
end
# Add 1 to y
y += 1
x = 0
# Indent if choice
if y >= $game_temp.choice_start
x = 8
end
# go to next text
next
end
# Draw text
self.contents.draw_text(4 + x, 32 * y, 40, 32, c)
# Add x to drawn text width
x += self.contents.text_size(c).width
end
end
# If choice
if $game_temp.choice_max > 0
@item_max = $game_temp.choice_max
self.active = true
self.index = 0
end
# If number input
if $game_temp.num_input_variable_id > 0
digits_max = $game_temp.num_input_digits_max
number = $game_variables[$game_temp.num_input_variable_id]
@input_number_window = Window_InputNumber.new(digits_max)
@input_number_window.number = number
@input_number_window.x = self.x + 8
@input_number_window.y = self.y + $game_temp.num_input_start * 32
end
end
end
# ==============================================================================
# AUTOMATIC WINDOWSKINS
# ------------------------------------------------------------------------------
# Modifies the Window_Base class so that each type of window searches the
# windowskin folder for a specific windowskin, selects it if found, selects
# the default windowskin otherwise.
# ------------------------------------------------------------------------------
# EXAMPLE: the Window_Menu will search for Windowskins/Menu.png and automatically
# use it if it exists.
# ==============================================================================
class Window_Base < Window
def initialize(x, y, width, height)
super()
#--------------------------------------------------------------------------
str = type.to_s
str.slice!("Window_")
@windowskin_name = FileTest.exist?("Graphics/Windowskins/#{str}.png") ? str : $game_system.windowskin_name
#--------------------------------------------------------------------------
self.windowskin = RPG::Cache.windowskin(@windowskin_name)
self.x = x
self.y = y
self.width = width
self.height = height
self.z = 100
end
def update
super
end
end
# ==============================================================================
# AUTOMATIC TRANSITIONS
# ------------------------------------------------------------------------------
# Modifies the Scene_Base class so that each type of scene searches the
# transition folder for a specific transition, selects it if found, selects
# the default transition otherwise. You may use a different transition for
# fade-in and fade-out.
# ------------------------------------------------------------------------------
# EXAMPLE: the Scene_Menu will search for Transitions/Menu.png and automatically
# use it if it exists.
# EXAMPLE 2: when exiting the menu, the Scene_Menu will search for
# Transitions/Menu-out.png and automatically use it if it exists.
# ------------------------------------------------------------------------------
# REQUIRES: Moonpearl's Scene_Base
# ==============================================================================
class Scene_Base
def main
setup
str = type.to_s
str.slice!("Scene_")
# Execute transition
if FileTest.exist?("Graphics/Transitions/#{str}.png")
Graphics.transition(40, "Graphics/Transitions/" + str)
else
Graphics.transition
end
# Main loop
while $scene == self
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
end
terminate
str = type.to_s
str.slice!("Scene_")
str += "-out"
# Execute transition
if FileTest.exist?("Graphics/Transitions/#{str}.png")
Graphics.transition(40, "Graphics/Transitions/" + str)
Graphics.freeze
end
end
end
# ==============================================================================
# VARIABLES & SWITCHES COMMANDS
# ------------------------------------------------------------------------------
# This allows to bind commands to changes in game variables by events.
# ------------------------------------------------------------------------------
# EXAMPLE: by entering the following, the first actor's HP will automatically
# change to the content of game variable #0001 each time the variable is
# changed via an event.
# $variables_command[1] = Proc.new { |v| $game_actors[1].hp = v }
# ==============================================================================
$switches_command = {}
$variables_command = {}
class Interpreter
alias mp_common_command_121 command_121
def command_121
mp_common_command_121
for i in @parameters[0]..@parameters[1]
unless $switches_command[i].nil?
$variables_command[i].call($game_switches[i])
end
end
end
alias mp_common_command_122 command_122
def command_122
mp_common_command_122
for i in @parameters[0]..@parameters[1]
unless $switches_command[i].nil?
$variables_command[i].call($game_variables[i])
end
end
end
end
#==============================================================================
# BITMASK
#------------------------------------------------------------------------------
# This class stores boolean information (true/false) as Integer bits, in
# order to save memory.
#==============================================================================
class Bitmask
attr_reader :size
def initialize(size = 1)
@data = [0]
resize(size)
end
def [](i)
if i >= @size
raise RangeError, "Bit ##{i} not defined (max = #{@size - 1}) in Bitmask#[]"
end
return @data[i >> 5][i % 32] == 1
end
def []=(i, b)
case b
when TrueClass, FalseClass
if self[i] == b
return nil
else
@data[i >> 5] ^= 2 ** (i % 32)
return b
end
else
raise TypeError, "TrueClass or FalseClass expected as parameters in Bitmask#[]="
end
end
def &(other)
bitmask = Bitmask.new(@size)
for i in 0...@size
bitmask[i] = self[i] & other[i]
end
return bitmask
end
def |(other)
bitmask = Bitmask.new(@size)
for i in 0...@size
bitmask[i] = self[i] | other[i]
end
return bitmask
end
def each
for i in 0...@size
yield i if self[i]
end
end
def each_false
for i in 0...@size
unless self[i]
yield i
end
end
end
def resize(size)
while (size >> 5) >= @data.size
@data << 0
end
@size = size
end
def to_s
str = String.new
for i in 0...@size
if i & 7 == 0
str << " "
end
str << @data[i >> 5][i & 31].to_s
end
return str
end
def ==(other)
case other
when Bitmask
#return true if @data == other.data
return false unless @size == other.size
for i in 0...@size
return false unless self[i] == other[i]
end
return true
end
return false
end
alias :inspect :to_s
end
# ==============================================================================
# RUBY EXPANSION
# ------------------------------------------------------------------------------
# Adds new functions to existing Ruby classes. Each new feature is commented
# individually.
# ==============================================================================
class Object
# Make all objects respond to :display for compatibility purposes
alias :display :inspect
end
class Array
# Returns an item selected at random
def sample
return self[rand(self.size)]
end
# Return a copy with items shuffled
def shuffle
src = self.clone
ary = Array.new()
until src.empty?
ary << src.delete(src.sample)
end
return ary
end
# Shuffle items
def shuffle!
self.replace(self.shuffle)
end
end
class Dir
# Returns all files matching given extensions in specified directory as an array
# - directory: directory to be searched
# - filters: strings representing extensions to be kept
def self.files(directory = self.pwd, *filters)
ary = []
for filename in self.entries(directory)
next if File.directory?(filename) or filename == "." or filename == ".."
if filters.empty? or filters.include?(File.extname(filename))
ary << filename
end
end
return ary
end
# Returns all subdirectories in specified directory as an array
def self.subdirectories(directory = self.pwd)
ary = []
for filename in self.entries(directory)
if File.directory?(filename)
ary << filename
end
end
return ary
end
end
class File
# Assess whether a filename is a directory name or not
def self.directory?(filename)
return false if filename == "."
return true if self.extname(filename) == ""
return false
end
end
class Integer
# Computes self factorial
def factorial
f = 1
for i in 1..self
f *= i
end
return f
end
# Compute number of combinations from k in self
# - k: a positive integer less than or equal to self
def combin(k)
return self.factorial / (k.factorial * (n - k).factorial)
end
end
class String
# Breaks string into several lines
# - amount: max number of characters per line
def break_into_lines(amount)
if self.size <= amount
yield self
else
i = 0
until i >= self.size
n = self[i, amount].reverse.index(" ")
n = amount - (n.nil? ? 0 : n)
yield self[i, n]
i += n
end
end
end
# Make string into a symbol name
def symbolize
return :empty if self.empty?
return self.downcase.gsub(" ", "_").to_sym
end
end
class Symbol
# Make symbol into a string ready fot display
def display
str = ""
name = self.to_s
name.split("_").each { |s| str += s.capitalize + " " }
str = str.rstrip
return str
end
# Comparison functions, included for compatiblity purposes
def ===(other)
return (self <=> other) == 0
end
def >(other)
case other
when Numeric
return nil
end
return (self <=> other) == 1
end
def <(other)
case other
when Numeric
return nil
end
return (self <=> other) == -1
end
def <=>(other)
return self.to_s <=> other.to_s
end
end
# ==============================================================================
# DIALOG BOXES
# ------------------------------------------------------------------------------
# Makes dialog boxes to give warning messages and confirm choices.
# ==============================================================================
module RPG
def self.warn(message)
$game_system.se_play($data_system.decision_se)
Graphics.freeze
window = Window_Base.new(32, 192, 576, 96)
window.contents = Bitmap.new(window.width - 32, window.height - 32)
window.contents.draw_text(0, 0, window.width - 32, 32, message, 1)
window.contents.draw_text(0, 32, 544, 32, "OK", 1)
window.cursor_rect.set(208, 32, 128, 32)
window.active = true
window.z = 5000
Graphics.transition
loop do
Input.update
Graphics.update
window.update
if Input.trigger?(Input::C) or Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
break
end
end
Graphics.freeze
window.dispose
Graphics.transition
return
end
def self.confirm(message)
$game_system.se_play($data_system.buzzer_se)
Graphics.freeze
window = Window_Base.new(32, 192, 576, 96)
window.contents = Bitmap.new(window.width - 32, window.height - 32)
window.contents.draw_text(0, 0, window.width - 32, 32, message, 1)
window.contents.draw_text(0, 32, 272, 32, "OK", 1)
window.contents.draw_text(272, 32, 272, 32, "Cancel", 1)
window.cursor_rect.set(72, 32, 128, 32)
window.active = true
window.z = 5000
Graphics.transition
index = 0
result = nil
while result.nil?
Input.update
Graphics.update
window.update
if Input.repeat?(Input::LEFT) or Input.repeat?(Input::RIGHT)
$game_system.se_play($data_system.cursor_se)
index += 1
index %= 2
window.cursor_rect.set(72 + 272 * index, 32, 128, 32)
end
if Input.trigger?(Input::C)
$game_system.se_play($data_system.decision_se)
result = index == 0
end
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
result = false
end
end
Graphics.freeze
window.dispose
Graphics.transition
return result
end
end