RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
Adding a feature to Modern's Dialogue Script

0 Members and 1 Guest are viewing this topic.

********
Rep:
Level 96
2011 Most Missed Member2010 Zero To Hero
Hi again! I'm trying to add a feature where you can make a call that plays a sound effect in the middle of text to Modern's dialogue system.

The original script is here.

Code: [Select]
#=======================================================================
#  Modern Algebra Message Script
#  Version 0.5
#  Author: modern algebra
#  February 22, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Special Thanks to:
#      Arrow-1 for the request. I loved the animated facesets idea
#      Zeriab for his regular expressions tutorial
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Current Features:
#     - Precise letter-by-letter timing control
#     - Animated Facesets
#     - Can play a sound effect with each letter drawn
#     - numerous additional codes - see below for all the codes
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Current Codes:
#     - \< Slows the speed at which the text is drawn
#     - \> Increases the speed at which the text is drawn
#     - \b bold text
#     - \i italicized text
#     - \name[text] name box
#     - \ne[enemy_id] name of enemy
#     - \ni[item_id] Name of item
#     - \nw[weapon_id] Name of weapon
#     - \na[armor_id] Name of Armor
#     - \pi[item_id] price of item
#     - \pw[weapon_id] price of weapon
#     - \pa[armor_id] price of Armor
#     - \icon[icon_index] draw icon assigned to icon_index
#     - \iicon[item_id] draw icon of item
#     - \wicon[weapon_id] draw icon of weapon
#     - \aicon[armor_id] draw icon of armor
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#    Fill in the constants below for default settings. You can change pretty much all of these
#    constants in-game with the codes:
#
#        Message_Options.letter_by_letter_sound = true/false
#        Message_Options.message_se = 'filename'
#        Message_Options.default_timing = integer (lower = faster)
#        Message_Options.namebox_windowskin = 'Windowskin'
#        Message_Options.namebox_color = integer (0..32)
#        Message_Options.namebox_fontname = 'font name'
#        Message_Options.namebox_fontsize = 'Windowskin'
#        Message_Options.namebox_offset_x = integer
#        Message_Options.namebox_offset_y = integer
#        Message_Options.opacity = integer (0..255)
#
#  To use animated facesets, merely use a face graphic that ends with _a and you must have
#  another faceset with the same name but ending with _b.
#=======================================================================

module Message_Options
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Constants
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  DEFAULT_TIMING = 0 # The default amount of frames between each letter as it is drawn
  LETTER_BY_LETTER_SOUND = true # Whether there should be an SE played with each character drawn
  MESSAGE_SE = 'Open1' # The SE to be played if LETTER_BY_LETTER_SOUND == true
  ANIMATED_FACESETS = true  # true => active animated facesets; false => deactivated
  NAMEBOX_WINDOWSKIN = "Window" # The windowskin for the name box
  NAMEBOX_COLOR = 5 # The Color of the text in the namebox
  NAMEBOX_FONTNAME = 'Times New Roman' # The Font of the namebox
  NAMEBOX_FONTSIZE = 20 # The Size of the text in the namebox
  NAMEBOX_OFFSET_X = 16 # How much the Namebox is in the X direction away from default
  NAMEBOX_OFFSET_Y = 16 # How much the Namebox is in the Y direction away from default
  NAMEBOX_OPACITY = 100 # The opacity of the name box
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Message SE (Lazy Initialization)
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.message_se
    self.message_se = MESSAGE_SE if @message_se.nil?
    return @message_se
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Message SE =
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.message_se= (file_name)
    @message_se = RPG::SE.new  (file_name)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Message_SE_Active?
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.message_se_active?
    @letter_by_letter_sound = LETTER_BY_LETTER_SOUND if @letter_by_letter_sound.nil?
    return @letter_by_letter_sound 
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Letter BY Letter Sound =
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.letter_by_letter_sound= (boolean)
    @letter_by_letter_sound = boolean
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Windowskin
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_windowskin
    @namebox_windowskin = Cache.system (NAMEBOX_WINDOWSKIN) if @namebox_windowskin == nil
    return @namebox_windowskin
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Windowskin=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_windowskin= (string)
    @namebox_windowskin = Cache.system (string)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Color
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_color
    @namebox_color = NAMEBOX_COLOR if @namebox_color == nil
    return @namebox_color
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Color=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_color= (value)
    @namebox_color = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Fontname
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_fontname
    @namebox_font = NAMEBOX_FONTNAME if @namebox_font == nil
    return @namebox_font
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Fontname=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_fontname= (string)
    @namebox_font = string
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Fontsize
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_fontsize
    @namebox_fontsize = NAMEBOX_FONTSIZE if @namebox_fontsize == nil
    return @namebox_fontsize
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Fontsize=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_fontsize= (value)
    @namebox_fontsize = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Offset X
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_offset_x
    @namebox_x = NAMEBOX_OFFSET_X if @namebox_x == nil
    return @namebox_x
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Offset X=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_offset_x= (value)
    @namebox_x = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Offset Y
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_offset_y
    @namebox_y = NAMEBOX_OFFSET_Y if @namebox_y == nil
    return @namebox_y
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Offset Y=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_offset_y= (value)
    @namebox_y = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Opacity
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_opacity
    @namebox_opacity = NAMEBOX_OPACITY if @namebox_opacity == nil
    return @namebox_opacity
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Opacity=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_opacity= (value)
    @namebox_opacity = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Default timing
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.default_timing
    @default_timing = DEFAULT_TIMING if @default_timing == nil
    return @default_timing
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Default Timing =
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.default_timing= (value)
    value = [value, 0].max
    @default_timing = value
  end
