Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

[RGSS] Command index not updating properly

Welcome to the "I was so close to figuring this out then this happened" Chronicles

So, what I was trying to do was make a one-scene CMS, which is going great. In fact, everything is working fine.
The problem is that when I was adding the Equip info (which I knew it was going to be the hardest so I saved it for last), moving up and down the choice slots isn't working correctly. The other screens are, and still are, working.

When I activate the "Equip" window, it selects and can equip properly, but every time I press the "down" and "up" button the index of the window jumps by two instead of one. And, when selecting replacement equipment in the equip item window, the index jumps by 3 instead of one. Everything equips properly, it's just really annoying to see the jump all the time.

Here are the scripts that correspond with the menu and the processing that handles the equip windows.

Part 1
Code:
 

#==============================================================================

# ** Scene_Menu

#------------------------------------------------------------------------------

#  This class performs menu screen processing.

#==============================================================================

 

class Scene_Menu

  #--------------------------------------------------------------------------

  # * Object Initialization

  #     menu_index : command cursor's initial position

  #--------------------------------------------------------------------------

  def initialize(menu_index = 0, actor_index = 0)

    @menu_index = menu_index

    @actor_index = actor_index

  end

  #--------------------------------------------------------------------------

  # * Main Processing

  #--------------------------------------------------------------------------

  def main

    @actor = $game_party.actors[@actor_index]

    # Make command window

    s1 = $data_system.words.item

    s2 = $data_system.words.skill

    s3 = $data_system.words.equip

    s5 = "System"

    @command_window = Window_HorizCommand.new(640, [s1, s2, s3, s5])

    @command_window.index = @menu_index

    @command_window.opacity = 255

    

    @system_window = Window_Command.new(120, ["Save", "Load", "To Title"])

    @system_window.x = 490

    @system_window.y = 45

    @system_window.z += 10

    

    @system_window.visible = false

    @system_window.active = false

    

    @skill_window = Window_Skill.new(@actor)

    @skill_window.visible = false

    @skill_window.active = false

    

    @item_window = Window_Item.new

    @item_window.visible = false

    @item_window.active = false

    

    @equipright_window = Window_EquipRight.new(@actor)

    @equipitem_window1 = Window_EquipItem.new(@actor, 0)

    @equipitem_window4 = Window_EquipItem.new(@actor, 3)

    @equipitem_window5 = Window_EquipItem.new(@actor, 4)

    @equipright_window.visible = false

    @equipright_window.active = false

    @equipitem_window1.visible = false

    @equipitem_window1.active = false

    @equipitem_window4.visible = false

    @equipitem_window4.active = false

    @equipitem_window5.visible = false

    @equipitem_window5.active = false

    

    @help_window = Window_Help.new

    @help_window.visible = false

    

    @target_window = Window_Target.new

    @target_window.visible = false

    @target_window.active = false

    

    # If number of party members is 0

    if $game_party.actors.size == 0

      # Disable items, skills, equipment, and status

      @command_window.disable_item(0)

      @command_window.disable_item(1)

      @command_window.disable_item(2)

    end

    # Make play time window

    @spriteset = Spriteset_Map.new

    

    #left window

    @playtime_window = Window_Awesome.new(@actor)

    @playtime_window.opacity = 160

    @playtime_window.x = 0

    @playtime_window.y = 64

    #right window

    @playtimeb_window = Window_Awesome2.new(@actor)

    @playtimeb_window.opacity = 0

    @playtimeb_window.y = 64

    

    equiprefreshinitial

    # 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

    @command_window.dispose

    @playtime_window.dispose

    @playtimeb_window.dispose

    @system_window.dispose

    @skill_window.dispose

    @item_window.dispose

    @equipright_window.dispose

    @equipitem_window1.dispose

    @equipitem_window4.dispose

    @equipitem_window5.dispose

    @help_window.dispose

    @spriteset.dispose    

  end

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  def update

    # Update windows

    @command_window.update

    @playtime_window.update

    @playtimeb_window.update

    @system_window.update

    @skill_window.update

    @item_window.update

    @equipright_window.update

    @equipitem_window1.update

    @equipitem_window4.update

    @equipitem_window5.update

    @help_window.update

    if @equipitem_window

      if @equipitem_window.active

        @equipitem_window.update

      end

    end

    @spriteset.update

    # If command window is active: call update_command

    if @command_window.active

      update_command

      return

    end

    # update system

    if @system_window.active

      update_system

      return

    end

    #update skill

    if @skill_window.active

      update_skill

      return

    end

    #update item

    if @item_window.active

      update_item

      return

    end

 

    #update equip

    if @equipright_window.active

      update_equip

      return

    end

    if @equipitem_window

      if @equipitem_window.active

        update_equip

        return

      end

    end

 

  end

end

 

