질문과 답변

Extra Form

    #==============================================================================
    #    ATS: Face Options
    #    Version: 1.0.3
    #    Author: modern algebra (rmrk.net)
    #    Date: 20 July 2013
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  Description:
    #    
    #    This script allows you to control the face settings of a message. Not only
    #   can you now give faces a talking animation and a blinking animation, but
    #   this also lets you use bigger facesets, to set the faceset based on actor
    #   ID or party ID, to encapsulate faces in their own windows, to set its
    #   position, to fade it in or scroll it in, and much more. For a complete list
    #   of features, be sure to read the Instructions starting at line 30 as well
    #   as the Editable Region starting at line 176.
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  ATS Series:
    #
    #    This script is part of the Advanced Text System series of scripts. These
    #   scripts are based off the Advanced Text System for RMVX, but since RMVX Ace
    #   has a much more sensibly designed message system, it is no longer necessary
    #   that it be one large script. For that reason, and responding to feedback on
    #   the ATS, I have split the ATS into multiple different scripts so that you
    #   only need to pick up the components for the features that you want. It is
    #   therefore easier to customize and configure.
    #
    #    To find more scripts in the ATS Series, please visit:
    #      http://rmrk.net/index.php/topic,44525.0.html
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  Instructions:
    #    
    #    Paste this script into its own slot in the Script Editor, above Main but
    #   below Materials.
    #
    #    ~Animated Faces~
    #
    #    For talking animations, you need to do two things. Firstly, the
    #   :animate_faces setting must be set to true. Secondly, the name of the
    #   faceset must include the following code:
    #
    #        %[n]
    #
    #   where n is the number of poses in the animation. Ex: a faceset named
    #   "Actor1%[4]" would have 4 poses. Starting from the selected index, the
    #   face would show the first pose, then the second, then the third, then the
    #   fourth, and then back to the first to repeat. You set the speed at which it
    #   animates by changing the :chars_per_face setting.
    #
    #    To set a blinking animation, it does not matter whether :animate_faces is
    #   true, and you do not need to use special filenames. Rather, you simply need
    #   to identify a blink face. This can be done in two ways. First, you can do
    #   it in a script call before the message. The important settings are
    #   :blink_face_name and :blink_face_index. Where filenames can be long, it is
    #   best to set it to a local variable first, like so:
    #
    #        n = "Actor1"
    #        ats_next(:blink_face_name, n)
    #        ats_next(:blink_face_index, 5)
    #
    #   Naturally, "Actor1" is the name of the faceset which houses the blinking
    #   pose, and the index is 5 (so second row, second column). If the blinking
    #   pose is located within the same faceset as the normal pose, then you only
    #   need to set the :blink_face_index.
    #
    #    The second way to do it is with the following message code, included at
    #   the very start of the message:
    #
    #      \fb{"Actor1", 5}
    #
    #   Again, change "Actor1" to whatever name you want the face to be, and 5 to
    #   whatever index. Similarly, you can exclude the filename if it is the same
    #   as the regular pose.
    #
    #    You can change the rate at which the face blinks by changing the
    #   :frames_between_blinks and :frames_to_blink message settings. Read about
    #   them at lines 185-189.
    #
    #    Finally, blinking also works with a talking animation, so if you are using
    #   a talking animation it is a good idea to have a full set of blinking poses
    #   as well. However, if you have only one, be sure that it is not in a faceset
    #   identified as a talking animation (i.e. one with a %[n] code).
    #
    #
    #    ~Large Faces~
    #
    #    For large faces, you can of course make a set of 8. However, if you want
    #   to save each file separately, you can just make the very first character of
    #   the filename a $. In other words, an image saved as "Actor3-3" would be a
    #   regular faceset of 8 poses, while an image saved as "$Actor3-3" would be
    #   an image holding only a single large face. If a file has both $ and %[n]
    #   in its name, then it will treat it as a faceset with n poses, all aligned
    #   horizontally. In other words, "$Actor3-3%[2]" would be a set with two
    #   faces in, the first half of the image with one pose and the second with the
    #   second pose. Naturally, it will animate if used in a message, so this
    #   should only be done for large face talking animations.
    #
    #    You set large faces just as you would a normal face. If you want the whole
    #   thing to be shown, you should make sure that the :face_width and
    #   :face_height settings are both set to -1. If, on the other hand, you want
    #   only to cut out the centre of the large face, you can change those values
    #   to whatever proportions you want. So, for instance, setting :face_width to
    #   128 and face_height to 160 would cut out a 128x160 section of the face and
    #   show that.
    #
    #
    #    ~All Other Face Settings~
    #
    #    There are a lot of configuration options in this script, and I direct you
    #   to the Editable Region at line 176 for detailed comments on what each does
    #   Here, I will just list them:
    #
    #          :animate_faces                     :face_scroll_x
    #          :chars_per_face                    :face_scroll_y
    #          :frames_between_blinks             :face_scroll_speed
    #          :frames_to_blink                   :face_fadein
    #          :blink_face_name                   :face_fade_speed
    #          :blink_face_index                  :face_opacity
    #          :face_x                            :face_blend_type
    #          :face_x_offset                     :face_match_screen_tone
    #          :face_y                            :face_tone
    #          :face_y_offset                     :face_window
    #          :face_width                        :face_padding
    #          :face_height                       :face_win_opacity
    #          :face_mirror                       :face_win_back_opacity
    #          :face_overlap_allowed
    #
    #    As with other ATS scripts, you can change the value of these options in
    #   game with the following codes in a script call:
    #
    #      ats_next(:message_option, x)
    #      ats_all(:message_option, x)
    #
    #   Where :message_option is the symbol you want and x is the value you want
    #   to change it to. ats_next will only change it for the very next message,
    #   while ats_all will change it for every message to follow.
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  List of Special Message Codes:
    #
    #    The following is a complete list of the message codes at your disposal.
    #   Simply insert them into a Display Message command.
    #
    # \f{"filename":n} - set face to the one in "filename" at index n.
    # \f{n}  - set face to the pose at index n within the current faceset.
    # \fb{"filename":n} - set blink face to the one in "filename" at index n.
    # \fb{n} - set blink face to the pose at index in within the current faceset.
    # \af[n] - set face to the face of the actor with ID n in the database.
    # \mf[n] - set face to the face of party member in index n. 1 is the leader.
    # \fa[n] - plays animation with ID n on the face.
    # \fam[n] - plays a mirror of animation with ID n on the face.
    # \fx[n] - sets :face_x to n, where n is: L, C, R, or an integer. See line 198.
    # \fy[n] - sets :face_y to n, where n is: A, U, T, C, B, D, or an integer. See
    #         line 207.
    # \fw    - turns :face_window to true for this message. See line 273.
    # \fm    - turns :face_mirror to true for this message. See line 255.
    # \ff    - turns :face_fadein to true for this message. See line 251.
    # \fsx   - turns :face_scroll_x to true for this message. See line 242.
    # \fsy   - turns :face_scroll_y to true for this message. See line 245.
    #==============================================================================
     
    $imported = {} unless $imported
    $imported[:MA_ATS_FaceOptions] = true
     
    #==============================================================================
    # ** Game_ATS
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  Summary of Changes:
    #    new public instance variables - animate_faces; chars_per_face;
    #      frames_between_blinks; frames_to_blink; face_x; face_y; face_x_offset;
    #      face_y_offset; face_width; face_height; face_scroll_x; face_scroll_y;
    #      face_scroll_speed; face_fadein; face_fade_speed; face_mirror;
    #      face_opacity; face_blend_type; face_tone; face_window; face_padding;
    #      face_win_opacity; face_win_back_opacity; face_overlap_allowed;
    #      blink_face_name; blink_face_index
    #==============================================================================
     
    class Game_ATS
      CONFIG ||= {}
      CONFIG[:ats_face_options] = {
              ats_face_options: true,
        #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
        #  EDITABLE REGION
              #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
        #    ~Face Animation Settings~
        #
        #  :animate_faces - true or false. Set this to true if you want faces to
        # animate. Set it to false if you don't, but that should be rare since only
        # faces with a %[n] code will animate, where n is the number of frames in
        # the animation. No other faceset will animate. As such, this option should
        # only ever be set to false if you only want a single pose from a faceset
        # which with a %[n] code.
        animate_faces:         true,
        #  :chars_per_face - integer. When animating a face, this sets how many
        # letters should be drawn before switching to the next frame.
        chars_per_face:        4,
        #  :frames_between_blinks - x...y; x & y both integers. If using a blink
        # face, the time between blinks in frames. There are 60 frames in 1 second.
        frames_between_blinks: 180..300,
        #  :frames_to_blink - integer. Number of frames to show the blinking face.
        frames_to_blink:       12,
        #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
        #    ~Face Position and Size~
        #
        #  :face_x - integer, :L, :C, or :R. The X coordinate of the face. If an
        # integer, the face's x-coordinate is set directly to that position. You
        # can also set it so that it is automatically positioned according to the
        # position of the message window. If you set it to :L, it will be at the
        # left end of the message window, and if you set it to :R it will be at the
        # right end of the message window. If you set it to :C, it will be centred,
        # but naturally that setting should only ever be used if the Y position of
        # the face does not overlap with the message window.
        face_x:                :R,
        #  :face_y - integer, :A, :U, :T, :C, :B, or :D. The Y coordinate of the
        # face. If an integer, the face's y-coordinate is set directly to that
        # position. You can also set it so that it is automatically positioned
        # according to the position of the message window. If you set it to :U (Up),
        # the bottom of the face will be flush with the top border of the message
        # window. If you set it to :T (Top), then the top of the face will be flush
        # with the top border of the message window. If you set it to :C (Centre),
        # then the centre of the face will match the centre of the message window.
        # If you set it to :B (Bottom), then the bottom border of the face will be
        # flush with the bottom border of the message window. If you set it to
        # :D (Down), then the top of the face will be flush with the bottom border
        # of the message window. Finally, if you set it to :A (Automatic), then it
        # will be :C if the face is smaller than the message window, and otherwise
        # it will be :T if the message window is in the upper portion of the screen
        # or :B if the message window is in the lower portion of the screen. The
        # recommended value is :C if you are using regular facesets or :A if you
        # are using large facesets.
        face_y:                :B,
        #  :face_x_offset - integer. If using an automatic setting for :face_x,
        # this is added or subtracted from the x placement, as appropriate.
        face_x_offset:         0,
        #  :face_y_offset - integer. If using an automatic setting for :face_y,
        # this is added or subtracted from the y placement, as appropriate.
        face_y_offset:         0,
        #  :face_width - integer. The horizontal size of the face. If -1, it will
        # be set to the width of the face used. If less than the width of the face
        # used, it will take as much of the centre of the face as possible
        face_width:            0,
        #  :face_height - integer. The vertical size of the face. If -1, it will be
        # set to the height of the face used. If less than the height of the face
        # used, it will take as much of the centre of the face as possible
        face_height:           0,
        #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
        #    ~Face Settings~
        #
        #  :face_scroll_x - true or false. Whether the face should scroll in to
        # place horizontally
        face_scroll_x:         false,
        #  :face_scroll_y - true or false. Whether the face should scroll in to
        # place vertically
        face_scroll_y:         false,
        #  :face_scroll_speed - integer. The number of frames it takes to scroll
        # into position.
        face_scroll_speed:     15,
        #  :face_fadein - true or false. Whether face should fade in gradually.
        face_fadein:           true,
        #  :face_fade_speed - integer. The number of frames it takes to fade in.
        face_fade_speed:       1,
        #  :face_mirror - true or false. Whether the face should be flipped to face
        # the opposite direction.
        face_mirror:           false,
        #  :face_opacity - 0-255. The degree of transparancy of the face.
        face_opacity:          255,
        #  :face_blend_type - 0-2. 0 => Normal; 1 => Add; 2 => Subtract. This
        # should almost always be set to 0 as either other option changes the face
        # dramatically. However, it can be used for a ghost or darkness effect.
        face_blend_type:       0,
        #  :face_match_screen_tone - true or false. If true, the tone of the face
        # will be the same as that of the screen unless you set :face_tone to
        # something other than nil. Otherwise there will be no automatic setting.
        face_match_screen_tone: false,
        #  :face_tone - Tone.new(-255 - 255, -225 - 255, -255 - 255, -255 - 255) -
        # This allows you to blend a tone with the face. The values are
        # (red, green, blue, gray). It should usually be set to nil, but might be
        # useful for flashbacks or lighting effects, etc...
        face_tone:             nil,
        #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
        #    ~Face Window Settings~
        #
        #  :face_window - true or false. If true, face shown in its own window
        face_window:           false,
        #  :face_padding - integer. If using window, the size of the border.
        face_padding:          6,
        #  :face_win_opacity - 0-255. The total opacity of the face window
        face_win_opacity:      255,
        #  :face_win_back_opacity - 0-255. The back opacity of the face window
        face_win_back_opacity: 192,
        #  :face_overlap_allowed - true or false. If false, this will not permit
        # any overlap between the face's window and the regular window, and it
        # will resize the message window to avoid it. It should not be used unless
        # you are using either a flush left or flush right placement for the face
        # window. Recommended value is true.
        face_overlap_allowed:  true,
        
        face_scroll_side:      :R,
              #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
        #  END EDITABLE REGION
        #////////////////////////////////////////////////////////////////////////
        blink_face_name:       "",
        blink_face_index:      -1,
      }
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Public Instance Variables
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CONFIG[:ats_face_options].keys.each { |key| attr_accessor key }
    end
     
    #==============================================================================
    #  Initialize Common ATS Data if no other ATS script interpreted first
    #==============================================================================
     
    if !$imported[:AdvancedTextSystem]
      #============================================================================
      # *** DataManager
      #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      #  Summary of Changes:
      #    aliased method - create_game_objects; make_save_contents;
      #      extract_save_contents
      #============================================================================
      module DataManager
        class << self
          alias modb_ats_crtgmobj_6yh7 create_game_objects
          alias mlba_ats_mksave_5tg9 make_save_contents
          alias ma_ats_extrcsvcon_8uj2 extract_save_contents
        end
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # * Create Game Objects
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        def self.create_game_objects(*args, &block)
          modb_ats_crtgmobj_6yh7(*args, &block)
          $game_ats = Game_ATS.new
          $game_ats.init_new_installs
        end
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # * Make Save Contents
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        def self.make_save_contents(*args, &block)
          contents = mlba_ats_mksave_5tg9(*args, &block)
          contents[:ats] = $game_ats
          contents
        end
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # * Extract Save Contents
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        def self.extract_save_contents(contents, *args, &block)
          ma_ats_extrcsvcon_8uj2(contents, *args, &block)
          $game_ats = contents[:ats] ? contents[:ats] : Game_ATS.new
          $game_ats.init_new_installs
        end
      end
     
      #============================================================================
      # ** Game_ATS
      #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      #  This class holds the default data for all scripts in the ATS series
      #============================================================================
     
      class Game_ATS
        def initialize; reset; end
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # * Reset any or all installed ATS scripts
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        def reset(script_name = nil)
          if script_name.is_a? (Symbol) # If script to reset specified
            CONFIG[script_name].each_pair { |key, value|
              self.send("#{key}=".to_sym, value)
              $game_message.send("#{key}=".to_sym, value)
            }
          else                          # Reset all ATS scripts
            CONFIG.keys.each { |script| reset(script) }
          end
        end
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # * Initialize any newly installed ATS scripts
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        def init_new_installs
          CONFIG.keys.each { |script| reset(script) unless self.send(script) }
        end
      end
     
      #============================================================================
      # ** Game_Message
      #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      #  Summary of Changes:
      #    aliased method - clear
      #============================================================================
     
      class Game_Message
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # * Clear
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        alias mlb_ats_clrats_5tv1 clear
        def clear(*args, &block)
          mlb_ats_clrats_5tv1(*args, &block) # Run Original Method
          return if !$game_ats
          Game_ATS::CONFIG.values.each { |installed|
            installed.keys.each { |key| self.send("#{key}=".to_sym, $game_ats.send(key)) }
          }
        end
      end
     
      #============================================================================
      # ** Game_Interpreter
      #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      #  Summary of Changes:
      #    new methods - ats_all; ats_next
      #============================================================================
     
      class Game_Interpreter
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # * ATS All
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        def ats_all(sym, *args, &block)
          $game_ats.send("#{sym}=".to_sym, *args, &block)
          ats_next(sym, *args, &block)
        end
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # * ATS Next
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        def ats_next(sym, *args, &block)
          $game_message.send("#{sym}=".to_sym, *args, &block)
        end
      end
     
      $imported[:AdvancedTextSystem] = true
    end
     
    #==============================================================================
    # ** Game_Message
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  Summary of Changes:
    #    new public instance variables - animate_faces; chars_per_face;
    #      frames_between_blinks; frames_to_blink; face_x; face_y; face_x_offset;
    #      face_y_offset; face_width; face_height; face_scroll_x; face_scroll_y;
    #      face_scroll_speed; face_fadein; face_fade_speed; face_mirror;
    #      face_opacity; face_blend_type; face_tone; face_window; face_padding;
    #      face_win_opacity; face_win_back_opacity; face_overlap_allowed;
    #      blink_face_name; blink_face_index
    #==============================================================================
     
    class Game_Message
      Game_ATS::CONFIG[:ats_face_options].keys.each { |key| attr_accessor key }
    end
     
    #==============================================================================
    # ** Sprite_ATS_Face
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  This sprite shows a face graphic for messages.
    #==============================================================================
     
    class Sprite_ATS_Face < Sprite_Base
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Public Instance Variable
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      attr_reader :num_frames
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Object Initialization
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def initialize(viewport = nil)
        super(viewport)
        self.bitmap = Bitmap.new(96, 96)
        @num_frames = 1
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Free
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def dispose(*args)
        bitmap.dispose if bitmap && !bitmap.disposed?
        super(*args)
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Setup
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def setup(faces, blink_faces = [])
        if faces.empty? # No Face
          bitmap.clear  
          @num_frames = 1                                        # Clear Bitmap
        else
          bitmap.dispose if bitmap && !bitmap.disposed?          # Dispose old bitmap
          rect = Rect.new(0, 0, faces[0].width, faces[0].height) # Set Rect
          # Create Bitmap
          h = blink_faces.empty? ? rect.height : rect.height*2
          self.bitmap = Bitmap.new(rect.width*faces.size, h)
          @num_frames = faces.size
          # Draw all faces onto the bitmap
          for i in 0...@num_frames
            x = i*rect.width
            bitmap.blt(x, 0, faces[i], rect)
            bitmap.blt(x, rect.height, blink_faces[i % blink_faces.size], rect) if !blink_faces.empty?
          end
          src_rect.set(rect) # Set Source Rect
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Set Face Frame
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def set_column(index = 0)
        src_rect.x = index*src_rect.width
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Set Face Frame
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def set_row(index = 0)
        src_rect.y = index*src_rect.height
      end
    end
     
    #==============================================================================
    # ** Window_ATS_Face
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  This window displays a face graphic for messages.
    #==============================================================================
     
    class Window_ATS_Face < Window_Base
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Create Face
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def create_face(face_name, face_index)
        contents.clear
        draw_face(face_name, face_index, 0, 0)
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Draw Face Graphic
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def draw_face(face_name, face_index, x, y, enabled = true, *args)
        bmp = Cache.face(face_name)
        fw, fh = bmp.width, bmp.height
        if face_name[/\A\$/] != nil # SINGLE
          if face_name[/\%\[\s*(\d+)\s*\]/] != nil
            fw /= $1.to_i
          else
            face_index = 0
          end
          cw, ch = contents.width - x, contents.height - y
          rect = Rect.new((face_index*fw) + ((fw - cw) / 2), (fh - ch) / 2, cw, ch)
          contents.blt(x, y, bmp, rect, enabled ? 255 : translucent_alpha)
        else
          fw /= 4
          fh /= 2
          rect = Rect.new(face_index % 4 * fw, face_index / 4 * fh, fw, fh)
          contents.blt(x, y, bmp, rect, enabled ? 255 : translucent_alpha)
        end
        bmp.dispose
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Resize Window
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def resize(w, h)
        self.width = w + (standard_padding*2)
        self.height = h + (standard_padding*2)
        create_contents
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Standard Padding
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def standard_padding
        $game_message.face_padding
      end
    end
     
    #==============================================================================
    # ** Spriteset_ATS_Face
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  This class creates and control the window and sprite for showing faces
    #==============================================================================
     
    class Spriteset_ATS_Face
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Public Instance Variables
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      attr_reader   :face_window
      attr_reader   :face_sprite
      attr_reader   :x
      attr_reader   :y
      attr_reader   :z
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Object Initialization
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def initialize(message_window, viewport = nil)
        @message_window = message_window
        @face_window = Window_ATS_Face.new(0, 0, 120, 120)
        @face_sprite = Sprite_ATS_Face.new(viewport)
        if $game_message.face_scroll_side == :L
          self.x, self.y = 0, 0
        else
          self.x = Graphics.width - @face_sprite.width
          self.y = Graphics.height - @face_sprite.height 
        end
        @dest_x, @dest_y = 0, 0
        @dest_scroll_x_speed, @dest_scroll_y_speed = 0, 0
        @dest_sprite_opacity, @dest_window_opacity = 0, 0
        @dest_s_fade_speed, @dest_w_fade_speed = 0, 0
        self.z = message_window.z - 1
        clear
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Free
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def dispose
        @face_window.dispose
        @face_sprite.dispose
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Update
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def update
        @face_sprite.update
        @face_window.update
        @face_window.visible = !empty? && $game_message.face_window
        @face_sprite.visible = @face_window.open? if @face_window.visible
        update_scroll
        update_fade
        update_blink
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Update Scroll
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def update_scroll
        # Scroll X
        if @dest_x > self.x
          self.x = [self.x + @dest_scroll_x_speed, @dest_x].min
        elsif @dest_x < self.x
          self.x = [self.x + @dest_scroll_x_speed, @dest_x].max
        end
        # Scroll Y
        if @dest_y > self.y
          self.y = [self.y + @dest_scroll_y_speed, @dest_y].min
        elsif @dest_y < self.y
          self.y = [self.y + @dest_scroll_y_speed, @dest_y].max
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Update fade
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def update_fade
        if @dest_sprite_opacity != @face_sprite.opacity
          @face_sprite.opacity += @dest_s_fade_speed
          @face_sprite.opacity = @dest_sprite_opacity if @face_sprite.opacity > @dest_sprite_opacity
        end
        if @dest_window_opacity != face_window.opacity
          @face_window.opacity += @dest_w_fade_speed
          @face_window.opacity = @dest_window_opacity if @face_window.opacity > @dest_window_opacity
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Update Blink
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def update_blink
        if blinking?
          @blink_timer -= 1
          if @blink_timer <= 0
            @blink_status = (@blink_status + 1) % 2
            @face_sprite.set_row(@blink_status)
            @blink_timer = case @blink_status
            when 0
              fbb = $game_message.frames_between_blinks
              fbb.first + rand(fbb.last - fbb.first)
            when 1 then $game_message.frames_to_blink
            end
          end
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Clear
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def clear
        @face_name, @face_index, @blink_face_name, @blink_face_index = "", 0, "", 0
        @face_width, @face_height = 0, 0
        @active_face = -1
        @blink_status, @blink_timer = 0, 0
        @face_sprite.setup([])
        hide
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Refresh
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def refresh(face_name = @face_name, face_index = @face_index)
        @face_name, @face_index = face_name, face_index
        @blink_face_name, @blink_face_index = $game_message.blink_face_name, $game_message.blink_face_index
        return if empty?
        # If blink face partially set, set the other aspect.
        if $game_message.blink_face_index >= 0 && $game_message.blink_face_name.empty?
          $game_message.blink_face_name = face_name
        elsif !$game_message.blink_face_name.empty? && $game_message.blink_face_index < 0
          $game_message.blink_face_index = 0
        end
        @face_width = $game_message.face_width + $game_message.face_padding
        @face_height = $game_message.face_height + $game_message.face_padding
        resize_face(face_name, face_index)
        @face_sprite.setup(collect_faces, collect_faces($game_message.blink_face_name, $game_message.blink_face_index))
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Setup
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def setup(face_name = $game_message.face_name, face_index = $game_message.face_index)
        need_refresh = (@face_name != face_name || @face_index != face_index ||
          @blink_face_name != $game_message.blink_face_name ||
          @blink_face_index != $game_message.blink_face_index ||
          @face_width != ($game_message.face_width + $game_message.face_padding) ||
          @face_height != ($game_message.face_height + $game_message.face_padding))
        refresh(face_name, face_index) if need_refresh
        unless empty?
          @message_window.restore_overlap_width
          update_placement
          @message_window.adjust_placement_for_face
          #@face_sprite.opacity = $game_message.face_opacity #optional
          @face_window.opacity = $game_message.face_win_opacity
          # Only Scroll and Fade if a new face
          if need_refresh
            setup_scroll
            setup_fade
          end
          @face_sprite.mirror = $game_message.face_mirror
          @face_sprite.blend_type = $game_message.face_blend_type
          # Set Tone
          case $game_message.face_tone
          when Tone then @face_sprite.tone.set($game_message.face_tone)
          when Array then @face_sprite.tone.set(*$game_message.face_tone)
          else
            ($game_message.face_match_screen_tone ?
              @face_sprite.tone.set($game_map.screen.tone) :
              @face_sprite.tone.set(0, 0, 0, 0))
          end
          @face_window.back_opacity = $game_message.face_win_back_opacity
          fbb = $game_message.frames_between_blinks
          @blink_status = 0
          @blink_timer = fbb.first + rand(fbb.last - fbb.first)  
          show
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Setup Scroll
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def setup_scroll
        if $game_message.face_scroll_x
          self.x = (self.x + @face_window.width) > (Graphics.width - self.x) ?
            Graphics.width-@face_window.width : Graphics.width-@face_window.width-15
          @dest_scroll_x_speed = (@dest_x - self.x) / $game_message.face_scroll_speed
        end
        if $game_message.face_scroll_y
          self.y = (self.y + @face_window.height) > (Graphics.height - self.y) ?
            Graphics.height : -@face_window.height
          @dest_scroll_y_speed = (@dest_y - self.y) / $game_message.face_scroll_speed
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Setup Fade
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def setup_fade
        if $game_message.face_fadein
          @face_sprite.opacity = 0
          @face_window.opacity = 0
          @dest_sprite_opacity = $game_message.face_opacity
          @dest_window_opacity = $game_message.face_win_opacity
          @dest_s_fade_speed = @dest_sprite_opacity / $game_message.face_fade_speed
          @dest_w_fade_speed = @dest_window_opacity / $game_message.face_fade_speed
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Collect Faces
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def collect_faces(face_name = @face_name, face_index = @face_index)
        return [] if !face_name || face_name.empty?
        faces = []
        # If face_file has animation code, add each frame
        num = $game_message.animate_faces && face_name[/\%\[\s*(\d+)\s*\]/] ? $1.to_i : 1
        for i in face_index...(face_index + num)
          @face_window.create_face(face_name, i)
          faces.push(@face_window.contents.dup)
        end
        @face_window.contents.clear
        return faces.compact
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Resize Face
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def resize_face(face_name, face_index = 0)
        # Get set size
        wdth, hght = $game_message.face_width, $game_message.face_height
        face = Cache.face(face_name)
        fw, fh = face.width, face.height
        face.dispose
        # Adjust face width and height if faceset not single
        if face_name[/\A\$/] == nil
          fw /= 4
          fh /= 2
        else
          fw /= $1.to_i if face_name[/\%\[\s*(\d+)\s*\]/]
        end
        wdth = wdth <= 0 ? fw : [fw, wdth].min
        hght = hght <= 0 ? fh : [fh, hght].min
        @face_window.resize([wdth, $game_message.face_width].max, [hght, $game_message.face_height].max)
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Update Position
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def update_placement
        set_x_placement
        set_y_placement
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Set X Position
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def set_x_placement
        # Update X
        side_offset = $game_message.face_x_offset
        side_offset += (@message_window.padding - $game_message.face_padding)
        @dest_x = case $game_message.face_x
        when Integer then $game_message.face_x - ($game_message.face_window ? 0 : $game_message.face_padding)
        when :l, :L then @message_window.x + side_offset
        when :c, :C then @message_window.x + ((@message_window.width -
          @face_window.width) / 2) + $game_message.face_x_offset
        when :r, :R then @message_window.x + @message_window.width -
          @face_window.width - side_offset
        end
        self.x = @dest_x unless $game_message.face_scroll_x
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Set Y Position
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def set_y_placement
        # Update Y
        fy = $game_message.face_y
        fy = fy.to_s.upcase.to_sym if fy.is_a?(Symbol)
        # Automatic Set
        if fy == :A
          if @face_window.height <= @message_window.height
            fy = :C # Centre if face smaller than message window
          elsif @message_window.y < (Graphics.height - @message_window.height) / 2
            fy = :T # Align with Top if message window above mid-screen
          else
            fy = :B # Align with Bottom otherwise
          end
        end
        w_pad = ($game_message.face_window ? 0 : $game_message.face_padding)
        @dest_y = case fy
        when Integer then fy - w_pad
        when :U, :AT then @message_window.y - @face_window.height +
          $game_message.face_y_offset + w_pad
        when :T, :BT then @message_window.y + $game_message.face_y_offset - w_pad
        when :C then @message_window.y + ((@message_window.height -
          @face_window.height) / 2) + $game_message.face_y_offset
        when :B, :AB then @message_window.y + @message_window.height -
          @face_window.height - $game_message.face_y_offset + w_pad
        when :D, :BB then @message_window.y + @message_window.height -
          $game_message.face_y_offset - w_pad
        end
        self.y = @dest_y unless $game_message.face_scroll_y
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Empty?
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def empty?
        @face_name.empty?
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Animate Face?
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def animate_face?
        !empty? && ($game_message.animate_faces && @face_sprite.src_rect.width < @face_sprite.bitmap.width)
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Blinking?
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def blinking?
        !empty? && ($game_message.blink_face_name && !$game_message.blink_face_name.empty?)
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Scrolling?
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def scrolling?
        !empty? && ((@dest_x != self.x) || (@dest_y != self.y))
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Fading
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def fading?
        !empty? && ((@dest_sprite_opacity != @face_sprite.opacity) || (@dest_window_opacity != face_window.opacity))
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Next Face
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def draw_next_face(direct = nil)
        return if @active_face == direct
        @active_face = direct ? direct : (@active_face + 1) % @face_sprite.num_frames
        @face_sprite.set_column(@active_face)
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Screen Ranges
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def screen_ranges
        fx, fw = @dest_x, @face_window.width
        fy, fh = @dest_y, @face_window.height
        unless  $game_message.face_window
          fx += @face_window.padding
          fy += @face_window.padding
          fw -= 2*@face_window.padding
          fh -= 2*@face_window.padding
        end
        return (fx...(fx + fw)), (fy...(fy + fh))
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Show / Hide
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def show
        @face_sprite.visible = true
        @face_window.visible = $game_message.face_window
        if !@message_window.open?
          @face_window.openness = 0
          @face_window.open
        end
      end
      def hide
        @face_sprite.visible = false
        @face_window.visible = false
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Check if Visible?
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def visible?
        @face_sprite.visible || @face_window.visible
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Set X, Y
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      [:x, :y].each { |writer|
        define_method(:"#{writer}=") do |val|
          instance_variable_set(:"@#{writer}", val)
          @face_window.send(:"#{writer}=", val)
          @face_sprite.send(:"#{writer}=", val + $game_message.face_padding)
        end
      }
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Set Z
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def z=(val)
        @z = val - 1
        @face_window.z = val
        @face_sprite.z = val - 1
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Method Missing
      #    If method missing, call it on either sprite or window
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def method_missing(meth, *args, &block)
        # Face Sprite Check
        if @face_sprite && @face_sprite.respond_to?(meth)
          return @face_sprite.send(meth, *args, &block)
        # Face Window
        elsif @face_window && @face_window.respond_to?(meth)
          return @face_window.send(meth, *args, &block)
        else
          super
        end
      end
    end
     
    #==============================================================================
    # ** Window_ChoiceList
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  Summary of Changes:
    #    aliased method - update_placement
    #    new method - screen_ranges
    #==============================================================================
     
    class Window_ChoiceList
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Update Placement
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      alias maatsfo_updplacm_6yh2 update_placement
      def update_placement(*args)
        maatsfo_updplacm_6yh2(*args)
        @message_window.adjust_choice_placement_for_face
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Screen Ranges
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      unless method_defined?(:screen_ranges)
        def screen_ranges
          return ((self.x + self.padding)...(self.x + self.width - self.padding)),
            ((self.y + self.padding)...(self.y + self.height - self.padding))
        end
      end
    end
     
    #==============================================================================
    # ** Window_ATS_Name (compatibility with ATS: Message Options)
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  Summary of Changes:
    #    new method - screen_ranges
    #==============================================================================
     
    class Window_ATS_Name < Window_Base
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Screen Ranges
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      unless method_defined?(:screen_ranges)
        def screen_ranges
          return ((self.x + self.padding)...(self.x + self.width - self.padding)),
            ((self.y + self.padding)...(self.y + self.height - self.padding))
        end
      end
    end
     
    #==============================================================================
    # ** Window_Message
    #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  Summary of Changes:
    #    aliased methods - create_all_windows; new_page; process_escape_character
    #    overwritten method - draw_face
    #==============================================================================
     
    class Window_Message
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Create All Windows
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      alias maatsfo_creatwins_3hn6 create_all_windows
      def create_all_windows(*args, &block)
        maatsfo_creatwins_3hn6(*args, &block) # Call Original Method
        @atsfo_face = Spriteset_ATS_Face.new(self)
        @atsmo_all_windows.push(@atsfo_face.face_window) if $imported[:ATS_MessageOptions]
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Update All Windows
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      alias maatsfo_updatewins_8jv3 update_all_windows
      def update_all_windows(*args, &block)
        maatsfo_updatewins_8jv3(*args, &block)
        @atsfo_face.update
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Dispose All Windows
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      alias maatsfo_disposallwins_6xq1 dispose_all_windows
      def dispose_all_windows(*args, &block)
        maatsfo_disposallwins_6xq1(*args, &block)
        @atsfo_face.dispose
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Update Placement
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      alias maatsfo_update_placement update_placement
      def update_placement(*args)
        restore_overlap_width
        maatsfo_update_placement(*args) # Call Original Method
        # Remove AF or PF code and process it
        text = $game_message.all_text.dup
        process_face_setting_codes(text)
        while text.slice!(/\A\\([AM]?FB?)(\[\d+\]|{\s*['"]?.*?['"]?[\s,;:]*\d*\s*})/i) != nil
         process_face_code($1, $2)
       end
       @atsfo_face.setup
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Restore Overlap Width
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     def restore_overlap_width
       if @overlap_width_adjust
         self.x = @overlap_width_adjust[0]
         resize(@overlap_width_adjust[1], height)
         @overlap_width_adjust = nil
       end
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Process Face Setting Codes
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     def process_face_setting_codes(text)
       text.gsub!(/[\\\e]FX\[(\d+|[RLC])\]/i) {
         process_face_setting_code('FX', "[#{$1}]")
          ""
        }
        text.gsub!(/[\\\e]FY\[(\d+|[AUTCBD])\]/i) {
          process_face_setting_code('FY', "[#{$1}]")
          ""
        }
        text.gsub!(/[\\\e](FF|FSX|FSY|FW|FM)/i) {
          process_face_setting_code($1, "")
          ""
        }
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Close
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      if instance_methods(false).include?(:close)
        alias maatsfo_close_4hn6 close
        def close(*args)
          @atsfo_face.clear
          maatsfo_close_4hn6(*args) # Call Original Method
        end
      else
        def close(*args)
          @atsfo_face.clear
          super(*args) # Call Original Method
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * New Page
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      alias maatsfo_newpag_7uj2 new_page
      def new_page(text, pos, *args)
        process_face_setting_codes(text)
        while text[/\A\e[AM]?FB?(\[\d+\]|{\s*['"]?.*?['"]?[\s,;:]*\d*\s*})/i] != nil
         text.slice!(/\A\e([AM]?FB?)/i)
         process_face_code($1, text)
       end
       maatsfo_newpag_7uj2(text, pos, *args)
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Draw Face (overwritten super method)
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     def draw_face(face_name, face_index, *args)
       atsfo_change_face(face_name, face_index)
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Change Face
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     def atsfo_change_face(face_name, face_index, blink = false)
       return if @atsf_testing
       @atsfo_face_count = 0
       if blink
         $game_message.blink_face_name = face_name
         $game_message.blink_face_index = face_index
         @atsfo_face.refresh($game_message.face_name, $game_message.face_index)
       else
         $game_message.face_name = face_name
         $game_message.face_index = face_index
         @atsfo_face.setup($game_message.face_name, $game_message.face_index)
       end
       @atsfo_face.empty? ? @atsfo_face.hide : @atsfo_face.show
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * New Line X
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     alias maatsfo_nwlinex_4jn6 new_line_x
     def new_line_x(*args)
       if @atsfo_face.visible?
         return 0 if !$game_message.face_overlap_allowed
         rfx, rfy = @atsfo_face.screen_ranges
         rmx, rmy = screen_ranges
         # If face window overlaps left side & overlaps some of the window
         if (rfy === rmy.first || rmy === rfy.first) # normally !()
           return 0
         # If more room on the right side of the face than the left
         elsif (rfx.first - rmx.first) < (rmx.last - rfx.last)
           return [rfx.last - rmx.first + 16, 0].max
         else # Left-aligned Text
           return 0
         end
       else
         maatsfo_nwlinex_4jn6(*args)
       end
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Update Face Animation
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     def update_face_animation
       if @show_fast || @line_show_fast
         @atsfo_face.draw_next_face(0)
       else
         @atsfo_face_count = (@atsfo_face_count + 1) % $game_message.chars_per_face
         @atsfo_face.draw_next_face if @atsfo_face_count == 0
       end
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Process Normal Character
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     alias maatsfo_procsnormchar_8zj6 process_normal_character
     def process_normal_character(*args)
       update_face_animation if @atsfo_face.animate_face?
       maatsfo_procsnormchar_8zj6(*args) # Call original method
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Process Escape Character
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     alias maatsfo_procescchar_6ca8 process_escape_character
     def process_escape_character(code, text, *args, &block)
       result = process_face_setting_code(code, text) || process_face_code(code, text)
       if code[/FA(M?)/]
         mirror = !$1.empty?
         anim_id = obtain_escape_param(text)
         @atsfo_face.face_sprite.start_animation($data_animations[anim_id], mirror) unless @atsf_testing
         result = true
       end
       # Call Original Method
       maatsfo_procescchar_6ca8(code, text, *args, &block) unless result
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Process Face Code
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     def process_face_code(code, text)
       code.upcase!
       blink = (code.slice!(/B\Z/) != nil)
       if code[/([AM])F/] != nil # AF (Actor Face) or PF (Party Face)
         type = ($1 == 'A')
         param = obtain_escape_param(text)
         actor = type ? $game_actors[param] : $game_party.members[[param - 1, 0].max]
         # Change Face to chosen Actor
         atsfo_change_face(actor.face_name, actor.face_index, blink) if actor
       elsif code == 'F' # F (Face)
         if text.slice!(/^{\s*['"]?(.*?)['"]?[\s,;:]*(\d*)\s*}/)
           atsfo_change_face($1.empty? ? $game_message.face_name : $1, $2.to_i, blink)
         end
       else
         return false
       end
       return true
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Process Face Setting Code
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     def process_face_setting_code(code, text)
       return false if code.nil? || code.empty?
       case code.upcase
       when 'FF' then $game_message.face_fadein = true
       when 'FSX' then $game_message.face_scroll_x = true
       when 'FSY' then $game_message.face_scroll_y = true
       when 'FW' then $game_message.face_window = true
       when 'FM' then $game_message.face_mirror = true
       when 'FX'
         $game_message.face_x = text.slice!(/\A\[([LCR])\]/i) != nil ? $1.to_sym :
           obtain_escape_param(text)
       when 'FY'
         $game_message.face_y = text.slice!(/\A\[([AUTCBD])\]/i) != nil ? $1.to_sym :
           obtain_escape_param(text)
       else
         return false
       end
       return true
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Wait / Input Pause / Input Choice / Input Number / Input Item
     #``````````````````````````````````````````````````````````````````````````
     # Change Face to Idle
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     [:wait, :input_pause, :input_choice, :input_number, :input_item].each { |meth|
       alias_method(:"maatsfo_#{meth}_7uj1", meth)
       define_method(meth) do |*args|
         @atsfo_face.draw_next_face(0)
         send(:"maatsfo_#{meth}_7uj1", *args)
       end
     }
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Settings Changed?
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     alias maatsfo_setngchn_5ov6 settings_changed?
     def settings_changed?(*args)
       return true if @overlap_width_adjust
       maatsfo_setngchn_5ov6(*args) # Call Original Method
     end
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     # * Update Message Window Position
     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     def adjust_placement_for_face
       rfx, rfy = @atsfo_face.screen_ranges
       # Unless user allows face overlap with message window
       unless $game_message.face_overlap_allowed
         rmx, rmy = screen_ranges
         # If face window overlaps vertically
         if (rfy === rmy.first || rmy === rfy.first)
           # If more space on right than left
           if (rfx.first - rmx.first) < (rmx.last - rfx.last)
             # Don't resize if it makes message window too small
              if (rmx.last - rfx.last) > padding + 32
                @overlap_width_adjust = [x, width]
                # Resize and move message window to right of face
                w = x + width - rfx.last
                resize(w, height)
                self.x = rfx.last
              end
            else
              # Don't resize if it makes message window too small
              if (rfx.first - rmx.first) > padding + 32
                @overlap_width_adjust = [x, width]
                # Resize so message window all to left of face
                w = rfx.first - x
                resize(w, height)
              end
            end
          end
        end
        # Move Name Window if necessary
        if $imported[:ATS_MessageOptions] && $game_message.message_name
          @atsmo_name_window.z = self.z + 4
          rnx, rny = @atsmo_name_window.screen_ranges
          # If name overlaps with face window
          if (rny === rfy.first || rfy === rny.first) && (rnx === rfx.first ||
            rfx === rnx.first)
            # if message window to left
            if rfx.first - @atsmo_name_window.width > x
              # Move name window to left of face
              @atsmo_name_window.x = rfx.first - @atsmo_name_window.width
            else
              @atsmo_name_window.x = rfx.last
            end
          end
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Adjust Choice Window Placement
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def adjust_choice_placement_for_face
        rcx, rcy = @choice_window.screen_ranges
        rfx, rfy = @atsfo_face.screen_ranges
        # If face window overlaps with choice window
        if (rfy === rcy.first || rcy === rfy.first) && (rfx === rcx.first ||
          rcx === rfx.first)
          # if message window to left
          if rfx.first - @choice_window.width > x
            # Move name window to left of face
            @choice_window.x = rfx.first - @choice_window.width
          else
            @choice_window.x = rfx.last
          end
          # Adjust to make sure not over a name
          if $imported[:ATS_MessageOptions] && $game_message.message_name
            rnx, rny = @atsmo_name_window.screen_ranges
            rcx, rcy = @choice_window.screen_ranges
            # If overlaps name window
            if (rny === rcy.first || rcy === rny.first) && (rnx === rcx.first ||
              rcx === rnx.first)
              # Try to Centre
              if rnx.first - @choice_window.width > x
                @choice_window.x = rnx.first - @choice_window.width
              else
                @choice_window.x = rnx.last
              end
            end
          end
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Resize
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def resize(w, h)
        if w != self.width || h != self.height
          self.width = w
          self.height = h
          create_contents
        end
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Screen Ranges
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def screen_ranges
        rmx = (self.x + self.padding)...(self.x + self.width - self.padding)
        rmy = (self.y + self.padding)...(self.y + self.height - self.padding)
        return rmx, rmy
      end
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      # * Total Line Width
      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      def maatsfo_line_width(y = 0)
        nlx = new_line_x
        w = contents_width
        if @atsfo_face.visible?
          rfx, rfy = @atsfo_face.screen_ranges
          rmx, rmy = screen_ranges
          if (rfy === rmy.first || rmy === rfy.first) && nlx < rfx.first &&
            (rfx.first < (x + width - padding))
            w = rfx.first - (x + padding)
          end
        end
        w - nlx
      end
      if $imported[:ATS_Formatting]
        def maatsf_total_line_width(y = 0); maatsfo_line_width(y); end
      end
    end

이게 스크립트인데

asdgsdg.png


저기 파란색 부분에서

ATS Face Options' Line 1194 : NoMethodError occurred.
undefined method 'upcase!' for nil:NilClass

이런 메세지가 뜨면서 더이상 진행이 안 되네요.
원본의 스크립트를 전부 가져와서 덮어씌우기도 해봤지만 결과가 똑같습니다.
혹시 해결 할 수 있는 방법이 없을까요?


List of Articles
종류 분류 제목 글쓴이 날짜 조회 수
공지 묻고 답하기 가이드 습작 2014.06.14 13222
RMVXA 띄운 그림안에 캐릭터... 2 무명시절 2015.10.07 175
RMVXA 메뉴 화면 뜰 때 뒤의 게임 화면이 어두워지지 않게 할 수 있을까요? 2 여줄가리 2015.10.07 351
RMVXA 메뉴 화면 열 때 바로 뜨게 구현할 수 있을까요? 4 여줄가리 2015.10.07 216
기타 몬스터 디자인 선택 1 file LuPZ 2015.10.07 236
기타 특정한 버튼을 사용하여 손전등 이미지를 뜨게하는이벤트 3 꼬닭 2015.10.07 405
RMVXA 질문합니다. 1 류미엘 2015.10.07 98
기타 robf s4u 치트있나용? 1 호로치 2015.10.06 2688
RMVXA 게임 한글화 도중 스크립트 오류 질문 드립니다. file 발렌 2015.10.05 374
RMVXA 선물주기 시스템 9 file 마린걸 2015.10.05 416
RMVXA rpg vxa 윈도우10 설치후 스크립트 창 너비 조절방법이 있나요? 3 로브남 2015.10.04 539
RMVX 게임을 시작할때 주인공의 뒷모습이 나오게 하고싶어요 2 새콤짱 2015.10.04 228
기타 조건분기 변수 설정시 나오는 '이외'는 뭔가요? 2 무명시절 2015.10.04 126
RMMV rpg maker mv에 관하여... 1 E.C.E.H 2015.10.01 299
기타 알만툴이 원래 이런가요?ㅁ 1 2034 2015.10.01 214
RMVXA 스크립트 없이 전등에 불빛효과 넣는 방법 좀 알려주세요. 1 치느 2015.10.01 463
RMVXA 스크립트 없이 8방향(대각선)이동 하는 법 없나요? 무명시절 2015.09.30 275
RM2k3 윈도우8 rpg2000게임 실행 5 file 김수한무거북이와두루삽천갑자동방삭 2015.09.28 605
기타 아이콘 모음 스샷을 어떻게 아이콘으로 만드나요? 1 체력을가르다. 2015.09.28 217
RMXP 이 스크립트를 어떻게 사용해야하는 건가요? 2 체력을가르다. 2015.09.28 174
RMVXA 특정 이벤트의 좌표 알아내는 법. 1 불새우 2015.09.27 181
Board Pagination Prev 1 ... 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 ... 517 Next
/ 517