Chaos Project

RPG Maker => RPG Maker Scripts => Script Troubleshooting => Topic started by: Xim on December 24, 2014, 12:54:24 pm

Title: [RMXP] Modifying/fixing Scrolling Message System EX
Post by: Xim on December 24, 2014, 12:54:24 pm
Hi, I'm using Scrolling Message System EX for my game. I've tried a few other message systems but they don't work for some reason but this one seem to work better than most. I asked the author for help but he was understandably busy but he gave me permission to ask for help over here.

#==============================================================
# ** Scrolling Message System EX
#------------------------------------------------------------------------------
# Slipknot (http://www.creationasylum.net/)
# Version 1.2x (edited by LiTTleDRAgo)
# May 13, 2007
#==============================================================
# Features
#
# Default in RTP
#
# Color: \c[ID]
# Actor Name: \n[ActorID]
# Show Gold Window: \g
# Variable: \v[ID]
# -
# Default in SMS
#
# Letter by Letter: the characters are drawed one by one.
# Scrolling: the text lines are scrolled, the time of this can be changed.
# Stop: the message window can be stopped until the player press a key. \!
# Autoclose: the message will close without the player input. \%
# Choices: the choices are showed in a different window, they are also scrolled
#           when are more than two.
# The choice window is shown inside the window like Default Message System
# Height: The height of lines can be changed, everything is adjusted to this.
# Above Events: You can draw the window above an event. \p[event]
# Bold and Italic: \b and \i
# Face: A small graphic is shown inside the message \face[file]
# Name Box: Text is shown in a small window above message \name[text]
# -
# Added Features in EX Version
#
# Furigana: Insert small text above a sentence \r[sentence,furigana]
# Font change: Change the font name or font size
#    1. \font[fontname] Change the font name
#    2. \font[fontsize] Change the font size (Integer)
#    3. \font[fontname,fontsize]  Change both the font name or font size
# Conditional Text: Show the text if condition is met (for advanced user
#    1. \if[condition,text] Will show the text if condition is met
#                           (else nothing shown)
#    2. \unless[condition,text] Will show the text if condition is not met
#                               (else nothing shown)
# Game Related: Show Information related to the game
#    1. display name of current map \map
#    2. display name of item, weapon, armor or skill
#        2a. \N[In] = display name of item with id n (note the "I")
#        2b. \N[Wn] = display name of weapon with id n (note the "W")
#        2c. \N[An] = display name of armor with id n (note the "A")
#        2d. \N[Sn] = display name of skill with id n (note the "S")
#        2e. \N[En] = display name of enemies with id n (note the "E")
#        2f. \N[Pn] = display name of event with id n (note the "P")
#    3. display icon of item, weapon, armor or skill
#        3a. \I[In] = display icon of item with id n (note the "I")
#        3b. \I[Wn] = display icon of weapon with id n (note the "W")
#        3c. \I[An] = display icon of armor with id n (note the "A")
#        3d. \I[Sn] = display icon of skill with id n (note the "S")
#    4. display icon and name of item, weapon, armor or skill
#        4a. \I&N[In] = display icon and name of item with id n (note the "I")
#        4b. \I&N[Wn] = display icon and name of weapon with id n (note the "W")
#        4c. \I&N[An] = display icon and name of armor with id n (note the "A")
#        4d. \I&N[Sn] = display icon and name of skill with id n (note the "S)

$scrolling_message_system = true

module Message
  #--------------------------------------------------------------------------
  # * Settings
  #--------------------------------------------------------------------------
  # ~ Font
  FontName = Font.default_name
  FontSize = Font.default_size
  # ~ Size
  Width = 520
  Height = 32
  # ~ Delay
  TextDelay = 1
  Scroll = 30
  Autoclose = 16
  #--------------------------------------------------------------------------
  # * Font
  #--------------------------------------------------------------------------
  def self.font
    Font.new(FontName, FontSize)
  end
end

if $scrolling_message_system

class Game_Temp
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :input_type
end



