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.

Grid Item Menu System

Grid Item Menu System
Version 1
By: EmuMaster2002 (If you choose to credit, please credit as Eathanu)

Introduction:
This is a relatively simple little item menu system that is the first script I've made basically on my own. Basically, instead of the item name being shown in the menu itself, it's in the description box, and the body of the menu is a grid of icons with little numbers beside them, like in a lot of Western RPGs and various MMORPGs (in my case directly inspired by Morrowind and to a lesser extent Neverwinter Nights 2). It's fairly minimalistic as far as editing goes, with only one or two small changes to Scene_Item itself, but a rewrite of Window_Help under a different name for compatibility reasons and a lot of changes to Window_Item. It's nothing hugely spectacular, but I've not seen any item menus like this before as far as I can remember.

Screenshots:
The regular menu:
Griditem1.png


As seen from battle:
Griditem2.png

I didn't know how to make the help window work the same way in battle without breaking things or otherwise needing to rewrite a big important part of Scene_Battle 1, so I left it with just the description. I'm sure you can do it with aliasing, but I have no idea how that stuff works yet.

Script:
Code:
#Grid Item Menu System

#By Eathanu (or EmuMaster2002, as the case may be)

#Posted as-is; I won't be able to offer much help if you run into problems.

 

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

# ** Window_Help

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

#  This window shows skill and item explanations along with actor status.

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

 

class Window_Help_Item < Window_Base

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

  # * Object Initialization

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

  def initialize

    super(0, 392, 640, 88)

    self.contents = Bitmap.new(width - 32, height - 32)

      if $game_temp.in_battle

        self.y = 256

        self.height = 88

        self.back_opacity = 160

      end

  end

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

  # * Set Text

  #  text  : text string displayed in window

  #  align : alignment (0..flush left, 1..center, 2..flush right)

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

  def set_text(itemname, text, align = 0)

    # If at least one part of text and alignment differ from last time

    if itemname != @itemname or text != @text or align != @align

      # Redraw text

      self.contents.clear

      self.contents.font.color = system_color

      self.contents.draw_text(4, 0, self.width - 40, 32, itemname, 0)

      self.contents.font.color = normal_color

      self.contents.draw_text(4, 24, self.width - 40, 32, text, align)

      @itemname = itemname

      @text = text

      @align = align

      @actor = nil

    end

    self.visible = true

  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, 0, 640, 392)

    @column_max = 10

    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 = 160

    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

    x = 4 + index % 10 * 64

    y = index / 10 * 32

    rect = Rect.new(x, y, self.width / @column_max - 32, 32)

    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))

    bitmap = RPG::Cache.icon(item.icon_name)

    self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), 255)

    self.contents.font.size = 14

    self.contents.draw_text(x + 2, y + 16, 24, 24, number.to_s, 2)

  end

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

  # * Help Text Update

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

  def update_help

      if $game_temp.in_battle

        @help_window.set_text(self.item == nil ? "" : self.item.description)

      else

        @help_window.set_text(self.item == nil ? "" : self.item.name, self.item == nil ? "" : self.item.description)

      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_Item.new

    @item_window = Window_Item.new

    # 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

    @target_window.dispose

  end

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

  # * Frame Update

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

  def update

    # Update windows

    @help_window.update

    @item_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 = 0

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

          @item_window.update_help

        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

Instructions:
Just paste above main somewhere. You can delete Scene_Item and Window_Item, if you want, but Window_Help is used elsewhere.
I would suggest using descriptive descriptions, rather than what the RTP does, so that picking out items is a little easier in battle.

Compatibility:
Should be fairly compatible with anything that doesn't affect the item menu or window.
That said, script offered as-is. If you do have problems, I can almost guarantee I won't know how to solve it.

Credits and Thanks:
MicKo for rewriting the menu system used in my game, which I was able to use to learn the very basics of RGSS.
Ares for giving me a little snippet that helped me debug this thing.

Terms and Conditions:
I don't need to be credited, personally, but you're certainly welcome to.
I have no love for commercial projects. Please don't use anything I make in one.
 

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