Â
#==============================================================================
# ** Game_Message
#------------------------------------------------------------------------------
# Â This class handles the message data
#==============================================================================
Â
class Game_Message
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_accessor :letter_by_letter, :speed, :can_skip, :height, :font,
  :sound_enable, :sound, :path, :face_rect, :fit, :skin, :nb_skin,
  :nbyo, :opacity, :shadow, :outline, :pause, :autoclose_frames
 #--------------------------------------------------------------------------
 # * Object Initialization
 #--------------------------------------------------------------------------
 def initialize
  # Letter by letter mode
  @letter_by_letter = true
  # Lettter by letter mode's speed
  @speed = 3
  # If this option is false, the player can't skip the message
  @can_skip = true
  # Height of each line, used within the fit or above event options
  @height = 32
  # Always resize the message
  @fit = false
  # Font for the mesage text
  @font = Font.default_name
  # Sound enable
  @sound_enable = false
  # Sound for letter by letter, ['filename', vol]
  @sound = ['032-Switch01', 80]
  # Folder for the message pictures
  @path = 'Graphics/Pictures/'
  # Face rect (only the last two numbers are used)
  @face_rect = Rect.new(0, 0, 96, 96)
  # Skin for the message window, nil = default
  @skin = nil
  # Skin for the name box, nil = default
  @nb_skin = nil
  # Name box y offset
  @nbyo = 20
  # Message window's opacity
  @opacity = 160
  # Outline text
  @outline = false
  # Shadow text
  @shadow = false
  # Show or not the pause graphic
  @pause = true
  # Frames before the message autoclose
  @autoclose_frames = 8
 end
end
Â
#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
# Â Adds Game Message
#==============================================================================
Â
class Game_System
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_reader :message
 #--------------------------------------------------------------------------
 # * Alias Listing
 #--------------------------------------------------------------------------
 alias slipknot_lblms_initialize initialize
 #--------------------------------------------------------------------------
 # * Load Database
 #--------------------------------------------------------------------------
 def initialize
  slipknot_lblms_initialize
  @message = Game_Message.new
 end
end
Â
#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
# Â Adds a reader to the Event Name
#==============================================================================
Â
class Game_Event < Game_Character
 #--------------------------------------------------------------------------
 # * Name
 #--------------------------------------------------------------------------
 def name
  @event.name
 end