class Interpreter
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias slipknot_sms_command_101 command_101
  alias slipknot_sms_command_102 command_102
  alias slipknot_sms_command_103 command_103
  #--------------------------------------------------------------------------
  # * Show Text
  #--------------------------------------------------------------------------
  def command_101
    if false
      return slipknot_sms_command_101
    end
    return false if (temp = $game_temp).message_text
    @message_waiting = true
    temp.message_proc = Proc.new { @message_waiting = false }
    temp.message_text = @list.at(@index).parameters.at(0) + "\n"
    loop do
      com = @list.at(@index + 1)
      if com.code == 401 || com.code == 101
        temp.message_text += com.parameters.at(0) + "\n"
      else
        if com.code == 102
          temp.message_text += "\n\n"
          slipknot_sms_set_choice(com.parameters)
          current_indent = com.indent
          temp.choice_proc = Proc.new { |n| @branch[current_indent] = n }
          @index += 1
        elsif com.code == 103
          @index += 1
          temp.message_text += "\n"
          slipknot_sms_set_inputnumber(com.parameters)
        end
        return true
      end
      @index += 1
    end
  end
  #--------------------------------------------------------------------------
  # * slipknot_sms_set_choice
  #--------------------------------------------------------------------------
  def slipknot_sms_set_choice(parameters)
    if !$choice.nil? && $choice.is_a?(Array)
      parameters[0] = $choice
    end
    $game_temp.choice_max = parameters.at(0).size
    $game_temp.instance_variable_set(:@mes_choices, parameters.at(0))
    $game_temp.choice_cancel_type = parameters.at(1)
  end
  #--------------------------------------------------------------------------
  # * slipknot_sms_set_inputnumber
  #--------------------------------------------------------------------------
  def slipknot_sms_set_inputnumber(parameters)
    $game_temp.num_input_variable_id = parameters.at(0)
    $game_temp.num_input_digits_max = parameters.at(1)
  end
  #--------------------------------------------------------------------------
  # * Show Choices
  #--------------------------------------------------------------------------
  def command_102()  end
  #--------------------------------------------------------------------------
  # * Input Number
  #--------------------------------------------------------------------------
  def command_103()  end
end


