Szyu's Item Class Restriction Script causing crash when using items on enemies.

ShinySlowqueen

Veteran
Veteran
Joined
Dec 22, 2015
Messages
49
Reaction score
3
First Language
English
Primarily Uses
RMVXA
I am using Szyu's Item Class Restriction Script to make several items only usable by actors 1 and 2, and several others only usable by actor 3. It works perfectly well doing this.

However, whenever I use an attack item in battle, the game crashes with the error:


line 71: NoMethodError occured.
undefined method 'class_id' for #<Game_Enemy:0x9f8bebc>


The line "(item.forbid_classes.include?(self.class_id) || item.forbid_actors.include?(self.id))" seems to be where it collapses. I'm guessing because enemies don't have classes or actor ids? Is there a way to bypass the class/actor ID check when using an item on an enemy?

Copying entire script below:

Code:
#==============================================================================
# Szyu's Item's Class Restriction
# Version 1.2
# By Szyu
#
# About:
# Easily specify items, weapons and armors, which can only be used/equipped
# by certain classes
#
# Instructions:
# - Place below "▼ Materials" but above "▼ Main Process".
#
# How to Use:
# - An item's note have to contain one of these:
# <classes: x> # This will allow specified classes to use this item
# <!classes: x> # This will forbit specified classes to use this item
#
# Seperate multiple classes with ','!
# Allowed Database Items, which can be restricted by this script:
# - Items
# - Weapons
# - Armors
#
# If There is none of those tags in the items note, every class is permitted to
# use or equip this item
#
#
# Requires:
# - RPG Maker VX Ace
#
# Terms of Use:
# - Free for commercal and non-commercial use. Please list me
#   in the credits to support my work.
#
#
# Changelog:
# - Same syntax can now be used to restrict for actors:
#   <actors: x>
#   <!actors: x>
# - Added Use Restriction for battles too. Restricted classes and actors can no
#   longer use restricted items in battle
#
#
#
# Pastebin:
# http://adf.ly/rYIZm
#
#
#==============================================================
#   * Game_BattlerBase
#==============================================================
class Game_BattlerBase
  alias sz_iucr_equippable? equippable?

  def equippable?(item)
    return false unless item.is_a?(RPG::EquipItem)
    return false if self.is_a?(Game_Actor) &&
      (item.forbid_classes.include?(self.class_id) || item.forbid_actors.include?(self.id))
    return sz_iucr_equippable?(item)
  end
end

#==============================================================
#   * Game_Battler
#==============================================================
class Game_Battler < Game_BattlerBase
  alias sz_iucr_item_test item_test

  def item_test(user, item)
    return false if item.is_a?(RPG::Item) &&
      (item.forbid_classes.include?(self.class_id) || item.forbid_actors.include?(self.id))
    return sz_iucr_item_test(user, item)
  end
end

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#==============================================================
#   * Initialize BaseItems
#==============================================================
module DataManager
  class << self
    alias load_db_iucr_sz load_database
  end

  def self.load_database
    load_db_iucr_sz
    load_iucr_items
  end

  def self.load_iucr_items
    groups = [$data_items, $data_weapons, $data_armors]
    for group in groups
      for obj in group
        next if obj.nil?
        obj.load_iucr_notetags_sz
      end
    end
  end
end

#==============================================================================
# ** Window_BattleActor
#------------------------------------------------------------------------------
#  This window is for selecting an actor's action target on the battle screen.
#==============================================================================
class Window_BattleActor < Window_BattleStatus
  #--------------------------------------------------------------------------
  # * Get Activation State of Selection Item
  #--------------------------------------------------------------------------
  def current_item_enabled?
    return false if !BattleManager.actor.input.item.is_a?(RPG::UsableItem) ||
      BattleManager.actor.input.item.forbid_classes.include?(BattleManager.actor.input.subject.class_id) ||
      BattleManager.actor.input.item.forbid_actors.include?(BattleManager.actor.input.subject.id)
    return true
  end
end

#==============================================================
#   * Content of Recycling Items
#==============================================================
class RPG::BaseItem
  attr_accessor :forbid_classes
  attr_accessor :forbid_actors

  def load_iucr_notetags_sz
    @forbid_classes = []
    @forbid_actors = []
    self.note.split(/[\r\n]+/).each do |line|
      # Forbid Classes
      if line =~ /<classes:([\d+,?\s*]+)>/i
        $data_classes.each do |cl|
          @forbid_classes.push(cl.id) if cl
        end
        $1.scan(/\s*,?\d+,?\s*/i).each do |cl|
          @forbid_classes.delete(cl.to_i)
        end
      elsif line =~ /<!classes:([\d+,?\s*]+)>/i
        $1.scan(/\s*,?\d+,?\s*/i).each do |cl|
          @forbid_classes.push(cl.to_i)
        end
        # Forbid Actors
      elsif line =~ /<actors:([\d+,?\s*]+)>/i
        $data_actors.each do |ac|
          @forbid_actors.push(ac.id) if ac
        end
        $1.scan(/\s*,?\d+,?\s*/i).each do |ac|
          @forbid_actors.delete(ac.to_i)
        end
      elsif line =~ /<!actors:([\d+,?\s*]+)>/i
        $1.scan(/\s*,?\d+,?\s*/i).each do |ac|
          @forbid_actors.push(ac.to_i)
        end
      end
    end
  end 
end
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
Add this line before the first return line of that method (item_test)

Code:
return sz_iucr_item_test(user, item) if self.is_a?(Game_Enemy)
Looking at the code, it seems to be made with menu item usage in mind, where the target (self) is the "user" too.. While on battle, self is the target and can be different from the user..

Right now, the code is actually checking if the item is usable by the target, not by the user.

I suggest changing the whole method to this

Code:
def item_test(user, item)
  return sz_iucr_item_test(user, item) if self.is_a?(Game_Enemy)
  if SceneManager.scene_is?(Scene_Battle)
    return false if item.is_a?(RPG::Item) &&
     (item.forbid_classes.include?(user.class_id) || item.forbid_actors.include?(user.id))
   else
     return false if item.is_a?(RPG::Item) &&
     (item.forbid_classes.include?(self.class_id) || item.forbid_actors.include?(self.id))
   end
   return sz_iucr_item_test(user, item)
  end
 
Last edited:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,867
Messages
1,017,061
Members
137,575
Latest member
akekaphol101
Top