/* DaleMUD v2.0 Released 2/1994 See license.doc for distribution terms. DaleMUD is based on DIKUMUD */ #include <stdio.h> #include <string.h> #include "protos.h" /* external vars */ #if HASH extern struct hash_header room_db; #else extern struct room_data *room_db; #endif extern struct char_data *character_list; extern struct descriptor_data *descriptor_list; extern struct index_data *obj_index; extern int rev_dir[]; extern char *dirs[]; extern int movement_loss[]; extern char *exits[]; int make_exit_ok(struct char_data *ch, struct room_data **rpp, int dir); void NotLegalMove(struct char_data *ch) { send_to_char("Alas, you cannot go that way...\n\r", ch); } int ValidMove( struct char_data *ch, int cmd) { char tmp[256]; struct room_direction_data *exitp; exitp = EXIT(ch, cmd); if (affected_by_spell(ch, SPELL_WEB)) { if (!saves_spell(ch, SAVING_PARA)) { send_to_char("You are entrapped in sticky webs!\n\r", ch); send_to_char("Your struggles only entrap you further!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE*5); if (!IS_PC(ch)) GET_MOVE(ch)=0; return(FALSE); } else { WAIT_STATE(ch, PULSE_VIOLENCE); GET_MOVE(ch)-=50; send_to_char("You briefly pull free from the sticky webbing!\n\r", ch); } } if (MOUNTED(ch)) { if (GET_POS(MOUNTED(ch)) < POSITION_FIGHTING) { send_to_char("Your mount must be standing\n\r", ch); return(FALSE); } if (ch->in_room != MOUNTED(ch)->in_room) { Dismount(ch, MOUNTED(ch), POSITION_STANDING); } } /* if (RIDDEN(ch)) { if (ch->in_room != RIDDEN(ch)->in_room) { Dismount(RIDDEN(ch), ch, POSITION_STANDING); } } */ if (!exit_ok(exitp,NULL)) { /* altered by msw */ #if 0 if (!make_exit_ok(ch,real_roomp(ch->in_room),cmd)) { #endif NotLegalMove(ch); return(FALSE); } else if (IS_SET(exitp->exit_info, EX_CLOSED)) { if (exitp->keyword) { if (!IS_SET(exitp->exit_info, EX_SECRET) && (strcmp(fname(exitp->keyword), "secret"))) { sprintf(tmp, "The %s seems to be closed.\n\r", fname(exitp->keyword)); send_to_char(tmp, ch); return(FALSE); } else { NotLegalMove(ch); return(FALSE); } } else { NotLegalMove(ch); return(FALSE); } } else if (IS_SET(exitp->exit_info, EX_CLIMB) && !IS_AFFECTED(ch, AFF_FLYING) ) { send_to_char("Sorry, you'd either have to be flying or climbing to get there!\n\r", ch); return(FALSE); } else { struct room_data *rp; rp = real_roomp(exitp->to_room); if (IS_SET(rp->room_flags, TUNNEL)) { if ((MobCountInRoom(rp->people) >= rp->moblim) && (!IS_IMMORTAL(ch))) { send_to_char("Sorry, there is no room to get in there.\n\r", ch); return(FALSE); } } if (IS_SET(rp->room_flags, PRIVATE)) { if (MobCountInRoom(rp->people) > 2) { send_to_char("Sorry, that room is private.\n\r", ch); return(FALSE); } } if (IS_SET(rp->room_flags, INDOORS)) { if (MOUNTED(ch)) { send_to_char("Your mount refuses to go that way\n\r", ch); return(FALSE); } } if (IS_SET(rp->room_flags, DEATH)) { if (MOUNTED(ch)) { send_to_char("Your mount refuses to go that way\n\r", ch); return(FALSE); } } return(TRUE); } } int RawMove(struct char_data *ch, int dir) { int need_movement, new_r; struct obj_data *obj; bool has_boat; struct room_data *from_here, *to_here; int special(struct char_data *ch, int dir, char *arg); if (special(ch, dir+1, ""))/* Check for special routines(North is 1)*/ return(FALSE); if (!ValidMove(ch, dir)) { return(FALSE); } if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master) && (ch->in_room == ch->master->in_room)) { act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM); act("You burst into tears at the thought of leaving $N", FALSE, ch, 0, ch->master, TO_CHAR); return(FALSE); } from_here = real_roomp(ch->in_room); to_here = real_roomp(from_here->dir_option[dir]->to_room); new_r = from_here->dir_option[dir]->to_room; if (to_here==NULL) { char_from_room(ch); char_to_room(ch, 0); send_to_char("Uh-oh. The ground melts beneath you as you fall into the swirling chaos.\n\r",ch); do_look(ch, "\0",15); if( IS_SET(ch->player.user_flags,SHOW_EXITS) ) { act("$c0015-----------------",FALSE,ch,0,0,TO_CHAR); do_exits(ch,"",8); act("$c0015-----------------",FALSE,ch,0,0,TO_CHAR); } return TRUE; } if( IS_IMMORTAL(ch) && IS_SET(ch->specials.act, PLR_NOHASSLE) && (!MOUNTED(ch))) { char_from_room(ch); char_to_room(ch, new_r); do_look(ch, "\0",15); if( IS_SET(ch->player.user_flags,SHOW_EXITS) ){ act("$c0015-----------------",FALSE,ch,0,0,TO_CHAR); do_exits(ch,"",8); act("$c0015-----------------",FALSE,ch,0,0,TO_CHAR); } return(TRUE); } /* * nail the unlucky with traps. */ if (!MOUNTED(ch)) { if (CheckForMoveTrap(ch, dir)) return(FALSE); } else { if (CheckForMoveTrap(MOUNTED(ch), dir)) return(FALSE); } if (IS_AFFECTED(ch,AFF_FLYING)) { need_movement = 1; if (IS_SET(to_here->room_flags, INDOORS)) need_movement += 2; } else if (IS_AFFECTED(ch, AFF_TRAVELLING) && !IS_SET(from_here->room_flags, INDOORS)) { need_movement = 1; } else { need_movement = (movement_loss[from_here->sector_type]+ movement_loss[to_here->sector_type]) / 2; } /* ** Movement in water_nowswim */ if ((from_here->sector_type == SECT_WATER_NOSWIM) || (to_here->sector_type == SECT_WATER_NOSWIM)) { if (!IS_AFFECTED(ch,AFF_FLYING)) { if (MOUNTED(ch)) { if (!IS_AFFECTED(MOUNTED(ch), AFF_WATERBREATH) && !IS_AFFECTED(MOUNTED(ch), AFF_FLYING)) { send_to_char("Your mount would have to fly or swim to go there\n\r", ch); return(FALSE); } } else { 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(IS_IMMORTAL(ch) && IS_SET(ch->specials.act, PLR_NOHASSLE)) has_boat = TRUE; if (!has_boat && !IS_AFFECTED(ch, AFF_WATERBREATH)) { send_to_char("You need a boat to go there.\n\r", ch); return(FALSE); } if (has_boat) need_movement = 1; } } } /* Movement in SECT_AIR */ if ((from_here->sector_type == SECT_AIR) || (to_here->sector_type == SECT_AIR)) { if (!IS_AFFECTED(ch,AFF_FLYING)) { if ((!MOUNTED(ch) || !IS_AFFECTED(MOUNTED(ch), AFF_FLYING))) { send_to_char("You would have to fly to go there!\n\r",ch); return(FALSE); } } } /* Movement in SECT_UNDERWATER */ if ((from_here->sector_type == SECT_UNDERWATER) || (to_here->sector_type == SECT_UNDERWATER)) { if (!IS_AFFECTED(ch,AFF_WATERBREATH)) { send_to_char("You would need gills to go there!\n\r",ch); return(FALSE); } if (MOUNTED(ch)) { if (!IS_AFFECTED(MOUNTED(ch),AFF_WATERBREATH)) { send_to_char("Your mount would need gills to go there!\n\r",ch); return(FALSE); } } } if ((from_here->sector_type == SECT_TREE) || (to_here->sector_type == SECT_TREE)) { if (!IS_AFFECTED(ch,AFF_TREE_TRAVEL)) { send_to_char("You would have to be able to walk through trees to go there!\n\r",ch); return(FALSE); } if (MOUNTED(ch)) { if (!IS_AFFECTED(MOUNTED(ch),AFF_TREE_TRAVEL)) { send_to_char("Your mount would have to be able to walk through trees to go there!\n\r",ch); return(FALSE); } } } if (!MOUNTED(ch)) { if (GET_MOVE(ch)<need_movement) { send_to_char("You are too exhausted.\n\r",ch); return(FALSE); } } else { if (GET_MOVE(MOUNTED(ch))<need_movement) { send_to_char("Your mount is too exhausted.\n\r", ch); return(FALSE); } } if (!IS_IMMORTAL(ch) || MOUNTED(ch)) { if (IS_NPC(ch)) { GET_MOVE(ch) -= 1; } else { if (MOUNTED(ch)) { GET_MOVE(MOUNTED(ch)) -= need_movement; } else { GET_MOVE(ch) -= need_movement; } } } if (MOUNTED(ch)) { char_from_room(ch); char_to_room(ch, new_r); char_from_room(MOUNTED(ch)); char_to_room(MOUNTED(ch), new_r); } else { char_from_room(ch); char_to_room(ch, new_r); } do_look(ch, "\0",15); if (IS_SET(to_here->room_flags, DEATH) && !IS_IMMORTAL(ch)) { if (MOUNTED(ch)) NailThisSucker(MOUNTED(ch)); NailThisSucker(ch); return(FALSE); } /* ** do something with track */ if (IS_NPC(ch)) { if (ch->specials.hunting) { if (IS_SET(ch->specials.act, ACT_HUNTING) && ch->desc) WAIT_STATE(ch, PULSE_VIOLENCE); } } else { if (ch->specials.hunting) { if (IS_SET(ch->specials.act, PLR_HUNTING)) { send_to_char("You search for a trail\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); } } } /* show exits */ if( IS_SET(ch->player.user_flags,SHOW_EXITS) ){ act("$c0015-----------------",FALSE,ch,0,0,TO_CHAR); do_exits(ch,"",8); act("$c0015-----------------",FALSE,ch,0,0,TO_CHAR); } return(TRUE); } int MoveOne(struct char_data *ch, int dir) { int was_in; was_in = ch->in_room; if (RawMove(ch, dir)) { /* no error */ DisplayOneMove(ch, dir, was_in); return TRUE; } else return FALSE; } int MoveGroup( struct char_data *ch, int dir) { struct char_data *heap_ptr[50]; int was_in, i, heap_top, heap_tot[50]; struct follow_type *k, *next_dude; /* * move the leader. (leader never duplicates) */ was_in = ch->in_room; if (RawMove(ch, dir)) { /* no error */ DisplayOneMove(ch, dir, was_in); if (ch->followers) { heap_top = 0; for(k = ch->followers; k; k = next_dude) { next_dude = k->next; /* * compose a list of followers, w/heaping */ if ((was_in == k->follower->in_room) && (GET_POS(k->follower) >= POSITION_STANDING)) { act("You follow $N.", FALSE, k->follower, 0, ch, TO_CHAR); if (k->follower->followers) { MoveGroup(k->follower, dir); } else { if (RawMove(k->follower, dir)) { if (!AddToCharHeap(heap_ptr, &heap_top, heap_tot, k->follower)) { DisplayOneMove(k->follower, dir, was_in); } } } } } /* * now, print out the heaped display message */ for (i=0;i<heap_top;i++) { if (heap_tot[i] > 1) { DisplayGroupMove(heap_ptr[i], dir, was_in, heap_tot[i]); } else { DisplayOneMove(heap_ptr[i], dir, was_in); } } } } return(TRUE); } int DisplayOneMove(struct char_data *ch, int dir, int was_in) { DisplayMove(ch, dir, was_in, 1); return(TRUE); } int DisplayGroupMove(struct char_data *ch, int dir, int was_in, int total) { DisplayMove(ch, dir, was_in, total); return(TRUE); } void do_move(struct char_data *ch, char *argument, int cmd) { dlog("in do_move"); if (RIDDEN(ch)) { if (RideCheck(RIDDEN(ch), 0)) { do_move(RIDDEN(ch), argument, cmd); return; } else { FallOffMount(RIDDEN(ch), ch); Dismount(RIDDEN(ch), ch, POSITION_SITTING); } } cmd -= 1; /* ** the move is valid, check for follower/master conflicts. */ if (ch->attackers > 1) { send_to_char("There's too many people around, no place to flee!\n\r", ch); return; } if (!ch->followers && !ch->master) { MoveOne(ch,cmd); } else { if (!ch->followers) { MoveOne(ch, cmd); } else { MoveGroup(ch, cmd); } } } /* MoveOne and MoveGroup print messages. Raw move sends success or failure. */ int DisplayMove( struct char_data *ch, int dir, int was_in, int total) { struct char_data *tmp_ch; char tmp[256]; for (tmp_ch = real_roomp(was_in)->people; tmp_ch; tmp_ch= tmp_ch->next_in_room) { if ((!IS_AFFECTED(ch, AFF_SNEAK)) || (IS_IMMORTAL(tmp_ch))) { if ((ch != tmp_ch) && (AWAKE(tmp_ch)) && (CAN_SEE(tmp_ch, ch))) { if (!IS_AFFECTED(ch, AFF_SILENCE) || number(0,2)) { if (total > 1) { if (IS_NPC(ch)) { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp,"%s flies %s. [%d]\n\r",ch->player.short_descr, dirs[dir], total); } else sprintf(tmp,"%s leaves %s. [%d]\n\r",ch->player.short_descr, dirs[dir], total); } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp,"%s flies %s. [%d]\n\r",GET_NAME(ch),dirs[dir], total); } else sprintf(tmp,"%s leaves %s. [%d]\n\r",GET_NAME(ch),dirs[dir], total); } } else { if (IS_NPC(ch)) { if (MOUNTED(ch)) { sprintf(tmp,"%s leaves %s, riding on %s\n\r",ch->player.short_descr, dirs[dir], MOUNTED(ch)->player.short_descr); } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp,"%s flies %s.\n\r", ch->player.short_descr,dirs[dir]); } else sprintf(tmp,"%s leaves %s.\n\r",ch->player.short_descr, dirs[dir]); } } else { if (MOUNTED(ch)) { sprintf(tmp,"%s leaves %s, riding on %s\n\r",GET_NAME(ch), dirs[dir], MOUNTED(ch)->player.short_descr); } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp,"%s flies %s.\n\r", GET_NAME(ch),dirs[dir]); } else sprintf(tmp,"%s leaves %s\n\r",GET_NAME(ch),dirs[dir]); } } } send_to_char(tmp, tmp_ch); } } } } for (tmp_ch = real_roomp(ch->in_room)->people; tmp_ch; tmp_ch = tmp_ch->next_in_room) { if (((!IS_AFFECTED(ch, AFF_SNEAK)) || (IS_IMMORTAL(tmp_ch))) && (CAN_SEE(tmp_ch,ch)) && (AWAKE(tmp_ch))) { if (tmp_ch != ch && (!IS_AFFECTED(ch, AFF_SILENCE) || number(0,2))) { if (dir < 4) { if (total == 1) { if (MOUNTED(ch)) { sprintf(tmp, "%s has arrived from the %s, riding on %s", PERS(ch, tmp_ch),dirs[rev_dir[dir]], PERS(MOUNTED(ch), tmp_ch)); } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp, "%s flies in from the %s.", PERS(ch, tmp_ch),dirs[rev_dir[dir]]); } else sprintf(tmp, "%s has arrived from the %s.", PERS(ch, tmp_ch),dirs[rev_dir[dir]]); } } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp, "%s flies in from the %s.", PERS(ch, tmp_ch),dirs[rev_dir[dir]]); } else sprintf(tmp, "%s has arrived from the %s.", PERS(ch, tmp_ch),dirs[rev_dir[dir]]); } } else if (dir == 4) { if (total == 1) { if (MOUNTED(ch)) { sprintf(tmp, "%s has arrived from below, riding on %s", PERS(ch, tmp_ch), PERS(MOUNTED(ch), tmp_ch)); } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp, "%s flies up from below.", PERS(ch, tmp_ch)); } else sprintf(tmp, "%s has arrived from below.", PERS(ch, tmp_ch)); } } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp, "%s flies up from below.", PERS(ch, tmp_ch)); } else sprintf(tmp, "%s has arrived from below.", PERS(ch, tmp_ch)); } } else if (dir == 5) { if (total == 1) { if (MOUNTED(ch)) { sprintf(tmp, "%s has arrived from above, riding on %s", PERS(ch, tmp_ch), PERS(MOUNTED(ch), tmp_ch)); } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp, "%s flies down from above.", PERS(ch, tmp_ch)); } else sprintf(tmp, "%s has arrived from above", PERS(ch, tmp_ch)); } } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp, "%s flies down from above.", PERS(ch, tmp_ch)); } else sprintf(tmp, "%s has arrived from above.", PERS(ch, tmp_ch)); } } else { if (total == 1) { if (MOUNTED(ch)) { sprintf(tmp, "%s has arrived from somewhere, riding on %s", PERS(ch, tmp_ch), PERS(MOUNTED(ch), tmp_ch)); } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp, "%s flies in from somewhere.", PERS(ch, tmp_ch)); } else sprintf(tmp, "%s has arrived from somewhere.", PERS(ch, tmp_ch)); } } else { if (IS_AFFECTED(ch,AFF_FLYING)) { sprintf(tmp, "%s flies in from somewhere.", PERS(ch, tmp_ch)); } else sprintf(tmp, "%s has arrived from somewhere.", PERS(ch, tmp_ch)); } } if (total > 1) { sprintf(tmp+strlen(tmp), " [%d]", total); } strcat(tmp, "\n\r"); send_to_char(tmp, tmp_ch); } } } return(TRUE); } int AddToCharHeap( struct char_data *heap[50], int *top, int total[50], struct char_data *k) { int found, i; if (*top > 50) { return(FALSE); } else { found = FALSE; for (i=0;(i<*top&& !found);i++) { if (*top>0) { if ((IS_NPC(k)) && (k->nr == heap[i]->nr) && (heap[i]->player.short_descr) && (!strcmp(k->player.short_descr, heap[i]->player.short_descr))) { total[i] += 1; found=TRUE; } } } if (!found) { heap[*top] = k; total[*top] = 1; *top+=1; } } return(TRUE); } int find_door(struct char_data *ch, char *type, char *dir) { char buf[MAX_STRING_LENGTH]; int door; struct room_direction_data *exitp; if (*dir) { /* a direction was specified */ if ((door = search_block(dir, dirs, FALSE)) == -1) { /* Partial Match */ send_to_char("That's not a direction.\n\r", ch); return(-1); } exitp = EXIT(ch, door); if (exitp) { if (!exitp->keyword) return(door); if ((isname(type, exitp->keyword))&& (strcmp(type,"secret"))) { return(door); } else { if ((door = search_block(type, dirs, FALSE)) != -1) { send_to_char("Thats a direction, not a portal.\n\r", ch); return(-1); } sprintf(buf, "I see no %s there.\n\r", type); send_to_char(buf, ch); return(-1); } } else { if ((door = search_block(type, dirs, FALSE)) != -1) { send_to_char("Thats a direction, not a portal.\n\r", ch); return(-1); } sprintf(buf, "I see no %s there.\n\r", type); send_to_char(buf, ch); return(-1); } } else { /* try to locate the keyword */ if (strcmp(type,"secret")) { for (door = 0; door <= 5; door++) if ((exitp=EXIT(ch, door)) && exitp->keyword && isname(type, exitp->keyword)) return(door); if ((door = search_block(type, dirs, FALSE)) != -1) { send_to_char("Thats a direction, not a portal.\n\r", ch); return(-1); } } sprintf(buf, "I see no %s here.\n\r", type); send_to_char(buf, ch); return(-1); } } int open_door(struct char_data *ch, int dir) /* remove all necessary bits and send messages */ { struct room_direction_data *exitp, *back; struct room_data *rp; char buf[MAX_INPUT_LENGTH]; rp = real_roomp(ch->in_room); if (rp==NULL) { sprintf(buf, "NULL rp in open_door() for %s.", PERS(ch,ch)); log_string(buf); } exitp = rp->dir_option[dir]; REMOVE_BIT(exitp->exit_info, EX_CLOSED); if (exitp->keyword) { if (strcmp(fname(exitp->keyword), "secret") && (!IS_SET(exitp->exit_info, EX_SECRET))) { sprintf(buf, "$n opens the %s", fname(exitp->keyword)); act(buf, FALSE, ch, 0, 0, TO_ROOM); } else { act("$n reveals a hidden passage!", FALSE, ch, 0, 0, TO_ROOM); } } else act("$n opens the door.", FALSE, ch, 0, 0, TO_ROOM); /* now for opening the OTHER side of the door! */ if (exit_ok(exitp, &rp) && (back = rp->dir_option[rev_dir[dir]]) && (back->to_room == ch->in_room)) { REMOVE_BIT(back->exit_info, EX_CLOSED); if (back->keyword && (strcmp("secret", fname(back->keyword)))) { sprintf(buf, "The %s is opened from the other side.\n\r", fname(back->keyword)); send_to_room(buf, exitp->to_room); } else { send_to_room("The door is opened from the other side.\n\r", exitp->to_room); } } return(TRUE); } int raw_open_door(struct char_data *ch, int dir) /* remove all necessary bits and send messages */ { struct room_direction_data *exitp, *back; struct room_data *rp; char buf[MAX_INPUT_LENGTH]; rp = real_roomp(ch->in_room); if (rp==NULL) { sprintf(buf, "NULL rp in open_door() for %s.", PERS(ch,ch)); log_string(buf); } exitp = rp->dir_option[dir]; REMOVE_BIT(exitp->exit_info, EX_CLOSED); /* now for opening the OTHER side of the door! */ if (exit_ok(exitp, &rp) && (back = rp->dir_option[rev_dir[dir]]) && (back->to_room == ch->in_room)) { REMOVE_BIT(back->exit_info, EX_CLOSED); if (back->keyword && (strcmp("secret", fname(back->keyword)))) { sprintf(buf, "The %s is opened from the other side.\n\r", fname(back->keyword)); send_to_room(buf, exitp->to_room); } else { send_to_room("The door is opened from the other side.\n\r", exitp->to_room); } } return(TRUE); } void do_open_exit(struct char_data *ch, char *argument, int cmd) { int door; char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH]; struct room_direction_data *exitp,*back; struct room_data *rp; char *cmdname=FindCommandName(cmd); char *dir_desc[] = { "to the north", /* 0 */ "to the east", /* 1 */ "to the south", /* 2 */ "to the west", /* 3 */ "upwards", /* 4 */ "downwards" /* 5 */ }; dlog("in do_open_exit"); if(!cmdname) { sprintf(buf,"something really wrong happen in do_open_exit, cmd:%d\r\n",cmd); log_string(buf); return; } argument_interpreter(argument, type, dir); if (!*type) { sprintf(buf,"%s what?!\r\n",cmdname); *buf=toupper(*buf); /* ;-) */ send_to_char(buf,ch); return; } else if ((door = find_door(ch, type, dir)) >= 0) { /* perhaps it is a something like door */ exitp = EXIT(ch, door); if (!IS_SET(exitp->exit_info, EX_ISDOOR)) send_to_char("That's impossible, I'm afraid.\n\r", ch); else if(exitp->open_cmd!=-1 && cmd==exitp->open_cmd) { if (!IS_SET(exitp->exit_info, EX_CLOSED)) { SET_BIT(exitp->exit_info, EX_CLOSED); if(!strcmp(fname(exitp->keyword), "secret")) { sprintf(buf,"$n closed a secret passage %s",dir_desc[door]); act(buf,0,ch,0,0,TO_ROOM); } else { sprintf(buf,"$n %ss the $F and closed the passage %s",cmdname,dir_desc[door]); act(buf,0,ch,0,exitp->keyword,TO_ROOM); } sprintf(buf,"You %s the %s and close the passage %s\r\n",cmdname,fname(exitp->keyword),dir_desc[door]); send_to_char(buf,ch); /* handle backdoor */ if (exit_ok(exitp,&rp) && (back = rp->dir_option[rev_dir[door]]) && (back->to_room == ch->in_room) ) { SET_BIT(back->exit_info, EX_CLOSED); } } /* end if !closed */ else { raw_open_door(ch,door); if(!strcmp(fname(exitp->keyword), "secret")) { sprintf(buf,"$n opens secret passage %s",dir_desc[door]); act(buf,0,ch,0,0,TO_ROOM); } else { sprintf(buf,"$n %ss the $F and opens a passage %s",cmdname,dir_desc[door]); act(buf,0,ch,0,exitp->keyword,TO_ROOM); } sprintf(buf,"You %s the %s and open a passage %s\r\n",cmdname,fname(exitp->keyword),dir_desc[door]); send_to_char(buf,ch); } } else { send_to_char("No-no! do it somewhere else, please...\n\r",ch); } } } void do_open(struct char_data *ch, char *argument, int cmd) { int door; char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH]; struct obj_data *obj; struct char_data *victim; struct room_direction_data *exitp; dlog("in do_open"); argument_interpreter(argument, type, dir); if (!*type) send_to_char("Open what?\n\r", 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.\n\r", ch); else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED)) send_to_char("But it's already open!\n\r", ch); else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSEABLE)) send_to_char("You can't do that.\n\r", ch); else if (IS_SET(obj->obj_flags.value[1], CONT_LOCKED)) send_to_char("It seems to be locked.\n\r", ch); else { REMOVE_BIT(obj->obj_flags.value[1], CONT_CLOSED); send_to_char("Ok.\n\r", 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 */ exitp = EXIT(ch, door); if (!IS_SET(exitp->exit_info, EX_ISDOOR)) send_to_char("That's impossible, I'm afraid.\n\r", ch); else if (!IS_SET(exitp->exit_info, EX_CLOSED)) send_to_char("It's already open!\n\r", ch); else if (IS_SET(exitp->exit_info, EX_LOCKED)) send_to_char("It seems to be locked.\n\r", ch); else if (exitp->open_cmd==-1 || exitp->open_cmd==cmd) { open_door(ch, door); send_to_char("Ok.\n\r", ch); } else { send_to_char("You can't OPEN that.\r\n", ch); } } } void do_close(struct char_data *ch, char *argument, int cmd) { int door; char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH]; struct room_direction_data *back, *exitp; struct obj_data *obj; struct char_data *victim; struct room_data *rp; dlog("in do_close"); argument_interpreter(argument, type, dir); if (!*type) send_to_char("Close what?\n\r", 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.\n\r", ch); else if (IS_SET(obj->obj_flags.value[1], CONT_CLOSED)) send_to_char("But it's already closed!\n\r", ch); else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSEABLE)) send_to_char("That's impossible.\n\r", ch); else { SET_BIT(obj->obj_flags.value[1], CONT_CLOSED); send_to_char("Ok.\n\r", ch); act("$n closes $p.", FALSE, ch, obj, 0, TO_ROOM); } } else if ((door = find_door(ch, type, dir)) >= 0) { /* Or a door */ exitp = EXIT(ch, door); if (!IS_SET(exitp->exit_info, EX_ISDOOR)) send_to_char("That's absurd.\n\r", ch); else if (IS_SET(exitp->exit_info, EX_CLOSED)) send_to_char("It's already closed!\n\r", ch); else if( exitp->open_cmd != -1) send_to_char("You can't CLOSE that\r\n",ch); else { SET_BIT(exitp->exit_info, EX_CLOSED); if (exitp->keyword && strcmp("secret", fname(exitp->keyword))) act("$n closes the $F.", 0, ch, 0, exitp->keyword, TO_ROOM); else act("$n closes the door.", FALSE, ch, 0, 0, TO_ROOM); send_to_char("Ok.\n\r", ch); /* now for closing the other side, too */ if (exit_ok(exitp,&rp) && (back = rp->dir_option[rev_dir[door]]) && (back->to_room == ch->in_room) ) { SET_BIT(back->exit_info, EX_CLOSED); if (back->keyword) { sprintf(buf, "The %s closes quietly.\n\r", back->keyword); send_to_room(buf, exitp->to_room); } else send_to_room( "The door closes quietly.\n\r", exitp->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 raw_unlock_door( struct char_data *ch, struct room_direction_data *exitp, int door) { struct room_data *rp; struct room_direction_data *back; char buf[128]; REMOVE_BIT(exitp->exit_info, EX_LOCKED); /* now for unlocking the other side, too */ rp = real_roomp(exitp->to_room); if (rp && (back = rp->dir_option[rev_dir[door]]) && back->to_room == ch->in_room) { REMOVE_BIT(back->exit_info, EX_LOCKED); } else { sprintf(buf, "Inconsistent door locks in rooms %d->%d", ch->in_room, exitp->to_room); log_string(buf); } } void raw_lock_door( struct char_data *ch, struct room_direction_data *exitp, int door) { struct room_data *rp; struct room_direction_data *back; char buf[128]; SET_BIT(exitp->exit_info, EX_LOCKED); /* now for locking the other side, too */ rp = real_roomp(exitp->to_room); if (rp && (back = rp->dir_option[rev_dir[door]]) && back->to_room == ch->in_room) { SET_BIT(back->exit_info, EX_LOCKED); } else { sprintf(buf, "Inconsistent door locks in rooms %d->%d", ch->in_room, exitp->to_room); log_string(buf); } } void do_lock(struct char_data *ch, char *argument, int cmd) { int door; char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH]; struct room_direction_data *exitp; struct obj_data *obj; struct char_data *victim; dlog("in do_lock"); argument_interpreter(argument, type, dir); if (!*type) send_to_char("Lock what?\n\r", 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.\n\r", ch); else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED)) send_to_char("Maybe you should close it first...\n\r", ch); else if (obj->obj_flags.value[2] < 0) send_to_char("That thing can't be locked.\n\r", ch); else if (!has_key(ch, obj->obj_flags.value[2])) send_to_char("You don't seem to have the proper key.\n\r", ch); else if (IS_SET(obj->obj_flags.value[1], CONT_LOCKED)) send_to_char("It is locked already.\n\r", ch); else { SET_BIT(obj->obj_flags.value[1], CONT_LOCKED); send_to_char("*Cluck*\n\r", 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 */ exitp = EXIT(ch, door); if (!IS_SET(exitp->exit_info, EX_ISDOOR)) send_to_char("That's absurd.\n\r", ch); else if (!IS_SET(exitp->exit_info, EX_CLOSED)) send_to_char("You have to close it first, I'm afraid.\n\r", ch); else if (exitp->key < 0) send_to_char("There does not seem to be any keyholes.\n\r", ch); else if (!has_key(ch, exitp->key)) send_to_char("You don't have the proper key.\n\r", ch); else if (IS_SET(exitp->exit_info, EX_LOCKED)) send_to_char("It's already locked!\n\r", ch); else { if (exitp->keyword && strcmp("secret", fname(exitp->keyword))) act("$n locks the $F.", 0, ch, 0, exitp->keyword, TO_ROOM); else act("$n locks the door.", FALSE, ch, 0, 0, TO_ROOM); send_to_char("*Click*\n\r", ch); raw_lock_door(ch, exitp, door); } } } void do_unlock(struct char_data *ch, char *argument, int cmd) { int door; char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH]; struct room_direction_data *exitp; struct obj_data *obj; struct char_data *victim; dlog("in do_unlock"); argument_interpreter(argument, type, dir); if (!*type) send_to_char("Unlock what?\n\r", 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.\n\r", ch); else if (obj->obj_flags.value[2] < 0) send_to_char("Odd - you can't seem to find a keyhole.\n\r", ch); else if (!has_key(ch, obj->obj_flags.value[2])) send_to_char("You don't seem to have the proper key.\n\r", ch); else if (!IS_SET(obj->obj_flags.value[1], CONT_LOCKED)) send_to_char("Oh.. it wasn't locked, after all.\n\r", ch); else { REMOVE_BIT(obj->obj_flags.value[1], CONT_LOCKED); send_to_char("*Click*\n\r", ch); act("$n unlocks $p.", FALSE, ch, obj, 0, TO_ROOM); } } else if ((door = find_door(ch, type, dir)) >= 0) { /* it is a door */ exitp = EXIT(ch, door); if (!IS_SET(exitp->exit_info, EX_ISDOOR)) send_to_char("That's absurd.\n\r", ch); else if (!IS_SET(exitp->exit_info, EX_CLOSED)) send_to_char("Heck.. it ain't even closed!\n\r", ch); else if (exitp->key < 0) send_to_char("You can't seem to spot any keyholes.\n\r", ch); else if (!has_key(ch, exitp->key)) send_to_char("You do not have the proper key for that.\n\r", ch); else if (!IS_SET(exitp->exit_info, EX_LOCKED)) send_to_char("It's already unlocked, it seems.\n\r", ch); else { if (exitp->keyword && strcmp("secret", fname(exitp->keyword))) act("$n unlocks the $F.", 0, ch, 0, exitp->keyword, TO_ROOM); else act("$n unlocks the door.", FALSE, ch, 0, 0, TO_ROOM); send_to_char("*click*\n\r", ch); raw_unlock_door(ch, exitp, door); } } } void do_pick(struct char_data *ch, char *argument, int cmd) { byte percent; int door; char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH]; struct room_direction_data *exitp; struct obj_data *obj; struct char_data *victim; dlog("in do_pick"); argument_interpreter(argument, type, dir); percent=number(1,101); /* 101% is a complete failure */ if (!ch->skills) { send_to_char("You failed to pick the lock.\n\r", ch); return; } if (!HasClass(ch, CLASS_THIEF) && !HasClass(ch, CLASS_MONK)) { send_to_char("You're no thief!\n\r", ch); return; } if (percent > (ch->skills[SKILL_PICK_LOCK].learned)) { send_to_char("You failed to pick the lock.\n\r", ch); LearnFromMistake(ch, SKILL_PICK_LOCK, 0, 90); WAIT_STATE(ch, PULSE_VIOLENCE*4); return; } if (!*type) { send_to_char("Pick what?\n\r", 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.\n\r", ch); else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED)) send_to_char("Silly - it ain't even closed!\n\r", ch); else if (obj->obj_flags.value[2] < 0) send_to_char("Odd - you can't seem to find a keyhole.\n\r", ch); else if (!IS_SET(obj->obj_flags.value[1], CONT_LOCKED)) send_to_char("Oho! This thing is NOT locked!\n\r", ch); else if (IS_SET(obj->obj_flags.value[1], CONT_PICKPROOF)) send_to_char("It resists your attempts at picking it.\n\r", ch); else { REMOVE_BIT(obj->obj_flags.value[1], CONT_LOCKED); send_to_char("*Click*\n\r", ch); act("$n fiddles with $p.", FALSE, ch, obj, 0, TO_ROOM); } } else if ((door = find_door(ch, type, dir)) >= 0) { exitp = EXIT(ch, door); if (!IS_SET(exitp->exit_info, EX_ISDOOR)) send_to_char("That's absurd.\n\r", ch); else if (!IS_SET(exitp->exit_info, EX_CLOSED)) send_to_char("You realize that the door is already open.\n\r", ch); else if (exitp->key < 0) send_to_char("You can't seem to spot any lock to pick.\n\r", ch); else if (!IS_SET(exitp->exit_info, EX_LOCKED)) send_to_char("Oh.. it wasn't locked at all.\n\r", ch); else if (IS_SET(exitp->exit_info, EX_PICKPROOF)) send_to_char("You seem to be unable to pick this lock.\n\r", ch); else { if (exitp->keyword) act("$n skillfully picks the lock of the $F.", 0, ch, 0, exitp->keyword, TO_ROOM); else act("$n picks the lock.",TRUE,ch,0,0,TO_ROOM); send_to_char("The lock quickly yields to your skills.\n\r", ch); raw_unlock_door(ch, exitp, door); } } } void do_enter(struct char_data *ch, char *argument, int cmd) { int door; char buf[MAX_INPUT_LENGTH], tmp[MAX_STRING_LENGTH]; struct room_direction_data *exitp; struct room_data *rp; dlog("in do_enter"); one_argument(argument, buf); if (*buf) { /* an argument was supplied, search for door keyword */ for (door = 0; door <= 5; door++) if (exit_ok(exitp=EXIT(ch, door), NULL) && exitp->keyword && 0==str_cmp(exitp->keyword, buf)) { do_move(ch, "", ++door); return; } sprintf(tmp, "There is no %s here.\n\r", buf); send_to_char(tmp, ch); } else if (IS_SET(real_roomp(ch->in_room)->room_flags, INDOORS)) { send_to_char("You are already indoors.\n\r", ch); } else { /* try to locate an entrance */ for (door = 0; door <= 5; door++) if (exit_ok(exitp=EXIT(ch, door), &rp) && !IS_SET(exitp->exit_info, EX_CLOSED) && IS_SET(rp->room_flags, INDOORS)) { do_move(ch, "", ++door); return; } send_to_char("You can't seem to find anything to enter.\n\r", ch); } } void do_leave(struct char_data *ch, char *argument, int cmd) { int door; struct room_direction_data *exitp; struct room_data *rp; dlog("in do_leave"); if (!IS_SET(RM_FLAGS(ch->in_room), INDOORS)) send_to_char("You are outside.. where do you want to go?\n\r", ch); else { for (door = 0; door <= 5; door++) if (exit_ok(exitp=EXIT(ch, door), &rp) && !IS_SET(exitp->exit_info, EX_CLOSED) && !IS_SET(rp->room_flags, INDOORS)) { do_move(ch, "", ++door); return; } send_to_char("I see no obvious exits to the outside.\n\r", ch); } } void do_stand(struct char_data *ch, char *argument, int cmd) { dlog("in do_stand"); /* can't stand while memorizing! */ if (affected_by_spell(ch,SKILL_MEMORIZE)) { SpellWearOff(SKILL_MEMORIZE,ch); affect_from_char(ch,SKILL_MEMORIZE); } /* end if */ /* can't stand and meditate! */ if (affected_by_spell(ch,SKILL_MEDITATE)) { SpellWearOff(SKILL_MEDITATE,ch); affect_from_char(ch,SKILL_MEDITATE); } /* end if */ 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; case POSITION_MOUNTED: { send_to_char("Not while riding you don't!\n\r", ch); 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) { dlog("in do_sit"); 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.\n\r", 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; case POSITION_MOUNTED: { send_to_char("Not while riding you don't!\n\r", ch); 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) { dlog("in do_rest"); 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; case POSITION_MOUNTED: { send_to_char("Not while riding you don't!\n\r", ch); 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) { dlog("in do_sleep"); switch(GET_POS(ch)) { case POSITION_STANDING : case POSITION_SITTING : case POSITION_RESTING : { send_to_char("You go to sleep.\n\r", 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.\n\r", ch); } break; case POSITION_FIGHTING : { send_to_char("Sleep while fighting? are you MAD?\n\r", ch); } break; case POSITION_MOUNTED: { send_to_char("Not while riding you don't!\n\r", 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]; dlog("in do_wake"); 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_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.\n\r", ch); } } } else { if (IS_AFFECTED(ch,AFF_SLEEP)) { send_to_char("You can't wake up!\n\r", ch); } else { if (GET_POS(ch) > POSITION_SLEEPING) send_to_char("You are already awake...\n\r", ch); else { send_to_char("You wake, and sit up.\n\r", ch); act("$n awakens.", TRUE, ch, 0, 0, TO_ROOM); GET_POS(ch) = POSITION_SITTING; } } } } 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); dlog("in do_follow"); only_argument(argument, name); if (*name) { if (!(leader = get_char_room_vis(ch, name))) { send_to_char("I see no person by that name here!\n\r", ch); return; } } else { send_to_char("Who do you wish to follow?\n\r", 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.\n\r", 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(IS_AFFECTED(ch, AFF_GROUP)) REMOVE_BIT(ch->specials.affected_by, AFF_GROUP); add_follower(ch, leader); } } } void do_run(struct char_data *ch, char *argument, int cmd) { char buff[MAX_INPUT_LENGTH]; int keyno, was_in; struct room_direction_data *exitdata; static char *keywords[]= { "north", "east", "south", "west", "up", "down", "\n" }; dlog("in do_run"); only_argument(argument, buff); if (!*buff) { send_to_char("The proper format for this command is RUN <DIRECTION>.\n\r", ch); return; } keyno = search_block(buff, keywords, FALSE); if (keyno == -1) { send_to_char("Sorry, but that isn't a valid direction to run in.\n\r", ch); return; } if (GET_MOVE(ch) <= 20) { send_to_char("You feel too tired to run at this moment.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master) && (ch->in_room == ch->master->in_room)) { act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM); act("You burst into tears at the thought of running away from $N", FALSE, ch, 0, ch->master, TO_CHAR); return; } if (!CAN_GO(ch, keyno)) { send_to_char("Do you like to run into things doofus? Please pick an open direction!", ch); return; } if (!clearpath(ch,ch->in_room,keyno)) { send_to_char("To run in that direction seems futile.\n\r", ch); return; } exitdata = (real_roomp(ch->in_room)->dir_option[keyno]); if((exitdata->to_room)==(ch->in_room)) { send_to_char("To run in that direction seems futile.\n\r", ch); return; } send_to_char("You take off, running as fast as you can!\n\r", ch); act("$n suddenly takes off, running as fast as they can!", FALSE,ch,0,0,TO_ROOM); was_in=ch->in_room; while ((CAN_GO(ch, keyno)) && (GET_MOVE(ch) > 20) && (RawMove(ch, keyno))) { DisplayOneMove(ch, keyno, was_in); GET_MOVE(ch) -= 1; was_in=ch->in_room; } if (GET_MOVE(ch) > 25) { act("$n slows down to a screeching halt, exhausted from their run.", FALSE,ch,0,0,TO_ROOM); send_to_char("Sorry, but you can not run in this direction any further.\n\r", ch); } else { act("$n slows down to a screeching halt, panting heavily from their run.", FALSE,ch,0,0,TO_ROOM); send_to_char("You feel too tired to run any further.\n\r", ch); } }