Part 2
Code:
 

#==============================================================================

# ** Scene_Menu

#------------------------------------------------------------------------------

#  This class performs menu screen processing.

#==============================================================================

 

class Scene_Menu  

  #--------------------------------------------------------------------------

  # * 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 < 3

        # 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)

        # Switch to item screen

        @item_window.active = true

        @item_window.visible = true

        @command_window.active = false

        @command_window.visible = false

        @help_window.visible = true

        @playtime_window.visible = false

        @item_window.help_window = @help_window

      when 1  # skill

        # Play decision SE

        $game_system.se_play($data_system.decision_se)

        # Make status window active

        @skill_window.active = true

        @skill_window.visible = true

        @command_window.active = false

        @command_window.visible = false

        @help_window.visible = true

        @skill_window.help_window = @help_window

 

      when 2  # equipment

        # Play decision SE

        $game_system.se_play($data_system.decision_se)

        # Make status window active

        @playtime_window.visible = false

        @equipright_window.visible = true

        @equipright_window.active = true

        @command_window.active = false

        @command_window.visible = false

        @equipright_window.help_window = @help_window

        @equipitem_window1.help_window = @help_window

        @equipitem_window4.help_window = @help_window

        @equipitem_window5.help_window = @help_window

        @equipright_window.index = 0

        when 3  # end game

        # Play decision SE

        $game_system.se_play($data_system.decision_se)

        # Switch to end game screen

        @command_window.active = false

        @system_window.visible = true

        @system_window.active = true

      end

      return

    end

  end

  #--------------------------------------------------------------------------

  # * Frame Update (when system window is active)

  #--------------------------------------------------------------------------

  def update_system

    # If B button was pressed

    if Input.trigger?(Input::B)

      # Play cancel SE

      $game_system.se_play($data_system.cancel_se)

      @command_window.active = true

      @system_window.visible = false

      @system_window.active = false

      return

    end

    # If C button was pressed

    if Input.trigger?(Input::C)

      # If command other than save or end game, and party members = 0

      # Branch by command window cursor position

      case @system_window.index

        when 0 

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          $scene = Scene_Save.new

        when 1  

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          $banana = true

          $scene = Scene_Load.new

        when 2  

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          Audio.bgm_fade(800)

          Audio.bgs_fade(800)

          Audio.me_fade(800)

          $scene = Scene_Title.new

        end

      return

    end

  end

end

 

Part 3
Code:
 

class Scene_Menu

  #--------------------------------------------------------------------------

  # * RefreshInitial

  #--------------------------------------------------------------------------

  def equiprefreshinitial

    # Set current item window to @item_window

    case @equipright_window.index

    when 0

      @equipitem_window = @equipitem_window1

    when 1

      @equipitem_window = @equipitem_window4

    when 2

      @equipitem_window = @equipitem_window5

    end

  end

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def equiprefresh

    # Set item window to visible

    @equipitem_window1.visible = (@equipright_window.index == 0)

    @equipitem_window4.visible = (@equipright_window.index == 1)

    @equipitem_window5.visible = (@equipright_window.index == 2)

    # Set current item window to @item_window

    case @equipright_window.index

    when 0

      @equipitem_window = @equipitem_window1

    when 1

      @equipitem_window = @equipitem_window4

    when 2

      @equipitem_window = @equipitem_window5

    end

  end

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  def update_equip

    # Update windows

    @playtime_window.update

    @equipright_window.update

#    if @equipitem_window

      @equipitem_window.update