class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias slipknot_sms_init initialize
  alias slipknot_sms_refresh refresh
  alias slipknot_sms_update update
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize
    slipknot_sms_init
    @original_height = self.height
    @row_max = 4
    self.height = Message::Height * @row_max + 32
    self.back_opacity = 160
    self.windowskin = windowskin.clone
    self.windowskin.fill_rect(144, 16, 32, 32, Color.new(0, 0, 0, 0))
    @ey = 1.0
    @y = 0
  end
  #--------------------------------------------------------------------------
  # * Opacity
  #--------------------------------------------------------------------------
  def opacity=(val)
    super
    @choices.opacity = val if @choices
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    contents.clear
    contents.font = Message.font
    self.height = Message::Height * @row_max + 32
    @x = @y = @ex = @ey = 0
    return if ! (@text = (temp = $game_temp).message_text)
    replace_code
    gold_win |= @text.gsub!(/\\[Gg]/, '')
    if fit |= @text[/\\[Pp]/]
      if @text.sub!(/\\[Pp]\[([-1,-2,-3,-4,0-9]+)\]/, '')
        @event = $1.to_i
        self.height = Message::Height * 2 + 32
      elsif @text.gsub!(/\\[Pp]/, '')
        @event = ev_ac
        self.height = Message::Height * 2 + 32
      end
    end
    lines_size = [0]
    save, @lines = @text.clone, 0
    while @c = @text.slice!(/./m)
      if @c == "\n"
        @lines += 1
        lines_size << 0
        next
      end
      lines_size[@lines] += eval_text(self.contents, true)
    end
    if temp.choice_max > 0
      @c_data = [Bitmap.new(640 - Message::Width/4, Message::Height *
        temp.choice_max), Array.new(temp.choice_max, 0)]
      @c_data.at(0).font = Message.font
      mes_choices = temp.instance_variable_get(:@mes_choices)||['']
      @cond = mes_choices.collect {|s| s.is_a?(Array) ? s[1] : nil }
      @text = mes_choices.collect {|s| s.is_a?(Array) ? s[0] : s }
      @text.each_with_index {|s,i|
        if !@cond.nil? && !@cond[i].nil? && !@cond[i] &&
          mes_choices[i].is_a?(Array) && mes_choices[i][2]
          @text[i] = mes_choices[i][2]
        end}
      @text = @text.join("\n")
      replace_basic_code
      @y = 0
      while @c = @text.slice!(/./m)
        @c_data.at(0).font.color.alpha=!@cond[@y].nil?&&!@cond[@y] ? 100 : 255
        @c_data.at(1)[@y] += eval_text(@c_data.at(0))
      end
      @c_data[1] = @c_data.at(1).max + 8
      @x = @y = 0
    end
    @text = save
    twidth = temp.choice_max > 0 ? @c_data.at(1) + 32 : 0
    #self.width = fit ? lines_size.max + 40 + @ex : Message::Width - twidth
    self.width = [lines_size.max,twidth].max + 40 + @ex if @event
    self.width = Message::Width if !@event
    twidth += self.width
    self.contents = Bitmap.new(self.width - 32, @lines * Message::Height)
    contents.font = Message.font
    if !@event #|| in_battle?
      h2 = self.height / 2
      self.y = in_battle? ? 96 - h2 :
        case $game_system.message_position
        when 0 then 96 - h2
        when 1 then 240 - h2
        when 2 then 384 - h2
        end
      self.x = 320 - self.width / 2
    else
      if in_battle?
        if @event > 0
          spr = spriteset.instance_variable_get(:@enemy_sprites)[@event-1]
        elsif @event < 0
          spr = spriteset.instance_variable_get(:actor_sprites)[(-@event)-1]
        end
        return terminate_message if spr == nil
        sprite = spr
        char_height = sprite.height
        char_width = sprite.width
        fx = sprite.x
        fy = sprite.y - char_height/2
      else
        c = @event > 0 ? $game_map.events[@event] : $game_player
        sprite = RPG::Cache.character(c.character_name,0)
        mx, my = 636 - twidth, 476 - self.height
        ch = [sprite.height / 4 + 4, 48].max
        fx = [[c.screen_x - self.width / 2, 4].max, mx].min
        fy = [[c.screen_y - (ch + self.height), 4].max, my].min
      end
      self.x, self.y = fx, fy
      self.x = [[fx,0].max,640-self.width].min
      self.y = [[fy,0].max,480-self.height].min
    end
    self.opacity = $game_system.message_frame == 0 ? 255 : 0
    if gold_win
      @gold_window = Window_Gold.new
      @gold_window.x = 560 - @gold_window.width
      @gold_window.z = self.z
      if in_battle?
        @gold_window.y = 192
      else
        @gold_window.y = self.y >= 128 ? 32 : 384
      end
      @gold_window.opacity = self.opacity
    end
    if temp.choice_max > 0
      row_max = ((self.height - 32) / Message::Height) - 1
      ch = [row_max - 2,0].max
      x = self.x
      y = self.y + Message::Height * ch + 32
      y = self.y + Message::Height if @lines == 3
      y = self.y if @event
      size = 2
      size = 3 if @lines == 3
      @choices = Window_MesChoices.new(x, y, @c_data,size)
      #@choices.x = self.width/2 - @choices.width/2
      @choices.z = self.z
      @choices.back_opacity = 0
      @choices.opacity = 0
      @choices.visible = false
    end
    return
    if temp.choice_max > 0
      @choices = Window_MesChoices.new(self.x + self.width, self.y, @c_data)
      @choices.z = self.z
      @choices.back_opacity = self.back_opacity
    end
  end
  #--------------------------------------------------------------------------
  # * In Battle?
  #--------------------------------------------------------------------------
  def in_battle?
    return false if $scene.is_a?(Scene_Map)
    return true if $scene.is_a?(Scene_Battle)
  end
  #--------------------------------------------------------------------------
  # * Replace Code
  #--------------------------------------------------------------------------
  def replace_code
    replace_basic_code
    @text.gsub!('\!') { "\003" }
    @text.gsub!('\.') { "\004" }
    @text.gsub!(/\\\%\[(\d+)\]/) { "\011[#$1]" }
    @text.gsub!('\%') { "\011" }
    @text.gsub!("\\#\n") { "" }
  end
  def replace_basic_code
    @text.gsub!(/\\\\/) { "\000" }
    @text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
    @text.gsub!('\$') { $game_party.gold.to_s }
    @text.gsub!(/\\[Nn]\[([0-9]+)\]/) do
       $game_actors[$1.to_i] ? $game_actors[$1.to_i].name : ''
    end
    @text.gsub!(/\\[Cc]\[([0-9]+?)\]/) { "\001[#$1]" }
  end
  #--------------------------------------------------------------------------
  # * Evaluate Text
  #--------------------------------------------------------------------------
  def eval_text(bitmap, read = false)
    case @c
    when "\000"
      @c = '\\'
    when "\001"
      @text.sub!(/\[(\d+)\]/, '')
      return 0 if read
      bitmap.font.color = text_color($1.to_i)
      return 0
    when "\002"
      @text.sub!(/\[(.*?)\]/, '')
      return 24 if read
      y = Message::Height * @y
      bitmap.blt(@ex + @x + 4, y, RPG::Cache.icon($1.to_s),Rect.new(0,0,24,24))
      @x += 24
      return 0
    when "\003"
      return 0 if read
      @stop = true
      return 0
    when "\004"
      return 0 if read
      @wait_count += 10
      return 0
    when "\011"
      @text.sub!(/\[(\d+)\]/, '')
      return 0 if read || $game_temp.num_input_variable_id > 0 ||
                  $game_temp.choice_max > 0
      @autoclose = $1 ? $1.to_i : Message::Autoclose
      return 0
    end
    eval_extra(bitmap)
    return 0 if @c == '' || @c == nil
    if @c == "\n"
      @y += 1
      @x = 0
      return 0
    end
    w = bitmap.text_size(@c).width
    unless read
      y1 = Message::Height
      bitmap.draw_text(@ex + @x + 4, y1 * @y, w, Message::Height, @c)
      @x += w
    end
    return w
  end
  def eval_extra(bitmap)  end
  #--------------------------------------------------------------------------
  # * Variables
  #--------------------------------------------------------------------------
  def ev_ac()  interpreter.instance_variable_get(:@event_id)  end
  def spriteset()  $scene.instance_variable_get(:@spriteset) end
  def interpreter()
    return $game_system.map_interpreter    if !in_battle?
    return $game_system.battle_interpreter if in_battle?
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    if @contents_showing
      super
      y1 = ((self.height - 32) / Message::Height) - 1
      scroll = self.oy < (@y - y1) * Message::Height && @y < @lines
      if scroll
        @ey += Message::Height / Message::Scroll.to_f
        ey = @ey - @ey.floor
        self.oy += @ey.floor
        @ey = ey
      end
      if @text
        if Input.trigger?(Input::C) && @stop
          self.pause = @stop = false
          return
        elsif @stop
          return
        elsif @wait_count > 0
          @wait_count -= 1
          return
        end
        @wait_count = 0
        return if scroll
        if (@c = @text.slice!(/./m))
          eval_text(contents)
          if @stop
            self.pause = true
            return
          end
          @wait_count += Input.press?(Input::C) ? 0 : Message::TextDelay
          @wait_count = 0 if Input.press?(Input::CTRL)
        else
          @text = nil
        end
        return if @text || @autoclose != -1
        if $game_temp.num_input_variable_id > 0
          digits_max = $game_temp.num_input_digits_max
          ch = [y1 - 1,0].max
          x = self.x
          y = self.y + Message::Height * ch + 32
          y = self.y + Message::Height * (@lines-2) + 32 if @lines == 3
          if self.height == Message::Height * 2 + 32 || @lines == 2
            y = self.y + Message::Height * 1
          end
          @input_number_window = Window_InputNumber.new(digits_max)
          @input_number_window.number =
             $game_variables[$game_temp.num_input_variable_id]
          @input_number_window.x = x
          @input_number_window.y = y
          @input_number_window.z = self.z + 10
          @y -= 1
          @ey -= 1.0
        end
        @choices.index, @choices.active,@choices.visible = 0,true,true if @choices
        return
      else
        if @autoclose > 0
          @autoclose -= 1
          return
        elsif @autoclose == 0
          terminate_message
          @autoclose = -1
          return
        end
      end
      if @input_number_window
        @input_number_window.update
        if Input.trigger?(Input::C)
          $game_system.se_play($data_system.decision_se)
          $game_variables[$game_temp.num_input_variable_id] =
                       @input_number_window.number
          $game_map.need_refresh = true
          @input_number_window.dispose
          @input_number_window = nil
          terminate_message
        end
        return
      elsif @choices
        @choices.update
      end
      self.pause = true
      if Input.trigger?(Input::B)
        if $game_temp.choice_max > 0 && $game_temp.choice_cancel_type > 0
          result = $game_temp.choice_cancel_type - 1
          if !@cond.nil? && !@cond[result].nil? && !@cond[result]
            $game_system.se_play($data_system.buzzer_se)
            return
          end
          $game_system.se_play($data_system.cancel_se)
          @choices.visible = false
          if !$choice.nil?
            $choice_result = result
            $choice = nil
          end
          $game_temp.choice_proc.call(result)
          terminate_message
        end
      end
      if Input.trigger?(Input::C)
        if $game_temp.choice_max > 0
          result = @choices.index
          if !@cond.nil? && !@cond[result].nil? && !@cond[result]
            $game_system.se_play($data_system.buzzer_se)
            return
          end
          $game_system.se_play($data_system.decision_se)
          @choices.visible = false
          if !$choice.nil?
            $choice_result = result
            $choice = nil
          end
          $game_temp.choice_proc.call(result)
        end
        terminate_message
      end
      return
    end
    if ! @fade_out && $game_temp.message_text
      @contents_showing = $game_temp.message_window_showing = true
      if @choices
        @choices.visible = false
        @choices.dispose
        @choices = nil
      end
      self.oy = 0
      @stop = false
      @autoclose = -1
      refresh
      @wait_count, self.visible = 0.0, true
      return
    end
    return if ! visible
    @fade_out = true
    self.opacity -= 48
    if self.opacity == 0
      self.visible = @fade_out = false
      if @choices
        @choices.visible = false
        @choices.dispose
        @choices = nil
      end
      $game_temp.message_window_showing = false
    end
  end
