[Resolved][XP] Blizzard's bestiary

Started by Simon Greedwell, January 03, 2014, 09:31:11 pm

Previous topic - Next topic

Simon Greedwell

January 03, 2014, 09:31:11 pm Last Edit: January 04, 2014, 01:34:03 pm by Simon Greedwell
Blizzard's script keeps throwing an error when I have more than 10 entries in the Custom Beast Info Database. There's the script:

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Bestiary by Blizzard
# Version: 2.3b
# Type: Enemy Catalogue Display
# Date: 5.7.2006
# Date v1.1: 18.9.2006
# Date v1.2b: 23.2.2007
# Date v1.3b: 7.7.2007
# Date v2.0b: 12.7.2007
# Date v2.1b: 6.8.2007
# Date v2.2b: 24.9.2007
# Date v2.21b: 8.4.2008
# Date v2.3b: 28.7.2009
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#  
#  This work is protected by the following license:
# #----------------------------------------------------------------------------
# #  
# #  Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
# #  ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
# #  
# #  You are free:
# #  
# #  to Share - to copy, distribute and transmit the work
# #  to Remix - to adapt the work
# #  
# #  Under the following conditions:
# #  
# #  Attribution. You must attribute the work in the manner specified by the
# #  author or licensor (but not in any way that suggests that they endorse you
# #  or your use of the work).
# #  
# #  Noncommercial. You may not use this work for commercial purposes.
# #  
# #  Share alike. If you alter, transform, or build upon this work, you may
# #  distribute the resulting work only under the same or similar license to
# #  this one.
# #  
# #  - For any reuse or distribution, you must make clear to others the license
# #    terms of this work. The best way to do this is with a link to this web
# #    page.
# #  
# #  - Any of the above conditions can be waived if you get permission from the
# #    copyright holder.
# #  
# #  - Nothing in this license impairs or restricts the author's moral rights.
# #  
# #----------------------------------------------------------------------------
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# Compatibility:
#
#   98% compatible with SDK v1.x. 70% compatible with SDK v2.x. May cause
#   incompatibility issues with exotic CBS-es. WILL corrupt your old savegames.
#
#
# Features:
#
#   - display of full data of enemies
#   - option to disable different information
#   - integrated support for my "Advanced Analyze System"
#   - press SHIFT/ENTER to change the appearance of the Bestiary window
#   - use LEFT/RIGHT/UP/DOWN to navigate through the information database
#
# new in v1.1b:
#   - bugs fixed
#
# new in v1.2b:
#   - improved coding (uses less RAM now and processes faster)
#
# new in v1.3b:
#   - increased compatibility
#
# new in v2.0b:
#   - completely overworked and fixed compatibility issues
#
# new in v2.1b:
#   - added custom info possibility
#
# new in v2.2b:
#   - rewritten conditions using classic syntax to avoid RGSS conditioning bug
#   - added SORT_BEASTS option
#   - improved coding
#
# new in v2.21b:
#   - improved coding
#
# new in v2.3b:
#   - improved coding
#
#
# Instructions:
#
# - Explanation:
#
#   This script will allow your characters to retrieve information about
#   enemies during battle and show them in a window. It also has built-in
#   compatibility for my "Advanced Analyze System" script and allows adding
#   enemies to it only if enemies were analyzed at least once. This script can
#   easily be used for Pokémon typed games.
#
# - Configuration:
#
#   Configure the part below and make one or more skills, that can analyze
#   enemies. Add the IDs into the array called ANALYZE_IDS and separate them
#   with commas. If you have one or more scripts using dummy elements (e.g. my
#   EQUAP Skills, SephirothSpawn's Limit Break, etc.) be sure to include every
#   dummy element ID in the array called ELM_DUMMIES, also separated by commas.
#   Below is everything explained, how to set the bestiary up. It has
#   additional options for rendering single or all enemies "Unknown" and adding
#   them into the bestiary as such. Later you can use a syntax described below
#   to enable their information display (e.g. like in Pokémon games, you get
#   the real info about a pokémon not when you meet it, but when you catch it).
#   You can use $game_system.bestiary_missing? to check how many enemies were
#   not added into the Bestiary. If you wish to see how many were added, use
#   $game_system.beasts.size
#
#
# Important notes:
#
#   You MUST configure the part below if you have scripts that use dummy
#   elements! Do NOT give your enemies MORE than 11 elements/status effects of
#   one resistance type (e.g. 12 or more elements, that are absorbed), because
#   they won't be displayed.
#
#
# If you find any bugs, please report them here:
# http://forum.chaos-project.com
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

ELM_DUMMIES = [] # include EVERY dummy element ID, that is used by other scripts
STA_DUMMIES = [] # include EVERY dummy status effect ID, that you use
EVASION = 'Eva' # word used to display Evasion
MAP_BACKGROUND = true # true will show the map background, false won't
BESTIARY_SIZE = 999 # change this if to as many
NEVER_ADD = [] # include IDs of enemies which will never be added
SORT_BEASTS = true # set to false if you don't want all enemies to be sorted by ID

# enemy IDs from enemies, that are unknown (e.g. bosses), to make an enemy
# known use $game_system.enable(ENEMY_ID) through the event command
# "Call Script" to enable the display of information

