Mount update 2

This commit is contained in:
kinther 2025-12-30 18:07:00 -08:00
parent 4ff54bf429
commit 1b7a53f953
11 changed files with 447 additions and 3 deletions

View file

@ -66,6 +66,8 @@ Changes in v1.1.0-alpha:
Features to be implemented in the next few releases:
* Height and weight normalized to species
* Stables will take mounts and provide tickets to get them out
* Updated door code so that it can be closed/locked/saved with rsave code
* SECTOR/ROOM type changes to make terrain movement easier or more difficult
* Subclass selection to personalize character further
@ -73,7 +75,8 @@ Features to be implemented in the next few releases:
* 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)
* Plantlife introduced
* Plantlife introduced, allowing a plant object to produce fruit or herbs every few hours/days
* Plantlife can be refreshed to spawn fruits/herbs more frequently by watering it
* Updated lockpicking skill
* Trap as a skill - one focused on city and one focused on desert
* Poisons and antidotes

View file

@ -175,14 +175,18 @@ ACMD(do_gen_door);
/* Functions without subcommands */
ACMD(do_enter);
ACMD(do_follow);
ACMD(do_hitch);
ACMD(do_leave);
ACMD(do_mount);
ACMD(do_move);
ACMD(do_pack);
ACMD(do_rest);
ACMD(do_dismount);
ACMD(do_sit);
ACMD(do_sleep);
ACMD(do_stand);
ACMD(do_unhitch);
ACMD(do_unpack);
ACMD(do_unfollow);
ACMD(do_wake);
/* Global variables from act.movement.c */

View file