#    end

    equiprefresh

    # If right window is active: call update_right

    if @equipright_window.active

      update_equipright

      return

    end

    # If item window is active: call update_item

    if @equipitem_window.active

      update_equipitem

      return

    end

  end

  #--------------------------------------------------------------------------

  # * Frame Update (when right window is active)

  #--------------------------------------------------------------------------

  def update_equipright

    # 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

      @playtime_window.visible = true

      @equipright_window.active = false

      @equipright_window.visible = false

      @equipitem_window.visible = false

      @command_window.visible = true

      @command_window.active = true

      return

    end

    # If C button was pressed

    if Input.trigger?(Input::C)

      # If equipment is fixed

      if @actor.equip_fix?(@equipright_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

      @equipright_window.active = false

      @equipitem_window.active = true

      @equipitem_window.index = 0

      return

    end

  end

  #--------------------------------------------------------------------------

  # * Frame Update (when item window is active)

  #--------------------------------------------------------------------------

  def update_equipitem

    # If B button was pressed

    if Input.trigger?(Input::B)

      # Play cancel SE

      $game_system.se_play($data_system.cancel_se)

      # Activate right window

      @equipright_window.active = true

      @equipitem_window.active = false

      @equipitem_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 = @equipitem_window.item

      # Change equipment

      if @equipright_window.index == 0

        @actor.equip(@equipright_window.index, item == nil ? 0 : item.id)

      else

        @actor.equip(@equipright_window.index + 2, item == nil ? 0 : item.id)

      end

      # Activate right window

      @equipright_window.active = true

      @equipitem_window.active = false

      @equipitem_window.index = -1

      # Remake right window and item window contents

      @equipright_window.refresh

      @equipitem_window.refresh

      @playtime_window.refresh

      return

    end

  end

end

 

Sooo much code, sorry.
This also probably isn't the best way to do this, either, but hey I wanted to write my own code and it's working (except FOR THIS ONE THING) so I'm happy....
I've been over this so many times I just cannot see where the issue is.

Thanks for your help, everyone!
 
The problem might not be in this script. The cursor update is under window_selectable, which is probably being written over somewhere else.
I wanted to plug this script in to investigate but the Window_HorizCommand.new isn't part of what you posted.


Part 3: line 15(at the end) looks suspicious.

@actor.equip(@equipright_window.index + 2, item == nil ? 0 : item.id)

adds 2 to the index if it C is pressed and the equipright window index isn't 0.
 
Oh, sorry, I can give it here.
As far as I know, it's not written over anywhere (besides HorizCommand but it's not called in that window)
if you need the rest of the menu I can give it if you want, though i've tested it with the default other scenes too and it still does this.

this is HorizCommand
Code:
 

#==============================================================================

# ** Window_HorizCommand

#------------------------------------------------------------------------------

#  This window deals with general command choices. (Horizontal)

#==============================================================================

 

class Window_HorizCommand < Window_Selectable

  #--------------------------------------------------------------------------

  # * Public Instance Variables

  #--------------------------------------------------------------------------

  attr_reader   :commands

  attr_accessor :c_spacing

  attr_accessor :alignment

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(width, commands, c_spacing = (width - 32) / commands.size)

    # Compute window height from command quantity

    super(0, 0, width, 64)

    @commands     = commands

    @item_max     = commands.size

    @column_max   = @item_max

    @c_spacing    = c_spacing

    @alignment    = 1

    self.contents = Bitmap.new(@item_max * @c_spacing, height - 32)

    refresh

    self.index = 0

  end

  #--------------------------------------------------------------------------

  # * Command

  #--------------------------------------------------------------------------

  def command(index = self.index)

    return @commands[index]

  end

  #--------------------------------------------------------------------------

  # * Commands

  #--------------------------------------------------------------------------

  def commands=(commands)

    # Return if Commands Are Same

    return if @commands == commands

    # Reset Commands

    @commands = commands

    # Resets Item Max

    item_max    = @item_max

    @item_max   = @commands.size

    @column_max = @item_max

    # If Item Max Changes

    unless item_max == @item_max

      # Deletes Existing Contents (If Exist)

      unless self.contents.nil?

        self.contents.dispose

        self.contents = nil

      end

      # Recreates Contents

    self.contents = Bitmap.new(@item_max * @c_spacing, height - 32)

    end

    # Refresh Window

    refresh

  end

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh

    self.contents.clear

    for i in 0...@item_max

      draw_item(i, normal_color)

    end

  end

  #--------------------------------------------------------------------------

  # * Draw Item

  #--------------------------------------------------------------------------

  def draw_item(index, color)

    command = commands[index]

    x = index * @c_spacing + 4

    self.contents.font.color = color

    self.contents.draw_text(x, 0, @c_spacing - 8, 32, command, @alignment)

  end

  #--------------------------------------------------------------------------

  # * Disable Item

  #--------------------------------------------------------------------------

  def disable_item(index)

    draw_item(index, disabled_color)

  end

  #--------------------------------------------------------------------------

  # * Cursor Rectangle Update

  #--------------------------------------------------------------------------

  def update_cursor_rect

    if @index < 0

      self.cursor_rect.empty

    else

      self.cursor_rect.set(@c_spacing * @index, 0, @c_spacing, 32)

    end

  end

end

 
 
Fixed, replied in PM.
@coyotecraft: that was significant part of the issue, good spot!

the other part was that the inherited window_selectable functionality was not working as you needed since these windows were a bit unusual in their construction. I overrode Window_Selectable.update for your equipleft and equipright windows and used a grandfather access hack to update the base window while bypassing the Window_Selectable's update altogether.

For any other scripters that don't know how to access super.super:
Be aware that OOP-wise, its considered a violation of "good design". That said, in RM scripts, where the goal is to override functions minimally, I see it as no worse than using alias. The actual implementation has a few varieties, but this one works in RMXP and is simple:

supersuper = self.class.superclass.superclass
supermethod = supersuper.instance_method:)the_method_name_goes_here)
supermethod.bind(self).call

Sorry for getting to this so late! I was sleeping.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top