end


class Window_MesChoices < Window_Selectable
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(x, y, data,size = 2)
    super(x, y, data.at(1) + 32, size * (h = Message::Height) + 32)
    self.back_opacity = 0
    self.opacity = 0
    @size = size
    self.index, self.active, @item_max = -1, false, $game_temp.choice_max
    self.contents = Bitmap.new(data.at(1), @item_max * h)
    contents.blt(0, 0, data.at(0), Rect.new(0, 0, data.at(1), h * @item_max))
  end
  #--------------------------------------------------------------------------
  # * Update Cursor
  #--------------------------------------------------------------------------
  def update_cursor_rect
    if @index < 0
      self.cursor_rect.empty
      return
    end
    self.oy = [[@index, @item_max].min - (@size-1), 0].max * Message::Height
    y = @index * Message::Height - self.oy
    cursor_rect.set(0, y, width - 32, Message::Height)
  end
end


class Window_InputNumber < Window_Base
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(digits_max)
    case $game_temp.input_type
    when nil,"default"
      @character_array = ["0","1","2","3","4","5","6","7","8","9"]
    when "binary"
      @character_array = ["0","1"]
    when "hexa"
      @character_array = ["0","1","2","3","4","5","6","7","8","9",
                          "A","B","C","D","E","F"]
    when "upcase_letters"
      @character_array = ["A","B","C","D","E","F","G","H","I",
                          "J","K","L","M","N","O","P","Q","R","S",
                          "T","U","V","W","X","Y","Z"," "]
    when "lowercase_letters"
      @character_array = ["a","b","c","d","e","f","g","h","i",
                          "j","k","l","m","n","o","p","q","r","s",
                          "t","u","v","w","x","y","z"," "]
    when "all_letters"
      @character_array = ["A","B","C","D","E","F","G","H","I",
                          "J","K","L","M","N","O","P","Q","R","S",
                          "T","U","V","W","X","Y","Z","a","b","c",
                          "d","e","f","g","h","i","j","k","l","m",
                          "n","o","p","q","r","s","t","u","v","w",
                          "x","y","z"," "]
    when "all_characters"
      @character_array = ["A","B","C","D","E","F","G","H","I",
                          "J","K","L","M","N","O","P","Q","R","S",
                          "T","U","V","W","X","Y","Z","a","b","c",
                          "d","e","f","g","h","i","j","k","l","m",
                          "n","o","p","q","r","s","t","u","v","w",
                          "x","y","z","0","1","2","3","4","5","6",
                          "7","8","9","+","-","*","/","!","#","$",
                          "%","&","@",".",",","-"," "]
    # when...
    end
    @digits_max = digits_max
    @type = $game_temp.input_type || "default"
    $game_temp.input_type = @type
    @letter_array = []
    @digits_max.times{@letter_array.push(0)}
    dummy_bitmap = Bitmap.new(32, 32)
   
    @cursor_width = 8
    for i in 0...@character_array.size
      letter_size = dummy_bitmap.text_size(@character_array[i]).width + 8
      @cursor_width = [@cursor_width, letter_size].max
    end
    dummy_bitmap.dispose
    super(0, 0, @cursor_width * @digits_max + 32+ 4, Message::Height+32)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.z += 9999
    self.opacity = 0
    @index = 0
    refresh
    update_cursor_rect
  end

  def letter(index)
    return @character_array[@letter_array[index]]
  end

  def increase_letter_array(index)
    if @letter_array[index] == (@character_array.size-1)
      @letter_array[index] = 0
    else
      @letter_array[index] += 1
    end
  end

  def decrease_letter_array(index)
    if @letter_array[index] == 0
      @letter_array[index] = (@character_array.size-1)
    else
      @letter_array[index] -= 1
    end
  end

  def update_cursor_rect
    cursor_rect.set(@index * @cursor_width+2, 0, @cursor_width, Message::Height)
  end

  def update
    super
    if Input.repeat?(Input::UP)
      $game_system.se_play($data_system.cursor_se)
      increase_letter_array(@index)
      refresh
    end
    if Input.repeat?(Input::DOWN)
      $game_system.se_play($data_system.cursor_se)
      decrease_letter_array(@index)
      refresh
    end
    if Input.repeat?(Input::RIGHT)
      if @digits_max >= 2
        $game_system.se_play($data_system.cursor_se)
        @index = (@index + 1) % @digits_max
      end
    end
    if Input.repeat?(Input::LEFT)
      if @digits_max >= 2
        $game_system.se_play($data_system.cursor_se)
        @index = (@index + @digits_max - 1) % @digits_max
      end
    end
    if Input.trigger?(Input::B)
      @letter_array[@index] = 0
      refresh
    end
    update_cursor_rect
  end

  def refresh
    contents.clear
    contents.font.color = normal_color
    (0...@digits_max).each {|i|
      s = i * @cursor_width + 4
      contents.draw_text(s,0,@cursor_width,Message::Height,letter(i),1) }
  end

  def number
    @number = []
    (0...@digits_max).each {|i| @number.push(letter(i))}
    integer = @number.find_all {|i| !("0".."9").to_a.include?(i)}.size == 0
    @number = @number.join
    return integer ? @number.to_i : @number
  end

  def number=(number)
    if number != 0
      num = number.to_s
      @array = num.scan(/./)
      if @array.size != @digits_max
        begin
          @array.unshift(@character_array[0])
        end until @array.size == @digits_max
      end
      (0...@digits_max).each {|i|
        (0..@character_array.size).each {|j|
           @letter_array[i] = j if @array[i] == @character_array[j]
         }}
    end
    refresh
  end