if $override_bestiary
 UNKNOWN = [4] # overrides the commands further below
else
 UNKNOWN = [] # DO NOT TOUCH THIS
end

# every enemy is initially unknown (e.g. for Pokémon games), so you don't have
# to fill the array above with all the IDs of your enemy database

ALL_UNKNOWN = false

# If a display below is disabled, the appropriate part above will be overriden.
# The values below can also be changed during gameplay by just calling the
# "Call script" event command and changing the values like below
# DO NOT SET EVERYTHING TO true! THIS WILL BUG YOUR BESTIARY!

# set to true to disable display of basic info
DISABLE_BEAST_BASIC = false
# set to true to disable display of basic stats
DISABLE_BEAST_STATS = false
# set to true to disable display of extended stats
DISABLE_BEAST_EXTSTATS = false
# set to true to disable display of extreme element weakness
DISABLE_BEAST_XTRWEAK = false
# set to true to disable display of element weakness
DISABLE_BEAST_WEAK = false
# set to true to disable display of element resistance
DISABLE_BEAST_RESIST = false
# set to true to disable display of element nullification
DISABLE_BEAST_NULLIFY = false
# set to true to disable display of element absorbtion
DISABLE_BEAST_ABSORB = false
# set to true to disable display of extreme status effect weakness
DISABLE_BEAST_XTRWEAK_S = false
# set to true to disable display of status effect weakness
DISABLE_BEAST_WEAK_S = false
# set to true to disable display of status effect resistance
DISABLE_BEAST_RESIST_S = false
# set to true to disable display of status effect nullification
DISABLE_BEAST_NULLIFY_S = false
# set to true to disable display of status effect absorbtion
DISABLE_BEAST_ABSORB_S = false
# set to false to enable custom display
DISABLE_BEAST_CUSTOM = false

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

if $DUMMY_ELEMENTS == nil
 $DUMMY_ELEMENTS = ELM_DUMMIES.clone
else
 $DUMMY_ELEMENTS |= ELM_DUMMIES
end
ELM_DUMMIES = nil
if $DUMMY_STATES == nil
 $DUMMY_STATES = STA_DUMMIES.clone
else
 $DUMMY_STATES |= STA_DUMMIES
end
STA_DUMMIES = nil

$bestiary_enabled = 2.3

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

class Game_System
 
 attr_accessor :window_mode
 attr_accessor :known
 
 def get_bestiary_info(id)
   return get_analyze_info(id) if $override_bestiary_info
   case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Custom Beast Info Database
#
# Use following template to add custom information about monsters:
#
#    when ID then return "STRING"
#
# ID is the enemy ID and STRING is a string with the information that should be
# displayed. Type all the information into one string, the script will slice
# the text by itself. Note that special characters like a " (double quote)
# need the use of the escape character \ (backslash). If you get and error
# with your string or the character doesn't appear right on the screen, try to
# use the escape character (i.e. for a " it would be \" instead of just ").
# The backslash itself needs an escape character (i.e. \\).
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   when 1 then return "Until now I believed there is no such thing as a ghost. It's hard to not believe in something that is trying to kill you."
   when 2 then return "These creatures can be found in swamps and marshes. They are said to be able to have the ability to turn anything they glaze at into stone. If this rumor is true, these creatures can be considered as part of the family of \"Gorgons\"."
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Custom Beast Info Database
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   end
   return 'Unknown'
 end

 alias init_beast_later initialize
 def initialize
   init_beast_later
   @window_mode, @beasts, @known = 0, [], []
 end
 
 def beasts
   return ($bestiary_override ? @analyzed : @beasts) - NEVER_ADD
 end
 
 def add_beast(beast)
   unless @beasts.include?(beast)
     @beasts.push(beast)
     @beasts.sort! if SORT_BEASTS
   end
 end
 
 def bestiary_missing?
   return (BESTIARY_SIZE - @beasts.size)
 end
 
 def enable(id)
   $game_system.known.push(id) unless $game_system.known.include?(id)
   return
 end
 
end

#==============================================================================
# RPG::Enemy
#==============================================================================

class RPG::Enemy
 
 def known
   return ($game_system.known.include?(self.id)) if ALL_UNKNOWN
   return (!UNKNOWN.include?(self.id))
 end
 
end

#==============================================================================
# Window_Base
#==============================================================================

class Window_Base
 
 def draw_bestiary_battler(enemy, w, h)
   bitmap = RPG::Cache.battler(enemy.battler_name, enemy.battler_hue)
   bitmap_w = bitmap.width / 2
   bitmap_h = bitmap.height / 2
   src_rect = Rect.new(0, 0, bitmap.width, bitmap.height)
   self.contents.blt(w/2 - bitmap_w, h/2 - bitmap_h, bitmap, src_rect, 192)
 end
 
end

#==============================================================================
# Bitmap
#==============================================================================

class Bitmap
 
 def slice_text(text, width)
   words = text.split(' ')
   return words if words.size == 1
   result, current_text = [], words.shift
   words.each_index {|i|
       if self.text_size("#{current_text} #{words[i]}").width > width
         result.push(current_text)
         current_text = words[i]
       else
         current_text = "#{current_text} #{words[i]}"
       end
       result.push(current_text) if i >= words.size - 1}
   return result
 end
 
end

