From 7880742956210d463ba364b88dc7ddc5ca51355c Mon Sep 17 00:00:00 2001 From: Asheraf Date: Sun, 26 May 2019 07:43:35 +0100 Subject: Update PACKET_ZC_STATE_CHANGE to use struct format --- src/map/clif.c | 56 ++++++++++++++++-------------------------------- src/map/packets_struct.h | 21 ++++++++++++++++++ 2 files changed, 39 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index 942e492c2..9e69dcc44 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -4032,51 +4032,31 @@ static void clif_misceffect(struct block_list *bl, int type) /// 0229 .L .W .W .L .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; - 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); - } else { - clif->send(buf,packet_len(0x229),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; + 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); + 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(0x119),bl,AREA); + clif->send(&p, sizeof(p), bl, AREA); } -#endif } /// Displays status change effects on NPCs/monsters (ZC_NPC_SHOWEFST_UPDATE). 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) -- cgit v1.2.3-70-g09d2 From 28ae3af5455447a379320a83a32658e6e2c154b3 Mon Sep 17 00:00:00 2001 From: Asheraf Date: Sun, 26 May 2019 07:51:34 +0100 Subject: Add a function to send PACKET_ZC_STATE_CHANGE to a single target --- src/map/clif.c | 28 ++++++++++++++++++++++++++++ src/map/clif.h | 1 + 2 files changed, 29 insertions(+) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index 9e69dcc44..d41a17e0b 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -4059,6 +4059,33 @@ static void clif_changeoption(struct block_list *bl) } } +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)) { + p.AID = -bl->id; + clif->send(&p, sizeof(p), target_bl, target); + p.AID = bl->id; + p.effectState = OPTION_INVISIBLE; + } + clif->send(&p, sizeof(p), target_bl, target); +} + /// Displays status change effects on NPCs/monsters (ZC_NPC_SHOWEFST_UPDATE). /// 028a .L .L .L .L static void clif_changeoption2(struct block_list *bl) @@ -24192,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); -- cgit v1.2.3-70-g09d2 From 89408e2401a3019c8cb1de0dab9f7e754c4dbfb4 Mon Sep 17 00:00:00 2001 From: Asheraf Date: Sun, 26 May 2019 08:19:59 +0100 Subject: Add new script commands cloakonnpc/cloakoffnpc --- doc/script_commands.txt | 12 ++++++++++++ src/map/script.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) (limited to 'src') diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 244de4c0c..b8f856877 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7041,6 +7041,18 @@ NPCs talking while hidden then revealing... you can wonder around =P). --------------------------------------- +*cloakonnpc(""{, }) +*cloakoffnpc(""{, }) + +These commands are used to apply the cloaking effect on npcs +this is a visual effect only and it does NOT stop the player +from interacting with the npc. + +If an account_id is specified then the effect will only display to the given id, +otherwise it's displayed to the entire npc area. + +--------------------------------------- + *doevent("::") This command will start a new execution thread in a specified NPC object diff --git a/src/map/script.c b/src/map/script.c index 1d5919d3b..557550be2 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. * @@ -26672,6 +26722,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???"), -- cgit v1.2.3-70-g09d2 From 8695b790286586ae5e664bd1ef51fcb9debcc7c1 Mon Sep 17 00:00:00 2001 From: Asheraf Date: Wed, 15 Jan 2020 16:28:45 +0100 Subject: Add script command achievement_iscompleted to check for achievement status --- doc/script_commands.txt | 8 ++++++++ src/map/script.c | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'src') diff --git a/doc/script_commands.txt b/doc/script_commands.txt index b8f856877..6a97bae1d 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -10634,6 +10634,14 @@ returns progress on success and false on failure --------------------------------------- +*achievement_iscompleted({, }) + +Checks whether the attached player have completed all the given achievement objectives. + +returns true if yes and false if no. + +--------------------------------------- + *itempreview() Update already opened preview window with item from diff --git a/src/map/script.c b/src/map/script.c index 557550be2..3879d8efb 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -22269,6 +22269,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 *------------------------------------------*/ @@ -27006,6 +27023,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"), -- cgit v1.2.3-70-g09d2