summaryrefslogblamecommitdiff
path: root/src/gui/chat.cpp
blob: 9b1d6e4c4f3d4b1ab4d0f6a80b2696f1d46e2a24 (plain) (tree)
1
  


















                                                                             
 
                 
 


                                          


                                                                 
 

   
                                                


                                                              

 

   
               

                         

 

   


                               










                                                                    
  
                                                                    































                                                                
 

                                                 
 
                            

 


                                                                             
                                                           
                                                 


 










                                                                         

                                                               





























                                                                                                                           

 























                                                                    
                                                           












                                                              
            


















                                                                                 
 
 





                                                                

                                             
                                               








































































                                                                              

 
                                

                    
 
/*
 *  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
 */

#include "chat.h"

/*
 * Simple ChatLog Object v0.5 (i'd say...)
 *
 * Author: kth5 aka Alexander Baldeck
 * pipe your questions, suggestions and flames to: kth5@gawab.com
 */

/*
 */
Chat::Chat(const char * logfile, int item_num) {
    chatlog_file.open(logfile, std::ios::out | std::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. Parameters:
 * 
 * line: message text
 * own:  type of message (usually the owner-type)
 * 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(std::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);
}

/*
 * function overload -> calls original chat_log() after processing the packet
 */
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(std::string nick, std::string msg) {
    short packid;

    // 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 if(msg.substr(0,IS_WHERE_LENGTH) == IS_WHERE) {
        } else {
            packid = 0x008c;
        }
        // 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;
    }

    msg += "\0";

    // send processed message
    WFIFOW(0) = net_w_value(packid);
    WFIFOW(2) = net_w_value((unsigned short)(msg.length()+4));
    memcpy(WFIFOP(4), msg.c_str(), msg.length());
    WFIFOSET((int)msg.length()+4);
    nick = msg = "";
    return "";
}

/*
 * PRIVATE :
 * NOTE:
 * these usually will be left undocumented coz u can't call them
 * directly anyway. ;-)
 */

/** constructs failed messages for actions */
std::string Chat::const_msg(CHATSKILL action) {
    std::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;
}

std::string const_msg(int own) {
    std::string msg;
    return msg;
}