|
@@ -980,7 +980,7 @@ static int clif_setlevel(struct block_list* bl) {
|
|
|
/*==========================================
|
|
|
* Prepares 'unit standing/spawning' packet
|
|
|
*------------------------------------------*/
|
|
|
-static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool spawn)
|
|
|
+static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool spawn, bool option, unsigned int option_val)
|
|
|
{
|
|
|
struct map_session_data* sd;
|
|
|
struct status_change* sc = status_get_sc(bl);
|
|
@@ -996,6 +996,9 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool
|
|
|
#endif
|
|
|
sd = BL_CAST(BL_PC, bl);
|
|
|
|
|
|
+ if (!option)
|
|
|
+ option_val = ((sc) ? sc->option : 0);
|
|
|
+
|
|
|
#if PACKETVER < 20091103
|
|
|
if(type)
|
|
|
WBUFW(buf,0) = spawn ? 0x7c : 0x78;
|
|
@@ -1053,7 +1056,7 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool
|
|
|
WBUFW(buf,10) = (sc)? sc->opt2 : 0;
|
|
|
#if PACKETVER < 20091103
|
|
|
if (type&&spawn) { //uses an older and different packet structure
|
|
|
- WBUFW(buf,12) = (sc)? sc->option : 0;
|
|
|
+ WBUFW(buf,12) = option_val;
|
|
|
WBUFW(buf,14) = vd->hair_style;
|
|
|
WBUFW(buf,16) = vd->weapon;
|
|
|
WBUFW(buf,18) = vd->head_bottom;
|
|
@@ -1062,18 +1065,18 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool
|
|
|
} else {
|
|
|
#endif
|
|
|
#if PACKETVER >= 20091103
|
|
|
- WBUFL(buf,12) = (sc)? sc->option : 0;
|
|
|
+ WBUFL(buf,12) = option_val;
|
|
|
offset+=2;
|
|
|
buf = WBUFP(buffer,offset);
|
|
|
#elif PACKETVER >= 7
|
|
|
if (!type) {
|
|
|
- WBUFL(buf,12) = (sc)? sc->option : 0;
|
|
|
+ WBUFL(buf,12) = option_val;
|
|
|
offset+=2;
|
|
|
buf = WBUFP(buffer,offset);
|
|
|
} else
|
|
|
- WBUFW(buf,12) = (sc)? sc->option : 0;
|
|
|
+ WBUFW(buf,12) = option_val;
|
|
|
#else
|
|
|
- WBUFW(buf,12) = (sc)? sc->option : 0;
|
|
|
+ WBUFW(buf,12) = option_val;
|
|
|
#endif
|
|
|
WBUFW(buf,14) = vd->class_;
|
|
|
WBUFW(buf,16) = vd->hair_style;
|
|
@@ -1455,7 +1458,7 @@ int clif_spawn(struct block_list *bl)
|
|
|
if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
|
|
|
return 0;
|
|
|
|
|
|
- len = clif_set_unit_idle(bl, buf, (bl->type == BL_NPC && vd->dead_sit ? false : true));
|
|
|
+ len = clif_set_unit_idle(bl, buf, (bl->type == BL_NPC && vd->dead_sit ? false : true), false, 0);
|
|
|
clif_send(buf, len, bl, AREA_WOS);
|
|
|
if (disguised(bl))
|
|
|
clif_setdisguise(bl, buf, len);
|
|
@@ -3937,57 +3940,60 @@ void clif_misceffect(struct block_list* bl,int type)
|
|
|
/// Notifies clients in the area of a state change.
|
|
|
/// 0119 <id>.L <body state>.W <health state>.W <effect state>.W <pk mode>.B (ZC_STATE_CHANGE)
|
|
|
/// 0229 <id>.L <body state>.W <health state>.W <effect state>.L <pk mode>.B (ZC_STATE_CHANGE3)
|
|
|
-void clif_changeoption(struct block_list* bl)
|
|
|
+void clif_changeoption_target(struct block_list* bl, struct block_list *target)
|
|
|
{
|
|
|
- unsigned char buf[32];
|
|
|
- struct status_change *sc;
|
|
|
- struct map_session_data* sd;
|
|
|
-
|
|
|
nullpo_retv(bl);
|
|
|
- sc = status_get_sc(bl);
|
|
|
- if (!sc) return; //How can an option change if there's no sc?
|
|
|
- sd = BL_CAST(BL_PC, bl);
|
|
|
|
|
|
-#if PACKETVER >= 7
|
|
|
- WBUFW(buf,0) = 0x229;
|
|
|
+ struct status_change *sc = status_get_sc(bl);
|
|
|
+
|
|
|
+ if (!sc || (target && (target->type != BL_PC || bl->type != BL_NPC)))
|
|
|
+ return; //How can an option change if there's no sc?
|
|
|
+
|
|
|
+ struct map_session_data *sd = BL_CAST(BL_PC, bl);
|
|
|
+ unsigned char buf[32];
|
|
|
+#if PAKCETVER >= 7
|
|
|
+ int cmd = 0x229;
|
|
|
+#else
|
|
|
+ int cmd = 0x119;
|
|
|
+#endif
|
|
|
+
|
|
|
+ WBUFW(buf,0) = cmd;
|
|
|
WBUFL(buf,2) = bl->id;
|
|
|
WBUFW(buf,6) = sc->opt1;
|
|
|
WBUFW(buf,8) = sc->opt2;
|
|
|
WBUFL(buf,10) = sc->option;
|
|
|
+#if PACKETVER >= 7
|
|
|
WBUFB(buf,14) = (sd)? sd->status.karma : 0;
|
|
|
- if(disguised(bl)) {
|
|
|
- clif_send(buf,packet_len(0x229),bl,AREA_WOS);
|
|
|
- WBUFL(buf,2) = -bl->id;
|
|
|
- clif_send(buf,packet_len(0x229),bl,SELF);
|
|
|
- WBUFL(buf,2) = bl->id;
|
|
|
- WBUFL(buf,10) = OPTION_INVISIBLE;
|
|
|
- clif_send(buf,packet_len(0x229),bl,SELF);
|
|
|
- } else
|
|
|
- clif_send(buf,packet_len(0x229),bl,AREA);
|
|
|
#else
|
|
|
- WBUFW(buf,0) = 0x119;
|
|
|
- WBUFL(buf,2) = bl->id;
|
|
|
- WBUFW(buf,6) = sc->opt1;
|
|
|
- WBUFW(buf,8) = sc->opt2;
|
|
|
- WBUFW(buf,10) = sc->option;
|
|
|
WBUFB(buf,12) = (sd)? sd->status.karma : 0;
|
|
|
- if(disguised(bl)) {
|
|
|
- clif_send(buf,packet_len(0x119),bl,AREA_WOS);
|
|
|
- WBUFL(buf,2) = -bl->id;
|
|
|
- clif_send(buf,packet_len(0x119),bl,SELF);
|
|
|
- WBUFL(buf,2) = bl->id;
|
|
|
- WBUFW(buf,10) = OPTION_INVISIBLE;
|
|
|
- clif_send(buf,packet_len(0x119),bl,SELF);
|
|
|
- } else
|
|
|
- clif_send(buf,packet_len(0x119),bl,AREA);
|
|
|
#endif
|
|
|
+ if (!target) {
|
|
|
+ if (disguised(bl)) {
|
|
|
+ clif_send(buf,packet_len(cmd),bl,AREA_WOS);
|
|
|
+ WBUFL(buf,2) = -bl->id;
|
|
|
+ clif_send(buf,packet_len(cmd),bl,SELF);
|
|
|
+ WBUFL(buf,2) = bl->id;
|
|
|
+ WBUFL(buf,10) = OPTION_INVISIBLE;
|
|
|
+ clif_send(buf,packet_len(cmd),bl,SELF);
|
|
|
+ } else
|
|
|
+ clif_send(buf,packet_len(cmd),bl,AREA);
|
|
|
|
|
|
- //Whenever we send "changeoption" to the client, the provoke icon is lost
|
|
|
- //There is probably an option for the provoke icon, but as we don't know it, we have to do this for now
|
|
|
- if (sc->data[SC_PROVOKE]) {
|
|
|
- const struct TimerData *td = get_timer(sc->data[SC_PROVOKE]->timer);
|
|
|
+ //Whenever we send "changeoption" to the client, the provoke icon is lost
|
|
|
+ //There is probably an option for the provoke icon, but as we don't know it, we have to do this for now
|
|
|
+ if (sc->data[SC_PROVOKE]) {
|
|
|
+ const struct TimerData *td = get_timer(sc->data[SC_PROVOKE]->timer);
|
|
|
|
|
|
- clif_status_change(bl, StatusIconChangeTable[SC_PROVOKE], 1, (!td ? INFINITE_TICK : DIFF_TICK(td->tick, gettick())), 0, 0, 0);
|
|
|
+ clif_status_change(bl, StatusIconChangeTable[SC_PROVOKE], 1, (!td ? INFINITE_TICK : DIFF_TICK(td->tick, gettick())), 0, 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if (disguised(bl)) {
|
|
|
+ WBUFL(buf,2) = -bl->id;
|
|
|
+ clif_send(buf,packet_len(cmd),target,SELF);
|
|
|
+ WBUFL(buf,2) = bl->id;
|
|
|
+ WBUFL(buf,10) = OPTION_INVISIBLE;
|
|
|
+ }
|
|
|
+ clif_send(buf,packet_len(cmd),target,SELF);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -4644,10 +4650,14 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d
|
|
|
|
|
|
void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
|
|
|
{
|
|
|
+ nullpo_retv(bl);
|
|
|
+
|
|
|
uint8 buf[128];
|
|
|
struct unit_data *ud;
|
|
|
struct view_data *vd;
|
|
|
int len;
|
|
|
+ bool option = false;
|
|
|
+ unsigned int option_val = 0;
|
|
|
|
|
|
vd = status_get_viewdata(bl);
|
|
|
if (!vd || vd->class_ == JT_INVISIBLE)
|
|
@@ -4660,7 +4670,15 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
|
|
|
return;
|
|
|
|
|
|
ud = unit_bl2ud(bl);
|
|
|
- len = ( ud && ud->walktimer != INVALID_TIMER ) ? clif_set_unit_walking(bl,ud,buf) : clif_set_unit_idle(bl,buf,false);
|
|
|
+ if (sd && bl->type == BL_NPC) { // npc option changed?
|
|
|
+ npc_data* nd = BL_CAST(BL_NPC, bl);
|
|
|
+ option_val = nd->sc.option;
|
|
|
+ option = true;
|
|
|
+
|
|
|
+ if (std::find(sd->cloaked_npc.begin(), sd->cloaked_npc.end(), nd->bl.id) != sd->cloaked_npc.end())
|
|
|
+ option_val ^= OPTION_CLOAK;
|
|
|
+ }
|
|
|
+ len = ( ud && ud->walktimer != INVALID_TIMER ) ? clif_set_unit_walking(bl,ud,buf) : clif_set_unit_idle(bl,buf,false,option,option_val);
|
|
|
clif_send(buf,len,&sd->bl,SELF);
|
|
|
|
|
|
if (vd->cloth_color)
|