From 7535be49a31cddbd56586934ac3c7cef9e592bb5 Mon Sep 17 00:00:00 2001 From: Lucien Date: Sat, 11 Jan 2025 23:14:32 -0800 Subject: [PATCH] First pass of gatekeeper mob. --- src/db.cpp | 14 +++++-- src/limits.cpp | 10 +++++ src/medit.cpp | 4 +- src/spec_assign.cpp | 7 ++++ src/spec_procs.cpp | 95 +++++++++++++++++++++++++++++++++++++++++++++ src/utils.cpp | 9 ++++- 6 files changed, 134 insertions(+), 5 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 78b62bdf4..cb074657f 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -4277,7 +4277,6 @@ struct char_data *read_mobile(int nr, int type) mob->player.time.logon = time(0); mob->player.tradition = mob->player.aspect = 0; mob->char_specials.saved.left_handed = (!number(0, 9) ? 1 : 0); - GET_POS(mob) = (GET_DEFAULT_POS(mob) > 0 ? GET_DEFAULT_POS(mob) : POS_STANDING); mob_index[i].number++; @@ -4309,6 +4308,15 @@ struct char_data *read_mobile(int nr, int type) affect_total(mob); + GET_POS(mob) = (GET_DEFAULT_POS(mob) > 0 ? GET_DEFAULT_POS(mob) : POS_STANDING); + + if (GET_POS(mob) == POS_STUNNED) { + GET_MENTAL(mob) = -10 * 100; + } else if (GET_POS(mob) == POS_MORTALLYW) { + GET_PHYSICAL(mob) = 0; + GET_MENTAL(mob) = 0; + } + if ((GET_MOB_SPEC(mob) || GET_MOB_SPEC2(mob)) && !MOB_FLAGGED(mob, MOB_SPEC)) MOB_FLAGS(mob).SetBit(MOB_SPEC); @@ -5771,8 +5779,8 @@ void reset_char(struct char_data * ch) ch->next_fighting = NULL; ch->next_in_room = NULL; FIGHTING(ch) = NULL; - ch->char_specials.position = POS_STANDING; - ch->mob_specials.default_pos = POS_STANDING; + GET_POS(ch) = POS_STANDING; + GET_DEFAULT_POS(ch) = POS_STANDING; calc_weight(ch); if (GET_PHYSICAL(ch) < 100) diff --git a/src/limits.cpp b/src/limits.cpp index 33600b291..7c0f685e2 100644 --- a/src/limits.cpp +++ b/src/limits.cpp @@ -64,6 +64,11 @@ void mental_gain(struct char_data * ch) return; } + // Can't regenerate? Skip. + if (IS_NPC(ch) && GET_DEFAULT_POS(ch) <= POS_STUNNED) { + return; + } + bool is_npc = IS_NPC(ch); if (is_npc && ch->desc && ch->desc->original && PLR_FLAGS(ch->desc->original).IsSet(PLR_PROJECT) && GET_MOB_VNUM(ch) == 22) { @@ -164,6 +169,11 @@ void physical_gain(struct char_data * ch) return; } + // Can't regenerate? Skip. + if (IS_NPC(ch) && GET_DEFAULT_POS(ch) == POS_MORTALLYW) { + return; + } + int gain = 0; bool is_npc = IS_NPC(ch); diff --git a/src/medit.cpp b/src/medit.cpp index 3a1e6a8b4..9f53c8a6d 100644 --- a/src/medit.cpp +++ b/src/medit.cpp @@ -518,6 +518,8 @@ void medit_parse(struct descriptor_data *d, const char *arg) for (struct obj_data *obj = mob_proto[mob_number].bioware; obj; obj = obj->next_content) obj->carried_by = &mob_proto[mob_number]; + // Diagnostic catch for mortallyw not sticking. + assert(GET_DEFAULT_POS(&mob_proto[mob_number]) == GET_DEFAULT_POS(d->edit_mob)); } else { // if not, we need to make a new spot in the list int counter; int found = FALSE; @@ -1880,7 +1882,7 @@ void write_mobs_to_disk(vnum_t zone_num) if (GET_POS(mob) != POS_STANDING) fprintf(fp, "Position:\t%s\n", position_types[(int)GET_POS(mob)]); - if (GET_DEFAULT_POS(mob)) + if (GET_DEFAULT_POS(mob) != POS_STANDING && GET_DEFAULT_POS(mob) != POS_DEAD) fprintf(fp, "DefaultPos:\t%s\n", position_types[(int)GET_DEFAULT_POS(mob)]); diff --git a/src/spec_assign.cpp b/src/spec_assign.cpp index 9f8575005..3a64f5f0c 100644 --- a/src/spec_assign.cpp +++ b/src/spec_assign.cpp @@ -653,6 +653,13 @@ void assign_mobiles(void) ASSIGNMOB(95902, receptionist_95902); ASSIGNMOB(31135, graffiti_cleaner); ASSIGNMOB(6902, soulbound_unbinder); + + + SPECIAL(grenada_gatekeeper); + + ASSIGNMOB(101310, grenada_gatekeeper) + ASSIGNMOB(101311, grenada_gatekeeper) + ASSIGNMOB(101312, grenada_gatekeeper) #else ASSIGNMOB(10011, soulbound_unbinder); #endif diff --git a/src/spec_procs.cpp b/src/spec_procs.cpp index c81f12360..5f51fa613 100644 --- a/src/spec_procs.cpp +++ b/src/spec_procs.cpp @@ -7883,6 +7883,101 @@ SPECIAL(oppressive_atmosphere) { return FALSE; } +#define GATEKEEPER_A_CODEWORD "the game is more fun if you don't try to look things up like this" +#define GATEKEEPER_B_CODEWORD "the game is more fun if you don't try to look things up like this" +#define GATEKEEPER_C_CODEWORD "the game is more fun if you don't try to look things up like this" +SPECIAL(grenada_gatekeeper) +{ + struct char_data *mob = (struct char_data *) me; + if (!AWAKE(mob)) + return FALSE; + + switch (GET_MOB_VNUM(mob)) { + case 101310: + if (CMD_IS("north")) { + if (EXIT(ch, NORTH) && !IS_SET(EXIT(ch, NORTH)->exit_info, EX_CLOSED)) { + send_to_char(ch, "The door slides shut as you approach it.\r\n"); + SET_BIT(EXIT(ch, NORTH)->exit_info, EX_CLOSED); + return TRUE; + } + } + break; + case 101311: + if (CMD_IS("west")) { + if (EXIT(ch, WEST) && !IS_SET(EXIT(ch, WEST)->exit_info, EX_CLOSED)) { + send_to_char(ch, "The door slides shut as you approach it.\r\n"); + SET_BIT(EXIT(ch, WEST)->exit_info, EX_CLOSED); + return TRUE; + } + } + break; + case 101312: + if (CMD_IS("east")) { + if (EXIT(ch, EAST) && !IS_SET(EXIT(ch, EAST)->exit_info, EX_CLOSED)) { + send_to_char(ch, "The door slides shut as you approach it.\r\n"); + SET_BIT(EXIT(ch, EAST)->exit_info, EX_CLOSED); + return TRUE; + } + } + break; + default: + mudlog_vfprintf(ch, LOG_SYSLOG, "SYSERR: Got mob vnum %ld to grenada_gatekeeper spec!", GET_MOB_VNUM(mob)); + return FALSE; + } + + if ((CMD_IS("say") || CMD_IS("'") || CMD_IS("sayto")) && !IS_ASTRAL(ch) && *argument) { + skip_spaces(&argument); + + if (CMD_IS("sayto")) { + char sayto_target[MAX_INPUT_LENGTH]; + one_argument(argument, sayto_target); + // Eventually we should verify the sayto target, but for now, we skip it. This block just serves to allow the next to identify the blue-eyes string. + } + + // Switch based on the mob's vnum. + bool said_passphrase = FALSE; + vnum_t to_room_vnum; + + switch (GET_MOB_VNUM(mob)) { + case 101310: + said_passphrase = str_str(argument, GATEKEEPER_A_CODEWORD); + to_room_vnum = 101302; + break; + case 101311: + said_passphrase = str_str(argument, GATEKEEPER_B_CODEWORD); + to_room_vnum = 101311; + break; + case 101312: + said_passphrase = str_str(argument, GATEKEEPER_C_CODEWORD); + to_room_vnum = 101321; + break; + default: + mudlog_vfprintf(ch, LOG_SYSLOG, "SYSERR: Got mob vnum %ld to grenada_gatekeeper spec!", GET_MOB_VNUM(mob)); + return FALSE; + } + + if (said_passphrase) { + act("$N glances around, then ushers you towards the sliding door.", FALSE, ch, NULL, mob, TO_CHAR); + act("$N glances around, then ushers $n towards the sliding door.", TRUE, ch, NULL, mob, TO_NOTVICT); + act("You glance around, then usher $N towards the sliding door.", FALSE, ch, NULL, mob, TO_CHAR); + + rnum_t to_room = real_room(to_room_vnum); + if (to_room < 0) { + mudlog_vfprintf(ch, LOG_SYSLOG, "SYSERR: Missing room %ld for gatekeeper_a proc. Sending to Dante's.", to_room_vnum); + to_room = real_room(RM_ENTRANCE_TO_DANTES); + } + + char_from_room(ch); + char_to_room(ch, &world[to_room]); + + act("$n is ushered in.", FALSE, ch, NULL, mob, TO_ROOM); + return TRUE; + } + } + + return FALSE; +} + /* SPECIAL(business_card_printer) { struct obj_data *printer = (struct obj_data *) me; diff --git a/src/utils.cpp b/src/utils.cpp index f90fb8227..a0b52268f 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -3559,7 +3559,6 @@ void copy_over_necessary_info(struct char_data *original, struct char_data *clon REPLICATE(char_specials.hunting); REPLICATE(char_specials.programming); REPLICATE(char_specials.defined_position); - REPLICATE(char_specials.position); REPLICATE(char_specials.subscribe); REPLICATE(char_specials.rigging); REPLICATE(char_specials.mindlink); @@ -3586,6 +3585,14 @@ void copy_over_necessary_info(struct char_data *original, struct char_data *clon REPLICATE(points.extras[0]); REPLICATE(points.extras[1]); + if (GET_POS(clone) != GET_POS(original)) { + // Copy over important positions (fighting, stunned, morted) + if (GET_POS(original) == POS_FIGHTING || GET_POS(original) == POS_STUNNED || GET_POS(original) == POS_MORTALLYW) { + GET_POS(clone) = GET_POS(original); + } + // Otherwise, assume the medited version is right + } + REPLICATE(vfront); copy_vision_from_original_to_clone(original, clone);