summaryrefslogtreecommitdiff
path: root/src/gui/chat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/chat.cpp')
-rw-r--r--src/gui/chat.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
new file mode 100644
index 00000000..2f0385c9
--- /dev/null
+++ b/src/gui/chat.cpp
@@ -0,0 +1,303 @@
+/**
+
+ The Mana World
+ Copyright 2004 The Mana World Development Team
+
+ This file is part of The Mana World.
+
+ The Mana World is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ The Mana World is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Mana World; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**
+ Simple ChatLog Object v0.5 (i'd say...)
+
+ Bestviewd w/ Bitstream Vera Sans Mono @ 9pt and a tab-width of 2 spaces
+
+ Author: kth5 aka Alexander Baldeck
+ pipe your questions, suggestions and flames to: kth5@gawab.com
+*/
+
+#include "../main.h"
+#include "chat.h"
+#include <list>
+#include <string>
+#include <fstream>
+
+using namespace std;
+
+
+Chat::Chat(const char * logfile, int item_num) {
+ chatlog_file.open(logfile, ios::out | ios::app);
+ items = 0;
+ items_keep = item_num;
+}
+
+Chat::~Chat() {
+ chatlog_file.flush();
+ chatlog_file.close();
+}
+
+void Chat::chat_dlgrsize(int) {
+}
+
+/** adds a line of text to our message list
+
+ string line -> message text
+ int own -> type of message (usually the owner-type)
+ ALFONT_FONT * font -> font that'll be used to draw the text later
+
+ NOTE:
+ to all of you who wonder why the font needs to be passed, simple.
+ i already store the width in pixel in the list rather than
+ calculating it again and again on every draw event. ;-)
+*/
+void Chat::chat_log(string line, int own, ALFONT_FONT * font) {
+ int pos;
+ CHATLOG tmp;
+
+ if(items<=items_keep)
+ items++; // delete overhead from the end of the list
+ else
+ chatlog.pop_back();
+
+ pos = 0;
+ pos = (int)line.find(" : ", 0);
+ if(pos > 0) {
+ tmp.nick = line.substr(0,pos);
+ switch(own) {
+ case ACT_IS :
+ tmp.nick += CAT_IS;
+ break;
+ case ACT_WHISPER :
+ tmp.nick += CAT_WHISPER;
+ break;
+ default :
+ tmp.nick += CAT_NORMAL;
+ }
+ tmp.width = TEXT_GETWIDTH(tmp.nick.c_str())+2;
+ line.erase(0,pos+3);
+ }else {
+ tmp.nick = "";
+ tmp.width = 1;
+ }
+ tmp.own = own;
+ tmp.text = line;
+
+ chatlog_file << tmp.nick << tmp.text << "\n";
+ chatlog_file.flush();
+
+ chatlog.push_front(tmp);
+}
+
+void Chat::chat_log(CHATSKILL action, ALFONT_FONT * font) {
+ chat_log(const_msg(action), BY_SERVER, font);
+}
+
+
+/** draw first n lines of the list onto a Allegro type bitmap buffer
+ using Alfont
+
+ BITMAP * bmp -> Allegro type bitmap buffer to draw onto
+ int n -> number of lines to be drawn
+ ALFONT_FONT * font -> font to use
+
+ NOTE:
+ take great care using this, make sure the buffer passed is
+ empty! ;-) anyway, line wrapping is not supported yet.
+*/
+void Chat::chat_draw(BITMAP * bmp, int n, ALFONT_FONT * font) {
+ int y = 600-35, i = 0;
+ CHATLOG line;
+ n -= 1;
+
+ for(iter = chatlog.begin(); iter != chatlog.end(); iter++) {
+ line = *iter;
+ y -=11;
+
+ switch(line.own) {
+ case BY_GM :
+ alfont_textprintf_aa(bmp, font, 1, y, COLOR_BLUE, "Global announcement: ");
+ alfont_textprintf_aa(bmp, font, TEXT_GETWIDTH("Global announcement: "), y, COLOR_GREEN, line.text.c_str());
+ break;
+ case BY_PLAYER :
+ alfont_textprintf_aa(bmp, font, 1, y, COLOR_YELLOW, line.nick.c_str());
+ alfont_textprintf_aa(bmp, font, line.width, y, COLOR_WHITE, line.text.c_str());
+ break;
+ case BY_OTHER :
+ alfont_textprintf_aa(bmp, font, 1, y, COLOR_GREEN, line.nick.c_str());
+ alfont_textprintf_aa(bmp, font, line.width, y, COLOR_WHITE, line.text.c_str());
+ break;
+ default :
+ alfont_textprintf_aa(bmp, font, 1, y, COLOR_LIGHTBLUE, line.text.c_str());
+ }
+
+ if(i>=n)
+ return;
+ i++;
+ }
+}
+
+/** determines wether to send a command or an ordinary message, then
+ contructs packets & sends them
+
+ string nick -> the character's name to display infront
+ string msg -> the message's text which is to be send.
+
+ NOTE:
+ the nickname is required by the server, if not specified
+ the message may not be sent unless a command was intended
+ which requires another packet to be constructed! you can
+ achieve this by putting a slash ("/") infront of the
+ message followed by the command name and the message.
+ of course all slash-commands need implemented handler-
+ routines. ;-)
+ remember, a line starting w/ "@" is not a command that needs
+ to be parsed rather is sent using the normal chat-packet.
+
+ EXAMPLE:
+ // for an global announcement /- command
+ chatlog.chat_send("", "/announce Hello to all logged in users!");
+ // for simple message by a user /- message
+ chatlog.chat_send("Zaeiru", "Hello to all users on the screen!");
+*/
+char * Chat::chat_send(string nick, string msg) {
+ short len = 0, packid;
+ char *temp = NULL;
+
+ // prepare command
+ if(msg.substr(0,1)=="/") {
+ // global announcement
+ if(msg.substr(0,IS_ANNOUNCE_LENGTH) == IS_ANNOUNCE) {
+ msg.erase(0,IS_ANNOUNCE_LENGTH);
+ packid = 0x0099;
+ } else {
+ packid = 0x008c;
+ len = (short)msg.length()+4;
+ }
+ len = (short)msg.length()+4;
+ // prepare ordinary message
+ } else {
+ // temporary hack to make messed-up-keyboard-ppl able to send GM commands
+ if(msg.substr(0,1)=="#")
+ msg.replace(0,1,"@");
+ // end temp. hack XD
+ nick += " : ";
+ nick += msg;
+ msg = nick;
+ packid = 0x008c;
+ len = (short)(nick.length()+msg.length()+3);
+ }
+
+ // send processed message
+ temp = new char[len];
+ memcpy(temp, msg.c_str(), len);
+ WFIFOW(0) = net_w_value(packid);
+ WFIFOW(2) = net_w_value(len+4);
+ memcpy(WFIFOP(4), temp, len);
+ WFIFOSET(len+4);
+ delete temp;
+ nick = msg = "";
+ return "";
+}
+
+/** PRIVATE :
+ NOTE:
+ these usually will be left undocumented coz u can't call them
+ directly anyway. ;-)
+*/
+
+/** constructs failed messages for actions */
+string Chat::const_msg(CHATSKILL action) {
+ string msg;
+ if(action.success == SKILL_FAILED && action.skill == SKILL_BASIC) {
+ switch(action.bskill) {
+ case BSKILL_TRADE :
+ msg = "Trade failed!";
+ break;
+ case BSKILL_EMOTE :
+ msg = "Emote failed!";
+ break;
+ case BSKILL_SIT :
+ msg = "Sit failed!";
+ break;
+ case BSKILL_CREATECHAT :
+ msg = "Chat creating failed!";
+ break;
+ case BSKILL_JOINPARTY :
+ msg = "Could not join party!";
+ break;
+ case BSKILL_SHOUT :
+ msg = "Cannot shout!";
+ break;
+ }
+
+ switch(action.reason) {
+ case RFAIL_SKILLDEP :
+ msg += " You have not yet reached a high enough lvl!";
+ break;
+ case RFAIL_INSUFHP :
+ msg += " Insufficient HP!";
+ break;
+ case RFAIL_INSUFSP :
+ msg += " Insufficient SP!";
+ break;
+ case RFAIL_NOMEMO :
+ msg += " You have no memos!";
+ break;
+ case RFAIL_SKILLDELAY :
+ msg += " You cannot do that right now!";
+ break;
+ case RFAIL_ZENY :
+ msg += " Seems you need more Zeny... ;-)";
+ break;
+ case RFAIL_WEAPON :
+ msg += " You cannot use this skill with that kind of weapon!";
+ break;
+ case RFAIL_REDGEM :
+ msg += " You need another red gem!";
+ break;
+ case RFAIL_BLUEGEM :
+ msg += " You need another blue gem!";
+ break;
+ case RFAIL_OVERWEIGHT :
+ msg += " You're carrying to much to do this!";
+ break;
+ default :
+ msg += " Huh? What's that?";
+ break;
+ }
+ }else{
+ switch(action.skill) {
+ case SKILL_WARP :
+ msg = "Warp failed...";
+ break;
+ case SKILL_STEAL :
+ msg = "Could not steal anything...";
+ break;
+ case SKILL_ENVENOM :
+ msg = "Poison had no effect...";
+ break;
+ }
+ }
+
+ return msg;
+}
+
+string const_msg(int own) {
+ string msg;
+ return msg;
+}
+