Mail Box System
Authors: game_guy
Version: 1.1
Type: Messaging System
Key Term: Misc System
IntroductionSmall mail-box system. Have npc's send your players mail. Then have your Player read it. Sorta like the pokemon cellphone system. Where trainers would call you for a rematch.
Features
- Completely Customizable
- -Customize Text
- -Customize Color
- -Customize Opacity
- Easy to setup mail
- Easy to get mail
- Check to see if a mail has been read
ScreenshotsUnread Mail
(http://i678.photobucket.com/albums/vv143/GameGuysProjects/unread.png)
Read Mail
(http://i678.photobucket.com/albums/vv143/GameGuysProjects/layout.png)
DemoN/A
Script
#===============================================================================
# Mail Box System
# Author game_guy
# Version 1.1
#-------------------------------------------------------------------------------
# Intro:
# Small mail-box system. Have npc's send your players mail. Then have your
# Player read it. Sorta like the pokemon cellphone system. Where trainers
# would call you for a rematch.
#
# Features:
# Completely Customizable
# -Customize Text
# -Customize Color
# -Customize Opacity
# Easy to setup mail
# Easy to get mail
# Check to see if a mail has been read
#
# Instructions:
# Go down to config. Configure the variables there.
# Everythings self explanatory down below.
# Colors are setup like this.
# Color.new(red, green, blue)
#
# Script Calls:
# Use
# $scene = Scene_Mail.new to go to mail box
# Use
# $game_party.add_mail(mail_id) to add a new mail
# Use
# $game_party.take_mail(mail_id) to delete a mail
# Use
# $game_party.mark_read(mail_id) to mark a message read
# To see if a message has been read, use the script call in
# a conditional branch.
# $game_party.mail_read?(mail_id)
#
# Compatibility:
# Not tested with SDK.
#
# Credits:
# game_guy ~ For making it
# Darth Spy ~ Requesting it
#===============================================================================
module GGMail
#===================================================
# Config
#===================================================
#--------------------
# Mail Bag - Name of your mail holder.
# Example: Mail Box :O
#--------------------
Mail_Word = "Mail Bag"
#--------------------
# Action_Message - Text to show
# how to mark messages read.
#--------------------
Action_Message = "Press Space to Mark as Read"
#--------------------
# From_Text - Text displayed
# with the sender of the mail
# Example: Sender:
#--------------------
From_Text = "From: "
#--------------------
# Title_Text - Text displayed
# with the title of the mail.
#--------------------
Title_Text = "Title: "
#--------------------
# Message_Text - Text displayed
# with the message of the mail.
#--------------------
Message_Text = "Message: "
#--------------------
# Label_Color - Color of
# From, Title, and Message text
#--------------------
Label_Color = Color.new(192, 224, 255, 255)
#--------------------
# New_Color - Color of new
# unread mail
#--------------------
New_Color = Color.new(255, 255, 64, 255)
#--------------------
# Read_Color - Color of
# old already read mail
#--------------------
Read_Color = Color.new(255, 255, 255)
#--------------------
# Mail - Ignore this line
#--------------------
Mail = []
#--------------------
# Opacity - The transparency
# of the windows in the layout
#--------------------
Opacity = 128
#--------------------
# Background - The background
# that displays in the mail
# scene.
# 0 = blank
# 1 = map
# "quoted string" = picture
#--------------------
Background = 1
#--------------------
# Return_Scene - Scene
# that it goes to when exiting
# the mail
#--------------------
Return_Scene = Scene_Map
#===================================================
# Configure Mail
#---------------------------------------------------
# Add a new line
# Mail[id of mail] = ["title", "sender", "message"]
Mail[1] = ["How goes it?", "Granny", "Hey sonny. Was wondering how you were doing. Be safe and don't die!"]
Mail[2] = ["Help!", "Hooker", "Help me! I was working my corner and I was kidnapped!"]
#===================================================
# End Config
#===================================================
end
class Game_Party
attr_accessor :mail
attr_accessor :mread
alias gg_init_mail_party_lat initialize
def initialize
@mail = []
@mread = []
gg_init_mail_party_lat
end
def add_mail(id)
msg = GGMail::Mail[id]
return if msg == nil
unless @mail.include?(id)
@mail.push(id)
@mread[id] = false
end
end
def take_mail(id)
msg = GGMail::Mail[id]
return if msg == nil
if @mail.include?(id)
@mail.delete(id)
end
end
def mark_read(id)
return if id == nil
msg = GGMail::Mail[id]
return if msg == nil
if @mail.include?(id)
@mread[id] = true
end
end
def mail_read?(id)
return if id == nil
msg = GGMail::Mail[id]
return if msg == nil
return @mread[id]
end
end
class Window_Mail_Help < Window_Base
def initialize
super(16, 16, 576, 96)
self.back_opacity = GGMail::Opacity
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
self.contents.draw_text(0, 0, 576, 32, GGMail::Mail_Word, 1)
self.contents.draw_text(0, 32, 576, 32, GGMail::Action_Message, 1)
end
end
class Bitmap
def format_text(text, width)
words = text.split(' ')
return words if words.size == 1
result, current_text = [], words.shift
words.each_index {|i|
if self.text_size("#{current_text} #{words[i]}").width > width
result.push(current_text)
current_text = words[i]
else
current_text = "#{current_text} #{words[i]}"
end
result.push(current_text) if i >= words.size - 1}
return result
end
end
class Window_Mail_Message < Window_Base
def initialize
super(192 + 16, 96 + 16, 416 - 32, 388 - 32)
self.back_opacity = GGMail::Opacity
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
return if @mail_id == nil
msg = GGMail::Mail[@mail_id]
return if msg == nil
self.contents.clear
w = self.contents.text_size("Title: ").width
w2 = self.contents.text_size("From: ").width
self.contents.font.color = system_color
self.contents.draw_text(0, 0, self.width, 32, "Title: ")
self.contents.draw_text(0, 48, self.width, 32, "From: ")
self.contents.draw_text(0, 96, self.width, 32, "Message: ")
self.contents.font.color = normal_color
self.contents.draw_text(w + 8, 0, self.width, 32, msg[0])
self.contents.draw_text(w2 + 8, 48, self.width, 32, msg[1])
draw_msg(msg[2], 0, 128)
end
def draw_msg(msg, x, y)
text = self.contents.format_text(msg, 392)
text.each_index {|i|
self.contents.draw_text(x, y + i*32, 544, 32, text[i])}
end
def set_mail(id)
return if @mail_id == id
@mail_id = id
refresh
end
end
class Scene_Mail
def main
create_background
@mail = $game_party.mail
@messages = []
@mail.each {|i|
@messages.push(GGMail::Mail[i][0])}
@messages = [""] if @messages.size < 1
@mail_window = Window_Command.new(192, @messages)
@mail_window.x = 16
@mail_window.back_opacity = GGMail::Opacity
@mail_window.height = 388 - 32
@mail_window.y = 96 + 16
j = 0
@mail.each{|i|
if $game_party.mread[i] == false
@mail_window.draw_item(j, GGMail::New_Color)
end
j += 1}
@mail_help = Window_Mail_Help.new
@mail_info = Window_Mail_Message.new
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
@mail_window.dispose
@mail_help.dispose
@mail_info.dispose
if @back != nil
@back.dispose
end
end
def create_background
n = GGMail::Background
if GGMail::Background.is_a?(Integer)
if n == 1
@back = Spriteset_Map.new
end
else
@back = Sprite.new
@back.bitmap = RPG::Cache.picture(n)
end
end
def refresh_command
@messages = []
@mail_window.dispose
@mail_window = nil
@mail.each {|i|
@messages.push(GGMail::Mail[i][0])}
@messages = [""] if @messages.size < 1
@mail_window = Window_Command.new(192, @messages)
@mail_window.x = 16
@mail_window.height = 388 - 32
@mail_window.y = 96 + 16
@mail_window.back_opacity = GGMail::Opacity
j = 0
@mail.each{|i|
if $game_party.mread[i] == false
@mail_window.draw_item(j, GGMail::New_Color)
end
j += 1}
end
def update
@mail_window.update
@mail_help.update
@mail_info.update
@mail_info.set_mail(@mail[@mail_window.index])
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
$scene = GGMail::Return_Scene.new
return
elsif Input.trigger?(Input::C)
$game_system.se_play($data_system.decision_se)
$game_party.mark_read(@mail[@mail_window.index])
refresh_command
return
end
end
end
InstructionsIn the script. Place below Scene_Debug.
CompatibilityNot tested with SDK.
Credits and Thanks
- game_guy ~ For making it
- mattfriends ~ For Requesting it
Author's NotesEnjoy! :D
I thought SBR* requested it.
From pm
QuoteDarth Spy
Basic Member
Level: 0
[Level++] [Level--]
Offline
Gender:
Posts: 14
Light up guys!!
PLEASE HELP!!!
« Sent to: game_guy on: July 30, 2010, 03:51:03 AM »
« You have forwarded or responded to this message. » Quote Reply Remove
Can you give me one script? The script that can storge mails.
Example:
Command:
Mail.add("From","Title","Message")
Screen:
+----------------------------------------------------------------------------------------+
| Mails |
+----------------------------------------------------------------------------------------+
| Title 1 | TITLE: Title 1 |
| Title 2 | |
| Title 3 | FROM: Someone |
| Title 4 | |
| | MESSAGE: |
| | This is Someone and the example message. |
| | |
| | |
| | |
+----------------------------------------------------------------------------------------+
Thank you in advice.
By the looks of things, this is quite a bit like the mail system in Crisis Core, yes?
Actually yea it is. :D Never realized it til now xD
Well done, G_G, this is awesome. For it, I shall consent to being your slave. But you should change the line in your signature to "Is Niche's master"
I might use it at some point, but I think my game has enough scripts in it for the minute.
This is really nice. I don't know if I'm going to use it though, maybe, but I have a feature idea for those who are.
Just as in GTA IV, there could be a Positive Reply and a Negative Reply. And also two call scripts, one for checking if you got an email and one for checking if you have replied to one.
Just an idea, nothing you have to do :D
Ur really a great scripter...
U should make a mail system for RMX-os so u can send mails to other players online in ur friend list or somethin :P
*points to PMs in RMX-OS*
Actually, in me and subs project, I planned on replacing the way you read pms with this. You'll still sends pm's through the chatbox but this way you can read them.
Also planned on making a buddys list for our game.
Other planned things if you care:
Server Status - Tells whether server is on or off (done)
Online Users List - Shows whos online (almost done)
Buddys List
New Inbox
Animation Chat Commands - Type in /sit it'll change your graphic to a sitting one.
Vehicles
Costumes
Minigames
I think I've said too much.
That's something different. That would be wrapping up the PM system and putting it on a GUI. I am all for it.
Quote from: Blizzard on August 01, 2010, 05:09:45 pm
I thought SBR* requested it.
No way! I would've scripted this myself...
I bet. :V:
That said, you could try doing another version of this, like the phone in pokemon or something else you might happen to come up with.
Is it possible to activate any type of switch/variable when the player open a particular PM? If possible, how can I do that (Call Script, editing the script, other?)?
Good work however, level ++! ;)
Updated.
@Nadim: I updated it so you can now use this in a conditional branch
$game_party.mail_read?(id)
If its been read you can turn on a switch or whatever you need. ;D Thanks for the idea
Quote from: Adjutant game_guy on August 04, 2010, 12:37:43 pm
Updated.
@Nadim: I updated it so you can now use this in a conditional branch
$game_party.mail_read?(id)
If its been read you can turn on a switch or whatever you need. ;D Thanks for the idea
Thank you man! Tomorrow I'll try this script and I'll decide to use it or not. Thanks, however! ;)
Okay, it's working. I'm getting this to work slowly xD
this is very nice script but I can't use command like \n[1] or \v[1] in mail box
well, that isn't much matter for me but for suggestion, can you add a function like that in your script? ^^
Nice script *.*
Would it be more cool if npc has the ability of sending you items/gold as well *.*
Quote from: Mimi Chan on October 15, 2010, 11:16:39 am
Nice script *.*
Would it be more cool if npc has the ability of sending you items/gold as well *.*
you could do that manually in event
script : $scene = Scene_Mail.new
change gold : + 400000
so after you close the mail, you'll receive 400000 G
After you close the scene yeah.. But I think she meant that you could send gold and when you open a specific mail, you'll get them. What you do is that no matter what mail you open, you get that money.
not if you use this
Quote$game_party.mail_read?(id)
How do you make the text message wrap so the words in a line would not get cut off?
And how come when pressing ENTER after reading a message, the Mail Title list's window is shrunk?
Your first question, its a small bitmap snippet by Blizzard. Very useful.
class Bitmap
def format_text(text, width)
words = text.split(' ')
return words if words.size == 1
result, current_text = [], words.shift
words.each_index {|i|
if self.text_size("#{current_text} #{words[i]}").width > width
result.push(current_text)
current_text = words[i]
else
current_text = "#{current_text} #{words[i]}"
end
result.push(current_text) if i >= words.size - 1}
return result
end
end
Second, small typo I had when making the script. Its fixed now.
Thanks for the reply, game_guy.
1. I don't understand how the text wrap is used. Could you post any example?
2. The shrunk window is fixed now, but the window is moved a little to the right and into the message window after a mail is selected.
1. Here's an example from the script.
def draw_msg(msg, x, y)
text = self.contents.format_text(msg, 392) #msg is the text it formats, 392 is the max width
text.each_index {|i|
self.contents.draw_text(x, y + i*32, 544, 32, text[i])}
end
2. Fixed.
How can I call this Mail scene from the menu or something like that. That's mean I don't have to create an event to call the script.
Sorry for :n00b: question :haha:
*cough*
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Object Initialization
# menu_index : command cursor's initial position
#--------------------------------------------------------------------------
def initialize(menu_index = 0)
@menu_index = menu_index
end
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Make command window
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "Status"
s5 = "Mail"
s6 = "Save"
s7 = "End Game"
@command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6, s7])
@command_window.index = @menu_index
# If number of party members is 0
if $game_party.actors.size == 0
# Disable items, skills, equipment, and status
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
# If save is forbidden
if $game_system.save_disabled
# Disable save
@command_window.disable_item(4)
end
# Make play time window
@playtime_window = Window_PlayTime.new
@playtime_window.x = 0
@playtime_window.y = 224
# Make steps window
@steps_window = Window_Steps.new
@steps_window.x = 0
@steps_window.y = 320
# Make gold window
@gold_window = Window_Gold.new
@gold_window.x = 0
@gold_window.y = 416
# Make status window
@status_window = Window_MenuStatus.new
@status_window.x = 160
@status_window.y = 0
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@command_window.dispose
@playtime_window.dispose
@steps_window.dispose
@gold_window.dispose
@status_window.dispose
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Update windows
@command_window.update
@playtime_window.update
@steps_window.update
@gold_window.update
@status_window.update
# If command window is active: call update_command
if @command_window.active
update_command
return
end
# If status window is active: call update_status
if @status_window.active
update_status
return
end
end
#--------------------------------------------------------------------------
# * Frame Update (when command window is active)
#--------------------------------------------------------------------------
def update_command
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to map screen
$scene = Scene_Map.new
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# If command other than save or end game, and party members = 0
if $game_party.actors.size == 0 and @command_window.index < 4
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Branch by command window cursor position
case @command_window.index
when 0 # item
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to item screen
$scene = Scene_Item.new
when 1 # skill
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 4 # mail
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Transfer to the mail screen
$scene = Scene_Mail.new
when 5 # save
# If saving is forbidden
if $game_system.save_disabled
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to save screen
$scene = Scene_Save.new
when 6 # end game
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to end game screen
$scene = Scene_End.new
end
return
end
end
#--------------------------------------------------------------------------
# * Frame Update (when status window is active)
#--------------------------------------------------------------------------
def update_status
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Make command window active
@command_window.active = true
@status_window.active = false
@status_window.index = -1
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Branch by command window cursor position
case @command_window.index
when 1 # skill
# If this actor's action limit is 2 or more
if $game_party.actors[@status_window.index].restriction >= 2
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to skill screen
$scene = Scene_Skill.new(@status_window.index)
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to equipment screen
$scene = Scene_Equip.new(@status_window.index)
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to status screen
$scene = Scene_Status.new(@status_window.index)
end
return
end
end
end
*cough*
Line 114 in the Mail script should be set to:
Return_Scene = Scene_Menu
Replace you default menu with that or follow a how to add a option to a menu guide if you have a custom one.
Note the only reason it isn't a snippet is that I don't have time at the moment
I'm sorry for necroposting.. again. :>.<:
But I've been struggling with a problem which I can't seem to overcome.
Quote from: game_guy on August 04, 2010, 12:37:43 pm
Updated.
@Nadim: I updated it so you can now use this in a conditional branch
$game_party.mail_read?(id)
If its been read you can turn on a switch or whatever you need. ;D Thanks for the idea
This feature is great, but the problem is triggering it.
I'm trying to have this script work together with the Quest Log script, also from G_G.
So, I would like an event to run as a result of reading a message.
Problem is, I can't seem to get this to work.
Basically, I want the event to run as soon as the mailbox is closed.
(in this event i'll put some conditional branches for mails being required, which will then add quests to the quest log)
Any idea how to do this?
You could have a parallel process common event that all the time checks if the message have been read, and then just make the event you want to run being within the Conditional Branch. Or if you want a map event to run, have the common event check and it is it true, then make it set a switch to true and have that switch as a startup condition for the desired event.
I did try something similar, but my game froze as a result.
I figured the same would happen if I did it your way, I could be wrong.
Thanks for the suggestion :)
Execute this in the Script Call.
$game_switches[INSERT_ID_HERE] = $game_party.mail_read?(INSERT_ID_HERE)
Thanks a lot, that should do the trick.
I'm sorry for the double post,
but I'm still having a small problem.
Using the script call you gave me, allows me to add quests, but..
I have a message that is normally displayed whenever a quest is added,
but since in this case the quests are added while the mail scene is still active,
no message can be displayed.
Would it be possible to have something occur as soon as the player presses X (B button) and thus leaves the mail scene?
And if so, how?
Anything will do: the running of an event, switch turning on.
Pseudo code here. You could try doing it like this.
Call mail menu
if party.has_quest(id) and switch[id] is off
display message
switch[id] = on
end
Thats the only thing I can think of.
I know I'm necro-posting here, but I found an easier and better solution to the problem I was having.
Figured I'd share it, in case anyone ever has trouble with the same issue.
Just put this after line 301 in the script, that's all.
$game_switches[id] = true
Sorry for necro-posting, guys, I just wanted to ask if there is a way to add an Icon (next to mail's name) for unreaded messages and a different one for readed messages.
Nice script, by the way. 8)
It's very possible. If you can wait a day or two, I can whip it up real fast.
thanks, man, I really aprecciate your help :)