From 6e9c67cb82b19e80d5905248f8eafbe435cc7ab9 Mon Sep 17 00:00:00 2001 From: aleos89 Date: Sun, 22 May 2016 09:22:20 -0400 Subject: [PATCH] Fixed active_transform not getting removed (fixes #1282) * Corrected active_transform and transform stacking display issues. * Implemented ZC_EFST_SET_ENTER and ZC_EFST_SET_ENTER2. - Adjusted the sc_display to make use of this. Thanks to @exneval for the packet info! --- src/map/clif.c | 116 +++++++++++++++++++++++++---------------------- src/map/clif.h | 3 +- src/map/pc.c | 2 +- src/map/status.c | 3 ++ 4 files changed, 69 insertions(+), 55 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 50a5b00443..ff2cc5e3ea 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1403,7 +1403,6 @@ int clif_spawn(struct block_list *bl) { unsigned char buf[128]; struct view_data *vd; - struct status_change *sc = status_get_sc(bl); int len; vd = status_get_viewdata(bl); @@ -1431,7 +1430,7 @@ int clif_spawn(struct block_list *bl) case BL_PC: { TBL_PC *sd = ((TBL_PC*)bl); - int i; + if (sd->spiritball > 0) clif_spiritball(&sd->bl); if(sd->state.size==SZ_BIG) // tiny/big players [Valaris] @@ -1442,14 +1441,9 @@ int clif_spawn(struct block_list *bl) clif_sendbgemblem_area(sd); if (sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0) clif_spiritcharm(sd); - for (i = 0; i < sd->sc_display_count; i++) { - if (sc && (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE|OPTION_CHASEWALK))) - clif_status_change2(&sd->bl,sd->bl.id,AREA,SI_BLANK,0,0,0); - else - clif_status_change2(&sd->bl,sd->bl.id,AREA,StatusIconChangeTable[sd->sc_display[i]->type],sd->sc_display[i]->val1,sd->sc_display[i]->val2,sd->sc_display[i]->val3); - } if (sd->status.robe) clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA); + clif_efst_status_change_sub(sd, bl, AREA); } break; case BL_MOB: @@ -4493,12 +4487,6 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d clif_spiritball_single(sd->fd, dstsd); if (dstsd->spiritcharm_type != CHARM_TYPE_NONE && dstsd->spiritcharm > 0) clif_spiritcharm_single(sd->fd, dstsd); - for( i = 0; i < dstsd->sc_display_count; i++ ) { - if (dstsd->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE|OPTION_CHASEWALK)) - clif_status_change2(&sd->bl, dstsd->bl.id, SELF, SI_BLANK, 0, 0, 0); - else - clif_status_change2(&sd->bl, dstsd->bl.id, SELF, StatusIconChangeTable[dstsd->sc_display[i]->type], dstsd->sc_display[i]->val1, dstsd->sc_display[i]->val2, dstsd->sc_display[i]->val3); - } 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) @@ -4549,6 +4537,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) case BL_PC: { TBL_PC* tsd = (TBL_PC*)bl; + clif_getareachar_pc(sd, tsd); if(tsd->state.size==SZ_BIG) // tiny/big players [Valaris] clif_specialeffect_single(bl,423,sd->fd); @@ -4558,25 +4547,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) clif_sendbgemblem_single(sd->fd,tsd); if ( tsd->status.robe ) clif_refreshlook(&sd->bl,bl->id,LOOK_ROBE,tsd->status.robe,SELF); - - if (!&tsd->sc) - break; - if( tsd->sc.data[SC_CAMOUFLAGE] ) - clif_status_load(bl,SI_CAMOUFLAGE,1); - if( tsd->sc.data[SC_ACTIVE_MONSTER_TRANSFORM] ) // Overrides SC_MONSTER_TRANSFORM - clif_status_change(bl,SI_MONSTER_TRANSFORM,1,0,tsd->sc.data[SC_ACTIVE_MONSTER_TRANSFORM]->val1,0,0); - else if( tsd->sc.data[SC_MONSTER_TRANSFORM] ) - clif_status_change(bl,SI_MONSTER_TRANSFORM,1,0,tsd->sc.data[SC_MONSTER_TRANSFORM]->val1,0,0); - if( tsd->sc.data[SC_MOONSTAR] ) - clif_status_load(bl,SI_MOONSTAR,1); - if( tsd->sc.data[SC_SUPER_STAR] ) - clif_status_load(bl,SI_SUPER_STAR,1); - if( tsd->sc.data[SC_DECORATION_OF_MUSIC] ) - clif_status_load(bl,SI_DECORATION_OF_MUSIC,1); - if( tsd->sc.data[SC_STRANGELIGHTS] ) - clif_status_load(bl,SI_STRANGELIGHTS,1); - if( tsd->sc.data[SC_ALL_RIDING] ) - clif_status_load(bl,SI_ALL_RIDING,1); + clif_efst_status_change_sub(sd, bl, SELF); } break; case BL_MER: // Devotion Effects @@ -5904,33 +5875,72 @@ void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val clif_send(buf,packet_len(WBUFW(buf,0)),bl, (sd && sd->status.option&OPTION_INVISIBLE) ? SELF : AREA); } +/** + * Send any active EFST to those around. + * @param sd: Player to send the packet to + * @param bl: Objects walking into view + * @param target: Client send type + */ +void clif_efst_status_change_sub(struct map_session_data *sd, struct block_list *bl, enum send_target target) { + struct map_session_data *tsd = NULL; + unsigned char i; -void clif_status_change2(struct block_list *bl, int tid, enum send_target target, int type, int val1, int val2, int val3) { + nullpo_retv(sd); + nullpo_retv(bl); + + if (target == SELF) + tsd = (TBL_PC *)bl; + else + tsd = sd; + + for (i = 0; i < tsd->sc_display_count; i++) { + enum sc_type type = tsd->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); + int tick = 0; + + if (td) + tick = DIFF_TICK(td->tick, gettick()); + clif_efst_status_change((target == SELF) ? &sd->bl : bl, bl->id, target, StatusIconChangeTable[type], tick, tsd->sc_display[i]->val1, tsd->sc_display[i]->val2, tsd->sc_display[i]->val3); + } +} + +/// 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, int tick, int val1, int val2, int val3) { unsigned char buf[32]; +#if PACKETVER >= 20120618 + const int cmd = 0x984; +#elif PACKETVER >= 20111108 + const int cmd = 0x8ff; +#endif + int offset = 0; - if (type == SI_BLANK) //It shows nothing on the client + if (type == SI_BLANK) return; nullpo_retv(bl); - WBUFW(buf,0) = 0x43f; - WBUFW(buf,2) = type; - WBUFL(buf,4) = tid; - WBUFB(buf,8) = 1; - WBUFL(buf,9) = 9999; - WBUFL(buf,13) = val1; - WBUFL(buf,17) = val2; - WBUFL(buf,21) = val3; - clif_send(buf,packet_len(0x43f),bl,target); + 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) = tick; // Set remaining status duration [exneval] +#if PACKETVER >= 20120618 + WBUFL(buf,offset + 12) = tick; + offset += 4; +#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); } - -/// 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) -//! TODO -//void clif_efst_enter(); - - /// Send message (modified by [Yor]) (ZC_NOTIFY_PLAYERCHAT). /// 008e .W .?B void clif_displaymessage(const int fd, const char* mes) @@ -19124,7 +19134,7 @@ void packetdb_readdb(bool reload) 0, 0, 0, 0, 0, 0, 0, 20, 34, 0, 0, 0, 0, 0, 0, 10, 9, 7, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, //#0x0900 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -19136,7 +19146,7 @@ void packetdb_readdb(bool reload) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 7, 0, 0, 0, 0, 2, 0, 0, 14, 6, 50, -1, 0, 0, 0, 0, -1, //#0x0980 - 7, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 29, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, -1, 8, 11, 9, 8, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 12, 10, 14, 10, 14, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 6, 4, 0, 0, 0, 0, 0, 0, diff --git a/src/map/clif.h b/src/map/clif.h index e94f4127a7..a5b6dbc93f 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -644,7 +644,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, int tick, int val1, int val2, int val3); -void clif_status_change2(struct block_list *bl, int tid, enum send_target target, int type, int val1, int val2, int val3); +void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, int tick, int val1, int val2, int val3); +void clif_efst_status_change_sub(struct map_session_data *sd, struct block_list *bl, enum send_target target); void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len); void clif_wis_end(int fd, int result); diff --git a/src/map/pc.c b/src/map/pc.c index 6d36949e32..541294de36 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -8670,7 +8670,7 @@ bool pc_setcart(struct map_session_data *sd,int type) { clif_cartlist(sd); clif_updatestatus(sd, SP_CARTINFO); sc_start(&sd->bl,&sd->bl, SC_PUSH_CART, 100, type, 0); - clif_status_change2(&sd->bl, sd->bl.id, AREA, SI_ON_PUSH_CART, type, 0, 0); + clif_efst_status_change(&sd->bl, sd->bl.id, AREA, SI_ON_PUSH_CART, 9999, type, 0, 0); if( sd->sc.data[SC_PUSH_CART] )/* forcefully update */ sd->sc.data[SC_PUSH_CART]->val1 = type; break; diff --git a/src/map/status.c b/src/map/status.c index 681e6e8545..702e26ca9d 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1016,6 +1016,7 @@ void initChangeTables(void) StatusIconChangeTable[SC_DEFSET] = SI_SET_NUM_DEF; StatusIconChangeTable[SC_MDEFSET] = SI_SET_NUM_MDEF; StatusIconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM; + StatusIconChangeTable[SC_ACTIVE_MONSTER_TRANSFORM] = SI_ACTIVE_MONSTER_TRANSFORM; StatusIconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING; StatusIconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART; StatusIconChangeTable[SC_MTF_ASPD] = SI_MTF_ASPD; @@ -1221,6 +1222,8 @@ void initChangeTables(void) StatusDisplayType[SC__MANHOLE] = true; StatusDisplayType[SC_JYUMONJIKIRI] = true; StatusDisplayType[SC_AKAITSUKI] = true; + StatusDisplayType[SC_MONSTER_TRANSFORM] = true; + StatusDisplayType[SC_ACTIVE_MONSTER_TRANSFORM] = true; StatusDisplayType[SC_DARKCROW] = true; StatusDisplayType[SC_OFFERTORIUM] = true; StatusDisplayType[SC_TELEKINESIS_INTENSE] = true;