/* Mount, ok ppl lets mount them damn horses, i knew they had to be good
* for something.
*
* Code written by Celestian on Oct 1st 1996
*
* Originally written for ThrynnMUD 2.0, Merc 2.2 based.
*
* Copyright (c) 1996 Virtual Research
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
/* external functions
*/
void log_string ( const char * str );
int move_gain ( CHAR_DATA * ch );
/* functions for riding
*/
void stop_riding ( CHAR_DATA *ch );
void do_mount ( CHAR_DATA *ch, char *argument );
void do_dismount ( CHAR_DATA *ch, char *argument );
bool check_valid_ride ( CHAR_DATA *ch );
void do_mount( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *mount;
if ( IS_NPC ( ch ) )
{
send_to_char ( "Mob can't ride anything!\n\r ", ch );
return;
}
one_argument(argument, arg);
if (*arg)
{
if ( ( mount = get_char_room( ch, arg ) ) == NULL )
{
send_to_char ( "I see no one by that name "
"here!\n\r", ch );
return;
}
} else {
send_to_char ( "Whom do you wish to ride?\n\r", ch );
return;
}
if (ch->position == POS_RIDING)
{
if ( (ch->riding == NULL))
{
ch->position = POS_STANDING;
send_to_char ( "Odd, you were mounted on thin air!\n\r",
ch );
return;
}
}
if ( mount == ch )
{
send_to_char ( "Ride on your own back? How?\n\r", ch );
return;
}
if ( ch->position == POS_RIDING )
{
send_to_char ( "You are already riding on something.\n\r",
ch );
return;
}
if ( ch->in_room->room_flags & ROOM_SOLITARY )
{
send_to_char ( "This room is too narrow to ride.\n\r",
ch );
return;
}
if ( IS_NPC ( mount ) )
{
if ( !IS_SET ( mount->act, ACT_MOUNT ) )
{
act ( "It's too difficult to ride on $N.", ch, 0,
mount, TO_CHAR );
return;
}
if ( IS_AFFECTED ( mount, AFF_CHARM ) && mount->master != ch )
{
act ( "$N does not recognize you and refuses to "
"let you ride $M.", ch, 0, mount, TO_CHAR );
return;
}
if ( IS_NPC ( ch ) || ch->pcdata->learned[gsn_mount] == 0
|| ( get_psuedo_level( ch ) < get_psuedo_level( mount ) ) )
{
act ( "You are not skillful enough to ride $N.",
ch, NULL, mount, TO_CHAR );
return;
}
if ( mount->rider && mount->rider != ch )
{
act ( "Someone else is riding on $N.", ch, 0,
mount, TO_CHAR );
return;
}
if ( ch->move < MOUNT_COST )
{
ch->move = 0;
move_gain ( ch );
act( "You are too tired to ride $N.", ch, 0,
mount, TO_CHAR );
return;
}
ch->move -= MOUNT_COST;
move_gain( ch );
ch->riding = mount;
mount->rider = ch;
ch->position = POS_RIDING;
if ( !IS_SET ( mount->act, ACT_SENTINEL ) )
SET_BIT ( mount->act, ACT_SENTINEL );
act ( "You climb on and ride $N.", ch, 0, mount, TO_CHAR );
act ( "$n climbs on and rides $N.", ch, 0, mount, TO_ROOM );
act ( "$n climbs on and rides you.", ch, 0, mount, TO_VICT );
} else {
send_to_char ( "You can't ride on another player!", ch );
}
}
/* returns true if char is in same room. Don't want to check ch
* directly because it may be an invalid pointer already.
* i.e. Someone summons ride away and kills it.
*/
static int valid_ride ( int room, CHAR_DATA * ch )
{
CHAR_DATA * i;
if ( room == NOWHERE )
return FALSE;
if ( ch->in_room == NULL )
return FALSE;
for ( i = ch->in_room->first_person;
i;
i = i->next_in_room )
{
if ( IS_NPC ( i ) && ( i == ch ) )
return TRUE;
}
return FALSE;
}
void do_dismount ( CHAR_DATA *ch, char *argument )
{
if ( IS_NPC ( ch ) )
{
send_to_char ( "You can't dismount.\n\r", ch );
return;
}
if ( ch->position == POS_RIDING )
{
if ( !IS_RIDING ( ch ) )
{
ch->position = POS_STANDING;
send_to_char ( "Odd, you were mounted on thin air!\n\r", ch );
return;
}
}
if ( ch->position == POS_RIDING )
{
if ( valid_ride ( ch->in_room->vnum, ch->riding ) )
{
if ( ch->in_room->sector_type >= SECT_WATER_SWIM
&& ch->level < 5 && !IS_AFFECTED ( ch, AFF_FLYING ) )
act ( "Here? That's not too wise.", ch, 0,
0, TO_CHAR );
else {
act ( "You dismount $N.", ch, 0,
ch->riding, TO_CHAR );
act ( "$n dismounts $N.", ch, 0,
ch->riding, TO_ROOM );
if ( is_same_group( ch, ch->riding ) )
do_group( ch, ch->riding->name );
ch->position = POS_STANDING;
ch->riding->rider = 0;
ch->riding = 0;
}
} else /* mount not in same room??? How did this happen? */
stop_riding ( ch );
if ( ch->riding != NULL )
stop_follower ( ch->riding );
} else
send_to_char( "You are not riding anything!\n\r", ch );
}
/* update riding info when mount/rider no longer in same room
*/
void stop_riding ( CHAR_DATA * ch )
{
CHAR_DATA * mount, * t_ch;
if ( !ch )
return;
if (IS_NPC ( ch ) )
{
mount = ch;
t_ch = mount->rider;
} else {
t_ch = ch;
mount = t_ch->riding;
}
if ( !t_ch ) /* rider has gone poof */
{
if ( !mount ) /* so has the mount! */
{
return;
} else {
if ( !IS_NPC ( mount ) )
{
send_to_char ( "We would appreciate it if "
"you explained how a player"
"became a mount?\r\n", mount );
mount->riding = NULL;
mount->position = POS_STANDING;
update_pos ( mount );
return;
} else {
act ( "You realize that you no longer have "
"a rider!", mount, 0, 0, TO_CHAR );
mount->rider = 0;
return;
}
}
} else { /* well we have a rider of some sort */
if (IS_NPC(t_ch))
{
char buf [MAX_STRING_LENGTH];
sprintf ( buf, "NPC %s got on a mount somehow",
t_ch->short_descr );
log_string ( buf );
t_ch->rider = NULL;
update_pos ( t_ch );
if ( mount )
{
send_to_char ( "Your analomous rider has "
"been forcibly dismounted.\r\n",
mount );
if ( IS_NPC ( mount ) )
mount->rider = NULL;
else {
send_to_char ( "We would "
"appreciate it if you "
"explained how a player "
"became a mount?\r\n",
mount );
mount->riding = NULL;
mount->position = POS_STANDING;
update_pos( mount );
}
}
return;
}
if ( t_ch->position != POS_RIDING )
{
if ( IS_RIDING ( t_ch ) )
{
char buf [ MAX_STRING_LENGTH ];
sprintf ( buf, "%s on mount, but not "
"RIDING", t_ch->name );
log_string ( buf );
t_ch->position = POS_RIDING;
} else
return;
}
if (!mount) /* but mount has vanished! */
{
act ( "You fall to the ground. You stop riding.",
t_ch, 0, 0, TO_CHAR );
t_ch->riding = NULL;
t_ch->position = POS_RESTING;
update_pos( t_ch );
} else { /* ok, mount and rider both exist, but t_ch is no longer riding */
if ( t_ch->in_room != mount->in_room )
{
act ( "You fall to the ground. You stop "
"riding.", ch, 0, 0, TO_CHAR );
t_ch->riding = NULL;
ch->position = POS_RESTING;
update_pos( ch );
if ( !IS_NPC ( mount ) )
{
send_to_char ( "We would "
"appreciate it if you "
"explained how a player "
"became a mount?\r\n",
mount );
mount->riding = NULL;
mount->position = POS_STANDING;
update_pos( mount );
return;
} else {
act ( "You realize that you no "
"longer have a rider!",
mount, 0, 0, TO_CHAR );
mount->rider = NULL;
}
} else {
act ( "You stop riding $N.", t_ch, 0,
mount, TO_CHAR );
if ( is_same_group( ch, mount ) )
{
do_group( ch, mount->name );
}
t_ch->riding = NULL;
mount->rider = NULL;
t_ch->position = POS_STANDING;
}
}
}
}
/* check to make sure mount and rider both exist and are in same room
*/
bool check_valid_ride ( CHAR_DATA * ch )
{
if ( !ch || IS_NPC ( ch ) )
return FALSE;
if ( valid_ride ( ch->in_room->vnum, ch->riding ) )
if ( (ch->riding)->rider == ch )
return TRUE;
stop_riding( ch );
return FALSE;
}