#==============================================================================
# ** Team Scriptastic's Script Console                           [RPG Maker VX]
#    Version 1.20
#------------------------------------------------------------------------------
#  This script adds an in-game script console that allows for on-the-fly script
#  entry and debugging.
#  Requires :
#  -  Aleworks Library
#  -  Aleworks Input Module
#  -  Aleworks Keyboard Module
#  -  Aleworks Write Line
#==============================================================================
# * Version History
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#   Version 1.00 ------------------------------------------------- (2009-07-??)
#     - Initial Version
#     - Author: theory
#   Version 1.10 ------------------------------------------------- (2009-07-??)
#     - Added History
#     - Improved Layout
#     - Author: Ulqiorra (Near)
#    Version 1.20 ------------------------------------------------ (2009-08-15)
#      - Cleaned code
#      - Converted to work with VX
#      - Author: Glitchfinder
#==============================================================================
# * Instructions
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#  Place this script above Main, and below the default scripts. (I realize this
#  is obvious to most, but some people don't get it.)
#
#  Simply press the tilde key (~) , located above Tab and below Esc on most US
#  keyboards, to open the script console.  From here, you can type any script
#  command to test it.  A technical note, you start at Kernal, for heiarchy.
#  A good knowledge of RGSS2 is expected to get the most of this utility.
#  You can call methods by their relative globals.
#
#  Note that this is a utility script for scripters (or advanced script users).
#  If you do not understand what this script does, it is probably not intended
#  for you at this point, nor would you find it useful.
#==============================================================================
# * Method List
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#  This script is plug 'n play. Therefore, no knowledge of methods is required.
#==============================================================================
# * Special Thanks
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#  Special thanks goes to Aleworks for their amazing work with the Write Line
#  script, which is the cornerstone that made this in-game script console
#  possible to develop to a releasable state.
#==============================================================================
# * Contact
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#  Glitchfinder, one of the authors of this script, may be contacted through
#  his website, found at http://www.glitchkey.com
#
#  You may also find Glitchfinder at http://www.hbgames.org
#==============================================================================
# * Usage
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#  This script may be used with the following terms and conditions:
#
#    1. This script is free to use in any noncommercial project. If you wish to
#       use this script in a commercial (paid) project, please contact
#       Glitchfinder at his website.
#    2. This script may only be hosted at the following domains:
#         http://www.glitchkey.com
#         http://www.hbgames.org
#    3. If you wish to host this script elsewhere, please contact Glitchfinder.
#    4. If you wish to translate this script, please contact Glitchfinder. He
#       will need the web address that you plan to host the script at, as well
#       as the language this script is being translated to.
#    5. This header must remain intact at all times.
#    6. Glitchfinder remains the sole owner of this code. He may modify or
#       revoke this license at any time, for any reason.
#    7. Any code derived from code within this script is owned by Glitchfinder,
#       and you must have his permission to publish, host, or distribute his
#       code.
#    8. This license applies to all code derived from the code within this
#       script.
#    9. If you use this script within your project, you must include visible
#       credit to Glitchfinder, theory, and Ulqiorra, within reason.
#
#  Note that this script utilizes the foundation set by Aleworks.  Their script
#  does not specify clear terms of service, but it is suggested that you
#  contact them regarding specifics for terms of use pertaining to their script.
#
#  Aleworks' scripts contain additional credits to third parties.  While this
#  is more of a development tool than an item intended for commercial
#  application, it is advised to do a bit of homework regarding applicable
#  license information before using this script for commercial purposes.
#==============================================================================
 
#==============================================================================
# ** Window_History
#------------------------------------------------------------------------------
#  This window displays the code input history for the Script Console.
#==============================================================================
 
class Window_History < Window_Base
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     x      : window x-coordinate
  #     y      : window y-coordinate
  #--------------------------------------------------------------------------
  def initialize(x = 4, y = 48)
    super(x, y, 544, 346)
    @history = []
    @need_refresh = true
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    for i in 0...12
      if ! @history[i].nil?
        y = 24 * (12 - i)
        self.contents.draw_text(0, y, 544, 24, @history[i])
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    if @need_refresh
      refresh
      @need_refresh = false
    end
    super
  end
  #--------------------------------------------------------------------------
  # * Add Line
  #--------------------------------------------------------------------------
  def add_line(code)
    @history = @history.insert(-1, code)
    until @history.size <= 15
      @history.delete_at(@history.size - 1)
    end
    @need_refresh = true
  end
  #--------------------------------------------------------------------------
  # * Return Last Line
  #--------------------------------------------------------------------------
  def last_line
    return @history[0]
  end
  #--------------------------------------------------------------------------
  # * Memorize History
  #--------------------------------------------------------------------------
  def memorize
    Memory.filling = @history
  end
  #--------------------------------------------------------------------------
  # * Restore History
  #--------------------------------------------------------------------------
  def restore
    @history = Memory.filling
  end
