#==============================================================================
# ** Ring Menu
#------------------------------------------------------------------------------
# by Syvkal
# Version 1.2
# 03-04-12
#------------------------------------------------------------------------------
# * Original available at:
# [url]www.rpgmakervxace.net[/url] & forums.rpgmakerweb.com
# Please do not redistribute this script
#------------------------------------------------------------------------------
# * Terms of Use
# Available for use in commercial games provided that I get a free copy :P
# Please do not redistribute this script
#==============================================================================
#
# - INTRODUCTION -
#
# This system implements a Plug 'N' Play Ring Menu
# Movement based off XRXS, Dubealex & Hypershadow180's original XP Ring Menu,
# which was devised through some simple, but clever trigonometry
#
#------------------------------------------------------------------------------
#
# - USAGE -
#
# Any additional scenes that are added to the menu require an icon
# Place them in the pictures folder, they are advised to be 48x48 pixels
#
# The name of the icons must be of the form:
# [Command Name] Icon
#
# For example 'Items Icon.png' or 'Equipment Icon.png'
#
# If you are unsure what it needs to be called, wait for the error message,
# then call it the name of the file it can not find
#
#------------------------------------------------------------------------------
#
# - COMPATIBILITY -
#
# Additional scenes should be automatically added assuming thier creators
# utilise the 'add_original_commands' feature in Window_MenuCommand
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
# This script redefines the following methods:
# * create_status_window (Scene_Menu)
# * on_formation_ok (Scene_Menu)
# * on_formation_cancel (Scene_Menu)
# * draw_character (Window_Base)
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
# This script Aliases the following methods:
# * add_save_command (Window_MenuCommand)
# * start (Scene_Menu)
# * create_command_window (Scene_Menu)
# * command_personal (Scene_Menu)
# * command_formation (Scene_Menu)
# * on_personal_cancel (Scene_Menu)
#
#==============================================================================
#===================================================#
# ** C O N F I G U R A T I O N S Y S T E M ** #
#===================================================#
#--------------------------------------------------------------------------
# * Startup Frames
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Amount of frames for the Startup Animation
#--------------------------------------------------------------------------
STARTUP_FRAMES = 20
#--------------------------------------------------------------------------
# * Movement Frames
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Amount of frames for Movement Animation
#--------------------------------------------------------------------------
MOVING_FRAMES = 15
#--------------------------------------------------------------------------
# * Menu Ring Radius
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Radius of the Menu Ring
#--------------------------------------------------------------------------
RING_R = 100
#--------------------------------------------------------------------------
# * Show Disabled Options
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Set to false to exclude disabled options for the menu
#--------------------------------------------------------------------------
DISABLED_SHOW = false
#--------------------------------------------------------------------------
# * Disabled Icon
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# The icon displayed over disabled options
# (only used when DISABLED_SHOW = true)
#--------------------------------------------------------------------------
ICON_DISABLE = Cache::picture('DisableIcon')
#--------------------------------------------------------------------------
# * Skip Single Actor Select
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Set to true to skip the actor selection if there's only one party member
#--------------------------------------------------------------------------
ACTOR_SKIP = true
#--------------------------------------------------------------------------
# * Load Command Vocab
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Text displayed for the loading option
#--------------------------------------------------------------------------
Vocab::Load = "日记"
#===================================================#
# ** E N D C O N F I G U R A T I O N ** #
#===================================================#
#==============================================================================
# ** Ring_Menu Module
#------------------------------------------------------------------------------
# Module designed to rewrite methods defined in the desired Superclass.
#==============================================================================
module Ring_Menu
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(*args)
super(*args)
@cx = contents.width / 2; @cy = contents.height / 2
self.opacity = 0
@startup = STARTUP_FRAMES
@icons = []
@mode = :start
@steps = @startup
end
#--------------------------------------------------------------------------
# * Update Cursor
#--------------------------------------------------------------------------
def update_cursor
end
#--------------------------------------------------------------------------
# * Determines if is moving
#--------------------------------------------------------------------------
def animation?
return @mode != :wait
end
#--------------------------------------------------------------------------
# * Move Cursor Down
#--------------------------------------------------------------------------
def cursor_down(wrap)
cursor_right(wrap)
end
#--------------------------------------------------------------------------
# * Move Cursor Up
#--------------------------------------------------------------------------
def cursor_up(wrap)
cursor_left(wrap)
end
#--------------------------------------------------------------------------
# * Move Cursor Right
#--------------------------------------------------------------------------
def cursor_right(wrap)
unless animation?
select((index + 1) % item_max)
@mode = :mover
@steps = MOVING_FRAMES
Sound.play_cursor
end
end
#--------------------------------------------------------------------------
# * Move Cursor Left
#--------------------------------------------------------------------------
def cursor_left(wrap)
unless animation?
select((index - 1 + item_max) % item_max)
@mode = :movel
@steps = MOVING_FRAMES
Sound.play_cursor
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
refresh if animation?
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
case @mode
when :start
refresh_start
when :wait
refresh_wait
when :mover
refresh_move(1)
when :movel
refresh_move(0)
end
end
#--------------------------------------------------------------------------
# * Refresh Start Period
#--------------------------------------------------------------------------
def refresh_start
d1 = 2.0 * Math::PI / item_max
d2 = 1.0 * Math::PI / @startup
r = RING_R - 1.0 * RING_R * @steps / @startup
for i in 0...item_max
d = d1 * i + d2 * @steps
x = @cx + ( r * Math.sin( d ) ).to_i
y = @cy - ( r * Math.cos( d ) ).to_i
draw_item(x, y, i)
end
@steps -= 1
if @steps < 0
@mode = :wait
end
end
#--------------------------------------------------------------------------
# * Refresh Wait Period
#--------------------------------------------------------------------------
def refresh_wait
d = 2.0 * Math::PI / item_max
for i in 0...item_max
j = i - index
x = @cx + ( RING_R * Math.sin( d * j) ).to_i
y = @cy - ( RING_R * Math.cos( d * j) ).to_i
draw_item(x, y, i)
end
end
#--------------------------------------------------------------------------
# * Refresh Movement Period
#--------------------------------------------------------------------------
def refresh_move( mode )
d1 = 2.0 * Math::PI / item_max
d2 = d1 / MOVING_FRAMES
d2 *= -1 unless mode != 0
for i in 0...item_max
j = i - index
d = d1 * j + d2 * @steps
x = @cx + ( RING_R * Math.sin( d ) ).to_i
y = @cy - ( RING_R * Math.cos( d ) ).to_i
draw_item(x, y, i)
end
@steps -= 1
if @steps < 0
@mode = :wait
end
end
end
#==============================================================================
# ** Window_MenuCommand
#------------------------------------------------------------------------------
# Converted into a Ring Menu.
#==============================================================================
class Window_MenuCommand < Window_Command
#--------------------------------------------------------------------------
# * Includes The Ring_Menu Module
#--------------------------------------------------------------------------
include Ring_Menu
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias add_save_command_ring_menu_original add_save_command
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 0)
unless DISABLED_SHOW
@list.delete_if {|i| !i[:enabled]}
end
for i in 0...item_max
@icons.push(Cache::picture(command_name(i) + 'Icon'))
end
if @@last_command_symbol != nil
index = @list.index(@@last_command_symbol)
@mode = :wait
end
select_last
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
super
rect = Rect.new(0, 196, self.contents.width, line_height)
draw_text(rect, command_name(index), 1)
end
#--------------------------------------------------------------------------
# * Get Window Width
#--------------------------------------------------------------------------
def window_width
return 544
end
#--------------------------------------------------------------------------
# * Get Window Height
#--------------------------------------------------------------------------
def window_height
return 416
end
#--------------------------------------------------------------------------
# * Add Load to Command List
#--------------------------------------------------------------------------
def add_save_command
add_save_command_ring_menu_original
add_command(Vocab::Load, :load)
end
#--------------------------------------------------------------------------
# * Draw Item
# x : draw spot x-coordinate
# y : draw spot y-coordinate
# i : item number
#--------------------------------------------------------------------------
def draw_item(x, y, i)
rect = Rect.new(0, 0, @icons[i].width, @icons[i].height)
if i == index
self.contents.blt(x - rect.width/2, y - rect.height/2, @icons[i], rect )
unless command_enabled?(index)
self.contents.blt(x - rect.width/2, y - rect.height/2, ICON_DISABLE, rect )
end
else
self.contents.blt(x - rect.width/2, y - rect.height/2, @icons[i], rect, 128 )
end
end
end
#==============================================================================
# ** Window_RingStatus
#------------------------------------------------------------------------------
# Ring Menu for selection of Party Members
#==============================================================================
class Window_RingStatus < Window_Selectable
#--------------------------------------------------------------------------
# * Includes The Ring_Menu Module
#--------------------------------------------------------------------------
include Ring_Menu
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :pending_index # Pending position (for formation)
attr_accessor :pending # Pending
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 0, 544, 416)
self.hide
@mode = :wait
@pending_index = -1
@pending = false
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
super
rect = Rect.new(0, 196, self.contents.width, line_height)
draw_text(rect, $game_party.members[index].name, 1)
end
#--------------------------------------------------------------------------
# * Get Number of Items
#--------------------------------------------------------------------------
def item_max
$game_party.members.size
end
#--------------------------------------------------------------------------
# * Refresh Movement Period
#--------------------------------------------------------------------------
def refresh_move( mode )
unless pending_index >= 0
super
else
d = 2.0 * Math::PI / item_max
for i in 0...item_max
j = i - pending_index
x = @cx + ( RING_R * Math.sin( d * j) ).to_i
y = @cy - ( RING_R * Math.cos( d * j) ).to_i
draw_item(x, y, i)
end
@mode = :wait
end
end
#--------------------------------------------------------------------------
# * Draw Item
# x : draw spot x-coordinate
# y : draw spot y-coordinate
# index : item number
#--------------------------------------------------------------------------
def draw_item(x, y, i)
if i == index && !(@pending && @pending_index < 0)
draw_character($game_party.members[i].character_name,
$game_party.members[i].character_index , x, y, true, true)
else
draw_character($game_party.members[i].character_name,
$game_party.members[i].character_index , x, y, false, true)
end
end
#--------------------------------------------------------------------------
# * Processing When OK Button Is Pressed
#--------------------------------------------------------------------------
def process_ok
super
$game_party.menu_actor = $game_party.members[index] unless pending
end
#--------------------------------------------------------------------------
# * Restore Previous Selection Position
#--------------------------------------------------------------------------
def select_last
select($game_party.members.index($game_party.menu_actor) || 0)
refresh
end
end
#==============================================================================
# ** Scene_Menu
#==============================================================================
class Scene_Menu < Scene_MenuBase
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias start_ring_original start
alias create_command_window_ring_menu_original create_command_window
alias command_personal_ring_original command_personal
alias command_formation_ring_original command_formation
alias on_personal_cancel_ring_original on_personal_cancel
#--------------------------------------------------------------------------
# * Start Processing
#--------------------------------------------------------------------------
def start
start_ring_original
create_location_window
end
#--------------------------------------------------------------------------
# * Create Location Window
#--------------------------------------------------------------------------
def create_location_window
@location_window = Window_location.new(0, 0)
end
#--------------------------------------------------------------------------
# * Create Command Window
#--------------------------------------------------------------------------
def create_command_window
create_command_window_ring_menu_original
@command_window.set_handler(:load, method(:command_load))
end
#--------------------------------------------------------------------------
# * Create Status Window
#--------------------------------------------------------------------------
def create_status_window
@status_window = Window_RingStatus.new
end
#--------------------------------------------------------------------------
# * [Skill], [Equipment] and [Status] Commands
#--------------------------------------------------------------------------
def command_personal
if $game_party.members.size < 2 && ACTOR_SKIP
on_personal_ok
else
@command_window.hide
@status_window.show
command_personal_ring_original
end
end
#--------------------------------------------------------------------------
# * [Formation] Command
#--------------------------------------------------------------------------
def command_formation
@status_window.pending = true
@command_window.hide
command_formation_ring_original
@status_window.index = 0
@status_window.refresh
@status_window.show
end
#--------------------------------------------------------------------------
# * [Load] Command
#--------------------------------------------------------------------------
def command_load
SceneManager.call(Scene_Load)
end
#--------------------------------------------------------------------------
# * [Cancel] Personal Command
#--------------------------------------------------------------------------
def on_personal_cancel
@status_window.hide
on_personal_cancel_ring_original
@status_window.deactivate
@command_window.show
end
#--------------------------------------------------------------------------
# * Formation [OK]
#--------------------------------------------------------------------------
def on_formation_ok
if @status_window.pending_index >= 0
$game_party.swap_order(@status_window.index,
@status_window.pending_index)
@status_window.index = @status_window.pending_index
@status_window.pending_index = -1
else
@status_window.pending_index = @status_window.index
end
@status_window.refresh
@status_window.activate
end
#--------------------------------------------------------------------------
# * Formation [Cancel]
#--------------------------------------------------------------------------
def on_formation_cancel
if @status_window.pending_index >= 0
@status_window.index = @status_window.pending_index
@status_window.pending_index = -1
@status_window.activate
@status_window.refresh
else
@status_window.pending = false
@status_window.hide
@status_window.select_last
@status_window.deactivate
@command_window.show
@command_window.activate
end
end
end
#==============================================================================
# ** Window_Base
#------------------------------------------------------------------------------
# Edited to allow disabled character icons and y centring
#==============================================================================
class Window_Base < Window
#--------------------------------------------------------------------------
# * Draw Character Graphic
#--------------------------------------------------------------------------
def draw_character(character_name, character_index, x, y, enabled = true, centred = false)
return if character_name == nil
bitmap = Cache.character(character_name)
sign = character_name[/^[\!\$]./]
if sign && sign.include?('$')
cw = bitmap.width / 3
ch = bitmap.height / 4
else
cw = bitmap.width / 12
ch = bitmap.height / 8
end
n = character_index
src_rect = Rect.new((n%4*3+1)*cw, (n/4*4)*ch, cw, ch)
self.contents.blt(x - cw / 2, centred ? y - ch/2 : y - ch, bitmap, src_rect,
enabled ? 255 : 128)
end
end
#==============================================================================
# ** Window_Location
#------------------------------------------------------------------------------
# This class shows the current map name.
#==============================================================================
class Window_location < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(x, y)
super(30, 350, 200, (line_height)+32)
self.opacity = 0
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
#~ self.contents.font.color=Color.new(255,0,0)
contents.clear
@map = load_data(sprintf("Data/Map%03d.rvdata2", $game_map.map_id))
#~ change_color(system_color)
#~ draw_text(4, 0, 128, line_height, "当前所在位置:")
change_color(normal_color)
draw_text(0, 0, 128, line_height, @map.display_name, 1)
end
end