end

module Sound
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Play Message SE
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.play_message_se
    Message_Options.message_se.play
  end
end

#======================================================================
# ** Sprite Message Face
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  A sprite to reduce lag when using Animated  Facesets
#======================================================================

class Sprite_MessageFace < Sprite_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def initialize (face_file, face_index = 0, size = 96, single = false)
    super ()
    self.visible = false
    self.z = 250
    face = Cache.face (face_file)
    if single
      self.bitmap = face
    else
      self.bitmap = Bitmap.new (face.width / 4, face.height / 2)
      rect = Rect.new(0, 0, 0, 0)
      rect.x = face_index %  4* 96 + (96 - size) / 2
      rect.y = face_index / 4 * 96 + (96 - size) / 2
      rect.width = size
      rect.height = size
      self.bitmap.blt(x, y, face, rect)
      face.dispose
    end
  end
end

#========================================================================
# ** Window Name Box
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This window displays the name of a speaker in Window_Message
#========================================================================

class Window_NameBox < Window_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def initialize (x, y, string)
    temp_bitmap = Bitmap.new (1, 1)
    temp_bitmap.font.name = Message_Options.namebox_fontname
    temp_bitmap.font.size = Message_Options.namebox_fontsize
    rect = temp_bitmap.text_size (string)
    temp_bitmap.dispose
    super (x, y, rect.width + 32, rect.height + 32)
    self.z = 300
    create_contents
    # Use Namebox settings
    self.back_opacity = Message_Options.namebox_opacity
    self.windowskin = Message_Options.namebox_windowskin
    self.contents.font.name = Message_Options.namebox_fontname
    self.contents.font.size = Message_Options.namebox_fontsize
    self.contents.font.color = text_color(Message_Options.namebox_color)
    # Draw the text
    self.contents.draw_text (0, 0, rect.width, rect.height, string)
  end
end

#======================================================================
# ** Window_Message
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of changes:
#     Basically, this script changes the way letter-by-letter works in order to allow for various
#     options: namely speed variability, sound effects, and animated facesets
#
#     aliased method - convert_special_characters
#     overwritten methods - update_message
#======================================================================