end

#==============================================================
# ** Scrolling Message System / Name Box
#------------------------------------------------------------------------------
# Slipknot (http://www.creationasylum.net/)
# Version 1.1
# March 13, 2007
#==============================================================
class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias slipknot_sms_nb_refresh refresh
  alias slipknot_sms_nb_repcod replace_code
  alias slipknot_sms_nb_termmes terminate_message
  #--------------------------------------------------------------------------
  # * Terminate Message
  #--------------------------------------------------------------------------
  def terminate_message
    slipknot_sms_nb_termmes
    if @name_box
      @name_box.dispose
      @name_box = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    slipknot_sms_nb_refresh
    if @name_text
      @name_box = Window_MessageNameBox.new(x, y - 16, @name_text)
      @name_box.back.opacity = 0 if $game_system.message_frame == 1
      @name_box.z = self.z
      @name_text = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Replace Code
  #--------------------------------------------------------------------------
  def replace_code
    slipknot_sms_nb_repcod
    @text.gsub!(/\\[Nn]ame\[(.*?)\]/) { @name_text = $1; '' }
  end
end

class Window_MessageNameBox < Window_Base
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_reader :back
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(x, y, text)
    dumb = Bitmap.new(160, 32)
    dumb.font = Message.font
    color = nil
    text.sub!(/\\[Cc](\d)/) { color = text_color($1.to_i); '' }
    size = dumb.text_size(text).width
    dumb.dispose
    @back = Window_Base.new(x, y, size + 12, 32)
    @back.z = 9998
    super(x - 10, y - 11, size + 32, 54)
    self.z = 9999
    self.opacity = 0
    self.contents = Bitmap.new(size, 22)
    contents.font = Message.font
    contents.font.color = color if color
    contents.draw_text(0, 0, size, 22, text)
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    @back.dispose
    @back = nil
    super
  end
