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.

[Resolved]Creating Menu System, need some help

Tdata

Sponsor

Okay. I never did get that index problem fixed... But, no worries. :)

I am trying to divide the items into Loot, Usable, Equip, and Key items. I don't know the best place to start. Someone told me once that there was a simple way to do it buy editing the default Scene_Item class... Please help me.
 
You need to only filter data in the Window_Item class.

Code:
    for i in 1...$data_items.size
      if $game_party.item_number(i) > 0
        @data.push($data_items[i])
      end
    end

The easiest and most common way to do this is to use the element set.

So add this method into Window_Item

Code:
  def filter_with_element(element_id = 0)
    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
        if $data_items.element_set.include?(element_id)
          @data.push($data_items[i])
        end
      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

Now, in Scene_Item, you can have something like this:

Code:
  def update
    if Input.trigger?(Input::BUTTON)
      $game_system.se_play($data_system.cursor_se)
      @item_window.filter_with_element(ELEMENT_ID)
    elsif Input.trigger?(Input::BUTTON)
      $game_system.se_play($data_system.cursor_se)
      @item_window.filter_with_element(ELEMENT_ID)
    # ...
    end
    # Old update
  end

That's a simple way to filter items with element tags. Just replace your BUTTON and ELEMENT_ID with whatever you want and that should do the trick. You can do this with a command window or whatever else you wish.


(If you wait long enough, I have made a function / script that will sort and filter through a list of items more dynamicly than what I have put here. If you wish, I could see if I can dig it up, since I need to finish it anyways).
 

Tdata

Sponsor

That might be helpful... I tried calling like this:
Code:
$item = Window_Item.new
$scene = $item.filter_with_element(17)
I get one of two things happening.

It loads the window for a second then the game exits (When i have no items)
or
It gives me a undefined method 'element_set' for
Code:
        if $data_items.element_set.include?(element_id)
When i do have items. I've tryied doing it with Scene_Item but i get an:
undefined method 'filter_with_element' .

I'd do it your way, adding the edit to Scene_Item, but it wouldn't help in this case... I think it won't in anycase...
 
Your $scene has to be reserved for Scene_class objects. The main loop in the game requires the main method, or exits.

Code:
if $data_items[item_id].element_set.include?(element_id)

That's what it should be.

It does work doing it my way. Here, try this: (add below everything else)

Code:
class Window_Item
  def filter_with_element(element_id = 0)
    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
        if $data_items.element_set.include?(element_id)
          @data.push($data_items[i])
        end
      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
end

class Scene_Item
  alias seph_filteritems_scnitm_update update
  def update
    if Input.trigger?(Input::BUTTON)
      $game_system.se_play($data_system.cursor_se)
      @item_window.filter_with_element(ELEMENT_ID)
    elsif Input.trigger?(Input::BUTTON)
      $game_system.se_play($data_system.cursor_se)
      @item_window.filter_with_element(ELEMENT_ID)
    # ...
    end
    seph_filteritems_scnitm_update
  end
end

Now, just change these lines:
Code:
    if Input.trigger?(Input::BUTTON)
      $game_system.se_play($data_system.cursor_se)
      @item_window.filter_with_element(ELEMENT_ID)
    elsif Input.trigger?(Input::BUTTON)
      $game_system.se_play($data_system.cursor_se)
      @item_window.filter_with_element(ELEMENT_ID)
    # ...
    end

for your buttons and element id. CHANGE NOTHING ELSE.
 
Sephi made an error :P
Fixed code. Same instructions and all.
Code:
class Window_Item
  def filter_with_element(element_id = 0)
    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
        if $data_items[i].element_set.include?(element_id)
          @data.push($data_items[i])
        end
      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
end

class Scene_Item
  alias seph_filteritems_scnitm_update update
  def update
    if Input.trigger?(Input::BUTTON)
      $game_system.se_play($data_system.cursor_se)
      @item_window.filter_with_element(ELEMENT_ID)
    elsif Input.trigger?(Input::BUTTON)
      $game_system.se_play($data_system.cursor_se)
      @item_window.filter_with_element(ELEMENT_ID)
    # ...
    end
    seph_filteritems_scnitm_update
  end
end
 

Tdata

Sponsor

