From f4fbfb32993457dc64d371b1bf8fd55e599bbe91 Mon Sep 17 00:00:00 2001 From: Atemo Date: Sat, 11 Sep 2021 14:56:36 +0200 Subject: [PATCH] Clean-up the npc_enable_target function (#6248) * Clean-up the npc_enable_target function Thanks to @Lemongrass3110 and @aleos89 --- src/map/atcommand.cpp | 4 +- src/map/npc.cpp | 88 +++++++++++++++++++++---------------------- src/map/npc.hpp | 16 +++++++- src/map/script.cpp | 32 +++++++++------- 4 files changed, 78 insertions(+), 62 deletions(-) diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index cec774abf2..5f08d7f899 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -4747,7 +4747,7 @@ ACMD_FUNC(shownpc) npc_data* nd = npc_name2id(NPCname); if (nd) { - npc_enable(nd, 1); + npc_enable(*nd, NPCVIEW_ENABLE); clif_displaymessage(fd, msg_txt(sd,110)); // Npc Enabled. } else { clif_displaymessage(fd, msg_txt(sd,111)); // This NPC doesn't exist. @@ -4779,7 +4779,7 @@ ACMD_FUNC(hidenpc) return -1; } - npc_enable(nd, 0); + npc_enable(*nd, NPCVIEW_DISABLE); clif_displaymessage(fd, msg_txt(sd,112)); // Npc Disabled. return 0; } diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 22ec2a3e37..9de50fcc73 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -254,83 +254,81 @@ static int npc_cloaked_sub(struct block_list *bl, va_list ap) /*========================================== * Disable / Enable NPC *------------------------------------------*/ -bool npc_enable_target(npc_data* nd, uint32 char_id, int flag) +bool npc_enable_target(npc_data& nd, uint32 char_id, e_npcv_status flag) { - nullpo_ret(nd); - - if (char_id > 0 && (flag & 24)) { + if (char_id > 0 && (flag & NPCVIEW_CLOAK)) { map_session_data *sd = map_charid2sd(char_id); if (!sd) { - ShowError("npc_enable: Attempted to %s a NPC '%s' on an invalid target %d.\n", (flag & 8) ? "show" : "hide", nd->name, char_id); + ShowError("npc_enable: Attempted to %s a NPC '%s' on an invalid target %d.\n", (flag & NPCVIEW_VISIBLE) ? "show" : "hide", nd.name, char_id); return false; } - unsigned int option = nd->sc.option; - if (flag&8) - nd->sc.option &= ~OPTION_CLOAK; + unsigned int option = nd.sc.option; + if (flag & NPCVIEW_CLOAKOFF) + nd.sc.option &= ~OPTION_CLOAK; else - nd->sc.option |= OPTION_CLOAK; + nd.sc.option |= OPTION_CLOAK; - auto it = std::find(sd->cloaked_npc.begin(), sd->cloaked_npc.end(), nd->bl.id); + auto it = std::find(sd->cloaked_npc.begin(), sd->cloaked_npc.end(), nd.bl.id); - if (it == sd->cloaked_npc.end() && option != nd->sc.option) - sd->cloaked_npc.push_back(nd->bl.id); - else if (it != sd->cloaked_npc.end() && option == nd->sc.option) + if (it == sd->cloaked_npc.end() && option != nd.sc.option) + sd->cloaked_npc.push_back(nd.bl.id); + else if (it != sd->cloaked_npc.end() && option == nd.sc.option) sd->cloaked_npc.erase(it); - if (nd->class_ != JT_WARPNPC && nd->class_ != JT_GUILD_FLAG) - clif_changeoption_target(&nd->bl, &sd->bl); + if (nd.class_ != JT_WARPNPC && nd.class_ != JT_GUILD_FLAG) + clif_changeoption_target(&nd.bl, &sd->bl); else { - if (nd->sc.option&(OPTION_HIDE|OPTION_INVISIBLE|OPTION_CLOAK)) - clif_clearunit_single(nd->bl.id, CLR_OUTSIGHT, sd->fd); + if (nd.sc.option&(OPTION_HIDE|OPTION_INVISIBLE|OPTION_CLOAK)) + clif_clearunit_single(nd.bl.id, CLR_OUTSIGHT, sd->fd); else - clif_spawn(&nd->bl); + clif_spawn(&nd.bl); } - nd->sc.option = option; + nd.sc.option = option; } else { - if (flag&1) { - nd->sc.option &= ~OPTION_INVISIBLE; - clif_spawn(&nd->bl); + if (flag & NPCVIEW_ENABLE) { + nd.sc.option &= ~OPTION_INVISIBLE; + clif_spawn(&nd.bl); } - else if (flag&2) - nd->sc.option &= ~OPTION_HIDE; - else if (flag&4) - nd->sc.option |= OPTION_HIDE; - else if (flag&8) - nd->sc.option &= ~OPTION_CLOAK; - else if (flag&16) - nd->sc.option |= OPTION_CLOAK; + else if (flag & NPCVIEW_HIDEOFF) + nd.sc.option &= ~OPTION_HIDE; + else if (flag & NPCVIEW_HIDEON) + nd.sc.option |= OPTION_HIDE; + else if (flag & NPCVIEW_CLOAKOFF) + nd.sc.option &= ~OPTION_CLOAK; + else if (flag & NPCVIEW_CLOAKON) + nd.sc.option |= OPTION_CLOAK; else { //Can't change the view_data to invisible class because the view_data for all npcs is shared! [Skotlex] - nd->sc.option |= OPTION_INVISIBLE; - clif_clearunit_area(&nd->bl,CLR_OUTSIGHT); // Hack to trick maya purple card [Xazax] + nd.sc.option |= OPTION_INVISIBLE; + clif_clearunit_area(&nd.bl,CLR_OUTSIGHT); // Hack to trick maya purple card [Xazax] } - if (nd->class_ != JT_WARPNPC && nd->class_ != JT_GUILD_FLAG) //Client won't display option changes for these classes [Toms] - clif_changeoption(&nd->bl); + if (nd.class_ != JT_WARPNPC && nd.class_ != JT_GUILD_FLAG) //Client won't display option changes for these classes [Toms] + clif_changeoption(&nd.bl); else { - if (nd->sc.option&(OPTION_HIDE|OPTION_INVISIBLE|OPTION_CLOAK)) - clif_clearunit_area(&nd->bl,CLR_OUTSIGHT); + if (nd.sc.option&(OPTION_HIDE|OPTION_INVISIBLE|OPTION_CLOAK)) + clif_clearunit_area(&nd.bl,CLR_OUTSIGHT); else - clif_spawn(&nd->bl); + clif_spawn(&nd.bl); } - map_foreachinmap(npc_cloaked_sub, nd->bl.m, BL_PC, nd->bl.id); // Because npc option has been updated we remove the npc id from sd->cloaked_npc + map_foreachinmap(npc_cloaked_sub, nd.bl.m, BL_PC, nd.bl.id); // Because npc option has been updated we remove the npc id from sd->cloaked_npc } - if (flag&11) { // check if player standing on a OnTouchArea + if (flag & NPCVIEW_VISIBLE) { // check if player standing on a OnTouchArea int xs = -1, ys = -1; - switch (nd->subtype) { + switch (nd.subtype) { case NPCTYPE_SCRIPT: - xs = nd->u.scr.xs; - ys = nd->u.scr.ys; + xs = nd.u.scr.xs; + ys = nd.u.scr.ys; break; case NPCTYPE_WARP: - xs = nd->u.warp.xs; - ys = nd->u.warp.ys; + xs = nd.u.warp.xs; + ys = nd.u.warp.ys; break; } if (xs > -1 && ys > -1) - map_foreachinallarea( npc_enable_sub, nd->bl.m, nd->bl.x-xs, nd->bl.y-ys, nd->bl.x+xs, nd->bl.y+ys, BL_PC, nd ); + map_foreachinallarea( npc_enable_sub, nd.bl.m, nd.bl.x-xs, nd.bl.y-ys, nd.bl.x+xs, nd.bl.y+ys, BL_PC, &nd ); } return true; diff --git a/src/map/npc.hpp b/src/map/npc.hpp index 7e54c43f28..c349fa684f 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -1305,6 +1305,20 @@ enum npce_event : uint8 { NPCE_KILLNPC, NPCE_MAX }; + +// Status of NPC view. +enum e_npcv_status : uint8 { + NPCVIEW_DISABLE = 0x01, + NPCVIEW_ENABLE = 0x02, + NPCVIEW_HIDEOFF = 0x04, + NPCVIEW_HIDEON = 0x08, + NPCVIEW_CLOAKOFF = 0x10, + NPCVIEW_CLOAKON = 0x20, + + NPCVIEW_VISIBLE = 0x16, + NPCVIEW_INVISIBLE = 0x29, + NPCVIEW_CLOAK = 0x30, +}; struct view_data* npc_get_viewdata(int class_); int npc_chat_sub(struct block_list* bl, va_list ap); int npc_event_dequeue(struct map_session_data* sd,bool free_script_stack=true); @@ -1330,7 +1344,7 @@ void npc_setcells(struct npc_data* nd); void npc_unsetcells(struct npc_data* nd); bool npc_movenpc(struct npc_data* nd, int16 x, int16 y); bool npc_is_cloaked(struct npc_data* nd, struct map_session_data* sd); -bool npc_enable_target(npc_data* nd, uint32 char_id, int flag); +bool npc_enable_target(npc_data& nd, uint32 char_id, e_npcv_status flag); #define npc_enable(nd, flag) npc_enable_target(nd, 0, flag) void npc_setdisplayname(struct npc_data* nd, const char* newname); void npc_setclass(struct npc_data* nd, short class_); diff --git a/src/map/script.cpp b/src/map/script.cpp index c03c3e239e..17afe663ee 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -11685,7 +11685,7 @@ BUILDIN_FUNC(getareadropitem) BUILDIN_FUNC(enablenpc) { npc_data* nd; - int flag = 0; + e_npcv_status flag = NPCVIEW_DISABLE; int char_id = script_hasdata(st, 3) ? script_getnum(st, 3) : 0; const char* command = script_getfuncname(st); @@ -11695,27 +11695,31 @@ BUILDIN_FUNC(enablenpc) nd = map_id2nd(st->oid); if (!strcmp(command,"enablenpc")) - flag = 1; + flag = NPCVIEW_ENABLE; else if (!strcmp(command,"disablenpc")) - flag = 0; + flag = NPCVIEW_DISABLE; else if (!strcmp(command,"hideoffnpc")) - flag = 2; + flag = NPCVIEW_HIDEOFF; else if (!strcmp(command,"hideonnpc")) - flag = 4; + flag = NPCVIEW_HIDEON; else if (!strcmp(command,"cloakoffnpc")) - flag = 8; + flag = NPCVIEW_CLOAKOFF; else if (!strcmp(command,"cloakonnpc")) - flag = 16; - - if (!nd) { - if (script_hasdata(st, 2)) - ShowError("buildin_%s: Attempted to %s a non-existing NPC '%s' (flag=%d).\n", (flag&11) ? "show" : "hide", command, script_getstr(st,2), flag); - else - ShowError("buildin_%s: Attempted to %s a non-existing NPC (flag=%d).\n", (flag&11) ? "show" : "hide", command, flag); + flag = NPCVIEW_CLOAKON; + else{ + ShowError( "buildin_enablenpc: Undefined command \"%s\".\n", command ); return SCRIPT_CMD_FAILURE; } - if (npc_enable_target(nd, char_id, flag)) + if (!nd) { + if (script_hasdata(st, 2)) + ShowError("buildin_%s: Attempted to %s a non-existing NPC '%s' (flag=%d).\n", (flag & NPCVIEW_VISIBLE) ? "show" : "hide", command, script_getstr(st,2), flag); + else + ShowError("buildin_%s: Attempted to %s a non-existing NPC (flag=%d).\n", (flag & NPCVIEW_VISIBLE) ? "show" : "hide", command, flag); + return SCRIPT_CMD_FAILURE; + } + + if (npc_enable_target(*nd, char_id, flag)) return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_FAILURE;