class Window_Message < Window_Selectable
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Convert Special Characters
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_msg_script_special_char_conversion convert_special_characters
  def  convert_special_characters
    # New codes
    modalg_msg_script_special_char_conversion
    @text.gsub!(/\\NE\[([0-9]+)\]/i) { $data_enemies[$1.to_i].name } # Name Enemy
    @text.gsub!(/\\NI\[([0-9]+)\]/i) { $data_items[$1.to_i].name }   # Name Item
    @text.gsub!(/\\NW\[([0-9]+)\]/i) { $data_weapons[$1.to_i].name } # Name Weapon
    @text.gsub!(/\\NA\[([0-9]+)\]/i) { $data_armors[$1.to_i].name } # Name Armor
    @text.gsub!(/\\PI\[([0-9]+)\]/i) { $data_items[$1.to_i].price.to_s } # Price Item
    @text.gsub!(/\\PW\[([0-9]+)\]/i) { $data_weapons[$1.to_i].price.to_s } # Price Weapon
    @text.gsub!(/\\PA\[([0-9]+)\]/i) { $data_armors[$1.to_i].price.to_s } # Price Armor
    @text.gsub! (/\\IICON\[([0-9]+)\]/i) { "\x10[#{$data_items[$1.to_i].icon_index}]" } # Icon Item
    @text.gsub! (/\\WICON\[([0-9]+)\]/i) { "\x10[#{$data_weapons[$1.to_i].icon_index}]" } # Icon Weapon
    @text.gsub! (/\\AICON\[([0-9]+)\]/i) { "\x10[#{$data_armors[$1.to_i].icon_index}]" } # Icon Armor
    # Retrieve Name
    name = @text[/\\NAME\[.*?\]/i]
    name.sub! (/\\NAME/i, '') unless name == nil
    @text.gsub! (/\\NAME\[.*?\]/i) { "\x09#{name}" } # Name Window
    @text.gsub! (/\\ICON\[([0-9]+)\]/i) { "\x10[#{$1}]" } # Icon
    @text.gsub!(/\\B/i) { "\x11" } # Bold
    @text.gsub!(/\\I/i) { "\x12" } # Italic
    # Run original script
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_msg_script_init initialize
  def initialize
    # Run original method
    modalg_msg_script_init
    @letter_timing = Message_Options.default_timing
    @face_sprites = []
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * New Page
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def new_page
    contents.clear
    if $game_message.face_name.empty?
      @contents_x = 0
    else
      @face_sprites.clear
      name = $game_message.face_name.dup
      index = $game_message.face_index
      # Determine if the face is a single graphic
      single = name[/^\$/] != nil
      face = Sprite_MessageFace.new (name, index, 96, single)
      face.x = self.x + 16
      face.y = self.y + 16
      face.visible = true
      @face_sprites.push (face)
      @current_face = 0
      unless name[/\_a$/i] == nil
        name.gsub! (/\_a$/i) {|s| s = '_b'}
        face = Sprite_MessageFace.new (name, index, 96, single)
        face.x = self.x + 16
        face.y = self.y + 16
        @face_sprites.push (face)
      end
      @contents_x = 112
    end
    @contents_y = 0
    @line_count = 0
    @show_fast = false
    @line_show_fast = false
    @pause_skip = false
    contents.font.color = text_color(0)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update Message
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   def update_message
     loop do
      @wait_count = Message_Options.default_timing
      c = @text.slice!(/./m)            # ???????
      case c
      when nil                          # ??????????
        finish_message                  # ????
        break
      when "\x00"                       # ??
        new_line
        if @line_count >= MAX_LINE      # ????????
          unless @text.empty?           # ??????????
            self.pause = true           # ????????
            break
          end
        end
        break
      when "\x01"                       # \C[n]  (?????)
        @text.sub!(/\[([0-9]+)\]/, "")
        contents.font.color = text_color($1.to_i)
        next
      when "\x02"                       # \G  (?????)
        @gold_window.refresh
        @gold_window.open
      when "\x03"                       # \.  (???? 1/4 ?)
        @wait_count = 15
        break
      when "\x04"                       # \|  (???? 1 ?)
        @wait_count = 60
        break
      when "\x05"                       # \!  (????)
        self.pause = true
      when "\x06"                       # \>  (???? ON)
        @letter_timing -= 1
        @letter_timing = 0 if @letter_timing < 0
      when "\x07"                       # \<  (???? OFF)
        @letter_timing += 1
      when "\x08"                       # \^  (??????)
        @pause_skip = true
      when "\x09"                       # \name Name Box
        name = @text[/\[.*?\]/]
        @text.sub!(/\[.*?\]/, "")
        name = name[1, name.size - 2]
        x = self.x + Message_Options.namebox_offset_x
        y = self.y + Message_Options.namebox_offset_y
        @name_window = Window_NameBox.new (x, y, name)
        @name_window.y -= @name_window.height
      when "\x10"                      # \icon Shows an icon
        @text.sub!(/\[([0-9]+)\]/, "")
        draw_icon ($1.to_i, @contents_x, @contents_y)
        @contents_x += 24
        @wait_count += @letter_timing
      when "\x11"                       # \b Bold
        # Toggle Bold
        self.contents.font.bold = self.contents.font.bold ? false : true
      when "\x12"                       # \i Italic           
        # Toggle Italic
        self.contents.font.italic = self.contents.font.italic ? false : true
      else                              # ?????
        contents.draw_text(@contents_x, @contents_y, 40, WLH, c)
        c_width = contents.text_size(c).width
        @contents_x += c_width
        Sound.play_message_se if Message_Options.message_se_active?
        @wait_count += @letter_timing
        # Switch Facesets
        if Message_Options::ANIMATED_FACESETS && @face_sprites.size > 1
          @face_sprites[@current_face].visible = false
          @current_face += 1
          @current_face %= @face_sprites.size
          @face_sprites[@current_face].visible = true
        end
      end
      break unless @show_fast or @line_show_fast
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Finish Message
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_msg_script_message_fin finish_message
  def finish_message
    # Show initial face
    unless @face_sprites.empty?
      @face_sprites[@current_face].visible = false
      @current_face = 0
      @face_sprites[0].visible = true
    end
    @letter_timing = Message_Options.default_timing
    modalg_msg_script_message_fin
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Terminate Message
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_msg_script_message_term terminate_message
  def terminate_message
    self.contents.font.bold = false
    self.contents.font.italic = false
    modalg_msg_script_message_term
    @face_sprites.each {|face| face.dispose}
    @name_window.dispose unless @name_window.nil? || @name_window.disposed?
    @face_sprites.clear
  end
end

Quote
  • Hey, what are you doing?
  • Stop being nosy and get off of that suspiciously pink bench!
  • The nerve of you kids, making life so hard for us aliens- er...\SE[spooky] homosexual senior citizens!

The part in bold is key here. This command would trigger a part in Modern's script I'm trying to add that would play the specified sound- which in this case is Audio/SE/spooky.

Now I've been looking at the script, and it seems that to make it so an in text command triggers a part of a script, I need to use something like the following:

