diff --git a/conf/atcommand_athena.conf b/conf/atcommand_athena.conf index 5a0a5b289d..67af3b91f1 100644 --- a/conf/atcommand_athena.conf +++ b/conf/atcommand_athena.conf @@ -56,6 +56,7 @@ aliases: { guildstorage: ["gstorage"] accinfo: ["accountinfo"] itemreset: ["clearinventory"] + channel: ["main"] } /* Commands help file */ diff --git a/conf/channels.conf b/conf/channels.conf new file mode 100644 index 0000000000..69c416691e --- /dev/null +++ b/conf/channels.conf @@ -0,0 +1,44 @@ +/* Channel system configuration file */ + +chsys: ( +{ + /* Default channels (available to all players) */ + default_channels: { + /* channel_name : channel_messages_color */ + main: "Orange" + support: "Blue" + trade: "Red" + offtopic: "Cyan" + /* Add as many channels as you'd like. */ + } + + /* Colors available */ + colors: { + Default: "0xffffff" /* Custom channels will use the first in the list unless a font is selected through @channel. */ + Red: "0xff0000" + Blue: "0x83cfe9" + Orange: "0xe57c00" + Cyan: "0x00b89d" + Yellow: "0xffff90" + Green: "0x28bf00" + Normal: "0x00ff00" + /* Add as many channels as you'd like. */ + } + + /* Allow users to create their own (private) channels through @channels command? */ + /* (must also allow players to use @channels in groups.conf) */ + allow_user_channel_creation: true + + /* "map_local_channel" is an instanced channel unique to each map. */ + map_local_channel: true + map_local_channel_name: "map" + map_local_channel_color: "Yellow" + map_local_channel_autojoin: true /* Disable autojoin in specific maps through mapflag 'nomapchannelautojoin'. */ + + /* "ally_channel" is a channel shared by all your guild allies. */ + ally_channel_enabled: true + ally_channel_name: "ally" + ally_channel_color: "Green" + ally_channel_autojoin: true +} +) diff --git a/conf/groups.conf b/conf/groups.conf index a243716e63..0a641395aa 100644 --- a/conf/groups.conf +++ b/conf/groups.conf @@ -123,13 +123,13 @@ groups: ( refresh: true noask: true noks: true - main: true autoloot: true alootid: true autotrade: true request: true go: true breakguild: true + channel: true } permissions: { } @@ -272,6 +272,7 @@ groups: ( use_check: true use_changemaptype: true all_commands: true + channel_admin: true } } ) diff --git a/conf/help.txt b/conf/help.txt index d23d037f24..51337126ad 100644 --- a/conf/help.txt +++ b/conf/help.txt @@ -6,7 +6,6 @@ // This file uses libconfig syntax. help: "Params: \n" "Shows help for specified command." -main: "Params: [on|off|]\n" "Turns on or off main (server-wide) chat. Sends message to main chat." noask: "Auto rejects deals/invites." gmotd: "Broadcasts the Message of The Day to all players." me: "Params: \n" "Displays normal text as a message in this format: *name message* (like /me in mIRC)." diff --git a/conf/inter_athena.conf b/conf/inter_athena.conf index 77986d5a87..9d1442b7cb 100644 --- a/conf/inter_athena.conf +++ b/conf/inter_athena.conf @@ -116,7 +116,4 @@ mapreg_db: mapreg // Use SQL item_db, mob_db and mob_skill_db for the map server? (yes/no) use_sql_db: no -// Nick for sending main chat messages, similar to a whisper. -main_chat_nick: Main - import: conf/import/inter_conf.txt diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index 9ac5794445..d57f5e4df9 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -1410,5 +1410,46 @@ // @skillid (extension) 1398: -- Displaying first %d partial matches: +// @join +1399: Unknown Channel (usage: %s <#channel_name>) +1400: Unknown Channel '%s' (usage: %s <#channel_name>) +1401: '%s' Channel is password protected (usage: %s <#channel_name> ) +1402: You're not in that channel, type '@join <#channel_name>' +1403: You're now in the '%s' channel. + +// @channel +1404: %s failed. +1405: Channel name must start with '#'. +1406: Channel length must be between 3 and %d. +1407: Channel '%s' is not available. +1408: Channel password may not contain spaces. +1409: - #%s (%d users) +1410: ---- Public Channels ---- +1411: Unknown color '%s'. +1412: You're not the owner of channel '%s'. +1413: '%s' channel color updated to '%s'. +1414: ---- Available options: +1415: * %s create <#channel_name> +1416: -- Creates a new channel. +1417: * %s list +1418: -- Lists all public channels. +1419: * %s list colors +1420: -- Lists all available colors for custom channels. +1421: * %s setcolor <#channel_name> +1422: -- Changes channel text to the specified color (channel owners only). +1423: * %s leave <#channel_name> +1424: -- Leaves the specified channel. +1425: You're not part of the '%s' channel. +1426: You've left the '%s' channel. +1427: * %s bindto <#channel_name> +1428: -- Binds your global chat to the specified channel, sending all global messages to that channel. +1429: * %s unbind +1430: -- Unbinds your global chat from the attached channel, if any. +1431: Your global chat is now binded to the '%s' channel. +1432: Your global chat is not binded to any channel. +1433: Your global chat is now unbinded from the '#%s' channel. +1434: You're already in the '%s' channel. +1435: You're now in the '#%s' channel for '%s'. + //Custom translations import: conf/import/msg_conf.txt diff --git a/doc/atcommands.txt b/doc/atcommands.txt index a0afa043c4..ce0591bea6 100644 --- a/doc/atcommands.txt +++ b/doc/atcommands.txt @@ -24,6 +24,7 @@ The format of this file is as follows: 7. Guild Commands 8. Pet Commands 9. Homunculus Commands + 10. Channel Commands ====================== | 1. System Commands | @@ -537,13 +538,6 @@ Displays the text as a normal message with the format "*name *" instead --------------------------------------- -@main {} - -Broadcasts a message to all players with @main enabled. -Using the command without a message will enable or disable main chat. - ---------------------------------------- - @storage Opens your Kafra storage. @@ -1428,4 +1422,53 @@ Sets the intimacy level of your homunculus, with 1000 being "Loyal". Sets the hunger level of your homunculus, with 100 being "Stuffed". ---------------------------------------- \ No newline at end of file +--------------------------------------- + +======================== +| 10. Channel Commands | +======================== + +@join <#channel_name> {} + +Joins the specified channel. + +--------------------------------------- + +@channel create <#channel_name> + +Creates a new channel. +'allow_user_channel_creation' must be enabled in '/conf/channels.conf'. + +--------------------------------------- + +@channel list + +Displays a list of all public channels. + +--------------------------------------- + +@channel list colors + +Displays a list of all available colors for custom channels. + +--------------------------------------- + +@channel setcolor <#channel_name> + +Changes the text color of the specified channel. +You must either be the channel's owner or have the channel_admin permission. + +--------------------------------------- + +@channel leave <#channel_name> + +Leaves the specified channel. + +--------------------------------------- + +@channel bindto <#channel_name> +@channel unbind + +Binds or unbinds your global chat with the specified channel, which sends all global messages to the specified channel. + +--------------------------------------- diff --git a/doc/permissions.txt b/doc/permissions.txt index 129d384f4f..bdf8a048f6 100644 --- a/doc/permissions.txt +++ b/doc/permissions.txt @@ -3,7 +3,7 @@ //===== By: ================================================== //= rAthena Dev Team //===== Current Version: ===================================== -//= 20120606 +//= 20130402 //===== Description: ========================================= //= Player group permissions, configured in /conf/groups.conf. //============================================================ @@ -30,4 +30,6 @@ receive_requests : Ability to receive @requests. show_bossmobs : Ability to see boss mobs with @showmobs. disable_pvm : Ability to disable Player vs. Monster. disable_pvp : Ability to disable Player vs. Player. -disable_commands_when_dead : Ability to disable @command usage when dead. \ No newline at end of file +disable_commands_when_dead : Ability to disable @command usage when dead. +channel_admin : Ability to modify channel settings regardless of ownership and join password-protected + channels without a password. \ No newline at end of file diff --git a/src/char/char.c b/src/char/char.c index e0359499b4..8318a32be1 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1484,7 +1484,7 @@ int check_char_name(char * name, char * esc_name) return -2; // control chars in name // check for reserved names - if( strcmpi(name, main_chat_nick) == 0 || strcmpi(name, wisp_server_name) == 0 ) + if( strcmpi(name, wisp_server_name) == 0 ) return -1; // nick reserved for internal server messages // Check Authorised letters/symbols in the name of the character diff --git a/src/char/inter.c b/src/char/inter.c index 3cba1ae691..18d17c4553 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -43,7 +43,6 @@ char default_codepage[32] = ""; //Feature by irmin. static struct accreg *accreg_pt; unsigned int party_share_level = 10; -char main_chat_nick[16] = "Main"; // recv. packet list int inter_recv_packet_length[] = { @@ -667,8 +666,6 @@ static int inter_config_read(const char* cfgName) party_share_level = atoi(w2); else if(!strcmpi(w1,"log_inter")) log_inter = atoi(w2); - else if(!strcmpi(w1,"main_chat_nick")) - safestrncpy(main_chat_nick, w2, sizeof(main_chat_nick)); else if(!strcmpi(w1,"import")) inter_config_read(w2); } diff --git a/src/char/inter.h b/src/char/inter.h index 7ea9cf25cb..628e9f1f34 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -23,8 +23,6 @@ extern unsigned int party_share_level; extern Sql* sql_handle; extern Sql* lsql_handle; -extern char main_chat_nick[16]; - int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type); uint64 inter_chk_lastuid(int8 flag, uint64 value); diff --git a/src/common/mmo.h b/src/common/mmo.h index a213d75336..8b3d89b571 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -5,6 +5,7 @@ #define _MMO_H_ #include "cbasetypes.h" +#include "../common/db.h" #include // server->client protocol version @@ -514,7 +515,9 @@ struct guild { struct guild_expulsion expulsion[MAX_GUILDEXPULSION]; struct guild_skill skill[MAX_GUILDSKILL]; + /* TODO: still used for something? */ unsigned short save_flag; // for TXT saving + void *channel; }; struct guild_castle { diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 005fc3512f..5788b91700 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -597,7 +597,7 @@ ACMD_FUNC(who) } default: { struct party_data *p = party_search(pl_sd->status.party_id); - struct guild *g = guild_search(pl_sd->status.guild_id); + struct guild *g = pl_sd->guild; StringBuf_Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s " if (pc_get_group_id(pl_sd) > 0) // Player title, if exists @@ -700,7 +700,7 @@ ACMD_FUNC(whogm) clif_displaymessage(fd, atcmd_output); p = party_search(pl_sd->status.party_id); - g = guild_search(pl_sd->status.guild_id); + g = pl_sd->guild; sprintf(atcmd_output,msg_txt(916), // Party: '%s' | Guild: '%s' p?p->party.name:msg_txt(917), g?g->name:msg_txt(917)); // None. @@ -3244,7 +3244,7 @@ ACMD_FUNC(breakguild) if (sd->status.guild_id) { // Check if the player has a guild struct guild *g; - g = guild_search(sd->status.guild_id); // Search the guild + g = sd->guild; // Search the guild if (g) { // Check if guild was found if (sd->state.gmaster_flag) { // Check if player is guild master int ret = 0; @@ -5246,7 +5246,7 @@ ACMD_FUNC(cleargstorage) struct guild_storage *gstorage; nullpo_retr(-1, sd); - g = guild_search(sd->status.guild_id); + g = sd->guild; if (g == NULL) { clif_displaymessage(fd, msg_txt(43)); @@ -6163,7 +6163,7 @@ ACMD_FUNC(npctalk) snprintf(temp, sizeof(temp), "%s : %s", name, mes); if(ifcolor) clif_messagecolor(&nd->bl,color,temp); - else clif_message(&nd->bl, temp); + else clif_disp_overhead(&nd->bl, temp); return 0; } @@ -6227,7 +6227,7 @@ ACMD_FUNC(pettalk) } snprintf(temp, sizeof temp ,"%s : %s", pd->pet.name, mes); - clif_message(&pd->bl, temp); + clif_disp_overhead(&pd->bl, temp); return 0; } @@ -7017,7 +7017,7 @@ ACMD_FUNC(homtalk) } snprintf(temp, sizeof temp ,"%s : %s", sd->hd->homunculus.name, mes); - clif_message(&sd->hd->bl, temp); + clif_disp_overhead(&sd->hd->bl, temp); return 0; } @@ -7399,7 +7399,7 @@ ACMD_FUNC(me) } sprintf(atcmd_output, msg_txt(270), sd->status.name, tempmes); // *%s %s* - clif_disp_overhead(sd, atcmd_output); + clif_disp_overhead(&sd->bl, atcmd_output); return 0; @@ -7944,58 +7944,6 @@ ACMD_FUNC(clone) return 0; } -/*=================================== - * Main chat [LuzZza] - * Usage: @main - *-----------------------------------*/ -ACMD_FUNC(main) -{ - if( message[0] ) { - - if(strcmpi(message, "on") == 0) { - if(!sd->state.mainchat) { - sd->state.mainchat = 1; - clif_displaymessage(fd, msg_txt(380)); // Main chat has been activated. - } else { - clif_displaymessage(fd, msg_txt(381)); // Main chat already activated. - } - } else if(strcmpi(message, "off") == 0) { - if(sd->state.mainchat) { - sd->state.mainchat = 0; - clif_displaymessage(fd, msg_txt(382)); // Main chat has been disabled. - } else { - clif_displaymessage(fd, msg_txt(383)); // Main chat already disabled. - } - } else { - if(!sd->state.mainchat) { - sd->state.mainchat = 1; - clif_displaymessage(fd, msg_txt(380)); // Main chat has been activated. - } - if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) { - clif_displaymessage(fd, msg_txt(387)); - return -1; - } - - if ( battle_config.min_chat_delay ) { - if( DIFF_TICK(sd->cantalk_tick, gettick()) > 0 ) - return 0; - sd->cantalk_tick = gettick() + battle_config.min_chat_delay; - } - - // send the message using inter-server system - intif_main_message( sd, message ); - } - - } else { - - if(sd->state.mainchat) - clif_displaymessage(fd, msg_txt(384)); // Main chat currently enabled. Usage: @main , @main . - else - clif_displaymessage(fd, msg_txt(385)); // Main chat currently disabled. Usage: @main , @main . - } - return 0; -} - /*===================================== * Autorejecting Invites/Deals [LuzZza] * Usage: @noask @@ -8796,6 +8744,300 @@ ACMD_FUNC(cart) { #undef MC_CART_MDFY } +/* Channel System [Ind] */ +ACMD_FUNC(join) { + struct raChSysCh *channel; + char name[RACHSYS_NAME_LENGTH], pass[RACHSYS_NAME_LENGTH]; + DBMap* channel_db = clif_get_channel_db(); + + if( !message || !*message || sscanf(message, "%s %s", name, pass) < 1 ) { + sprintf(atcmd_output, msg_txt(1399),command); // Unknown Channel (usage: %s <#channel_name>) + clif_displaymessage(fd, atcmd_output); + return -1; + } + if( raChSys.local && strcmpi(name + 1, raChSys.local_name) == 0 ) { + if( !map[sd->bl.m].channel ) { + clif_chsys_mjoin(sd); + return 0; + } else + channel = map[sd->bl.m].channel; + } else if( raChSys.ally && sd->status.guild_id && strcmpi(name + 1, raChSys.ally_name) == 0 ) { + struct guild *g = sd->guild; + if( !g ) return -1;/* unlikely, but we wont let it crash anyway. */ + channel = (struct raChSysCh *)g->channel; + } else if( !( channel = strdb_get(channel_db, name + 1) ) ) { + sprintf(atcmd_output, msg_txt(1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>) + clif_displaymessage(fd, atcmd_output); + return -1; + } + + if( idb_exists(channel->users, sd->status.char_id) ) { + sprintf(atcmd_output, msg_txt(1434),name); // You're already in the '%s' channel. + clif_displaymessage(fd, atcmd_output); + return -1; + } + if( channel->pass[0] != '\0' && strcmp(channel->pass,pass) != 0 ) { + if( pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) { + sd->stealth = true; + } else { + sprintf(atcmd_output, msg_txt(1401),name,command); // '%s' Channel is password protected (usage: %s <#channel_name> ) + clif_displaymessage(fd, atcmd_output); + return -1; + } + } + + if( !( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) { + sprintf(atcmd_output, msg_txt(1403),name); // You're now in the '%s' channel. + clif_displaymessage(fd, atcmd_output); + } + + clif_chsys_join(channel,sd); + + return 0; +} + +inline void atcmd_channel_help(int fd, const char *command, bool can_create) { + clif_displaymessage(fd, msg_txt(1414));// ---- Available options: + if( can_create ) { + sprintf(atcmd_output, msg_txt(1415),command);// * %s create <#channel_name> + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, msg_txt(1416));// -- Creates a new channel. + } + sprintf(atcmd_output, msg_txt(1417),command);// * %s list + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, msg_txt(1418));// -- Lists all public channels. + if( can_create ) { + sprintf(atcmd_output, msg_txt(1419),command);// * %s list colors + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, msg_txt(1420));// -- Lists all available colors for custom channels. + sprintf(atcmd_output, msg_txt(1421),command);// * %s setcolor <#channel_name> + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, msg_txt(1422));// -- Changes channel text to the specified color (channel owners only). + } + sprintf(atcmd_output, msg_txt(1423),command);// * %s leave <#channel_name> + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, msg_txt(1424));// -- Leaves the specified channel. + sprintf(atcmd_output, msg_txt(1427),command);// * %s bindto <#channel_name> + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, msg_txt(1428));// -- Binds your global chat to the specified channel, sending all global messages to that channel. + sprintf(atcmd_output, msg_txt(1429),command);// * %s unbind + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, msg_txt(1430));// -- Unbinds your global chat from the attached channel, if any. + sprintf(atcmd_output, msg_txt(1404),command); // %s failed. + clif_displaymessage(fd, atcmd_output); +} + +ACMD_FUNC(channel) { + struct raChSysCh *channel; + char key[RACHSYS_NAME_LENGTH], sub1[RACHSYS_NAME_LENGTH], sub2[RACHSYS_NAME_LENGTH], sub3[RACHSYS_NAME_LENGTH]; + unsigned char k = 0; + DBMap* channel_db = clif_get_channel_db(); + sub1[0] = sub2[0] = sub3[0] = '\0'; + + if( !message || !*message || sscanf(message, "%s %s %s %s", key, sub1, sub2, sub3) < 1 ) { + atcmd_channel_help(fd,command,( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) )); + return 0; + } + + if( strcmpi(key,"create") == 0 && ( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) ) { + if( sub1[0] != '#' ) { + clif_displaymessage(fd, msg_txt(1405));// Channel name must start with '#'. + return -1; + } else if ( strlen(sub1) < 3 || strlen(sub1) > RACHSYS_NAME_LENGTH ) { + sprintf(atcmd_output, msg_txt(1406), RACHSYS_NAME_LENGTH);// Channel length must be between 3 and %d. + clif_displaymessage(fd, atcmd_output); + return -1; + } else if ( sub3[0] != '\0' ) { + clif_displaymessage(fd, msg_txt(1408)); // Channel password may not contain spaces. + return -1; + } + if( strcmpi(sub1 + 1,raChSys.local_name) == 0 || strcmpi(sub1 + 1,raChSys.ally_name) == 0 || strdb_exists(channel_db, sub1 + 1) ) { + sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available. + clif_displaymessage(fd, atcmd_output); + return -1; + } + + CREATE( channel, struct raChSysCh, 1 ); + + clif_chsys_create(channel,sub1 + 1,sub2,0); + + channel->owner = sd->status.char_id; + channel->type = raChSys_PRIVATE; + + if( !( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) { + sprintf(atcmd_output, msg_txt(1403),sub1); // You're now in the '%s' channel. + clif_displaymessage(fd, atcmd_output); + } + + clif_chsys_join(channel,sd); + + } else if ( strcmpi(key,"list") == 0 ) { + if( sub1[0] != '\0' && strcmpi(sub1,"colors") == 0 ) { + char mout[40]; + for( k = 0; k < raChSys.colors_count; k++ ) { + unsigned short msg_len = 1; + msg_len += sprintf(mout, "[ %s list colors ] : %s",command,raChSys.colors_name[k]); + + WFIFOHEAD(fd,msg_len + 12); + WFIFOW(fd,0) = 0x2C1; + WFIFOW(fd,2) = msg_len + 12; + WFIFOL(fd,4) = 0; + WFIFOL(fd,8) = raChSys.colors[k]; + safestrncpy((char*)WFIFOP(fd,12), mout, msg_len); + WFIFOSET(fd, msg_len + 12); + } + } else { + DBIterator *iter = db_iterator(channel_db); + bool show_all = pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ? true : false; + clif_displaymessage(fd, msg_txt(1410)); // ---- Public Channels ---- + if( raChSys.local ) { + sprintf(atcmd_output, msg_txt(1409), raChSys.local_name, map[sd->bl.m].channel ? db_size(map[sd->bl.m].channel->users) : 0);// - #%s ( %d users ) + clif_displaymessage(fd, atcmd_output); + } + if( raChSys.ally && sd->status.guild_id ) { + struct guild *g = sd->guild; + if( !g ) return -1; + sprintf(atcmd_output, msg_txt(1409), raChSys.ally_name, db_size(((struct raChSysCh *)g->channel)->users));// - #%s ( %d users ) + clif_displaymessage(fd, atcmd_output); + } + for(channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) { + if( show_all || channel->type == raChSys_PUBLIC ) { + sprintf(atcmd_output, msg_txt(1409), channel->name, db_size(channel->users));// - #%s (%d users) + clif_displaymessage(fd, atcmd_output); + } + } + dbi_destroy(iter); + } + } else if ( strcmpi(key,"setcolor") == 0 ) { + + if( sub1[0] != '#' ) { + clif_displaymessage(fd, msg_txt(1405));// Channel name must start with '#'. + return -1; + } + + if( !(channel = strdb_get(channel_db, sub1 + 1)) ) { + sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available. + clif_displaymessage(fd, atcmd_output); + return -1; + } + + if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) { + sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s'. + clif_displaymessage(fd, atcmd_output); + return -1; + } + + for( k = 0; k < raChSys.colors_count; k++ ) { + if( strcmpi(sub2,raChSys.colors_name[k]) == 0 ) + break; + } + if( k == raChSys.colors_count ) { + sprintf(atcmd_output, msg_txt(1411), sub2);// Unknown color '%s'. + clif_displaymessage(fd, atcmd_output); + return -1; + } + channel->color = k; + sprintf(atcmd_output, msg_txt(1413),sub1,raChSys.colors_name[k]);// '%s' channel color updated to '%s'. + clif_displaymessage(fd, atcmd_output); + } else if ( strcmpi(key,"leave") == 0 ) { + + if( sub1[0] != '#' ) { + clif_displaymessage(fd, msg_txt(1405));// Channel name must start with '#'. + return -1; + } + + for(k = 0; k < sd->channel_count; k++) { + if( strcmpi(sub1+1,sd->channels[k]->name) == 0 ) + break; + } + if( k == sd->channel_count ) { + sprintf(atcmd_output, msg_txt(1425),sub1);// You're not part of the '%s' channel. + clif_displaymessage(fd, atcmd_output); + return -1; + } + clif_chsys_left(sd->channels[k],sd); + sprintf(atcmd_output, msg_txt(1426),sub1); // You've left the '%s' channel. + clif_displaymessage(fd, atcmd_output); + } else if ( strcmpi(key,"bindto") == 0 ) { + + if( sub1[0] != '#' ) { + clif_displaymessage(fd, msg_txt(1405));// Channel name must start with '#'. + return -1; + } + + for(k = 0; k < sd->channel_count; k++) { + if( strcmpi(sub1+1,sd->channels[k]->name) == 0 ) + break; + } + if( k == sd->channel_count ) { + sprintf(atcmd_output, msg_txt(1425),sub1);// You're not part of the '%s' channel. + clif_displaymessage(fd, atcmd_output); + return -1; + } + + sd->gcbind = sd->channels[k]; + sprintf(atcmd_output, msg_txt(1431),sub1); // Your global chat is now binded to the '%s' channel. + clif_displaymessage(fd, atcmd_output); + } else if ( strcmpi(key,"unbind") == 0 ) { + + if( sd->gcbind == NULL ) { + clif_displaymessage(fd, msg_txt(1432));// Your global chat is not binded to any channel. + return -1; + } + + sprintf(atcmd_output, msg_txt(1433),sd->gcbind->name); // Your global chat is now unbinded from the '#%s' channel. + clif_displaymessage(fd, atcmd_output); + + sd->gcbind = NULL; + } else { + atcmd_channel_help(fd,command,( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) )); + } + + return 0; +} +/* debug only, delete after */ +ACMD_FUNC(fontcolor) { + unsigned char k; + + if( !message || !*message ) { + char mout[40]; + for( k = 0; k < raChSys.colors_count; k++ ) { + unsigned short msg_len = 1; + msg_len += sprintf(mout, "[ %s ] : %s",command,raChSys.colors_name[k]); + + WFIFOHEAD(fd,msg_len + 12); + WFIFOW(fd,0) = 0x2C1; + WFIFOW(fd,2) = msg_len + 12; + WFIFOL(fd,4) = 0; + WFIFOL(fd,8) = raChSys.colors[k]; + safestrncpy((char*)WFIFOP(fd,12), mout, msg_len); + WFIFOSET(fd, msg_len + 12); + } + return -1; + } + + if( message[0] == '0' ) { + sd->fontcolor = 0; + pc_disguise(sd,0); + return 0; + } + + for( k = 0; k < raChSys.colors_count; k++ ) { + if( strcmpi(message,raChSys.colors_name[k]) == 0 ) + break; + } + if( k == raChSys.colors_count ) { + sprintf(atcmd_output, msg_txt(1411), message);// Unknown color '%s'. + clif_displaymessage(fd, atcmd_output); + return -1; + } + + sd->fontcolor = k + 1; + pc_disguise(sd,sd->status.class_); + + return 0; +} + /** * Fills the reference of available commands in atcommand DBMap **/ @@ -9008,7 +9250,6 @@ void atcommand_basecommands(void) { ACMD_DEF(leave), ACMD_DEF(accept), ACMD_DEF(reject), - ACMD_DEF(main), ACMD_DEF(clone), ACMD_DEF2("slaveclone", clone), ACMD_DEF2("evilclone", clone), @@ -9056,7 +9297,10 @@ void atcommand_basecommands(void) { ACMD_DEF2("rmvperm", addperm), ACMD_DEF(unloadnpcfile), ACMD_DEF(cart), - ACMD_DEF(mount2) + ACMD_DEF(mount2), + ACMD_DEF(join), + ACMD_DEF(channel), + ACMD_DEF(fontcolor) }; AtCommandInfo* atcommand; int i; diff --git a/src/map/battle.c b/src/map/battle.c index 166212bf0f..74ab997c1c 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1326,7 +1326,7 @@ int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int dama } } if(src->type != BL_MOB) { - struct guild *g = guild_search(status_get_guild_id(src)); + struct guild *g = src->type == BL_PC ? ((TBL_PC *)src)->guild : guild_search(status_get_guild_id(src)); if (class_ == MOBID_EMPERIUM && (!g || guild_checkskill(g,GD_APPROVAL) <= 0 )) return 0; diff --git a/src/map/clif.c b/src/map/clif.c index 3d29764e23..3864c3b330 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -12,6 +12,7 @@ #include "../common/strlib.h" #include "../common/utils.h" #include "../common/ers.h" +#include "../common/conf.h" #include "map.h" #include "chrif.h" @@ -51,6 +52,8 @@ /* for clif_clearunit_delayed */ static struct eri *delay_clearunit_ers; +static DBMap* channel_db; // channels +DBMap* clif_get_channel_db(void){ return channel_db; } //#define DUMP_UNKNOWN_PACKET //#define DUMP_INVALID_PACKET @@ -260,7 +263,7 @@ uint16 clif_getport(void) #if PACKETVER >= 20071106 static inline unsigned char clif_bl_type(struct block_list *bl) { switch (bl->type) { - case BL_PC: return disguised(bl)?0x1:0x0; //PC_TYPE + case BL_PC: return disguised(bl) && pcdb_checkid(status_get_viewdata(bl)->class_)? 0x1:0x0; //PC_TYPE case BL_ITEM: return 0x2; //ITEM_TYPE case BL_SKILL: return 0x3; //SKILL_TYPE case BL_CHAT: return 0x4; //UNKNOWN_TYPE @@ -366,7 +369,7 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd; struct s_mapiterator* iter; - if( type != ALL_CLIENT && type != CHAT_MAINCHAT ) + if( type != ALL_CLIENT ) nullpo_ret(bl); sd = BL_CAST(BL_PC, bl); @@ -441,20 +444,6 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target } break; - case CHAT_MAINCHAT: //[LuzZza] - iter = mapit_getallusers(); - while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL ) - { - if( tsd->state.mainchat && tsd->chatID == 0 && packet_db[tsd->packet_ver][RBUFW(buf,0)].len ) - { // packet must exist for the client version - WFIFOHEAD(tsd->fd, len); - memcpy(WFIFOP(tsd->fd,0), buf, len); - WFIFOSET(tsd->fd,len); - } - } - mapit_free(iter); - break; - case PARTY_AREA: case PARTY_AREA_WOS: x0 = bl->x - AREA_SIZE; @@ -549,7 +538,7 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target case GUILD_WOS: case GUILD_NOBG: if (sd && sd->status.guild_id) - g = guild_search(sd->status.guild_id); + g = sd->guild; if (g) { for(i = 0; i < g->max_member; i++) { @@ -893,16 +882,11 @@ void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, un //To make the assignation of the level based on limits clearer/easier. [Skotlex] static int clif_setlevel_sub(int lv) { - if( lv < battle_config.max_lv ) - { + if( lv < battle_config.max_lv ) { ; - } - else if( lv < battle_config.aura_lv ) - { + } else if( lv < battle_config.aura_lv ) { lv = battle_config.max_lv - 1; - } - else - { + } else { lv = battle_config.max_lv; } @@ -914,8 +898,7 @@ static int clif_setlevel(struct block_list* bl) int lv = status_get_lv(bl); if( battle_config.client_limit_unit_lv&bl->type ) return clif_setlevel_sub(lv); - switch( bl->type ) - { + switch( bl->type ) { case BL_NPC: case BL_PET: // npcs and pets do not have level @@ -1274,10 +1257,6 @@ static void clif_weather_check(struct map_session_data *sd) || map[m].flag.fireworks || map[m].flag.sakura || map[m].flag.leaves - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //|| map[m].flag.rain || map[m].flag.clouds2) { if (map[m].flag.snow) @@ -2061,7 +2040,6 @@ void clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, in WFIFOSET(fd,packet_len(0x144)); } - /// Displays an illustration image. /// 0145 .16B .B (ZC_SHOW_IMAGE) /// 01b3 .64B .B (ZC_SHOW_IMAGE2) @@ -4519,8 +4497,7 @@ int clif_outsight(struct block_list *bl,va_list ap) sd = BL_CAST(BL_PC, bl); tsd = BL_CAST(BL_PC, tbl); - if (tsd && tsd->fd) - { //tsd has lost sight of the bl object. + if (tsd && tsd->fd) { //tsd has lost sight of the bl object. switch(bl->type){ case BL_PC: if (sd->vd.class_ != INVISIBLE_CLASS) @@ -4552,8 +4529,7 @@ int clif_outsight(struct block_list *bl,va_list ap) break; } } - if (sd && sd->fd) - { //sd is watching tbl go out of view. + if (sd && sd->fd) { //sd is watching tbl go out of view. if (((vd=status_get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS) && !(tbl->type == BL_NPC && (((TBL_NPC*)tbl)->sc.option&OPTION_INVISIBLE))) clif_clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd); @@ -4575,8 +4551,7 @@ int clif_insight(struct block_list *bl,va_list ap) sd = BL_CAST(BL_PC, bl); tsd = BL_CAST(BL_PC, tbl); - if (tsd && tsd->fd) - { //Tell tsd that bl entered into his view + if (tsd && tsd->fd) { //Tell tsd that bl entered into his view switch(bl->type){ case BL_ITEM: clif_getareachar_item(tsd,(struct flooritem_data*)bl); @@ -4589,8 +4564,7 @@ int clif_insight(struct block_list *bl,va_list ap) break; } } - if (sd && sd->fd) - { //Tell sd that tbl walked into his view + if (sd && sd->fd) { //Tell sd that tbl walked into his view clif_getareachar_unit(sd,tbl); } return 0; @@ -5460,27 +5434,6 @@ void clif_GlobalMessage(struct block_list* bl, const char* message) { } -/*========================================== - * Send main chat message [LuzZza] - *------------------------------------------*/ -void clif_MainChatMessage(const char* message) { - uint8 buf[200]; - int len; - - if(!message) - return; - - len = strlen(message)+1; - if (len+8 > sizeof(buf)) { - ShowDebug("clif_MainChatMessage: Received message too long (len %d): %s\n", len, message); - len = sizeof(buf)-8; - } - WBUFW(buf,0)=0x8d; - WBUFW(buf,2)=len+8; - WBUFL(buf,4)=0; - safestrncpy((char *) WBUFP(buf,8),message,len); - clif_send(buf,WBUFW(buf,2),NULL,CHAT_MAINCHAT); -} /// Send broadcast message with font formatting (ZC_BROADCAST2). /// 01c3 .W .L .W .W .W .W .?B @@ -5502,6 +5455,304 @@ void clif_broadcast2(struct block_list* bl, const char* mes, int len, unsigned l aFree(buf); } +/*========================================== + * Channel System + *------------------------------------------*/ +void clif_chsys_create(struct raChSysCh *channel, char *name, char *pass, unsigned char color) { + channel->users = idb_alloc(DB_OPT_BASE); + if( name ) + safestrncpy(channel->name, name, RACHSYS_NAME_LENGTH); + channel->color = color; + if( !pass ) + channel->pass[0] = '\0'; + else + safestrncpy(channel->pass, pass, RACHSYS_NAME_LENGTH); + + channel->opt = raChSys_OPT_BASE; + + if( channel->type != raChSys_MAP && channel->type != raChSys_ALLY ) + strdb_put(channel_db, channel->name, channel); +} + +void clif_chsys_join(struct raChSysCh *channel, struct map_session_data *sd) { + RECREATE(sd->channels, struct raChSysCh *, ++sd->channel_count); + sd->channels[ sd->channel_count - 1 ] = channel; + idb_put(channel->users, sd->status.char_id, sd); + + if( sd->stealth ) { + sd->stealth = false; + } else if( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) { + char message[60]; + sprintf(message, "#%s '%s' joined",channel->name,sd->status.name); + clif_chsys_msg(channel,sd,message); + } + + /* someone is cheating, we kindly disconnect the bastard */ + if( sd->channel_count > 200 ) { + set_eof(sd->fd); + } +} + +void clif_chsys_send(struct raChSysCh *channel, struct map_session_data *sd, char *msg) { + char message[150]; + snprintf(message, 150, "[ #%s ] %s : %s",channel->name,sd->status.name, msg); + clif_chsys_msg(channel,sd,message); +} + +void clif_chsys_msg(struct raChSysCh *channel, struct map_session_data *sd, char *msg) { + DBIterator *iter = db_iterator(channel->users); + struct map_session_data *user; + unsigned short msg_len = strlen(msg) + 1; + + WFIFOHEAD(sd->fd,msg_len + 12); + WFIFOW(sd->fd,0) = 0x2C1; + WFIFOW(sd->fd,2) = msg_len + 12; + WFIFOL(sd->fd,4) = 0; + WFIFOL(sd->fd,8) = raChSys.colors[channel->color]; + safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len); + + for( user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter) ) { + if( user->fd == sd->fd ) + continue; + WFIFOHEAD(user->fd,msg_len + 12); + memcpy(WFIFOP(user->fd,0), WFIFOP(sd->fd,0), msg_len + 12); + WFIFOSET(user->fd, msg_len + 12); + } + + WFIFOSET(sd->fd, msg_len + 12); + + dbi_destroy(iter); +} + +void clif_chsys_mjoin(struct map_session_data *sd) { + if( !map[sd->bl.m].channel ) { + CREATE(map[sd->bl.m].channel, struct raChSysCh , 1); + safestrncpy(map[sd->bl.m].channel->name, raChSys.local_name, RACHSYS_NAME_LENGTH); + map[sd->bl.m].channel->type = raChSys_MAP; + map[sd->bl.m].channel->m = sd->bl.m; + + clif_chsys_create(map[sd->bl.m].channel,NULL,NULL,raChSys.local_color); + } + clif_chsys_join(map[sd->bl.m].channel,sd); + + if( !( map[sd->bl.m].channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) { + char mout[60]; + sprintf(mout, msg_txt(1435),raChSys.local_name,map[sd->bl.m].name); // You're now in the '#%s' channel for '%s'. + clif_disp_onlyself(sd, mout, strlen(mout)); + } +} + +void clif_chsys_left(struct raChSysCh *channel, struct map_session_data *sd) { + unsigned char i; + idb_remove(channel->users,sd->status.char_id); + + if( channel == sd->gcbind ) + sd->gcbind = NULL; + + if( !db_size(channel->users) && channel->type == raChSys_PRIVATE ) { + clif_chsys_delete(channel); + } else if( !raChSys.closing && (channel->opt & raChSys_OPT_ANNOUNCE_JOIN) ) { + char message[60]; + sprintf(message, "#%s '%s' left",channel->name,sd->status.name); + clif_chsys_msg(channel,sd,message); + } + + for( i = 0; i < sd->channel_count; i++ ) { + if( sd->channels[i] == channel ) { + sd->channels[i] = NULL; + break; + } + } + + if( i < sd->channel_count ) { + unsigned char cursor = 0; + for( i = 0; i < sd->channel_count; i++ ) { + if( sd->channels[i] == NULL ) + continue; + if( cursor != i ) { + sd->channels[cursor] = sd->channels[i]; + } + cursor++; + } + if ( !(sd->channel_count = cursor) ) { + aFree(sd->channels); + sd->channels = NULL; + } + } + +} + +void clif_chsys_delete(struct raChSysCh *channel) { + if( db_size(channel->users) && !raChSys.closing ) { + DBIterator *iter; + struct map_session_data *sd; + unsigned char i; + iter = db_iterator(channel->users); + for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) ) { + for( i = 0; i < sd->channel_count; i++ ) { + if( sd->channels[i] == channel ) { + sd->channels[i] = NULL; + break; + } + } + if( i < sd->channel_count ) { + unsigned char cursor = 0; + for( i = 0; i < sd->channel_count; i++ ) { + if( sd->channels[i] == NULL ) + continue; + if( cursor != i ) { + sd->channels[cursor] = sd->channels[i]; + } + cursor++; + } + if ( !(sd->channel_count = cursor) ) { + aFree(sd->channels); + sd->channels = NULL; + } + } + } + } + db_destroy(channel->users); + if( channel->m ) { + map[channel->m].channel = NULL; + aFree(channel); + } else if ( channel->type == raChSys_ALLY ) + aFree(channel); + else if( !raChSys.closing ) + strdb_remove(channel_db, channel->name); +} + +void clif_read_channels_config(void) { + config_t channels_conf; + config_setting_t *chsys = NULL; + const char *config_filename = "conf/channels.conf"; // FIXME hardcoded name + + if (conf_read_file(&channels_conf, config_filename)) + return; + + chsys = config_lookup(&channels_conf, "chsys"); + + if (chsys != NULL) { + config_setting_t *settings = config_setting_get_elem(chsys, 0); + config_setting_t *channels; + config_setting_t *colors; + int i,k; + const char *local_name, *ally_name, + *local_color, *ally_color; + int ally_enabled = 0, local_enabled = 0, + local_autojoin = 0, ally_autojoin = 0, + allow_user_channel_creation = 0; + + if( !config_setting_lookup_string(settings, "map_local_channel_name", &local_name) ) + local_name = "map"; + safestrncpy(raChSys.local_name, local_name, RACHSYS_NAME_LENGTH); + + if( !config_setting_lookup_string(settings, "ally_channel_name", &ally_name) ) + ally_name = "ally"; + safestrncpy(raChSys.ally_name, ally_name, RACHSYS_NAME_LENGTH); + + config_setting_lookup_bool(settings, "map_local_channel", &local_enabled); + config_setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled); + + if( local_enabled ) + raChSys.local = true; + if( ally_enabled ) + raChSys.ally = true; + + config_setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin); + config_setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin); + + if( local_autojoin ) + raChSys.local_autojoin = true; + if( ally_autojoin ) + raChSys.ally_autojoin = true; + + config_setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation); + + if( allow_user_channel_creation ) + raChSys.allow_user_channel_creation = true; + + if( (colors = config_setting_get_member(settings, "colors")) != NULL ) { + int color_count = config_setting_length(colors); + CREATE( raChSys.colors, unsigned long, color_count ); + CREATE( raChSys.colors_name, char *, color_count ); + for(i = 0; i < color_count; i++) { + config_setting_t *color = config_setting_get_elem(colors, i); + + CREATE( raChSys.colors_name[i], char, RACHSYS_NAME_LENGTH ); + + safestrncpy(raChSys.colors_name[i], config_setting_name(color), RACHSYS_NAME_LENGTH); + + raChSys.colors[i] = strtoul(config_setting_get_string_elem(colors,i),NULL,0); + raChSys.colors[i] = (raChSys.colors[i] & 0x0000FF) << 16 | (raChSys.colors[i] & 0x00FF00) | (raChSys.colors[i] & 0xFF0000) >> 16;//RGB to BGR + } + raChSys.colors_count = color_count; + } + + config_setting_lookup_string(settings, "map_local_channel_color", &local_color); + + for (k = 0; k < raChSys.colors_count; k++) { + if( strcmpi(raChSys.colors_name[k],local_color) == 0 ) + break; + } + + if( k < raChSys.colors_count ) { + raChSys.local_color = k; + } else { + ShowError("channels.conf: unknown color '%s' for channel 'map_local_channel_color', disabling '#%s'...\n",local_color,local_name); + raChSys.local = false; + } + + config_setting_lookup_string(settings, "ally_channel_color", &ally_color); + + for (k = 0; k < raChSys.colors_count; k++) { + if( strcmpi(raChSys.colors_name[k],ally_color) == 0 ) + break; + } + + if( k < raChSys.colors_count ) { + raChSys.ally_color = k; + } else { + ShowError("channels.conf: unknown color '%s' for channel 'ally_channel_color', disabling '#%s'...\n",local_color,ally_name); + raChSys.ally = false; + } + + if( (channels = config_setting_get_member(settings, "default_channels")) != NULL ) { + int channel_count = config_setting_length(channels); + + for(i = 0; i < channel_count; i++) { + config_setting_t *channel = config_setting_get_elem(channels, i); + const char *name = config_setting_name(channel); + const char *color = config_setting_get_string_elem(channels,i); + struct raChSysCh *chd; + + for (k = 0; k < raChSys.colors_count; k++) { + if( strcmpi(raChSys.colors_name[k],color) == 0 ) + break; + } + if( k == raChSys.colors_count ) { + ShowError("channels.conf: unknown color '%s' for channel '%s', skipping channel...\n",color,name); + continue; + } + if( strcmpi(name,raChSys.local_name) == 0 || strcmpi(name,raChSys.ally_name) == 0 || strdb_exists(channel_db, name) ) { + ShowError("channels.conf: duplicate channel '%s', skipping channel...\n",name); + continue; + + } + CREATE( chd, struct raChSysCh, 1 ); + + safestrncpy(chd->name, name, RACHSYS_NAME_LENGTH); + chd->type = raChSys_PUBLIC; + + clif_chsys_create(chd,NULL,NULL,k); + } + } + + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' channels in '"CL_WHITE"%s"CL_RESET"'.\n", db_size(channel_db), config_filename); + config_destroy(&channels_conf); + } +} + /// Displays heal effect (ZC_RECOVERY). /// 013d .W .W @@ -6178,8 +6429,7 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* ven WFIFOW(fd,0) = 0x136; WFIFOW(fd,2) = 8+count*22; WFIFOL(fd,4) = id; - for( i = 0; i < count; i++ ) - { + for( i = 0; i < count; i++ ) { int index = vending[i].index; struct item_data* data = itemdb_search(sd->status.cart[index].nameid); WFIFOL(fd, 8+i*22) = vending[i].value; @@ -6687,8 +6937,7 @@ void clif_sendegg(struct map_session_data *sd) nullpo_retv(sd); fd=sd->fd; - if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m)) - { //Disable pet hatching in GvG grounds during Guild Wars [Skotlex] + if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m)) { //Disable pet hatching in GvG grounds during Guild Wars [Skotlex] clif_displaymessage(fd, msg_txt(666)); return; } @@ -7119,7 +7368,7 @@ void clif_guild_send_onlineinfo(struct map_session_data *sd) p_len = packet_len(0x16d); - if(!(g = guild_search(sd->status.guild_id))) + if(!(g = sd->guild)) return; for(i=0; imax_member; i++) { @@ -7173,7 +7422,7 @@ void clif_guild_basicinfo(struct map_session_data *sd) { nullpo_retv(sd); fd = sd->fd; - if( (g = guild_search(sd->status.guild_id)) == NULL ) + if( (g = sd->guild) == NULL ) return; WFIFOHEAD(fd,packet_len(0x1b6)); @@ -7207,7 +7456,7 @@ void clif_guild_allianceinfo(struct map_session_data *sd) struct guild *g; nullpo_retv(sd); - if( (g = guild_search(sd->status.guild_id)) == NULL ) + if( (g = sd->guild) == NULL ) return; fd = sd->fd; @@ -7243,7 +7492,7 @@ void clif_guild_memberlist(struct map_session_data *sd) if( (fd = sd->fd) == 0 ) return; - if( (g = guild_search(sd->status.guild_id)) == NULL ) + if( (g = sd->guild) == NULL ) return; WFIFOHEAD(fd, g->max_member * 104 + 4); @@ -7279,7 +7528,7 @@ void clif_guild_positionnamelist(struct map_session_data *sd) struct guild *g; nullpo_retv(sd); - if( (g = guild_search(sd->status.guild_id)) == NULL ) + if( (g = sd->guild) == NULL ) return; fd = sd->fd; @@ -7307,7 +7556,7 @@ void clif_guild_positioninfolist(struct map_session_data *sd) struct guild *g; nullpo_retv(sd); - if( (g = guild_search(sd->status.guild_id)) == NULL ) + if( (g = sd->guild) == NULL ) return; fd = sd->fd; @@ -7429,7 +7678,7 @@ void clif_guild_skillinfo(struct map_session_data* sd) int i,c; nullpo_retv(sd); - if( (g = guild_search(sd->status.guild_id)) == NULL ) + if( (g = sd->guild) == NULL ) return; fd = sd->fd; @@ -7575,7 +7824,7 @@ void clif_guild_expulsionlist(struct map_session_data* sd) nullpo_retv(sd); - if( (g = guild_search(sd->status.guild_id)) == NULL ) + if( (g = sd->guild) == NULL ) return; fd = sd->fd; @@ -7910,12 +8159,9 @@ void clif_disp_message(struct block_list* src, const char* mes, int len, enum se { unsigned char buf[256]; - if( len == 0 ) - { + if( len == 0 ) { return; - } - else if( len > sizeof(buf)-5 ) - { + } else if( len > sizeof(buf)-5 ) { ShowWarning("clif_disp_message: Truncated message '%s' (len=%d, max=%d, aid=%d).\n", mes, len, sizeof(buf)-5, src->id); len = sizeof(buf)-5; } @@ -8178,7 +8424,7 @@ int clif_colormes(struct map_session_data * sd, enum clif_colors color, const ch WFIFOL(sd->fd,4) = 0; WFIFOL(sd->fd,8) = color_table[color]; safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len); - clif_send(WFIFOP(sd->fd,0), WFIFOW(sd->fd,2), &sd->bl, SELF); + WFIFOSET(sd->fd, msg_len + 12); return 0; } @@ -8192,8 +8438,7 @@ void clif_messagecolor(struct block_list* bl, unsigned long color, const char* m nullpo_retv(bl); - if( msg_len > sizeof(buf)-12 ) - { + if( msg_len > sizeof(buf)-12 ) { ShowWarning("clif_messagecolor: Truncating too long message '%s' (len=%u).\n", msg, msg_len); msg_len = sizeof(buf)-12; } @@ -8207,26 +8452,6 @@ void clif_messagecolor(struct block_list* bl, unsigned long color, const char* m clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); } -/// Public chat message [Valaris] (ZC_NOTIFY_CHAT). -/// 008d .W .L .?B -void clif_message(struct block_list* bl, const char* msg) { - unsigned short msg_len = strlen(msg) + 1; - uint8 buf[256]; - nullpo_retv(bl); - - if( msg_len > sizeof(buf)-8 ) { - ShowWarning("clif_message: Truncating too long message '%s' (len=%u).\n", msg, msg_len); - msg_len = sizeof(buf)-8; - } - - WBUFW(buf,0) = 0x8d; - WBUFW(buf,2) = msg_len + 8; - WBUFL(buf,4) = bl->id; - safestrncpy((char*)WBUFP(buf,8), msg, msg_len); - - clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); -} - // refresh the client's screen, getting rid of any effects void clif_refresh(struct map_session_data *sd) { @@ -8308,8 +8533,7 @@ void clif_charnameack (int fd, struct block_list *bl) if (ssd->fd == fd && ssd->disguise) WBUFL(buf,2) = -bl->id; - if( ssd->fakename[0] ) - { + if( ssd->fakename[0] ) { WBUFW(buf, 0) = cmd = 0x195; memcpy(WBUFP(buf,6), ssd->fakename, NAME_LENGTH); WBUFB(buf,30) = WBUFB(buf,54) = WBUFB(buf,78) = 0; @@ -8317,21 +8541,17 @@ void clif_charnameack (int fd, struct block_list *bl) } memcpy(WBUFP(buf,6), ssd->status.name, NAME_LENGTH); - if( ssd->status.party_id ) - { + if( ssd->status.party_id ) { p = party_search(ssd->status.party_id); } - if( ssd->status.guild_id ) - { - if( ( g = guild_search(ssd->status.guild_id) ) != NULL ) - { + if( ssd->status.guild_id ) { + if( ( g = ssd->guild ) != NULL ) { ARR_FIND(0, g->max_member, i, g->member[i].account_id == ssd->status.account_id && g->member[i].char_id == ssd->status.char_id); if( i < g->max_member ) ps = g->member[i].position; } } - if( !battle_config.display_party_name && g == NULL ) - {// do not display party unless the player is also in a guild + if( !battle_config.display_party_name && g == NULL ) {// do not display party unless the player is also in a guild p = NULL; } @@ -8445,14 +8665,14 @@ void clif_charnameupdate (struct map_session_data *ssd) memcpy(WBUFP(buf,6), ssd->status.name, NAME_LENGTH); if (!battle_config.display_party_name) { - if (ssd->status.party_id > 0 && ssd->status.guild_id > 0 && (g = guild_search(ssd->status.guild_id)) != NULL) + if (ssd->status.party_id > 0 && ssd->status.guild_id > 0 && (g = ssd->guild) != NULL) p = party_search(ssd->status.party_id); }else{ if (ssd->status.party_id > 0) p = party_search(ssd->status.party_id); } - if( ssd->status.guild_id > 0 && (g = guild_search(ssd->status.guild_id)) != NULL ) + if( ssd->status.guild_id > 0 && (g = ssd->guild) != NULL ) { int i; ARR_FIND(0, g->max_member, i, g->member[i].account_id == ssd->status.account_id && g->member[i].char_id == ssd->status.char_id); @@ -8505,10 +8725,9 @@ void clif_slide(struct block_list *bl, int x, int y) } -/*------------------------------------------ - * @me command by lordalfa, rewritten implementation by Skotlex - *------------------------------------------*/ -void clif_disp_overhead(struct map_session_data *sd, const char* mes) +/// Public chat message (ZC_NOTIFY_CHAT). lordalfa/Skotlex - used by @me as well +/// 008d .W .L .?B +void clif_disp_overhead(struct block_list *bl, const char* mes) { unsigned char buf[256]; //This should be more than sufficient, the theorical max is CHAT_SIZE + 8 (pads and extra inserted crap) int len_mes = strlen(mes)+1; //Account for \0 @@ -8520,15 +8739,17 @@ void clif_disp_overhead(struct map_session_data *sd, const char* mes) // send message to others WBUFW(buf,0) = 0x8d; WBUFW(buf,2) = len_mes + 8; // len of message + 8 (command+len+id) - WBUFL(buf,4) = sd->bl.id; + WBUFL(buf,4) = bl->id; safestrncpy((char*)WBUFP(buf,8), mes, len_mes); - clif_send(buf, WBUFW(buf,2), &sd->bl, AREA_CHAT_WOC); + clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); // send back message to the speaker - WBUFW(buf,0) = 0x8e; - WBUFW(buf, 2) = len_mes + 4; - safestrncpy((char*)WBUFP(buf,4), mes, len_mes); - clif_send(buf, WBUFW(buf,2), &sd->bl, SELF); + if( bl->type == BL_PC ) { + WBUFW(buf,0) = 0x8e; + WBUFW(buf, 2) = len_mes + 4; + safestrncpy((char*)WBUFP(buf,4), mes, len_mes); + clif_send(buf, WBUFW(buf,2), bl, SELF); + } } /*========================== @@ -8632,16 +8853,11 @@ void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsig *------------------------------------------*/ void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int class_, unsigned char type) { - if( pcdb_checkid(class_) ) - { + if( pcdb_checkid(class_) ) { clif_starskill(sd, job_name(class_), class_, hate_level, type ? 10 : 11); - } - else if( mobdb_checkid(class_) ) - { + } else if( mobdb_checkid(class_) ) { clif_starskill(sd, mob_db(class_)->jname, class_, hate_level, type ? 10 : 11); - } - else - { + } else { ShowWarning("clif_hate_info: Received invalid class %d for this packet (char_id=%d, hate_level=%u, type=%u).\n", class_, sd->status.char_id, (unsigned int)hate_level, (unsigned int)type); } } @@ -8984,8 +9200,7 @@ static int clif_guess_PacketVer(int fd, int get_previous, int *error) CHECK_PACKET_VER();//Default packet version found. - for (packet_ver = MAX_PACKET_VER; packet_ver > 0; packet_ver--) - { //Start guessing the version, giving priority to the newer ones. [Skotlex] + for (packet_ver = MAX_PACKET_VER; packet_ver > 0; packet_ver--) { //Start guessing the version, giving priority to the newer ones. [Skotlex] CHECK_PACKET_VER(); } if( error ) @@ -9006,7 +9221,7 @@ static int clif_guess_PacketVer(int fd, int get_previous, int *error) /// 0072 .L .L .L .L .B (CZ_ENTER) /// 0436 .L .L .L .L .B (CZ_ENTER2) /// There are various variants of this packet, some of them have padding between fields. -void clif_parse_WantToConnection(int fd, TBL_PC* sd) +void clif_parse_WantToConnection(int fd, struct map_session_data* sd) { struct block_list* bl; struct auth_node* node; @@ -9042,8 +9257,7 @@ void clif_parse_WantToConnection(int fd, TBL_PC* sd) return; } - if( runflag != MAPSERVER_ST_RUNNING ) - {// not allowed + if( runflag != MAPSERVER_ST_RUNNING ) {// not allowed clif_authfail_fd(fd,1);// server closed return; } @@ -9097,15 +9311,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if(sd->bl.prev != NULL) return; - if (!sd->state.active) - { //Character loading is not complete yet! + if (!sd->state.active) { //Character loading is not complete yet! //Let pc_reg_received reinvoke this when ready. sd->state.connect_new = 0; return; } - if (sd->state.rewarp) - { //Rewarp player. + if (sd->state.rewarp) { //Rewarp player. sd->state.rewarp = 0; clif_changemap(sd, sd->mapindex, sd->bl.x, sd->bl.y); return; @@ -9151,12 +9363,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if( map[sd->bl.m].users++ == 0 && battle_config.dynamic_mobs ) map_spawnmobs(sd->bl.m); - if( !(sd->sc.option&OPTION_INVISIBLE) ) - {// increment the number of pvp players on the map + if( !(sd->sc.option&OPTION_INVISIBLE) ) { // increment the number of pvp players on the map map[sd->bl.m].users_pvp++; } - if( map[sd->bl.m].instance_id ) - { + if( map[sd->bl.m].instance_id ) { instance[map[sd->bl.m].instance_id].users++; instance_check_idle(map[sd->bl.m].instance_id); } @@ -9204,15 +9414,11 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) map_foreachinarea(clif_getareachar, sd->bl.m, sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, BL_ALL, sd); // pet - if( sd->pd ) - { - if( battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m) ) - { //Return the pet to egg. [Skotlex] + if( sd->pd ) { + if( battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m) ) { //Return the pet to egg. [Skotlex] clif_displaymessage(sd->fd, msg_txt(666)); pet_menu(sd, 3); //Option 3 is return to egg. - } - else - { + } else { map_addblock(&sd->pd->bl); clif_spawn(&sd->pd->bl); clif_send_petdata(sd,sd->pd,0,0); @@ -9222,8 +9428,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) } //homunculus [blackhole89] - if( merc_is_hom_active(sd->hd) ) - { + if( merc_is_hom_active(sd->hd) ) { map_addblock(&sd->hd->bl); clif_spawn(&sd->hd->bl); clif_send_homdata(sd,SP_ACK,0); @@ -9319,8 +9524,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) npc_event_dequeue(sd); } - if( sd->state.changemap ) - {// restore information that gets lost on map-change + if( sd->state.changemap ) {// restore information that gets lost on map-change #if PACKETVER >= 20070918 clif_partyinvitationstate(sd); clif_equipcheckbox(sd); @@ -9360,6 +9564,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) map_iwall_get(sd); // Updates Walls Info on this Map to Client status_calc_pc(sd, false); // Some conditions are map-dependent so we must recalculate sd->state.changemap = false; + + if( raChSys.local && raChSys.local_autojoin && !map[sd->bl.m].flag.chsysnolocalaj ) { + clif_chsys_mjoin(sd); + } } mail_clear(sd); @@ -9653,12 +9861,32 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; - if( battle_config.min_chat_delay ) - { //[Skotlex] + if( battle_config.min_chat_delay ) { //[Skotlex] if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0) return; sd->cantalk_tick = gettick() + battle_config.min_chat_delay; } + + if( sd->gcbind ) { + clif_chsys_send(sd->gcbind,sd,message); + return; + } else if ( sd->fontcolor && !sd->chatID ) { + char mout[200]; + unsigned char mylen = 1; + + mylen += snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message); + + WFIFOHEAD(fd,mylen + 12); + WFIFOW(fd,0) = 0x2C1; + WFIFOW(fd,2) = mylen + 12; + WFIFOL(fd,4) = -sd->bl.id; + WFIFOL(fd,8) = raChSys.colors[sd->fontcolor - 1]; + safestrncpy((char*)WFIFOP(fd,12), mout, mylen); + clif_send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, AREA_WOS); + WFIFOSET(fd, mylen + 12); + return; + } + /** * Fake Name Design by FatalEror (bug report #9) **/ @@ -9788,8 +10016,7 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd) } sd->emotionlasttime = time(NULL); - if(battle_config.client_reshuffle_dice && emoticon>=E_DICE1 && emoticon<=E_DICE6) - {// re-roll dice + if(battle_config.client_reshuffle_dice && emoticon>=E_DICE1 && emoticon<=E_DICE6) {// re-roll dice emoticon = rnd()%6+E_DICE1; } @@ -10028,15 +10255,38 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) return; } - } else if(strcmpi(target, main_chat_nick) == 0) { // Main chat [LuzZza] - if(!sd->state.mainchat) - clif_displaymessage(fd, msg_txt(388)); // You should enable main chat with "@main on" command. - else { - // send the main message using inter-server system - intif_main_message( sd, message ); - } + } else if( target[0] == '#' ) { + struct raChSysCh *channel = NULL; + char* chname = target; - return; + chname++; + + if( raChSys.local && strcmpi(chname, raChSys.local_name) == 0 ) { + if( !map[sd->bl.m].channel ) { + clif_chsys_mjoin(sd); + } + channel = map[sd->bl.m].channel; + } else if( raChSys.ally && sd->status.guild_id && strcmpi(chname, raChSys.ally_name) == 0 ) { + struct guild *g = sd->guild; + if( !g ) return; + channel = (struct raChSysCh *)g->channel; + } + if( channel || (channel = strdb_get(channel_db,chname)) ) { + unsigned char k; + for( k = 0; k < sd->channel_count; k++ ) { + if( sd->channels[k] == channel ) + break; + } + if( k < sd->channel_count ) { + clif_chsys_send(channel,sd,message); + } else if( channel->pass[0] == '\0' ) { + clif_chsys_join(channel,sd); + clif_chsys_send(channel,sd,message); + } else { + clif_displaymessage(fd, msg_txt(1402)); + } + return; + } } // searching destination character @@ -10522,8 +10772,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd) return; } - if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 1) - { + if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 1) { clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,0); return; } @@ -10793,14 +11042,12 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) if (tmp&INF_GROUND_SKILL || !tmp) return; //Using a ground/passive skill on a target? WRONG. - if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE + MAX_HOMUNSKILL ) - { + if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE + MAX_HOMUNSKILL ) { clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skill_id, skill_lv, target_id); return; } - if( skill_id >= MC_SKILLBASE && skill_id < MC_SKILLBASE + MAX_MERCSKILL ) - { + if( skill_id >= MC_SKILLBASE && skill_id < MC_SKILLBASE + MAX_MERCSKILL ) { clif_parse_UseSkillToId_mercenary(sd->md, sd, tick, skill_id, skill_lv, target_id); return; } @@ -10829,15 +11076,11 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) if( target_id < 0 && -target_id == sd->bl.id ) // for disguises [Valaris] target_id = sd->bl.id; - if( sd->ud.skilltimer != INVALID_TIMER ) - { + if( sd->ud.skilltimer != INVALID_TIMER ) { if( skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST ) return; - } - else if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 ) - { - if( sd->skillitem != skill_id ) - { + } else if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 ) { + if( sd->skillitem != skill_id ) { clif_skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0); return; } @@ -10898,8 +11141,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin return; } - if( skill_id >= MC_SKILLBASE && skill_id < MC_SKILLBASE + MAX_MERCSKILL ) - { + if( skill_id >= MC_SKILLBASE && skill_id < MC_SKILLBASE + MAX_MERCSKILL ) { clif_parse_UseSkillToPos_mercenary(sd->md, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo); return; } @@ -10909,10 +11151,8 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin if( skillnotok(skill_id, sd) ) return; - if( skillmoreinfo != -1 ) - { - if( pc_issit(sd) ) - { + if( skillmoreinfo != -1 ) { + if( pc_issit(sd) ) { clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); return; } @@ -11366,8 +11606,7 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) if (sd->state.storage_flag == 1) storage_storageget(sd, item_index, item_amount); - else - if(sd->state.storage_flag == 2) + else if(sd->state.storage_flag == 2) storage_guild_storageget(sd, item_index, item_amount); } @@ -11383,8 +11622,7 @@ void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) if (sd->state.storage_flag == 1) storage_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); - else - if (sd->state.storage_flag == 2) + else if (sd->state.storage_flag == 2) storage_guild_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); } @@ -11479,13 +11717,11 @@ void clif_parse_CreateParty(int fd, struct map_session_data *sd) char* name = (char*)RFIFOP(fd,2); name[NAME_LENGTH-1] = '\0'; - if( map[sd->bl.m].flag.partylock ) - {// Party locked. + if( map[sd->bl.m].flag.partylock ) {// Party locked. clif_displaymessage(fd, msg_txt(227)); return; } - if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 7 ) - { + if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 7 ) { clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,4); return; } @@ -11500,13 +11736,11 @@ void clif_parse_CreateParty2(int fd, struct map_session_data *sd) int item2 = RFIFOB(fd,27); name[NAME_LENGTH-1] = '\0'; - if( map[sd->bl.m].flag.partylock ) - {// Party locked. + if( map[sd->bl.m].flag.partylock ) {// Party locked. clif_displaymessage(fd, msg_txt(227)); return; } - if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 7 ) - { + if( battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 7 ) { clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,4); return; } @@ -11522,16 +11756,14 @@ void clif_parse_PartyInvite(int fd, struct map_session_data *sd) { struct map_session_data *t_sd; - if(map[sd->bl.m].flag.partylock) - {// Party locked. + if(map[sd->bl.m].flag.partylock) {// Party locked. clif_displaymessage(fd, msg_txt(227)); return; } t_sd = map_id2sd(RFIFOL(fd,2)); - if(t_sd && t_sd->state.noask) - {// @noask [LuzZza] + if(t_sd && t_sd->state.noask) {// @noask [LuzZza] clif_noask_sub(sd, t_sd, 1); return; } @@ -11545,16 +11777,14 @@ void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) char *name = (char*)RFIFOP(fd,2); name[NAME_LENGTH-1] = '\0'; - if(map[sd->bl.m].flag.partylock) - {// Party locked. + if(map[sd->bl.m].flag.partylock) {// Party locked. clif_displaymessage(fd, msg_txt(227)); return; } t_sd = map_nick2sd(name); - if(t_sd && t_sd->state.noask) - {// @noask [LuzZza] + if(t_sd && t_sd->state.noask) {// @noask [LuzZza] clif_noask_sub(sd, t_sd, 1); return; } @@ -11584,8 +11814,7 @@ void clif_parse_ReplyPartyInvite2(int fd,struct map_session_data *sd) /// 0100 void clif_parse_LeaveParty(int fd, struct map_session_data *sd) { - if(map[sd->bl.m].flag.partylock) - { //Guild locked. + if(map[sd->bl.m].flag.partylock) { //Guild locked. clif_displaymessage(fd, msg_txt(227)); return; } @@ -11597,8 +11826,7 @@ void clif_parse_LeaveParty(int fd, struct map_session_data *sd) /// 0103 .L .24B void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) { - if(map[sd->bl.m].flag.partylock) - { //Guild locked. + if(map[sd->bl.m].flag.partylock) { //Guild locked. clif_displaymessage(fd, msg_txt(227)); return; } @@ -11863,8 +12091,7 @@ void clif_parse_CloseVending(int fd, struct map_session_data* sd) /// 0130 .L void clif_parse_VendingListReq(int fd, struct map_session_data* sd) { - if( sd->npc_id ) - {// using an NPC + if( sd->npc_id ) {// using an NPC return; } vending_vendinglistreq(sd,RFIFOL(fd,2)); @@ -11943,8 +12170,7 @@ void clif_parse_CreateGuild(int fd,struct map_session_data *sd) char* name = (char*)RFIFOP(fd,6); name[NAME_LENGTH-1] = '\0'; - if(map[sd->bl.m].flag.guildlock) - { //Guild locked. + if(map[sd->bl.m].flag.guildlock) { //Guild locked. clif_displaymessage(fd, msg_txt(228)); return; } @@ -12109,8 +12335,7 @@ void clif_parse_GuildInvite(int fd,struct map_session_data *sd) { struct map_session_data *t_sd; - if(map[sd->bl.m].flag.guildlock) - { //Guild locked. + if(map[sd->bl.m].flag.guildlock) { //Guild locked. clif_displaymessage(fd, msg_txt(228)); return; } @@ -12142,13 +12367,11 @@ void clif_parse_GuildReplyInvite(int fd,struct map_session_data *sd) /// 0159 .L .L .L .40B void clif_parse_GuildLeave(int fd,struct map_session_data *sd) { - if(map[sd->bl.m].flag.guildlock) - { //Guild locked. + if(map[sd->bl.m].flag.guildlock) { //Guild locked. clif_displaymessage(fd, msg_txt(228)); return; } - if( sd->bg_id ) - { + if( sd->bg_id ) { clif_displaymessage(fd, msg_txt(670)); //"You can't leave battleground guilds." return; } @@ -12216,8 +12439,7 @@ void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) if(!sd->state.gmaster_flag) return; - if(map[sd->bl.m].flag.guildlock) - { //Guild locked. + if(map[sd->bl.m].flag.guildlock) { //Guild locked. clif_displaymessage(fd, msg_txt(228)); return; } @@ -12255,8 +12477,7 @@ void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd) if(!sd->state.gmaster_flag) return; - if(map[sd->bl.m].flag.guildlock) - { //Guild locked. + if(map[sd->bl.m].flag.guildlock) { //Guild locked. clif_displaymessage(fd, msg_txt(228)); return; } @@ -12273,8 +12494,7 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) if(!sd->state.gmaster_flag) return; - if(map[sd->bl.m].flag.guildlock) - { //Guild locked. + if(map[sd->bl.m].flag.guildlock) { //Guild locked. clif_displaymessage(fd, msg_txt(228)); return; } @@ -12298,8 +12518,7 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) /// field name and size is same as the one in CH_DELETE_CHAR. void clif_parse_GuildBreak(int fd, struct map_session_data *sd) { - if( map[sd->bl.m].flag.guildlock ) - { //Guild locked. + if( map[sd->bl.m].flag.guildlock ) { //Guild locked. clif_displaymessage(fd, msg_txt(228)); return; } @@ -12336,8 +12555,7 @@ void clif_parse_CatchPet(int fd, struct map_session_data *sd) /// 01a7 .W void clif_parse_SelectEgg(int fd, struct map_session_data *sd) { - if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_val != -1) - { + if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_val != -1) { //Forged packet, disconnect them [Kevin] clif_authfail_fd(fd, 0); return; @@ -12480,8 +12698,7 @@ void clif_parse_GMRemove2(int fd, struct map_session_data* sd) struct map_session_data* pl_sd; account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]); - if( (pl_sd = map_id2sd(account_id)) != NULL ) - { + if( (pl_sd = map_id2sd(account_id)) != NULL ) { char command[NAME_LENGTH+8]; sprintf(command, "%cjumpto %s", atcommand_symbol, pl_sd->status.name); is_atcommand(fd, sd, command, 1); @@ -12518,8 +12735,7 @@ void clif_parse_GMRecall2(int fd, struct map_session_data* sd) struct map_session_data* pl_sd; account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]); - if( (pl_sd = map_id2sd(account_id)) != NULL ) - { + if( (pl_sd = map_id2sd(account_id)) != NULL ) { char command[NAME_LENGTH+8]; sprintf(command, "%crecall %s", atcommand_symbol, pl_sd->status.name); is_atcommand(fd, sd, command, 1); @@ -12680,8 +12896,7 @@ void clif_parse_PMIgnore(int fd, struct map_session_data* sd) nick[NAME_LENGTH-1] = '\0'; // to be sure that the player name has at most 23 characters type = RFIFOB(fd,26); - if( type == 0 ) - { // Add name to ignore list (block) + if( type == 0 ) { // Add name to ignore list (block) if (strcmp(wisp_server_name, nick) == 0) { clif_wisexin(sd, type, 1); // fail return; @@ -12689,27 +12904,22 @@ void clif_parse_PMIgnore(int fd, struct map_session_data* sd) // try to find a free spot, while checking for duplicates at the same time ARR_FIND( 0, MAX_IGNORE_LIST, i, sd->ignore[i].name[0] == '\0' || strcmp(sd->ignore[i].name, nick) == 0 ); - if( i == MAX_IGNORE_LIST ) - {// no space for new entry + if( i == MAX_IGNORE_LIST ) {// no space for new entry clif_wisexin(sd, type, 2); // too many blocks return; } - if( sd->ignore[i].name[0] != '\0' ) - {// name already exists + if( sd->ignore[i].name[0] != '\0' ) {// name already exists clif_wisexin(sd, type, 0); // Aegis reports success. return; } //Insert in position i safestrncpy(sd->ignore[i].name, nick, NAME_LENGTH); - } - else - { // Remove name from ignore list (unblock) + } else { // Remove name from ignore list (unblock) // find entry ARR_FIND( 0, MAX_IGNORE_LIST, i, sd->ignore[i].name[0] == '\0' || strcmp(sd->ignore[i].name, nick) == 0 ); - if( i == MAX_IGNORE_LIST || sd->ignore[i].name[i] == '\0' ) - { //Not found + if( i == MAX_IGNORE_LIST || sd->ignore[i].name[i] == '\0' ) { //Not found clif_wisexin(sd, type, 1); // fail return; } @@ -12733,17 +12943,14 @@ void clif_parse_PMIgnoreAll(int fd, struct map_session_data *sd) { int type = RFIFOB(fd,2), flag; - if( type == 0 ) - {// Deny all + if( type == 0 ) {// Deny all if( sd->state.ignoreAll ) { flag = 1; // fail } else { sd->state.ignoreAll = 1; flag = 0; // success } - } - else - {//Unblock everyone + } else {//Unblock everyone if( sd->state.ignoreAll ) { sd->state.ignoreAll = 0; flag = 0; // success @@ -12771,8 +12978,7 @@ void clif_PMIgnoreList(struct map_session_data* sd) WFIFOHEAD(fd,4+ARRAYLENGTH(sd->ignore)*NAME_LENGTH); WFIFOW(fd,0) = 0xd4; - for( i = 0; i < ARRAYLENGTH(sd->ignore) && sd->ignore[i].name[0]; i++ ) - { + for( i = 0; i < ARRAYLENGTH(sd->ignore) && sd->ignore[i].name[0]; i++ ) { memcpy(WFIFOP(fd,4+i*NAME_LENGTH), sd->ignore[i].name, NAME_LENGTH); } @@ -12795,8 +13001,7 @@ void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd) { if (sd->state.doridori) return; - switch (sd->class_&MAPID_UPPERMASK) - { + switch (sd->class_&MAPID_UPPERMASK) { case MAPID_SOUL_LINKER: case MAPID_STAR_GLADIATOR: case MAPID_TAEKWON: @@ -12819,16 +13024,13 @@ void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd) /// "Help me out~ Please~ T_T" void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd) { - if( ( sd->class_&MAPID_UPPERMASK ) == MAPID_SUPER_NOVICE ) - { + if( ( sd->class_&MAPID_UPPERMASK ) == MAPID_SUPER_NOVICE ) { unsigned int next = pc_nextbaseexp(sd); if( next == 0 ) next = pc_thisbaseexp(sd); - if( next ) - { + if( next ) { int percent = (int)( ( (float)sd->status.base_exp/(float)next )*1000. ); - if( percent && ( percent%100 ) == 0 ) - {// 10.0%, 20.0%, ..., 90.0% + if( percent && ( percent%100 ) == 0 ) {// 10.0%, 20.0%, ..., 90.0% sc_start(&sd->bl,&sd->bl, status_skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill_get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex] clif_skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions } @@ -12886,8 +13088,7 @@ void clif_friendslist_send(struct map_session_data *sd) // Send friends list WFIFOHEAD(fd, MAX_FRIENDS * 32 + 4); WFIFOW(fd, 0) = 0x201; - for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++) - { + for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++) { WFIFOL(fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id; WFIFOL(fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id; memcpy(WFIFOP(fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH); @@ -12898,8 +13099,7 @@ void clif_friendslist_send(struct map_session_data *sd) WFIFOSET(fd, WFIFOW(fd,2)); } - for (n = 0; n < i; n++) - { //Sending the online players + for (n = 0; n < i; n++) { //Sending the online players if (map_charid2sd(sd->status.friends[n].char_id)) clif_friendslist_toggle(sd, sd->status.friends[n].account_id, sd->status.friends[n].char_id, 1); } @@ -12922,8 +13122,7 @@ void clif_friendslist_reqack(struct map_session_data *sd, struct map_session_dat WFIFOHEAD(fd,packet_len(0x209)); WFIFOW(fd,0) = 0x209; WFIFOW(fd,2) = type; - if (f_sd) - { + if (f_sd) { WFIFOL(fd,4) = f_sd->status.account_id; WFIFOL(fd,8) = f_sd->status.char_id; memcpy(WFIFOP(fd, 12), f_sd->status.name,NAME_LENGTH); @@ -12970,8 +13169,7 @@ void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) return; } - if( sd->bl.id == f_sd->bl.id ) - {// adding oneself as friend + if( sd->bl.id == f_sd->bl.id ) {// adding oneself as friend return; } @@ -13016,8 +13214,7 @@ void clif_parse_FriendsListReply(int fd, struct map_session_data *sd) reply = RFIFOL(fd,10); #endif - if( sd->bl.id == account_id ) - {// adding oneself as friend + if( sd->bl.id == account_id ) {// adding oneself as friend return; } @@ -13695,8 +13892,7 @@ void clif_Mail_refreshinbox(struct map_session_data *sd) } WFIFOSET(fd,len); - if( md->full ) - {// TODO: is this official? + if( md->full ) {// TODO: is this official? char output[100]; sprintf(output, "Inbox is full (Max %d). Delete some mails.", MAIL_MAX_INBOX); clif_disp_onlyself(sd, output, strlen(output)); @@ -13729,14 +13925,11 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) int i, fd = sd->fd; ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); - if( i == MAIL_MAX_INBOX ) - { + if( i == MAIL_MAX_INBOX ) { clif_Mail_return(sd->fd, mail_id, 1); // Mail doesn't exist ShowWarning("clif_parse_Mail_read: char '%s' trying to read a message not the inbox.\n", sd->status.name); return; - } - else - { + } else { struct mail_message *msg = &sd->mail.inbox.msg[i]; struct item *item = &msg->item; struct item_data *data; @@ -13758,8 +13951,7 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) WFIFOL(fd,72) = 0; WFIFOL(fd,76) = msg->zeny; - if( item->nameid && (data = itemdb_exists(item->nameid)) != NULL ) - { + if( item->nameid && (data = itemdb_exists(item->nameid)) != NULL ) { WFIFOL(fd,80) = item->amount; WFIFOW(fd,84) = (data->view_id)?data->view_id:item->nameid; WFIFOW(fd,86) = data->type; @@ -13770,8 +13962,7 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) WFIFOW(fd,93) = item->card[1]; WFIFOW(fd,95) = item->card[2]; WFIFOW(fd,97) = item->card[3]; - } - else // no item, set all to zero + } else // no item, set all to zero memset(WFIFOP(fd,80), 0x00, 19); WFIFOB(fd,99) = (unsigned char)msg_len; @@ -13824,22 +14015,19 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd) if( sd->mail.inbox.msg[i].zeny < 1 && (sd->mail.inbox.msg[i].item.nameid < 1 || sd->mail.inbox.msg[i].item.amount < 1) ) return; - if( sd->mail.inbox.msg[i].zeny + sd->status.zeny > MAX_ZENY ) - { + if( sd->mail.inbox.msg[i].zeny + sd->status.zeny > MAX_ZENY ) { clif_Mail_getattachment(fd, 1); return; } - if( sd->mail.inbox.msg[i].item.nameid > 0 ) - { + if( sd->mail.inbox.msg[i].item.nameid > 0 ) { struct item_data *data; unsigned int weight; if ((data = itemdb_exists(sd->mail.inbox.msg[i].item.nameid)) == NULL) return; - switch( pc_checkadditem(sd, data->nameid, sd->mail.inbox.msg[i].item.amount) ) - { + switch( pc_checkadditem(sd, data->nameid, sd->mail.inbox.msg[i].item.amount) ) { case ADDITEM_NEW: fail = ( pc_inventoryblank(sd) == 0 ); break; @@ -13847,15 +14035,13 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd) fail = true; } - if( fail ) - { + if( fail ) { clif_Mail_getattachment(fd, 1); return; } weight = data->weight * sd->mail.inbox.msg[i].item.amount; - if( sd->weight + weight > sd->max_weight ) - { + if( sd->weight + weight > sd->max_weight ) { clif_Mail_getattachment(fd, 2); return; } @@ -13884,12 +14070,10 @@ void clif_parse_Mail_delete(int fd, struct map_session_data *sd) return; ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); - if (i < MAIL_MAX_INBOX) - { + if (i < MAIL_MAX_INBOX) { struct mail_message *msg = &sd->mail.inbox.msg[i]; - if( (msg->item.nameid > 0 && msg->item.amount > 0) || msg->zeny > 0 ) - {// can't delete mail without removing attachment first + if( (msg->item.nameid > 0 && msg->item.amount > 0) || msg->zeny > 0 ) {// can't delete mail without removing attachment first clif_Mail_delete(sd->fd, mail_id, 1); return; } @@ -13971,8 +14155,7 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd) return; } - if( DIFF_TICK(sd->cansendmail_tick, gettick()) > 0 ) - { + if( DIFF_TICK(sd->cansendmail_tick, gettick()) > 0 ) { clif_displaymessage(sd->fd,msg_txt(675)); //"Cannot send mails too fast!!." clif_Mail_send(fd, true); // fail return; @@ -13983,8 +14166,7 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd) if (body_len > MAIL_BODY_LENGTH) body_len = MAIL_BODY_LENGTH; - if( !mail_setattachment(sd, &msg) ) - { // Invalid Append condition + if( !mail_setattachment(sd, &msg) ) { // Invalid Append condition clif_Mail_send(sd->fd, true); // fail mail_removeitem(sd,0); mail_removezeny(sd,0); @@ -14053,8 +14235,7 @@ void clif_Auction_results(struct map_session_data *sd, short count, short pages, WFIFOL(fd,4) = pages; WFIFOL(fd,8) = count; - for( i = 0; i < count; i++ ) - { + for( i = 0; i < count; i++ ) { memcpy(&auction, RBUFP(buf,i * len), len); k = 12 + (i * 83); @@ -14125,14 +14306,12 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd) if( sd->auction.amount > 0 ) sd->auction.amount = 0; - if( idx < 0 || idx >= MAX_INVENTORY ) - { + if( idx < 0 || idx >= MAX_INVENTORY ) { ShowWarning("Character %s trying to set invalid item index in auctions.\n", sd->status.name); return; } - if( amount != 1 || amount > sd->status.inventory[idx].amount ) - { // By client, amount is always set to 1. Maybe this is a future implementation. + if( amount != 1 || amount > sd->status.inventory[idx].amount ) { // By client, amount is always set to 1. Maybe this is a future implementation. ShowWarning("Character %s trying to set invalid amount in auctions.\n", sd->status.name); return; } @@ -14204,33 +14383,28 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) auction.hours = RFIFOW(fd,10); // Invalid Situations... - if( sd->auction.amount < 1 ) - { + if( sd->auction.amount < 1 ) { ShowWarning("Character %s trying to register auction without item.\n", sd->status.name); return; } - if( auction.price >= auction.buynow ) - { + if( auction.price >= auction.buynow ) { ShowWarning("Character %s trying to alter auction prices.\n", sd->status.name); return; } - if( auction.hours < 1 || auction.hours > 48 ) - { + if( auction.hours < 1 || auction.hours > 48 ) { ShowWarning("Character %s trying to enter an invalid time for auction.\n", sd->status.name); return; } // Auction checks... - if( sd->status.zeny < (auction.hours * battle_config.auction_feeperhour) ) - { + if( sd->status.zeny < (auction.hours * battle_config.auction_feeperhour) ) { clif_Auction_message(fd, 5); // You do not have enough zeny to pay the Auction Fee. return; } - if( auction.buynow > battle_config.auction_maximumprice ) - { // Zeny Limits + if( auction.buynow > battle_config.auction_maximumprice ) { // Zeny Limits auction.buynow = battle_config.auction_maximumprice; if( auction.price >= auction.buynow ) auction.price = auction.buynow - 1; @@ -14383,8 +14557,7 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points #endif - for( i = 0; i < nd->u.shop.count; i++ ) - { + for( i = 0; i < nd->u.shop.count; i++ ) { struct item_data* id = itemdb_search(nd->u.shop.shop_item[i].nameid); WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value; WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price @@ -14436,8 +14609,7 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd) if( sd->state.trading || !sd->npc_shopid ) fail = 1; - else - { + else { #if PACKETVER < 20101116 short nameid = RFIFOW(fd,2); short amount = RFIFOW(fd,4); @@ -14554,21 +14726,15 @@ void clif_bossmapinfo(int fd, struct mob_data *md, short flag) memset(WFIFOP(fd,0),0,70); WFIFOW(fd,0) = 0x293; - if( md != NULL ) - { - if( md->bl.prev != NULL ) - { // Boss on This Map - if( flag ) - { + if( md != NULL ) { + if( md->bl.prev != NULL ) { // Boss on This Map + if( flag ) { WFIFOB(fd,2) = 1; WFIFOL(fd,3) = md->bl.x; WFIFOL(fd,7) = md->bl.y; - } - else + } else WFIFOB(fd,2) = 2; // First Time - } - else if (md->spawn_timer != INVALID_TIMER) - { // Boss is Dead + } else if (md->spawn_timer != INVALID_TIMER) { // Boss is Dead const struct TimerData * timer_data = get_timer(md->spawn_timer); unsigned int seconds; int hours, minutes; @@ -14637,8 +14803,7 @@ void clif_quest_send_list(struct map_session_data * sd) WFIFOW(fd, 2) = len; WFIFOL(fd, 4) = sd->avail_quests; - for( i = 0; i < sd->avail_quests; i++ ) - { + for( i = 0; i < sd->avail_quests; i++ ) { WFIFOL(fd, i*5+8) = sd->quest_log[i].quest_id; WFIFOB(fd, i*5+12) = sd->quest_log[i].state; } @@ -14661,15 +14826,13 @@ void clif_quest_send_mission(struct map_session_data * sd) WFIFOW(fd, 2) = len; WFIFOL(fd, 4) = sd->avail_quests; - for( i = 0; i < sd->avail_quests; i++ ) - { + for( i = 0; i < sd->avail_quests; i++ ) { WFIFOL(fd, i*104+8) = sd->quest_log[i].quest_id; WFIFOL(fd, i*104+12) = sd->quest_log[i].time - quest_db[sd->quest_index[i]].time; WFIFOL(fd, i*104+16) = sd->quest_log[i].time; WFIFOW(fd, i*104+20) = quest_db[sd->quest_index[i]].num_objectives; - for( j = 0 ; j < quest_db[sd->quest_index[i]].num_objectives; j++ ) - { + for( j = 0 ; j < quest_db[sd->quest_index[i]].num_objectives; j++ ) { WFIFOL(fd, i*104+22+j*30) = quest_db[sd->quest_index[i]].mob[j]; WFIFOW(fd, i*104+26+j*30) = sd->quest_log[i].count[j]; mob = mob_db(quest_db[sd->quest_index[i]].mob[j]); @@ -14697,8 +14860,7 @@ void clif_quest_add(struct map_session_data * sd, struct quest * qd, int index) WFIFOL(fd, 11) = qd->time; WFIFOW(fd, 15) = quest_db[index].num_objectives; - for( i = 0; i < quest_db[index].num_objectives; i++ ) - { + for( i = 0; i < quest_db[index].num_objectives; i++ ) { WFIFOL(fd, i*30+17) = quest_db[index].mob[i]; WFIFOW(fd, i*30+21) = qd->count[i]; mob = mob_db(quest_db[index].mob[i]); @@ -14735,8 +14897,7 @@ void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd WFIFOW(fd, 2) = len; WFIFOW(fd, 4) = quest_db[index].num_objectives; - for( i = 0; i < quest_db[index].num_objectives; i++ ) - { + for( i = 0; i < quest_db[index].num_objectives; i++ ) { WFIFOL(fd, i*12+6) = qd->quest_id; WFIFOL(fd, i*12+10) = quest_db[index].mob[i]; WFIFOW(fd, i*12+14) = quest_db[index].count[i]; @@ -14815,8 +14976,7 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type) WFIFOHEAD(fd,packet_len(0x2a2)); WFIFOW(fd,0) = 0x2a2; WFIFOW(fd,2) = type; - switch( type ) - { + switch( type ) { case SP_ATK1: { int atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk; @@ -15113,8 +15273,7 @@ void clif_parse_BattleChat(int fd, struct map_session_data* sd) if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; - if( battle_config.min_chat_delay ) - { + if( battle_config.min_chat_delay ) { if( DIFF_TICK(sd->cantalk_tick, gettick()) > 0 ) return; sd->cantalk_tick = gettick() + battle_config.min_chat_delay; @@ -15264,26 +15423,21 @@ int clif_instance(int instance_id, int type, int flag) void clif_instance_join(int fd, int instance_id) { - if( instance[instance_id].idle_timer != INVALID_TIMER ) - { + if( instance[instance_id].idle_timer != INVALID_TIMER ) { WFIFOHEAD(fd,packet_len(0x02CD)); WFIFOW(fd,0) = 0x02CD; memcpy(WFIFOP(fd,2),instance[instance_id].name,61); WFIFOL(fd,63) = 0; WFIFOL(fd,67) = (uint32)instance[instance_id].idle_timeout; WFIFOSET(fd,packet_len(0x02CD)); - } - else if( instance[instance_id].progress_timer != INVALID_TIMER ) - { + } else if( instance[instance_id].progress_timer != INVALID_TIMER ) { WFIFOHEAD(fd,packet_len(0x02CD)); WFIFOW(fd,0) = 0x02CD; memcpy(WFIFOP(fd,2),instance[instance_id].name,61); WFIFOL(fd,63) = (uint32)instance[instance_id].progress_timeout;; WFIFOL(fd,67) = 0; WFIFOSET(fd,packet_len(0x02CD)); - } - else - { + } else { WFIFOHEAD(fd,packet_len(0x02CB)); WFIFOW(fd,0) = 0x02CB; memcpy(WFIFOP(fd,2),instance[instance_id].name,61); @@ -15856,8 +16010,7 @@ void clif_search_store_info_ack(struct map_session_data* sd) WFIFOB(fd,5) = searchstore_querynext(sd); WFIFOB(fd,6) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX); - for( i = start; i < end; i++ ) - { + for( i = start; i < end; i++ ) { struct s_search_store_info_item* ssitem = &sd->searchstore.items[i]; struct item it; @@ -15975,8 +16128,7 @@ void clif_parse_debug(int fd,struct map_session_data *sd) // clif_parse ensures, that there is at least 2 bytes of data cmd = RFIFOW(fd,0); - if( sd ) - { + if( sd ) { packet_len = packet_db[sd->packet_ver][cmd].len; if( packet_len == 0 ) @@ -16486,9 +16638,6 @@ static int clif_parse(int fd) else if( sd && sd->bl.prev == NULL && packet_db[packet_ver][cmd].func != clif_parse_LoadEndAck ) ; //Only valid packet when player is not on a map - else - if( sd && session[sd->fd]->flag.eof ) - ; //No more packets accepted else packet_db[packet_ver][cmd].func(fd, sd); } @@ -17152,9 +17301,33 @@ int do_init_clif(void) { delay_clearunit_ers = ers_new(sizeof(struct block_list),"clif.c::delay_clearunit_ers",ERS_OPT_CLEAR); + channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, RACHSYS_NAME_LENGTH); + raChSys.ally = raChSys.local = raChSys.ally_autojoin = raChSys.local_autojoin = false; + clif_read_channels_config(); + return 0; } void do_final_clif(void) { + DBIterator *iter = db_iterator(channel_db); + struct raChSysCh *channel; + unsigned char i; + + for( channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter) ) { + clif_chsys_delete(channel); + } + + dbi_destroy(iter); + + for(i = 0; i < raChSys.colors_count; i++) { + aFree(raChSys.colors_name[i]); + } + + if( raChSys.colors_count ) { + aFree(raChSys.colors_name); + aFree(raChSys.colors); + } + + db_destroy(channel_db); ers_destroy(delay_clearunit_ers); } diff --git a/src/map/clif.h b/src/map/clif.h index ab6b2fb2ce..4345e65c4e 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -5,6 +5,7 @@ #define _CLIF_H_ #include "../common/cbasetypes.h" +#include "../common/db.h" //dbmap //#include "../common/mmo.h" struct item; struct storage_data; @@ -73,8 +74,8 @@ typedef enum send_target { GUILD_NOBG, DUEL, DUEL_WOS, - CHAT_MAINCHAT, // everyone on main chat SELF, + BG, // BattleGround System BG_WOS, BG_SAMEMAP, @@ -573,7 +574,6 @@ void clif_displaymessage(const int fd, const char* mes); void clif_disp_onlyself(struct map_session_data *sd, const char *mes, int len); void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target); void clif_broadcast(struct block_list* bl, const char* mes, int len, int type, enum send_target target); -void clif_MainChatMessage(const char* message); void clif_broadcast2(struct block_list* bl, const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target); void clif_heal(int fd,int type,int val); void clif_resurrection(struct block_list *bl,int type); @@ -604,7 +604,6 @@ void clif_weather(int16 m); // [Valaris] void clif_specialeffect(struct block_list* bl, int type, enum send_target target); // special effects [Valaris] void clif_specialeffect_single(struct block_list* bl, int type, int fd); void clif_messagecolor(struct block_list* bl, unsigned long color, const char* msg); // Mob/Npc color talk [SnakeDrak] -void clif_message(struct block_list* bl, const char* msg); void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, send_target target); void clif_GM_kickack(struct map_session_data *sd, int id); @@ -612,7 +611,7 @@ void clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd); void clif_manner_message(struct map_session_data* sd, uint32 type); void clif_GM_silence(struct map_session_data* sd, struct map_session_data* tsd, uint8 type); -void clif_disp_overhead(struct map_session_data *sd, const char* mes); +void clif_disp_overhead(struct block_list *bl, const char* mes); void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, unsigned short *lhand); @@ -767,6 +766,56 @@ enum clif_colors { unsigned long color_table[COLOR_MAX]; int clif_colormes(struct map_session_data * sd, enum clif_colors color, const char* msg); +/** + * Channel System + **/ +#define RACHSYS_NAME_LENGTH 20 + +enum raChSysChOpt { + raChSys_OPT_BASE = 0, + raChSys_OPT_ANNOUNCE_JOIN = 1, +}; + +enum raChSysChType { + raChSys_PUBLIC = 0, + raChSys_PRIVATE = 1, + raChSys_MAP = 2, + raChSys_ALLY = 3, +}; + +struct { + unsigned long *colors; + char **colors_name; + unsigned char colors_count; + bool local, ally; + bool local_autojoin, ally_autojoin; + char local_name[RACHSYS_NAME_LENGTH], ally_name[RACHSYS_NAME_LENGTH]; + unsigned char local_color, ally_color; + bool closing; + bool allow_user_channel_creation; +} raChSys; + +struct raChSysCh { + char name[RACHSYS_NAME_LENGTH]; + char pass[RACHSYS_NAME_LENGTH]; + unsigned char color; + DBMap *users; + unsigned int opt; + unsigned int owner; + enum raChSysChType type; + uint16 m; +}; + +struct DBMap* clif_get_channel_db(void); +void clif_chsys_create(struct raChSysCh *channel, char *name, char *pass, unsigned char color); +void clif_chsys_msg(struct raChSysCh *channel, struct map_session_data *sd, char *msg); +void clif_chsys_send(struct raChSysCh *channel, struct map_session_data *sd, char *msg); +void clif_chsys_join(struct raChSysCh *channel, struct map_session_data *sd); +void clif_chsys_left(struct raChSysCh *channel, struct map_session_data *sd); +void clif_chsys_delete(struct raChSysCh *channel); +void clif_chsys_mjoin(struct map_session_data *sd); +void clif_read_channels_config(void); + #define clif_menuskill_clear(sd) (sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0; #endif /* _CLIF_H_ */ diff --git a/src/map/guild.c b/src/map/guild.c index cf919c6b98..0039b5cbec 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -259,7 +259,7 @@ int guild_getposition(struct guild* g, struct map_session_data* sd) { int i; - if( g == NULL && (g=guild_search(sd->status.guild_id)) == NULL ) + if( g == NULL && (g=sd->guild) == NULL ) return -1; ARR_FIND( 0, g->max_member, i, g->member[i].account_id == sd->status.account_id && g->member[i].char_id == sd->status.char_id ); @@ -481,8 +481,7 @@ int guild_recv_noinfo(int guild_id) struct s_mapiterator* iter; iter = mapit_getallusers(); - for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) - { + for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) { if( sd->status.guild_id == guild_id ) sd->status.guild_id = 0; // erase guild } @@ -499,20 +498,52 @@ int guild_recv_info(struct guild *sg) DBData data; struct map_session_data *sd; bool guild_new = false; + void *aChSysSave = NULL; nullpo_ret(sg); - if((g = (struct guild*)idb_get(guild_db,sg->guild_id))==NULL) - { + if((g = guild_search(sg->guild_id))==NULL) { guild_new = true; g=(struct guild *)aCalloc(1,sizeof(struct guild)); idb_put(guild_db,sg->guild_id,g); - before=*sg; + if( raChSys.ally ) { + struct raChSysCh *channel; - //Perform the check on the user because the first load + CREATE(channel, struct raChSysCh , 1); + safestrncpy(channel->name, raChSys.ally_name, RACHSYS_NAME_LENGTH); + channel->type = raChSys_ALLY; + + clif_chsys_create(channel,NULL,NULL,raChSys.ally_color); + if( raChSys.ally_autojoin ) { + struct s_mapiterator* iter = mapit_getallusers(); + + for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) { + if( sd->status.guild_id ) { + if( sd->status.guild_id == sg->guild_id ) { + clif_chsys_join(channel,sd); + sd->guild = g; + continue; + } + + for (i = 0; i < MAX_GUILDALLIANCE; i++) { + if( sg->alliance[i].guild_id == sd->status.guild_id ) { + clif_chsys_join(channel,sd); + break; + } + } + } + } + + mapit_free(iter); + } + + aChSysSave = (void*)channel; + + } + before=*sg; + //Perform the check on the user because the first load guild_check_member(sg); - if ((sd = map_nick2sd(sg->master)) != NULL) - { + if ((sd = map_nick2sd(sg->master)) != NULL) { //If the guild master is online the first time the guild_info is received, //that means he was the first to join, so apply guild skill blocking here. if( battle_config.guild_skill_relog_delay ) @@ -523,12 +554,16 @@ int guild_recv_info(struct guild *sg) clif_charnameupdate(sd); // [LuzZza] clif_guild_masterormember(sd); } - }else + } else { before=*g; + if( g->channel ) + aChSysSave = g->channel; + } memcpy(g,sg,sizeof(struct guild)); - if(g->max_member > MAX_GUILD) - { + g->channel = aChSysSave; + + if(g->max_member > MAX_GUILD) { ShowError("guild_recv_info: Received guild with %d members, but MAX_GUILD is only %d. Extra guild-members have been lost!\n", g->max_member, MAX_GUILD); g->max_member = MAX_GUILD; } @@ -570,10 +605,9 @@ int guild_recv_info(struct guild *sg) } //Occurrence of an event - if (guild_infoevent_db->remove(guild_infoevent_db, db_i2key(sg->guild_id), &data)) - { + if (guild_infoevent_db->remove(guild_infoevent_db, db_i2key(sg->guild_id), &data)) { struct eventlist *ev = db_data2ptr(&data), *ev2; - while(ev){ + while(ev) { npc_event_do(ev->name); ev2=ev->next; aFree(ev); @@ -593,7 +627,7 @@ int guild_invite(struct map_session_data *sd, struct map_session_data *tsd) { nullpo_ret(sd); - g=guild_search(sd->status.guild_id); + g=sd->guild; if(tsd==NULL || g==NULL) return 0; @@ -684,6 +718,7 @@ int guild_reply_invite(struct map_session_data* sd, int guild_id, int flag) return 0; } + sd->guild = g; guild_makemember(&m,sd); intif_guild_addmember(guild_id, &m); //TODO: send a minimap update to this player @@ -705,8 +740,7 @@ void guild_member_joined(struct map_session_data *sd) guild_request_info(sd->status.guild_id); return; } - if (strcmp(sd->status.name,g->master) == 0) - { // set the Guild Master flag + if (strcmp(sd->status.name,g->master) == 0) { // set the Guild Master flag sd->state.gmaster_flag = g; // prevent Guild Skills from being used directly after relog if( battle_config.guild_skill_relog_delay ) @@ -715,8 +749,22 @@ void guild_member_joined(struct map_session_data *sd) i = guild_getindex(g, sd->status.account_id, sd->status.char_id); if (i == -1) sd->status.guild_id = 0; - else + else { g->member[i].sd = sd; + sd->guild = g; + + if( raChSys.ally && raChSys.ally_autojoin ) { + struct guild* sg = NULL; + clif_chsys_join((struct raChSysCh*)g->channel,sd); + + for (i = 0; i < MAX_GUILDALLIANCE; i++) { + if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) { + clif_chsys_join((struct raChSysCh*)sg->channel,sd); + break; + } + } + } + } } /*========================================== @@ -775,7 +823,7 @@ int guild_leave(struct map_session_data* sd, int guild_id, int account_id, int c nullpo_ret(sd); - g = guild_search(sd->status.guild_id); + g = sd->guild; if(g==NULL) return 0; @@ -800,7 +848,7 @@ int guild_expulsion(struct map_session_data* sd, int guild_id, int account_id, i nullpo_ret(sd); - g = guild_search(sd->status.guild_id); + g = sd->guild; if(g==NULL) return 0; @@ -859,8 +907,14 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c if (sd->state.storage_flag == 2) //Close the guild storage. storage_guild_storageclose(sd); guild_send_dot_remove(sd); - + if( raChSys.ally ) { + for (i = 0; i < sd->channel_count; i++) { + if( sd->channels[i] && sd->channels[i]->type == raChSys_ALLY ) + clif_chsys_left(sd->channels[i],sd); + } + } sd->status.guild_id = 0; + sd->guild = NULL; sd->guild_emblem_id = 0; clif_charnameupdate(sd); //Update display name [Skotlex] @@ -878,7 +932,7 @@ int guild_send_memberinfoshort(struct map_session_data *sd,int online) if(sd->status.guild_id <= 0) return 0; - if(!(g = guild_search(sd->status.guild_id))) + if(!(g = sd->guild)) return 0; intif_guild_memberinfoshort(g->guild_id, @@ -1097,7 +1151,7 @@ int guild_change_emblem(struct map_session_data *sd,int len,const char *data) nullpo_ret(sd); if (battle_config.require_glory_guild && - !((g = guild_search(sd->status.guild_id)) && guild_checkskill(g, GD_GLORYGUILD)>0)) { + !((g = sd->guild) && guild_checkskill(g, GD_GLORYGUILD)>0)) { clif_skill_fail(sd,GD_GLORYGUILD,USESKILL_FAIL_LEVEL,0); return 0; } @@ -1196,7 +1250,7 @@ unsigned int guild_payexp(struct map_session_data *sd,unsigned int exp) if (!exp) return 0; if (sd->status.guild_id == 0 || - (g = guild_search(sd->status.guild_id)) == NULL || + (g = sd->guild) == NULL || (per = guild_getposition(g,sd)) < 0 || (per = g->position[per].exp_mode) < 1) return 0; @@ -1226,7 +1280,7 @@ int guild_getexp(struct map_session_data *sd,int exp) struct guild_expcache *c; nullpo_ret(sd); - if (sd->status.guild_id == 0 || guild_search(sd->status.guild_id) == NULL) + if (sd->status.guild_id == 0 || sd->guild == NULL) return 0; c = db_data2ptr(guild_expcache_db->ensure(guild_expcache_db, db_i2key(sd->status.char_id), create_expcache, sd)); @@ -1249,7 +1303,7 @@ int guild_skillup(TBL_PC* sd, uint16 skill_id) nullpo_ret(sd); if( idx < 0 || idx >= MAX_GUILDSKILL || // not a guild skill - sd->status.guild_id == 0 || (g=guild_search(sd->status.guild_id)) == NULL || // no guild + sd->status.guild_id == 0 || (g=sd->guild) == NULL || // no guild strcmp(sd->status.name, g->master) ) // not the guild master return 0; @@ -1380,8 +1434,8 @@ int guild_reqalliance(struct map_session_data *sd,struct map_session_data *tsd) if(tsd==NULL || tsd->status.guild_id<=0) return 0; - g[0]=guild_search(sd->status.guild_id); - g[1]=guild_search(tsd->status.guild_id); + g[0]=sd->guild; + g[1]=tsd->guild; if(g[0]==NULL || g[1]==NULL) return 0; @@ -1433,15 +1487,15 @@ int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag) return 0; } - if (sd->guild_alliance != tsd->status.guild_id) // proposed guild_id alliance doesn't match tsd guildid + if (sd->guild_alliance != tsd->status.guild_id) // proposed guild_id alliance doesn't match tsd guildid return 0; - if (flag == 1) { // consent + if (flag == 1) { // consent int i; - struct guild *g, *tg; // Reconfirm the number of alliance - g=guild_search(sd->status.guild_id); - tg=guild_search(tsd->status.guild_id); + struct guild *g, *tg; // Reconfirm the number of alliance + g=sd->guild; + tg=tsd->guild; if(g==NULL || guild_get_alliance_count(g,0) >= battle_config.max_guild_alliance){ clif_guild_allianceack(sd,4); @@ -1467,11 +1521,11 @@ int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag) tsd->status.account_id,sd->status.account_id,9 ); } - // inform other servers + // inform other servers intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, sd->status.account_id,tsd->status.account_id,0 ); return 0; - } else { // deny + } else { // deny sd->guild_alliance=0; sd->guild_alliance_account=0; if(tsd!=NULL) @@ -1506,7 +1560,7 @@ int guild_opposition(struct map_session_data *sd,struct map_session_data *tsd) nullpo_ret(sd); - g=guild_search(sd->status.guild_id); + g=sd->guild; if(g==NULL || tsd==NULL) return 0; @@ -1683,6 +1737,7 @@ int guild_broken(int guild_id,int flag) if(sd->state.storage_flag == 2) storage_guild_storage_quit(sd,1); sd->status.guild_id=0; + sd->guild = NULL; clif_guild_broken(g->member[i].sd,0); clif_charnameupdate(sd); // [LuzZza] } @@ -1691,6 +1746,11 @@ int guild_broken(int guild_id,int flag) guild_db->foreach(guild_db,guild_broken_sub,guild_id); castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id); guild_storage_delete(guild_id); + if( raChSys.ally ) { + if( g->channel != NULL ) { + clif_chsys_delete(( struct raChSysCh * )g->channel); + } + } idb_remove(guild_db,guild_id); return 0; } @@ -1743,14 +1803,12 @@ int guild_gm_changed(int guild_id, int account_id, int char_id) g->member[0].position = 0; //Position 0: guild Master. strcpy(g->master, g->member[0].name); - if (g->member[pos].sd && g->member[pos].sd->fd) - { + if (g->member[pos].sd && g->member[pos].sd->fd) { clif_displaymessage(g->member[pos].sd->fd, msg_txt(678)); //"You no longer are the Guild Master." g->member[pos].sd->state.gmaster_flag = 0; } - if (g->member[0].sd && g->member[0].sd->fd) - { + if (g->member[0].sd && g->member[0].sd->fd) { clif_displaymessage(g->member[0].sd->fd, msg_txt(679)); //"You have become the Guild Master!" g->member[0].sd->state.gmaster_flag = g; //Block his skills for 5 minutes to prevent abuse. @@ -1780,7 +1838,7 @@ int guild_break(struct map_session_data *sd,char *name) nullpo_ret(sd); - if( (g=guild_search(sd->status.guild_id))==NULL ) + if( (g=sd->guild)==NULL ) return 0; if(strcmp(g->name,name)!=0) return 0; @@ -2136,12 +2194,21 @@ void do_init_guild(void) { } void do_final_guild(void) { - + DBIterator *iter = db_iterator(guild_db); + struct guild *g; + + for( g = dbi_first(iter); dbi_exists(iter); g = dbi_next(iter) ) { + if( g->channel != NULL ) + clif_chsys_delete((struct raChSysCh *)g->channel); + } + + dbi_destroy(iter); + db_destroy(guild_db); castle_db->destroy(castle_db,guild_castle_db_final); guild_expcache_db->destroy(guild_expcache_db,guild_expcache_db_final); guild_infoevent_db->destroy(guild_infoevent_db,eventlist_db_final); ers_destroy(expcache_ers); - + aFree(guild_flags);/* never empty; created on boot */ } diff --git a/src/map/intif.c b/src/map/intif.c index f11ba23500..c9ff1ad02a 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -170,10 +170,7 @@ int intif_broadcast(const char* mes, int len, int type) int intif_broadcast2(const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY) { // Send to the local players - if (fontColor == 0xFE000000) // This is main chat message [LuzZza] - clif_MainChatMessage(mes); - else - clif_broadcast2(NULL, mes, len, fontColor, fontType, fontSize, fontAlign, fontY, ALL_CLIENT); + clif_broadcast2(NULL, mes, len, fontColor, fontType, fontSize, fontAlign, fontY, ALL_CLIENT); if (CheckForCharServer()) return 0; @@ -2183,8 +2180,6 @@ int intif_parse(int fd) case 0x3800: if (RFIFOL(fd,4) == 0xFF000000) //Normal announce. clif_broadcast(NULL, (char *) RFIFOP(fd,16), packet_len-16, 0, ALL_CLIENT); - else if (RFIFOL(fd,4) == 0xFE000000) //Main chat message [LuzZza] - clif_MainChatMessage((char *)RFIFOP(fd,16)); else //Color announce. clif_broadcast2(NULL, (char *) RFIFOP(fd,16), packet_len-16, RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), ALL_CLIENT); break; diff --git a/src/map/map.c b/src/map/map.c index 6b7b11a68b..fbaf5d4f82 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -81,10 +81,6 @@ char log_db_pw[32] = "ragnarok"; char log_db_db[32] = "log"; Sql* logmysql_handle; -// This param using for sending mainchat -// messages like whispers to this nick. [LuzZza] -char main_chat_nick[16] = "Main"; - // DBMap declaartion static DBMap* id_db=NULL; // int id -> struct block_list* static DBMap* pc_db=NULL; // int id -> struct map_session_data* @@ -1698,10 +1694,33 @@ int map_quit(struct map_session_data *sd) { unit_remove_map(&sd->ed->bl,CLR_TELEPORT); } + if( raChSys.ally && sd->status.guild_id ) { + struct guild *g = sd->guild, *sg; + if( g ) { + if( idb_exists(((struct raChSysCh *)g->channel)->users, sd->status.char_id) ) + clif_chsys_left((struct raChSysCh *)g->channel,sd); + for (i = 0; i < MAX_GUILDALLIANCE; i++) { + if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) { + if( idb_exists(((struct raChSysCh *)sg->channel)->users, sd->status.char_id) ) + clif_chsys_left((struct raChSysCh *)sg->channel,sd); + break; + } + } + } + } + + if( sd->channel_count ) { + for( i = 0; i < sd->channel_count; i++ ) { + if( sd->channels[i] != NULL ) + clif_chsys_left(sd->channels[i],sd); + } + if( raChSys.closing ) + aFree(sd->channels); + } + unit_remove_map_pc(sd,CLR_TELEPORT); - if( map[sd->bl.m].instance_id ) - { // Avoid map conflicts and warnings on next login + if( map[sd->bl.m].instance_id ) { // Avoid map conflicts and warnings on next login int16 m; struct point *pt; if( map[sd->bl.m].save.map ) @@ -3354,9 +3373,6 @@ int inter_config_read(char *cfgName) if( sscanf(line,"%[^:]: %[^\r\n]",w1,w2) < 2 ) continue; - if(strcmpi(w1, "main_chat_nick")==0) - safestrncpy(main_chat_nick, w2, sizeof(main_chat_nick)); - else if(strcmpi(w1,"item_db_db")==0) strcpy(item_db_db,w2); else @@ -3553,6 +3569,7 @@ void do_final(void) struct s_mapiterator* iter; ShowStatus("Terminating...\n"); + raChSys.closing = true; //Ladies and babies first. iter = mapit_getallusers(); diff --git a/src/map/map.h b/src/map/map.h index 4d62ff198c..d60bc726e0 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -20,6 +20,7 @@ struct npc_data; struct item_data; +struct raChSysCh; enum E_MAPSERVER_ST { @@ -573,6 +574,7 @@ struct map_data { unsigned guildlock :1; unsigned src4instance : 1; // To flag this map when it's used as a src map for instances unsigned reset :1; // [Daegaladh] + unsigned chsysnolocalaj : 1; } flag; struct point save; struct npc_data *npc[MAX_NPC_PER_MAP]; @@ -598,6 +600,9 @@ struct map_data { // Instance Variables int instance_id; int instance_src_map; + + /* rAthena Local Chat */ + struct raChSysCh *channel; }; /// Stores information about a remote map (for multi-mapserver setups). @@ -775,8 +780,6 @@ typedef struct elemental_data TBL_ELEM; ( ((bl) == (struct block_list*)NULL || (bl)->type != (type_)) ? (T ## type_ *)NULL : (T ## type_ *)(bl) ) -extern char main_chat_nick[16]; - #ifdef BETA_THREAD_TEST extern char default_codepage[32]; diff --git a/src/map/npc.c b/src/map/npc.c index 01a74683ce..9b5802419c 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -3424,6 +3424,8 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con map[m].flag.guildlock=state; else if (!strcmpi(w3,"reset")) map[m].flag.reset=state; + else if (!strcmpi(w3,"nomapchannelautojoin")) + map[m].flag.chsysnolocalaj = state; else ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer)); diff --git a/src/map/pc.c b/src/map/pc.c index 2cf35744de..a2257162d5 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1228,8 +1228,7 @@ int pc_reg_received(struct map_session_data *sd) intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox intif_request_questlog(sd); - if (sd->state.connect_new == 0 && sd->fd) - { //Character already loaded map! Gotta trigger LoadEndAck manually. + if (sd->state.connect_new == 0 && sd->fd) { //Character already loaded map! Gotta trigger LoadEndAck manually. sd->state.connect_new = 1; clif_parse_LoadEndAck(sd->fd, sd); } @@ -4743,6 +4742,10 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y clif_displaymessage (sd->fd, msg_txt(276)); // "You can't open a shop on this map" vending_closevending(sd); } + + if( raChSys.local && map[sd->bl.m].channel && idb_exists(map[sd->bl.m].channel->users, sd->status.char_id) ) { + clif_chsys_left(map[sd->bl.m].channel,sd); + } } if( m < 0 ) @@ -4924,16 +4927,13 @@ int pc_memo(struct map_session_data* sd, int pos) int pc_checkskill(struct map_session_data *sd,uint16 skill_id) { if(sd == NULL) return 0; - if( skill_id >= GD_SKILLBASE && skill_id < GD_MAX ) - { + if( skill_id >= GD_SKILLBASE && skill_id < GD_MAX ) { struct guild *g; - if( sd->status.guild_id>0 && (g=guild_search(sd->status.guild_id))!=NULL) + if( sd->status.guild_id>0 && (g=sd->guild)!=NULL) return guild_checkskill(g,skill_id); return 0; - } - else if(skill_id >= ARRAYLENGTH(sd->status.skill) ) - { + } else if(skill_id >= ARRAYLENGTH(sd->status.skill) ) { ShowError("pc_checkskill: Invalid skill id %d (char_id=%d).\n", skill_id, sd->status.char_id); return 0; } @@ -8570,7 +8570,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) } if(pos & EQP_SHOES) clif_changelook(&sd->bl,LOOK_SHOES,0); - if(pos&EQP_GARMENT) { + if(pos&EQP_GARMENT && pc_checkequip(sd,EQP_COSTUME_GARMENT) == -1) { sd->status.robe = id ? id->look : 0; clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe); } diff --git a/src/map/pc.h b/src/map/pc.h index 5ce9ed5479..2e21bf43d4 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -136,7 +136,6 @@ struct map_session_data { unsigned int showdelay :1; unsigned int showexp :1; unsigned int showzeny :1; - unsigned int mainchat :1; //[LuzZza] unsigned int noask :1; // [LuzZza] unsigned int trading :1; //[Skotlex] is 1 only after a trade has started. unsigned int deal_locked :2; //1: Clicked on OK. 2: Clicked on TRADE @@ -386,6 +385,7 @@ struct map_session_data { int party_invite, party_invite_account; // for handling party invitation (holds party id and account id) int adopt_invite; // Adoption + struct guild *guild; // [Ind] speed everything up int guild_invite,guild_invite_account; int guild_emblem_id,guild_alliance,guild_alliance_account; short guild_x,guild_y; // For guildmate position display. [Skotlex] should be short [zzo] @@ -496,6 +496,13 @@ struct map_session_data { int shadowform_id; + /* Channel System [Ind] */ + struct raChSysCh **channels; + unsigned char channel_count; + struct raChSysCh *gcbind; + bool stealth; + unsigned char fontcolor; /* debug-only */ + // temporary debugging of bug #3504 const char* delunit_prevfile; int delunit_prevline; diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h index 65c48935a6..9918913561 100644 --- a/src/map/pc_groups.h +++ b/src/map/pc_groups.h @@ -39,10 +39,11 @@ enum e_pc_permission { PC_PERM_USE_CHANGEMAPTYPE = 0x004000, PC_PERM_USE_ALL_COMMANDS = 0x008000, PC_PERM_RECEIVE_REQUESTS = 0x010000, - PC_PERM_SHOW_BOSS = 0x020000, - PC_PERM_DISABLE_PVM = 0x040000, - PC_PERM_DISABLE_PVP = 0x080000, + PC_PERM_SHOW_BOSS = 0x020000, + PC_PERM_DISABLE_PVM = 0x040000, + PC_PERM_DISABLE_PVP = 0x080000, PC_PERM_DISABLE_CMD_DEAD = 0x100000, + PC_PERM_CHANNEL_ADMIN = 0x200000, }; static const struct { @@ -70,6 +71,7 @@ static const struct { { "disable_pvm", PC_PERM_DISABLE_PVM }, { "disable_pvp", PC_PERM_DISABLE_PVP }, { "disable_commands_when_dead", PC_PERM_DISABLE_CMD_DEAD }, + { "channel_admin", PC_PERM_CHANNEL_ADMIN }, }; #endif // _PC_GROUPS_H_ diff --git a/src/map/script.c b/src/map/script.c index d4ee1f6a3b..6b1b44b340 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -7259,22 +7259,16 @@ BUILDIN_FUNC(strcharinfo) script_pushstrcopy(st,sd->status.name); break; case 1: - if( ( p = party_search(sd->status.party_id) ) != NULL ) - { + if( ( p = party_search(sd->status.party_id) ) != NULL ) { script_pushstrcopy(st,p->party.name); - } - else - { + } else { script_pushconststr(st,""); } break; case 2: - if( ( g = guild_search(sd->status.guild_id) ) != NULL ) - { + if( ( g = guild_search(sd->status.guild_id) ) != NULL ) { script_pushstrcopy(st,g->name); - } - else - { + } else { script_pushconststr(st,""); } break; @@ -12973,7 +12967,7 @@ BUILDIN_FUNC(npctalk) safestrncpy(name, nd->name, sizeof(name)); strtok(name, "#"); // discard extra name identifier if present safesnprintf(message, sizeof(message), "%s : %s", name, str); - clif_message(&nd->bl, message); + clif_disp_overhead(&nd->bl, message); } return 0; @@ -15459,7 +15453,7 @@ BUILDIN_FUNC(unittalk) struct StringBuf sbuf; StringBuf_Init(&sbuf); StringBuf_Printf(&sbuf, "%s : %s", status_get_name(bl), message); - clif_message(bl, StringBuf_Value(&sbuf)); + clif_disp_overhead(bl, StringBuf_Value(&sbuf)); if( bl->type == BL_PC ) clif_displaymessage(((TBL_PC*)bl)->fd, StringBuf_Value(&sbuf)); StringBuf_Destroy(&sbuf); diff --git a/src/map/skill.c b/src/map/skill.c index 69eff8136e..476e0885d1 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5992,7 +5992,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui //NOTE: mobs don't have the sprite animation that is used when performing this skill (will cause glitches) char temp[70]; snprintf(temp, sizeof(temp), "%s : %s !!",md->name,skill_db[skill_id].desc); - clif_message(&md->bl,temp); + clif_disp_overhead(&md->bl,temp); } break;