[C#] RPG Maker ScriptEditor Development Thread

Started by ForeverZer0, August 24, 2011, 01:53:27 am

Previous topic - Next topic

Ryex

hey, F0. do you think that you could tackle the script editor control for ARC? you've already worked with the concepts here so I think you could do it faster than me.
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

ForeverZer0

I'll give it a go.  I'm getting pretty familiar with ScintillaNET, which is just a wrapper for SciLexer, so hopefully it won't be to difficult to apply what I know to Python, though I admit I am still a little inexperienced with Python.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Ryex

there is a wxPython text control that uses scintilla it already highlights ruby ect. you can probably use that as a base.
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

AngryPacman

The shortcut for Open brings up the Import Script selection.
G_G's a silly boy.

ForeverZer0

Here's some things I got done tonight (sorry, no new upload):

  • Window size/location memory

  • Character map can be called with a click for inserting Unicode characters

  • Autocomplete has been disabled for comments

  • Autocomplete drops words with Ctrl (Just for you, GG  <3

  • Added configuration for minimum number of characters of current word before autocomplete enables

  • Enhanced context menu for the script editor

  • Fixed Find/Replace issue for opening multiple find windows

  • Split the Find/Replace button into two separate buttons

  • Added "Project Open" to main toolbar, as well as rename the original button to "Import"

  • Fixed a bug that occurred when trying to remove multiple work groups from the autocomplete list at one time.  It would only work when a single group was chosen to remove



Here are some other ideas I have and/or started working on:

  • Code analysis for quick syntax checking without need to run game or save (This is proving a bit problematic at the moment since the scripts are not ran from a file, it is difficult to get the proper stack trace for the Exception, though it is finding the errors)

  • A "Surround With..." function for placing selected code within various blocks

  • Found some various minor bugs with auto-indentation to work out

  • Begin formulating a loose idea for a snippet manager. Actually shouldn't be too difficult

I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

G_G

Snippet manager would be great. It'd be really awesome if some of the same features could get implemented into ARC. Speaking of which *walks away to start on editor* Anyways nice job F0.

LivingstoneIPresume

First of all, this is awesome. Second, I have a suggestion.
Would it be possible to highlight undefined methods? I always mispell or miscapitalize my methods, and it would be nice to know which ones don't exist. I don't know C# at all, so I have no idea how difficult this would be.

ForeverZer0

That's not really a matter of C#, but of Ruby.  That is pretty difficult to implement in a simple IDE created by an amateur.  You find that sort of a thing in Visual Studio and other large design programs.  It requires the data to be constantly scrutinized by the interpreter, catch the exceptions, determine what exactly the real issue is, and alert the user accordingly.  What makes this even harder in a scripted language is that the functions are not all defined ahead of time, but interpreted on the fly at runtime. This means the script would constantly be having to be "running" in the background, which it can't do for RPG Maker games, since there are a lot of classes defined by the game engine, that I won't be creating for this.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

LivingstoneIPresume

I just meant that it would look for lines that start with 'def' and find all the methods after them, and then check that with a list of methods that you call.
For example, it would see this script:
Init.new
Run.new(45, 1, 3)
Gow.new(3, 6)
def Init
do stuff
end
def Run(x, y, z, a)
do stuff
end
def Go(x, y)
do stuff
end

And highlight the method "Gow" because it doesn't exist, along with maybe checking for the number of arguments after "Run" and highlighting that.
If this is what you were thinking, that's fine, but I feel like what you said was a bit more complicated.

ForeverZer0

The actual check is simple. Its a matter of the interpreter always running in the background checking for this, and keeping track of things. If were as simple as you just stated, I would have implemented it already.  Its not, though.  You need to have "live code" in order for this to work in any intelligent manner, and I'm not gonna attempt to implement that.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

ForeverZer0

Woot, woot!  Just finished a "line normalize" function.  It structures your code according to Ruby conventions with the click of a single button. For example, say you have this script:

Spoiler: ShowHide
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
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[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_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[i])}
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[i])}
bio.each_index {|i| self.contents.draw_text(8, (320+y)+i*y, width, y, bio[i])} 
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::B)
$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::B)
$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


You then click the button, and the script converts to this:
Spoiler: ShowHide
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
# Journal
# Author: ForeverZer0
# Version: 2.3
# 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)
#
#     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
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[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_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[i])}
    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[i])}
    bio.each_index {|i| self.contents.draw_text(8, (320+y)+i*y, width, y, bio[i])} 
  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::B)
      $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::B)
      $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
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

G_G


ForeverZer0

Alrighty, the newest build is uploaded, check the original link in the first post.  I still need to prettify it with better icons for the toolbar and application, but it is nearing completion right now. The auto-indent is has been improved a lot for this build.  I think I am finally about happy with it.  I still may attempt the "code analysis" feature for syntax checking.  It may get scrapped depending on the amount of pain in the ass it turns into considering it is only saving the user a second by not play-testing, although it would allow for it to be tested without saving first...
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.