diff options
-rw-r--r-- | src/map/atcommand.c | 21 | ||||
-rw-r--r-- | src/map/clif.c | 24 | ||||
-rw-r--r-- | src/map/map.h | 17 | ||||
-rw-r--r-- | src/map/pc.c | 15 |
4 files changed, 76 insertions, 1 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index ea92f34..d10139f 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -220,6 +220,8 @@ ATCOMMAND_FUNC(set_magic); // [Fate] ATCOMMAND_FUNC(magic_info); // [Fate] ATCOMMAND_FUNC(log); // [Fate] ATCOMMAND_FUNC(tee); // [Fate] +ATCOMMAND_FUNC(invisible); // [Fate] +ATCOMMAND_FUNC(visible); // [Fate] #ifndef TXT_ONLY ATCOMMAND_FUNC(checkmail); // [Valaris] @@ -471,6 +473,8 @@ static AtCommandInfo atcommand_info[] = { { AtCommand_Log, "@l", 60, atcommand_log }, // [Fate] { AtCommand_Tee, "@tee", 60, atcommand_tee }, // [Fate] { AtCommand_Tee, "@t", 60, atcommand_tee }, // [Fate] + { AtCommand_Tee, "@invisible", 60, atcommand_invisible }, // [Fate] + { AtCommand_Tee, "@visible", 60, atcommand_visible }, // [Fate] #ifndef TXT_ONLY // sql-only commands { AtCommand_CheckMail, "@checkmail", 1, atcommand_listmail }, // [Valaris] @@ -8037,3 +8041,20 @@ atcommand_tee(const int fd, struct map_session_data* sd, clif_message(&sd->bl, data); return 0; } + +int +atcommand_invisible(const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + pc_invisibility(sd, 1); + return 0; +} + +int +atcommand_visible(const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + pc_invisibility(sd, 0); + return 0; +} + diff --git a/src/map/clif.c b/src/map/clif.c index 653865b..82860e5 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -286,6 +286,27 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) { if (type != ALL_CLIENT) { nullpo_retr(0, bl); + + if (bl->type == BL_PC) { + struct map_session_data *sd = (struct map_session_data *) bl; + if (sd->status.option & OPTION_INVISIBILITY) { + // Obscure hidden GMs + + switch (type) { + case AREA: + case AREA_WOC: + type = SELF; + break; + + case AREA_WOS: + case AREA_WOSC: + return; + + default: + break; + } + } + } } switch(type) { @@ -3565,6 +3586,9 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds { int len; + if (dstsd->status.option & OPTION_INVISIBILITY) + return; + nullpo_retv(sd); nullpo_retv(dstsd); diff --git a/src/map/map.h b/src/map/map.h index afaf61e..d407016 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -41,7 +41,22 @@ #define DEFAULT_AUTOSAVE_INTERVAL 60*1000 -#define OPTION_HIDE 0x40 +// [Fate] status.option properties. These are persistent status changes. +// IDs that are not listed are not used in the code (to the best of my knowledge) +#define OPTION_HIDE2 0x0002 // apparently some weaker non-GM hide +#define OPTION_CLOAK 0x0004 +#define OPTION_10 0x0010 +#define OPTION_20 0x0020 +#define OPTION_HIDE 0x0040 // [Fate] This is the GM `@hide' flag +#define OPTION_800 0x0800 +#define OPTION_INVISIBILITY 0x1000 // [Fate] Complete invisibility to other clients +#define OPTION_SCRIBE 0x2000 // [Fate] Auto-logging of nearby comments +#define OPTION_CHASEWALK 0x4000 + +// Below are special clif_changestatus() IDs reserved for option updates +#define CLIF_OPTION_SC_BASE 0x1000 +#define CLIF_OPTION_SC_INVISIBILITY (CLIF_OPTION_SC_BASE) +#define CLIF_OPTION_SC_SCRIBE (CLIF_OPTION_SC_BASE + 1) enum { BL_NUL, BL_PC, BL_NPC, BL_MOB, BL_ITEM, BL_CHAT, BL_SKILL, BL_PET, BL_SPELL }; enum { WARP, SHOP, SCRIPT, MONS, MESSAGE }; diff --git a/src/map/pc.c b/src/map/pc.c index 62e2cd5..bed6fc6 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -7765,3 +7765,18 @@ pc_cleanup(struct map_session_data *sd) { magic_stop_completely(sd); } + + +void +pc_invisibility(struct map_session_data *sd, int enabled) +{ + if (enabled && !(sd->status.option & OPTION_INVISIBILITY)) { + clif_clearchar_area(&sd->bl, 3); + sd->status.option |= OPTION_INVISIBILITY; + clif_status_change(&sd->bl, CLIF_OPTION_SC_INVISIBILITY, 1); + } else { + sd->status.option &= ~OPTION_INVISIBILITY; + clif_status_change(&sd->bl, CLIF_OPTION_SC_INVISIBILITY, 0); + pc_setpos(sd, map[sd->bl.m].name, sd->bl.x, sd->bl.y, 3); + } +} |