This is nothing special, but something I tried to experiment with scripting, and in this case, changing the characters' equipment during battle, as I thought it would be an interesting mechanic. This is just using the default battle system, so nothing really special is going on here. Needless to say, I keep failing at it. :facepalm:
Basically, Scene_Battle 1 and 3 are the ones I am editing to test this out, but I think I am just doing things without understanding how it works. The issue is mostly with Scene_Battle 3, as 1 is only the menu which you use to edit the battle menu, so I have that done. So as of now, the segment from line 110ish looks like this:
Quotedef update_phase3_basic_command
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Go to command input for previous actor
phase3_prior_actor
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Branch by actor command window cursor position
case @actor_command_window.index
when 0 # attack
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Set action
@active_battler.current_action.kind = 0
@active_battler.current_action.basic = 0
# Start enemy selection
start_enemy_select
when 1 # skill
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Set action
@active_battler.current_action.kind = 1
# Start skill selection
start_skill_select
when 2 # equip
$game_system.se_play($data_system.decision_se)
$scene = Scene_Equip.new
when 3 # guard
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Set action
@active_battler.current_action.kind = 0
@active_battler.current_action.basic = 1
# Go to command input for next actor
phase3_next_actor
when 4 # item
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Set action
@active_battler.current_action.kind = 2
# Start item selection
start_item_select
end
return
end
end
I know I have to do more than this to get it to work, and I experimented with a lot of things, but comes up with "uninitialized constant" and other assorted errors. I would like any form of assistance. Thank you.
Obvious problem is that you can't use Scene_Equip directly. That $scene global variable is a finicky thing to work with. The idea behind scenes, at least in the way Enterbrain designed them, is that they assume you are done with the previous scene and no longer need it. Everything gets disposed and all the little switches and variables that the previous scene stored are now gone. So even if you were able to get to Scene_Equip and go back to Scene_Battle...you'd be right back at the start of a new fight.
The best way to handle this situation is to make Scene_Equip, well, scene-less. Like so
class Sceneless_Equip
#--------------------------------------------------------------------------
# * Object Initialization
# actor_index : actor index
# equip_index : equipment index
#--------------------------------------------------------------------------
def initialize(actor_index = 0, equip_index = 0)
@actor_index = actor_index
@equip_index = equip_index
end
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Get actor
@actor = $game_actors[@actor_index]
# Make windows
@help_window = Window_Help.new
@left_window = Window_EquipLeft.new(@actor)
@right_window = Window_EquipRight.new(@actor)
@item_window1 = Window_EquipItem.new(@actor, 0)
@item_window2 = Window_EquipItem.new(@actor, 1)
@item_window3 = Window_EquipItem.new(@actor, 2)
@item_window4 = Window_EquipItem.new(@actor, 3)
@item_window5 = Window_EquipItem.new(@actor, 4)
# Associate help window
@right_window.help_window = @help_window
@item_window1.help_window = @help_window
@item_window2.help_window = @help_window
@item_window3.help_window = @help_window
@item_window4.help_window = @help_window
@item_window5.help_window = @help_window
# Set cursor position
@right_window.index = @equip_index
@abort = false
refresh
# 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
break if @abort
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@help_window.dispose
@left_window.dispose
@right_window.dispose
@item_window1.dispose
@item_window2.dispose
@item_window3.dispose
@item_window4.dispose
@item_window5.dispose
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
# Set item window to visible
@item_window1.visible = (@right_window.index == 0)
@item_window2.visible = (@right_window.index == 1)
@item_window3.visible = (@right_window.index == 2)
@item_window4.visible = (@right_window.index == 3)
@item_window5.visible = (@right_window.index == 4)
# Get currently equipped item
item1 = @right_window.item
# Set current item window to @item_window
case @right_window.index
when 0
@item_window = @item_window1
when 1
@item_window = @item_window2
when 2
@item_window = @item_window3
when 3
@item_window = @item_window4
when 4
@item_window = @item_window5
end
# If right window is active
if @right_window.active
# Erase parameters for after equipment change
@left_window.set_new_parameters(nil, nil, nil)
end
# If item window is active
if @item_window.active
# Get currently selected item
item2 = @item_window.item
# Change equipment
last_hp = @actor.hp
last_sp = @actor.sp
@actor.equip(@right_window.index, item2 == nil ? 0 : item2.id)
# Get parameters for after equipment change
new_atk = @actor.atk
new_pdef = @actor.pdef
new_mdef = @actor.mdef
# Return equipment
@actor.equip(@right_window.index, item1 == nil ? 0 : item1.id)
@actor.hp = last_hp
@actor.sp = last_sp
# Draw in left window
@left_window.set_new_parameters(new_atk, new_pdef, new_mdef)
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Update windows
@left_window.update
@right_window.update
@item_window.update
refresh
# If right window is active: call update_right
if @right_window.active
update_right
return
end
# If item window is active: call update_item
if @item_window.active
update_item
return
end
end
#--------------------------------------------------------------------------
# * Frame Update (when right window is active)
#--------------------------------------------------------------------------
def update_right
# 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
@abort = true
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# If equipment is fixed
if @actor.equip_fix?(@right_window.index)
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Activate item window
@right_window.active = false
@item_window.active = true
@item_window.index = 0
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)
# Activate right window
@right_window.active = true
@item_window.active = false
@item_window.index = -1
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Play equip SE
$game_system.se_play($data_system.equip_se)
# Get currently selected data on the item window
item = @item_window.item
# Change equipment
@actor.equip(@right_window.index, item == nil ? 0 : item.id)
# Activate right window
@right_window.active = true
@item_window.active = false
@item_window.index = -1
# Remake right window and item window contents
@right_window.refresh
@item_window.refresh
return
end
end
end
And you call it up like so from Scene_Battle
s = Sceneless_Equip.new(@active_battler.id)
s.main
The only change is that I got rid of the pesky
$scene != self to signify when we are done. Instead, this is handled with a single boolean
@abort, which gets turned to true when the B button is pressed. I also got rid of the L and R buttons to toggle between the different actors. Everything else is still the same.
Using the snippet you provided of your Scene_Battle 3, this is what I would do:
when 2 # equip
$game_system.se_play($data_system.decision_se)
Graphics.freeze
@status_window.visible = false
@actor_command_window.visible = false
@spriteset.toggle_viewports
s = Sceneless_Equip.new(@active_battler.id)
s.main
@spriteset.toggle_viewports
@status_window.visible = true
@actor_command_window.visible = true
Graphics.transition
And here's the
toggle_viewports method.
class Spriteset_Battle
def toggle_viewports
@viewport1.visible = @viewport2.visible =
@viewport3.visible = @viewport4.visible = !@viewport1.visible
end
end
We first freeze the graphics so that we can make a smooth transition to our equipment scene. We then hide the windows and viewports since they stick up through the equipment windows (go ahead and remove those lines to see for yourself). Then we call our equip "scene" and its update loop
main. It stays at this point until we abort the equip, which it will then bring back the windows and viewports we hid earlier, and makes the Graphics transition to smooth ourselves back into battle.
And the GIF of it working (4MB)
(http://i.imgur.com/cORTfeK.gif)
Thanks a lot! I did not realise those dispose window stuff meant completely discarding the information. It also would have caused problems too as using Scene_Equip directly with some of Blizzard's scripts ended up getting me to the Stat Distribution Window, and of course exiting it led to crashes. I think this should just be a regular script for others to use as well, but it really is just reconfiguring the main scripts anyways.
It's not just the "dispose window" that discards the information. It's also the fact you're removing the instance stored in $scene variable from memory. In battle, $scene is an instance of Scene_Battle. When you do
you're overwriting the Scene_Battle instance with Scene_Equip now. You're telling the program "I'm done with Scene_Battle. Remove it from memory." All the stuff outside of the scene's loop (disposing of windows) is then called to properly dispose its graphics so that they don't "bleed" into the next scene.
In RMVXA, they have a Scene_Manager class that keeps track of the order you go from one scene to the next, so I think it's possible to switch scenes without destroying the previous one. Can't recall.