This is a cobbled together and probably terrible example of the first thing I ever scripted myself. I didn't follow a tutorial or look up how to do anything, I just messed with things until they worked and it was so long ago, I have honestly forgotten everything I learned. Now I want to relearn so I can finish what I started, and I've hit a wall just trying to get what little is here to work.
As it is, it works in the project I coded it in and in my older test project but not in any new project(namely, the one I want it for). The ini files are basically identical, so it's not the dlls as far as I know. I tried copying all of the extra scripts I'm using to the projects the cms works in and it still works, so it's not a script conflict. I'm not sure what else to try.
I'd really like to finish the menu and use it, but if just this little bit wont work, there's no point.
The specific crash that happens is not immediate. It only crashes if I open the menu, close the menu and then try to open it again. The RGSS player stops working.
So- I am asking if any of the actual scripters out there could look it over and tell me if it's the script itself that's causing the crashes. I plan to rewrite the entire thing anyway, but I'd like to know what is wrong with this one so I don't make the same mistakes.
I'm not going to lie about how utterly new I am to this, so feel free to point and laugh if it's something anyone with half a brain would have noticed. ><
Attachment; .zip file of icons needed to actually test it
#==============================================================================
# One Hero CMS
# Very simple menu
# Cobbled together by; Dyre
#==============================================================================
class Window_Base < Window
def draw_actor_battler(actor, x, y)
face = RPG::Cache.battler(actor.name, actor.character_hue)
fw = face.width
fh = face.height
src_rect = Rect.new(0, 0, fw, fh)
self.contents.blt(20, -2, face, src_rect)
end
end
class Window_MenuStatus < Window_Selectable
def initialize
super(240, 122, 120, 280)
self.contents = Bitmap.new(110, 182)
refresh
end
def refresh
self.contents.clear
self.contents.font.size = 14
self.contents.font.name = $defaultfonttype
@item_max = 0
x = 180
y = 60
actor = $game_party.actors[0]
draw_actor_battler(actor, x, y)
draw_actor_name(actor, x, y )
draw_actor_state(actor, x, y)
self.contents.font.color = system_color
draw_actor_hp(actor, x , y)
draw_actor_sp(actor, x , y)
end
end
#----------------
##----Scene_Menu
#----------------
class Scene_Menu
#--------------------------------------------------------------------------
# * Object Initialization
# menu_index : command cursor's initial position
#--------------------------------------------------------------------------
def initialize(menu_index = 0)
@menu_index = menu_index
end
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Make command window
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "Status"
s5 = "End Game"
@spriteset = Spriteset_Map.new
@command_window = Window_Command.new(87, [s1, s2, s3, s4, s5])
@command_window.opacity = 128
@command_window.x = 157
@command_window.y = 135
@command_window.index = @menu_index
# If number of party members is 0
if $game_party.actors.size == 0
# Disable items, skills, equipment, and status
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
@command_window.disable_item(4)
end
# Make gold window
@gold_window = Window_Gold.new
@gold_window.height = 60
@gold_window.x = 82
@gold_window.y = 65
@gold_window.opacity= 128
# Make status window
@status_window = Window_MenuStatus.new
@status_window.width = 145
@status_window.height = 216
@status_window.opacity= 128
# Make location window
@window_location = Window_Location.new
@window_location.x = 195
@window_location.y = 65
@window_location.opacity = 128
#mMake playtime window
@playtime_window = Window_PlayTime.new
@playtime_window.x = 420
@playtime_window.y = 65
@playtime_window.opacity = 128
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@window_location.dispose
@command_window.dispose
@playtime_window.dispose
@gold_window.dispose
@status_window.dispose
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Update windows
@spriteset.update
@window_location.update
@command_window.update
@playtime_window.update
@gold_window.update
@status_window.update
# If command window is active: call update_command
if @command_window.active
update_command
return
end
# If status window is active: call update_status
if @status_window.active
update_status
return
end
end
#--------------------------------------------------------------------------
# * Frame Update (when command window is active)
#--------------------------------------------------------------------------
def update_command
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to map screen
$scene = Scene_Map.new
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# If command other than save or end game, and party members = 0
if $game_party.actors.size == 0 and @command_window.index < 4
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Branch by command window cursor position
case @command_window.index
when 0 # item
# Play decision SE
$game_system.se_play($data_system.decision_se)
$scene = Scene_Item.new
when 1 # skill
# Play decision SE
$game_system.se_play($data_system.decision_se)
$scene = Scene_Skill.new
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
$scene = Scene_Equip.new
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
$scene = Scene_Status.new
when 4 # end game
# Play decision SE
$game_system.se_play($data_system.decision_se)
$scene = Scene_End.new
end
return
end
end
#--------------------------------------------------------------------------
# * Frame Update (when status window is active)
#--------------------------------------------------------------------------
def update_status
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Make command window active
@command_window.active = true
@status_window.active = false
@status_window.index = -1
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Branch by command window cursor position
case @command_window.index
when 1 # skill
# If this actor's action limit is 2 or more
if $game_party.actors[@status_window.index].restriction >= 2
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to skill screen
$scene = Scene_Skill.new(@status_window.index)
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to equipment screen
$scene = Scene_Equip.new(@status_window.index)
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to status screen
$scene = Scene_Status.new(@status_window.index)
end
return
end
end
class Window_Command < Window_Selectable
#--------------------------------------------------------------------------
# * Object Initialization
# width : window width
# commands : command text string array
#--------------------------------------------------------------------------
def initialize(width, commands)
# Compute window height from command quantity
super(0, 0, width, commands.size * 32 + 32)
@item_max = commands.size
@commands = commands
self.contents = Bitmap.new(width - 32, @item_max * 32)
self.contents.font.name = $defaultfonttype
self.contents.font.size = $defaultfontsize
refresh
self.index = 0
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
for i in 0...@item_max
draw_item(i, normal_color)
end
end
#--------------------------------------------------------------------------
# * Draw Item
# index : item number
# color : text color
#--------------------------------------------------------------------------
def draw_item(index, color)
rect = Rect.new(16, 32 * index + 5, 24, 24)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
ico_bmp = RPG::Cache.icon(@commands[index])
self.contents.stretch_blt(rect, ico_bmp, Rect.new(0,0,ico_bmp.width, ico_bmp.height))
end
#--------------------------------------------------------------------------
# * Disable Item
# index : item number
#--------------------------------------------------------------------------
def disable_item(index)
draw_item(index, disabled_color)
end
end
#----Window_Gold
class Window_Gold < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(10, 0, 120, 60)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = $defaultfonttype
self.contents.font.size = 14
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
cx = contents.text_size($data_system.words.gold).width
self.contents.font.color = normal_color
self.contents.draw_text(26, 0, 60, 32, $game_party.gold.to_s, 1)
self.contents.font.color = system_color
self.contents.blt(0, 0, RPG::Cache.icon("032-item01"), Rect.new(0, 0, 24, 24))
end
end
#---- Window_PlayTime
class Window_PlayTime < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 0, 120, 60)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = "Georgia"
self.contents.font.size = 14
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
self.contents.font.color = system_color
self.contents.blt(-2, 0, RPG::Cache.icon("Playtime"), Rect.new(0, 0, 24, 24))
@total_sec = Graphics.frame_count / Graphics.frame_rate
hour = @total_sec / 60 / 60
min = @total_sec / 60 % 60
sec = @total_sec % 60
text = sprintf("%02d:%02d:%02d", hour, min, sec)
self.contents.font.color = normal_color
self.contents.draw_text(2, 0, 100, 32, text, 1)
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
if Graphics.frame_count / Graphics.frame_rate != @total_sec
refresh
end
end
end
#=========================================================================
# ** Window_Location
#------------------------------------------------------------------------------
# This window displays play time on the menu screen.
#==============================================================================
class Window_Location < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 0, 230, 65)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = "Georgia"
self.contents.font.size = 14
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
$location_info = load_data("Data/MapInfos.rxdata")
self.contents.font.color = system_color
self.contents.draw_text(42, -10, 120, 32, "Location:", 1)
self.contents.font.color = normal_color
self.contents.font.name = "Gabriola"
self.contents.font.size = 26
text = $location_info[$game_map.map_id].name
self.contents.draw_text ( 20 , 10, 160, 32, text, 1)
end
end
##end##
####-----------------####
####BEGIN SCENE TEST####
####-----------------####
# ** Scene_Status
#------------------------------------------------------------------------------
# This class performs status screen processing.
#==============================================================================
class Scene_Status
#--------------------------------------------------------------------------
# * Object Initialization
# actor_index : actor index
#--------------------------------------------------------------------------
def initialize(actor_index = 0, equip_index = 0)
@actor_index = actor_index
end
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Get actor
@actor = $game_party.actors[@actor_index]
# Make status window
@status_window = Window_Status.new(@actor)
@status_window.opacity = 128
@status_window.height = 450
@status_window.width = 250
@status_window.x = 190
@status_window.y = 10
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@status_window.dispose
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to menu screen
$scene = Scene_Menu.new(3)
return
end
# If R button was pressed
if Input.trigger?(Input::R)
# Play cursor SE
$game_system.se_play($data_system.cursor_se)
# To next actor
@actor_index += 1
@actor_index %= $game_party.actors.size
# Switch to different status screen
$scene = Scene_Status.new(@actor_index)
return
end
# If L button was pressed
if Input.trigger?(Input::L)
# Play cursor SE
$game_system.se_play($data_system.cursor_se)
# To previous actor
@actor_index += $game_party.actors.size - 1
@actor_index %= $game_party.actors.size
# Switch to different status screen
$scene = Scene_Status.new(@actor_index)
return
end
end
end
#==============================================================================
# ** Window_Status
#------------------------------------------------------------------------------
# This window displays full status specs on the status screen.
#==============================================================================
class Window_Status < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
# actor : actor
#--------------------------------------------------------------------------
def initialize(actor)
super(0, 0, 250, 450)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = "Georgia"
self.contents.font.size = 16
@actor = actor
refresh
end
def draw_actor_battler(actor, x, y)
face = RPG::Cache.battler(actor.character_name, actor.character_hue)
fw = 120
fh = 210
src_rect = Rect.new(0, 0, fw, fh)
self.contents.blt(65, 100, face, src_rect)
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
draw_actor_battler(@actor, -5, 0)
draw_actor_name(@actor, 85, 0)
draw_actor_class(@actor, 20, 30)
draw_actor_state(@actor, 8 + 140, 30)
draw_actor_hp(@actor, 30, 55, 172)
draw_actor_sp(@actor, 30, 75, 172)
draw_actor_parameter(@actor, 25, 114, 0)
draw_actor_parameter(@actor, 25, 134, 1)
draw_actor_parameter(@actor, 25, 156, 2)
draw_actor_parameter(@actor, 25, 190, 3)
draw_actor_parameter(@actor, 25, 236, 4)
draw_actor_parameter(@actor, 25, 268, 5)
draw_actor_parameter(@actor, 25, 290, 6)
self.contents.font.name = "Arial"
self.contents.font.size = 12
draw_item_name($data_weapons[@actor.weapon_id], 55, 325)
draw_item_name($data_armors[@actor.armor1_id], -1, 390)
draw_item_name($data_armors[@actor.armor2_id], 130, 355)
draw_item_name($data_armors[@actor.armor3_id], -1, 355)
draw_item_name($data_armors[@actor.armor4_id], 130, 390)
end
def dummy
self.contents.font.color = system_color
self.contents.draw_text(58, 330, 96, 32, $data_system.words.weapon)
self.contents.draw_text(-5, 360, 96, 32, $data_system.words.armor1)
self.contents.draw_text(135, 380, 96, 32, $data_system.words.armor2)
self.contents.draw_text(-5, 360, 96, 32, $data_system.words.armor3)
self.contents.draw_text(135, 380, 96, 32, $data_system.words.armor4)
draw_item_name($data_weapons[@actor.weapon_id], 50, 144)
draw_item_name($data_armors[@actor.armor1_id], -3, 208)
draw_item_name($data_armors[@actor.armor2_id], 120, 272)
draw_item_name($data_armors[@actor.armor3_id], -3, 336)
draw_item_name($data_armors[@actor.armor4_id], 120, 400)
end
end
end
#==============================================================================
# ** Scene_Item
#------------------------------------------------------------------------------
# This class performs item screen processing.
#==============================================================================
class Scene_Item
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Make help window, item window
@help_window = Window_Help.new
@help_window.opacity = 128
@help_window.width = 260
@help_window.x = 190
@help_window.y = 30
@item_window = Window_Item.new
@item_window.opacity = 128
@item_window.width = 260
@item_window.height = 290
@item_window.x = 190
@item_window.y = 90
@itemname_window = Window_Base.new (190, 375, 260, 80)
@itemname_window.opacity = 128
# Associate help window
@item_window.help_window = @help_window
# Make target window (set to invisible / inactive)
@target_window = Window_Target.new
@target_window.visible = false
@target_window.active = false
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@help_window.dispose
@item_window.dispose
@itemname_window.dispose
@target_window.dispose
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Update windows
@help_window.update
@item_window.update
@itemname_window.update
@target_window.update
# If item window is active: call update_item
if @item_window.active
update_item
return
end
# If target window is active: call update_target
if @target_window.active
update_target
return
end
end
#--------------------------------------------------------------------------
# * Frame Update (when item window is active)
#--------------------------------------------------------------------------
def update_item
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to menu screen
$scene = Scene_Menu.new(0)
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Get currently selected data on the item window
@item = @item_window.item
# If not a use item
unless @item.is_a?(RPG::Item)
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# If it can't be used
unless $game_party.item_can_use?(@item.id)
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# If effect scope is an ally
if @item.scope >= 3
# Activate target window
@item_window.active = false
@target_window.x = (@item_window.index + 1) % 2 * 304
@target_window.visible = true
@target_window.active = true
# Set cursor position to effect scope (single / all)
if @item.scope == 4 || @item.scope == 6
@target_window.index = -1
else
@target_window.index = 0
end
# If effect scope is other than an ally
else
# If command event ID is valid
if @item.common_event_id > 0
# Command event call reservation
$game_temp.common_event_id = @item.common_event_id
# Play item use SE
$game_system.se_play(@item.menu_se)
# If consumable
if @item.consumable
# Decrease used items by 1
$game_party.lose_item(@item.id, 1)
# Draw item window item
@item_window.draw_item(@item_window.index)
end
# Switch to map screen
$scene = Scene_Map.new
return
end
end
return
end
end
#--------------------------------------------------------------------------
# * Frame Update (when target window is active)
#--------------------------------------------------------------------------
def update_target
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# If unable to use because items ran out
unless $game_party.item_can_use?(@item.id)
# Remake item window contents
@item_window.refresh
end
# Erase target window
@item_window.active = true
@target_window.visible = false
@target_window.active = false
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# If items are used up
if $game_party.item_number(@item.id) == 0
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# If target is all
if @target_window.index == -1
# Apply item effects to entire party
used = false
for i in $game_party.actors
used |= i.item_effect(@item)
end
end
# If single target
if @target_window.index >= 0
# Apply item use effects to target actor
target = $game_party.actors[@target_window.index]
used = target.item_effect(@item)
end
# If an item was used
if used
# Play item use SE
$game_system.se_play(@item.menu_se)
# If consumable
if @item.consumable
# Decrease used items by 1
$game_party.lose_item(@item.id, 1)
# Redraw item window item
@item_window.draw_item(@item_window.index)
end
# Remake target window contents
@target_window.refresh
# If all party members are dead
if $game_party.all_dead?
# Switch to game over screen
$scene = Scene_Gameover.new
return
end
# If common event ID is valid
if @item.common_event_id > 0
# Common event call reservation
$game_temp.common_event_id = @item.common_event_id
# Switch to map screen
$scene = Scene_Map.new
return
end
end
# If item wasn't used
unless used
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
end
return
end
end
end
#==============================================================================
# ** Window_Item
#------------------------------------------------------------------------------
# This window displays items in possession on the item and battle screens.
#==============================================================================
class Window_Item < Window_Selectable
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 64, 260, 290)
@column_max = 5
refresh
self.index = 0
# If in battle, move window to center of screen
# and make it semi-transparent
if $game_temp.in_battle
self.y = 64
self.height = 256
self.back_opacity = 128
end
end
#--------------------------------------------------------------------------
# * Get Item
#--------------------------------------------------------------------------
def item
return @data[self.index]
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
# Add item
for i in 1...$data_items.size
if $game_party.item_number(i) > 0
@data.push($data_items[i])
end
end
# Also add weapons and items if outside of battle
unless $game_temp.in_battle
for i in 1...$data_weapons.size
if $game_party.weapon_number(i) > 0
@data.push($data_weapons[i])
end
end
for i in 1...$data_armors.size
if $game_party.armor_number(i) > 0
@data.push($data_armors[i])
end
end
end
# If item count is not 0, make a bit map and draw all items
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
for i in 0...@item_max
draw_item(i)
end
end
end
#--------------------------------------------------------------------------
# * Draw Item
# index : item number
#--------------------------------------------------------------------------
def draw_item(index)
item = @data[index]
case item
when RPG::Item
number = $game_party.item_number(item.id)
when RPG::Weapon
number = $game_party.weapon_number(item.id)
when RPG::Armor
number = $game_party.armor_number(item.id)
end
if item.is_a?(RPG::Item) and
$game_party.item_can_use?(item.id)
self.contents.font.color = normal_color
else
self.contents.font.color = disabled_color
end
x = - 3 + index % 5 * (20 + 32)
y = index / 5 * 32
rect = Rect.new(x, y, self.width / @column_max - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
self.contents.font.name = "Georgia"
self.contents.font.size = 12
bitmap = RPG::Cache.icon(item.icon_name)
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
self.contents.draw_text(x , y + 10, 24, 24, number.to_s, 2)
end
#--------------------------------------------------------------------------
# * Help Text Update
#--------------------------------------------------------------------------
def update_help
@help_window.set_text(self.item == nil ? "" : self.item.description)
end
def update_itemname
@itemname_window.set_text(self.item == nil ? "" : self.item.name)
end
end
Just a warning: this is a pretty long post because I like explaining. The tl;dr version is there's an attachment with a version of your script that almost works. You need to change a line of code, but you'll have to read the post to find what bit (it has to do with RPG::Cache being given the wrong filename).
After reformatting the code layout (it's worth making sure that code is written using a 2 space indentation in the same way the default scripts are written), and taking out the nested classes, I got an error telling me that there is 'no implicit conversion from nil to integer'.
This comes up because you have the variables $defaultfonttype and $defaultfontsize that are never initialized with a value, thus when you first use them they are given the value 'nil' by default. $defaultfonttype is fine being nil, because Font doesn't do any type checking on this. Font does do type checking on passed in sizes, however, meaning a TypeError will flag when trying to set font.size to anything other than an integer (it may also check for positive values or take the absolute value of the integer passed in).
The Font class does already contain class properties that define the default values for name, size, bold, italic and color that are shared across all instances of Font, that are used to initialise the instance properties. You can change these at any time. You can do this like so:
Font.default_name = "MS PMincho"
Font.default_size = 12
Font.default_bold = true
Would make all Fonts use MS PMincho, with size 12 and bolded, unless otherwise told to use something different.
This code you can place pretty much anywhere, for example:
#==============================================================================
# One Hero CMS
# Very simple menu
# Cobbled together by; Dyre
#==============================================================================
Font.default_name = "MS PMincho"
Font.default_size = 12
Font.default_bold = true
class Window_Base < Window
#class stuff
end
As for those nested classes, they probably weren't intentional. Pay close attention to where those ends are and make sure they line up. That's why code layout is important; it allows you to see almost instantly where there could be problems.
I went through the code and stripped out all of the methods and the code within them. This way, we can see your class hierarchy a little more clearer:
class Window_Base < Window
end
class Window_MenuStatus < Window_Selectable
end
class Scene_Menu
class Window_Command < Window_Selectable
end
class Window_Gold < Window_Base
end
class Window_PlayTime < Window_Base
end
class Window_Location < Window_Base
end
class Scene_Status
end
class Window_Status < Window_Base
end
end
class Scene_Item
end
class Window_Item < Window_Selectable
end
Window_Command
Window_Gold
Window_PlayTime
Window_Location
Scene_Status
Window_Status
All of the above list of classes are nested within Scene_Menu. Whilst this isn't a huge problem, in fact you probably won't see any issue whatsoever as it is, it means that any changes you later make to those classes, say with another script, will not be changing the class you would be expecting.
For example, say you use a script that enhances Scene_Status to add in more stats to the display (assuming you are using a script that gives additional stats). The Scene_Status class that will be enhanced will be the Scene_Status that exists in the global namespace. Your Scene_Status is actually known as Scene_Menu::Scene_Status.
Like I said earlier, this probably wasn't done intentionally, especially if it was a first script. Chances are you came across the "expected end but got something else" error at line 530 and plopped in an end to make it work.
Another issue that I have, is that my battler graphics aren't named to correspond to the actual actor's name; they are of the default "xxx-class_name_yy" variant. This error is caused by line 17 in my formatted version:
face = RPG::Cache.battler(actor.name, actor.character_hue)
The filename you are giving to load the bitmap for is the name of the actor. You want to change this line to:
face = RPG::Cache.battler(actor.battler_name, actor.character_hue)
This will now load up the correct file.
I haven't added this change in my formatted version of the script, so you'll have to do this part.
Once this line has been changed, I have had no issues with the script. You may want to change the Font info to suit, but other than that, there shouldn't be too many problems now.
So, the only real issue you had was the 'nil to integer' error caused by uninitialised variables. The rest is mostly cleaning up and pointing RPG::Cache to the correct file name.
You'll find the formatted and edited version of your script below in attachments. It provides the default values for the Font class that you can uncomment and change. I also removed the nesting of those classes as it will improve compatibility with other scripts; rather I should say to ensure they work in the way you would expect.
Let me know if there's any issues with the attached script.
As an added note, here's a tip to make sure you don't accidently nest classes unintentionally (and to help make sure you're ends are matching):
Whenever you write an 'end', make a comment after it explicitly noting what the end matches to. You can always sweep them off when the script is done, but I do this sometimes when the method is long or contains a lot of ends. Another way is to make sure you write your ends first before adding other code:
class New_Class_Name #1
def method #3
if some_condition#5
some_if_code #7
end#6, if some_condition
end #4, def method
end #2, class
The numbers denote the order I wrote the code (you don't have to write those), and a note after saying what it ends (but do write this). These comments can easily be removed once you're finished and have done proof reading it (removing those comments also means you are proof reading as you find them).
Hopefully this all helps.
That was incredibly helpful for future scripting attempts. Unfortunately, the script itself is still crashing the RGSS player. Also, everything now uses icons instead of text for some reason. No text is shown in the title menu, or the equip menu, just icons.
I'm thinking it may just be my project. It works in new projects (though the icon issue is still present), just not in the one I want it for. I will probably have to copy my maps, events and database over to a new project if I want to use this menu.
Still, thank you for the assistance. Now I know it's my project at least.
Do you have any other scripts being used in your project?
I only looked at this as a script on it's own with no other non-default scripts in place. There may be a conflict somewhere else. If you want to upload a copy of your project (you can PM me a link if you want it kept out of public view) and I'll take a look at it.
The icons showing up instead of text happens for me too. Let me just nosy through the script a moment...
Right, what you've done is overwritten how Window_Command works. Lines 280-285 is the particular method and I'll put it up here:
def draw_item(index, color)
rect = Rect.new(16, 32 * index + 5, 24, 24)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
ico_bmp = RPG::Cache.icon(@commands[index])
self.contents.stretch_blt(rect, ico_bmp, Rect.new(0,0,ico_bmp.width, ico_bmp.height))
end
If we work through those lines we can see that no text is ever drawn, only an icon that is then block transferred to the contents bitmap. What you also need to do is call the draw_text method on the bitmap 'contents' after the icon has been placed.
Something akin to this:
def draw_item(index, color)
rect = Rect.new(16, 32 * index + 5, 24, 24)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
ico_bmp = RPG::Cache.icon(@commands[index])
self.contents.stretch_blt(rect, ico_bmp, Rect.new(0,0,ico_bmp.width, ico_bmp.height))
rect.x += ico_bmp.width
rect.width = self.contents.width
self.contents.draw_text(rect, @commands[index])
end
Three extra lines appended to the method. The first two just makes use of the already existing rect object to use for our text bitmap. I prefer to reuse variables wherever I can - it's a little cheaper than making a whole new Rect object when all I need to do is make one or two slight changes compared to the already existing object.
Then we just draw the name located at the index element of the @commands array.
This brings up a very important issue with regards to reopening classes and taking care when overwriting methods. When you've reopened a class - by using the line class Klass_Name (where Klass_Name already exists) - if you then define a method that also already exists in the class, you'll overwrite the original version. That is, assuming the reopened class changes the method after the original version has been defined - if you swapped the scripts around, you'd find that your version is overwritten by the default script in the case of 'class Window_Command'.
There's two ways (that I know of) that can help this:
The first is aliasing the method. This is giving the original method a new name, whilst retaining the old definition (so that it can still be accessed when you call it). I won't go into too much on it right now, but you can look it up online (I used this (http://blog.jayfields.com/2006/12/ruby-alias-method-alternative.html) the first time I looked it up). The other, and easier way I think, is to make a new class that inherits from Window_Command:
class My_Window_Command < Window_Command
def draw_item
#An instance of My_Window_Command draws items like this and not like it
# does in Window_Command.
end
end
Inheriting from another class allows access to the methods in the base class (the class we inherited from) and we can use the same names as the methods in the base class without overwriting them. We can still access them too via the super keyword:
class My_Window_Command < Window_Command
def draw_item(index)
# Draw item as you would in Window_Command first
super
# Then continue to draw_item in this way
end
end
If there are arguments being passed into draw_item, like index, then using the 'super' keyword alone will pass all of the same arguments to the draw_item method in Window_Command. If you do 'super()', then no arguments are passed. Then you can also specify which arguments are passed like so: 'super(index)'. Sometimes you need to be aware of what arguments might need to be passed, if any, when using super - you might end up with some 'wrong number of arguments (x for y)' errors and this is why and how to fix it.
There are differences between aliasing and inheriting, where one is better to do than the other, but I'll also leave that out for now.
As a note, you might want to play around with the design of the menu. The text doesn't quite fit properly in that little window you have for the menu commands with icons there too.
Hopefully this is also of assistance. Like I said, I'm happy to look over the project and see what might be causing the issue. Just PM me a link to an upload and I'll get to it when I can.
You'll find an updated version of the script below that contains both fixes - the battler_name issues I mentioned in the previous post, and also the fix for Window_Command.