end
#==============================================================
# ** Scrolling Message System / Face
#------------------------------------------------------------------------------
# Slipknot (http://www.creationasylum.net/)
# Version 1.0
# May 13, 2007
#==============================================================

class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias slipknot_sms_f_refresh refresh
  alias slipknot_sms_f_repcod replace_code
  alias slipknot_sms_f_termmes terminate_message
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def terminate_message
    slipknot_sms_f_termmes
    if @face
      @face.dispose
      @face = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    slipknot_sms_f_refresh
    if @face_name
      @face = Sprite.new
      @face.x = self.x + 16
      @face.y = self.y + 16
      @face.z = self.z + 1
      if @face_name.to_i > 0
        actor = $game_actors[@face_name.to_i]
        return @face_name = nil if actor.nil?
        bitmap = RPG::Cache.windowskin("Actor#{actor.id}_HFace") rescue
                RPG::Cache.windowskin("#{actor.name}_HFace") rescue
                RPG::Cache.picture("Actor#{actor.id}_HFace") rescue
                RPG::Cache.picture("#{actor.name}_HFace")
        size = [bitmap.width,bitmap.height].min
        rect = Rect.new(0,0,size,size)
      else
        bitmap = RPG::Cache.picture(@face_name)
        rect = Rect.new(0,0,bitmap.width,bitmap.height)
      end
      @face.bitmap = Bitmap.new(60,60)
      x = 30 - rect.width / 2
      y = 30 - rect.height / 2
      x, y = 0,0 if false
      @face.bitmap.blt(x, y, bitmap, rect)
      @face_name = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Replace Code
  #--------------------------------------------------------------------------
  def replace_code
    slipknot_sms_f_repcod
    @text.sub!(/\\[Ff]ace\[(.*?)\]/) do
      @face_name = $1
      @ex += Message::Height * 2 + 4
      ''
    end
  end
