Advertisement
LiTTleDRAgo

[RGSS] Multiple Message Windows

Feb 11th, 2012
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 136.96 KB | None | 0 0
  1. #==============================================================================
  2. # ** Multiple Message Windows Ex 1.6                                  2012-06-17
  3. #------------------------------------------------------------------------------
  4. # Originally written by Wachunga
  5. # Optimized and De-SDK'ed by ForeverZer0
  6. # Ex Version by LiTTleDRAgo
  7. #==============================================================================
  8. =begin
  9.  
  10. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  11.  
  12.   ForeverZer0's Notes
  13.  
  14. - Credit for the original script is 100% Wachunga. Original map and events
  15.   are also Wachunga's original.
  16. - Edits have been made by ForeverZer0 to eliminate the SDK requirement
  17.   and improve coding and performance
  18. - I have added a compatibility switch for Blizzard's simple shaded text if you
  19.   are you using that, because it doesn't look right with message text. The
  20.   switch will disable it whenever a message is showing, but otherwise will
  21.   shade everything else.
  22. - This script must be placed below Blizzard's Tons-of-Add-ons if you are
  23.   using it. If you don't you will get an error. It has something to do with
  24.   the Lagless HUD script. Some bug I couldn't isolate... If you find it, let
  25.   me know, else just keep it under Tons.
  26.  
  27. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  28. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  29.  
  30.   LiTTleDRAgo's Notes
  31.  
  32. - This script is edited and remodeled a bit by me to make it compatible with
  33.   Blizz ABS (and pst... H Mode 7)
  34. - Although this version is de-SDK-ed by F0, This version should be 80%
  35.   compatible with SDK
  36. - Some features were added to enhance this script functionality
  37.  
  38. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  39.  
  40.   This custom message system adds numerous features on top of the default
  41.   message system, the most notable being the ability to have multiple message
  42.   windows open at once. The included features are mostly themed around turning
  43.   messages into speech (and thought) balloons, but default-style messages are
  44.   of course still possible.
  45.  
  46.   The original version of the script uses the SDK, seems to be lost
  47.  
  48.   FEATURES
  49.   New in 1.6 (feature by ThallionDarkshine)
  50.       \ani[TYPE]
  51.          TYPE - Which type of animation the text should have
  52.            0  - Turn off Animation
  53.            1  - Grow             4  - Shake
  54.            2  - Rock             5  - Float
  55.            3  - Shrink           6  - Color Rotate
  56.            
  57.            7  - Bounce           10 - Letter Grow (2)
  58.            8  - Fade             11 - Letter Swivel
  59.            9  - Letter Grow (1)  12 - Letter Colorize
  60.            
  61.            13 - Letter Fade (1)   16 - Letter Shrink (2)
  62.            14 - Letter Fade (2)   17 - Letter Bounce
  63.            15 - Letter Shrink (1) 18 - Letter Float
  64.            
  65.   New in 1.5x
  66.  
  67.   * \f[face_image] = display faceset image
  68.                    image must be placed in folder pictures and the size
  69.                    is 80x80
  70.   * \a[name]       = display message name
  71.   * \r[string]     = display furigana text
  72.   * \F+  = character puts their Foot Forward
  73.   * \F*  = character puts their Other Foot Forward
  74.   * \F-  = character resets their Foot Forward
  75.  
  76.   * \font[fontname,fontsize] = change font name and font size
  77.   * \z[value]      = change z value from message  
  78.  
  79.   - message.auto_comma_pause = true/false
  80.   - message.auto_comma_delay = n
  81.   - message.opacity = (0-255)
  82.   - message.sound = true / false
  83.   - message.sound_audio = '001-System01'
  84.   - message.sound_volume = n
  85.   - message.sound_pitch = n
  86.   - message.sound_pitch_range = n
  87.   - message.sound_frequency = n
  88.   - message.sound_vary_pitch = true / false / 'random'
  89.   - message.shortcut[:(shortcut)] = 'Message'
  90.   - message.speech_windowskin  = [windowskin_name,tail_windowskin_name]
  91.   - message.thought_windowskin = [windowskin_name,tail_windowskin_name]
  92.   - message.message_log = true / false
  93.  
  94.   * fixed face sprite bug
  95.   * added message log  
  96.  
  97.   New in 1.5:
  98.   * \C[#ffffff] for hexadecimal color
  99.   * \C for return to default color
  100.   * display name of item, weapon, armor or skill
  101.     * \N[In] = display name of item with id n (note the "I")
  102.     * \N[Wn] = display name of weapon with id n (note the "W")
  103.     * \N[An] = display name of armor with id n (note the "A")
  104.     * \N[Sn] = display name of skill with id n (note the "S")
  105.   * display icon of item, weapon, armor or skill
  106.     * \I[In] = display icon of item with id n (note the "I")
  107.     * \I[Wn] = display icon of weapon with id n (note the "W")
  108.     * \I[An] = display icon of armor with id n (note the "A")
  109.     * \I[Sn] = display icon of skill with id n (note the "S")
  110.   * display icon and name of item, weapon, armor or skill
  111.     * \I&N[In] = display icon and name of item with id n (note the "I")
  112.     * \I&N[Wn] = display icon and name of weapon with id n (note the "W")
  113.     * \I&N[An] = display icon and name of armor with id n (note the "A")
  114.     * \I&N[Sn] = display icon and name of skill with id n (note the "S")
  115.   * new windowskins available
  116.   * speech windowskin now definable separately from default windowskin
  117.   * fixed bold bug where degree sign would occasionally appear
  118.   * input number window now shares parent window's font
  119.   * changed \Var[n] back to default of \V[n]
  120.  
  121.   New in 1.1:
  122.   * message.autocenter for automatically centering text within messages
  123.   * \N[en] for displaying name of enemy with id n (note the "e")
  124.   * \MAP for displaying the name of the current map
  125.  
  126.   At a glance:
  127.   * multiple message windows
  128.   * speech balloons
  129.     * position over player/event (follows movement and scrolling)
  130.     * optional message tail (for speech or thought balloons)
  131.     * can specify location relative to player/event (up, down, left, right)
  132.   * thought balloons
  133.     * can use different windowskin, message tail and font color
  134.   * letter-by-letter mode
  135.     * variable speed (and delays)
  136.     * skippable on button press
  137.   * autoresize messages
  138.   * player movement allowed during messages
  139.     * if speaker moves offscreen, message closes (like ChronoTrigger)
  140.   * everything also works during battle
  141.   * settings configurable at anytime  
  142.  
  143.   Full list of options:
  144.  
  145.   (Note that all are case *insensitive*.)
  146.  
  147.   =============================================================================
  148.    Local (specified in message itself and resets at message end)
  149.   =============================================================================
  150.   - \L = letter-by-letter mode toggle
  151.   - \S[n] = set speed at which text appears in letter-by-letter mode
  152.   - \D[n] = set delay (in frames) before next text appears
  153.   - \P[n] = position message over event with id n
  154.             * use n=0 for player
  155.             * in battle, use n=a,b,c,d for actors (e.g. \P[a] for first actor)
  156.               and n=1,...,n for enemies (e.g. \P[1] for first enemy)
  157.               where order is actually the reverse of troop order (in database)
  158.   - \P = position message over current event (default for floating messages)
  159.   - \^ = message appears directly over its event
  160.   - \v = message appears directly below its event
  161.   - \< = message appears directly to the left of its event
  162.   - \> = message appears directly to the right of its event
  163.   - \B = bold text
  164.   - \I = italic text
  165.   - \C[#xxxxxx] = change to color specified by hexadecimal (eg. ffffff = white)
  166.   - \C = change color back to default
  167.   - \! = message autoclose
  168.   - \? = wait for user input before continuing
  169.   - \+ = make message appear at same time as preceding one
  170.          * note: must be at the start of message to work
  171.   - \# = insert the last message with line text the preceding one      
  172.   - \@ = thought balloon
  173.   - \N[En] = display name of enemy with id n (note the "E")
  174.   - \N[Pn] = display name of event with id n (note the "P")
  175.   - \N[In] = display name of item with id n (note the "I")
  176.   - \N[Wn] = display name of weapon with id n (note the "W")
  177.   - \N[An] = display name of armor with id n (note the "A")
  178.   - \N[Sn] = display name of skill with id n (note the "S")
  179.   - \I[In] = display icon of item with id n (note the "I")
  180.   - \I[Wn] = display icon of weapon with id n (note the "W")
  181.   - \I[An] = display icon of armor with id n (note the "A")
  182.   - \I[Sn] = display icon of skill with id n (note the "S")
  183.   - \I&N[In] = display icon and name of item with id n (note the "I")
  184.   - \I&N[Wn] = display icon and name of weapon with id n (note the "W")
  185.   - \I&N[An] = display icon and name of armor with id n (note the "A")
  186.   - \I&N[Sn] = display icon and name of skill with id n (note the "S")
  187.   - \MAP = display the name of the current map
  188.  
  189.   These are, of course, in addition to the default options:
  190.   - \V[n] = display value of variable n
  191.   - \N[n] = display name of actor with id n
  192.   - \C[n] = change color to n
  193.   - \G = display gold window
  194.   - \\ = show the '\' character
  195.  
  196.   * Foot Forward Notes * - Sprite Sheets only have 16 total Frames of Animation
  197.     and of which, 4 are duplicates.  Foot Forward Options allow access to
  198.     ALL of the frames of animation available in Default Sprite Sheets.
  199.    
  200.   - \F+  = character puts their Foot Forward
  201.   - \F*  = character puts their Other Foot Forward
  202.   - \F-  = character resets their Foot Forward
  203.  
  204.   *NOTE* - Foot Forward Animation will RESET if the event is moved off screen.
  205.          - Change @auto_ff_reset if this feature causes you trouble with
  206.            character animations.
  207.    
  208.     It also ONLY works with the following conditions
  209.     - Direction Fix is OFF
  210.     - Move Animation is ON
  211.     - Stop Animation is OFF (technically thats Step, they typo'd)
  212.     - @auto_ff_reset is TRUE
  213.     - * These settings are the DEFAULT when a New Event is created
  214.    
  215.   =============================================================================
  216.    Global (specified below or by Call Script and persist until changed)
  217.   =============================================================================
  218.  
  219.   Zer0 Note:
  220.   If you use any of these in another script, etc. and not a script call, you
  221.   will need to place "$game_system." before each command.
  222.  
  223.   Miscellaneous:
  224.   - message.move_during = true/false
  225.     * allow/disallow player to move during messages
  226.   - message.show_pause = true/false
  227.     * show/hide "waiting for player" pause graphic
  228.   - message.autocenter = true/false
  229.     * enable/disable automatically centering text within messages
  230.   - message.auto_comma_pause = true/false
  231.     * inserts a delay before the next character after these characters ,!.?
  232.     * expects correct punctuation.  One space after a comma, the rest 2 spaces
  233.   - message.auto_comma_delay = n
  234.     * changes how long to wait after a pausable character
  235.   - message.auto_shrink = true/false
  236.     * shrink the balloon message to one liner, but enlarge after
  237.       exceeding one line
  238.   - message.opacity = (0-255)
  239.     * change opacity for every message
  240.   - message.speech_windowskin = [windowskin_name,tail_windowskin_name]
  241.   - message.thought_windowskin = [windowskin_name,tail_windowskin_name]
  242.  
  243.   Speech/thought balloon related:
  244.   - message.resize = true/false
  245.     * enable/disable automatic resizing of messages (only as big as necessary)
  246.   - message.floating = true/false
  247.     * enable/disable positioning messages above current event by default
  248.       (i.e. equivalent to including \P in every message)
  249.   - message.location = TOP, BOTTOM, LEFT or RIGHT
  250.     * set default location for floating messages relative to their event
  251.   - message.show_tail = true/false
  252.     * show/hide message tail for speech/thought balloons
  253.  
  254.   Letter-by-letter related:
  255.   - message.letter_by_letter = true/false
  256.     * enable/disable letter-by-letter mode (globally)
  257.   - message.text_speed = 0-20
  258.     * set speed at which text appears in letter-by-letter mode (globally)
  259.   - message.skippable = true/false
  260.     * allow/disallow player to skip to end of message with button press
  261.  
  262.   Font:
  263.   - message.font_name = font
  264.     * set font to use for text, overriding all defaults
  265.       (font can be any TrueType from Windows/Fonts folder)
  266.   - message.font_size = size
  267.     * set size of text  (default 22), overriding all defaults
  268.   - message.font_color = color
  269.     * set color of text, overriding all defaults
  270.     * you can use same 0-7 as for \C[n] or "#xxxxxx" for hexadecimal
  271.    
  272.   Sound related:
  273.  
  274.   - message.sound = true / false
  275.     * Enables or Disables Text Sounds  
  276.   - message.sound_audio = '001-System01'    
  277.     * Audio SE (in DB) to play
  278.   - message.sound_volume = n
  279.     * Text Sound Volume (0 - 100)
  280.   - message.sound_pitch = n
  281.     * Text Sound Pitch (100 is default)
  282.   - message.sound_pitch_range = n
  283.     * How Much to vary the Pitch (10 = pitch of 90 to 110 with base 100)
  284.   - message.sound_frequency = n
  285.     * Plays a sound this many letters  
  286.   - message.sound_vary_pitch = true / false / 'random'    
  287.     *  Whether to Vary the Pitch or not, or totally randomize
  288.     ** If random, use quotes and lower case: 'random'    
  289.  
  290.   Note that the default thought and shout balloon windowskins don't
  291.   stretch to four lines very well (unfortunately).
  292.    
  293.   Thanks:
  294.   XRXS code for self-close and wait for input
  295.   Slipknot for a convenient approach to altering settings in-game
  296.   SephirothSpawn for bitmap rotate method
  297.   Heretic86 for Sound related method, auto comma delay and fixed choice bug
  298.   ThallionDarkshine for Animated Letter
  299.  
  300. =end
  301.  
  302. #==============================================================================
  303. # Settings
  304. #==============================================================================
  305.  
  306.   # Zer0 Edit. Blizzard's Simple Shaded Text just looks kinda funny when used
  307.   # on black text (which is default for MMS). If you are using Shaded Text and
  308.   # do not want it to display for the message windows, set this to true. It will
  309.   # still show for everything else.
  310.  
  311.   Blizzard_Shaded_Text_Fix = true
  312.  
  313.   #----------------------------------------------------------------------------
  314.   # Windowskins
  315.   #----------------------------------------------------------------------------
  316.   # Note: all files must be in the Graphics/Windowskins/ folder
  317.   # Tip: tails don't look right on windowskins with gradient backgrounds
  318.  
  319.   # filenames of tail and windowskin used for speech balloons
  320.   FILENAME_SPEECH_TAIL        = 'white-tail_speech.png'
  321.   FILENAME_SPEECH_WINDOWSKIN  = 'white-windowskin_speech.png'
  322.  
  323.   # filenames of tail and windowskin used for thought balloons
  324.   FILENAME_THOUGHT_TAIL       = 'white-tail_thought.png'
  325.   FILENAME_THOUGHT_WINDOWSKIN = 'white-windowskin_thought.png'
  326.  
  327.   #----------------------------------------------------------------------------
  328.   # MESSAGE LOG
  329.   #----------------------------------------------------------------------------
  330.   # this will used for message log
  331.   MESSAGE_LOG_TEXT            = 'MESSAGE LOG'
  332.   MESSAGE_LOG_FONT            = [Font.default_name, 'Arial', 30]
  333.   MESSAGE_LOG_WINDOWSKIN      = '001-Blue01'
  334.   #----------------------------------------------------------------------------
  335.   # Fonts
  336.   #----------------------------------------------------------------------------
  337.   # Note: if floating or resize (i.e. 'speech balloons') are disabled,
  338.   # Font.default_name, Font.default_size and Font.default_color are used
  339.   # (you can change these in Main)
  340.   # During gameplay, you can use message.font_name etc to override all defaults
  341.  
  342.   # defaults for speech text
  343.   SPEECH_FONT_COLOR   = "#000000"
  344.   SPEECH_FONT_NAME    = ['Comic Sans MS', 'Arial']
  345.   SPEECH_FONT_SIZE    = 20
  346.  
  347.   # defaults for thought text
  348.   THOUGHT_FONT_COLOR  = "#000000"
  349.   THOUGHT_FONT_NAME   = ['Comic Sans MS', 'Arial']
  350.   THOUGHT_FONT_SIZE   = 20
  351.  
  352.   # note that you can use an array of fonts for SPEECH_FONT_NAME, etc.
  353.   # e.g. ['Verdana', 'MS PGothic']
  354.   # (if Verdana is not available, MS PGothic will be used instead)
  355.  
  356.   #----------------------------------------------------------------------------
  357.   # Misc
  358.   #----------------------------------------------------------------------------
  359.   # If using a specialty windowskin (e.g. the default thought balloon one),
  360.   # you can force the window width to always be a multiple of the number
  361.   # specified in this constant (even when using the resize feature).
  362.   # This allows, for example, the windowskin frame to be designed to
  363.   # repeat every 16 pixels so that the frame never looks cut off.
  364.   THOUGHT_WIDTH_MULTIPLE = 16
  365.   # (set to 0 if you're not using any such windowskins)
  366.  
  367. class Game_Message
  368.  
  369.   # Any of the below can be changed by a Call Script event during gameplay.
  370.   # E.g. turn letter-by-letter mode off with: message.letter_by_letter = false
  371.  
  372.   attr_accessor :speech_windowskin
  373.   attr_accessor :thought_windowskin
  374.   attr_accessor :message_log
  375.   attr_accessor :move_during
  376.   attr_accessor :letter_by_letter
  377.   attr_accessor :text_speed
  378.   attr_accessor :skippable
  379.   attr_accessor :resize
  380.   attr_accessor :floating
  381.   attr_accessor :autocenter
  382.   attr_accessor :show_tail
  383.   attr_accessor :show_pause
  384.   attr_accessor :location
  385.   attr_accessor :font_name
  386.   attr_accessor :font_size
  387.   attr_accessor :font_color
  388.   attr_accessor :auto_shrink
  389.   attr_accessor :opacity
  390.   attr_accessor :auto_comma_pause
  391.   attr_accessor :auto_comma_delay
  392.   attr_accessor :allow_cancel_numbers
  393.   attr_accessor :sound            
  394.   attr_accessor :sound_audio
  395.   attr_accessor :sound_volume
  396.   attr_accessor :sound_pitch
  397.   attr_accessor :sound_pitch_range
  398.   attr_accessor :sound_vary_pitch
  399.   attr_accessor :sound_frequency  
  400.   attr_accessor :shortcut  
  401.   attr_accessor :auto_ff_reset
  402.   attr_accessor :cinema
  403.   attr_accessor :cinema_z
  404.   attr_accessor :reposition_on_turn
  405.   attr_accessor :allow_offscreen
  406.   attr_accessor :dist_exit
  407.   attr_accessor :dist_max
  408.  
  409.   def default_setting
  410.     # change windowskin at message
  411.     @speech_windowskin  = [FILENAME_SPEECH_WINDOWSKIN,  FILENAME_SPEECH_TAIL ]
  412.     @thought_windowskin = [FILENAME_THOUGHT_WINDOWSKIN, FILENAME_THOUGHT_TAIL]
  413.    
  414.     # enable/disable message log
  415.     @message_log = true
  416.  
  417.     # whether or not messages appear one letter at a time
  418.     @letter_by_letter = true
  419.     # note: can also change within a single message with \L
  420.  
  421.     # the default speed at which text appears in letter-by-letter mode
  422.     @text_speed = 1
  423.     # note: can also change within a single message with \S[n]
  424.    
  425.     # whether or not players can skip to the end of (letter-by-letter) messages
  426.     @skippable = true
  427.    
  428.     # whether or not messages are automatically resized based on the message
  429.     @resize = true
  430.    
  431.     # whether or not message windows are positioned above
  432.     # characters/events by default, i.e. without needing \P every message
  433.     # (only works if resize messages enabled -- otherwise would look very odd)
  434.     @floating = true
  435.    
  436.     # whether or not to automatically center lines within the message
  437.     @autocenter = true
  438.    
  439.     # whether or not event-positioned messages have a tail(for speech balloons)
  440.     # (only works if floating and resized messages enabled -- otherwise would
  441.     # look very odd indeed)
  442.     @show_tail = true
  443.    
  444.     # whether or not to display "waiting for user input" pause graphic
  445.     # (probably want this disabled for speech balloons)
  446.     @show_pause = false
  447.  
  448.     # whether the player is permitted to move while messages are displayed
  449.     @move_during = true
  450.    
  451.     # the default location for floating messages (relative to the event)
  452.     # note that an off-screen message will be "flipped" automatically
  453.     @location = TOP
  454.    
  455.     # font details
  456.     # overrides all defaults; leave nil to just use defaults (e.g. as above)
  457.     @font_name = nil
  458.     @font_size = nil
  459.     @font_color = nil
  460.    
  461.     # auto shrink (buggy)
  462.     @auto_shrink = false
  463.    
  464.     # message opacity, insert 0-255
  465.     @opacity = 180
  466.    
  467.    
  468.     # pause on these characters ,.?!
  469.     # pause for delay number of frames if this is true, toggle with \A in Text
  470.     @auto_comma_pause = true
  471.     # inserts this number of frames to ,!.? characters, nil for off    
  472.     @auto_comma_delay = 10
  473.    
  474.     # designers can allow or disallow choices, why not number windows too?
  475.     @allow_cancel_numbers = false
  476.    
  477.     # Sounds While Speaking Related
  478.     @sound = false                          # Enables or Disables Text Sounds  
  479.     @sound_audio = '001-System01'          # Audio SE (in DB) to play
  480.     @sound_volume = 80                     # Text Sound Volume
  481.     @sound_pitch = 100                     # Text Sound Pitch
  482.     @sound_pitch_range = 20                # How Much to vary the Pitch
  483.     @sound_vary_pitch = true               # Whether to Vary the Pitch or not
  484.     @sound_frequency = 3                   # Plays a sound this many letters
  485.    
  486.     # reset foot_forward stance on auto-close due to Event going off-screen
  487.     @auto_ff_reset = true
  488.    
  489.     # For shortcut reference
  490.     @shortcut = {
  491.        :A => 'This is for shortcut purposes',
  492.        :Wdyt => 'What do you think?',
  493.     }
  494.    
  495.     @cinema = false # Cinema movie flag (don't change it)
  496.     @cinema_z = 900 # Screen z for cinema movie mode
  497.    
  498.     # reposition the message window if the speaker turns
  499.     @reposition_on_turn = true
  500.     @allow_offscreen = false
  501.    
  502.     # exit if distance from speaker is too great
  503.     @dist_exit = true
  504.     # distance player can be before window closes
  505.     @dist_max = 4
  506.   end
  507.  
  508. end
  509.  
  510. #==============================================================================
  511. # Private constants (don't edit)
  512. #==============================================================================
  513.  
  514.   # used for message.location
  515.   TOP    = 8
  516.   BOTTOM = 2
  517.   LEFT   = 4
  518.   RIGHT  = 6
  519.  
  520.   Nothing = Struct.new(:update, :dispose)
  521.  
  522. #==============================================================================
  523. # ? SG::Skin
  524. #==============================================================================
  525.  
  526. class Skin_Windowskin
  527.   #--------------------------------------------------------------------------
  528.   # ? instances settings
  529.   #--------------------------------------------------------------------------
  530.   attr_accessor  :margin, :bitmap
  531.   #--------------------------------------------------------------------------
  532.   # ? initialize
  533.   #--------------------------------------------------------------------------
  534.   def initialize
  535.     @bitmap = nil
  536.     @values = {}
  537.     @values['bg'] = Rect.new(0, 0, 128, 128)
  538.     @values['pause0'] = Rect.new(160, 64, 16, 16)
  539.     @values['pause1'] = Rect.new(176, 64, 16, 16)
  540.     @values['pause2'] = Rect.new(160, 80, 16, 16)
  541.     @values['pause3'] = Rect.new(176, 80, 16, 16)
  542.     @values['arrow_up'] = Rect.new(152, 16, 16, 8)
  543.     @values['arrow_down'] = Rect.new(152, 40, 16, 8)
  544.     @values['arrow_left'] = Rect.new(144, 24, 8, 16)
  545.     @values['arrow_right'] = Rect.new(168, 24, 8, 16)
  546.     self.margin = 16
  547.   end
  548.   #--------------------------------------------------------------------------
  549.   # ? width
  550.   #--------------------------------------------------------------------------
  551.   def margin=(width)
  552.     @margin = width
  553.     set_values
  554.   end
  555.   #--------------------------------------------------------------------------
  556.   # ? set_values
  557.   #--------------------------------------------------------------------------
  558.   def set_values
  559.     w = @margin
  560.     @values['ul_corner'] = Rect.new(128, 0, w, w)
  561.     @values['ur_corner'] = Rect.new(192-w, 0, w, w)
  562.     @values['dl_corner'] = Rect.new(128, 64-w, w, w)
  563.     @values['dr_corner'] = Rect.new(192-w, 64-w, w, w)
  564.     @values['up'] = Rect.new(128+w, 0, 64-2*w, w)
  565.     @values['down'] = Rect.new(128+w, 64-w, 64-2*w, w)
  566.     @values['left'] = Rect.new(128, w, w, 64-2*w)
  567.     @values['right'] = Rect.new(192-w, w, w, 64-2*w)
  568.   end
  569.   #--------------------------------------------------------------------------
  570.   # ? []
  571.   #--------------------------------------------------------------------------
  572.   def [](value) @values[value] end
  573. end
  574.  
  575. #==============================================================================
  576. # ** Window_Message
  577. #------------------------------------------------------------------------------
  578. #  This message window is used to display text.
  579. #==============================================================================
  580. class Window_Message < Window_Selectable
  581.   #--------------------------------------------------------------------------
  582.   # * Public Instance Variables
  583.   #--------------------------------------------------------------------------
  584.   attr_accessor :choice_window, :event_id
  585.   # Characters that produce Text Sounds - a to z and 0 thru 9
  586.   CHARACTERS = [('a'..'z'),('0'..'9')].map{|i| i.to_a}.flatten
  587.   #--------------------------------------------------------------------------
  588.   # * Initialize
  589.   #--------------------------------------------------------------------------
  590.   def initialize(msgindex=0)
  591.     super(80, 304, 480, 160)
  592.     self.contents = Bitmap.new(width - 32, height - 32)
  593.     self.visible = false
  594.     self.z = 1000 + msgindex * 5 # permits messages to overlap legibly
  595.     $game_system.update if !$game_system.message
  596.     message_eval('message.default_setting if !message.text_speed')
  597.     @fade_in = @fade_out = @contents_showing = false
  598.     @cursor_width = 0
  599.     self.active = false
  600.     self.index = -1
  601.     @msgindex = msgindex
  602.     @tail = Sprite.new
  603.     create_bitmap_tail
  604.     # make origin the center, not top left corner
  605.     @tail.ox = @tail.bitmap.width/2
  606.     @tail.oy = @tail.bitmap.height/2
  607.     @tail.z = self.z + 10
  608.     @tail.visible = false
  609.     create_bitmap_windowskin
  610.     refresh_font
  611.     @update_text = true
  612.     @letter_by_letter = $game_system.message.letter_by_letter
  613.     @text_speed       = $game_system.message.text_speed
  614.     # id of character for speech balloons
  615.     @float_id = nil
  616.     # location of box relative to speaker
  617.     @location         = $game_system.message.location
  618.     @auto_ff_reset    = $game_system.message.auto_ff_reset
  619.     @fwindowskin      = Sprite.new
  620.     @fwindowskin.bitmap = Bitmap.new(640,480)
  621.   end
  622.   #--------------------------------------------------------------------------
  623.   # * create_bitmap_tail
  624.   #--------------------------------------------------------------------------
  625.   def create_bitmap_tail
  626.     @tail.bitmap = if @speech_windowskin && @speech_windowskin.is_a?(Array) &&
  627.       FileTest.exist?('Graphics/Windowskins/'+@speech_windowskin[1])
  628.         if @msgindex == 0
  629.           RPG::Cache.windowskin(@speech_windowskin[1])
  630.         else
  631.           # don't use cached version or else all tails
  632.           # are rotated when multiple are visible at once
  633.           Bitmap.new('Graphics/Windowskins/'+@speech_windowskin[1])
  634.         end
  635.       else
  636.         RPG::Cache.windowskin('')
  637.       end
  638.     # keep track of orientation of tail bitmap
  639.     @tail.bitmap.orientation = 0 if @tail.bitmap.orientation == nil
  640.   end
  641.   #--------------------------------------------------------------------------
  642.   # * create_bitmap_windowskin
  643.   #--------------------------------------------------------------------------
  644.   def create_bitmap_windowskin
  645.     @windowskin = if $game_system.message.floating && @speech_windowskin &&
  646.         $game_system.message.resize &&  @speech_windowskin.is_a?(Array) &&
  647.          FileTest.exist?('Graphics/Windowskins/'+@speech_windowskin[0])
  648.         @speech_windowskin[0]
  649.       else
  650.         # use windowskin specified in database
  651.         $game_system.windowskin_name
  652.       end
  653.   end
  654.   #--------------------------------------------------------------------------
  655.   # * refresh font
  656.   #--------------------------------------------------------------------------
  657.   def refresh_font
  658.     if $game_system.message.floating && $game_system.message.resize
  659.       # if used as speech balloons, use constants
  660.       @font_name = $game_system.message.font_name || SPEECH_FONT_NAME
  661.       @font_color = check_color($game_system.message.font_color ||
  662.                     SPEECH_FONT_COLOR)
  663.       @font_size = $game_system.message.font_size || SPEECH_FONT_SIZE
  664.     else
  665.       # use default font
  666.       @font_name = Font.default_name
  667.       @font_color = Font.default_color
  668.       @font_size = Font.default_size
  669.     end
  670.   end
  671.   #--------------------------------------------------------------------------
  672.   # * Dispose
  673.   #--------------------------------------------------------------------------
  674.   def dispose
  675.     terminate_message
  676.     # have to check all windows before claiming that no window is showing
  677.     if $game_temp.message_text.compact.empty?
  678.       $game_temp.message_window_showing = false
  679.     end
  680.     @fwindowskin.dispose if !@fwindowskin.disposed?
  681.     @input_number_window.dispose if @input_number_window != nil
  682.     super
  683.   end
  684.   #--------------------------------------------------------------------------
  685.   # * Terminate Message
  686.   #--------------------------------------------------------------------------
  687.   def terminate_message
  688.     return if $game_temp.input_in_window
  689.     self.active = false
  690.     self.pause = false
  691.     self.index = -1
  692.     self.contents.clear
  693.     @fwindowskin.bitmap.clear if !@fwindowskin.nil? && !@fwindowskin.disposed?
  694.     # Clear showing flag
  695.     @contents_showing = false
  696.     # Clear variables related to text, choices, and number input
  697.     @tail.visible = false
  698.     # note that these variables are now indexed arrays
  699.     $game_temp.message_text = [] if !$game_temp.message_text.is_a?(Array)
  700.     $game_temp.message_proc = [] if !$game_temp.message_proc.is_a?(Array)
  701.     $game_temp.message_text[@msgindex] = nil
  702.     # Call message callback
  703.     if $game_temp.message_proc[@msgindex] != nil
  704.       # make sure no message boxes are displaying
  705.       if $game_temp.message_text.compact.empty?
  706.         $game_temp.message_proc[@msgindex].call
  707.         message_interpreter.class.send(:attr_accessor,:message_waiting)
  708.         $game_temp.message_window_showing = false  
  709.         message_interpreter.message_waiting = false
  710.       end
  711.       $game_temp.message_proc[@msgindex] = nil
  712.     end
  713.     @update_text = true
  714.     $game_temp.choice_start = 99
  715.     $game_temp.choice_max = 0
  716.     $game_temp.choice_cancel_type = 0
  717.     $game_temp.choice_proc = nil
  718.     $game_temp.num_input_start = 99
  719.     $game_temp.num_input_variable_id = 0
  720.     $game_temp.num_input_digits_max = 0
  721.     # Open gold window
  722.     if @gold_window != nil
  723.       @gold_window.dispose
  724.       @gold_window = nil
  725.     end
  726.   end
  727.   #--------------------------------------------------------------------------
  728.   # * Refresh
  729.   #--------------------------------------------------------------------------
  730.   def refresh
  731.     self.contents.clear
  732.     @fwindowskin.bitmap.clear if !@fwindowskin.nil? && !@fwindowskin.disposed?
  733.     @x = @y = 0 # now instance variables
  734.     @float_id = nil
  735.     @location = $game_system.message.location
  736.     @speech_windowskin  = $game_system.message.speech_windowskin
  737.     @thought_windowskin = $game_system.message.thought_windowskin
  738.     refresh_font
  739.     # override font defaults
  740.     @line_widths = nil
  741.     @wait_for_input = false
  742.     create_bitmap_windowskin
  743.     create_bitmap_tail
  744.     @dist_exit = $game_system.message.dist_exit
  745.     @dist_max = $game_system.message.dist_max
  746.     @text_speed = $game_system.message.text_speed
  747.     @letter_by_letter = $game_system.message.letter_by_letter
  748.     @delay = @text_speed
  749.     @player_skip = false
  750.     @cursor_width = 0
  751.     # Indent if choice
  752.     if $game_temp.choice_start == 0
  753.       @x = 8
  754.     end
  755.     # If waiting for a message to be displayed
  756.     if $game_temp.message_text[@msgindex] != nil
  757.       @text = $game_temp.message_text[@msgindex] # now an instance variable
  758.       # Control text processing
  759.       begin
  760.         last_text = @text.clone
  761.         @text.gsub!(/\[:(.+?)\]/) { $game_system.message.shortcut[$1.to_sym] }
  762.         @text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
  763.       end until @text == last_text
  764.       if @text.gsub!(/\\[Ee]\[([0-9]+),([0-9]+)\]/, '') != nil
  765.         @float_id = $1.to_i
  766.         @location = case $2.to_i
  767.           when 1..2 then 2
  768.           when 3..4 then 4
  769.           when 5..6 then 6
  770.           else 8
  771.         end
  772.       end
  773.       @text.gsub!(/\\[Nn]\[([0-9]+)\]/) {
  774.         $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : '' }
  775.       @text.gsub!(/\\[Nn][Aa][Mm][Ee]\[([0-9]+)\]/) {
  776.         $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : '' }
  777.       # Change "\\\\" to "\000" for convenience
  778.       @text.gsub!(/\\\\/) { "\000" }
  779.       @text.gsub!(/\\[Gg]/) { "\002" }
  780.       # display icon of item, weapon, armor or skill
  781.       @text.gsub!(/\\[Ii]\[([IiWwAaSs][0-9]+)\]/) { "\013[#{$1}]" }
  782.       # display name of enemy, item, weapon, armor or skill
  783.       @text.gsub!(/\\[Nn]\[([EeIiWwAaSsPp])([0-9]+)\]/) {
  784.         entity = case $1.downcase
  785.           when 'e' then $data_enemies[$2.to_i]
  786.           when 'i' then $data_items[$2.to_i]
  787.           when 'w' then $data_weapons[$2.to_i]
  788.           when 'a' then $data_armors[$2.to_i]
  789.           when 's' then $data_skills[$2.to_i]
  790.           when 'p' then $game_map.events[$2.to_i]
  791.         end
  792.         entity != nil ? entity.name : ''   }
  793.       # display icon and name of item, weapon, armor or skill
  794.       @text.gsub!(/\\[Ii]&[Nn]\[([IiWwAaSs])([0-9]+)\]/) {
  795.         entity = case $1.downcase
  796.           when 'e' then $data_enemies[$2.to_i]
  797.           when 'i' then $data_items[$2.to_i]
  798.           when 'w' then $data_weapons[$2.to_i]
  799.           when 'a' then $data_armors[$2.to_i]
  800.           when 's' then $data_skills[$2.to_i]
  801.         end
  802.         entity != nil ? "\013[#{$1+$2}] " + entity.name : ''    }      
  803.       # display name of current map
  804.       @text.gsub!(/\\[Mm][Aa][Pp]/) { $game_map.name }
  805.       # change font color
  806.       @text.gsub!(/\\[Cc]\[([0-9]+|#[0-9A-Fa-f]{6,6})\]/) { "\001[#{$1}]" }
  807.       # return to default color
  808.       @text.gsub!(/\\[Cc]/) { "\001" }
  809.       # toggle letter-by-letter mode
  810.       @text.gsub!(/\\[Ll]/) { "\003" }
  811.       # change text speed (for letter-by-letter)
  812.       @text.gsub!(/\\[Ss]\[([0-9]+)\]/) { "\004[#{$1}]" }
  813.       # insert delay
  814.       @text.gsub!(/\\[Dd]\[([0-9]+)\]/) { "\005[#{$1}]" }      
  815.       # change z
  816.       @text.gsub!(/\\[Zz]\[([0-9]+)\]/) { "\024[#{$1}]" }      
  817.      
  818.      
  819.       # self close message
  820.       @text.gsub!(/\\[!]/) { "\006" }
  821.       # wait for button input
  822.       @text.gsub!(/\\[?]/) { "\007" }
  823.       # bold
  824.       @text.gsub!(/\\[Bb]/) { "\010" }
  825.       # italic
  826.       @text.gsub!(/\\[Ii]/) { "\011" }
  827.       # new line
  828.       @text.gsub!(/\\[n]/) { "\n" }
  829.       # name
  830.       @text.gsub!(/\\[Ff][Oo][Nn][Tt]\[(.+?),([0-9]+)\]/) { "\023[#{$1},#{$2}]" }
  831.       @text.gsub!(/\\[Ff]\+/) { "\020" }
  832.       @text.gsub!(/\\[Ff]\-/) { "\021" }      
  833.       @text.gsub!(/\\[Ff]\*/) { "\022" }        
  834.       @text.gsub!(/\\[Ff]\[(.+?)(?:,(\d+))?\]/) { "\014[#{$1}]" }
  835.       @text.gsub!(/\\[Aa]\[([0-9]+),([0-9]+)\]/) { "\015[#{$1},#{$2}]" }
  836.       @text.gsub!(/\\[Aa]\[(.+?)(?:(\d+))?\]/) { "\016[#{$1}]" }
  837.       @text.gsub!(/\\[Rr]\[(.+?)\]/) { "\017[#{$1}]" }
  838.       # insert delays for commas, periods, questions and exclamations
  839.       @text.gsub!(/, /) { ", \017[#d]" }    # Comma with One Space
  840.       @text.gsub!(/!  /) { "!  \017[#d]" }  # Exclamation Point with Two Spaces
  841.       @text.gsub!(/\?  /) { "?  \017[#d]"} # Question Mark with Two Spaces
  842.       @text.gsub!(/\.  /) { ".  \017[#d]" } # Period with Two Spaces
  843.      
  844.       @text.gsub!(/\\[*]/, '<!@multi_message, @message_waiting = true, false>')
  845.       @text.gsub!(/\\[Mm][Oo][Vv]/) { '<!message.cinema = !message.cinema>' }
  846.       @text.gsub!(/\\[Dd][Ii][Ss][Tt]\[([0-9]+)\]/) { "<@@dist = #{$1}>" }
  847.       @text.gsub!(/[<][!](.+?)[>]/) { "\017[#si#{$1}]" }
  848.       @text.gsub!(/[<][@](.+?)[>]/) { "\017[#ss#{$1}]" }
  849.      
  850.       # thought balloon
  851.       if @text.gsub!(/\\[@]/, '') != nil
  852.         @windowskin = @thought_windowskin && @thought_windowskin.is_a?(Array) &&
  853.            FileTest.exist?('Graphics/Windowskins/'+@thought_windowskin[0]) ?
  854.             @thought_windowskin[0] : $game_system.windowskin_name
  855.         @font_name = THOUGHT_FONT_NAME
  856.         @font_size = THOUGHT_FONT_SIZE
  857.         @font_color = check_color(THOUGHT_FONT_COLOR)
  858.         @tail.bitmap = if @thought_windowskin &&
  859.           @thought_windowskin.is_a?(Array) &&
  860.           FileTest.exist?('Graphics/Windowskins/'+@thought_windowskin[1])
  861.             if @msgindex == 0
  862.               RPG::Cache.windowskin(@thought_windowskin[1])
  863.             else
  864.               Bitmap.new('Graphics/Windowskins/'+@thought_windowskin[1])
  865.             end
  866.           else
  867.             RPG::Cache.windowskin('')
  868.           end
  869.         @tail.bitmap.orientation = 0 if @tail.bitmap.orientation == nil
  870.       end
  871.       # Get rid of "\\+" (multiple messages)
  872.       @text.gsub!(/\\[+]/, '')
  873.       @text.gsub!(/\\[#]/, '')
  874.      
  875.       # Get rid of "\\P" (position window to given character)
  876.       if @text.gsub!(/\\[Pp]\[([0-9]+),([0-9]+)\]/, '') != nil
  877.         @float_id = [$1.to_i,$2.to_i]
  878.       elsif @text.gsub!(/\\[Pp]\[([0-9]+)\]/, '') != nil
  879.         @float_id = $1.to_i
  880.       elsif @text.gsub!(/\\[Pp]\[([a-zA-Z])\]/, '') != nil &&
  881.           $game_temp.in_battle
  882.         @float_id = $1.downcase
  883.       elsif @text.gsub!(/\\[Pp]/, '') != nil ||
  884.         ($game_system.message.floating && $game_system.message.resize) &&
  885.         (!$game_temp.in_battle)
  886.         message_interpreter.class.send(:attr_reader, :event_id)
  887.         @float_id = message_interpreter.event_id
  888.       end
  889.      
  890.       # Get rid of "\\^", "\\v", "\\<", "\\>" (relative message location)
  891.       if @text.gsub!(/\\\^/, '') != nil
  892.         @location = 8
  893.       elsif @text.gsub!(/\\[Vv]/, '') != nil
  894.         @location = 2
  895.       elsif @text.gsub!(/\\[<]/, '') != nil
  896.         @location = 4
  897.       elsif @text.gsub!(/\\[>]/, '') != nil
  898.         @location = 6
  899.       elsif @text.gsub!(/\\[%]/, '') != nil && !$game_temp.in_battle    
  900.         e = (@float_id > 0) ? $game_map.events[@float_id] : $game_player
  901.         @auto_orient = 1    
  902.         @location = case e.direction
  903.         when 8 then 2
  904.         when 2 then 8
  905.         when 6 then 4
  906.         when 4 then 6
  907.         end
  908.       end
  909.       ufmt = @text.clone
  910.       ufmt.gsub!(/[\001-\007](\[[#A-Fa-f0-9]+\])?/, '')
  911.       ufmt.gsub!(/\013\[(.+?)\]/, '\013')
  912.       ufmt.gsub!(/[\014-\017](\[(.+?)(?:(\d+))?\])?/, '')
  913.       ufmt.gsub!(/\016\[(.+?),(.+?)\]/, '')
  914.       ufmt.gsub!(/[\020-\025]\[(.+?),([0-9]+)\]?/, '')
  915.       @text.gsub!(/\\[Aa][Nn][Ii](?:\[([0-9]+)\])?/, '')
  916.       if $game_system.message.resize || $game_system.message.autocenter
  917.         # calculate length of lines
  918.         text = ufmt.clone
  919.         temp_bitmap = Bitmap.new(1,1)
  920.         temp_bitmap.font.name = @font_name
  921.         temp_bitmap.font.size = @font_size
  922.         @linerenew = false
  923.         @line_widths = [0,0,0,0,0,0,0,0]
  924.         (0..@line_widths.size-1).each  do |i|
  925.           line = text.split(/\n/)[@line_widths.size-1-i]
  926.           next if line.nil?
  927.           line.gsub!(/\\[Aa][Nn][Ii](?:\[([0-9]+)\])?/, '')
  928.           line.chomp.split(//).each do |c|
  929.             case c
  930.             when "\000"
  931.               c = "\\"
  932.             when "\010"
  933.               # bold
  934.               temp_bitmap.font.bold = !temp_bitmap.font.bold
  935.               next
  936.             when "\011"
  937.               # italics
  938.               temp_bitmap.font.italic = !temp_bitmap.font.italic
  939.               next
  940.             when "\013"
  941.               # icon
  942.               @line_widths[@line_widths.size-1-i] += 24
  943.               next
  944.             end
  945.             @line_widths[@line_widths.size-1-i] += temp_bitmap.text_size(c).width
  946.           end
  947.           if (@line_widths.size-1-i) >= $game_temp.choice_start
  948.             # account for indenting
  949.             @line_widths[@line_widths.size-1-i] += 8 unless $game_system.message.autocenter
  950.           end
  951.         end
  952.         if $game_temp.num_input_variable_id > 0
  953.           # determine cursor_width as in Window_InputNumber
  954.           # (can't get from @input_number_window because it doesn't exist yet)
  955.           cursor_width = temp_bitmap.text_size('0').width + 8
  956.           # use this width to calculate line width (+8 for indent)
  957.           input_number_width = cursor_width*$game_temp.num_input_digits_max
  958.           input_number_width += 8 unless $game_system.message.autocenter
  959.           @line_widths[$game_temp.num_input_start] = input_number_width
  960.         end
  961.         temp_bitmap.dispose
  962.       end
  963.       resize
  964.       reposition if @float_id != nil
  965.       self.contents.font.name = @font_name
  966.       self.contents.font.size = @font_size
  967.       self.contents.font.color = @font_color
  968.       self.windowskin = RPG::Cache.windowskin(@windowskin)
  969.       # autocenter first line if enabled
  970.       # (subsequent lines are done as '\n' is encountered)
  971.       if $game_system.message.autocenter && @text != ''
  972.         @x = (self.width-40)/2 - @line_widths[0]/2
  973.       end
  974.        @animations.each { |ani| unless ani.disposed?;ani.bitmap.dispose;ani.dispose;end } unless @animations.nil?
  975.       @letter_animations.each { |ani| ani.dispose } unless @letter_animations.nil?
  976.       @animations = []
  977.       @letter_animations = []
  978.  
  979.       ufmt.gsub!(/\\[Aa][Nn][Ii]/) { "\001" }
  980.       temp_bitmap = Bitmap.new(1,1)
  981.       temp_bitmap.font.name = @font_name
  982.       temp_bitmap.font.size = @font_size
  983.       animation = [0, []]
  984.       lanimation = [0, []]
  985.       x, y = 0, 0
  986.       center = $game_system.message.autocenter
  987.       if (center && x == (self.width-40)/2 - @line_widths[0]/2)  ||
  988.          (!center && x == 0)
  989.          x = center ? ((self.width-40)/2 - @line_widths[0]/2) : 0
  990.       end
  991.       # Update cursor width if choice
  992.       if $game_temp.choice_start == 0
  993.         width = $game_system.message.autocenter ? @line_widths[y]+8 : x
  994.       end
  995.       if $game_system.message.autocenter && ufmt != ''
  996.         x = (self.width-40)/2 - @line_widths[y]/2 if @line_widths[y]
  997.       else
  998.         x = 0
  999.         # Indent if choice
  1000.         x = 8 if $game_temp.choice_start == 0
  1001.       end
  1002.       while ((c = ufmt.slice!(/./m)) != nil)
  1003.         case c
  1004.         when "\000"
  1005.           c = "\\"
  1006.         when "\010"
  1007.           temp_bitmap.font.bold = !temp_bitmap.font.bold
  1008.           next
  1009.         when "\011"
  1010.           temp_bitmap.font.italic = !temp_bitmap.font.italic
  1011.           next
  1012.         when "\001"
  1013.           if animation[0] != 0
  1014.             animation[1][-1].width = x + 4 - animation[1][-1].x
  1015.             @animations.push(animation)
  1016.           elsif lanimation[0] != 0
  1017.             @letter_animations.push(lanimation)
  1018.           end
  1019.           animation = [0, []]
  1020.           lanimation = [0, []]
  1021.           if ufmt.index(/\[(\d+)\]/) == 0
  1022.             ufmt.sub!(/\[(\d+)\]/, '')
  1023.             type = $1.to_i
  1024.             if type == 0
  1025.               animation[1] = []
  1026.             elsif type <= 8
  1027.               animation[0] = $1.to_i
  1028.               animation[1].push(Rect.new(4 + x, 32 * y, 0, 32))
  1029.             else
  1030.               lanimation[0] = $1.to_i - 8
  1031.             end
  1032.           else
  1033.             animation[0] = 0
  1034.             lanimation[0] = 0
  1035.           end
  1036.           next
  1037.         when "\n"
  1038.           if animation[0] != 0
  1039.             animation[1][-1].width = x + 4 - animation[1][-1].x
  1040.           end
  1041.           center = $game_system.message.autocenter
  1042.           if (center && x == (self.width-40)/2 - @line_widths[y]/2)  ||
  1043.              (!center && x == 0)
  1044.              x = center ? ((self.width-40)/2 - @line_widths[y]/2) : 0
  1045.           end
  1046.           # Update cursor width if choice
  1047.           if y >= $game_temp.choice_start
  1048.             width = $game_system.message.autocenter ? @line_widths[y]+8 : x
  1049.           end
  1050.           # Add 1 to y
  1051.           y += 1
  1052.           if $game_system.message.autocenter && ufmt != ''
  1053.             x = (self.width-40)/2 - @line_widths[y]/2 if @line_widths[y]
  1054.           else
  1055.             x = 0
  1056.             # Indent if choice
  1057.             x = 8 if y >= $game_temp.choice_start
  1058.           end
  1059.           if animation[0] != 0
  1060.             animation[1].push(Rect.new(x + 4, y * 32, 0, 32))
  1061.           end
  1062.           # go to next text
  1063.           next
  1064.         end
  1065.        
  1066.         size = contents.text_size(c)
  1067.         if lanimation[0] != 0
  1068.           lanimation[1].push(Rect.new(x + 4, y * 32, size.width, 32))
  1069.         end
  1070.         x += size.width
  1071.       end
  1072.       if animation[0] != 0
  1073.         animation[1][-1].width = x + 4 - animation[1][-1].x
  1074.         @animations.push(animation)
  1075.       elsif lanimation[0] != 0
  1076.         @letter_animations.push(lanimation)
  1077.       end
  1078.     end
  1079.   end
  1080.   #--------------------------------------------------------------------------
  1081.   # * Resize Window
  1082.   #--------------------------------------------------------------------------
  1083.   def resize
  1084.     if !$game_system.message.resize
  1085.       # reset to defaults
  1086.       self.width = 480
  1087.       self.height = 160
  1088.       self.contents = Bitmap.new(width - 32, height - 32)
  1089.       self.x = 80 # undo any centering
  1090.       return
  1091.     end
  1092.     max_x = @line_widths.max
  1093.     max_y = 8
  1094.     @line_widths.each {|line| max_y -= 1 if line == 0 && max_y > 1}
  1095.     if $game_temp.choice_max  > 0
  1096.       # account for indenting
  1097.       max_x += 8 unless $game_system.message.autocenter
  1098.     end
  1099.     new_width = max_x + 40
  1100.     t = @thought_windowskin && @thought_windowskin.is_a?(Array)
  1101.     if t && @windowskin == @thought_windowskin[0] && THOUGHT_WIDTH_MULTIPLE >0
  1102.       # force window width to be a multiple of THOUGHT_WIDTH_MULTIPLE
  1103.       # so that specialty windowskins (e.g. thought balloon) look right
  1104.       if new_width % THOUGHT_WIDTH_MULTIPLE != 0
  1105.         new_width += THOUGHT_WIDTH_MULTIPLE-(new_width%THOUGHT_WIDTH_MULTIPLE)
  1106.       end
  1107.     end
  1108.     self.width = new_width
  1109.     new_height = max_y * 32 + 32
  1110.     self.height = $game_system.message.auto_shrink ? 1 * 32 + 32 : new_height    
  1111.     self.contents = Bitmap.new(width - 32, new_height - 32)
  1112.     self.x = 320 - (self.width/2) # center
  1113.   end
  1114.   #--------------------------------------------------------------------------
  1115.   # * Reposition Window
  1116.   #--------------------------------------------------------------------------
  1117.   def reposition
  1118.     if @float_id.is_a?(Array)
  1119.       char_height = 1
  1120.       char_width = 1
  1121.       char_x = @float_id[0]
  1122.       char_y = @float_id[1]
  1123.     elsif $game_temp.in_battle
  1124.       if 'abcd'.include?(@float_id) # must be between a and d
  1125.         @float_id = @float_id[0] - 97 # a = 0, b = 1, c = 2, d = 3
  1126.         return if $scene.spriteset.actor_sprites[@float_id] == nil
  1127.         sprite = $scene.spriteset.actor_sprites[@float_id]
  1128.       else
  1129.         @float_id -= 1 # account for, e.g., player entering 1 for index 0
  1130.         return if $scene.spriteset.enemy_sprites[@float_id] == nil
  1131.         sprite = $scene.spriteset.enemy_sprites[@float_id]
  1132.       end
  1133.       char_height = sprite.height
  1134.       char_width = sprite.width
  1135.       char_x = sprite.x
  1136.       char_y = sprite.y - char_height/2
  1137.     else # not in battle...
  1138.       char = (@float_id == 0 ? $game_player : $game_map.events[@float_id])
  1139.       if char == nil
  1140.         # no such character
  1141.         @float_id = nil
  1142.         return
  1143.       end
  1144.       # close message (and stop event processing) if speaker is off-screen
  1145.       if speaker_offscreen(char) ||  
  1146.         ($game_system.message.allow_offscreen && !$game_temp.in_battle &&
  1147.         (self.height - self.y > 480 || self.height + self.y < 0 ||
  1148.           self.width - self.x > 640 || self.width + self.x < 0)) ||
  1149.          ($game_system.message.move_during &&  @dist_exit &&
  1150.            @float_id > 0 && !char.within_range?(@dist_max, @float_id) &&
  1151.            @float_id == @event_id )
  1152.         terminate_message
  1153.         message_interpreter.command_115
  1154.         if !@fwindowskin.nil? && !@fwindowskin.disposed?
  1155.           @fwindowskin.visible = false
  1156.           @fwindowskin.bitmap.dispose if !@fwindowskin.bitmap.disposed?
  1157.           @fwindowskin.dispose
  1158.           @fwindowskin = nil
  1159.         end
  1160.         char.foot_forward_off  if @auto_ff_reset && !char.no_ff
  1161.         @auto_ff_reset = false
  1162.         return
  1163.       end
  1164.       if char.character_name =~ /[8]/i
  1165.         char_height = RPG::Cache.character(char.character_name,0).height / 8
  1166.       else
  1167.         char_height = RPG::Cache.character(char.character_name,0).height / 4
  1168.       end
  1169.       if char.character_name =~ /[s]/i
  1170.         char_width = RPG::Cache.character(char.character_name,0).width / 8
  1171.       else
  1172.         char_width = RPG::Cache.character(char.character_name,0).width / 4
  1173.       end
  1174.       # record coords of character's center
  1175.       char_x = record_screen_xy(char)[0]
  1176.       char_y = record_screen_xy(char)[1] - char_height/2
  1177.     end
  1178.     params = [char_height, char_width, char_x, char_y]
  1179.     # position window and message tail
  1180.     vars = new_position(params)
  1181.     x,y = vars[0], vars[1]
  1182.     # check if any window locations need to be 'flipped'
  1183.     offsc = (!$game_system.message.allow_offscreen || $game_temp.in_battle)
  1184.     flip = need_flip?(@float_id, @location, x, y, params)
  1185.     loc4 = ((x < 0 && !@face) || (x < 90 && @face)) && offsc
  1186.     if @location == 4 && (loc4 || flip)
  1187.       if @auto_orient == 1 and need_flip?(@float_id, @location, x, y)
  1188.         @location = put_behind(@float_id, 6)
  1189.       else  # switch to right
  1190.         @location = 6
  1191.       end
  1192.       vars = new_position(params)
  1193.       x = vars[0]
  1194.       if (x + self.width) > 640 && offsc
  1195.         # right is no good either...
  1196.         if y >= 0
  1197.           # switch to top
  1198.           @location = 8
  1199.           vars = new_position(params)
  1200.         else
  1201.           # switch to bottom
  1202.           @location = 2
  1203.           vars = new_position(params)
  1204.         end
  1205.       end
  1206.     elsif @location == 6 && (((x + self.width) > 640 && offsc) || flip)
  1207.       if @auto_orient == 1 and need_flip?(@float_id, @location, x, y)
  1208.         @location = put_behind(@float_id, 4)
  1209.       else     # switch to left
  1210.         @location = 4
  1211.       end
  1212.       vars = new_position(params)
  1213.       x = vars[0]
  1214.       if x < 0 && offsc
  1215.         # left is no good either...
  1216.         if y >= 0
  1217.           # switch to top
  1218.           @location = 8
  1219.           vars = new_position(params)
  1220.         else
  1221.           # switch to bottom
  1222.           @location = 2
  1223.           vars = new_position(params)
  1224.         end
  1225.       end
  1226.     elsif @location == 8 && ((y < 0 && offsc) || flip)
  1227.       if @auto_orient == 1 and need_flip?(@float_id, @location, x, y)
  1228.         @location = put_behind(@float_id, 2)
  1229.       else     # switch to bottom
  1230.         @location = 2
  1231.       end
  1232.       vars = new_position(params)
  1233.       y = vars[1]
  1234.       if (y + self.height) > 480 && offsc
  1235.         # bottom is no good either...
  1236.         # note: this will probably never occur given only 3 lines of text
  1237.         x = vars[0]
  1238.         if x >= 0
  1239.           # switch to left
  1240.           @location = 4
  1241.           vars = new_position(params)
  1242.         else
  1243.           # switch to right
  1244.           @location = 6
  1245.           vars = new_position(params)
  1246.         end
  1247.       end
  1248.     elsif @location == 2 && (((y + self.height) > 480 && offsc) || flip)
  1249.       if @auto_orient == 1 and need_flip?(@float_id, @location, x, y)
  1250.         @location = put_behind(@float_id, 8)
  1251.       else   # switch to top
  1252.         @location = 8
  1253.       end
  1254.       vars = new_position(params)
  1255.       y = vars[1]
  1256.       if y < 0 && offsc
  1257.         # top is no good either...
  1258.         # note: this will probably never occur given only 3 lines of text
  1259.         x = vars[0]
  1260.         if x >= 0
  1261.           # switch to left
  1262.           @location = 4
  1263.           vars = new_position(params)
  1264.         else
  1265.           # switch to right
  1266.           @location = 6
  1267.           vars = new_position(params)
  1268.         end
  1269.       end
  1270.     end
  1271.     x = vars[0]
  1272.     y = vars[1]
  1273.     tail_x = vars[2]
  1274.     tail_y = vars[3]    
  1275.     # adjust windows if near edge of screen
  1276.     if offsc
  1277.       if x < 0 && !@face
  1278.         x = 0
  1279.       elsif x < 90 && @face
  1280.         x = 90
  1281.       elsif (x + self.width) > 640
  1282.         x = 640 - self.width
  1283.       end
  1284.       if y < 0
  1285.         y = [y, 0].max
  1286.       elsif (y + self.height) > 480
  1287.         y = 480 - self.height
  1288.       elsif $game_temp.in_battle && @location == 2 && (y > (320 - self.height))
  1289.         # when in battle, prevent enemy messages from overlapping battle status
  1290.         # (note that it could still happen from actor messages, though)
  1291.         y = 320 - self.height
  1292.         tail_y = y
  1293.       end
  1294.     end
  1295.     # finalize positions
  1296.     self.x = x
  1297.     self.y = y
  1298.     @tail.x = tail_x
  1299.     @tail.y = tail_y
  1300.     v = case @location
  1301.     when 2, 6 then -15
  1302.     when 4, 8 then -17
  1303.     end
  1304.     if @contents_showing  #!$game_temp.message_text.compact.empty?
  1305.       draw_window
  1306.       @fwindowskin.dispose if !@fwindowskin.nil? && !@fwindowskin.disposed?
  1307.       @fwindowskin = Sprite.new
  1308.       @fwindowskin.z = self.z - 10
  1309.       @fwindowskin.bitmap = Bitmap.new(640,480)
  1310.       @fwindowskin.bitmap.blt(x,y,@frame.bitmap,@frame.bitmap.rect)
  1311.       @fwindowskin.bitmap.blt(tail_x+v,tail_y+v,@tail.bitmap,
  1312.                  @tail.bitmap.rect) if show_message_tail?
  1313.       @fwindowskin.opacity = $game_system.message.opacity
  1314.       if @face && self.height > 64
  1315.         a = 80
  1316.         while a >= -10
  1317.           @fwindowskin.bitmap.blt(@face.x+a,y,@frame.bitmap,
  1318.             Rect.new(0,0,@face.bitmap.width-45,@frame.bitmap.height))
  1319.           a = (a == 5) ? 15 : a - 25
  1320.         end
  1321.       end
  1322.       self.opacity = @tail.opacity = 0
  1323.       @frame.dispose
  1324.     end
  1325.     bit = @tail.bitmap
  1326.   end
  1327.   #--------------------------------------------------------------------------
  1328.   # Prevent Player from walking under Message Bubbles
  1329.   #--------------------------------------------------------------------------
  1330.   def need_flip?(event_id, loc, x, y, params = nil)
  1331.     return false if !@auto_orient || @fade_out ||  event_id.nil? ||
  1332.                     (event_id != 0 && $game_map.events[event_id].erased) ||
  1333.                     $game_temp.in_battle ||
  1334.                     !$game_system.message.reposition_on_turn ||
  1335.                     !$game_system.message.move_during
  1336.     # vars for speaker
  1337.     event = (event_id > 0) ? $game_map.events[event_id] : $game_player
  1338.     dir = event.direction
  1339.     # if an argument is passed called params and not allowed offscreen  
  1340.     if params and not $game_system.message.allow_offscreen
  1341.       case loc
  1342.         when 2 then new_loc = 8
  1343.         when 4 then new_loc = 6
  1344.         when 6 then new_loc = 4
  1345.         when 8 then new_loc = 2
  1346.       end
  1347.       # check what the new coordinates of a repositioned window will be  
  1348.       new_vars = new_position(params, new_loc, no_rotate = true)
  1349.       new_x = new_vars[0]
  1350.       new_y = new_vars[1]
  1351.       # return false if not allowed off screen and new position is off screen
  1352.       if (new_x < 0 && new_loc == 4) ||    (new_x + self.width > 640) ||
  1353.          (new_y < 0) ||    (new_y + self.height > 480)
  1354.         # if not allowed offscreen and trying to flip offscreen
  1355.         return false
  1356.       end
  1357.     end
  1358.     # default result
  1359.     result = false
  1360.     result = true if @auto_orient == 2 &&  dir == loc
  1361.     if @auto_orient == 1
  1362.       if event_id > 1
  1363.         # If Auto Orient Any Direction, try to put preference on top / bottom
  1364.         # Top / Bottom Preference was made for readability of Msgs
  1365.         # because it is easier to go off screen left and right
  1366.         if dir == loc ||  ((dir == 2 || dir == 8) && (loc == 4 || loc == 6))
  1367.           result = true
  1368.         end
  1369.       elsif event_id == 0
  1370.         if ((dir == 2 && loc != 8) || (dir == 4 && loc != 6) ||
  1371.            (dir == 6 && loc != 4) ||  (dir == 8 && loc != 2))
  1372.           result = true
  1373.         end
  1374.       end
  1375.     end
  1376.     return result
  1377.   end
  1378.   #--------------------------------------------------------------------------
  1379.   # Place Message Bubble behind Speaker
  1380.   #--------------------------------------------------------------------------
  1381.   def put_behind(event_id, default_loc)
  1382.     return default_loc if event_id.nil? or $game_temp.in_battle
  1383.     dir = (event_id > 0 ) ? $game_map.events[event_id].direction :
  1384.           $game_player.direction
  1385.     return 2 if dir == 8
  1386.     return 4 if dir == 6
  1387.     return 6 if dir == 4
  1388.     return 8 if dir == 2
  1389.     return default_loc
  1390.   end  
  1391.   #--------------------------------------------------------------------------
  1392.   # ? speaker_offscreen
  1393.   #--------------------------------------------------------------------------
  1394.   def speaker_offscreen(char)
  1395.     return record_screen_xy(char)[0] <= 0 || record_screen_xy(char)[0] >= 640 ||
  1396.            record_screen_xy(char)[1] <= 0 || record_screen_xy(char)[1] > 480
  1397.   end
  1398.   #--------------------------------------------------------------------------
  1399.   # ? record_screen_xy
  1400.   #--------------------------------------------------------------------------
  1401.   def record_screen_xy(char)
  1402.     return char.rev_scr_xy || [char.screen_x,char.screen_y]
  1403.   end
  1404.   #--------------------------------------------------------------------------
  1405.   # ? draw_window
  1406.   #--------------------------------------------------------------------------
  1407.   def draw_window(width = self.width, height = self.height,win = @windowskin )
  1408.     @skin = Skin_Windowskin.new
  1409.     @skin.bitmap = RPG::Cache.windowskin(win)
  1410.     @frame,@bg   = Sprite.new, Sprite.new()
  1411.     @width,@height = width, height
  1412.     return if @skin.bitmap == nil
  1413.     return if @width == 0 or @height == 0
  1414.     m = @skin.margin
  1415.     if @frame.bitmap.nil?
  1416.       @frame.bitmap = Bitmap.new(@width, @height)
  1417.       @bg.bitmap = Bitmap.new(@width - 4, @height - 4)
  1418.     end
  1419.     @frame.bitmap.clear
  1420.     @bg.bitmap.clear
  1421.     dest_rect = Rect.new(0, 0, @width-4, @height-4)
  1422.     @bg.bitmap.stretch_blt(dest_rect, @skin.bitmap, @skin['bg'])
  1423.     bx = Integer((@width - m*2) / @skin['up'].width) + 1
  1424.     by = Integer((@height - m*2) / @skin['left'].height) + 1
  1425.     (0..bx).each { |x|
  1426.       w = @skin['up'].width
  1427.       @frame.bitmap.blt(x * w + m, 0, @skin.bitmap, @skin['up'])
  1428.       @frame.bitmap.blt(x * w + m, @height - m, @skin.bitmap, @skin['down'])}
  1429.     @frame.bitmap.stretch_blt(Rect.new(2, 2, @frame.bitmap.width-4,
  1430.          @frame.bitmap.height-4), @bg.bitmap, @bg.bitmap.rect)
  1431.     (0..by).each { |y|
  1432.       h = @skin['left'].height
  1433.       @frame.bitmap.blt(0, y * h + m, @skin.bitmap, @skin['left'])
  1434.       @frame.bitmap.blt(@width - m, y * h + m, @skin.bitmap, @skin['right'])}
  1435.     @frame.bitmap.erase(@width - m, 0, m, m)
  1436.     @frame.bitmap.erase(0, @height - m, m, m)
  1437.     @frame.bitmap.erase(@width - m, @height - m, m, m)
  1438.     @frame.bitmap.stretch_blt(Rect.new(2, 2, @frame.bitmap.width-4,
  1439.          @frame.bitmap.height-4), @bg.bitmap, @bg.bitmap.rect)
  1440.     @frame.bitmap.blt(0, 0, @skin.bitmap, @skin['ul_corner'])
  1441.     @frame.bitmap.blt(@width - m, 0, @skin.bitmap, @skin['ur_corner'])
  1442.     @frame.bitmap.blt(0, @height - m, @skin.bitmap, @skin['dl_corner'])
  1443.     @frame.bitmap.blt(@width - m, @height - m, @skin.bitmap, @skin['dr_corner'])
  1444.     @frame.bitmap.blt(@width - m, @height - m, @skin.bitmap, @skin['dr_corner'])
  1445.     @bg.dispose
  1446.   end
  1447.   #--------------------------------------------------------------------------
  1448.   # * Determine New Window Position
  1449.   #--------------------------------------------------------------------------  
  1450.   def new_position(params, location = @location, no_rotate = nil)
  1451.     char_height, char_width, char_x, char_y = params
  1452.     if location == 8
  1453.       # top
  1454.       x = char_x - self.width/2
  1455.       y = char_y - char_height/2 - self.height - @tail.bitmap.height/2
  1456.       @tail.bitmap.rotation(0)  unless no_rotate
  1457.       tail_x = x + self.width/2
  1458.       tail_y = y + self.height
  1459.     elsif location == 2
  1460.       # bottom
  1461.       x = char_x - self.width/2
  1462.       y = char_y + char_height/2 + @tail.bitmap.height/2
  1463.       @tail.bitmap.rotation(180) unless no_rotate
  1464.       tail_x = x + self.width/2
  1465.       tail_y = y
  1466.     elsif location == 4
  1467.       # left
  1468.       x = char_x - char_width/2 - self.width - @tail.bitmap.width/2
  1469.       y = char_y - self.height/2
  1470.       @tail.bitmap.rotation(270) unless no_rotate
  1471.       tail_x = x + self.width
  1472.       tail_y = y + self.height/2
  1473.     elsif location == 6
  1474.       # right
  1475.       x = char_x + char_width/2 + @tail.bitmap.width/2
  1476.       y = char_y - self.height/2
  1477.       @tail.bitmap.rotation(90) unless no_rotate
  1478.       tail_x = x
  1479.       tail_y = y + self.height/2
  1480.     end
  1481.     return [x,y,tail_x,tail_y]
  1482.   end
  1483.   #--------------------------------------------------------------------------
  1484.   # * Update Text
  1485.   #--------------------------------------------------------------------------  
  1486.   def update_text
  1487.     if @text != nil
  1488.       # Get 1 text character in c (loop until unable to get text)
  1489.       while ((c = @text.slice!(/./m)) != nil)
  1490.         # Plays Sounds for each Letter, Numbers and Spaces Excluded
  1491.         if $game_system.message.sound && @letter_by_letter && !@player_skip &&
  1492.            CHARACTERS.include?(c.downcase)
  1493.           # Increment for each Letter Sound Played
  1494.           @sound_counter = @sound_counter || 0 + 1
  1495.           # Prevents Division by Zero, allows 0 to play a sound every letter
  1496.           frequency = $game_system.message.sound_frequency
  1497.           frequency = (frequency == 0) ? @sound_counter : frequency
  1498.           # Play Sound for each New Word or if Remainder is 0
  1499.           if @sound_counter == 1 or @sound_counter % frequency == 0
  1500.             # Play correct sound for each letter
  1501.             play_text_sound(c.downcase)
  1502.           end
  1503.         else
  1504.           @sound_counter = 0
  1505.         end        
  1506.         # If \\
  1507.         if c == "\000"
  1508.           # Return to original text
  1509.           c = "\\"
  1510.         end
  1511.         # If \C[n] or \C[#xxxxxx] or \C
  1512.         if c == "\001"
  1513.           # Change text color
  1514.           @text.sub!(/\[([0-9]+|#[0-9A-Fa-f]{6,6})\]/, '')
  1515.           if $1 != nil
  1516.             self.contents.font.color = check_color($1)
  1517.           else
  1518.             # return to default color
  1519.             if $game_system.message.font_color != nil
  1520.               color = check_color($game_system.message.font_color)
  1521.             elsif $game_system.message.floating && $game_system.message.resize
  1522.               color = check_color(SPEECH_FONT_COLOR)
  1523.             else
  1524.               # use defaults
  1525.               color = Font.default_color
  1526.             end
  1527.             self.contents.font.color = color
  1528.           end
  1529.           # go to next text
  1530.           next
  1531.         end
  1532.         # If \G
  1533.         if c == "\002"
  1534.           # Make gold window
  1535.           if @gold_window == nil
  1536.             @gold_window = Window_Gold.new
  1537.             @gold_window.x = 560 - @gold_window.width
  1538.             if $game_temp.in_battle
  1539.               @gold_window.y = 192
  1540.             else
  1541.               @gold_window.y = self.y >= 128 ? 32 : 384
  1542.             end
  1543.             @gold_window.opacity = $game_system.message.opacity
  1544.             @gold_window.back_opacity = self.back_opacity
  1545.           end
  1546.           # go to next text
  1547.           next
  1548.         end
  1549.         # If \L
  1550.         if c == "\003"
  1551.           # toggle letter-by-letter mode
  1552.           @letter_by_letter = !@letter_by_letter
  1553.           # go to next text
  1554.           next
  1555.         end
  1556.         # If \S[n]
  1557.         if c == "\004"
  1558.           @text.sub!(/\[([0-9]+)\]/, '')
  1559.           speed = $1.to_i
  1560.           if speed >= 0
  1561.             @text_speed = speed
  1562.             # reset player skip after text speed change
  1563.             @player_skip = false            
  1564.           end
  1565.           return
  1566.         end
  1567.         # If \D[n]
  1568.         if c == "\005"
  1569.           @text.sub!(/\[([0-9]+)\]/, '')
  1570.           delay = $1.to_i
  1571.           if delay >= 0
  1572.             @delay += delay
  1573.             # reset player skip after delay
  1574.             @player_skip = false
  1575.           end
  1576.           return
  1577.         end  
  1578.         # If \!
  1579.         if c == "\006"
  1580.           # close message and return from method
  1581.           terminate_message
  1582.           return
  1583.         end
  1584.         # If \?
  1585.         if c == "\007"
  1586.           @wait_for_input = true
  1587.           return
  1588.         end
  1589.         if c == "\010"
  1590.           # bold
  1591.           self.contents.font.bold = !self.contents.font.bold
  1592.           return
  1593.         end
  1594.         if c == "\023"
  1595.           # change font
  1596.           @text.sub!(/\[(.+?),([0-9]+)\]/,  '')
  1597.           self.contents.font.name = $1
  1598.           self.contents.font.size = $2.to_i
  1599.           return
  1600.         end
  1601.         if c == "\011"
  1602.           # italics
  1603.           self.contents.font.italic = !self.contents.font.italic
  1604.           return
  1605.         end
  1606.         if c == "\013"
  1607.           # display icon of item, weapon, armor or skill
  1608.           @text.sub!(/\[([IiWwAaSs])([0-9]+)\]/, '')
  1609.           return if $1.nil?
  1610.           case $1.downcase
  1611.             when 'i'
  1612.               item = $data_items[$2.to_i]
  1613.             when 'w'
  1614.               item = $data_weapons[$2.to_i]
  1615.             when 'a'
  1616.               item = $data_armors[$2.to_i]
  1617.             when 's'
  1618.               item = $data_skills[$2.to_i]
  1619.           end
  1620.           if item == nil
  1621.             return
  1622.           end
  1623.           bitmap = RPG::Cache.icon(item.icon_name)
  1624.           self.contents.blt(4+@x, 32*@y+4, bitmap, Rect.new(0, 0, 24, 24))
  1625.           @x += 24
  1626.           #self.contents.draw_text(x + 28, y, 212, 32, item.name)
  1627.           return
  1628.         end
  1629.         if c == "\014"
  1630.           @text.sub!(/\[(.+?)(?:,(\d+))?\]/, '')
  1631.           face = $1.to_s
  1632.           if  face != '' && face['|']
  1633.             face = face.split('|')
  1634.             create_portrait(face)
  1635.             return
  1636.           end
  1637.           create_face_sprite(face) if face != ''  
  1638.           return
  1639.         end
  1640.         if c == "\015" || c == "\016"
  1641.           if c == "\015"
  1642.             @text.sub!(/\[([0-9]+),([0-9]+)\]/, '')
  1643.             name = $game_actors[$1.to_i].name.dup
  1644.             face = case $1.to_i
  1645.             when 1 then sprintf("zdc-%02d", $2.to_i)
  1646.             when 2 then sprintf("spc-%02d", $2.to_i)
  1647.             when 3 then sprintf("freya-%02d", $2.to_i)
  1648.             when 4 then sprintf("chris-%02d", $2.to_i)
  1649.             end
  1650.           elsif c == "\016"
  1651.             @text.sub!(/\[(.+?)(?:(\d+))?\]/, '')
  1652.             name = $1.to_s
  1653.           end
  1654.           create_name_sprite(name) if name != ''
  1655.           create_face_sprite(face)
  1656.         end
  1657.         if c == "\017"
  1658.           @text.sub!(/\[(.+?)\]/, '')
  1659.           text = [$1.to_s]
  1660.           if text[0] == "#d"
  1661.             if $game_system.message.auto_comma_pause && @letter_by_letter
  1662.               delay = @text_speed + $game_system.message.auto_comma_delay
  1663.               if delay >= 0
  1664.                 @delay += delay
  1665.                 # reset player skip after delay
  1666.                 @player_skip = false
  1667.               end
  1668.             end
  1669.             return    
  1670.           elsif text[0].sub!(/#si/, '') != nil
  1671.             text[0].sub!('(!', '[')
  1672.             text[0].sub!('!)', ']')
  1673.             message_eval(text[0])
  1674.           elsif text[0].sub!(/#ss/, '') != nil
  1675.             text[0].sub!('(!', '[')
  1676.             text[0].sub!('!)', ']')
  1677.             eval(text[0])
  1678.           else
  1679.             self.contents.font.size -= 4
  1680.             text[1] = self.contents.text_size( text[0]  ).width
  1681.             self.contents.draw_text(4 + @x, 32 * @y-10, 10*text[1], 32,text[0] )
  1682.             self.contents.font.size += 4
  1683.           end
  1684.         end
  1685.         # if \F+ (Foot Forward Animation On)
  1686.         if c == "\020" && @float_id && !@float_id.is_a?(Array)
  1687.           speaker = (@float_id > 0) ? $game_map.events[@float_id] : $game_player
  1688.           speaker.foot_forward_on
  1689.           return
  1690.         end
  1691.         # if \F- (Foot Forward Animation Off)  
  1692.         if c == "\021" && @float_id && !@float_id.is_a?(Array)
  1693.           speaker = (@float_id > 0) ? $game_map.events[@float_id] : $game_player
  1694.           speaker.foot_forward_off
  1695.           return
  1696.         end
  1697.         # if \F* (Foot Forward Animation On "Other" Foot)
  1698.         if c == "\022" && @float_id && !@float_id.is_a?(Array)
  1699.           speaker = (@float_id > 0) ? $game_map.events[@float_id] : $game_player
  1700.           speaker.foot_forward_on(frame = 1)
  1701.           return
  1702.         end          
  1703.         # If \Z[n]
  1704.         if c == "\024"
  1705.           @text.sub!(/\[([0-9]+)\]/, '')
  1706.           self.z = $1.to_i
  1707.           @tail.z = self.z + 10
  1708.           @face.z = self.z  if @face
  1709.           @fwindowskin.z = self.z if @fwindowskin
  1710.           @name_sprite.z = self.z + 101 if @name_sprite
  1711.           return
  1712.         end        # If new line text
  1713.         if c == "\n"
  1714.           center = $game_system.message.autocenter
  1715.           if (center && @x == (self.width-40)/2 - @line_widths[@y]/2)  ||
  1716.              (!center && @x == 0)  
  1717.              @line_widths[@y] = nil
  1718.              @line_widths.compact!
  1719.              @x = center ? ((self.width-40)/2 - @line_widths[@y]/2) : 0
  1720.             return
  1721.           end
  1722.           # Update cursor width if choice
  1723.           if @y >= $game_temp.choice_start
  1724.             width = $game_system.message.autocenter ? @line_widths[@y]+8 : @x
  1725.             @cursor_width = [@cursor_width, width].max
  1726.           end
  1727.           # Add 1 to y
  1728.           @y += 1
  1729.           if $game_system.message.auto_shrink
  1730.             while self.height < @y * 32 + 32
  1731.               Graphics.update
  1732.               self.height += 1
  1733.               reposition
  1734.             end
  1735.             face_position
  1736.             self.height = @y * 32 + 32
  1737.           end
  1738.           if $game_system.message.autocenter && @text != ''
  1739.             @x = (self.width-40)/2 - @line_widths[@y]/2 if @line_widths[@y]
  1740.           else
  1741.             @x = 0
  1742.             # Indent if choice
  1743.             @x = 8 if @y >= $game_temp.choice_start
  1744.           end
  1745.           # go to next text
  1746.           next
  1747.         end
  1748.         # Draw text
  1749.         self.contents.draw_text(4 + @x, 32 * @y, 40, 32, c)
  1750.         # Add x to drawn text width
  1751.         @x += self.contents.text_size( c ).width
  1752.         # add text speed to time to display next character
  1753.         @delay += @text_speed unless !@letter_by_letter || @player_skip
  1754.         return if @letter_by_letter && !@player_skip
  1755.       end
  1756.      
  1757.       @animations = @animations.map { |ani|
  1758.              AnimationSprite.new(ani[0], self.x + 16,
  1759.              self.y + 16, self.z + 1, ani[1], self.contents) }
  1760.       @letter_animations = @letter_animations.map { |ani|
  1761.                 AnimationLetters.new(ani[0], self.x + 16,
  1762.                 self.y + 16, self.z + 1, ani[1], self.contents) }
  1763.       @animations.each { |i| i.opacity = self.contents_opacity }
  1764.       @letter_animations.each { |i| i.opacity = self.contents_opacity }
  1765.      
  1766.       height = self.contents.height+10
  1767.       height = [height, @face.bitmap.height+20].max if @face
  1768.       saved_bitmap = Bitmap.new(640,height)
  1769.       saved_bitmap.blt(100,10,self.contents,self.contents.rect)
  1770.       saved_bitmap.blt(@face.x-self.x+100,@face.y-self.y+10,
  1771.                     @face.bitmap,@face.bitmap.rect) if @face
  1772.       saved_bitmap.blt(@name_sprite.x-self.x+100,@name_sprite.y-self.y+10,
  1773.                 @name_sprite.bitmap,@name_sprite.bitmap.rect) if @name_sprite
  1774.       d =  $multiple_message_windows['saved']
  1775.       $multiple_message_windows['saved']=[] if !d || !d.is_a?(Array)  
  1776.       $multiple_message_windows['saved'].push (saved_bitmap)
  1777.       $multiple_message_windows['saved'].shift if d && d.size + 1 > 30
  1778.     end
  1779.     # If choice
  1780.     if $game_temp.choice_max > 0 && @choice_window
  1781.       @item_max = $game_temp.choice_max
  1782.       self.active = true
  1783.       if $choice_index && $choice_index.is_a?(Integer) &&
  1784.          $choice_index < $game_temp.choice_max
  1785.         self.index = $choice_index
  1786.       else
  1787.         self.index = 0
  1788.       end
  1789.     end
  1790.     # If number input
  1791.     if $game_temp.num_input_variable_id > 0 && @choice_window  
  1792.       digits_max = $game_temp.num_input_digits_max
  1793.       number = $game_variables[$game_temp.num_input_variable_id]
  1794.       @input_number_window = Window_InputNumber.new(digits_max)
  1795.       @input_number_window.set_font(@font_name, @font_size, @font_color)
  1796.       @input_number_window.number = number
  1797.       @input_number_window.x =
  1798.         if $game_system.message.autocenter
  1799.           offset = (self.width-40)/2-@line_widths[$game_temp.num_input_start]/2
  1800.           self.x + offset + 4
  1801.         else
  1802.           self.x + 8
  1803.         end
  1804.       @input_number_window.y = self.y + $game_temp.num_input_start * 32
  1805.     end
  1806.     @update_text = false
  1807.   end
  1808.   #--------------------------------------------------------------------------
  1809.   # * Message_Eval
  1810.   #--------------------------------------------------------------------------
  1811.   def message_eval(v)
  1812.     message_interpreter.message_eval(v)
  1813.   end
  1814.   #--------------------------------------------------------------------------
  1815.   # * Message_Interpreter
  1816.   #--------------------------------------------------------------------------
  1817.   def message_interpreter
  1818.     if $scene.is_a?(Scene_Map)
  1819.       $game_system.map_interpreter
  1820.     elsif $scene.is_a?(Scene_Battle)
  1821.       $game_system.battle_interpreter
  1822.     else
  1823.       Interpreter.new
  1824.     end
  1825.   end
  1826.   #--------------------------------------------------------------------------
  1827.   # * Reset Window
  1828.   #--------------------------------------------------------------------------
  1829.   def reset_window
  1830.     case $game_system.message_position
  1831.     when 0 then self.y = 16  # up
  1832.     when 1 then self.y = 160 # middle
  1833.     when 2 then self.y = 304 # down
  1834.     end
  1835.     self.y=16 if $game_temp.in_battle
  1836.     self.y=394 if $game_system.message.cinema && $game_system.message_frame > 0
  1837.     $game_system.message.opacity = 255 unless $game_system.message.opacity
  1838.     self.opacity = $game_system.message_frame == 0 ?
  1839.       $game_system.message.opacity : 0
  1840.     # transparent speech balloons don't look right, so keep opacity at 255
  1841.     # self.back_opacity = 160
  1842.     @tail.opacity = $game_system.message.opacity
  1843.   end
  1844.   #--------------------------------------------------------------------------
  1845.   # * Frame Update
  1846.   #--------------------------------------------------------------------------
  1847.   def update
  1848.     super
  1849.    
  1850.     if !@animations.nil? && !@fade_out &&
  1851.         @animations.all? { |ani|  ani.is_a?(AnimationSprite) } &&
  1852.         @letter_animations.all? { |ani| ani.is_a?(AnimationLetters) }
  1853.       @animations.each { |ani| ani.update(self.x + 16, self.y + 16) }
  1854.       @letter_animations.each { |ani| ani.update(self.x + 16, self.y + 16) }
  1855.     end
  1856.     # If fade in
  1857.     if @fade_in
  1858.       self.contents_opacity += 24
  1859.       if @input_number_window != nil
  1860.         @input_number_window.contents_opacity += 24
  1861.       end
  1862.       if !@animations.nil? &&  !@fade_out &&
  1863.           @animations.all? { |ani| ani.is_a?(AnimationSprite) } &&
  1864.           @letter_animations.all? { |ani| ani.is_a?(AnimationLetters) }
  1865.         @animations.each { |ani| ani.opacity = self.contents_opacity }
  1866.         @letter_animations.each { |ani| ani.opacity = self.contents_opacity }
  1867.       end
  1868.       if self.contents_opacity == 255
  1869.         @fade_in = false
  1870.       end
  1871.     end
  1872.     # If inputting number
  1873.     if @input_number_window != nil
  1874.       @input_number_window.update
  1875.       # Confirm
  1876.       if Input.trigger?(Input::C)
  1877.         # Allows windows to be closed
  1878.         $game_temp.input_in_window = false
  1879.         $game_system.se_play($data_system.decision_se)
  1880.         $game_variables[$game_temp.num_input_variable_id] =
  1881.           @input_number_window.number
  1882.         $game_system.number_cancelled = false        
  1883.         $game_map.need_refresh = true
  1884.         # Dispose of number input window
  1885.         @input_number_window.dispose
  1886.         @input_number_window = nil
  1887.         terminate_message
  1888.         return
  1889.       elsif Input.trigger?(Input::B) and
  1890.             $game_system.message.allow_cancel_numbers
  1891.         # play cancel sound effect
  1892.         $game_system.se_play($data_system.cancel_se)
  1893.         # Allows windows to be closed
  1894.         $game_temp.input_in_window = false
  1895.         # Set Variable to identify the Number Window was Cancelled
  1896.         $game_system.number_cancelled = true
  1897.         # Dispose of number input window
  1898.         @input_number_window.dispose
  1899.         @input_number_window = nil        
  1900.         if $scene.multi_message_window.compact.size > 1
  1901.           $scene.multi_message_window.each {|msg| msg.terminate_message }
  1902.         else
  1903.           terminate_message
  1904.         end
  1905.       end
  1906.     end
  1907.     # If message is being displayed
  1908.     if @contents_showing
  1909.       # Confirm or cancel finishes waiting for input or message
  1910.       if Input.trigger?(Input::C) || Input.trigger?(Input::B)
  1911.         if @wait_for_input
  1912.           @wait_for_input = false
  1913.           self.pause = false
  1914.         elsif $game_system.message.skippable
  1915.           @player_skip = true
  1916.         end
  1917.         # Dont close the window if waiting for choices to be displayed
  1918.         if $game_temp.input_in_window &&
  1919.            $game_temp.message_text.compact.size > 1 &&
  1920.            !$input_window_wait
  1921.           # wait until next input to confirm any choices
  1922.           $input_window_wait = true
  1923.           return
  1924.         else
  1925.           $input_window_wait = false          
  1926.         end
  1927.       end
  1928.       if need_reposition?
  1929.         reposition # update message position for character/screen movement
  1930.         if @contents_showing == false
  1931.           # i.e. if char moved off screen
  1932.           return
  1933.         end
  1934.       end
  1935.       if @update_text && !@wait_for_input
  1936.         if @delay == 0
  1937.           update_text
  1938.         else
  1939.           @delay -= 1
  1940.         end
  1941.         return
  1942.       end
  1943.       # If choice isn't being displayed, show pause sign
  1944.       if !self.pause && ($game_temp.choice_max == 0 || @wait_for_input)
  1945.         self.pause = true if $game_system.message.show_pause
  1946.       end
  1947.       # Cancel
  1948.       if Input.trigger?(Input::B)
  1949.         if $game_temp.choice_max > 0 && $game_temp.choice_cancel_type > 0
  1950.           # Allow ALL windows to be closed
  1951.           $game_temp.input_in_window = false
  1952.           $game_system.se_play($data_system.cancel_se)
  1953.           $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
  1954.           # If multi window cancel choice
  1955.           if $scene.multi_message_window.compact.size > 1
  1956.             $scene.multi_message_window.each {|msg| msg.terminate_message }
  1957.           else
  1958.             terminate_message
  1959.           end
  1960.         end
  1961.         # personal preference: cancel button should also continue
  1962.         terminate_message
  1963.       end
  1964.       # Confirm
  1965.       if Input.trigger?(Input::C)
  1966.         if $game_temp.choice_max > 0
  1967.           $game_temp.input_in_window = false
  1968.           if $scene.multi_message_window.compact.size > 1
  1969.             $scene.multi_message_window.compact.each { |window|
  1970.               if window.choice_window
  1971.                 # return selection position by index of the choice window
  1972.                 @index = window.index
  1973.               end    }
  1974.           end          
  1975.           $game_system.se_play($data_system.decision_se)
  1976.           $game_temp.choice_proc.call(self.index)
  1977.         end
  1978.         # If Preceeding Window not closed because choice displayed
  1979.         if $scene.multi_message_window.compact.size > 1
  1980.           choice = false
  1981.           $scene.multi_message_window.compact.each { |window|
  1982.             if window.choice_window
  1983.               choice = true
  1984.               break
  1985.             end }
  1986.           # If window is a choice window and other windows held open
  1987.           if choice
  1988.             # close all the message windows
  1989.             $scene.multi_message_window.each {|msg|  msg.terminate_message }
  1990.           else
  1991.             # close the single message window            
  1992.             terminate_message
  1993.           end
  1994.         else
  1995.           if $game_temp.choice_max > 0
  1996.             $game_system.se_play($data_system.decision_se)
  1997.             $game_temp.choice_proc.call(self.index)
  1998.           end
  1999.           terminate_message
  2000.         end
  2001.       end
  2002.         return
  2003.     end
  2004.     # If display wait message or choice exists when not fading out
  2005.     $game_temp.message_text = [] if !$game_temp.message_text.is_a?(Array)
  2006.     $game_temp.message_proc = [] if !$game_temp.message_proc.is_a?(Array)
  2007.     if @fade_out == false && $game_temp.message_text[@msgindex] != nil
  2008.       @contents_showing = true
  2009.       $game_temp.message_window_showing = true
  2010.       reset_window
  2011.       refresh
  2012.       Graphics.frame_reset
  2013.       self.visible = true
  2014.       if show_message_tail?
  2015.         @tail.visible = true
  2016.       elsif @tail.visible
  2017.         @tail.visible = false
  2018.       end
  2019.       self.contents_opacity = 0
  2020.       if !@animations.nil?  && !@fade_out &&
  2021.           @animations.all? { |ani| ani.is_a?(AnimationSprite) } &&
  2022.           @letter_animations.all? { |ani| ani.is_a?(AnimationLetters) }
  2023.         @animations.each { |ani| ani.opacity = self.contents_opacity }
  2024.         @letter_animations.each { |ani| ani.opacity = self.contents_opacity }
  2025.       end
  2026.       if @input_number_window != nil
  2027.         @input_number_window.contents_opacity = 0
  2028.       end
  2029.       @fade_in = true
  2030.       return
  2031.     end
  2032.     # If message which should be displayed is not shown, but window is visible
  2033.     if self.visible
  2034.       @fade_out = true
  2035.       self.opacity -= 96
  2036.       @tail.opacity -= 96 if @tail.opacity > 0
  2037.       if !@animations.nil?  && !@fade_out &&
  2038.         @animations.all? { |ani| ani.is_a?(AnimationSprite) } &&
  2039.         @letter_animations.all? { |ani| ani.is_a?(AnimationLetters) }
  2040.         @animations.each { |ani| ani.opacity =
  2041.                  self.opacity * self.contents_opacity / 255 }
  2042.         @letter_animations.each { |ani| ani.opacity =
  2043.                  self.opacity * self.contents_opacity / 255 }
  2044.       end
  2045.       if need_reposition?
  2046.         reposition # update message position for character/screen movement
  2047.       end
  2048.       if self.opacity == 0 #@fwindowskin.opacity == 0
  2049.         self.visible = false
  2050.         unless @animations.nil? || @animations.any? { |i| i.is_a?(Array) } ||
  2051.           @letter_animations.any? { |i| i.is_a?(Array) }
  2052.           @animations.each { |ani| ani.bitmap.dispose;ani.dispose }
  2053.           @letter_animations.each { |ani| ani.dispose }
  2054.         else
  2055.           @animations = @letter_animations = []
  2056.         end
  2057.       @fade_out = false
  2058.         @tail.visible = false if @tail.visible
  2059.         # have to check all windows before claiming that no window is showing
  2060.         if $game_temp.message_text.compact.empty?
  2061.           $game_temp.message_window_showing = false  
  2062.         end
  2063.       end
  2064.       return
  2065.     end
  2066.   end
  2067.   #--------------------------------------------------------------------------
  2068.   # * Repositioning Determination
  2069.   #--------------------------------------------------------------------------
  2070.   def need_reposition?
  2071.     if (!$game_temp.in_battle) && $game_system.message.floating &&
  2072.         $game_system.message.resize && @float_id != nil
  2073.       char = (@float_id == 0 ? $game_player : $game_map.events[@float_id])
  2074.       if !char.nil? && @screen_xy != record_screen_xy(char)
  2075.         @screen_xy = record_screen_xy(char)
  2076.         return true
  2077.       elsif $game_system.message.move_during && @float_id == 0 &&
  2078.           (($game_player.last_real_xy[0] != $game_player.real_x) ||
  2079.           ($game_player.last_real_xy[1] != $game_player.real_y))
  2080.           # player with floating message moved
  2081.           # (note that relying on moving? leads to "jumpy" message boxes)
  2082.           return true
  2083.       elsif ($game_map.last_disp_xy[1] != $game_map.display_y) ||
  2084.          ($game_map.last_disp_xy[0] != $game_map.display_x)
  2085.         # player movement or scroll event caused the screen to scroll
  2086.         return true
  2087.       else
  2088.         char = $game_map.events[@float_id]
  2089.         if char != nil &&
  2090.           ((char.last_real_xy[0] != char.real_x) ||
  2091.           (char.last_real_xy[1] != char.real_y))
  2092.           # character moved
  2093.           return true
  2094.         end
  2095.       end    
  2096.     end
  2097.     return false
  2098.   end
  2099.   #--------------------------------------------------------------------------
  2100.   # * Show Message Tail Determination
  2101.   #--------------------------------------------------------------------------
  2102.   def show_message_tail?
  2103.     if $game_system.message.show_tail && $game_system.message.floating &&
  2104.       $game_system.message.resize && $game_system.message_frame == 0 &&
  2105.       @float_id != nil
  2106.       return true
  2107.     end
  2108.     return false
  2109.   end
  2110.   #--------------------------------------------------------------------------
  2111.   # * update_cursor_rect
  2112.   #--------------------------------------------------------------------------
  2113.   def update_cursor_rect
  2114.     if @index >= 0
  2115.       n = $game_temp.choice_start + @index
  2116.       if $game_system.message.autocenter
  2117.         x = 4 + (self.width-40)/2 - @cursor_width/2
  2118.       else
  2119.         x = 8
  2120.       end
  2121.       self.cursor_rect.set(x, n * 32, @cursor_width, 32)
  2122.     else
  2123.       self.cursor_rect.empty
  2124.     end
  2125.   end
  2126.   #--------------------------------------------------------------------------
  2127.   # * Alias Listing
  2128.   #--------------------------------------------------------------------------
  2129.   alias drg128_term terminate_message unless method_defined?(:drg128_term)
  2130.   alias drg128_upd update unless method_defined?(:drg128_upd)
  2131.   alias drg128_rep reposition unless method_defined?(:drg128_rep)
  2132.   #--------------------------------------------------------------------------
  2133.   # * Create Face_Sprite
  2134.   #--------------------------------------------------------------------------
  2135.   def create_face_sprite(face='')
  2136.     terminate_face rescue return
  2137.     return if face.nil? || face == ' '
  2138.     dir = 'Graphics/Faces'
  2139.     Dir.mkdir(dir) unless File.directory?(dir)
  2140.     face = Bitmap.new("#{dir}/#{face}")
  2141.     bitmap = Bitmap.new(80,80)
  2142.     bitmap.stretch_blt(bitmap.rect, face, face.rect)
  2143.     create_face_cont(bitmap)
  2144.   end
  2145.   #--------------------------------------------------------------------------
  2146.   # * Create Face_Sprite
  2147.   #--------------------------------------------------------------------------
  2148.   def create_face_cont(bitmap)
  2149.     @face = Sprite.new
  2150.     @face.bitmap = bitmap
  2151.     @face.opacity = $game_system.message.opacity
  2152.     face_position rescue return
  2153.     reposition
  2154.   end
  2155.   #--------------------------------------------------------------------------
  2156.   # * Create Name_Sprite
  2157.   #--------------------------------------------------------------------------
  2158.   def create_name_sprite(name='')
  2159.     terminate_name_sprite
  2160.     bitmap = Bitmap.new(name.length*10, 32)
  2161.     bitmap.font = self.contents.font
  2162.     bitmap.font.size += 4
  2163.     bitmap.font.color = normal_color
  2164.       (0...2).each {|i|
  2165.         bitmap.draw_text(-i, i, name.length*10, 32, name)
  2166.         bitmap.draw_text(i, -i, name.length*10, 32, name)
  2167.         bitmap.draw_text(-i, -i, name.length*10, 32, name)
  2168.         bitmap.draw_text(i, i, name.length*10, 32, name)  }
  2169.     bitmap.font.color = self.contents.font.color
  2170.       (0...1).each {|i|
  2171.         bitmap.draw_text(-i, i, name.length*10, 32, name)
  2172.         bitmap.draw_text(i, -i, name.length*10, 32, name)
  2173.         bitmap.draw_text(-i, -i, name.length*10, 32, name)
  2174.         bitmap.draw_text(i, i, name.length*10, 32, name)   }
  2175.     @name_sprite = Sprite.new
  2176.     @name_sprite.bitmap = bitmap
  2177.     name_sprite_position
  2178.   end
  2179.   #--------------------------------------------------------------------------
  2180.   # * Face Position
  2181.   #--------------------------------------------------------------------------
  2182.   def face_position
  2183.     return if !@face || @face.disposed?  
  2184.     if $game_system.message.floating
  2185.       @face.x = self.x - (@face.bitmap.width * @face.zoom_x + 2)
  2186.       @face.y = self.y  + 20 * ([64-64, 0].max/32).floor
  2187.       @face.y -= [(10 - (self.height - 64)), -6].max
  2188.     else
  2189.       @face.zoom_x = 1.2
  2190.       @face.zoom_y = 1.2
  2191.       @face.x = self.x + (self.width - (@face.bitmap.width * @face.zoom_x + 8))
  2192.       @face.y = self.y + 10
  2193.     end
  2194.     @face.z = self.z
  2195.   end
  2196.   #--------------------------------------------------------------------------
  2197.   # * Name_Sprite Position
  2198.   #--------------------------------------------------------------------------
  2199.   def name_sprite_position
  2200.     return if !@name_sprite || @name_sprite.disposed?
  2201.     @name_sprite.y = self.y - 15
  2202.     @name_sprite.x = self.x + 10
  2203.     @name_sprite.z = self.z + 101
  2204.   end
  2205.   #--------------------------------------------------------------------------
  2206.   # * Terminate Face
  2207.   #--------------------------------------------------------------------------
  2208.   def terminate_face()  eval ('@face.dispose; @face = nil') if @face   end
  2209.   #--------------------------------------------------------------------------
  2210.   # * Terminate Name_Sprite
  2211.   #--------------------------------------------------------------------------
  2212.   def terminate_name_sprite()
  2213.     eval('@name_sprite.dispose; @name_sprite = nil')if @name_sprite
  2214.   end
  2215.   #--------------------------------------------------------------------------
  2216.   # * Terminate Message
  2217.   #--------------------------------------------------------------------------
  2218.   def terminate_message
  2219.     @fwindowskin.bitmap.clear if !@fwindowskin.nil? && !@fwindowskin.disposed?
  2220.     terminate_face
  2221.     terminate_name_sprite
  2222.     drg128_term
  2223.   end
  2224.   #--------------------------------------------------------------------------
  2225.   # * Update Frame
  2226.   #--------------------------------------------------------------------------
  2227.   def update
  2228.     temp = $game_temp.in_battle
  2229.     $game_temp.in_battle = $scene.is_a?(Scene_Battle)
  2230.     drg128_upd
  2231.     $game_temp.in_battle = temp
  2232.   end
  2233.   #--------------------------------------------------------------------------
  2234.   # * Reposition Window
  2235.   #--------------------------------------------------------------------------
  2236.   def reposition
  2237.     drg128_rep
  2238.     face_position
  2239.     name_sprite_position
  2240.   end
  2241.   #--------------------------------------------------------------------------
  2242.   # * Text Sound
  2243.   #--------------------------------------------------------------------------  
  2244.   def play_text_sound(char)
  2245.     sound = 'Audio/SE/' + $game_system.message.sound_audio
  2246.     volume = $game_system.message.sound_volume
  2247.     @sound_pitch =       $game_system.message.sound_pitch
  2248.    
  2249.     if $game_system.message.sound_vary_pitch and @sound_pitch
  2250.       @sound_pitch_range = $game_system.message.sound_pitch_range
  2251.       # Prevent Negative Numbers...
  2252.       sound_pitch_range = (@sound_pitch_range > @sound_pitch) ?
  2253.           @sound_pitch : @sound_pitch_range      
  2254.       # If we want to Randomize the Sounds
  2255.       if @sound_vary_pitch == 'random'
  2256.         # Random within the Range
  2257.         pitch = rand(sound_pitch_range * 2) + @sound_pitch - sound_pitch_range
  2258.       # Vary Sound Pitch to be based on Letter Sounds
  2259.       else
  2260.         # Note to Self - Reorganize based on actual Letter Sounds, not so Random
  2261.         if ['l','m','n','q','u','w','2'].include?(char)
  2262.           pitch = @sound_pitch - sound_pitch_range
  2263.         elsif ['a','f','h','j','k','o','r','x','1','4','7','8'].include?(char)
  2264.           pitch = @sound_pitch - sound_pitch_range / 2
  2265.         elsif ['b','c','d','e','g','p','t','v','z','0','3','6'].to_a.include?(char)
  2266.           pitch = @sound_pitch
  2267.         elsif ['s','7'].to_a.include?(char)
  2268.           pitch = @sound_pitch + sound_pitch_range / 2
  2269.         elsif ['i','y','5','9'].to_a.include?(char)
  2270.           pitch = @sound_pitch + sound_pitch_range
  2271.         else
  2272.           pitch = rand(@sound_pitch_range * 2) + @sound_pitch
  2273.         end
  2274.       end
  2275.     else
  2276.       pitch=(@sound_pitch and @sound_pitch.is_a?(Numeric)) ? @sound_pitch : 100
  2277.     end
  2278.     # Play the Sound
  2279.     Audio.se_play(sound, volume, pitch)
  2280.   end
  2281.   #--------------------------------------------------------------------------
  2282.   # * Alias Listing
  2283.   #--------------------------------------------------------------------------
  2284.   alias upd_mess_log update unless method_defined?(:upd_mess_log)
  2285.   alias dis_mess_log dispose unless method_defined?(:dis_mess_log)
  2286.   #--------------------------------------------------------------------------
  2287.   # * Create Message Log
  2288.   #--------------------------------------------------------------------------
  2289.   def create_message_log(win = MESSAGE_LOG_WINDOWSKIN)
  2290.     @message_log_sprite = [@message_log = Sprite.new,
  2291.                           @message_log_text = Sprite.new]
  2292.     @message_log.bitmap = Bitmap.new(600,460)
  2293.     @message_log_text.bitmap = @message_log.bitmap.dup
  2294.     @message_log.bitmap.clear
  2295.     @message_log_text.bitmap.clear
  2296.     @message_log.x, @message_log.y = 20, 10
  2297.     @message_log.z = self.z * 2
  2298.     @message_log.opacity = 200
  2299.     @message_log_text.opacity = 255
  2300.     @message_log_text.z = @message_log.z + 10
  2301.     draw_window(@message_log.bitmap.width, @message_log.bitmap.height, win)
  2302.     frame, mess = @frame.bitmap, @message_log.bitmap
  2303.     cls = [Color.new(0,0,0,0), Color.new(255,255,255,255)]
  2304.     @message_log.bitmap.blt(0,0,frame,frame.rect)
  2305.     @message_log_height = 0
  2306.     $multiple_message_windows['saved'].reverse.each_with_index {|i,s|
  2307.       next if s < @message_log_index
  2308.       @message_log_height +=(i.height+20)
  2309.       v = mess.height - @message_log_height
  2310.       @message_log_text.bitmap.blt(20 ,v ,i, i.rect)
  2311.       @message_log.bitmap.fill_rect( Rect.new(30,v-15,mess.width-60,2),cls[0])}
  2312.     @message_log.bitmap.blt(0,0,frame, Rect.new(0,0,frame.width,50))
  2313.     @message_log.bitmap.fill_rect( Rect.new(10,40, mess.width-20,2), cls[1])
  2314.     @message_log_text.bitmap.fill_rect( Rect.new(0,0,frame.width,55), cls[0])
  2315.     @message_log.bitmap.font.name = MESSAGE_LOG_FONT
  2316.     @message_log.bitmap.font.size = [MESSAGE_LOG_FONT[-1].to_i, 12].max
  2317.     @message_log.bitmap.draw_text(10,0,mess.width,  45,MESSAGE_LOG_TEXT)
  2318.     [@frame].each {|i| i.dispose}
  2319.   end
  2320.   #--------------------------------------------------------------------------
  2321.   # * Update Frame
  2322.   #--------------------------------------------------------------------------
  2323.   def update
  2324.     message_log_input if $game_system.message.message_log
  2325.     upd_mess_log if !@message_log
  2326.   end
  2327.   #--------------------------------------------------------------------------
  2328.   # * message_log_input
  2329.   #--------------------------------------------------------------------------
  2330.   def message_log_input
  2331.     sc = scroll #$game_temp.message_window_showing ? scroll : scroll
  2332.     if $multiple_message_windows['saved'] &&
  2333.       !$multiple_message_windows['saved'].empty? &&
  2334.       !@message_log && @msgindex == 0
  2335.       if input_message_log(sc)
  2336.         @message_log_move = [$game_system.message.move_during,
  2337.                             $game_temp.message_window_showing]
  2338.         $game_temp.message_window_showing = true
  2339.         $game_system.message.move_during = false
  2340.         $game_system.se_play($data_system.decision_se)
  2341.         @message_log_index = 0
  2342.         create_message_log
  2343.       end
  2344.     elsif @message_log && @msgindex == 0
  2345.       if cansel_mesage_log
  2346.         $game_system.message.move_during = @message_log_move[0]
  2347.         $game_temp.message_window_showing = @message_log_move[1]
  2348.         $game_system.se_play($data_system.cancel_se)
  2349.         @message_log_sprite.compact.each {|i| i.dispose}
  2350.         @message_log = nil
  2351.       end
  2352.       if elmessage_log(sc)
  2353.         s = @message_log_index
  2354.         @message_log_index = [@message_log_index + 1,
  2355.               $multiple_message_windows['saved'].size-1].min
  2356.         $game_system.se_play($data_system.cursor_se) if s != @message_log_index
  2357.         @message_log_sprite.compact.each {|i| i.dispose}
  2358.         create_message_log
  2359.       end
  2360.       if ermessage_log(sc)
  2361.         s = @message_log_index
  2362.         @message_log_index = [@message_log_index - 1,0].max
  2363.         $game_system.se_play($data_system.cursor_se) if s != @message_log_index
  2364.         @message_log_sprite.compact.each {|i| i.dispose}
  2365.         create_message_log
  2366.       end
  2367.     end
  2368.   end
  2369.   #--------------------------------------------------------------------------
  2370.   # * Button Trigger Message Log
  2371.   #--------------------------------------------------------------------------
  2372.   def input_message_log(sc = 0)
  2373.     return true if Input.trigger?(Input::F8)
  2374.     return true if sc > 0
  2375.     return false
  2376.   end
  2377.   def cansel_mesage_log
  2378.     begin
  2379.       return true if Input.trigger?(Input::F8)
  2380.       return true if Input.trigger?(Input::B)
  2381.       return true if Mouse_Glitchfinder.press?(Mouse_Glitchfinder::RBUTTON)
  2382.     rescue
  2383.       false
  2384.     end
  2385.     return false
  2386.   end
  2387.   def elmessage_log(sc = 0)
  2388.     return true if Input.trigger?(Input::L)
  2389.     return true if Input.repeat?(Input::UP)
  2390.     return true if sc > 0
  2391.     return false
  2392.   end
  2393.   def ermessage_log(sc = 0)
  2394.     return true if Input.trigger?(Input::R)
  2395.     return true if Input.repeat?(Input::DOWN)
  2396.     return true if sc < 0
  2397.     return false
  2398.   end
  2399.  
  2400.   def scroll
  2401.     @scroll_count = (@scroll_count || 0) + 1
  2402.     return 0 if @scroll_count < 5
  2403.     @scroll_count = 0
  2404.     result = Mouse_Glitchfinder.scroll rescue nil
  2405.     result = result[-1] if result != nil
  2406.     return result || 0
  2407.   end
  2408.   #--------------------------------------------------------------------------
  2409.   # * Dispose
  2410.   #--------------------------------------------------------------------------
  2411.   def dispose
  2412.     dis_mess_log
  2413.     @message_log_sprite.compact.each {|i| i.dispose} if @message_log_sprite
  2414.   end
  2415.   #--------------------------------------------------------------------------
  2416.   # * Alias Listing
  2417.   #--------------------------------------------------------------------------
  2418.   alias upd_portrait update unless method_defined?(:upd_portrait)
  2419.   alias term_face_por terminate_face unless method_defined?(:term_face_por)
  2420.   #--------------------------------------------------------------------------
  2421.   # * create_portrait
  2422.   #--------------------------------------------------------------------------
  2423.   def create_portrait(face)
  2424.     terminate_face rescue return
  2425.     return if face.nil? || face == ' ' #\f [portrait,face,coord,color,xy]
  2426.     dir, a, b = 'Graphics/Portrait', [204+5,28,204,204], [0,0]
  2427.     Dir.mkdir(dir) unless File.directory?(dir)
  2428.     a = face[2].split(',').map {|x| x.to_i } if face[2] && face[2] != ' '
  2429.     b = face[4].split(',').map {|x| x.to_i } if face[4] && face[4] != ' '
  2430.     c = face[3]
  2431.     d = Bitmap.new("#{dir}/#{face[0]}")
  2432.     e = Bitmap.new("#{dir}/#{face[1]}")  if face[1] && face[1][0].chr != ' '
  2433.     f = Bitmap.new(80,80)
  2434.     @portrait = Sprite.new
  2435.     @portrait.bitmap, @portrait.opacity = d, 0
  2436.     @portrait.x, @portrait.y = b[0], b[1]
  2437.     @portrait.bitmap.blt(0, 0, e || Bitmap.new(1,1),
  2438.         Rect.new(0,0,@portrait.bitmap.width,a[1]+a[3]))
  2439.     unless  c == ' '    
  2440.       f.fill_rect(Rect.new(0,0,80,80),check_color(0)) if c
  2441.       f.stretch_blt(f.rect, @portrait.bitmap, Rect.new(*a)) if face[1] != ' '
  2442.       f.fill_rect(Rect.new(0,0,80,2),check_color(c))  if c
  2443.       f.fill_rect(Rect.new(0,78,80,2),check_color(c)) if c
  2444.       f.fill_rect(Rect.new(0,0,2,80),check_color(c))  if c
  2445.       f.fill_rect(Rect.new(78,0,2,80),check_color(c)) if c
  2446.     end
  2447.     create_face_cont(f)
  2448.   end
  2449.   #--------------------------------------------------------------------------
  2450.   # * Update Frame
  2451.   #--------------------------------------------------------------------------
  2452.   def update
  2453.     @portrait.opacity = [@portrait.opacity+15, 255].min if @portrait
  2454.     upd_portrait
  2455.   end
  2456.   #--------------------------------------------------------------------------
  2457.   # * terminate_face
  2458.   #--------------------------------------------------------------------------
  2459.   def terminate_face
  2460.     term_face_por
  2461.     eval '@portrait.dispose;  @portrait = nil' if @portrait
  2462.   end
  2463. end
  2464. #==============================================================================
  2465. # ** Game_Character
  2466. #------------------------------------------------------------------------------
  2467. #  This class deals with characters. It's used as a superclass for the
  2468. #  Game_Player and Game_Event classes.
  2469. #==============================================================================
  2470.  
  2471. class Game_Character
  2472.   #--------------------------------------------------------------------------
  2473.   # * Public Instance Variables
  2474.   #--------------------------------------------------------------------------
  2475.   attr_accessor   :no_ff, :rev_scr_xy
  2476.   #--------------------------------------------------------------------------
  2477.   # * Name
  2478.   #---------------------------------------------------------------------------
  2479.   def name() self.is_a?(Game_Event) ? @event.name : $game_party.actors[0].name end
  2480.   #--------------------------------------------------------------------------
  2481.   # * last_real_xy
  2482.   #--------------------------------------------------------------------------
  2483.   def last_real_xy() [@real_x, @real_y] end
  2484.   #----------------------------------------------------------------------------
  2485.   # * Allows Animation Change regardless of Direction
  2486.   #----------------------------------------------------------------------------
  2487.   unless self.method_defined?('foot_forward_on')  
  2488.     def foot_forward_on(frame = 0)
  2489.       return if @direction_fix || !@walk_anime || @step_anime ||
  2490.                 $game_temp.in_battle
  2491.       @pattern = case @direction
  2492.       when 2       then frame == 0 ? 3 : 1
  2493.       when 4, 6, 8 then frame == 0 ? 1 : 3
  2494.       end || 0
  2495.       @original_pattern = @pattern
  2496.       refresh
  2497.     end
  2498.     def foot_forward_off
  2499.       # If called by walking off screen, dont affect a Sign or Stepping Actor
  2500.       return if $game_temp.in_battle || @direction_fix || !@walk_anime || @no_ff
  2501.       @pattern, @original_pattern = 0, 0
  2502.     end
  2503.   end
  2504.   #----------------------------------------------------------------------------
  2505.   # * within_range?
  2506.   #----------------------------------------------------------------------------
  2507.   def within_range?(range = 4, id = @event_id)
  2508.     e = $game_map.events[id]
  2509.     # using real_x and real_y to support BlizzABS pixel movement
  2510.     e = (Math.hypot((e.x-$game_player.real_x/128),
  2511.         (e.y-$game_player.real_y/128))).abs if e
  2512.     return (e <= range) if e
  2513.   end  
  2514. end
  2515.  
  2516. #==============================================================================
  2517. # ** Sprite_Battler
  2518. #------------------------------------------------------------------------------
  2519. #  This sprite is used to display the battler.It observes the Game_Character
  2520. #  class and automatically changes sprite conditions.
  2521. #==============================================================================
  2522. (0...3).each {|i| eval "
  2523. class #{['Sprite_Battler','Spriteset_Battle','Game_Temp'][i]}
  2524.  #--------------------------------------------------------------------------
  2525.  # * Public Instance Variables
  2526.  #--------------------------------------------------------------------------
  2527.  # necessary for positioning messages relative to battlers
  2528.  attr_reader :height, :width, :actor_sprites, :enemy_sprites
  2529.  attr_accessor :num_input_variable_id_backup, :input_in_window
  2530. end#"}
  2531.  
  2532. #==============================================================================
  2533. # ** Scene_Map
  2534. #------------------------------------------------------------------------------
  2535. #  This class performs map screen processing.
  2536. #==============================================================================
  2537. (0...4).each {|i| eval "
  2538. class #{['Scene_Map','Scene_Battle','Game_Player','Game_System'][i]}
  2539.  #--------------------------------------------------------------------------
  2540.  # * Public Instance Variables
  2541.  #--------------------------------------------------------------------------
  2542.  # necessary for accessing actor/enemy sprites in battle
  2543.  attr_accessor :spriteset, :multi_message_window
  2544.  attr_accessor :number_cancelled, :message
  2545.  #--------------------------------------------------------------------------
  2546.  # * Alias Listing
  2547.  #--------------------------------------------------------------------------
  2548.  alias drg128_upd update unless method_defined?(:drg128_upd)
  2549.  if [0,1].include?(#{i})
  2550.    alias drg128_main main unless method_defined?(:drg128_main)
  2551.  #--------------------------------------------------------------------------
  2552.  # * drg152_main
  2553.  #--------------------------------------------------------------------------
  2554.    def drg152_main
  2555.      @multi_message_window = [Window_Message.new(0)]  
  2556.      @cinemasks = [ create_cinema(640,48,0,-48), create_cinema(640,72,0,480),
  2557.                     create_cinema(640,480,0,0,199,0)]
  2558.      drg128_main
  2559.      @multi_message_window.each {|mw| mw.dispose}    
  2560.    end
  2561.    #--------------------------------------------------------------------------
  2562.    # * Main Processing
  2563.    #--------------------------------------------------------------------------
  2564.    def main()  drg152_main end
  2565.    #--------------------------------------------------------------------------
  2566.    # * New Message Window Addition
  2567.    #--------------------------------------------------------------------------
  2568.    def new_message_window(index)
  2569.      if @multi_message_window[index] != nil
  2570.        # clear message windows at and after this index
  2571.        (@multi_message_window.size - 1).downto(index) { |i|
  2572.          next if @multi_message_window[i] == nil
  2573.          @multi_message_window[i].dispose
  2574.          @multi_message_window[i] = nil }
  2575.        @multi_message_window.compact!
  2576.      end
  2577.      @multi_message_window.push(Window_Message.new(index))
  2578.    end
  2579.    #--------------------------------------------------------------------------
  2580.    # * Cinemaskie
  2581.    #--------------------------------------------------------------------------
  2582.    def create_cinema(a=640,b=48,x=0,y=0,z=nil,o= nil)
  2583.      mask,@cinema_fadecount = Sprite.new, 24
  2584.      mask.bitmap = Bitmap.new(a,b)
  2585.      mask.bitmap.fill_rect(0,0,a,b, Color.new(0,0,0,255))
  2586.      mask.x, mask.y, mask.opacity = [x,y,o||255]
  2587.      mask.z = z || $game_system.message.cinema_z
  2588.      return mask
  2589.    end
  2590.    #--------------------------------------------------------------------------
  2591.    # Update Cinema
  2592.    #--------------------------------------------------------------------------
  2593.    def update_cinema
  2594.      cii = $game_system.message.cinema
  2595.      if (cii && @cinema_fadecount >  0) || (!cii && @cinema_fadecount < 24)
  2596.        @cinema_fadecount = (@cinema_fadecount || 24) + (cii ? -1 : 1)
  2597.        @cinemasks[0].y =   0 -  6 *       @cinema_fadecount  / 3
  2598.        @cinemasks[1].y = 480 -  9 * (24 - @cinema_fadecount) / 3
  2599.        @cinemasks[2].opacity =  4 * (24 - @cinema_fadecount)
  2600.      end
  2601.    end
  2602.    #--------------------------------------------------------------------------
  2603.    # * Frame Update
  2604.    #--------------------------------------------------------------------------
  2605.    def update_scene_cinema
  2606.      @message_window = Nothing.new if !@message_window.is_a?(Nothing)
  2607.      @multi_message_window.each {|mw| mw.update}    
  2608.      update_cinema
  2609.    end
  2610.  end
  2611.  #--------------------------------------------------------------------------
  2612.  # Can Move?
  2613.  #--------------------------------------------------------------------------
  2614.  def blizzabs_can_move?(type=0)
  2615.    player = $BlizzABS.actors[0]
  2616.    message_showing = $game_temp.message_window_showing
  2617.    interpreter = $game_system.map_interpreter.running?
  2618.    return type == 0 ? (((player.ai.act.defend? && player.attacked == 0) ||
  2619.          $game_system.turn_button && Input.press?(Input::Turn)) &&
  2620.          !player.moving? && !player.move_route_forcing &&
  2621.          (!interpreter || message_showing) &&
  2622.          (!message_showing || $game_system.message.move_during) &&
  2623.          $game_temp.choice_max <= 0 && $game_temp.num_input_digits_max <= 0) :
  2624.          (player.move_route_forcing ||  (interpreter && !message_showing) ||
  2625.          (message_showing && !$game_system.message.move_during) ||
  2626.          ($game_temp.choice_max > 0 || $game_temp.num_input_digits_max > 0))
  2627.  end
  2628.  #--------------------------------------------------------------------------
  2629.  # * Frame Update
  2630.  #--------------------------------------------------------------------------
  2631.  def update
  2632.    case #{i}
  2633.    when 0 then update_scene_cinema  
  2634.    when 1 then update_scene_cinema
  2635.    when 2 then update_mmw_moving
  2636.    when 3 then update_shaded_fix end
  2637.    drg128_upd
  2638.  end
  2639.  #--------------------------------------------------------------------------
  2640.  # * update_mmw_moving
  2641.  #--------------------------------------------------------------------------
  2642.  def update_mmw_moving
  2643.    message_showing = $game_temp.message_window_showing
  2644.    unless moving? || @move_route_forcing ||
  2645.      ($game_system.map_interpreter.running? && !message_showing) ||
  2646.      (message_showing && !$game_system.message.move_during) ||
  2647.      ($game_temp.choice_max > 0 || $game_temp.num_input_digits_max > 0)
  2648.      input = Input.dir4
  2649.      if input
  2650.        case input
  2651.        when 2 then move_down
  2652.        when 4 then move_left
  2653.        when 6 then move_right
  2654.        when 8 then move_up
  2655.        end
  2656.      end
  2657.    end
  2658.  end
  2659.  #--------------------------------------------------------------------------
  2660.  # * Frame Update
  2661.  #--------------------------------------------------------------------------
  2662.  def update_shaded_fix
  2663.    @message = Game_Message.new if !@message
  2664.    if @SHADED_TEXT != nil && Blizzard_Shaded_Text_Fix == true
  2665.      if $game_temp.message_window_showing
  2666.        @SHADED_TEXT = false
  2667.      else
  2668.        @SHADED_TEXT = true
  2669.      end
  2670.    end
  2671.  end
  2672.  #--------------------------------------------------------------------------
  2673.  # * Touch Event Starting Determinant
  2674.  #--------------------------------------------------------------------------
  2675.  # This is a fix if Blizzard's Optimized default scripts are being used
  2676.  def check_event_trigger_touch(x, y)
  2677.    result = false                         # <--------- MOVED from....
  2678.    # If event is running
  2679.    if $game_system.map_interpreter.running?
  2680.      return result
  2681.    end
  2682.    #result = false                        # <--------- ...HERE
  2683.    # All event loops
  2684.    $game_map.events.each_value {|event|
  2685.      # If event coordinates and triggers are consistent
  2686.      if event.x == x && event.y == y && [1,2].include?(event.trigger)
  2687.        # If starting determinant is front event (other than jumping)
  2688.        if !event.jumping? && !event.over_trigger?
  2689.          event.start
  2690.          result = true
  2691.        end
  2692.      end }
  2693.    return result
  2694.  end
  2695. end#"}
  2696. #==============================================================================
  2697. # ** Interpreter
  2698. #------------------------------------------------------------------------------
  2699. #  This interpreter runs event commands. This class is used within the
  2700. #  Game_System class and the Game_Event class.
  2701. #==============================================================================
  2702. class Interpreter
  2703.   #--------------------------------------------------------------------------
  2704.   # * Public Instance Variables
  2705.   #--------------------------------------------------------------------------
  2706.   #--------------------------------------------------------------------------
  2707.   # * Alias Listing
  2708.   #--------------------------------------------------------------------------
  2709.   alias drg128_setup setup unless method_defined?(:drg128_setup)
  2710.   alias drg128_upd update unless method_defined?(:drg128_upd)
  2711.   #--------------------------------------------------------------------------
  2712.   # * Setup
  2713.   #--------------------------------------------------------------------------
  2714.   def setup(*args)
  2715.     drg128_setup(*args)
  2716.     # index of window for the message
  2717.     @msgindex = 0
  2718.     $game_temp.message_text, $game_temp.message_proc = [],[]
  2719.     # whether multiple messages are displaying
  2720.     @multi_message = false
  2721.   end
  2722.   #--------------------------------------------------------------------------
  2723.   # * Update
  2724.   #--------------------------------------------------------------------------
  2725.   def update(*args)
  2726.     @message_waiting = $game_temp.message_window_showing
  2727.     drg128_upd(*args)
  2728.   end
  2729.   #--------------------------------------------------------------------------
  2730.   # * Message
  2731.   #--------------------------------------------------------------------------
  2732.   def message() message = $game_system.message if $game_system != nil  end
  2733.   def message_eval(v) eval(v)  end
  2734.   #--------------------------------------------------------------------------
  2735.   # * Setup Choices
  2736.   #--------------------------------------------------------------------------
  2737.   def setup_choices(parameters)
  2738.     # Set choice item count to choice_max
  2739.     $game_temp.choice_max = parameters[0].size
  2740.     # Set choice to message_text
  2741.     parameters[0].each {|text| $game_temp.message_text[@msgindex] += text + "\n"}
  2742.     # Set cancel processing
  2743.     $game_temp.choice_cancel_type = parameters[1]
  2744.     # Set callback
  2745.     current_indent = @list[@index].indent
  2746.     $game_temp.choice_proc = Proc.new { |n| @branch[current_indent] = n }
  2747.   end
  2748.   #--------------------------------------------------------------------------
  2749.   # * Show Text
  2750.   #--------------------------------------------------------------------------
  2751.   def command_101
  2752.     # If other text has been set to message_text
  2753.     if $game_temp.message_text[@msgindex] != nil
  2754.       if @multi_message
  2755.         @msgindex += 1
  2756.         $scene.new_message_window(@msgindex)
  2757.       else
  2758.         # End
  2759.         return false
  2760.       end
  2761.     end
  2762.     @msgindex = 0 if !@multi_message
  2763.     @multi_message = false
  2764.     # Set message end waiting flag and callback
  2765.     @message_waiting = true
  2766.     # just adding indexes
  2767.     $game_temp.message_proc[@msgindex] = Proc.new { @message_waiting = false }
  2768.     # Set message text on first line
  2769.     $game_temp.message_text[@msgindex] = @list[@index].parameters[0] + "\n"
  2770.     $scene.multi_message_window[@msgindex].event_id = @event_id
  2771.     line_count = 1
  2772.     # Loop
  2773.     loop do
  2774.       # If next event command text is on the second line or after
  2775.       if @list[@index+1].code == 401 || @list[@index+1].code == 101 &&
  2776.           @list[@index+1].parameters[0][0..1] == '\\#'
  2777.         # just adding index
  2778.         $game_temp.message_text[@msgindex] += @list[@index+1].parameters[0]+"\n"
  2779.         line_count += 1
  2780.       # If event command is not on the second line or after
  2781.       else
  2782.         # If next event command is show choices
  2783.         if @list[@index+1].code == 102
  2784.           # If choices fit on screen
  2785.           if @list[@index+1].parameters[0].size <= 4 - line_count
  2786.             # Prevent the closure of a single window with multiple windows
  2787.             $game_temp.input_in_window = true            
  2788.             # Flag this window as having choices displayed for multi
  2789.             $scene.multi_message_window[@msgindex].choice_window = @msgindex
  2790.             # Advance index
  2791.             @index += 1
  2792.             # Choices setup
  2793.             $game_temp.choice_start = line_count
  2794.             setup_choices(@list[@index].parameters)
  2795.           end
  2796.         # If next event command is input number
  2797.         elsif @list[@index+1].code == 103
  2798.           # If number input window fits on screen
  2799.           if line_count < 4
  2800.             # Prevent the closure of a single window with multiple windows
  2801.             $game_temp.input_in_window = true
  2802.             # Flag this window as having choices displayed
  2803.             $scene.multi_message_window[@msgindex].choice_window = @msgindex
  2804.             # Advance index
  2805.             @index += 1
  2806.             # Number input setup
  2807.             $game_temp.num_input_start = line_count
  2808.             $game_temp.num_input_variable_id = @list[@index].parameters[0]
  2809.             $game_temp.num_input_digits_max = @list[@index].parameters[1]
  2810.             $game_temp.num_input_variable_id_backup =
  2811.               @list[@index].parameters[0]
  2812.           end
  2813.         # start multimessage if next line is "Show Text" starting with "\\+"
  2814.         elsif @list[@index+1].code == 101
  2815.           if @list[@index+1].parameters[0][0..1]=='\\+'
  2816.             @multi_message,@message_waiting = true, false
  2817.           end
  2818.         end
  2819.         # Continue
  2820.         return true
  2821.       end
  2822.       # Advance index
  2823.       @index += 1
  2824.     end
  2825.   end
  2826.   #--------------------------------------------------------------------------
  2827.   # * Show Choices
  2828.   #--------------------------------------------------------------------------
  2829.   def command_102
  2830.     # Prevent the closure of a single window with multiple windows
  2831.     $game_temp.input_in_window = true
  2832.     # Flag this window as having choices displayed for multi
  2833.     $scene.multi_message_window[@msgindex].choice_window = @msgindex  
  2834.     # If text has been set to message_text
  2835.     # just adding index
  2836.     return false if $game_temp.message_text[@msgindex] != nil
  2837.     # Set message end waiting flag and callback
  2838.     @message_waiting = true
  2839.     # adding more indexes
  2840.     $game_temp.message_proc[@msgindex] = Proc.new { @message_waiting = false }
  2841.     # Choices setup
  2842.     $game_temp.message_text[@msgindex] = ''
  2843.     $game_temp.choice_start = 0
  2844.     setup_choices(@parameters)
  2845.     # Continue
  2846.     return true
  2847.   end
  2848.   #--------------------------------------------------------------------------
  2849.   # * Input Number
  2850.   #--------------------------------------------------------------------------
  2851.   def command_103
  2852.     # Prevent the closure of a single window with multiple windows
  2853.     $game_temp.input_in_window = true
  2854.     # Flag this window as having choices displayed for multi
  2855.     $scene.multi_message_window[@msgindex].choice_window = @msgindex  
  2856.     # If text has been set to message_text
  2857.     # just adding index
  2858.     return false if $game_temp.message_text[@msgindex] != nil
  2859.     # Set message end waiting flag and callback
  2860.     @message_waiting = true
  2861.     # adding more indexes
  2862.     $game_temp.message_proc[@msgindex] = Proc.new { @message_waiting = false }
  2863.     # Number input setup
  2864.     $game_temp.message_text[@msgindex] = ''
  2865.     $game_temp.num_input_start = 0
  2866.     $game_temp.num_input_variable_id = @parameters[0]
  2867.     $game_temp.num_input_digits_max = @parameters[1]
  2868.     $game_temp.num_input_variable_id_backup = @list[@index].parameters[0]
  2869.     # Continue
  2870.     return true
  2871.   end
  2872.   #--------------------------------------------------------------------------
  2873.   # * Script
  2874.   #--------------------------------------------------------------------------
  2875.   # Fix for RMXP bug: call script boxes that return false hang the game
  2876.   # See, e.g., http://rmxp.org/forums/showthread.php?p=106639  
  2877.   #--------------------------------------------------------------------------
  2878.   def command_355
  2879.     # Set first line to script
  2880.     script = @list[@index].parameters[0] + "\n"
  2881.     # Loop
  2882.     loop do
  2883.       # If next event command is second line of script or after
  2884.       if @list[@index+1].code == 655
  2885.         # Add second line or after to script
  2886.         script += @list[@index+1].parameters[0] + "\n"
  2887.       # If event command is not second line or after
  2888.       else
  2889.         # Abort loop
  2890.         break
  2891.       end
  2892.       # Advance index
  2893.       @index += 1
  2894.     end
  2895.     # Evaluation
  2896.     result = eval(script)
  2897.     # If return value is false
  2898.     if false #result == false
  2899.       # End
  2900.       return false
  2901.     end
  2902.     # Continue
  2903.     return true
  2904.   end
  2905. end
  2906. #==============================================================================
  2907. # ** Game_Map
  2908. #------------------------------------------------------------------------------
  2909. #  This class handles the map. It includes scrolling and passable determining
  2910. #  functions. Refer to "$game_map" for the instance of this class.
  2911. #==============================================================================
  2912. class Game_Map
  2913.   #--------------------------------------------------------------------------
  2914.   # * Define Method
  2915.   #--------------------------------------------------------------------------
  2916.   define_method(:last_disp_xy) { [@display_x, @display_y] }
  2917.   define_method(:name) { load_data('Data/MapInfos.rxdata')[@map_id].name  }
  2918. end
  2919. #==============================================================================
  2920. # ** Bitmap
  2921. #------------------------------------------------------------------------------
  2922. #  This class is for all in-game bitmap.
  2923. #==============================================================================
  2924. class Bitmap
  2925.   #--------------------------------------------------------------------------
  2926.   # * Public Instance Variables
  2927.   #--------------------------------------------------------------------------
  2928.   attr_accessor :orientation
  2929.   #--------------------------------------------------------------------------
  2930.   # * Rotation Calculation
  2931.   #--------------------------------------------------------------------------
  2932.   def rotation(t)
  2933.     return if not [0, 90, 180, 270].include?(t) # invalid orientation
  2934.     rotate(t - @orientation + (t-@orientation < 0 ? 360 : 0)) if @rotation != t
  2935.   end
  2936.   #--------------------------------------------------------------------------
  2937.   # * Rotate Square (Clockwise)
  2938.   #--------------------------------------------------------------------------
  2939.   def rotate(degrees = 90)
  2940.     # method originally by SephirothSpawn
  2941.     # would just use Sprite.angle but its rotation is buggy
  2942.     return if not [90, 180, 270].include?(degrees)
  2943.     copy = self.clone
  2944.     if degrees == 90
  2945.       # Passes Through all Pixels on Dummy Bitmap
  2946.       (0...self.height).each {|i| (0...self.width).each {|j|
  2947.           self.set_pixel(width - i - 1, j, copy.get_pixel(j, i))}}
  2948.     elsif degrees == 180
  2949.       (0...self.height).each {|i| (0...self.width).each {|j|
  2950.           self.set_pixel(width - j - 1, height - i - 1, copy.get_pixel(j, i))} }      
  2951.     elsif degrees == 270
  2952.       (0...self.height).each {|i| (0...self.width).each {|j|
  2953.           self.set_pixel(i, height - j - 1, copy.get_pixel(j, i)) } }
  2954.     end
  2955.     @orientation = (@orientation + degrees) % 360
  2956.   end
  2957.   #--------------------------------------------------------------------------
  2958.   # ? erase
  2959.   #--------------------------------------------------------------------------
  2960.   def erase(*args)
  2961.     case args.size
  2962.     when 1 then fill_rect( args[0], Color.new(0, 0, 0, 0))
  2963.     when 4 then fill_rect(Rect.new(*args), Color.new(0, 0, 0, 0))
  2964.     end
  2965.   end
  2966. end
  2967. #==============================================================================
  2968. # ** Window_Base
  2969. #------------------------------------------------------------------------------
  2970. #  This class is for all in-game windows.
  2971. #==============================================================================
  2972. class Window_Base
  2973.   #--------------------------------------------------------------------------
  2974.   # * Check Color
  2975.   #     color : color to check
  2976.   #--------------------------------------------------------------------------
  2977.   def check_color(color)
  2978.     if color.type == Color
  2979.       # already a Color object
  2980.       return color
  2981.     elsif color[0].chr == "#"
  2982.       # specified as hexadecimal
  2983.       r = color[1..2].hex
  2984.       g = color[3..4].hex
  2985.       b = color[5..6].hex
  2986.       return Color.new(r,g,b)
  2987.     else
  2988.       # specified as integer (0-7)
  2989.       color = color.to_i if color
  2990.       if color && color >= 0 && color <= 7
  2991.         return text_color(color)
  2992.       end
  2993.     end
  2994.     return normal_color
  2995.   end
  2996. end
  2997. #==============================================================================
  2998. # ** Window_InputNumber
  2999. #------------------------------------------------------------------------------
  3000. #  This window is for inputting numbers, and is used within the
  3001. #  message window.
  3002. #==============================================================================
  3003. class Window_InputNumber < Window_Base
  3004.   #--------------------------------------------------------------------------
  3005.   # * Set Font
  3006.   #--------------------------------------------------------------------------
  3007.   def set_font(fname, fsize, fcolor)
  3008.     return if fname == nil && fsize == nil && fcolor == nil
  3009.     # Calculate cursor width from number width
  3010.     dummy_bitmap = Bitmap.new(32, 32)
  3011.     dummy_bitmap.font.name = fname
  3012.     dummy_bitmap.font.size = fsize
  3013.     @cursor_width = dummy_bitmap.text_size('0').width + 8
  3014.     dummy_bitmap.dispose
  3015.     self.width = @cursor_width * @digits_max + 32
  3016.     self.contents = Bitmap.new(width - 32, height - 32)
  3017.     self.contents.font.name = fname
  3018.     self.contents.font.size = fsize
  3019.     self.contents.font.color = check_color(fcolor)
  3020.     refresh
  3021.     update_cursor_rect
  3022.   end
  3023.   #--------------------------------------------------------------------------
  3024.   # * Refresh
  3025.   #--------------------------------------------------------------------------
  3026.   def refresh
  3027.     self.contents.clear
  3028.     s = sprintf("%0*d", @digits_max, @number)
  3029.     (0...@digits_max).each {|i|
  3030.       self.contents.draw_text(i * @cursor_width + 4, 0, 32, 32, s[i,1]) }
  3031.   end
  3032. end
  3033.  
  3034. #==============================================================================
  3035. # ** AnimationSprite
  3036. #------------------------------------------------------------------------------
  3037. # Created by ThallionDarkshine
  3038. #  
  3039. #==============================================================================
  3040. class AnimationSprite < Sprite
  3041.   #--------------------------------------------------------------------------
  3042.   # * Object Initialization
  3043.   #--------------------------------------------------------------------------
  3044.   def initialize(type, x, y, z, rects, src_bitmap)
  3045.     super()
  3046.     @old_x, @old_y = x, y
  3047.     @type = type
  3048.     rects.compact!
  3049.     rects.delete_if { |rect| rect.width == 0 or rect.height == 0 }
  3050.     ry = rects.min { |i, e| i.y <=> e.y }.y
  3051.     rx = rects.min { |i, e| i.x <=> e.x }.x
  3052.     h = rects.max { |i, e| i.y + i.height <=> e.y + e.height }
  3053.     h = h.y + h.height - ry
  3054.     w = rects.max { |i, e| i.x + i.width <=> e.x + e.width }
  3055.     w = w.x + w.width - rx
  3056.     self.x, self.y, self.z = x + rx, y + ry, z
  3057.     self.ox, self.oy = w / 2, h / 2
  3058.     self.x += ox
  3059.     self.y += oy
  3060.     self.bitmap = Bitmap.new(w, h)
  3061.     rects.each { |rect|
  3062.       bitmap.blt(rect.x - rx, rect.y - ry, src_bitmap, rect)
  3063.       src_bitmap.fill_rect(rect, Color.new(0, 0, 0, 0)) }
  3064.     @frames = 0
  3065.     @fplus = 1
  3066.     case @type
  3067.     when 4:
  3068.       @shake = [0, 0]
  3069.       @shaked = 1
  3070.     when 6:
  3071.       @frames = -40
  3072.     when 7:
  3073.       @frames = 2
  3074.     end
  3075.   end
  3076.   #--------------------------------------------------------------------------
  3077.   # * Frame Update
  3078.   #--------------------------------------------------------------------------
  3079.   def update(x, y)
  3080.     return if self.disposed?
  3081.     if x != @old_x or y != @old_y
  3082.       repos(x, y)
  3083.     end
  3084.     @frames += @fplus
  3085.     case @type
  3086.     when 1:
  3087.       z = 1.0 + @frames * 0.1 / 20
  3088.       @fplus = -1 if @frames == 20
  3089.       @fplus = 1 if @frames == 0
  3090.       self.zoom_x = z
  3091.       self.zoom_y = z
  3092.     when 2:
  3093.       a = @frames * 5.0 / 12
  3094.       @fplus = -1 if @frames == 12
  3095.       @fplus = 1 if @frames == -12
  3096.       self.angle = a
  3097.     when 3:
  3098.       z = 1.0 - @frames * 0.1 / 20
  3099.       @fplus = -1 if @frames == 20
  3100.       @fplus = 1 if @frames == 0
  3101.       self.zoom_x = z
  3102.       self.zoom_y = z
  3103.     when 4:
  3104.       shake_power = 1
  3105.       shake_speed = 10
  3106.       delta = (shake_power * shake_speed * @fplus) / 15.0 + rand(3) - 1
  3107.       @shake[0] += delta
  3108.       if @shake[0] > shake_power
  3109.         @fplus = -1
  3110.       end
  3111.       if @shake[0] < - shake_power
  3112.         @fplus = 1
  3113.       end
  3114.       delta = (shake_power * shake_speed * @shaked) / 15.0 + rand(3) - 1
  3115.       @shake[1] += delta
  3116.       if @shake[1] > shake_power
  3117.         @shaked = -1
  3118.       end
  3119.       if @shake[1] < - shake_power
  3120.         @shaked = 1
  3121.       end
  3122.       self.ox = self.bitmap.width / 2 + @shake[0]
  3123.       self.oy = self.bitmap.height / 2 + @shake[1]
  3124.     when 5:
  3125.       amnt = 5
  3126.       amnt *= Math.sin(Math::PI * @frames / 30.0)
  3127.       self.oy = self.bitmap.height / 2 + amnt
  3128.     when 6:
  3129.       if @frames < 0
  3130.         a = 255 + @frames * 255 / 40
  3131.         self.color.set(255, 0, 0, a)
  3132.         return
  3133.       end
  3134.       r = g = b = 0
  3135.       tmp = (@frames % 360) * 255 / 360
  3136.       while tmp < 0
  3137.         tmp += 255
  3138.       end
  3139.       if tmp < 85
  3140.         g = tmp * 3
  3141.         r = (85 - tmp) * 3
  3142.       elsif tmp < 170
  3143.         b = (tmp - 85) * 3
  3144.         g = (170 - tmp) * 3
  3145.       else
  3146.         r = (tmp - 170) * 3
  3147.         b = (255 - tmp) * 3
  3148.       end
  3149.       self.color.set(r, g, b)
  3150.     when 7:
  3151.       amnt = 10
  3152.       amnt *= Math.sin(Math::PI * @frames / 30.0).abs
  3153.       self.oy = self.bitmap.height / 2 + amnt - 5
  3154.     when 8:
  3155.       self.opacity = 255 - 170 * @frames / 20
  3156.       @fplus = -1 if @frames == 20
  3157.       @fplus = 1 if @frames == 0
  3158.     end
  3159.   end
  3160.   #--------------------------------------------------------------------------
  3161.   # * Repos
  3162.   #--------------------------------------------------------------------------
  3163.   def repos(x, y)
  3164.     self.x += x - @old_x
  3165.     self.y += y - @old_y
  3166.     @old_x, @old_y = x, y
  3167.   end
  3168. end
  3169.  
  3170. #==============================================================================
  3171. # ** AnimationLetters
  3172. #------------------------------------------------------------------------------
  3173. #  Created by ThallionDarkshine
  3174. #  
  3175. #==============================================================================
  3176. class AnimationLetters
  3177.   #--------------------------------------------------------------------------
  3178.   # * Define Method
  3179.   #--------------------------------------------------------------------------
  3180.   define_method(:dispose) {@sprites.each {|i|[i.bitmap,i].each{|j|j.dispose}}}
  3181.   #--------------------------------------------------------------------------
  3182.   # * Object Initialization
  3183.   #--------------------------------------------------------------------------
  3184.   def initialize(type, x, y, z, rects, src_bitmap)
  3185.     @old_x, @old_y = x, y
  3186.     @type = type
  3187.     @sprites = []
  3188.     @data = []
  3189.     tmp_data = get_tmp_data(type, rects.length)
  3190.     rects.each { |rect|
  3191.       sprite = Sprite.new
  3192.       sprite.x, sprite.y, sprite.z = x + rect.x, y + rect.y, z
  3193.       sprite.bitmap = Bitmap.new(rect.width, rect.height)
  3194.       sprite.bitmap.blt(0, 0, src_bitmap, rect)
  3195.       sprite.ox, sprite.oy = rect.width / 2, rect.height / 2
  3196.       sprite.x += sprite.ox
  3197.       sprite.y += sprite.oy
  3198.       src_bitmap.fill_rect(rect, Color.new(0, 0, 0, 0))
  3199.       @sprites.push(sprite)
  3200.       @data.push(get_data(type, tmp_data)) }
  3201.     case @type
  3202.     when 4:
  3203.       @frames = -40
  3204.     else
  3205.       @frames = 0
  3206.     end
  3207.     @fplus = 1
  3208.   end
  3209.   #--------------------------------------------------------------------------
  3210.   # * Get Temporary Data
  3211.   #--------------------------------------------------------------------------
  3212.   def get_tmp_data(type, length)
  3213.     case type
  3214.     when 1, 5, 7:
  3215.       data = Array.new(length) { |i| i }
  3216.       @duration = length * 31
  3217.       @no_end = true
  3218.     when 2, 6, 8:
  3219.       len = (length / 2.0).floor
  3220.       data = Array.new(len) { |i| i }
  3221.       data = data.concat(data.clone)
  3222.       if len % 2 == 1
  3223.         data.push(rand(len))
  3224.       end
  3225.       @duration = len * 31
  3226.       @no_end = true
  3227.     when 9, 10:
  3228.       data = Array.new(length) { |i| i }
  3229.     when 11, 12:
  3230.       tmp = Array.new(length) { |i| i }
  3231.       data = []
  3232.       length.times {
  3233.         ind = rand(tmp.length)
  3234.         data.push(tmp[ind])
  3235.         tmp.delete_at(ind)  }
  3236.     else
  3237.       data = []
  3238.     end
  3239.     data
  3240.   end
  3241.   #--------------------------------------------------------------------------
  3242.   # * Get Data
  3243.   #--------------------------------------------------------------------------
  3244.   def get_data(type, tmp_data)
  3245.     data = {}
  3246.     case type
  3247.     when 1, 2, 5, 6, 7, 8:
  3248.       tmp = rand(tmp_data.length)
  3249.       data[:start] = tmp_data[tmp] * 31 + rand(11) - 5
  3250.       data[:middle] = data[:start] + 15
  3251.       while data[:start] < 0
  3252.         data[:start] += @duration
  3253.       end
  3254.       data[:end] = (data[:middle] + 15) % @duration
  3255.       tmp_data.delete_at(tmp)
  3256.     when 4:
  3257.       data[:hue] = rand(255)
  3258.       data[:mod] = rand(5) - 2
  3259.       while data[:mod] == 0
  3260.         data[:mod] = rand(5) - 2
  3261.       end
  3262.     when 9, 10, 11, 12:
  3263.       data[:end] = false
  3264.       len = tmp_data.length
  3265.       ind = tmp_data.shift
  3266.       len += ind
  3267.       data[:offset] = -ind * Math::PI / len
  3268.     end
  3269.     data
  3270.   end
  3271.   #--------------------------------------------------------------------------
  3272.   # * Update Frame
  3273.   #--------------------------------------------------------------------------
  3274.   def update(x, y)
  3275.     return if @sprites.any? { |i| i.disposed? }
  3276.     repos(x, y) if x != @old_x or y != @old_y
  3277.     @frames += @fplus
  3278.     case @type
  3279.     when 1, 2:
  3280.       @frames %= @duration
  3281.       @sprites.each_with_index { |sprite, i|
  3282.         data = @data[i]
  3283.         cur_frames = @frames
  3284.         start = data[:start]
  3285.         middle = data[:middle]
  3286.         endf = data[:end]
  3287.         while endf < start
  3288.           endf += @duration
  3289.         end
  3290.         while middle < start
  3291.           middle += @duration
  3292.         end
  3293.         while cur_frames < start
  3294.           cur_frames += @duration
  3295.         end
  3296.         while cur_frames > endf
  3297.           cur_frames -= @duration
  3298.         end
  3299.         while (cur_frames - start) > @duration
  3300.           cur_frames -= @duration
  3301.         end
  3302.         while (start - cur_frames) > @duration
  3303.           cur_frames += @duration
  3304.         end
  3305.         if cur_frames.between?(start, middle)
  3306.           @no_end = false
  3307.           z = 1.0 + (cur_frames - start) * 0.5 / (middle - start)
  3308.           sprite.zoom_x = sprite.zoom_y = z
  3309.         elsif cur_frames.between?(middle, endf) and !@no_end
  3310.           z = 1.0 + (endf - cur_frames) * 0.5 / (endf - middle)
  3311.           sprite.zoom_x = sprite.zoom_y = z
  3312.         else
  3313.           sprite.zoom_x = sprite.zoom_y = 1.0
  3314.         end
  3315.         mod = rand(5) - 2
  3316.         @data[i][:start] += mod
  3317.         @data[i][:middle] += mod
  3318.         @data[i][:end] += mod }
  3319.     when 3:
  3320.       a = @frames * 10.0 / 12
  3321.       @fplus = -1 if @frames == 30
  3322.       @fplus = 1 if @frames == -30
  3323.       @sprites.each { |i| i.angle = a }
  3324.     when 4:
  3325.       if @frames < 0
  3326.         a = 255 + @frames * 255 / 40
  3327.         @sprites.each_with_index { |sprite, i|
  3328.           @data[i][:hue] += @data[i][:mod]
  3329.           color = get_color(@data[i][:hue])
  3330.           color.alpha = a
  3331.           sprite.color = color   }
  3332.         return
  3333.       end
  3334.       @sprites.each_with_index { |sprite, i|
  3335.         @data[i][:hue] += @data[i][:mod]
  3336.         color = get_color(@data[i][:hue])
  3337.         sprite.color = color  }
  3338.     when 5, 6:
  3339.       @frames %= @duration
  3340.       @sprites.each_with_index { |sprite, i|
  3341.         data = @data[i]
  3342.         cur_frames = @frames
  3343.         start = data[:start]
  3344.         middle = data[:middle]
  3345.         endf = data[:end]
  3346.         while endf < start
  3347.           endf += @duration
  3348.         end
  3349.         while middle < start
  3350.           middle += @duration
  3351.         end
  3352.         while cur_frames < start
  3353.           cur_frames += @duration
  3354.         end
  3355.         while cur_frames > endf
  3356.           cur_frames -= @duration
  3357.         end
  3358.         while (cur_frames - start) > @duration
  3359.           cur_frames -= @duration
  3360.         end
  3361.         while (start - cur_frames) > @duration
  3362.           cur_frames += @duration
  3363.         end
  3364.         if cur_frames.between?(start, middle)
  3365.           @no_end = false
  3366.           sprite.opacity = 255 - (cur_frames - start) * 170 / (middle - start)
  3367.         elsif cur_frames.between?(middle, endf) and !@no_end
  3368.           sprite.opacity = 255 - (endf - cur_frames) * 170 / (endf - middle)
  3369.         else
  3370.           sprite.opacity = 255
  3371.         end
  3372.         mod = rand(5) - 2
  3373.         @data[i][:start] += mod
  3374.         @data[i][:middle] += mod
  3375.         @data[i][:end] += mod  }
  3376.     when 7, 8:
  3377.       @frames %= @duration
  3378.       @sprites.each_with_index { |sprite, i|
  3379.         data = @data[i]
  3380.         cur_frames = @frames
  3381.         start = data[:start]
  3382.         middle = data[:middle]
  3383.         endf = data[:end]
  3384.         while endf < start
  3385.           endf += @duration
  3386.         end
  3387.         while middle < start
  3388.           middle += @duration
  3389.         end
  3390.         while cur_frames < start
  3391.           cur_frames += @duration
  3392.         end
  3393.         while cur_frames > endf
  3394.           cur_frames -= @duration
  3395.         end
  3396.         while (cur_frames - start) > @duration
  3397.           cur_frames -= @duration
  3398.         end
  3399.         while (start - cur_frames) > @duration
  3400.           cur_frames += @duration
  3401.         end
  3402.         if cur_frames.between?(start, middle)
  3403.           @no_end = false
  3404.           z = 1.0 - (cur_frames - start) * 0.5 / (middle - start)
  3405.           sprite.zoom_x = sprite.zoom_y = z
  3406.         elsif cur_frames.between?(middle, endf) and !@no_end
  3407.           z = 1.0 - (endf - cur_frames) * 0.5 / (endf - middle)
  3408.           sprite.zoom_x = sprite.zoom_y = z
  3409.         else
  3410.           sprite.zoom_x = sprite.zoom_y = 1.0
  3411.         end
  3412.         mod = rand(5) - 2
  3413.         @data[i][:start] += mod
  3414.         @data[i][:middle] += mod
  3415.         @data[i][:end] += mod   }
  3416.     when 9, 11:
  3417.       @sprites.each_with_index { |sprite, i|
  3418.         data = @data[i]
  3419.         mod = 10 * Math.sin(Math::PI * @frames / 45.0 + data[:offset]).abs - 5
  3420.         mod2 = 10 * Math.sin(Math::PI * (@frames + 1) / 45.0 + data[:offset]).abs - 5
  3421.         if mod > 0 and mod <= 10 * Math.sin(Math::PI * 6 / 30.0).abs - 5 and mod2 > 0
  3422.           @data[i][:end] = true
  3423.         else
  3424.           next unless @data[i][:end]
  3425.         end
  3426.         sprite.oy = sprite.bitmap.height / 2 + mod  }
  3427.     when 10, 12:
  3428.       @sprites.each_with_index { |sprite, i|
  3429.         data = @data[i]
  3430.         mod = 5 * Math.sin(Math::PI * @frames / 30.0 + data[:offset])
  3431.         mod2 = 5 * Math.sin(Math::PI * (@frames + 1) / 30.0 + data[:offset])
  3432.         #p 10 * Math.sin(Math::PI * 2 * 3 / 30.0) - 5
  3433.         #p mod
  3434.         if mod > 0 and mod <= 5 * Math.sin(Math::PI * 6 / 30.0) and mod2 > 0
  3435.           @data[i][:end] = true
  3436.         else
  3437.           next unless @data[i][:end]
  3438.         end
  3439.         sprite.oy = sprite.bitmap.height / 2 + mod  }
  3440.     end
  3441.   end
  3442.   #--------------------------------------------------------------------------
  3443.   # * Get Color
  3444.   #--------------------------------------------------------------------------
  3445.   def get_color(hue)
  3446.     r = g = b = 0
  3447.     tmp = hue % 255
  3448.     while tmp < 0
  3449.       tmp += 255
  3450.     end
  3451.     if tmp < 85
  3452.       g = tmp * 3
  3453.       r = (85 - tmp) * 3
  3454.     elsif tmp < 170
  3455.       b = (tmp - 85) * 3
  3456.       g = (170 - tmp) * 3
  3457.     else
  3458.       r = (tmp - 170) * 3
  3459.       b = (255 - tmp) * 3
  3460.     end
  3461.     return Color.new(r, g, b)
  3462.   end
  3463.   #--------------------------------------------------------------------------
  3464.   # * Opacity
  3465.   #--------------------------------------------------------------------------
  3466.   def opacity=(v) @sprites.each { |i| i.opacity = v }  end  
  3467.   #--------------------------------------------------------------------------
  3468.   # * Repos
  3469.   #--------------------------------------------------------------------------
  3470.   def repos(x, y)
  3471.     @sprites.each { |i| i.x += x - @old_x;i.y += y - @old_y }
  3472.     @old_x, @old_y = x, y
  3473.   end
  3474. end
  3475.  
  3476. $multiple_message_windows = {}
  3477. $multiple_message_windows['ver'] = 1.6
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement