/**************************************************************************/ // 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; } } /**************************************************************************/ /**************************************************************************/ /**************************************************************************/ /**************************************************************************/ /**************************************************************************/