end
#==============================================================
# ** Scrolling Message System / Bold & Italic
#------------------------------------------------------------------------------
# Slipknot (http://www.creationasylum.net/)
# Version 1.0
# May 13, 2007
#==============================================================

class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias slipknot_sms_bi_evalextra eval_extra
  alias slipknot_sms_bi_repbcod replace_basic_code
  #--------------------------------------------------------------------------
  # * Eval Extra
  #--------------------------------------------------------------------------
  def eval_extra(bitmap)
    slipknot_sms_bi_evalextra(bitmap)
    if @c == "\005"
      bitmap.font.bold = !bitmap.font.bold
      @c = ''
    end
    if @c == "\006"
      bitmap.font.italic = !bitmap.font.italic
      @c = ''
    end
  end
  #--------------------------------------------------------------------------
  # * Replace Basic Code
  #--------------------------------------------------------------------------
  def replace_basic_code
    slipknot_sms_bi_repbcod
    @text.gsub!('\\b', "\005")
    @text.gsub!('\\i', "\006")
  end
end

#==============================================================
# ** Scrolling Message System / Furigana
#------------------------------------------------------------------------------
# LiTTleDRAgo (http://littledrago.blogspot.com/)
# Version 1.0
# June 27, 2013
#==============================================================

class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias drg3x4dkc2dx_evalextra eval_extra
  alias drg3x4dkc2dx_evaltext eval_text
  alias drg3x4dkc2dx_repbcod replace_basic_code
  #--------------------------------------------------------------------------
  # * Eval Extra
  #--------------------------------------------------------------------------
  def eval_extra(bitmap)
    drg3x4dkc2dx_evalextra(bitmap)
    if @c == "\031"
      @text.sub!(/\[(.*?),(.*?)\]/, '')
      text = [$1,$2,bitmap.font.size]
      bitmap.font.size -= 6
      text << bitmap.text_size(text[1])
      @furigana = Bitmap.new(text[3].width,text[3].height)
      @furigana.font = bitmap.font.dup
      @furigana.draw_text(0,0,text[3].width,text[3].height,text[1])
      bitmap.font.size = text[2]
      text << bitmap.text_size(text[0])
      x1 = [@ex + @x + (text[4].width/2 - text[3].width/2),0].max
      y1 = Message::Height
      x2 = [x1,self.width-text[3].width].min
      y2 = y1 * @y - y1/10
      @furigana_position = [x2,y2]
      @c = text[0]
    end
  end
  #--------------------------------------------------------------------------
  # * Eval Extra
  #--------------------------------------------------------------------------
  def eval_text(*args)
    result = drg3x4dkc2dx_evaltext(*args)
    if @furigana && !@furigana.disposed?
      x,y = @furigana_position
      args[0].blt(x, y,@furigana,@furigana.rect) if !args[1]
      @furigana.dispose
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * Replace Basic Code
  #--------------------------------------------------------------------------
  def replace_basic_code
    drg3x4dkc2dx_repbcod
    @text.gsub!(/\\[Rr]\[(.*?),(.*?)\]/) { "\031[#$1,#$2]" }
  end
end

#==============================================================
# ** Scrolling Message System / Condition Text
#------------------------------------------------------------------------------
# LiTTleDRAgo (http://littledrago.blogspot.com/)
# Version 1.0
# June 27, 2013
#==============================================================

