diff options
author | ai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2010-12-26 22:36:41 +0000 |
---|---|---|
committer | ai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2010-12-26 22:36:41 +0000 |
commit | 6096ce0b42a3eee07dc70ae5ef489aa4c30bf515 (patch) | |
tree | e91f8afd3b7b8b80f0c55aae07f7a478f469c37a /src/map/clif.c | |
parent | 23e1b7db5ba2277a406fc84c30e87c324a83097c (diff) | |
download | hercules-6096ce0b42a3eee07dc70ae5ef489aa4c30bf515.tar.gz hercules-6096ce0b42a3eee07dc70ae5ef489aa4c30bf515.tar.bz2 hercules-6096ce0b42a3eee07dc70ae5ef489aa4c30bf515.tar.xz hercules-6096ce0b42a3eee07dc70ae5ef489aa4c30bf515.zip |
* Merged changes from trunk [14496:14630/trunk].
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/renewal@14632 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/clif.c')
-rw-r--r-- | src/map/clif.c | 692 |
1 files changed, 360 insertions, 332 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index e55a27108..c5796555a 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -168,9 +168,9 @@ static inline unsigned char clif_bl_type(struct block_list *bl) { case BL_ITEM: return 0x2; //ITEM_TYPE case BL_SKILL: return 0x3; //SKILL_TYPE case BL_CHAT: return 0x4; //UNKNOWN_TYPE - case BL_MOB: return pcdb_checkid(((TBL_MOB*)bl)->vd->class_)?0x0:0x5; //NPC_MOB_TYPE + case BL_MOB: return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x5; //NPC_MOB_TYPE case BL_NPC: return 0x6; //NPC_EVT_TYPE - case BL_PET: return 0x7; //NPC_PET_TYPE + case BL_PET: return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x7; //NPC_PET_TYPE case BL_HOM: return 0x8; //NPC_HOM_TYPE case BL_MER: return 0x9; //NPC_MERSOL_TYPE // case BL_ELEM: return 0xA; //NPC_ELEMENTAL_TYPE @@ -658,7 +658,7 @@ int clif_clearflooritem(struct flooritem_data *fitem, int fd) * 3 - teleported / logged out * fd : the target client *------------------------------------------*/ -int clif_clearunit_single(int id, uint8 type, int fd) +int clif_clearunit_single(int id, clr_type type, int fd) { WFIFOHEAD(fd, packet_len(0x80)); WFIFOW(fd,0) = 0x80; @@ -676,7 +676,7 @@ int clif_clearunit_single(int id, uint8 type, int fd) * 2 - respawned * 3 - teleported / logged out *------------------------------------------*/ -int clif_clearunit_area(struct block_list* bl, uint8 type) +int clif_clearunit_area(struct block_list* bl, clr_type type) { unsigned char buf[16]; @@ -686,7 +686,7 @@ int clif_clearunit_area(struct block_list* bl, uint8 type) WBUFL(buf,2) = bl->id; WBUFB(buf,6) = type; - clif_send(buf, packet_len(0x80), bl, type == 1 ? AREA : AREA_WOS); + clif_send(buf, packet_len(0x80), bl, type == CLR_DEAD ? AREA : AREA_WOS); if(disguised(bl)) { WBUFL(buf,2) = -bl->id; @@ -699,7 +699,7 @@ int clif_clearunit_area(struct block_list* bl, uint8 type) static int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr data) { struct block_list *bl = (struct block_list *)data; - clif_clearunit_area(bl, 0); + clif_clearunit_area(bl, CLR_OUTSIGHT); aFree(bl); return 0; } @@ -1059,16 +1059,6 @@ static void clif_spiritball_single(int fd, struct map_session_data *sd) WFIFOSET(fd, packet_len(0x1e1)); } -// new and improved weather display [Valaris] -static void clif_weather_sub(int fd, int id, int type) -{ - WFIFOHEAD(fd,packet_len(0x1f3)); - WFIFOW(fd,0) = 0x1f3; - WFIFOL(fd,2) = id; - WFIFOL(fd,6) = type; - WFIFOSET(fd,packet_len(0x1f3)); -} - /*========================================== * *------------------------------------------*/ @@ -1086,24 +1076,24 @@ static void clif_weather_check(struct map_session_data *sd) || map[m].flag.clouds2) { if (map[m].flag.snow) - clif_weather_sub(fd, sd->bl.id, 162); + clif_specialeffect_single(&sd->bl, 162, fd); if (map[m].flag.clouds) - clif_weather_sub(fd, sd->bl.id, 233); + clif_specialeffect_single(&sd->bl, 233, fd); if (map[m].flag.clouds2) - clif_weather_sub(fd, sd->bl.id, 516); + clif_specialeffect_single(&sd->bl, 516, fd); if (map[m].flag.fog) - clif_weather_sub(fd, sd->bl.id, 515); + clif_specialeffect_single(&sd->bl, 515, fd); if (map[m].flag.fireworks) { - clif_weather_sub(fd, sd->bl.id, 297); - clif_weather_sub(fd, sd->bl.id, 299); - clif_weather_sub(fd, sd->bl.id, 301); + clif_specialeffect_single(&sd->bl, 297, fd); + clif_specialeffect_single(&sd->bl, 299, fd); + clif_specialeffect_single(&sd->bl, 301, fd); } if (map[m].flag.sakura) - clif_weather_sub(fd, sd->bl.id, 163); + clif_specialeffect_single(&sd->bl, 163, fd); if (map[m].flag.leaves) - clif_weather_sub(fd, sd->bl.id, 333); + clif_specialeffect_single(&sd->bl, 333, fd); if (map[m].flag.rain) - clif_weather_sub(fd, sd->bl.id, 161); + clif_specialeffect_single(&sd->bl, 161, fd); } } @@ -1280,13 +1270,14 @@ int clif_homskillinfoblock(struct map_session_data *sd) void clif_homskillup(struct map_session_data *sd, int skill_num) { //[orn] struct homun_data *hd; - int fd=sd->fd, skillid; - WFIFOHEAD(fd, packet_len(0x239)); + int fd, skillid; nullpo_retv(sd); skillid = skill_num - HM_SKILLBASE; + fd=sd->fd; hd=sd->hd; + WFIFOHEAD(fd, packet_len(0x239)); WFIFOW(fd,0) = 0x239; WFIFOW(fd,2) = skill_num; WFIFOW(fd,4) = hd->homunculus.hskill[skillid].lv; @@ -1468,9 +1459,10 @@ void clif_blown(struct block_list *bl) clif_slide(bl, bl->x, bl->y); } -/*========================================== - * - *------------------------------------------*/ +/// Visually moves(slides) a character to x,y. If the target cell +/// isn't walkable, the char doesn't move at all. If the char is +/// sitting it will stand up. +/// S 0088 <gid>.L <x>.W <y>.W void clif_fixpos(struct block_list *bl) { unsigned char buf[10]; @@ -1529,9 +1521,7 @@ int clif_buylist(struct map_session_data *sd, struct npc_data *nd) if( id == NULL ) continue; WFIFOL(fd, 4+c*11) = val; - if (!id->flag.value_notdc) - val = pc_modifybuyvalue(sd,val); - WFIFOL(fd, 8+c*11) = val; + WFIFOL(fd, 8+c*11) = pc_modifybuyvalue(sd,val); WFIFOB(fd,12+c*11) = itemtype(id->type); WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid; c++; @@ -1570,9 +1560,7 @@ int clif_selllist(struct map_session_data *sd) continue; WFIFOW(fd,4+c*10)=i+2; WFIFOL(fd,6+c*10)=val; - if( !sd->inventory_data[i]->flag.value_notoc ) - val=pc_modifysellvalue(sd,val); - WFIFOL(fd,10+c*10)=val; + WFIFOL(fd,10+c*10)=pc_modifysellvalue(sd,val); c++; } } @@ -2166,7 +2154,7 @@ void clif_equiplist(struct map_session_data *sd) } } -void clif_storagelist(struct map_session_data* sd, struct storage_data* stor) +void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length) { struct item_data *id; int i,n,ne; @@ -2187,21 +2175,21 @@ void clif_storagelist(struct map_session_data* sd, struct storage_data* stor) const int cmd = 28; #endif - buf = (unsigned char*)aMallocA(MAX_STORAGE * s + 4); - bufe = (unsigned char*)aMallocA(MAX_STORAGE * cmd + 4); + buf = (unsigned char*)aMallocA(items_length * s + 4); + bufe = (unsigned char*)aMallocA(items_length * cmd + 4); - for( i = 0, n = 0, ne = 0; i < MAX_STORAGE; i++ ) + for( i = 0, n = 0, ne = 0; i < items_length; i++ ) { - if( stor->items[i].nameid <= 0 ) + if( items[i].nameid <= 0 ) continue; - id = itemdb_search(stor->items[i].nameid); + id = itemdb_search(items[i].nameid); if( !itemdb_isstackable2(id) ) { //Equippable WBUFW(bufe,ne*cmd+4)=i+1; - clif_item_sub(bufe, ne*cmd+6, &stor->items[i], id, id->equip); - clif_addcards(WBUFP(bufe, ne*cmd+16), &stor->items[i]); + clif_item_sub(bufe, ne*cmd+6, &items[i], id, id->equip); + clif_addcards(WBUFP(bufe, ne*cmd+16), &items[i]); #if PACKETVER >= 20071002 - WBUFL(bufe,ne*cmd+24)=stor->items[i].expire_time; + WBUFL(bufe,ne*cmd+24)=items[i].expire_time; WBUFW(bufe,ne*cmd+28)=0; //Unknown #endif ne++; @@ -2209,93 +2197,12 @@ void clif_storagelist(struct map_session_data* sd, struct storage_data* stor) else { //Stackable WBUFW(buf,n*s+4)=i+1; - clif_item_sub(buf, n*s+6, &stor->items[i], id,-1); + clif_item_sub(buf, n*s+6, &items[i], id,-1); #if PACKETVER >= 5 - clif_addcards(WBUFP(buf,n*s+14), &stor->items[i]); + clif_addcards(WBUFP(buf,n*s+14), &items[i]); #endif #if PACKETVER >= 20080102 - WBUFL(buf,n*s+22)=stor->items[i].expire_time; -#endif - n++; - } - } - if( n ) - { -#if PACKETVER < 5 - WBUFW(buf,0)=0xa5; -#elif PACKETVER < 20080102 - WBUFW(buf,0)=0x1f0; -#else - WBUFW(buf,0)=0x2ea; -#endif - WBUFW(buf,2)=4+n*s; - clif_send(buf, WBUFW(buf,2), &sd->bl, SELF); - } - if( ne ) - { -#if PACKETVER < 20071002 - WBUFW(bufe,0)=0xa6; -#else - WBUFW(bufe,0)=0x2d1; -#endif - WBUFW(bufe,2)=4+ne*cmd; - clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF); - } - - if( buf ) aFree(buf); - if( bufe ) aFree(bufe); -} - -//Unified storage function which sends all of the storage (requires two packets, one for equipable items and one for stackable ones. [Skotlex] -void clif_guildstoragelist(struct map_session_data *sd,struct guild_storage *stor) -{ - struct item_data *id; - int i,n,ne; - unsigned char *buf; - unsigned char *bufe; -#if PACKETVER < 5 - const int s = 10; //Entry size. -#elif PACKETVER < 20080102 - const int s = 18; -#else - const int s = 22; -#endif -#if PACKETVER < 20071002 - const int cmd = 20; -#elif PACKETVER < 20100629 - const int cmd = 26; -#else - const int cmd = 28; -#endif - - buf = (unsigned char*)aMallocA(MAX_GUILD_STORAGE * s + 4); - bufe = (unsigned char*)aMallocA(MAX_GUILD_STORAGE * cmd + 4); - - for( i = 0, n = 0, ne = 0; i < MAX_GUILD_STORAGE; i++ ) - { - if( stor->storage_[i].nameid <= 0 ) - continue; - id = itemdb_search(stor->storage_[i].nameid); - if( !itemdb_isstackable2(id) ) - { //Equippable - WBUFW(bufe,ne*cmd+4)=i+1; - clif_item_sub(bufe, ne*cmd+6, &stor->storage_[i], id, id->equip); - clif_addcards(WBUFP(bufe, ne*cmd+16), &stor->storage_[i]); -#if PACKETVER >= 20071002 - WBUFL(bufe,ne*cmd+24)=stor->storage_[i].expire_time; - WBUFW(bufe,ne*cmd+28)=0; //Unknown -#endif - ne++; - } - else - { //Stackable - WBUFW(buf,n*s+4)=i+1; - clif_item_sub(buf, n*s+6, &stor->storage_[i], id,-1); -#if PACKETVER >= 5 - clif_addcards(WBUFP(buf,n*s+14), &stor->storage_[i]); -#endif -#if PACKETVER >= 20080102 - WBUFL(buf,n*s+22)=stor->storage_[i].expire_time; + WBUFL(buf,n*s+22)=items[i].expire_time; #endif n++; } @@ -3089,23 +2996,7 @@ int clif_misceffect(struct block_list* bl,int type) return 0; } -int clif_misceffect2(struct block_list *bl, int type) -{ - unsigned char buf[24]; - - nullpo_ret(bl); - - memset(buf, 0, packet_len(0x1f3)); - - WBUFW(buf,0) = 0x1f3; - WBUFL(buf,2) = bl->id; - WBUFL(buf,6) = type; - - clif_send(buf, packet_len(0x1f3), bl, AREA); - - return 0; -} /*========================================== * 表示オプション変更 *------------------------------------------*/ @@ -3226,11 +3117,13 @@ int clif_useitemack(struct map_session_data *sd,int index,int amount,int ok) return 0; } -/*========================================== - * Inform client whether chatroom creation was successful or not - * R 00d6 <fail>.B - *------------------------------------------*/ -void clif_createchat(struct map_session_data* sd, int fail) +/// Inform client whether chatroom creation was successful or not +/// R 00d6 <flag>.B +/// flag: +/// 0 = Room has been successfully created (opens chat room) +/// 1 = Room limit exceeded +/// 2 = Same room already exists +void clif_createchat(struct map_session_data* sd, int flag) { int fd; @@ -3239,7 +3132,7 @@ void clif_createchat(struct map_session_data* sd, int fail) fd = sd->fd; WFIFOHEAD(fd,packet_len(0xd6)); WFIFOW(fd,0) = 0xd6; - WFIFOB(fd,2) = fail; + WFIFOB(fd,2) = flag; WFIFOSET(fd,packet_len(0xd6)); } @@ -3327,10 +3220,18 @@ int clif_clearchat(struct chat_data *cd,int fd) return 0; } -/*========================================== - * - *------------------------------------------*/ -int clif_joinchatfail(struct map_session_data *sd,int fail) +/// Displays message (mostly) regarding join chat +/// failures +/// R 0x00da <flag>.B +/// flag: +/// 0 = The room is already full. +/// 1 = Incorrect password, please try again. +/// 2 = You have been kicked out of the room. +/// 4 = You don't have enough money. +/// 5 = You are not the required level. +/// 6 = Too high level for this job. +/// 7 = Not the suitable job for this type of work. +int clif_joinchatfail(struct map_session_data *sd,int flag) { int fd; @@ -3340,7 +3241,7 @@ int clif_joinchatfail(struct map_session_data *sd,int fail) WFIFOHEAD(fd,packet_len(0xda)); WFIFOW(fd,0) = 0xda; - WFIFOB(fd,2) = fail; + WFIFOB(fd,2) = flag; WFIFOSET(fd,packet_len(0xda)); return 0; @@ -3393,7 +3294,7 @@ int clif_addchat(struct chat_data* cd,struct map_session_data *sd) /*========================================== * Announce the new owner - * R 00e1 <index>.l <nick>.24B + * R 00e1 <owner flag>.l <nick>.24B *------------------------------------------*/ void clif_changechatowner(struct chat_data* cd, struct map_session_data* sd) { @@ -3405,6 +3306,8 @@ void clif_changechatowner(struct chat_data* cd, struct map_session_data* sd) //FIXME: this announces a swap between positions 0 and 1 (probably not what we want) [ultramage] //FIXME: aegis sends obviously incorrect packets; need to figure out what to send to display it correctly :X //TODO: is it just owner swap, or can it do general-purpose reordering? + // It's not position, but operator flag, everyone set to 1 gets chat + // operator menu (yes, that means a chat may host multiple operators) [Ai4rei] WBUFW(buf, 0) = 0xe1; WBUFL(buf, 2) = 1; @@ -3690,41 +3593,6 @@ void clif_updateguildstorageamount(struct map_session_data* sd, int amount) } /*========================================== - * - *------------------------------------------*/ -void clif_guildstorageitemadded(struct map_session_data* sd, struct item* i, int index, int amount) -{ - int view,fd; - unsigned char *buf; -#if PACKETVER < 20090603 - const int cmd = 0xf4; -#else - const int cmd = 0x1c4; -#endif - - nullpo_retv(sd); - nullpo_retv(i); - fd=sd->fd; - view = itemdb_viewid(i->nameid); - buf = WFIFOP(fd,0); - - WFIFOHEAD(fd,packet_len(cmd)); - WBUFW(buf, 0) = cmd; // Storage item added - WBUFW(buf, 2) = index+1; // index - WBUFL(buf, 4) = amount; // amount - WBUFW(buf, 8) = ( view > 0 ) ? view : i->nameid; // id -#if PACKETVER >= 20090603 - WBUFB(buf,10) = itemdb_type(i->nameid); //type - buf = WBUFP(buf,1); //Advance 1B -#endif - WBUFB(buf,10) = i->identify; //identify flag - WBUFB(buf,11) = i->attribute; // attribute - WBUFB(buf,12) = i->refine; //refine - clif_addcards(WBUFP(buf,13), i); - WFIFOSET(fd,packet_len(cmd)); -} - -/*========================================== * カプラ倉庫からアイテムを取り去る *------------------------------------------*/ void clif_storageitemremoved(struct map_session_data* sd, int index, int amount) @@ -3885,7 +3753,8 @@ static int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int da /*========================================== * Sends a 'damage' packet (src performs action on dst) - * R 008a <src ID>.l <dst ID>.l <server tick>.l <src speed>.l <dst speed>.l <param1>.w <param2>.w <type>.B <param3>.w + * R 008a <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.W <div>.W <type>.B <damage2>.W + * R 02e1 <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.L <div>.W <type>.B <damage2>.L * * type=00 damage [param1: total damage, param2: div, param3: assassin dual-wield damage] * type=01 pick up item @@ -4131,12 +4000,11 @@ void clif_skill_delunit(struct skill_unit *unit) } /*========================================== - * Unknown... trap related? - * Sent when an object gets ankle-snared + * Sent when an object gets ankle-snared (ZC_SKILL_UPDATE) * Only affects units with class [139,153] client-side * R 01ac <object id>.l *------------------------------------------*/ -void clif_01ac(struct block_list* bl) +void clif_skillunit_update(struct block_list* bl) { unsigned char buf[6]; nullpo_retv(bl); @@ -4195,7 +4063,7 @@ int clif_outsight(struct block_list *bl,va_list ap) switch(bl->type){ case BL_PC: if (sd->vd.class_ != INVISIBLE_CLASS) - clif_clearunit_single(bl->id,0,tsd->fd); + clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd); if(sd->chatID){ struct chat_data *cd; cd=(struct chat_data*)map_id2bl(sd->chatID); @@ -4213,14 +4081,14 @@ int clif_outsight(struct block_list *bl,va_list ap) break; default: if ((vd=status_get_viewdata(bl)) && vd->class_ != INVISIBLE_CLASS) - clif_clearunit_single(bl->id,0,tsd->fd); + clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd); break; } } if (sd && sd->fd) { //sd is watching tbl go out of view. if ((vd=status_get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS) - clif_clearunit_single(tbl->id,0,sd->fd); + clif_clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd); } return 0; } @@ -4414,6 +4282,15 @@ int clif_skillup(struct map_session_data *sd,int skill_num) /*========================================== * スキル詠唱エフェクトを送信する + * pl: + * 0 = Yellow cast aura + * 1 = Water elemental cast aura + * 2 = Earth elemental cast aura + * 3 = Fire elemental cast aura + * 4 = Wind elemental cast aura + * 5 = Poison elemental cast aura + * 6 = White cast aura + * ? = like 0 *------------------------------------------*/ 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) @@ -7081,8 +6958,8 @@ int clif_guild_notice(struct map_session_data* sd, struct guild* g) WFIFOHEAD(fd,packet_len(0x16f)); WFIFOW(fd,0) = 0x16f; - memcpy(WFIFOP(fd,2), g->mes1, 60); - memcpy(WFIFOP(fd,62), g->mes2, 120); + memcpy(WFIFOP(fd,2), g->mes1, MAX_GUILDMES1); + memcpy(WFIFOP(fd,62), g->mes2, MAX_GUILDMES2); WFIFOSET(fd,packet_len(0x16f)); return 0; } @@ -7106,7 +6983,12 @@ int clif_guild_invite(struct map_session_data *sd,struct guild *g) return 0; } /*========================================== - * ギルドメンバ勧誘結果 + * Reply to invite request + * Flag: + * 0 = Already in guild. + * 1 = Offer rejected. + * 2 = Offer accepted. + * 3 = Guild full. *------------------------------------------*/ int clif_guild_inviteack(struct map_session_data *sd,int flag) { @@ -7285,7 +7167,11 @@ int clif_guild_delalliance(struct map_session_data *sd,int guild_id,int flag) return 0; } /*========================================== - * ギルド敵対結果 + * Reply to opposition request + * Flag: + * 0 = Antagonist has been set. + * 1 = Guild has too many Antagonists. + * 2 = Already set as an Antagonist. *------------------------------------------*/ int clif_guild_oppositionack(struct map_session_data *sd,int flag) { @@ -7579,20 +7465,17 @@ int clif_wisall(struct map_session_data *sd,int type,int flag) /*========================================== * Play a BGM! [Rikter/Yommy] *------------------------------------------*/ -void clif_playBGM(struct map_session_data* sd, struct block_list* bl, const char* name) +void clif_playBGM(struct map_session_data* sd, const char* name) { int fd; nullpo_retv(sd); - nullpo_retv(bl); fd = sd->fd; WFIFOHEAD(fd,packet_len(0x7fe)); WFIFOW(fd,0) = 0x7fe; safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH); WFIFOSET(fd,packet_len(0x7fe)); - - return; } /*========================================== @@ -7742,7 +7625,7 @@ int clif_refresh(struct map_session_data *sd) if( pc_issit(sd) ) clif_sitting(&sd->bl); // FIXME: just send to self, not area if( pc_isdead(sd) ) //When you refresh, resend the death packet. - clif_clearunit_single(sd->bl.id,1,sd->fd); + clif_clearunit_single(sd->bl.id,CLR_DEAD,sd->fd); else clif_changed_dir(&sd->bl, SELF); @@ -7928,6 +7811,9 @@ int clif_charnameupdate (struct map_session_data *ssd) return 0; } +/// Visually moves(instant) a character to x,y. The char moves even +/// when the target cell isn't walkable. If the char is sitting it +/// stays that way. void clif_slide(struct block_list *bl, int x, int y) { unsigned char buf[10]; @@ -8014,21 +7900,58 @@ void clif_gospel_info(struct map_session_data *sd, int type) WFIFOSET(fd, packet_len(0x215)); } + +/// Multi purpose mission information packet (ZC_STARSKILL). +/// 0x20e <mapname>.24B <monster_id>.L <star>.B <result>.B +/// result: +/// 0 = Star Gladiator %s has designed <mapname>'s as the %s. +/// star: +/// 0 = Place of the Sun +/// 1 = Place of the Moon +/// 2 = Place of the Stars +/// 1 = Star Gladiator %s's %s: <mapname> +/// star: +/// 0 = Place of the Sun +/// 1 = Place of the Moon +/// 2 = Place of the Stars +/// 10 = Star Gladiator %s has designed <mapname>'s as the %s. +/// star: +/// 0 = Target of the Sun +/// 1 = Target of the Moon +/// 2 = Target of the Stars +/// 11 = Star Gladiator %s's %s: <mapname used as monster name> +/// star: +/// 0 = Monster of the Sun +/// 1 = Monster of the Moon +/// 2 = Monster of the Stars +/// 20 = [TaeKwon Mission] Target Monster : <mapname used as monster name> (<star>%) +/// 21 = [Taming Mission] Target Monster : <mapname used as monster name> +/// 22 = [Collector Rank] Target Item : <monster_id used as item id> +/// 30 = [Sun, Moon and Stars Angel] Designed places and monsters have been reset. +/// 40 = Target HP : <monster_id used as HP> +void clif_starskill(struct map_session_data* sd, const char* mapname, int monster_id, unsigned char star, unsigned char result) +{ + int fd = sd->fd; + + WFIFOHEAD(fd,packet_len(0x20e)); + WFIFOW(fd,0) = 0x20e; + safestrncpy((char*)WFIFOP(fd,2), mapname, NAME_LENGTH); + WFIFOL(fd,26) = monster_id; + WFIFOB(fd,30) = star; + WFIFOB(fd,31) = result; + WFIFOSET(fd,packet_len(0x20e)); +} + /*========================================== * Info about Star Glaldiator save map [Komurka] * type: 1: Information, 0: Map registered *------------------------------------------*/ void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsigned char type) { - int fd=sd->fd; + char mapname[MAP_NAME_LENGTH_EXT]; - WFIFOHEAD(fd,packet_len(0x20e)); - WFIFOW(fd,0) = 0x20e; - mapindex_getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), (char*)WFIFOP(fd,2)); - WFIFOL(fd,26) = sd->bl.id; - WFIFOB(fd,30) = feel_level; - WFIFOB(fd,31) = type?1:0; - WFIFOSET(fd,packet_len(0x20e)); + mapindex_getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), mapname); + clif_starskill(sd, mapname, 0, feel_level, type ? 1 : 0); } /*========================================== @@ -8037,19 +7960,18 @@ 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) { - int fd=sd->fd; - WFIFOHEAD(fd,packet_len(0x20e)); - WFIFOW(fd,0)=0x20e; - if (pcdb_checkid(class_)) - strncpy((char*)WFIFOP(fd,2),job_name(class_), NAME_LENGTH); - else if (mobdb_checkid(class_)) - strncpy((char*)WFIFOP(fd,2),mob_db(class_)->jname, NAME_LENGTH); - else //Really shouldn't happen... - memset(WFIFOP(fd,2), 0, NAME_LENGTH); - WFIFOL(fd,26)=sd->bl.id; - WFIFOB(fd,30)=hate_level; - WFIFOB(fd,31)=type?10:11; //Register/Info - WFIFOSET(fd, packet_len(0x20e)); + if( pcdb_checkid(class_) ) + { + clif_starskill(sd, job_name(class_), class_, hate_level, type ? 10 : 11); + } + else if( mobdb_checkid(class_) ) + { + clif_starskill(sd, mob_db(class_)->jname, class_, hate_level, type ? 10 : 11); + } + 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); + } } /*========================================== @@ -8057,14 +7979,7 @@ void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int cl *------------------------------------------*/ void clif_mission_info(struct map_session_data *sd, int mob_id, unsigned char progress) { - int fd=sd->fd; - WFIFOHEAD(fd,packet_len(0x20e)); - WFIFOW(fd,0)=0x20e; - strncpy((char*)WFIFOP(fd,2),mob_db(mob_id)->jname, NAME_LENGTH); - WFIFOL(fd,26)=mob_id; - WFIFOB(fd,30)=progress; //Message to display - WFIFOB(fd,31)=20; - WFIFOSET(fd, packet_len(0x20e)); + clif_starskill(sd, mob_db(mob_id)->jname, mob_id, progress, 20); } /*========================================== @@ -8072,14 +7987,7 @@ void clif_mission_info(struct map_session_data *sd, int mob_id, unsigned char pr *------------------------------------------*/ void clif_feel_hate_reset(struct map_session_data *sd) { - int fd=sd->fd; - WFIFOHEAD(fd,packet_len(0x20e)); - WFIFOW(fd,0)=0x20e; - memset(WFIFOP(fd,2), 0, NAME_LENGTH); //Blank name as all was reset. - WFIFOL(fd,26)=sd->bl.id; - WFIFOB(fd,30)=0; //Feel/hate level: irrelevant - WFIFOB(fd,31)=30; - WFIFOSET(fd, packet_len(0x20e)); + clif_starskill(sd, "", 0, 0, 30); } /*========================================== @@ -8175,12 +8083,9 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts WFIFOSET(fd, WFIFOW(fd, 2)); } -/*========================================== - * View player equip request denied - * R 0291 <message>.W - * TODO: this looks like a general-purpose packet to print msgstringtable entries. - *------------------------------------------*/ -void clif_viewequip_fail(struct map_session_data* sd) +/// Display msgstringtable.txt string (ZC_MSG) +/// R 0291 <message>.W +void clif_msg(struct map_session_data* sd, unsigned short id) { int fd; nullpo_retv(sd); @@ -8188,10 +8093,16 @@ void clif_viewequip_fail(struct map_session_data* sd) WFIFOHEAD(fd, packet_len(0x291)); WFIFOW(fd, 0) = 0x291; - WFIFOW(fd, 2) = 0x54d; // This controls which message is displayed. 0x54d is the correct one. Maybe it's used for something else too? + WFIFOW(fd, 2) = id; // zero-based msgstringtable.txt index WFIFOSET(fd, packet_len(0x291)); } +/// View player equip request denied +void clif_viewequip_fail(struct map_session_data* sd) +{ + clif_msg(sd, 0x54d); +} + /// Validates one global/guild/party/whisper message packet and tries to recognize its components. /// Returns true if the packet was parsed successfully. /// Formats: 0 - <packet id>.w <packet len>.w (<name> : <message>).?B 00 @@ -8329,6 +8240,10 @@ static int clif_guess_PacketVer(int fd, int get_previous, int *error) err = n;\ //define SET_ERROR + // FIXME: If the packet is not received at once, this will FAIL. + // Figure out, when it happens, that only part of the packet is + // received, or fix the function to be able to deal with that + // case. #define CHECK_PACKET_VER() \ if( cmd != clif_config.connect_cmd[packet_ver] || packet_len != packet_db[packet_ver][cmd].len )\ ;/* not wanttoconnection or wrong length */\ @@ -8561,20 +8476,22 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) // must use foreachinarea (CIRCULAR_AREA interferes with foreachinrange) 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); - //TODO: merge it with the code below - if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m) && sd->pd) - { //Return the pet to egg. [Skotlex] - clif_displaymessage(sd->fd, "Pets are not allowed in Guild Wars."); - pet_menu(sd, 3); //Option 3 is return to egg. - } - // pet - if(sd->pd) { - map_addblock(&sd->pd->bl); - clif_spawn(&sd->pd->bl); - clif_send_petdata(sd,sd->pd,0,0); - clif_send_petstatus(sd); -// skill_unit_move(&sd->pd->bl,gettick(),1); + 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, "Pets are not allowed in Guild Wars."); + pet_menu(sd, 3); //Option 3 is return to egg. + } + else + { + map_addblock(&sd->pd->bl); + clif_spawn(&sd->pd->bl); + clif_send_petdata(sd,sd->pd,0,0); + clif_send_petstatus(sd); +// skill_unit_move(&sd->pd->bl,gettick(),1); + } } //homunculus [blackhole89] @@ -8605,7 +8522,9 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) sd->state.connect_new = 0; clif_skillinfoblock(sd); clif_hotkeys_send(sd); + clif_updatestatus(sd,SP_BASEEXP); clif_updatestatus(sd,SP_NEXTBASEEXP); + clif_updatestatus(sd,SP_JOBEXP); clif_updatestatus(sd,SP_NEXTJOBEXP); clif_updatestatus(sd,SP_SKILLPOINT); clif_initialstatus(sd); @@ -8720,7 +8639,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) // If player is dead, and is spawned (such as @refresh) send death packet. [Valaris] if(pc_isdead(sd)) - clif_clearunit_area(&sd->bl, 1); + clif_clearunit_area(&sd->bl, CLR_DEAD); // Uncomment if you want to make player face in the same direction he was facing right before warping. [Skotlex] // else // clif_changed_dir(&sd->bl, SELF); @@ -8821,7 +8740,7 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd) int cmd; if (pc_isdead(sd)) { - clif_clearunit_area(&sd->bl, 1); + clif_clearunit_area(&sd->bl, CLR_DEAD); return; } @@ -8940,6 +8859,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) WFIFOW(fd,2) = 8 + textlen; WFIFOL(fd,4) = sd->bl.id; safestrncpy((char*)WFIFOP(fd,8), text, textlen); + //FIXME: chat has range of 9 only clif_send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC); // send back message to the speaker @@ -9063,10 +8983,10 @@ void clif_parse_ChangeDir(int fd, struct map_session_data *sd) *------------------------------------------*/ void clif_parse_Emotion(int fd, struct map_session_data *sd) { - unsigned char buf[64]; + int emoticon = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]); if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 2) { - if (RFIFOB(fd,2) == 34) {// prevent use of the mute emote [Valaris] + if (emoticon == E_MUTE) {// prevent use of the mute emote [Valaris] clif_skill_fail(sd, 1, 0, 1); return; } @@ -9077,11 +8997,13 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd) return; } sd->emotionlasttime = time(NULL) + 1; // not more than 1 per second (using /commands the client can spam it) - - WBUFW(buf,0) = 0xc0; - WBUFL(buf,2) = sd->bl.id; - WBUFB(buf,6) = RFIFOB(fd,2); - clif_send(buf, packet_len(0xc0), &sd->bl, AREA); + + if(battle_config.client_reshuffle_dice && emoticon>=E_DICE1 && emoticon<=E_DICE6) + {// re-roll dice + emoticon = rand()%6+E_DICE1; + } + + clif_emotion(&sd->bl, emoticon); } else clif_skill_fail(sd, 1, 0, 1); } @@ -9100,7 +9022,7 @@ void clif_parse_HowManyConnections(int fd, struct map_session_data *sd) void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, unsigned int tick) { if (pc_isdead(sd)) { - clif_clearunit_area(&sd->bl, 1); + clif_clearunit_area(&sd->bl, CLR_DEAD); return; } @@ -9198,7 +9120,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) { switch(RFIFOB(fd,2)) { case 0x00: - pc_respawn(sd,2); + pc_respawn(sd,CLR_RESPAWN); break; case 0x01: /* Rovert's Prevent logout option - Fixed [Valaris] */ @@ -9219,7 +9141,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) /*========================================== * Validates and processes whispered messages - * S 0096 <packet len>.w <nick>.23B 00 <message>.?B + * S 0096 <packet len>.w <nick>.24B <message>.?B *------------------------------------------*/ void clif_parse_WisMessage(int fd, struct map_session_data* sd) { @@ -9416,7 +9338,7 @@ void clif_parse_TakeItem(int fd, struct map_session_data *sd) do { if (pc_isdead(sd)) { - clif_clearunit_area(&sd->bl, 1); + clif_clearunit_area(&sd->bl, CLR_DEAD); break; } @@ -9451,7 +9373,8 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd) { int item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2; int item_amount = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]); - do { + + for(;;) { if (pc_isdead(sd)) break; @@ -9469,7 +9392,7 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd) break; return; - } while (0); + } //Because the client does not like being ignored. clif_dropitem(sd, item_index,0); @@ -9483,7 +9406,7 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd) int n; if (pc_isdead(sd)) { - clif_clearunit_area(&sd->bl, 1); + clif_clearunit_area(&sd->bl, CLR_DEAD); return; } @@ -9516,7 +9439,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) int index; if(pc_isdead(sd)) { - clif_clearunit_area(&sd->bl,1); + clif_clearunit_area(&sd->bl,CLR_DEAD); return; } index = RFIFOW(fd,2)-2; @@ -9559,7 +9482,7 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd) int index; if(pc_isdead(sd)) { - clif_clearunit_area(&sd->bl,1); + clif_clearunit_area(&sd->bl,CLR_DEAD); return; } @@ -9581,7 +9504,7 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd) struct block_list *bl; if(pc_isdead(sd)) { - clif_clearunit_area(&sd->bl,1); + clif_clearunit_area(&sd->bl,CLR_DEAD); return; } @@ -9592,8 +9515,6 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd) if (!bl) return; switch (bl->type) { case BL_MOB: - clif_parse_ActionRequest_sub(sd, 0x07, bl->id, gettick()); - break; case BL_PC: clif_parse_ActionRequest_sub(sd, 0x07, bl->id, gettick()); break; @@ -10260,6 +10181,11 @@ void clif_parse_Cooking(int fd,struct map_session_data *sd) //int type = RFIFOW(fd,2); // '1' for cooking, but what do other values mean? int nameid = RFIFOW(fd,4); + if( sd->menuskill_id != AM_PHARMACY ) + { + return; + } + if (pc_istrading(sd)) { //Make it fail to avoid shop exploits where you sell something different than you see. clif_skill_fail(sd,sd->ud.skillid,0,0); @@ -10379,9 +10305,15 @@ void clif_parse_NpcCloseClicked(int fd,struct map_session_data *sd) *------------------------------------------*/ void clif_parse_ItemIdentify(int fd,struct map_session_data *sd) { + short idx = RFIFOW(fd,2); + if (sd->menuskill_id != MC_IDENTIFY) return; - skill_identify(sd,RFIFOW(fd,2)-2); + if( idx == -1 ) + {// cancel pressed + return; + } + skill_identify(sd,idx-2); sd->menuskill_val = sd->menuskill_id = 0; } /*========================================== @@ -10585,7 +10517,7 @@ void clif_parse_StoragePassword(int fd, struct map_session_data *sd) /*========================================== * Party creation request * S 00f9 <party name>.24S - * S 01e8 <party name>.24S <item1>.B <item2>.B + * S 01e8 <party name>.24S <share flag>.B <share type>.B *------------------------------------------*/ void clif_parse_CreateParty(int fd, struct map_session_data *sd) { @@ -10796,10 +10728,10 @@ void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data* sd) { short level = RFIFOW(fd,2); short mapid = RFIFOW(fd,4); - short job[6]; + short job[PARTY_BOOKING_JOBS]; int i; - for(i=0; i<6; i++) + for(i=0; i<PARTY_BOOKING_JOBS; i++) job[i] = RFIFOB(fd,6+i*2); party_booking_register(sd, level, mapid, job); @@ -10832,7 +10764,7 @@ void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data* sd) /*========================================== * more_result: 0 - no more, 1 - more *------------------------------------------*/ -void clif_PartyBookingSearchAck(int fd, unsigned long *index, int count, bool more_result) +void clif_PartyBookingSearchAck(int fd, struct party_booking_ad_info** results, int count, bool more_result) { int i, j; int size = sizeof(struct party_booking_ad_info); // structure size (48) @@ -10840,17 +10772,16 @@ void clif_PartyBookingSearchAck(int fd, unsigned long *index, int count, bool mo WFIFOHEAD(fd,size*count + 5); WFIFOW(fd,0) = 0x805; WFIFOW(fd,2) = size*count + 5; - WFIFOB(fd,4) = (bool)more_result; + WFIFOB(fd,4) = more_result; for(i=0; i<count; i++) { - pb_ad = party_booking_getdata(index[i]); - if(pb_ad == NULL) return; + pb_ad = results[i]; WFIFOL(fd,i*size+5) = pb_ad->index; memcpy(WFIFOP(fd,i*size+9),pb_ad->charname,NAME_LENGTH); WFIFOL(fd,i*size+33) = pb_ad->starttime; WFIFOW(fd,i*size+37) = pb_ad->p_detail.level; WFIFOW(fd,i*size+39) = pb_ad->p_detail.mapid; - for(j=0; j<6; j++) + for(j=0; j<PARTY_BOOKING_JOBS; j++) WFIFOW(fd,i*size+41+j*2) = pb_ad->p_detail.job[j]; } WFIFOSET(fd,WFIFOW(fd,2)); @@ -10858,7 +10789,7 @@ void clif_PartyBookingSearchAck(int fd, unsigned long *index, int count, bool mo void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data* sd) { - if(party_booking_delete(sd, false)) + if(party_booking_delete(sd)) clif_PartyBookingDeleteAck(sd, 0); } @@ -10877,10 +10808,10 @@ void clif_PartyBookingDeleteAck(struct map_session_data* sd, int flag) void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data* sd) { - short job[6]; + short job[PARTY_BOOKING_JOBS]; int i; - for(i=0; i<6; i++) + for(i=0; i<PARTY_BOOKING_JOBS; i++) job[i] = RFIFOW(fd,2+i*2); party_booking_update(sd, job); @@ -10889,32 +10820,32 @@ void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data* sd) void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad) { int i; + uint8 buf[38+PARTY_BOOKING_JOBS*2]; if(pb_ad == NULL) return; - WFIFOHEAD(sd->fd,packet_len(0x809)); - WFIFOW(sd->fd,0) = 0x809; - WFIFOL(sd->fd,2) = pb_ad->index; - memcpy(WFIFOP(sd->fd,6),pb_ad->charname,NAME_LENGTH); - WFIFOL(sd->fd,30) = pb_ad->starttime; - WFIFOW(sd->fd,34) = pb_ad->p_detail.level; - WFIFOW(sd->fd,36) = pb_ad->p_detail.mapid; - for(i=0; i<6; i++) - WFIFOW(sd->fd,38+i*2) = pb_ad->p_detail.job[i]; + WBUFW(buf,0) = 0x809; + WBUFL(buf,2) = pb_ad->index; + memcpy(WBUFP(buf,6),pb_ad->charname,NAME_LENGTH); + WBUFL(buf,30) = pb_ad->starttime; + WBUFW(buf,34) = pb_ad->p_detail.level; + WBUFW(buf,36) = pb_ad->p_detail.mapid; + for(i=0; i<PARTY_BOOKING_JOBS; i++) + WBUFW(buf,38+i*2) = pb_ad->p_detail.job[i]; - WFIFOSET(sd->fd,packet_len(0x809)); + clif_send(buf, packet_len(0x809), &sd->bl, ALL_CLIENT); } void clif_PartyBookingUpdateNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad) { int i; - uint8 buf[18]; + uint8 buf[6+PARTY_BOOKING_JOBS*2]; if(pb_ad == NULL) return; WBUFW(buf,0) = 0x80a; WBUFL(buf,2) = pb_ad->index; - for(i=0; i<6; i++) + for(i=0; i<PARTY_BOOKING_JOBS; i++) WBUFW(buf,6+i*2) = pb_ad->p_detail.job[i]; clif_send(buf,packet_len(0x80a),&sd->bl,ALL_CLIENT); // Now UPDATE all client. } @@ -10941,10 +10872,11 @@ void clif_parse_CloseVending(int fd, struct map_session_data* sd) *------------------------------------------*/ void clif_parse_VendingListReq(int fd, struct map_session_data* sd) { - vending_vendinglistreq(sd,RFIFOL(fd,2)); - if( sd->npc_id ) - npc_event_dequeue(sd); + {// using an NPC + return; + } + vending_vendinglistreq(sd,RFIFOL(fd,2)); } /*========================================== @@ -11075,6 +11007,7 @@ void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd) /*========================================== * ギルドメンバ役職変更 + * S 0155 <packet len>.W {<account id>.L <char id>.L <idx>.L} *------------------------------------------*/ void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd) { @@ -11103,6 +11036,7 @@ void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd) /*========================================== * ギルドエンブレム変更 + * S 0153 <packet len>.W <emblem data>.?B *------------------------------------------*/ void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd) { @@ -11128,7 +11062,7 @@ void clif_parse_GuildChangeNotice(int fd, struct map_session_data* sd) // compensate for some client defects when using multilanguage mode if (msg1[0] == '|' && msg1[3] == '|') msg1+= 3; // skip duplicate marker if (msg2[0] == '|' && msg2[3] == '|') msg2+= 3; // skip duplicate marker - if (msg2[0] == '|') msg2[strnlen(msg2, 120)-1] = '\0'; // delete extra space at the end of string + if (msg2[0] == '|') msg2[strnlen(msg2, MAX_GUILDMES2)-1] = '\0'; // delete extra space at the end of string guild_change_notice(sd, guild_id, msg1, msg2); } @@ -11186,7 +11120,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd) /*========================================== * Request to expel a member of a guild - * S 015b <guild_id>.L <account_id>.L <char_id>.L <reason>.39B 00 + * S 015b <guild_id>.L <account_id>.L <char_id>.L <reason>.40B *------------------------------------------*/ void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd) { @@ -11458,10 +11392,11 @@ void clif_parse_GMKickAll(int fd, struct map_session_data* sd) } /*========================================== - * /shift <name> + * /remove <account name> + * /shift <char name> *------------------------------------------*/ void clif_parse_GMShift(int fd, struct map_session_data *sd) -{ +{// FIXME: remove is supposed to receive account name for clients prior 20100803RE char *player_name; int lv; @@ -11480,11 +11415,47 @@ void clif_parse_GMShift(int fd, struct map_session_data *sd) } } + +/// Warps oneself to the location of the character given by account id ( /remove <account id> ). +/// R 0843 <account id>.L +void clif_parse_GMRemove2(int fd, struct map_session_data* sd) +{ + int account_id, lv; + struct map_session_data* pl_sd; + + if( battle_config.atc_gmonly && !pc_isGM(sd) ) + { + return; + } + + if( pc_isGM(sd) < ( lv = get_atcommand_level(atcommand_jumpto) ) ) + { + return; + } + + account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]); + + if( ( pl_sd = map_id2sd(account_id) ) != NULL && pc_isGM(sd) >= pc_isGM(pl_sd) ) + { + pc_warpto(sd, pl_sd); + } + + if( log_config.gm && lv >= log_config.gm ) + { + char message[32]; + + sprintf(message, "/remove %d", account_id); + log_atcommand(sd, message); + } +} + + /*========================================== - * /recall <name> + * /recall <account name> + * /summon <char name> *------------------------------------------*/ void clif_parse_GMRecall(int fd, struct map_session_data *sd) -{ +{// FIXME: recall is supposed to receive account name for clients prior 20100803RE char *player_name; int lv; @@ -11504,8 +11475,44 @@ void clif_parse_GMRecall(int fd, struct map_session_data *sd) } } + +/// Summons a character given by account id to one's own position ( /recall <account id> ) +/// R 0842 <account id>.L +void clif_parse_GMRecall2(int fd, struct map_session_data* sd) +{ + int account_id, lv; + struct map_session_data* pl_sd; + + if( battle_config.atc_gmonly && !pc_isGM(sd) ) + { + return; + } + + if( pc_isGM(sd) < ( lv = get_atcommand_level(atcommand_recall) ) ) + { + return; + } + + account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]); + + if( ( pl_sd = map_id2sd(account_id) ) != NULL && pc_isGM(sd) >= pc_isGM(pl_sd) ) + { + pc_recall(sd, pl_sd); + } + + if( log_config.gm && lv >= log_config.gm ) + { + char message[32]; + + sprintf(message, "/recall %d", account_id); + log_atcommand(sd, message); + } +} + + /*========================================== * /monster /item + * R 01F3 <name>.24B *------------------------------------------*/ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) { @@ -11663,11 +11670,11 @@ void clif_parse_GMReqAccountName(int fd, struct map_session_data *sd) /*========================================== * GM single cell type change request - * /changemaptype <x> <y> <type> + * /changemaptype <x> <y> <type:0-1> * S 0198 <x>.W <y>.W <gat>.W *------------------------------------------*/ void clif_parse_GMChangeMapType(int fd, struct map_session_data *sd) -{ +{// FIXME: type sent by client is 0 or 1 (even if you enter 2+); that suggests, that it is walkable gat attribute int x,y,type; if( battle_config.atc_gmonly && !pc_isGM(sd) ) @@ -12107,6 +12114,7 @@ void clif_parse_PVPInfo(int fd,struct map_session_data *sd) /*========================================== * /blacksmith + * S 0217 *------------------------------------------*/ void clif_parse_Blacksmith(int fd,struct map_session_data *sd) { @@ -12150,6 +12158,7 @@ int clif_fame_blacksmith(struct map_session_data *sd, int points) /*========================================== * /alchemist + * S 0218 *------------------------------------------*/ void clif_parse_Alchemist(int fd,struct map_session_data *sd) { @@ -12193,6 +12202,7 @@ int clif_fame_alchemist(struct map_session_data *sd, int points) /*========================================== * /taekwon + * S 0225 *------------------------------------------*/ void clif_parse_Taekwon(int fd,struct map_session_data *sd) { @@ -12234,7 +12244,8 @@ int clif_fame_taekwon(struct map_session_data *sd, int points) } /*========================================== - * PK Ranking table? + * /pk + * S 0237 *------------------------------------------*/ void clif_parse_RankingPk(int fd,struct map_session_data *sd) { @@ -12259,7 +12270,7 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd) if (sd->menuskill_id != SG_FEEL) return; i = sd->menuskill_val-1; - if (i<0 || i > 2) return; //Bug? + if (i<0 || i >= MAX_PC_FEELHATE) return; //Bug? sd->feel_map[i].index = map_id2index(sd->bl.m); sd->feel_map[i].m = sd->bl.m; @@ -12738,9 +12749,10 @@ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd) /*------------------------------------------ * Mail Window Operation + * S 0246 <flag>.W * 0 : Switch to 'new mail' window, or Close mailbox * 1 : ??? - * 2 : ??? + * 2 : Zeny entering start *------------------------------------------*/ void clif_parse_Mail_winopen(int fd, struct map_session_data *sd) { @@ -13592,12 +13604,9 @@ void clif_parse_mercenary_action(int fd, struct map_session_data* sd) * 2 = Your mercenary soldier has been fired. * 3 = Your mercenary soldier has ran away. *------------------------------------------*/ -void clif_mercenary_message(int fd, int message) +void clif_mercenary_message(struct map_session_data* sd, int message) { - WFIFOHEAD(fd,4); - WFIFOW(fd,0) = 0x0291; - WFIFOW(fd,2) = 1266 + message; - WFIFOSET(fd,4); + clif_msg(sd, 1266 + message); } /*------------------------------------------ @@ -13959,6 +13968,23 @@ void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, b return; } +/// Displays digital clock digits on top of the screen (ZC_SHOWDIGIT). +/// type: +/// 0: Displays 'value' for 5 seconds. +/// 1: Incremental counter (1 tick/second), negated 'value' specifies start value (e.g. using -10 lets the counter start at 10). +/// 2: Decremental counter (1 tick/second), negated 'value' specifies start value (does not stop when reaching 0, but overflows). +/// 3: Decremental counter (2 ticks/second), 'value' specifies start value (stops when reaching 0, displays at most 2 digits). +/// value: +/// Except for type 3 it is interpreted as seconds for displaying as DD:HH:MM:SS, HH:MM:SS, MM:SS or SS (leftmost '00' is not displayed). +void clif_showdigit(struct map_session_data* sd, unsigned char type, int value) +{ + WFIFOHEAD(sd->fd, packet_len(0x1b1)); + WFIFOW(sd->fd,0) = 0x1b1; + WFIFOB(sd->fd,0) = type; + WFIFOL(sd->fd,0) = value; + WFIFOSET(sd->fd, packet_len(0x1b1)); +} + /*========================================== * パケットデバッグ *------------------------------------------*/ @@ -13987,10 +14013,10 @@ int clif_parse(int fd) TBL_PC* sd; int pnum; - //TODO apply deplays or disconnect based on packet throughput [FlavioJS] + //TODO apply delays or disconnect based on packet throughput [FlavioJS] // Note: "click masters" can do 80+ clicks in 10 seconds - for( pnum = 0; pnum < 3; ++pnum )// Limit max packets per cycle to 3 (delay packet spammers) [FlavioJS] + for( pnum = 0; pnum < 3; ++pnum )// Limit max packets per cycle to 3 (delay packet spammers) [FlavioJS] -- This actually aids packet spammers, but stuff like /str+ gets slow without it [Ai4rei] { // begin main client packet processing loop sd = (TBL_PC *)session[fd]->session_data; @@ -14491,6 +14517,8 @@ static int packetdb_readdb(void) {clif_parse_GMShift,"shift"}, {clif_parse_GMChangeMapType,"changemaptype"}, {clif_parse_GMRc,"rc"}, + {clif_parse_GMRecall2,"recall2"}, + {clif_parse_GMRemove2,"remove2"}, {clif_parse_NoviceDoriDori,"sndoridori"}, {clif_parse_NoviceExplosionSpirits,"snexplosionspirits"}, |