/**************************************************************************/
// act_move.cpp - handles moving players between rooms etc
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with all the licenses *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
***************************************************************************
* >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. *
* >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* >> ROM 2.4 is copyright 1993-1995 Russ Taylor and has been brought to *
* you by the ROM consortium: Russ Taylor(rtaylor@pacinfo.com), *
* Gabrielle Taylor(gtaylor@pacinfo.com) & Brian Moore(rom@rom.efn.org) *
* >> Oblivion 1.2 is copyright 1996 Wes Wagner *
**************************************************************************/
#include "include.h" // dawn standard includes
#include "track.h"
#include "msp.h"
#include "lockers.h"
// command procedures needed
DECLARE_DO_FUN( do_look );
DECLARE_DO_FUN( do_recall );
DECLARE_DO_FUN( do_stand );
DECLARE_DO_FUN( do_scan );
DECLARE_DO_FUN( do_map ); // Kal
DECLARE_DO_FUN( do_dmap ); // Kal
void landchar( char_data *ch);
bool trapcheck_open( char_data *ch, OBJ_DATA *obj );
bool trapcheck_move( char_data *ch, int door );
/**************************************************************************/
char *const dir_shortname[]= {"N","E","S","W","U","D","Ne","Se","Sw","Nw"};
char *const dir_name[]=
{
"north", "east", "south", "west", "up", "down", "northeast", "southeast",
"southwest", "northwest"
};
const sh_int rev_dir [] =
{
2, 3, 0, 1, 5, 4, 8, 9, 6, 7
};
const sh_int movement_loss [SECT_MAX] =
{
1, 2, 2, 3, 4, 6, 4, 7, 10, 10, 6, 4, 6
};
/**************************************************************************/
/*
* Local functions.
*/
int find_door args( ( char_data *ch, char *arg, char *action ));// action = NULL/lock/unlock/open/close etc
bool has_key args( ( char_data *ch, int key ) );
bool has_locker_key args( ( char_data *ch) );
void mount args( ( char_data *, char_data *) );
void dismount args( ( char_data *) );
void tame_a_little args( (char_data * ch, char_data * victim));
/**************************************************************************/
void move_char( char_data *ch, int door, bool)
{
char_data *fch;
char_data *fch_next;
ROOM_INDEX_DATA *in_room;
ROOM_INDEX_DATA *to_room = NULL;
EXIT_DATA *pexit;
OBJ_DATA *obj;
if ( door < 0 || door >=MAX_DIR )
{
bugf( "do_move(): bad door number %d.", door );
return;
}
// Exit trigger, if activated, bail out. Only PCs are triggered.
if ( !IS_NPC(ch) && mp_exit_trigger( ch, door ) )
return;
in_room = ch->in_room;
if ( ( pexit = in_room->exit[door] ) == NULL
|| ( to_room = pexit->u1.to_room ) == NULL
|| !can_see_room(ch,pexit->u1.to_room))
{
ch->println( "Alas, you cannot go that way." );
return;
}
if (IS_SET(pexit->exit_info, EX_CLOSED)
&& (!IS_AFFECTED(ch, AFF_PASS_DOOR) || IS_SET(pexit->exit_info,EX_NOPASS))
&& !IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK))
{
ch->printlnf("The %s is closed.", IS_NULLSTR(pexit->keyword)?"door":pexit->keyword);
return;
}
if ( trapcheck_move( ch, door )){
return;
}
if ( IS_AFFECTED(ch, AFF_CHARM)
&& ch->master != NULL
&& in_room == ch->master->in_room )
{
ch->println( "What? And leave your beloved master?" );
return;
}
if ( is_affected( ch, gsn_cause_fear )
&& IS_SET(to_room->room_flags, ROOM_OOC))
{
ch->println( "You can't enter OOC while under the affects of cause fear." );
return;
}
if ( is_affected( ch, gsn_fear_magic )
&& IS_SET(to_room->room_flags, ROOM_OOC))
{
ch->println( "You can't enter OOC while under the affects of fear magic." );
return;
}
if (is_room_private_to_char( to_room, ch ))
{
if ( !IS_IMMORTAL( ch ))
{
if(!IS_NULLSTR(to_room->owner)){
if(!is_room_owner(ch, to_room)
&& !player_on_rooms_invite_list(ch, to_room))
{
ch->println( "That room is owned by someone, and you are not on the room invitation list." );
return;
}
}
ch->println( "That room is private right now." );
return;
}
else if ( IS_SET( to_room->room_flags, ROOM_OOC )
|| INVIS_LEVEL(ch)< LEVEL_IMMORTAL )
{
ch->println( "That room is private right now." );
return;
}
}
if (( IS_SET( to_room->room_flags, ROOM_NOFLY ))
&& IS_AFFECTED( ch, AFF_FLYING ))
{
ch->println( "The winds are too strong, you must be on the ground to get there." );
return;
}
if (ch->ridden_by){
ch->println("You must go where your rider leads you.");
return;
}
if (ch->tethered){
ch->println("You cannot move while tethered.");
return;
}
// premove trigger, activated only on mobs with the trigger
// if mp_premove_trigger() returns false, movement was canceled
if ( IS_NPC(ch)
&& HAS_TRIGGER(ch, TRIG_PREMOVE)
&& mp_premove_trigger( ch, to_room->vnum, door ) )
{
ch->println("Movement changed/canceled by premove mobprog trigger.");
return;
}
// basic mount checks - dont move ch's yet
if (ch->mounted_on){
if IS_SET(to_room->room_flags, ROOM_OOC){
ch->println( "You cannot bring mounts into OOC rooms." );
return;
}
// No Mounts UNDERWATER unless they are Otterlunged
if (( to_room->sector_type==SECT_UNDERWATER
|| IS_SET( to_room->affected_by, ROOMAFF_UNDERWATER ))
&& !IS_AFFECTED( ch->mounted_on, AFF_OTTERLUNGS ))
{
ch->println( "Your mount cannot travel underwater." );
return;
}
// lava check - darksun/daos
if(to_room->sector_type==SECT_LAVA
&& !IS_AFFECTED( ch->mounted_on, AFF_FLYING))
{
ch->println( "Your mount cannot travel on lava!!!");
return;
}
if (IS_SET(to_room->room_flags,ROOM_LAW)
&& (IS_NPC(ch->mounted_on)
&& IS_SET(ch->mounted_on->act,ACT_AGGRESSIVE)))
{
act("Your aggressive mount $N refuses to ride into the city.",
ch,NULL,ch->mounted_on,TO_CHAR);
act("You aren't allowed in the city.",
ch->mounted_on,NULL,NULL,TO_CHAR);
return;
}
if IS_SET(to_room->room_flags, ROOM_INDOORS){
ch->println("`xYou cannot bring mounts inside.");
ch->println("You will either have to `=Cdismount`x or `=Ctether`x your mount.");
return;
}
if (ch->mounted_on->bucking){
ch->println("Your mount is out of your control!");
return;
}
}
// do all checks that only affect pc's
// and then movement calculations
if ( !IS_NPC(ch)){
int move;
/* // the guild code is performed by mobprogs now
int iGuild;
if (IS_SET(to_room->room_flags, ROOM_CLASS_RESTRICTION)
&& !IS_SET(ch->act,PLR_HOLYWALK)
&& !IS_IN_REDIT(ch))
{
bool NOT_ALLOWED= true;
for ( iGuild = 0; iGuild < MAX_GUILD; iGuild ++)
{
if (class_table[ch->clss].guild[iGuild] == to_room->vnum)
{
NOT_ALLOWED=false;
}
}
if (NOT_ALLOWED)
{
ch->println("You can't go in there, tis not your guild.");
return;
}
}
*/
// UNDERWATER checking
if ( to_room->sector_type==SECT_UNDERWATER
|| IS_SET( to_room->affected_by, ROOMAFF_UNDERWATER ))
{
OBJ_DATA *obj2;
obj2 = ( get_eq_char( ch, WEAR_LIGHT ));
if(!IS_AFFECTED( ch, AFF_OTTERLUNGS )
&& !IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK))
{
if ( !obj2 || (obj2 && !IS_SET(obj2->extra_flags, OBJEXTRA_OTTERLUNGS )))
{
ch->println( "You would drown there." );
return;
}
}
}
// Lava check - Daos/darksun
if( to_room->sector_type==SECT_LAVA
&& !IS_AFFECTED(ch, AFF_FLYING)
&& !IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK))
{
ch->println("You would burn there.");
return;
}
// can't go into ooc rooms with a noquit timer on
if (IS_SET(to_room->room_flags, ROOM_OOC)
&& !IS_OOC(ch) && ch->pknoquit>0)
{
ch->println( "You cannot enter an ooc room while you have a pknoquit timer." );
return;
}
if (!ch->mounted_on)
{
if (in_room->sector_type == SECT_AIR
|| to_room->sector_type == SECT_AIR
|| in_room->sector_type == SECT_LAVA
|| to_room->sector_type == SECT_LAVA)
{
if ( !IS_AFFECTED(ch, AFF_FLYING)
&& !IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK)){
ch->println( "You can't fly." );
return;
}
}
if (( in_room->sector_type == SECT_WATER_NOSWIM
||to_room->sector_type == SECT_WATER_NOSWIM )
&& !IS_AFFECTED(ch,AFF_FLYING))
{
OBJ_DATA *obj;
bool found;
// Look for a boat
found = false;
if (IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK))
found = true;
for ( obj = ch->carrying; obj; obj = obj->next_content ){
if ( obj->item_type == ITEM_BOAT )
{
found = true;
break;
}
}
if ( !found ){
ch->println( "You need a boat to go there." );
return;
}
}
}else{ // mounted movement
if (in_room->sector_type == SECT_AIR
|| to_room->sector_type == SECT_AIR
|| in_room->sector_type == SECT_LAVA
|| to_room->sector_type == SECT_LAVA)
{
if ( !IS_AFFECTED(ch->mounted_on, AFF_FLYING))
{
ch->println( "Your mount can't fly." );
return;
}
}
if (( in_room->sector_type == SECT_WATER_NOSWIM
|| to_room->sector_type == SECT_WATER_NOSWIM )
&& !IS_AFFECTED(ch->mounted_on,AFF_FLYING))
{
ch->println( "Your mount cannot swim." );
return;
}
} // endif for is mounted?
// get the average for moving between sector types
move = (movement_loss[UMIN(SECT_MAX-1, in_room->sector_type)]
+ movement_loss[UMIN(SECT_MAX-1, to_room->sector_type)])/2;
// No movement loss in OOC
if ( IS_OOC(ch)){
move = 0;
}
// conditional effects
if (!ch->mounted_on){
if (IS_AFFECTED(ch,AFF_FLYING) || IS_AFFECTED(ch,AFF_HASTE))
move /= 2;
if (IS_AFFECTED(ch,AFF_SLOW))
move *= 2;
if (IS_AFFECTED(ch, AFF_SNEAK))
move = (move* number_range(15,35))/10;
//Y: Walking is painful if you have a headache
if (is_affected( ch, gsn_cause_headache ))
move += (move/2);
if ( ch->move < move && !IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK))
{
ch->println("You are too exhausted.");
return;
}
if (!IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK)
&& !IS_IN_REDIT(ch))
ch->move -= move;
}else{
if (IS_AFFECTED(ch->mounted_on,AFF_FLYING)
|| IS_AFFECTED(ch->mounted_on,AFF_HASTE))
move /= 2;
if (IS_AFFECTED(ch->mounted_on,AFF_SLOW))
move *= 2;
if (IS_AFFECTED(ch->mounted_on, AFF_SNEAK))
move = (move* number_range(15,35))/10;
if ( ch->mounted_on->move < move )
{
ch->println("Your mount is too exhausted.");
return;
}
ch->mounted_on->move -= move;
}
} // endif (!IS_NPC(ch))
// Check if the character is Treeformed and if so, strip the spell
if ( IS_SET( ch->affected_by2, AFF2_TREEFORM ))
{
AFFECT_DATA *paf;
AFFECT_DATA *paf_next;
REMOVE_BIT( ch->affected_by2, AFF2_TREEFORM );
for (paf = ch->affected; paf != NULL; paf = paf_next)
{
paf_next = paf->next;
if ( paf->type == gsn_treeform )
{
affect_remove( ch, paf );
ch->println("You assume your original shape.");
act( "A tree suddenly transforms into $n.", ch, NULL, NULL, TO_ROOM );
break;
}
}
}
// OOC/IC room system
if ( (IS_SET(in_room->room_flags, ROOM_OOC) != IS_SET(to_room->room_flags, ROOM_OOC))
&& (!IS_SET(ch->comm, COMM_BUILDING) // dont use system on builders
&& !IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK))) // or those with holywalk on
{
// check for going into ooc from ic
if (IS_SET(to_room->room_flags, ROOM_OOC))
{
ch->last_ic_room = in_room;
if ( !IS_AFFECTED(ch, AFF_SNEAK) && INVIS_LEVEL(ch)<=LEVEL_HERO)
act( "$n leaves $T [ENTERS AN OOC ROOM].", ch, NULL, dir_name[door], TO_ROOM );
}
else // leaving ooc rooms
{
if (ch->last_ic_room)
{
to_room = ch->last_ic_room;
}
ch->last_ic_room= NULL;
act( "$n leaves $T [LEAVES OOC AREA].", ch, NULL, dir_name[door], TO_ROOM );
}
}else{
if (ch->mounted_on)
{
act( "$n rides $T.", ch, NULL, dir_name[door], TO_ROOM );
}
else if (IS_AFFECTED(ch, AFF_SNEAK) && IS_IC(ch)) // no sneaking in ooc
{
int old_invis_level;
old_invis_level=ch->invis_level;
// hide them to mortals
ch->invis_level = UMAX(ch->invis_level, LEVEL_IMMORTAL);
// inform the imms in the room someone snuck in
act( "$n leaves $T. [SNEAKING]", ch, NULL, dir_name[door], TO_ROOM );
// restore their wizi
ch->invis_level=old_invis_level;
}
else
{
if ( !IS_SET(ch->act, ACT_IS_UNSEEN ))
{
act( "$n leaves $T.", ch, NULL, dir_name[door], TO_ROOM );
}
}
}
// take damage from lodged objects
obj=get_eq_char( ch, WEAR_LODGED_LEG );
if(obj){
act( "$p twists in your leg as you walk, hurting you greatly.", ch, obj, NULL, TO_CHAR );
ch->hit -= obj->level / 15;
ch->move -= obj->level / 8;
}
obj=get_eq_char( ch, WEAR_LODGED_RIB );
if(obj){
act( "$p twists in your ribs as you walk, hurting you greatly.", ch, obj, NULL, TO_CHAR );
ch->hit -= obj->level / 12;
}
// make the tracks
ch->in_room->tracks->add_track(ch, door, TRACKTYPE_MOVE);
//move the character from room to new room
char_from_room( ch );
char_to_room( ch, to_room );
if (ch->mounted_on){
char_from_room(ch->mounted_on);
char_to_room(ch->mounted_on, to_room);
act( "$n has arrived on $N.", ch, NULL, ch->mounted_on, TO_ROOM );
}else{
if (IS_AFFECTED(ch, AFF_SNEAK)){
int old_invis_level;
// back up the wizi level
old_invis_level= ch->invis_level;
// hide them to mortals
ch->invis_level = UMAX(ch->invis_level, LEVEL_IMMORTAL);
// inform the imms in the room someone snuck in
act( "$n arrives. [SNEAKING]", ch, NULL, dir_name[door], TO_ROOM );
// restore their wizi
ch->invis_level=old_invis_level;
}else{
act( "$n has arrived.", ch, NULL, NULL, TO_ROOM );
}
}
do_look( ch, "auto" );
// check PC's falling off their mount
if (ch->mounted_on && !IS_NPC(ch))
{
if ((get_skill(ch, gsn_riding)==0)&&(number_range(1, 100)<=3))
{
ch->println("`CYou fall off your mount!`x");
ch->println("You should really learn to ride.");
act( "`C$n falls off of $N, how embarrassing.`x", ch, NULL, ch->mounted_on, TO_ROOM );
ch->position=POS_RESTING;
dismount(ch);
}
if (get_skill(ch, gsn_riding)<75){
check_improve(ch,gsn_riding,true,2);
}
}
if(!to_room){ // no following into NULL
return;
}
if (in_room == to_room){ // no circular follows
return;
}
for ( fch = in_room->people; fch != NULL; fch = fch_next )
{
fch_next = fch->next_in_room;
if ( !IS_NPC(fch) )
{
if( fch->pcdata->is_trying_aware && !IS_IMMORTAL(ch) &&
number_percent()<get_skill(fch, gsn_awareness) &&
fch->position==POS_SLEEPING &&
!IS_AFFECTED(fch,AFF_SLEEP))
{
fch->position=POS_RESTING;
fch->println("You are awakened suddenly by a presence.");
do_stand(fch,"");
check_improve(fch,gsn_awareness,true,14);
}
}
if ( fch->master == ch && IS_AFFECTED(fch,AFF_CHARM)
&& fch->position < POS_STANDING)
do_stand(fch,"");
if ( fch->master == ch && fch->position == POS_STANDING
&& can_see_room(fch,to_room))
{
if (IS_SET(ch->in_room->room_flags,ROOM_LAW)
&& (IS_NPC(fch) && IS_SET(fch->act,ACT_AGGRESSIVE)))
{
act("You can't bring $N into the city.",
ch,NULL,fch,TO_CHAR);
act("You aren't allowed in the city.",
fch,NULL,NULL,TO_CHAR);
continue;
}
{
char fbuf[MIL];
sprintf(fbuf,"You follow $N `Y%s`x.", dir_name[door]);
act( fbuf, fch, NULL, ch, TO_CHAR );
}
move_char( fch, door, true );
}
}
// If someone is following the char, these triggers get activated
// for the followers before the char, but it's safer this way...
if( IS_NPC( ch ) && HAS_TRIGGER( ch, TRIG_ENTRY ) ){
mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_ENTRY );
}
if( !IS_NPC( ch ) ){
mp_greet_trigger( ch );
}
return;
}
/**************************************************************************/
void do_northeast( char_data *ch, char *)
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_NORTHEAST, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_southeast( char_data *ch, char *)
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_SOUTHEAST, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_southwest( char_data *ch, char *)
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_SOUTHWEST, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_northwest( char_data *ch, char *)
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_NORTHWEST, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_north( char_data *ch, char *)
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_NORTH, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_east( char_data *ch, char * )
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_EAST, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_south( char_data *ch, char * )
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_SOUTH, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_west( char_data *ch, char * )
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_WEST, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_up( char_data *ch, char * )
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_UP, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
void do_down( char_data *ch, char * )
{
ROOM_INDEX_DATA *was_room = ch->in_room;
move_char( ch, DIR_DOWN, false );
if ( was_room == ch->in_room )
free_speedwalk( ch->desc );
return;
}
/**************************************************************************/
int find_door( char_data *ch, char *arg, char *action )// action = NULL/lock/unlock/open/close etc
{
EXIT_DATA *pexit;
int door;
if ( !str_cmp( arg, "n" ) || !str_cmp( arg, "north" ) ) door = 0;
else if ( !str_cmp( arg, "e" ) || !str_cmp( arg, "east" ) ) door = 1;
else if ( !str_cmp( arg, "s" ) || !str_cmp( arg, "south" ) ) door = 2;
else if ( !str_cmp( arg, "w" ) || !str_cmp( arg, "west" ) ) door = 3;
else if ( !str_cmp( arg, "u" ) || !str_cmp( arg, "up" ) ) door = 4;
else if ( !str_cmp( arg, "d" ) || !str_cmp( arg, "down" ) ) door = 5;
else if ( !str_cmp( arg, "ne" ) || !str_cmp( arg, "northeast" ) ) door = 6;
else if ( !str_cmp( arg, "se" ) || !str_cmp( arg, "southeast" ) ) door = 7;
else if ( !str_cmp( arg, "sw" ) || !str_cmp( arg, "southwest" ) ) door = 8;
else if ( !str_cmp( arg, "nw" ) || !str_cmp( arg, "northwest" ) ) door = 9;
else
{
for ( door = 0; door < MAX_DIR; door++ )
{
if ( ( pexit = ch->in_room->exit[door] ) != NULL
&& pexit->exit_info>0
&& pexit->keyword != NULL
&& is_name( arg, pexit->keyword ) )
return door;
}
ch->printlnf("I see no %s here to %s.", arg, action);
return -1;
}
if ( ( pexit = ch->in_room->exit[door] ) == NULL )
{
if(IS_NULLSTR(action)){
ch->printlnf( "I see no door %s.", arg);
}else{
ch->printlnf( "I see no door %s here to %s.", arg, action);
}
return -1;
}
if ( pexit->exit_info==0 )
{
ch->printlnf( "You can't %s the %s exit.", action, dir_name[door]);
return -1;
}
return door;
}
/**************************************************************************/
void do_unlock( char_data *ch, char *argument );
/**************************************************************************/
void do_open( char_data *ch, char *argument )
{
char arg[MIL];
OBJ_DATA *obj;
int door;
one_argument( argument, arg );
if(IS_NULLSTR(arg)){
ch->println("Open what?");
return;
}
if ( ( obj = get_obj_here( ch, arg ) ) != NULL )
{
// open portal
if (obj->item_type == ITEM_PORTAL)
{
if (!IS_SET(obj->value[1], EX_ISDOOR))
{
act( "You can't open $p.", ch, obj, NULL, TO_CHAR );
return;
}
if (!IS_SET(obj->value[1], EX_CLOSED))
{
act( "$p is already open.", ch, obj, NULL, TO_CHAR );
return;
}
if (IS_SET(obj->value[1], EX_LOCKED))
{
act( "$p is locked.", ch, obj, NULL, TO_CHAR );
return;
}
REMOVE_BIT(obj->value[1], EX_CLOSED);
act("You open $p.",ch,obj,NULL,TO_CHAR);
act("$n opens $p.",ch,obj,NULL,TO_ROOM);
return;
}
// 'open object'
if ( obj->item_type != ITEM_CONTAINER){
act( "$p is not a container.", ch, obj, NULL, TO_CHAR );
return;
}
if ( !IS_SET(obj->value[1], CONT_CLOSED) ){
act( "$p is already open.", ch, obj, NULL, TO_CHAR );
return;
}
if ( !IS_SET(obj->value[1], CONT_CLOSEABLE) ){
act( "$p can't be opened.", ch, obj, NULL, TO_CHAR );
return;
}
// traps
if (trapcheck_open( ch, obj )){
return;
}
// attempt to automatically unlock it
if(IS_SET(obj->value[1], CONT_LOCKED)){
do_unlock(ch, argument);
}
if ( IS_SET(obj->value[1], CONT_LOCKED) ){
act( "$p is locked.", ch, obj, NULL, TO_CHAR );
return;
}
REMOVE_BIT(obj->value[1], CONT_CLOSED);
act("You open $p.",ch,obj,NULL,TO_CHAR);
act( "$n opens $p.", ch, obj, NULL, TO_ROOM );
return;
}
if ( ( door = find_door( ch, arg, "open" ) ) >= 0 )
{
// 'open door'
ROOM_INDEX_DATA *to_room;
EXIT_DATA *pexit;
EXIT_DATA *pexit_rev= NULL;
pexit = ch->in_room->exit[door];
if ( !IS_SET(pexit->exit_info, EX_CLOSED) )
{ ch->println("It's already open."); return; }
if ( IS_SET(pexit->exit_info, EX_LOCKED) )
{ ch->println("It's locked."); return; }
REMOVE_BIT(pexit->exit_info, EX_CLOSED);
act( "$n opens the $d.", ch, NULL, pexit->keyword, TO_ROOM );
msp_to_room(MSPT_ACTION, MSP_SOUND_OPEN_DOOR, 0, ch, false, true);
ch->println("Ok.");
{
char_data *rch;
// update peoples mappers
for ( rch = ch->in_room->people; rch; rch = rch->next_in_room ){
if (!IS_NPC(rch) && IS_AWAKE(rch)){
if(IS_SET(rch->act,PLR_AUTOMAP)){
do_map(rch,"");
}
}
}
// open the other side
if ( ( to_room = pexit->u1.to_room ) != NULL
&& ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL
&& pexit_rev->u1.to_room == ch->in_room )
{
REMOVE_BIT(pexit_rev->exit_info, EX_CLOSED);
for ( rch = to_room->people; rch; rch = rch->next_in_room ){
act( "The $d opens.", rch, NULL, pexit_rev->keyword, TO_CHAR );
if (!IS_NPC(rch) && IS_AWAKE(rch)){
if(IS_SET(rch->act,PLR_AUTOMAP)){
do_map(rch,"");
}
}
}
}
}
}
return;
}
/**************************************************************************/
void do_close( char_data *ch, char *argument )
{
char arg[MIL];
OBJ_DATA *obj;
int door;
one_argument( argument, arg );
if(IS_NULLSTR(arg)){
ch->println("Close what?");
return;
}
if ( ( obj = get_obj_here( ch, arg ) ) != NULL )
{
// portal stuff
if (obj->item_type == ITEM_PORTAL)
{
if (!IS_SET(obj->value[1],EX_ISDOOR)
|| IS_SET(obj->value[1],EX_NOCLOSE))
{
act( "You can't close $p.", ch, obj, NULL, TO_CHAR );
return;
}
if (IS_SET(obj->value[1],EX_CLOSED))
{
act( "$p is already closed.", ch, obj, NULL, TO_CHAR );
return;
}
SET_BIT(obj->value[1],EX_CLOSED);
act("You close $p.",ch,obj,NULL,TO_CHAR);
act("$n closes $p.",ch,obj,NULL,TO_ROOM);
return;
}
// 'close object'
if ( obj->item_type != ITEM_CONTAINER ){
act( "$p is not a container.", ch, obj, NULL, TO_CHAR );
return;
}
if ( IS_SET(obj->value[1], CONT_CLOSED) ){
act( "$p is already closed.", ch, obj, NULL, TO_CHAR );
return;
}
if ( !IS_SET(obj->value[1], CONT_CLOSEABLE) ){
act( "$p can't be closed.", ch, obj, NULL, TO_CHAR );
return;
}
SET_BIT(obj->value[1], CONT_CLOSED);
act("You close $p.",ch,obj,NULL,TO_CHAR);
act( "$n closes $p.", ch, obj, NULL, TO_ROOM );
return;
}
if ( ( door = find_door( ch, arg, "close" ) ) >= 0 )
{
// 'close door'
ROOM_INDEX_DATA *to_room;
EXIT_DATA *pexit;
EXIT_DATA *pexit_rev= NULL;
pexit = ch->in_room->exit[door];
if ( IS_SET(pexit->exit_info, EX_CLOSED) ){
ch->println("It's already closed.");
return;
}
if(IS_SET(pexit->exit_info, EX_NOCLOSE) )
{ ch->println("That door may not be closed once opened."); return; }
SET_BIT(pexit->exit_info, EX_CLOSED);
act( "$n closes the $d.", ch, NULL, pexit->keyword, TO_ROOM );
act( "You close the $d.", ch, NULL, pexit->keyword, TO_CHAR );
msp_to_room(MSPT_ACTION, MSP_SOUND_CLOSE_DOOR, 0, ch, false, true);
{
char_data *rch;
// update peoples mappers
for ( rch = ch->in_room->people; rch; rch = rch->next_in_room ){
if (!IS_NPC(rch) && IS_SET(rch->act,PLR_AUTOMAP)){
do_map(rch,"");
}
}
// close the other side
if ( ( to_room = pexit->u1.to_room ) != NULL
&& ( pexit_rev = to_room->exit[rev_dir[door]] ) != 0
&& pexit_rev->u1.to_room == ch->in_room )
{
char_data *rch;
SET_BIT(pexit_rev->exit_info, EX_CLOSED);
for ( rch = to_room->people; rch != NULL; rch = rch->next_in_room )
{
act( "The $d closes.", rch, NULL, pexit_rev->keyword, TO_CHAR );
if (!IS_NPC(rch) && IS_SET(rch->act,PLR_AUTOMAP)){
do_map(rch,"");
}
}
}
}
}
return;
}
/**************************************************************************/
bool has_key( char_data *ch, int key )
{
OBJ_DATA *obj;
for ( obj = ch->carrying; obj != NULL; obj = obj->next_content )
{
if ( obj->pIndexData->vnum == key )
return true;
}
return false;
}
/**************************************************************************/
void do_lock( char_data *ch, char *argument )
{
char arg[MIL];
OBJ_DATA *obj;
OBJ_INDEX_DATA *key;
int door;
one_argument( argument, arg );
if(IS_NULLSTR(arg)){
ch->println("Lock what?");
return;
}
if ( ( obj = get_obj_here( ch, arg ) ) != NULL )
{
// portal stuff
if (obj->item_type == ITEM_PORTAL)
{
if (!IS_SET(obj->value[1],EX_ISDOOR)
|| IS_SET(obj->value[1],EX_NOCLOSE))
{
act( "You can't lock $p.", ch, obj, NULL, TO_CHAR );
return;
}
if (!IS_SET(obj->value[1],EX_CLOSED)){
act( "Try closing $p first.", ch, obj, NULL, TO_CHAR );
return;
}
if (obj->value[4] < 0 || IS_SET(obj->value[1],EX_NOLOCK))
{
act( "$p can't be locked.", ch, obj, NULL, TO_CHAR );
return;
}
if (!has_key(ch,obj->value[4]))// locking, portal key
{
act( "You lack the key to lock $p.", ch, obj, NULL, TO_CHAR );
return;
}
if (IS_SET(obj->value[1],EX_LOCKED))
{
act( "$p is already locked.", ch, obj, NULL, TO_CHAR );
return;
}
SET_BIT(obj->value[1],EX_LOCKED);
// check if key exists (should be 100% at this point but better to be safe)
if (( key = get_obj_index( obj->value[4])) == NULL )
{
ch->printlnf( "do_lock: vnum %d not found, report this to admin.", obj->value[4] );
act("You lock $p.", ch, obj, NULL, TO_CHAR );
}
else
{
act("You lock $p with $T.", ch, obj, key->short_descr, TO_CHAR );
}
act("$n locks $p.",ch,obj,NULL,TO_ROOM);
msp_to_room(MSPT_ACTION, MSP_SOUND_LOCK, 0, ch, false, true);
return;
}
// 'lock object'
if ( obj->item_type != ITEM_CONTAINER ){
act( "$p is not a container.", ch, obj, NULL, TO_CHAR );
return;
}
// attempt to automatically close it
if (!IS_SET(obj->value[1], CONT_CLOSED)){
do_close(ch, argument);
}
if ( !IS_SET(obj->value[1], CONT_CLOSED) ){
act( "$p is not closed.", ch, obj, NULL, TO_CHAR );
return;
}
if ( obj->value[2] < 0 ){
act( "$p can't be locked.", ch, obj, NULL, TO_CHAR );
return;
}
if ( IS_SET(obj->value[1], CONT_LOCKED) ){
act( "$p is already locked.", ch, obj, NULL, TO_CHAR );
return;
}
// check for the 'key'
if ( IS_SET(obj->value[1], CONT_LOCKER) ){
if ( !lockers->has_access( ch, obj) ) // locking, locker object key
{ ch->println("You don't have access to lock this locker."); return; }
}else{
if ( !has_key( ch, obj->value[2] ) ){ // locking, object key
act( "You lack the key to $p.", ch, obj, NULL, TO_CHAR );
return;
}
}
SET_BIT(obj->value[1], CONT_LOCKED);
msp_to_room(MSPT_ACTION, MSP_SOUND_LOCK, 0, ch, false, true);
if (( key = get_obj_index( obj->value[2])) != NULL ){
act("You lock $p with $T.", ch, obj, key->short_descr, TO_CHAR );
}else{
act("You lock $p.", ch, obj, NULL, TO_CHAR );
}
act( "$n locks $p.", ch, obj, NULL, TO_ROOM );
return;
}
if ( ( door = find_door( ch, arg, "lock" ) ) >= 0 )
{
// 'lock door'
ROOM_INDEX_DATA *to_room;
EXIT_DATA *pexit;
EXIT_DATA *pexit_rev=NULL;
pexit = ch->in_room->exit[door];
if ( !IS_SET(pexit->exit_info, EX_CLOSED) )
{ ch->println("It's not closed."); return; }
if ( pexit->key < 0 || IS_SET(pexit->exit_info, EX_NOLOCK) )
{ ch->println("It can't be locked."); return; }
if ( !has_key( ch, pexit->key) ) // locking, door key
{ ch->println("You lack the key."); return; }
if ( IS_SET(pexit->exit_info, EX_LOCKED) )
{ ch->println("It's already locked."); return; }
SET_BIT(pexit->exit_info, EX_LOCKED);
if (( key = get_obj_index( pexit->key )) == NULL )
{
ch->printlnf( "do_lock: vnum %d not found, report this to admin.", pexit->key );
act("You lock $p.", ch, obj, NULL, TO_CHAR );
}
else
{
act("*CLICK* You've locked the $t with $T.", ch, pexit->keyword, key->short_descr, TO_CHAR );
}
act( "$n locks the $d.", ch, NULL, pexit->keyword, TO_ROOM );
msp_to_room(MSPT_ACTION, MSP_SOUND_LOCK, 0, ch, false, true);
// lock the other side
if ( ( to_room = pexit->u1.to_room ) != NULL
&& ( pexit_rev = to_room->exit[rev_dir[door]] ) != 0
&& pexit_rev->u1.to_room == ch->in_room )
{
SET_BIT(pexit_rev->exit_info, EX_LOCKED);
}
}
return;
}
/**************************************************************************/
void do_unlock( char_data *ch, char *argument )
{
char arg[MIL];
OBJ_DATA *obj;
OBJ_INDEX_DATA *key;
int door;
one_argument( argument, arg );
if(IS_NULLSTR(arg)){
ch->println("Unlock what?");
return;
}
if ( ( obj = get_obj_here( ch, arg ) ) != NULL )
{
// portal stuff
if (obj->item_type == ITEM_PORTAL)
{
if (IS_SET(obj->value[1],EX_ISDOOR))
{
act( "You can't unlock $p.", ch, obj, NULL, TO_CHAR );
return;
}
if (!IS_SET(obj->value[1],EX_CLOSED))
{
act( "$p isn't closed.", ch, obj, NULL, TO_CHAR );
return;
}
if (obj->value[4] < 0)
{
act( "$p can't be unlocked.", ch, obj, NULL, TO_CHAR );
return;
}
if (!has_key(ch,obj->value[4])) // unlocking, portal key
{
act( "You lack the key to unlock $p.", ch, obj, NULL, TO_CHAR );
return;
}
if (!IS_SET(obj->value[1],EX_LOCKED))
{
act( "$p is already unlocked.", ch, obj, NULL, TO_CHAR );
return;
}
REMOVE_BIT(obj->value[1],EX_LOCKED);
msp_to_room(MSPT_ACTION, MSP_SOUND_UNLOCK, 0, ch, false, true);
if (( key = get_obj_index( obj->value[4])) != NULL ){
act("You unlock $p with $T.", ch, obj, key->short_descr, TO_CHAR );
}else{
act("You unlock $p.", ch, obj, NULL, TO_CHAR );
}
act("$n unlocks $p.", ch, obj, NULL, TO_ROOM );
return;
}
// 'unlock object'
if ( obj->item_type != ITEM_CONTAINER ){
act( "$p is not a container.", ch, obj, NULL, TO_CHAR );
return;
}
if ( !IS_SET(obj->value[1], CONT_CLOSED) ){
act( "$p is not closed.", ch, obj, NULL, TO_CHAR );
ch->println( "It's not closed." );
return;
}
if ( obj->value[2] < 0 ){
act( "$p can't be unlocked.", ch, obj, NULL, TO_CHAR );
return;
}
if ( !IS_SET(obj->value[1], CONT_LOCKED) ){
act( "$p is already unlocked.", ch, obj, NULL, TO_CHAR );
return;
}
// check for the 'key'
if ( IS_SET(obj->value[1], CONT_LOCKER) ){
if ( !lockers->has_access( ch, obj) ) // unlocking, locker object key
{ ch->println( "You don't have access to unlock this locker." ); return; }
}else{
if ( !has_key( ch, obj->value[2] ) ){ // unlocking, object key
act( "You lack the key to unlock $p.", ch, obj, NULL, TO_CHAR );
return;
}
}
REMOVE_BIT(obj->value[1], CONT_LOCKED);
msp_to_room(MSPT_ACTION, MSP_SOUND_UNLOCK, 0, ch, false, true);
if (( key = get_obj_index( obj->value[2])) != NULL ){
act("You unlock $p with $T.", ch, obj, key->short_descr, TO_CHAR );
}else{
act("You unlock $p.", ch, obj, NULL, TO_CHAR );
}
act("$n unlocks $p.", ch, obj, NULL, TO_ROOM );
return;
}
if ( ( door = find_door( ch, arg, "unlock" ) ) >= 0 )
{
// 'unlock door'
ROOM_INDEX_DATA *to_room;
EXIT_DATA *pexit;
EXIT_DATA *pexit_rev=NULL;
pexit = ch->in_room->exit[door];
if ( !IS_SET(pexit->exit_info, EX_CLOSED) )
{ ch->println("It's not closed."); return; }
if ( pexit->key < 0 )
{ ch->println("It can't be unlocked."); return; }
if ( !has_key( ch, pexit->key) ) // unlocking, door key
{ ch->println("You lack the key."); return; }
if ( !IS_SET(pexit->exit_info, EX_LOCKED) )
{ ch->println("It's already unlocked."); return; }
REMOVE_BIT(pexit->exit_info, EX_LOCKED);
msp_to_room(MSPT_ACTION, MSP_SOUND_UNLOCK, 0, ch, false, true);
// check if key exists (should be 100% at this point but better to be safe)
if (( key = get_obj_index( pexit->key )) == NULL )
{
ch->printlnf( "do_unlock: vnum %d not found, report this to admin.", pexit->key );
act("You unlock $p.", ch, obj, NULL, TO_CHAR );
}
else
{
act("*CLICK* You've unlocked the $t with $T.", ch, pexit->keyword, key->short_descr, TO_CHAR );
}
act( "$n unlocks the $d.", ch, NULL, pexit->keyword, TO_ROOM );
// unlock the other side
if ( ( to_room = pexit->u1.to_room ) != NULL
&& ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL
&& pexit_rev->u1.to_room == ch->in_room )
{
REMOVE_BIT(pexit_rev->exit_info, EX_LOCKED);
}
}
return;
}
/**************************************************************************/
void do_pick( char_data *ch, char *argument )
{
char arg[MIL];
char_data *gch;
OBJ_DATA *obj;
int door;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
ch->println("Pick what?");
return;
}
if (get_skill(ch,gsn_pick_lock)==0)
{
if (number_range(1, 10)==1)
{
ch->println("You pick your nose when you think no one is looking.");
act("$n picks $s nose discretely.", ch, NULL, NULL, TO_ROOM);
return;
}
ch->println( "You failed." );
return;
}
if(ch->fighting){
ch->println( "You failed." );
return;
}
// look for guards
for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
{
if ( IS_NPC(gch) && !IS_SET(gch->act, ACT_IS_UNSEEN) &&
IS_AWAKE(gch) && ch->level + 5 < gch->level )
{
act( "$N is standing too close to the lock.",
ch, NULL, gch, TO_CHAR );
return;
}
}
// can't pick locks by spamming
if (ch->desc && ch->desc->repeat>15)
{
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
ch->println("You failed.");
return;
}
if ( number_percent( ) > get_skill(ch,gsn_pick_lock)+10 || IS_NPC(ch))
{
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
ch->println("You failed.");
check_improve(ch,gsn_pick_lock,false,2);
return;
}
if ( ( obj = get_obj_here( ch, arg ) ) != NULL )
{
// portal stuff
if (obj->item_type == ITEM_PORTAL)
{
if (!IS_SET(obj->value[1],EX_ISDOOR))
{
ch->println("You can't do that.");
return;
}
if (!IS_SET(obj->value[1],EX_CLOSED))
{
ch->println("It's not closed.");
return;
}
if (obj->value[4] < 0)
{
ch->println("It can't be unlocked.");
return;
}
if (IS_SET(obj->value[1],EX_PICKPROOF))
{
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
ch->println("You failed.");
return;
}
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
REMOVE_BIT(obj->value[1],EX_LOCKED);
act("You pick the lock on $p.",ch,obj,NULL,TO_CHAR);
act("$n picks the lock on $p.",ch,obj,NULL,TO_ROOM);
msp_skill_sound(ch, gsn_pick_lock);
check_improve(ch,gsn_pick_lock,true,2);
return;
}
// 'pick object'
if ( obj->item_type != ITEM_CONTAINER )
{ ch->println( "That's not a container." ); return; }
if ( !IS_SET(obj->value[1], CONT_CLOSED) )
{ ch->println( "It's not closed." ); return; }
if ( obj->value[2] < 0 )
{ ch->println( "It can't be unlocked." ); return; }
if ( !IS_SET(obj->value[1], CONT_LOCKED) )
{ ch->println( "It's already unlocked." ); return; }
// lockers are 10 times harder to pick than normal containers
if ( IS_SET(obj->value[1], CONT_LOCKER) && number_range(1,10)!=1){
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
act("You fail to pick the lock on $p.",ch,obj,NULL,TO_CHAR);
act("$n attempts to pick the lock on $p but fails.",ch,obj,NULL,TO_ROOM);
return;
}
if ( IS_SET(obj->value[1], CONT_PICKPROOF) )
{
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
ch->println( "You failed." );
return;
}
REMOVE_BIT(obj->value[1], CONT_LOCKED);
act("You pick the lock on $p.",ch,obj,NULL,TO_CHAR);
act("$n picks the lock on $p.",ch,obj,NULL,TO_ROOM);
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
msp_skill_sound(ch, gsn_pick_lock);
check_improve(ch,gsn_pick_lock,true,2);
return;
}
if ( ( door = find_door( ch, arg, "pick" ) ) >= 0 )
{
/* 'pick door' */
ROOM_INDEX_DATA *to_room;
EXIT_DATA *pexit;
EXIT_DATA *pexit_rev=NULL;
pexit = ch->in_room->exit[door];
if ( !IS_SET(pexit->exit_info,EX_CLOSED) )
{ ch->println("It's not closed."); return; }
if ( pexit->key < 0 && !IS_IMMORTAL(ch))
{ ch->println("It can't be picked."); return; }
if ( !IS_SET(pexit->exit_info, EX_LOCKED) )
{ ch->println("It's already unlocked."); return; }
if ((IS_SET(pexit->exit_info, EX_PICKPROOF) && !IS_IMMORTAL(ch))
|| (IS_SET(pexit->exit_info, EX_HARD) && number_range(1,4)!=1)
|| (IS_SET(pexit->exit_info, EX_INFURIATING) && number_range(1,20)!=1)
)
{
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
ch->println("You failed.");
return;
}
WAIT_STATE( ch, skill_table[gsn_pick_lock].beats );
REMOVE_BIT(pexit->exit_info, EX_LOCKED);
ch->println("*Click*");
msp_skill_sound(ch, gsn_pick_lock);
act( "$n picks the $d.", ch, NULL, pexit->keyword, TO_ROOM );
check_improve(ch,gsn_pick_lock,true,2);
/* pick the other side */
if ( ( to_room = pexit->u1.to_room ) != NULL
&& ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL
&& pexit_rev->u1.to_room == ch->in_room )
{
REMOVE_BIT(pexit_rev->exit_info, EX_LOCKED);
}
}
return;
}
/**************************************************************************/
void do_stand( char_data *ch, char *argument )
{
OBJ_DATA *obj = NULL;
if (ch->mounted_on!=NULL)
{
ch->println("You cannot do that while mounted.");
return;
}
if ( argument[0] != '\0' )
{
if (ch->position == POS_FIGHTING)
{
ch->println("Maybe you should finish fighting first?");
return;
}
obj = get_obj_list(ch,argument,ch->in_room->contents);
if (obj == NULL)
{
ch->println("You don't see that here.");
return;
}
if (obj->item_type != ITEM_FURNITURE
|| (!IS_SET(obj->value[2],STAND_AT)
&& !IS_SET(obj->value[2],STAND_ON)
&& !IS_SET(obj->value[2],STAND_UNDER)
&& !IS_SET(obj->value[2],STAND_IN)))
{
ch->println("You can't seem to find a place to stand.");
return;
}
if (ch->on != obj && count_users(obj) >= obj->value[0])
{
act_new("There's no room to stand on $p.", ch, obj, NULL, TO_ROOM, POS_DEAD);
return;
}
}
switch ( ch->position )
{
case POS_SLEEPING:
ch->println("You can't wake up!");
return;
case POS_RESTING:
case POS_SITTING:
case POS_KNEELING:
if (obj == NULL)
{
ch->println("You stand up.");
act( "$n stands up.", ch, NULL, NULL, TO_ROOM );
ch->on = NULL;
ch->is_trying_sleep=false;
}
else if (IS_SET(obj->value[2],STAND_AT))
{
act("You stand at $p.",ch,obj,NULL,TO_CHAR);
act("$n stands at $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],STAND_ON))
{
act("You stand on $p.",ch,obj,NULL,TO_CHAR);
act("$n stands on $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],STAND_UNDER))
{
act("You stand under $p.",ch,obj,NULL,TO_CHAR);
act("$n stands under $p.",ch,obj,NULL,TO_ROOM);
}
else
{
act("You stand in $p.",ch,obj,NULL,TO_CHAR);
act("$n stands in $p.",ch,obj,NULL,TO_ROOM);
}
ch->position = POS_STANDING;
break;
case POS_STANDING:
ch->println("You are already standing.");
ch->is_trying_sleep=false;
break;
case POS_FIGHTING:
ch->println("You are already fighting!");
break;
}
return;
}
/**************************************************************************/
void do_kneel( char_data *ch, char *argument )
{
OBJ_DATA *obj = NULL;
if(ch->mounted_on!=NULL)
{
ch->println( "You cannot kneel while mounted, dismount first." );
return;
}
if(!IS_NULLSTR(argument))
{
if(ch->position == POS_FIGHTING){
ch->println( "Maybe you should finish fighting first?" );
return;
}
obj = get_obj_list(ch,argument,ch->in_room->contents);
if(!obj){
ch->printlnf( "You don't see any '%s' here to kneel on.", argument );
return;
}
if (obj->item_type != ITEM_FURNITURE
|| (!IS_SET(obj->value[2],KNEEL_AT)
&& !IS_SET(obj->value[2],KNEEL_ON)
&& !IS_SET(obj->value[2],KNEEL_UNDER)
&& !IS_SET(obj->value[2],KNEEL_IN)))
{
ch->println("You can't seem to find a place to kneel.");
return;
}
if (ch->on != obj && count_users(obj) >= obj->value[0])
{
act_new("There's no room to kneel on $p.", ch,obj,NULL,TO_ROOM,POS_DEAD);
return;
}
}
switch ( ch->position )
{
case POS_SLEEPING:
ch->println( "You can't wake up!" );
return;
case POS_RESTING:
case POS_SITTING:
case POS_STANDING:
if (obj == NULL)
{
ch->println( "You kneel on the floor." );
act( "$n kneels on the floor.", ch, NULL, NULL, TO_ROOM );
ch->on = NULL;
ch->is_trying_sleep=false;
}
else if (IS_SET(obj->value[2],KNEEL_AT))
{
act("You kneel at $p.",ch,obj,NULL,TO_CHAR);
act("$n kneels at $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],KNEEL_ON))
{
act("You kneel on $p.",ch,obj,NULL,TO_CHAR);
act("$n kneels on $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],KNEEL_UNDER))
{
act("You kneel under $p.",ch,obj,NULL,TO_CHAR);
act("$n kneels under $p.",ch,obj,NULL,TO_ROOM);
}
else
{
act("You kneel in $p.",ch,obj,NULL,TO_CHAR);
act("$n kneels in $p.",ch,obj,NULL,TO_ROOM);
}
ch->position = POS_KNEELING;
break;
case POS_FIGHTING:
ch->println("You are fighting!");
break;
}
return;
}
/**************************************************************************/
void do_rest( char_data *ch, char *argument )
{
OBJ_DATA *obj = NULL;
if (ch->mounted_on!=NULL)
{
ch->println("You cannot do that while mounted.");
return;
}
if (!ch->fighting && ch->position == POS_FIGHTING)
{
bug("do_rest: !ch->fighting && ch->position == POS_FIGHTING");
ch->position = POS_STANDING;
}
if (ch->position == POS_FIGHTING)
{
ch->println("You are already fighting!");
return;
}
// okay, now that we know we can rest, find an object to rest on
if (argument[0] != '\0')
{
obj = get_obj_list(ch,argument,ch->in_room->contents);
if (obj == NULL)
{
ch->println("You don't see that here.");
return;
}
}else{
obj = ch->on;
}
if (obj != NULL)
{
if (obj->item_type != ITEM_FURNITURE
|| (!IS_SET(obj->value[2],REST_ON)
&& !IS_SET(obj->value[2],REST_IN)
&& !IS_SET(obj->value[2],REST_UNDER)
&& !IS_SET(obj->value[2],REST_AT)))
{
ch->println("You can't rest on that!");
return;
}
if (ch->on != obj && count_users(obj) >= obj->value[0])
{
act_new("There is no room on $p for you.",ch,obj,NULL,TO_CHAR,POS_DEAD);
return;
}
ch->on = obj;
}
switch ( ch->position )
{
case POS_SLEEPING:
ch->println("You can't wake yourself up!!");
break;
case POS_RESTING:
ch->println("You are already resting.");
break;
case POS_STANDING:
case POS_KNEELING:
if (obj == NULL)
{
ch->println("You rest.");
act( "$n sits down and rests.", ch, NULL, NULL, TO_ROOM );
}
else if (IS_SET(obj->value[2],REST_AT))
{
act("You sit down at $p and rest.",ch,obj,NULL,TO_CHAR);
act("$n sits down at $p and rests.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],REST_ON))
{
act("You sit on $p and rest.",ch,obj,NULL,TO_CHAR);
act("$n sits on $p and rests.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],REST_UNDER))
{
act("You sit under $p and rest.",ch,obj,NULL,TO_CHAR);
act("$n sits under $p and rests.",ch,obj,NULL,TO_ROOM);
}
else
{
act("You rest in $p.",ch,obj,NULL,TO_CHAR);
act("$n rests in $p.",ch,obj,NULL,TO_ROOM);
}
ch->position = POS_RESTING;
break;
case POS_SITTING:
if (obj == NULL)
{
ch->println("You rest.");
act("$n rests.",ch,NULL,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],REST_AT))
{
act("You rest at $p.",ch,obj,NULL,TO_CHAR);
act("$n rests at $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],REST_ON))
{
act("You rest on $p.",ch,obj,NULL,TO_CHAR);
act("$n rests on $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],REST_UNDER))
{
act("You rest under $p.",ch,obj,NULL,TO_CHAR);
act("$n rests under $p.",ch,obj,NULL,TO_ROOM);
}
else
{
act("You rest in $p.",ch,obj,NULL,TO_CHAR);
act("$n rests in $p.",ch,obj,NULL,TO_ROOM);
}
ch->position = POS_RESTING;
break;
}
if ( IS_AFFECTED(ch, AFF_FLYING) && HAS_CONFIG(ch, CONFIG_AUTOLANDONREST)){
landchar(ch);
ch->println("You stop flying.");
}
return;
}
/**************************************************************************/
void do_sit (char_data *ch, char *argument )
{
OBJ_DATA *obj = NULL;
if(ch->mounted_on){
ch->println("You are already sitting on something (your mount).");
return;
}
if(ch->position == POS_FIGHTING){
ch->println("Maybe you should finish this fight first?");
return;
}
// okay, now that we know we can sit, find an object to sit on
if(!IS_NULLSTR(argument)){
obj = get_obj_list(ch,argument,ch->in_room->contents);
if (obj == NULL)
{
ch->printlnf("You don't see any %s here to sit on/in/under/at.", argument);
return;
}
}else{
obj = ch->on;
}
if (obj != NULL)
{
if (!IS_SET(obj->item_type,ITEM_FURNITURE)
|| (!IS_SET(obj->value[2],SIT_ON)
&& !IS_SET(obj->value[2],SIT_IN)
&& !IS_SET(obj->value[2],SIT_UNDER)
&& !IS_SET(obj->value[2],SIT_AT)))
{
ch->println("You can't sit on that.");
return;
}
if (obj != NULL && ch->on != obj && count_users(obj) >= obj->value[0])
{
act_new("There's no more room on $p.",ch,obj,NULL,TO_CHAR,POS_DEAD);
return;
}
ch->on = obj;
}
switch (ch->position)
{
case POS_SLEEPING:
ch->println("You must wake up first.");
break;
case POS_RESTING:
if (obj == NULL)
ch->println("You stop resting.");
else if (IS_SET(obj->value[2],SIT_AT))
{
act("You sit at $p.",ch,obj,NULL,TO_CHAR);
act("$n sits at $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SIT_UNDER))
{
act("You sit under $p.",ch,obj,NULL,TO_CHAR);
act("$n sits under $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SIT_IN))
{
act("You sit in $p.",ch,obj,NULL,TO_CHAR);
act("$n sits in $p.",ch,obj,NULL,TO_ROOM);
}
else
{
act("You sit on $p.",ch,obj,NULL,TO_CHAR);
act("$n sits on $p.",ch,obj,NULL,TO_ROOM);
}
ch->position = POS_SITTING;
break;
case POS_KNEELING:
if (obj == NULL)
ch->println("You stop kneeling.");
else if (IS_SET(obj->value[2],SIT_AT))
{
act("You sit at $p.",ch,obj,NULL,TO_CHAR);
act("$n sits at $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SIT_UNDER))
{
act("You sit under $p.",ch,obj,NULL,TO_CHAR);
act("$n sits under $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SIT_IN))
{
act("You sit in $p.",ch,obj,NULL,TO_CHAR);
act("$n sits in $p.",ch,obj,NULL,TO_ROOM);
}
else
{
act("You sit on $p.",ch,obj,NULL,TO_CHAR);
act("$n sits on $p.",ch,obj,NULL,TO_ROOM);
}
ch->position = POS_SITTING;
break;
case POS_SITTING:
ch->println("You are already sitting down.");
break;
case POS_STANDING:
if (obj == NULL)
{
ch->println("You sit down.");
act("$n sits down on the ground.",ch,NULL,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SIT_AT))
{
act("You sit down at $p.",ch,obj,NULL,TO_CHAR);
act("$n sits down at $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SIT_IN))
{
act("You sit in $p.",ch,obj,NULL,TO_CHAR);
act("$n sits in $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SIT_UNDER))
{
act("You sit under $p.",ch,obj,NULL,TO_CHAR);
act("$n sits under $p.",ch,obj,NULL,TO_ROOM);
}
else
{
act("You sit down on $p.",ch,obj,NULL,TO_CHAR);
act("$n sits down on $p.",ch,obj,NULL,TO_ROOM);
}
ch->position = POS_SITTING;
break;
}
return;
}
/**************************************************************************/
void do_sleep( char_data *ch, char *argument )
{
OBJ_DATA *obj = NULL;
if (ch->mounted_on!=NULL)
{
ch->println( "You cannot do that while mounted." );
return;
}
// dont spam message
if (ch->desc && ch->desc->repeat>5)
{
ch->println( "Spamming the sleep command isn't going to make you go to" );
ch->println( "sleep any faster. You will fall asleep when you fall asleep." );
return;
}
switch ( ch->position )
{
case POS_SLEEPING:
ch->println( "You are already sleeping." );
break;
case POS_RESTING:
case POS_SITTING:
case POS_STANDING:
case POS_KNEELING:
if (argument[0] == '\0' && ch->on == NULL)
{
ch->println( "You attempt to go to sleep." );
ch->is_trying_sleep=true;
ch->position=POS_RESTING;
if(IS_NEWBIE(ch)){
ch->println("note: you won't fall asleep instantly unless you are very tired.");
}
}
else // find an object and sleep on it
{
if (argument[0] == '\0'){
obj = ch->on;
}else{
obj = get_obj_list( ch, argument, ch->in_room->contents );
}
if (obj == NULL){
ch->printlnf( "You don't see any '%s' in the room to sleep on.", argument );
if(IS_NEWBIE(ch)){
ch->println("Note: you must drop carried items such as bedrolls before sleeping on/in them.");
}
return;
}
if (obj->item_type != ITEM_FURNITURE
|| (!IS_SET(obj->value[2],SLEEP_ON)
&& !IS_SET(obj->value[2],SLEEP_IN)
&& !IS_SET(obj->value[2],SLEEP_UNDER)
&& !IS_SET(obj->value[2],SLEEP_AT)))
{
ch->printlnf( "You can't sleep on %s!", obj->short_descr);
return;
}
if (ch->on != obj && count_users(obj) >= obj->value[0]){
act_new("There is no room on $p for you.",ch,obj,NULL,TO_CHAR,POS_DEAD);
return;
}
ch->on = obj;
if (IS_SET(obj->value[2],SLEEP_AT))
{
act("You go to sleep at $p.",ch,obj,NULL,TO_CHAR);
act("$n tries to sleep at $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SLEEP_UNDER))
{
act("You try to go to sleep under $p.",ch,obj,NULL,TO_CHAR);
act("$n tries to go to sleep under $p.",ch,obj,NULL,TO_ROOM);
}
else if (IS_SET(obj->value[2],SLEEP_ON))
{
act("You try to go to sleep on $p.",ch,obj,NULL,TO_CHAR);
act("$n tries to go to sleep on $p.",ch,obj,NULL,TO_ROOM);
}
else
{
act("You try to go to sleep in $p.",ch,obj,NULL,TO_CHAR);
act("$n tries to go to sleep in $p.",ch,obj,NULL,TO_ROOM);
}
ch->is_trying_sleep=true;
ch->position=POS_RESTING;
}
break;
case POS_FIGHTING:
ch->println( "You are already fighting!" );
break;
}
if ( IS_AFFECTED(ch, AFF_FLYING) && HAS_CONFIG(ch, CONFIG_AUTOLANDONREST)){
landchar(ch);
ch->println( "You stop flying." );
}
// instant sleep for mobs
if(IS_NPC(ch) && ch->is_trying_sleep)
{
ch->position=POS_SLEEPING;
ch->println("You drift off into the dreamscape.");
act( "$n goes to sleep.", ch, NULL, NULL, TO_ROOM );
}
return;
}
/**************************************************************************/
void do_wake( char_data *ch, char *argument )
{
char arg[MIL];
char_data *victim;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
if(ch->mounted_on || ch->fighting || ch->position==POS_FIGHTING )
{
ch->println( "You are already awake." );
return;
}
if(!IS_NPC(ch))
{
if(ch->pcdata->tired>30 || IS_AFFECTED(ch,AFF_SLEEP) )
{
// dont spam message
if (ch->desc && ch->desc->repeat>10)
{
ch->println( "Spamming the wake command isn't going to help you wakeup." );
return;
}
ch->println( "You cannot wake yourself." );
}
else
{
if(ch->position==POS_STANDING)
{
ch->println( "You are already standing." );
ch->is_trying_sleep=false;
}
else
{
// if you wake up while drunk, you'll have a nasty little headache
if ( ch->pcdata->condition[COND_DRUNK] )
{
AFFECT_DATA af;
af.where = WHERE_MODIFIER;
af.type = gsn_cause_headache;
af.level = ch->level;
af.duration = 3;
af.location = APPLY_SD;
af.modifier = - ch->level/5;
af.bitvector = 0;
affect_to_char( ch, &af );
ch->println("You wake up with a major hangover.");
ch->pcdata->condition[COND_DRUNK] = 0;
}
ch->position=POS_RESTING;
do_stand(ch,"");
}
}
}
else
{
if(ch->position==POS_STANDING)
{
ch->println("You are already standing.");
ch->is_trying_sleep=false;
}else{
ch->position=POS_RESTING;
do_stand(ch,"");
}
}
return;
}
if ( !IS_AWAKE(ch) )
{ ch->println("You are asleep yourself!"); return; }
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{ ch->println("They aren't here."); return; }
if ( IS_AWAKE(victim) )
{ act( "$N is already awake.", ch, NULL, victim, TO_CHAR ); return; }
if ( IS_AFFECTED(victim, AFF_SLEEP) )
{ act( "You can't wake $M!", ch, NULL, victim, TO_CHAR ); return; }
act_new( "$n wakes you.", ch, NULL, victim, TO_VICT,POS_SLEEPING );
victim->position=POS_RESTING;
victim->subdued= false;
// if you wake up while drunk, you'll have a nasty little headache
if ( !IS_NPC( victim ))
{
if ( victim->pcdata->condition[COND_DRUNK] )
{
AFFECT_DATA af;
af.where = WHERE_MODIFIER;
af.type = gsn_cause_headache;
af.level = victim->level;
af.duration = 3;
af.location = APPLY_SD;
af.modifier = - victim->level/5;
af.bitvector = 0;
affect_to_char( victim, &af );
victim->println("You wake up with a major hangover.");
victim->pcdata->condition[COND_DRUNK] = 0;
}
}
do_stand(victim,"");
return;
}
/**************************************************************************/
void do_sneak( char_data *ch, char *)
{
AFFECT_DATA af;
if (ch->mounted_on!=NULL)
{
ch->println( "You cannot do that while mounted." );
return;
}
ch->println( "You attempt to move silently." );
affect_strip( ch, gsn_sneak );
if (IS_AFFECTED(ch,AFF_SNEAK))
return;
if ( number_percent( ) < get_skill(ch,gsn_sneak))
{
check_improve(ch,gsn_sneak,true,3);
af.where = WHERE_AFFECTS;
af.type = gsn_sneak;
af.level = ch->level;
af.duration = ch->level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SNEAK;
affect_to_char( ch, &af );
}else{
check_improve(ch,gsn_sneak,false,3);
}
return;
}
/**************************************************************************/
void do_hide( char_data *ch, char *)
{
if (ch->mounted_on!=NULL){
ch->println( "You cannot do that while mounted." );
return;
}
ch->println( "You attempt to hide." );
if( IS_AFFECTED(ch, AFF_HIDE) ){
REMOVE_BIT(ch->affected_by, AFF_HIDE);
}
if ( number_percent( ) < get_skill(ch,gsn_hide)){
SET_BIT(ch->affected_by, AFF_HIDE);
check_improve(ch,gsn_hide,true,3);
}else{
check_improve(ch,gsn_hide,false,3);
}
return;
}
/**************************************************************************/
void do_vanish( char_data *ch, char *)
{
AFFECT_DATA af;
if (IS_NPC(ch))
{
ch->println( "Players only." );
return;
}
if (get_skill(ch, gsn_vanish) < 1)
{
ch->println( "You put your hands in front of your eyes, hoping no one will see you." );
return;
}
if (ch->mounted_on!=NULL)
{
ch->println( "You cannot do that while mounted." );
return;
}
if ( IS_AFFECTED2(ch, AFF2_VANISH) )
{
ch->println( "You are already out of sight." );
return;
}
if (ch->pcdata->next_vanish>current_time)
{
ch->println( "You are not able to vanish just yet." );
return;
}
ch->println( "You attempt to vanish from plain sight." );
if ( number_percent( ) < get_skill(ch,gsn_vanish))
{
af.where = WHERE_AFFECTS2;
af.type = gsn_vanish;
af.level = ch->level;
af.duration = (ch->level/20)+1;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF2_VANISH;
affect_to_char( ch, &af );
check_improve(ch,gsn_vanish,true,3);
ch->pcdata->next_vanish = current_time + (150 - ch->level)*8;
act( "$n vanishes from plain sight.", ch, NULL, NULL, TO_ROOM );
}
else
{
check_improve(ch,gsn_vanish,false,3);
ch->pcdata->next_vanish = current_time + (150 - ch->level);
}
return;
}
/**************************************************************************/
void do_sscan( char_data *ch, char *argument )
{
if ( number_percent( ) < get_skill(ch,gsn_scan) || IS_CONTROLLED(ch))
{
do_scan( ch, argument);
check_improve(ch,gsn_scan,true,1);
}
else
{
check_improve(ch,gsn_scan,false,1);
ch->println("Your scanning is insufficient.");
}
return;
}
/**************************************************************************/
// by Alander
void do_visible( char_data *ch, char *argument)
{
affect_strip ( ch, gsn_invisibility );
affect_strip ( ch, gsn_mass_invis );
affect_strip ( ch, gsn_sneak );
REMOVE_BIT ( ch->affected_by, AFF_HIDE );
REMOVE_BIT ( ch->affected_by, AFF_INVISIBLE );
REMOVE_BIT ( ch->affected_by, AFF_SNEAK );
if ( IS_SET( ch->affected_by2, AFF2_TREEFORM ))
{
REMOVE_BIT( ch->affected_by2, AFF2_TREEFORM );
act( "A tree suddenly transforms into $n.", ch, NULL, NULL, TO_ROOM );
ch->println( "You assume your normal form." );
}
if ( IS_SET( ch->affected_by2, AFF2_VANISH ))
{
REMOVE_BIT( ch->affected_by2, AFF2_VANISH );
affect_strip ( ch, gsn_vanish );
act( "A swirl of dust reveals $n.", ch, NULL, NULL, TO_ROOM );
ch->println( "You shake the `#`Bfaerie-dust`^ from your body." );
}
if(strcmp(argument,"auto"))
{
ch->println( "You make yourself visible." );
}
return;
}
/**************************************************************************/
// find the players recall vnum in order of priority
// 1st - a manually set vnum
// 2nd - level 1 to 5 newbie recall vnum
// 3rd - court location
// 4th - clan location if not on pkill port
// 5th - class recall point (guild[0] for now)
// 6th - default racial location
int get_recallvnum(char_data *ch)
{
int vnum=ROOM_VNUM_OOC;
if (ch->recall_inn_room>0) {
vnum=ch->recall_inn_room;
} else if (ch->recall_room > 0 ){
vnum= ch->recall_room;
// using IS_SET to check for the court flag since when switched it
// shouldn't get the court status of the controling player, but the mob
}else if (IS_COURT(ch)){
vnum=ROOM_VNUM_COURT_RECALL;
}else if (ch->level<6 && ROOM_VNUM_NEWBIE_RECALL){
vnum=ROOM_VNUM_NEWBIE_RECALL;
}else if (ch->clan && !GAMESETTING5(GAMESET5_DEDICATED_PKILL_STYLE_MUD)){
vnum=ch->clan->recall_room();
}else if ( class_table[ch->clss].recall > 0 ){
vnum= class_table[ch->clss].recall;
} else {
vnum=race_table[ch->race]->recall_room;
}
return vnum;
};
/**************************************************************************/
void do_recall( char_data *ch, char *arg)
{
char_data *victim;
ROOM_INDEX_DATA *location;
ROOM_INDEX_DATA *innlocation;
static int pvnum;
int recall_vnum;
if (IS_NPC(ch) && !IS_SET(ch->act,ACT_PET))
{
ch->println("Only players can recall.");
return;
}
// Recall reset resets the recal_inn_room to zero. This means the player recalls to his
// default recall spot.
if (!str_cmp("reset", arg)) {
// The inn recall room is set.
if ( ch->recall_inn_room!=0 ) {
// Check the room is valid before printing the name of the room to the player.
if ( ((innlocation=get_room_index(ch->recall_inn_room)) != NULL) &&
(innlocation->name != NULL) ) {
// Inform the player which room is no longer his recall room.
ch->printlnf("You no longer recall to %s.", innlocation->name);
}
} else {
// Inn recall room wasn't set.
ch->println("You weren't recalling anywhere specific.");
}
// Reset the inn recall variables.
ch->recall_inn_room = 0;
ch->expire_recall_inn = 0;
return;
}
// stop pets recalling if they are asleep
if(!IS_AWAKE(ch)){
ch->println( "You can't recall when you are sleeping!" );
return;
}
// Check to see if ch is charmed and being ordered to cast
if ( IS_AFFECTED(ch,AFF_CHARM) && !IS_SET( ch->dyn, DYN_IS_BEING_ORDERED ))
{
ch->println( "You must wait for your master to tell you to recall." );
return;
}
location = ch->last_ic_room;
if ( IS_SET( ch->in_room->room_flags, ROOM_ANTIMAGIC )) {
ch->println( "You pray for transportation but nothing happens." );
return;
}
if (IS_OOC(ch) && IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) )
{
act( "$n prays for transportation!", ch, 0, 0, TO_ROOM );
ch->wrapln("As you pray for transportation, You feel an inward "
"tugging but realise you haven't gone anywhere.");
return;
}
if (IS_OOC(ch) && location)
{
act( "$n decides to go back to the IC realm.", ch, 0, 0, TO_ROOM );
ch->last_ic_room= NULL;
}
else
{
act( "$n prays for transportation!", ch, 0, 0, TO_ROOM );
// pets recall to their masters
if (IS_NPC(ch) && ch->master){
recall_vnum = ch->master->in_room->vnum;
}else{
recall_vnum=get_recallvnum(ch);
}
if ( ( location = get_room_index( recall_vnum ) ) == NULL )
{
ch->println( "You are completely lost." );
if ( ( location = get_room_index( ROOM_VNUM_OOC ) ) == NULL)
{
ch->printlnf( "BUG: Cant find the main ooc room (vnum = %d)\r\n"
"Please report this to an admin.", ROOM_VNUM_OOC);
return;
}
else
{
if (IS_SET(location->room_flags, ROOM_OOC))
{
ch->printlnf( "Taking you to the main OOC room since your normal recall (%d) doesnt exist.", recall_vnum);
}
else
{
ch->printlnf( "BUG: Taking you to the main ooc room (vnum = %d)\r\n"
"This room SHOULD be an OOC room - please report this bug to an admin.", ROOM_VNUM_OOC);
}
}
}
if (ch->pknorecall>0){
ch->println("You may not recall so soon after conflict.");
return;
}
if(IS_NPC(ch)){
location = get_room_index(pvnum);
}
if ( ch->in_room == location ){
ch->println("There would be no point in recalling, since you are already at your recall location.");
return;
}
if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)
|| IS_AFFECTED(ch, AFF_CURSE))
{
ch->println("You pray for transportation, but nothing appears to happen.");
return;
}
if ( ( victim = ch->fighting ) != NULL )
{
int lose,skill;
skill = get_skill(ch,gsn_recall);
if ( number_percent() < 80 * skill / 100 )
{
check_improve(ch,gsn_recall,false,6);
WAIT_STATE( ch, 4 );
ch->println("You failed!");
return;
}
lose = (ch->desc != NULL) ? 25 : 50;
gain_exp( ch, 0 - lose );
if ( IS_HERO( ch ))
do_heroxp( ch, 0 - lose );
check_improve(ch,gsn_recall,true,4);
ch->printlnf( "You recall from combat! You lose %d exps.", lose );
stop_fighting( ch, true );
}
if (ch->move>0 && IS_IC(ch) && ch->level>5){
ch->move /= 2;
}
if (ch->mounted_on!=NULL){
ch->mounted_on->move/=2;
}
}
if (ch->mounted_on){
act( "$n and $N disappear.", ch, NULL, ch->mounted_on, TO_ROOM );
char_from_room(ch->mounted_on);
char_to_room(ch->mounted_on, location);
}else{
act( "$n disappears.", ch, NULL, NULL, TO_ROOM );
}
char_from_room( ch );
char_to_room( ch, location );
if (ch->mounted_on){
act( "$n appears in the room riding $N.", ch, NULL, ch->mounted_on, TO_ROOM );
}else{
act( "$n appears in the room.", ch, NULL, NULL, TO_ROOM );
}
do_look( ch, "auto" );
if ( ch->pet && (ch->mounted_on!=ch->pet))
{
pvnum = location->vnum;
SET_BIT( ch->pet->dyn, DYN_IS_BEING_ORDERED );
do_recall(ch->pet,"");
REMOVE_BIT( ch->pet->dyn, DYN_IS_BEING_ORDERED );
}
return;
}
/**************************************************************************/
void do_train( char_data *ch, char *argument )
{
char buf[MSL];
char_data *mob;
sh_int stat = - 1;
char *pOutput = NULL;
int cost, amount, stat_diff;
if ( IS_NPC(ch) ){
ch->println( "Only players can train sorry." );
return;
}
// Check for trainer.
for ( mob = ch->in_room->people; mob; mob = mob->next_in_room )
{
if ( IS_NPC(mob) && IS_SET(mob->act, ACT_TRAIN) )
break;
}
if ( !mob )
{
ch->println("You can't train here.");
return;
}
// pretrain trigger, activated only on mobs with the trigger
// if the command 'mob preventtrain' is called, then the
// training is aborted
if ( IS_NPC(mob) && HAS_TRIGGER(mob, TRIG_PRETRAIN)){
mobprog_preventtrain_used=false;
if(mp_percent_trigger( mob, ch, NULL, NULL, TRIG_PRETRAIN)){
if(mobprog_preventtrain_used){
mob->printlnf("Training prevented on %s", PERS(ch, NULL));
return;
}
}
}
if ( argument[0] == '\0' )
{
ch->printlnf( "You have %d training sessions.", ch->train );
argument = "foo";
}
cost = 1;
if ( !str_prefix( argument, "strength" ) ){
stat = STAT_ST;
pOutput = "strength";
}else if ( !str_prefix( argument, "quickness" ) ){
stat = STAT_QU;
pOutput = "quickness";
} else if ( !str_prefix( argument, "presence" ) ){
stat = STAT_PR;
pOutput = "presence";
} else if ( !str_prefix( argument, "empathy" ) ){
stat = STAT_EM;
pOutput = "empathy";
} else if ( !str_prefix( argument, "intutition" ) ){
if(!str_cmp(argument, "in") || !str_cmp(argument, "int")){
ch->println("Note: 'int' on this mud is short for intuition (NOT intelligence)");
ch->println(" Intelligence is combination of memory and reasoning.");
ch->println(" type 'train intu' if you really want to train intuition.");
ch->println(" type 'train mem' to train memory.");
ch->println(" type 'train rea' to train reasoning.");
return;
}
stat = STAT_IN;
pOutput = "intuition";
} else if ( !str_prefix( argument, "constitution" ) ){
stat = STAT_CO;
pOutput = "constitution";
} else if ( !str_prefix( argument, "agility" ) ){
stat = STAT_AG;
pOutput = "agility";
} else if ( !str_cmp( argument, "sd" ) || !str_prefix( argument, "self-discipline" ) ){
stat = STAT_SD;
pOutput = "self-discipline";
} else if ( !str_prefix( argument, "memory" ) ){
stat = STAT_ME;
pOutput = "memory";
} else if ( !str_prefix( argument, "reasoning" ) ){
stat = STAT_RE;
pOutput = "reasoning";
}else if ( !str_cmp(argument, "hp" ) || !str_prefix( argument, "hitpoints" ) ){
cost = 1;
}else if ( !str_cmp(argument, "mana" ) ){
cost = 1;
}else if ( !str_cmp(argument, "moves" )|| !str_cmp( argument, "mv" ) ){
cost = 1;
}else{
strcpy( buf, "You can train:" );
if ( ch->perm_stats[STAT_ST] < ch->potential_stats[STAT_ST] ) {
strcat( buf, " strength" );
}
if ( ch->perm_stats[STAT_QU] < ch->potential_stats[STAT_QU] ){
strcat( buf, " quickness" );
}
if ( ch->perm_stats[STAT_PR] < ch->potential_stats[STAT_PR] ){
strcat( buf, " presence" );
}
if ( ch->perm_stats[STAT_EM] < ch->potential_stats[STAT_EM] ){
strcat( buf, " empathy" );
}
if ( ch->perm_stats[STAT_IN] < ch->potential_stats[STAT_IN] ){
strcat( buf, " intuition" );
}
if ( ch->perm_stats[STAT_CO] < ch->potential_stats[STAT_CO] ){
strcat( buf, " constitution" );
}
if ( ch->perm_stats[STAT_AG] < ch->potential_stats[STAT_AG] ){
strcat( buf, " agility" );
}
if ( ch->perm_stats[STAT_SD] < ch->potential_stats[STAT_SD] ){
strcat( buf, " self-discipline" );
}
if ( ch->perm_stats[STAT_ME] < ch->potential_stats[STAT_ME] ){
strcat( buf, " memory" );
}
if ( ch->perm_stats[STAT_RE] < ch->potential_stats[STAT_RE] ){
strcat( buf, " reasoning" );
}
if ( ch->pcdata->perm_hit < race_table[ch->race]->max_hp ){
strcat( buf, " hitpoints" );
}
strcat( buf, " moves");
strcat( buf, " mana.");
ch->printlnf( "%s", buf );
return;
}
if (!str_cmp("hp",argument) || !str_prefix( argument, "hitpoints" ))
{
if ( cost > ch->train )
{
ch->println( "You don't have enough training sessions." );
return;
}
if(ch->pcdata->perm_hit>=race_table[ch->race]->max_hp)
{
ch->println( "Your hps are already maxed." );
return;
}
ch->train -= cost;
amount = number_range(class_table[ch->clss].hp_min,
class_table[ch->clss].hp_max);
ch->printlnf( "Your durability increases from %d to %d!",
ch->pcdata->perm_hit, ch->pcdata->perm_hit+amount);
ch->pcdata->perm_hit += amount;
ch->pcdata->perm_hit=UMIN(ch->pcdata->perm_hit, race_table[ch->race]->max_hp);
ch->max_hit += amount;
ch->hit += amount;
act( "$n's durability increases!",ch,NULL,NULL,TO_ROOM);
ch->printlnf( "You now have %d training session%s left.",
ch->train, ch->train==1?"":"s");
return;
}
if (!str_cmp("moves",argument) || !str_cmp( argument, "mv" ))
{
int value = number_range(7, 15);
if ( cost > ch->train )
{
ch->println("You don't have enough training sessions.");
return;
}
ch->train -= cost;
ch->printlnf( "Your moves increase from %d to %d!",
ch->pcdata->perm_move,
ch->pcdata->perm_move + value);
ch->pcdata->perm_move += value;
ch->max_move += value;
ch->move += value;
act( "$n's endurance increases!",ch,NULL,NULL,TO_ROOM);
ch->printlnf( "You now have %d training session%s left.",
ch->train, ch->train==1?"":"s");
return;
}
if (!str_cmp("mana",argument))
{
if ( cost > ch->train )
{
ch->println("You don't have enough training sessions.");
return;
}
ch->train -= cost;
int increase;
if(class_table[ch->clss].fMana){
increase=number_range(6,15);
}else{
increase=number_range(3,6);
}
ch->printlnf( "Your power increases from %d to %d!",
ch->pcdata->perm_mana, ch->pcdata->perm_mana+increase);
ch->pcdata->perm_mana += increase;
ch->max_mana += increase;
ch->mana += increase;
act( "$n's power increases!",ch,NULL,NULL,TO_ROOM);
ch->printlnf( "You now have %d training session%s left.",
ch->train, ch->train==1?"":"s");
return;
}
if ( ch->perm_stats[stat] >= ch->potential_stats[stat] )
{
act( "Your $T is already at maximum.", ch, NULL, pOutput, TO_CHAR );
return;
}
if ( cost > ch->train )
{
ch->println("You don't have enough training sessions.");
return;
}
ch->train-= cost;
stat_diff = ch->potential_stats[stat] - ch->perm_stats[stat];
amount = stat_diff;
amount = amount * number_range(1,100);
amount = amount / 100;
// miniums for large stat differences
if (stat_diff>60 && amount<5){
amount =5;
}
if (stat_diff>45 && amount<4){
amount =4;
}else if (stat_diff>30 && amount<3){
amount =3;
}else if (stat_diff>15 && amount<2){
amount =2;
}
if(amount<1) {
amount=1;
}
if(amount>9) {
amount=9;
}
ch->printlnf( "Your %s increases from %d to %d/%d!", pOutput,
ch->perm_stats[stat], ch->perm_stats[stat]+amount,
ch->potential_stats[stat]);
act( "$n's $T increases!", ch, NULL, pOutput, TO_ROOM );
ch->perm_stats[stat] += amount;
ch->printlnf( "You now have %d training session%s left.",
ch->train, ch->train==1?"":"s");
// patch a bug where a level 1 newbie could be raged
// then train to increase stats
if(ch->pcdata->last_level==0){
ch->pcdata->last_level=1;
}
reset_char(ch);
}
/**************************************************************************/
void do_bank( char_data *ch, char *argument)
{
char arg[MIL];
char arg2[MIL];
int number;
argument = one_argument( argument, arg );
argument = one_argument( argument, arg2 );
if(arg[0]=='\0')
{
ch->println("Syntax: bank <deposit|balance|withdraw> <amount>");
ch->println(" There is a fee of 5 gold on any deposit or withdraw.");
ch->println(" The bank only deals in gold.");
ch->println("Note: If you are in a clan with a bank account setup, your clan bank will be used.");
return;
}
// check if this is a clan bank, it is, it takes prority over a normal bank
// note: clan banks shouldn't have the bank room flag set
if( ch->in_room && ch->clan && ch->clan->m_BankRoom== ch->in_room->vnum)
{
// argument has been destroyed previously, so we'll send it piecemeal
clan_bank( ch, arg, arg2 );
return;
}
if( !ch->in_room || !IS_SET(ch->in_room->room_flags,ROOM_BANK) )
{
ch->println( "You must be in a bank to make a transaction." );
return;
}
if(!str_prefix(arg,"balance") )
{
ch->printlnf( "You have an account balance of %ld gold.", ch->bank );
return;
}
if(!is_number(arg2))
{
ch->println( "The second argument must be a number." );
return;
}
number=atoi(arg2);
if(number<=0)
{
ch->println( "The second argument must be a number greater than 0." );
return;
}
if(number>1250000){
ch->println( "Sorry, we dont deal in such large amounts." );
return;
}
if(!str_prefix(arg,"deposit"))
{
if( number+5>ch->gold )
{
if( number>ch->gold ){
ch->println( "You do not have that much money." );
}else{
ch->println( "We charge a fee of 5 gold per deposit, banking all that money\r\n"
"will not leave you with enough to pay our deposit fee." );
}
return;
}
ch->gold-=number+5;
ch->bank+=number;
ch->println( "Deposit made.\r\nThank you for your patronage." );
save_char_obj(ch); // resave them
WAIT_STATE(ch, PULSE_PER_SECOND*3);
return;
}
if(!str_prefix(arg,"withdraw"))
{
if(number<6)
{
ch->println("Due to the surcharge of 5 gold you can not withdraw that small of an amount.");
return;
}
if(number>ch->bank-5)
{
ch->println("You do not have that much in the bank.");
return;
}
ch->gold+=number;
ch->bank-=number+5;
ch->println( "Withdrawal made.\r\nThank you for your patronage." );
save_char_obj(ch); // resave them
WAIT_STATE(ch, PULSE_PER_SECOND*3);
return;
}
ch->printlnf( "'%s' is not a valid bank transaction.", arg);
return;
}
/**************************************************************************/
// Kalahn - July 98
void do_goooc( char_data *ch, char * )
{
ROOM_INDEX_DATA *location;
if (IS_OOC(ch)){
ch->println("You are already in an OOC room.");
return;
}
if (IS_NPC(ch))
{
ch->println("Only players can use GoOOC.");
return;
}
if (IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) )
{
ch->println("You can't use GoOOC from rooms you can't recall out of.");
return;
}
if (ch->pknorecall>0 || ch->pknoquit>0)
{
ch->println("You can't use GoOOC while you have a pkill timer.");
return;
}
if ( IS_AFFECTED(ch, AFF_CURSE))
{
ch->println("You can't use GoOOC while cursed.");
return;
}
if ( IS_SWITCHED(ch))
{
ch->println("Goooc is disabled while you are switched, If you really must move the");
ch->printlnf( "mob you are controlling to the ooc rooms type trans self %d.", ROOM_VNUM_OOC );
return;
}
// find the room and check it is there
if ( ( location = get_room_index( ROOM_VNUM_OOC )) == NULL )
{
ch->println("For some reason the main ooc room is missing!");
ch->printlnf( "Please note the admin (room vnum = %d)", ROOM_VNUM_OOC);
return;
}
if (ch->in_room==location)
{
ch->println("You are already in that room.");
return;
}
if ( ch->fighting )
{
ch->println("You can't use GoOOC while fighting!");
return;
}
if (ch->mounted_on)
{
ch->println("Climb off your mount first.");
return;
}
// check for going into ooc from ic
if (IS_SET(location->room_flags, ROOM_OOC)){
ch->last_ic_room = ch->in_room;
}else{
ch->println("For some reason the main ooc room isnt marked as an OOC room!");
ch->println("You can not be transfered there as such.");
ch->printlnf( "Please note the bug admin (room vnum = %d)", ROOM_VNUM_OOC);
return;
}
act( "$n DISAPPEARS INTO THE OOC ROOMS", ch, 0, 0, TO_ROOM );
ch->println("Transferring you to the main OOC room now.");
char_from_room( ch );
char_to_room( ch, location );
act( "$n APPEARS FROM THE IC REALM", ch, 0, 0, TO_ROOM );
do_look( ch, "auto" );
return;
}
/**************************************************************************/
// Kal - August 99
void do_fly( char_data *ch, char * )
{
int launch_cost=10;
// it is easier for some races to take off
// originally designed for faeries
if(IS_SET(race_table[ch->race]->flags, RACEFLAG_LOWCOST_LAUNCH)){
launch_cost=2;
}
if(!IS_SET(race_table[ch->race]->aff,AFF_FLYING)){
ch->println( "Your race can't naturally fly, sorry." );
return;
}
if ( IS_SET( ch->in_room->room_flags, ROOM_NOFLY )){
ch->println( "The powerful winds prevent you from taking to air." );
return;
}
if ( IS_AFFECTED(ch, AFF_FLYING) ){
ch->println( "You are already flying!" );
return;
}
if (ch->fighting) {
ch->println( "You attempt to take off the ground, but your opponent prevents you!" );
WAIT_STATE(ch, PULSE_PER_SECOND*3);
return;
}
if(ch->move<launch_cost*3/2){
ch->println( "You dont feel you have enough energy to take off." );
return;
}
do_visible(ch,"auto");
ch->move-=launch_cost;
act( "$n launches $mself into the air.", ch, NULL, NULL, TO_ROOM );
ch->println("You launch yourself into the air.");
SET_BIT(ch->affected_by,AFF_FLYING);
SET_BIT(ch->dyn,DYN_NONMAGICAL_FLYING);
}
/**************************************************************************/
void landchar( char_data *ch)
{
// loop thru removing all fly affects
AFFECT_DATA *paf, *paf_next;
for ( paf= ch->affected; paf; paf = paf_next )
{
paf_next=paf->next;
if ( paf->bitvector== AFF_FLYING){
affect_remove( ch, paf );
}
}
REMOVE_BIT(ch->dyn,DYN_NONMAGICAL_FLYING);
REMOVE_BIT(ch->affected_by, AFF_FLYING);
}
/**************************************************************************/
DECLARE_SPELL_FUN( spell_null );
/**************************************************************************/
// Kal - August 99
void do_land( char_data *ch, char * )
{
if ( !IS_AFFECTED(ch, AFF_FLYING) ){
ch->println("You arent currently flying!");
return;
}
landchar(ch);
act( "$n returns to the ground.", ch, NULL, NULL, TO_ROOM );
ch->println("You land on the ground.");
}
/**************************************************************************/
// the below code could be used to give ideas for how to make the magic
// system prevent players from casting the same spell_function on others
// twice under different names
/* // loop thru all the spells finding any that use spell_fly,
// and if we find any remove them if ch is affected by that spell
SPELL_FUN * spell_fun=skill_table[gsn_fly].spell_fun;
if(spell_fun && spell_fun!=spell_null){
for ( int sn = FIRST_SPELL; sn < LAST_SPELL+1; sn++ )
{
if ( skill_table[sn].name == NULL )
break;
// we have a spell that uses the spell_fly spell_function
if(skill_table[sn].spell_fun==spell_fun)
{
if(is_affected(ch, sn)){
paf=affect_find(ch->affected, sn);
affect_remove( ch, paf );
break;
}
}
}
}
spell_fun=skill_table[gsn_animal_essence].spell_fun;
if(spell_fun && spell_fun!=spell_null){
for ( int sn = FIRST_SPELL; sn < LAST_SPELL+1; sn++ )
{
if ( skill_table[sn].name == NULL )
break;
// we have a spell that uses the spell_animal_essence spell_function
if(skill_table[sn].spell_fun==spell_fun)
{
if(is_affected(ch, sn)){
paf=affect_find(ch->affected, sn);
affect_remove( ch, paf );
break;
}
}
}
}
*/
/**************************************************************************/
void do_speedwalk( char_data *ch, char *argument )
{
char buf[MSL];
char arg[MIL];
char *direction;
bool found = false;
if ( !ch->desc || IS_NULLSTR( argument ))
{
ch->println("You must include directions. Read `=Chelp speedwalk`x for more information.");
return;
}
buf[0] = '\0';
while ( *argument != '\0' )
{
argument = one_argument( argument, arg );
strcat( buf, arg );
}
for ( direction = buf + str_len(buf)-1; direction >= buf; direction-- )
{
if ( !is_digit( *direction))
{
switch ( *direction )
{
case 'n':
case 'e':
case 's':
case 'w':
case 'r': // Northwest
case 't': // Northeast
case 'g': // Southeast
case 'f': // Southwest
case 'u':
case 'd':
found = true;
break;
case 'o':
break;
default:
ch->println("Invalid direction!");
return;
}
}
else if (!found)
*direction ='\0';
}
if ( !found )
{
ch->println("No directions specified.");
return;
}
ch->desc->speedwalk_buf = str_dup( buf );
ch->desc->speedwalk_head = ch->desc->speedwalk_buf;
ch->println("You start to walk...");
return;
}
/**************************************************************************/
void do_knock( char_data *ch, char *argument )\
{
char arg[MIL];
int door;
one_argument( argument, arg );
if ( IS_NULLSTR( arg ))
{
ch->println( "Knock on what?" );
return;
}
if ( ch->fighting ) // no knocking while fighting
{
ch->println( "You have better things to do with your knuckles right now." );
return;
}
if (( door = find_door( ch, arg, "knock on")) >= 0 )
{
ROOM_INDEX_DATA *to_room;
EXIT_DATA *pexit;
EXIT_DATA *pexit_rev=NULL;
pexit = ch->in_room->exit[door];
if ( !IS_SET( pexit->exit_info, EX_CLOSED )) // door already open
{
ch->println( "Why knock? It's open." );
return;
}
// door closed, so lets knock
act( "You knock loudly on the $d.", ch, NULL, pexit->keyword, TO_CHAR );
act( "$n knocks loudly on the $d.", ch, NULL, pexit->keyword, TO_ROOM );
if (( to_room = pexit->u1.to_room ) != NULL
&& ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL
&& pexit_rev->u1.to_room == ch->in_room )
{
char_data *rch;
for ( rch = to_room->people; rch; rch = rch->next_in_room )
{
act( "Someone knocks loudly from the other side of the $d.",
rch, NULL, pexit_rev->keyword, TO_CHAR );
}
}
}
else
{
act( "You knock on your forehead but nobody answers.", ch, NULL, NULL, TO_CHAR );
act( "$n knocks on $s forehead but nobody answers.", ch, NULL, NULL, TO_ROOM );
}
return;
}
/**************************************************************************/
void do_invitelist(char_data *ch, char *argument)
{
if(IS_NPC(ch)){
ch->println("Players only.");
return;
}
if(GAMESETTING4(GAMESET4_ROOM_INVITES_DISABLED)){
ch->println("The room invites system is currently disabled.");
return;
}
ROOM_INDEX_DATA *room=ch->in_room;
if(IS_NULLSTR(room->owner)){
if(IS_ADMIN(ch)){
ch->println("There are no owners in this room, therefore invite lists are ignored.");
}else{
ch->println("You are not the owner of this room, so you can't modify its invite list.");
}
return;
}
if(!is_exact_name(ch->name, room->owner) && !IS_ADMIN(ch)){
ch->println("You are not the owner of this room, so you can't modify its invite list.");
return;
}
char arg[MIL];
one_argument(argument, arg);
smash_tilde(arg);
if(IS_NULLSTR(arg)){
if(IS_ADMIN(ch)){
ch->printlnf("Current room %d owner = '%s'", room->vnum, room->owner);
}
ch->printlnf("Current room invite list = '%s'", ltrim_string(rtrim_string(room->invite_list)));
ch->println("Type 'invitelist <playername>' to add or remove it from this list.");
ch->println("Type 'invitelist clan=<clanname>' to add or remove clan from this list.");
return;
}
if(has_colour(arg)){
ch->println("You can't use colour codes here.");
return;
}
if(is_exact_name(arg, room->invite_list)){
ch->printlnf("Removing '%s' from room invite list.", arg);
// remove them from the rooms invite list
room->invite_list=string_replace_all(room->invite_list, FORMATF(" %s ", arg), " ");
room->invite_list=string_replace_all(room->invite_list, " ", " ");
ch->printlnf("Room invite list now: '%s'", ltrim_string(rtrim_string(room->invite_list)));
SET_BIT( room->area->olc_flags, OLCAREA_INVITELISTCHANGED );
return;
}else{
// add them to the rooms invite list
if(str_len(room->invite_list)> MIL){
ch->println("Too many names listed in room invite list, remove some first.");
ch->printlnf("Room invite list now: '%s'", ltrim_string(rtrim_string(room->invite_list)));
return;
}
ch->printlnf("Adding '%s' to room invite list.", arg);
if(IS_NULLSTR(room->invite_list)){
replace_string(room->invite_list, FORMATF(" %s ", arg));
}else{
char *f=FORMATF("%s%s ", room->invite_list, arg);
replace_string(room->invite_list, f);
}
ch->printlnf("Room invite list now: '%s'", ltrim_string(rtrim_string(room->invite_list)));
SET_BIT( room->area->olc_flags, OLCAREA_INVITELISTCHANGED );
return;
}
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/