diff --git a/src/char/char_mapif.cpp b/src/char/char_mapif.cpp index 7e9496237e..d389f0c549 100644 --- a/src/char/char_mapif.cpp +++ b/src/char/char_mapif.cpp @@ -279,7 +279,7 @@ int chmapif_parse_askscdata(int fd){ int aid, cid; aid = RFIFOL(fd,2); cid = RFIFOL(fd,6); - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, tick_total, val1, val2, val3, val4 from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4, tick_total from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", schema_config.scdata_db, aid, cid) ) { Sql_ShowDebug(sql_handle); @@ -299,11 +299,11 @@ int chmapif_parse_askscdata(int fd){ { Sql_GetData(sql_handle, 0, &data, NULL); scdata.type = atoi(data); Sql_GetData(sql_handle, 1, &data, NULL); scdata.tick = strtoll( data, nullptr, 10 ); - Sql_GetData(sql_handle, 2, &data, NULL); scdata.tick_total = strtoll(data, nullptr, 10); - Sql_GetData(sql_handle, 3, &data, NULL); scdata.val1 = atoi(data); - Sql_GetData(sql_handle, 4, &data, NULL); scdata.val2 = atoi(data); - Sql_GetData(sql_handle, 5, &data, NULL); scdata.val3 = atoi(data); - Sql_GetData(sql_handle, 6, &data, NULL); scdata.val4 = atoi(data); + Sql_GetData(sql_handle, 2, &data, NULL); scdata.val1 = atoi(data); + Sql_GetData(sql_handle, 3, &data, NULL); scdata.val2 = atoi(data); + Sql_GetData(sql_handle, 4, &data, NULL); scdata.val3 = atoi(data); + Sql_GetData(sql_handle, 5, &data, NULL); scdata.val4 = atoi(data); + Sql_GetData(sql_handle, 6, &data, NULL); scdata.tick_total = strtoll(data, nullptr, 10); memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &scdata, sizeof(struct status_change_data)); } if (count >= 50) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 1a6e67be65..6e13387b6c 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -6127,6 +6127,7 @@ void clif_cooking_list( struct map_session_data *sd, int trigger, uint16 skill_i /// 043f .W .L .B .L { .L }*3 (ZC_MSG_STATE_CHANGE2) [used exclusively for starting statuses on pcs] /// 0983 .W .L .B .L .L { .L }*3 (ZC_MSG_STATE_CHANGE3) (PACKETVER >= 20120618) /// @param bl: Sends packet to clients around this object +/// @param id: ID of object that has this effect /// @param type: Status icon (see efst_types) /// @param flag: 1:Active, 0:Inactive /// @param tick_total: Total duration in ms @@ -6134,7 +6135,7 @@ void clif_cooking_list( struct map_session_data *sd, int trigger, uint16 skill_i /// @param val1: Value 1 /// @param val2: Value 2 /// @param val3: Value 3 -void clif_status_change_sub(struct block_list *bl, int type, int flag, t_tick tick_total, t_tick tick, int val1, int val2, int val3) +void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, t_tick tick_total, t_tick tick, int val1, int val2, int val3) { nullpo_retv(bl); @@ -6164,20 +6165,18 @@ void clif_status_change_sub(struct block_list *bl, int type, int flag, t_tick ti tick = 9999; // this is indeed what official servers do break; } + } - p.PacketType = status_changeType; - } else - p.PacketType = sc_notickType; + p.PacketType = status_changeType; p.index = type; - p.AID = bl->id; + p.AID = id; p.state = (uint8)flag; -#if PACKETVER >= 20120618 - if (battle_config.display_status_timers > 0) - p.Total = client_tick(tick_total); -#endif #if PACKETVER >= 20090121 if (battle_config.display_status_timers > 0) { +#if PACKETVER >= 20120618 + p.Total = client_tick(tick_total); +#endif p.Left = client_tick(tick); p.val1 = val1; p.val2 = val2; @@ -6185,7 +6184,7 @@ void clif_status_change_sub(struct block_list *bl, int type, int flag, t_tick ti } #endif - clif_send(&p, sizeof(p), bl, (sd && sd->status.option & OPTION_INVISIBLE) ? SELF : AREA); + clif_send(&p, sizeof(p), bl, pc_isinvisible(sd) ? SELF : AREA); } /* Sends status effect to clients around the bl @@ -6198,7 +6197,7 @@ void clif_status_change_sub(struct block_list *bl, int type, int flag, t_tick ti * @param val3: Value 3 */ void clif_status_change(struct block_list *bl, int type, int flag, t_tick tick_total, int val1, int val2, int val3) { - clif_status_change_sub(bl, type, flag, tick_total, tick_total, val1, val2, val3); + clif_status_change_sub(bl, bl->id, type, flag, tick_total, tick_total, val1, val2, val3); } /** @@ -6208,13 +6207,12 @@ void clif_status_change(struct block_list *bl, int type, int flag, t_tick tick_t * @param target: Client send type */ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, enum send_target target) { - unsigned char i; + nullpo_retv(bl); + struct sc_display_entry **sc_display; unsigned char sc_display_count; bool spheres_sent; - nullpo_retv(bl); - switch( bl->type ){ case BL_PC: { struct map_session_data* sd = (struct map_session_data*)bl; @@ -6236,26 +6234,29 @@ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, return; } - for (i = 0; i < sc_display_count; i++) { + for (unsigned char i = 0; i < sc_display_count; i++) { enum sc_type type = sc_display[i]->type; struct status_change *sc = status_get_sc(bl); - const struct TimerData *td = (sc && sc->data[type] ? get_timer(sc->data[type]->timer) : NULL); - t_tick tick = 0; + const TimerData *td_total = (sc && sc->data[type] ? get_timer(sc->data[type]->tick_total) : nullptr); + const TimerData *td = (sc && sc->data[type] ? get_timer(sc->data[type]->timer) : nullptr); + t_tick tick_total = 0, tick = 0, cur_tick = gettick(); - if (td) - tick = DIFF_TICK(td->tick, gettick()); + if (td_total != nullptr) + tick_total = DIFF_TICK(td_total->tick, cur_tick); + if (td != nullptr) + tick = DIFF_TICK(td->tick, cur_tick); if( spheres_sent && type >= SC_SPHERE_1 && type <= SC_SPHERE_5 ){ #if PACKETVER > 20120418 - clif_efst_status_change(tbl, bl->id, AREA_WOS, StatusIconChangeTable[type], tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3); + clif_efst_status_change(tbl, bl->id, AREA_WOS, StatusIconChangeTable[type], tick_total, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3); #else - clif_status_change_sub(tbl, StatusIconChangeTable[type], 1, tick, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3, AREA_WOS); + clif_status_change_sub(tbl, bl->id, StatusIconChangeTable[type], 1, tick, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3, AREA_WOS); #endif }else{ #if PACKETVER > 20120418 - clif_efst_status_change(tbl, bl->id, target, StatusIconChangeTable[type], tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3); + clif_efst_status_change(tbl, bl->id, target, StatusIconChangeTable[type], tick_total, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3); #else - clif_status_change_sub(tbl, StatusIconChangeTable[type], 1, tick, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3, target); + clif_status_change_sub(tbl, bl->id, StatusIconChangeTable[type], 1, tick, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3, target); #endif } } @@ -6264,38 +6265,30 @@ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, /// Notifies the client when a player enters the screen with an active EFST. /// 08ff .L .W .L { .L }*3 (ZC_EFST_SET_ENTER) (PACKETVER >= 20111108) /// 0984 .L .W .L .L { .L }*3 (ZC_EFST_SET_ENTER2) (PACKETVER >= 20120618) -void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, t_tick tick, int val1, int val2, int val3) { +void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, t_tick tick_total, t_tick tick, int val1, int val2, int val3) { #if PACKETVER >= 20111108 - unsigned char buf[32]; -#if PACKETVER >= 20120618 - const int cmd = 0x984; -#elif PACKETVER >= 20111108 - const int cmd = 0x8ff; -#endif - int offset = 0; + nullpo_retv(bl); if (type == EFST_BLANK) return; - nullpo_retv(bl); - - if (tick <= 0) + if (tick < 0) tick = 9999; - WBUFW(buf,offset + 0) = cmd; - WBUFL(buf,offset + 2) = tid; - WBUFW(buf,offset + 6) = type; -#if PACKETVER >= 20111108 - WBUFL(buf,offset + 8) = client_tick(tick); // Set remaining status duration [exneval] -#if PACKETVER >= 20120618 - WBUFL(buf,offset + 12) = client_tick(tick); - offset += 4; + PACKET_EFST_SET_ENTER p = { 0 }; + + p.PacketType = HEADER_ZC_EFST_SET_ENTER; + p.GID = tid; + p.type = type; + p.remaining = client_tick(tick); +#ifdef PACKETVER >= 20120618 + p.total = client_tick(tick_total); #endif - WBUFL(buf,offset + 12) = val1; - WBUFL(buf,offset + 16) = val2; - WBUFL(buf,offset + 20) = val3; -#endif - clif_send(buf,packet_len(cmd),bl,target); + p.val1 = val1; + p.val2 = val2; + p.val3 = val3; + + clif_send(&p, sizeof(p), bl, target); #endif } diff --git a/src/map/clif.hpp b/src/map/clif.hpp index eb99c6ca3e..fce1d2bf49 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -729,8 +729,8 @@ void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_targe #define clif_status_load(bl, type, flag) clif_status_change((bl), (type), (flag), 0, 0, 0, 0) void clif_status_change(struct block_list *bl, int type, int flag, t_tick tick_total, int val1, int val2, int val3); -void clif_status_change_sub(struct block_list *bl, int type, int flag, t_tick tick_total, t_tick tick, int val1, int val2, int val3); -void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, t_tick tick, int val1, int val2, int val3); +void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, t_tick tick_total, t_tick tick, int val1, int val2, int val3); +void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, t_tick tick_total, t_tick tick, int val1, int val2, int val3); void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, enum send_target target); void clif_wis_message(struct map_session_data* sd, const char* nick, const char* mes, int mes_len, int gmlvl); diff --git a/src/map/packets.hpp b/src/map/packets.hpp index f101e04408..a51e6d94f3 100644 --- a/src/map/packets.hpp +++ b/src/map/packets.hpp @@ -159,6 +159,19 @@ struct PACKET_ZC_ACK_GUILDSTORAGE_LOG{ struct PACKET_ZC_ACK_GUILDSTORAGE_LOG_sub items[]; }; +struct PACKET_EFST_SET_ENTER { + int16 PacketType; + uint32 GID; + uint16 type; + uint32 remaining; +#if PACKETVER >= 20120618 + uint32 total; +#endif + int32 val1; + int32 val2; + int32 val3; +}; + // 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 ) @@ -177,6 +190,11 @@ DEFINE_PACKET_HEADER(ZC_NOTIFY_BARGAIN_SALE_CLOSE, 0x9b3) DEFINE_PACKET_HEADER(ZC_ACK_COUNT_BARGAIN_SALE_ITEM, 0x9c4) DEFINE_PACKET_HEADER(ZC_ACK_GUILDSTORAGE_LOG, 0x9da) DEFINE_PACKET_HEADER(CZ_REQ_APPLY_BARGAIN_SALE_ITEM2, 0xa3d) +#if PACKETVER >= 20120618 +DEFINE_PACKET_HEADER(ZC_EFST_SET_ENTER, 0x984) +#elif PACKETVER >= 20111108 +DEFINE_PACKET_HEADER(ZC_EFST_SET_ENTER, 0x8ff) +#endif 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 ) ); diff --git a/src/map/status.cpp b/src/map/status.cpp index f29398dbef..8d2235537b 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -12617,10 +12617,12 @@ int status_change_start_sub(struct block_list* src, struct block_list* bl,enum s calc_flag&=~SCB_BODY; }*/ - t_tick tick = duration; + t_tick tick; if (!(flag & SCSTART_LOADED)) tick = tick_total; // When starting a new SC (not loading), its remaining duration is the same as the total + else + tick = duration; if (!(flag&SCSTART_NOICON) && !(flag&SCSTART_LOADED && StatusDisplayType[type])) { int status_icon = StatusIconChangeTable[type]; @@ -12629,7 +12631,7 @@ int status_change_start_sub(struct block_list* src, struct block_list* bl,enum s status_icon = EFST_ATTACK_PROPERTY_NOTHING + val1; // Assign status icon for older clients #endif - clif_status_change_sub(bl, status_icon, 1, tick_total, tick, (val_flag & 1) ? val1 : 1, (val_flag & 2) ? val2 : 0, (val_flag & 4) ? val3 : 0); + clif_status_change_sub(bl, bl->id, status_icon, 1, tick_total, tick, (val_flag & 1) ? val1 : 1, (val_flag & 2) ? val2 : 0, (val_flag & 4) ? val3 : 0); } // Used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.