Multiple Message Windows Ex
Authors: Wachunga, ForeverZer0, LiTTleDRAgo
Version: 1.6c
Type: Custom Message System
Key Term: Custom Message System
IntroductionThis is edited version of MMW (http://forum.chaos-project.com/index.php/topic,5907.0.html) so can work with Blizz ABS
In this version, there is no need for change Scene_Map and Scene Battle
I already edited them magically in the script, plug and play
changed the script name since this script is not the original MMW anymore (with countless edits and added features)
Features
- Multiple Message Windows
- Speech and Thought Balloons
- Position over player/event (follows movement and scrolling)
- Optional message tail (for speech or thought balloons)
- Can specify location relative to player/event (up, down, left, right)
- Can use different windowskin, message tail and font color
- Letter-by-letter mode
- Variable speed (and delays)
- Skippable on button press
- Autoresize messages
- Player movement allowed during messages
- If speaker moves offscreen, message closes (like ChronoTrigger)
- Everything also works during battle
- Settings configurable at anytime
- Can revert back to normal messages at anytime
- Change Opacity message
- Play Looping SE in message
- Can use shortcut for message
- Message Log
- Blizz ABS Compatible
- H Mode 7 Compatible
- Animated Letter
Screenshots(http://i.imgur.com/Yk0CF.jpg)
(http://i.imgur.com/81SbPiL.jpg)
DemoHere (http://littledrago.blogspot.com/2012/02/rgss-multiple-message-windows-ex.html)
InstructionsLook at the script
Graphics needed in the demo
CompatibilityQuote from: ForeverZer0 on March 24, 2010, 04:07:12 pm
Not compatible with other Custom Message Systems.
Will likely cause issues with scripts that heavily alter the Window_Message class.
If you use a Custom Movement script, it will likely disable the ability to move while a message is showing unless
you do some editing in the update method for Game_Player in the script.
Other than that, should be relatively compatible with most other scripts.
80% Compatible with SDK
Compatible with Blizz ABS
Compatible with H Mode 7
Credits and Thanks
- Wachunga, for the original writer of the script
- ForeverZer0, for the optimization, editing, and de-SDK-ing
- LiTTleDRAgo, for make it compatible with BlizzABS
- Heretic86, for some method that being used
- ThallionDarkshine, for animated letters
Author's Notes~
Now if only this had the option of adding image face emotes to the bubbles. ^^ That's all that is really keeping me from switching to this now in my game. ^^l
I never thought faces would look appropriate in a thought bubble, it kinda defeats the purpose in my personal opinion.
I always like the face graphics, it shows more emotion then you could do in a small sprite. :P
Can you have more then two kind of word baloons? There's one for normal talk, one for thinking.. what about like one for whispering and yelling?
YES! This is awesome! It works with pixel movement! I'm going to try it out!
Quote from: Taiine on February 15, 2012, 10:15:13 am
Can you have more then two kind of word baloons? There's one for normal talk, one for thinking.. what about like one for whispering and yelling?
how about resizing the font / baloon?
when shouting use larger font size and whispering with small font size
Wow! it's amazing! the only thing left is the face graphics! it's the most important thing...(at least for me :^_^':)
Why is this not in the database....
* Moves *
Everything would be fine if it were not a problem that bothers me personally (or rather, all who live in my country). My fuckin' provider don't let me enter to the sites, based on the some social engines, and that's including blogspot-sites too. So can you at least put the text of script separately on the forum, please?
#==============================================================================
# ** Multiple Message Windows
#------------------------------------------------------------------------------
# Originally written by Wachunga
# Optimized and De-SDK'ed by ForeverZer0
# Blizz Abs Version by LiTTleDRAgo
# 1.5
# 2006-11-17
#==============================================================================
=begin
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- Credit for the original script is 100% Wachunga. Original map and events
are also Wachunga's original.
- Edits have been made by ForeverZer0 to eliminate the SDK requirement
and improve coding and performance
- I have added a compatibility switch for Blizzard's simple shaded text if you
are you using that, because it doesn't look right with message text. The
switch will disable it whenever a message is showing, but otherwise will
shade everything else.
- This script must be placed below Blizzard's Tons-of-Add-ons if you are
using it. If you don't you will get an error. It has something to do with
the Lagless HUD script. Some bug I couldn't isolate... If you find it, let
me know, else just keep it under Tons.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
This custom message system adds numerous features on top of the default
message system, the most notable being the ability to have multiple message
windows open at once. The included features are mostly themed around turning
messages into speech (and thought) balloons, but default-style messages are
of course still possible.
Note:
This version of the script uses the SDK, available from:
http://www.rmxp.org/forums/showthread.php?t=1802
FEATURES
New in 1.5:
* \C[#ffffff] for hexadecimal color
* \C for return to default color
* display name of item, weapon, armor or skill
* \N[In] = display name of item with id n (note the "I")
* \N[Wn] = display name of weapon with id n (note the "W")
* \N[An] = display name of armor with id n (note the "A")
* \N[Sn] = display name of skill with id n (note the "S")
* display icon of item, weapon, armor or skill
* \I[In] = display icon of item with id n (note the "I")
* \I[Wn] = display icon of weapon with id n (note the "W")
* \I[An] = display icon of armor with id n (note the "A")
* \I[Sn] = display icon of skill with id n (note the "S")
* display icon and name of item, weapon, armor or skill
* \I&N[In] = display icon and name of item with id n (note the "I")
* \I&N[Wn] = display icon and name of weapon with id n (note the "W")
* \I&N[An] = display icon and name of armor with id n (note the "A")
* \I&N[Sn] = display icon and name of skill with id n (note the "S")
* new windowskins available
* speech windowskin now definable separately from default windowskin
* fixed bold bug where degree sign would occasionally appear
* input number window now shares parent window's font
* changed \Var[n] back to default of \V[n]
New in 1.1:
* message.autocenter for automatically centering text within messages
* \N[en] for displaying name of enemy with id n (note the "e")
* \MAP for displaying the name of the current map
At a glance:
* multiple message windows
* speech balloons
* position over player/event (follows movement and scrolling)
* optional message tail (for speech or thought balloons)
* can specify location relative to player/event (up, down, left, right)
* thought balloons
* can use different windowskin, message tail and font color
* letter-by-letter mode
* variable speed (and delays)
* skippable on button press
* autoresize messages
* player movement allowed during messages
* if speaker moves offscreen, message closes (like ChronoTrigger)
* everything also works during battle
* settings configurable at anytime
Full list of options:
(Note that all are case *insensitive*.)
=============================================================================
Local (specified in message itself and resets at message end)
=============================================================================
- \L = letter-by-letter mode toggle
- \S[n] = set speed at which text appears in letter-by-letter mode
- \D[n] = set delay (in frames) before next text appears
- \P[n] = position message over event with id n
* use n=0 for player
* in battle, use n=a,b,c,d for actors (e.g. \P[a] for first actor)
and n=1,...,n for enemies (e.g. \P[1] for first enemy)
where order is actually the reverse of troop order (in database)
- \P = position message over current event (default for floating messages)
- \^ = message appears directly over its event
- \v = message appears directly below its event
- \< = message appears directly to the left of its event
- \> = message appears directly to the right of its event
- \B = bold text
- \I = italic text
- \C[#xxxxxx] = change to color specified by hexadecimal (eg. ffffff = white)
- \C = change color back to default
- \! = message autoclose
- \? = wait for user input before continuing
- \+ = make message appear at same time as preceding one
* note: must be at the start of message to work
- \@ = thought balloon
- \N[En] = display name of enemy with id n (note the "E")
- \N[In] = display name of item with id n (note the "I")
- \N[Wn] = display name of weapon with id n (note the "W")
- \N[An] = display name of armor with id n (note the "A")
- \N[Sn] = display name of skill with id n (note the "S")
- \I[In] = display icon of item with id n (note the "I")
- \I[Wn] = display icon of weapon with id n (note the "W")
- \I[An] = display icon of armor with id n (note the "A")
- \I[Sn] = display icon of skill with id n (note the "S")
- \I&N[In] = display icon and name of item with id n (note the "I")
- \I&N[Wn] = display icon and name of weapon with id n (note the "W")
- \I&N[An] = display icon and name of armor with id n (note the "A")
- \I&N[Sn] = display icon and name of skill with id n (note the "S")
- \MAP = display the name of the current map
These are, of course, in addition to the default options:
- \V[n] = display value of variable n
- \N[n] = display name of actor with id n
- \C[n] = change color to n
- \G = display gold window
- \\ = show the '\' character
=============================================================================
Global (specified below or by Call Script and persist until changed)
=============================================================================
Zer0 Note:
If you use any of these in another script, etc. and not a script call, you
will need to place "$game_system." before each command.
Miscellaneous:
- message.move_during = true/false
* allow/disallow player to move during messages
- message.show_pause = true/false
* show/hide "waiting for player" pause graphic
- message.autocenter = true/false
* enable/disable automatically centering text within messages
Speech/thought balloon related:
- message.resize = true/false
* enable/disable automatic resizing of messages (only as big as necessary)
- message.floating = true/false
* enable/disable positioning messages above current event by default
(i.e. equivalent to including \P in every message)
- message.location = TOP, BOTTOM, LEFT or RIGHT
* set default location for floating messages relative to their event
- message.show_tail = true/false
* show/hide message tail for speech/thought balloons
Letter-by-letter related:
- message.letter_by_letter = true/false
* enable/disable letter-by-letter mode (globally)
- message.text_speed = 0-20
* set speed at which text appears in letter-by-letter mode (globally)
- message.skippable = true/false
* allow/disallow player to skip to end of message with button press
Font:
- message.font_name = font
* set font to use for text, overriding all defaults
(font can be any TrueType from Windows/Fonts folder)
- message.font_size = size
* set size of text (default 22), overriding all defaults
- message.font_color = color
* set color of text, overriding all defaults
* you can use same 0-7 as for \C[n] or "#xxxxxx" for hexadecimal
Note that the default thought and shout balloon windowskins don't
stretch to four lines very well (unfortunately).
Thanks:
XRXS code for self-close and wait for input
Slipknot for a convenient approach to altering settings in-game
SephirothSpawn for bitmap rotate method
=end
#==============================================================================
# Settings
#==============================================================================
# Zer0 Edit. Blizzard's Simple Shaded Text just looks kinda funny when used
# on black text (which is default for MMS). If you are using Shaded Text and
# do not want it to display for the message windows, set this to true. It will
# still show for everything else.
Blizzard_Shaded_Text_Fix = true
#----------------------------------------------------------------------------
# Windowskins
#----------------------------------------------------------------------------
# Note: all files must be in the Graphics/Windowskins/ folder
# Tip: tails don't look right on windowskins with gradient backgrounds
# filenames of tail and windowskin used for speech balloons
FILENAME_SPEECH_TAIL = 'white-tail_speech.png'
FILENAME_SPEECH_WINDOWSKIN = 'white-windowskin_speech.png'
# filenames of tail and windowskin used for thought balloons
FILENAME_THOUGHT_TAIL = 'white-tail_thought.png'
FILENAME_THOUGHT_WINDOWSKIN = 'white-windowskin_thought.png'
#----------------------------------------------------------------------------
# Fonts
#----------------------------------------------------------------------------
# Note: if floating or resize (i.e. 'speech balloons') are disabled,
# Font.default_name, Font.default_size and Font.default_color are used
# (you can change these in Main)
# During gameplay, you can use message.font_name etc to override all defaults
# defaults for speech text
SPEECH_FONT_COLOR = "#000000"
SPEECH_FONT_NAME = ['Comic Sans MS', 'Arial']
SPEECH_FONT_SIZE = 20
# defaults for thought text
THOUGHT_FONT_COLOR = "#000000"
THOUGHT_FONT_NAME = ['Comic Sans MS', 'Arial']
THOUGHT_FONT_SIZE = 20
# note that you can use an array of fonts for SPEECH_FONT_NAME, etc.
# e.g. ['Verdana', 'MS PGothic']
# (if Verdana is not available, MS PGothic will be used instead)
#----------------------------------------------------------------------------
# Misc
#----------------------------------------------------------------------------
# If using a specialty windowskin (e.g. the default thought balloon one),
# you can force the window width to always be a multiple of the number
# specified in this constant (even when using the resize feature).
# This allows, for example, the windowskin frame to be designed to
# repeat every 16 pixels so that the frame never looks cut off.
THOUGHT_WIDTH_MULTIPLE = 16
# (set to 0 if you're not using any such windowskins)
class Game_Message
# Any of the below can be changed by a Call Script event during gameplay.
# E.g. turn letter-by-letter mode off with: message.letter_by_letter = false
attr_accessor :move_during
attr_accessor :letter_by_letter
attr_accessor :text_speed
attr_accessor :skippable
attr_accessor :resize
attr_accessor :floating
attr_accessor :autocenter
attr_accessor :show_tail
attr_accessor :show_pause
attr_accessor :location
attr_accessor :font_name
attr_accessor :font_size
attr_accessor :font_color
def initialize
# whether or not messages appear one letter at a time
@letter_by_letter = true
# note: can also change within a single message with \L
# the default speed at which text appears in letter-by-letter mode
@text_speed = 0
# note: can also change within a single message with \S[n]
# whether or not players can skip to the end of (letter-by-letter) messages
@skippable = true
# whether or not messages are automatically resized based on the message
@resize = true
# whether or not message windows are positioned above
# characters/events by default, i.e. without needing \P every message
# (only works if resize messages enabled -- otherwise would look very odd)
@floating = true
# whether or not to automatically center lines within the message
@autocenter = true
# whether or not event-positioned messages have a tail(for speech balloons)
# (only works if floating and resized messages enabled -- otherwise would
# look very odd indeed)
@show_tail = true
# whether or not to display "waiting for user input" pause graphic
# (probably want this disabled for speech balloons)
@show_pause = false
# whether the player is permitted to move while messages are displayed
@move_during = false
# the default location for floating messages (relative to the event)
# note that an off-screen message will be "flipped" automatically
@location = TOP
# font details
# overrides all defaults; leave nil to just use defaults (e.g. as above)
@font_name = nil
@font_size = nil
@font_color = nil
end
end
#==============================================================================
# Private constants (don't edit)
#==============================================================================
# used for message.location
TOP = 8
BOTTOM = 2
LEFT = 4
RIGHT = 6
#------------------------------------------------------------------------------
class Window_Message < Window_Selectable
def initialize(msgindex)
super(80, 304, 480, 160)
self.contents = Bitmap.new(width - 32, height - 32)
self.visible = false
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
self.z = 9000 + msgindex * 5 # permits messages to overlap legibly
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
@fade_in = false
@fade_out = false
@contents_showing = false
@cursor_width = 0
self.active = false
self.index = -1
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
@msgindex = msgindex
@tail = Sprite.new
@tail.bitmap =
if @msgindex == 0
RPG::Cache.windowskin(FILENAME_SPEECH_TAIL)
else
# don't use cached version or else all tails
# are rotated when multiple are visible at once
Bitmap.new('Graphics/Windowskins/'+FILENAME_SPEECH_TAIL)
end
# keep track of orientation of tail bitmap
if @tail.bitmap.orientation == nil
@tail.bitmap.orientation = 0
end
# make origin the center, not top left corner
@tail.ox = @tail.bitmap.width/2
@tail.oy = @tail.bitmap.height/2
@tail.z = 9999
@tail.visible = false
if $game_system.message.floating && $game_system.message.resize
@windowskin = FILENAME_SPEECH_WINDOWSKIN
else
# use windowskin specified in database
@windowskin = $game_system.windowskin_name
end
if $game_system.message.floating && $game_system.message.resize
# if used as speech balloons, use constants
@font_name = SPEECH_FONT_NAME
@font_color = check_color(SPEECH_FONT_COLOR)
@font_size = SPEECH_FONT_SIZE
else
# use defaults
@font_name = Font.default_name
@font_color = Font.default_color
@font_size = Font.default_size
end
# override defaults if necessary
if $game_system.message.font_name != nil
@font_name = $game_system.message.font_name
end
if $game_system.message.font_color != nil
@font_color = check_color($game_system.message.font_color)
end
if $game_system.message.font_size != nil
@font_size = $game_system.message.font_size
end
@update_text = true
@letter_by_letter = $game_system.message.letter_by_letter
@text_speed = $game_system.message.text_speed
# id of character for speech balloons
@float_id = nil
# location of box relative to speaker
@location = $game_system.message.location
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
def dispose
terminate_message
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# have to check all windows before claiming that no window is showing
if $game_temp.message_text.compact.empty?
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
$game_temp.message_window_showing = false
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
if @input_number_window != nil
@input_number_window.dispose
end
super
end
def terminate_message
self.active = false
self.pause = false
self.index = -1
self.contents.clear
# Clear showing flag
@contents_showing = false
# Clear variables related to text, choices, and number input
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
@tail.visible = false
# note that these variables are now indexed arrays
$game_temp.message_text[@msgindex] = nil
# Call message callback
if $game_temp.message_proc[@msgindex] != nil
# make sure no message boxes are displaying
if $game_temp.message_text.compact.empty?
$game_temp.message_proc[@msgindex].call
end
$game_temp.message_proc[@msgindex] = nil
end
@update_text = true
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
$game_temp.choice_start = 99
$game_temp.choice_max = 0
$game_temp.choice_cancel_type = 0
$game_temp.choice_proc = nil
$game_temp.num_input_start = 99
$game_temp.num_input_variable_id = 0
$game_temp.num_input_digits_max = 0
# Open gold window
if @gold_window != nil
@gold_window.dispose
@gold_window = nil
end
end
def refresh
self.contents.clear
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
@x = @y = 0 # now instance variables
@float_id = nil
@location = $game_system.message.location
if $game_system.message.floating && $game_system.message.resize
@windowskin = FILENAME_SPEECH_WINDOWSKIN
else
# use windowskin specified in database
@windowskin = $game_system.windowskin_name
end
if $game_system.message.floating && $game_system.message.resize
# if used as speech balloons, use constants
@font_name = SPEECH_FONT_NAME
@font_color = check_color(SPEECH_FONT_COLOR)
@font_size = SPEECH_FONT_SIZE
else
# use default font
@font_name = Font.default_name
@font_color = Font.default_color
@font_size = Font.default_size
end
# override font defaults
if $game_system.message.font_name != nil
@font_name = $game_system.message.font_name
end
if $game_system.message.font_color != nil
@font_color = check_color($game_system.message.font_color)
end
if $game_system.message.font_size != nil
@font_size = $game_system.message.font_size
end
@line_widths = nil
@wait_for_input = false
@tail.bitmap =
if @msgindex == 0
RPG::Cache.windowskin(FILENAME_SPEECH_TAIL)
else
Bitmap.new('Graphics/Windowskins/'+FILENAME_SPEECH_TAIL)
end
RPG::Cache.windowskin(FILENAME_SPEECH_TAIL)
@tail.bitmap.orientation = 0 if @tail.bitmap.orientation == nil
@text_speed = $game_system.message.text_speed
@letter_by_letter = $game_system.message.letter_by_letter
@delay = @text_speed
@player_skip = false
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
@cursor_width = 0
# Indent if choice
if $game_temp.choice_start == 0
@x = 8
end
# If waiting for a message to be displayed
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
if $game_temp.message_text[@msgindex] != nil
@text = $game_temp.message_text[@msgindex] # now an instance variable
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
# Control text processing
begin
last_text = @text.clone
@text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
end until @text == last_text
@text.gsub!(/\\[Nn]\[([0-9]+)\]/) {
$game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : '' }
@text.gsub!(/\\[Nn][Aa][Mm][Ee]\[([0-9]+)\]/) {
$game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : '' }
# Change "\\\\" to "\000" for convenience
@text.gsub!(/\\\\/) { "\000" }
@text.gsub!(/\\[Gg]/) { "\002" }
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# display icon of item, weapon, armor or skill
@text.gsub!(/\\[Ii]\[([IiWwAaSs][0-9]+)\]/) { "\013[#{$1}]" }
# display name of enemy, item, weapon, armor or skill
@text.gsub!(/\\[Nn]\[([EeIiWwAaSs])([0-9]+)\]/) {
case $1.downcase
when 'e'
entity = $data_enemies[$2.to_i]
when 'i'
entity = $data_items[$2.to_i]
when 'w'
entity = $data_weapons[$2.to_i]
when 'a'
entity = $data_armors[$2.to_i]
when 's'
entity = $data_skills[$2.to_i]
end
entity != nil ? entity.name : ''
}
# display icon and name of item, weapon, armor or skill
@text.gsub!(/\\[Ii]&[Nn]\[([IiWwAaSs])([0-9]+)\]/) {
case $1.downcase
when 'e'
entity = $data_enemies[$2.to_i]
when 'i'
entity = $data_items[$2.to_i]
when 'w'
entity = $data_weapons[$2.to_i]
when 'a'
entity = $data_armors[$2.to_i]
when 's'
entity = $data_skills[$2.to_i]
end
entity != nil ? "\013[#{$1+$2}] " + entity.name : ''
}
# display name of current map
@text.gsub!(/\\[Mm][Aa][Pp]/) { $game_map.name }
# change font color
@text.gsub!(/\\[Cc]\[([0-9]+|#[0-9A-Fa-f]{6,6})\]/) { "\001[#{$1}]" }
# return to default color
@text.gsub!(/\\[Cc]/) { "\001" }
# toggle letter-by-letter mode
@text.gsub!(/\\[Ll]/) { "\003" }
# change text speed (for letter-by-letter)
@text.gsub!(/\\[Ss]\[([0-9]+)\]/) { "\004[#{$1}]" }
# insert delay
@text.gsub!(/\\[Dd]\[([0-9]+)\]/) { "\005[#{$1}]" }
# self close message
@text.gsub!(/\\[!]/) { "\006" }
# wait for button input
@text.gsub!(/\\[?]/) { "\007" }
# bold
@text.gsub!(/\\[Bb]/) { "\010" }
# italic
@text.gsub!(/\\[Ii]/) { "\011" }
# thought balloon
if @text.gsub!(/\\[@]/, '') != nil
@windowskin = FILENAME_THOUGHT_WINDOWSKIN
@font_name = THOUGHT_FONT_NAME
@font_size = THOUGHT_FONT_SIZE
@font_color = check_color(THOUGHT_FONT_COLOR)
@tail.bitmap =
if @msgindex == 0
RPG::Cache.windowskin(FILENAME_THOUGHT_TAIL)
else
Bitmap.new('Graphics/Windowskins/'+FILENAME_THOUGHT_TAIL)
end
@tail.bitmap.orientation = 0 if @tail.bitmap.orientation == nil
end
# Get rid of "\\+" (multiple messages)
@text.gsub!(/\\[+]/, '')
# Get rid of "\\^", "\\v", "\\<", "\\>" (relative message location)
if @text.gsub!(/\\\^/, '') != nil
@location = 8
elsif @text.gsub!(/\\[Vv]/, '') != nil
@location = 2
elsif @text.gsub!(/\\[<]/, '') != nil
@location = 4
elsif @text.gsub!(/\\[>]/, '') != nil
@location = 6
end
# Get rid of "\\P" (position window to given character)
if @text.gsub!(/\\[Pp]\[([0-9]+)\]/, '') != nil
@float_id = $1.to_i
elsif @text.gsub!(/\\[Pp]\[([a-zA-Z])\]/, '') != nil &&
$game_temp.in_battle
@float_id = $1.downcase
elsif @text.gsub!(/\\[Pp]/, '') != nil ||
($game_system.message.floating && $game_system.message.resize) &&
(!$game_temp.in_battle or $BlizzABS)
@float_id = $game_system.map_interpreter.event_id
end
if $game_system.message.resize || $game_system.message.autocenter
# calculate length of lines
text = @text.clone
temp_bitmap = Bitmap.new(1,1)
temp_bitmap.font.name = @font_name
temp_bitmap.font.size = @font_size
@line_widths = [0,0,0,0]
(0..3).each do |i|
line = text.split(/\n/)[3-i]
if line == nil
next
end
line.gsub!(/[\001-\007](\[[#A-Fa-f0-9]+\])?/, '')
line.gsub!(/\013\[[IiWwAaSs][0-9]+\]/, "\013")
line.chomp.split(//).each do |c|
case c
when "\000"
c = "\\"
when "\010"
# bold
temp_bitmap.font.bold = !temp_bitmap.font.bold
next
when "\011"
# italics
temp_bitmap.font.italic = !temp_bitmap.font.italic
next
when "\013"
# icon
@line_widths[3-i] += 24
next
end
@line_widths[3-i] += temp_bitmap.text_size(c).width
end
if (3-i) >= $game_temp.choice_start
# account for indenting
@line_widths[3-i] += 8 unless $game_system.message.autocenter
end
end
if $game_temp.num_input_variable_id > 0
# determine cursor_width as in Window_InputNumber
# (can't get from @input_number_window because it doesn't exist yet)
cursor_width = temp_bitmap.text_size('0').width + 8
# use this width to calculate line width (+8 for indent)
input_number_width = cursor_width*$game_temp.num_input_digits_max
input_number_width += 8 unless $game_system.message.autocenter
@line_widths[$game_temp.num_input_start] = input_number_width
end
temp_bitmap.dispose
end
resize
reposition if @float_id != nil
self.contents.font.name = @font_name
self.contents.font.size = @font_size
self.contents.font.color = @font_color
self.windowskin = RPG::Cache.windowskin(@windowskin)
# autocenter first line if enabled
# (subsequent lines are done as "\n" is encountered)
if $game_system.message.autocenter && @text != ''
@x = (self.width-40)/2 - @line_widths[0]/2
end
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
end
#--------------------------------------------------------------------------
# * Resize Window
#--------------------------------------------------------------------------
def resize
if !$game_system.message.resize
# reset to defaults
self.width = 480
self.height = 160
self.contents = Bitmap.new(width - 32, height - 32)
self.x = 80 # undo any centering
return
end
max_x = @line_widths.max
max_y = 4
@line_widths.each {|line| max_y -= 1 if line == 0 && max_y > 1}
if $game_temp.choice_max > 0
# account for indenting
max_x += 8 unless $game_system.message.autocenter
end
new_width = max_x + 40
if @windowskin == FILENAME_THOUGHT_WINDOWSKIN && THOUGHT_WIDTH_MULTIPLE >0
# force window width to be a multiple of THOUGHT_WIDTH_MULTIPLE
# so that specialty windowskins (e.g. thought balloon) look right
if new_width % THOUGHT_WIDTH_MULTIPLE != 0
new_width += THOUGHT_WIDTH_MULTIPLE-(new_width%THOUGHT_WIDTH_MULTIPLE)
end
end
self.width = new_width
self.height = max_y * 32 + 32
self.contents = Bitmap.new(width - 32, height - 32)
self.x = 320 - (self.width/2) # center
end
#--------------------------------------------------------------------------
# * Reposition Window
#--------------------------------------------------------------------------
def reposition
if $game_temp.in_battle && !$BlizzABS
if 'abcd'.include?(@float_id) # must be between a and d
@float_id = @float_id[0] - 97 # a = 0, b = 1, c = 2, d = 3
return if $scene.spriteset.actor_sprites[@float_id] == nil
sprite = $scene.spriteset.actor_sprites[@float_id]
else
@float_id -= 1 # account for, e.g., player entering 1 for index 0
return if $scene.spriteset.enemy_sprites[@float_id] == nil
sprite = $scene.spriteset.enemy_sprites[@float_id]
end
char_height = sprite.height
char_width = sprite.width
char_x = sprite.x
char_y = sprite.y - char_height/2
else # not in battle...
char = (@float_id == 0 ? $game_player : $game_map.events[@float_id])
if char == nil
# no such character
@float_id = nil
return
end
# close message (and stop event processing) if speaker is off-screen
if char.screen_x <= 0 || char.screen_x >= 640 ||
char.screen_y <= 0 || char.screen_y > 480
terminate_message
$game_system.map_interpreter.command_115
return
end
char_height = RPG::Cache.character(char.character_name,0).height / 4
char_width = RPG::Cache.character(char.character_name,0).width / 4
# record coords of character's center
char_x = char.screen_x
char_y = char.screen_y - char_height/2
end
params = [char_height, char_width, char_x, char_y]
# position window and message tail
vars = new_position(params)
x = vars[0]
y = vars[1]
# check if any window locations need to be "flipped"
if @location == 4 && x < 0
# switch to right
@location = 6
vars = new_position(params)
x = vars[0]
if (x + self.width) > 640
# right is no good either...
if y >= 0
# switch to top
@location = 8
vars = new_position(params)
else
# switch to bottom
@location = 2
vars = new_position(params)
end
end
elsif @location == 6 && (x + self.width) > 640
# switch to left
@location = 4
vars = new_position(params)
x = vars[0]
if x < 0
# left is no good either...
if y >= 0
# switch to top
@location = 8
vars = new_position(params)
else
# switch to bottom
@location = 2
vars = new_position(params)
end
end
elsif @location == 8 && y < 0
# switch to bottom
@location = 2
vars = new_position(params)
y = vars[1]
if (y + self.height) > 480
# bottom is no good either...
# note: this will probably never occur given only 3 lines of text
x = vars[0]
if x >= 0
# switch to left
@location = 4
vars = new_position(params)
else
# switch to right
@location = 6
vars = new_position(params)
end
end
elsif @location == 2 && (y + self.height) > 480
# switch to top
@location = 8
vars = new_position(params)
y = vars[1]
if y < 0
# top is no good either...
# note: this will probably never occur given only 3 lines of text
x = vars[0]
if x >= 0
# switch to left
@location = 4
vars = new_position(params)
else
# switch to right
@location = 6
vars = new_position(params)
end
end
end
x = vars[0]
y = vars[1]
tail_x = vars[2]
tail_y = vars[3]
# adjust windows if near edge of screen
if x < 0
x = 0
elsif (x + self.width) > 640
x = 640 - self.width
end
if y < 0
y = 0
elsif (y + self.height) > 480
y = 480 - self.height
elsif $game_temp.in_battle && @location == 2 && (y > (320 - self.height))
# when in battle, prevent enemy messages from overlapping battle status
# (note that it could still happen from actor messages, though)
y = 320 - self.height
tail_y = y
end
# finalize positions
self.x = x
self.y = y
@tail.x = tail_x
@tail.y = tail_y
end
#--------------------------------------------------------------------------
# * Determine New Window Position
#--------------------------------------------------------------------------
def new_position(params)
char_height = params[0]
char_width = params[1]
char_x = params[2]
char_y = params[3]
if @location == 8
# top
x = char_x - self.width/2
y = char_y - char_height/2 - self.height - @tail.bitmap.height/2
@tail.bitmap.rotation(0)
tail_x = x + self.width/2
tail_y = y + self.height
elsif @location == 2
# bottom
x = char_x - self.width/2
y = char_y + char_height/2 + @tail.bitmap.height/2
@tail.bitmap.rotation(180)
tail_x = x + self.width/2
tail_y = y
elsif @location == 4
# left
x = char_x - char_width/2 - self.width - @tail.bitmap.width/2
y = char_y - self.height/2
@tail.bitmap.rotation(270)
tail_x = x + self.width
tail_y = y + self.height/2
elsif @location == 6
# right
x = char_x + char_width/2 + @tail.bitmap.width/2
y = char_y - self.height/2
@tail.bitmap.rotation(90)
tail_x = x
tail_y = y + self.height/2
end
return [x,y,tail_x,tail_y]
end
#--------------------------------------------------------------------------
# * Update Text
#--------------------------------------------------------------------------
def update_text
if @text != nil
# Get 1 text character in c (loop until unable to get text)
while ((c = @text.slice!(/./m)) != nil)
# If \\
if c == "\000"
# Return to original text
c = "\\"
end
# If \C[n] or \C[#xxxxxx] or \C
if c == "\001"
# Change text color
@text.sub!(/\[([0-9]+|#[0-9A-Fa-f]{6,6})\]/, '')
if $1 != nil
self.contents.font.color = check_color($1)
else
# return to default color
if $game_system.message.font_color != nil
color = check_color($game_system.message.font_color)
elsif $game_system.message.floating && $game_system.message.resize
color = check_color(SPEECH_FONT_COLOR)
else
# use defaults
color = Font.default_color
end
self.contents.font.color = color
end
# go to next text
next
end
# If \G
if c == "\002"
# Make gold window
if @gold_window == nil
@gold_window = Window_Gold.new
@gold_window.x = 560 - @gold_window.width
if $game_temp.in_battle
@gold_window.y = 192
else
@gold_window.y = self.y >= 128 ? 32 : 384
end
@gold_window.opacity = self.opacity
@gold_window.back_opacity = self.back_opacity
end
# go to next text
next
end
# If \L
if c == "\003"
# toggle letter-by-letter mode
@letter_by_letter = !@letter_by_letter
# go to next text
next
end
# If \S[n]
if c == "\004"
@text.sub!(/\[([0-9]+)\]/, '')
speed = $1.to_i
if speed >= 0
@text_speed = speed
# reset player skip after text speed change
@player_skip = false
end
return
end
# If \D[n]
if c == "\005"
@text.sub!(/\[([0-9]+)\]/, '')
delay = $1.to_i
if delay >= 0
@delay += delay
# reset player skip after delay
@player_skip = false
end
return
end
# If \!
if c == "\006"
# close message and return from method
terminate_message
return
end
# If \?
if c == "\007"
@wait_for_input = true
return
end
if c == "\010"
# bold
self.contents.font.bold = !self.contents.font.bold
return
end
if c == "\011"
# italics
self.contents.font.italic = !self.contents.font.italic
return
end
if c == "\013"
# display icon of item, weapon, armor or skill
@text.sub!(/\[([IiWwAaSs])([0-9]+)\]/, '')
case $1.downcase
when 'i'
item = $data_items[$2.to_i]
when 'w'
item = $data_weapons[$2.to_i]
when 'a'
item = $data_armors[$2.to_i]
when 's'
item = $data_skills[$2.to_i]
end
if item == nil
return
end
bitmap = RPG::Cache.icon(item.icon_name)
self.contents.blt(4+@x, 32*@y+4, bitmap, Rect.new(0, 0, 24, 24))
@x += 24
#self.contents.draw_text(x + 28, y, 212, 32, item.name)
return
end
# If new line text
if c == "\n"
# Update cursor width if choice
if @y >= $game_temp.choice_start
width = $game_system.message.autocenter ? @line_widths[@y]+8 : @x
@cursor_width = [@cursor_width, width].max
end
# Add 1 to y
@y += 1
if $game_system.message.autocenter && @text != ''
@x = (self.width-40)/2 - @line_widths[@y]/2
else
@x = 0
# Indent if choice
if @y >= $game_temp.choice_start
@x = 8
end
end
# go to next text
next
end
# Draw text
self.contents.draw_text(4 + @x, 32 * @y, 40, 32, c)
# Add x to drawn text width
@x += self.contents.text_size( c ).width
# add text speed to time to display next character
@delay += @text_speed unless !@letter_by_letter || @player_skip
return if @letter_by_letter && !@player_skip
end
end
# If choice
if $game_temp.choice_max > 0
@item_max = $game_temp.choice_max
self.active = true
self.index = 0
end
# If number input
if $game_temp.num_input_variable_id > 0
digits_max = $game_temp.num_input_digits_max
number = $game_variables[$game_temp.num_input_variable_id]
@input_number_window = Window_InputNumber.new(digits_max)
@input_number_window.set_font(@font_name, @font_size, @font_color)
@input_number_window.number = number
@input_number_window.x =
if $game_system.message.autocenter
offset = (self.width-40)/2-@line_widths[$game_temp.num_input_start]/2
self.x + offset + 4
else
self.x + 8
end
@input_number_window.y = self.y + $game_temp.num_input_start * 32
end
@update_text = false
end
def reset_window
if $game_temp.in_battle
self.y = 16
else
case $game_system.message_position
when 0 # up
self.y = 16
when 1 # middle
self.y = 160
when 2 # down
self.y = 304
end
end
if $game_system.message_frame == 0
self.opacity = 255
else
self.opacity = 0
end
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# transparent speech balloons don't look right, so keep opacity at 255
# self.back_opacity = 160
@tail.opacity = 255
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
def update
super
# If fade in
if @fade_in
self.contents_opacity += 24
if @input_number_window != nil
@input_number_window.contents_opacity += 24
end
if self.contents_opacity == 255
@fade_in = false
end
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# return
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
# If inputting number
if @input_number_window != nil
@input_number_window.update
# Confirm
if Input.trigger?(Input::C)
$game_system.se_play($data_system.decision_se)
$game_variables[$game_temp.num_input_variable_id] =
@input_number_window.number
$game_map.need_refresh = true
# Dispose of number input window
@input_number_window.dispose
@input_number_window = nil
terminate_message
end
return
end
# If message is being displayed
if @contents_showing
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# Confirm or cancel finishes waiting for input or message
if Input.trigger?(Input::C) || Input.trigger?(Input::B)
if @wait_for_input
@wait_for_input = false
self.pause = false
elsif $game_system.message.skippable
@player_skip = true
end
end
if need_reposition?
reposition # update message position for character/screen movement
if @contents_showing == false
# i.e. if char moved off screen
return
end
end
if @update_text && !@wait_for_input
if @delay == 0
update_text
else
@delay -= 1
end
return
end
# If choice isn't being displayed, show pause sign
if !self.pause && ($game_temp.choice_max == 0 || @wait_for_input)
self.pause = true unless !$game_system.message.show_pause
end
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
# Cancel
if Input.trigger?(Input::B)
if $game_temp.choice_max > 0 && $game_temp.choice_cancel_type > 0
$game_system.se_play($data_system.cancel_se)
$game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
terminate_message
end
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# personal preference: cancel button should also continue
terminate_message
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
# Confirm
if Input.trigger?(Input::C)
if $game_temp.choice_max > 0
$game_system.se_play($data_system.decision_se)
$game_temp.choice_proc.call(self.index)
end
terminate_message
end
return
end
# If display wait message or choice exists when not fading out
if @fade_out == false && $game_temp.message_text[@msgindex] != nil
@contents_showing = true
$game_temp.message_window_showing = true
reset_window
refresh
Graphics.frame_reset
self.visible = true
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
if show_message_tail?
@tail.visible = true
elsif @tail.visible
@tail.visible = false
end
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
self.contents_opacity = 0
if @input_number_window != nil
@input_number_window.contents_opacity = 0
end
@fade_in = true
return
end
# If message which should be displayed is not shown, but window is visible
if self.visible
@fade_out = true
self.opacity -= 96
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
@tail.opacity -= 96 if @tail.opacity > 0
if need_reposition?
reposition # update message position for character/screen movement
end
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
if self.opacity == 0
self.visible = false
@fade_out = false
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
@tail.visible = false if @tail.visible
# have to check all windows before claiming that no window is showing
if $game_temp.message_text.compact.empty?
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
$game_temp.message_window_showing = false
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
return
end
end
#--------------------------------------------------------------------------
# * Repositioning Determination
#--------------------------------------------------------------------------
def need_reposition?
if (!$game_temp.in_battle or $BlizzABS) && $game_system.message.floating &&
$game_system.message.resize && @float_id != nil
if $game_system.message.move_during && @float_id == 0 &&
(($game_player.last_real_x != $game_player.real_x) ||
($game_player.last_real_y != $game_player.real_y))
# player with floating message moved
# (note that relying on moving? leads to "jumpy" message boxes)
return true
elsif ($game_map.last_display_y != $game_map.display_y) ||
($game_map.last_display_x != $game_map.display_x)
# player movement or scroll event caused the screen to scroll
return true
else
char = $game_map.events[@float_id]
if char != nil &&
((char.last_real_x != char.real_x) ||
(char.last_real_y != char.real_y))
# character moved
return true
end
end
end
return false
end
#--------------------------------------------------------------------------
# * Show Message Tail Determination
#--------------------------------------------------------------------------
def show_message_tail?
if $game_system.message.show_tail && $game_system.message.floating &&
$game_system.message.resize && $game_system.message_frame == 0 &&
@float_id != nil
return true
end
return false
end
def update_cursor_rect
if @index >= 0
n = $game_temp.choice_start + @index
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
if $game_system.message.autocenter
x = 4 + (self.width-40)/2 - @cursor_width/2
else
x = 8
end
self.cursor_rect.set(x, n * 32, @cursor_width, 32)
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
else
self.cursor_rect.empty
end
end
end
#------------------------------------------------------------------------------
class Game_Character
attr_reader :last_real_x # last map x-coordinate
attr_reader :last_real_y # last map y-coordinate
alias wachunga_game_char_update update
def update
@last_real_x = @real_x
@last_real_y = @real_y
wachunga_game_char_update
end
end
#------------------------------------------------------------------------------
class Game_Temp
alias wachunga_mmw_game_temp_initialize initialize
def initialize
wachunga_mmw_game_temp_initialize
@message_text = []
@message_proc = []
end
end
#------------------------------------------------------------------------------
class Sprite_Battler < RPG::Sprite
# necessary for positioning messages relative to battlers
attr_reader :height
attr_reader :width
end
#------------------------------------------------------------------------------
class Scene_Battle
# necessary for accessing actor/enemy sprites in battle
attr_reader :spriteset
end
#------------------------------------------------------------------------------
class Spriteset_Battle
# necessary for accessing actor/enemy sprites in battle
attr_reader :actor_sprites
attr_reader :enemy_sprites
end
#------------------------------------------------------------------------------
class Scene_Map
#--------------------------------------------------------------------------
# * New Message Window Addition
#--------------------------------------------------------------------------
def new_message_window(index)
if @message_window[index] != nil
# clear message windows at and after this index
last_index = @message_window.size - 1
last_index.downto(index) { |i|
if @message_window[i] != nil
@message_window[i].dispose
@message_window[i] = nil
end
}
@message_window.compact!
end
@message_window.push(Window_Message.new(index))
end
end
#------------------------------------------------------------------------------
class Scene_Battle
#--------------------------------------------------------------------------
# * New Message Window Addition
#--------------------------------------------------------------------------
def new_message_window(index)
if @message_window[index] != nil
# clear message windows at and after this index
last_index = @message_window.size - 1
last_index.downto(index) { |i|
if @message_window[i] != nil
@message_window[i].dispose
@message_window[i] = nil
end
}
@message_window.compact!
end
@message_window.push(Window_Message.new(index))
end
end
#------------------------------------------------------------------------------
class Game_System
attr_reader :message
alias wachunga_mmw_game_system_init initialize
def initialize
wachunga_mmw_game_system_init
@message = Game_Message.new
end
# Zer0 Edit
alias zer0_shaded_text_fix_upd update
def update
zer0_shaded_text_fix_upd
if @SHADED_TEXT != nil && Blizzard_Shaded_Text_Fix == true
if $game_temp.message_window_showing
@SHADED_TEXT = false
else
@SHADED_TEXT = true
end
end
end
end
#------------------------------------------------------------------------------
class Game_Player < Game_Character # Zer0 edit
# Redefines the update method
def update
# Remember whether or not moving in local variables
last_moving = moving?
# If moving, event running, move route forcing, and message window
# display are all not occurring
unless moving? ||
@move_route_forcing ||
($game_system.map_interpreter.running? &&
!$game_temp.message_window_showing) ||
($game_temp.message_window_showing &&
!$game_system.message.move_during) ||
($game_temp.choice_max > 0 || $game_temp.num_input_digits_max > 0)
# Move player in the direction the directional button is being pressed
case Input.dir4
when 2
move_down
when 4
move_left
when 6
move_right
when 8
move_up
end
end
# Remember coordinates in local variables
last_real_x = @real_x
last_real_y = @real_y
super
# If character moves down and is positioned lower than the center
# of the screen
if @real_y > last_real_y and @real_y - $game_map.display_y > CENTER_Y
# Scroll map down
$game_map.scroll_down(@real_y - last_real_y)
end
# If character moves left and is positioned more let on-screen than
# center
if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X
# Scroll map left
$game_map.scroll_left(last_real_x - @real_x)
end
# If character moves right and is positioned more right on-screen than
# center
if @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X
# Scroll map right
$game_map.scroll_right(@real_x - last_real_x)
end
# If character moves up and is positioned higher than the center
# of the screen
if @real_y < last_real_y and @real_y - $game_map.display_y < CENTER_Y
# Scroll map up
$game_map.scroll_up(last_real_y - @real_y)
end
# If not moving
unless moving?
# If player was moving last time
if last_moving
# Event determinant is via touch of same position event
result = check_event_trigger_here([1,2])
# If event which started does not exist
if result == false
# Disregard if debug mode is ON and ctrl key was pressed
unless $DEBUG and Input.press?(Input::CTRL)
# Encounter countdown
if @encounter_count > 0
@encounter_count -= 1
end
end
end
end
# If C button was pressed
if Input.trigger?(Input::C)
# Same position and front event determinant
check_event_trigger_here([0])
check_event_trigger_there([0,1,2])
end
end
end
#--------------------------------------------------------------------------
# * Touch Event Starting Determinant
#--------------------------------------------------------------------------
# This is a fix if Blizzard's Optimized default scripts are being used
def check_event_trigger_touch(x, y)
result = false # <--------- MOVED from....
# If event is running
if $game_system.map_interpreter.running?
return result
end
#result = false # <--------- ...HERE
# All event loops
$game_map.events.each_value {|event|
# If event coordinates and triggers are consistent
if event.x == x && event.y == y && [1,2].include?(event.trigger)
# If starting determinant is front event (other than jumping)
if !event.jumping? && !event.over_trigger?
event.start
result = true
end
end
}
return result
end
end
#------------------------------------------------------------------------------
class Interpreter
attr_reader :event_id
alias wachunga_mmw_interp_setup setup
def setup(list, event_id)
wachunga_mmw_interp_setup(list, event_id)
# index of window for the message
@msgindex = 0
# whether multiple messages are displaying
@multi_message = false
end
def setup_choices(parameters)
# Set choice item count to choice_max
$game_temp.choice_max = parameters[0].size
# Set choice to message_text
parameters[0].each {|text| $game_temp.message_text[@msgindex] += text + "\n"}
# Set cancel processing
$game_temp.choice_cancel_type = parameters[1]
# Set callback
current_indent = @list[@index].indent
$game_temp.choice_proc = Proc.new { |n| @branch[current_indent] = n }
end
#--------------------------------------------------------------------------
# * Show Text
#--------------------------------------------------------------------------
def command_101
# If other text has been set to message_text
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
if $game_temp.message_text[@msgindex] != nil
if @multi_message
@msgindex += 1
$scene.new_message_window(@msgindex)
else
# End
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
return false
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
end
@msgindex = 0 if !@multi_message
@multi_message = false
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
# Set message end waiting flag and callback
@message_waiting = true
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# just adding indexes
$game_temp.message_proc[@msgindex] = Proc.new { @message_waiting = false }
# Set message text on first line
$game_temp.message_text[@msgindex] = @list[@index].parameters[0] + "\n"
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
line_count = 1
# Loop
loop do
# If next event command text is on the second line or after
if @list[@index+1].code == 401
# Add the second line or after to message_text
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# just adding index
$game_temp.message_text[@msgindex]+=@list[@index+1].parameters[0]+"\n"
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
line_count += 1
# If event command is not on the second line or after
else
# If next event command is show choices
if @list[@index+1].code == 102
# If choices fit on screen
if @list[@index+1].parameters[0].size <= 4 - line_count
# Advance index
@index += 1
# Choices setup
$game_temp.choice_start = line_count
setup_choices(@list[@index].parameters)
end
# If next event command is input number
elsif @list[@index+1].code == 103
# If number input window fits on screen
if line_count < 4
# Advance index
@index += 1
# Number input setup
$game_temp.num_input_start = line_count
$game_temp.num_input_variable_id = @list[@index].parameters[0]
$game_temp.num_input_digits_max = @list[@index].parameters[1]
end
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# start multimessage if next line is "Show Text" starting with "\\+"
elsif @list[@index+1].code == 101
if @list[@index+1].parameters[0][0..1]=="\\+"
@multi_message = true
@message_waiting = false
end
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
end
# Continue
return true
end
# Advance index
@index += 1
end
end
#--------------------------------------------------------------------------
# * Show Choices
#--------------------------------------------------------------------------
def command_102
# If text has been set to message_text
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# just adding index
if $game_temp.message_text[@msgindex] != nil
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
# End
return false
end
# Set message end waiting flag and callback
@message_waiting = true
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# adding more indexes
$game_temp.message_proc[@msgindex] = Proc.new { @message_waiting = false }
# Choices setup
$game_temp.message_text[@msgindex] = ''
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
$game_temp.choice_start = 0
setup_choices(@parameters)
# Continue
return true
end
#--------------------------------------------------------------------------
# * Input Number
#--------------------------------------------------------------------------
def command_103
# If text has been set to message_text
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# just adding index
if $game_temp.message_text[@msgindex] != nil
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
# End
return false
end
# Set message end waiting flag and callback
@message_waiting = true
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
# adding more indexes
$game_temp.message_proc[@msgindex] = Proc.new { @message_waiting = false }
# Number input setup
$game_temp.message_text[@msgindex] = ''
#------------------------------------------------------------------------------
# End Multiple Message Windows Edit
#------------------------------------------------------------------------------
$game_temp.num_input_start = 0
$game_temp.num_input_variable_id = @parameters[0]
$game_temp.num_input_digits_max = @parameters[1]
# Continue
return true
end
#--------------------------------------------------------------------------
# * Script
#--------------------------------------------------------------------------
# Fix for RMXP bug: call script boxes that return false hang the game
# See, e.g., http://rmxp.org/forums/showthread.php?p=106639
#--------------------------------------------------------------------------
def command_355
# Set first line to script
script = @list[@index].parameters[0] + "\n"
# Loop
loop do
# If next event command is second line of script or after
if @list[@index+1].code == 655
# Add second line or after to script
script += @list[@index+1].parameters[0] + "\n"
# If event command is not second line or after
else
# Abort loop
break
end
# Advance index
@index += 1
end
# Evaluation
result = eval(script)
# If return value is false
if result == false
# End
#------------------------------------------------------------------------------
# Begin Edit
#------------------------------------------------------------------------------
#return false
#------------------------------------------------------------------------------
# End Edit
#------------------------------------------------------------------------------
end
# Continue
return true
end
def message
message = $game_system.message if $game_system != nil
end
end
#------------------------------------------------------------------------------
class Game_Map
attr_accessor :last_display_x # last display x-coord * 128
attr_accessor :last_display_y # last display y-coord * 128
alias wachunga_mmw_game_map_update update
def update
@last_display_x = @display_x
@last_display_y = @display_y
wachunga_mmw_game_map_update
end
def name
return load_data('Data/MapInfos.rxdata')[@map_id].name
end
end
#------------------------------------------------------------------------------
class Bitmap
attr_accessor :orientation
#--------------------------------------------------------------------------
# * Rotation Calculation
#--------------------------------------------------------------------------
def rotation(target)
return if not [0, 90, 180, 270].include?(target) # invalid orientation
if @rotation != target
degrees = target - @orientation
if degrees < 0
degrees += 360
end
rotate(degrees)
end
end
#--------------------------------------------------------------------------
# * Rotate Square (Clockwise)
#--------------------------------------------------------------------------
def rotate(degrees = 90)
# method originally by SephirothSpawn
# would just use Sprite.angle but its rotation is buggy
# (see http://www.rmxp.org/forums/showthread.php?t=12044)
return if not [90, 180, 270].include?(degrees)
copy = self.clone
if degrees == 90
# Passes Through all Pixels on Dummy Bitmap
(0...self.height).each {|i|
(0...self.width).each {|j|
self.set_pixel(width - i - 1, j, copy.get_pixel(j, i))
}
}
elsif degrees == 180
(0...self.height).each {|i|
(0...self.width).each {|j|
self.set_pixel(width - j - 1, height - i - 1, copy.get_pixel(j, i))
}
}
elsif degrees == 270
(0...self.height).each {|i|
(0...self.width).each {|j|
self.set_pixel(i, height - j - 1, copy.get_pixel(j, i))
}
}
end
@orientation = (@orientation + degrees) % 360
end
end
#------------------------------------------------------------------------------
class Window_Base
#--------------------------------------------------------------------------
# * Check Color
# color : color to check
#--------------------------------------------------------------------------
def check_color(color)
if color.type == Color
# already a Color object
return color
elsif color[0].chr == "#"
# specified as hexadecimal
r = color[1..2].hex
g = color[3..4].hex
b = color[5..6].hex
return Color.new(r,g,b)
else
# specified as integer (0-7)
color = color.to_i
if color >= 0 && color <= 7
return text_color(color)
end
end
return normal_color
end
end
#------------------------------------------------------------------------------
class Window_InputNumber < Window_Base
def set_font(fname, fsize, fcolor)
return if fname == nil && fsize == nil && fcolor == nil
# Calculate cursor width from number width
dummy_bitmap = Bitmap.new(32, 32)
dummy_bitmap.font.name = fname
dummy_bitmap.font.size = fsize
@cursor_width = dummy_bitmap.text_size('0').width + 8
dummy_bitmap.dispose
self.width = @cursor_width * @digits_max + 32
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = fname
self.contents.font.size = fsize
self.contents.font.color = check_color(fcolor)
refresh
update_cursor_rect
end
def refresh
self.contents.clear
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
#self.contents.font.color = normal_color
#------------------------------------------------------------------------------
# Begin Multiple Message Windows Edit
#------------------------------------------------------------------------------
s = sprintf("%0*d", @digits_max, @number)
(0...@digits_max).each {|i|
self.contents.draw_text(i * @cursor_width + 4, 0, 32, 32, s[i,1])
}
end
end
Also, replace Scene_Map with this:
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs map screen processing.
#==============================================================================
class Scene_Map
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Make sprite set
@spriteset = Spriteset_Map.new
# Make message window
#--------------------------------------------------------------------------
@message_window = [] # Zer0 edit
@message_window[0] = Window_Message.new(0)
#--------------------------------------------------------------------------
# Transition run
Graphics.transition
# Main loop
loop {
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
}
# Prepare for transition
Graphics.freeze
# Dispose of sprite set
@spriteset.dispose
# Dispose of message window
#--------------------------------------------------------------------------
@message_window.each {|mw| mw.dispose} # Zer0 edit
#--------------------------------------------------------------------------
# If switching to title screen
if $scene.is_a?(Scene_Title)
# Fade out screen
Graphics.transition
Graphics.freeze
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Loop
loop {
# Update map, interpreter, and player order
# (this update order is important for when conditions are fulfilled
# to run any event, and the player isn't provided the opportunity to
# move in an instant)
$game_map.update
$game_system.map_interpreter.update
$game_player.update
# Update system (timer), screen
$game_system.update
$game_screen.update
# Abort loop if player isn't place moving
unless $game_temp.player_transferring
break
end
# Run place move
transfer_player
# Abort loop if transition processing
if $game_temp.transition_processing
break
end
}
# Update sprite set
@spriteset.update
# Update message window
#--------------------------------------------------------------------------
@message_window.each {|mw| mw.update} # Zer0 edit
#--------------------------------------------------------------------------
# If game over
if $game_temp.gameover
# Switch to game over screen
$scene = Scene_Gameover.new
return
end
# If returning to title screen
if $game_temp.to_title
# Change to title screen
$scene = Scene_Title.new
return
end
# If transition processing
if $game_temp.transition_processing
# Clear transition processing flag
$game_temp.transition_processing = false
# Execute transition
if $game_temp.transition_name == ''
Graphics.transition(20)
else
Graphics.transition(40, 'Graphics/Transitions/' +
$game_temp.transition_name)
end
end
# If showing message window
if $game_temp.message_window_showing
return
end
# If encounter list isn't empty, and encounter count is 0
if $game_player.encounter_count == 0 && $game_map.encounter_list != []
# If event is running or encounter is not forbidden
unless $game_system.map_interpreter.running? ||
$game_system.encounter_disabled
# Confirm troop
n = rand($game_map.encounter_list.size)
troop_id = $game_map.encounter_list[n]
# If troop is valid
if $data_troops[troop_id] != nil
# Set battle calling flag
$game_temp.battle_calling = true
$game_temp.battle_troop_id = troop_id
$game_temp.battle_can_escape = true
$game_temp.battle_can_lose = false
$game_temp.battle_proc = nil
end
end
end
# If B button was pressed
if Input.trigger?(Input::B)
# If event is running, or menu is not forbidden
unless $game_system.map_interpreter.running? ||
$game_system.menu_disabled
# Set menu calling flag or beep flag
$game_temp.menu_calling = true
$game_temp.menu_beep = true
end
end
# If debug mode is ON and F9 key was pressed
if $DEBUG && Input.press?(Input::F9)
# Set debug calling flag
$game_temp.debug_calling = true
end
# If player is not moving
unless $game_player.moving?
# Run calling of each screen
if $game_temp.battle_calling
call_battle
elsif $game_temp.shop_calling
call_shop
elsif $game_temp.name_calling
call_name
elsif $game_temp.menu_calling
call_menu
elsif $game_temp.save_calling
call_save
elsif $game_temp.debug_calling
call_debug
end
end
end
#--------------------------------------------------------------------------
# * Battle Call
#--------------------------------------------------------------------------
def call_battle
# Clear battle calling flag
$game_temp.battle_calling = false
# Clear menu calling flag
$game_temp.menu_calling = false
$game_temp.menu_beep = false
# Make encounter count
$game_player.make_encounter_count
# Memorize map BGM and stop BGM
$game_temp.map_bgm = $game_system.playing_bgm
$game_system.bgm_stop
# Play battle start SE
$game_system.se_play($data_system.battle_start_se)
# Play battle BGM
$game_system.bgm_play($game_system.battle_bgm)
# Straighten player position
$game_player.straighten
# Switch to battle screen
$scene = Scene_Battle.new
end
#--------------------------------------------------------------------------
# * Shop Call
#--------------------------------------------------------------------------
def call_shop
# Clear shop call flag
$game_temp.shop_calling = false
# Straighten player position
$game_player.straighten
# Switch to shop screen
$scene = Scene_Shop.new
end
#--------------------------------------------------------------------------
# * Name Input Call
#--------------------------------------------------------------------------
def call_name
# Clear name input call flag
$game_temp.name_calling = false
# Straighten player position
$game_player.straighten
# Switch to name input screen
$scene = Scene_Name.new
end
#--------------------------------------------------------------------------
# * Menu Call
#--------------------------------------------------------------------------
def call_menu
# Clear menu call flag
$game_temp.menu_calling = false
# If menu beep flag is set
if $game_temp.menu_beep
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Clear menu beep flag
$game_temp.menu_beep = false
end
# Straighten player position
$game_player.straighten
# Switch to menu screen
$scene = Scene_Menu.new
end
#--------------------------------------------------------------------------
# * Save Call
#--------------------------------------------------------------------------
def call_save
# Straighten player position
$game_player.straighten
# Switch to save screen
$scene = Scene_Save.new
end
#--------------------------------------------------------------------------
# * Debug Call
#--------------------------------------------------------------------------
def call_debug
# Clear debug call flag
$game_temp.debug_calling = false
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Straighten player position
$game_player.straighten
# Switch to debug screen
$scene = Scene_Debug.new
end
#--------------------------------------------------------------------------
# * Player Place Move
#--------------------------------------------------------------------------
def transfer_player
# Clear player place move call flag
$game_temp.player_transferring = false
# If move destination is different than current map
if $game_map.map_id != $game_temp.player_new_map_id
# Set up a new map
$game_map.setup($game_temp.player_new_map_id)
end
# Set up player position
$game_player.moveto($game_temp.player_new_x, $game_temp.player_new_y)
# Set player direction
case $game_temp.player_new_direction
when 2 # down
$game_player.turn_down
when 4 # left
$game_player.turn_left
when 6 # right
$game_player.turn_right
when 8 # up
$game_player.turn_up
end
# Straighten player position
$game_player.straighten
# Update map (run parallel process event)
$game_map.update
# Remake sprite set
@spriteset.dispose
@spriteset = Spriteset_Map.new
# If processing transition
if $game_temp.transition_processing
# Clear transition processing flag
$game_temp.transition_processing = false
# Execute transition
Graphics.transition(20)
end
# Run automatic change for BGM and BGS set on the map
$game_map.autoplay
# Frame reset
Graphics.frame_reset
# Update input information
Input.update
end
end
@Boba Fett Link :
probably you didn't notice, the script needs some code below blizz abs to work with the player movement
@Agckuu Coceg
http://dl.dropbox.com/u/74796308/RMXP/Multiple%20Message%20Windows%20Demo.rar
----edit
updated
* Added Faceset
Huh, I didn't see that. Wasn't using it my game but it was working...
Quote from: Boba Fett Link on April 29, 2012, 02:54:55 pm
Huh, I didn't see that. Wasn't using it my game but it was working...
that patch will make player can move during message
Quote
- message.move_during = true/false
* allow/disallow player to move during messages
without that snippet, that feature won't work on blizz abs
I'm having a weird problem with this script on one specific scene.
I have 2 autorun events 1 shows text, the other manages movement, sounds etc etc now the problem is the text event doesn't want to work no matter what I do. (Tried placing it in parallel process but no use)
Also in this scene I had the player graphic change for a few seconds but it doesn't want to keep the appearance but goes back to default instantly dunno the cause too.
Don't have script that should be giving me problems so I don't understand why it's happening :S
Any idea what could be problem?
If you want I can pm you a demo with the scene.
Thanks
okay, upload your sample project
but don't expect a fast reply, I have exam this month
edit : check your PM
Thanks
Can someone make it compatible with Landith HUD ? please. It gives my this error:
http://imageshack.us/photo/my-images/18/99991223.jpg/ (http://imageshack.us/photo/my-images/18/99991223.jpg/)
upload a demo to mediafire with this script, blizz abs, and landith hud script inside it
Thanks for helping!
http://www.mediafire.com/?6j93u2ukgw16ydk (http://www.mediafire.com/?6j93u2ukgw16ydk)
script updated
new feature look at first post
added Landith Hud Compatibility Patch
Thank you very much!!!
Now I have another problem...The hud won't dissapear when I open the menu...I've reuploaded the project.
http://www.mediafire.com/?ddngwuzul69vzp8 (http://www.mediafire.com/?ddngwuzul69vzp8)
fixed glitch in Landith Compatibility Patch
Thank you again! Now looks like everything works fine :)
added compatibility with H Mode 7 :p
Hey littledrago I had this idea in my head yesterday during work about this custom message script and was wondering if it would be hard to separate the choice of "talking" for the not moving option.
I was thinking if it would be possible to have the main talking window making you unable to walk while the thought bubble chat lets you freely walk. (With an option to enable/disable if possible for cutscenes)
Would it be hard to do?
Thanks
you can use call script to disable move during messages though
- message.move_during = true/false
* allow/disallow player to move during messages
I forgot about that heh I'll test it out.
*update*
fixed bug in message log
I got ArugmentError when using this script together with BlizzABS and Tons-of-Add-ons
Can you be more specific about the error and script versions you are using?
try placing the script below tons of addons and above blizz abs
Quote from: LiTTleDRAgo on November 19, 2012, 12:02:18 am
try placing the script below tons of addons and above blizz abs
No Error window pop out,but message window didn't work properly.
I upload my game project.
http://www.mediafire.com/?pd1fy4tm13mnlep
*script updated*
added support for blizz-abs pixel movement
Pixel Movement! Schweet!
Just wondering if any of the other enhancements I put in ever transfer? I may come back to this script at some point, but I have something else totally stuck in my brain right now.
Now, how would one go about animating letters, like making them "shake"? "This is \shake[1]Shaky\shake text.", like in Super Mario RPG? That might be the next thing for us to take a whack at...
Quote from: Heretic86 on November 30, 2012, 01:19:42 am
Pixel Movement! Schweet!
Just wondering if any of the other enhancements I put in ever transfer? I may come back to this script at some point, but I have something else totally stuck in my brain right now.
Now, how would one go about animating letters, like making them "shake"? "This is \shake[1]Shaky\shake text.", like in Super Mario RPG? That might be the next thing for us to take a whack at...
まあ~ you can compare your attr_accessor with mine to see your enchancement that I use
I didn't have much free time currently, so probably I won't developing this script at least for now
The message window works strange and the player can't walk when there is a parallel process event running.
can't reproduce the problem, mind uploading a demo with all your script (and your parallel event) included?
http://www.mediafire.com/?ooreos0od5515v5
when a message window is showing && player is walking && parallel process is running, message text position is strange.
After the strange message is dispose, player is freeze and unable to talk to other event.
I'll confirm it is a bug not related to any of the other scripts. I dont have a solution at this time, but I am looking a bit deeper as class Game_Player isnt causing it, but it is hanging there becase $game_system.map_interpreter.running? is returning true, even when the parallel process has an empty list.
NOTE: BlizzABS was removed while testing the bug, so it isnt related to any other scripts.
I tried to recreate this in the SDK dependant version I worked with and the bug doesnt appear there. But it wasnt built to be Blizz compatible.
Definitely a bug, but I dont have the time to find a solution to it right now.
---
Aside from this bug, I took a peek at the initialization method for the windows. Is this face display using animated faces? Should the Bitmap be cached to speed up performance? Might even need to blt cache the whole pic, then display a small part of a big image. Refresh is also called quite a bit when redrawing the letter by letter text, so just a performance suggestion...
*fixed*
probably I didn't fix it in elegant way since I didn't have much free time right now
Just out of curiousity, what did you do?
When I get some free time, I might come back to this script again...
Quote#--------------------------------------------------------------------------
# * Terminate Message
#--------------------------------------------------------------------------
def terminate_message
return if $game_temp.input_in_window
self.active = false
self.pause = false
self.index = -1
self.contents.clear
@fwindowskin.bitmap.clear if !@fwindowskin.nil? && !@fwindowskin.disposed?
# Clear showing flag
@contents_showing = false
# Clear variables related to text, choices, and number input
@tail.visible = false
# note that these variables are now indexed arrays
$game_temp.message_text = [] if !$game_temp.message_text.is_a?(Array)
$game_temp.message_proc = [] if !$game_temp.message_proc.is_a?(Array)
$game_temp.message_text[@msgindex] = nil
# Call message callback
if $game_temp.message_proc[@msgindex] != nil
# make sure no message boxes are displaying
if $game_temp.message_text.compact.empty?
$game_temp.message_proc[@msgindex].call
message_interpreter.class.send(:attr_accessor,:message_waiting)
$game_temp.message_window_showing = false
message_interpreter.message_waiting = false
end
$game_temp.message_proc[@msgindex] = nil
end
@update_text = true
$game_temp.choice_start = 99
$game_temp.choice_max = 0
$game_temp.choice_cancel_type = 0
$game_temp.choice_proc = nil
$game_temp.num_input_start = 99
$game_temp.num_input_variable_id = 0
$game_temp.num_input_digits_max = 0
# Open gold window
if @gold_window != nil
@gold_window.dispose
@gold_window = nil
end
end
Quote
#--------------------------------------------------------------------------
# * Message_Eval
#--------------------------------------------------------------------------
def message_eval(v)
message_interpreter.message_eval(v)
end
#--------------------------------------------------------------------------
# * Message_Interpreter
#--------------------------------------------------------------------------
def message_interpreter
if $scene.is_a?(Scene_Map)
$game_system.map_interpreter
elsif $scene.is_a?(Scene_Battle)
$game_system.battle_interpreter
else
Interpreter.new
end
end
Quote#--------------------------------------------------------------------------
# * Reposition Window
#--------------------------------------------------------------------------
def reposition
if @float_id.is_a?(Array)
char_height = 1
char_width = 1
char_x = @float_id[0]
char_y = @float_id[1]
elsif $game_temp.in_battle
if 'abcd'.include?(@float_id) # must be between a and d
@float_id = @float_id[0] - 97 # a = 0, b = 1, c = 2, d = 3
return if $scene.spriteset.actor_sprites[@float_id] == nil
sprite = $scene.spriteset.actor_sprites[@float_id]
else
@float_id -= 1 # account for, e.g., player entering 1 for index 0
return if $scene.spriteset.enemy_sprites[@float_id] == nil
sprite = $scene.spriteset.enemy_sprites[@float_id]
end
char_height = sprite.height
char_width = sprite.width
char_x = sprite.x
char_y = sprite.y - char_height/2
else # not in battle...
char = (@float_id == 0 ? $game_player : $game_map.events[@float_id])
if char == nil
# no such character
@float_id = nil
return
end
# close message (and stop event processing) if speaker is off-screen
if speaker_offscreen(char) ||
($game_system.message.allow_offscreen && !$game_temp.in_battle &&
(self.height - self.y > 480 || self.height + self.y < 0 ||
self.width - self.x > 640 || self.width + self.x < 0)) ||
($game_system.message.move_during && @dist_exit &&
@float_id > 0 && !char.within_range?(@dist_max, @float_id) &&
@float_id == @event_id )
terminate_message
if !@fwindowskin.nil? && !@fwindowskin.disposed?
@fwindowskin.visible = false
@fwindowskin.bitmap.dispose if !@fwindowskin.bitmap.disposed?
@fwindowskin.dispose
@fwindowskin = nil
end
char.foot_forward_off if @auto_ff_reset && !char.no_ff
@auto_ff_reset = false
return
end
if char.character_name =~ /[8]/i
char_height = RPG::Cache.character(char.character_name,0).height / 8
else
char_height = RPG::Cache.character(char.character_name,0).height / 4
end
if char.character_name =~ /[s]/i
char_width = RPG::Cache.character(char.character_name,0).width / 8
else
char_width = RPG::Cache.character(char.character_name,0).width / 4
end
# record coords of character's center
char_x = record_screen_xy(char)[0]
char_y = record_screen_xy(char)[1] - char_height/2
end
params = [char_height, char_width, char_x, char_y]
# position window and message tail
vars = new_position(params)
x,y = vars[0], vars[1]
# check if any window locations need to be "flipped"
offsc = (!$game_system.message.allow_offscreen || $game_temp.in_battle)
flip = need_flip?(@float_id, @location, x, y, params)
loc4 = ((x < 0 && !@face) || (x < 90 && @face)) && offsc
if @location == 4 && (loc4 || flip)
if @auto_orient == 1 and need_flip?(@float_id, @location, x, y)
@location = put_behind(@float_id, 6)
else # switch to right
@location = 6
end
vars = new_position(params)
x = vars[0]
if (x + self.width) > 640 && offsc
# right is no good either...
if y >= 0
# switch to top
@location = 8
vars = new_position(params)
else
# switch to bottom
@location = 2
vars = new_position(params)
end
end
elsif @location == 6 && (((x + self.width) > 640 && offsc) || flip)
if @auto_orient == 1 and need_flip?(@float_id, @location, x, y)
@location = put_behind(@float_id, 4)
else # switch to left
@location = 4
end
vars = new_position(params)
x = vars[0]
if x < 0 && offsc
# left is no good either...
if y >= 0
# switch to top
@location = 8
vars = new_position(params)
else
# switch to bottom
@location = 2
vars = new_position(params)
end
end
elsif @location == 8 && ((y < 0 && offsc) || flip)
if @auto_orient == 1 and need_flip?(@float_id, @location, x, y)
@location = put_behind(@float_id, 2)
else # switch to bottom
@location = 2
end
vars = new_position(params)
y = vars[1]
if (y + self.height) > 480 && offsc
# bottom is no good either...
# note: this will probably never occur given only 3 lines of text
x = vars[0]
if x >= 0
# switch to left
@location = 4
vars = new_position(params)
else
# switch to right
@location = 6
vars = new_position(params)
end
end
elsif @location == 2 && (((y + self.height) > 480 && offsc) || flip)
if @auto_orient == 1 and need_flip?(@float_id, @location, x, y)
@location = put_behind(@float_id, 8)
else # switch to top
@location = 8
end
vars = new_position(params)
y = vars[1]
if y < 0 && offsc
# top is no good either...
# note: this will probably never occur given only 3 lines of text
x = vars[0]
if x >= 0
# switch to left
@location = 4
vars = new_position(params)
else
# switch to right
@location = 6
vars = new_position(params)
end
end
end
x = vars[0]
y = vars[1]
tail_x = vars[2]
tail_y = vars[3]
# adjust windows if near edge of screen
if offsc
if x < 0 && !@face
x = 0
elsif x < 90 && @face
x = 90
elsif (x + self.width) > 640
x = 640 - self.width
end
if y < 0
y = [y, 0].max
elsif (y + self.height) > 480
y = 480 - self.height
elsif $game_temp.in_battle && @location == 2 && (y > (320 - self.height))
# when in battle, prevent enemy messages from overlapping battle status
# (note that it could still happen from actor messages, though)
y = 320 - self.height
tail_y = y
end
end
# finalize positions
self.x = x
self.y = y
@tail.x = tail_x
@tail.y = tail_y
v = case @location
when 2, 6 then -15
when 4, 8 then -17
end
if self.visible #!$game_temp.message_text.compact.empty?
draw_window
@fwindowskin.dispose if !@fwindowskin.nil? && !@fwindowskin.disposed?
@fwindowskin = Sprite.new
@fwindowskin.z = self.z - 10
@fwindowskin.bitmap = Bitmap.new(640,480)
@fwindowskin.bitmap.blt(x,y,@frame.bitmap,@frame.bitmap.rect)
@fwindowskin.bitmap.blt(tail_x+v,tail_y+v,@tail.bitmap,
@tail.bitmap.rect) if show_message_tail?
@fwindowskin.opacity = $game_system.message.opacity
if @face && self.height > 64
a = 80
while a >= -10
@fwindowskin.bitmap.blt(@face.x+a,y,@frame.bitmap,
Rect.new(0,0,@face.bitmap.width-45,@frame.bitmap.height))
a = (a == 5) ? 15 : a - 25
end
end
self.opacity = @tail.opacity = 0
@frame.dispose
end
bit = @tail.bitmap
end
Quote
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
class Interpreter
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias drg128_setup setup unless method_defined?(:drg128_setup)
alias drg128_upd update unless method_defined?(:drg128_upd)
#--------------------------------------------------------------------------
# * Setup
#--------------------------------------------------------------------------
def setup(*args)
drg128_setup(*args)
# index of window for the message
@msgindex = 0
$game_temp.message_text, $game_temp.message_proc = [],[]
# whether multiple messages are displaying
@multi_message = false
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update(*args)
@message_waiting = $game_temp.message_window_showing
drg128_upd(*args)
end
...
end
Im bad. I never update. I R teh Lay-zee.
Then I updated RMXP to 1.04 last night. I just sat on 1.02 for years before even starting to use it. Now it seems as if I have created a new issue for myself in regards to MMW features I added. When I am using the "Foot Forward" options, XP1.04 now shows Box Characters any place that \F+ and \F- exist in the text. I am sure this will affect other people. But a quick edit of the ini and reverting to RGSS102E.dll over 104 makes those boxes go away, but the version is also old.
Any fast solutions to resolve this minor bug?
Edit: NVM, got it. Add c = '' for each foot forward call in def update_text
Alright, I ported the animation feature from my Window Message Mod script to MMW, and here is the script. I also fixed a few inefficient pieces of code that was using for loops instead of each loops.
http://pastebin.com/raw.php?i=cuGgw297 (http://pastebin.com/raw.php?i=cuGgw297)
*update the script and demo*
- fixed "foot forward" glitch
- fixed "exit by player distance" glitch
- added ThallionDarkshine's Animated Letters
- added an option for switching windowskins
I can't live without this script. It's too awesome.
I have found a little weird glitch though. Whenever I finish talking to a character their event replays over and over unless I either hold the move button to instantly move away after the event after they finish talking, or add a wait command after the event. 1 frame is enough to stop the loop. Any fast fixes to this?
Damn, i'm posting a lot today!
Just tried testing but not sure if i'll put this in my game, and seems like im having the same problem with MarkHest.
I can't move because the message is repeating until i hold a move button.
Is it a bug??
For now, I don't have enough free time to fix the script, sorry
You can use wait 1 frame in the end of event to avoid this problem
Another thing I want to mention is that the @sound_frequency option doesn't work no matter what you put it to. The sound is always the same speed.
I have a question is method and properties named cinemamask, create_cinema, update_cinema important or i can comment it without worrying that it will destroy some function of MMW Ex. My problem was that it create a black bar on non standard resolution
you can just change all 640 & 480 into your resolution
@cinemasks = [ create_cinema(640,48,0,-48), create_cinema(640,72,0,480),
create_cinema(640,480,0,0,199,0)]
@cinemasks[1].y = 480 - 9 * (24 - @cinema_fadecount) / 3[/codde]
Found a new bug with the script. Parallel Events refuses to run while a text box is active. This is a problem for me :p
Things that I want to request fixes on:
- The 'wait 1 frame' problem I mentioned before.
- The 'sound frequency' problem I mentioned before.
- The 'Parallel Event' problem explained here.
Think you can do it when you have time?
If its a bug in this version of the script, there are "workarounds". Before your message displays where a parallel event is expected to run, try running a couple Script calls:
$game_map.event[41].refresh
$game_map.events[41].start
Calling "start" can force an event to start executing, even if the event is set to "Action Button".
Still worth while to find out why a Parallel wont run for you. Is the parallel event on the screen viewable by the player? Not just on the same map, but visible to the player (if it had a graphic)? Bug may also be coming from some form of Framerate Optimizer...
The Parallel process just won't run at all while a text box is active. I tried it on both my project with lots of other scripts and a new project with only this script in it. Same problem.
It's like the text boxes pauses the game completely from running anything else.
e.g:
-Let's say I talk to a guy and activate a switch for a parallel process next to him.
-This parallel process should now start to jump infinitely because of the event command telling him to jump.
-A text box is active from talking to the first event and the event next to him won't jump at all.
-the text box ends and the parallel event starts jumping but stops once another text box is active. Then starts again once the text box ends.
I even tried common events.
when I testing this script, I'm surprised there are glitch that hard to fix.
maybe I'll overhaul this script when I have time.
but I'm sorry, for now, I lack the time & motivation to do that.
---
update to 1.6b
* fixed the repeating bug
updated the script and demo again to 1.6c
* fix the bug when animated letters didn't displayed properly into message log
Thanks for keep updating the script.
Will there be a fix in the future for the letter by letter mode not working with the auto shrink feature?
Thanks in advance.
maybe not.... as I said earlier, I lack time.
unless there are fatal bug, I probably wont update it.
sorry about that.