@ -1435,6 +1435,9 @@ ACMD(do_score)
send_to_char(ch, "Sdesc: %s\r\n", sdesc && *sdesc ? sdesc : "someone");
send_to_char(ch, "Ldesc: %s\r\n", *ldesc ? ldesc : "None");
send_to_char(ch, "Weight: %d Height: %d\r\n",
GET_WEIGHT(ch), GET_HEIGHT(ch));
send_to_char(ch,
"HP: %d/%d Mana: %d/%d Stamina: %d/%d\r\n",
GET_HIT(ch), GET_MAX_HIT(ch),

View file

@ -47,6 +47,10 @@ 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);
static int count_hitched_mounts(struct char_data *ch);
static int max_hitched_mounts(struct char_data *ch);
static struct char_data *first_hitched_mount_in_room(struct char_data *ch);
static struct char_data *find_hitched_mount_for_pack(struct char_data *ch, struct obj_data *obj);
/* simple function to determine if char can walk on water */
@ -275,8 +279,11 @@ static void clear_mount_state(struct char_data *ch)
return;
mount = MOUNT(ch);
if (mount && RIDDEN_BY(mount) == ch)
if (mount && RIDDEN_BY(mount) == ch) {
int rider_weight = GET_WEIGHT(ch) + IS_CARRYING_W(ch);
IS_CARRYING_W(mount) = MAX(0, IS_CARRYING_W(mount) - rider_weight);
RIDDEN_BY(mount) = NULL;
}
MOUNT(ch) = NULL;
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_MOUNTED);
}
@ -327,6 +334,74 @@ static bool resolve_mounted_move(struct char_data *ch, struct char_data **mount)
*mount = mount_ch;
return TRUE;
}
static int count_hitched_mounts(struct char_data *ch)
{
struct follow_type *follow;
int count = 0;
if (!ch)
return 0;
for (follow = ch->followers; follow; follow = follow->next) {
if (HITCHED_TO(follow->follower) == ch &&
MOB_FLAGGED(follow->follower, MOB_MOUNT))
count++;
}
return count;
}
static int max_hitched_mounts(struct char_data *ch)
{
int skill = GET_SKILL(ch, SKILL_ANIMAL_HANDLING);
if (skill > 59)
return 2;
return 1;
}
static struct char_data *first_hitched_mount_in_room(struct char_data *ch)
{
struct follow_type *follow;
if (!ch)
return NULL;
for (follow = ch->followers; follow; follow = follow->next) {
if (HITCHED_TO(follow->follower) == ch &&
MOB_FLAGGED(follow->follower, MOB_MOUNT) &&
IN_ROOM(follow->follower) == IN_ROOM(ch))
return follow->follower;
}
return NULL;
}
static struct char_data *find_hitched_mount_for_pack(struct char_data *ch, struct obj_data *obj)
{
struct follow_type *follow;
if (!ch || !obj)
return NULL;
for (follow = ch->followers; follow; follow = follow->next) {
struct char_data *mount = follow->follower;
if (HITCHED_TO(mount) != ch || !MOB_FLAGGED(mount, MOB_MOUNT))
continue;
if (IN_ROOM(mount) != IN_ROOM(ch))
continue;
if ((IS_CARRYING_N(mount) + 1) > CAN_CARRY_N(mount))
continue;
if ((IS_CARRYING_W(mount) + GET_OBJ_WEIGHT(obj)) > CAN_CARRY_W(mount))
continue;
return mount;
}
return NULL;
}
/** 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
@ -1022,10 +1097,64 @@ ACMD(do_stand)
{
char token[MAX_INPUT_LENGTH];
struct obj_data *furniture = NULL, *current_furniture = SITTING(ch);
struct char_data *mount = NULL;
char arg[MAX_INPUT_LENGTH];
bool has_target = FALSE, used_number = FALSE;
int ordinal = 0;
int orig_pos = GET_POS(ch);
if (*argument) {
one_argument(argument, arg);
if (*arg && !is_abbrev(arg, "at"))
mount = get_char_vis(ch, arg, NULL, FIND_CHAR_ROOM);
if (mount && MOB_FLAGGED(mount, MOB_MOUNT) && HITCHED_TO(mount) != ch) {
act("You don't have $N hitched.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (mount && HITCHED_TO(mount) == ch && MOB_FLAGGED(mount, MOB_MOUNT)) {
if (FIGHTING(mount)) {
act("$N is fighting right now.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (GET_POS(mount) == POS_RESTING) {
act("You get $N to stand up.", FALSE, ch, 0, mount, TO_CHAR);
act("$n gets $N to stand up.", TRUE, ch, 0, mount, TO_ROOM);
GET_POS(mount) = POS_STANDING;
clear_custom_ldesc(mount);
return;
}
if (GET_POS(mount) == POS_SLEEPING) {
act("$N has to wake up first.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
act("$N is already standing.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
}
if (!*argument && AFF_FLAGGED(ch, AFF_MOUNTED) && MOUNT(ch)) {
mount = MOUNT(ch);
if (IN_ROOM(mount) != IN_ROOM(ch) || RIDDEN_BY(mount) != ch) {
clear_mount_state(ch);
send_to_char(ch, "You aren't mounted on anything.\r\n");
return;
}
if (FIGHTING(mount)) {
send_to_char(ch, "Your mount is fighting right now.\r\n");
return;
}
if (GET_POS(mount) != POS_SLEEPING) {
act("You get $N to rest and dismount.", FALSE, ch, 0, mount, TO_CHAR);
act("$n gets $N to rest and dismounts.", TRUE, ch, 0, mount, TO_ROOM);
GET_POS(mount) = POS_RESTING;
clear_custom_ldesc(mount);
} else {
act("$N is already asleep.", FALSE, ch, 0, mount, TO_CHAR);
}
clear_mount_state(ch);
return;
}
if (AFF_FLAGGED(ch, AFF_MOUNTED)) {
send_to_char(ch, "You must dismount first.\r\n");
return;
@ -1267,9 +1396,64 @@ ACMD(do_rest)
{
char token[MAX_INPUT_LENGTH];
struct obj_data *furniture = NULL, *current_furniture = SITTING(ch);
struct char_data *mount = NULL;
char arg[MAX_INPUT_LENGTH];
bool has_target = FALSE, used_number = FALSE;
int ordinal = 0;
if (*argument) {
one_argument(argument, arg);
if (*arg && !is_abbrev(arg, "at"))
mount = get_char_vis(ch, arg, NULL, FIND_CHAR_ROOM);
if (mount && MOB_FLAGGED(mount, MOB_MOUNT) && HITCHED_TO(mount) != ch) {
act("You don't have $N hitched.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (mount && HITCHED_TO(mount) == ch && MOB_FLAGGED(mount, MOB_MOUNT)) {
if (FIGHTING(mount)) {
act("$N is fighting right now.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (GET_POS(mount) == POS_RESTING) {
act("$N is already resting.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (GET_POS(mount) == POS_SLEEPING) {
act("$N is already asleep.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
act("You pull on $N's reins, forcing it to rest.", FALSE, ch, 0, mount, TO_CHAR);
act("$n pulls on $N's reins, forcing it to rest.", TRUE, ch, 0, mount, TO_ROOM);
GET_POS(mount) = POS_RESTING;
clear_custom_ldesc(mount);
return;
}
}
if (!*argument && AFF_FLAGGED(ch, AFF_MOUNTED) && MOUNT(ch)) {
mount = MOUNT(ch);
if (IN_ROOM(mount) != IN_ROOM(ch) || RIDDEN_BY(mount) != ch) {
clear_mount_state(ch);
send_to_char(ch, "You aren't mounted on anything.\r\n");
return;
}
if (FIGHTING(mount)) {
send_to_char(ch, "Your mount is fighting right now.\r\n");
return;
}
if (GET_POS(mount) == POS_SLEEPING) {
act("$N is already asleep.", FALSE, ch, 0, mount, TO_CHAR);
clear_mount_state(ch);
return;
}
act("You pull on $N's reins, forcing it to rest.", FALSE, ch, 0, mount, TO_CHAR);
act("$n pulls on $N's reins, forcing it to rest and dismounts.", TRUE, ch, 0, mount, TO_ROOM);
GET_POS(mount) = POS_RESTING;
clear_custom_ldesc(mount);
clear_mount_state(ch);
return;
}
if (AFF_FLAGGED(ch, AFF_MOUNTED)) {
send_to_char(ch, "You must dismount first.\r\n");
return;
@ -1621,14 +1805,25 @@ ACMD(do_mount)
return;
}
if (HITCHED_TO(mount) && HITCHED_TO(mount) != ch) {
act("$N is already hitched to someone else.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (RIDDEN_BY(mount)) {
act("$N is already being ridden.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if ((GET_WEIGHT(ch) + IS_CARRYING_W(ch) + IS_CARRYING_W(mount)) > CAN_CARRY_W(mount)) {
act("$N can't carry that much weight.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
SET_BIT_AR(AFF_FLAGS(ch), AFF_MOUNTED);
MOUNT(ch) = mount;
RIDDEN_BY(mount) = ch;
IS_CARRYING_W(mount) += GET_WEIGHT(ch) + IS_CARRYING_W(ch);
act("You mount $N.", FALSE, ch, 0, mount, TO_CHAR);
act("$n mounts $N.", TRUE, ch, 0, mount, TO_ROOM);
@ -1649,6 +1844,214 @@ ACMD(do_dismount)
clear_mount_state(ch);
}
ACMD(do_hitch)
{
char arg[MAX_INPUT_LENGTH];
struct char_data *mount;
int max_hitched;
one_argument(argument, arg);
if (!*arg) {
send_to_char(ch, "Hitch what?\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 hitch yourself.\r\n");
return;
}
if (!IS_NPC(mount) || !MOB_FLAGGED(mount, MOB_MOUNT)) {
send_to_char(ch, "You can't hitch %s!\r\n", get_char_sdesc(mount));
return;
}
if (RIDDEN_BY(mount) && RIDDEN_BY(mount) != ch) {
act("$N is already being ridden.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (HITCHED_TO(mount) == ch) {
act("$N is already hitched to you.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (HITCHED_TO(mount) && HITCHED_TO(mount) != ch) {
act("$N is already hitched to someone else.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (mount->master && mount->master != ch) {
act("$N is already following someone else.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
max_hitched = max_hitched_mounts(ch);
if (count_hitched_mounts(ch) >= max_hitched) {
send_to_char(ch, "You can't hitch any more mounts.\r\n");
return;
}
if (!mount->master)
add_follower(mount, ch);
HITCHED_TO(mount) = ch;
act("You hitch $N to you.", FALSE, ch, 0, mount, TO_CHAR);
act("$n hitches $N to $m.", TRUE, ch, 0, mount, TO_ROOM);
}
ACMD(do_unhitch)
{
char arg[MAX_INPUT_LENGTH];
struct char_data *mount;
one_argument(argument, arg);
if (!*arg) {
send_to_char(ch, "Unhitch what?\r\n");
return;
}
if (!(mount = get_char_vis(ch, arg, NULL, FIND_CHAR_ROOM))) {
send_to_char(ch, "%s", CONFIG_NOPERSON);
return;
}
if (HITCHED_TO(mount) != ch || !MOB_FLAGGED(mount, MOB_MOUNT)) {
act("You don't have $N hitched.", FALSE, ch, 0, mount, TO_CHAR);
return;
}
if (mount->master == ch)
stop_follower(mount);
else
HITCHED_TO(mount) = NULL;
act("You unhitch $N.", FALSE, ch, 0, mount, TO_CHAR);
act("$n unhitches $N.", TRUE, ch, 0, mount, TO_ROOM);
}
ACMD(do_pack)
{
char arg[MAX_INPUT_LENGTH];
struct char_data *mount;
struct obj_data *obj;
struct follow_type *follow;
bool found_mount = FALSE;
one_argument(argument, arg);
if (!*arg) {
for (follow = ch->followers; follow; follow = follow->next) {
bool found_item = FALSE;
mount = follow->follower;
if (HITCHED_TO(mount) != ch || !MOB_FLAGGED(mount, MOB_MOUNT))
continue;
if (IN_ROOM(mount) != IN_ROOM(ch))
continue;
found_mount = TRUE;
send_to_char(ch, "Packed on %s:\r\n", get_char_sdesc(mount));
for (obj = mount->carrying; obj; obj = obj->next_content) {
if (GET_OBJ_TYPE(obj) != ITEM_CONTAINER)
continue;
if (!CAN_SEE_OBJ(ch, obj))
continue;
send_to_char(ch, " %s\r\n", obj->short_description ? obj->short_description : "something");
found_item = TRUE;
}
if (!found_item)
send_to_char(ch, " Nothing.\r\n");
}
if (!found_mount)
send_to_char(ch, "You don't have any mounts hitched.\r\n");
return;
}
if (!(obj = get_obj_in_list_vis(ch, arg, NULL, ch->carrying))) {
send_to_char(ch, "You don't seem to have that.\r\n");
return;
}
if (GET_OBJ_TYPE(obj) != ITEM_CONTAINER) {
send_to_char(ch, "You can only pack containers onto a mount.\r\n");
return;
}
mount = find_hitched_mount_for_pack(ch, obj);
if (!mount) {
if (!first_hitched_mount_in_room(ch))
send_to_char(ch, "You don't have any mounts hitched here.\r\n");
else
send_to_char(ch, "Your mount can't carry that much.\r\n");
return;
}
obj_from_char(obj);
obj_to_char(obj, mount);
act("You pack $p onto $N.", FALSE, ch, obj, mount, TO_CHAR);
act("$n packs $p onto $N.", TRUE, ch, obj, mount, TO_ROOM);
}
ACMD(do_unpack)
{
char arg[MAX_INPUT_LENGTH];
struct char_data *mount;
struct obj_data *obj;
struct follow_type *follow;
one_argument(argument, arg);
if (!*arg) {
send_to_char(ch, "Unpack what?\r\n");
return;
}
for (follow = ch->followers; follow; follow = follow->next) {
mount = follow->follower;
if (HITCHED_TO(mount) != ch || !MOB_FLAGGED(mount, MOB_MOUNT))
continue;
if (IN_ROOM(mount) != IN_ROOM(ch))
continue;
obj = get_obj_in_list_vis(ch, arg, NULL, mount->carrying);
if (!obj)
continue;
if (GET_OBJ_TYPE(obj) != ITEM_CONTAINER)
continue;
if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch)) {
send_to_char(ch, "You can't carry any more items.\r\n");
return;
}
if ((IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj)) > CAN_CARRY_W(ch)) {
send_to_char(ch, "You can't carry that much weight.\r\n");
return;
}
obj_from_char(obj);
obj_to_char(obj, ch);
act("You unpack $p from $N.", FALSE, ch, obj, mount, TO_CHAR);
act("$n unpacks $p from $N.", TRUE, ch, obj, mount, TO_ROOM);
return;
}
send_to_char(ch, "You don't have that packed on a hitched mount.\r\n");
}
ACMD(do_unfollow)
{
if (ch->master) {

View file

@ -1829,6 +1829,9 @@ static void do_stat_character(struct char_data *ch, struct char_data *k)
GET_STR(k), GET_INT(k), GET_WIS(k),
GET_DEX(k), GET_CON(k), GET_CHA(k));
stat_table_row_fmt(ch, "Size", "Weight %d, Height %d",
GET_WEIGHT(k), GET_HEIGHT(k));
stat_table_row_fmt(ch, "Saving Throws",
"Str %+d Dex %+d Con %+d Int %+d Wis %+d Cha %+d",
get_save_mod(k, ABIL_STR),

View file

@ -446,6 +446,8 @@ void obj_to_char(struct obj_data *object, struct char_data *ch)
RoomSave_mark_dirty_room(__rs_room);
IS_CARRYING_W(ch) += GET_OBJ_WEIGHT(object);
IS_CARRYING_N(ch)++;
if (AFF_FLAGGED(ch, AFF_MOUNTED) && MOUNT(ch) && RIDDEN_BY(MOUNT(ch)) == ch)
IS_CARRYING_W(MOUNT(ch)) += GET_OBJ_WEIGHT(object);
autoquest_trigger_check(ch, NULL, object, AQ_OBJ_FIND);
@ -487,6 +489,11 @@ void obj_from_char(struct obj_data *object)
IS_CARRYING_W(object->carried_by) -= GET_OBJ_WEIGHT(object);
IS_CARRYING_N(object->carried_by)--;
if (AFF_FLAGGED(object->carried_by, AFF_MOUNTED) &&
MOUNT(object->carried_by) &&
RIDDEN_BY(MOUNT(object->carried_by)) == object->carried_by)
IS_CARRYING_W(MOUNT(object->carried_by)) =
MAX(0, IS_CARRYING_W(MOUNT(object->carried_by)) - GET_OBJ_WEIGHT(object));
object->carried_by = NULL;
object->next_content = NULL;
if (__rs_room != NOWHERE)
@ -559,6 +566,8 @@ void equip_char(struct char_data *ch, struct obj_data *obj, int pos)
obj->worn_by = ch;
obj->worn_on = pos;
IS_CARRYING_W(ch) += GET_OBJ_WEIGHT(obj);
if (AFF_FLAGGED(ch, AFF_MOUNTED) && MOUNT(ch) && RIDDEN_BY(MOUNT(ch)) == ch)
IS_CARRYING_W(MOUNT(ch)) += GET_OBJ_WEIGHT(obj);
if (GET_OBJ_TYPE(obj) == ITEM_ARMOR)
GET_AC(ch) -= apply_ac(ch, pos);
@ -592,6 +601,9 @@ struct obj_data *unequip_char(struct char_data *ch, int pos)
obj->worn_by = NULL;
obj->worn_on = -1;
IS_CARRYING_W(ch) -= GET_OBJ_WEIGHT(obj);
if (AFF_FLAGGED(ch, AFF_MOUNTED) && MOUNT(ch) && RIDDEN_BY(MOUNT(ch)) == ch)
IS_CARRYING_W(MOUNT(ch)) =
MAX(0, IS_CARRYING_W(MOUNT(ch)) - GET_OBJ_WEIGHT(obj));
if (GET_OBJ_TYPE(obj) == ITEM_ARMOR)
GET_AC(ch) += apply_ac(ch, pos);
@ -1005,8 +1017,11 @@ 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)
if (mount && RIDDEN_BY(mount) == ch) {
int rider_weight = GET_WEIGHT(ch) + IS_CARRYING_W(ch);
IS_CARRYING_W(mount) = MAX(0, IS_CARRYING_W(mount) - rider_weight);
RIDDEN_BY(mount) = NULL;
}
MOUNT(ch) = NULL;
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_MOUNTED);
}

View file

@ -181,6 +181,7 @@ cpp_extern const struct command_info cmd_info[] = {
{ "hold" , "hold" , POS_RESTING , do_grab , 1, 0 },
{ "holylight", "holy" , POS_DEAD , do_gen_tog , LVL_IMMORT, SCMD_HOLYLIGHT },
{ "house" , "house" , POS_RESTING , do_house , 0, 0 },
{ "hitch" , "hitc" , POS_STANDING, do_hitch , 0, 0 },
{ "inventory", "i" , POS_DEAD , do_inventory, 0, 0 },
{ "idea" , "ide" , POS_DEAD , do_ibt , 0, SCMD_IDEA },
@ -233,6 +234,7 @@ cpp_extern const struct command_info cmd_info[] = {
{ "ocopy" , "ocopy" , POS_DEAD , do_oasis_copy, LVL_GOD, CON_OEDIT },
{ "put" , "p" , POS_RESTING , do_put , 0, 0 },
{ "pack" , "pac" , POS_RESTING , do_pack , 0, 0 },
{ "peace" , "pe" , POS_DEAD , do_peace , LVL_BUILDER, 0 },
{ "pemote" , "pem" , POS_SLEEPING, do_pemote , 0, SCMD_PEMOTE },
{ "phemote" , "phem" , POS_SLEEPING, do_phemote , 0, SCMD_PHEMOTE },
@ -329,7 +331,9 @@ cpp_extern const struct command_info cmd_info[] = {
{ "unlock" , "unlock" , POS_SITTING , do_gen_door , 0, SCMD_UNLOCK },
{ "unban" , "unban" , POS_DEAD , do_unban , LVL_GRGOD, 0 },
{ "unaffect" , "unaffect", POS_DEAD , do_wizutil , LVL_GOD, SCMD_UNAFFECT },
{ "unhitch" , "unh" , POS_STANDING, do_unhitch , 0, 0 },
{ "unfollow" , "unf" , POS_RESTING , do_unfollow , 0, 0 },
{ "unpack" , "unpa" , POS_RESTING , do_unpack , 0, 0 },
{ "uptime" , "uptime" , POS_DEAD , do_date , LVL_GOD, SCMD_UPTIME },
{ "use" , "use" , POS_SITTING , do_use , 1, SCMD_USE },
{ "users" , "users" , POS_DEAD , do_users , LVL_GOD, 0 },

View file

@ -551,6 +551,10 @@ int load_char(const char *name, struct char_data *ch)
update_roleplay_age(ch);
ch->player.time.birth = time(0) - get_total_played_seconds(ch);
affect_total(ch);
MOUNT(ch) = NULL;
RIDDEN_BY(ch) = NULL;
HITCHED_TO(ch) = NULL;
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_MOUNTED);
/* initialization for imms */
if (GET_LEVEL(ch) >= LVL_IMMORT) {

View file

@ -1009,6 +1009,7 @@ struct char_special_data
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 *hitched_to; /**< Person this mount is hitched to; else NULL */
struct char_data *next_in_furniture; /**< Next person sitting, else NULL */
byte position; /**< Standing, fighting, sleeping, etc. */

View file

@ -654,6 +654,8 @@ void stop_follower(struct char_data *ch)
}
ch->master = NULL;
if (HITCHED_TO(ch))
HITCHED_TO(ch) = NULL;
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_CHARM);
}

View file

@ -200,6 +200,8 @@ void char_from_furniture(struct char_data *ch);
#define MOUNT(ch) ((ch)->char_specials.mount)
/** Rider currently mounted on ch. */
#define RIDDEN_BY(ch) ((ch)->char_specials.rider)
/** Person ch is hitched to. */
#define HITCHED_TO(ch) ((ch)->char_specials.hitched_to)
/** Who is sitting next to ch, if anyone. */
#define NEXT_SITTING(ch) ((ch)->char_specials.next_in_furniture)
/** Who is sitting on this obj */