modern_algebra

[VXA] ATS: Face Options 1.0.3

Jul 15th, 2013
3,997
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #==============================================================================
  2. #    ATS: Face Options
  3. #    Version: 1.0.3
  4. #    Author: modern algebra (rmrk.net)
  5. #    Date: 20 July 2013
  6. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7. #  Description:
  8. #    
  9. #    This script allows you to control the face settings of a message. Not only
  10. #   can you now give faces a talking animation and a blinking animation, but
  11. #   this also lets you use bigger facesets, to set the faceset based on actor
  12. #   ID or party ID, to encapsulate faces in their own windows, to set its
  13. #   position, to fade it in or scroll it in, and much more. For a complete list
  14. #   of features, be sure to read the Instructions starting at line 30 as well
  15. #   as the Editable Region starting at line 176.
  16. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  17. #  ATS Series:
  18. #
  19. #    This script is part of the Advanced Text System series of scripts. These
  20. #   scripts are based off the Advanced Text System for RMVX, but since RMVX Ace
  21. #   has a much more sensibly designed message system, it is no longer necessary
  22. #   that it be one large script. For that reason, and responding to feedback on
  23. #   the ATS, I have split the ATS into multiple different scripts so that you
  24. #   only need to pick up the components for the features that you want. It is
  25. #   therefore easier to customize and configure.
  26. #
  27. #    To find more scripts in the ATS Series, please visit:
  28. #      http://rmrk.net/index.php/topic,44525.0.html
  29. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  30. #  Instructions:
  31. #    
  32. #    Paste this script into its own slot in the Script Editor, above Main but
  33. #   below Materials.
  34. #
  35. #    ~Animated Faces~
  36. #
  37. #    For talking animations, you need to do two things. Firstly, the
  38. #   :animate_faces setting must be set to true. Secondly, the name of the
  39. #   faceset must include the following code:
  40. #
  41. #        %[n]
  42. #
  43. #   where n is the number of poses in the animation. Ex: a faceset named
  44. #   "Actor1%[4]" would have 4 poses. Starting from the selected index, the
  45. #   face would show the first pose, then the second, then the third, then the
  46. #   fourth, and then back to the first to repeat. You set the speed at which it
  47. #   animates by changing the :chars_per_face setting.
  48. #
  49. #    To set a blinking animation, it does not matter whether :animate_faces is
  50. #   true, and you do not need to use special filenames. Rather, you simply need
  51. #   to identify a blink face. This can be done in two ways. First, you can do
  52. #   it in a script call before the message. The important settings are
  53. #   :blink_face_name and :blink_face_index. Where filenames can be long, it is
  54. #   best to set it to a local variable first, like so:
  55. #
  56. #        n = "Actor1"
  57. #        ats_next(:blink_face_name, n)
  58. #        ats_next(:blink_face_index, 5)
  59. #
  60. #   Naturally, "Actor1" is the name of the faceset which houses the blinking
  61. #   pose, and the index is 5 (so second row, second column). If the blinking
  62. #   pose is located within the same faceset as the normal pose, then you only
  63. #   need to set the :blink_face_index.
  64. #
  65. #    The second way to do it is with the following message code, included at
  66. #   the very start of the message:
  67. #
  68. #      \fb{"Actor1", 5}
  69. #
  70. #   Again, change "Actor1" to whatever name you want the face to be, and 5 to
  71. #   whatever index. Similarly, you can exclude the filename if it is the same
  72. #   as the regular pose.
  73. #
  74. #    You can change the rate at which the face blinks by changing the
  75. #   :frames_between_blinks and :frames_to_blink message settings. Read about
  76. #   them at lines 185-189.
  77. #
  78. #    Finally, blinking also works with a talking animation, so if you are using
  79. #   a talking animation it is a good idea to have a full set of blinking poses
  80. #   as well. However, if you have only one, be sure that it is not in a faceset
  81. #   identified as a talking animation (i.e. one with a %[n] code).
  82. #
  83. #
  84. #    ~Large Faces~
  85. #
  86. #    For large faces, you can of course make a set of 8. However, if you want
  87. #   to save each file separately, you can just make the very first character of
  88. #   the filename a $. In other words, an image saved as "Actor3-3" would be a
  89. #   regular faceset of 8 poses, while an image saved as "$Actor3-3" would be
  90. #   an image holding only a single large face. If a file has both $ and %[n]
  91. #   in its name, then it will treat it as a faceset with n poses, all aligned
  92. #   horizontally. In other words, "$Actor3-3%[2]" would be a set with two
  93. #   faces in, the first half of the image with one pose and the second with the
  94. #   second pose. Naturally, it will animate if used in a message, so this
  95. #   should only be done for large face talking animations.
  96. #
  97. #    You set large faces just as you would a normal face. If you want the whole
  98. #   thing to be shown, you should make sure that the :face_width and
  99. #   :face_height settings are both set to -1. If, on the other hand, you want
  100. #   only to cut out the centre of the large face, you can change those values
  101. #   to whatever proportions you want. So, for instance, setting :face_width to
  102. #   128 and face_height to 160 would cut out a 128x160 section of the face and
  103. #   show that.
  104. #
  105. #
  106. #    ~All Other Face Settings~
  107. #
  108. #    There are a lot of configuration options in this script, and I direct you
  109. #   to the Editable Region at line 176 for detailed comments on what each does
  110. #   Here, I will just list them:
  111. #
  112. #          :animate_faces                     :face_scroll_x
  113. #          :chars_per_face                    :face_scroll_y
  114. #          :frames_between_blinks             :face_scroll_speed
  115. #          :frames_to_blink                   :face_fadein
  116. #          :blink_face_name                   :face_fade_speed
  117. #          :blink_face_index                  :face_opacity
  118. #          :face_x                            :face_blend_type
  119. #          :face_x_offset                     :face_match_screen_tone
  120. #          :face_y                            :face_tone
  121. #          :face_y_offset                     :face_window
  122. #          :face_width                        :face_padding
  123. #          :face_height                       :face_win_opacity
  124. #          :face_mirror                       :face_win_back_opacity
  125. #          :face_overlap_allowed
  126. #
  127. #    As with other ATS scripts, you can change the value of these options in
  128. #   game with the following codes in a script call:
  129. #
  130. #      ats_next(:message_option, x)
  131. #      ats_all(:message_option, x)
  132. #
  133. #   Where :message_option is the symbol you want and x is the value you want
  134. #   to change it to. ats_next will only change it for the very next message,
  135. #   while ats_all will change it for every message to follow.
  136. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  137. #  List of Special Message Codes:
  138. #
  139. #    The following is a complete list of the message codes at your disposal.
  140. #   Simply insert them into a Display Message command.
  141. #
  142. # \f{"filename":n} - set face to the one in "filename" at index n.
  143. # \f{n}  - set face to the pose at index n within the current faceset.
  144. # \fb{"filename":n} - set blink face to the one in "filename" at index n.
  145. # \fb{n} - set blink face to the pose at index in within the current faceset.
  146. # \af[n] - set face to the face of the actor with ID n in the database.
  147. # \mf[n] - set face to the face of party member in index n. 1 is the leader.
  148. # \fa[n] - plays animation with ID n on the face.
  149. # \fam[n] - plays a mirror of animation with ID n on the face.
  150. # \fx[n] - sets :face_x to n, where n is: L, C, R, or an integer. See line 198.
  151. # \fy[n] - sets :face_y to n, where n is: A, U, T, C, B, D, or an integer. See
  152. #         line 207.
  153. # \fw    - turns :face_window to true for this message. See line 273.
  154. # \fm    - turns :face_mirror to true for this message. See line 255.
  155. # \ff    - turns :face_fadein to true for this message. See line 251.
  156. # \fsx   - turns :face_scroll_x to true for this message. See line 242.
  157. # \fsy   - turns :face_scroll_y to true for this message. See line 245.
  158. #==============================================================================
  159.  
  160. $imported = {} unless $imported
  161. $imported[:MA_ATS_FaceOptions] = true
  162.  
  163. #==============================================================================
  164. # ** Game_ATS
  165. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  166. #  Summary of Changes:
  167. #    new public instance variables - animate_faces; chars_per_face;
  168. #      frames_between_blinks; frames_to_blink; face_x; face_y; face_x_offset;
  169. #      face_y_offset; face_width; face_height; face_scroll_x; face_scroll_y;
  170. #      face_scroll_speed; face_fadein; face_fade_speed; face_mirror;
  171. #      face_opacity; face_blend_type; face_tone; face_window; face_padding;
  172. #      face_win_opacity; face_win_back_opacity; face_overlap_allowed;
  173. #      blink_face_name; blink_face_index
  174. #==============================================================================
  175.  
  176. class Game_ATS
  177.   CONFIG ||= {}
  178.   CONFIG[:ats_face_options] = {
  179.       ats_face_options: true,
  180.     #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  181.     #  EDITABLE REGION
  182.       #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  183.     #    ~Face Animation Settings~
  184.     #
  185.     #  :animate_faces - true or false. Set this to true if you want faces to
  186.     # animate. Set it to false if you don't, but that should be rare since only
  187.     # faces with a %[n] code will animate, where n is the number of frames in
  188.     # the animation. No other faceset will animate. As such, this option should
  189.     # only ever be set to false if you only want a single pose from a faceset
  190.     # which with a %[n] code.
  191.     animate_faces:         true,
  192.     #  :chars_per_face - integer. When animating a face, this sets how many
  193.     # letters should be drawn before switching to the next frame.
  194.     chars_per_face:        8,
  195.     #  :frames_between_blinks - x...y; x & y both integers. If using a blink
  196.     # face, the time between blinks in frames. There are 60 frames in 1 second.
  197.     frames_between_blinks: 180..300,
  198.     #  :frames_to_blink - integer. Number of frames to show the blinking face.
  199.     frames_to_blink:       12,
  200.     #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  201.     #    ~Face Position and Size~
  202.     #
  203.     #  :face_x - integer, :L, :C, or :R. The X coordinate of the face. If an
  204.     # integer, the face's x-coordinate is set directly to that position. You
  205.     # can also set it so that it is automatically positioned according to the
  206.     # position of the message window. If you set it to :L, it will be at the
  207.     # left end of the message window, and if you set it to :R it will be at the
  208.     # right end of the message window. If you set it to :C, it will be centred,
  209.     # but naturally that setting should only ever be used if the Y position of
  210.     # the face does not overlap with the message window.
  211.     face_x:                :L,
  212.     #  :face_y - integer, :A, :U, :T, :C, :B, or :D. The Y coordinate of the
  213.     # face. If an integer, the face's y-coordinate is set directly to that
  214.     # position. You can also set it so that it is automatically positioned
  215.     # according to the position of the message window. If you set it to :U (Up),
  216.     # the bottom of the face will be flush with the top border of the message
  217.     # window. If you set it to :T (Top), then the top of the face will be flush
  218.     # with the top border of the message window. If you set it to :C (Centre),
  219.     # then the centre of the face will match the centre of the message window.
  220.     # If you set it to :B (Bottom), then the bottom border of the face will be
  221.     # flush with the bottom border of the message window. If you set it to
  222.     # :D (Down), then the top of the face will be flush with the bottom border
  223.     # of the message window. Finally, if you set it to :A (Automatic), then it
  224.     # will be :C if the face is smaller than the message window, and otherwise
  225.     # it will be :T if the message window is in the upper portion of the screen
  226.     # or :B if the message window is in the lower portion of the screen. The
  227.     # recommended value is :C if you are using regular facesets or :A if you
  228.     # are using large facesets.
  229.     face_y:                :A,
  230.     #  :face_x_offset - integer. If using an automatic setting for :face_x,
  231.     # this is added or subtracted from the x placement, as appropriate.
  232.     face_x_offset:         0,
  233.     #  :face_y_offset - integer. If using an automatic setting for :face_y,
  234.     # this is added or subtracted from the y placement, as appropriate.
  235.     face_y_offset:         0,
  236.     #  :face_width - integer. The horizontal size of the face. If -1, it will
  237.     # be set to the width of the face used. If less than the width of the face
  238.     # used, it will take as much of the centre of the face as possible
  239.     face_width:            -1,
  240.     #  :face_height - integer. The vertical size of the face. If -1, it will be
  241.     # set to the height of the face used. If less than the height of the face
  242.     # used, it will take as much of the centre of the face as possible
  243.     face_height:           -1,
  244.     #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  245.     #    ~Face Settings~
  246.     #
  247.     #  :face_scroll_x - true or false. Whether the face should scroll in to
  248.     # place horizontally
  249.     face_scroll_x:         false,
  250.     #  :face_scroll_y - true or false. Whether the face should scroll in to
  251.     # place vertically
  252.     face_scroll_y:         false,
  253.     #  :face_scroll_speed - integer. The number of frames it takes to scroll
  254.     # into position.
  255.     face_scroll_speed:     15,
  256.     #  :face_fadein - true or false. Whether face should fade in gradually.
  257.     face_fadein:           false,
  258.     #  :face_fade_speed - integer. The number of frames it takes to fade in.
  259.     face_fade_speed:       15,
  260.     #  :face_mirror - true or false. Whether the face should be flipped to face
  261.     # the opposite direction.
  262.     face_mirror:           false,
  263.     #  :face_opacity - 0-255. The degree of transparancy of the face.
  264.     face_opacity:          255,
  265.     #  :face_blend_type - 0-2. 0 => Normal; 1 => Add; 2 => Subtract. This
  266.     # should almost always be set to 0 as either other option changes the face
  267.     # dramatically. However, it can be used for a ghost or darkness effect.
  268.     face_blend_type:       0,
  269.     #  :face_match_screen_tone - true or false. If true, the tone of the face
  270.     # will be the same as that of the screen unless you set :face_tone to
  271.     # something other than nil. Otherwise there will be no automatic setting.
  272.     face_match_screen_tone: false,
  273.     #  :face_tone - Tone.new(-255 - 255, -225 - 255, -255 - 255, -255 - 255) -
  274.     # This allows you to blend a tone with the face. The values are
  275.     # (red, green, blue, gray). It should usually be set to nil, but might be
  276.     # useful for flashbacks or lighting effects, etc...
  277.     face_tone:             nil,
  278.     #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  279.     #    ~Face Window Settings~
  280.     #
  281.     #  :face_window - true or false. If true, face shown in its own window
  282.     face_window:           false,
  283.     #  :face_padding - integer. If using window, the size of the border.
  284.     face_padding:          6,
  285.     #  :face_win_opacity - 0-255. The total opacity of the face window
  286.     face_win_opacity:      255,
  287.     #  :face_win_back_opacity - 0-255. The back opacity of the face window
  288.     face_win_back_opacity: 192,
  289.     #  :face_overlap_allowed - true or false. If false, this will not permit
  290.     # any overlap between the face's window and the regular window, and it
  291.     # will resize the message window to avoid it. It should not be used unless
  292.     # you are using either a flush left or flush right placement for the face
  293.     # window. Recommended value is true.
  294.     face_overlap_allowed:  true,
  295.       #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  296.     #  END EDITABLE REGION
  297.     #////////////////////////////////////////////////////////////////////////
  298.     blink_face_name:       "",
  299.     blink_face_index:      -1,
  300.   }
  301.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  302.   # * Public Instance Variables
  303.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  304.   CONFIG[:ats_face_options].keys.each { |key| attr_accessor key }
  305. end
  306.  
  307. #==============================================================================
  308. #  Initialize Common ATS Data if no other ATS script interpreted first
  309. #==============================================================================
  310.  
  311. if !$imported[:AdvancedTextSystem]
  312.   #============================================================================
  313.   # *** DataManager
  314.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  315.   #  Summary of Changes:
  316.   #    aliased method - create_game_objects; make_save_contents;
  317.   #      extract_save_contents
  318.   #============================================================================
  319.   module DataManager
  320.     class << self
  321.       alias modb_ats_crtgmobj_6yh7 create_game_objects
  322.       alias mlba_ats_mksave_5tg9 make_save_contents
  323.       alias ma_ats_extrcsvcon_8uj2 extract_save_contents
  324.     end
  325.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  326.     # * Create Game Objects
  327.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  328.     def self.create_game_objects(*args, &block)
  329.       modb_ats_crtgmobj_6yh7(*args, &block)
  330.       $game_ats = Game_ATS.new
  331.       $game_ats.init_new_installs
  332.     end
  333.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  334.     # * Make Save Contents
  335.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  336.     def self.make_save_contents(*args, &block)
  337.       contents = mlba_ats_mksave_5tg9(*args, &block)
  338.       contents[:ats] = $game_ats
  339.       contents
  340.     end
  341.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  342.     # * Extract Save Contents
  343.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  344.     def self.extract_save_contents(contents, *args, &block)
  345.       ma_ats_extrcsvcon_8uj2(contents, *args, &block)
  346.       $game_ats = contents[:ats] ? contents[:ats] : Game_ATS.new
  347.       $game_ats.init_new_installs
  348.     end
  349.   end
  350.  
  351.   #============================================================================
  352.   # ** Game_ATS
  353.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  354.   #  This class holds the default data for all scripts in the ATS series
  355.   #============================================================================
  356.  
  357.   class Game_ATS
  358.     def initialize; reset; end
  359.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  360.     # * Reset any or all installed ATS scripts
  361.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  362.     def reset(script_name = nil)
  363.       if script_name.is_a? (Symbol) # If script to reset specified
  364.         CONFIG[script_name].each_pair { |key, value|
  365.           self.send("#{key}=".to_sym, value)
  366.           $game_message.send("#{key}=".to_sym, value)
  367.         }
  368.       else                          # Reset all ATS scripts
  369.         CONFIG.keys.each { |script| reset(script) }
  370.       end
  371.     end
  372.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  373.     # * Initialize any newly installed ATS scripts
  374.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  375.     def init_new_installs
  376.       CONFIG.keys.each { |script| reset(script) unless self.send(script) }
  377.     end
  378.   end
  379.  
  380.   #============================================================================
  381.   # ** Game_Message
  382.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  383.   #  Summary of Changes:
  384.   #    aliased method - clear
  385.   #============================================================================
  386.  
  387.   class Game_Message
  388.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  389.     # * Clear
  390.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  391.     alias mlb_ats_clrats_5tv1 clear
  392.     def clear(*args, &block)
  393.       mlb_ats_clrats_5tv1(*args, &block) # Run Original Method
  394.       return if !$game_ats
  395.       Game_ATS::CONFIG.values.each { |installed|
  396.         installed.keys.each { |key| self.send("#{key}=".to_sym, $game_ats.send(key)) }
  397.       }
  398.     end
  399.   end
  400.  
  401.   #============================================================================
  402.   # ** Game_Interpreter
  403.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  404.   #  Summary of Changes:
  405.   #    new methods - ats_all; ats_next
  406.   #============================================================================
  407.  
  408.   class Game_Interpreter
  409.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  410.     # * ATS All
  411.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  412.     def ats_all(sym, *args, &block)
  413.       $game_ats.send("#{sym}=".to_sym, *args, &block)
  414.       ats_next(sym, *args, &block)
  415.     end
  416.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  417.     # * ATS Next
  418.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  419.     def ats_next(sym, *args, &block)
  420.       $game_message.send("#{sym}=".to_sym, *args, &block)
  421.     end
  422.   end
  423.  
  424.   $imported[:AdvancedTextSystem] = true
  425. end
  426.  
  427. #==============================================================================
  428. # ** Game_Message
  429. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  430. #  Summary of Changes:
  431. #    new public instance variables - animate_faces; chars_per_face;
  432. #      frames_between_blinks; frames_to_blink; face_x; face_y; face_x_offset;
  433. #      face_y_offset; face_width; face_height; face_scroll_x; face_scroll_y;
  434. #      face_scroll_speed; face_fadein; face_fade_speed; face_mirror;
  435. #      face_opacity; face_blend_type; face_tone; face_window; face_padding;
  436. #      face_win_opacity; face_win_back_opacity; face_overlap_allowed;
  437. #      blink_face_name; blink_face_index
  438. #==============================================================================
  439.  
  440. class Game_Message
  441.   Game_ATS::CONFIG[:ats_face_options].keys.each { |key| attr_accessor key }
  442. end
  443.  
  444. #==============================================================================
  445. # ** Sprite_ATS_Face
  446. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  447. #  This sprite shows a face graphic for messages.
  448. #==============================================================================
  449.  
  450. class Sprite_ATS_Face < Sprite_Base
  451.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  452.   # * Public Instance Variable
  453.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  454.   attr_reader :num_frames
  455.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  456.   # * Object Initialization
  457.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  458.   def initialize(viewport = nil)
  459.     super(viewport)
  460.     self.bitmap = Bitmap.new(96, 96)
  461.     @num_frames = 1
  462.   end
  463.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  464.   # * Free
  465.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  466.   def dispose(*args)
  467.     bitmap.dispose if bitmap && !bitmap.disposed?
  468.     super(*args)
  469.   end
  470.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  471.   # * Setup
  472.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  473.   def setup(faces, blink_faces = [])
  474.     if faces.empty? # No Face
  475.       bitmap.clear  
  476.       @num_frames = 1                                        # Clear Bitmap
  477.     else
  478.       bitmap.dispose if bitmap && !bitmap.disposed?          # Dispose old bitmap
  479.       rect = Rect.new(0, 0, faces[0].width, faces[0].height) # Set Rect
  480.       # Create Bitmap
  481.       h = blink_faces.empty? ? rect.height : rect.height*2
  482.       self.bitmap = Bitmap.new(rect.width*faces.size, h)
  483.       @num_frames = faces.size
  484.       # Draw all faces onto the bitmap
  485.       for i in 0...@num_frames
  486.         x = i*rect.width
  487.         bitmap.blt(x, 0, faces[i], rect)
  488.         bitmap.blt(x, rect.height, blink_faces[i % blink_faces.size], rect) if !blink_faces.empty?
  489.       end
  490.       src_rect.set(rect) # Set Source Rect
  491.     end
  492.   end
  493.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  494.   # * Set Face Frame
  495.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  496.   def set_column(index = 0)
  497.     src_rect.x = index*src_rect.width
  498.   end
  499.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  500.   # * Set Face Frame
  501.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  502.   def set_row(index = 0)
  503.     src_rect.y = index*src_rect.height
  504.   end
  505. end
  506.  
  507. #==============================================================================
  508. # ** Window_ATS_Face
  509. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  510. #  This window displays a face graphic for messages.
  511. #==============================================================================
  512.  
  513. class Window_ATS_Face < Window_Base
  514.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  515.   # * Create Face
  516.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  517.   def create_face(face_name, face_index)
  518.     contents.clear
  519.     draw_face(face_name, face_index, 0, 0)
  520.   end
  521.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  522.   # * Draw Face Graphic
  523.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  524.   def draw_face(face_name, face_index, x, y, enabled = true, *args)
  525.     bmp = Cache.face(face_name)
  526.     fw, fh = bmp.width, bmp.height
  527.     if face_name[/\A\$/] != nil # SINGLE
  528.       if face_name[/\%\[\s*(\d+)\s*\]/] != nil
  529.         fw /= $1.to_i
  530.       else
  531.         face_index = 0
  532.       end
  533.       cw, ch = contents.width - x, contents.height - y
  534.       rect = Rect.new((face_index*fw) + ((fw - cw) / 2), (fh - ch) / 2, cw, ch)
  535.       contents.blt(x, y, bmp, rect, enabled ? 255 : translucent_alpha)
  536.     else
  537.       fw /= 4
  538.       fh /= 2
  539.       rect = Rect.new(face_index % 4 * fw, face_index / 4 * fh, fw, fh)
  540.       contents.blt(x, y, bmp, rect, enabled ? 255 : translucent_alpha)
  541.     end
  542.     bmp.dispose
  543.   end
  544.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  545.   # * Resize Window
  546.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  547.   def resize(w, h)
  548.     self.width = w + (standard_padding*2)
  549.     self.height = h + (standard_padding*2)
  550.     create_contents
  551.   end
  552.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  553.   # * Standard Padding
  554.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  555.   def standard_padding
  556.     $game_message.face_padding
  557.   end
  558. end
  559.  
  560. #==============================================================================
  561. # ** Spriteset_ATS_Face
  562. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  563. #  This class creates and control the window and sprite for showing faces
  564. #==============================================================================
  565.  
  566. class Spriteset_ATS_Face
  567.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  568.   # * Public Instance Variables
  569.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  570.   attr_reader   :face_window
  571.   attr_reader   :face_sprite
  572.   attr_reader   :x
  573.   attr_reader   :y
  574.   attr_reader   :z
  575.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  576.   # * Object Initialization
  577.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  578.   def initialize(message_window, viewport = nil)
  579.     @message_window = message_window
  580.     @face_window = Window_ATS_Face.new(0, 0, 120, 120)
  581.     @face_sprite = Sprite_ATS_Face.new(viewport)
  582.     self.x, self.y, @dest_x, @dest_y = 0, 0, 0, 0
  583.     @dest_scroll_x_speed, @dest_scroll_y_speed = 0, 0
  584.     @dest_sprite_opacity, @dest_window_opacity = 255, 255
  585.     @dest_s_fade_speed, @dest_w_fade_speed = 0, 0
  586.     self.z = message_window.z + 1
  587.     clear
  588.   end
  589.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  590.   # * Free
  591.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  592.   def dispose
  593.     @face_window.dispose
  594.     @face_sprite.dispose
  595.   end
  596.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  597.   # * Update
  598.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  599.   def update
  600.     @face_sprite.update
  601.     @face_window.update
  602.     @face_window.visible = !empty? && $game_message.face_window
  603.     @face_sprite.visible = @face_window.open? if @face_window.visible
  604.     update_scroll
  605.     update_fade
  606.     update_blink
  607.   end
  608.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  609.   # * Update Scroll
  610.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  611.   def update_scroll
  612.     # Scroll X
  613.     if @dest_x > self.x
  614.       self.x = [self.x + @dest_scroll_x_speed, @dest_x].min
  615.     elsif @dest_x < self.x
  616.       self.x = [self.x + @dest_scroll_x_speed, @dest_x].max
  617.     end
  618.     # Scroll Y
  619.     if @dest_y > self.y
  620.       self.y = [self.y + @dest_scroll_y_speed, @dest_y].min
  621.     elsif @dest_y < self.y
  622.       self.y = [self.y + @dest_scroll_y_speed, @dest_y].max
  623.     end
  624.   end
  625.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  626.   # * Update fade
  627.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  628.   def update_fade
  629.     if @dest_sprite_opacity != face_sprite.opacity
  630.       face_sprite.opacity += @dest_s_fade_speed
  631.       face_sprite.opacity = @dest_sprite_opacity if face_sprite.opacity > @dest_sprite_opacity
  632.     end
  633.     if @dest_window_opacity != face_window.opacity
  634.       face_window.opacity += @dest_w_fade_speed
  635.       face_window.opacity = @dest_window_opacity if face_window.opacity > @dest_window_opacity
  636.     end
  637.   end
  638.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  639.   # * Update Blink
  640.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  641.   def update_blink
  642.     if blinking?
  643.       @blink_timer -= 1
  644.       if @blink_timer <= 0
  645.         @blink_status = (@blink_status + 1) % 2
  646.         @face_sprite.set_row(@blink_status)
  647.         @blink_timer = case @blink_status
  648.         when 0
  649.           fbb = $game_message.frames_between_blinks
  650.           fbb.first + rand(fbb.last - fbb.first)
  651.         when 1 then $game_message.frames_to_blink
  652.         end
  653.       end
  654.     end
  655.   end
  656.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  657.   # * Clear
  658.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  659.   def clear
  660.     @face_name, @face_index, @blink_face_name, @blink_face_index = "", 0, "", 0
  661.     @face_width, @face_height = 0, 0
  662.     @active_face = -1
  663.     @blink_status, @blink_timer = 0, 0
  664.     @face_sprite.setup([])
  665.     hide
  666.   end
  667.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  668.   # * Refresh
  669.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  670.   def refresh(face_name = @face_name, face_index = @face_index)
  671.     @face_name, @face_index = face_name, face_index
  672.     @blink_face_name, @blink_face_index = $game_message.blink_face_name, $game_message.blink_face_index
  673.     return if empty?
  674.     # If blink face partially set, set the other aspect.
  675.     if $game_message.blink_face_index >= 0 && $game_message.blink_face_name.empty?
  676.       $game_message.blink_face_name = face_name
  677.     elsif !$game_message.blink_face_name.empty? && $game_message.blink_face_index < 0
  678.       $game_message.blink_face_index = 0
  679.     end
  680.     @face_width = $game_message.face_width + $game_message.face_padding
  681.     @face_height = $game_message.face_height + $game_message.face_padding
  682.     resize_face(face_name, face_index)
  683.     @face_sprite.setup(collect_faces, collect_faces($game_message.blink_face_name, $game_message.blink_face_index))
  684.   end
  685.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  686.   # * Setup
  687.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  688.   def setup(face_name = $game_message.face_name, face_index = $game_message.face_index)
  689.     need_refresh = (@face_name != face_name || @face_index != face_index ||
  690.       @blink_face_name != $game_message.blink_face_name ||
  691.       @blink_face_index != $game_message.blink_face_index ||
  692.       @face_width != ($game_message.face_width + $game_message.face_padding) ||
  693.       @face_height != ($game_message.face_height + $game_message.face_padding))
  694.     refresh(face_name, face_index) if need_refresh
  695.     unless empty?
  696.       @message_window.restore_overlap_width
  697.       update_placement
  698.       @message_window.adjust_placement_for_face
  699.       @face_sprite.opacity = $game_message.face_opacity
  700.       @face_window.opacity = $game_message.face_win_opacity
  701.       # Only Scroll and Fade if a new face
  702.       if need_refresh
  703.         setup_scroll
  704.         setup_fade
  705.       end
  706.       @face_sprite.mirror = $game_message.face_mirror
  707.       @face_sprite.blend_type = $game_message.face_blend_type
  708.       # Set Tone
  709.       case $game_message.face_tone
  710.       when Tone then @face_sprite.tone.set($game_message.face_tone)
  711.       when Array then @face_sprite.tone.set(*$game_message.face_tone)
  712.       else
  713.         ($game_message.face_match_screen_tone ?
  714.           @face_sprite.tone.set($game_map.screen.tone) :
  715.           @face_sprite.tone.set(0, 0, 0, 0))
  716.       end
  717.       @face_window.back_opacity = $game_message.face_win_back_opacity
  718.       fbb = $game_message.frames_between_blinks
  719.       @blink_status = 0
  720.       @blink_timer = fbb.first + rand(fbb.last - fbb.first)  
  721.       show
  722.     end
  723.   end
  724.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  725.   # * Setup Scroll
  726.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  727.   def setup_scroll
  728.     if $game_message.face_scroll_x
  729.       self.x = (self.x + @face_window.width) > (Graphics.width - self.x) ?
  730.         Graphics.width : -@face_window.width
  731.       @dest_scroll_x_speed = (@dest_x - self.x) / $game_message.face_scroll_speed
  732.     end
  733.     if $game_message.face_scroll_y
  734.       self.y = (self.y + @face_window.height) > (Graphics.height - self.y) ?
  735.         Graphics.height : -@face_window.height
  736.       @dest_scroll_y_speed = (@dest_y - self.y) / $game_message.face_scroll_speed
  737.     end
  738.   end
  739.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  740.   # * Setup Fade
  741.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  742.   def setup_fade
  743.     if $game_message.face_fadein
  744.       @face_sprite.opacity = 0
  745.       @face_window.opacity = 0
  746.       @dest_sprite_opacity = $game_message.face_opacity
  747.       @dest_window_opacity = $game_message.face_win_opacity
  748.       @dest_s_fade_speed = @dest_sprite_opacity / $game_message.face_fade_speed
  749.       @dest_w_fade_speed = @dest_window_opacity / $game_message.face_fade_speed
  750.     end
  751.   end
  752.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  753.   # * Collect Faces
  754.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  755.   def collect_faces(face_name = @face_name, face_index = @face_index)
  756.     return [] if !face_name || face_name.empty?
  757.     faces = []
  758.     # If face_file has animation code, add each frame
  759.     num = $game_message.animate_faces && face_name[/\%\[\s*(\d+)\s*\]/] ? $1.to_i : 1
  760.     for i in face_index...(face_index + num)
  761.       @face_window.create_face(face_name, i)
  762.       faces.push(@face_window.contents.dup)
  763.     end
  764.     @face_window.contents.clear
  765.     return faces.compact
  766.   end
  767.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  768.   # * Resize Face
  769.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  770.   def resize_face(face_name, face_index = 0)
  771.     # Get set size
  772.     wdth, hght = $game_message.face_width, $game_message.face_height
  773.     face = Cache.face(face_name)
  774.     fw, fh = face.width, face.height
  775.     face.dispose
  776.     # Adjust face width and height if faceset not single
  777.     if face_name[/\A\$/] == nil
  778.       fw /= 4
  779.       fh /= 2
  780.     else
  781.       fw /= $1.to_i if face_name[/\%\[\s*(\d+)\s*\]/]
  782.     end
  783.     wdth = wdth <= 0 ? fw : [fw, wdth].min
  784.     hght = hght <= 0 ? fh : [fh, hght].min
  785.     @face_window.resize([wdth, $game_message.face_width].max, [hght, $game_message.face_height].max)
  786.   end
  787.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  788.   # * Update Position
  789.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  790.   def update_placement
  791.     set_x_placement
  792.     set_y_placement
  793.   end
  794.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  795.   # * Set X Position
  796.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  797.   def set_x_placement
  798.     # Update X
  799.     side_offset = $game_message.face_x_offset
  800.     side_offset += (@message_window.padding - $game_message.face_padding)
  801.     @dest_x = case $game_message.face_x
  802.     when Integer then $game_message.face_x - ($game_message.face_window ? 0 : $game_message.face_padding)
  803.     when :l, :L then @message_window.x + side_offset
  804.     when :c, :C then @message_window.x + ((@message_window.width -
  805.       @face_window.width) / 2) + $game_message.face_x_offset
  806.     when :r, :R then @message_window.x + @message_window.width -
  807.       @face_window.width - side_offset
  808.     end
  809.     self.x = @dest_x unless $game_message.face_scroll_x
  810.   end
  811.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  812.   # * Set Y Position
  813.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  814.   def set_y_placement
  815.     # Update Y
  816.     fy = $game_message.face_y
  817.     fy = fy.to_s.upcase.to_sym if fy.is_a?(Symbol)
  818.     # Automatic Set
  819.     if fy == :A
  820.       if @face_window.height <= @message_window.height
  821.         fy = :C # Centre if face smaller than message window
  822.       elsif @message_window.y < (Graphics.height - @message_window.height) / 2
  823.         fy = :T # Align with Top if message window above mid-screen
  824.       else
  825.         fy = :B # Align with Bottom otherwise
  826.       end
  827.     end
  828.     w_pad = ($game_message.face_window ? 0 : $game_message.face_padding)
  829.     @dest_y = case fy
  830.     when Integer then fy - w_pad
  831.     when :U, :AT then @message_window.y - @face_window.height +
  832.       $game_message.face_y_offset + w_pad
  833.     when :T, :BT then @message_window.y + $game_message.face_y_offset - w_pad
  834.     when :C then @message_window.y + ((@message_window.height -
  835.       @face_window.height) / 2) + $game_message.face_y_offset
  836.     when :B, :AB then @message_window.y + @message_window.height -
  837.       @face_window.height - $game_message.face_y_offset + w_pad
  838.     when :D, :BB then @message_window.y + @message_window.height -
  839.       $game_message.face_y_offset - w_pad
  840.     end
  841.     self.y = @dest_y unless $game_message.face_scroll_y
  842.   end
  843.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  844.   # * Empty?
  845.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  846.   def empty?
  847.     @face_name.empty?
  848.   end
  849.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  850.   # * Animate Face?
  851.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  852.   def animate_face?
  853.     !empty? && ($game_message.animate_faces && @face_sprite.src_rect.width < @face_sprite.bitmap.width)
  854.   end
  855.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  856.   # * Blinking?
  857.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  858.   def blinking?
  859.     !empty? && ($game_message.blink_face_name && !$game_message.blink_face_name.empty?)
  860.   end
  861.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  862.   # * Scrolling?
  863.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  864.   def scrolling?
  865.     !empty? && ((@dest_x != self.x) || (@dest_y != self.y))
  866.   end
  867.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  868.   # * Fading
  869.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  870.   def fading?
  871.     !empty? && ((@dest_sprite_opacity != face_sprite.opacity) || (@dest_window_opacity != face_window.opacity))
  872.   end
  873.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  874.   # * Next Face
  875.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  876.   def draw_next_face(direct = nil)
  877.     return if @active_face == direct
  878.     @active_face = direct ? direct : (@active_face + 1) % @face_sprite.num_frames
  879.     @face_sprite.set_column(@active_face)
  880.   end
  881.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  882.   # * Screen Ranges
  883.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  884.   def screen_ranges
  885.     fx, fw = @dest_x, @face_window.width
  886.     fy, fh = @dest_y, @face_window.height
  887.     unless  $game_message.face_window
  888.       fx += @face_window.padding
  889.       fy += @face_window.padding
  890.       fw -= 2*@face_window.padding
  891.       fh -= 2*@face_window.padding
  892.     end
  893.     return (fx...(fx + fw)), (fy...(fy + fh))
  894.   end
  895.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  896.   # * Show / Hide
  897.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  898.   def show
  899.     @face_sprite.visible = true
  900.     @face_window.visible = $game_message.face_window
  901.     if !@message_window.open?
  902.       @face_window.openness = 0
  903.       @face_window.open
  904.     end
  905.   end
  906.   def hide
  907.     @face_sprite.visible = false
  908.     @face_window.visible = false
  909.   end
  910.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  911.   # * Check if Visible?
  912.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  913.   def visible?
  914.     @face_sprite.visible || @face_window.visible
  915.   end
  916.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  917.   # * Set X, Y
  918.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  919.   [:x, :y].each { |writer|
  920.     define_method(:"#{writer}=") do |val|
  921.       instance_variable_set(:"@#{writer}", val)
  922.       @face_window.send(:"#{writer}=", val)
  923.       @face_sprite.send(:"#{writer}=", val + $game_message.face_padding)
  924.     end
  925.   }
  926.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  927.   # * Set Z
  928.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  929.   def z=(val)
  930.     @z = val + 1
  931.     @face_window.z = val
  932.     @face_sprite.z = val + 1
  933.   end
  934.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  935.   # * Method Missing
  936.   #    If method missing, call it on either sprite or window
  937.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  938.   def method_missing(meth, *args, &block)
  939.     # Face Sprite Check
  940.     if @face_sprite && @face_sprite.respond_to?(meth)
  941.       return @face_sprite.send(meth, *args, &block)
  942.     # Face Window
  943.     elsif @face_window && @face_window.respond_to?(meth)
  944.       return @face_window.send(meth, *args, &block)
  945.     else
  946.       super
  947.     end
  948.   end
  949. end
  950.  
  951. #==============================================================================
  952. # ** Window_ChoiceList
  953. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  954. #  Summary of Changes:
  955. #    aliased method - update_placement
  956. #    new method - screen_ranges
  957. #==============================================================================
  958.  
  959. class Window_ChoiceList
  960.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  961.   # * Update Placement
  962.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  963.   alias maatsfo_updplacm_6yh2 update_placement
  964.   def update_placement(*args)
  965.     maatsfo_updplacm_6yh2(*args)
  966.     @message_window.adjust_choice_placement_for_face
  967.   end
  968.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  969.   # * Screen Ranges
  970.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  971.   unless method_defined?(:screen_ranges)
  972.     def screen_ranges
  973.       return ((self.x + self.padding)...(self.x + self.width - self.padding)),
  974.         ((self.y + self.padding)...(self.y + self.height - self.padding))
  975.     end
  976.   end
  977. end
  978.  
  979. #==============================================================================
  980. # ** Window_ATS_Name (compatibility with ATS: Message Options)
  981. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  982. #  Summary of Changes:
  983. #    new method - screen_ranges
  984. #==============================================================================
  985.  
  986. class Window_ATS_Name < Window_Base
  987.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  988.   # * Screen Ranges
  989.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  990.   unless method_defined?(:screen_ranges)
  991.     def screen_ranges
  992.       return ((self.x + self.padding)...(self.x + self.width - self.padding)),
  993.         ((self.y + self.padding)...(self.y + self.height - self.padding))
  994.     end
  995.   end
  996. end
  997.  
  998. #==============================================================================
  999. # ** Window_Message
  1000. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1001. #  Summary of Changes:
  1002. #    aliased methods - create_all_windows; new_page; process_escape_character
  1003. #    overwritten method - draw_face
  1004. #==============================================================================
  1005.  
  1006. class Window_Message
  1007.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1008.   # * Create All Windows
  1009.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1010.   alias maatsfo_creatwins_3hn6 create_all_windows
  1011.   def create_all_windows(*args, &block)
  1012.     maatsfo_creatwins_3hn6(*args, &block) # Call Original Method
  1013.     @atsfo_face = Spriteset_ATS_Face.new(self)
  1014.     @atsmo_all_windows.push(@atsfo_face.face_window) if $imported[:ATS_MessageOptions]
  1015.   end
  1016.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1017.   # * Update All Windows
  1018.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1019.   alias maatsfo_updatewins_8jv3 update_all_windows
  1020.   def update_all_windows(*args, &block)
  1021.     maatsfo_updatewins_8jv3(*args, &block)
  1022.     @atsfo_face.update
  1023.   end
  1024.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1025.   # * Dispose All Windows
  1026.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1027.   alias maatsfo_disposallwins_6xq1 dispose_all_windows
  1028.   def dispose_all_windows(*args, &block)
  1029.     maatsfo_disposallwins_6xq1(*args, &block)
  1030.     @atsfo_face.dispose
  1031.   end
  1032.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1033.   # * Update Placement
  1034.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1035.   alias maatsfo_update_placement update_placement
  1036.   def update_placement(*args)
  1037.     restore_overlap_width
  1038.     maatsfo_update_placement(*args) # Call Original Method
  1039.     # Remove AF or PF code and process it
  1040.     text = $game_message.all_text.dup
  1041.     process_face_setting_codes(text)
  1042.     while text.slice!(/\A\\([AM]?FB?)(\[\d+\]|{\s*['"]?.*?['"]?[\s,;:]*\d*\s*})/i) != nil
  1043.      process_face_code($1, $2)
  1044.    end
  1045.    @atsfo_face.setup
  1046.  end
  1047.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1048.  # * Restore Overlap Width
  1049.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1050.  def restore_overlap_width
  1051.    if @overlap_width_adjust
  1052.      self.x = @overlap_width_adjust[0]
  1053.      resize(@overlap_width_adjust[1], height)
  1054.      @overlap_width_adjust = nil
  1055.    end
  1056.  end
  1057.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1058.  # * Process Face Setting Codes
  1059.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1060.  def process_face_setting_codes(text)
  1061.    text.gsub!(/[\\\e]FX\[(\d+|[RLC])\]/i) {
  1062.      process_face_setting_code('FX', "[#{$1}]")
  1063.       ""
  1064.     }
  1065.     text.gsub!(/[\\\e]FY\[(\d+|[AUTCBD])\]/i) {
  1066.       process_face_setting_code('FY', "[#{$1}]")
  1067.       ""
  1068.     }
  1069.     text.gsub!(/[\\\e](FF|FSX|FSY|FW|FM)/i) {
  1070.       process_face_setting_code($1, "")
  1071.       ""
  1072.     }
  1073.   end
  1074.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1075.   # * Close
  1076.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1077.   if instance_methods(false).include?(:close)
  1078.     alias maatsfo_close_4hn6 close
  1079.     def close(*args)
  1080.       @atsfo_face.clear
  1081.       maatsfo_close_4hn6(*args) # Call Original Method
  1082.     end
  1083.   else
  1084.     def close(*args)
  1085.       @atsfo_face.clear
  1086.       super(*args) # Call Original Method
  1087.     end
  1088.   end
  1089.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1090.   # * New Page
  1091.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1092.   alias maatsfo_newpag_7uj2 new_page
  1093.   def new_page(text, pos, *args)
  1094.     process_face_setting_codes(text)
  1095.     while text[/\A\e[AM]?FB?(\[\d+\]|{\s*['"]?.*?['"]?[\s,;:]*\d*\s*})/i] != nil
  1096.      text.slice!(/\A\e([AM]?FB?)/i)
  1097.      process_face_code($1, text)
  1098.    end
  1099.    maatsfo_newpag_7uj2(text, pos, *args)
  1100.  end
  1101.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1102.  # * Draw Face (overwritten super method)
  1103.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1104.  def draw_face(face_name, face_index, *args)
  1105.    atsfo_change_face(face_name, face_index)
  1106.  end
  1107.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1108.  # * Change Face
  1109.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1110.  def atsfo_change_face(face_name, face_index, blink = false)
  1111.    return if @atsf_testing
  1112.    @atsfo_face_count = 0
  1113.    if blink
  1114.      $game_message.blink_face_name = face_name
  1115.      $game_message.blink_face_index = face_index
  1116.      @atsfo_face.refresh($game_message.face_name, $game_message.face_index)
  1117.    else
  1118.      $game_message.face_name = face_name
  1119.      $game_message.face_index = face_index
  1120.      @atsfo_face.setup($game_message.face_name, $game_message.face_index)
  1121.    end
  1122.    @atsfo_face.empty? ? @atsfo_face.hide : @atsfo_face.show
  1123.  end
  1124.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1125.  # * New Line X
  1126.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1127.  alias maatsfo_nwlinex_4jn6 new_line_x
  1128.  def new_line_x(*args)
  1129.    if @atsfo_face.visible?
  1130.      return 0 if !$game_message.face_overlap_allowed
  1131.      rfx, rfy = @atsfo_face.screen_ranges
  1132.      rmx, rmy = screen_ranges
  1133.      # If face window overlaps left side & overlaps some of the window
  1134.      if !(rfy === rmy.first || rmy === rfy.first)
  1135.        return 0
  1136.      # If more room on the right side of the face than the left
  1137.      elsif (rfx.first - rmx.first) < (rmx.last - rfx.last)
  1138.        return [rfx.last - rmx.first + 16, 0].max
  1139.      else # Left-aligned Text
  1140.        return 0
  1141.      end
  1142.    else
  1143.      maatsfo_nwlinex_4jn6(*args)
  1144.    end
  1145.  end
  1146.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1147.  # * Update Face Animation
  1148.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1149.  def update_face_animation
  1150.    if @show_fast || @line_show_fast
  1151.      @atsfo_face.draw_next_face(0)
  1152.    else
  1153.      @atsfo_face_count = (@atsfo_face_count + 1) % $game_message.chars_per_face
  1154.      @atsfo_face.draw_next_face if @atsfo_face_count == 0
  1155.    end
  1156.  end
  1157.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1158.  # * Process Normal Character
  1159.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1160.  alias maatsfo_procsnormchar_8zj6 process_normal_character
  1161.  def process_normal_character(*args)
  1162.    update_face_animation if @atsfo_face.animate_face?
  1163.    maatsfo_procsnormchar_8zj6(*args) # Call original method
  1164.  end
  1165.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1166.  # * Process Escape Character
  1167.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1168.  alias maatsfo_procescchar_6ca8 process_escape_character
  1169.  def process_escape_character(code, text, *args, &block)
  1170.    result = process_face_setting_code(code, text) || process_face_code(code, text)
  1171.    if code[/FA(M?)/]
  1172.      mirror = !$1.empty?
  1173.      anim_id = obtain_escape_param(text)
  1174.      @atsfo_face.face_sprite.start_animation($data_animations[anim_id], mirror) unless @atsf_testing
  1175.      result = true
  1176.    end
  1177.    # Call Original Method
  1178.    maatsfo_procescchar_6ca8(code, text, *args, &block) unless result
  1179.  end
  1180.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1181.  # * Process Face Code
  1182.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1183.  def process_face_code(code, text)
  1184.    code.upcase!
  1185.    blink = (code.slice!(/B\Z/) != nil)
  1186.    if code[/([AM])F/] != nil # AF (Actor Face) or PF (Party Face)
  1187.      type = ($1 == 'A')
  1188.      param = obtain_escape_param(text)
  1189.      actor = type ? $game_actors[param] : $game_party.members[[param - 1, 0].max]
  1190.      # Change Face to chosen Actor
  1191.      atsfo_change_face(actor.face_name, actor.face_index, blink) if actor
  1192.    elsif code == 'F' # F (Face)
  1193.      if text.slice!(/^{\s*['"]?(.*?)['"]?[\s,;:]*(\d*)\s*}/)
  1194.        atsfo_change_face($1.empty? ? $game_message.face_name : $1, $2.to_i, blink)
  1195.      end
  1196.    else
  1197.      return false
  1198.    end
  1199.    return true
  1200.  end
  1201.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1202.  # * Process Face Setting Code
  1203.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1204.  def process_face_setting_code(code, text)
  1205.    return false if code.nil? || code.empty?
  1206.    case code.upcase
  1207.    when 'FF' then $game_message.face_fadein = true
  1208.    when 'FSX' then $game_message.face_scroll_x = true
  1209.    when 'FSY' then $game_message.face_scroll_y = true
  1210.    when 'FW' then $game_message.face_window = true
  1211.    when 'FM' then $game_message.face_mirror = true
  1212.    when 'FX'
  1213.      $game_message.face_x = text.slice!(/\A\[([LCR])\]/i) != nil ? $1.to_sym :
  1214.        obtain_escape_param(text)
  1215.    when 'FY'
  1216.      $game_message.face_y = text.slice!(/\A\[([AUTCBD])\]/i) != nil ? $1.to_sym :
  1217.        obtain_escape_param(text)
  1218.    else
  1219.      return false
  1220.    end
  1221.    return true
  1222.  end
  1223.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1224.  # * Wait / Input Pause / Input Choice / Input Number / Input Item
  1225.  #``````````````````````````````````````````````````````````````````````````
  1226.  # Change Face to Idle
  1227.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1228.  [:wait, :input_pause, :input_choice, :input_number, :input_item].each { |meth|
  1229.    alias_method(:"maatsfo_#{meth}_7uj1", meth)
  1230.    define_method(meth) do |*args|
  1231.      @atsfo_face.draw_next_face(0)
  1232.      send(:"maatsfo_#{meth}_7uj1", *args)
  1233.    end
  1234.  }
  1235.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1236.  # * Settings Changed?
  1237.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1238.  alias maatsfo_setngchn_5ov6 settings_changed?
  1239.  def settings_changed?(*args)
  1240.    return true if @overlap_width_adjust
  1241.    maatsfo_setngchn_5ov6(*args) # Call Original Method
  1242.  end
  1243.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1244.  # * Update Message Window Position
  1245.  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1246.  def adjust_placement_for_face
  1247.    rfx, rfy = @atsfo_face.screen_ranges
  1248.    # Unless user allows face overlap with message window
  1249.    unless $game_message.face_overlap_allowed
  1250.      rmx, rmy = screen_ranges
  1251.      # If face window overlaps vertically
  1252.      if (rfy === rmy.first || rmy === rfy.first)
  1253.        # If more space on right than left
  1254.        if (rfx.first - rmx.first) < (rmx.last - rfx.last)
  1255.          # Don't resize if it makes message window too small
  1256.           if (rmx.last - rfx.last) > padding + 32
  1257.             @overlap_width_adjust = [x, width]
  1258.             # Resize and move message window to right of face
  1259.             w = x + width - rfx.last
  1260.             resize(w, height)
  1261.             self.x = rfx.last
  1262.           end
  1263.         else
  1264.           # Don't resize if it makes message window too small
  1265.           if (rfx.first - rmx.first) > padding + 32
  1266.             @overlap_width_adjust = [x, width]
  1267.             # Resize so message window all to left of face
  1268.             w = rfx.first - x
  1269.             resize(w, height)
  1270.           end
  1271.         end
  1272.       end
  1273.     end
  1274.     # Move Name Window if necessary
  1275.     if $imported[:ATS_MessageOptions] && $game_message.message_name
  1276.       @atsmo_name_window.z = self.z + 4
  1277.       rnx, rny = @atsmo_name_window.screen_ranges
  1278.       # If name overlaps with face window
  1279.       if (rny === rfy.first || rfy === rny.first) && (rnx === rfx.first ||
  1280.         rfx === rnx.first)
  1281.         # if message window to left
  1282.         if rfx.first - @atsmo_name_window.width > x
  1283.           # Move name window to left of face
  1284.           @atsmo_name_window.x = rfx.first - @atsmo_name_window.width
  1285.         else
  1286.           @atsmo_name_window.x = rfx.last
  1287.         end
  1288.       end
  1289.     end
  1290.   end
  1291.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1292.   # * Adjust Choice Window Placement
  1293.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1294.   def adjust_choice_placement_for_face
  1295.     rcx, rcy = @choice_window.screen_ranges
  1296.     rfx, rfy = @atsfo_face.screen_ranges
  1297.     # If face window overlaps with choice window
  1298.     if (rfy === rcy.first || rcy === rfy.first) && (rfx === rcx.first ||
  1299.       rcx === rfx.first)
  1300.       # if message window to left
  1301.       if rfx.first - @choice_window.width > x
  1302.         # Move name window to left of face
  1303.         @choice_window.x = rfx.first - @choice_window.width
  1304.       else
  1305.         @choice_window.x = rfx.last
  1306.       end
  1307.       # Adjust to make sure not over a name
  1308.       if $imported[:ATS_MessageOptions] && $game_message.message_name
  1309.         rnx, rny = @atsmo_name_window.screen_ranges
  1310.         rcx, rcy = @choice_window.screen_ranges
  1311.         # If overlaps name window
  1312.         if (rny === rcy.first || rcy === rny.first) && (rnx === rcx.first ||
  1313.           rcx === rnx.first)
  1314.           # Try to Centre
  1315.           if rnx.first - @choice_window.width > x
  1316.             @choice_window.x = rnx.first - @choice_window.width
  1317.           else
  1318.             @choice_window.x = rnx.last
  1319.           end
  1320.         end
  1321.       end
  1322.     end
  1323.   end
  1324.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1325.   # * Resize
  1326.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1327.   def resize(w, h)
  1328.     if w != self.width || h != self.height
  1329.       self.width = w
  1330.       self.height = h
  1331.       create_contents
  1332.     end
  1333.   end
  1334.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1335.   # * Screen Ranges
  1336.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1337.   def screen_ranges
  1338.     rmx = (self.x + self.padding)...(self.x + self.width - self.padding)
  1339.     rmy = (self.y + self.padding)...(self.y + self.height - self.padding)
  1340.     return rmx, rmy
  1341.   end
  1342.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1343.   # * Total Line Width
  1344.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1345.   def maatsfo_line_width(y = 0)
  1346.     nlx = new_line_x
  1347.     w = contents_width
  1348.     if @atsfo_face.visible?
  1349.       rfx, rfy = @atsfo_face.screen_ranges
  1350.       rmx, rmy = screen_ranges
  1351.       if (rfy === rmy.first || rmy === rfy.first) && nlx < rfx.first &&
  1352.         (rfx.first < (x + width - padding))
  1353.         w = rfx.first - (x + padding)
  1354.       end
  1355.     end
  1356.     w - nlx
  1357.   end
  1358.   if $imported[:ATS_Formatting]
  1359.     def maatsf_total_line_width(y = 0); maatsfo_line_width(y); end
  1360.   end
  1361. end
RAW Paste Data