class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias drg3x4dkc2dy_repbcod replace_basic_code
  #--------------------------------------------------------------------------
  # * Replace Basic Code
  #--------------------------------------------------------------------------
  def replace_basic_code
    drg3x4dkc2dy_repbcod
    @text.gsub!(/\\[Ii][Ff]\[(.*?),(.*?)\]/) {
          interpreter.send(:eval,"#$1") ? "#$2" : ""}
    @text.gsub!(/\\[Uu][Nn][Ll][Ee][Ss][Ss]\[(.*?),(.*?)\]/) {
          interpreter.send(:eval,"#$1") ? "" : "#$2"}
  end
end


#==============================================================
# ** Scrolling Message System / Font Name & Size
#------------------------------------------------------------------------------
# LiTTleDRAgo (http://littledrago.blogspot.com/)
# Version 1.0
# July 04, 2013
#==============================================================

class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias drg3x4dkc2dz_evalextra eval_extra
  alias drg3x4dkc2dz_repbcod replace_basic_code
  #--------------------------------------------------------------------------
  # * Eval Extra
  #--------------------------------------------------------------------------
  def eval_extra(bitmap)
    drg3x4dkc2dz_evalextra(bitmap)
    if @c == "\023"
      @text.sub!(/\[(.*?)\]/,  '')
      font = $1
      if font.to_i <= 0
        bitmap.font.name = font
      else
        bitmap.font.size = font.to_i
      end
      @c = ''
    end
  end
  #--------------------------------------------------------------------------
  # * Replace Basic Code
  #--------------------------------------------------------------------------
  def replace_basic_code
    drg3x4dkc2dz_repbcod
    @text.gsub!(/\\[Ff][Oo][Nn][Tt]\[(.*?),([0-9]+)\]/) { "\\font[#$1]\\font[#$2]" }
    @text.gsub!(/\\[Ff][Oo][Nn][Tt]\[(.*?)\]/) { "\023[#$1]" }
  end
end


#==============================================================
# ** Scrolling Message System / Game Related
#------------------------------------------------------------------------------
# LiTTleDRAgo (http://littledrago.blogspot.com/)
# Version 1.0
# July 04, 2013
#==============================================================

class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias drg3x4dkc2ea_repbcod replace_basic_code
  #--------------------------------------------------------------------------
  # * Replace Basic Code
  #--------------------------------------------------------------------------
  def replace_basic_code
    @text.gsub!(/\\[Ii]&[Nn]\[([EeIiWwAaSsPp])([0-9]+)\]/) {
       entity = "#$1#$2"
       "\\i[#{entity}] \\n[#{entity}]"}
    @text.gsub!(/\\[Ii]\[([EeIiWwAaSsPp])([0-9]+)\]/) {
        entity = case $1.downcase
          when 'i' then $data_items[$2.to_i]
          when 'w' then $data_weapons[$2.to_i]
          when 'a' then $data_armors[$2.to_i]
          when 's' then $data_skills[$2.to_i]
          end
        entity != nil ? "\002[#{entity.icon_name}]" : '' }
    @text.gsub!(/\\[Ii]\[(.*?)\]/) { "\002[#$1]" }
    @text.gsub!(/\\[Nn]\[([EeIiWwAaSsPp])([0-9]+)\]/) {
      entity = case $1.downcase
        when 'e' then $data_enemies[$2.to_i]
        when 'i' then $data_items[$2.to_i]
        when 'w' then $data_weapons[$2.to_i]
        when 'a' then $data_armors[$2.to_i]
        when 's' then $data_skills[$2.to_i]
        when 'p' then $game_map.events[$2.to_i]
      end
      entity != nil ? entity.name : ''   }
    @text.gsub!(/\\[$]\[([EeIiWwAaSsPp])([0-9]+)\]/) {
        e = case $1.downcase
          when 'i' then $data_items[$2.to_i]
          when 'w' then $data_weapons[$2.to_i]
          when 'a' then $data_armors[$2.to_i]
          when 's' then $data_skills[$2.to_i]
          end
        e != nil ? e.is_a?(RPG::Skill) ? e.sp_cost : e.price : '' }
    @text.gsub!(/\\[Mm][Aa][Pp]/) {
        load_data('Data/MapInfos.rxdata')[$game_map.map_id].name }
    drg3x4dkc2ea_repbcod
  end
end
end


What I'd like to have done
-Face graphic size up to 96x96 pixels.
-The choices window to properly show more than two choices, it doesn't seem to work for some reason.  (http://i.imgur.com/8MMXeZ1.jpg)

Scripts I'm using (in this order)
Scrolling Message System EX, Brewmeister's Empty Containers, Law's Custom Shop Screen, Weapon Specific Skills Script by TerreAqua, Game guy's Skill Shop, KK20's Organized Quest System, STCMS - Hybrid Edition and Blizz ABS.