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.

Bestiary Script Doesn't work...

Status
Not open for further replies.
Using a Bestiary Script found on this site doesn't seem to work. i call the script using the proper command, in a common event used by an item, and it comes up with the message:

"Script 'Monster Guide' line 117: NoMethodError Occurred.

undefined method `[]' for nil:NilClass"

WHAT?!? I'm at a loss. here is line 117:

Code:
   if enemy_exist?(i) && @enemy_encountered[i] && !@enemy_defeated[i] && !MG::HIDE_ENEMIES.include?(i)

Please Can Somebody suggest what is going on? I'm not literate at all in RGSS and i'm stumped. Btw Line 117 is in Red Below.

Code:
#------------------------------------------------------------------------------
# Monster Guide
# Written by: KGC (?)
# Modified, Indented, and Commented by Carey Metcalfe
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# USAGE
# To use this script, just put it in a new slot before main and
# after Scene_debug.
# You must then configure the constants to suit your game
#------------------------------------------------------------------------------
# SCENE CALLING
# $scene = Scene_MonsterGuide.new(true/false)
# The boolean arg should be true if you are calling it from the map
# and false if you are calling it from the main menu.
#------------------------------------------------------------------------------
# CREDIT
# If you use this script in your game you must give credit to KGC (whoever that is)
# I don't require that you put my name in the credits but if you want to go for it
#------------------------------------------------------------------------------


#==============================================================================
# Setup
#==============================================================================

module MG
  # transparent background
  BACK_TRANSPARENT = false
  
  # to hide an enemy, put it's ID in the brackets (bosses, etc.)
  HIDE_ENEMIES = []
  
  # how many elements (1..# of elements)
  ELEMENT_RANGE = 1..16
  
  # colour of the monsters weaknesses text
  WEAK_COLOR = Color.new(255, 128, 128)
  
  # colour of the monsters strength text
  STRONG_COLOR = Color.new(128, 128, 255)
  
  # whether you have to click on the monster to show its stats
  SELECT_REFRESH = false
  
  # to show the monster SN or not
  SERIAL_NUMBER = true
  
  # show the SNs in order (true) or show the SNs based on ENEMY_ORDER (false)
  SERIAL_ORDER = true
  
  #order of enemies displayed in ranges and #s seperated by commas (nil for default)
  ENEMY_ORDER = nil
  # Example: ENEMY_ORDER = [1..5, 8..13, 6, 7, 14, 15]
  
  # change this to suit your custom menu
  MENU_INDEX = 6
end

#==============================================================================
#  Game_System
#==============================================================================

class Game_System
  #--------------------------------------------------------------------------
  # ● Public instances variables
  #--------------------------------------------------------------------------
  attr_accessor :enemy_encountered        # enemies encountered
  attr_accessor :enemy_defeated           # enemies killed
  #--------------------------------------------------------------------------
  # ● initialize
  #--------------------------------------------------------------------------
  alias initialize_KGC_MonsterGuide initialize
  def initialize
    # initialize the guide and the arrays
    initialize_KGC_MonsterGuide
    @enemy_encountered, @enemy_defeated = [], []
  end
  #--------------------------------------------------------------------------
  # ● Checks to see if an enemy exists
  #--------------------------------------------------------------------------
  def enemy_exist?(enemy_id)
    return $data_enemies[enemy_id] != nil && $data_enemies[enemy_id].name != ""
  end
  #--------------------------------------------------------------------------
  # ● Return the total types of enemies
  #--------------------------------------------------------------------------
  def all_enemies_count
    n = 0
    # count the enemies excluding the hidden ones
    (1...$data_enemies.size).each { |i|
      n += 1 if enemy_exist?(i) && !MG::HIDE_ENEMIES.include?(i)
    }
    return n
  end
  #--------------------------------------------------------------------------
  # ● Return the total types of enemies killed
  #--------------------------------------------------------------------------
  def defeated_enemies_count
    n = 0
    # count the enemies excluding the hidden ones
    (1...$data_enemies.size).each { |i|
      if enemy_exist?(i) && @enemy_encountered[i] && @enemy_defeated[i] && !MG::HIDE_ENEMIES.include?(i)
        n += 1
      end
    }
    return n
  end
  
  #--------------------------------------------------------------------------
  # ● Return the total types of enemies seen and not defeated
  #--------------------------------------------------------------------------
  def encountered_enemies_count
    n = 0
    # count the enemies excluding the hidden ones
    (1...$data_enemies.size).each { |i|
      [COLOR=Red]if enemy_exist?(i) && @enemy_encountered[i] && !@enemy_defeated[i] && !MG::HIDE_ENEMIES.include?(i)[/COLOR]        n += 1
      end
    }
    return n
  end
    
  #--------------------------------------------------------------------------
  # ● Return the percent completed
  #--------------------------------------------------------------------------
  def monster_guide_completion
    return defeated_enemies_count * 100 / all_enemies_count
  end
end

#==============================================================================
#  Game_Enemy
#==============================================================================

class Game_Enemy < Game_Battler
  #--------------------------------------------------------------------------
  # ● Public instance variables
  #--------------------------------------------------------------------------
  attr_reader   :original_id              # original enemy ID
  #--------------------------------------------------------------------------
  # ● Initialize
  #     troop_id     : ID of the enemy troop
  #     member_index : Index of the enemy in the troop
  #--------------------------------------------------------------------------
  alias initialize_KGC_MonsterGuide initialize
  def initialize(troop_id, member_index)
    # initialize the guide
    initialize_KGC_MonsterGuide(troop_id, member_index)
    @original_id = []
    # unless the enemy is hidden change the encountered var to true
    unless @hidden
      $game_system.enemy_encountered[@enemy_id] = true
    end
  end
  #--------------------------------------------------------------------------
  # ● Transform
  #     enemy_id : ID of the enemy
  #--------------------------------------------------------------------------
  alias transform_KGC_MonsterGuide transform
  def transform(enemy_id)
    # push the original enemy ID
    @original_id.push(@enemy_id)
    #call this method
    transform_KGC_MonsterGuide(enemy_id)
    # change the enemy encountered for the new enemy to true
    $game_system.enemy_encountered[@enemy_id] = true
  end
  #--------------------------------------------------------------------------
  # ● Hide an enemy
  #--------------------------------------------------------------------------
  def hidden=(value)
    @hidden = value
    # Unless the enemy is hidden change the enemy encountered to true
    unless @hidden
      $game_system.enemy_encountered[@enemy_id] = true
    end
  end
end

#==============================================================================
#  Window_MonsterGuideTop
#------------------------------------------------------------------------------
# Top left window of the guide
#==============================================================================

class Window_MonsterGuideTop < Window_Base
  #--------------------------------------------------------------------------
  # ● Initialize
  #--------------------------------------------------------------------------
  def initialize
    super(0, 0, 240, 126)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.back_opacity = 160 if MG::BACK_TRANSPARENT
    refresh
  end
  #--------------------------------------------------------------------------
  # ● Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    text = "#{$game_system.encountered_enemies_count + $game_system.defeated_enemies_count} out of #{$game_system.all_enemies_count} seen"
    self.contents.draw_text(0, 0, width - 32, 32, text)
    text = "#{$game_system.defeated_enemies_count} out of #{$game_system.all_enemies_count} killed"
    self.contents.draw_text(0, 32, width - 32, 32, text)
    text = "Guide #{$game_system.monster_guide_completion}% complete"
    self.contents.draw_text(0, 64, width - 32, 32, text)
  end
end

#==============================================================================
#  Window_MonsterGuideLeft
#------------------------------------------------------------------------------
# The window on the left with all the enemies in it
#==============================================================================

class Window_MonsterGuideLeft < Window_Selectable
  #--------------------------------------------------------------------------
  # ● Initialize
  #--------------------------------------------------------------------------
  def initialize
    super(0, 126, 240, 354)
    self.index = 0
    self.back_opacity = 160 if MG::BACK_TRANSPARENT
    refresh
  end
  #--------------------------------------------------------------------------
  # ● Item
  #--------------------------------------------------------------------------
  def item
    return @data[self.index]
  end
  #--------------------------------------------------------------------------
  # ● Refresh
  #--------------------------------------------------------------------------
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    # if there is no order
    if MG::ENEMY_ORDER == nil
      # #for every monster by thier ID
      (1...$data_enemies.size).each { |i|
        if $game_system.enemy_exist?(i) && !MG::HIDE_ENEMIES.include?(i)
          @data.push($data_enemies[i])
        end
      }
    else # if there is an order
      #for every monster by thier order
      MG::ENEMY_ORDER.each { |i|
        if i.is_a?(Range) #if the array value is a range (ex. 1..5)
          i.each { |j|
            #load all the numbers in the range in order into the data array
            if $game_system.enemy_exist?(j) && !MG::HIDE_ENEMIES.include?(j)
              @data.push($data_enemies[j])
            end
          }
        else  # if the array value is a number (ex. 6)
          #load the number into that data array
          if $game_system.enemy_exist?(i) && !MG::HIDE_ENEMIES.include?(i)
            @data.push($data_enemies[i])
          end
        end
      }
    end
    # make the items (buttons) with the data array on them
    @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 : the index of the item
  #--------------------------------------------------------------------------
  def draw_item(index)
    enemy = @data[index]
    # colour the item text
    if $game_system.enemy_defeated[enemy.id]
      self.contents.font.color = normal_color
    else
      self.contents.font.color = disabled_color
    end
    x = 4
    y = index * 32
    rect = Rect.new(x, y, self.width - 40, 32)
    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
    # Number the items
    if MG::SERIAL_NUMBER
      s_num = MG::SERIAL_ORDER ? (index + 1) : enemy.id
    end
    if $game_system.enemy_encountered[enemy.id]
      if MG::SERIAL_NUMBER
        text = sprintf("%03d: %s", s_num, enemy.name)
      else
        text = enemy.name
      end
      self.contents.draw_text(x, y, self.width - 40, 32, text)
    else
      if MG::SERIAL_NUMBER
        text = sprintf("%03d: %s", s_num, "? ? ? ? ? ? ? ?")
        self.contents.draw_text(x, y, self.width - 40, 32, text)
      else
        self.contents.draw_text(x, y, self.width - 40, 32, "? ? ? ? ? ? ? ?", 1)
      end
    end
  end
end

#==============================================================================
#  Window_MonsterGuideRight
#------------------------------------------------------------------------------
# The window on the right that shows the stats, error messages, etc.
#==============================================================================

class Window_MonsterGuideRight < Window_Base
  #--------------------------------------------------------------------------
  # ● Initialize
  #--------------------------------------------------------------------------
  def initialize
    super(240, 0, 400, 480)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.back_opacity = 160 if MG::BACK_TRANSPARENT
  end
  #--------------------------------------------------------------------------
  # ● Refresh
  #     enemy       : enemy stats to show
  #     show_status : show the stats or not
  #--------------------------------------------------------------------------
  def refresh(enemy, show_status = true)
    self.contents.clear
    # not seen yet - no data
    unless $game_system.enemy_encountered[enemy.id]
      self.contents.font.color = disabled_color
      self.contents.draw_text(0, 208, 368, 32, "- No Data -", 1)
      return
    end
    # if enemy has been seen display the picture
    bitmap = RPG::Cache.battler(enemy.battler_name, enemy.battler_hue)
    cw = bitmap.width; ch = bitmap.height
    self.contents.blt(184 - cw / 2, 0, bitmap, bitmap.rect)
    # if show status is false dont show the stats
    return unless show_status
    # if the enemy has been defeated
    if $game_system.enemy_defeated[enemy.id]
      # draw the descriptions
      self.contents.font.color = system_color
      self.contents.draw_text(  0, 224,  64, 32, $data_system.words.hp + ":")
      self.contents.draw_text(122, 224,  75, 32, $data_system.words.dex + ":")
      self.contents.draw_text(244, 224,  80, 32, $data_system.words.str + ":")
      self.contents.draw_text(  0, 256,  64, 32, $data_system.words.sp + ":")
      self.contents.draw_text(122, 256,  80, 32, $data_system.words.atk + ":")
      self.contents.draw_text(244, 256,  80, 32, $data_system.words.int + ":")
      self.contents.draw_text(  0, 288,  80, 32, $data_system.words.agi + ":")
      self.contents.draw_text(122, 288,  80, 32, $data_system.words.pdef + ":")
      self.contents.draw_text(244, 288,  80, 32, $data_system.words.mdef + ":")
      self.contents.draw_text(  0, 320,  96, 32, "Weaknesses" + ":")
      self.contents.draw_text(  0, 352,  96, 32, "Strengths" + ":")
      self.contents.draw_text(  0, 384,  96, 32, "Experience" + ":")
      self.contents.draw_text(184, 384, 384, 32, $data_system.words.gold + ":")
      self.contents.draw_text(  0, 416,  64, 32, $data_system.words.item + ":")
      # draw the values
      self.contents.font.color = normal_color
      self.contents.draw_text( 48, 224,  64, 32, enemy.maxhp.to_s, 2)
      self.contents.draw_text(170, 224,  64, 32, enemy.dex.to_s, 2)
      self.contents.draw_text(292, 224,  64, 32, enemy.str.to_s, 2)
      self.contents.draw_text( 48, 256,  64, 32, enemy.maxsp.to_s, 2)
      self.contents.draw_text(170, 256,  64, 32, enemy.atk.to_s, 2)
      self.contents.draw_text(292, 256,  64, 32, enemy.int.to_s, 2)
      self.contents.draw_text( 48, 288,  64, 32, enemy.agi.to_s, 2)
      self.contents.draw_text(170, 288,  64, 32, enemy.pdef.to_s, 2)
      self.contents.draw_text(292, 288,  64, 32, enemy.mdef.to_s, 2)
      self.contents.draw_text(  0, 384, 144, 32, enemy.exp.to_s, 2)
      self.contents.draw_text(184, 384, 144, 32, enemy.gold.to_s, 2)
      
      # Draw Weaknseses
      text = ""
      MG::ELEMENT_RANGE.each { |i|
        # if status efficiantcy is A or B
        if enemy.element_ranks[i] < 3
          text += "/" if text != ""
          text += $data_system.elements[i]
        end
      }
      self.contents.font.color = MG::WEAK_COLOR.dup
      if text != ""
        self.contents.draw_text(104, 320, 264, 32, text)
      else
        self.contents.draw_text(104, 320, 264, 32, "[NONE]")
      end
      
      # Draw Strengths
      text = ""
      MG::ELEMENT_RANGE.each { |i|
        # if status efficiancy is D,E or F
        if enemy.element_ranks[i] > 3
          text += "/" if text != ""
          text += $data_system.elements[i]
        end
      }
      self.contents.font.color = MG::STRONG_COLOR.dup
      if text != ""
        self.contents.draw_text(104, 352, 264, 32, text)
      else
        self.contents.draw_text(104, 352, 264, 32, "[NONE]")
      end
      self.contents.font.color = normal_color
      
      # Draw probibility and item
      prob = "#{enemy.treasure_prob}%"
      if enemy.item_id > 0
        icon = RPG::Cache.icon($data_items[enemy.item_id].icon_name)
        text = $data_items[enemy.item_id].name
      elsif enemy.weapon_id > 0
        icon = RPG::Cache.icon($data_weapons[enemy.weapon_id].icon_name)
        text = $data_weapons[enemy.weapon_id].name
      elsif enemy.armor_id > 0
        icon = RPG::Cache.icon($data_armors[enemy.armor_id].icon_name)
        text = $data_armors[enemy.armor_id].name
      else
        icon = Bitmap.new(24, 24)
        text = "None"
        prob = ""
      end
      self.contents.blt(48, 420, icon, Rect.new(0, 0, 24, 24))
      self.contents.draw_text(70 , 416, 204, 32, text)
      if prob != ""
        self.contents.font.color = system_color
        self.contents.draw_text(240, 416, 80, 32, "Probability:")
        self.contents.font.color = normal_color
        self.contents.draw_text(315, 416, 100, 32, prob)
      end
    # havent defeated the enemy
    else
      self.contents.font.color = disabled_color
      self.contents.draw_text(0, 280, 368, 32, "- Not Defeated -", 1)
    end
  end
end

#==============================================================================
#  Scene_MonsterGuide
#------------------------------------------------------------------------------
# 
#==============================================================================

class Scene_MonsterGuide
  #--------------------------------------------------------------------------
  # ● Initialize
  #     map_call : if it should go back to the map or not when you cancel
  #--------------------------------------------------------------------------
  def initialize(map_call = false)
    @map_call = map_call
  end
  #--------------------------------------------------------------------------
  # ● Main
  #--------------------------------------------------------------------------
  def main
    # if the window is going to be transparent
    @spriteset = Spriteset_Map.new if MG::BACK_TRANSPARENT
    # define the windows
    @guide_top_window = Window_MonsterGuideTop.new
    @guide_left_window = Window_MonsterGuideLeft.new
    @guide_right_window = Window_MonsterGuideRight.new
    # show the monster stats
    @show_status = true
    # the enemy is whatever enemy is selected in the left window
    enemy = @guide_left_window.item
    # refresh the right window
    @guide_right_window.refresh(enemy, @show_status)
    Graphics.transition
    # constantly update graphics and input until the scene changes
    while true
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    # freeze the graphics
    Graphics.freeze
    # dispose the windows
    @spriteset.dispose if MG::BACK_TRANSPARENT
    @guide_top_window.dispose
    @guide_left_window.dispose
    @guide_right_window.dispose
  end
  #--------------------------------------------------------------------------
  # ● Update
  #--------------------------------------------------------------------------
  def update
    # update the windows
    @guide_top_window.update
    @guide_left_window.update
    @guide_right_window.update
    # B Pressed
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # if this scene was called from the map
      if @map_call
        # go to the map
        $scene = Scene_Map.new
      else
        # go to the menu
        $scene = Scene_Menu.new(MG::MENU_INDEX)
      end
      return
    end
    # A Pressed
    if Input.trigger?(Input::A)
      # play SE
      $game_system.se_play($data_system.decision_se)
      # toggle showing stats
      @show_status = !@show_status
      # the current enemy to display is the one selected in the left window
      enemy = @guide_left_window.item
      # refresh the window on the right
      @guide_right_window.refresh(enemy, @show_status)
      return
    end
    # C Pressed
    if Input.trigger?(Input::C)
      # play SE
      $game_system.se_play($data_system.decision_se)
      # the current enemy to display is the one selected in the left window
      enemy = @guide_left_window.item
      # refresh the right window
      @guide_right_window.refresh(enemy, @show_status)
      return
    end
    #you dont have to click on a monster to view it's stats
    if MG::SELECT_REFRESH == false && @last_index != @guide_left_window.index
      # store current index
      @last_index = @guide_left_window.index
      # set the enemy to whatever enemy is selected
      enemy = @guide_left_window.item
      # refresh the right window
      @guide_right_window.refresh(enemy, @show_status)
      return
    end
  end
end

#==============================================================================
#  Scene_Battle (Phase 2)
#==============================================================================

class Scene_Battle
  #--------------------------------------------------------------------------
  # ● Start_Phase5
  #--------------------------------------------------------------------------
  alias start_phase5_KGC_MonsterGuide start_phase5
  def start_phase5
    # for every enemy in the troop
    $game_troop.enemies.each { |enemy|
      # skip enemy if it's hidden
      next if enemy.hidden
      # set the defeated variable for the enemy to true
      $game_system.enemy_defeated[enemy.id] = true
      enemy.original_id.compact.each { |i|
        $game_system.enemy_defeated[i] = true
      }
    }
    start_phase5_KGC_MonsterGuide
  end
end
 
This is a faulty copy. The translator renamed some of the 'defs' in the script and while he inserted some fairly easy-to-understand nstructions... he blew it by attempting to change the code itself.

LINK TO THE FORUM WITH THE SCRIPT
(It's in Japanese. You may need a translating service like Babelfish)

Note: This is a KGC script and errors like these are probably one of the things that the KGC Terms and Conditions were to prevent by stating no posting of KGC scripts were to be performed on other sites without permission. No biggie posting THIS under a 'HELP' topic. It's flawed anyway. The original japanese one works.

Also note that this script's text-drawing system is dependant on another KGC script known as 'KGC_FrameShadowText' which you can also find over there. Won't work without it.
 
Status
Not open for further replies.

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