Code: [Select]
@text.gsub!(<text, though I can't quite figure out how the slashes are supposed to go>) {<replacement for text>}

So what I'm asking is, how do I represent the text, "\SE[string]" for the first section, and how do I make sure the sound effect called in the second part is the one defined in the first?
« Last Edit: March 17, 2008, 09:02:40 PM by Arrow-1 »

*
Resident Cloud
Rep:
Level 91
/\\SE\[([0-9a-z]+)\]/i

might be the regex string you need but i dont know

*
? ? ? ? ? ? ? ? ? The nice kind of alien~
Rep:
Level 92
Martian - Occasionally kind
I have edited the script so you now can put sound effects in the middle of the text ^^

Code: [Select]
#=======================================================================
#  Modern Algebra Message Script
#  Version 0.5
#  Author: modern algebra
#  February 22, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Special Thanks to:
#      Arrow-1 for the request. I loved the animated facesets idea
#      Zeriab for his regular expressions tutorial
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Current Features:
#     - Precise letter-by-letter timing control
#     - Animated Facesets
#     - Can play a sound effect with each letter drawn
#     - numerous additional codes - see below for all the codes
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Current Codes:
#     - \< Slows the speed at which the text is drawn
#     - \> Increases the speed at which the text is drawn
#     - \b bold text
#     - \i italicized text
#     - \name[text] name box
#     - \ne[enemy_id] name of enemy
#     - \ni[item_id] Name of item
#     - \nw[weapon_id] Name of weapon
#     - \na[armor_id] Name of Armor
#     - \pi[item_id] price of item
#     - \pw[weapon_id] price of weapon
#     - \pa[armor_id] price of Armor
#     - \icon[icon_index] draw icon assigned to icon_index
#     - \iicon[item_id] draw icon of item
#     - \wicon[weapon_id] draw icon of weapon
#     - \aicon[armor_id] draw icon of armor
#     - \se[se_name] play the sound effect
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#    Fill in the constants below for default settings. You can change pretty much all of these
#    constants in-game with the codes:
#
#        Message_Options.letter_by_letter_sound = true/false
#        Message_Options.message_se = 'filename'
#        Message_Options.default_timing = integer (lower = faster)
#        Message_Options.namebox_windowskin = 'Windowskin'
#        Message_Options.namebox_color = integer (0..32)
#        Message_Options.namebox_fontname = 'font name'
#        Message_Options.namebox_fontsize = 'Windowskin'
#        Message_Options.namebox_offset_x = integer
#        Message_Options.namebox_offset_y = integer
#        Message_Options.opacity = integer (0..255)
#
#  To use animated facesets, merely use a face graphic that ends with _a and you must have
#  another faceset with the same name but ending with _b.
#=======================================================================

module Message_Options
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Constants
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  DEFAULT_TIMING = 0 # The default amount of frames between each letter as it is drawn
  LETTER_BY_LETTER_SOUND = true # Whether there should be an SE played with each character drawn
  MESSAGE_SE = 'Open1' # The SE to be played if LETTER_BY_LETTER_SOUND == true
  ANIMATED_FACESETS = true  # true => active animated facesets; false => deactivated
  NAMEBOX_WINDOWSKIN = "Window" # The windowskin for the name box
  NAMEBOX_COLOR = 5 # The Color of the text in the namebox
  NAMEBOX_FONTNAME = 'Times New Roman' # The Font of the namebox
  NAMEBOX_FONTSIZE = 20 # The Size of the text in the namebox
  NAMEBOX_OFFSET_X = 16 # How much the Namebox is in the X direction away from default
  NAMEBOX_OFFSET_Y = 16 # How much the Namebox is in the Y direction away from default
  NAMEBOX_OPACITY = 100 # The opacity of the name box
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Message SE (Lazy Initialization)
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.message_se
    self.message_se = MESSAGE_SE if @message_se.nil?
    return @message_se
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Message SE =
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.message_se= (file_name)
    @message_se = RPG::SE.new  (file_name)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Message_SE_Active?
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.message_se_active?
    @letter_by_letter_sound = LETTER_BY_LETTER_SOUND if @letter_by_letter_sound.nil?
    return @letter_by_letter_sound 
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Letter BY Letter Sound =
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.letter_by_letter_sound= (boolean)
    @letter_by_letter_sound = boolean
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Windowskin
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_windowskin
    @namebox_windowskin = Cache.system (NAMEBOX_WINDOWSKIN) if @namebox_windowskin == nil
    return @namebox_windowskin
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Windowskin=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_windowskin= (string)
    @namebox_windowskin = Cache.system (string)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Color
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_color
    @namebox_color = NAMEBOX_COLOR if @namebox_color == nil
    return @namebox_color
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Color=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_color= (value)
    @namebox_color = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Fontname
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_fontname
    @namebox_font = NAMEBOX_FONTNAME if @namebox_font == nil
    return @namebox_font
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Fontname=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_fontname= (string)
    @namebox_font = string
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Fontsize
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_fontsize
    @namebox_fontsize = NAMEBOX_FONTSIZE if @namebox_fontsize == nil
    return @namebox_fontsize
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Fontsize=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_fontsize= (value)
    @namebox_fontsize = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Offset X
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_offset_x
    @namebox_x = NAMEBOX_OFFSET_X if @namebox_x == nil
    return @namebox_x
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Offset X=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_offset_x= (value)
    @namebox_x = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Offset Y
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_offset_y
    @namebox_y = NAMEBOX_OFFSET_Y if @namebox_y == nil
    return @namebox_y
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Offset Y=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_offset_y= (value)
    @namebox_y = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Opacity
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_opacity
    @namebox_opacity = NAMEBOX_OPACITY if @namebox_opacity == nil
    return @namebox_opacity
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * NameBox Opacity=
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.namebox_opacity= (value)
    @namebox_opacity = value
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Default timing
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.default_timing
    @default_timing = DEFAULT_TIMING if @default_timing == nil
    return @default_timing
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Default Timing =
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.default_timing= (value)
    value = [value, 0].max
    @default_timing = value
  end
end

module Sound
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Play Message SE
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.play_message_se
    Message_Options.message_se.play
  end
end

#======================================================================
# ** Sprite Message Face
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  A sprite to reduce lag when using Animated  Facesets
#======================================================================

class Sprite_MessageFace < Sprite_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def initialize (face_file, face_index = 0, size = 96, single = false)
    super ()
    self.visible = false
    self.z = 250
    face = Cache.face (face_file)
    if single
      self.bitmap = face
    else
      self.bitmap = Bitmap.new (face.width / 4, face.height / 2)
      rect = Rect.new(0, 0, 0, 0)
      rect.x = face_index %  4* 96 + (96 - size) / 2
      rect.y = face_index / 4 * 96 + (96 - size) / 2
      rect.width = size
      rect.height = size
      self.bitmap.blt(x, y, face, rect)
      face.dispose
    end
  end
end

#========================================================================
# ** Window Name Box
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This window displays the name of a speaker in Window_Message
#========================================================================

class Window_NameBox < Window_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def initialize (x, y, string)
    temp_bitmap = Bitmap.new (1, 1)
    temp_bitmap.font.name = Message_Options.namebox_fontname
    temp_bitmap.font.size = Message_Options.namebox_fontsize
    rect = temp_bitmap.text_size (string)
    temp_bitmap.dispose
    super (x, y, rect.width + 32, rect.height + 32)
    self.z = 300
    create_contents
    # Use Namebox settings
    self.back_opacity = Message_Options.namebox_opacity
    self.windowskin = Message_Options.namebox_windowskin
    self.contents.font.name = Message_Options.namebox_fontname
    self.contents.font.size = Message_Options.namebox_fontsize
    self.contents.font.color = text_color(Message_Options.namebox_color)
    # Draw the text
    self.contents.draw_text (0, 0, rect.width, rect.height, string)
  end
end

#======================================================================
# ** Window_Message
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of changes:
#     Basically, this script changes the way letter-by-letter works in order to allow for various
#     options: namely speed variability, sound effects, and animated facesets
#
#     aliased method - convert_special_characters
#     overwritten methods - update_message
#======================================================================

class Window_Message < Window_Selectable
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Convert Special Characters
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_msg_script_special_char_conversion convert_special_characters
  def  convert_special_characters
    # New codes
    modalg_msg_script_special_char_conversion
    @text.gsub!(/\\NE\[([0-9]+)\]/i) { $data_enemies[$1.to_i].name } # Name Enemy
    @text.gsub!(/\\NI\[([0-9]+)\]/i) { $data_items[$1.to_i].name }   # Name Item
    @text.gsub!(/\\NW\[([0-9]+)\]/i) { $data_weapons[$1.to_i].name } # Name Weapon
    @text.gsub!(/\\NA\[([0-9]+)\]/i) { $data_armors[$1.to_i].name } # Name Armor
    @text.gsub!(/\\PI\[([0-9]+)\]/i) { $data_items[$1.to_i].price.to_s } # Price Item
    @text.gsub!(/\\PW\[([0-9]+)\]/i) { $data_weapons[$1.to_i].price.to_s } # Price Weapon
    @text.gsub!(/\\PA\[([0-9]+)\]/i) { $data_armors[$1.to_i].price.to_s } # Price Armor
    @text.gsub! (/\\IICON\[([0-9]+)\]/i) { "\x10[#{$data_items[$1.to_i].icon_index}]" } # Icon Item
    @text.gsub! (/\\WICON\[([0-9]+)\]/i) { "\x10[#{$data_weapons[$1.to_i].icon_index}]" } # Icon Weapon
    @text.gsub! (/\\AICON\[([0-9]+)\]/i) { "\x10[#{$data_armors[$1.to_i].icon_index}]" } # Icon Armor
    # Retrieve Name
    name = @text[/\\NAME\[.*?\]/i]
    name.sub! (/\\NAME/i, '') unless name == nil
    @text.gsub! (/\\NAME\[.*?\]/i) { "\x09#{name}" } # Name Window
    @text.gsub! (/\\ICON\[([0-9]+)\]/i) { "\x10[#{$1}]" } # Icon
    @text.gsub!(/\\B/i) { "\x11" } # Bold
    @text.gsub!(/\\I/i) { "\x12" } # Italic
    @text.gsub!(/\\SE\[(.+?)\]/i) { "\x13[#{$1}]" } # Sound effect
    # Run original script
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_msg_script_init initialize
  def initialize
    # Run original method
    modalg_msg_script_init
    @letter_timing = Message_Options.default_timing
    @face_sprites = []
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * New Page
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def new_page
    contents.clear
    if $game_message.face_name.empty?
      @contents_x = 0
    else
      @face_sprites.clear
      name = $game_message.face_name.dup
      index = $game_message.face_index
      # Determine if the face is a single graphic
      single = name[/^\$/] != nil
      face = Sprite_MessageFace.new (name, index, 96, single)
      face.x = self.x + 16
      face.y = self.y + 16
      face.visible = true
      @face_sprites.push (face)
      @current_face = 0
      unless name[/\_a$/i] == nil
        name.gsub! (/\_a$/i) {|s| s = '_b'}
        face = Sprite_MessageFace.new (name, index, 96, single)
        face.x = self.x + 16
        face.y = self.y + 16
        @face_sprites.push (face)
      end
      @contents_x = 112
    end
    @contents_y = 0
    @line_count = 0
    @show_fast = false
    @line_show_fast = false
    @pause_skip = false
    contents.font.color = text_color(0)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update Message
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   def update_message
     loop do
      @wait_count = Message_Options.default_timing
      c = @text.slice!(/./m)            # ???????
      case c
      when nil                          # ??????????
        finish_message                  # ????
        break
      when "\x00"                       # ??
        new_line
        if @line_count >= MAX_LINE      # ????????
          unless @text.empty?           # ??????????
            self.pause = true           # ????????
            break
          end
        end
        break
      when "\x01"                       # \C[n]  (?????)
        @text.sub!(/\[([0-9]+)\]/, "")
        contents.font.color = text_color($1.to_i)
        next
      when "\x02"                       # \G  (?????)
        @gold_window.refresh
        @gold_window.open
      when "\x03"                       # \.  (???? 1/4 ?)
        @wait_count = 15
        break
      when "\x04"                       # \|  (???? 1 ?)
        @wait_count = 60
        break
      when "\x05"                       # \!  (????)
        self.pause = true
      when "\x06"                       # \>  (???? ON)
        @letter_timing -= 1
        @letter_timing = 0 if @letter_timing < 0
      when "\x07"                       # \<  (???? OFF)
        @letter_timing += 1
      when "\x08"                       # \^  (??????)
        @pause_skip = true
      when "\x09"                       # \name Name Box
        name = @text[/\[.*?\]/]
        @text.sub!(/\[.*?\]/, "")
        name = name[1, name.size - 2]
        x = self.x + Message_Options.namebox_offset_x
        y = self.y + Message_Options.namebox_offset_y
        @name_window = Window_NameBox.new (x, y, name)
        @name_window.y -= @name_window.height
      when "\x10"                      # \icon Shows an icon
        @text.sub!(/\[([0-9]+)\]/, "")
        draw_icon ($1.to_i, @contents_x, @contents_y)
        @contents_x += 24
        @wait_count += @letter_timing
      when "\x11"                       # \b Bold
        # Toggle Bold
        self.contents.font.bold = self.contents.font.bold ? false : true
      when "\x12"                       # \i Italic           
        # Toggle Italic
        self.contents.font.italic = self.contents.font.italic ? false : true
      when "\x13"                       # \SE[file] Play Sound effect
        # Play sound effect
        @text.sub!(/\[(.*?)\]/, "")
        begin
          RPG::SE.new($1).play
        rescue
        end
      else                              # ?????
        contents.draw_text(@contents_x, @contents_y, 40, WLH, c)
        c_width = contents.text_size(c).width
        @contents_x += c_width
        Sound.play_message_se if Message_Options.message_se_active?
        @wait_count += @letter_timing
        # Switch Facesets
        if Message_Options::ANIMATED_FACESETS && @face_sprites.size > 1
          @face_sprites[@current_face].visible = false
          @current_face += 1
          @current_face %= @face_sprites.size
          @face_sprites[@current_face].visible = true
        end
      end
      break unless @show_fast or @line_show_fast
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Finish Message
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_msg_script_message_fin finish_message
  def finish_message
    # Show initial face
    unless @face_sprites.empty?
      @face_sprites[@current_face].visible = false
      @current_face = 0
      @face_sprites[0].visible = true
    end
    @letter_timing = Message_Options.default_timing
    modalg_msg_script_message_fin
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Terminate Message
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_msg_script_message_term terminate_message
  def terminate_message
    self.contents.font.bold = false
    self.contents.font.italic = false
    modalg_msg_script_message_term
    @face_sprites.each {|face| face.dispose}
    @name_window.dispose unless @name_window.nil? || @name_window.disposed?
    @face_sprites.clear
  end
end

The substitution part work with /\\SE\[(.+?)\]/i as the regular expression. (Line 308)

The code that plays the sound effect is located at lines 417-423
Code: [Select]
when "\x13"                       # \SE[file] Play Sound effect
        # Play sound effect
        @text.sub!(/\[(.*?)\]/, "")
        begin
          RPG::SE.new($1).play
        rescue
        end
The idea here is that we take what's inside the square brackets [] and try to play it assuming it's a valid file.
The begin-rescue-end structure prevents the system from crashing if an non-existing sound is played and instead nothing happens. (No sound)

Should I go more into detail or is this fine?

********
Rep:
Level 96
2011 Most Missed Member2010 Zero To Hero
If it isn't any trouble for you, I would love detail. I grasp the concept but the more in depth you go the more I am sure I can apply to seperate situations. :D

(AND THANKS MUCH)

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Best Member2012 Best RPG Maker User (Scripting)2012 Favorite Staff Member2012 Most Mature MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Best Use Of Avatar And Signature Space2010 Favourite Staff Member
That's a good feature. I'm bad at thinking of good features for scripts.

What do you want more detail on? The begin-rescue-end or the regexp? I'll probably let Zeriab answer anyway because he's better at regexp everything than I am.

I'm still learning after all. Even at the time I wrote that, I didn't understand $1, $2... at all, as is apparent.
Anyway, take a look at the topic in RMRK+ please if you have time. I added that feature, with credit to you two of course, but there are also a ton of other stuff that I added.

*
? ? ? ? ? ? ? ? ? The nice kind of alien~
Rep:
Level 92
Martian - Occasionally kind
That's a good idea Modern ^^
Try to explain in-depth how I make it work.
If you still don't really understand it then it would be much more beneficial to you if you try and explain it. I can always step in afterwards if I see a need.

I am still your teacher after all ;)

