#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
# Journal
# Author: ForeverZer0
# Version: 2.4
# Data: 12.30.2010
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#
# Introduction:
# Â I wrote this script after seeing a request here on CP for something similar.
# Â It basically just allows the player to view a Journal that show the player
# Â information about people they have encountered and places they have visited.
# Â Can also log weapons, armors, and items.
# Â Â
# Features:
# Â - Easy to use/configure
# Â - Nice simple interface
# Â - Will log people, places, weapons, armors, and items seperately
# Â - Configurable what type of entries you would like to log.
# Â - Configurable layout
# Â - Option to use pictures
# Â - Fully compatible "stats" you want the system to display.
#
# Instructions:
# Â - Place script in the usual place.
# Â - All configuration is below, and explained in each section.
# Â - All pictures must be in folder labeled "Journal" within your game'sÂ
# Â Â Picture folder.
# Â - All you have to do is assign arbitrary "ids" to each person and location
# Â Â respectively. After you have completed configuration, when you want the
# Â Â person/place to be added to the Journal, use these script calls:
#
# Â Â Â Journal.add_character(ID)
# Â Â Â Journal.add_location(ID)
# Â Â Â Journal.add_weapon(ID)
# Â Â Â Journal.add_armor(ID)
# Â Â Â Journal.add_item(ID)
#
# Â Â Â You can also delete entries in the same way:
#
# Â Â Â Journal.delete_character(id)
# Â Â Â Journal.delete_location(id)
# Â Â Â Journal.delete_weapon(id)
# Â Â Â Journal.delete_armor(id)
# Â Â Â Journal.delete_item(id)
#
# Â Â Where the "ID" is the number you assigned to each.
# Â - To call the scene, use this script call:
#
# Â Â Â $scene = Scene_Journal.new
#
# Â - The script comes with a fix for those who like to use smaller text sizes
# Â Â (like myself), which will allow for more information to be displayed on
# Â Â the screen at once.
# Â - If you would like to change the look up a little bit, just change around
# Â Â the X and Y values in Window_Journal.
#
# Credits/Thanks:
# Â - ForeverZer0, for the script.
#
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
# Â Â Â Â Â Â Â Â Â Â Â Â Â BEGIN CONFIGURATION
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
module Journal
 Â
 # If true, a line height of 20 pixels will be used, which looks better with
 # smaller font sizes.
 SMALL_TEXT = true
 # The width of the entry list used for Scene_Journal. The other windows will
 # automatically adjust to this width.
 LIST_WIDTH = 192
 Â
 # Define what aspects of the journal you would like to use. Choose from the
 # values listed below and add them to the array. DO NOT change the values.
 # Omit values for types you do not want to use.
 #     'People' - 'Places' - 'Weapons' - 'Armors' - 'Items'
 LIST_ORDER = ['People', 'Places', 'Weapons', 'Armors', 'Items']
 Â
 # Configure if you would like for items, weapons, and armors to be unlocked
 # automatically when they are first aquired by the player. If using this
 # options, IDs MUST match the IDs used in the Database. You will also need to
 # manually add anything the player begins with at game start.
 AUTO_WEAPONS = true
 AUTO_ARMORS = true
 AUTO_ITEMS = true
 Â
#-------------------------------------------------------------------------------
 CHARACTER_STATS = ['Name:', 'Race:', 'Age:', 'Height:', 'Weight:']
 Â
 # Configure the values used for the above array for each character. Just make
 # sure the value that corresponds to each stat is at the same index in the [].
 # Just make sure that the first stat is the name, it will be used on the menu
 # to select which character/location will be viewed.
 def self.character_info(id)
  info = case id
  when 1 then ['Aluxes', 'Human', '19', '5\'10"', '165 lbs.']
  when 2 then ['Hilda', 'Human', '20', '5\'5"', '113']
  when 3 then ['Basil', 'Human', '24', '6\'0"', '187 lbs.']
  end
  return info != nil ? info : []
 end
 Â
 # Short paragraph/description of character. Uses Blizzard's slice_text method
 # to automatically break to next line when needed, so do not concern yourself
 # with that.
 def self.character_bio(id)
  text = case id
  when 1
   'Our everyday hero, that seems to make an appearance in every demo.'
  when 2
   'Random witch girl.'
  when 3
   'Another RPGXP character.'
  end
  return text != nil ? text : ''
 end
