diff options
Diffstat (limited to 'src/gui/chat.cpp')
-rw-r--r-- | src/gui/chat.cpp | 303 |
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; +} + |