#===============================================================================
#
# HERETIC'S CIRCULAR SPRITE MOTION [XP]
# Version 1.1
# Sunday, March 15th, 2015
#
#===============================================================================
#
#
# ***** REQUIRES HERETICS MODULAR PASSABLE SCRIPT *****
#
#
# ----- OVERVIEW -----
#
# This script will allow you to apply Circular Motion to Sprites.
#
# NOTE: Requires Heretic's Modular Passable
#
# NOTE: Does NOT affect Collisions, Sprite ONLY.
#
#
# ----- INSTRUCTIONS -----
#
# Default Values for Events are set by putting a \comment[values] Comment on
# each Page of an Event. Values can be changed later with Script Calls.
#
# For installation, place this script above MAIN, and below Modular Passable.
#
# For Character Sprites to Spin, they must have a \spin and \spin_radius[N]
# comment within the first *10 Lines on each Page.
#
# To use these properties on the Player, use a Move Route Script to change
# the corresponding property name. \spin comments should be set by using
# a Move Route Script -> @spin = true
#
# These patterns are intended as Effects ONLY! They do NOT affect collisions
# in any way shape or form. You will probably want to set "Always On Top"
# because Sprites can appear under other Events below the location
# of the "Spinning" Event.
#
# * 10 Lines is a Modifiable Parameter in the Modular Passable Script. It
# can be overridden per event page with a comment: \comment_limit[N] where
# the letter N is a number higher than 10. Increasing this number to an
# excessive degree can impact performance, this, using this \comment_limit
# option is useful as very few events should need to exceed the Limit of 10.
#
#
# ----- COMMENT CONFIGURATION OPTIONS -----
#
# Apply each of the following Comments to an Event for corresponding Effects:
#
# /spin - Enables Circular Motion Effects
# /spin_radius[N] - Distance in Pixels from actual Event Map location
# /spin_radius[N, N] - Distance in X, Y Distance for a Elliptical Movement
# /spin_speed[N] - Speed in Degrees Per Frame
# /spin_speed[N, N] - X and Y have different Rotational Speeds (non circles)
# /spin_angle[N] - Initial Angle (0.0 - 360.0)
# /spin_angle[N, N] - X and Y have different Inital Angles
#
#
# ----- SCRIPT CALL OPTIONS -----
#
# @spin = true / false
# - enable or disable Circular Movement of Sprites
# @spin_radius = 32
# - set the radius of Circular Movement to 32 Pixels from actual Character
# @spin_radius = [64, 32]
# - set the X, Y to shape Elliptical Movement. X = 64 pixels and Y = 32
# @spin_speed = 10
# - set the speed of Circular Movement to 10 Degrees per Frame
# @spin_speed = [5, 7.5]
# - set X and Y Rotations to have independent speeds
#
# --- Transitions ----
#
# All numeric properties can be transitioned. These scripts should be called
# from a Move Route Script, or character.script
#
# spin_speed_to(new_speed, duration=0)
# - Transitions from current speed to new speed over duration in frames
#
# spin_speed_to([new_x_speed, new_y_speed], duration=0)
# - Transition both X and Y to new Targets using same duration in frames
# * Non Circular and Non Elliptical Movements
#
# spin_radius_to(new_radius, duration=0)
# - Transitions from current Radius to New Radius over duration in frames
#
# spin_radius_x_to(new_x_radius, duration=0)
# - Transition from current Radius X to alter the X size of the Ellipse
#
# spin_radius_y_to(new_y_radius, duration=0)
# - Transition from current Radius Y to altery the Y size of the Ellipse
#
#
# NOTE: You can transition from a Circle with one Radius to a Double Radius
#
# Examples:
#
# $game_map.events[12].spin = true
# $game_map.events[12].spin_speed = 10
# $game_map.events[12].spin_speed = -5.5
# $game_map.events[12].spin_speed_to(5, 40)
# $game_map.events[12].spin_radius_to(32, 20)
#
# These work on the Game Player as well
#
# $game_player.spin = true
# $game_player.spin_speed = 12
# $game_player.spin_speed_to(5, 40)
# $game_player.spin_radius_to = 64
#
#
# ----- VERSION HISTORY -----
#
# Version 1.1 - Friday, July 3rd, 2015
# * Changed Spin Speed from Integer to allow for XY Arrays
# - Array allows for more interesting "patterns" of movement
# - You can now set the Spin Speed by putting in seperate values
# for both the X and Y Speeds of Rotation
# \spin_speed[4] - Same value for both X and Y Rotations
# \spin_speed[2.5, 4.3] - X and Y Rotational Speeds are Independant
# * Changed initial Spin Angle to also have separate XY Starting Values
# - You can now set the Initial Vectors by putting in separate values
# \spin_angle[45] - Initial Starting Value when Speeds are the same
# \spin_angle[0, 45] - Different Starting Values for both X and Y
# Version 1.0 - Sunday, March 15th, 2015
# * Initial Release
# ----- PAGE OPTIONS -----
#
# These Comments are applied Per Event Page! This allows you to have
# different configurations on each Event Page! One Page just Rotates
# to the Left, then Right. Another Page could be used to Point at
# the Player by giving the Rotating Event a Rotate Target!
#
# All Page Values will be cleared when an Event changes to another valid Page.
# Check for Modular Passable Script - REQUIRED - DO NOT EDIT
unless $Modular_Passable
print "Fatal Error: Heretics Uniform Circular Sprite Motion script\n",
"requires Heretics Modular Passable Script!\n\n",
"Modular Passable is Not Available or is below this script.\n",
"Modular Passable MUST be above this script.\n\n",
"The Game will now Exit"
# End game before fatal errors
exit
end
#==============================================================================
# ** Game_Character
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Public Instance Variables - Game_Character
#--------------------------------------------------------------------------
attr_accessor :spin # If Character Spins
attr_accessor :spin_angle # Initial Angle of Character
attr_accessor :spin_speed # How quickly to Spin
attr_accessor :spin_radius # Distance to Offset Sprite from Char [x, y]
#--------------------------------------------------------------------------
# * Frame Update - Game_Character
#--------------------------------------------------------------------------
alias spin_char_initialize initialize unless $@
def initialize
# New Property for Spinning Sprites
@spin_angle = 0
# Call Original or other Aliases
spin_char_initialize
end
#--------------------------------------------------------------------------
# * Frame Update - Game_Character
#--------------------------------------------------------------------------
alias spin_update update unless $@
def update
# If Spin Speed To Transition is taking place
if @spin_speed_target and @spin_speed_duration and @spin_speed_duration > 0
# If Speed Target has different values for X and Y (Array)
if @spin_speed_target.is_a?(Array)
# Shorthand for X and Y
tx = @spin_speed_target[0].to_f
ty = @spin_speed_target[1].to_f
# Duration is same for both X and Y in a Transition
d = @spin_speed_duration
# Adjust the Spin Speed over Duration Frames for X and Y
@spin_speed[0] = (@spin_speed[0] * (d - 1) + tx) / d
@spin_speed[1] = (@spin_speed[1] * (d - 1) + ty) / d
# If Spin Speed To has not completed
if @spin_speed_duration > 0
# Decrease the Duration Cycle to End
@spin_speed_duration -= 1
end
# End the Spin Speed To Transition
@spin_speed[0] = @spin_speed_target[0] if @spin_speed_target[0] == 0
@spin_speed[1] = @spin_speed_target[1] if @spin_speed_target[1] == 0
# Else Spin Speed uses same Speed
else
# Shorthand
t = @spin_speed_target.to_f
d = @spin_speed_duration
# Adjust the Spin Speed over Duration Frames
@spin_speed = (@spin_speed * (d - 1) + t) / d
# If Spin Speed To has not completed
if @spin_speed_duration > 0
# Decrease the Duration Cycle to End
@spin_speed_duration -= 1
end
# End the Spin Speed To Transition
@spin_speed = @spin_speed_target if @spin_speed_target == 0
end
end
# If Spin Radius Transition for X, Y Radius for Shaped Orbits
if (@spin_radius_x_duration and @spin_radius_x_duration > 0) or
(@spin_radius_y_duration and @spin_radius_y_duration > 0)
# If Radius X Transition
if @spin_radius_x_target and @spin_radius_x_duration > 0
# Shorthand
t = @spin_radius_x_target.to_f
d = @spin_radius_x_duration
# Adjust the Spin Radius X over Duration Frames
@spin_radius[0] = (@spin_radius[0] * (d - 1) + t) / d
# If Spin Radius To has not completed
if @spin_radius_x_duration > 0
# Decrease the Duration Cycle to End
@spin_radius_x_duration -= 1
end
# End the Spin radius To Transition
@spin_radius[0] = @spin_radius_x_target if @spin_radius_x_duration == 0
end
# If Radius Y Transition
if @spin_radius_y_target and @spin_radius_y_duration > 0
# Shorthand
t = @spin_radius_y_target.to_f
d = @spin_radius_y_duration
# Adjust the Spin Radius Y over Duration Frames
@spin_radius[1] = (@spin_radius[1] * (d - 1) + t) / d
# If Spin Radius To has not completed
if @spin_radius_y_duration > 0
# Decrease the Duration Cycle to End
@spin_radius_y_duration -= 1
end
# End the Spin radius To Transition
@spin_radius[1] = @spin_radius_y_target if @spin_radius_x_duration == 0
end
# If Spin Radius To Transition is taking place
elsif @spin_radius_target and @spin_radius_duration and
@spin_radius_duration > 0
# Shorthand
t = @spin_radius_target.to_f
d = @spin_radius_duration
# Adjust the Spin Radius over Duration Frames
@spin_radius = (@spin_radius * (d - 1) + t) / d
# If Spin Radius To has not completed
if @spin_radius_duration > 0
# Decrease the Duration Cycle to End
@spin_radius_duration -= 1
end
# End the Spin radius To Transition
@spin_radius = @spin_radius_target if @spin_radius_duration == 0
end
# Update Spin Counter
if @spin_speed
# If Speed has different Speeds for both X and Y (Array)
if @spin_speed.is_a?(Array)
# If Angle is not an Array
if not @spin_angle.is_a?(Array)
# Change the Angle into an Array using Current Angle Value for X, Y
@spin_angle = [@spin_angle, @spin_angle]
end
# Update X and Y Speeds independently
@spin_angle[0] += @spin_speed[0]
@spin_angle[1] += @spin_speed[1]
# Clamp to 360 Degrees for both X and Y values
@spin_angle[0] %= 360.0
@spin_angle[1] %= 360.0
# If the Angle is an Array and Speed is not an Array
elsif @spin_angle.is_a?(Array)
# Apply Speed changes to both X and Y value so ther is no "Snapping"
@spin_angle[0] += @spin_speed
@spin_angle[1] += @spin_speed
# Clamp to 360 Degrees
@spin_angle[0] %= 360.0
@spin_angle[1] %= 360.0
# Else Spin Speed is a Single Value not an Array
else
# Increase the Spin Counter
@spin_angle += @spin_speed
# Clamp to 360 Degrees
@spin_angle %= 360.0
end
end
# Call Original or other Aliases
spin_update
end
#--------------------------------------------------------------------------
# * Spin Speed To - Game_Character
# target : Target in Pixels to Clip the Sprites Base
# duration : Duration in Frames (Optional)
#--------------------------------------------------------------------------
def spin_speed_to(target, duration = 0)
# If No Duration
if duration == 0
# Just set the Spin Speed with no Transition
@spin_speed = target
return
end
# The Target Spin Speed when finished
@spin_speed_target = target
# The Number of Frames to take to adjust Spin Speed
@spin_speed_duration = duration
end
#--------------------------------------------------------------------------
# * Spin Radius To - Game_Character
# target : Target Radius
# duration : Duration in Frames (Optional)
#--------------------------------------------------------------------------
def spin_radius_to(target, duration = 0)
# Check for nil Radius
@spin_radius = 0 if @spin_radius.nil?
# If No Duration
if duration == 0
# Just set the Spin Radius with no Transition
@spin_radius = target
return
end
# If Radius is an Array for X, Y
if @spin_radius.is_a?(Array)
# Set the Target for both X and Y values
@spin_radius_x_target = @spin_radius_y_target = target
# The Number of Frames to take to adjust Spin Radius
@spin_radius_x_duration = @spin_radius_y_duration = duration
else
# The Target Spin Radius when finished
@spin_radius_target = target
# The Number of Frames to take to adjust Spin Radius
@spin_radius_duration = duration
end
end
#--------------------------------------------------------------------------
# * Spin Radius X To - Game_Character
# target : Target Radius X Size
# duration : Duration in Frames (Optional)
#--------------------------------------------------------------------------
def spin_radius_x_to(target, duration = 0)
# Check for nil Radius
@spin_radius = 0 if @spin_radius.nil?
# If No Duration
if duration == 0
# Old Radius Y Value
orig_ry = (@spin_radius.is_a?(Array)) ? @spin_radius[1] : @spin_radius
# Just set the Spin Radius X with no Transition
@spin_radius = [target, orig_ry]
return
end
# If current Radius is not an Array
if @spin_radius.is_a?(Numeric)
# Old Radius Value
orig_r = @spin_radius
# Convert Value to Array for both Values to allow Transition on X
@spin_radius = [orig_r, orig_r]
end
# The Target Spin Radius when finished
@spin_radius_x_target = target
# The Number of Frames to take to adjust Spin Radius
@spin_radius_x_duration = duration
end
#--------------------------------------------------------------------------
# * Spin Radius Y To - Game_Character
# target : Target Radius Y Size
# duration : Duration in Frames (Optional)
#--------------------------------------------------------------------------
def spin_radius_y_to(target, duration = 0)
# Check for nil Radius
@spin_radius = 0 if @spin_radius.nil?
# If No Duration
if duration == 0
# Old Radius X Value
orig_rx = (@spin_radius.is_a?(Array)) ? @spin_radius[0] : @spin_radius
# Just set the Spin Radius Y with no Transition
@spin_radius = [orig_rx, target]
return
end
# If current Radius is not an Array
if @spin_radius.is_a?(Numeric)
# Old Radius Value
orig_r = @spin_radius
# Convert Value to Array for both Values to allow Transition on Y
@spin_radius = [orig_r, orig_r]
end
# The Target Spin Radius Y when finished
@spin_radius_y_target = target
# The Number of Frames to take to adjust Spin Radius Y
@spin_radius_y_duration = duration
end
#--------------------------------------------------------------------------
# * Get Screen X-Coordinates
#--------------------------------------------------------------------------
alias spin_screen_x screen_x unless $@
def screen_x
# Get Original or other Aliases
orig_x = spin_screen_x
# If has a Spin property
if @spin and @spin_radius
# Use Value or 2nd Array Arg as Radius
radius = (@spin_radius.is_a?(Array) ) ? @spin_radius[0] : @spin_radius
# Use Value or 2nd Array Arg as Angle
angle = (@spin_angle.is_a?(Array) ) ? @spin_angle[0] : @spin_angle
# Calculate X Offset Distance (Round to prevent Screen Tearing)
orig_x += (radius * Math.cos(angle * Math::PI / 180.0)).round
end
# Return Modified Value
return orig_x
end
#--------------------------------------------------------------------------
# * Get Screen Y-Coordinates
#--------------------------------------------------------------------------
alias spin_screen_y screen_y unless $@
def screen_y
# Get Original or other Aliases
orig_y = spin_screen_y
# If has a Spin property
if @spin and @spin_radius
# Use Value or 2nd Array Arg as Radius
radius = (@spin_radius.is_a?(Array) ) ? @spin_radius[1] : @spin_radius
# Use Value or 2nd Array Arg as Angle
angle = (@spin_angle.is_a?(Array) ) ? @spin_angle[1] : @spin_angle
# Calculate Y Offset Distance (Round to prevent Screen Tearing)
orig_y += (radius * Math.sin(angle * Math::PI / 180.0)).round
end
# Return Modified Value
return orig_y
end
end
#==============================================================================
# ** Game_Event - Class
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
# * Object Initialization
# map_id : map ID
# event : event (RPG::Event)
#--------------------------------------------------------------------------
alias spin_initialize initialize unless $@
def initialize(map_id, event)
# Call Original or other Aliases
spin_initialize(map_id, event)
end
#--------------------------------------------------------------------------
# * Reset Page Comment Config - Game_Event
# - Aliasing Requires Modular Passable, otherwise this is unique
# - Resets Rotation Options set by Comment Config during a Page Change
#--------------------------------------------------------------------------
alias spin_reset_page_comment_config reset_page_comment_config unless $@
def reset_page_comment_config
# Reset to set again by Comment Conditions
@spin = nil
@spin_angle = 0
@spin_speed = nil
@spin_speed_target = nil
@spin_speed_duration = nil
@spin_radius = nil
@spin_radius_target = nil
@spin_radius_duration = nil
@spin_radius_x_target = nil
@spin_radius_y_target = nil
@spin_radius_x_duration = nil
@spin_radius_y_duration = nil
# Runs Original or Other Aliases
spin_reset_page_comment_config
end
#--------------------------------------------------------------------------
# * Spin Check Comment Page Config - Game_Event
# comment : the Comment to be checked to adjust Page Properties
# count : integer of which List of Event Commands is checked
#
# Note: When aliasing, please return the value of aliased methods for
# the local variable count to be altered as needed.
# return alias_check_page_comment_config(comment, count)
#--------------------------------------------------------------------------
alias spin_check_page_comment_config check_page_comment_config unless $@
def check_page_comment_config(comment, count)
# Looks for "\spin_speed[N]" Comments (to Floating or Array of Integers)
comment.gsub(/^\\spin_speed\[([-0-9., ]+)\]\z/i){
# Single Number Capture
@spin_speed = $1.to_f if $1.to_f.is_a?(Numeric);
# If Capture is intended as an [X, Y] Array
@spin_speed = $1.split(",").map { |s| s.to_f } if $1.include?(",")
# Allow other Scripts to use this Count to modify Events with M.P.
return count;}
# Looks for "\spin_radius[N]" Comments (to Float or Array)
comment.gsub(/^\\spin_radius\[([-0-9., ]+)\]\z/i){
# Single Number Capture
@spin_radius = $1.to_f if $1.to_f.is_a?(Numeric);
# If Capture is intended as an [X, Y] Array
@spin_radius = $1.split(",").map { |s| s.to_f } if $1.include?(",")
# Allow other Scripts to use this Count to modify Events with M.P.
return count; }
# Look for Initial "spin_angle[N.n]" in the Comments
comment.gsub(/^\\spin_angle\[([-0-9., ]+)\]\z/i){
# Single Number Capture
@spin_angle = $1.to_f % 360.0 if $1.to_f.is_a?(Numeric);
# If Capture is intended as an [X, Y] Array
@spin_angle = $1.split(",").map { |s| s.to_f } if $1.include?(",")
# Allow other Scripts to use this Count to modify Events with M.P.
return count;}
# Looks for "\spin" in the Comments (Use on Character Events)
comment.gsub(/^\\spin\z/i){@spin = true; return count}
# Return adjusted or unadjusted counter for other scripts to use this
return spin_check_page_comment_config(comment, count)
end
end