mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-26 22:26:33 +01:00
Mount update 1
This commit is contained in:
parent
dedc5b7def
commit
b6bbe522bb
11 changed files with 359 additions and 32 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
$
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue