From b6bbe522bbb61ea952fa2757a566c16760c7c884 Mon Sep 17 00:00:00 2001 From: kinther Date: Tue, 30 Dec 2025 13:31:56 -0800 Subject: [PATCH] Mount update 1 --- README.md | 5 +- lib/world/mob/1.mob | 70 ++++++++++++----- src/act.h | 2 + src/act.informative.c | 104 ++++++++++++++++++++++++- src/act.movement.c | 177 ++++++++++++++++++++++++++++++++++++++++-- src/constants.c | 2 + src/handler.c | 16 ++++ src/interpreter.c | 2 + src/mobact.c | 1 + src/structs.h | 8 +- src/utils.h | 4 + 11 files changed, 359 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index bc81ff2..de12984 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,9 @@ Changes in v1.1.0-alpha: * "audit ac" command for immortals (formerly "acaudit"), allowing for further audit commands in the future * Minor score output change to only show quest status while on a quest, PC/NPC name, sdesc, and current ldesc * Added ability to reroll initial stats if they are not to player's liking, and undo reroll if needed - * Removed alignment from game - no more GOOD/EVIL flags and restrictions on items/shops + * Removed alignment from game - no more GOOD/EVIL flags or restrictions on shops + * Removed ANTI_ flags related to class restrictions on what objects they can use + * Mounts added to help with long trips, and ability to use them as pack animals Features to be implemented in the next few releases: @@ -68,7 +70,6 @@ Features to be implemented in the next few releases: * SECTOR/ROOM type changes to make terrain movement easier or more difficult * Subclass selection to personalize character further * Combat is slowed down so it isn't over in < 15 seconds (unless you're far outmatched) -* Mounts added to help with long trips * Wagons added to help with caravans * BUILDING object type created to allow enter/leave * Updated BUILDING object type so that it can be damaged and no longer enterable (but someone can leave at cost to health) diff --git a/lib/world/mob/1.mob b/lib/world/mob/1.mob index 6defa73..3be2f7b 100644 --- a/lib/world/mob/1.mob +++ b/lib/world/mob/1.mob @@ -20,6 +20,7 @@ B + ~ 6218 0 0 0 0 0 0 0 0 E 1 3d20+40 @@ -38,17 +39,17 @@ Skill 145 5 Skill 146 5 Skill 147 5 E -L 3 118 1 -L 5 131 1 -L 6 110 1 -L 7 108 1 -L 8 115 1 -L 9 124 1 -L 10 107 1 -L 11 111 1 -L 15 117 1 -L 16 117 1 L 17 127 1 +L 16 117 1 +L 15 117 1 +L 11 111 1 +L 10 107 1 +L 9 124 1 +L 8 115 1 +L 7 108 1 +L 6 110 1 +L 5 131 1 +L 3 118 1 #101 Sally~ slim lanky human soldier guard~ @@ -72,6 +73,7 @@ B + ~ 6218 0 0 0 0 0 0 0 0 E 1 3d20+40 @@ -92,17 +94,17 @@ Skill 152 5 Skill 156 5 Skill 163 5 E -L 17 127 1 -L 16 117 1 -L 15 117 1 -L 11 111 1 -L 10 107 1 -L 9 124 1 -L 8 115 1 -L 7 108 1 -L 6 110 1 -L 5 131 1 L 3 118 1 +L 5 131 1 +L 6 110 1 +L 7 108 1 +L 8 115 1 +L 9 124 1 +L 10 107 1 +L 11 111 1 +L 15 117 1 +L 16 117 1 +L 17 127 1 #102 Baldy~ barkeep stocky bald~ @@ -126,13 +128,14 @@ B + ~ 10 0 0 0 0 0 0 0 0 E 1 3d12+60 8 8 1 E -L 14 113 1 L 9 112 1 +L 14 113 1 #103 Lanky~ woman lanky scarred~ @@ -157,6 +160,7 @@ B + ~ 10 0 0 0 0 0 0 0 0 E 1 3d8+60 @@ -191,6 +195,7 @@ B + It's a rat. ~ 8 0 0 0 0 0 0 0 0 E @@ -206,4 +211,27 @@ Species: 25 Age: 42 AtkT 4 E +#105 +Kank~ +kank sandy brown~ +a sandy brown kank~ +A sandy brown kank is here, clacking its pincers. +~ +It looks unfinished. +~ +B +No background has been recorded. +~ +1048584 0 0 0 0 0 0 0 0 E +0 0d0+10 +8 8 0 +Str: 18 +Dex: 5 +Int: 2 +Wis: 7 +Con: 18 +Cha: 1 +Species: 21 +AtkT 4 +E $ diff --git a/src/act.h b/src/act.h index fc47183..38971b9 100644 --- a/src/act.h +++ b/src/act.h @@ -176,8 +176,10 @@ ACMD(do_gen_door); ACMD(do_enter); ACMD(do_follow); ACMD(do_leave); +ACMD(do_mount); ACMD(do_move); ACMD(do_rest); +ACMD(do_dismount); ACMD(do_sit); ACMD(do_sleep); ACMD(do_stand); diff --git a/src/act.informative.c b/src/act.informative.c index b972054..19d3328 100644 --- a/src/act.informative.c +++ b/src/act.informative.c @@ -569,6 +569,43 @@ static void list_one_char(struct char_data *i, struct char_data *ch) CCNRM(ch, C_NRM)); } + if (AFF_FLAGGED(i, AFF_MOUNTED) && MOUNT(i) && + IN_ROOM(MOUNT(i)) == IN_ROOM(i) && + MOB_FLAGGED(MOUNT(i), MOB_MOUNT)) { + const char *rdesc = get_char_sdesc(i); + const char *mdesc = get_char_sdesc(MOUNT(i)); + + if (rdesc && *rdesc) + send_to_char(ch, "%c%s", UPPER(*rdesc), rdesc + 1); + else + send_to_char(ch, "Someone"); + + if (mdesc && *mdesc) + send_to_char(ch, " is riding %s here.", mdesc); + else + send_to_char(ch, " is riding someone here."); + + if (AFF_FLAGGED(i, AFF_INVISIBLE)) + send_to_char(ch, " (invisible)"); + if (AFF_FLAGGED(i, AFF_HIDE)) + send_to_char(ch, " (hidden)"); + if (!IS_NPC(i) && !i->desc) + send_to_char(ch, " (linkless)"); + if (!IS_NPC(i) && PLR_FLAGGED(i, PLR_WRITING)) + send_to_char(ch, " (writing)"); + if (!IS_NPC(i) && PRF_FLAGGED(i, PRF_BUILDWALK)) + send_to_char(ch, " (buildwalk)"); + if (!IS_NPC(i) && PRF_FLAGGED(i, PRF_AFK)) + send_to_char(ch, " (AFK)"); + + send_to_char(ch, "\r\n"); + + if (AFF_FLAGGED(i, AFF_SANCTUARY)) + act("...$e glows with a bright light!", FALSE, i, 0, ch, TO_VICT); + + return; + } + /* Custom ldesc overrides position-based output. */ if (i->char_specials.custom_ldesc && i->player.long_descr) { if (AFF_FLAGGED(i, AFF_INVISIBLE)) @@ -692,6 +729,23 @@ static void build_current_ldesc(const struct char_data *ch, char *out, size_t ou return; } + if (AFF_FLAGGED(ch, AFF_MOUNTED) && MOUNT(ch) && + IN_ROOM(MOUNT(ch)) == IN_ROOM(ch) && + MOB_FLAGGED(MOUNT(ch), MOB_MOUNT)) { + const char *rdesc = get_char_sdesc(ch); + const char *mdesc = get_char_sdesc(MOUNT(ch)); + + if (!rdesc || !*rdesc) + rdesc = "someone"; + if (!mdesc || !*mdesc) + mdesc = "someone"; + + snprintf(out, outsz, "%c%s is riding %s here.", + UPPER(*rdesc), rdesc + 1, mdesc); + strip_trailing_crlf(out); + return; + } + if (ch->char_specials.custom_ldesc && ch->player.long_descr) { strlcpy(out, ch->player.long_descr, outsz); strip_trailing_crlf(out); @@ -746,6 +800,9 @@ static void list_char_to_char(struct char_data *list, struct char_data *ch) if (!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT) && IS_NPC(i) && i->player.long_descr && *i->player.long_descr == '.') continue; + if (RIDDEN_BY(i) && IN_ROOM(RIDDEN_BY(i)) == IN_ROOM(i) && + CAN_SEE(ch, RIDDEN_BY(i))) + continue; send_to_char(ch, "%s", CCYEL(ch, C_NRM)); if (CAN_SEE(ch, i)) list_one_char(i, ch); @@ -972,6 +1029,9 @@ static bool look_list_direction_chars(struct char_data *ch, room_rnum room) if (!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT) && IS_NPC(tch) && tch->player.long_descr && *tch->player.long_descr == '.') continue; + if (RIDDEN_BY(tch) && IN_ROOM(RIDDEN_BY(tch)) == room && + CAN_SEE(ch, RIDDEN_BY(tch))) + continue; if (AFF_FLAGGED(tch, AFF_HIDE)) { if (CAN_SEE(ch, tch) || look_can_spot_hidden(ch, tch, room)) { @@ -1135,6 +1195,42 @@ static void look_at_target(struct char_data *ch, char *arg) return; } + if (!found_char) { + struct char_data *tch; + char tmp[MAX_INPUT_LENGTH]; + char *name = tmp; + int matchnum; + + strlcpy(tmp, arg, sizeof(tmp)); + matchnum = get_number(&name); + if (matchnum > 0) { + for (tch = world[IN_ROOM(ch)].people; tch && matchnum; tch = tch->next_in_room) { + if (tch == ch) + continue; + if (!AFF_FLAGGED(tch, AFF_MOUNTED)) + continue; + if (!CAN_SEE(ch, tch)) + continue; + if (isname(name, (char *)get_char_sdesc(tch))) { + if (--matchnum == 0) { + found_char = tch; + break; + } + } + } + } + } + + if (found_char != NULL) { + look_at_char(found_char, ch); + if (ch != found_char) { + if (CAN_SEE(found_char, ch)) + act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT); + act("$n looks at $N.", TRUE, ch, 0, found_char, TO_NOTVICT); + } + return; + } + /* Strip off "number." from 2.foo and friends. */ if (!(fnum = get_number(&arg))) { send_to_char(ch, "Look at what?\r\n"); @@ -1436,7 +1532,13 @@ ACMD(do_score) FIGHTING(ch) ? PERS(FIGHTING(ch), ch) : "thin air"); break; case POS_STANDING: - send_to_char(ch, "You are standing.\r\n"); + if (AFF_FLAGGED(ch, AFF_MOUNTED) && MOUNT(ch) && + IN_ROOM(MOUNT(ch)) == IN_ROOM(ch) && + MOB_FLAGGED(MOUNT(ch), MOB_MOUNT)) { + send_to_char(ch, "You are riding %s.\r\n", get_char_sdesc(MOUNT(ch))); + } else { + send_to_char(ch, "You are standing.\r\n"); + } break; default: send_to_char(ch, "You are floating.\r\n"); diff --git a/src/act.movement.c b/src/act.movement.c index 224993f..036c5ab 100644 --- a/src/act.movement.c +++ b/src/act.movement.c @@ -44,6 +44,9 @@ static bool validate_furniture_use(struct char_data *ch, struct obj_data *furnit bool already_there); static void attach_char_to_furniture(struct char_data *ch, struct obj_data *furniture); static const char *position_gerund(int pos); +static void clear_mount_state(struct char_data *ch); +static bool mount_skill_check(struct char_data *ch, int dc); +static bool resolve_mounted_move(struct char_data *ch, struct char_data **mount); /* simple function to determine if char can walk on water */ @@ -263,6 +266,67 @@ static const char *position_gerund(int pos) return "using"; } } + +static void clear_mount_state(struct char_data *ch) +{ + struct char_data *mount; + + if (!ch) + return; + + mount = MOUNT(ch); + if (mount && RIDDEN_BY(mount) == ch) + RIDDEN_BY(mount) = NULL; + MOUNT(ch) = NULL; + REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_MOUNTED); +} + +static bool mount_skill_check(struct char_data *ch, int dc) +{ + int total = roll_skill_check(ch, SKILL_ANIMAL_HANDLING, 0, NULL); + bool success = (total >= dc); + + gain_skill(ch, "animal handling", success); + return success; +} + +static bool resolve_mounted_move(struct char_data *ch, struct char_data **mount) +{ + struct char_data *mount_ch; + + if (!AFF_FLAGGED(ch, AFF_MOUNTED)) + return FALSE; + + mount_ch = MOUNT(ch); + if (!mount_ch || IN_ROOM(mount_ch) != IN_ROOM(ch)) { + clear_mount_state(ch); + send_to_char(ch, "You aren't mounted on anything.\r\n"); + return FALSE; + } + + if (!mount_skill_check(ch, 5)) { + send_to_char(ch, "%s refuses to move.\r\n", get_char_sdesc(mount_ch)); + act("$n tries to urge $N forward, but $N refuses to move.", + TRUE, ch, 0, mount_ch, TO_ROOM); + return FALSE; + } + + if (!mount_skill_check(ch, 3)) { + int dam = dice(1, 8); + + send_to_char(ch, "You are thrown from %s!\r\n", get_char_sdesc(mount_ch)); + act("$n is thrown from $N!", TRUE, ch, 0, mount_ch, TO_ROOM); + clear_mount_state(ch); + GET_POS(ch) = POS_RESTING; + WAIT_STATE(ch, PULSE_VIOLENCE); + damage(ch, ch, dam, TYPE_SUFFERING); + return FALSE; + } + + if (mount) + *mount = mount_ch; + return TRUE; +} /** Move a PC/NPC character from their current location to a new location. This * is the standard movement locomotion function that all normal walking * movement by characters should be sent through. This function also defines @@ -293,6 +357,9 @@ int do_simple_move(struct char_data *ch, int dir, int need_specials_check) /* How many stamina points are required to travel from was_in to going_to. * We redefine this later when we need it. */ int need_movement = 0; + /* Character whose stamina is used for movement (mounts override). */ + struct char_data *stamina_ch = ch; + bool mounted_move = FALSE; /* Contains the "leave" message to display to the was_in room. */ char leave_message[SMALL_BUFSIZE]; /*---------------------------------------------------------------------*/ @@ -406,10 +473,18 @@ int do_simple_move(struct char_data *ch, int dir, int need_specials_check) movement_loss[SECT(going_to)]) / 2; /* Move Point Requirement Check */ - if (GET_STAMINA(ch) < need_movement && !IS_NPC(ch)) + if (AFF_FLAGGED(ch, AFF_MOUNTED) && MOUNT(ch) && IN_ROOM(MOUNT(ch)) == was_in) + { + stamina_ch = MOUNT(ch); + mounted_move = TRUE; + } + + if (GET_STAMINA(stamina_ch) < need_movement && (mounted_move || !IS_NPC(ch))) { if (need_specials_check && ch->master) send_to_char(ch, "You are too exhausted to follow.\r\n"); + else if (mounted_move) + send_to_char(ch, "Your mount is too exhausted.\r\n"); else send_to_char(ch, "You are too exhausted.\r\n"); @@ -423,8 +498,8 @@ int do_simple_move(struct char_data *ch, int dir, int need_specials_check) /* Begin: the leave operation. */ /*---------------------------------------------------------------------*/ /* If applicable, subtract movement cost. */ - if (GET_LEVEL(ch) < LVL_IMMORT && !IS_NPC(ch)) - GET_STAMINA(ch) -= need_movement; + if (GET_LEVEL(ch) < LVL_IMMORT && (mounted_move || !IS_NPC(ch))) + GET_STAMINA(stamina_ch) -= need_movement; /* Generate the leave message and display to others in the was_in room. */ if (AFF_FLAGGED(ch, AFF_SNEAK)) { @@ -500,6 +575,7 @@ int perform_move(struct char_data *ch, int dir, int need_specials_check) { room_rnum was_in; struct follow_type *k, *next; + struct char_data *mount = NULL; if (ch == NULL || dir < 0 || dir >= NUM_OF_DIRS || FIGHTING(ch)) return (0); @@ -513,13 +589,22 @@ int perform_move(struct char_data *ch, int dir, int need_specials_check) else send_to_char(ch, "It seems to be closed.\r\n"); } else { - if (!ch->followers) - return (do_simple_move(ch, dir, need_specials_check)); - was_in = IN_ROOM(ch); + if (AFF_FLAGGED(ch, AFF_MOUNTED) && + !resolve_mounted_move(ch, &mount)) + return (0); + if (!do_simple_move(ch, dir, need_specials_check)) return (0); + if (mount && IN_ROOM(mount) == was_in) { + char_from_room(mount); + char_to_room(mount, IN_ROOM(ch)); + } + + if (!ch->followers) + return (1); + for (k = ch->followers; k; k = next) { next = k->next; if ((IN_ROOM(k->follower) == was_in) && @@ -941,6 +1026,11 @@ ACMD(do_stand) int ordinal = 0; int orig_pos = GET_POS(ch); + if (AFF_FLAGGED(ch, AFF_MOUNTED)) { + send_to_char(ch, "You must dismount first.\r\n"); + return; + } + if (*argument) { if (!extract_furniture_token(ch, argument, token, sizeof(token), "Stand")) return; @@ -1067,6 +1157,11 @@ ACMD(do_sit) int ordinal = 0; int orig_pos = GET_POS(ch); + if (AFF_FLAGGED(ch, AFF_MOUNTED)) { + send_to_char(ch, "You must dismount first.\r\n"); + return; + } + if (*argument) { if (!extract_furniture_token(ch, argument, token, sizeof(token), "Sit")) return; @@ -1175,6 +1270,11 @@ ACMD(do_rest) bool has_target = FALSE, used_number = FALSE; int ordinal = 0; + if (AFF_FLAGGED(ch, AFF_MOUNTED)) { + send_to_char(ch, "You must dismount first.\r\n"); + return; + } + if (*argument) { if (!extract_furniture_token(ch, argument, token, sizeof(token), "Rest")) return; @@ -1303,6 +1403,11 @@ ACMD(do_sleep) bool has_target = FALSE, used_number = FALSE; int ordinal = 0; + if (AFF_FLAGGED(ch, AFF_MOUNTED)) { + send_to_char(ch, "You must dismount first.\r\n"); + return; + } + if (*argument) { if (!extract_furniture_token(ch, argument, token, sizeof(token), "Sleep")) return; @@ -1484,6 +1589,66 @@ ACMD(do_follow) } } +ACMD(do_mount) +{ + char arg[MAX_INPUT_LENGTH]; + struct char_data *mount; + + one_argument(argument, arg); + + if (!*arg) { + send_to_char(ch, "Mount what?\r\n"); + return; + } + + if (AFF_FLAGGED(ch, AFF_MOUNTED)) { + send_to_char(ch, "You are already mounted.\r\n"); + return; + } + + if (!(mount = get_char_vis(ch, arg, NULL, FIND_CHAR_ROOM))) { + send_to_char(ch, "%s", CONFIG_NOPERSON); + return; + } + + if (mount == ch) { + send_to_char(ch, "You can't mount yourself.\r\n"); + return; + } + + if (!IS_NPC(mount) || !MOB_FLAGGED(mount, MOB_MOUNT)) { + send_to_char(ch, "You can't mount %s!\r\n", get_char_sdesc(mount)); + return; + } + + if (RIDDEN_BY(mount)) { + act("$N is already being ridden.", FALSE, ch, 0, mount, TO_CHAR); + return; + } + + SET_BIT_AR(AFF_FLAGS(ch), AFF_MOUNTED); + MOUNT(ch) = mount; + RIDDEN_BY(mount) = ch; + + act("You mount $N.", FALSE, ch, 0, mount, TO_CHAR); + act("$n mounts $N.", TRUE, ch, 0, mount, TO_ROOM); +} + +ACMD(do_dismount) +{ + struct char_data *mount = MOUNT(ch); + + if (!AFF_FLAGGED(ch, AFF_MOUNTED) || !mount) { + clear_mount_state(ch); + send_to_char(ch, "You aren't mounted on anything.\r\n"); + return; + } + + act("You dismount $N.", FALSE, ch, 0, mount, TO_CHAR); + act("$n dismounts $N.", TRUE, ch, 0, mount, TO_ROOM); + clear_mount_state(ch); +} + ACMD(do_unfollow) { if (ch->master) { diff --git a/src/constants.c b/src/constants.c index 6fe471b..dd7a187 100644 --- a/src/constants.c +++ b/src/constants.c @@ -240,6 +240,7 @@ const char *action_bits[] = { "NO_BLIND", "NO_KILL", "DEAD", /* You should never see this. */ + "MOUNT", "\n" }; @@ -311,6 +312,7 @@ const char *affected_bits[] = "CHARM", "BANDAGED", "LISTEN", + "MOUNTED", "\n" }; diff --git a/src/handler.c b/src/handler.c index 3b2acbc..ec6c3d1 100644 --- a/src/handler.c +++ b/src/handler.c @@ -1003,6 +1003,22 @@ void extract_char_final(struct char_data *ch) } } + if (AFF_FLAGGED(ch, AFF_MOUNTED) || MOUNT(ch)) { + struct char_data *mount = MOUNT(ch); + if (mount && RIDDEN_BY(mount) == ch) + RIDDEN_BY(mount) = NULL; + MOUNT(ch) = NULL; + REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_MOUNTED); + } + if (RIDDEN_BY(ch)) { + struct char_data *rider = RIDDEN_BY(ch); + if (rider && MOUNT(rider) == ch) { + MOUNT(rider) = NULL; + REMOVE_BIT_AR(AFF_FLAGS(rider), AFF_MOUNTED); + } + RIDDEN_BY(ch) = NULL; + } + /* On with the character's assets... */ if (ch->followers || ch->master) die_follower(ch); diff --git a/src/interpreter.c b/src/interpreter.c index 1b63132..99a938a 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -137,6 +137,7 @@ cpp_extern const struct command_info cmd_info[] = { { "detach" , "detach" , POS_DEAD , do_detach , LVL_BUILDER, 0 }, { "diagnose" , "diag" , POS_RESTING , do_diagnose , 0, 0 }, { "dig" , "dig" , POS_DEAD , do_dig , LVL_BUILDER, 0 }, + { "dismount" , "dism" , POS_STANDING, do_dismount , 0, 0 }, { "display" , "disp" , POS_DEAD , do_display , 0, 0 }, { "drink" , "dri" , POS_RESTING , do_drink , 0, SCMD_DRINK }, { "drop" , "dro" , POS_RESTING , do_drop , 0, SCMD_DROP }, @@ -198,6 +199,7 @@ cpp_extern const struct command_info cmd_info[] = { { "last" , "last" , POS_DEAD , do_last , LVL_GOD, 0 }, { "leave" , "lea" , POS_STANDING, do_leave , 0, 0 }, { "list" , "lis" , POS_STANDING, do_not_here , 0, 0 }, + { "mount" , "mou" , POS_STANDING, do_mount , 0, 0 }, { "listen" , "lisn" , POS_RESTING , do_listen , 0, 0 }, { "links" , "lin" , POS_STANDING, do_links , LVL_GOD, 0 }, { "lock" , "loc" , POS_SITTING , do_gen_door , 0, SCMD_LOCK }, diff --git a/src/mobact.c b/src/mobact.c index 2e38d39..9f5bf34 100644 --- a/src/mobact.c +++ b/src/mobact.c @@ -81,6 +81,7 @@ void mobile_activity(void) ((door = rand_number(0, 18)) < DIR_COUNT) && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_DEATH) && + !RIDDEN_BY(ch) && (!MOB_FLAGGED(ch, MOB_STAY_ZONE) || (world[EXIT(ch, door)->to_room].zone == world[IN_ROOM(ch)].zone))) { diff --git a/src/structs.h b/src/structs.h index 9653622..ce16dcb 100644 --- a/src/structs.h +++ b/src/structs.h @@ -267,8 +267,9 @@ #define MOB_NOBLIND 17 /**< Mob can't be blinded */ #define MOB_NOKILL 18 /**< Mob can't be attacked */ #define MOB_NOTDEADYET 19 /**< (R) Mob being extracted */ +#define MOB_MOUNT 20 /**< Mob can be mounted */ -#define NUM_MOB_FLAGS 19 +#define NUM_MOB_FLAGS 21 /* Preference flags: used by char_data.player_specials.pref */ #define PRF_BRIEF 0 /**< Room descs won't normally be shown */ @@ -333,8 +334,9 @@ #define AFF_CHARM 22 /**< Char is charmed */ #define AFF_BANDAGED 23 /**< Character was bandaged recently */ #define AFF_LISTEN 24 /**< Actively eavesdropping */ +#define AFF_MOUNTED 25 /**< Riding a mount */ /** Total number of affect flags */ -#define NUM_AFF_FLAGS 25 +#define NUM_AFF_FLAGS 26 /* Modes of connectedness: used by descriptor_data.state */ #define CON_PLAYING 0 /**< Playing - Nominal state */ @@ -1005,6 +1007,8 @@ struct char_special_data struct char_data *fighting; /**< Target of fight; else NULL */ struct char_data *hunting; /**< Target of NPC hunt; else NULL */ struct obj_data *furniture; /**< Object being sat on/in; else NULL */ + struct char_data *mount; /**< Mount being ridden; else NULL */ + struct char_data *rider; /**< Rider, if being mounted; else NULL */ struct char_data *next_in_furniture; /**< Next person sitting, else NULL */ byte position; /**< Standing, fighting, sleeping, etc. */ diff --git a/src/utils.h b/src/utils.h index 49a3b74..cc7bbab 100644 --- a/src/utils.h +++ b/src/utils.h @@ -196,6 +196,10 @@ void advance_level(struct char_data *ch); void char_from_furniture(struct char_data *ch); /** What ch is currently sitting on. */ #define SITTING(ch) ((ch)->char_specials.furniture) +/** Mount ch is currently riding. */ +#define MOUNT(ch) ((ch)->char_specials.mount) +/** Rider currently mounted on ch. */ +#define RIDDEN_BY(ch) ((ch)->char_specials.rider) /** Who is sitting next to ch, if anyone. */ #define NEXT_SITTING(ch) ((ch)->char_specials.next_in_furniture) /** Who is sitting on this obj */