#-------------------------------------------------------------------------------
 LOCATION_STATS = ['Name:', 'Country:']
 Â
 # Configure the values used for the above array for each location. Just make
 # sure the value that corresponds to each stat is at the same index in the [].
 # Just make sure that the first stat is the name, it will be used on the menu
 # to select which character/location will be viewed.
 def self.location_info(id)
  info = case id
  when 1 then ['New York', 'USA']
  when 2 then ['Ohio', 'USA']
  when 3 then ['Iowa', 'Who cares...']
  end
  return info != nil ? info : []
 end
 Â
 # Short paragraph/description of location. Uses Blizzard's slice_text method
 # to automatically break to next line when needed, so do not concern yourself
 # with that.
 def self.location_bio(id)
  return case id
  when 1
   'The state north of Pennsylvania.'
  when 2
   'The state west of Pennsylvania.'
  when 3
   'A boring state.'
  else
   ''
  end
 end
#-------------------------------------------------------------------------------
 WEAPON_STATS = ['Name:', 'Origin:']
  Â
 def self.weapon_info(id)
  text = case id
  when 1 then ['Bronze Sword', 'Everywhere.']
  when 2 then ['Iron Sword', 'Right here.']
  when 3 then ['Mythril Sword', 'Blah blah.']
  end
 end
 Â
 def self.weapon_bio(id)
  return case id
  when 1Â
   'Simple sword. Seems to be the standard that all RPG games have the hero start with.'
  when 2
   'Slighly better than the Bronze sword.'
  when 3
   'Yet another sword that is in almost every RPG.'
  else
   ''
  end
 end
#-------------------------------------------------------------------------------
 ARMOR_STATS = ['Name:', 'Origin:']
  Â
 def self.armor_info(id)
  text = case id
  when 1 then ['', '']
  when 2 then ['', '']
  when 3 then ['', '']
  end
 end
 Â
 def self.armor_bio(id)
  return case id
  when 1Â
   ''
  when 2
   ''
  when 3
   ''
  else
   ''
  end
 end
#-------------------------------------------------------------------------------
 ITEM_STATS = ['Name:', 'Origin:']
 Â
 def self.item_info(id)
  text = case id
  when 1 then ['', '']
  when 2 then ['', '']
  when 3 then ['', '']
  end
 end
 Â
 def self.item_bio(id)
  return case id
  when 1Â
   ''
  when 2
   ''
  when 3
   ''
  else
   ''
  end
 end
#-------------------------------------------------------------------------------
 # Set the following to true if you would loke pictures to be displayed for
 # the respective type of Journal entries. They will be defined below.
 CHARACTER_PIC = true
 LOCATION_PIC = true
 WEAPON_PIC = true
 ARMOR_PIC = true
 ITEM_PIC = true
 Â
 # Filenames of character pictures.Â
 def self.character_pic(id)
  file = case id
  when 1 then 'Aluxes'
  when 2 then 'Hilda'
  when 3 then 'Basil'
  end
  return file != nil ? RPG::Cache.picture("Journal/#{file}") : Bitmap.new(1,1)
 end
 Â
 # Filenames of location pictures.Â
 def self.location_pic(id)
  file = case id
  when 1 then ''
  when 2 then ''
  when 3 then ''
  end
  return file != nil ? RPG::Cache.picture("Journal/#{file}") : Bitmap.new(1,1)
 end  Â
 Â
 # Filename of weapon pictures.Â
 def self.weapon_pic(id)
  file = case id
  when 1 then ''
  when 2 then ''
  when 3 then ''
  end
  return file != nil ? RPG::Cache.picture("Journal/#{file}") : Bitmap.new(1,1)
 end
 Â
 # Filename of weapon pictures.Â
 def self.armor_pic(id)
  file = case id
  when 1 then ''
  when 2 then ''
  when 3 then ''
  end
  return file != nil ? RPG::Cache.picture("Journal/#{file}") : Bitmap.new(1,1)
 end
 # Filenames of item pictures.Â
 def self.item_pic(id)
  file = case id
  when 1 then ''
  when 2 then ''
  when 3 then ''
  end
  return file != nil ? RPG::Cache.picture("Journal/#{file}") : Bitmap.new(1,1)
 end
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
# Â Â Â Â Â Â Â Â Â Â Â Â Â END CONFIGURATION
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 def self.add_character(id)
  unless $game_system.journal['People'].include?(id)
   $game_system.journal['People'].push(id)
   $game_system.journal['People'].sort!
  end
 end
 Â
 def self.add_location(id)
  unless $game_system.journal['Places'].include?(id)
   $game_system.journal['Places'].push(id)
   $game_system.journal['Places'].sort!
  end
 end
 Â
 def self.add_weapon(id)
  unless $game_system.journal['Weapons'].include?(id)Â
   $game_system.journal['Weapons'].push(id)
   $game_system.journal['Weapons'].sort!
  end
 end
 Â
 def self.add_armor(id)
  unless $game_system.journal['Armors'].include?(id)Â
   $game_system.journal['Armors'].push(id)
   $game_system.journal['Armors'].sort!
  end
 end
 Â
 def self.add_item(id)
  unless $game_system.journal['Items'].include?(id)Â
   $game_system.journal['Items'].push(id)
   $game_system.journal['Items'].sort!
  end
 end
 def self.delete_character(id)
  $game_system.journal['People'].delete(id)
  $game_system.journal['People'].sort!
 end
 Â
 def self.delete_location(id)
  $game_system.journal['Places'].delete(id)
  $game_system.journal['Places'].sort!
 end
 Â
 def self.delete_weapon(id)
  $game_system.journal['Weapons'].delete(id)
  $game_system.journal['Weapons'].sort!
 end
 Â
 def self.delete_armor(id)
  $game_system.journal['Armors'].delete(id)
  $game_system.journal['Armors'].sort!
 end
 Â
 def self.delete_item(id)
  $game_system.journal['Items'].delete(id)
  $game_system.journal['Items'].sort!
 end