end
 
#==============================================================================
# ** Memory
#------------------------------------------------------------------------------
#  This module is used to keep track of the Script Console code history
#  between different scenes.
#==============================================================================
 
module Memory
  @filling = nil
  #--------------------------------------------------------------------------
  # * Return Memorized History
  #--------------------------------------------------------------------------
  def self.filling
    return @filling
  end
  #--------------------------------------------------------------------------
  # * Set Memorized History
  #--------------------------------------------------------------------------
  def self.filling=(f)
    @filling = f
    return @filling
  end
  #--------------------------------------------------------------------------
  # * Add Line
  #--------------------------------------------------------------------------
  def self.full?
    return ! @filling.nil?
  end
end
 
 
##==============================================================================
# ** Scene_Base
#------------------------------------------------------------------------------
#  This is a superclass of all scenes in the game.
#==============================================================================
 
class Scene_Base
  #--------------------------------------------------------------------------
  # * Alias Methods
  #--------------------------------------------------------------------------
  alias scriptastic_script_console_scene_base_update update
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    # Call original method
    scriptastic_script_console_scene_base_update
    # If in debug mode and the ~ key is pressed
    if Input.trigger?(Keys::OEM_7) && $TEST && ! $scene.is_a?(Scene_Console)
      # Store old Scene
      $old_scene = $scene.clone
      # Activate console
      $scene = Scene_Console.new
    end
  end
end
 
#=============================================================================
# ** Scene_Console
#=============================================================================
#  This class performs code input processing in Debug mode.
#=============================================================================
 
Input::REPEAT_TIME = 3
 
class Scene_Console < Scene_Base
  #--------------------------------------------------------------------------
  # * Start processing
  #--------------------------------------------------------------------------
  def start
    super
    create_input_window
    display_instructions
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    @window_write.update
    @history.update
    if Input.trigger?(Keys::OEM_7)
      Sound.play_cancel
      @history.memorize
      $scene = $old_scene
    elsif Input.trigger?(Keys::RETURN)
      @console_entry = @window_write.write.pwrited
      @history.add_line(@console_entry)
      @error = "@window_write.write.clear"
      Kernel.eval(@console_entry) rescue @error
      @window_write.write.clear
      @window_write.write.update
    elsif Input.trigger?(Keys::F5)
      if @window_write.show_chr == '*'
        @window_write.show_chr = nil
      else
        @window_write.show_chr = '*'
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Termination Processing
  #--------------------------------------------------------------------------
  def terminate
    dispose_input_window
    dispose_instructions
  end
  #--------------------------------------------------------------------------
  # * Create Input Window
  #--------------------------------------------------------------------------
  def create_input_window
    @window_write = Window_AWrite.new(0, 416 - 54, 500, 54)
    @window_write.write.max_pixel_width = 468
    @window_write.opacity = 0
    font = Font.new
    font.name = "Courier New"
    @window_write.write.font = font
    @history = Window_History.new
    @history.restore if Memory.full?
    @history.opacity = 0
  end
  #--------------------------------------------------------------------------
  # * Dispose Input Window
  #--------------------------------------------------------------------------
  def dispose_input_window
    @window_write.dispose
    @history.dispose
  end
  #--------------------------------------------------------------------------
  # * Display Instructions
  #--------------------------------------------------------------------------
  def display_instructions
    @indications = Sprite.new
    @indications.y = 24
    @indications.bitmap = Bitmap.new(544, 24)
    @indications.bitmap.font.size = 12
    @indications.bitmap.font.bold = true
    @indications.bitmap.font.name = 'Courier New'
    w = ['Enter script command: (Press F5 to mask text)']
    @indications.bitmap.draw_text(0, 0, 544, nil, w, 1)
  end
  #--------------------------------------------------------------------------
  # * Dispose Instructions
  #--------------------------------------------------------------------------
  def dispose_instructions
    @indications.dispose
  end
end