Here is the menu:
Code:
class Scene_Menu
  
  
  #---
  # Begin Initialization
  #---
  
  def initialize(menu_index = 0)
    @menu_index = menu_index
  end
  
  #---
  # End Initialization
  #---
  
  #---
  # Begin Main
  #---
  
  def main
  @sprite = Spriteset_Map.new
  #---
  # Begin Constants
  #---
    
  main_menu = ["Player", "Item", "File"]
  player_menu = ["Status", "Equip", "Skills"]
  item_menu = ["Loot", "Usable", "Equip", "Key"]
  file_menu = ["Save", "Load", "Quit"]
  
  #---
  # End Constants
  #---
  
  #---
  # Begin Menus
  #---
  
  @main_menu = Window_ShopCommand_clone.new
  @main_menu.active = true
  @main_menu.visible = true
  @main_menu.index = @menu_index
  
  @player_menu = Window_Command.new(120, player_menu)
  @player_menu.x = 20
  @player_menu.y = 65
  @player_menu.index = @menu_index
  $player_menu_index = @player_menu.index
  @player_menu.active = false
  @player_menu.visible = false
  
  @item_menu = Window_Command.new(120, item_menu)
  @item_menu.x = 140
  @item_menu.y = 65
  @item_menu.index = @menu_index
  @item_menu.active = false
  @item_menu.visible = false
  
  @status_window = Window_MenuStatus.new
  @status_window.index = @menu_index
  @status_window.x = (20 + 120)
  @status_window.y = 65
  @status_window.active = false
  @status_window.visible = false
  
  #---
  # End Menus
  #---
  
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     if $scene != self
       break
     end
   end
   Graphics.freeze

   @main_menu.dispose
   @player_menu.dispose
   @sprite.dispose
   @status_window.dispose
   @item_menu.dispose

 end
 def update
   @main_menu.update
   @player_menu.update
   @item_menu.update
   @sprite.update
   @status_window.update
   if @main_menu.active == true
     main_menu_update
   elsif @player_menu.active == true
     player_menu_update
   elsif @status_window.active == true
     update_status
   elsif @item_menu.active == true
     update_item
     end
 end
 def main_menu_update
    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 Input.trigger?(Input::A) or Input.trigger?(Input::C)
      case @main_menu.index
      when 0
      $game_system.se_play($data_system.decision_se)
      @main_menu.active = false
      @player_menu.active = true
      @player_menu.visible = true
      return
      when 1
      $game_system.se_play($data_system.decision_se)
      @main_menu.active = false
      @item_menu.active = true
      @item_menu.visible = true
        return
      when 2
        return
      end
    end
 end     
 def player_menu_update
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Switch to map screen
      @player_menu.active = false
      @player_menu.visible = false
      @main_menu.active = true
      @main_menu.index = 0
      return
    end
    if Input.trigger?(Input::A) or Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
        @status_window.visible = true
        @status_window.active = true
        @player_menu.active = false
        return
    end
  end
    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
        @player_menu.active = true
        @status_window.active = false
        @status_window.visible = false
        return
      end
      # If C button was pressed
      if Input.trigger?(Input::A) or Input.trigger?(Input::C)
        # Branch by command window cursor position
        case @player_menu.index
        when 0  # status
          # Play decision SE
          $game_system.se_play($data_system.decision_se)
          # Switch to status screen
          $scene = Scene_Status.new(@status_window.index)
        when 1  # equipment
            # Play decision SE
            $game_system.se_play($data_system.decision_se)
            # Switch to equipment screen
            $scene = Scene_Equip.new(@status_window.index)
        when 2  # 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)
        end      
      end
    end
    def update_item
      if Input.trigger?(Input::B)
        # Play cancel SE
        $game_system.se_play($data_system.cancel_se)
        # Make command window active
        @item_menu.active = true
        @status_window.active = false
        @status_window.visible = false
        return
      end
      # If C button was pressed
      if Input.trigger?(Input::A) or Input.trigger?(Input::C)
        # Branch by command window cursor position
        $game_system.se_play($data_system.decision_se)
        case @item_menu.index
        when 0  #Loot
          # Play decision SE
          # Switch to status screen
          $item_element = 17
          $scene = Scene_Item.new
          
          return
        when 1  #Usable
          $item_element = 18
          $scene = Scene_Item.new
          return
         when 2  #Equipl
           return
          when 3
            return
        end      
      end
    end