end
#===============================================================================
# ** Game_System
#===============================================================================
class Game_System
 Â
 attr_accessor :journal
 Â
 alias zer0_journal_init initialize
 def initialize
  zer0_journal_init
  @journal = {}
  Journal::LIST_ORDER.each {|key| @journal[key] = [] }
 end
 Â
 def journal_entries(type)
  entries = []
  case type
  when 'People'
   @journal[type].each {|id| entries.push(Journal.character_info(id)[0]) }
  when 'Places'
   @journal[type].each {|id| entries.push(Journal.location_info(id)[0]) }
  when 'Weapons'
   @journal[type].each {|id| entries.push(Journal.weapon_info(id)[0]) }
  when 'Armors'
   @journal[type].each {|id| entries.push(Journal.armor_info(id)[0]) }
  when 'Items'
   @journal[type].each {|id| entries.push(Journal.item_info(id)[0]) }
  end
  return entries.empty? ? ['None'] : entries
 end
end
#===============================================================================
# ** Game_Party
#===============================================================================
class Game_Party
 Â
 alias zer0_auto_add_weapon gain_weapon
 def gain_weapon(weapon_id, n)
  # Unlock weapon ID if recieved.Â
  if Journal::AUTO_WEAPONS& ![nil, 0].include?(weapon_id)
   Journal.add_weapon(weapon_id)Â
  end
  zer0_auto_add_weapon(weapon_id, n)
 end
 alias zer0_auto_add_armor gain_armor
 def gain_armor(armor_id, n)
  # Unlock armor ID if recieved.Â
  if Journal::AUTO_ARMORS && ![nil, 0].include?(armor_id)
   Journal.add_armor(armor_id)Â
  end
  zer0_auto_add_armor(armor_id, n)
 end
 Â
 alias zer0_auto_add_item gain_item
 def gain_item(item_id, n)
  # Unlock item ID if recieved.Â
   if Journal::AUTO_ITEMS && ![nil, 0].include?(item_id)
   Journal.add_item(item_id)
  end
  zer0_auto_add_item(item_id, n)
 end
end
#===============================================================================
# ** Bitmap (slice_text method by Blizzard)
#===============================================================================
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}").width > width
   result.push(current_text)
   current_text = words
  else
   current_text = "#{current_text} #{words}"
  end
  result.push(current_text) if i >= words.size - 1}
  return result
 end
