diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 53 | ||||
-rw-r--r-- | src/char/int_status.c | 4 | ||||
-rw-r--r-- | src/char_sql/char.c | 50 | ||||
-rw-r--r-- | src/common/mmo.h | 50 | ||||
-rw-r--r-- | src/map/atcommand.c | 54 | ||||
-rw-r--r-- | src/map/battle.c | 4 | ||||
-rw-r--r-- | src/map/clif.c | 164 | ||||
-rw-r--r-- | src/map/clif.h | 32 | ||||
-rw-r--r-- | src/map/npc.c | 1 | ||||
-rw-r--r-- | src/map/party.c | 51 | ||||
-rw-r--r-- | src/map/party.h | 1 | ||||
-rw-r--r-- | src/map/script.c | 105 | ||||
-rw-r--r-- | src/map/skill.c | 3 |
13 files changed, 445 insertions, 127 deletions
diff --git a/src/char/char.c b/src/char/char.c index 200257584..f2910751f 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1675,16 +1675,19 @@ int count_users(void) return users; } -/// Writes char data to the buffer in the format used by the client. -/// Used in packets 0x6b (chars info) and 0x6d (new char info) -/// Returns the size (106 or 108) -int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p) +// Writes char data to the buffer in the format used by the client. +// Used in packets 0x6b (chars info) and 0x6d (new char info) +// Returns the size +#define MAX_CHAR_BUF 110 //Max size (for WFIFOHEAD calls) +int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) { - int size = 106; + unsigned short offset = 0; + uint8* buf; - if( buf == NULL || p == NULL ) + if( buffer == NULL || p == NULL ) return 0; + buf = WBUFP(buffer,0); WBUFL(buf,0) = p->char_id; WBUFL(buf,4) = min(p->base_exp, LONG_MAX); WBUFL(buf,8) = p->zeny; @@ -1696,8 +1699,15 @@ int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p) WBUFL(buf,32) = p->karma; WBUFL(buf,36) = p->manner; WBUFW(buf,40) = min(p->status_point, SHRT_MAX); +#if PACKETVER > 20081217 + WBUFL(buf,42) = p->hp; + WBUFL(buf,46) = p->max_hp; + offset+=4; + buf = WBUFP(buffer,offset); +#else WBUFW(buf,42) = min(p->hp, SHRT_MAX); WBUFW(buf,44) = min(p->max_hp, SHRT_MAX); +#endif WBUFW(buf,46) = min(p->sp, SHRT_MAX); WBUFW(buf,48) = min(p->max_sp, SHRT_MAX); WBUFW(buf,50) = DEFAULT_WALK_SPEED; // p->speed; @@ -1722,10 +1732,9 @@ int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p) WBUFW(buf,104) = p->slot; #if PACKETVER >= 20061023 WBUFW(buf,106) = ( p->rename > 0 ) ? 0 : 1; - size += 2; + offset += 2; #endif - - return size; + return 106+offset; } //---------------------------------------- @@ -1747,7 +1756,7 @@ int mmo_char_send006b(int fd, struct char_session_data* sd) sd->found_char[i] = -1; j = 24; // offset - WFIFOHEAD(fd,j + found_num*108); // or 106(!) + WFIFOHEAD(fd,j + found_num*MAX_CHAR_BUF); WFIFOW(fd,0) = 0x6b; memset(WFIFOP(fd,4), 0, 20); // unknown bytes for(i = 0; i < found_num; i++) @@ -3473,7 +3482,7 @@ int parse_char(int fd) { int len; // send to player - WFIFOHEAD(fd,110); + WFIFOHEAD(fd,MAX_CHAR_BUF+2); WFIFOW(fd,0) = 0x6d; len = 2 + mmo_char_tobuf(WFIFOP(fd,2), &char_dat[i].status); WFIFOSET(fd,len); @@ -3613,6 +3622,28 @@ int parse_char(int fd) RFIFOSKIP(fd,34); break; + // captcha code request (not implemented) + // R 07e5 <?>.w <aid>.l + case 0x7e5: + WFIFOHEAD(fd,5); + WFIFOW(fd,0) = 0x7e9; + WFIFOW(fd,2) = 5; + WFIFOB(fd,4) = 1; + WFIFOSET(fd,5); + RFIFOSKIP(fd,8); + break; + + // captcha code check (not implemented) + // R 07e7 <len>.w <aid>.l <code>.b10 <?>.b14 + case 0x7e7: + WFIFOHEAD(fd,5); + WFIFOW(fd,0) = 0x7e9; + WFIFOW(fd,2) = 5; + WFIFOB(fd,4) = 1; + WFIFOSET(fd,5); + RFIFOSKIP(fd,32); + break; + // login as map-server case 0x2af8: if (RFIFOREST(fd) < 60) diff --git a/src/char/int_status.c b/src/char/int_status.c index bf5d94155..52b14ebbe 100644 --- a/src/char/int_status.c +++ b/src/char/int_status.c @@ -54,7 +54,7 @@ static void inter_status_tostr(char* line, struct scdata *sc_data) len = sprintf(line, "%d,%d,%d\t", sc_data->account_id, sc_data->char_id, sc_data->count); for(i = 0; i < sc_data->count; i++) { - len += sprintf(line + len, "%d,%d,%d,%d,%d,%d\t", sc_data->data[i].type, sc_data->data[i].tick, + len += sprintf(line + len, "%d,%ld,%ld,%ld,%ld,%ld\t", sc_data->data[i].type, sc_data->data[i].tick, sc_data->data[i].val1, sc_data->data[i].val2, sc_data->data[i].val3, sc_data->data[i].val4); } return; @@ -74,7 +74,7 @@ static int inter_scdata_fromstr(char *line, struct scdata *sc_data) for (i = 0; i < sc_data->count; i++) { - if (sscanf(line + next, "%hu,%d,%d,%d,%d,%d\t%n", &sc_data->data[i].type, &sc_data->data[i].tick, + if (sscanf(line + next, "%hu,%ld,%ld,%ld,%ld,%ld\t%n", &sc_data->data[i].type, &sc_data->data[i].tick, &sc_data->data[i].val1, &sc_data->data[i].val2, &sc_data->data[i].val3, &sc_data->data[i].val4, &len) < 6) { aFree(sc_data->data); diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 85e7d83c0..ee1e08bdb 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -132,7 +132,6 @@ struct char_session_data { char new_name[NAME_LENGTH]; }; -int char_num, char_max; int max_connect_user = 0; int gm_allow_level = 99; int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; @@ -811,6 +810,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit return 0; } +#define MAX_CHAR_BUF 110 //Max size (for WFIFOHEAD calls) int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p); #ifndef TXT_SQL_CONVERT @@ -1538,14 +1538,16 @@ int count_users(void) /// Writes char data to the buffer in the format used by the client. /// Used in packets 0x6b (chars info) and 0x6d (new char info) -/// Returns the size (106 or 108) -int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p) +// Returns the size +int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) { - int size = 106; + unsigned short offset = 0; + uint8* buf; - if( buf == NULL || p == NULL ) + if( buffer == NULL || p == NULL ) return 0; + buf = WBUFP(buffer,0); WBUFL(buf,0) = p->char_id; WBUFL(buf,4) = min(p->base_exp, LONG_MAX); WBUFL(buf,8) = p->zeny; @@ -1557,8 +1559,15 @@ int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p) WBUFL(buf,32) = p->karma; WBUFL(buf,36) = p->manner; WBUFW(buf,40) = min(p->status_point, SHRT_MAX); +#if PACKETVER > 20081217 + WBUFL(buf,42) = p->hp; + WBUFL(buf,46) = p->max_hp; + offset+=4; + buf = WBUFP(buffer,offset); +#else WBUFW(buf,42) = min(p->hp, SHRT_MAX); WBUFW(buf,44) = min(p->max_hp, SHRT_MAX); +#endif WBUFW(buf,46) = min(p->sp, SHRT_MAX); WBUFW(buf,48) = min(p->max_sp, SHRT_MAX); WBUFW(buf,50) = DEFAULT_WALK_SPEED; // p->speed; @@ -1583,10 +1592,9 @@ int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p) WBUFW(buf,104) = p->slot; #if PACKETVER >= 20061023 WBUFW(buf,106) = ( p->rename > 0 ) ? 0 : 1; - size += 2; + offset+=2; #endif - - return size; + return 106+offset; } int mmo_char_send006b(int fd, struct char_session_data* sd) @@ -1597,7 +1605,7 @@ int mmo_char_send006b(int fd, struct char_session_data* sd) ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id); j = 24; // offset - WFIFOHEAD(fd,j + MAX_CHARS*108); // or 106(!) + WFIFOHEAD(fd,j + MAX_CHARS*MAX_CHAR_BUF); WFIFOW(fd,0) = 0x6b; memset(WFIFOP(fd,4), 0, 20); // unknown bytes j+=mmo_chars_fromsql(sd, WFIFOP(fd,j)); @@ -3204,7 +3212,7 @@ int parse_char(int fd) mmo_char_fromsql(i, &char_dat, false); //Only the short data is needed. // send to player - WFIFOHEAD(fd,110); + WFIFOHEAD(fd,2+MAX_CHAR_BUF); WFIFOW(fd,0) = 0x6d; len = 2 + mmo_char_tobuf(WFIFOP(fd,2), &char_dat); WFIFOSET(fd,len); @@ -3345,6 +3353,28 @@ int parse_char(int fd) } break; + // captcha code request (not implemented) + // R 07e5 <?>.w <aid>.l + case 0x7e5: + WFIFOHEAD(fd,5); + WFIFOW(fd,0) = 0x7e9; + WFIFOW(fd,2) = 5; + WFIFOB(fd,4) = 1; + WFIFOSET(fd,5); + RFIFOSKIP(fd,8); + break; + + // captcha code check (not implemented) + // R 07e7 <len>.w <aid>.l <code>.b10 <?>.b14 + case 0x7e7: + WFIFOHEAD(fd,5); + WFIFOW(fd,0) = 0x7e9; + WFIFOW(fd,2) = 5; + WFIFOB(fd,4) = 1; + WFIFOSET(fd,5); + RFIFOSKIP(fd,32); + break; + // log in as map-server case 0x2af8: if (RFIFOREST(fd) < 60) diff --git a/src/common/mmo.h b/src/common/mmo.h index d772f6fea..69a316dc4 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -7,6 +7,41 @@ #include "cbasetypes.h" #include <time.h> +// server->client protocol version +// 0 - pre-? +// 1 - ? - 0x196 +// 2 - ? - 0x78, 0x79 +// 3 - ? - 0x1c8, 0x1c9, 0x1de +// 4 - ? - 0x1d7, 0x1d8, 0x1d9, 0x1da +// 5 - 2003-12-18aSakexe+ - 0x1ee, 0x1ef, 0x1f0, ?0x1c4, 0x1c5? +// 6 - 2004-03-02aSakexe+ - 0x1f4, 0x1f5 +// 7 - 2005-04-11aSakexe+ - 0x229, 0x22a, 0x22b, 0x22c +// 20070521 - 2007-05-21aSakexe+ - 0x283 +// 20070821 - 2007-08-21aSakexe+ - 0x2c5 +// 20070918 - 2007-09-18aSakexe+ - 0x2d7, 0x2d9, 0x2da +// 20071106 - 2007-11-06aSakexe+ - 0x78, 0x7c, 0x22c +// 20081126 - 2008-11-26aSakexe+ - 0x1a2 +// 20090408 - 2009-04-08aSakexe+ - 0x44a (dont use as it overlaps with RE client packets) +// 20080827 - 2008-08-27aRagexeRE+ - First RE Client +// 20081217 - 2008-12-17aRagexeRE+ - 0x6d (Note: This one still use old Char Info Packet Structure) +// 20081218 - 2008-12-17bRagexeRE+ - 0x6d (Note: From this one client use new Char Info Packet Structure) +// 20090603 - 2009-06-03aRagexeRE+ - 0x7d7, 0x7d8, 0x7d9, 0x7da +// 20090617 - 2009-06-17aRagexeRE+ - 0x7d9 +// 20090922 - 2009-09-22aRagexeRE+ - 0x7e5, 0x7e7, 0x7e8, 0x7e9 +#ifndef PACKETVER + #define PACKETVER 20081126 + //#define PACKETVER 20090922 +#endif +// backward compatible PACKETVER 8 and 9 +#if PACKETVER == 8 +#undef PACKETVER +#define PACKETVER 20070521 +#endif +#if PACKETVER == 9 +#undef PACKETVER +#define PACKETVER 20071106 +#endif + #define FIFOSIZE_SERVERLINK 256*1024 //Remove/Comment this line to disable sc_data saving. [Skotlex] @@ -15,8 +50,17 @@ //Note that newer clients no longer save hotkeys in the registry! #define HOTKEY_SAVING -//The number is the max number of hotkeys to save (27 = 9 skills x 3 bars) -#define MAX_HOTKEYS 27 +//The number is the max number of hotkeys to save +#if PACKETVER < 20090603 + // (27 = 9 skills x 3 bars) (0x02b9,191) + #define MAX_HOTKEYS 27 +#elif PACKETVER < 20090617 + // (36 = 9 skills x 4 bars) (0x07d9,254) + #define MAX_HOTKEYS 36 +#else + // (38 = 9 skills x 4 bars & 2 Quickslots)(0x07d9,268) + #define MAX_HOTKEYS 38 +#endif #define MAX_MAP_PER_SERVER 1500 // Increased to allow creation of Instance Maps #define MAX_INVENTORY 100 @@ -172,7 +216,7 @@ struct accreg { //For saving status changes across sessions. [Skotlex] struct status_change_data { unsigned short type; //SC_type - int val1, val2, val3, val4, tick; //Remaining duration. + long val1, val2, val3, val4, tick; //Remaining duration. }; struct storage_data { diff --git a/src/map/atcommand.c b/src/map/atcommand.c index fe86cced7..bb8c1d683 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -2725,8 +2725,7 @@ int atcommand_produce(const int fd, struct map_session_data* sd, const char* com if ((item_data = itemdb_searchname(item_name)) == NULL && (item_data = itemdb_exists(atoi(item_name))) == NULL) { - strcpy(atcmd_output, msg_txt(170)); // The item is not equipable. - clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, msg_txt(170)); //This item is not an equipment. return -1; } item_id = item_data->nameid; @@ -5950,62 +5949,17 @@ int atcommand_changegm(const int fd, struct map_session_data* sd, const char* co *------------------------------------------*/ int atcommand_changeleader(const int fd, struct map_session_data* sd, const char* command, const char* message) { - struct party_data *p; - struct map_session_data *pl_sd; - int mi, pl_mi; nullpo_retr(-1, sd); - - if (sd->status.party_id == 0 || (p = party_search(sd->status.party_id)) == NULL) - { //Need to be a party leader. - clif_displaymessage(fd, msg_txt(282)); - return -1; - } - - if( map[sd->bl.m].flag.partylock ) - { - clif_displaymessage(fd, "You cannot change party leaders on this map."); - return -1; - } - - ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd ); - if (mi == MAX_PARTY) - return -1; //Shouldn't happen - - if (!p->party.member[mi].leader) - { //Need to be a party leader. - clif_displaymessage(fd, msg_txt(282)); - return -1; - } if (strlen(message)==0) { clif_displaymessage(fd, "Command usage: @changeleader <party member name>"); return -1; } - - if((pl_sd=map_nick2sd((char *) message)) == NULL || pl_sd->status.party_id != sd->status.party_id) { - clif_displaymessage(fd, msg_txt(283)); - return -1; - } - for (pl_mi = 0; pl_mi < MAX_PARTY && p->data[pl_mi].sd != pl_sd; pl_mi++); - - if (pl_mi == MAX_PARTY) - return -1; //Shouldn't happen - - //Change leadership. - p->party.member[mi].leader = 0; - if (p->data[mi].sd->fd) - clif_displaymessage(p->data[mi].sd->fd, msg_txt(284)); - p->party.member[pl_mi].leader = 1; - if (p->data[pl_mi].sd->fd) - clif_displaymessage(p->data[pl_mi].sd->fd, msg_txt(285)); - - intif_party_leaderchange(p->party.party_id,p->party.member[pl_mi].account_id,p->party.member[pl_mi].char_id); - //Update info. - clif_party_info(p,NULL); - - return 0; + if (party_changeleader(sd, map_nick2sd((char *) message))) + return 0; + return -1; } /*========================================== diff --git a/src/map/battle.c b/src/map/battle.c index adf87c367..dd70de892 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3345,7 +3345,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f else return -1; } - else if( flag == BCT_NOONE ) //Why would someone use this? no clue. + if( flag == BCT_NOONE ) //Why would someone use this? no clue. return -1; if( t_bl == s_bl ) @@ -3730,7 +3730,7 @@ static const struct _battle_data { { "hack_info_GM_level", &battle_config.hack_info_GM_level, 60, 0, 100, }, { "any_warp_GM_min_level", &battle_config.any_warp_GM_min_level, 20, 0, 100, }, { "who_display_aid", &battle_config.who_display_aid, 40, 0, 100, }, - { "packet_ver_flag", &battle_config.packet_ver_flag, 0xFFFF, 0x0000, 0xFFFF, }, + { "packet_ver_flag", &battle_config.packet_ver_flag, 0xFFFFFF,0x0000,INT_MAX, }, { "min_hair_style", &battle_config.min_hair_style, 0, 0, INT_MAX, }, { "max_hair_style", &battle_config.max_hair_style, 23, 0, INT_MAX, }, { "min_hair_color", &battle_config.min_hair_color, 0, 0, INT_MAX, }, diff --git a/src/map/clif.c b/src/map/clif.c index 2eb614780..fe04ada31 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -821,11 +821,17 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool WBUFW(buf,30) = vd->cloth_color; WBUFW(buf,32) = (sd)? sd->head_dir : 0; if (type&&spawn) { //End of packet 0x7c - WBUFB(buf,34) = 0; // karma + WBUFB(buf,34) = (sd)?sd->status.karma:0; // karma WBUFB(buf,35) = vd->sex; WBUFPOS(buf,36,bl->x,bl->y,unit_getdir(bl)); WBUFB(buf,39) = 0; +#if PACKETVER >= 20071106 WBUFB(buf,40) = 0; +#endif +#if PACKETVER > 20081217 + WBUFB(buf,41) = 0; + WBUFB(buf,42) = 0; +#endif return packet_len(0x7c); } WBUFL(buf,34) = status_get_guild_id(bl); @@ -4061,7 +4067,7 @@ int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int range) int clif_skillinfoblock(struct map_session_data *sd) { int fd; - int i,c,len,id; + int i,len,id; nullpo_retr(0, sd); @@ -4070,7 +4076,7 @@ int clif_skillinfoblock(struct map_session_data *sd) WFIFOHEAD(fd, MAX_SKILL * 37 + 4); WFIFOW(fd,0) = 0x10f; - for ( i = 0, c = 0, len = 4; i < MAX_SKILL; i++) + for ( i = 0, len = 4; i < MAX_SKILL; i++) { if( (id = sd->status.skill[i].id) != 0 ) { @@ -4089,7 +4095,6 @@ int clif_skillinfoblock(struct map_session_data *sd) else WFIFOB(fd,len+36) = 0; len += 37; - c++; } } WFIFOW(fd,2)=len; @@ -4229,6 +4234,27 @@ int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype) } /*========================================== + * skill cooldown display icon + * R 043d <skill ID>.w <tick>.l + *------------------------------------------*/ +int clif_skill_cooldown(struct map_session_data *sd, int skillid, unsigned int tick) +{ +#if PACKETVER>=20081112 + int fd; + + nullpo_retr(0, sd); + + fd=sd->fd; + WFIFOHEAD(fd,packet_len(0x043d)); + WFIFOW(fd,0) = 0x043d; + WFIFOW(fd,2) = skillid; + WFIFOL(fd,4) = tick; + WFIFOSET(fd,packet_len(0x043d)); +#endif + return 0; +} + +/*========================================== * skill attack effect and damage * R 01de <skill ID>.w <src ID>.l <dst ID>.l <tick>.l <src delay>.l <dst delay>.l <damage>.l <skillv>.w <div>.w <type>.B *------------------------------------------*/ @@ -5681,6 +5707,11 @@ void clif_party_inviteack(struct map_session_data* sd, const char* nick, int fla int clif_party_option(struct party_data *p,struct map_session_data *sd,int flag) { unsigned char buf[16]; +#if PACKETVER<20090603 + const int cmd = 0x101; +#else + const int cmd = 0x7d8; +#endif nullpo_retr(0, p); @@ -5691,14 +5722,18 @@ int clif_party_option(struct party_data *p,struct map_session_data *sd,int flag) sd = p->data[i].sd; } if(!sd) return 0; - WBUFW(buf,0)=0x101; + WBUFW(buf,0)=cmd; // WBUFL(buf,2) // that's how the client reads it, still need to check it's uses [FlavioJS] WBUFW(buf,2)=((flag&0x01)?2:p->party.exp); WBUFW(buf,4)=0; +#if PACKETVER>=20090603 + WBUFB(buf,6)=(p->party.item&1)?1:0; + WBUFB(buf,7)=(p->party.item&2)?1:0; +#endif if(flag==0) - clif_send(buf,packet_len(0x101),&sd->bl,PARTY); + clif_send(buf,packet_len(cmd),&sd->bl,PARTY); else - clif_send(buf,packet_len(0x101),&sd->bl,SELF); + clif_send(buf,packet_len(cmd),&sd->bl,SELF); return 0; } /*========================================== @@ -8328,15 +8363,20 @@ void clif_hotkeys_send(struct map_session_data *sd) { #ifdef HOTKEY_SAVING const int fd = sd->fd; int i; +#if PACKETVER<20090603 + const int cmd = 0x02b9; +#else + const int cmd = 0x07d9; +#endif if (!fd) return; WFIFOHEAD(fd, 2+MAX_HOTKEYS*7); - WFIFOW(fd, 0) = 0x02b9; + WFIFOW(fd, 0) = cmd; for(i = 0; i < MAX_HOTKEYS; i++) { WFIFOB(fd, 2 + 0 + i * 7) = sd->status.hotkeys[i].type; // type: 0: item, 1: skill WFIFOL(fd, 2 + 1 + i * 7) = sd->status.hotkeys[i].id; // item or skill ID WFIFOW(fd, 2 + 5 + i * 7) = sd->status.hotkeys[i].lv; // skill level } - WFIFOSET(fd, packet_len(0x02b9)); + WFIFOSET(fd, packet_len(cmd)); #endif } @@ -10345,6 +10385,15 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd) party_send_message(sd, text, textlen); } +/* + * Changes Party Leader + * S 07da <account ID>.L + *------------------------------------------*/ +void clif_parse_PartyChangeLeader(int fd, struct map_session_data* sd) +{ + party_changeleader(sd, map_id2sd(RFIFOL(fd,2))); +} + /*========================================== * 露店閉鎖 *------------------------------------------*/ @@ -12800,6 +12849,22 @@ void clif_quest_update_status(struct map_session_data * sd, int quest_id, bool a WFIFOSET(fd, packet_len(0x02B7)); } +void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, short state, short color) +{ +#if PACKETVER >= 20090218 + int fd = sd->fd; + + WFIFOHEAD(fd, packet_len(0x446)); + WFIFOW(fd, 0) = 0x446; + WFIFOL(fd, 2) = bl->id; + WFIFOW(fd, 6) = bl->x; + WFIFOW(fd, 8) = bl->y; + WFIFOW(fd, 10) = state; + WFIFOW(fd, 12) = color; + WFIFOSET(fd, packet_len(0x446)); +#endif +} + /*========================================== * Mercenary System *==========================================*/ @@ -13513,13 +13578,19 @@ static int packetdb_readdb(void) //#0x0040 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2, +#if PACKETVER <= 20081217 + 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,110, 3, 2, +#else + 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,114, 3, 2, +#endif #if PACKETVER < 2 3, 28, 19, 11, 3, -1, 9, 5, 52, 51, 56, 58, 41, 2, 6, 6, #elif PACKETVER < 20071106 // 78-7b 亀島以降 lv99エフェクト用 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6, -#else // change in 0x78 and 0x7c +#elif PACKETVER <= 20081217 // change in 0x78 and 0x7c 3, 28, 19, 11, 3, -1, 9, 5, 55, 53, 58, 60, 42, 2, 6, 6, +#else + 3, 28, 19, 11, 3, -1, 9, 5, 55, 53, 58, 60, 44, 2, 6, 6, #endif //#0x0080 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 2, -1, -1, -1, 0, // 0x8b changed to 2 (was 23) @@ -13577,7 +13648,7 @@ static int packetdb_readdb(void) 0, 0, 0, 6, 0, 0, 0, 0, 0, 8, 18, 0, 0, 0, 0, 0, 0, 4, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,107, 6, 0, 7, 7, 22,191, 0, 0, 0, 0, 0, 0, + 85, -1, -1,107, 6, -1, 7, 7, 22,191, 0, 0, 0, 0, 0, 0, //#0x02C0 0, 0, 0, 0, 0, 30, 0, 0, 0, 3, 0, 65, 4, 71, 10, 0, 0, 0, 0, 0, 29, 0, 6, -1, 10, 10, 3, 0, -1, 32, 6, 0, @@ -13607,9 +13678,9 @@ static int packetdb_readdb(void) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 25, //#0x0440 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -13623,6 +13694,70 @@ static int packetdb_readdb(void) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x0500 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + //#0x0540 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x0580 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x05C0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x0600 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + //#0x0640 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x0680 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x06C0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x0700 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + //#0x0740 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x0780 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x07C0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#if PACKETVER < 20090617 + 6, 2, -1, 4, 4, 4, 4, 8, 8,254, 6, 8, 6, 54, 30, 54, +#else // 0x7d9 changed + 6, 2, -1, 4, 4, 4, 4, 8, 8,268, 6, 8, 6, 54, 30, 54, +#endif + 0, 0, 0, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; struct { void (*func)(int, struct map_session_data *); @@ -13708,6 +13843,7 @@ static int packetdb_readdb(void) {clif_parse_RemovePartyMember,"removepartymember"}, {clif_parse_PartyChangeOption,"partychangeoption"}, {clif_parse_PartyMessage,"partymessage"}, + {clif_parse_PartyChangeLeader,"partychangeleader"}, {clif_parse_CloseVending,"closevending"}, {clif_parse_VendingListReq,"vendinglistreq"}, {clif_parse_PurchaseReq,"purchasereq"}, diff --git a/src/map/clif.h b/src/map/clif.h index 43fd8b1f7..fd9bea645 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -26,36 +26,8 @@ struct guild; struct battleground_data; struct quest; #include <stdarg.h> - -// server->client protocol version -// 0 - pre-? -// 1 - ? - 0x196 -// 2 - ? - 0x78, 0x79 -// 3 - ? - 0x1c8, 0x1c9, 0x1de -// 4 - ? - 0x1d7, 0x1d8, 0x1d9, 0x1da -// 5 - 2003-12-18aSakexe+ - 0x1ee, 0x1ef, 0x1f0, ?0x1c4, 0x1c5? -// 6 - 2004-03-02aSakexe+ - 0x1f4, 0x1f5 -// 7 - 2005-04-11aSakexe+ - 0x229, 0x22a, 0x22b, 0x22c -// 20070521 - 2007-05-21aSakexe+ - 0x283 -// 20070821 - 2007-08-21aSakexe+ - 0x2c5 -// 20070918 - 2007-09-18aSakexe+ - 0x2d7, 0x2d9, 0x2da -// 20071106 - 2007-11-06aSakexe+ - 0x78, 0x7c, 0x22c -// 20081126 - 2008-11-26aSakexe+ - 0x1a2 -#ifndef PACKETVER - #define PACKETVER 20081126 -#endif -// backward compatible PACKETVER 8 and 9 -#if PACKETVER == 8 -#undef PACKETVER -#define PACKETVER 20070521 -#endif -#if PACKETVER == 9 -#undef PACKETVER -#define PACKETVER 20071106 -#endif - // packet DB -#define MAX_PACKET_DB 0x500 +#define MAX_PACKET_DB 0x800 #define MAX_PACKET_VER 25 struct s_packet_db { @@ -224,6 +196,7 @@ int clif_skillup(struct map_session_data *sd,int skill_num); int clif_skillcasting(struct block_list* bl,int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int pl,int casttime); int clif_skillcastcancel(struct block_list* bl); int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype); +int clif_skill_cooldown(struct map_session_data *sd, int skillid, unsigned int tick); int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type); //int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type); int clif_skill_nodamage(struct block_list *src,struct block_list *dst,int skill_id,int heal,int fail); @@ -437,6 +410,7 @@ void clif_quest_add(struct map_session_data * sd, struct quest * qd, int index); void clif_quest_delete(struct map_session_data * sd, int quest_id); void clif_quest_update_status(struct map_session_data * sd, int quest_id, bool active); void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd, int index); +void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, short state, short color); int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type); int do_final_clif(void); diff --git a/src/map/npc.c b/src/map/npc.c index 0a412de41..2a92a0e1b 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -2395,7 +2395,6 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch int npc_duplicate4instance(struct npc_data *snd, int m) { char newname[NAME_LENGTH]; - int i = 0; if( map[m].instance_id == 0 ) return 1; diff --git a/src/map/party.c b/src/map/party.c index 4a10036d3..be54455d7 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -606,6 +606,57 @@ int party_optionchanged(int party_id,int account_id,int exp,int item,int flag) return 0; } +bool party_changeleader(struct map_session_data *sd, struct map_session_data *tsd) +{ + struct party_data *p; + int mi, tmi; + + if (!sd || !sd->status.party_id) + return false; + + if (!tsd || tsd->status.party_id != sd->status.party_id) { + clif_displaymessage(sd->fd, msg_txt(283)); + return false; + } + + if( map[sd->bl.m].flag.partylock ) + { + clif_displaymessage(sd->fd, "You cannot change party leaders on this map."); + return false; + } + + if ((p = party_search(sd->status.party_id)) == NULL) + return false; + + ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd ); + if (mi == MAX_PARTY) + return false; //Shouldn't happen + + if (!p->party.member[mi].leader) + { //Need to be a party leader. + clif_displaymessage(sd->fd, msg_txt(282)); + return false; + } + + ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd); + if (tmi == MAX_PARTY) + return false; //Shouldn't happen + + //Change leadership. + p->party.member[mi].leader = 0; + if (p->data[mi].sd->fd) + clif_displaymessage(p->data[mi].sd->fd, msg_txt(284)); + + p->party.member[tmi].leader = 1; + if (p->data[tmi].sd->fd) + clif_displaymessage(p->data[tmi].sd->fd, msg_txt(285)); + + //Update info. + intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id); + clif_party_info(p,NULL); + return true; +} + /// Invoked (from char-server) when a party member /// - changes maps /// - logs in or out diff --git a/src/map/party.h b/src/map/party.h index bdaccc7e1..55142fa7e 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -54,6 +54,7 @@ int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short m int party_broken(int party_id); int party_optionchanged(int party_id,int account_id,int exp,int item,int flag); int party_changeoption(struct map_session_data *sd,int exp,int item); +bool party_changeleader(struct map_session_data *sd, struct map_session_data *t_sd); void party_send_movemap(struct map_session_data *sd); void party_send_levelup(struct map_session_data *sd); int party_send_logout(struct map_session_data *sd); diff --git a/src/map/script.c b/src/map/script.c index 8883f3783..57b11f305 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6086,6 +6086,9 @@ BUILDIN_FUNC(strcharinfo) else script_pushconststr(st,""); break; + case 3: + script_pushconststr(st,map[sd->bl.m].name); + break; default: ShowWarning("buildin_strcharinfo: unknown parameter.\n"); script_pushconststr(st,""); @@ -6231,7 +6234,7 @@ BUILDIN_FUNC(getbrokenid) num=script_getnum(st,2); for(i=0; i<MAX_INVENTORY; i++) { - if(sd->status.inventory[i].attribute==1){ + if(sd->status.inventory[i].attribute){ brokencounter++; if(num==brokencounter){ id=sd->status.inventory[i].nameid; @@ -6260,7 +6263,7 @@ BUILDIN_FUNC(repair) num=script_getnum(st,2); for(i=0; i<MAX_INVENTORY; i++) { - if(sd->status.inventory[i].attribute==1){ + if(sd->status.inventory[i].attribute){ repaircounter++; if(num==repaircounter){ sd->status.inventory[i].attribute=0; @@ -12608,6 +12611,75 @@ BUILDIN_FUNC(checkchatting) // check chatting [Marka] return 0; } +BUILDIN_FUNC(searchitem) +{ + struct script_data* data = script_getdata(st, 2); + const char *itemname = script_getstr(st,3); + struct item_data *items[MAX_SEARCH]; + int count; + + char* name; + int32 start; + int32 id; + int32 i; + TBL_PC* sd = NULL; + + if ((items[0] = itemdb_exists(atoi(itemname)))) + count = 1; + else { + count = itemdb_searchname_array(items, ARRAYLENGTH(items), itemname); + if (count > MAX_SEARCH) count = MAX_SEARCH; + } + + if (!count) { + script_pushint(st, 0); + return 0; + } + + if( !data_isreference(data) ) + { + ShowError("script:searchitem: not a variable\n"); + script_reportdata(data); + st->state = END; + return 1;// not a variable + } + + id = reference_getid(data); + start = reference_getindex(data); + name = reference_getname(data); + if( not_array_variable(*name) ) + { + ShowError("script:searchitem: illegal scope\n"); + script_reportdata(data); + st->state = END; + return 1;// not supported + } + + if( not_server_variable(*name) ) + { + sd = script_rid2sd(st); + if( sd == NULL ) + return 0;// no player attached + } + + if( is_string_variable(name) ) + {// string array + ShowError("script:searchitem: not an integer array reference\n"); + script_reportdata(data); + st->state = END; + return 1;// not supported + } + + for( i = 0; i < count; ++start, ++i ) + {// Set array + void* v = (void*)items[i]->nameid; + set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data)); + } + + script_pushint(st, count); + return 0; +} + int axtoi(const char *hexStg) { int n = 0; // position in string @@ -13057,8 +13129,10 @@ BUILDIN_FUNC(awake) struct linkdb_node *node = (struct linkdb_node *)sleep_db; nd = npc_name2id(script_getstr(st, 2)); - if( nd == NULL ) - return 0; + if( nd == NULL ) { + ShowError("awake: NPC \"%s\" not found\n", script_getstr(st, 2)); + return 1; + } while( node ) { @@ -13081,7 +13155,8 @@ BUILDIN_FUNC(awake) delete_timer(tst->sleep.timer, run_script_timer); node = script_erase_sleepdb(node); tst->sleep.timer = INVALID_TIMER; - //tst->sleep.tick = 0; + if(tst->state != RERUNLINE) + tst->sleep.tick = 0; run_script_main(tst); } else @@ -13490,6 +13565,24 @@ BUILDIN_FUNC(checkquest) return 0; } +BUILDIN_FUNC(showevent) +{ + TBL_PC *sd = script_rid2sd(st); + struct npc_data *nd = map_id2nd(st->oid); + int state, color; + + if( sd == NULL || nd == NULL ) + return 0; + state = script_getnum(st, 2); + color = script_getnum(st, 3); + + if( color < 0 || color > 4 ) + color = 0; // set default color + + clif_quest_show_event(sd, &nd->bl, state, color); + return 0; +} + /*========================================== * BattleGround System *------------------------------------------*/ @@ -14498,6 +14591,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(setcell,"siiiiii"), BUILDIN_DEF(setwall,"siiiiis"), BUILDIN_DEF(delwall,"s"), + BUILDIN_DEF(searchitem,"rs"), BUILDIN_DEF(mercenary_create,"ii"), BUILDIN_DEF(mercenary_heal,"ii"), BUILDIN_DEF(mercenary_sc_start,"iii"), @@ -14547,5 +14641,6 @@ struct script_function buildin_func[] = { BUILDIN_DEF(completequest, "i"), BUILDIN_DEF(checkquest, "i*"), BUILDIN_DEF(changequest, "ii"), + BUILDIN_DEF(showevent, "ii"), {NULL,NULL,NULL}, }; diff --git a/src/map/skill.c b/src/map/skill.c index c16eecdda..8d0b1cda9 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -11195,6 +11195,9 @@ int skill_blockpc_start(struct map_session_data *sd, int skillid, int tick) return -1; } + if( battle_config.display_status_timers ) + clif_skill_cooldown(sd, skillid, tick); + sd->blockskill[skillid] = 0x1|(0xFE&add_timer(gettick()+tick,skill_blockpc_end,sd->bl.id,skillid)); return 0; } |