*hugs*
 - Zeriab

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Best Member2012 Best RPG Maker User (Scripting)2012 Favorite Staff Member2012 Most Mature MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Best Use Of Avatar And Signature Space2010 Favourite Staff Member
You make life less worth living Zeriab.

I'll start with the regular expression itself:

Code: [Select]
/\\SE\[(.+?)\]/i

\\SE matches the actual characters \SE. A backslash in Regexp identifies a special code and so \\ is an actual backslash. Thus this part of the code searches for instances of \SE in the actual code, and the /i at the end of the code means it is case insensitive, so it will accept \se, or \SE, or \Se or \sE.

The next part of the code:

Code: [Select]
\[(.+?)\]
means that we want \se to be followed by a set of square brackets with something inside them. It will technically accept anything as long as it is not empty ([]) or incomplete ([...) It also means that it will not take anything that is just \SE.

So, what does this mean: (.+?)

Well, the round bracket means, as I have just recently discovered, that whatever the expression turns out to be, it will be saved in $1 (if there were two sets of round brackets, then the first would be saved to $1 and the second to $2. So on for more than 2).

 The . means that any character will be accepted.

The + means that it will take every thing that matches the previous regular expression up to the close bracket as long as there is at least one thing that matches it (since the previous regular expression is . (anything) it means that it will take everything between the brackets. Also, since + is used and not * it means that there has to be at least one thing that matches it before the close square bracket. And that means that \se[] will not match the regular expression since there is nothing that matches the . code). T

he ? means that it is non-greedy. In other words, once it gets to the first ']' it will stop; it will not take as much as it can.

That is actually confusing, so I will explain that part by example. The close bracket would normally be accepted as a character that could be taken by . So take the following string:

"\se[12a4] is [12] and that is a good thing."

Our code would match "\se[12a4]", but the code /\\SE\[(.+)\]/i (without the ?) would match "\se[12a4] is [12]"

Why is that? Because the non-greedy variant means, basically, it will take the smallest string that matches the regular expression. Since there is another ']' in the string, and since everything between the first '[' and the last ']' is matched by the regular expression .+, then both "\se[12a4]" and "\se[12a4] is [12]" could match the regular expression. Greedy takes as much as it can, and non-greedy takes the smallest string that matches the regular expression. In general, greedy takes the longest possible string, and non-greedy takes the shortest

Even explaining it like that makes me feel like I'm saying something confusing. Regular Expression is hard to explain. Read Zeriab's tutorial, as I think all I could have done was confuse you with that.



* Waits for Zeirab to step in
« Last Edit: March 18, 2008, 10:41:38 AM by modern algebra »

*
? ? ? ? ? ? ? ? ? The nice kind of alien~
Rep:
Level 92
Martian - Occasionally kind
Zeirab will not step in  >:(

At least not until you have finished explaining ^^

You have now explained one of the regular expressions. (Yes, I use two different regular expressions)
Well you haven't explained why \[ is used rather than just [, but whatever.
You have explained what it matches. Now what? What happens afterwards? How do we use the match to get something we can use for playing a sound?

Also it might be so that I make your life less worth living. That's a price I am willing to pay to turn you into a great scripter ^^
Well, I would have been willing to pay that price even if there were no benefit >_>
Though this time it's not an attempt to crack you. I am however planning my next attempt you break you down. If you survive you will become an even better scripter :3
And to continue the off-topicness a bit more. Do you know how to use back references in regular expressions?

*hugzors*

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Best Member2012 Best RPG Maker User (Scripting)2012 Favorite Staff Member2012 Most Mature MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Best Use Of Avatar And Signature Space2010 Favourite Staff Member
Well, I have a test in a second, so this explanation will be cut off once ten minutes have passed on my end.

I assume by 2nd regular expression:

Code: [Select]
    @text.gsub!(/\\SE\[(.+?)\]/i) { "\x13[#{$1}]" } # Sound effect

The \xdd (where d are characters) are hex. base 16 (0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 ...) are the characters accepted. I'll be honest here, I performed this conversion because the default scripts do. I am not sure what the benefit really is, aside from the fact that it converts what are multiple characters (\, s, e) into one character that still distinguishes between each of the codes and allows us to keep easy track of it. The rest of the line: gsub! is a method that replaces every instance of the code in round brackets with what is in curly brackets. So every time it matches the code it will replace it with the stuff in curly brackets. Now, for the  { "\x13[#{$1}]" } - This is just a string. To place the value of a variable inside a string you can use the notation #{variable name}, and that is all that is.

Oh, and the reason we use \[ and \] instead of [ and ] is because in Regexp, [ and ] denote a set of letters where any of the things contained can be used. so [abcde] means it would accept a, b, c, d, or e as the next character in the string. Putting the backslash there denotes you want the actual character '['or ']'

As to how this converts into playing an SE when that character comes up:

The letter-by-letter works by taking the current character in a string and interpreting it. It does this through a case branch:

Code: [Select]
      c = @text.slice!(/./m)            # ???????
      case c
      when nil                          # ??????????
        finish_message                  # ????
        break
      when "\x00"                       # ??
        new_line
        if @line_count >= MAX_LINE      # ????????
          unless @text.empty?           # ??????????
            self.pause = true           # ????????
            break
          end
        end
        break
      when "\x01"                       # \C[n]  (?????)
        @text.sub!(/\[([0-9]+)\]/, "")
        contents.font.color = text_color($1.to_i)
        next

etc....

Anyway, here is the benefit of using the hex (at least as far as I can see). If we had not converted it, then it would have taken "\", then "s", then "e" and you'd need to do some weird interpretive stuff before being able to determine what it means. You wouldn't be able to draw character by character really, without doing interpretive work first. However \xdd, is interpreted as a single character, so c = @text.slice! (/./m) gets the hex code and we can then interpret from that

So now we can make our case branch:

When we have our c = to one of these hex codes, we do something special, and if it doesn't match any of them then we just draw it. That is basically what the case branch does.

So the one that we are interested in is:

Code: [Select]
      when "\x13"                       # \SE[file] Play Sound effect
        # Play sound effect
        @text.sub!(/\[(.*?)\]/, "")
        begin
          RPG::SE.new($1).play
        rescue
        end


Alright, have to go now. I'll finish this when I get back on.

EDIT::
Okay, so since we substituted \se for \x13, as we are going through the string we will come to a "\x13", and this is what we have as our case branch. You've seen the first command, kind of. sub! is the same as gsub! but it only replaces the first string that matches the regexp that it comes to, rather than every single one. The part after the comma, the "", just means that it isn't replaced with anything; essentially we just want to delete it.

You've seen this regexp before: it is the exact same as the one we initially found. We are again extracting the characters within the brackets and they are put in $1.

RPG::SE.new($1).play - means that an SE object is created from the name given in the square brackets and then played. Thus, the point of the new code is executed here

Normally, if the name written in the brackets was not a file in the SE folder, then the game would break. What the rescue does (I think) is that if, while the begin is being run, an exception is thrown (and trying to access a non-existent file will throw an exception), the rescue traps it. You could make the rescue print something else if you wanted it to, by writing something like rescue "File does not exist", but we don't really want to do that because nobody wants their game to be interrupted by an ugly print statement unless they have dedicated testers who will be sure to try and break the game in every way possible and thus find these errors when they occur*.

Anyway, this was very long. I'm probably not entirely correct on some things (or at all) but hopefully I am. But don't worry about understanding everything I've said yet anyway. For a lot of scripts (some quite complicated), this stuff is unnecessary. It may look complicated right now, but soon enough it will become much easier to work with even if you still aren't sure what it all means. As well, I'm just plain bad at explaining things. For a beginning scripter, I think it is probably best to start by working with windows and scenes.

* PeopleTest.exist? (Dedicated Testers) = false.
« Last Edit: March 18, 2008, 06:45:14 PM by modern algebra »

*
? ? ? ? ? ? ? ? ? The nice kind of alien~
Rep:
Level 92
Martian - Occasionally kind
/\\SE\[(.+?)\]/i
/\[(.*?)\]/

They are two different regular expressions ;)

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Best Member2012 Best RPG Maker User (Scripting)2012 Favorite Staff Member2012 Most Mature MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Best Use Of Avatar And Signature Space2010 Favourite Staff Member
Well, I suppose. We don't need to take the \x13 since it's already been removed from the text (that's how we identified the special code) and \SE was replaced by that, so that the string we are left with has this left:

[SE Name]

 We don't want to draw this, so we remove it from the string completely by using this code:

Code: [Select]
/\[(.*?)\]/

It does not need to be case insensitive, because there are no letters there that we need to have, so that's why it does not end in i. Further, since we know that there is at least something inside the brackets (our previous regexp would not have replaced it with \x13 otherwise, because of the + operator), we can use the * operator which accepts the match if 0 or more of the previous regular expression is matched (whereas + matches only if there is at least one of the previous regular expression in the string. The non-greedy operator ? is still required because @text is a string that encompasses all of the message texts after the character we are currently on (meaning that there is the possibility there is another ']' in it somewhere)

That covers it I think.

It made me realize something though - in my message script, I use the regexp /\\AC\[(\d+?)\]/i and similar constructions frequently. But the non-greedy operator is unnecessary since ']' is not a digit. Anyway, I hoped that helped Arrow.