#============================================================================== # ** Ring Menu #------------------------------------------------------------------------------ # by Syvkal # Version 1.2 # 03-04-12 #------------------------------------------------------------------------------ # * Original available at: # www.rpgmakervxace.net & 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 # Email me: syvkal@hotmail.co.uk # 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 = 75 #-------------------------------------------------------------------------- # * 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('Disable Icon') #-------------------------------------------------------------------------- # * 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 = "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(x, y, 160, (line_height*2) + 32) refresh end #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh 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, "Location :") change_color(normal_color) draw_text(0, line_height, 128, line_height, @map.display_name, 1) end end