diff options
Diffstat (limited to 'src/map/clif.c')
-rw-r--r-- | src/map/clif.c | 466 |
1 files changed, 341 insertions, 125 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index ce88b32da..5d9802b57 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1360,6 +1360,7 @@ void clif_spiritball_single(int fd, struct map_session_data *sd) { *------------------------------------------*/ void clif_charm_single(int fd, struct map_session_data *sd) { +#if PACKETVER >= 20110809 nullpo_retv(sd); WFIFOHEAD(fd, packet_len(0x08cf)); WFIFOW(fd,0) = 0x08cf; @@ -1367,6 +1368,7 @@ void clif_charm_single(int fd, struct map_session_data *sd) WFIFOW(fd,6) = sd->charm_type; WFIFOW(fd,8) = sd->charm_count; WFIFOSET(fd, packet_len(0x08cf)); +#endif } /*========================================== @@ -1495,6 +1497,15 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag) struct status_data *hstatus; unsigned char buf[128]; enum homun_type htype; + int offset = 0; + +// probably can works also for < 20141223, but in 3CeaM packet size defined only for 20150513 +#if PACKETVER < 20150513 + int cmd = 0x22e; +#else + int cmd = 0x9f7; +#endif + int len = packet_len(cmd); nullpo_retv(sd); nullpo_retv(hd); @@ -1502,65 +1513,75 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag) hstatus = &hd->battle_status; htype = homun->class2type(hd->homunculus.class_); - memset(buf,0,packet_len(0x22e)); - WBUFW(buf,0)=0x22e; - memcpy(WBUFP(buf,2),hd->homunculus.name,NAME_LENGTH); + memset(buf, 0, len); + WBUFW(buf, 0) = cmd; + memcpy(WBUFP(buf, 2), hd->homunculus.name, NAME_LENGTH); // Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true) - WBUFB(buf,26)=(battle_config.hom_rename && hd->homunculus.rename_flag ? 0x1 : 0x0) | (hd->homunculus.vaporize == HOM_ST_REST ? 0x2 : 0) | (hd->homunculus.hp > 0 ? 0x4 : 0); - WBUFW(buf,27)=hd->homunculus.level; - WBUFW(buf,29)=hd->homunculus.hunger; - WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ; - WBUFW(buf,33)=0; // equip id + WBUFB(buf, 26) = (!battle_config.hom_rename && hd->homunculus.rename_flag ? 0x1 : 0x0) | (hd->homunculus.vaporize == HOM_ST_REST ? 0x2 : 0) | (hd->homunculus.hp > 0 ? 0x4 : 0); + WBUFW(buf, 27) = hd->homunculus.level; + WBUFW(buf, 29) = hd->homunculus.hunger; + WBUFW(buf, 31) = (unsigned short) (hd->homunculus.intimacy / 100) ; + WBUFW(buf, 33) = 0; // equip id #ifdef RENEWAL WBUFW(buf, 35) = cap_value(hstatus->rhw.atk2, 0, INT16_MAX); #else - WBUFW(buf,35)=cap_value(hstatus->rhw.atk2+hstatus->batk, 0, INT16_MAX); + WBUFW(buf,35) = cap_value(hstatus->rhw.atk2 + hstatus->batk, 0, INT16_MAX); #endif - WBUFW(buf,37)=cap_value(hstatus->matk_max, 0, INT16_MAX); - WBUFW(buf,39)=hstatus->hit; + WBUFW(buf,37) = cap_value(hstatus->matk_max, 0, INT16_MAX); + WBUFW(buf,39) = hstatus->hit; if (battle_config.hom_setting&0x10) - WBUFW(buf,41)=hstatus->luk/3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious] + WBUFW(buf, 41) = hstatus->luk / 3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious] else - WBUFW(buf,41)=hstatus->cri/10; + WBUFW(buf, 41) = hstatus->cri / 10; #ifdef RENEWAL WBUFW(buf, 43) = hstatus->def + hstatus->def2; WBUFW(buf, 45) = hstatus->mdef + hstatus->mdef2; #else - WBUFW(buf,43)=hstatus->def + hstatus->vit ; + WBUFW(buf, 43) =hstatus->def + hstatus->vit ; WBUFW(buf, 45) = hstatus->mdef; #endif - WBUFW(buf,47)=hstatus->flee; - WBUFW(buf,49)=(flag)?0:hstatus->amotion; + WBUFW(buf, 47) = hstatus->flee; + WBUFW(buf, 49) = (flag) ? 0 : hstatus->amotion; + +// probably can works also for < 20141223, but in 3CeaM packet size defined only for 20150513 +#if PACKETVER < 20150513 if (hstatus->max_hp > INT16_MAX) { - WBUFW(buf,51) = hstatus->hp/(hstatus->max_hp/100); - WBUFW(buf,53) = 100; + WBUFW(buf, 51) = hstatus->hp / (hstatus->max_hp / 100); + WBUFW(buf, 53) = 100; } else { - WBUFW(buf,51)=hstatus->hp; - WBUFW(buf,53)=hstatus->max_hp; + WBUFW(buf, 51) = hstatus->hp; + WBUFW(buf, 53) = hstatus->max_hp; } +#else + WBUFL(buf, 51) = hstatus->hp; + WBUFL(buf, 55) = hstatus->max_hp; + offset = 4; +#endif + if (hstatus->max_sp > INT16_MAX) { - WBUFW(buf,55) = hstatus->sp/(hstatus->max_sp/100); - WBUFW(buf,57) = 100; + WBUFW(buf, 55 + offset) = hstatus->sp / (hstatus->max_sp / 100); + WBUFW(buf, 57 + offset) = 100; } else { - WBUFW(buf,55)=hstatus->sp; - WBUFW(buf,57)=hstatus->max_sp; + WBUFW(buf, 55 + offset) = hstatus->sp; + WBUFW(buf, 57 + offset) = hstatus->max_sp; } - WBUFL(buf,59)=hd->homunculus.exp; - WBUFL(buf,63)=hd->exp_next; - switch( htype ) { + WBUFL(buf, 59 + offset) = hd->homunculus.exp; + WBUFL(buf, 63 + offset) = hd->exp_next; + switch (htype) { case HT_REG: case HT_EVO: - if( hd->homunculus.level >= battle_config.hom_max_level ) - WBUFL(buf,63)=0; + if (hd->homunculus.level >= battle_config.hom_max_level) + WBUFL(buf, 63 + offset) = 0; break; case HT_S: - if( hd->homunculus.level >= battle_config.hom_S_max_level ) - WBUFL(buf,63)=0; + if (hd->homunculus.level >= battle_config.hom_S_max_level) + WBUFL(buf, 63 + offset) = 0; break; } - WBUFW(buf,67)=hd->homunculus.skillpts; - WBUFW(buf,69)=status_get_range(&hd->bl); - clif->send(buf,packet_len(0x22e),&sd->bl,SELF); + WBUFW(buf, 67 + offset) = hd->homunculus.skillpts; + WBUFW(buf, 69 + offset) = status_get_range(&hd->bl); + + clif->send(buf, len, &sd->bl, SELF); } /// Notification about a change in homunuculus' state (ZC_CHANGESTATE_MER). @@ -3228,10 +3249,7 @@ void clif_changelook(struct block_list *bl,int type,int val) #endif break; case LOOK_BODY2: - if (val && ( - sd->sc.option&OPTION_WEDDING || sd->sc.option&OPTION_XMAS || - sd->sc.option&OPTION_SUMMER || sd->sc.option&OPTION_HANBOK || - sd->sc.option&OPTION_OKTOBERFEST)) + if (sd != NULL && (sd->sc.option&OPTION_COSTUME) != OPTION_NOTHING) val = 0; vd->body_style = val; break; @@ -5208,33 +5226,46 @@ int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tic } #endif // 0 -/// Non-damaging skill effect (ZC_USE_SKILL). -/// 011a <skill id>.W <skill lv>.W <dst id>.L <src id>.L <result>.B -int clif_skill_nodamage(struct block_list *src,struct block_list *dst,uint16 skill_id,int heal,int fail) +/// Non-damaging skill effect. +/// 011a <skill id>.W <skill lv>.W <dst id>.L <src id>.L <result>.B (ZC_USE_SKILL) +/// 09cb <skill id>.W <skill lv>.L <dst id>.L <src id>.L <result>.B (ZC_USE_SKILL2) +int clif_skill_nodamage(struct block_list *src, struct block_list *dst, uint16 skill_id, int heal, int fail) { unsigned char buf[32]; + short offset = 0; +#if PACKETVER < 20131223 + short cmd = 0x11a; +#else + short cmd = 0x9cb; +#endif + int len = packet_len(cmd); nullpo_ret(dst); - WBUFW(buf,0)=0x11a; - WBUFW(buf,2)=skill_id; - WBUFW(buf,4)=min(heal, INT16_MAX); - WBUFL(buf,6)=dst->id; - WBUFL(buf,10)=src?src->id:0; - WBUFB(buf,14)=fail; + WBUFW(buf, 0) = cmd; + WBUFW(buf, 2) = skill_id; +#if PACKETVER < 20131223 + WBUFW(buf, 4) = min(heal, INT16_MAX); +#else + WBUFL(buf, 4) = min(heal, INT_MAX); + offset += 2; +#endif + WBUFL(buf, 6 + offset) = dst->id; + WBUFL(buf, 10 + offset) = src ? src->id : 0; + WBUFB(buf, 14 + offset) = fail; if (clif->isdisguised(dst)) { - clif->send(buf,packet_len(0x11a),dst,AREA_WOS); - WBUFL(buf,6)=-dst->id; - clif->send(buf,packet_len(0x11a),dst,SELF); + clif->send(buf, len, dst, AREA_WOS); + WBUFL(buf, 6 + offset) = -dst->id; + clif->send(buf, len, dst, SELF); } else - clif->send(buf,packet_len(0x11a),dst,AREA); + clif->send(buf, len, dst, AREA); if (src && clif->isdisguised(src)) { - WBUFL(buf,10)=-src->id; + WBUFL(buf, 10 + offset) = -src->id; if (clif->isdisguised(dst)) - WBUFL(buf,6)=dst->id; - clif->send(buf,packet_len(0x11a),src,SELF); + WBUFL(buf, 6 + offset) = dst->id; + clif->send(buf, len, src, SELF); } return fail; @@ -5708,13 +5739,24 @@ void clif_broadcast2(struct block_list *bl, const char *mes, int len, unsigned i /// 5 = HP (SP_HP) /// 7 = SP (SP_SP) /// ? = ignored -void clif_heal(int fd,int type,int val) +void clif_heal(int fd, int type, int val) { - WFIFOHEAD(fd,packet_len(0x13d)); - WFIFOW(fd,0)=0x13d; - WFIFOW(fd,2)=type; - WFIFOW(fd,4)=cap_value(val,0,INT16_MAX); - WFIFOSET(fd,packet_len(0x13d)); +#if PACKETVER < 20150513 + short cmd = 0x13d; +#else + short cmd = 0xa27; +#endif + int len = packet_len(cmd); + + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = cmd; + WFIFOW(fd, 2) = type; +#if PACKETVER < 20150513 + WFIFOW(fd, 4) = cap_value(val, 0, INT16_MAX); +#else + WFIFOL(fd, 4) = cap_value(val, 0, INT_MAX); +#endif + WFIFOSET(fd, len); } /// Displays resurrection effect (ZC_RESURRECTION). @@ -6376,29 +6418,41 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* ven } WFIFOSET(fd,WFIFOW(fd,2)); -#if PACKETVER >= 20141022 +#if PACKETVER >= 20140625 /** should go elsewhere perhaps? it has to be bundled with this however. **/ - WFIFOHEAD(fd, 3); + WFIFOHEAD(fd, packet_len(0xa28)); WFIFOW(fd, 0) = 0xa28; WFIFOB(fd, 2) = 0;/** 1 is failure. our current responses to failure are working so not yet implemented **/ - WFIFOSET(fd, 3); + WFIFOSET(fd, packet_len(0xa28)); #endif } -/// Inform merchant that someone has bought an item (ZC_DELETEITEM_FROM_MCSTORE). -/// 0137 <index>.W <amount>.W -void clif_vendingreport(struct map_session_data* sd, int index, int amount) +/// Inform merchant that someone has bought an item. +/// 0137 <index>.W <amount>.W (ZC_DELETEITEM_FROM_MCSTORE). +/// 09e5 <index>.W <amount>.W <GID>.L <Date>.L <zeny>.L (ZC_DELETEITEM_FROM_MCSTORE2). +void clif_vendingreport(struct map_session_data* sd, int index, int amount, uint32 char_id, int zeny) { int fd; +#if PACKETVER < 20141016 // TODO : not sure for client date [Napster] + const int cmd = 0x137; +#else + const int cmd = 0x9e5; +#endif + const int len = packet_len(cmd); nullpo_retv(sd); fd = sd->fd; - WFIFOHEAD(fd,packet_len(0x137)); - WFIFOW(fd,0) = 0x137; - WFIFOW(fd,2) = index+2; - WFIFOW(fd,4) = amount; - WFIFOSET(fd,packet_len(0x137)); + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = cmd; + WFIFOW(fd, 2) = index + 2; + WFIFOW(fd, 4) = amount; +#if PACKETVER >= 20141016 + WFIFOL(fd,6) = char_id; // GID + WFIFOL(fd,10) = (int)time(NULL); // Date + WFIFOL(fd,14) = zeny; // zeny +#endif + WFIFOSET(fd, len); } /// Result of organizing a party (ZC_ACK_MAKE_GROUP). @@ -7050,21 +7104,31 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd) if( src->type == BL_MER ) { struct mercenary_data *md = BL_CAST(BL_MER,src); + int skill_lvl; if( md && md->master && md->devotion_flag ) WBUFL(buf,6) = md->master->bl.id; - WBUFW(buf,26) = skill->get_range2(src, ML_DEVOTION, mercenary->checkskill(md, ML_DEVOTION)); + skill_lvl = mercenary->checkskill(md, ML_DEVOTION); + if (skill_lvl > 0) + WBUFW(buf, 26) = skill->get_range2(src, ML_DEVOTION, skill_lvl); + else + WBUFW(buf, 26) = 0; } else { int i; struct map_session_data *sd = BL_CAST(BL_PC,src); + int skill_lvl; if( sd == NULL ) return; for( i = 0; i < MAX_PC_DEVOTION; i++ ) WBUFL(buf,6+4*i) = sd->devotion[i]; - WBUFW(buf,26) = skill->get_range2(src, CR_DEVOTION, pc->checkskill(sd, CR_DEVOTION)); + skill_lvl = pc->checkskill(sd, CR_DEVOTION); + if (skill_lvl > 0) + WBUFW(buf, 26) = skill->get_range2(src, CR_DEVOTION, skill_lvl); + else + WBUFW(buf, 26) = 0; } if( tsd ) @@ -9755,11 +9819,9 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd) __attribute__((non void clif_parse_QuitGame(int fd, struct map_session_data *sd) { /* Rovert's prevent logout option fixed [Valaris] */ - if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] && - (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) - { + if (!sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] && !sd->sc.data[SC_SUHIDE] && + (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout)) { sockt->eof(fd); - clif->disconnect_ack(sd, 0); } else { clif->disconnect_ack(sd, 1); @@ -9991,7 +10053,7 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd) { int emoticon = RFIFOB(fd,packet_db[RFIFOW(fd,0)].pos[0]); - if (battle_config.basic_skill_check == 0 || pc->checkskill(sd, NV_BASIC) >= 2) { + if (battle_config.basic_skill_check == 0 || pc->check_basicskill(sd, 2)) { if (emoticon == E_MUTE) {// prevent use of the mute emote [Valaris] clif->skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 1); return; @@ -10051,7 +10113,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, sd->sc.data[SC_TRICKDEAD] || (sd->sc.data[SC_AUTOCOUNTER] && action_type != 0x07) || sd->sc.data[SC_BLADESTOP] || - sd->sc.data[SC_DEEP_SLEEP] ) + sd->sc.data[SC_DEEP_SLEEP] || + sd->sc.data[SC_SUHIDE] ) ) return; @@ -10091,7 +10154,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, } break; case 0x02: // sitdown - if (battle_config.basic_skill_check && pc->checkskill(sd, NV_BASIC) < 3) { + if (battle_config.basic_skill_check && !pc->check_basicskill(sd, 3)) { clif->skill_fail(sd, 1, USESKILL_FAIL_LEVEL, 2); break; } @@ -10176,7 +10239,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) { case 0x01: /* Rovert's Prevent logout option - Fixed [Valaris] */ if (!sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] - && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] + && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] && !sd->sc.data[SC_SUHIDE] && (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) { //Send to char-server for character selection. @@ -10364,6 +10427,7 @@ void clif_parse_TakeItem(int fd, struct map_session_data *sd) sd->sc.data[SC_TRICKDEAD] || sd->sc.data[SC_BLADESTOP] || sd->sc.data[SC_CLOAKINGEXCEED] || + sd->sc.data[SC_SUHIDE] || pc_ismuted(&sd->sc, MANNER_NOITEM) ) ) break; @@ -10696,7 +10760,7 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd) if (pc_ismuted(&sd->sc, MANNER_NOROOM)) return; - if(battle_config.basic_skill_check && pc->checkskill(sd,NV_BASIC) < 4) { + if(battle_config.basic_skill_check && !pc->check_basicskill(sd, 4)) { clif->skill_fail(sd,1,USESKILL_FAIL_LEVEL,3); return; } @@ -10813,7 +10877,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->check_basicskill(sd, 1)) { clif->skill_fail(sd,1,USESKILL_FAIL_LEVEL,0); return; } @@ -11859,7 +11923,7 @@ void clif_parse_CreateParty(int fd, struct map_session_data *sd) clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map. return; } - if( battle_config.basic_skill_check && pc->checkskill(sd,NV_BASIC) < 7 ) { + if (battle_config.basic_skill_check && !pc->check_basicskill(sd, 7)) { clif->skill_fail(sd,1,USESKILL_FAIL_LEVEL,4); return; } @@ -11881,7 +11945,7 @@ void clif_parse_CreateParty2(int fd, struct map_session_data *sd) clif->message(fd, msg_fd(fd,227)); // Party modification is disabled in this map. return; } - if( battle_config.basic_skill_check && pc->checkskill(sd,NV_BASIC) < 7 ) { + if (battle_config.basic_skill_check && !pc->check_basicskill(sd, 7)) { clif->skill_fail(sd,1,USESKILL_FAIL_LEVEL,4); return; } @@ -13766,6 +13830,7 @@ void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd) case MAPID_TAEKWON: if (!sd->state.rest) break; + FALLTHROUGH case MAPID_SUPER_NOVICE: sd->state.doridori=1; break; @@ -14151,15 +14216,18 @@ void clif_ranklist_sub(unsigned char *buf, enum fame_list_type type) { } /// 097d <RankingType>.W {<CharName>.24B <point>L}*10 <mypoint>L (ZC_ACK_RANKING) -void clif_ranklist(struct map_session_data *sd, enum fame_list_type type) { +void clif_ranklist(struct map_session_data *sd, enum fame_list_type type) +{ +#if PACKETVER >= 20120502 int fd; int mypoint = 0; int upperMask; + int len = packet_len(0x97d); nullpo_retv(sd); fd = sd->fd; upperMask = sd->class_&MAPID_UPPERMASK; - WFIFOHEAD(fd, 288); + WFIFOHEAD(fd, len); WFIFOW(fd, 0) = 0x97d; WFIFOW(fd, 2) = type; clif_ranklist_sub(WFIFOP(fd,4), type); @@ -14174,7 +14242,8 @@ void clif_ranklist(struct map_session_data *sd, enum fame_list_type type) { } WFIFOL(fd, 284) = mypoint; //mypoint - WFIFOSET(fd, 288); + WFIFOSET(fd, len); +#endif } void clif_parse_ranklist(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -14194,8 +14263,9 @@ void clif_parse_ranklist(int fd, struct map_session_data *sd) { } // 097e <RankingType>.W <point>.L <TotalPoint>.L (ZC_UPDATE_RANKING_POINT) -void clif_update_rankingpoint(struct map_session_data *sd, enum fame_list_type type, int points) { -#if PACKETVER < 20130710 +void clif_update_rankingpoint(struct map_session_data *sd, enum fame_list_type type, int points) +{ +#if PACKETVER < 20120502 switch( type ) { case RANKTYPE_BLACKSMITH: clif->fame_blacksmith(sd,points); break; case RANKTYPE_ALCHEMIST: clif->fame_alchemist(sd,points); break; @@ -14204,15 +14274,16 @@ void clif_update_rankingpoint(struct map_session_data *sd, enum fame_list_type t #else int fd; + int len = packet_len(0x97e); nullpo_retv(sd); fd = sd->fd; - WFIFOHEAD(fd, 12); + WFIFOHEAD(fd, len); WFIFOW(fd, 0) = 0x97e; WFIFOW(fd, 2) = type; WFIFOL(fd, 4) = points; WFIFOL(fd, 8) = sd->status.fame; - WFIFOSET(fd, 12); + WFIFOSET(fd, len); #endif } @@ -15197,10 +15268,10 @@ void clif_Auction_message(int fd, unsigned char flag) /// 2 = Auction ID is incorrect void clif_Auction_close(int fd, unsigned char flag) { - WFIFOHEAD(fd,packet_len(0x25e)); + WFIFOHEAD(fd, 4); WFIFOW(fd,0) = 0x25d; // BUG: The client identifies this packet as 0x25d (CZ_AUCTION_REQ_MY_SELL_STOP) WFIFOW(fd,2) = flag; - WFIFOSET(fd,packet_len(0x25e)); + WFIFOSET(fd, 4); } void clif_parse_Auction_register(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -16126,28 +16197,46 @@ void clif_readbook(int fd, int book_id, int page) /// Battlegrounds /// -/// Updates HP bar of a camp member (ZC_BATTLEFIELD_NOTIFY_HP). -/// 02e0 <account id>.L <name>.24B <hp>.W <max hp>.W +/// Updates HP bar of a camp member. +/// 02e0 <account id>.L <name>.24B <hp>.W <max hp>.W (ZC_BATTLEFIELD_NOTIFY_HP). +/// 0a0e <account id>.L <hp>.L <max hp>.L (ZC_BATTLEFIELD_NOTIFY_HP2) void clif_bg_hp(struct map_session_data *sd) { unsigned char buf[34]; + +// packet version can be wrong, because inconsistend data in other servers. +#if PACKETVER < 20140613 const int cmd = 0x2e0; nullpo_retv(sd); - WBUFW(buf,0) = cmd; - WBUFL(buf,2) = sd->status.account_id; - memcpy(WBUFP(buf,6), sd->status.name, NAME_LENGTH); + WBUFW(buf, 0) = cmd; + WBUFL(buf, 2) = sd->status.account_id; + memcpy(WBUFP(buf, 6), sd->status.name, NAME_LENGTH); - if( sd->battle_status.max_hp > INT16_MAX ) + if (sd->battle_status.max_hp > INT16_MAX) { // To correctly display the %hp bar. [Skotlex] - WBUFW(buf,30) = sd->battle_status.hp/(sd->battle_status.max_hp/100); - WBUFW(buf,32) = 100; + WBUFW(buf, 30) = sd->battle_status.hp / (sd->battle_status.max_hp / 100); + WBUFW(buf, 32) = 100; } else { - WBUFW(buf,30) = sd->battle_status.hp; - WBUFW(buf,32) = sd->battle_status.max_hp; + WBUFW(buf, 30) = sd->battle_status.hp; + WBUFW(buf, 32) = sd->battle_status.max_hp; } +#else + const int cmd = 0xa0e; + nullpo_retv(sd); + + WBUFW(buf, 0) = cmd; + WBUFL(buf, 2) = sd->status.account_id; + if (sd->battle_status.max_hp > INT32_MAX) { + WBUFL(buf, 6) = sd->battle_status.hp / (sd->battle_status.max_hp / 100); + WBUFL(buf, 10) = 100; + } else { + WBUFL(buf, 6) = sd->battle_status.hp; + WBUFL(buf, 10) = sd->battle_status.max_hp; + } +#endif clif->send(buf, packet_len(cmd), &sd->bl, BG_AREA_WOS); } @@ -16606,6 +16695,7 @@ void clif_elemental_info(struct map_session_data *sd) { /// 0810 <slots>.B void clif_buyingstore_open(struct map_session_data* sd) { +#if PACKETVER >= 20100303 int fd; nullpo_retv(sd); @@ -16614,6 +16704,7 @@ void clif_buyingstore_open(struct map_session_data* sd) WFIFOW(fd,0) = 0x810; WFIFOB(fd,2) = sd->buyingstore.slots; WFIFOSET(fd,packet_len(0x810)); +#endif } void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -16667,6 +16758,7 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) { /// ? = nothing void clif_buyingstore_open_failed(struct map_session_data* sd, unsigned short result, unsigned int weight) { +#if PACKETVER >= 20100420 int fd; nullpo_retv(sd); @@ -16676,6 +16768,7 @@ void clif_buyingstore_open_failed(struct map_session_data* sd, unsigned short re WFIFOW(fd,2) = result; WFIFOL(fd,4) = weight; WFIFOSET(fd,packet_len(0x812)); +#endif } /// Notification, that the requested buying store was created (ZC_MYITEMLIST_BUYING_STORE). @@ -16708,6 +16801,7 @@ void clif_buyingstore_myitemlist(struct map_session_data* sd) /// 0814 <account id>.L <store name>.80B void clif_buyingstore_entry(struct map_session_data* sd) { +#if PACKETVER >= 20100420 uint8 buf[86]; nullpo_retv(sd); @@ -16716,9 +16810,11 @@ void clif_buyingstore_entry(struct map_session_data* sd) memcpy(WBUFP(buf,6), sd->message, MESSAGE_SIZE); clif->send(buf, packet_len(0x814), &sd->bl, AREA_WOS); +#endif } void clif_buyingstore_entry_single(struct map_session_data* sd, struct map_session_data* pl_sd) { +#if PACKETVER >= 20100420 int fd; nullpo_retv(sd); @@ -16728,6 +16824,7 @@ void clif_buyingstore_entry_single(struct map_session_data* sd, struct map_sessi WFIFOL(fd,2) = pl_sd->bl.id; memcpy(WFIFOP(fd,6), pl_sd->message, MESSAGE_SIZE); WFIFOSET(fd,packet_len(0x814)); +#endif } void clif_parse_ReqCloseBuyingStore(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -16741,6 +16838,7 @@ void clif_parse_ReqCloseBuyingStore(int fd, struct map_session_data* sd) { /// 0816 <account id>.L void clif_buyingstore_disappear_entry(struct map_session_data* sd) { +#if PACKETVER >= 20100309 uint8 buf[6]; nullpo_retv(sd); @@ -16748,9 +16846,12 @@ void clif_buyingstore_disappear_entry(struct map_session_data* sd) WBUFL(buf,2) = sd->bl.id; clif->send(buf, packet_len(0x816), &sd->bl, AREA_WOS); +#endif } + void clif_buyingstore_disappear_entry_single(struct map_session_data* sd, struct map_session_data* pl_sd) { +#if PACKETVER >= 20100309 int fd; nullpo_retv(sd); @@ -16760,6 +16861,7 @@ void clif_buyingstore_disappear_entry_single(struct map_session_data* sd, struct WFIFOW(fd,0) = 0x816; WFIFOL(fd,2) = pl_sd->bl.id; WFIFOSET(fd,packet_len(0x816)); +#endif } /// Request to open someone else's buying store (CZ_REQ_CLICK_TO_BUYING_STORE). @@ -16844,6 +16946,7 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) { /// ? = nothing void clif_buyingstore_trade_failed_buyer(struct map_session_data* sd, short result) { +#if PACKETVER >= 20100420 int fd; nullpo_retv(sd); @@ -16852,22 +16955,36 @@ void clif_buyingstore_trade_failed_buyer(struct map_session_data* sd, short resu WFIFOW(fd,0) = 0x81a; WFIFOW(fd,2) = result; WFIFOSET(fd,packet_len(0x81a)); +#endif } /// Updates the zeny limit and an item in the buying store item list (ZC_UPDATE_ITEM_FROM_BUYING_STORE). /// 081b <name id>.W <amount>.W <limit zeny>.L -void clif_buyingstore_update_item(struct map_session_data* sd, unsigned short nameid, unsigned short amount) +void clif_buyingstore_update_item(struct map_session_data* sd, unsigned short nameid, unsigned short amount, uint32 char_id, int zeny) { int fd; +#if PACKETVER < 20141016 // TODO : not sure for client date [Napster] + const int cmd = 0x81b; +#else + const int cmd = 0x9e6; +#endif + const int len = packet_len(cmd); nullpo_retv(sd); fd = sd->fd; - WFIFOHEAD(fd,packet_len(0x81b)); - WFIFOW(fd,0) = 0x81b; - WFIFOW(fd,2) = nameid; - WFIFOW(fd,4) = amount; // amount of nameid received - WFIFOL(fd,6) = sd->buyingstore.zenylimit; - WFIFOSET(fd,packet_len(0x81b)); + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = cmd; + WFIFOW(fd, 2) = nameid; + WFIFOW(fd, 4) = amount; // amount of nameid received +#if PACKETVER < 20141016 + WFIFOL(fd, 6) = sd->buyingstore.zenylimit; +#else + WFIFOL(fd, 6) = zeny; // zeny + WFIFOL(fd, 10) = sd->buyingstore.zenylimit; + WFIFOL(fd, 14) = char_id; // GID + WFIFOL(fd, 18) = (int)time(NULL); // date +#endif + WFIFOSET(fd, len); } /// Deletes item from inventory, that was sold to a buying store (ZC_ITEM_DELETE_BUYING_STORE). @@ -16878,6 +16995,7 @@ void clif_buyingstore_update_item(struct map_session_data* sd, unsigned short na /// NOTE: This function has to be called _instead_ of clif_delitem/clif_dropitem. void clif_buyingstore_delete_item(struct map_session_data* sd, short index, unsigned short amount, int price) { +#if PACKETVER >= 20100420 int fd; nullpo_retv(sd); @@ -16888,6 +17006,7 @@ void clif_buyingstore_delete_item(struct map_session_data* sd, short index, unsi WFIFOW(fd,4) = amount; WFIFOL(fd,6) = price; // price per item, client calculates total Zeny by itself WFIFOSET(fd,packet_len(0x81c)); +#endif } /// Notifies the seller, that a buying store trade failed (ZC_FAILED_TRADE_BUYING_STORE_TO_SELLER). @@ -16899,6 +17018,7 @@ void clif_buyingstore_delete_item(struct map_session_data* sd, short index, unsi /// ? = nothing void clif_buyingstore_trade_failed_seller(struct map_session_data* sd, short result, unsigned short nameid) { +#if PACKETVER >= 20100420 int fd; nullpo_retv(sd); @@ -16908,6 +17028,7 @@ void clif_buyingstore_trade_failed_seller(struct map_session_data* sd, short res WFIFOW(fd,2) = result; WFIFOW(fd,4) = nameid; WFIFOSET(fd,packet_len(0x824)); +#endif } void clif_parse_SearchStoreInfo(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -17027,6 +17148,7 @@ void clif_search_store_info_ack(struct map_session_data* sd) /// 4 = "No sale (purchase) information available." (0x705) void clif_search_store_info_failed(struct map_session_data* sd, unsigned char reason) { +#if PACKETVER >= 20100601 int fd; nullpo_retv(sd); @@ -17035,6 +17157,7 @@ void clif_search_store_info_failed(struct map_session_data* sd, unsigned char re WFIFOW(fd,0) = 0x837; WFIFOB(fd,2) = reason; WFIFOSET(fd,packet_len(0x837)); +#endif } void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -17052,6 +17175,7 @@ void clif_parse_SearchStoreInfoNextPage(int fd, struct map_session_data* sd) /// 1 = Search Stores (Cash), asks for confirmation, when clicking a store void clif_open_search_store_info(struct map_session_data* sd) { +#if PACKETVER >= 20100608 int fd; nullpo_retv(sd); @@ -17063,6 +17187,7 @@ void clif_open_search_store_info(struct map_session_data* sd) WFIFOB(fd,4) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX); #endif WFIFOSET(fd,packet_len(0x83a)); +#endif } void clif_parse_CloseSearchStoreInfo(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -17093,6 +17218,7 @@ void clif_parse_SearchStoreInfoListItemClick(int fd, struct map_session_data* sd /// 083d <xPos>.W <yPos>.W void clif_search_store_info_click_ack(struct map_session_data* sd, short x, short y) { +#if PACKETVER >= 20100608 int fd; nullpo_retv(sd); @@ -17102,6 +17228,7 @@ void clif_search_store_info_click_ack(struct map_session_data* sd, short x, shor WFIFOW(fd,2) = x; WFIFOW(fd,4) = y; WFIFOSET(fd,packet_len(0x83d)); +#endif } /// Parse function for packet debugging. @@ -17370,6 +17497,7 @@ void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) { *------------------------------------------*/ void clif_charm(struct map_session_data *sd) { +#if PACKETVER >= 20110809 unsigned char buf[10]; nullpo_retv(sd); @@ -17379,6 +17507,7 @@ void clif_charm(struct map_session_data *sd) WBUFW(buf,6) = sd->charm_type; WBUFW(buf,8) = sd->charm_count; clif->send(buf,packet_len(0x08cf),&sd->bl,AREA); +#endif } void clif_parse_MoveItem(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -17480,6 +17609,7 @@ void clif_cashshop_db(void) { /// Items that are in favorite tab of inventory (ZC_ITEM_FAVORITE). /// 0900 <index>.W <favorite>.B void clif_favorite_item(struct map_session_data* sd, unsigned short index) { +#if PACKETVER >= 20120410 int fd; nullpo_retv(sd); @@ -17489,9 +17619,11 @@ void clif_favorite_item(struct map_session_data* sd, unsigned short index) { WFIFOW(fd,2) = index+2; WFIFOB(fd,4) = (sd->status.inventory[index].favorite == 1) ? 0 : 1; WFIFOSET(fd,packet_len(0x908)); +#endif } void clif_snap( struct block_list *bl, short x, short y ) { +#if PACKETVER >= 20110809 unsigned char buf[10]; nullpo_retv(bl); @@ -17501,9 +17633,12 @@ void clif_snap( struct block_list *bl, short x, short y ) { WBUFW(buf,8) = y; clif->send(buf,packet_len(0x8d2),bl,AREA); +#endif } -void clif_monster_hp_bar( struct mob_data* md, struct map_session_data *sd ) { +void clif_monster_hp_bar(struct mob_data *md, struct map_session_data *sd) +{ +#if PACKETVER >= 20120228 struct packet_monster_hp p; nullpo_retv(md); @@ -17514,6 +17649,7 @@ void clif_monster_hp_bar( struct mob_data* md, struct map_session_data *sd ) { p.MaxHP = md->status.max_hp; clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif } /* [Ind/Hercules] placeholder for unsupported incoming packets (avoids server disconnecting client) */ @@ -17542,7 +17678,9 @@ void clif_parse_CashShopClose(int fd, struct map_session_data *sd) { } void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); -void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) { +void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) +{ +#if PACKETVER >= 20110614 int i, j = 0; for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) { @@ -17562,6 +17700,7 @@ void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) { WFIFOSET(fd, 8 + ( clif->cs.item_count[i] * 6 )); } +#endif } void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -17655,7 +17794,9 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) { void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /* [Ind/Hercules] */ -void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) { +void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) +{ +#if PACKETVER >= 20110222 short tab = RFIFOW(fd, 2); int j; @@ -17674,9 +17815,12 @@ void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) { } WFIFOSET(fd, 10 + ( clif->cs.item_count[tab] * 6 )); +#endif } + /* [Ind/Hercules] */ -void clif_maptypeproperty2(struct block_list *bl,enum send_target t) { +void clif_maptypeproperty2(struct block_list *bl,enum send_target t) +{ #if PACKETVER >= 20121010 struct packet_maptypeproperty2 p; struct map_session_data *sd = NULL; @@ -17729,6 +17873,7 @@ void clif_partytickack(struct map_session_data* sd, bool flag) { void clif_ShowScript(struct block_list *bl, const char *message) { +#if PACKETVER >= 20110111 char buf[256]; int len; nullpo_retv(bl); @@ -17748,6 +17893,7 @@ void clif_ShowScript(struct block_list *bl, const char *message) WBUFL(buf,4) = bl->id; safestrncpy(WBUFP(buf,8),message,len); clif->send(buf,WBUFW(buf,2),bl,AREA); +#endif } void clif_status_change_end(struct block_list *bl, int tid, enum send_target target, int type) { @@ -17904,14 +18050,17 @@ void clif_bgqueue_battlebegins(struct map_session_data *sd, unsigned char arena_ clif->send(&p,sizeof(p), &sd->bl, target); } -void clif_scriptclear(struct map_session_data *sd, int npcid) { +void clif_scriptclear(struct map_session_data *sd, int npcid) +{ +#if PACKETVER >= 20110928 struct packet_script_clear p; nullpo_retv(sd); p.PacketType = script_clearType; p.NpcID = npcid; - clif->send(&p,sizeof(p), &sd->bl, SELF); + clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif } /* Made Possible Thanks to Yommy! */ @@ -18033,7 +18182,9 @@ void clif_parse_BankWithdraw(int fd, struct map_session_data *sd) } void clif_parse_BankCheck(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); -void clif_parse_BankCheck(int fd, struct map_session_data* sd) { +void clif_parse_BankCheck(int fd, struct map_session_data* sd) +{ +#if PACKETVER >= 20130313 struct packet_banking_check p; if (!battle_config.feature_banking) { @@ -18046,6 +18197,7 @@ void clif_parse_BankCheck(int fd, struct map_session_data* sd) { p.Reason = (short)0; clif->send(&p,sizeof(p), &sd->bl, SELF); +#endif } void clif_parse_BankOpen(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -18058,7 +18210,9 @@ void clif_parse_BankClose(int fd, struct map_session_data* sd) { return; } -void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason) { +void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason) +{ +#if PACKETVER >= 20130313 struct packet_banking_deposit_ack p; nullpo_retv(sd); @@ -18068,9 +18222,12 @@ void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK r p.Reason = (short)reason; clif->send(&p,sizeof(p), &sd->bl, SELF); +#endif } -void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason) { +void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason) +{ +#if PACKETVER >= 20130313 struct packet_banking_withdraw_ack p; nullpo_retv(sd); @@ -18080,6 +18237,7 @@ void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK p.Reason = (short)reason; clif->send(&p,sizeof(p), &sd->bl, SELF); +#endif } /* TODO: official response packet (tried 0x8cb/0x97b but the display was quite screwed up.) */ @@ -18336,6 +18494,7 @@ void clif_PartyLeaderChanged(struct map_session_data *sd, int prev_leader_aid, i void clif_parse_RouletteOpen(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); /* Roulette System [Yommy/Hercules] */ void clif_parse_RouletteOpen(int fd, struct map_session_data* sd) { +#if PACKETVER >= 20140612 struct packet_roulette_open_ack p; if( !battle_config.feature_roulette ) { @@ -18354,10 +18513,13 @@ void clif_parse_RouletteOpen(int fd, struct map_session_data* sd) { p.SilverPoint = pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")); clif->send(&p,sizeof(p), &sd->bl, SELF); +#endif } void clif_parse_RouletteInfo(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); -void clif_parse_RouletteInfo(int fd, struct map_session_data* sd) { +void clif_parse_RouletteInfo(int fd, struct map_session_data* sd) +{ +#if PACKETVER >= 20140612 struct packet_roulette_info_ack p; unsigned short i, j, count = 0; @@ -18380,7 +18542,7 @@ void clif_parse_RouletteInfo(int fd, struct map_session_data* sd) { } } clif->send(&p,sizeof(p), &sd->bl, SELF); - return; +#endif } void clif_parse_RouletteClose(int fd, struct map_session_data* sd) __attribute__((nonnull (2))); @@ -18454,7 +18616,9 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) __attribut /** * Request to cash in! **/ -void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) { +void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) +{ +#if PACKETVER >= 20140612 struct packet_roulette_itemrecv_ack p; if( !battle_config.feature_roulette ) { @@ -18497,7 +18661,7 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) { p.Result = RECV_ITEM_FAILED; clif->send(&p,sizeof(p), &sd->bl, SELF); - return; +#endif } bool clif_parse_roulette_db(void) { @@ -18592,7 +18756,9 @@ bool clif_parse_roulette_db(void) { /** * **/ -void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID) { +void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID) +{ +#if PACKETVER >= 20140612 struct packet_roulette_generate_ack p; nullpo_retv(sd); @@ -18606,6 +18772,7 @@ void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char resul p.RemainSilver = pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")); clif->send(&p,sizeof(p), &sd->bl, SELF); +#endif } /** @@ -18613,6 +18780,7 @@ void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char resul */ void clif_openmergeitem(int fd, struct map_session_data *sd) { +#if PACKETVER > 20120228 int i = 0, n = 0, j = 0; struct merge_item merge_items[MAX_INVENTORY]; struct merge_item *merge_items_[MAX_INVENTORY] = {0}; @@ -18655,6 +18823,7 @@ void clif_openmergeitem(int fd, struct map_session_data *sd) for ( i = 0; i < j; i++ ) WFIFOW(fd,i*2+4) = merge_items_[i]->position; WFIFOSET(fd,2*j+4); +#endif } int clif_comparemergeitem(const void *a, const void *b) @@ -18671,6 +18840,7 @@ int clif_comparemergeitem(const void *a, const void *b) void clif_ackmergeitems(int fd, struct map_session_data *sd) { +#if PACKETVER > 20120228 int i = 0, n = 0, length = 0, count = 0; int16 nameid = 0, indexes[MAX_INVENTORY] = {0}, amounts[MAX_INVENTORY] = {0}; struct item item_data; @@ -18750,6 +18920,7 @@ void clif_ackmergeitems(int fd, struct map_session_data *sd) WFIFOW(fd,4) = count; WFIFOB(fd,6) = MERGEITEM_SUCCESS; WFIFOSET(fd,7); +#endif } void clif_cancelmergeitem (int fd, struct map_session_data *sd) @@ -18760,6 +18931,7 @@ void clif_cancelmergeitem (int fd, struct map_session_data *sd) void clif_dressroom_open(struct map_session_data *sd, int view) { +#if PACKETVER >= 20150513 int fd; nullpo_retv(sd); @@ -18769,6 +18941,7 @@ void clif_dressroom_open(struct map_session_data *sd, int view) WFIFOW(fd,0)=0xa02; WFIFOW(fd,2)=view; WFIFOSET(fd,packet_len(0xa02)); +#endif } /// Request to select cart's visual look for new cart design (ZC_SELECTCART). @@ -18793,6 +18966,48 @@ void clif_selectcart(struct map_session_data *sd) #endif } +/// Starts navigation to the given target on client side +void clif_navigate_to(struct map_session_data *sd, const char* mapname, uint16 x, uint16 y, uint8 flag, bool hideWindow, uint16 mob_id) +{ +// probably this packet with other fields present in older packet versions +#if PACKETVER >= 20120307 + int fd; + + nullpo_retv(sd); + nullpo_retv(mapname); + fd = sd->fd; + WFIFOHEAD(fd, packet_len(0x8e2)); + WFIFOW(fd, 0) = 0x8e2; + + // How detailed will our navigation be? + if (mob_id > 0) { + x = 0; + y = 0; + WFIFOB(fd, 2) = 3; // monster with destination field + } else if (x > 0 && y > 0) { + WFIFOB(fd, 2) = 0; // with coordinates + } else { + x = 0; + y = 0; + WFIFOB(fd, 2) = 1; // without coordinates(will fail if you are already on the map) + } + + // Which services can be used for transportation? + WFIFOB(fd, 3) = flag; + // If this flag is set, the navigation window will not be opened up + WFIFOB(fd, 4) = hideWindow; + // Target map + safestrncpy((char*)WFIFOP(fd, 5), mapname, MAP_NAME_LENGTH_EXT); + // Target x + WFIFOW(fd, 21) = x; + // Target y + WFIFOW(fd, 23) = y; + // Target monster ID + WFIFOW(fd, 25) = mob_id; + WFIFOSET(fd, packet_len(0x8e2)); +#endif +} + /** * Returns the name of the given bl, in a client-friendly format. * @@ -19636,6 +19851,7 @@ void clif_defaults(void) { clif->selectcart = clif_selectcart; /* */ clif->isdisguised = clif_isdisguised; + clif->navigate_to = clif_navigate_to; clif->bl_type = clif_bl_type; /*------------------------ |