Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Requesting Multiple Animated Faces for XP

Hello, Today I'm requesting an edit of either universal message system(UMS) or Hermes - Hermes Extends RMXP's MEssage System - Version 0.2.

I would like to have multiple animated faces on the screen at the same time and they should all be controllable via message code or call script command. for example one should be talking while the text is appearing and the other can blink until i call for that animated picture to move its mouth.

here is an example video:
http://www.youtube.com/watch?v=e0WvkMqPvdQ

Well it doesn't have to be an EDIT of the message system. It can an add-on to a message system.

also if you can could you make them moveable via command or message code as well?

Thank you.

(Below is the Hermes - Hermes Extends RMXP's MEssage System - Version 0.2 scripts)

■ Hermes - Hermes Extends RMXP's MEssage System - Version 0.2
#-----------------------------------------------------------------------------
# For more infos and latest updates, visit:
# http://www.uglyhorst.de/rPG%20Maker/rGSS-Scripts.txt
#
# Hermes is originally based on AMS which is based on XRXS which is based on
# the default RMXP message system. However, there isn't much left from any of
# those scripts. Almost everything has been revised or rewritten (or both).
#
# Special Thanks:
# - KD: You just rock. And, without you, I would never have finished this.
# - The users on Creation Asylum who support me with bug reports and
# great ideas for future versions.
# - Also the users from RPG Architects, which have supported me, too.
# - Knumonmaster, who inspired me to add some great, new features
# - Satoru Takabayashi for his great Ruby/Romkan library
#=============================================================================
=begin
Each of those "commands" can be used in your message events. None of them makes
any permanent changes, only temporary ones. If you want to know how to change
aspects of Hermes permanently, see below (search for "Permanent settings:").


Append a second message to your message:

\*

This appends the text (including commands) of the following message to the
current message. E.g.:

Show Message: These two lines will be\*

Show Message: displayed in one message box.

When more than four lines are to be shown in one message box (except for \p
messages), the text is scrolled upwards automatically.



Add a second message box:

\+

This will show a second (, third, fourth, ..., nth) message box on screen. This
could be used for 2 characters talking simultaneously, or just to make the
reader freak out because you have two message boxes on top of each other.

At the moment, only simultaneous starts and ends of the messages work.



Change the text color temporarily:

\tc[ColorID] or \tcolor[ColorID]

ColorID is either an RPGXP color ID (as defined in Window_Base starting at line
39), where 0 is white, or an HTML style hexadecimal color code, where #FFFFFF is
white and #000000 is black.

http://html-color-codes.com/ provides a handy collection of some of such codes.

If no argument is specified, the color will be reset to default stored in $msg.



Align the text in the window:

\ta[Horz,Vert] or \talign[Horz,Vert]

Enter a two-character code for the alignment in there. The first character is
for horizontal alignment, and can be l, c or r (left, center, right). The second
character is for vertical alignment, and can be t, m or b (top, middle, bottom).
E.g. \ta[c,m] will center the text in the image, horizontally and vertically.

Instead of l, c, r, t, m and b you can also write the words out, or you can
leave out the comma. For example, \ta[l,b], \talign[leftb] and \ta[l,bottom]
are the same.

If the argument is left out, it will be set to the default stored in $msg.



Bold and italic:

\b[on|off] / \bold[on|off], \i[on|off] / \italic[on|off]

Will turn bold or italic on or off. If no argument is specified, bold or italic
will be toggled. Example:

\b[on]This text is bold,\b \i[on]this text is italic, \bthis text is both
and\b\i[off] this text isn't bold nor italic.

If bold / italic are set by default, use \b or \i to unset them.



Show the gold window:

\G or \gold

This will show a gold window in a free corner of the screen, with the amount of
gold the player has in possesion.



Show an actor's name:

\a[ActorID] or \actor[ActorID]

Use the ID of the actor whose name you want to be displayed in the message box.

If the argument is left out, the party leader's name will be shown.



Show an event's name:

\e[EventID] or \event[EventID]

Shows the name of the event on the current map with the specified event id.

If no argument is specified or "this" is used, the current event's name will be
shown.




Get hero ID by position in party:

\Cid[PositionInParty]

Use this command to find out which ID the hero in your party has. E.g., \Cid[0]
gets the hero ID for the first hero in your party (i.e., the leader). Very
powerful when combined with, e.g. \a or \f commands!

If the argument is left out, it will get the party leader's ID.



Show an item's cost:

\cost[ItemID]

Use the item ID of the item which's price you want to be displayed in the
message box.

The argument must be specified.



Show the current map name:

\m or \Map

This will show the name of the map you are currently on.



Show a face graphic in your message box:

\f[FaceName(,ID)] or \face[FaceName(,ID)]

FaceName must be either the filename of a graphic file found in the directory
Graphics\Images of your RPG Maker XP project, or the ID of the Actor which's
face is to be shown. When specifying an Actor ID, it will look for the file
Graphics\Images\face_<id>, make sure your Actors' faces are saved there.
The file must either be a single face graphic of any size, or follow these
specifications:

- At least four faces of the same height* and width, lined up horizontally.
- The first line should represent a normal, a happy, a sad and an angry face.
- The faceset can have any number of rows, every face graphic must have equal
height and width.

*The height of the face graphics must be equally-sized (exception: single face
graphics), this height must be specified in the beginning on the configuration
file (Hermes::FACE_HEIGHT).
If FaceName is a set of more than one face graphic, you need to specify the ID
of the face you want to use. Either a number (beginning with 1) from the top
left to right bottom, or one of normal (=1), happy (=2), sad (=3) or angry (=4).

If the argument is left out, the normal face (id=1) of the party leader will be
shown.



Show the class name of a character:

\Cl[ActorID] or \class[ActorID]

Use the actor's ID whose class name you want to display in the message box.

If the argument isn't specified, the party leader's class is shown.



Show icons inline:

\icon[FileName]

Will show an icon in the text (24x24 pixels)

The argument must be specified.



Show variables, items, weapons, armor, skill names, and enemies:

\v[x,ID] or \var[x,ID]

You must replace the x by the first lettter of what you want to modify:
e = enemy, i = item, a = armor, w = weapon, s = skill
If x is left out, the variable with this ID is shown.
The comma can be left out (e.g., \v[i13]=\var[i,13]=Name of 13th item)

This command also shows the icon of your item / armor / weapon / skill.

The argument must be specified.



Show a name or other info in a name box:

\n[Text/HeroID] or \Name[Text/HeroID]

Use this to show a name box above the message box that will contain the text
you specified. When you enter a number instead of text, the name of the Actor
with that ID will be shown. Example:

\Name[\v[12]] --> Will show the value of variable 12 in the name box.
\n[derula] --> Will show "derula" in the name box.
\N[1] --> Will show the name of actor 1 in the name box.
\nAmE[\Cid[2]] --> Will show the name of your third party member.

If the argument is left out, the party leader's name will be shown in the box.



Show a name and a face graphic with one command:

\d[Name/HeroID(,FaceID)] or \data[Name/HeroID(,FaceID)]

(Please don't ask why I called it data...)

This will show a name and a face graphic at once. The graphic must exist. Either
the name or the Hero ID of the hero can be specified. Using the Hero ID will
search for a file "face_<ID>" in the Graphics\Images folder, where <ID> will
be replaced by the ID you've specified. When you use a Hero's name instead,
Hermes will use the picture with the same name. Examples:

\d[7] --> Will show the name of the 7th hero in the database and select the file
Graphics\Images\face_7 to use it as a face graphic.
\data[\Cid[1],sad] --> Will show the second party member's name and sad face.
\d[derula,5] --> Will show the name "derula" and the fifth face graphic found in
the faceset at Graphics\Facesets\derula.

If the argument is left out, the party leader's name and normal face are shown.



Modify the text opacity:

\to[Opacity] or \topacity[Opacity]

Use this to modify the opacity of the text in the message box. Enter a number
between 0 and 255, where 255 is fully opaque and 0 is fully transparent.

If the argument is left out, opacity will be reset to default value in $msg.



Modify the text speed:

\ts[Speed] or \tspeed[Speed]

Use this to modify the speed of the text in the message box. Enter a number
between 0 and 20, where 20 is the slowest. A value of 0 will result in the text
being shown immediately.

If the argument is left out, speed will be reset to the value stored in $msg.



Modify the text size:

\th[Size] or \theight[Size]

Use this to modify the size of the text in the message box. Enter a number
between 6 and 32, where 32 is the biggest.

If the argument is left out, text size will be reset to default stored in $msg.



Show the message box above player or events:

\p[Option] or \pop[Option]

Use this to set the window to appear whether above the player or any event
present in your map. Use the following options:

\p[Event ID]
\P[0] or \p[hero]
\p[-1] or \p[screen]
\p or \p[this]

Using "\p[Event ID]" will put the window on top of the specified event ID.
Using "\p[0]" or "\p[hero]" will put the window on top of the player.
Using "\p[-1]" or \p[screen]" will make a transparent full screen window.
Using only "\p" or \p[this] will cause the window to popup over the currently
playing event. Note that in you call "\p" without arguments from an autostart or
parallel process event, the window will pop up over the hero. BUT this leads to
a problem when showing messages during parallel process events: by starting to
talk to a character while a parallel process message is still to be shown, this
message will pop up over that character (RMXP bug).



Add wait in message and other commands like that:

\| --> Wait for 1 second
\. --> Wait for .25 second
\~ or \^ --> Auto close window at last letter
\! --> Wait for key input from the player
\\ --> Will show the backslash \ character



Allow / Disallow Text Skip button:

\%

Use this command to toggle prevention of text skipping. That means, the player
will no longer be able to let the whole message appear at once by pushing enter.
He will, however, be able to close the message boxes by himself. To prevent
that, use a combination of \. , \| and \~ commands.
It can be toggle multiple times while inside a message, but won't be saved
across messages.



Change the font in a message box:

\tf[FontName] or \tfont[FontName]

FontName must be a .TTF found in Windows\Fonts and is case sensitive. The
changes made to the font will only apply for the text after this command in the
same Window.

If the argument is left out, the default font will be used (as in $msg).



Play an SE as the letter are shown:

\s[FileName] or \sound[FileName]

File must be in directory Audio\SE
The sound will only be heard for the letters that follow this command.

If the argument is left out, the sound will be disabled.



Modify the text color of the name box:

\z[ColorID]

Use this as you use the normal color command \c[ColorID] - But this time it will
set the color used in the name box. In order for it to work, this must be called
after the \n command. Only applies to the current message.

If the argument is left out, the color will be reset to default saved in $msg.



Permanent settings:

To change settings permanently, use the global variable $msg. You must call
scripts that change the options of $msg to change any setting permanently.
Instance methods of the $msg object:
- $msg.font: The font used in the message window.
- $msg.name_font: The font used in the name window.
The two above should not be changed directly, the reason for this follows soon.
- $msg.font_name, $msg.font_size, ..., $msg.font_shadow:
Use these if you want to read or write single aspects of the message font.
- $msg.name_font_name, $msg.name_font_size, ..., $msg.name_font_shadow:
Use these if you want to read or write single aspects of the name box font.
- $msg.skin, $msg.name_skin: Windowskins of message and name box, respectively
- $msg.opacity, $msg.name_opacity: Opacities of the two boxes
- $msg.align, $msg.valign: Global setting for text alignments. Possible values
are "l", "c", "r" for $msg.align, and "t", "m", "b" for $msg.valign.
- $msg.prevent_skipping: global setting whether or not to prevent text skipping
- $msg.speed: global setting for text speed.
- $msg.sound: global setting for typing sound.
The defaults of all of these settings can be restored by setting the
corresponding value to nil. For example:
$msg.name_font_name = nil
print $msg.name_font_name # => Arial
This _doesn't work_ if you set $msg.name_font.name instead of
$msg.name_font_name:
$msg.font.size = nil
print $msg.font.size # => nil
$msg.font_size = nil
print $msg.font_size # => 22
So be careful! and better don't use $msg.font or $msg.name_font at all!



Customize other aspects of the Hermes:

In the config section of the Hermes, you can customize stuff.

That script helps you configure the defaults you will use in Hermes. This
includes, but is not limited to, the permanent settings described above.
Additionally, you can set global font settings which will affect the font in
every window. Of course you can also just leave it as it is, if you want to use
the default settings.

Additionally to the font settings, you can set the geometry for both the message
and the name box. These settings are a bit documented, if you don't understand
the documentation, just try it out. You can still repaste the original script if
you messed the settings up.

In the middle of the config section (maybe not the physical middle, but the
logical one), there's a hash called @@face_aliases. In this hash, you can
configure which special face name will be translated to which face number in the
\f command. You could, e.g., add something like this to the list:
"sleepy" => 5
end then, \f commands in the following style will be legit: \f[hero,sleepy] and
would simply be the same as \f[hero,5]. Note that commas need to be typed
between the replacement definitions.

Below that, there is a hash called @@replacements. This one is quite similar,
it replaces all commands of the form $x, where x is commonly a letter, with a
single character that cannot be typed easily normally. This setting defaults to
the same replacements as can be found in RPG2k (with a few exceptions, which are
explained there).

Beyond those hashes, the tags are configured. If you are interested in adding a
tag to Hermes, please have a look at the Hermes/Romkan sample extension. It is
well documented, and shouls help you out in many cases.

Have fun, and report any bug in the topic on Creation Asylum, or (if you speak
German) on RPG Architects. But take note that some bug may occur due to another
script, and I may not be able to help if it's the case (although I am willing to
try my best).
=end

#=============================================================================
# ■ Hermes - Hermes Extends RMXP's MEssage System - Version 0.2
#-----------------------------------------------------------------------------
# Settings class and message window stub
# The Hermes_Global_Settings class stores all Hermes preferences.
# It will be present at all times in the global object $msg.
# This object will be saved to and loaded from savegames.
# Below that, there are some basic methods for the Window_Message class.
#=============================================================================

#=============================================================================
# ▼ CLASS Hermes_Global_Settings Begins
#=============================================================================
class Hermes_Global_Settings
# Make the changeable options... changeable ;)
attr_reader :font, :name_font

def initialize
@font = Font.new
@name_font = Font.new
["", "name_"].each do |p|
["name","size","color","bold","italic","outline","shadow"].each do |n|
send("#{p}font_#{n}=".to_sym, nil)
end
["skin", "opacity"].each do |n|
send("#{p}#{n}=".to_sym, nil)
end
end
[:sound=, :align=, :valign=, :prevent_skipping=, :speed=].each do |p|
send p, nil
end
end

#--------------------------------------------------------------------------

["", "name_"].each do |p|
# Add methods [name_]font_name[=], ..., [name_]font_shadow[=]
["name", "size", "color", "bold", "italic", "outline", "shadow"].each do |n|
define_method("#{p}font_#{n}") do
return instance_variable_get("@#{p}font").send("#{n}")
end
define_method("#{p}font_#{n}=") do |arg|
# Gets the default if requested
arg = get_value(arg ? arg : (Hermes.const_get((p == "") ? "Message" :
"Name")::Text.const_get(n.upcase)), Font.send("default_#{n}"))
if n == "outline" or n == "shadow"
if arg.class == Array
arg = TextEffect.new(*arg)
elsif arg.class == TextEffect
arg = arg.dup
else
raise TypeError, "Argument specified must be a TextEffect object, "+
"an Array, \"default\", or left out (nil)."
end
end
return instance_variable_get("@#{p}font").send("#{n}=", arg)
end
end
# Add methods [name_]skin[=], [name_]opacity[=]
attr_reader("#{p}skin")
define_method("#{p}skin=") do |arg|
return instance_variable_set "@#{p}skin", get_value(arg ? arg :
(Hermes.const_get((p == "") ? "Message" : "Name")::Box::SKIN),
$game_system.windowskin_name)
end
# Add methods [name_]opacity[=]
attr_reader("#{p}opacity")
define_method("#{p}opacity=") do |arg|
return instance_variable_set "@#{p}opacity", arg ? arg :
(Hermes.const_get((p == "") ? "Message" : "Name")::Box::OPACITY)
end
end

# Add methods [v]align[=], prevent_skipping[=], speed[=]
["align", "valign", "prevent_skipping", "speed"].each do |p|
attr_reader(p)
define_method("#{p}=") do |arg|
return instance_variable_set "@#{p}",
(arg or Hermes::Message::Text.const_get(p.upcase))
end
end

# Add methods sound[=]
attr_reader :sound
def sound=(arg)
unless arg
arg = Hermes::Message::Text::SOUND
end
if arg == "off"
@sound = nil
else
@sound = arg
end
end

#--------------------------------------------------------------------------

def get_value(constant, default)
# Gets the default if requested
if constant != "default"
return constant
else
return default
end
end

protected :get_value
end
#=============================================================================
# ▲ CLASS Hermes_Global_Settings Ends
#=============================================================================

#=============================================================================
# ▼ CLASS Scene_Title Additional Code Begins
#=============================================================================
class Scene_Title
alias old_command_new_game command_new_game

def command_new_game
$msg = Hermes_Global_Settings.new
old_command_new_game
end
end
#=============================================================================
# ▲ CLASS Scene_Title Additional Code Ends
#=============================================================================

#=============================================================================
# ▼ CLASS Scene_Save Additional Code Begins
#=============================================================================
class Scene_Save < Scene_File
alias old_write_save_data write_save_data

def write_save_data(file)
old_write_save_data(file)
Marshal.dump($msg, file)
end
end
#=============================================================================
# ▲ CLASS Scene_Save Additional Code Ends
#=============================================================================

#=============================================================================
# ▼ CLASS Scene_Load Additional Code Begins
#=============================================================================
class Scene_Load < Scene_File
alias old_read_save_data read_save_data

def read_save_data(file)
old_read_save_data(file)
$msg = Marshal.load(file)
end
end
#=============================================================================
# ▲ CLASS Scene_Load Additional Code Ends
#=============================================================================

Tag = Struct.new("Tag", :params, :live, :method)
Command = Struct.new("Command", :method, :params)
Char = Struct.new("Char", :c, :commands)

#=============================================================================
# ▼ CLASS Window_Message Begins
#=============================================================================
class Window_Message

CLOSED = 0
TYPING = 2
PAUSE = 3
DONE = 4
CLOSING = 5
WIDTH_TRIAL = -1

def initialize
super(0, 0, 10, 10)
self.contents = Bitmap.new(1, 1)
self.visible = false
self.z = 9998
@cursor_width = 0
self.active = false
self.index = -1
@status = CLOSED
@combined_text = ""
@message_texts = []
end

@@tags = {}

def self.tag(tag, params = nil, &block)
method = "tag_#{@@tags.length + 1}".to_sym
define_method(method, &block)
return @@tags[tag] = Tag.new(params, false, method)
end

#--------------------------------------------------------------------------

def self.live_tag(tag, params = nil, &block)
tag(tag, params, &block).live = true
end

#--------------------------------------------------------------------------

# Function to add a command that will be executed later
def add_command(regex, params, ahead = 0)
# Don't add tags if not in actual parse mode
if @line and @pos
tag = @@tags[regex]
pos = @pos + ahead
# Parsed later
@commands[pos] = [] unless @commands[pos]
@commands[pos] << Command.new(tag.method, params)
end
end

#--------------------------------------------------------------------------

def terminate_message
self.active = false
self.pause = false
self.index = -1
self.contents.dispose
self.contents = Bitmap.new(1, 1)
# Call message callback
if $game_temp.message_proc != nil
$game_temp.message_proc.call
end
# Clear variables related to text, choices, and number input
$game_temp.message_text = nil
$game_temp.message_proc = nil
$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
# Terminate submessages
if @messages
@messages.each do |message|
message.terminate_message
end
end
# Set status to closing
@status = CLOSING
end

#--------------------------------------------------------------------------

def align_indent
text_width = @line_widths[@cur_line] ? @line_widths[@cur_line] : 0
# Calculate size of space for drawing text
textarea_width =
if not @choice_start or @cur_line < @choice_start
self.contents.width - @indent
else
# Writing the choices
@cursor_width
end
indent =
case @align
when "c"
(textarea_width - text_width) / 2
when "r"
textarea_width - text_width - 4
else
4
end
indent += @choice_indent if @choice_start and @cur_line >= @choice_start
return indent
end

#--------------------------------------------------------------------------

# Determine wether to show the text at once
def skip_text
# - We're NOT in pause mode and:
# - Write speed is at zero or
# - Allowed to skip and pressing enter or
# - In debug mode and control held and enter pressed
skip_key_trigger = Input.trigger?(Hermes::SKIP_TEXT_CODE)
@status != PAUSE and (
(@write_speed == 0) or
(not @prevent_skipping and skip_key_trigger) or
($DEBUG and Input.press?(Input::CTRL) and skip_key_trigger)
)
end

#--------------------------------------------------------------------------

def reset_size
# Set width and height of window
lines = @now_text.split("\n", -1)
# Get number of lines
line_count = lines.size
line_count += 1 if @input_number_window
if @popchar >= 0
# Get maximal line width
w = @line_widths.max
if @input_number_window and @input_number_window.width > w
# Adjust size when input number used
w = @input_number_window.width
end
# Minimum width
if w == 0
w = 33
else
w += 40 + @indent
end
# Calculate window height
h = line_count * Hermes::Message::Box::LINE_HEIGHT
# Minimum height
if h == 0
h = 33
else
h += 32
end
else
if @popchar == -1
w, h = 640, 480
else
w = Hermes::Message::Box::WIDTH
h = 4 * Hermes::Message::Box::LINE_HEIGHT + 32
end
end
self.width, self.height = w, h

# Apply vertical align if normal message with less than 4 lines or OSD
if (@popchar == -2 and line_count < 4) or @popchar == -1
h -= 32 + Hermes::Message::Box::LINE_HEIGHT * line_count
@align_offset =
case @valign
when "m"
h/2
when "b"
h
else
0
end
end

# Calculate choice indent
if @choice_start
textarea_width = w - 32 - @indent
@choice_indent =
case @align
when "c"
(textarea_width - @cursor_width) / 2
when "r"
textarea_width - @cursor_width
else
0
end
end

# Set position of the face sprite
if @face_sprite
# If window is tall enough
if self.height - 32 >= @face_sprite.face_height
@face_sprite.align = Sprite_Face::CENTER
end
end
end

#--------------------------------------------------------------------------

def reset_position
# Reset width, height and position of the message window
if @popchar >= 0
# This updates the message position if popchar is moving
# Get an event or player
if @character
# Calculate new position
x = [[@character.screen_x - Hermes::Message::Box::EVENT_X- self.width/2,
4].max, 636 - self.width].min
y = [[@character.screen_y - Hermes::Message::Box::EVENT_Y - self.height,
4].max, 476 - self.height].min
# Adjust position if we have a name window
if @name_window and not Hermes::Name::Box::SWAP
name_offset = @name_window.height - Hermes::Name::Box::OVERLAP
if Hermes::Name::Box::POS <= 1
y = name_offset + 4 if y < name_offset + 4
elsif y > 476 - self.height - name_offset
y = 476 - self.height - name_offset
end
name_offset = @name_window.width+Hermes::Name::Box::OFFSET-self.width
if (1..2) === Hermes::Name::Box::POS
x = name_offset + 4 if x < name_offset + 4
elsif x > 636 - self.width - name_offset
x = 636 - self.width - name_offset
end
end
end
elsif @popchar == -1
# Display across the whole screen
x = y = 0
else
# Normal display
if $game_temp.in_battle
y = 16
else
case $game_system.message_position
when 0
y = Hermes::Message::Box::MARGIN
when 1
y = 240 - (self.height / 2)
when 2
y = 480 - Hermes::Message::Box::MARGIN - self.height
end
end
x = 320 - (self.width / 2)
end
# Set new position
self.x, self.y = x, y
rect = Rect.new(x, y, self.width, self.height)
# Update Name Window position
if @name_window
pos = @name_window.reset_position(rect)
end
# Update Face Sprite position
if @face_sprite
condpos = @face_sprite.reset_position(rect)
# Update Name Window pos
if @name_window and pos == condpos and @name_window.indent == 0
@name_window.indent = @face_sprite.face_width + 32
end
end
# Update Input Number Window position
if @input_number_window
textarea_width = self.contents.width - @indent
case @align
when "c"
x = textarea_width / 2 - @input_number_window.width / 2 + 16
when "r"
x = textarea_width - @input_number_window.width + 32
else
x = 0
end
@input_number_window.x = self.x + x
@input_number_window.y = self.y + @align_offset +
@line_widths.length * Hermes::Message::Box::LINE_HEIGHT
end
# Update Gold Window position
if @gold_window
if $game_temp.in_battle or self.x + (self.width / 2) <= 320
@gold_window.x = 560 - @gold_window.width
else
@gold_window.x = 80
end
if $game_temp.in_battle
@gold_window.y = 192
else
@gold_window.y = (self.y + (self.height / 2) <= 240) ? 384 : 32
end
end
end

#--------------------------------------------------------------------------

def dispose
# Kill message
terminate_message

if @messages
@messages.each do |message|
message.dispose
end
end

# Update temp variable
$game_temp.message_window_showing = false
# Kill input number window
@input_number_window.dispose if @input_number_window
@name_window.dispose if @name_window
@face_sprite.dispose if @face_sprite
@gold_window.dispose if @gold_window
super
end

#--------------------------------------------------------------------------

def update_cursor_rect
# Update rect used for cursor display
if @index >= 0
self.cursor_rect.set(@indent + @choice_indent, (@choice_start + @index) *
Hermes::Message::Box::LINE_HEIGHT, @cursor_width,
Hermes::Message::Box::LINE_HEIGHT)
else
self.cursor_rect.empty
end
end
end
#=============================================================================
# ▲ CLASS Window_Message Ends
#=============================================================================

#=============================================================================
# ■ Hermes - Hermes Extends RMXP's MEssage System - Version 0.2
#-----------------------------------------------------------------------------
# Configuration and tag definition section
# This is where you can globally configure Hermes.
# Also, further down, all the message tags are defined.
# You can change their behavior there or add new ones.
#=============================================================================

#=============================================================================
# ▼ CLASS Hermes Begins
#=============================================================================
module Hermes
module GlobalText # Global Font / Style Configuration
NAME = ["Arial Unicode MS", "Arial"]
SIZE = Font.exist?("Arial Unicode MS") ? 24 : Font.default_size - 1
COLOR = Font.default_color # Text color (Color.new(red, green, blue))
BOLD = Font.default_bold # Text boldness (true/false)
ITALIC = Font.default_italic # Text italicness -"-
# The syntax of the following values is [strength(, color)?]
OUTLINE = [0] # Text outline
SHADOW = [2] # Text shadow
end

# Set the button to skip the dialog
# B = Escape, 0 (On The NumPad), X
# C = Enter, Space Bar and C
# A = Shift, Z
SKIP_TEXT_CODE = Input::C

# The height in pixels of the face graphics in facesets
FACE_HEIGHT = 128

module Message # Configuration for message box
module Text # Configuration for the text it contains
NAME = "default" # Default font's name (case sensitive)
SIZE = "default" # Default text size in pt
COLOR = "default" # Default text color (Color.new(r, g, b))
BOLD = "default" # Default text boldness (true/false)
ITALIC = "default" # Default text italicness -"-
ALIGN = "l" # Default horizontal text align (l,c,r)
VALIGN = "t" # Default vertical text align (t, m, b)
SOUND = "off" # Default sound to play on each letter
SPEED = 1 # Default speed for text display (0=∞)
PREVENT_SKIPPING = false # Default for text skipping prevention
# The syntax of the following values is [strength(, color)?] or "default"
OUTLINE = "default" # Default text outline
SHADOW = "default" # Default text shadow
end
module Box # Configuration for the box itself
WIDTH = 480 # Width (yeah, really?)
LINE_HEIGHT = 32 # And the height of each line
MARGIN = 16 # Spacing from border
EVENT_X = 0 # X offset when shown over an event
EVENT_Y = 48 # Y offset when shown over an event
OPACITY = 150 # Default opacity (255 = fully opaque)
SKIN = "default" # Default Windowskin
end
end

module Name # Configuration for name box
module Text # Configuration for the text it contains
NAME = "default" # Default font's name (case sensitive)
SIZE = "default" # Default text size in pt
COLOR = "default" # Default text color (Color.new(r, g, b))
BOLD = "default" # Default text boldness (true/false)
ITALIC = "default" # Default text italicness -"-
# The syntax of the following values is [strength(, color)?] or "default"
OUTLINE = "default" # Default text outline
SHADOW = "default" # Default text shadow
end
module Box # Configuration for the box itself
POS = 0 # Position: 0=top left, 1=top right,
# 3=bottom left, 2=bottom right
OVERLAP = 16 # Number of pixels overlapping the message box (y)
OFFSET = 8 # Number of pixels apart from the corner (x)
PADDING = 4 # Number of pixels left and right of the content
SWAP = true # Swap position when name box would leave screen
OPACITY = 200 # Default opacity (255 = fully opaque)
SKIN = "default" # Default Windowskin
end
end
end
#=============================================================================
# ▲ CLASS Hermes Ends
#=============================================================================

#=============================================================================
# ▼ CLASS Sprite_Face Begins
#=============================================================================
class Sprite_Face < Sprite
# Here you can specify which "special commands" the \f tag allows.
# E.g., \f[normal] wil be translated to \f[1], and so on.
@@face_aliases = {"normal" => 1, "happy" => 2, "sad" => 3, "angry" => 4}

def self.face_aliases
# Returns an all face aliases in the form normal|happy|...|special|
if @@face_aliases.empty?
return ""
else
return @@face_aliases.keys.join("|") + "|"
end
end
end
#=============================================================================
# ▲ CLASS Sprite_Face Ends
#=============================================================================

#=============================================================================
# ▼ CLASS Window_Message Begins
#=============================================================================
class Window_Message
# Character replacements ($A - $z)
@@replacements = {
"$" => "$", # Dollar sign
"a" => "☺", "b" => "☻", "c" => "☹", # Happy, black happy (1), and sad faces
"d" => "☁", "e" => "❄", # Cloud, snow flake (one / two water drops in RM2k)
"f" => "♤", "g" => "♡", "h" => "♢", "i" => "♧", # As below, but not filled
"j" => "♠", "k" => "♥", "l" => "♦", "m" => "♣", # Card game symbols
# Skull, Christian cross, Sun, Moon (2), Star/Bullet
"n" => "☠", "o" => "✟", "p" => "☀", "q" => "☾", "r" => "•",
"s" => "⇧", "t" => "⇨", "u" => "⇩", "v" => "⇦", # North, East, South, West
"w" => "⬀", "x" => "⬂", "y" => "⬃", "z" => "⬁", # NE, SE, SW and NW arrows
"A" => "☮", "B" => "☢", "C" => "✡", # Peace, radioactive, Star of David (3)
"D" => "☉", "E" => "☽", "F" => "☿", "G" => "♀", # Sun, Moon, Mercury, Venus
"H" => "♁", "I" => "♂", "J" => "♃", "K" => "♄", # Earth,Mars,Jupiter,Saturn
"L" => "♅", "M" => "♆", "N" => "♇", # Uranus, Neptune, Pluto
"O" => "♈", "P" => "♉", "Q" => "♊", # Aries, Taurus, Gemini
"R" => "♋", "S" => "♌", "T" => "♍", # Cancer, Leo, Virgo
"U" => "♎", "V" => "♏", "W" => "♐", # Libra, Scorpio, Sagittarius
"X" => "♑", "Y" => "♒", "Z" => "♓" # Capricorn, Aquarius, Pisces
# (1): This is a neutral face in RM2k.
# (2): In RM2k, this is a filled half moon. Here it's a mirrored $E.
# (3): Was Sword, Shield, Star of David in RM2k.
}

# Pop up over event
tag /p(?:eek:p)?/i, /screen|this|hero|-1|\d+/ do |m|
@popchar = case m[0]
when "screen" then -1
when "this", nil then $game_system.map_interpreter.event_id
when "hero" then 0
else m[0].to_i
end
@character = case @popchar
when 0 then $game_player
else $game_map.events[@popchar] ? $game_map.events[@popchar] : nil
end
""
end
# Show face tag
tag /f(?:ace)?/i, /([^,]+)(,(#{Sprite_Face.face_aliases}\d+))?/ do |m|
if @face_sprite
return false
else
if m[0]
if m[2]
face_id = m[3]
face_id = face_id.to_i if face_id[/\A\d+\z/]
else
face_id = 0
end
id = m[1]
else
face_id = 0
id = $game_party.actors[0].id
end
if id.kind_of? Integer or id[/\A\d+\z/]
face_file = "face_" + id.to_s
else
face_file = id
end
@face_sprite = Sprite_Face.new(face_file, self.z + 1, face_id)
@indent = 16 + @face_sprite.face_width
""
end
end
# Display name in name box
tag /n(?:ame)?/i, /(.+)/ do |m|
if @name_window
return false
else
id = (m[1] or $game_party.actors[0].id.to_s)
if id[/\A\d+\z/] and $game_actors[id.to_i]
name_text = $game_actors[id.to_i].name
else
name_text = id
end
@name_window = Window_Name.new(name_text, self.z + 1)
""
end
end
# Display name and face graphic
tag /d(?:ata)?/i, @@tags[/f(?:ace)?/i].params do |m|
return (send(@@tags[/f(?:ace)?/i].method, m)+
send(@@tags[/n(?:ame)?/i].method, m))
end
# Get Character ID from database, named after the famous airship guy
tag /cid/i, /[0-3]/ do |m|
$game_party.actors[m[0] ? m[0].to_i : 0].id
end
# Show character name
tag /a(?:ctor)?/i, /\d+/ do |m|
id = m[0] ? m[0].to_i : $game_party.actors[0].id
$game_actors[id] ? $game_actors[id].name : false
end
# Show event name
tag /e(?:vent)?/i, /this|\d+/ do |m|
if not m[0] or m[0] == "this"
id = $game_system.map_interpreter.event_id
else
id = m[0].to_i
end
return $game_map.events[id] ? $game_map.events[id].name : false
end
# Show item pricing
tag /co(?:st)?/i, /\d+/ do |m|
id = m[0] ? m[0].to_i : -1
$data_items[id] ? $data_items[id].price : false
end
# Show hero class
tag /cl(?:ass)?/i, /\d+/ do |m|
id = m[0] ? m[0].to_i : $game_party.actors[0].id
if $data_classes[$data_actors[id].class_id]
$data_classes[$data_actors[id].class_id].name
else
false
end
end
# Show current map
tag /m(?:ap)?/i do
$game_map.name ? $game_map.name : ""
end
# Show variables and item, weapon, armor, skill names
tag /v(?:ar)?/i, /([eiwas])?,?(\d+)/i do |m|
if m[0]
index = m[2].to_i
arg = m[1]
item =
case arg
when "e"
$data_enemies[index]
when "i"
$data_items[index]
when "w"
$data_weapons[index]
when "a"
$data_armors[index]
when "s"
$data_skills[index]
else
$game_variables[index]
end
else
item = nil
end
if not item
return false
elsif arg
add_command(/icon/i, [item.icon_name]) unless arg == "e"
@line_widths[@line] += 28
item.name
else
item
end
end
# Name box: Change text color
tag /z/i, /\d|\#[\dA-F]{6}/i do |m|
if @name_window
@name_window.color =
m[0] ? make_color(m[0]) : $msg.name_font.color.dup
""
else
return false
end
end
# Show gold Window
tag /g(?:eek:ld)?/i do
if not @gold_window
if @popchar != -1
@gold_window = Window_Gold.new
@gold_window.opacity = self.opacity
@gold_window.back_opacity = self.back_opacity
end
else
@gold_window.dispose
@gold_window = nil if @gold_window.disposed?
end
return ""
end
# Text align
tag /ta(?:lign)?/i,
/(l(?:eft)?|c(?:enter)?|r(?:ight)?),?(t(?:eek:p)?|m(?:iddle)?|b(?:eek:ttom)?)/ do |m|
if m[0]
@align = m[1][0,1]
@valign = m[2][0,1]
else
@align = $msg.align
@valign = $msg.valign
end
return ""
end
# Turn bold on or off
live_tag /tb(?:eek:ld)?/i, /on|off/ do |m|
self.contents.font.bold =
if m[0]
m[0] == "on"
else
not self.contents.font.bold
end
end
# Turn italic on or off
live_tag /ti(?:talic)?/i, /on|off/ do |m|
self.contents.font.italic =
if m[0]
m[0] == "on"
else
not self.contents.font.italic
end
end
# Change font type
live_tag /tf(?:eek:nt)?/i, /.+/ do |m|
self.contents.font.name = (m[0] or $msg.font.name)
end
# Change font color
live_tag /tc(?:eek:lor)?/i, /\d|\#[\dA-F]{6}/i do |m|
self.contents.font.color = m[0] ? make_color(m[0]) : $msg.font.color.dup
end
# Change text speed
live_tag /ts(?:peed)?/i, /\d+/ do |m|
# Don't change in width trial mode
unless @status == WIDTH_TRIAL
@write_speed = [[m[0] ? m[0].to_i : $msg.speed, 0].max, 20].min
end
end
# Change text opacity
live_tag /to(?:pacity)?/i, /\d{1,3}/ do |m|
self.contents.font.color.alpha = m[0] ? m[0].to_i : $msg.font.color.alpha
end
# Change text size
live_tag /th(?:eight)?/i, /\d+/ do |m|
size = m[0] ? m[0].to_i : $msg.font.size
self.contents.font.size = [[size, 6].max, 32].min
end
# Prevent text skipping on / off
live_tag /%/ do
unless @status == WIDTH_TRIAL
@prevent_skipping = (not @prevent_skipping)
end
end
# Show icon
live_tag /icon/i, /.+/ do |m|
# Disable in width trial mode
if @status == WIDTH_TRIAL
@line_widths[@line] += 28
else
if m[0]
self.contents.blt(@x , @y * Hermes::Message::Box::LINE_HEIGHT + 5 +
@align_offset, RPG::Cache.icon(m[0]),
Rect.new(0, 0, 24, 24))
Audio.se_play("Audio/SE/" + $msg.sound) if $msg.sound
end
@x += 28
end
end
# Change sound effect to be played on letter appearing
live_tag /s(?:eek:und)?/i, /.+/ do |m| @sound = m[0] end
# Wait 0.25 seconds
live_tag /\./ do @write_wait += 5 unless @status == WIDTH_TRIAL end
# Wait one second
live_tag /\|/ do @write_wait += 20 unless @status == WIDTH_TRIAL end
# Wait for keypress
live_tag /!/ do @status = PAUSE unless @status == WIDTH_TRIAL end
# Close message window
live_tag /~|\^/ do
terminate_message unless skip_text or (@status == WIDTH_TRIAL)
end
end
#=============================================================================
# ▲ CLASS Window_Message Ends
#=============================================================================

#=============================================================================
# ■ Hermes - Hermes Extends RMXP's MEssage System - Version 0.2
#-----------------------------------------------------------------------------
# Message window painting section
# This is where the messages get painted, refreshed, and so on.
#=============================================================================

#=============================================================================
# ▼ CLASS Window_Message Begins
#=============================================================================
class Window_Message
# Parses all the tags in a message
def parse_tags(string, internal = false)
# Keep completely empty lines
string.gsub!(/\n(?=\n|$)/, "\n\000")

# This translates all tags specified in @@tags and extracts line widths
result = ""
# This is needed so that tags only change the font
@status = WIDTH_TRIAL unless internal
replace = ""
m = nil
pos = line = 0
regex = tag = nil
tag_found = arg_found = ""
while char = string.slice!(/./m)
if char == "\\"
if string[0,1] == "\\"
# Escaping
string.slice!(/./m)
else
# Found a tag, check which one it is
@@tags.each do |regex, tag|
# Save the match for later
found = string.sub!(/\A(#{regex})#{
if tag.params then
'(?:\[(\{\d+\})(.*?)\]\2)?'
end}/) do
m, replace, tag_found, arg_found = [], true, $1, $3
# If [] brackets contain something other than nothing
if arg_found
# Parse tags in the argument
arg_found = parse_tags(arg_found, true)
# Match the result against the params RegExp
if (m = arg_found.match(/^#{tag.params}$/).to_a).length == 0
# Params invalid for this tag, don't replace
replace = false
end
end
if replace
# Save the line and pos so that tags cann call add_command
@line, @pos = line, pos unless internal
replace = send(tag.method, m)
if tag.live
# Delete only
replace = ""
unless internal
# Will again be executed later
add_command(regex, m)
end
end
end
replace or ("#{tag_found}"+(arg_found ? "[#{arg_found}]" : ""))
end
# Abort the loop if a tag was found and replaced
if found and replace
char = nil
break
end
end
end
elsif char == "\n"
# Delete empty lines
if result == "" or string[0,1] == "\n" or result[-1,1] == "\n"
char = nil
else
line += 1
@line_widths[line] = 0 unless internal
end
elsif char == "$"
# Set correct replacement from replacement table
char = string.slice!(/./m)
if @@replacements[char]
char = @@replacements[char]
else
char = "$#{char}"
end
end
if char
pos += char.u_length
result += char
@line_widths[line] +=self.contents.text_size(char).width unless internal
end
end

# Remove Nullbytes
result.gsub!("\000", "")

# Return to CLOSED mode, delete temporary variables
unless internal
@status = CLOSED
@line = @pos = nil
end

# Remove last character if it is a newline
result.sub(/\n\z/) do
# Also remove last entry from @line_widths
@line_widths.pop
""
end

return result
end

#--------------------------------------------------------------------------

def refresh
# Initialize variables
self.contents.font = $msg.font.dup
skin_file = $msg.skin
if FileTest.exist?("Graphics/Pictures/" + skin_file)
custom_skin = RPG::Cache.picture(skin_file)
else
custom_skin = nil
self.windowskin = RPG::Cache.windowskin(skin_file)
end
skin_file = nil
@sound = $msg.sound
@prevent_skipping = $msg.prevent_skipping
@write_speed = $msg.speed
@align, @valign = $msg.align, $msg.valign
@x = @y = @cursor_width = @choice_indent = @indent = 0
@opacity = 255
@cursor_width = 0
@write_wait = 0
@popchar = -2
@character = nil
@align_offset = 0
@cur_line = @scroll_break = 0
@messages = []
@line_widths = [0]
@commands = []
@choice_start = nil

# Get text (but remove whitespace)
@now_text = $game_temp.message_text.strip

# Combine messages
unless @combined_text.empty?
@now_text = @combined_text + @now_text
@combined_text = ""
end

# Create and parse other windows
texts, @message_texts = @message_texts, Array.new
texts.each do |text|
$game_temp.message_text = text
(message = Window_Message.new).update
message.active = false
@messages << message
end
texts = nil

# Before parsing, number the [] brackets in the message text
level = 0
r = ""
@now_text.gsub!(/(\[|\])/) do
level -= 1 if $1 == "]"
r = "#{$1}{#{level.to_s}}"
level += 1 if $1 == "["
r
end
r = level = nil

# Parse all tags and save output
@now_text = parse_tags(@now_text)
# This also sets: @line_widths

# Remove remaining bracket numberings
@now_text.gsub!(/\[(\{\d+\})(.*)?\]\1/, "[\\2]")

# Initiate Input Number Window
if $game_temp.num_input_variable_id > 0
@num_input_variable_id = $game_temp.num_input_variable_id
# Unset it as we have it right here *point*
$game_temp.num_input_variable_id = 0
@input_number_window =
Window_InputNumber.new($game_temp.num_input_digits_max)
@input_number_window.number =
$game_variables[@num_input_variable_id]
@input_number_window.visible = false
elsif $game_temp.choice_max > 0
# Set choice start and calculate cursor width
@choice_start = @line_widths.length - (@item_max = $game_temp.choice_max)
# Set choice width plus padding
@cursor_width = @line_widths[@choice_start..-1].max + 8
self.active = true
# Don't show the cursor in the beginning
self.index = -1
# Reset choice max (don't need it any more. hopefully)
$game_temp.choice_max = 0
end

# Set size of window
reset_size
# Sets self.width, self.height, @align_offset, @choice_indent and
# @face_sprite.align

# Create room to draw
self.contents = Bitmap.new(self.width - 32, self.height - 32)
self.contents.font = $msg.font.dup

# Set its position
reset_position
# Sets self.x, self.y[, @name_window.x, @name_window.y][, @face_sprite.x,
# @face_sprite.y[, @face_sprite.align][, @name_window.indent]]
# [, @input_number_window.x, @input_number_window.y][, @gold_window.x,
# @gold_window.y]

# Set opacities
if @popchar == -1 or custom_skin
self.opacity = 0
self.back_opacity = 0
elsif $game_system.message_frame == 0
self.opacity = 255
self.back_opacity = $msg.opacity
else
self.opacity = 0
self.back_opacity = $msg.opacity
end

# Draw custom window skin
if custom_skin and $game_system.message_frame != 0
self.contents.stretch_blt(self.contents.rect, custom_skin,
custom_skin.rect, $msg.opacity)
end

# First x offset
@x = @indent + align_indent
end

#--------------------------------------------------------------------------

def update
super()

# These actions must always be performed (unless closed)
unless @status == CLOSED
# Update sub-messages
if @messages
@messages.each do |message|
message.update
end
end

# Move Message Box with event
if @character and @character.moving?
reset_position
end

# Perform Fade-in
if self.contents_opacity < 255
self.contents_opacity += 24
@input_number_window.contents_opacity += 24 if @input_number_window
@name_window.contents_opacity += 24 if @name_window
@face_sprite.opacity += 24 if @face_sprite
end
end

case @status
when CLOSED
if $game_temp.message_text
# Do we want the next message to be appended?
if $game_temp.message_text.sub!(/\\\*/, '')
@combined_text += $game_temp.message_text.strip + "\n"
terminate_message
return
elsif $game_temp.message_text.sub!(/\\\+/, '')
if @combined_text.empty?
message_text = ""
else
message_text, @combined_text = @combined_text, ""
end
message_text += $game_temp.message_text.strip
@message_texts << message_text
terminate_message
return
end
# First call; start fading in
$game_temp.message_window_showing = true
refresh
Graphics.frame_reset
self.visible = true
self.active = true
self.contents_opacity = 0
@input_number_window.contents_opacity = 0 if @input_number_window
if @name_window
@name_window.contents_opacity = 0
# Draw the name
@name_window.draw_name
end
@face_sprite.opacity = 0 if @face_sprite
@status = TYPING
end
when TYPING
# Decrease frames to wait
@write_wait -= 1 if @write_wait > 0
# Wait until next frame unless we've waited long enough or are skipping
return unless @write_wait == 0 or skip_text

while @now_text != "" or @commands[0]

# Execute the commands one by one
if @commands[0]
while command = @commands[0].shift
# Execute it
send(command.method, command.params)
# Exit if we have to wait or status has changed
return unless @status == TYPING and (@write_wait == 0 or skip_text)
end
end

# Delete first command list (because it is empty! (or should be^^))
@commands.shift

if c = @now_text.slice!(/./m)
if c == "\n"
# New line
@cur_line += 1
@x = @indent + align_indent
if @popchar > -2 or @cur_line < 4
@y += 1
else
# Duplicate to blt it later
@oldcontents = self.contents.dup
@scroll_break = (@scroll_break + 1).modulo 4
if @scroll_break == 1
@status = PAUSE
break
end
end
else
# Move old three lines to top
if @oldcontents
self.contents.clear
self.contents.blt(0, -Hermes::Message::Box::LINE_HEIGHT,
@oldcontents, @oldcontents.rect)
@oldcontents.dispose
@oldcontents = nil
end
# We have a letter! Now let's draw!
self.contents.draw_text(@x, @y * Hermes::Message::Box::LINE_HEIGHT +
@align_offset, 40, Hermes::Message::Box::LINE_HEIGHT, c)
@x += self.contents.text_size( c ).width
# Don't play a sound during instant display
if @sound and @write_speed > 0
Audio.se_play("Audio/SE/" + @sound)
end
end
end

# Continue with next letter if skipping
if skip_text
next
else
# Stretch time to wait by global speed factor and add own wait time
@write_wait = (@write_wait + 1) * @write_speed
return
end
end

# Switch to done status when text is fully drawn
if @now_text == "" and @commands.empty? and
(@write_wait == 0 or (skip_text and @write_speed != 0))
# Also, show the choice cursor
@index = 0 if @choice_start
# ...and the input number window
@input_number_window.visible = true if @input_number_window
# Set status to done if fully faded in
@status = DONE
end
when PAUSE
# Switch to pause mode if not yet in it
if self.active and not self.pause
self.pause = true
@write_wait = 0
end

if Input.trigger?(Input::C)
# Enter key pressed: resume dialog
if @status == PAUSE
@status = TYPING
self.pause = false
return
else
terminate_message
end
end
when DONE
# Pass control to inpur number window
if @input_number_window
# Update input number window
@input_number_window.update
if Input.trigger?(Input::C)
# Enter key pressed
$game_system.se_play($data_system.decision_se)
$game_variables[@num_input_variable_id] =
@input_number_window.number
$game_map.need_refresh = true
@input_number_window.dispose
@input_number_window = nil
terminate_message
end
elsif @choice_start
# Choice is active
if Input.trigger?(Input::B) and
# Escape key pressed
if $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
end
if Input.trigger?(Input::C)
# Enter key pressed
$game_system.se_play($data_system.decision_se)
$game_temp.choice_proc.call(self.index)
terminate_message
end
else
# Switch to pause mode if not yet in it
if self.active and not self.pause
self.pause = true
end

# Enter key pressed: close dialog
terminate_message if Input.trigger?(Input::C)
end
when CLOSING
# Start fading out
if self.opacity == 0 or $game_temp.message_text
if @messages
@messages.each do |message|
message.dispose
end
end
@messages = []
# Open gold window
if @gold_window
@gold_window.dispose
@gold_window = nil
end
# Free some variables
if @name_window
@name_window.dispose
@name_window = nil
end
if @face_sprite
@face_sprite.dispose
@face_sprite = nil
end
self.visible = false unless $game_temp.message_text
@status = CLOSED
$game_temp.message_window_showing = false
return
end
self.opacity -= 48
@input_number_window.opacity -= 48 if @input_number_window
@name_window.opacity -= 48 if @name_window
@face_sprite.opacity -= 48 if @face_sprite
@gold_window.opacity -= 48 if @gold_window
end
end
end
#=============================================================================
# ▲ CLASS Window_Message Ends
#=============================================================================

=============================================================================
# ■ Hermes - Hermes Extends RMXP's MEssage System - Version 0.2
#-----------------------------------------------------------------------------
# Miscellaneous section
# This page contains miscellaneous adjustments for Hermes in other classes.
#=============================================================================

#=============================================================================
# ● FEATURE Unicode version for String#length
#=============================================================================

#=============================================================================
# ▼ CLASS String Additional Code Begins
#=============================================================================
class String
def u_length
return self.dup.gsub(/./m, " ").length
end
end
#=============================================================================
# ▲ CLASS String Additional Code Ends
#=============================================================================



#=============================================================================
# ● FEATURE Dynamic line heights
#=============================================================================

#=============================================================================
# ▼ CLASS Array Additional Code Begins
#=============================================================================
class Array
def sum(start = 0, count = self.length)
s = 0
count = [count.abs, self.length - start].min
start.upto(start + count - 1) do |i|
s += self
end
return s
end
end
#=============================================================================
# ▲ CLASS Array Additional Code Ends
#=============================================================================



#=============================================================================
# ● FEATURE Outline / Shadow
#=============================================================================

#=============================================================================
# ▼ CLASS TextEffect Begins
#=============================================================================
class TextEffect
attr_accessor :active, :size, :color

def initialize(size = 1, color = Color.new(0, 0, 0, 128))
@size = size.to_i
@color = color
@active = (@size > 0)
end

#--------------------------------------------------------------------------

def active?
return (@active and @size > 0)
end
end
#=============================================================================
# ▲ CLASS TextEffect Ends
#=============================================================================

#=============================================================================
# ▼ CLASS Font Additional Code Begins
#=============================================================================
unless defined? Font::MODDED
class Font
attr_accessor :eek:utline, :shadow

MODDED = true

self.default_name = Hermes::GlobalText::NAME
self.default_size = Hermes::GlobalText::SIZE
self.default_color = Hermes::GlobalText::COLOR
self.default_bold = Hermes::GlobalText::BOLD
self.default_italic = Hermes::GlobalText::ITALIC
@@default_outline = TextEffect.new(*Hermes::GlobalText::OUTLINE)
@@default_shadow = TextEffect.new(*Hermes::GlobalText::SHADOW)

def self.default_outline() @@default_outline end
def self.default_shadow() @@default_shadow end
def self.default_outline=(outline) @@default_outline = outline end
def self.default_shadow=(shadow) @@default_shadow = shadow end

alias old_font_init initialize

def initialize(*args)
old_font_init(*args)
@outline = @@default_outline.dup
@shadow = @@default_shadow.dup
end

#------------------------------------------------------------------------

# Code by KD - Make sure fonts can be saved and loaded
def marshal_dump(*args)
hash = Hash.new
instance_variables.each do |sym|
hash[sym.to_s[1..-1].to_sym] = instance_variable_get(sym)
end
[:name, :size, :color, :bold, :italic].each do |sym|
hash[sym] = send(sym)
end
hash
end

def marshal_load(hash)
initialize()
hash.each do |sym, value|
send("#{sym}=", value)
end
end
end
end
#=============================================================================
# ▲ CLASS Font Additional Code Ends
#=============================================================================

#=============================================================================
# ▼ CLASS Bitmap Additional Code Begins
#=============================================================================
unless defined? Bitmap::MODDED
class Bitmap
alias old_bitmap_dt draw_text

MODDED = true

def draw_text(x, y, *args)
return draw_text(x.x, x.y, x.width, x.height, y, *args) if x.class == Rect
oldcolor = font.color.dup
if font.shadow.active?
font.color = font.shadow.color
size = font.shadow.size
old_bitmap_dt(x + size, y + size, *args)
end
if font.outline.active?
font.color = font.outline.color
size = font.outline.size
range_x = (x - size)..(x + size)
range_y = (y - size)..(y + size)
font.color.alpha *= size / ((range_x.last - range_x.first) *
(range_y.last - range_y.first) - 1).to_f
range_x.each do |now_x|
range_y.each do |now_y|
unless x == now_x and y == now_y
old_bitmap_dt(now_x, now_y, *args)
end
end
end
end
font.color = oldcolor
old_bitmap_dt(x, y, *args)
end

#------------------------------------------------------------------------

# Code by KD - Copy special font properties when setting Bitmap font
alias set_font font=
def font=(newfont)
set_font(newfont)
newfont.instance_variables.each do |sym|
font.instance_variable_set(sym, newfont.instance_variable_get(sym))
end
end
end
end
#=============================================================================
# ▲ CLASS Bitmap Additional Code Ends
#=============================================================================



#=============================================================================
# ● FEATURE Avatar Display
#=============================================================================

#=============================================================================
# ▼ CLASS Sprite_Face Begins
#=============================================================================
class Sprite_Face < Sprite
# Faceset graphic, X / Y, Face ID, whether pinned on top instead of bottom
def initialize(graphic, z, id = 0)
# Initialize sprite
super()

# Load graphic
self.bitmap = RPG::Cache.picture(graphic)

# If single face graphic loaded
if id == 0
# Show complete bitmap
self.src_rect = self.bitmap.rect
# If face set loaded
else
# Special / invalid face IDs
unless id.kind_of? Integer
id = (@@face_aliases[id] or 1)
end
# Set source rect
src_y, src_x = *(id.to_i - 1).divmod(4)
face_width = self.bitmap.width / 4
src_x *= face_width
src_y *= Hermes::FACE_HEIGHT
self.src_rect = Rect.new(src_x, src_y, face_width, Hermes::FACE_HEIGHT)
end
# Set z order
self.z = z
end

#--------------------------------------------------------------------------

def reset_position(parent)
# If window is tall enough
if @align == CENTER
self.x = parent.x + 16 + (self.face_width/2)
self.y = parent.y + 16 + (self.face_width/2)
else
# Window is not tall enough
if parent.y + parent.height - 32 >= self.face_height
# Face can be shown aligned to bottom
self.align = BOTTOM
# Message is not displayed on top and not in full screen
self.x = parent.x + 16
self.y = parent.y + parent.height - 16
return 0
else
# Face must be aligned on top of the message
self.align = TOP
# Message is displayed on top or in full screen
self.x = parent.x + 16
self.y = parent.y + 16
return 3
end
end
end

#--------------------------------------------------------------------------

def face_width
# Return the selected face's width
return self.src_rect.width
end

#--------------------------------------------------------------------------

def face_height
# Return the selected face's height
return self.src_rect.height
end

#--------------------------------------------------------------------------

TOP = 0
CENTER = 1
BOTTOM = 2
attr_reader :align
def align=(align)
# Set pin position
case align
when TOP
self.ox = self.oy = 0
when BOTTOM
self.ox = 0
self.oy = self.src_rect.height
else
align = CENTER unless align == CENTER
self.ox = self.src_rect.width / 2
self.oy = self.src_rect.height / 2
end
@align = align
end

# Hide some methods
protected :eek:x=, :eek:y=
end
#=============================================================================
# ▲ CLASS Sprite_Face Ends
#=============================================================================



#=============================================================================
# ● FEATURE Map Name Display
#=============================================================================

#=============================================================================
# ▼ CLASS Game_Map Additional Code Begins
#=============================================================================
class Game_Map
alias old_initialize initialize

def initialize
@map_names = load_data("Data/MapInfos.rxdata")
@map_names.each do |key, info|
@map_names[key] = info.name
end
old_initialize
end

def name
@map_names[@map_id]
end
end
#=============================================================================
# ▲ CLASS Game_Map Additional Code Ends
#=============================================================================



#=============================================================================
# ● FEATURE Event Name Display
#=============================================================================

#=============================================================================
# ▼ CLASS Game_Event Additional Code Begins
#=============================================================================
class Game_Event
def name
return @event.name
end
end
#=============================================================================
# ▲ CLASS Game_Event Additional Code Ends
#=============================================================================



#=============================================================================
# ● FEATURE Popup over current event
#=============================================================================

#=============================================================================
# ▼ CLASS Interpreter Additional Code Begins
#=============================================================================
class Interpreter
def event_id
if @list and $game_map.events[@event_id].trigger <= 2
@event_id
else
0
end
end
end
#=============================================================================
# ▲ CLASS Interpreter Additional Code Ends
#=============================================================================



#=============================================================================
# ● FEATURE Hex Color Definition
#=============================================================================

#=============================================================================
# ▼ CLASS Window_Base Additional Code Begins
#=============================================================================
class Window_Base
def make_color(color)
if color.class == String and /\A\#[0-9A-F]{6}\z/i.match(color)
# Valid hex color, create it
return Color.new(color[1,2].hex, color[3,2].hex, color[5,2].hex,
self.contents.font.color.alpha)
else
# Create of of the predefined colors
return text_color(color.to_i)
end
end
end
#=============================================================================
# ▲ CLASS Window_Base Additional Code Ends
#=============================================================================



#=============================================================================
# ● FEATURE Name Window
#=============================================================================

#=============================================================================
# ▼ CLASS Window_Name Begins
#=============================================================================
class Window_Name < Window_Base
attr_reader :indent

# Class for the Name Window
def initialize(name, z)
@indent = 0
@name = name
super(0, 0, 33, 33)
self.windowskin = RPG::Cache.windowskin($msg.name_skin)
self.back_opacity = $msg.name_opacity
self.contents = Bitmap.new(1, 1)
self.contents.font = $msg.name_font
@size = self.contents.text_size(name)
w = 8 + @size.width + Hermes::Name::Box::PADDING * 2
self.width = w if w > 33
h = 8 + @size.height
self.height = h if h > 33
self.z = z
@text = Sprite.new
@text.bitmap = Bitmap.new(self.width, self.height)
@text.bitmap.font = self.contents.font.dup
self.contents.dispose
@text.src_rect = @text.bitmap.rect
@text.z = z + 1
end

#--------------------------------------------------------------------------

def draw_name
@text.bitmap.draw_text(@size, @name)
end

#--------------------------------------------------------------------------

def apply_pos(parent, pos)
return parent.x +
if pos == 1 or pos == 2 # right
parent.width - self.width - Hermes::Name::Box::OFFSET
else # left
Hermes::Name::Box::OFFSET
end,
parent.y +
if pos < 2 # top
Hermes::Name::Box::OVERLAP - self.height
else # bottom
parent.height - Hermes::Name::Box::OVERLAP
end
end

#--------------------------------------------------------------------------

def reset_position(parent)
pos = Hermes::Name::Box::POS
x, y = *apply_pos(parent, pos)
# Swap if exiting the screen
if (pos == 1 or pos == 2) and Hermes::Name::Box::SWAP and x < 0
pos = (pos-1) * 3
elsif Hermes::Name::Box::SWAP and x + self.width > 640
pos = (pos-1).abs
end
if pos < 2 and Hermes::Name::Box::SWAP and y < 0
pos = 3 - pos
elsif Hermes::Name::Box::SWAP and y + self.height > 480
pos = (pos - 3).abs
end
x, y = *apply_pos(parent, pos) unless pos == Hermes::Name::Box::POS
self.x, self.y = x, y
return pos
end

#--------------------------------------------------------------------------

alias real_x= x=
protected :real_x=
def x=(x)
super(@indent + x)
@text.x = @indent + x + 4 + Hermes::Name::Box::PADDING if @text
end

#--------------------------------------------------------------------------

def y=(y)
super(y)
@text.y = y + 4 if @text
end

#--------------------------------------------------------------------------

def color=(c)
@text.bitmap.font.color = c
end

#--------------------------------------------------------------------------

def opacity=(o)
super(o)
@text.opacity = o
end

#--------------------------------------------------------------------------

def indent=(indent)
self.real_x = self.x + indent - @indent
@text.x += indent - @indent
@indent = indent
end

#--------------------------------------------------------------------------

def dispose
@text.dispose
super
end

#--------------------------------------------------------------------------

def contents_opacity() @text.opacity end
def contents_opacity=(opac) @text.opacity = opac end
end
#=============================================================================
# ▲ CLASS Window_Name Ends
#=============================================================================


#=============================================================================
# ■ Hermes - Hermes Extends RMXP's MEssage System - Version 0.2
#-----------------------------------------------------------------------------
# Hermes/Romkan extension
# This is an example extension for Hermes which allows you to add Hiragana
# to your messages. Insert this script below all other Hermes scripts.
# This script uses Ruby/Romkan, Copyright (C) 2001 Satoru Takabayashi.
# For more information on Ruby/Romkan, and what I've changed in it, see below
#=============================================================================

# To add a new tag, there are several things to do. First, you must add the tag
# to Hermes's list of tags. This is done via the class methods
# Window_Message.tag or Window_Message.live_tag. Use the first of those if you
# want your tag's method to be executed while the message is being created.
# This is useful for settings that affect the complete message, like toe \p or
# \f tags.
# When using Window_Message.live_tag method, your method will be called twice:
# once while it is calculating the lines' widths of the message (this is the
# same moment where non-live tags are called), and once later, before the letter
# following to this command is being displayed. This is useful if you want to
# make dynamic changes, like changing the font (\t) or the size (\h) of the
# text following this tag.
# However, you must not change anything but the message font (@font) during the
# first call. To determine whether your method is called during text measuring
# or during text display (when you create a live tag), check if @status equals
# WIDTH_TRIAL. If it does, the message window is currently determining the width
# of the text. Remember that you may not change anything but @font in this case!
# If your tag isn't a live tag, the tag is replaced with the return value of
# your tag's function. If it is, it is replaced with an empty string.
# The following is the tag definition for the kana tag.

# This is the tag definition. The first argument is a regular expression that
# detects the tag. This one, e.g., recognizes \k, \K, \kaNA, \KANA, \Kana etc.
# The second argument is a regular expression which determines whether the
# argument is correct. The one below allows everything as an argument.
Window_Message.tag /k(?:ana)?/i, /.*/ do |m|
# Test if a kana tag is open. Of course, this isn't a standard variable.
unless @kana_font_before
# m is an array which contains all the arguments like specified in the
# regular expressions above. m[0] is the complete match including the tag,
# and m[1] the substring matched by the second RegExp above.
result = m[0]
# If an argument was specified
if result
# Ensures the font used for Kana display is present on the targent system.
# Of course, kana_font_name isn't a default value of $msg, it will be
# added below. Also, the font will only be changed if it isn't already.
if Font.exist?($msg.kana_font_name) and
$msg.kana_font_name != self.contents.font.name
# Only change the font if it isn't correct already
# The following is needed so that we remember to reset the font to
# the previous font name.
@kana_font_before = self.contents.font.name
# Add a command to change the font. This is needed, because the kana tag
# is not a live tag.
add_command(/tf(?:eek:nt)?/i, [$msg.kana_font_name])
# Set the font in width trial mode (in "live" mode this is performed by
# the type command added above)
self.contents.font.name = $msg.kana_font_name
# Convert the argument to kana (the to_kana method is specified below)
result = result.to_kana
# Now add a command that will change the font back to normal. The last
# argument ensures that it will not be added at the current position,
# but result.u_length characters ahead (see also Misc section)
add_command(/tf(?:eek:nt)?/i, [@kana_font_before], result.u_length)
# And add another kana tag that will change the font back to normal
# (see the elseif clause below)
result += "\\k"
end
else
# No argument specified (result is nil): set it to empty string
result = ""
end
return result
else
# This section is reached when a kana string has finished
# Reset the font to normal
self.contents.font.name = @kana_font_before
# Clear the font before thing
@kana_font_before = nil
# Return an empty string so the tag gets deleted
return ""
end
end

# In many cases, the above tag definition would be enough to completely define a
# tag. In the Configuration & Tags section of Hermes you can see many such
# examples. However, in this case, we also want to provide the user an option to
# be able to change the font used for kana tags both globally and during the
# game.

# The former can be achieved by extending the Hermes class:
module Hermes
# Default Japanese font (for use with \kana tag)
KANA_FONT_NAME = "Arial Unicode MS"
end

# However, this doesn't do anything but specify the standard setting. If you
# release your tag, you will most likely want to place the above snippet at the
# top of your code, so that users can easily change this setting.

# The latter (setting being saved in $msg) can be achieved this way:
class Hermes_Global_Settings # The class name of $msg.
# Make @kana_font_name readable
attr_reader :kana_font_name

# This will make $msg.kana_font_name changeable. Note that the convention is,
# when you call this function with nil as an argument, it will ne reset to the
# default value (see above).
def kana_font_name=(arg)
return @kana_font_name = (arg or Hermes::KANA_FONT_NAME)
end

# Finally, assign the default value on creation of the $msg class. You need to
# overwrite the initialize method for this. Therefore, create an alias for it,
# but use one that is as unique to your tag as possible, optimally the tag's
# name itself, so in this case:
alias kana_initialize initialize
def initialize
# Call the old initialize method
kana_initialize
# Now initialize the kana font name
self.kana_font_name = nil
# This will call the method created above. Note that this is neither the
# same as kana_font_name = nil (which would create a local variable), not as
# @kana_font_name = nil (which would actually set it to nil, but we want it
# to be reset to default).
end
end



#
# Ruby/Romkan - a Romaji <-> Kana conversion library for Ruby.
#
# Copyright (C) 2001 Satoru Takabayashi <satoru@namazu.org>
# All rights reserved.
# This is free software with ABSOLUTELY NO WARRANTY.
#
# You can redistribute it and/or modify it under the terms of
# the Ruby's licence.
#
# NOTE: Ruby/Romkan can work only with EUC_JP encoding. ($KCODE="e")
#
# NOTE (Hermes author): The above note isn't true, at least not for Romaji ->
# Kana conversion. I modified the original Ruby/Romkan library by simply
# running them through a little PHP script which converted it from EUC_JP
# to Unicode, and it works, as far as I can tell. I'm not sure whether
# Kana -> Romaji works though, as I've not tested it, but it should. Also,
# I've added Romaji to Katakana conversion (UPPER CASE LETTERS will be
# translated to Katakana, lower case ones to Hiragana).
# Also, I've removed all the methods that aren't used in the code above,
# which is all of them except normalize_double_n and to_kana. For the full
# version, see Takabayashi-san no webusaito at http://0xcc.net/ruby-romkan/
#

module Romkan
VERSION = '0.4'
end

class Array
def pairs(s=2)
0.step(self.size-1,s){
|x| yield self.slice(x,s)
}
end
end

class String
# This table is imported from KAKASI <http://kakasi.namazu.org/> and modified.
KUNREITAB = "\
ぁ xa あ a ぃ xi い i ぅ xu
う u う゛ vu う゛ぁ va う゛ぃ vi う゛ぇ ve
う゛ぉ vo ぇ xe え e ぉ xo お o

か ka が ga き ki きゃ kya きゅ kyu
きょ kyo ぎ gi ぎゃ gya ぎゅ gyu ぎょ gyo
く ku ぐ gu け ke げ ge こ ko
ご go

さ sa ざ za し si しゃ sya しゅ syu
しょ syo じ zi じゃ zya じゅ zyu じょ zyo
す su ず zu せ se ぜ ze そ so
ぞ zo

た ta だ da ち ti ちゃ tya ちゅ tyu
ちょ tyo ぢ di ぢゃ dya ぢゅ dyu ぢょ dyo

っ xtu
っう゛ vvu っう゛ぁ vva っう゛ぃ vvi
っう゛ぇ vve っう゛ぉ vvo
っか kka っが gga っき kki っきゃ kkya
っきゅ kkyu っきょ kkyo っぎ ggi っぎゃ ggya
っぎゅ ggyu っぎょ ggyo っく kku っぐ ggu
っけ kke っげ gge っこ kko っご ggo っさ ssa
っざ zza っし ssi っしゃ ssya
っしゅ ssyu っしょ ssho
っじ zzi っじゃ zzya っじゅ zzyu っじょ zzyo
っす ssu っず zzu っせ sse っぜ zze っそ sso
っぞ zzo った tta っだ dda っち tti
っちゃ ttya っちゅ ttyu っちょ ttyo っぢ ddi
っぢゃ ddya っぢゅ ddyu っぢょ ddyo っつ ttu
っづ ddu って tte っで dde っと tto っど ddo
っは hha っば bba っぱ ppa っひ hhi
っひゃ hhya っひゅ hhyu っひょ hhyo っび bbi
っびゃ bbya っびゅ bbyu っびょ bbyo っぴ ppi
っぴゃ ppya っぴゅ ppyu っぴょ ppyo っふ hhu
っふぁ ffa っふぃ ffi っふぇ ffe っふぉ ffo
っぶ bbu っぷ ppu っへ hhe っべ bbe っぺ ppe
っほ hho っぼ bbo っぽ ppo っや yya っゆ yyu
っよ yyo っら rra っり rri っりゃ rrya
っりゅ rryu っりょ rryo っる rru っれ rre
っろ rro

つ tu づ du て te で de と to
ど do

な na に ni にゃ nya にゅ nyu にょ nyo
ぬ nu ね ne の no

は ha ば ba ぱ pa ひ hi ひゃ hya
ひゅ hyu ひょ hyo び bi びゃ bya びゅ byu
びょ byo ぴ pi ぴゃ pya ぴゅ pyu ぴょ pyo
ふ hu ふぁ fa ふぃ fi ふぇ fe ふぉ fo
ぶ bu ぷ pu へ he べ be ぺ pe
ほ ho ぼ bo ぽ po

ま ma み mi みゃ mya みゅ myu みょ myo
む mu め me も mo

ゃ xya や ya ゅ xyu ゆ yu ょ xyo
よ yo

ら ra り ri りゃ rya りゅ ryu りょ ryo
る ru れ re ろ ro

ゎ xwa わ wa ゐ wi ゑ we
を wo ん n

ん n'
でぃ dyi
ー -
ちぇ tye
っちぇ ttye
じぇ zye

ァ XA ア A ィ XI イ I ゥ XU
ウ U ウ゛ VU ウ゛ァ VA ウ゛ィ VI ウ゛ェ VE
ウ゛ォ VO ェ XE エ E ォ XO オ O

カ KA ガ GA キ KI キャ KYA キュ KYU
キョ KYO ギ GI ギャ GYA ギュ GYU ギョ GYO
ク KU グ GU ケ KE ゲ GE コ KO
ゴ GO

サ SA ザ ZA シ SI シャ SYA シュ SYU
ショ SYO ジ ZI ジャ ZYA ジュ ZYU ジョ ZYO
ス SU ズ ZU セ SE ゼ ZE ソ SO
ゾ ZO

タ TA ダ DA チ TI チャ TYA チュ TYU
チョ TYO ヂ DI ヂャ DYA ヂュ DYU ヂョ DYO

ッ XTU
ッウ゛ VVU ッウ゛ァ VVA ッウ゛ィ VVI
ッウ゛ェ VVE ッウ゛ォ VVO
ッカ KKA ッガ GGA ッキ KKI ッキャ KKYA
ッキュ KKYU ッキョ KKYO ッギ GGI ッギャ GGYA
ッギュ GGYU ッギョ GGYO ック KKU ッグ GGU
ッケ KKE ッゲ GGE ッコ KKO ッゴ GGO ッサ SSA
ッザ ZZA ッシ SSI ッシャ SSYA
ッシュ SSYU ッショ SSHO
ッジ ZZI ッジャ ZZYA ッジュ ZZYU ッジョ ZZYO
ッス SSU ッズ ZZU ッセ SSE ッゼ ZZE ッソ SSO
ッゾ ZZO ッタ TTA ッダ DDA ッチ TTI
ッチャ TTYA ッチュ TTYU ッチョ TTYO ッヂ DDI
ッヂャ DDYA ッヂュ DDYU ッヂョ DDYO ッツ TTU
ッヅ DDU ッテ TTE ッデ DDE ット TTO ッド DDO
ッハ HHA ッバ BBA ッパ PPA ッヒ HHI
ッヒャ HHYA ッヒュ HHYU ッヒョ HHYO ッビ BBI
ッビャ BBYA ッビュ BBYU ッビョ BBYO ッピ PPI
ッピャ PPYA ッピュ PPYU ッピョ PPYO ッフ HHU
ッファ FFA ッフィ FFI ッフェ FFE ッフォ FFO
ッブ BBU ップ PPU ッヘ HHE ッベ BBE ッペ PPE
ッホ HHO ッボ BBO ッポ PPO ッヤ YYA ッユ YYU
ッヨ YYO ッラ RRA ッリ RRI ッリャ RRYA
ッリュ RRYU ッリョ RRYO ッル RRU ッレ RRE
ッロ RRO

ツ TU ヅ DU テ TE デ DE ト TO
ド DO

ナ NA ニ NI ニャ NYA ニュ NYU ニョ NYO
ヌ NU ネ NE ノ NO

ハ HA バ BA パ PA ヒ HI ヒャ HYA
ヒュ HYU ヒョ HYO ビ BI ビャ BYA ビュ BYU
ビョ BYO ピ PI ピャ PYA ピュ PYU ピョ PYO
フ HU ファ FA フィ FI フェ FE フォ FO
ブ BU プ PU ヘ HE ベ BE ペ PE
ホ HO ボ BO ポ PO

マ MA ミ MI ミャ MYA ミュ MYU ミョ MYO
ム MU メ ME モ MO

ャ XYA ヤ YA ュ XYU ユ YU ョ XYO
ヨ YO

ラ RA リ RI リャ RYA リュ RYU リョ RYO
ル RU レ RE ロ RO

ヮ XWA ワ WA ヰ WI ヱ WE
ヲ WO ン N

ン N'
ディ DYI
ー -
チェ TYE
ッチェ TTYE
ジェ ZYE
"

HEPBURNTAB = "\
ぁ xa あ a ぃ xi い i ぅ xu
う u う゛ vu う゛ぁ va う゛ぃ vi う゛ぇ ve
う゛ぉ vo ぇ xe え e ぉ xo お o


か ka が ga き ki きゃ kya きゅ kyu
きょ kyo ぎ gi ぎゃ gya ぎゅ gyu ぎょ gyo
く ku ぐ gu け ke げ ge こ ko
ご go

さ sa ざ za し shi しゃ sha しゅ shu
しょ sho じ ji じゃ ja じゅ ju じょ jo
す su ず zu せ se ぜ ze そ so
ぞ zo

た ta だ da ち chi ちゃ cha ちゅ chu
ちょ cho ぢ di ぢゃ dya ぢゅ dyu ぢょ dyo

っ xtsu
っう゛ vvu っう゛ぁ vva っう゛ぃ vvi
っう゛ぇ vve っう゛ぉ vvo
っか kka っが gga っき kki っきゃ kkya
っきゅ kkyu っきょ kkyo っぎ ggi っぎゃ ggya
っぎゅ ggyu っぎょ ggyo っく kku っぐ ggu
っけ kke っげ gge っこ kko っご ggo っさ ssa
っざ zza っし sshi っしゃ ssha
っしゅ sshu っしょ ssho
っじ jji っじゃ jja っじゅ jju っじょ jjo
っす ssu っず zzu っせ sse っぜ zze っそ sso
っぞ zzo った tta っだ dda っち cchi
っちゃ ccha っちゅ cchu っちょ ccho っぢ ddi
っぢゃ ddya っぢゅ ddyu っぢょ ddyo っつ ttsu
っづ ddu って tte っで dde っと tto っど ddo
っは hha っば bba っぱ ppa っひ hhi
っひゃ hhya っひゅ hhyu っひょ hhyo っび bbi
っびゃ bbya っびゅ bbyu っびょ bbyo っぴ ppi
っぴゃ ppya っぴゅ ppyu っぴょ ppyo っふ ffu
っふぁ ffa っふぃ ffi っふぇ ffe っふぉ ffo
っぶ bbu っぷ ppu っへ hhe っべ bbe っぺ ppe
っほ hho っぼ bbo っぽ ppo っや yya っゆ yyu
っよ yyo っら rra っり rri っりゃ rrya
っりゅ rryu っりょ rryo っる rru っれ rre
っろ rro

つ tsu づ du て te で de と to
ど do

な na に ni にゃ nya にゅ nyu にょ nyo
ぬ nu ね ne の no

は ha ば ba ぱ pa ひ hi ひゃ hya
ひゅ hyu ひょ hyo び bi びゃ bya びゅ byu
びょ byo ぴ pi ぴゃ pya ぴゅ pyu ぴょ pyo
ふ fu ふぁ fa ふぃ fi ふぇ fe ふぉ fo
ぶ bu ぷ pu へ he べ be ぺ pe
ほ ho ぼ bo ぽ po

ま ma み mi みゃ mya みゅ myu みょ myo
む mu め me も mo

ゃ xya や ya ゅ xyu ゆ yu ょ xyo
よ yo

ら ra り ri りゃ rya りゅ ryu りょ ryo
る ru れ re ろ ro

ゎ xwa わ wa ゐ wi ゑ we
を wo ん n

ん n'
でぃ dyi
ー -
ちぇ che
っちぇ cche
じぇ je

ァ XA ア A ィ XI イ I ゥ XU
ウ U ウ゛ VU ウ゛ァ VA ウ゛ィ VI ウ゛ェ VE
ウ゛ォ VO ェ XE エ E ォ XO オ O


カ KA ガ GA キ KI キャ KYA キュ KYU
キョ KYO ギ GI ギャ GYA ギュ GYU ギョ GYO
ク KU グ GU ケ KE ゲ GE コ KO
ゴ GO

サ SA ザ ZA シ SHI シャ SHA シュ SHU
ショ SHO ジ JI ジャ JA ジュ JU ジョ JO
ス SU ズ ZU セ SE ゼ ZE ソ SO
ゾ ZO

タ TA ダ DA チ CHI チャ CHA チュ CHU
チョ CHO ヂ DI ヂャ DYA ヂュ DYU ヂョ DYO

ッ XTSU
ッウ゛ VVU ッウ゛ァ VVA ッウ゛ィ VVI
ッウ゛ェ VVE ッウ゛ォ VVO
ッカ KKA ッガ GGA ッキ KKI ッキャ KKYA
ッキュ KKYU ッキョ KKYO ッギ GGI ッギャ GGYA
ッギュ GGYU ッギョ GGYO ック KKU ッグ GGU
ッケ KKE ッゲ GGE ッコ KKO ッゴ GGO ッサ SSA
ッザ ZZA ッシ SSHI ッシャ SSHA
ッシュ SSHU ッショ SSHO
ッジ JJI ッジャ JJA ッジュ JJU ッジョ JJO
ッス SSU ッズ ZZU ッセ SSE ッゼ ZZE ッソ SSO
ッゾ ZZO ッタ TTA ッダ DDA ッチ CCHI
ッチャ CCHA ッチュ CCHU ッチョ CCHO ッヂ DDI
ッヂャ DDYA ッヂュ DDYU ッヂョ DDYO ッツ TTSU
ッヅ DDU ッテ TTE ッデ DDE ット TTO ッド DDO
ッハ HHA ッバ BBA ッパ PPA ッヒ HHI
ッヒャ HHYA ッヒュ HHYU ッヒョ HHYO ッビ BBI
ッビャ BBYA ッビュ BBYU ッビョ BBYO ッピ PPI
ッピャ PPYA ッピュ PPYU ッピョ PPYO ッフ FFU
ッファ FFA ッフィ FFI ッフェ FFE ッフォ FFO
ッブ BBU ップ PPU ッヘ HHE ッベ BBE ッペ PPE
ッホ HHO ッボ BBO ッポ PPO ッヤ YYA ッユ YYU
ッヨ YYO ッラ RRA ッリ RRI ッリャ RRYA
ッリュ RRYU ッリョ RRYO ッル RRU ッレ RRE
ッロ RRO

ツ TSU ヅ DU テ TE デ DE ト TO
ド DO

ナ NA ニ NI ニャ NYA ニュ NYU ニョ NYO
ヌ NU ネ NE ノ NO

ハ HA バ BA パ PA ヒ HI ヒャ HYA
ヒュ HYU ヒョ HYO ビ BI ビャ BYA ビュ BYU
ビョ BYO ピ PI ピャ PYA ピュ PYU ピョ PYO
フ FU ファ FA フィ FI フェ FE フォ FO
ブ BU プ PU ヘ HE ベ BE ペ PE
ホ HO ボ BO ポ PO

マ MA ミ MI ミャ MYA ミュ MYU ミョ MYO
ム MU メ ME モ MO

ャ XYA ヤ YA ュ XYU ユ YU ョ XYO
ヨ YO

ラ RA リ RI リャ RYA リュ RYU リョ RYO
ル RU レ RE ロ RO

ヮ XWA ワ WA ヰ WI ヱ WE
ヲ WO ン N

ン N'
ディ DYI
ー -
チェ CHE
ッチェ CCHE
ジェ JE
"

KANROM = (kanaroma = Hash.new
(KUNREITAB + HEPBURNTAB).split(/\s+/).pairs {|x|
kana, roma = x
kanaroma[kana] = roma
}
kanaroma)

ROMKAN = (romakana = Hash.new
(KUNREITAB + HEPBURNTAB).split(/\s+/).pairs {|x|
kana, roma = x
romakana[roma] = kana
}
romakana)

# Sort in long order so that a longer Romaji sequence precedes.
ROMPAT = ROMKAN.keys.sort {|a, b| b.length <=> a.length}.join "|"

KANPAT = KANROM.keys.sort {|a, b|
b.length <=> a.length ||
KANROM[a].length <=> KANROM.length
}.join "|"

KUNREI = (i = 0; KUNREITAB. split(/\s+/).select {i += 1; i % 2 == 0})
HEPBURN = (i = 0; HEPBURNTAB.split(/\s+/).select {i += 1; i % 2 == 0})

KUNPAT = KUNREI.sort {|a, b| b.length <=> a.length }.join "|"
HEPPAT = HEPBURN.sort {|a, b| b.length <=> a.length }.join "|"

TO_HEPBURN = (romrom = Hash.new
KUNREI.each_with_index {|x, i|
romrom[KUNREI] = HEPBURN}
romrom)

TO_KUNREI = (romrom = Hash.new
HEPBURN.each_with_index {|x, i|
romrom[HEPBURN] = KUNREI}
romrom)

# FIXME: ad hod solution
# tanni => tan'i
# kannji => kanji
# hannnou => han'nou
# hannnya => han'nya
def normalize_double_n
self.gsub(/nn/, "n'").gsub(/n\'(?=[^aiueoyn]|$)/, "n")
end

# Romaji -> Kana
# It can handle both Hepburn and Kunrei sequences.
def to_kana
tmp = self.normalize_double_n
tmp.gsub(/(#{ROMPAT})/) { ROMKAN[$1] }
end
end
 

Jason

Awesome Bro

But it isn't 2-3 lines of code at all, if you want them to be ANIMATED faces, you'd need alot more than 2-3 lines, you'd also need to use call script in every event that has speech...

So instead you should stop being lazy and do the easiest method, which would be to event it, have each animation in a seperate common event, and just call the common event when the time comes.
 

Atoa

Member

a simple 2-3 lines of code is much easier.
Yes... easier for *you*.
If that was easy. You could do it by yourself.
Don't say something is easy unless you know how to do.

I wouldn't do something that can be easly evented, just because you're being lazy.

Anyway, good louck with you request.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top