end
Â
#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
# Â Adds a reader to the Character Sprites
#==============================================================================
Â
class Spriteset_Map
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_reader :character_sprites
end
Â
#==============================================================================
# ** Window_Message
#------------------------------------------------------------------------------
# Â Rewrites Window_Message
#==============================================================================
Â
class Window_Message < Window_Selectable
 #--------------------------------------------------------------------------
 # * Alias Listing
 #--------------------------------------------------------------------------
 alias slipknot_lblms_initialize initialize
 alias slipknot_lblms_terminatemessage terminate_message
 #--------------------------------------------------------------------------
 # * Initialize
 #--------------------------------------------------------------------------
 def initialize
  slipknot_lblms_initialize
  @autoclose = -1
 end
 #--------------------------------------------------------------------------
 # * Terminate Message
 #--------------------------------------------------------------------------
 def terminate_message
  slipknot_lblms_terminatemessage
  [@name_box, @picture].each do |x|
   x.dispose if x && ! x.disposed?
  end
 end
 #--------------------------------------------------------------------------
 # * Refresh
 #--------------------------------------------------------------------------
 def refresh
  self.opacity = $game_system.message_frame == 0 ? 255 : 0
  self.back_opacity = system.opacity
  unless system.fit
   self.width, self.height = 480, 160
   skin = system.skin ? system.skin : $game_system.windowskin_name
   self.windowskin = RPG::Cache.windowskin(skin)
   self.contents = Bitmap.new(448, 128)
  else
   contents.clear
   contents.font.color = normal_color
   contents.font.size = Font.default_size
  end
  contents.font.name = system.font
  @x = @y = @wait_count = indent = 0
  @fit_size, @sound = false, system.sound_enable
  @start_x = 4
  @cursor_width = [0, 0, 0, 0]
  @x = 8 if $game_temp.choice_start == 0
  return if ! (@text = $game_temp.message_text)
  @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!(/\\[Nn][Pp]\[([\d+])\]/) do
   $game_party.actors[$1.to_i] ? $game_party.actors[$1.to_i].name : ''
  end
  @text.gsub!(/\\[Cc]lass\[(\d+)\]/) do
   $game_actors[$1.to_i] ? $game_actors[$1.to_i].class_name : ''
  end
  @text.gsub!(/\\[Mm]ap/) { $data_map_infos[$game_map.map_id].name }
  gold_set = @text.gsub!(/\\[Gg]/, '')
  if @text[/\\[Nn]ame/]
   if @text.sub!(/\\[Nn]ame\[(.*?)\]/, '')
    name_text = $1
   elsif @text.sub!(/\\[Nn]ame/, '')
    name_text = $game_map.events[$game_system.map_interpreter.event_id].name
   end
  end
  if @text[/\\[Ff]ace/]
   # Left
   if @text.sub!(/\\[Ff]ace{(.+?)}/, '')
    face, face_name = 1, $1
   # Right
   elsif @text.sub!(/\\[Ff]ace\[(.+?)\]/, '')
    face, face_name = 2, $1
   end
  end
  picture = $1 if @text.sub!(/\\[Pp]ic\[(.+?)\]/, '')
  if @text[/\\[Pp]/]
   if @text.sub!(/\\[Pp]\[([-1,0-9]+)\]/, '')
    event = $1.to_i
   elsif @text.gsub!(/\\[Pp]/, '')
    event = $game_system.map_interpreter.event_id
   end
  end
  @text.gsub!('\$') { $game_party.gold.to_s }
  @text.gsub!(/\\[Cc]\[([0-9A-Fa-f #]+?)\]/) { "\001[#$1]" }
  @text.gsub!(/\\[Cc]/) { "\001[0]" }
  @text.gsub!(/\\[Ii]con{([IiWwAaSs])}\[(\d+)\]/) { change_icon($1, $2.to_i) }
  @text.gsub!(/\\[Ii]con\[(.*?)\]/) { "\002[#$1]" }
  @text.gsub!('\!') { "\003" }
  @text.gsub!('\.') { "\004" }
  @text.gsub!(/\\[Ss]\[([Xx\d]+)\]/) { "\005[#$1]" }
  @text.gsub!(/\\[Bb]/) { "\006" }
  @text.gsub!(/\\[Ii]/) { "\007" }
  @text.gsub!(/\\[Ff]\[(.*?)\]/) { "\010[#$1]" }
  @text.gsub!(/\\\%\[(\d+)\]/) { "\011[#$1]" }
  @text.gsub!('\%') { "\011" }
  if @fit_size = (event || system.fit)
   lines_size = [0, 0, 0, 0]
   save, lines = @text.clone, 0
   while (c = @text.slice!(/./m))
    if c == "\n"
     lines += 1
     break if lines == 4
     if lines >= $game_temp.choice_start
      lines_size[lines] += 16
     end
     next
    end
    lines_size[lines] += eval_text(c, true)
   end
  end
  if face
   if @fit_size
    mh = system.height
    fh = system.face_rect.height
    lines = (fh.to_f / mh.to_f).ceil if (lines * mh) < fh
    f_x = face == 2 ? 0 : lines_size.max + 16
    f_y = (lines * mh) <= fh ? 0 : (lines * mh - fh) / 2
    @start_x += system.face_rect.width + 4 if face == 2
    indent += system.face_rect.width + 8
   else
    f_x, f_y = face == 2 ? 16 : 336, 16
    @start_x += system.face_rect.width + 36 if face == 2
   end
   f_bitmap = RPG::Cache.load_bitmap(system.path, face_name)
  end
  if @fit_size
   @text = save
   self.height = lines * system.height + 32
   self.height += 32 if $game_temp.num_input_variable_id > 0
   self.width = lines_size.max + indent + 40
   windowskin = system.skin ? system.skin : $game_system.windowskin_name
   self.windowskin = RPG::Cache.windowskin(windowskin)
   self.contents = Bitmap.new(self.width - 32, self.height - 32)
   contents.font.name = system.font
  end
  contents.blt(f_x, f_y, f_bitmap, system.face_rect) if face
  if ! event
   h2 = self.height / 2
   self.y = $game_temp.in_battle ? 96 - h2 + system.nbyo :
    case $game_system.message_position
    when 0 then 96 - h2 + system.nbyo
    when 1 then 240 - h2
    when 2 then 384 - h2
    end
   self.x = 320 - self.width / 2
  else
   c = event > 0 ? $game_map.events[event] : $game_player
   mx, my = 636 - self.width, 476 - self.height
   fx = [[c.screen_x - self.width / 2, 4].max, mx].min
   sy = name_text ? system.nbyo + 4 : 4
   ch = [$scene.spriteset.character_sprites[event - 1].bitmap.height /
    4 + 4, 48].max
   fy = [[c.screen_y - (ch + self.height), sy].max, my].min
   self.x, self.y = fx, fy
  end
  if name_text
   @name_box = Window_NameBox.new(x, y - system.nbyo, name_text)
   @name_box.back.opacity = 0 if $game_system.message_frame == 1
  end
  if picture
   @picture = Sprite.new
   @picture.bitmap = RPG::Cache.load_bitmap(system.path, picture)
   @picture.x = self.x + self.width - @picture.bitmap.width
   @picture.y = self.y - @picture.bitmap.height
  end
  if gold_set
   @gold_window = Window_Gold.new
   @gold_window.x = 560 - @gold_window.width
   if $game_temp.in_battle
    @gold_window.y = 192
   else
    @gold_window.y = self.y >= 128 ? 32 : 384
   end
   @gold_window.opacity = self.opacity
   @gold_window.back_opacity = self.back_opacity
  end
 end
 #--------------------------------------------------------------------------
 # * Evaluate Text
 #--------------------------------------------------------------------------
 def eval_text(c, read = false)
  case c
  when "\000"
   c = '\\'
  when "\001"
   @text.sub!(/\[(.*?)\]/, '')
   return 0 if read
   h, c = $1, $1.to_i
   contents.font.color = h.slice!(/./) == '#' ? hex_color(h) : text_color(c)
   return
  when "\002"
   @text.sub!(/\[(.*?)\]/, '')
   return 24 if read
   y = @fit_size ? system.height * @y + (system.height - 24) / 2 : 32 * @y + 4
   contents.blt(@x + @start_x, y, RPG::Cache.icon($1.to_s), Rect.new(0, 0, 24, 24))
   @x += 24
   return unless @y >= $game_temp.choice_start
   @cursor_width[@y] += 24
   return
  when "\003"
   return 0 if read
   @stop = true
   return
  when "\004"
   return 0 if read
   @wait_count += 10
   return
  when "\005"
   @text.sub!(/\[([x\d]+)\]/, '')
   if $1.downcase == 'x'
    contents.font.size = Font.default_size
   else
    contents.font.size = [[$1.to_i, 6].max, system.height].min
   end
   return 0
  when "\006"
   contents.font.bold = (! contents.font.bold)
   return 0
  when "\007"
   contents.font.italic = (! contents.font.italic)
   return 0
  when "\010"
   @text.sub!(/\[(.*?)\]/, '')
   if $1.downcase == 'x'
    contents.font.name = system.font
   else
    contents.font.name = [$1.to_s, system.font]
   end
   return 0
  when "\011"
   @text.sub!(/\[(\d+)\]/, '')
   return 0 if read
   @autoclose = $1 ? $1.to_i : system.autoclose_frames
   return
  when "\n"
   @y += 1
   @x = 0
   @x = 8 if @y >= $game_temp.choice_start
   return
  end
  w = contents.text_size(c).width
  return w if read
  y = @fit_size ? system.height * @y : 32 * @y
  if system.outline
   color = contents.font.color.dup
   contents.font.color.set(0, 0, 0, 255)
   contents.draw_text(@x + @start_x + 1, y, w * 2, system.height, c)
   contents.draw_text(@x + @start_x, y + 1, w * 2, system.height, c)
   contents.draw_text(@x + @start_x - 1, y, w * 2, system.height, c)
   contents.draw_text(@x + @start_x, y - 1, w * 2, system.height, c)
   contents.font.color = color
   contents.draw_text(@x + @start_x, y, w * 2, system.height, c)
  elsif system.shadow
   color = contents.font.color.dup
   contents.font.color.set(0, 0, 0, 192)
   contents.draw_text(@x + @start_x + 2, y + 2, w * 2, system.height, c)
   contents.font.color = color
   contents.draw_text(@x + @start_x, y, w * 2, system.height, c)
  else
   contents.draw_text(@x + @start_x, y, w * 2, system.height, c)
  end
  @sound = (system.sound_enable && c != ' ')
  @x += w
  return if @y < $game_temp.choice_start || @y > 3
  @cursor_width[@y] += w
 end
 #--------------------------------------------------------------------------
 # * Finish
 #--------------------------------------------------------------------------
 def finish
  if temp.choice_max > 0
   @item_max, self.active, self.index = temp.choice_max, true, 0
  end
  if temp.num_input_variable_id > 0
   digits_max = temp.num_input_digits_max
   number = $game_variables[temp.num_input_variable_id]
   @input_number_window = Window_InputNumber.new(digits_max)
   input_number.number = number
   input_number.x = x + 8
   input_number.y = y + temp.num_input_start * (@fit_size ? system.height : 32)
  end
 end
 #--------------------------------------------------------------------------
 # * Database Icon
 #--------------------------------------------------------------------------
 def change_icon(option, index)
  s = case option.downcase
   when 'i'  then $data_items[index]
   when 'w' then $data_weapons[index]
   when 'a'  then $data_armors[index]
   when 's'  then $data_skills[index]
   end
  return sprintf("\002[%s]%s", s.icon_name, s.name) if s.name
 end
 #--------------------------------------------------------------------------
 # * Hexadecimal Color
 #--------------------------------------------------------------------------
 def hex_color(string)
  return normal_color if string.size != 6
  r = g = b = 0
  5.times do |i|
   s = string.slice!(/./m)
   v = hex_convert(s.downcase)
   case i
   when 0 then r += v * 16
   when 1 then r += v
   when 2 then g += v * 16
   when 3 then g += v
   when 4 then b += v * 16
   when 5 then b += v
   end
  end
  return Color.new(r, g, b)
 end
 #--------------------------------------------------------------------------
 def hex_convert(c)
  return c.to_i if c[/[0-9]/]
  case c
  when 'a' then 10
  when 'b' then 11
  when 'c' then 12
  when 'd' then 13
  when 'e' then 14
  when 'f' then 15
  end
 end
 #--------------------------------------------------------------------------
 # * Game Message
 #--------------------------------------------------------------------------
 def system() $game_system.message end
 #--------------------------------------------------------------------------
 # * Game Temp
 #--------------------------------------------------------------------------
 def temp() $game_temp end
 #--------------------------------------------------------------------------
 # * Input Number Window
 #--------------------------------------------------------------------------
 def input_number() @input_number_window end
 #--------------------------------------------------------------------------
 # * Frame Update
 #--------------------------------------------------------------------------
 def update
  if @contents_showing
   super
   if @fade_in
    self.contents_opacity += 24
    if input_number
     input_number.contents_opacity += 24
    end
    @fade_in = contents_opacity != 255
    return
   end
   if @text
    if Input.trigger?(13)
     if @stop
      self.pause = @stop = false
      return
     end
     @skip = system.can_skip
    end
    return if @stop
    if @wait_count > 0 && ! @skip
     @wait_count -= 1
     return
    end
    loop do
     if (c = @text.slice!(/./m))
      eval_text(c)
      if @stop
       self.pause = system.pause
       return
      end
      if ! @skip && @sound
       Audio.se_play('Audio/SE/' + system.sound[0], system.sound[1])
       @sound = false
      end
      @wait_count += system.speed
     else
      @text = nil
      break
     end
     break if ! @skip
    end
    return if @text || @autoclose != -1
    finish
    return
   else
    if @autoclose > 0
     @autoclose -= 1
     return
    elsif @autoclose == 0
     terminate_message
     @autoclose = -1
     return
    end
   end
  end
  if input_number
   input_number.update
   if Input.trigger?(13)
    $game_system.se_play($data_system.decision_se)
    $game_variables[$game_temp.num_input_variable_id] = input_number.number
    $game_map.need_refresh = true
    input_number.dispose
    @input_number_window = nil
    terminate_message
   end
   return
  end
  if @contents_showing
   self.pause = ($game_temp.choice_max == 0) & system.pause
   if Input.trigger?(12)
    if $game_temp.choice_max > 0 && $game_temp.choice_cancel_type > 0
     $game_system.se_play($data_system.cancel_se)
     $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
     terminate_message
    end
   end
   if Input.trigger?(13)
    if $game_temp.choice_max > 0
     $game_system.se_play($data_system.decision_se)
     $game_temp.choice_proc.call(self.index)
    end
    terminate_message
   end
   return
  end
  if ! @fade_out && $game_temp.message_text
   @contents_showing = temp.message_window_showing = true
   @stop = false
   @autoclose = -1
   @skip = (! system.letter_by_letter)
   reset_window
   refresh
   @wait_count, self.visible = 0, true
   return
  end
  return if ! visible
  @fade_out = true
  self.opacity -= 48
  if self.opacity == 0
   self.visible = @fade_out = false
   $game_temp.message_window_showing = false
  end
 end
 #--------------------------------------------------------------------------
 # * Updates Cursor Rectangle
 #--------------------------------------------------------------------------
 def update_cursor_rect
  if index >= 0
   n = $game_temp.choice_start + @index
   y = (@fit_size ? system.height : 32) * n
   cursor_rect.set(4 + @start_x, y, @cursor_width.max + 8,
    @fit_size ? system.height : 32)
  else
   cursor_rect.empty
  end
 end
end
Â
#==============================================================================
# ** Window_NameBox
#------------------------------------------------------------------------------
# Â This window is used to display the box above the message.
#==============================================================================
Â
class Window_NameBox < Sprite
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_reader :back
 #--------------------------------------------------------------------------
 # * Object Initialization
 #--------------------------------------------------------------------------
 def initialize(x, y, text)
  dumb = Bitmap.new(160, 42)
  dumb.font.name = system.font
  size = dumb.text_size(text).width
  dumb.dispose
  @back = Window_Base.new(x, y, size + 12, 32)
  skin = system.nb_skin ? system.nb_skin : $game_system.windowskin_name
  @back.windowskin = RPG::Cache.windowskin(skin)
  viewport = Viewport.new(x + 6, y + 5, size, 22)
  @back.z = viewport.z = 9999
  super(viewport)
  self.bitmap = Bitmap.new(size, 22)
  bitmap.font.name = system.font
  bitmap.draw_text(0, 0, size, 22, text)
 end
 #--------------------------------------------------------------------------
 # * Game Message
 #--------------------------------------------------------------------------
 def system() $game_system.message end
 #--------------------------------------------------------------------------
 # * Dispose
 #--------------------------------------------------------------------------
 def dispose
  @back.dispose
  @back = nil
  super
 end
end
Â
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# Â Adds a reader to the Event ID and Game Message
#==============================================================================
Â
class Interpreter
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_reader :event_id
 #--------------------------------------------------------------------------
 # * Game Message
 #--------------------------------------------------------------------------
 def message
  $game_system.message
 end
end
Â
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# Â Adds a reader to the Spriteset
#==============================================================================
Â
class Scene_Map
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_reader :spriteset
end