NoMethodError Help

Started by Jaiden, October 23, 2017, 04:19:10 pm

Previous topic - Next topic

Jaiden

I'm running into a little trouble with a NoMethodError and I'm just looking for a little help to get me into the right direction.

I am using a custom menu script made by "albertfish", it's quite old. I am using it as a framework to write my own custom menu.

I am currently using RPG Maker XP with the RPG Maker VX Ace engine, as defined here: http://forum.chaos-project.com/index.php/topic,12899.msg173956.html#msg173956

This error:
Spoiler: ShowHide


Appears when my actors receive items.

The specific line is here:
if $recent_items[i].id == $data_items[item_id].id && $recent_items[i].is_a?(RPG::Item)


The problem I'm having is with a custom "Game_Party" class. It is telling me the method "id" is not defined, but I'm pretty certain it is a built-in RGSS method. I'm not sure if the problem is due to me using the RPG Maker VX engine and that there is a syntax change, or it is a script conflict issue.

This is the particular area that it is flagging:
Spoiler: ShowHide
#--------------------------------------------------------------------------
  # * Gain Recent Items
  #     item_id  : item ID
  #--------------------------------------------------------------------------
  def gain_recent_item(item_id)
    for i in 0...$recent_items.size
      if $recent_items[i].id == $data_items[item_id].id && $recent_items[i].is_a?(RPG::Item)
        $recent_items.delete_at(i)
      end
    end
    $recent_items.push($data_items[item_id])
    if $recent_items.size > 40
      $recent_items.delete_at(0)
    end
  end


This script is pretty big I've uploaded the whole thing to pastebin:
https://pastebin.com/WEGdtdrK

Any sort of hints or advice would be helpful!



KK20

Can you post a demo instead? If it does happen to be another script conflicting with it, I will need that other script too. I can say for certainty that it has nothing to do with XPA.

Regarding the line

if $recent_items[i].id == $data_items[item_id].id

I'm betting that item_id is 0. That would mean albertfish's script has a bug.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Jaiden

Awesome, thanks for the help! I am using a side view combat system, but there weren't any conflicting Game_Party methods from what I could tell. I also wasn't sure if my edits to the menu system were disastrous.

I'll prepare a demo!

Jaiden


KK20

Yep, it's his bug.

Problem is with the logic regarding recent items.

for i in 0...$recent_items.size
  puts [i, $recent_items[i]].inspect
  if $recent_items[i].id == $data_items[item_id].id && $recent_items[i].is_a?(RPG::Item)
    $recent_items.delete_at(i)
  end
end
$recent_items.push(item)
if $recent_items.size > 40
  $recent_items.delete_at(0)
end

If you are to gain another item that you recently obtained, it deletes the item from the $recent_items list and then re-adds it again. However, if you were to gain item A, then item B, then item A, the use of $recent_items.delete_at(i) modifies the array WHILE we are currently iterating through it in the loop. This created a nil record, hence the error message received.

He should have used delete_if instead. I went ahead and modified the methods to do this. I also checked if he made this delete_at error anywhere else, and found out that the lose_item/weapon/armor methods he rewrote are completely wrong. I fixed those as well.

Replace the Game_Party class in the script with this:

