summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/HPMDataCheck.h1
-rw-r--r--src/map/clif.c80
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/packets_struct.h21
-rw-r--r--src/map/script.c70
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc2
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc1
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc26
9 files changed, 170 insertions, 36 deletions
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index 129ec7475..11f79a11b 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -744,6 +744,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "PACKET_ZC_SKILLINFO_LIST", sizeof(struct PACKET_ZC_SKILLINFO_LIST), SERVER_TYPE_MAP },
{ "PACKET_ZC_SKILLINFO_UPDATE2", sizeof(struct PACKET_ZC_SKILLINFO_UPDATE2), SERVER_TYPE_MAP },
{ "PACKET_ZC_SPRITE_CHANGE", sizeof(struct PACKET_ZC_SPRITE_CHANGE), SERVER_TYPE_MAP },
+ { "PACKET_ZC_STATE_CHANGE", sizeof(struct PACKET_ZC_STATE_CHANGE), SERVER_TYPE_MAP },
{ "PACKET_ZC_STATUS_CHANGE_ACK", sizeof(struct PACKET_ZC_STATUS_CHANGE_ACK), SERVER_TYPE_MAP },
{ "PACKET_ZC_STYLE_CHANGE_RES", sizeof(struct PACKET_ZC_STYLE_CHANGE_RES), SERVER_TYPE_MAP },
{ "PACKET_ZC_TALKBOX_CHATCONTENTS", sizeof(struct PACKET_ZC_TALKBOX_CHATCONTENTS), SERVER_TYPE_MAP },
diff --git a/src/map/clif.c b/src/map/clif.c
index 1223d2b7e..868117a96 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -4032,51 +4032,58 @@ static void clif_misceffect(struct block_list *bl, int type)
/// 0229 <id>.L <body state>.W <health state>.W <effect state>.L <pk mode>.B (ZC_STATE_CHANGE3)
static void clif_changeoption(struct block_list *bl)
{
- unsigned char buf[32];
- struct status_change *sc;
- struct map_session_data* sd;
-
nullpo_retv(bl);
- if ( !(sc = status->get_sc(bl)) && bl->type != BL_NPC ) return; //How can an option change if there's no sc?
+ struct status_change *sc = status->get_sc(bl);
- sd = BL_CAST(BL_PC, bl);
+ if (sc == NULL && bl->type != BL_NPC) // How can an option change if there's no sc?
+ return;
-#if PACKETVER >= 7
- WBUFW(buf,0) = 0x229;
- WBUFL(buf,2) = bl->id;
- WBUFW(buf,6) = (sc) ? sc->opt1 : 0;
- WBUFW(buf,8) = (sc) ? sc->opt2 : 0;
- WBUFL(buf,10) = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
- WBUFB(buf,14) = (sd)? sd->status.karma : 0;
+ struct map_session_data *sd = BL_CAST(BL_PC, bl);
+ struct PACKET_ZC_STATE_CHANGE p;
+ p.packetType = HEADER_ZC_STATE_CHANGE;
+ p.AID = bl->id;
+ p.bodyState = (sc != NULL) ? sc->opt1 : 0;
+ p.healthState = (sc != NULL) ? sc->opt2 : 0;
+ p.effectState = (sc != NULL) ? sc->option : BL_UCCAST(BL_NPC, bl)->option;
+ p.isPKModeON = (sd != NULL) ? sd->status.karma : 0;
if (clif->isdisguised(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);
+ clif->send(&p, sizeof(p), bl, AREA_WOS);
+ p.AID = -bl->id;
+ clif->send(&p, sizeof(p), bl, SELF);
+ p.AID = bl->id;
+ p.effectState = OPTION_INVISIBLE;
+ clif->send(&p, sizeof(p), bl, SELF);
} else {
- clif->send(buf,packet_len(0x229),bl,AREA);
+ clif->send(&p, sizeof(p), bl, AREA);
}
-#else
- WBUFW(buf,0) = 0x119;
- WBUFL(buf,2) = bl->id;
- WBUFW(buf,6) = (sc) ? sc->opt1 : 0;
- WBUFW(buf,8) = (sc) ? sc->opt2 : 0;
- WBUFL(buf,10) = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0);
- WBUFB(buf,12) = (sd)? sd->status.karma : 0;
+}
+
+static void clif_changeoption_target(struct block_list *bl, struct block_list *target_bl, enum send_target target)
+{
+ nullpo_retv(bl);
+ nullpo_retv(target_bl);
+
+ struct status_change *sc = status->get_sc(bl);
+
+ if (sc == NULL && bl->type != BL_NPC) // How can an option change if there's no sc?
+ return;
+
+ struct map_session_data *sd = BL_CAST(BL_PC, bl);
+ struct PACKET_ZC_STATE_CHANGE p;
+ p.packetType = HEADER_ZC_STATE_CHANGE;
+ p.AID = bl->id;
+ p.bodyState = (sc != NULL) ? sc->opt1 : 0;
+ p.healthState = (sc != NULL) ? sc->opt2 : 0;
+ p.effectState = (sc != NULL) ? sc->option : BL_UCCAST(BL_NPC, bl)->option;
+ p.isPKModeON = (sd != NULL) ? sd->status.karma : 0;
if (clif->isdisguised(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);
+ p.AID = -bl->id;
+ clif->send(&p, sizeof(p), target_bl, target);
+ p.AID = bl->id;
+ p.effectState = OPTION_INVISIBLE;
}
-#endif
+ clif->send(&p, sizeof(p), target_bl, target);
}
/// Displays status change effects on NPCs/monsters (ZC_NPC_SHOWEFST_UPDATE).
@@ -24212,6 +24219,7 @@ void clif_defaults(void)
/* visual effects client-side */
clif->misceffect = clif_misceffect;
clif->changeoption = clif_changeoption;
+ clif->changeoption_target = clif_changeoption_target;
clif->changeoption2 = clif_changeoption2;
clif->emotion = clif_emotion;
clif->talkiebox = clif_talkiebox;
diff --git a/src/map/clif.h b/src/map/clif.h
index 252dfefe1..25ac65af5 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -1006,6 +1006,7 @@ struct clif_interface {
/* visual effects client-side */
void (*misceffect) (struct block_list* bl,int type);
void (*changeoption) (struct block_list* bl);
+ void (*changeoption_target) (struct block_list *bl, struct block_list *target_bl, enum send_target target);
void (*changeoption2) (struct block_list* bl);
void (*emotion) (struct block_list *bl,int type);
void (*talkiebox) (struct block_list* bl, const char* talkie);
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index c2c99629a..31b28e831 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -3851,6 +3851,27 @@ struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE {
DEFINE_PACKET_HEADER(CZ_NPC_EXPANDED_BARTER_PURCHASE, 0x0b57);
#endif
+#if PACKETVER >= 7
+struct PACKET_ZC_STATE_CHANGE {
+ int16 packetType;
+ uint32 AID;
+ int16 bodyState;
+ int16 healthState;
+ int32 effectState;
+ int8 isPKModeON;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_STATE_CHANGE, 0x0229);
+#else
+struct PACKET_ZC_STATE_CHANGE {
+ int16 PacketType;
+ uint32 AID;
+ int16 bodyState;
+ int16 healthState;
+ int16 effectState;
+ int8 isPKModeON;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_STATE_CHANGE, 0x0119);
+#endif
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
diff --git a/src/map/script.c b/src/map/script.c
index c3e8436f7..b89176dba 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -12489,6 +12489,56 @@ static BUILDIN(hideonnpc)
npc->enable(str,4);
return true;
}
+/*==========================================
+ *------------------------------------------*/
+static BUILDIN(cloakonnpc)
+{
+ struct npc_data *nd = npc->name2id(script_getstr(st, 2));
+ if (nd == NULL) {
+ ShowError("buildin_cloakonnpc: invalid npc name '%s'.\n", script_getstr(st, 2));
+ return false;
+ }
+
+ if (script_hasdata(st, 3)) {
+ struct map_session_data *sd = map->id2sd(script_getnum(st, 3));
+ if (sd == NULL)
+ return false;
+
+ uint32 val = nd->option;
+ nd->option |= OPTION_CLOAK;
+ clif->changeoption_target(&nd->bl, &sd->bl, SELF);
+ nd->option = val;
+ } else {
+ nd->option |= OPTION_CLOAK;
+ clif->changeoption(&nd->bl);
+ }
+ return true;
+}
+/*==========================================
+ *------------------------------------------*/
+static BUILDIN(cloakoffnpc)
+{
+ struct npc_data *nd = npc->name2id(script_getstr(st, 2));
+ if (nd == NULL) {
+ ShowError("buildin_cloakoffnpc: invalid npc name '%s'.\n", script_getstr(st, 2));
+ return false;
+ }
+
+ if (script_hasdata(st, 3)) {
+ struct map_session_data *sd = map->id2sd(script_getnum(st, 3));
+ if (sd == NULL)
+ return false;
+
+ uint32 val = nd->option;
+ nd->option &= ~OPTION_CLOAK;
+ clif->changeoption_target(&nd->bl, &sd->bl, SELF);
+ nd->option = val;
+ } else {
+ nd->option &= ~OPTION_CLOAK;
+ clif->changeoption(&nd->bl);
+ }
+ return true;
+}
/* Starts a status effect on the target unit or on the attached player.
*
@@ -22241,6 +22291,23 @@ static BUILDIN(achievement_progress)
return true;
}
+static BUILDIN(achievement_iscompleted)
+{
+ struct map_session_data *sd = script_hasdata(st, 3) ? map->id2sd(script_getnum(st, 3)) : script->rid2sd(st);
+ if (sd == NULL)
+ return false;
+
+ int aid = script_getnum(st, 2);
+ const struct achievement_data *ad = achievement->get(aid);
+ if (ad == NULL) {
+ ShowError("buildin_achievement_iscompleted: Invalid Achievement %d provided.\n", aid);
+ return false;
+ }
+
+ script_pushint(st, achievement->check_complete(sd, ad));
+ return true;
+}
+
/*==========================================
* BattleGround System
*------------------------------------------*/
@@ -26705,6 +26772,8 @@ static void script_parse_builtin(void)
BUILDIN_DEF(disablenpc,"s"),
BUILDIN_DEF(hideoffnpc,"s"),
BUILDIN_DEF(hideonnpc,"s"),
+ BUILDIN_DEF(cloakonnpc,"s?"),
+ BUILDIN_DEF(cloakoffnpc,"s?"),
BUILDIN_DEF(sc_start,"iii???"),
BUILDIN_DEF2(sc_start,"sc_start2","iiii???"),
BUILDIN_DEF2(sc_start,"sc_start4","iiiiii???"),
@@ -26987,6 +27056,7 @@ static void script_parse_builtin(void)
BUILDIN_DEF(agitcheck2,""),
// Achievements [Smokexyz/Hercules]
BUILDIN_DEF(achievement_progress, "iiii?"),
+ BUILDIN_DEF(achievement_iscompleted, "i?"),
// BattleGround
BUILDIN_DEF(waitingroom2bg,"siiss?"),
BUILDIN_DEF(waitingroom2bg_single,"isiis"),
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 4345108d3..8c6f43433 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -1514,6 +1514,8 @@ typedef void (*HPMHOOK_pre_clif_misceffect) (struct block_list **bl, int *type);
typedef void (*HPMHOOK_post_clif_misceffect) (struct block_list *bl, int type);
typedef void (*HPMHOOK_pre_clif_changeoption) (struct block_list **bl);
typedef void (*HPMHOOK_post_clif_changeoption) (struct block_list *bl);
+typedef void (*HPMHOOK_pre_clif_changeoption_target) (struct block_list **bl, struct block_list **target_bl, enum send_target *target);
+typedef void (*HPMHOOK_post_clif_changeoption_target) (struct block_list *bl, struct block_list *target_bl, enum send_target target);
typedef void (*HPMHOOK_pre_clif_changeoption2) (struct block_list **bl);
typedef void (*HPMHOOK_post_clif_changeoption2) (struct block_list *bl);
typedef void (*HPMHOOK_pre_clif_emotion) (struct block_list **bl, int *type);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index b5f04af50..53ba3403c 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -1104,6 +1104,8 @@ struct {
struct HPMHookPoint *HP_clif_misceffect_post;
struct HPMHookPoint *HP_clif_changeoption_pre;
struct HPMHookPoint *HP_clif_changeoption_post;
+ struct HPMHookPoint *HP_clif_changeoption_target_pre;
+ struct HPMHookPoint *HP_clif_changeoption_target_post;
struct HPMHookPoint *HP_clif_changeoption2_pre;
struct HPMHookPoint *HP_clif_changeoption2_post;
struct HPMHookPoint *HP_clif_emotion_pre;
@@ -7969,6 +7971,8 @@ struct {
int HP_clif_misceffect_post;
int HP_clif_changeoption_pre;
int HP_clif_changeoption_post;
+ int HP_clif_changeoption_target_pre;
+ int HP_clif_changeoption_target_post;
int HP_clif_changeoption2_pre;
int HP_clif_changeoption2_post;
int HP_clif_emotion_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 1967f8c82..0904a1dac 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -576,6 +576,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->quitsave, HP_clif_quitsave) },
{ HP_POP(clif->misceffect, HP_clif_misceffect) },
{ HP_POP(clif->changeoption, HP_clif_changeoption) },
+ { HP_POP(clif->changeoption_target, HP_clif_changeoption_target) },
{ HP_POP(clif->changeoption2, HP_clif_changeoption2) },
{ HP_POP(clif->emotion, HP_clif_emotion) },
{ HP_POP(clif->talkiebox, HP_clif_talkiebox) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index d7d183f28..319e675a8 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -14402,6 +14402,32 @@ void HP_clif_changeoption(struct block_list *bl) {
}
return;
}
+void HP_clif_changeoption_target(struct block_list *bl, struct block_list *target_bl, enum send_target target) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_changeoption_target_pre > 0) {
+ void (*preHookFunc) (struct block_list **bl, struct block_list **target_bl, enum send_target *target);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_changeoption_target_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_changeoption_target_pre[hIndex].func;
+ preHookFunc(&bl, &target_bl, &target);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.changeoption_target(bl, target_bl, target);
+ }
+ if (HPMHooks.count.HP_clif_changeoption_target_post > 0) {
+ void (*postHookFunc) (struct block_list *bl, struct block_list *target_bl, enum send_target target);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_changeoption_target_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_changeoption_target_post[hIndex].func;
+ postHookFunc(bl, target_bl, target);
+ }
+ }
+ return;
+}
void HP_clif_changeoption2(struct block_list *bl) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_changeoption2_pre > 0) {