end
Is the Edited Classes:
Code:
class Scene_Status
  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(0)
      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
class Game_Party
  def add_actor(actor_id)
    # Get actor
    actor = $game_actors[actor_id]
    # If the party has less than 4 members and this actor is not in the party
    if @actors.size < 3 and not @actors.include?(actor)
      # Add actor
      @actors.push(actor)
      # Refresh player
      $game_player.refresh
    end
  end
end
class Window_MenuStatus < Window_Selectable  
  def initialize
    super(0, 0, 480, 360)
    self.contents = Bitmap.new(width - 32, height - 32)
    refresh
    self.active = false
    self.index = -1
  end
end
class Scene_Equip
  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
      $scene = Scene_Menu.new(0)
      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
    # 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 equipment screen
      $scene = Scene_Equip.new(@actor_index, @right_window.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 equipment screen
      $scene = Scene_Equip.new(@actor_index, @right_window.index)
      return
    end
  end
end
class Scene_Skill
  def update_skill
    # 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 skill window
      @skill = @skill_window.skill
      # If unable to use
      if @skill == nil or not @actor.skill_can_use?(@skill.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 ally
      if @skill.scope >= 3
        # Activate target window
        @skill_window.active = false
        @target_window.x = (@skill_window.index + 1) % 2 * 304
        @target_window.visible = true
        @target_window.active = true
        # Set cursor position to effect scope (single / all)
        if @skill.scope == 4 || @skill.scope == 6
          @target_window.index = -1
        elsif @skill.scope == 7
          @target_window.index = @actor_index - 10
        else
          @target_window.index = 0
        end
      # If effect scope is other than ally
      else
        # If common event ID is valid
        if @skill.common_event_id > 0
          # Common event call reservation
          $game_temp.common_event_id = @skill.common_event_id
          # Play use skill SE
          $game_system.se_play(@skill.menu_se)
          # Use up SP
          @actor.sp -= @skill.sp_cost
          # Remake each window content
          @status_window.refresh
          @skill_window.refresh
          @target_window.refresh
          # Switch to map screen
          $scene = Scene_Map.new
          return
        end
      end
      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 skill screen
      $scene = Scene_Skill.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 skill screen
      $scene = Scene_Skill.new(@actor_index)
      return
    end
  end
end
class Window_Item
  def filter_with_element(element_id = 0)
    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
        if $data_items[i].element_set.include?(element_id)
          @data.push($data_items[i])
        end
      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
end

class Scene_Item
  alias seph_filteritems_scnitm_update update
  def update
    case $item_element
    when 17  
    @item_window.filter_with_element(17)
    when 18
      @item_window.filter_with_element(18)
    # ...
    end
    seph_filteritems_scnitm_update
  end
  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(1)
      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
end
class Window_ShopCommand_clone < Window_Selectable
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    super(20, 0, 600, 64)
    self.contents = Bitmap.new(width - 32, height - 32)
    @item_max = 4
    @column_max = 4
    @commands = ["Player", "Item", "File", "Exit"]
    refresh
    self.index = 0
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    for i in 0...@item_max
      draw_item(i)
    end
  end
  #--------------------------------------------------------------------------
  # * Draw Item
  #     index : item number
  #--------------------------------------------------------------------------
  def draw_item(index)
    x = 4 + index * 160
    self.contents.draw_text(x, 0, 128, 32, @commands[index])
  end
end

It filters them now, but you can't use the items...
Here is the
 

Tdata

Sponsor

I've made 4 objects in the database with the added tags assigned. loot test is set to unuseable. Usable test is set to useable in battle+Menu. But the problem is that even though there is only 1 "Useable Test" item i can use it forever... Even if it is set as consumable...

Nevermind... I seemed to have forgotten to assign a target... :p
 

Tdata

Sponsor

One more thing before i ask for this to be resolved. Why don't the weapons filter like the items? I figure i need to add something to do that. What might that be? Something dealing with $data_weapons and $data_armour that i would need to add i would suppose...

edit:: Got it.
 

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