#==============================================================================
# ** Game_Party
#------------------------------------------------------------------------------
#  This class handles the party. It includes information on amount of gold
#  and items. Refer to "$game_party" for the instance of this class.
#==============================================================================
class Game_Party
  #--------------------------------------------------------------------------
  # * Gain Items (or lose)
  #     item_id : item ID
  #     n       : quantity
  #--------------------------------------------------------------------------
  def gain_item(item_id, n)
    # Update quantity data in the hash.
    if item_id > 0
      @items[item_id] = [[item_number(item_id) + n, 0].max, 99].min
      gain_recent_item(item_id) if n >= 0
    end
  end
  #--------------------------------------------------------------------------
  # * Gain Weapons (or lose)
  #     weapon_id : weapon ID
  #     n         : quantity
  #--------------------------------------------------------------------------
  def gain_weapon(weapon_id, n)
    # Update quantity data in the hash.
    if weapon_id > 0
      @weapons[weapon_id] = [[weapon_number(weapon_id) + n, 0].max, 99].min
      gain_recent_weapon(weapon_id) if n >= 0
    end
  end
  #--------------------------------------------------------------------------
  # * Gain Armor (or lose)
  #     armor_id : armor ID
  #     n        : quantity
  #--------------------------------------------------------------------------
  def gain_armor(armor_id, n)
    # Update quantity data in the hash.
    if armor_id > 0
      @armors[armor_id] = [[armor_number(armor_id) + n, 0].max, 99].min
      gain_recent_armor(armor_id) if n >= 0
    end
  end
  #--------------------------------------------------------------------------
  # * Lose Items
  #     item_id : item ID
  #     n       : quantity
  #--------------------------------------------------------------------------
  def lose_item(item_id, n)
    # Reverse the numerical value and call it gain_item
    gain_item(item_id, -n)
    if $game_party.item_number(item_id) == 0
      $recent_items.delete_if { |i| i.id == item_id && i.is_a?(RPG::Item) }
    end
  end
  #--------------------------------------------------------------------------
  # * Lose Weapons
  #     weapon_id : weapon ID
  #     n         : quantity
  #--------------------------------------------------------------------------
  def lose_weapon(weapon_id, n)
    # Reverse the numerical value and call it gain_weapon
    gain_weapon(weapon_id, -n)
    if $game_party.weapon_number(weapon_id) == 0
      $recent_items.delete_if { |i| i.id == weapon_id && i.is_a?(RPG::Weapon) }
    end
  end
  #--------------------------------------------------------------------------
  # * Lose Armor
  #     armor_id : armor ID
  #     n        : quantity
  #--------------------------------------------------------------------------
  def lose_armor(armor_id, n)
    # Reverse the numerical value and call it gain_armor
    gain_armor(armor_id, -n)
    if $game_party.armor_number(armor_id) == 0
      $recent_items.delete_if { |i| i.id == armor_id && i.is_a?(RPG::Armor) }
    end
  end
  #--------------------------------------------------------------------------
  # * Gain Recent Items
  #     item_id  : item ID
  #--------------------------------------------------------------------------
  def gain_recent_item(item_id)
    item = $data_items[item_id]
    $recent_items.delete_if { |i| i.id == item.id && i.is_a?(RPG::Item) }
    $recent_items.push(item)
    if $recent_items.size > 40
      $recent_items.delete_at(0)
    end
  end
  #--------------------------------------------------------------------------
  # * Gain Recent Weapons
  #     weapon_id : weapon ID
  #--------------------------------------------------------------------------
  def gain_recent_weapon(weapon_id)
    weapon = $data_weapons[weapon_id]
    $recent_items.delete_if { |i| i.id == weapon.id && i.is_a?(RPG::Weapon) }
    $recent_items.push(weapon)
    if $recent_items.size > 40
      $recent_items.delete_at(0)
    end
  end
  #--------------------------------------------------------------------------
  # * Gain Recent Armor
  #     armor_id  : armor ID
  #--------------------------------------------------------------------------
  def gain_recent_armor(armor_id)
    armor = $data_armors[armor_id]
    $recent_items.delete_if { |i| i.id == armor.id && i.is_a?(RPG::Armor) }
    $recent_items.push(armor)
    if $recent_items.size > 40
      $recent_items.delete_at(0)
    end
  end
  #--------------------------------------------------------------------------
  # * Gain Items (or lose)
  #     item_id : item ID
  #     n       : quantity
  #--------------------------------------------------------------------------
  def equip_item(item_id, n)
    # Update quantity data in the hash.
    if item_id > 0
      @items[item_id] = [[item_number(item_id) + n, 0].max, 99].min
    end
  end
  #--------------------------------------------------------------------------
  # * Gain Weapons (or lose)
  #     weapon_id : weapon ID
  #     n         : quantity
  #--------------------------------------------------------------------------
  def equip_weapon(weapon_id, n)
    # Update quantity data in the hash.
    if weapon_id > 0
      @weapons[weapon_id] = [[weapon_number(weapon_id) + n, 0].max, 99].min
    end
  end
  #--------------------------------------------------------------------------
  # * Gain Armor (or lose)
  #     armor_id : armor ID
  #     n        : quantity
  #--------------------------------------------------------------------------
  def equip_armor(armor_id, n)
    # Update quantity data in the hash.
    if armor_id > 0
      @armors[armor_id] = [[armor_number(armor_id) + n, 0].max, 99].min
    end
  end
end

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Jaiden

Incredible, thank you so much. I can't begin to express how grateful I am that you took the time to help me troubleshoot such an old script. The logic explanation is really helpful too.

It would have taken me a really long time to figure that out. Thanks again!