end
#===============================================================================
# ** Window_Journal
#===============================================================================
class Window_Journal < Window_Base
 Â
 attr_accessor :typeÂ
 Â
 def initialize
  super(Journal::LIST_WIDTH, 0, 640 - Journal::LIST_WIDTH, 480)
  self.contents = Bitmap.new(width - 32, height - 32)
  self.visible = false
  @type = ''
 end
 Â
 def id=(id)
  @id = id
  refresh
 end
 Â
 def refresh
  self.contents.clear
  return if @id == nil
  # Set local variables, branching by what type is being viewed.
  case @type
  when 'People'
   stats = Journal::CHARACTER_STATS
   info = Journal.character_info(@id)
   bio = Journal.character_bio(@id)
   pic = Journal::CHARACTER_PIC ? Journal.character_pic(@id) : nil
  when 'Places'
   stats = Journal::LOCATION_STATS
   info = Journal.location_info(@id)
   bio = Journal.location_bio(@id)
   pic = Journal::LOCATION_PIC ? Journal.location_pic(@id) : nil
  when 'Weapons'
   stats = Journal::WEAPON_STATS
   info = Journal.weapon_info(@id)
   bio = Journal.weapon_bio(@id)
   pic = Journal::WEAPON_PIC ? Journal.weapon_pic(@id) : nil
  when 'Armors'
   stats = Journal::ARMOR_STATS
   info = Journal.armor_info(@id)
   bio = Journal.armor_bio(@id)
   pic = Journal::ARMOR_PIC ? Journal.armor_pic(@id) : nil
  when 'Items'
   stats = Journal::ITEM_STATS
   info = Journal.item_info(@id)
   bio = Journal.item_bio(@id)
   pic = Journal::ITEM_PIC ? Journal.item_pic(@id) : nil
  end
  width = 640 - Journal::LIST_WIDTH - 40
  bio = self.contents.slice_text(bio, width)
  if pic != nil
   rect = Rect.new(0, 0, pic.width, pic.height)
   self.contents.blt(self.width-pic.width-64, 32, pic, rect)
  end
  # Draw the values on the window's bitmap.
  self.contents.font.color = system_color
  y = Journal::SMALL_TEXT ? 20 : 32
  stats.each_index {|i| self.contents.draw_text(0, i*(y*2), 128, y, stats)}
  self.contents.draw_text(0, 320, 128, y, 'Description:')
  self.contents.font.color = normal_color
  info.each_index {|i| self.contents.draw_text(8, y+i*(y*2), 128, y, info)}
  bio.each_index {|i| self.contents.draw_text(8, (320+y)+i*y, width, y, bio)} Â
 end
end
#===============================================================================
# ** Scene_Journal
#===============================================================================
class Scene_Journal
#-------------------------------------------------------------------------------
 def main
  # Create lists of the entries for each Journal content type.
  @entry_lists, @index = [], 0
  # Create list of entry titles.
  Journal::LIST_ORDER.each {|key|
   next unless $game_system.journal.has_key?(key)
   window = Window_Command.new(Journal::LIST_WIDTH, $game_system.journal_entries(key))
   window.visible = window.active = false
   window.height = 480
   @entry_lists.push(window)
  }
  # Create main command window.
  @command_window = Window_Command.new(Journal::LIST_WIDTH, Journal::LIST_ORDER)
  @command_window.height = 480
  # Create main window for viewing information and dummy window.
  @dummy_window = Window_Base.new(Journal::LIST_WIDTH, 0, 640 - Journal::LIST_WIDTH, 480)
  @journal_window = Window_Journal.new
  @windows = @entry_lists + [@journal_window, @command_window, @dummy_window]
  # Transition and start main loop for the scene.
  Graphics.transition
  loop {Graphics.update; Input.update; update; break if $scene != self}
  # Dispose all windows and prepare for transition.
  Graphics.freeze
  @windows.each {|window| window.dispose}
 end
#-------------------------------------------------------------------------------
 def update
  # Update all the windows.
  @windows.each {|window| window.update }
  # Branch update method depending on what window is active.
  @command_window.active ? update_command : update_entry_selection
 end
#-------------------------------------------------------------------------------
 def update_command
  if Input.trigger?(Input::
   $game_system.se_play($data_system.cancel_se)
   $scene = Scene_Map.new
  elsif Input.trigger?(Input::C)
   # Deactivate command window and make selected entry list active.
   @index = @command_window.index
   @command_window.active = @command_window.visible = false
   @entry_lists[@index].active = @entry_lists[@index].visible = true
  end
 end
#-------------------------------------------------------------------------------
 def update_entry_selection
  if Input.trigger?(Input::
   $game_system.se_play($data_system.cancel_se)
   # Deactivate entry list and make command window active.
   @command_window.active = @command_window.visible = true
   @entry_lists[@index].active = @entry_lists[@index].visible = false
   @journal_window.visible = false
  elsif Input.trigger?(Input::C)
   @journal_window.visible = true
   $game_system.se_play($data_system.decision_se)
   type = Journal::LIST_ORDER[@index]
   # Set the type and id variables for the journal window and refresh.
   @journal_window.type = type
   @journal_window.id = $game_system.journal[type][@entry_lists[@index].index]
  end
 end
end