diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 9422cd5e2e..ce71b07328 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -1490,19 +1490,6 @@ void clif_class_change_target(struct block_list *bl,int class_,int type, enum se } } - -/// Notifies the client of an object's spirits. -/// 01d0 .L .W (ZC_SPIRITS) -/// 01e1 .L .W (ZC_SPIRITS2) -static void clif_spiritball_single(int fd, struct map_session_data *sd) -{ - WFIFOHEAD(fd, packet_len(0x1e1)); - WFIFOW(fd,0)=0x1e1; - WFIFOL(fd,2)=sd->bl.id; - WFIFOW(fd,6)=sd->spiritball; - WFIFOSET(fd, packet_len(0x1e1)); -} - /// Notifies the client of an object's Millenium Shields. static void clif_millenniumshield_single(int fd, map_session_data *sd) { @@ -1532,29 +1519,6 @@ static void clif_spiritcharm_single(int fd, struct map_session_data *sd) WFIFOSET(fd, packet_len(0x08cf)); } - -/// Notifies the client of an object's souls. -/// Note: Spirit spheres and Soul spheres work on -/// seprate systems officially, but both send out -/// the same packet which leads to confusion on how -/// much soul energy a Soul Reaper acturally has -/// should the player also have spirit spheres. -/// They will likely create a new packet for this soon -/// to seprate the animations for spirit and soul spheres. -/// For now well use this and replace it later when possible. [Rytech] -/// -/// 01d0 .L .W (ZC_SPIRITS) -/// 01e1 .L .W (ZC_SPIRITS2) -static void clif_soulball_single(int fd, struct map_session_data *sd) -{ - WFIFOHEAD(fd, packet_len(0x1d0)); - WFIFOW(fd,0)=0x1d0; - WFIFOL(fd,2)=sd->bl.id; - WFIFOW(fd,6)=sd->soulball; - WFIFOSET(fd, packet_len(0x1d0)); -} - - /*========================================== * Run when player changes map / refreshes * Tells its client to display all weather settings being used by this map @@ -4705,29 +4669,25 @@ void clif_storageclose(struct map_session_data* sd) } -/// Notifies clients in an area of an object's souls. -/// Note: Spirit spheres and Soul spheres work on -/// seprate systems officially, but both send out -/// the same packet which leads to confusion on how -/// much soul energy a Soul Reaper actually has -/// should the player also have spirit spheres. -/// They will likely create a new packet for this soon -/// to seprate the animations for spirit and soul spheres. -/// For now we'll use this and replace it later when possible. [Rytech] -/// +/// Notifies clients in an area of a player's souls. /// 01d0 .L .W (ZC_SPIRITS) /// 01e1 .L .W (ZC_SPIRITS2) -void clif_soulball(struct map_session_data *sd) -{ - unsigned char buf[8]; +/// 0b73 .L .W +void clif_soulball( struct map_session_data *sd, struct block_list* target, enum send_target send_target ){ +#if PACKETVER_MAIN_NUM >= 20200916 || PACKETVER_RE_NUM >= 20200724 + struct PACKET_ZC_UNCONFIRMED_SPIRITS3 p = {}; - nullpo_retv(sd); + p.packetType = HEADER_ZC_UNCONFIRMED_SPIRITS3; +#else + struct PACKET_ZC_SPIRITS p = {}; - WBUFW(buf,0)=0x1d0; - WBUFL(buf,2)=sd->bl.id; - WBUFW(buf,6)=sd->soulball; - clif_send(buf,packet_len(0x1d0),&sd->bl,AREA); - return; + p.packetType = HEADER_ZC_SPIRITS; +#endif + + p.GID = sd->bl.id; + p.amount = sd->soulball; + + clif_send( &p, sizeof( p ), target == nullptr ? &sd->bl : target, send_target ); } @@ -4749,13 +4709,13 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d clif_buyingstore_entry_single(sd, dstsd); if(dstsd->spiritball > 0) - clif_spiritball_single(sd->fd, dstsd); + clif_spiritball( &dstsd->bl, &sd->bl, SELF ); if (dstsd->sc.data[SC_MILLENNIUMSHIELD]) clif_millenniumshield_single(sd->fd, dstsd); if (dstsd->spiritcharm_type != CHARM_TYPE_NONE && dstsd->spiritcharm > 0) clif_spiritcharm_single(sd->fd, dstsd); if (dstsd->soulball > 0) - clif_soulball_single(sd->fd, dstsd); + clif_soulball( dstsd, &sd->bl, SELF ); if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting. (sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround pc_has_permission(sd, PC_PERM_VIEW_HPMETER) @@ -8329,27 +8289,27 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd) clif_send(buf, packet_len(0x1cf), src, AREA); } -/*========================================== - * Server tells clients nearby 'sd' (and himself) to display 'sd->spiritball' number of spiritballs on 'sd' - * Notifies clients in an area of an object's spirits. - * 01d0 .L .W (ZC_SPIRITS) - * 01e1 .L .W (ZC_SPIRITS2) - *------------------------------------------*/ -void clif_spiritball(struct block_list *bl) { - unsigned char buf[16]; - TBL_PC *sd = BL_CAST(BL_PC,bl); - TBL_HOM *hd = BL_CAST(BL_HOM,bl); +/// Notifies the client of an object's spirits. +/// 01d0 .L .W (ZC_SPIRITS) +/// 01e1 .L .W (ZC_SPIRITS2) +void clif_spiritball( struct block_list *bl, struct block_list* target, enum send_target send_target ){ + nullpo_retv( bl ); - nullpo_retv(bl); + struct PACKET_ZC_SPIRITS p = {}; - WBUFW(buf, 0) = 0x1d0; - WBUFL(buf, 2) = bl->id; - WBUFW(buf, 6) = 0; //init to 0 - switch(bl->type){ - case BL_PC: WBUFW(buf, 6) = sd->spiritball; break; - case BL_HOM: WBUFW(buf, 6) = hd->homunculus.spiritball; break; - } - clif_send(buf, packet_len(0x1d0), bl, AREA); + p.packetType = HEADER_ZC_SPIRITS; + p.GID = bl->id; + + switch( bl->type ){ + case BL_PC: + p.amount = ( (struct map_session_data*)bl )->spiritball; + break; + case BL_HOM: + p.amount = ( (struct homun_data*)bl )->homunculus.spiritball; + break; + } + + clif_send( &p, sizeof( p ), target == nullptr ? bl : target, send_target ); } @@ -9677,13 +9637,13 @@ void clif_refresh(struct map_session_data *sd) clif_updatestatus(sd,SP_DEX); clif_updatestatus(sd,SP_LUK); if (sd->spiritball) - clif_spiritball_single(sd->fd, sd); + clif_spiritball( &sd->bl, &sd->bl, SELF ); if (sd->sc.data[SC_MILLENNIUMSHIELD]) clif_millenniumshield_single(sd->fd, sd); if (sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0) clif_spiritcharm_single(sd->fd, sd); if (sd->soulball) - clif_soulball_single(sd->fd, sd); + clif_soulball( sd, &sd->bl, SELF ); if (sd->vd.cloth_color) clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF); if (sd->vd.body_style) diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 816e2bd88e..c8c5daa19e 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -721,8 +721,8 @@ void clif_skillunit_update(struct block_list* bl); void clif_autospell(struct map_session_data *sd,uint16 skill_lv); void clif_devotion(struct block_list *src, struct map_session_data *tsd); -void clif_spiritball(struct block_list *bl); -void clif_soulball(struct map_session_data *sd); +void clif_spiritball( struct block_list *bl, struct block_list* target = nullptr, enum send_target send_target = AREA ); +void clif_soulball( struct map_session_data *sd, struct block_list* target = nullptr, enum send_target send_target = AREA ); void clif_combo_delay(struct block_list *bl,t_tick wait); void clif_bladestop(struct block_list *src, int dst_id, int active); void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_target target); diff --git a/src/map/packets.hpp b/src/map/packets.hpp index d291277818..bd338ed43e 100644 --- a/src/map/packets.hpp +++ b/src/map/packets.hpp @@ -195,6 +195,18 @@ struct PACKET_ZC_BROADCAST2{ char message[]; } __attribute__((packed)); +struct PACKET_ZC_SPIRITS{ + int16 packetType; + uint32 GID; + uint16 amount; +} __attribute__((packed)); + +struct PACKET_ZC_UNCONFIRMED_SPIRITS3{ + int16 packetType; + uint32 GID; + uint16 amount; +} __attribute__((packed)); + // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 ) #pragma pack( pop ) @@ -209,6 +221,7 @@ DEFINE_PACKET_HEADER(CZ_REQMAKINGITEM, 0x18e) DEFINE_PACKET_HEADER(ZC_ACK_REQMAKINGITEM, 0x18f) DEFINE_PACKET_HEADER(CZ_REQ_MAKINGARROW, 0x1ae) DEFINE_PACKET_HEADER(ZC_BROADCAST2, 0x1c3) +DEFINE_PACKET_HEADER(ZC_SPIRITS, 0x1d0) DEFINE_PACKET_HEADER(CZ_REQ_ITEMREPAIR, 0x1fd) #if PACKETVER >= 20190724 DEFINE_PACKET_HEADER(ZC_CHANGE_GUILD, 0x0b47) @@ -242,6 +255,7 @@ DEFINE_PACKET_HEADER(ZC_ACK_GUILDSTORAGE_LOG, 0x9da) DEFINE_PACKET_HEADER(CZ_NPC_MARKET_PURCHASE, 0x9d6) DEFINE_PACKET_HEADER(CZ_REQ_APPLY_BARGAIN_SALE_ITEM2, 0xa3d) DEFINE_PACKET_HEADER(CZ_GUILD_EMBLEM_CHANGE2, 0x0b46) +DEFINE_PACKET_HEADER(ZC_UNCONFIRMED_SPIRITS3, 0xb73) const int16 MAX_INVENTORY_ITEM_PACKET_NORMAL = ( ( INT16_MAX - ( sizeof( struct packet_itemlist_normal ) - ( sizeof( struct NORMALITEM_INFO ) * MAX_ITEMLIST) ) ) / sizeof( struct NORMALITEM_INFO ) ); const int16 MAX_INVENTORY_ITEM_PACKET_EQUIP = ( ( INT16_MAX - ( sizeof( struct packet_itemlist_equip ) - ( sizeof( struct EQUIPITEM_INFO ) * MAX_ITEMLIST ) ) ) / sizeof( struct EQUIPITEM_INFO ) );