/***************************************************************************
* file: act_move.c , Implementation of commands Part of DIKUMUD *
* Usage : Movement commands, close/open & lock/unlock doors. *
* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
* *
* Copyright (C) 1992, 1993 Michael Chastain, Michael Quan, Mitchell Tse *
* Performance optimization and bug fixes by MERC Industries. *
* You can use our stuff in any way you like whatsoever so long as this *
* copyright notice remains intact. If you like it please drop a line *
* to mec@garnet.berkeley.edu. *
* *
* This is free software and you are benefitting. We hope that you *
* share your changes too. What goes around, comes around. *
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include "structs.h"
#include "mob.h"
#include "obj.h"
#include "utils.h"
#include "interp.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
/* external vars */
extern struct room_data *world;
extern struct descriptor_data *descriptor_list;
extern struct index_data *obj_index;
extern int rev_dir[];
extern char *dirs[];
extern int movement_loss[];
/* external functs */
void death_cry(struct char_data *ch);
struct obj_data *get_obj_in_list_vis(struct char_data *ch, char *name,
struct obj_data *list);
int do_simple_move(struct char_data *ch, int cmd, int following)
/* Assumes,
1. That there is no master and no followers.
2. That the direction exists.
Returns :
1 : If succes.
0 : If fail
-1 : If dead.
*/
{
char tmp[80];
int was_in;
int need_movement;
struct obj_data *obj;
bool has_boat;
if (special(ch, cmd+1, "")) /* Check for special routines (North is 1) */
return(FALSE);
need_movement = (movement_loss[world[ch->in_room].sector_type]+
movement_loss[world[world[ch->in_room].dir_option[cmd]->to_room].
sector_type]) / 2;
if ((world[ch->in_room].sector_type == SECT_WATER_NOSWIM) ||
(world[world[ch->in_room].dir_option[cmd]->to_room].sector_type
== SECT_WATER_NOSWIM)) {
has_boat = FALSE;
/* See if char is carrying a boat */
for (obj=ch->carrying; obj; obj=obj->next_content)
if (obj->obj_flags.type_flag == ITEM_BOAT)
has_boat = TRUE;
if (!has_boat) {
send_to_char("You need a boat to go there.\r\n", ch);
return(FALSE);
}
}
if(GET_MOVE(ch)<need_movement && !IS_NPC(ch))
{
if(!following)
send_to_char("You are too exhausted.\r\n",ch);
else
send_to_char("You are too exhausted to follow.\r\n",ch);
return(FALSE);
}
if(GET_LEVEL(ch)<32 && !IS_NPC(ch))
GET_MOVE(ch) -= need_movement;
if (!IS_AFFECTED(ch, AFF_SNEAK)) {
sprintf(tmp, "$n leaves %s.", dirs[cmd]);
act(tmp, TRUE, ch, 0,0,TO_ROOM);
}
was_in = ch->in_room;
char_from_room(ch);
char_to_room(ch, world[was_in].dir_option[cmd]->to_room);
if (!IS_AFFECTED(ch, AFF_SNEAK))
act("$n has arrived.", TRUE, ch, 0,0, TO_ROOM);
do_look(ch, "\0",15);
return(1);
}
void do_move(struct char_data *ch, char *argument, int cmd)
{
char tmp[80];
int was_in;
struct follow_type *k, *next_dude;
--cmd;
if (!world[ch->in_room].dir_option[cmd]) {
send_to_char("Alas, you cannot go that way...\r\n", ch);
} else { /* Direction is possible */
if (IS_SET(EXIT(ch, cmd)->exit_info, EX_CLOSED)) {
if (EXIT(ch, cmd)->keyword) {
sprintf(tmp, "The %s seems to be closed.\r\n",
fname(EXIT(ch, cmd)->keyword));
send_to_char(tmp, ch);
} else {
send_to_char("It seems to be closed.\r\n", ch);
}
} else if (EXIT(ch, cmd)->to_room == NOWHERE)
send_to_char("Alas, you can't go that way.\r\n", ch);
else if (!ch->followers && !ch->master)
do_simple_move(ch,cmd,FALSE);
else {
if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master) &&
(ch->in_room == ch->master->in_room)) {
send_to_char(
"The thought of leaving your master makes you weep.\r\n", ch);
act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM);
} else {
was_in = ch->in_room;
if (do_simple_move(ch, cmd, TRUE) == 1) {
if (ch->followers) { /* If succes move followers */
for(k = ch->followers; k; k = next_dude) {
next_dude = k->next;
if ((was_in == k->follower->in_room) &&
(GET_POS(k->follower) >= POSITION_STANDING)) {
act("You follow $N.",
FALSE, k->follower, 0, ch, TO_CHAR);
cmd++;
send_to_char("\r\n", k->follower);
do_move(k->follower, argument, cmd);
cmd--;
}
}
}
}
}
}
}
}
int find_door(struct char_data *ch, char *type, char *dir)
{
char buf[MAX_STRING_LENGTH];
int door;
char *dirs[] =
{
"north",
"east",
"south",
"west",
"up",
"down",
"\n"
};
if (*dir) /* a direction was specified */
{
if ((door = search_block(dir, dirs, FALSE)) == -1) /* Partial Match */
{
send_to_char("That's not a direction.\r\n", ch);
return(-1);
}
if (EXIT(ch, door))
if (EXIT(ch, door)->keyword)
if (isname(type, EXIT(ch, door)->keyword))
return(door);
else
{
sprintf(buf, "I see no %s there.\r\n", type);
send_to_char(buf, ch);
return(-1);
}
else
return(door);
else
{
send_to_char( "There is no door there.\r\n", ch);
return(-1);
}
}
else /* try to locate the keyword */
{
for (door = 0; door <= 5; door++)
if (EXIT(ch, door))
if (EXIT(ch, door)->keyword)
if (isname(type, EXIT(ch, door)->keyword))
return(door);
sprintf(buf, "I see no %s here.\r\n", type);
send_to_char(buf, ch);
return(-1);
}
}
void do_open(struct char_data *ch, char *argument, int cmd)
{
int door, other_room;
char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
struct room_direction_data *back;
struct obj_data *obj;
struct char_data *victim;
void save_online_rooms(struct char_data *ch);
argument_interpreter(argument, type, dir);
if (!*type)
send_to_char("Open what?\r\n", ch);
else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
ch, &victim, &obj))
/* this is an object */
if (obj->obj_flags.type_flag != ITEM_CONTAINER)
send_to_char("That's not a container.\r\n", ch);
else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
send_to_char("But it's already open!\r\n", ch);
else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSEABLE))
send_to_char("You can't do that.\r\n", ch);
else if (IS_SET(obj->obj_flags.value[1], CONT_LOCKED))
send_to_char("It seems to be locked.\r\n", ch);
else
{
REMOVE_BIT(obj->obj_flags.value[1], CONT_CLOSED);
send_to_char("Ok.\r\n", ch);
act("$n opens $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else if ((door = find_door(ch, type, dir)) >= 0) {
/* perhaps it is a door */
if (IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED) && /*KALGEN*/
!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR)) {
SET_BIT(EXIT(ch, door)->exit_info, EX_ISDOOR);
SET_BIT(EXIT(ch, door)->exit_info, EX_PICKPROOF);
send_to_char("You just fixed a bug! Thank you! Saving..\r\n",ch);
save_online_rooms(ch);
}
if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
send_to_char("That's impossible, I'm afraid.\r\n", ch);
else if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
send_to_char("It's already open!\r\n", ch);
else if (IS_SET(EXIT(ch, door)->exit_info, EX_LOCKED))
send_to_char("It seems to be locked.\r\n", ch);
else
{
REMOVE_BIT(EXIT(ch, door)->exit_info, EX_CLOSED);
if (EXIT(ch, door)->keyword)
act("$n opens the $F.", FALSE, ch, 0, EXIT(ch, door)->keyword,
TO_ROOM);
else
act("$n opens the door.", FALSE, ch, 0, 0, TO_ROOM);
send_to_char("Ok.\r\n", ch);
/* now for opening the OTHER side of the door! */
if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
if ( ( back = world[other_room].dir_option[rev_dir[door]] ) != 0 )
if (back->to_room == ch->in_room)
{
REMOVE_BIT(back->exit_info, EX_CLOSED);
if (back->keyword)
{
sprintf(buf,
"The %s is opened from the other side.\r\n",
fname(back->keyword));
send_to_room(buf, EXIT(ch, door)->to_room);
}
else
send_to_room(
"The door is opened from the other side.\r\n",
EXIT(ch, door)->to_room);
}
}
}
}
void do_close(struct char_data *ch, char *argument, int cmd)
{
int door, other_room;
char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
struct room_direction_data *back;
struct obj_data *obj;
struct char_data *victim;
void save_online_rooms(struct char_data *ch);
argument_interpreter(argument, type, dir);
if (!*type)
send_to_char("Close what?\r\n", ch);
else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
ch, &victim, &obj))
/* this is an object */
if (obj->obj_flags.type_flag != ITEM_CONTAINER)
send_to_char("That's not a container.\r\n", ch);
else if (IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
send_to_char("But it's already closed!\r\n", ch);
else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSEABLE))
send_to_char("That's impossible.\r\n", ch);
else
{
SET_BIT(obj->obj_flags.value[1], CONT_CLOSED);
send_to_char("Ok.\r\n", ch);
act("$n closes $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else if ((door = find_door(ch, type, dir)) >= 0) {
/* Or a door */
if (IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED) && /*KALGEN*/
!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR)) {
SET_BIT(EXIT(ch, door)->exit_info, EX_ISDOOR);
SET_BIT(EXIT(ch, door)->exit_info, EX_PICKPROOF);
send_to_char("You just fixed a bug! Thank you! Saving..\r\n",ch);
save_online_rooms(ch);
}
if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
send_to_char("That's absurd.\r\n", ch);
else if (IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
send_to_char("It's already closed!\r\n", ch);
else
{
SET_BIT(EXIT(ch, door)->exit_info, EX_CLOSED);
if (EXIT(ch, door)->keyword)
act("$n closes the $F.", 0, ch, 0, EXIT(ch, door)->keyword,
TO_ROOM);
else
act("$n closes the door.", FALSE, ch, 0, 0, TO_ROOM);
send_to_char("Ok.\r\n", ch);
/* now for closing the other side, too */
if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
if ( ( back = world[other_room].dir_option[rev_dir[door]] ) != 0 )
if (back->to_room == ch->in_room)
{
SET_BIT(back->exit_info, EX_CLOSED);
if (back->keyword)
{
sprintf(buf,
"The %s closes quietly.\r\n", back->keyword);
send_to_room(buf, EXIT(ch, door)->to_room);
}
else
send_to_room(
"The door closes quietly.\r\n",
EXIT(ch, door)->to_room);
}
}
}
}
int has_key(struct char_data *ch, int key)
{
struct obj_data *o;
for (o = ch->carrying; o; o = o->next_content)
if (obj_index[o->item_number].virtual == key)
return(1);
if (ch->equipment[HOLD])
if (obj_index[ch->equipment[HOLD]->item_number].virtual == key)
return(1);
return(0);
}
void do_lock(struct char_data *ch, char *argument, int cmd)
{
int door, other_room;
char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH];
struct room_direction_data *back;
struct obj_data *obj;
struct char_data *victim;
argument_interpreter(argument, type, dir);
if (!*type)
send_to_char("Lock what?\r\n", ch);
else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
ch, &victim, &obj))
/* this is an object */
if (obj->obj_flags.type_flag != ITEM_CONTAINER)
send_to_char("That's not a container.\r\n", ch);
else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
send_to_char("Maybe you should close it first...\r\n", ch);
else if (obj->obj_flags.value[2] < 0)
send_to_char("That thing can't be locked.\r\n", ch);
else if (!has_key(ch, obj->obj_flags.value[2]))
send_to_char("You don't seem to have the proper key.\r\n", ch);
else if (IS_SET(obj->obj_flags.value[1], CONT_LOCKED))
send_to_char("It is locked already.\r\n", ch);
else
{
SET_BIT(obj->obj_flags.value[1], CONT_LOCKED);
send_to_char("*Cluck*\r\n", ch);
act("$n locks $p - 'cluck', it says.", FALSE, ch, obj, 0, TO_ROOM);
}
else if ((door = find_door(ch, type, dir)) >= 0)
{
/* a door, perhaps */
if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
send_to_char("That's absurd.\r\n", ch);
else if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
send_to_char("You have to close it first, I'm afraid.\r\n", ch);
else if (EXIT(ch, door)->key < 0)
send_to_char("There does not seem to be any keyholes.\r\n", ch);
else if (!has_key(ch, EXIT(ch, door)->key))
send_to_char("You don't have the proper key.\r\n", ch);
else if (IS_SET(EXIT(ch, door)->exit_info, EX_LOCKED))
send_to_char("It's already locked!\r\n", ch);
else
{
SET_BIT(EXIT(ch, door)->exit_info, EX_LOCKED);
if (EXIT(ch, door)->keyword)
act("$n locks the $F.", 0, ch, 0, EXIT(ch, door)->keyword,
TO_ROOM);
else
act("$n locks the door.", FALSE, ch, 0, 0, TO_ROOM);
send_to_char("*Click*\r\n", ch);
/* now for locking the other side, too */
if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
if ( ( back = world[other_room].dir_option[rev_dir[door]] ) != 0 )
if (back->to_room == ch->in_room)
SET_BIT(back->exit_info, EX_LOCKED);
}
}
}
void do_unlock(struct char_data *ch, char *argument, int cmd)
{
int door, other_room;
char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH];
struct room_direction_data *back;
struct obj_data *obj;
struct char_data *victim;
argument_interpreter(argument, type, dir);
if (!*type)
send_to_char("Unlock what?\r\n", ch);
else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
ch, &victim, &obj))
/* this is an object */
if (obj->obj_flags.type_flag != ITEM_CONTAINER)
send_to_char("That's not a container.\r\n", ch);
else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
send_to_char("Silly - it ain't even closed!\r\n", ch);
else if (obj->obj_flags.value[2] < 0)
send_to_char("Odd - you can't seem to find a keyhole.\r\n", ch);
else if (!has_key(ch, obj->obj_flags.value[2]))
send_to_char("You don't seem to have the proper key.\r\n", ch);
else if (!IS_SET(obj->obj_flags.value[1], CONT_LOCKED))
send_to_char("Oh.. it wasn't locked, after all.\r\n", ch);
else
{
REMOVE_BIT(obj->obj_flags.value[1], CONT_LOCKED);
send_to_char("*Click*\r\n", ch);
act("$n unlocks $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else if ((door = find_door(ch, type, dir)) >= 0)
{
/* it is a door */
if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
send_to_char("That's absurd.\r\n", ch);
else if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
send_to_char("Heck ... it ain't even closed!\r\n", ch);
else if (EXIT(ch, door)->key < 0)
send_to_char("You can't seem to spot any keyholes.\r\n", ch);
else if (!has_key(ch, EXIT(ch, door)->key))
send_to_char("You do not have the proper key for that.\r\n", ch);
else if (!IS_SET(EXIT(ch, door)->exit_info, EX_LOCKED))
send_to_char("It's already unlocked, it seems.\r\n", ch);
else
{
REMOVE_BIT(EXIT(ch, door)->exit_info, EX_LOCKED);
if (EXIT(ch, door)->keyword)
act("$n unlocks the $F.", 0, ch, 0, EXIT(ch, door)->keyword,
TO_ROOM);
else
act("$n unlocks the door.", FALSE, ch, 0, 0, TO_ROOM);
send_to_char("*click*\r\n", ch);
/* now for unlocking the other side, too */
if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
if ( ( back = world[other_room].dir_option[rev_dir[door]] ) != 0 )
if (back->to_room == ch->in_room)
REMOVE_BIT(back->exit_info, EX_LOCKED);
}
}
}
void do_pick(struct char_data *ch, char *argument, int cmd)
{
byte percent;
int door, other_room;
char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH];
struct room_direction_data *back;
struct obj_data *obj;
struct char_data *victim;
argument_interpreter(argument, type, dir);
percent=number(1,101); /* 101% is a complete failure */
if (percent > (ch->skills[SKILL_PICK_LOCK].learned)) {
send_to_char("You failed to pick the lock.\r\n", ch);
return;
}
if (!*type)
send_to_char("Pick what?\r\n", ch);
else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
ch, &victim, &obj))
/* this is an object */
if (obj->obj_flags.type_flag != ITEM_CONTAINER)
send_to_char("That's not a container.\r\n", ch);
else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
send_to_char("Silly - it ain't even closed!\r\n", ch);
else if (obj->obj_flags.value[2] < 0)
send_to_char("Odd - you can't seem to find a keyhole.\r\n", ch);
else if (!IS_SET(obj->obj_flags.value[1], CONT_LOCKED))
send_to_char("Oho! This thing is NOT locked!\r\n", ch);
else if (IS_SET(obj->obj_flags.value[1], CONT_PICKPROOF))
send_to_char("It resists your attempts at picking it.\r\n", ch);
else
{
REMOVE_BIT(obj->obj_flags.value[1], CONT_LOCKED);
send_to_char("*Click*\r\n", ch);
act("$n fiddles with $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else if ((door = find_door(ch, type, dir)) >= 0)
{
if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
send_to_char("That's absurd.\r\n", ch);
else if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
send_to_char("You realize that the door is already open.\r\n", ch);
else if (EXIT(ch, door)->key < 0)
send_to_char("You can't seem to spot any lock to pick.\r\n", ch);
else if (!IS_SET(EXIT(ch, door)->exit_info, EX_LOCKED))
send_to_char("Oh.. it wasn't locked at all.\r\n", ch);
else if (IS_SET(EXIT(ch, door)->exit_info, EX_PICKPROOF))
send_to_char("You seem to be unable to pick this lock.\r\n", ch);
else
{
REMOVE_BIT(EXIT(ch, door)->exit_info, EX_LOCKED);
if (EXIT(ch, door)->keyword)
act("$n skillfully picks the lock of the $F.", 0, ch, 0,
EXIT(ch, door)->keyword, TO_ROOM);
else
act("$n picks the lock of the.", TRUE, ch, 0, 0, TO_ROOM);
send_to_char("The lock quickly yields to your skills.\r\n", ch);
/* now for unlocking the other side, too */
if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
if ( ( back = world[other_room].dir_option[rev_dir[door]] ) != 0 )
if (back->to_room == ch->in_room)
REMOVE_BIT(back->exit_info, EX_LOCKED);
}
}
}
void do_enter(struct char_data *ch, char *argument, int cmd)
{
int door;
char buf[MAX_INPUT_LENGTH], tmp[MAX_STRING_LENGTH];
void do_move(struct char_data *ch, char *argument, int cmd);
one_argument(argument, buf);
if (*buf) /* an argument was supplied, search for door keyword */
{
for (door = 0; door <= 5; door++)
if (EXIT(ch, door))
if (EXIT(ch, door)->keyword)
if (!str_cmp(EXIT(ch, door)->keyword, buf))
{
do_move(ch, "", ++door);
return;
}
sprintf(tmp, "There is no %s here.\r\n", buf);
send_to_char(tmp, ch);
}
else
if (IS_SET(world[ch->in_room].room_flags, INDOORS))
send_to_char("You are already indoors.\r\n", ch);
else
{
/* try to locate an entrance */
for (door = 0; door <= 5; door++)
if (EXIT(ch, door))
if (EXIT(ch, door)->to_room != NOWHERE)
if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED) &&
IS_SET(world[EXIT(ch, door)->to_room].room_flags,
INDOORS))
{
do_move(ch, "", ++door);
return;
}
send_to_char("You can't seem to find anything to enter.\r\n", ch);
}
}
void do_leave(struct char_data *ch, char *argument, int cmd)
{
int door;
void do_move(struct char_data *ch, char *argument, int cmd);
if (!IS_SET(world[ch->in_room].room_flags, INDOORS))
send_to_char("You are outside.. where do you want to go?\r\n", ch);
else
{
for (door = 0; door <= 5; door++)
if (EXIT(ch, door))
if (EXIT(ch, door)->to_room != NOWHERE)
if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED) &&
!IS_SET(world[EXIT(ch, door)->to_room].room_flags,
INDOORS))
{
do_move(ch, "", ++door);
return;
}
send_to_char("I see no obvious exits to the outside.\r\n", ch);
}
}
void do_stand(struct char_data *ch, char *argument, int cmd)
{
switch(GET_POS(ch)) {
case POSITION_STANDING : {
act("You are already standing.",FALSE, ch,0,0,TO_CHAR);
} break;
case POSITION_SITTING : {
act("You stand up.", FALSE, ch,0,0,TO_CHAR);
act("$n clambers on $s feet.",TRUE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_STANDING;
} break;
case POSITION_RESTING : {
act("You stop resting, and stand up.", FALSE, ch,0,0,TO_CHAR);
act("$n stops resting, and clambers on $s feet.",
TRUE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_STANDING;
} break;
case POSITION_SLEEPING : {
act("You have to wake up first!", FALSE, ch, 0,0,TO_CHAR);
} break;
case POSITION_FIGHTING : {
act("Do you not consider fighting as standing?",
FALSE, ch, 0, 0, TO_CHAR);
} break;
default : {
act("You stop floating around, and put your feet on the ground.",
FALSE, ch, 0, 0, TO_CHAR);
act("$n stops floating around, and puts $s feet on the ground.",
TRUE, ch, 0, 0, TO_ROOM);
} break;
}
}
void do_sit(struct char_data *ch, char *argument, int cmd)
{
switch(GET_POS(ch)) {
case POSITION_STANDING : {
act("You sit down.", FALSE, ch, 0,0, TO_CHAR);
act("$n sits down.", FALSE, ch, 0,0, TO_ROOM);
GET_POS(ch) = POSITION_SITTING;
} break;
case POSITION_SITTING : {
send_to_char("You're sitting already.\r\n", ch);
} break;
case POSITION_RESTING : {
act("You stop resting, and sit up.", FALSE, ch,0,0,TO_CHAR);
act("$n stops resting.", TRUE, ch, 0,0,TO_ROOM);
GET_POS(ch) = POSITION_SITTING;
} break;
case POSITION_SLEEPING : {
act("You have to wake up first.", FALSE, ch, 0, 0, TO_CHAR);
} break;
case POSITION_FIGHTING : {
act("Sit down while fighting? are you MAD?",
FALSE, ch,0,0,TO_CHAR);
} break;
default : {
act("You stop floating around, and sit down.",
FALSE, ch,0,0,TO_CHAR);
act("$n stops floating around, and sits down.",
TRUE, ch,0,0,TO_ROOM);
GET_POS(ch) = POSITION_SITTING;
} break;
}
}
void do_rest(struct char_data *ch, char *argument, int cmd)
{
switch(GET_POS(ch)) {
case POSITION_STANDING : {
act("You sit down and rest your tired bones.",
FALSE, ch, 0, 0, TO_CHAR);
act("$n sits down and rests.", TRUE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_RESTING;
} break;
case POSITION_SITTING : {
act("You rest your tired bones.", FALSE, ch, 0, 0, TO_CHAR);
act("$n rests.", TRUE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_RESTING;
} break;
case POSITION_RESTING : {
act("You are already resting.", FALSE, ch, 0, 0, TO_CHAR);
} break;
case POSITION_SLEEPING : {
act("You have to wake up first.", FALSE, ch, 0, 0, TO_CHAR);
} break;
case POSITION_FIGHTING : {
act("Rest while fighting? are you MAD?", FALSE, ch, 0, 0, TO_CHAR);
} break;
default : {
act("You stop floating around, and stop to rest your tired bones.",
FALSE, ch, 0, 0, TO_CHAR);
act("$n stops floating around, and rests.",
FALSE, ch, 0,0, TO_ROOM);
GET_POS(ch) = POSITION_SITTING;
} break;
}
}
void do_sleep(struct char_data *ch, char *argument, int cmd)
{
switch(GET_POS(ch)) {
case POSITION_STANDING :
case POSITION_SITTING :
case POSITION_RESTING : {
send_to_char("You go to sleep.\r\n", ch);
act("$n lies down and falls asleep.", TRUE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_SLEEPING;
} break;
case POSITION_SLEEPING : {
send_to_char("You are already sound asleep.\r\n", ch);
} break;
case POSITION_FIGHTING : {
send_to_char("Sleep while fighting? are you MAD?\r\n", ch);
} break;
default : {
act("You stop floating around, and lie down to sleep.",
FALSE, ch, 0, 0, TO_CHAR);
act("$n stops floating around, and lie down to sleep.",
TRUE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_SLEEPING;
} break;
}
}
void do_wake(struct char_data *ch, char *argument, int cmd)
{
struct char_data *tmp_char;
char arg[MAX_STRING_LENGTH];
one_argument(argument,arg);
if (*arg) {
if (GET_POS(ch) == POSITION_SLEEPING) {
act("You can't wake people up if you are asleep yourself!",
FALSE, ch,0,0,TO_CHAR);
} else {
tmp_char = get_char_room_vis(ch, arg);
if (tmp_char) {
if (tmp_char == ch) {
act("If you want to wake yourself up, just type 'wake'",
FALSE, ch,0,0,TO_CHAR);
} else {
if (GET_POS(tmp_char) == POSITION_SLEEPING) {
if (IS_AFFECTED(tmp_char, AFF_SLEEP)) {
act("You can not wake $M up!",
FALSE, ch, 0, tmp_char, TO_CHAR);
} else {
act("You wake $M up.",
FALSE, ch, 0, tmp_char, TO_CHAR);
GET_POS(tmp_char) = POSITION_STANDING;
act("You are awakened by $n.",
FALSE, ch, 0, tmp_char, TO_VICT);
}
} else {
act("$N is already awake.",
FALSE,ch,0,tmp_char, TO_CHAR);
}
}
} else {
send_to_char("You do not see that person here.\r\n", ch);
}
}
} else {
if (IS_AFFECTED(ch,AFF_SLEEP)) {
send_to_char("You can't wake up!\r\n", ch);
} else {
if (GET_POS(ch) > POSITION_SLEEPING)
send_to_char("You are already awake...\r\n", ch);
else {
send_to_char("You wake, and stand up.\r\n", ch);
act("$n awakens.", TRUE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_STANDING;
}
}
}
}
void do_follow(struct char_data *ch, char *argument, int cmd)
{
char name[160];
struct char_data *leader;
void stop_follower(struct char_data *ch);
void add_follower(struct char_data *ch, struct char_data *leader);
one_argument(argument, name);
if (*name) {
if (!(leader = get_char_room_vis(ch, name))) {
send_to_char("I see no person by that name here!\r\n", ch);
return;
}
} else {
send_to_char("Who do you wish to follow?\r\n", ch);
return;
}
if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master)) {
act("But you only feel like following $N!",
FALSE, ch, 0, ch->master, TO_CHAR);
} else { /* Not Charmed follow person */
if (leader == ch) {
if (!ch->master) {
send_to_char("You are already following yourself.\r\n", ch);
return;
}
stop_follower(ch);
} else {
if (circle_follow(ch, leader)) {
act("Sorry, but following in 'loops' is not allowed.",
FALSE, ch, 0, 0, TO_CHAR);
return;
}
if (ch->master)
stop_follower(ch);
if ((abs(GET_LEVEL(ch)-GET_LEVEL(leader))<6) || GET_LEVEL(ch)>31)
add_follower(ch, leader);
else
{
act("Sorry, but you are not of the right caliber to follow.",
FALSE, ch, 0, 0, TO_CHAR);
return;
}
}
}
}