=begin
BigEd781' Final Fantasy IX Menu
Credit to PainHurt at rpgmakervx.net for most of the graphics
=end
module FF9_Config
# set this to 'true' if you would like to use a cusotm background image
USE_CUSTOM_BACK = false
# the name of the custom background image, without the file extension (no .png)
BACK_NAME = 'StoneBackground'
# if you set this to 'true', you must be using the enhanced
# Window class script that I posted: You can get that script here:
#
www.rpgmakervx.net/index.php?showtopic=8042&hl=
# this will make the provided FF9 windowskin look really good.
USE_TILED_WINDOW = false
# When this is set to 'true', the menu cirsor will animate back and forth.
# When set to 'false', it will stay in place
ANIMATE_CURSOR = true
# When set to 'true', four background panels are always drawn.
# When set to 'false', a panel is only drawn for each party member
DRAW_FOR_ALL = true
# the name of the font used in the menu.
# use 'Font.default_name' for the default font. Try 'Centaur' for a nice, smaller font.
DEFAULT_FONT = 'Calibri'
# set this to true to enable the font above for all windows.
# also sets the back_opacity to 255 for all windows.
# I recommend setting this to 'true' to maintain a consistent look.
USE_FOR_ALL = true
# the icon id for your gold window portion of the menu, 194 by default.
GOLD_ICON_ID = 194
end
if FF9_Config::USE_FOR_ALL
Font.default_name = FF9_Config::DEFAULT_FONT
class Window_Base < Window
alias :eds_pre_ff9_menu_base_initialize :initialize
def initialize(*args)
eds_pre_ff9_menu_base_initialize(*args)
self.stretch = false if FF9_Config::USE_TILED_WINDOW
self.back_opacity = 255
end
end
end
class Window_Base < Window
CAPTION_COLOR = Color.new(255,255,255)#(228, 228, 228)
CAPTION_HEIGHT = 12
X_OFFSET = 16
Y_OFFSET = -5
alias :eds_pre_window_caption_intialize :initialize
def initialize(*args)
eds_pre_window_caption_intialize(*args)
@caption_sprite = Sprite_Base.new(self.viewport)
create_caption_bitmap(1, CAPTION_HEIGHT)
@caption_sprite.x = self.x + X_OFFSET
@caption_sprite.y = self.y + Y_OFFSET
@caption_sprite.z = self.z + 1
end
def x=(value)
super
@caption_sprite.x = value + X_OFFSET unless @caption_sprite.nil?
end
def y=(value)
super
@caption_sprite.y = value + Y_OFFSET unless @caption_sprite.nil?
end
def z=(value)
super
@caption_sprite.z = value + 1 unless @caption_sprite.nil?
end
def caption=(text)
return unless text.is_a?(String)
return if text.empty?
@caption = text
width = @caption_sprite.bitmap.text_size(@caption).width
create_caption_bitmap(width, CAPTION_HEIGHT)
draw_caption
end
def create_caption_bitmap(w, h)
@caption_sprite.bitmap = Bitmap.new(w, h)
@caption_sprite.bitmap.font.size = 12
@caption_sprite.bitmap.font.color = CAPTION_COLOR
@caption_sprite.bitmap.font.bold = true
end
def draw_caption
unless @caption.nil?
h = @caption_sprite.bitmap.height
w = @caption_sprite.bitmap.width
rect = Rect.new( 0, h / 2, w, h / 4 )
@caption_sprite.bitmap.fill_rect(rect, Color.new(0, 0, 0, 96))
@caption_sprite.bitmap.draw_text(@caption_sprite.src_rect, @caption)
end
end
alias :eds_pre_caption_window_dispose :dispose
def dispose
eds_pre_caption_window_dispose
@caption_sprite.dispose
end
def find_window_width(text)
return Bitmap.new(544, 416).text_size(text).width + 32
end
end
class Window_TimeGold < Window_Base
def initialize(x, y)
width = find_window_width("9999999")
width = 140 if width < 140
super(x, y, width, WLH + 58)
self.back_opacity = 255
self.stretch = false if FF9_Config::USE_TILED_WINDOW
self.contents.font.name = FF9_Config::DEFAULT_FONT
self.caption = "TIME & #{Vocab.gold}"
@time_icon = Cache.picture('Timer')
@intern_frame_count = 0
refresh
end
def draw_time
sec = (Graphics.frame_count / 60) % 60
min = (Graphics.frame_count / 3600) % 60
hrs = Graphics.frame_count / 216000
self.contents.font.color = Color.new(255, 255, 255)
time = "%02d:%02d:%02d" % [hrs, min, sec]
self.contents.draw_text(0, 0, self.contents.width, WLH, time, 2)
end
def refresh
self.contents.clear
self.contents.blt(0, 0, @time_icon, @time_icon.rect)
draw_icon(FF9_Config::GOLD_ICON_ID, 2, WLH)
draw_currency_value($game_party.gold, 0, WLH, self.contents.width)
draw_time
end
def draw_currency_value(value, x, y, width)
gold_text = Vocab.gold
cx = contents.text_size(gold_text[0,1]).width
self.contents.font.color = normal_color
self.contents.draw_text(x, y, width - cx - 2, WLH, value, 2)
self.contents.font.color = system_color
# just print the first character of Vocab::gold
self.contents.draw_text(x, y, width, WLH, gold_text[0,1], 2)
end
def update
super
@intern_frame_count += 1
return if (@intern_frame_count % 60) != 0
refresh
end
def find_window_width(text)
return Bitmap.new(544, 416).text_size(text).width + 80
end
end
class Window_MenuLocation < Window_Base
def initialize(x, y)
@map_name = load_data("Data/MapInfos.rvdata")[$game_map.map_id].name
width = find_window_width(@map_name)
super(x, y, width, WLH + 32)
self.stretch = false if FF9_Config::USE_TILED_WINDOW
self.contents.font.name = FF9_Config::DEFAULT_FONT
self.back_opacity = 255
self.caption = "LOCATION"
refresh
end
def refresh
self.contents.clear
self.contents.draw_text(0, 0, self.contents.width, WLH, @map_name, 1)
end
def find_window_width(text)
return Bitmap.new(544, 416).text_size(text).width + 48
end
end
class Window_Command < Window_Selectable
alias :eds_pre_ff9_menu_win_command_init :initialize
def initialize(*args)
@font_name = Font.default_name
eds_pre_ff9_menu_win_command_init(*args)
end
#
# * OVERWRITTEN
#
def refresh
self.contents.clear
self.contents.font.name = @font_name
for i in 0...@item_max
draw_item(i)
end
end
def font_name=(name)
@font_name = name
end
end
class Window_Uses < Window_Base
def initialize(right, y, item)
@remaining_text = "Remaining: #{$game_party.item_number(item)}"
w = 160
x = right ? (544 - w) : 0
super(x, y, w, WLH + 32)
self.stretch = false if FF9_Config::USE_TILED_WINDOW
self.contents.font.name = FF9_Config::DEFAULT_FONT
refresh
end
def item=(item)
return unless item.is_a?(RPG::Item)
@remaining_text = "Remaining: #{$game_party.item_number(item)}"
refresh
end
def visible=(value)
super
refresh if value
end
def refresh
self.contents.clear
self.contents.draw_text(self.contents.rect, @remaining_text, 1)
end
end
class Window_SkillUses < Window_Base
def initialize(right, y, actor, skill)
@remaining_text = make_info_string(actor, skill)
w = 182
x = right ? (544 - w) : 0
super(x, y, w, WLH + 32)
self.stretch = false if FF9_Config::USE_TILED_WINDOW
self.contents.font.name = FF9_Config::DEFAULT_FONT
refresh
end
def make_info_string(actor, skill)
return if actor.nil? || skill.nil?
cost = actor.calc_mp_cost(skill)
return "Unlimited" if cost < 1
return "Remaining: #{actor.mp / cost}"
end
def set_skill(actor, skill)
return if actor.nil? || skill.nil?
return unless skill.is_a?(RPG::Skill)
@remaining_text = make_info_string(actor, skill)
refresh
end
def visible=(value)
super
refresh if value
end
def refresh
self.contents.clear
self.contents.draw_text(self.contents.rect, @remaining_text, 1)
end
end
class Window_MenuStatus < Window_Selectable
#
# * OVERWRITTEN
#
def initialize(x, y)
super(x, y, 452, 352)
@bg_image = Cache.picture('FF9_MenuBar')
@arrow_image = Cache.picture('Pointer')
create_arrow_sprites
@sprite_last_draw_x = 0
@sprite_inc_x = 1
@intern_frame_count = 0
self.stretch = false if FF9_Config::USE_TILED_WINDOW
self.contents.font.name = FF9_Config::DEFAULT_FONT
self.opacity = 0
self.z = 99
self.active = false
self.index = -1
refresh
end
#
# * create_arrow_sprites
#
def create_arrow_sprites
@arrow_sprites = []
for i in 0..3
@arrow_sprites << Sprite.new
@arrow_sprites
.bitmap = Bitmap.new(@arrow_image.width + 7, @arrow_image.height)
@arrow_sprites.x = self.x
@arrow_sprites.y = (i * 80) + self.y + 40
@arrow_sprites.z = 999
end
end
#
# * OVERWRITTEN
#
def refresh
self.contents.clear
@item_max = $game_party.members.size
draw_background_windows if FF9_Config::DRAW_FOR_ALL
for actor in $game_party.members
x = 104
y = actor.index * 80
y_offset = 6
draw_background_window(0, y) unless FF9_Config::DRAW_FOR_ALL
draw_actor_face(actor, 19, y + 4, 73)
draw_actor_name(actor, x, y + y_offset)
draw_actor_class(actor, x + 125, y + y_offset) if actor.states.empty?
draw_actor_level(actor, x, y + WLH * 1)
draw_actor_state(actor, x + 125, y + y_offset)
draw_actor_hp(actor, x, ((y) + (WLH * 2) - 5))
draw_actor_mp(actor, x + 125, ((y) + (WLH * 2) - 5))
end
end
#
# * OVERWRITTEN
#
def update_cursor
if @index < 0
#refactor into update arrow method
@arrow_sprites.each { |sprite| sprite.bitmap.clear }
return
end
@intern_frame_count += 1
return unless (@intern_frame_count % 5) == 0
if @sprite_last_draw_x >= 7
@sprite_inc_x = -1
elsif @sprite_last_draw_x <= 0
@sprite_inc_x = 1
end
update_arrow_sprites
end
#
# * update_arrow_sprites
#
def update_arrow_sprites
@arrow_sprites.each { |sprite| sprite.bitmap.clear }
if @index == 99 # all selected
return unless (@intern_frame_count % 10) == 0
draw_arrow_sprites(@arrow_sprites, false)
else
draw_arrow_sprites([@arrow_sprites[@index]], FF9_Config::ANIMATE_CURSOR)
end
end
#
# * draw_arrow_sprites
#
def draw_arrow_sprites(sprites, animated=true)
for sprite in sprites
image_x = animated ? @sprite_last_draw_x + @sprite_inc_x : 0
@sprite_last_draw_x = image_x
sprite.bitmap.blt(image_x, 0, @arrow_image, @arrow_image.rect)
end
end
#
# * y=
#
def y=(value)
super
unless @arrow_sprites.nil?
for i in 0..3
@arrow_sprites
.y = (i * 80) + value + 40
end
end
end
#
# * x=
#
def x=(value)
super
unless @arrow_sprites.nil?
@arrow_sprites.each { |sprite| sprite.x = value }
end
end
#
# * draw_background_windows
#
def draw_background_windows
self.contents.blt(0, 0, @bg_image, @bg_image.rect)
self.contents.blt(0, 80, @bg_image, @bg_image.rect)
self.contents.blt(0, 160, @bg_image, @bg_image.rect)
self.contents.blt(0, 240, @bg_image, @bg_image.rect)
end
#
# * draw_background_window (single)
#
def draw_background_window(x, y)
self.contents.blt(x, y, @bg_image, @bg_image.rect)
end
#
# * visible
#
def visible=(value)
super
@arrow_sprites.each { |sprite| sprite.visible = value }
end
#
# * dispose
#
alias :eds_pre_ff9_win_stat_dispose :dispose
def dispose
eds_pre_ff9_win_stat_dispose
@arrow_sprites.each { |sprite| sprite.dispose }
end
def enable_cursor?(rect=nil)
# for compatibility with the improved command window
return false
end
end
class Scene_Menu
#
# * create_menu_background (only if USE_CUSTOM_BACK == true)
#
if FF9_Config::USE_CUSTOM_BACK
def create_menu_background
@menuback_sprite = Sprite.new
@menuback_sprite.bitmap = Cache.picture(FF9_Config::BACK_NAME)
@menuback_sprite.color.set(16, 16, 16, 128)
update_menu_background
end
end
#
# * OVERWRITTEN
#
def create_command_window
s1 = Vocab::item
s2 = Vocab::skill
s3 = Vocab::equip
s4 = Vocab::status
s5 = Vocab::save
s6 = Vocab::game_end
# just changed the width of the window here
@command_window = Window_Command.new(132, [s1, s2, s3, s4, s5, s6])
@command_window.index = @menu_index
@command_window.stretch = false if FF9_Config::USE_TILED_WINDOW
if $game_party.members.size == 0 # If number of party members is 0
@command_window.draw_item(0, false) # Disable item
@command_window.draw_item(1, false) # Disable skill
@command_window.draw_item(2, false) # Disable equipment
@command_window.draw_item(3, false) # Disable status
end
if $game_system.save_disabled # If save is forbidden
@command_window.draw_item(4, false) # Disable save
end
# new stuff here
@command_window.font_name = FF9_Config::DEFAULT_FONT
@command_window.x = 528 - @command_window.width
@command_window.y = 16
@command_window.back_opacity = 255
end
#
# * This method is intended to fix some compatibility problems
# that scripts run into when they change the command window
# in some way. So, we let them override "create_command_window"
# and we simply don't call it from the "start" method.
# Instead, we call this method which does some extra checking.
#
def eds_create_command_window
create_command_window
old_commands = @command_window.commands
return if old_commands == [ Vocab::item,
Vocab::skill,
Vocab::equip,
Vocab::status,
Vocab::save,
Vocab::game_end ]
# so we know that the default command window is not being used
# we don't want to create another window, so we manually resize it
# before the player can see.
long = ''
# dynamically size the width based on the longest command
old_commands.each { |command| long = command if command.length > long.length }
# set the index to -1 so that the rectangle disappears.
# if we don't do this, you can see the selection rectangle resize.
@command_window.index = -1
@command_window.width = @command_window.contents.text_size(long).width + 42
@command_window.contents = Bitmap.new( @command_window.width - 32,
@command_window.height - 32 )
@command_window.font_name = FF9_Config::DEFAULT_FONT
@command_window.x = 528 - @command_window.width
@command_window.y = 16
@command_window.back_opacity = 255
@command_window.refresh
@command_window.index = @menu_index
end
#
# * OVERWRITTEN
#
def start
super
create_menu_background
#call this method for compatibility
eds_create_command_window
@gold_window = Window_TimeGold.new(372, 342)
@gold_window.y -= @gold_window.height
@gold_window.x = 528 - @gold_window.width
@status_window = Window_MenuStatus.new(0, 12)
@location_window = Window_MenuLocation.new(0, 0)
@location_window.x = 528 - @location_window.width
@location_window.y = 398 - @location_window.height
end
#
# * Termination Processing
#
alias :eds_pre_ff9_menu_scene_menu_terminate :terminate
def terminate
eds_pre_ff9_menu_scene_menu_terminate
@location_window.dispose
end
end
class Scene_Item < Scene_Base
#
# * start
#
alias :eds_pre_ff9_menu_scene_item_start :start
def start
eds_pre_ff9_menu_scene_item_start
@target_window.y = 58
@uses_window = Window_Uses.new(true, @help_window.height, nil)
@uses_window.visible = false
end
#
# * OVERWRITTEN
# - right-align flag ignored
#
alias :eds_pre_ff9_menu_win_stat_show_target_window :show_target_window
def show_target_window(right)
@uses_window.item = @item_window.item
@uses_window.visible = true
@item_window.visible = false
@item_window.active = false
@target_window.visible = true
@target_window.active = true
@viewport.rect.set(0, 0, 544, 416)
@viewport.ox = 0
end
#
# * hide_target_window
#
alias :eds_pre_ff9_menu_scene_item_hide_target_window :hide_target_window
def hide_target_window
eds_pre_ff9_menu_scene_item_hide_target_window
@uses_window.visible = false unless @uses_window.nil?
@item_window.visible = true
end
#
# * determine_target
#
alias :eds_pre_ff9_menu_scene_item_determine_target :determine_target
def determine_target
eds_pre_ff9_menu_scene_item_determine_target
@uses_window.item = @item_window.item
end
#
# * Termination Processing
#
alias :eds_pre_ff9_menu_scene_item_terminate :terminate
def terminate
eds_pre_ff9_menu_scene_item_terminate
@uses_window.dispose
end
end
class Scene_Skill < Scene_Base
#
# * start
#
alias :eds_pre_ff9_menu_scene_skill_start :start
def start
eds_pre_ff9_menu_scene_skill_start
@target_window.y = 58
@uses_window = Window_SkillUses.new(true, @help_window.height, nil, nil)
@uses_window.visible = false
end
#
# * OVERWRITTEN
# - right-align flag ignored
#
def show_target_window(right)
@uses_window.set_skill($game_party.members[@actor_index], @skill_window.skill)
@uses_window.visible = true
@status_window.visible = false
@skill_window.visible = false
@skill_window.active = false
@target_window.visible = true
@target_window.active = true
@viewport.rect.set(0, 0, 544, 416)
@viewport.ox = 0
end
#
# * hide_target_window
#
alias :eds_pre_ff9_menu_scene_skill_hide_target_window :hide_target_window
def hide_target_window
eds_pre_ff9_menu_scene_skill_hide_target_window
@uses_window.visible = false unless @uses_window.nil?
@skill_window.visible = true
@status_window.visible = true
end
#
# * determine_target
#
alias :eds_pre_ff9_menu_scene_skill_determine_target :determine_target
def determine_target
eds_pre_ff9_menu_scene_skill_determine_target
@uses_window.set_skill($game_party.members[@actor_index], @skill_window.skill)
end
#
# * Termination Processing
#
alias :eds_pre_ff9_menu_scene_item_terminate :terminate
def terminate
eds_pre_ff9_menu_scene_item_terminate
@uses_window.dispose
end
end