/* ************************************************************************
* File: act.movement.c Part of CircleMUD *
* Usage: movement commands, door handling, & sleep/rest/etc state *
* *
* All rights reserved. See license.doc for complete information. *
* *
* Copyright (C) 1993 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
************************************************************************ */
/* Archipelago changes by Alastair J. Neil Copyright (C) 1993, 94, 95, 96 */
#include <stdio.h>
#include <string.h>
#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
/* external vars */
extern struct room_data *world;
extern struct char_data *character_list;
extern struct descriptor_data *descriptor_list;
extern struct index_data *obj_index;
extern struct str_app_type str_app[];
extern int rev_dir[];
extern char *dirs[],*revdirs[];
extern int movement_loss[];
extern int top_of_world;
/* external functs */
char *first_name(char *arg);
int special(struct char_data *ch, int cmd, char *arg);
void death_cry(struct char_data *ch);
void add_event(int plse, int event, int inf1, int inf2, int inf3
, int inf4, char *arg, void *subj, void *vict);
void rmdamage(struct char_data *victim, int dam);
bool fall_down(struct char_data *ch);
bool fall_down(struct char_data *ch)
{
int fall, down_room;
fall = number(0,30);
fall -= (IS_CARRYING_W(ch)+GET_WEIGHT(ch))/100;
fall += GET_DEX(ch)/2;
fall += GET_STR(ch)/2;
fall += GET_FOC(ch)/2;
fall += GET_SKILL(ch,SKILL_CLIMB);
down_room = NOWHERE;
if (CAN_GO(ch,5))
down_room = EXIT(ch,5)->to_room;
else
return(FALSE);
if (down_room != NOWHERE){
if (IS_SET(world[ch->in_room].room_flags, CLIMB_MODERATE))
{
if (fall < 3 && !IS_AFFECTED(ch, AFF_FLY))
{
if (!number(0,5)){
act("Suddenly you nearly fall! but you catch yourself."
,TRUE,ch,0,0,TO_CHAR);
act("Suddenly $n nearly falls! but catches $mself."
,TRUE,ch,0,0,TO_ROOM);
if (!IS_AFFECTED(ch,AFF_FLY)){
act("You learn a new climbing move.",TRUE,ch,0,0,TO_CHAR);
SET_SKILL(ch,SKILL_CLIMB,MIN(30,GET_SKILL(ch,SKILL_CLIMB)
+ number (0,1)));}
return(FALSE);
}
act("\r\nSuddenly you fall!!",TRUE,ch,0,0,TO_CHAR);
act("\r\n$n falls!!",TRUE,ch,0,0,TO_ROOM);
if (down_room)
{
char_from_room(ch);
char_to_room(ch,down_room, TRUE);
act("\r\n$n falls down from above!",TRUE,ch,0,0,TO_ROOM);
do_look(ch,"",0,0);
GET_POS(ch) = POSITION_SITTING;
}
SET_SKILL(ch,SKILL_CLIMB,GET_SKILL(ch,SKILL_CLIMB)
- number(0,1));
rmdamage(ch,4*GET_MAX_HIT(ch)/10 + number(5,20));
act("you lose some confidence",TRUE,ch,0,0,TO_CHAR);
}
}
if (IS_SET(world[ch->in_room].room_flags, CLIMB_HARD))
{
if (fall < 35 && !IS_AFFECTED(ch, AFF_FLY))
{
if (!number(0,5)){
act("Suddenly you nearly fall! but you catch yourself."
,TRUE,ch,0,0,TO_CHAR);
act("Suddenly $n nearly falls! but catches $mself."
,TRUE,ch,0,0,TO_ROOM);
if (!IS_AFFECTED(ch,AFF_FLY)){
act("You learn a new climbing move.",TRUE,ch,0,0,TO_CHAR);
SET_SKILL(ch,SKILL_CLIMB,MIN(30,GET_SKILL(ch,SKILL_CLIMB)
+ number (0,1)));}
return(FALSE);
}
act("\r\nSuddenly you fall!!",TRUE,ch,0,0,TO_CHAR);
act("\r\n$n falls!!",TRUE,ch,0,0,TO_ROOM);
if (down_room)
{
char_from_room(ch);
char_to_room(ch,down_room, TRUE);
act("\r\n$n falls down from above!",TRUE,ch,0,0,TO_ROOM);
do_look(ch,"",0,0);
GET_POS(ch) = POSITION_SITTING;
}
SET_SKILL(ch,SKILL_CLIMB,GET_SKILL(ch,SKILL_CLIMB)
- number(0,1));
rmdamage(ch,6*GET_MAX_HIT(ch)/10 + number(20,50));
act("you lose some confidence",TRUE,ch,0,0,TO_CHAR);
}
}
if (IS_SET(world[ch->in_room].room_flags, CLIMB_SEVERE))
{
if (fall < 50 && !IS_AFFECTED(ch, AFF_FLY))
{
if (!number(0,5)){
act("Suddenly you nearly fall! but you catch yourself."
,TRUE,ch,0,0,TO_CHAR);
act("Suddenly $n nearly falls! but catches $mself."
,TRUE,ch,0,0,TO_ROOM);
if (!IS_AFFECTED(ch,AFF_FLY)){
act("You learn a new climbing move.",TRUE,ch,0,0,TO_CHAR);
SET_SKILL(ch,SKILL_CLIMB,MIN(30,GET_SKILL(ch,SKILL_CLIMB)
+ number (0,1)));}
return (FALSE);
}
act("\r\nSuddenly you fall!!",TRUE,ch,0,0,TO_CHAR);
act("\r\n$n falls!!",TRUE,ch,0,0,TO_ROOM);
if (down_room)
{
char_from_room(ch);
char_to_room(ch,down_room, TRUE);
act("\r\n$n falls down from above!",TRUE,ch,0,0,TO_ROOM);
do_look(ch,"",0,0);
GET_POS(ch) = POSITION_SITTING;
}
SET_SKILL(ch,SKILL_CLIMB,GET_SKILL(ch,SKILL_CLIMB)
- number(0,1));
rmdamage(ch,9*GET_MAX_HIT(ch)/10 + number(50,100));
act("you lose some confidence",TRUE,ch,0,0,TO_CHAR);
}
}
if (IS_SET(world[ch->in_room].room_flags, CLIMB_EXTREME))
{
if (fall < 75 && !IS_AFFECTED(ch, AFF_FLY))
{
if (!number(0,5)){
act("Suddenly you nearly fall! but you catch yourself."
,TRUE,ch,0,0,TO_CHAR);
act("Suddenly $n nearly falls! but catches $mself."
,TRUE,ch,0,0,TO_ROOM);
if (!IS_AFFECTED(ch,AFF_FLY)){
act("You learn a new climbing move.",TRUE,ch,0,0,TO_CHAR);
SET_SKILL(ch,SKILL_CLIMB,MIN(30,GET_SKILL(ch,SKILL_CLIMB)
+ number (0,2)));}
return(FALSE);
}
act("\r\nSuddenly you fall!!",TRUE,ch,0,0,TO_CHAR);
act("\r\n$n falls!!",TRUE,ch,0,0,TO_ROOM);
if (down_room)
{
char_from_room(ch);
char_to_room(ch,down_room, TRUE);
act("\r\n$n falls down from above!",TRUE,ch,0,0,TO_ROOM);
do_look(ch,"",0,0);
GET_POS(ch) = POSITION_SITTING;
}
SET_SKILL(ch,SKILL_CLIMB,GET_SKILL(ch,SKILL_CLIMB)
- number(1,2));
rmdamage(ch,49*GET_MAX_HIT(ch)/50 + number(100,200));
act("you lose some confidence",TRUE,ch,0,0,TO_CHAR);
}
}
return(TRUE);
}
return(FALSE);
}
bool throw_rider(struct char_data *ch) {
int num;
struct char_data *tmp;
if (!ch->specials.mount)
return(FALSE);
if (GET_SKILL(ch, SKILL_RIDING) < (num = number(0,31)) && !number(0,31))
if (GET_SKILL(ch, SKILL_RIDING) < (num = number(0,31))) {
act("$N slips and throws $n!", FALSE,ch,0,ch->specials.mount,TO_ROOM);
act("$N slips and throws you!", FALSE,ch,0,ch->specials.mount,TO_CHAR);
act("You slip and throws $n!", FALSE,ch,0,ch->specials.mount,TO_VICT);
GET_POS(ch) = POSITION_SITTING;
rmdamage(ch,GET_HEIGHT(ch->specials.mount)/number(5,20));
if (num == 0 && (number(0,31) == 0)
&& (number(0,31) > GET_SKILL(ch, SKILL_RIDING))
&& (GET_SKILL(ch, SKILL_RIDING) < 30)) {
send_to_char("You realise how you can improve your riding technique\r\n.",ch);
SET_SKILL(ch, SKILL_RIDING,(GET_SKILL(ch,SKILL_RIDING) + 1));
rmdamage(ch,GET_HEIGHT(ch->specials.mount)/number(5,20));
}
tmp = ch->specials.mount;
unmount(ch);
if (!number(0,10) && IS_MOB(tmp) && (GET_INT(tmp) < 10))
do_flee(tmp,"",0,0);
return(TRUE);
}
return(FALSE);
}
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.
*/
{
int special(struct char_data *ch, int cmd, char *arg);
int need_movement, target_sect, curr_sect, nteam, total_weight;
int delay,num;
struct char_data *tmp;
struct obj_data *obj, *cart;
struct room_data *target_room;
struct follow_type *k;
bool has_boat, cart_move;
if (special(ch, cmd + 1, "")) /* Check for special routines (North is 1) */
return(FALSE);
if (ch->specials.mount)
if ((GET_POS(ch->specials.mount) != POSITION_STANDING)
|| IS_AFFECTED(ch->specials.mount, AFF_PARALYSIS)
|| MOB_FLAGGED(ch->specials.mount, MOB_TETHERED)
){
send_to_char("Your mount seems unable to move.\r\n",ch);
return(FALSE);
}
if (IS_MOB(ch) && MOB_FLAGGED(ch,MOB_TETHERED))
return(FALSE);
if (IS_SET(world[real_room(world[ch->in_room].dir_option[cmd]->to_room)].room_flags,UNFINISHED) && GET_LEVEL(ch) < LEVEL_BUILDER){
send_to_char("A strange force bars your movement in that direction.\r\n",ch);
return(FALSE);
}
if ((world[ch->in_room].dir_option[cmd]->to_room == 0) &&
world[ch->in_room].dir_option[cmd]->general_description){
send_to_char( world[ch->in_room].dir_option[cmd]->general_description,ch);
return(FALSE);
}
else if (world[ch->in_room].dir_option[cmd]->to_room == 0){
send_to_char("A strange force bars your movement in that direction.\r\n",ch);
return(FALSE);
}
target_room =&world[real_room(world[ch->in_room].dir_option[cmd]->to_room)];
target_sect= target_room->sector_type;
curr_sect = world[ch->in_room].sector_type;
if (IS_PULLING(ch)
&& (target_sect != SECT_CITY
&& target_sect != SECT_FIELD
&& target_sect != SECT_HILLS
&& target_sect != SECT_FOREST)){
send_to_char("You can't drag cart there.\r\n",ch);
return(FALSE);}
if (ch->specials.mount && (target_sect == SECT_INSIDE)) {
send_to_char("You can't ride indoors.\r\n",ch);
return(FALSE);
}
if (IS_AFFECTED(ch, AFF_SLIPPY) && !number(0,1)){
act("$n slips and falls down.", TRUE, ch, 0,0,TO_ROOM);
send_to_char("You slip and fall down.\r\n",ch);
GET_POS(ch) = POSITION_SITTING;
if (ch->specials.rider)
if(throw_rider(ch->specials.rider))
;
if (ch->specials.carrying)
do_drop_mob(ch);
return(FALSE);
}
need_movement = (movement_loss[curr_sect] + movement_loss[target_sect])/ 2;
if (IS_AFFECTED(ch,AFF_FLY) &&
((curr_sect != SECT_UNDER_WATER) || (target_sect != SECT_UNDER_WATER)))
need_movement = 1;
/* 9-22-94: patch by Scarrow to make water rooms easier with a boat */
has_boat = FALSE;
/* See if char is carrying a boat */
for (obj = ch->inventory; obj; obj = obj->next_content)
if (obj->obj_flags.type_flag == ITEM_BOAT)
has_boat = TRUE;
/* if it's water (swim or noswim) and we have a boat and aren't flying */
/* halve the computed cost of movement -- Scarrow (9-22-94) */
if (((world[ch->in_room].sector_type == SECT_WATER_SWIM) ||
(world[ch->in_room].sector_type == SECT_WATER_NOSWIM) ||
(target_room->sector_type == SECT_WATER_SWIM) ||
(target_room->sector_type == SECT_WATER_NOSWIM)) &&
has_boat && (!IS_AFFECTED(ch, AFF_FLY) ||
(ch->specials.mount && !IS_AFFECTED(ch->specials.mount, AFF_FLY)))) {
need_movement /= 2;
}
if ((world[ch->in_room].sector_type == SECT_WATER_NOSWIM) ||
(target_room->sector_type == SECT_WATER_NOSWIM)) {
if (!has_boat && !IS_AFFECTED(ch,AFF_FLY) && !ch->specials.carried_by &&
!IS_AFFECTED(ch, AFF_WATER_BREATH)
&& !(ch->specials.mount &&(IS_AFFECTED(ch->specials.mount,AFF_FLY) ||
IS_AFFECTED(ch->specials.mount, AFF_WATER_BREATH)))) {
send_to_char("You thrash about trying to stay afloat.\r\n", ch);
need_movement *= 2;
}
}
if ((world[ch->in_room].sector_type == SECT_FLY) ||
(target_room->sector_type == SECT_FLY)) {
if (!IS_AFFECTED(ch,AFF_FLY) && !ch->specials.carried_by
&& !(ch->specials.mount && IS_AFFECTED(ch->specials.mount,AFF_FLY))) {
send_to_char("You would need wings to go there.\r\n", ch);
return(FALSE);
}
}
if ((world[ch->in_room].sector_type == SECT_THICKET) ||
(world[real_room(world[ch->in_room].dir_option[cmd]->to_room)].sector_type == SECT_THICKET)) {
if (GET_LEVEL(ch) < LEVEL_BUILDER && GET_SIZE(ch) < 6) {
send_to_char("Ouch! you are raked by briar thorns.\r\n", ch);
if (ch->specials.mount) {
rmdamage(ch,number(4,32));
rmdamage(ch->specials.mount,number(4,32));
}
else
rmdamage(ch,number(2,16));
}
else
send_to_char("The briar thorns bounce harmlessly off your skin.\r\n", ch);
}
if ((world[ch->in_room].sector_type == SECT_UNDER_WATER) ||
(target_room->sector_type == SECT_UNDER_WATER)) {
if (!IS_AFFECTED(ch,AFF_WATER_BREATH) && !ch->specials.carried_by &&
!(ch->specials.mount
&& IS_AFFECTED(ch->specials.mount,AFF_WATER_BREATH))) {
send_to_char("You thrash about. You are Drowning!\r\n", ch);
need_movement *= 2;
}
}
if (IS_SET(target_room->room_flags,SMALL))
if ((GET_SIZE(ch) < 4) ||
(ch->specials.mount && (GET_SIZE(ch->specials.mount) < 4))){
send_to_char("You bump your head.\r\n",ch);
send_to_char("You can't go there, you are too big.\r\n",ch);
return(FALSE);}
else if ( (GET_SIZE(ch) < 5) ||
(ch->specials.mount && (GET_SIZE(ch->specials.mount) < 5)))
send_to_char("You bump your head.\r\n",ch);
if (IS_SET(target_room->room_flags,TINY))
if ( (GET_SIZE(ch) < 5) ||
(ch->specials.mount && (GET_SIZE(ch->specials.mount) < 5))){
send_to_char("You bump your head.\r\n",ch);
send_to_char("You can't go there, you are too big.\r\n",ch);
return(FALSE);}
else if ((GET_SIZE(ch) < 6) ||
(ch->specials.mount && (GET_SIZE(ch->specials.mount) < 6)))
send_to_char("You bump your head.\r\n",ch);
if ((cmd == 4 || cmd ==5) && !ch->specials.carried_by &&
!(IS_AFFECTED(ch,AFF_FLY) ||
(ch->specials.mount && IS_AFFECTED(ch->specials.mount,AFF_FLY))) &&
(((IS_SET(world[TO_RM(ch,cmd)].room_flags,CLIMB_MODERATE) ||
IS_SET(world[ch->in_room].room_flags, CLIMB_MODERATE))
&& (GET_SKILL(ch,SKILL_CLIMB) < 8) && number(0,3)) ||
((IS_SET(world[TO_RM(ch,cmd)].room_flags,CLIMB_HARD) ||
IS_SET(world[ch->in_room].room_flags, CLIMB_HARD))
&& (GET_SKILL(ch,SKILL_CLIMB) < 18) && number(0,6)) ||
((IS_SET(world[TO_RM(ch,cmd)].room_flags,CLIMB_SEVERE) ||
IS_SET(world[ch->in_room].room_flags, CLIMB_SEVERE))
&& (GET_SKILL(ch,SKILL_CLIMB) < 26) && number(0,8)) ||
((IS_SET(world[TO_RM(ch,cmd)].room_flags,CLIMB_EXTREME) ||
IS_SET(world[ch->in_room].room_flags, CLIMB_EXTREME))
&& (GET_SKILL(ch,SKILL_CLIMB) < 29) && number(0,15))))
{
if (ch->specials.mount) {
act("$N cannot manage the climb.",FALSE,ch,0,ch->specials.mount,TO_CHAR);
return(FALSE);
}
send_to_char("You aren't a good enough climber.\r\n",ch);
if (IS_CLIMB(ch, cmd))
fall_down(ch);
if (cmd != 5){
send_to_char("You fall back onto your backside.\r\n",ch);
GET_POS(ch) = POSITION_SITTING;
if (!IS_AFFECTED(ch,AFF_FLY) && !ch->specials.carried_by){
if ((IS_SET(world[ch->in_room].room_flags, CLIMB_MODERATE) && (number(0,20) <= 1)) || (IS_SET(world[ch->in_room].room_flags, CLIMB_HARD) && (number(0,20) <= 3)) || (IS_SET(world[ch->in_room].room_flags, CLIMB_SEVERE) && (number(0,20) <= 5)) || (IS_SET(world[ch->in_room].room_flags, CLIMB_EXTREME) && (number(0,20) <= 8))){
act("You learn a new climbing move.",TRUE,ch,0,0,TO_CHAR);
SET_SKILL(ch,SKILL_CLIMB,MIN(30,GET_SKILL(ch,SKILL_CLIMB) + number (0,2)));
}
}
}
return(FALSE);
}
if (IS_PULLING(ch)){
total_weight = 0;
for (k = IS_PULLING(ch)->pulled_by;k;k = k->next)
total_weight += GET_WEIGHT(k->follower);
need_movement += (need_movement*GET_OBJ_WEIGHT(IS_PULLING(ch))/
total_weight);}
need_movement *= encumberance_level(ch);
if (ch->specials.mount)
if ((GET_MOVE(ch->specials.mount) < 2*need_movement) &&
(GET_HIT(ch->specials.mount) < GET_MAX_HIT(ch->specials.mount)/4)) {
send_to_char("Your mount is too exhausted.\r\n", ch);
return(FALSE);
}
if ((GET_MOVE(ch) < need_movement) &&
(GET_HIT(ch) < GET_MAX_HIT(ch)/4)
) {
if (following && !ch->master)
send_to_char("You are too exhausted to follow.\r\n", ch);
else
send_to_char("You are too exhausted.\r\n", ch);
return(FALSE);
}
if (!ch->specials.carried_by) {
if (ch->specials.mount) {
GET_MOVE(ch) -= need_movement/4;
GET_MOVE(ch->specials.mount) -=
need_movement*(2*CAN_CARRY_W(ch->specials.mount)
/(GET_WEIGHT(ch)+ IS_CARRYING_W(ch)));
if (GET_MOVE(ch) < 0)
GET_HIT(ch) -= MAX(1,GET_HIT(ch)/4);
}
else {
if (GET_LEVEL(ch) < LEVEL_BUILDER || IS_NPC(ch)){
GET_MOVE(ch) -= need_movement;
if (GET_MOVE(ch) < 0){
send_to_char("You are wracked with pain as you overexert yourself.\r\n",ch);
act("Though exhausted $n manages to move.",FALSE,ch,0,0,TO_NOTCHAR);
GET_HIT(ch) -= MAX(1,GET_HIT(ch)/4);
}
}
}
}
if (ch->specials.mount)
delay = (need_movement*GET_MAX_MOVE(ch->specials.mount))
/(MAX(1,GET_MOVE(ch->specials.mount))
*(10 + GET_STR(ch->specials.mount)/2));
else
delay = need_movement/10;
if (ch->specials.mount)
if (throw_rider(ch))
return(FALSE);
if ((cart = IS_PULLING(ch))){
/* add leave events for all hitched */
cart_move = TRUE;
nteam = 0;
for (k = cart->pulled_by;k;k = k->next)
if (GET_MOVE(k->follower) < 0) {
nteam++;
cart_move = FALSE;
}
if(cart_move){
for (k = cart->pulled_by;k;k = k->next){
WAIT_STATE(k->follower,delay);
add_event(0, EVENT_LEAVE, cmd,has_boat,0,0,0,k->follower,0);}
/* and the cart itself */
add_event(0, EVENT_CART_LEAVE,cmd,cart->in_room,0,0,0,cart,0);
}
else{
if (nteam > 1){
act("The team strains to move $p."
,TRUE,cart->pulled_by->follower,cart,0,TO_ROOM);
act("But they are too exhausted."
,TRUE,cart->pulled_by->follower,cart,0,TO_ROOM);}
else{
act("$n strains to move $p."
,TRUE,cart->pulled_by->follower,cart,0,TO_ROOM);
act("But $e is too exhausted."
,TRUE,cart->pulled_by->follower,cart,0,TO_ROOM);}
}
}
else
add_event(0, EVENT_LEAVE, cmd,has_boat,0,0,0,ch,0);
WAIT_STATE(ch,delay);
if (ch->desc)
ch->desc->prompt_mode =0;
if ((cart = IS_PULLING(ch))){
if(cart_move){
for (k = cart->pulled_by;k;k = k->next)
add_event(delay, EVENT_ARRIVE,
cmd,world[ch->in_room].dir_option[cmd]->to_room
,0,0,0,k->follower,0);
/* and the cart itself */
add_event(delay, EVENT_CART_ARRIVE,cmd
,world[ch->in_room].dir_option[cmd]->to_room
,0,0,0,cart,0);
}
}
else
add_event(delay, EVENT_ARRIVE, cmd,world[ch->in_room].dir_option[cmd]->to_room,0,0,0,ch,0);
return(1);
}
ACMD(do_move)
{
int was_in,ex,nexits,which;
struct follow_type *k, *next_dude;
if (ch->specials.carried_by) {
act("Ask $N to drop you first.",
FALSE,ch,0,ch->specials.carried_by,TO_CHAR);
return;
}
if (IS_SET(world[ch->in_room].room_flags, SPIN)){
nexits=0;
for (ex=0;ex < NUM_OF_DIRS;ex++)
{
if (EXIT(ch,ex))
nexits++;
}
if (nexits >1) {
which = number(1,nexits);
nexits=0;
for (ex=0;ex < NUM_OF_DIRS && nexits < which;ex++)
{
if (EXIT(ch,ex))
nexits++;
}
cmd = ex;
}
}
--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)
&& !IS_SET(EXIT(ch,cmd)->exit_info,EX_SECRET)
&& !IS_SET(EXIT(ch,cmd)->exit_info,EX_DARK)) {
if (EXIT(ch, cmd)->keyword) {
sprintf(buf2, "The %s seems to be closed.\r\n",
fname(EXIT(ch, cmd)->keyword));
send_to_char(buf2, ch);
}
else
send_to_char("It seems to be closed.\r\n", ch);
}
else if (IS_SET(EXIT(ch, cmd)->exit_info, EX_CLOSED)
&& (IS_SET(EXIT(ch,cmd)->exit_info,EX_SECRET)
|| IS_SET(EXIT(ch,cmd)->exit_info,EX_DARK)))
send_to_char("Alas, you cannot go that way...\r\n", ch);
else if (EXIT(ch, cmd)->to_room == NOWHERE)
send_to_char("Alas, you cannot go that way...\r\n", ch);
else if (!ch->followers && !ch->master)
do_simple_move(ch, cmd, FALSE);
else {
was_in = ch->in_room;
if (do_simple_move(ch, cmd, TRUE) == 1) { /* Move the character */
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) &&
!k->follower->specials.fighting){
if(IS_NPC(ch) && !number(0,3) && GET_LEVEL(k->follower) < LEVEL_BUILDER && !IS_NPC(k->follower)){
act("You lost track of $n.",TRUE,ch,0,k->follower,TO_VICT);
break;}
else {
act("You follow $N.\r\n", FALSE, k->follower, 0, ch, TO_CHAR);
do_move(k->follower, argument, cmd + 1, 0);
}
}
}
}
}
}
}
}
int find_door(struct char_data *ch, char *type, char *dir)
{
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(buf2, "I see no %s there.\r\n", type);
send_to_char(buf2, ch);
return(-1);
}
else
return(door);
else {
send_to_char("I really don't see how you can close anything there.\r\n", ch);
return(-1);
}
}
else /* try to locate the keyword */ {
for (door = 0; door < NUM_OF_DIRS; door++)
if (EXIT(ch, door))
if (EXIT(ch, door)->keyword)
if (isname(type, EXIT(ch, door)->keyword))
return(door);
sprintf(buf2, "I see no %s here.\r\n", type);
send_to_char(buf2, ch);
return(-1);
}
}
ACMD(do_open)
{
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("Open what?\r\n", ch);
else if (generic_find(argument,FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP
,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);
act("$n opens $p.", FALSE, ch, obj, 0, TO_ROOM);
act("you open $p.", FALSE, ch, obj, 0, TO_CHAR);
}
else if ((door = find_door(ch, type, dir)) >= 0)
/* perhaps it is a door */
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 ){
if (IS_SET(EXIT(ch,door)->exit_info, EX_SECRET))
act("$n opens a hidden passage.", FALSE, ch, 0,0, TO_ROOM);
else
act("$n opens the $F.", FALSE, ch, 0,
EXIT(ch, door)->keyword, TO_ROOM);
act("You open the $F.", FALSE, ch, 0,
EXIT(ch, door)->keyword, TO_CHAR);
}
else if (IS_SET(EXIT(ch,door)->exit_info, EX_SECRET)){
act("$n opens a hidden passage.", FALSE, ch, 0,0, TO_ROOM);
act("you open the door.", FALSE, ch, 0,0, TO_CHAR);
}
else{
act("$n opens a door.", FALSE, ch, 0, 0, TO_ROOM);
act("you open the door.", FALSE, ch, 0,0, TO_CHAR);
}
/* now for opening the OTHER side of the door! */
if ((other_room = real_room(EXIT(ch, door)->to_room)) != NOWHERE)
if ((back = world[other_room].dir_option[rev_dir[door]]))
if (world[ch->in_room].number == back->to_room) {
REMOVE_BIT(back->exit_info, EX_CLOSED);
if (back->keyword) {
if (IS_SET(back->exit_info, EX_SECRET))
sprintf(buf, "A hidden passage is opened from the other side.\r\n");
else
sprintf(buf, "The %s is opened from the other side.\r\n",fname(back->keyword));
send_to_room(buf, EXIT(ch, door)->to_room, TRUE);
}
else if (IS_SET(back->exit_info, EX_SECRET))
send_to_room("A hidden passage is opened from the other side.\r\n", EXIT(ch, door)->to_room, TRUE);
else
send_to_room("The door is opened from the other side.\r\n",
EXIT(ch, door)->to_room, TRUE);
}
}
}
ACMD(do_close)
{
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("Close what?\r\n", ch);
else if (generic_find(argument,FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP
,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);
act("$n closes $p.", FALSE, ch, obj, 0, TO_ROOM);
act("You close $p.", FALSE, ch, obj, 0, TO_CHAR);
}
else if ((door = find_door(ch, type, dir)) >= 0)
/* Or 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("It's already closed!\r\n", ch);
else {
SET_BIT(EXIT(ch, door)->exit_info, EX_CLOSED);
if (EXIT(ch, door)->keyword){
if (IS_SET(EXIT(ch,door)->exit_info, EX_SECRET))
act("$n closes a hidden passage.", 0, ch, 0,0,TO_ROOM);
else
act("$n closes the $F.", 0, ch, 0, EXIT(ch, door)->keyword,
TO_ROOM);
act("You close the $F.", 0, ch, 0, EXIT(ch, door)->keyword,TO_CHAR);
}
else if (IS_SET(EXIT(ch,door)->exit_info, EX_SECRET)){
act("$n closes a hidden passage.", 0, ch, 0,0,TO_ROOM);
act("You close a hidden passage.", 0, ch, 0,0,TO_CHAR);
}
else{
act("$n closes the door.", FALSE, ch, 0, 0, TO_ROOM);
act("You close the door.", FALSE, ch, 0, 0, TO_CHAR);
}
/* now for closing the other side, too */
if ((other_room = real_room(EXIT(ch, door)->to_room)) != NOWHERE)
if ((back = world[other_room].dir_option[rev_dir[door]]))
if (world[ch->in_room].number == back->to_room) {
SET_BIT(back->exit_info, EX_CLOSED);
if (back->keyword) {
if (IS_SET(back->exit_info, EX_SECRET))
sprintf(buf, "A hidden passage closes quietly.\r\n");
else
sprintf(buf, "The %s closes quietly.\r\n", fname(back->keyword));
send_to_room(buf, EXIT(ch, door)->to_room, TRUE);
} else
if (IS_SET(back->exit_info, EX_SECRET))
send_to_room("A hidden passage closes quietly.\r\n", EXIT(ch, door)->to_room, TRUE);
else
send_to_room("The door closes quietly.\r\n", EXIT(ch, door)->to_room, TRUE);
}
}
}
int has_key(struct char_data *ch, int key)
{
struct obj_data *o;
for (o = ch->inventory; 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);
}
ACMD(do_lock)
{
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 (ch->specials.mount) {
send_to_char("You had better dismount first.\r\n", ch);
return;}
if (!*type)
send_to_char("Lock what?\r\n", ch);
else if (generic_find(argument,FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP
,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)
if (IS_SET(EXIT(ch,door)->exit_info, EX_SECRET))
act("$n locks a hidden door.", FALSE, ch, 0,0, TO_ROOM);
else
act("$n locks the $F.", 0, ch, 0, EXIT(ch, door)->keyword,
TO_ROOM);
else if (IS_SET(EXIT(ch,door)->exit_info, EX_SECRET))
act("$n locks a hidden door.", FALSE, ch, 0,0, 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 = real_room(EXIT(ch, door)->to_room)) != NOWHERE)
if ((back = world[other_room].dir_option[rev_dir[door]]))
if (back->to_room == world[ch->in_room].number)
SET_BIT(back->exit_info, EX_LOCKED);
}
}
ACMD(do_unlock)
{
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 (ch->specials.mount) {
send_to_char("You had better dismount first.\r\n", ch);
return;}
if (!*type)
send_to_char("Unlock what?\r\n", ch);
else if (generic_find(argument,FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP
,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)
if (IS_SET(EXIT(ch,door)->exit_info, EX_SECRET))
act("$n unlocks a hidden door.", FALSE, ch, 0,0, TO_ROOM);
else
act("$n unlocks the $F.", 0, ch, 0, EXIT(ch, door)->keyword,
TO_ROOM);
else if (IS_SET(EXIT(ch,door)->exit_info, EX_SECRET))
act("$n unlocks a hidden door.", FALSE, ch, 0,0, 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 = real_room(EXIT(ch, door)->to_room)) != NOWHERE)
if ((back = world[other_room].dir_option[rev_dir[door]]))
if (back->to_room == world[ch->in_room].number)
REMOVE_BIT(back->exit_info, EX_LOCKED);
}
}
ACMD(do_pick)
{
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, 31); /* 101% is a complete failure */
if ((IS_NPC(ch) && percent > GET_LEVEL(ch)/10) ||
(!IS_NPC(ch) && (percent > GET_SKILL(ch, SKILL_PICK_LOCK)))) {
send_to_char("You failed to pick the lock.\r\n", ch);
return;
}
if (ch->specials.mount) {
send_to_char("Pick locks while riding? Fat chance.\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 | FIND_OBJ_EQUIP
, 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 isn'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 door.", 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 = real_room(EXIT(ch, door)->to_room)) != NOWHERE)
if ((back = world[other_room].dir_option[rev_dir[door]]))
if (back->to_room == world[ch->in_room].number)
REMOVE_BIT(back->exit_info, EX_LOCKED);
}
}
ACMD(do_enter)
{
int door, was_in;
struct follow_type *k, *next_dude;
struct obj_data *cont;
ACMD(do_move);
one_argument(argument, buf);
if (ch->specials.carried_by) {
act("Ask $N to drop you first.",
FALSE,ch,0,ch->specials.carried_by,TO_CHAR);
return;
}
if (*buf) /* an argument was supplied, search for door keyword */ {
for (door = 0; door < NUM_OF_DIRS; door++)
if (EXIT(ch, door))
if (EXIT(ch, door)->keyword)
if (!str_cmp(EXIT(ch, door)->keyword, buf)) {
do_move(ch, "", ++door, 0);
return;
}
/* ok not a door how about an object */
if ((cont = get_obj_in_list_vis(ch,buf,world[ch->in_room].contents)))
{
if (HASROOM(cont))
if (!IS_SET(cont->obj_flags.value[1],CONT_CLOSED))
{
if (GET_OBJ_SIZE(cont) - GET_SIZE(ch) > 1){
sprintf(buf1,
"The %s is too small you can't fit."
,first_name(cont->name));
act(buf1,TRUE,ch,0,0,TO_CHAR);
return;
}
if ((GET_WEIGHT(ch)
+ IS_CARRYING_W(ch) +
+ GET_OBJ_WEIGHT(cont))
> cont->obj_flags.value[0])
{
sprintf(buf1,
"There is no room in the %s."
,first_name(cont->name));
act(buf1,TRUE,ch,0,0,TO_CHAR);
return;
}
if(real_room(cont->obj_flags.value[3]) == -1){
send_to_char("You can't enter that!\r\n",ch);
return;
}
act("$n enters $p.",TRUE,ch,cont,0,TO_ROOM);
act("You enter $p.",TRUE,ch,cont,0,TO_CHAR);
was_in = ch->in_room;
char_from_room(ch);
char_to_room(ch,cont->obj_flags.value[3],
TRUE);
do_look(ch,"",0,0);
if (!IS_SET(world[ch->in_room]
.obj->obj_flags.value[1], CONT_ONEWAY))
act("$n enters $p.",TRUE,ch,cont,0,TO_ROOM);
else
act("Suddenly, $n arrives!",TRUE,ch,cont,0,TO_ROOM);
if (ch->followers) {
for (k = ch->followers; k; k = next_dude) {
next_dude = k->next;
if ((k->follower->in_room == was_in) &&
(GET_POS(k->follower) >= POSITION_STANDING)
&& !k->follower->specials.fighting){
if(IS_NPC(ch) && !number(0,3)
&& GET_LEVEL(k->follower)
< LEVEL_BUILDER && !IS_NPC(k->follower)){
act("You lost track of $n.",TRUE,ch,0,k->follower,TO_VICT);
break;}
else {
act("You follow $N.\r\n", FALSE, k->follower, 0, ch, TO_CHAR);
do_enter(k->follower, argument,0,0);
}
}
}
}
return;
}
else
{
sprintf(buf1,"The %s seems to be closed."
,first_name(cont->name));
act(buf1,TRUE,ch,cont,0,TO_CHAR);
return;
}
else{
send_to_char("You can't enter that!\r\n",ch);
return;
}
}
sprintf(buf2, "There is no %s here.\r\n", buf);
send_to_char(buf2, 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 < NUM_OF_DIRS; 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[real_room(EXIT(ch, door)->to_room)].room_flags,
INDOORS)) {
do_move(ch, "", ++door, 0);
return;
}
/* ok not a door how about an object */
if ((cont = get_obj_in_list_vis(ch,buf,world[ch->in_room].contents)))
{
if (HASROOM(cont))
if (!IS_SET(cont->obj_flags.value[1],CONT_CLOSED))
{
if (GET_OBJ_SIZE(cont) - GET_SIZE(ch) > 1){
sprintf(buf1,
"The %s is too small you can't fit."
,first_name(cont->name));
act(buf1,TRUE,ch,0,0,TO_CHAR);
return;
}
if ((GET_WEIGHT(ch)+IS_CARRYING_W(ch)
+ GET_OBJ_WEIGHT(cont))
> cont->obj_flags.value[0])
{
sprintf(buf1,
"There is no room in the %s."
,first_name(cont->name));
act(buf1,TRUE,ch,0,0,TO_CHAR);
return;
}
if(real_room(cont->obj_flags.value[3]) == -1){
send_to_char("You can't enter that!\r\n",ch);
return;
}
/* sprintf(buf1,"$n enters the %s."
,first_name(cont->name));*/
act("$n enters $p.",TRUE,ch,cont,0,TO_ROOM);
/* sprintf(buf1,"You enter the %s."
,first_name(cont->name)); */
act("you enter $p.",TRUE,ch,cont,0,TO_CHAR);
char_from_room(ch);
char_to_room(ch,real_room(cont->obj_flags.value[3])
,FALSE);
do_look(ch,"",0,0);
/* sprintf(buf1,"$n enters the %s."
,first_name(cont->name)); */
act("$n enters $p.",TRUE,ch,cont,0,TO_ROOM);
return;
}
else
{
sprintf(buf1,"The %s seems to be closed."
,first_name(cont->name));
act(buf1,TRUE,ch,cont,0,TO_CHAR);
return;
}
else
{
send_to_char("You can't enter that!\r\n",ch);
return;
}
}
send_to_char("You can't seem to find anything to enter.\r\n", ch);
}
}
ACMD(do_leave)
{
int door, to_room, was_in;
struct follow_type *k, *next_dude;
struct obj_data *cont;
ACMD(do_move);
if (ch->specials.carried_by) {
act("Ask $N to drop you first.",
FALSE,ch,0,ch->specials.carried_by,TO_CHAR);
return;
}
if (world[ch->in_room].obj)
{
cont = world[ch->in_room].obj;
if (GET_ITEM_TYPE(cont) == ITEM_CONTAINER &&
!IS_SET(cont->obj_flags.value[1], CONT_ONEWAY) &&
!IS_SET(cont->obj_flags.value[1],CONT_CLOSED)){
if (GET_OBJ_SIZE(cont) - GET_SIZE(ch) > 1){
sprintf(buf1,
"The %s is too small you are stuck!"
,first_name(cont->name));
act(buf1,TRUE,ch,0,0,TO_CHAR);
return;
}
if (cont->in_room != NOWHERE){
act("You leave $p.",TRUE,ch,cont,0,TO_CHAR);
act("$n leaves $p.",TRUE,ch,cont,0,TO_ROOM);
to_room = cont->in_room;
was_in = ch->in_room;
char_from_room(ch);
char_to_room(ch,to_room, FALSE);
do_look(ch,"",0,0);
act("$n leaves $p.",TRUE,ch,cont,0,TO_ROOM);
if (ch->followers) {
for (k = ch->followers; k; k = next_dude) {
next_dude = k->next;
if ((k->follower->in_room == was_in) &&
(GET_POS(k->follower) >= POSITION_STANDING)
&& !k->follower->specials.fighting){
if(IS_NPC(ch) && !number(0,3)
&& GET_LEVEL(k->follower)
< LEVEL_BUILDER && !IS_NPC(k->follower)){
act("You lost track of $n.",TRUE,ch,0,k->follower,TO_VICT);
break;}
else {
act("You follow $N.\r\n", FALSE, k->follower, 0, ch, TO_CHAR);
do_leave(k->follower, argument,0,0);
}
}
}
}
return;
}
}
else if (!IS_SET(cont->obj_flags.value[1], CONT_ONEWAY)){
sprintf(buf1,"The %s seems to be closed.",first_name(cont->name));
act(buf1,TRUE,ch,cont,0,TO_CHAR);
return;
}
}
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 < NUM_OF_DIRS; 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[real_room(EXIT(ch, door)->to_room)].room_flags, INDOORS)) {
do_move(ch, "", ++door, 0);
return;
}
send_to_char("I see no obvious exits to the outside.\r\n", ch);
}
}
ACMD(do_stand)
{
if (IS_AFFECTED(ch, AFF_PARALYSIS)) {
send_to_char("Lie still you can't move a muscle.\r\n",ch);
return;
}
if (ch->specials.mount && GET_POS(ch) != POSITION_STANDING) {
GET_POS(ch) = POSITION_STANDING;
send_to_char("Stand? Your mount might not like that.\r\n", ch);
return;}
if (GET_POS(ch) == POSITION_STANDING){
send_to_char("You are already standing.\r\n",ch);
return;
}
if (IS_AFFECTED(ch, AFF_SLIPPY))
if((number(0,2) && IS_NPC(ch)) || (number(0,1) && !IS_NPC(ch))){
act("$n tries to stand up but slips and falls!", TRUE, ch,0,0,TO_ROOM);
send_to_char("You try to stand but you slip and fall.\r\n", ch);
return;
}
if (IS_AFFECTED(ch, AFF_BASH)){
if((number(0,2) && IS_NPC(ch)) || (number(0,1) && !IS_NPC(ch))){
act("$n tries to stand up but is too winded!", TRUE, ch,0,0,TO_ROOM);
act("You try to stand but you are unable to catch your breath.", FALSE, ch,0,0,TO_CHAR);
return;
}
else
affect_from_char(ch, SKILL_BASH);
}
switch (GET_POS(ch)) {
case POSITION_SITTING :
act("You stand up.", FALSE, ch, 0, 0, TO_CHAR);
act("$n clambers to $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;
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;
}
}
ACMD(do_sit)
{
if (ch->specials.mount) {
send_to_char("Sit where? you are riding?\r\n", ch);
return;}
if (ch->specials.fighting){
act("Sit down while fighting? Are you MAD?", FALSE, ch, 0, 0, TO_CHAR);
return;}
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'r 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;
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;
}
}
ACMD(do_rest)
{
if (ch->specials.mount) {
send_to_char("Rest while riding? Well you can try?\r\n", ch);
return;}
if (ch->specials.fighting){
act("Rest while fighting? Are you MAD?", FALSE, ch, 0, 0, TO_CHAR);
return;}
switch (GET_POS(ch)) {
case POSITION_STANDING :
act("You lie down and rest your tired bones.", FALSE, ch, 0, 0, TO_CHAR);
act("$n lies 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;
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;
}
}
ACMD(do_sleep)
{
if (ch->specials.mount) {
send_to_char("Sleep while riding? Are you MAD?\r\n", ch);
return;}
if (ch->specials.fighting){
send_to_char("Sleep while fighting? Are you MAD?\r\n", ch);
return;}
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;
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;
}
}
ACMD(do_wake)
{
struct char_data *tmp_char;
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) || GET_MOVE(tmp_char) < 0) {
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_SITTING;
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) || (GET_MOVE(ch) < 0 && number(0,3)) ) {
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 sit up.\r\n", ch);
act("$n awakens.", TRUE, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_SITTING;
}
}
}
}
ACMD(do_follow)
{
struct char_data *leader;
int result;
void stop_follower(struct char_data *ch);
int add_follower(struct char_data *ch, struct char_data *leader);
one_argument(argument, buf);
if (*buf) {
if (!str_cmp(buf, "self"))
leader = ch;
else if (!(leader = get_char_room_vis(ch, buf))) {
send_to_char("I see no person by that name here!\r\n", ch);
return;
}
} else {
send_to_char("Whom do you wish to follow?\r\n", ch);
return;
}
if (ch->master == leader) {
sprintf(buf, "You are already following %s.\r\n", HMHR(leader));
send_to_char(buf, 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);
REMOVE_BIT(ch->specials.affected_by, AFF_GROUP);
if (( result = add_follower(ch, leader)) == 0)
{
act("$N tried to follow you but you already have too many followers."
,FALSE,leader,0,ch,TO_CHAR);
act("$n already has too many followers."
,FALSE,leader,0,ch,TO_VICT);
}
}
}
}