#==============================================================================
# Window_Beast
#==============================================================================

class Window_Beast < Window_Base

 attr_accessor :mode
 
 def initialize
   super(0, 0, 576, 416)
   @index_enemy = 0
   @index_page = 0
   @d = [DISABLE_BEAST_BASIC, DISABLE_BEAST_STATS, DISABLE_BEAST_EXTSTATS,
         DISABLE_BEAST_XTRWEAK, DISABLE_BEAST_WEAK, DISABLE_BEAST_RESIST,
         DISABLE_BEAST_NULLIFY, DISABLE_BEAST_ABSORB, DISABLE_BEAST_XTRWEAK_S,
         DISABLE_BEAST_WEAK_S, DISABLE_BEAST_RESIST_S, DISABLE_BEAST_NULLIFY_S,
         DISABLE_BEAST_ABSORB_S, DISABLE_BEAST_CUSTOM]
   @pages = 14 - ((0..13).find_all {|i| @d[i]}).size
   @mode = $game_system.window_mode
   @enemies = []
   for id in ($override_bestiary ? $game_system.analyzed : $game_system.beasts)
     @enemies.push($data_enemies[id]) if id != nil
   end
   self.contents = Bitmap.new(width - 32, height - 32)
   if $fontface != nil
     self.contents.font.name = $fontface
     self.contents.font.size = $fontsize
   elsif $defaultfonttype != nil
     self.contents.font.name = $defaultfonttype
     self.contents.font.size = $defaultfontsize
   end
   self.x = 320 - self.width / 2
   self.y = 240 - self.height / 2
   refresh
 end
 
 def update
   return if @enemies.size == 0
   if Input.trigger?(Input::RIGHT)
     $game_system.se_play($data_system.cursor_se)
     @index_enemy = (@index_enemy + 1) % @enemies.size
     refresh
   elsif Input.trigger?(Input::LEFT)
     $game_system.se_play($data_system.cursor_se)
     @index_enemy = (@index_enemy + @enemies.size - 1) % @enemies.size
     refresh
   elsif Input.trigger?(Input::DOWN)
     $game_system.se_play($data_system.cursor_se)
     @index_page = (@index_page + 1) % @pages
     refresh
   elsif Input.trigger?(Input::UP)
     $game_system.se_play($data_system.cursor_se)
     @index_page = (@index_page + @pages - 1) % @pages
     refresh
   end
 end
 
 def refresh
   self.contents.clear
   x = y = 0
   ox = x + 64
   enemy = @enemies[@index_enemy]
   if enemy == nil
     self.contents.draw_text(0, 64, 544, 32, 'Bestiary is empty', 1)
     return
   end
   self.contents.draw_text(0, 0, 544, 32, "#{enemy.id}.  #{enemy.name}", 1)
   draw_bestiary_battler(enemy, self.width, self.height)
   if enemy.known
     case @index_page
     when (0 - ((0..0).find_all {|i| @d[i]}).size)
       if enemy.item_id > 0
         drop = $data_items[enemy.item_id]
         t = "#{drop.name} (#{enemy.treasure_prob}% chance)"
       elsif enemy.weapon_id > 0
         drop = $data_weapons[enemy.weapon_id]
         t = "#{drop.name} (#{enemy.treasure_prob}% chance)"
       elsif enemy.armor_id > 0
         drop = $data_armors[enemy.armor_id]
         t = "#{drop.name} (#{enemy.treasure_prob}% chance)"
       end
       self.contents.draw_text(x, 32, 128, 32, $data_system.words.hp)
       self.contents.draw_text(x, 96, 128, 32, $data_system.words.sp)
       self.contents.draw_text(x, 160, 128, 32, 'EXP')
       self.contents.draw_text(x, 224, 128, 32, $data_system.words.gold)
       self.contents.draw_text(x, 288, 128, 32, 'Drops')
       self.contents.draw_text(ox, 64, 256, 32, enemy.maxhp.to_s)
       self.contents.draw_text(ox, 128, 256, 32, enemy.maxsp.to_s)
       self.contents.draw_text(ox, 192, 256, 32, enemy.exp.to_s)
       self.contents.draw_text(ox, 256, 256, 32, enemy.gold.to_s)
       self.contents.draw_text(ox, 320, 256, 32, (drop != nil ? t : 'nothing'))
     when (1 - ((0..1).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 128, 32, $data_system.words.str)
       self.contents.draw_text(x, 96, 128, 32, $data_system.words.dex)
       self.contents.draw_text(x, 160, 128, 32, $data_system.words.agi)
       self.contents.draw_text(x, 224, 128, 32, $data_system.words.int)
       self.contents.draw_text(ox, 64, 256, 32, enemy.str.to_s)
       self.contents.draw_text(ox, 128, 256, 32, enemy.dex.to_s)
       self.contents.draw_text(ox, 256, 256, 32, enemy.agi.to_s)
       self.contents.draw_text(ox, 192, 256, 32, enemy.int.to_s)
     when (2 - ((0..2).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 128, 32, $data_system.words.atk)
       self.contents.draw_text(x, 96, 128, 32, $data_system.words.pdef)
       self.contents.draw_text(x, 160, 128, 32, $data_system.words.mdef)
       self.contents.draw_text(x, 224, 128, 32, EVASION)
       self.contents.draw_text(ox, 64, 256, 32, enemy.atk.to_s)
       self.contents.draw_text(ox, 128, 256, 32, enemy.pdef.to_s)
       self.contents.draw_text(ox, 192, 256, 32, enemy.mdef.to_s)
       self.contents.draw_text(ox, 256, 256, 32, enemy.eva.to_s)
     when (3 - ((0..3).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Extremely efficient elements:')
       draw_elements(enemy, x, 1)
     when (4 - ((0..4).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Efficient elements:')
       draw_elements(enemy, x, 2)
     when (5 - ((0..5).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Elemental resistances:')
       draw_elements(enemy, x, 4)
     when (6 - ((0..6).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Elemental nullifications:')
       draw_elements(enemy, x, 5)
     when (7 - ((0..7).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Elemental absorbtions:')
       draw_elements(enemy, x, 6)
     when (8 - ((0..8).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Extremely efficient status effects:')
       draw_states(enemy, x, 1)
     when (9 - ((0..9).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Efficient status effects:')
       draw_states(enemy, x, 2)
     when (10 - ((0..10).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Status effect resistances:')
       draw_states(enemy, x, 4)
     when (11 - ((0..11).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Strong status effect resistances:')
       draw_states(enemy, x, 5)
     when (12 - ((0..12).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Status effect immunities:')
       draw_states(enemy, x, 6)
     when (13 - ((0..13).find_all {|i| @d[i]}).size)
       self.contents.draw_text(x, 32, 544, 32, 'Informations:')
       draw_info(enemy, x)
     end
   else
     self.contents.draw_text(0, 64, 544, 32, 'Unknown', 1)
   end
 end
 
 def draw_elements(enemy, x, index)
   elements = []
   (1...$data_system.elements.size).each {|id|
       if !$DUMMY_ELEMENTS.include?(id) &&
           index == $data_enemies[@enemies[@index_enemy].id].element_ranks[id]
         elements.push($data_system.elements[id])
       end}
   elements = ['Nothing'] if elements.size == 0
   elements.each_index {|i|
       self.contents.draw_text(x, 64 + i * 32, 544, 32, elements[i])}
 end
   
 def draw_states(enemy, x, index)
   states = []
   (1...$data_states.size).each {|id|
       if !$DUMMY_STATES.include?(id) &&
           index == $data_enemies[@enemies[@index_enemy].id].state_ranks[id]
         states.push($data_states[id].name)
       end}
   states = ['Nothing'] if states.size == 0
   states.each_index {|i|
       self.contents.draw_text(x, 64 + i * 32, 544, 32, states[i])}
 end
 
 def draw_info(enemy, x)
   text = self.contents.slice_text($game_system.get_bestiary_info(enemy.id), 528)
   text.each_index {|i|
       self.contents.draw_text(x, 64 + i*32, 544, 32, text[i])}
 end
   
end

#==============================================================================
# Scene_Bestiary
#==============================================================================

class Scene_Bestiary
 
 def main
   @spriteset = Spriteset_Map.new if MAP_BACKGROUND
   @beast_window = Window_Beast.new
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     break if $scene != self
   end
   Graphics.freeze
   @spriteset.dispose if MAP_BACKGROUND
   @beast_window.dispose
 end
 
 def update
   @beast_window.update
   if MAP_BACKGROUND && (Input.trigger?(Input::A) || Input.trigger?(Input::C))
     Graphics.freeze
     $game_system.se_play($data_system.cursor_se)
     case @beast_window.mode
     when 0 then @beast_window.back_opacity = 128
     when 1 then @beast_window.opacity = 0
     when 2 then @beast_window.opacity = @beast_window.back_opacity = 255
     end
     $game_system.window_mode = ($game_system.window_mode+1) % 3
     @beast_window.mode = $game_system.window_mode
     Graphics.transition(5)
   end
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     $scene = Scene_Map.new
   end
 end


end
 
#==============================================================================
# Scene_Battle
#==============================================================================

class Scene_Battle
 
 alias update_beast_later update
 def update
   if @log == nil && !$override_bestiary
     @log = true
     $game_troop.enemies.each {|enemy| $game_system.add_beast(enemy.id)}
   end
   update_beast_later
 end
 
end


Tgese are the other scripts I'm using:

(*) STCMS - Hybrid Edition
Game_System *
Other Classes *

Gold and Experience Percent Add On
Interpreter Fix
Large Party
HP Absorbption Skills
Custom Equipment Screen
Custom Window Skill
HP/SP bonus in armors
Face
FF-styled Item Scene
Large Party Scene Shop
Break HP Limit for Foes
Advanced Message Script
Absorb_Setup
System
Mods to Classes
Custom Prices

Bury with my...money!

KK20

It'd help if you posted what the error is and where/when you get it.

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!

Simon Greedwell

It's a syntax error that takes place in the line where the tenth and/or eleventh entry on the Custom Beast Info Database are. For example, here's the script with my bestiary entries included.

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Bestiary by Blizzard
# Version: 2.3b
# Type: Enemy Catalogue Display
# Date: 5.7.2006
# Date v1.1: 18.9.2006
# Date v1.2b: 23.2.2007
# Date v1.3b: 7.7.2007
# Date v2.0b: 12.7.2007
# Date v2.1b: 6.8.2007
# Date v2.2b: 24.9.2007
# Date v2.21b: 8.4.2008
# Date v2.3b: 28.7.2009
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#   
#  This work is protected by the following license:
# #----------------------------------------------------------------------------
# # 
# #  Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
# #  ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
# # 
# #  You are free:
# # 
# #  to Share - to copy, distribute and transmit the work
# #  to Remix - to adapt the work
# # 
# #  Under the following conditions:
# # 
# #  Attribution. You must attribute the work in the manner specified by the
# #  author or licensor (but not in any way that suggests that they endorse you
# #  or your use of the work).
# # 
# #  Noncommercial. You may not use this work for commercial purposes.
# # 
# #  Share alike. If you alter, transform, or build upon this work, you may
# #  distribute the resulting work only under the same or similar license to
# #  this one.
# # 
# #  - For any reuse or distribution, you must make clear to others the license
# #    terms of this work. The best way to do this is with a link to this web
# #    page.
# # 
# #  - Any of the above conditions can be waived if you get permission from the
# #    copyright holder.
# # 
# #  - Nothing in this license impairs or restricts the author's moral rights.
# # 
# #----------------------------------------------------------------------------
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# Compatibility:
#
#   98% compatible with SDK v1.x. 70% compatible with SDK v2.x. May cause
#   incompatibility issues with exotic CBS-es. WILL corrupt your old savegames.
#
#
# Features:
#
#   - display of full data of enemies
#   - option to disable different information
#   - integrated support for my "Advanced Analyze System"
#   - press SHIFT/ENTER to change the appearance of the Bestiary window
#   - use LEFT/RIGHT/UP/DOWN to navigate through the information database
#
# new in v1.1b:
#   - bugs fixed
#
# new in v1.2b:
#   - improved coding (uses less RAM now and processes faster)
#
# new in v1.3b:
#   - increased compatibility
#
# new in v2.0b:
#   - completely overworked and fixed compatibility issues
#
# new in v2.1b:
#   - added custom info possibility
#
# new in v2.2b:
#   - rewritten conditions using classic syntax to avoid RGSS conditioning bug
#   - added SORT_BEASTS option
#   - improved coding
#
# new in v2.21b:
#   - improved coding
#
# new in v2.3b:
#   - improved coding
#
#
# Instructions:
#
# - Explanation:
#
#   This script will allow your characters to retrieve information about
#   enemies during battle and show them in a window. It also has built-in
#   compatibility for my "Advanced Analyze System" script and allows adding
#   enemies to it only if enemies were analyzed at least once. This script can
#   easily be used for Pokémon typed games.
#
# - Configuration:
#
#   Configure the part below and make one or more skills, that can analyze
#   enemies. Add the IDs into the array called ANALYZE_IDS and separate them
#   with commas. If you have one or more scripts using dummy elements (e.g. my
#   EQUAP Skills, SephirothSpawn's Limit Break, etc.) be sure to include every
#   dummy element ID in the array called ELM_DUMMIES, also separated by commas.
#   Below is everything explained, how to set the bestiary up. It has
#   additional options for rendering single or all enemies "Unknown" and adding
#   them into the bestiary as such. Later you can use a syntax described below
#   to enable their information display (e.g. like in Pokémon games, you get
#   the real info about a pokémon not when you meet it, but when you catch it).
#   You can use $game_system.bestiary_missing? to check how many enemies were
#   not added into the Bestiary. If you wish to see how many were added, use
#   $game_system.beasts.size
#
#
# Important notes:
#
#   You MUST configure the part below if you have scripts that use dummy
#   elements! Do NOT give your enemies MORE than 11 elements/status effects of
#   one resistance type (e.g. 12 or more elements, that are absorbed), because
#   they won't be displayed.
#
#
# If you find any bugs, please report them here:
# http://forum.chaos-project.com
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

ELM_DUMMIES = [] # include EVERY dummy element ID, that is used by other scripts
STA_DUMMIES = [] # include EVERY dummy status effect ID, that you use
EVASION = 'Eva' # word used to display Evasion
MAP_BACKGROUND = true # true will show the map background, false won't
BESTIARY_SIZE = 999 # change this if to as many
NEVER_ADD = [] # include IDs of enemies which will never be added
SORT_BEASTS = true # set to false if you don't want all enemies to be sorted by ID

# enemy IDs from enemies, that are unknown (e.g. bosses), to make an enemy
# known use $game_system.enable(ENEMY_ID) through the event command
# "Call Script" to enable the display of information

if $override_bestiary
  UNKNOWN = [4] # overrides the commands further below
else
  UNKNOWN = [] # DO NOT TOUCH THIS
end

# every enemy is initially unknown (e.g. for Pokémon games), so you don't have
# to fill the array above with all the IDs of your enemy database

ALL_UNKNOWN = false

# If a display below is disabled, the appropriate part above will be overriden.
# The values below can also be changed during gameplay by just calling the
# "Call script" event command and changing the values like below
# DO NOT SET EVERYTHING TO true! THIS WILL BUG YOUR BESTIARY!

# set to true to disable display of basic info
DISABLE_BEAST_BASIC = false
# set to true to disable display of basic stats
DISABLE_BEAST_STATS = false
# set to true to disable display of extended stats
DISABLE_BEAST_EXTSTATS = false
# set to true to disable display of extreme element weakness
DISABLE_BEAST_XTRWEAK = false
# set to true to disable display of element weakness
DISABLE_BEAST_WEAK = false
# set to true to disable display of element resistance
DISABLE_BEAST_RESIST = false
# set to true to disable display of element nullification
DISABLE_BEAST_NULLIFY = false
# set to true to disable display of element absorbtion
DISABLE_BEAST_ABSORB = false
# set to true to disable display of extreme status effect weakness
DISABLE_BEAST_XTRWEAK_S = false
# set to true to disable display of status effect weakness
DISABLE_BEAST_WEAK_S = false
# set to true to disable display of status effect resistance
DISABLE_BEAST_RESIST_S = false
# set to true to disable display of status effect nullification
DISABLE_BEAST_NULLIFY_S = false
# set to true to disable display of status effect absorbtion
DISABLE_BEAST_ABSORB_S = false
# set to false to enable custom display
DISABLE_BEAST_CUSTOM = false

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

if $DUMMY_ELEMENTS == nil
  $DUMMY_ELEMENTS = ELM_DUMMIES.clone
else
  $DUMMY_ELEMENTS |= ELM_DUMMIES
end
ELM_DUMMIES = nil
if $DUMMY_STATES == nil
  $DUMMY_STATES = STA_DUMMIES.clone
else
  $DUMMY_STATES |= STA_DUMMIES
end
STA_DUMMIES = nil

$bestiary_enabled = 2.3

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

class Game_System
 
  attr_accessor :window_mode
  attr_accessor :known
 
  def get_bestiary_info(id)
    return get_analyze_info(id) if $override_bestiary_info
    case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Custom Beast Info Database
#
# Use following template to add custom information about monsters:
#
#    when ID then return "STRING"
#
# ID is the enemy ID and STRING is a string with the information that should be
# displayed. Type all the information into one string, the script will slice
# the text by itself. Note that special characters like a " (double quote)
# need the use of the escape character \ (backslash). If you get and error
# with your string or the character doesn't appear right on the screen, try to
# use the escape character (i.e. for a " it would be \" instead of just ").
# The backslash itself needs an escape character (i.e. \\).
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    when 1 then return "A barely sentient pile of ooze that enjoys eyeballing unsuspected travelers. Not a difficult opponent at all."
    when 2 then return "Large-sized maggot that lurks on forests. Uses \"Sticky End\" to slowdown foes."
    when 3 then return "Tired of being stepped on, this walking grass decided to strike back."
    when 4 then return "A seed that developed a deep-seated hatred for the cold, uncaring world that didn't allow it to grow."   
    when 5 then return "A guardian beast with the appearance of a large, armoured wolly creature. One of the most popular model available on the market."
    when 6 then return "A hostil ghost possessing a bunch of stones. It will relentessly pursue any intruders on its turf."
    when 7 then return "Short-tempered and highly territorial, Nruffs will butt heads with everyone on the vicinity and with little provocation."
    when 8 then return "It thinks that impaling people with its oversized horn is a demostration of friendship. Most would disagree."
    when 9 then return "An angry knight with a sizeable chip on his shoulder and a mean streak a mile while. Was on pursuit of the Pearl of Balance."
    when 10 then return "A hapless mage at beck and call of his partner. Legrous' magical prowess leaves something to be desired, so does his commitment to work".
     when 11 then return "Drowzy demon that believes that sleeping is the greatest joy anyone can experience\.
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Custom Beast Info Database
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    end
    return 'Unknown'
  end

  alias init_beast_later initialize
  def initialize
    init_beast_later
    @window_mode, @beasts, @known = 0, [], []
  end
 
  def beasts
    return ($bestiary_override ? @analyzed : @beasts) - NEVER_ADD
  end
 
  def add_beast(beast)
    unless @beasts.include?(beast)
      @beasts.push(beast)
      @beasts.sort! if SORT_BEASTS
    end
  end
 
  def bestiary_missing?
    return (BESTIARY_SIZE - @beasts.size)
  end
 
  def enable(id)
    $game_system.known.push(id) unless $game_system.known.include?(id)
    return
  end
 
end

#==============================================================================
# RPG::Enemy
#==============================================================================

class RPG::Enemy
 
  def known
    return ($game_system.known.include?(self.id)) if ALL_UNKNOWN
    return (!UNKNOWN.include?(self.id))
  end
 
end

#==============================================================================
# Window_Base
#==============================================================================

class Window_Base
 
  def draw_bestiary_battler(enemy, w, h)
    bitmap = RPG::Cache.battler(enemy.battler_name, enemy.battler_hue)
    bitmap_w = bitmap.width / 2
    bitmap_h = bitmap.height / 2
    src_rect = Rect.new(0, 0, bitmap.width, bitmap.height)
    self.contents.blt(w/2 - bitmap_w, h/2 - bitmap_h, bitmap, src_rect, 192)
  end
 
end

#==============================================================================
# Bitmap
#==============================================================================

class Bitmap
 
  def slice_text(text, width)
    words = text.split(' ')
    return words if words.size == 1
    result, current_text = [], words.shift
    words.each_index {|i|
        if self.text_size("#{current_text} #{words[i]}").width > width
          result.push(current_text)
          current_text = words[i]
        else
          current_text = "#{current_text} #{words[i]}"
        end
        result.push(current_text) if i >= words.size - 1}
    return result
  end
 
end

#==============================================================================
# Window_Beast
#==============================================================================

class Window_Beast < Window_Base

  attr_accessor :mode
 
  def initialize
    super(0, 0, 576, 416)
    @index_enemy = 0
    @index_page = 0
    @d = [DISABLE_BEAST_BASIC, DISABLE_BEAST_STATS, DISABLE_BEAST_EXTSTATS,
          DISABLE_BEAST_XTRWEAK, DISABLE_BEAST_WEAK, DISABLE_BEAST_RESIST,
          DISABLE_BEAST_NULLIFY, DISABLE_BEAST_ABSORB, DISABLE_BEAST_XTRWEAK_S,
          DISABLE_BEAST_WEAK_S, DISABLE_BEAST_RESIST_S, DISABLE_BEAST_NULLIFY_S,
          DISABLE_BEAST_ABSORB_S, DISABLE_BEAST_CUSTOM]
    @pages = 14 - ((0..13).find_all {|i| @d[i]}).size
    @mode = $game_system.window_mode
    @enemies = []
    for id in ($override_bestiary ? $game_system.analyzed : $game_system.beasts)
      @enemies.push($data_enemies[id]) if id != nil
    end
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    self.x = 320 - self.width / 2
    self.y = 240 - self.height / 2
    refresh
  end
 
  def update
    return if @enemies.size == 0
    if Input.trigger?(Input::RIGHT)
      $game_system.se_play($data_system.cursor_se)
      @index_enemy = (@index_enemy + 1) % @enemies.size
      refresh
    elsif Input.trigger?(Input::LEFT)
      $game_system.se_play($data_system.cursor_se)
      @index_enemy = (@index_enemy + @enemies.size - 1) % @enemies.size
      refresh
    elsif Input.trigger?(Input::DOWN)
      $game_system.se_play($data_system.cursor_se)
      @index_page = (@index_page + 1) % @pages
      refresh
    elsif Input.trigger?(Input::UP)
      $game_system.se_play($data_system.cursor_se)
      @index_page = (@index_page + @pages - 1) % @pages
      refresh
    end
  end
 
  def refresh
    self.contents.clear
    x = y = 0
    ox = x + 64
    enemy = @enemies[@index_enemy]
    if enemy == nil
      self.contents.draw_text(0, 64, 544, 32, 'Bestiary is empty', 1)
      return
    end
    self.contents.draw_text(0, 0, 544, 32, "#{enemy.id}.  #{enemy.name}", 1)
    draw_bestiary_battler(enemy, self.width, self.height)
    if enemy.known
      case @index_page
      when (0 - ((0..0).find_all {|i| @d[i]}).size)
        if enemy.item_id > 0
          drop = $data_items[enemy.item_id]
          t = "#{drop.name} (#{enemy.treasure_prob}% chance)"
        elsif enemy.weapon_id > 0
          drop = $data_weapons[enemy.weapon_id]
          t = "#{drop.name} (#{enemy.treasure_prob}% chance)"
        elsif enemy.armor_id > 0
          drop = $data_armors[enemy.armor_id]
          t = "#{drop.name} (#{enemy.treasure_prob}% chance)"
        end
        self.contents.draw_text(x, 32, 128, 32, $data_system.words.hp)
        self.contents.draw_text(x, 96, 128, 32, $data_system.words.sp)
        self.contents.draw_text(x, 160, 128, 32, 'EXP')
        self.contents.draw_text(x, 224, 128, 32, $data_system.words.gold)
        self.contents.draw_text(x, 288, 128, 32, 'Drops')
        self.contents.draw_text(ox, 64, 256, 32, enemy.maxhp.to_s)
        self.contents.draw_text(ox, 128, 256, 32, enemy.maxsp.to_s)
        self.contents.draw_text(ox, 192, 256, 32, enemy.exp.to_s)
        self.contents.draw_text(ox, 256, 256, 32, enemy.gold.to_s)
        self.contents.draw_text(ox, 320, 256, 32, (drop != nil ? t : 'nothing'))
      when (1 - ((0..1).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 128, 32, $data_system.words.str)
        self.contents.draw_text(x, 96, 128, 32, $data_system.words.dex)
        self.contents.draw_text(x, 160, 128, 32, $data_system.words.agi)
        self.contents.draw_text(x, 224, 128, 32, $data_system.words.int)
        self.contents.draw_text(ox, 64, 256, 32, enemy.str.to_s)
        self.contents.draw_text(ox, 128, 256, 32, enemy.dex.to_s)
        self.contents.draw_text(ox, 256, 256, 32, enemy.agi.to_s)
        self.contents.draw_text(ox, 192, 256, 32, enemy.int.to_s)
      when (2 - ((0..2).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 128, 32, $data_system.words.atk)
        self.contents.draw_text(x, 96, 128, 32, $data_system.words.pdef)
        self.contents.draw_text(x, 160, 128, 32, $data_system.words.mdef)
        self.contents.draw_text(x, 224, 128, 32, EVASION)
        self.contents.draw_text(ox, 64, 256, 32, enemy.atk.to_s)
        self.contents.draw_text(ox, 128, 256, 32, enemy.pdef.to_s)
        self.contents.draw_text(ox, 192, 256, 32, enemy.mdef.to_s)
        self.contents.draw_text(ox, 256, 256, 32, enemy.eva.to_s)
      when (3 - ((0..3).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Extremely efficient elements:')
        draw_elements(enemy, x, 1)
      when (4 - ((0..4).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Efficient elements:')
        draw_elements(enemy, x, 2)
      when (5 - ((0..5).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Elemental resistances:')
        draw_elements(enemy, x, 4)
      when (6 - ((0..6).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Elemental nullifications:')
        draw_elements(enemy, x, 5)
      when (7 - ((0..7).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Elemental absorbtions:')
        draw_elements(enemy, x, 6)
      when (8 - ((0..8).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Extremely efficient status effects:')
        draw_states(enemy, x, 1)
      when (9 - ((0..9).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Efficient status effects:')
        draw_states(enemy, x, 2)
      when (10 - ((0..10).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Status effect resistances:')
        draw_states(enemy, x, 4)
      when (11 - ((0..11).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Strong status effect resistances:')
        draw_states(enemy, x, 5)
      when (12 - ((0..12).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Status effect immunities:')
        draw_states(enemy, x, 6)
      when (13 - ((0..13).find_all {|i| @d[i]}).size)
        self.contents.draw_text(x, 32, 544, 32, 'Biography:')
        draw_info(enemy, x)
      end
    else
      self.contents.draw_text(0, 64, 544, 32, 'Unknown', 1)
    end
  end
 
  def draw_elements(enemy, x, index)
    elements = []
    (1...$data_system.elements.size).each {|id|
        if !$DUMMY_ELEMENTS.include?(id) &&
            index == $data_enemies[@enemies[@index_enemy].id].element_ranks[id]
          elements.push($data_system.elements[id])
        end}
    elements = ['Nothing'] if elements.size == 0
    elements.each_index {|i|
        self.contents.draw_text(x, 64 + i * 32, 544, 32, elements[i])}
  end
   
  def draw_states(enemy, x, index)
    states = []
    (1...$data_states.size).each {|id|
        if !$DUMMY_STATES.include?(id) &&
            index == $data_enemies[@enemies[@index_enemy].id].state_ranks[id]
          states.push($data_states[id].name)
        end}
    states = ['Nothing'] if states.size == 0
    states.each_index {|i|
        self.contents.draw_text(x, 64 + i * 32, 544, 32, states[i])}
  end
 
  def draw_info(enemy, x)
    text = self.contents.slice_text($game_system.get_bestiary_info(enemy.id), 528)
    text.each_index {|i|
        self.contents.draw_text(x, 64 + i*32, 544, 32, text[i])}
  end
   
end

#==============================================================================
# Scene_Bestiary
#==============================================================================

class Scene_Bestiary
 
  def main
    @spriteset = Spriteset_Map.new if MAP_BACKGROUND
    @beast_window = Window_Beast.new
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      break if $scene != self
    end
    Graphics.freeze
    @spriteset.dispose if MAP_BACKGROUND
    @beast_window.dispose
  end
 
  def update
    @beast_window.update
    if MAP_BACKGROUND && (Input.trigger?(Input::A) || Input.trigger?(Input::C))
      Graphics.freeze
      $game_system.se_play($data_system.cursor_se)
      case @beast_window.mode
      when 0 then @beast_window.back_opacity = 128
      when 1 then @beast_window.opacity = 0
      when 2 then @beast_window.opacity = @beast_window.back_opacity = 255
      end
      $game_system.window_mode = ($game_system.window_mode+1) % 3
      @beast_window.mode = $game_system.window_mode
      Graphics.transition(5)
    end
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Map.new
    end
  end


end
 
#==============================================================================
# Scene_Battle
#==============================================================================

class Scene_Battle
 
  alias update_beast_later update
  def update
    if @log == nil && !$override_bestiary
      @log = true
      $game_troop.enemies.each {|enemy| $game_system.add_beast(enemy.id)}
    end
    update_beast_later
  end
 
end


The syntax error occurres at line 249, where the eleventh entry is. Doing another test, I noticed another error at line 547 - at the very end of the script - if I have only ten entries on the bestiary.

Bury with my...money!

PhoenixFire

Well, if this is an exact copy, it may just be a really silly error... On entry 11, take a look at the end of it... you have a / instead of a " to close the return argument.
Quote from: Subsonic_Noise on July 01, 2011, 02:42:19 amNext off, how to create a first person shooter using microsoft excel.

Quote from: Zeriab on September 09, 2011, 02:58:58 pm<Remember when computers had turbo buttons?

Simon Greedwell

I didn't noticed that. The Syntax error persists even after I fixed it though.

It seems the script works as long as you have less than 9 entries in the Custom Beast Info Database.
Bury with my...money!

ThallionDarkshine

also, on entry 10 you have the period outside of the quotes. that could be causing the syntax error on line 547

Simon Greedwell

With both those typos gone, the script works now. A thousand thanks.

Man, it's really embarrassing how those silly mistakes caused me so many troubles :facepalm:.

I'll be extra careful now.
Bury with my...money!