/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.0 (C) 1994, 1995, 1996 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh and Tricops |~'~.VxvxV.~'~* **************************************************************************** * The MUDprograms are heavily based on the original MOBprogram code that * * was written by N'Atas-ha. * ****************************************************************************/ /*static char rcsid[] = "$Id: mud_comm.c,v 1.29 2004/04/06 22:00:10 dotd Exp $";*/ #include <sys/types.h> #include <stdio.h> #include <string.h> #include "mud.h" #include "gsn.h" DECLARE_DO_FUN(do_help); DECLARE_DO_FUN(do_look); DECLARE_DO_FUN(do_recall); DECLARE_DO_FUN(do_flee); DECLARE_DO_FUN(do_sit); DECLARE_DO_FUN(do_variables); DECLARE_DO_FUN(do_order); bool MOBtrigger; int get_exflag( char *flag ); ch_ret simple_damage( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt ); char *mprog_type_to_name( sh_int type ) { switch ( type ) { case IN_FILE_PROG: return "in_file_prog"; case ACT_PROG: return "act_prog"; case SPEECH_PROG: return "speech_prog"; case RAND_PROG: return "rand_prog"; case FIGHT_PROG: return "fight_prog"; case HITPRCNT_PROG: return "hitprcnt_prog"; case DEATH_PROG: return "death_prog"; case BIRTH_PROG: return "birth_prog"; case ENTRY_PROG: return "entry_prog"; case GREET_PROG: return "greet_prog"; case ALL_GREET_PROG: return "all_greet_prog"; case GIVE_PROG: return "give_prog"; case BRIBE_PROG: return "bribe_prog"; case HOUR_PROG: return "hour_prog"; case TIME_PROG: return "time_prog"; case WEAR_PROG: return "wear_prog"; case REMOVE_PROG: return "remove_prog"; case SAC_PROG : return "sac_prog"; case LOOK_PROG: return "look_prog"; case EXA_PROG: return "exa_prog"; case ZAP_PROG: return "zap_prog"; case GET_PROG: return "get_prog"; case DROP_PROG: return "drop_prog"; case REPAIR_PROG: return "repair_prog"; case DAMAGE_PROG: return "damage_prog"; case PULL_PROG: return "pull_prog"; case PUSH_PROG: return "push_prog"; case SCRIPT_PROG: return "script_prog"; case SLEEP_PROG: return "sleep_prog"; case REST_PROG: return "rest_prog"; case LEAVE_PROG: return "leave_prog"; case USE_PROG: return "use_prog"; case QUEST_PROG: return "quest_prog"; case COMMAND_PROG: return "command_prog"; case AREA_RESET_PROG: return "area_reset_prog"; case AREA_INIT_PROG: return "area_init_prog"; default: return "ERROR_PROG"; } } bool charm_order_check(CHAR_DATA *ch) { /* don't need to check AFF_CHARM, master is enough */ if (ch->master) { if (ch->master->last_cmd == do_order) { sprintf(log_buf, "%s tried to order an mpcommand", GET_NAME(ch->master)); log_string_plus(log_buf, LOG_MONITOR, LEVEL_LOG_CSET, SEV_ALERT); return TRUE; } } return FALSE; } /* A trivial rehack of do_mstat. This doesnt show all the data, but just * enough to identify the mob and give its basic condition. It does however, * show the MUDprograms which are set. */ void do_mpstat( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; MPROG_DATA *mprg; CHAR_DATA *victim; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "MProg stat whom?\n\r", ch ); return; } if ( ( victim = get_char_world( ch, arg ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( !IS_NPC( victim ) ) { send_to_char( "Only Mobiles can have MobPrograms!\n\r", ch); return; } if ( xIS_EMPTY(victim->pIndexData->progtypes) ) { send_to_char( "That Mobile has no Programs set.\n\r", ch); return; } ch_printf( ch, "Name: %s. Vnum: %d.\n\r", victim->name, victim->vnum ); ch_printf( ch, "Short description: %s.\n\rLong description: %s", victim->short_descr, victim->long_descr[0] != '\0' ? victim->long_descr : "(none).\n\r" ); ch_printf( ch, "Hp: %d/%d. Mana: %d/%d. Move: %d/%d. \n\r", GET_HIT(victim), GET_MAX_HIT(victim), GET_MANA(victim), GET_MAX_MANA(victim), GET_MOVE(victim), GET_MAX_MOVE(victim) ); ch_printf( ch, "Lv: %s. Class: %s. Align: %d. AC: %d. Exp: %d.\n\r", GetLevelString(victim), GetClassString(victim), victim->alignment, GET_AC( victim ), GET_EXP(victim) ); for ( mprg = victim->pIndexData->mudprogs; mprg; mprg = mprg->next ) ch_printf( ch, ">%s %s\n\r%s\n\r", mprog_type_to_name( mprg->progtype ), mprg->arglist, mprg->comlist ); return; } /* Opstat - Scryn 8/12*/ void do_opstat( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; MPROG_DATA *mprg; OBJ_DATA *obj; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "OProg stat what?\n\r", ch ); return; } if ( ( obj = get_obj_world( ch, arg ) ) == NULL ) { send_to_char( "You cannot find that.\n\r", ch ); return; } if ( xIS_EMPTY(obj->pIndexData->progtypes) ) { send_to_char( "That object has no programs set.\n\r", ch); return; } ch_printf( ch, "Name: %s. Vnum: %d.\n\r", obj->name, obj->vnum ); ch_printf( ch, "Short description: %s.\n\r", obj->short_descr ); for ( mprg = obj->pIndexData->mudprogs; mprg; mprg = mprg->next ) ch_printf( ch, ">%s %s\n\r%s\n\r", mprog_type_to_name( mprg->progtype ), mprg->arglist, mprg->comlist ); return; } /* Rpstat - Scryn 8/12 */ void do_rpstat( CHAR_DATA *ch, char *argument ) { MPROG_DATA *mprg; if ( xIS_EMPTY(ch->in_room->progtypes) ) { send_to_char( "This room has no programs set.\n\r", ch); return; } ch_printf( ch, "Name: %s. Vnum: %d.\n\r", ch->in_room->name, ch->in_room->vnum ); for ( mprg = ch->in_room->mudprogs; mprg; mprg = mprg->next ) ch_printf( ch, ">%s %s\n\r%s\n\r", mprog_type_to_name( mprg->progtype ), mprg->arglist, mprg->comlist ); return; } /* Drops absolutely w/o messages. */ void do_mpdrop( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; if (!ch ) { bug("Nonexistent ch in do_mpdrop!"); return; } if ( charm_order_check(ch) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } if ( argument[0] == '\0' ) { progbug( "Mpdrop - No argument", ch ); return; } if ((obj = get_obj_carry(ch, argument)) == NULL) return; separate_obj(obj); obj_from_char(obj); obj = obj_to_room(obj, ch->in_room); return; } /* Prints the argument to all the rooms around the mobile */ void do_mpasound( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *was_in_room; EXIT_DATA *pexit; int actflags; if (!ch ) { bug("Nonexistent ch in do_mpasound!"); return; } if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } if ( argument[0] == '\0' ) { progbug( "Mpasound - No argument", ch ); return; } actflags = ch->act; REMOVE_BIT(ch->act, ACT_SECRETIVE); was_in_room = ch->in_room; for ( pexit = was_in_room->first_exit; pexit; pexit = pexit->next ) { if ( pexit->to_room && pexit->to_room != was_in_room ) { ch->in_room = pexit->to_room; MOBtrigger = FALSE; act( AT_SAY, argument, ch, NULL, NULL, TO_ROOM ); } } ch->act = actflags; ch->in_room = was_in_room; return; } /* lets the mobile kill any player or mobile without murder*/ void do_mpkill( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; if (!ch ) { bug( "Nonexistent ch in do_mpkill!" ); return; } if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { progbug( "MpKill - no argument", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { progbug( "MpKill - Victim not in room", ch ); return; } if ( victim == ch ) { progbug( "MpKill - Bad victim to attack", ch ); return; } if ( charm_order_check( ch ) && ch->master == victim ) { progbug( "MpKill - Charmed mob attacking master", ch ); return; } if ( ch->position == POS_FIGHTING ) { progbug( "MpKill - Already fighting", ch ); return; } multi_hit( ch, victim, TYPE_UNDEFINED ); return; } /* lets the mobile destroy an object in its inventory it can also destroy a worn object and it can destroy items using all.xxxxx or just plain all of them */ void do_mpjunk( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; OBJ_DATA *obj; OBJ_DATA *obj_next; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] == '\0') { progbug( "Mpjunk - No argument", ch ); return; } if ( str_cmp( arg, "all" ) && str_prefix( "all.", arg ) ) { if ( ( obj = get_obj_wear( ch, arg ) ) != NULL ) { unequip_char( ch, obj ); extract_obj( obj ); return; } if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) return; extract_obj( obj ); } else for ( obj = ch->first_carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if ( arg[3] == '\0' || is_name( &arg[4], obj->name ) ) { if ( obj->wear_loc != WEAR_NONE) unequip_char( ch, obj ); extract_obj( obj ); } } return; } /* * This function examines a text string to see if the first "word" is a * color indicator (e.g. _red, _whi_, _blu). - Gorog */ int get_color(char *argument) /* get color code from command string */ { char color[MAX_INPUT_LENGTH]; char *cptr; static char const * color_list= "_bla_red_dgr_bro_dbl_pur_cya_cha_dch_ora_gre_yel_blu_pin_lbl_whi"; static char const * blink_list= "*bla*red*dgr*bro*dbl*pur*cya*cha*dch*ora*gre*yel*blu*pin*lbl*whi"; one_argument (argument, color); if (color[0]!='_' && color[0]!='*') return 0; if ( (cptr = strstr(color_list, color)) ) return (cptr - color_list) / 4; if ( (cptr = strstr(blink_list, color)) ) return (cptr - blink_list) / 4 + AT_BLINK; return 0; } /* prints the message to everyone */ void do_mpechoall( CHAR_DATA *ch, char *argument ) { if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } echo_to_all(AT_PLAIN, argument, ECHOTAR_ALL); } /* prints the message to everyone in the room other than the mob and victim */ void do_mpechoaround( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; int actflags; sh_int color; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg ); if ( arg[0] == '\0' ) { progbug( "Mpechoaround - No argument", ch ); return; } if ( !( victim=get_char_room( ch, arg ) ) ) { progbug( "Mpechoaround - victim does not exist", ch ); return; } actflags = ch->act; REMOVE_BIT(ch->act, ACT_SECRETIVE); if ( (color = get_color(argument)) ) { argument = one_argument( argument, arg ); act( color, argument, ch, NULL, victim, TO_NOTVICT ); } else act( AT_ACTION, argument, ch, NULL, victim, TO_NOTVICT ); ch->act = actflags; } /* prints message only to victim */ void do_mpechoat( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; int actflags; sh_int color; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg ); if ( arg[0] == '\0' || argument[0] == '\0' ) { progbug( "Mpechoat - No argument", ch ); return; } if ( !( victim = get_char_room( ch, arg ) ) ) { progbug( "Mpechoat - victim does not exist", ch ); return; } actflags = ch->act; REMOVE_BIT(ch->act, ACT_SECRETIVE); if ( (color = get_color(argument)) ) { argument = one_argument( argument, arg ); act( color, argument, ch, NULL, victim, TO_VICT ); } else act( AT_ACTION, argument, ch, NULL, victim, TO_VICT ); ch->act = actflags; } /* prints message to room at large. */ void do_mpecho( CHAR_DATA *ch, char *argument ) { char arg1 [MAX_INPUT_LENGTH]; sh_int color; int actflags; if ( charm_order_check( ch ) ) return; if ( !IS_NPC(ch) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } if ( argument[0] == '\0' ) { progbug( "Mpecho - called w/o argument", ch ); return; } actflags = ch->act; REMOVE_BIT(ch->act, ACT_SECRETIVE); if ( (color = get_color(argument)) ) { argument = one_argument ( argument, arg1 ); act( color, argument, ch, NULL, NULL, TO_ROOM ); } else act( AT_ACTION, argument, ch, NULL, NULL, TO_ROOM ); ch->act = actflags; } /* lets the mobile load an item or mobile. All items are loaded into inventory. you can specify a level with the load object portion as well. */ void do_mpmload( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] == '\0' || !is_number(arg) ) { progbug( "Mpmload - Bad vnum as arg", ch ); return; } if ( ( victim = create_mobile( atoi( arg ) ) ) == NULL ) { progbug( "Mpmload - Bad mob vnum", ch ); return; } char_to_room( victim, ch->in_room ); mprog_birth_trigger(ch, victim); return; } void do_mpoload( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; OBJ_DATA *obj; int timer = 0; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); if ( arg1[0] == '\0' || !is_number( arg1 ) ) { progbug( "Mpoload - Bad syntax", ch ); return; } /* * New feature from Thoric. */ timer = atoi( argument ); if ( timer < 0 ) { progbug( "Mpoload - Bad timer", ch ); return; } if ( ( obj = create_object( atoi( arg1 ) ) ) == NULL ) { progbug( "Mpoload - Bad vnum arg", ch ); return; } obj->timer = timer; if ( CAN_WEAR(obj, ITEM_TAKE) ) obj_to_char( obj, ch ); else obj_to_room( obj, ch->in_room ); return; } /* lets the mobile purge all objects and other npcs in the room, or purge a specified object or mob in the room. It can purge itself, but this had best be the last command in the MUDprogram otherwise ugly stuff will happen */ void do_mppurge( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; OBJ_DATA *obj; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { /* 'purge' */ CHAR_DATA *vnext; for ( victim = ch->in_room->first_person; victim; victim = vnext ) { vnext = victim->next_in_room; if ( IS_NPC( victim ) && victim != ch ) extract_char( victim, TRUE ); } while ( ch->in_room->first_content ) extract_obj( ch->in_room->first_content ); return; } if ( (victim = get_char_room( ch, arg )) == NULL ) { if ( (obj = get_obj_here( ch, arg )) != NULL ) extract_obj( obj ); else progbug( "Mppurge - Bad argument", ch ); return; } if ( !IS_NPC( victim ) ) { progbug( "Mppurge - Trying to purge a PC", ch ); return; } if ( victim == ch ) { progbug( "Mppurge - Trying to purge oneself", ch ); return; } if ( IS_NPC( victim ) && victim->vnum == 3 ) { progbug( "Mppurge: trying to purge supermob", ch ); return; } extract_char( victim, TRUE ); return; } /* Allow mobiles to go wizinvis with programs -- SB */ void do_mpinvis( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; sh_int level; if ( !IS_NPC(ch) || (ch->desc)) { send_to_char( "Huh?\n\r", ch); return; } argument = one_argument( argument, arg ); if ( arg && arg[0] != '\0' ) { if ( !is_number( arg ) ) { progbug( "Mpinvis - Non numeric argument ", ch ); return; } level = atoi( arg ); if ( level < 2 || level > 51 ) { progbug( "MPinvis - Invalid level ", ch ); return; } ch->mobinvis = level; ch_printf( ch, "Mobinvis level set to %d.\n\r", level ); return; } if ( ch->mobinvis < 2 ) ch->mobinvis = GetMaxLevel(ch); if ( IS_SET(ch->act, ACT_MOBINVIS) ) { REMOVE_BIT(ch->act, ACT_MOBINVIS); act(AT_IMMORT, "$n slowly fades into existence.", ch, NULL, NULL,TO_ROOM ); send_to_char( "You slowly fade back into existence.\n\r", ch ); } else { SET_BIT(ch->act, ACT_MOBINVIS); act( AT_IMMORT, "$n slowly fades into thin air.", ch, NULL, NULL, TO_ROOM ); send_to_char( "You slowly vanish into thin air.\n\r", ch ); } return; } /* lets the mobile goto any location it wishes that is not private */ void do_mpgoto( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; ROOM_INDEX_DATA *location; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { progbug( "Mpgoto - No argument", ch ); return; } if ( ( location = find_location( ch, arg ) ) == NULL ) { progbug( "Mpgoto - No such location", ch ); return; } if ( ch->fighting ) stop_fighting( ch, TRUE ); char_from_room( ch ); char_to_room( ch, location ); return; } /* lets the mobile do a command at another location. Very useful */ void do_mpat( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; ROOM_INDEX_DATA *location; ROOM_INDEX_DATA *original; CHAR_DATA *wch; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg ); if ( arg[0] == '\0' || argument[0] == '\0' ) { progbug( "Mpat - Bad argument", ch ); return; } if ( ( location = find_location( ch, arg ) ) == NULL ) { progbug( "Mpat - No such location", ch ); return; } original = ch->in_room; char_from_room( ch ); char_to_room( ch, location ); interpret( ch, argument ); /* * See if 'ch' still exists before continuing! * Handles 'at XXXX quit' case. */ for ( wch = first_char; wch; wch = wch->next ) if ( wch == ch ) { char_from_room( ch ); char_to_room( ch, original ); break; } return; } /* allow a mobile to advance a player's level... very dangerous */ void do_mpadvance( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int level; int iLevel, i; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ch->desc ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg ); if ( arg[0] == '\0' ) { progbug( "Mpadvance - Bad syntax", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { progbug( "Mpadvance - Victim not there", ch ); return; } if ( IS_NPC(victim) ) { progbug( "Mpadvance - Victim is NPC", ch ); return; } if ( GetMaxLevel(victim) >= LEVEL_AVATAR ) return; level = GetMaxLevel(victim) + 1; if ( GetMaxLevel(victim) > GetMaxLevel(ch) ) { act( AT_TELL, "$n tells you, 'Sorry... you must seek someone more powerful than I.'", ch, NULL, victim, TO_VICT ); return; } if (GetMaxLevel(victim) >= LEVEL_AVATAR) { set_char_color( AT_IMMORT, victim ); act( AT_IMMORT, "$n makes some arcane gestures with $s hands, then points $s fingers at you!", ch, NULL, victim, TO_VICT ); act( AT_IMMORT, "$n makes some arcane gestures with $s hands, then points $s fingers at $N!", ch, NULL, victim, TO_NOTVICT ); set_char_color( AT_WHITE, victim ); send_to_char( "You suddenly feel very strange...\n\r\n\r", victim ); set_char_color( AT_LBLUE, victim ); } switch(level) { default: send_to_char( "You feel more powerful!\n\r", victim ); break; case LEVEL_IMMORTAL: do_help(victim, "M_GODLVL1_" ); send_to_char( "You awake... all your possessions are gone.\n\r", victim ); while ( victim->first_carrying ) extract_obj( victim->first_carrying ); break; case LEVEL_ACOLYTE: do_help(victim, "M_GODLVL2_" ); break; case LEVEL_CREATOR: do_help(victim, "M_GODLVL3_" ); break; case LEVEL_SAVIOR: do_help(victim, "M_GODLVL4_" ); break; case LEVEL_DEMI: do_help(victim, "M_GODLVL5_" ); break; case LEVEL_TRUEIMM: do_help(victim, "M_GODLVL6_" ); break; case LEVEL_LESSER: do_help(victim, "M_GODLVL7_" ); break; case LEVEL_GOD: do_help(victim, "M_GODLVL8_" ); break; case LEVEL_GREATER: do_help(victim, "M_GODLVL9_" ); break; case LEVEL_ASCENDANT: do_help(victim, "M_GODLVL10_" ); break; case LEVEL_SUB_IMPLEM: do_help(victim, "M_GODLVL11_" ); break; case LEVEL_IMPLEMENTOR: do_help(victim, "M_GODLVL12_" ); break; case LEVEL_ETERNAL: do_help(victim, "M_GODLVL13_" ); break; case LEVEL_INFINITE: do_help(victim, "M_GODLVL14_" ); break; case LEVEL_SUPREME: do_help(victim, "M_GODLVL15_" ); } for (i = 0; i < MAX_CLASS; ++i) { if (IS_ACTIVE(victim, i) && !HAD_CLASS(ch, i)) { for ( iLevel = GET_LEVEL(victim, i) ; iLevel < level; iLevel++ ) { if (level < LEVEL_IMMORTAL) send_to_char( "You raise a level!! ", victim ); advance_level( victim, i ); } } } victim->exp = 1000 * UMAX( 1, GetMaxLevel(victim) ); victim->trust = 0; return; } /* lets the mobile transfer people. the all argument transfers everyone in the current room to the specified location */ void do_mptransfer( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char buf[MAX_STRING_LENGTH]; ROOM_INDEX_DATA *location; CHAR_DATA *victim; CHAR_DATA *nextinroom; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' ) { progbug( "Mptransfer - Bad syntax", ch ); return; } /* Put in the variable nextinroom to make this work right. -Narn */ if ( !str_cmp( arg1, "all" ) ) { for ( victim = ch->in_room->first_person; victim; victim = nextinroom ) { nextinroom = victim->next_in_room; if ( victim != ch && !NOT_AUTHED(victim) && can_see( ch, victim ) ) { sprintf( buf, "\"%s\" %s", victim->name, arg2 ); do_mptransfer( ch, buf ); } } return; } /* * Thanks to Grodyn for the optional location parameter. */ if ( arg2[0] == '\0' ) { location = ch->in_room; } else { if ( ( location = find_location( ch, arg2 ) ) == NULL ) { progbug( "Mptransfer - No such location", ch ); return; } if ( room_is_private( location ) ) { progbug( "Mptransfer - Private room", ch ); return; } } if ( ( victim = get_char_world( ch, arg1 ) ) == NULL ) { progbug( "Mptransfer - No such person", ch ); return; } if ( !victim->in_room ) { progbug( "Mptransfer - Victim in Limbo", ch ); return; } if (NOT_AUTHED(victim) && location->area != victim->in_room->area) { progbug( "Mptransfer - transferring unauthorized player", ch); return; } /* If victim not in area's level range, do not transfer */ if ( !in_hard_range( victim, location->area ) && !IS_SET( location->room_flags, ROOM_PROTOTYPE ) ) return; if ( victim->fighting ) stop_fighting( victim, TRUE ); char_from_room( victim ); char_to_room( victim, location ); return; } /* lets the mobile force someone to do something. must be mortal level and the all argument only affects those in the room with the mobile */ void do_mpforce( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ch->desc ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg ); if ( arg[0] == '\0' || argument[0] == '\0' ) { progbug( "Mpforce - Bad syntax", ch ); return; } if ( !str_cmp( arg, "all" ) ) { CHAR_DATA *vch; for ( vch = ch->in_room->first_person; vch; vch = vch->next_in_room ) if ( get_trust( vch ) < get_trust( ch ) && can_see( ch, vch ) ) interpret( vch, argument ); } else { CHAR_DATA *victim; if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { progbug( "Mpforce - No such victim", ch ); return; } if ( victim == ch ) { progbug( "Mpforce - Forcing oneself", ch ); return; } if ( !IS_NPC( victim ) && ( !victim->desc ) && IS_IMMORTAL( victim ) ) { progbug( "Mpforce - Attempting to force link dead immortal", ch ); return; } interpret( victim, argument ); } return; } /* * Haus' toys follow: */ /* * syntax: mppractice victim spell_name max% * */ void do_mp_practice( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char arg3[ MAX_INPUT_LENGTH ]; char buf[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; int sn, max, tmp, adept; char *skill_name; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || (ch->desc)) /* security breach, i guess */ { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); if ( arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' ) { send_to_char( "Mppractice: bad syntax", ch ); progbug( "Mppractice - Bad syntax", ch ); return; } if ( ( victim = get_char_room( ch, arg1 ) ) == NULL ) { send_to_char("Mppractice: Student not in room? Invis?", ch); progbug( "Mppractice: Invalid student not in room", ch ); return; } if ( ( sn = skill_lookup( arg2 ) ) < 0 ) { send_to_char("Mppractice: Invalid spell/skill name", ch); progbug( "Mppractice: Invalid spell/skill name", ch ); return; } if(IS_NPC(victim)) { send_to_char("Mppractice: Can't train a mob", ch); progbug("Mppractice: Can't train a mob", ch ); return; } skill_name = skill_table[sn]->name; max = atoi( arg3 ); if( (max<0) || (max>100) ) { sprintf( bug_buf, "mp_practice: Invalid maxpercent: %d", max ); send_to_char( bug_buf, ch); progbug( bug_buf, ch ); return; } if(GetMaxLevel(victim) < skill_table[sn]->skill_level[LowSkCl(ch, sn)]) { sprintf(buf,"$n attempts to tutor you in %s, but it's beyond your comprehension.",skill_name); act( AT_TELL, buf, ch, NULL, victim, TO_VICT ); return; } /* adept is how high the player can learn it */ /* adept = class_table[ch->class]->skill_adept; */ adept = GET_ADEPT(victim,sn); if ( (LEARNED(victim, sn) >= adept ) || (LEARNED(victim, sn) >= max ) ) { sprintf(buf,"$n shows some knowledge of %s, but yours is clearly superior.",skill_name); act( AT_TELL, buf, ch, NULL, victim, TO_VICT ); return; } /* past here, victim learns something */ tmp = UMIN(LEARNED(victim, sn) + int_app[get_curr_int(victim)].learn, max); act( AT_ACTION, "$N demonstrates $t to you. You feel more learned in this subject.", victim, skill_table[sn]->name, ch,TO_CHAR ); victim->pcdata->learned[sn] = max; if ( LEARNED(victim, sn) >= adept ) { victim->pcdata->learned[sn] = adept; act( AT_TELL, "$n tells you, 'You have learned all I know on this subject...'", ch, NULL, victim, TO_VICT ); } return; } /* * syntax: mpslay (character) */ void do_mp_slay( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ch->desc ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); if ( arg1[0] == '\0' ) { send_to_char( "mpslay whom?\n\r", ch ); progbug( "Mpslay: invalid (nonexistent?) argument", ch ); return; } if ( ( victim = get_char_room( ch, arg1 ) ) == NULL ) { send_to_char( "Victim must be in room.\n\r", ch ); progbug( "Mpslay: victim not in room", ch ); return; } if ( victim == ch ) { send_to_char( "You try to slay yourself. You fail.\n\r", ch ); progbug( "Mpslay: trying to slay self", ch ); return; } if ( IS_NPC( victim ) && victim->vnum == 3 ) { send_to_char( "You cannot slay supermob!\n\r", ch ); progbug( "Mpslay: trying to slay supermob", ch ); return; } if( GetMaxLevel(victim) < LEVEL_IMMORTAL) { /* act( AT_IMMORT, "You slay $M in cold blood!", ch, NULL, victim, TO_CHAR); act( AT_IMMORT, "$n slays you in cold blood!", ch, NULL, victim, TO_VICT); act( AT_IMMORT, "$n slays $N in cold blood!", ch, NULL, victim, TO_NOTVICT); */ set_cur_char(victim); raw_kill( ch, victim, TYPE_UNDEFINED ); stop_fighting( ch, FALSE ); stop_hating( ch ); stop_fearing( ch ); stop_hunting( ch ); } else { act( AT_IMMORT, "You attempt to slay $M and fail!", ch, NULL, victim, TO_CHAR); act( AT_IMMORT, "$n attempts to slay you. What a kneebiter!", ch, NULL, victim, TO_VICT); act( AT_IMMORT, "$n attempts to slay $N. Needless to say $e fails.", ch, NULL, victim, TO_NOTVICT); } return; } /* * syntax: mpdamage (character) (#hps) */ void do_mp_damage( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; int dam; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ( ch->desc && get_trust( ch ) < LEVEL_IMMORTAL ) ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' ) { send_to_char( "mpdamage whom?\n\r", ch ); progbug( "Mpdamage: invalid argument1", ch ); return; } if ( arg2[0] == '\0' ) { send_to_char( "mpdamage inflict how many hps?\n\r", ch ); progbug( "Mpdamage: invalid argument2", ch ); return; } if ( ( victim = get_char_room( ch, arg1 ) ) == NULL ) { send_to_char( "Victim must be in room.\n\r", ch ); progbug( "Mpdamage: victim not in room", ch ); return; } if ( victim == ch ) { send_to_char( "You can't mpdamage yourself.\n\r", ch ); progbug( "Mpdamage: trying to damage self", ch ); return; } dam = atoi(arg2); if( (dam<0) || (dam>32000) ) { send_to_char( "Mpdamage how much?\n\r", ch ); progbug( "Mpdamage: invalid (nonexistent?) argument", ch ); return; } /* this is kinda begging for trouble */ /* * Note from Thoric to whoever put this in... * Wouldn't it be better to call damage(ch, ch, dam, dt)? * I hate redundant code */ if ( simple_damage(ch, victim, dam, TYPE_UNDEFINED ) == rVICT_DIED ) { stop_fighting( ch, FALSE ); stop_hating( ch ); stop_fearing( ch ); stop_hunting( ch ); } return; } /* * syntax: mprestore (character) (#hps) Gorog */ void do_mp_restore( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; int hp; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ( ch->desc && get_trust( ch ) < LEVEL_IMMORTAL ) ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' ) { send_to_char( "mprestore whom?\n\r", ch ); progbug( "Mprestore: invalid argument1", ch ); return; } if ( arg2[0] == '\0' ) { send_to_char( "mprestore how many hps?\n\r", ch ); progbug( "Mprestore: invalid argument2", ch ); return; } if ( ( victim = get_char_room( ch, arg1 ) ) == NULL ) { send_to_char( "Victim must be in room.\n\r", ch ); progbug( "Mprestore: victim not in room", ch ); return; } hp = atoi(arg2); if( (hp<0) || (hp>32000) ) { send_to_char( "Mprestore how much?\n\r", ch ); progbug( "Mprestore: invalid (nonexistent?) argument", ch ); return; } hp += GET_HIT(victim); GET_HIT(victim) = (hp > 32000 || hp < 0 || hp > GET_MAX_HIT(victim)) ? GET_MAX_HIT(victim) : hp; } /* * Syntax mpfavor target number * Raise a player's favor in progs. */ void do_mpfavor( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; int favor; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ( ch->desc && get_trust( ch ) < LEVEL_IMMORTAL ) ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' ) { send_to_char( "mpfavor whom?\n\r", ch ); progbug( "Mpfavor: invalid argument1", ch ); return; } if ( arg2[0] == '\0' ) { send_to_char( "mpfavor how much favor?\n\r", ch ); progbug( "Mpfavor: invalid argument2", ch ); return; } if ( ( victim = get_char_room( ch, arg1 ) ) == NULL ) { send_to_char( "Victim must be in room.\n\r", ch ); progbug( "Mpfavor: victim not in room", ch ); return; } favor = atoi(arg2); victim->pcdata->favor = URANGE( -1000, victim->pcdata->favor + favor, 1000 ); } /* * Syntax mp_open_passage x y z * * opens a 1-way passage from room x to room y in direction z * * won't mess with existing exits */ void do_mp_open_passage( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char arg3[ MAX_INPUT_LENGTH ]; ROOM_INDEX_DATA *targetRoom, *fromRoom; int targetRoomVnum, fromRoomVnum, exit_num, flags = EX_PASSAGE; EXIT_DATA *pexit; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ( ch->desc && get_trust( ch ) < LEVEL_IMMORTAL ) ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); if ( arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' ) { progbug( "MpOpenPassage - Bad syntax", ch ); return; } if( !is_number(arg1) ) { progbug( "MpOpenPassage - Bad syntax", ch ); return; } fromRoomVnum = atoi(arg1); if( (fromRoom = get_room_index( fromRoomVnum ) ) ==NULL) { progbug( "MpOpenPassage - Bad syntax", ch ); return; } if( !is_number(arg2) ) { progbug( "MpOpenPassage - Bad syntax", ch ); return; } targetRoomVnum = atoi(arg2); if( (targetRoom = get_room_index( targetRoomVnum ) ) ==NULL) { progbug( "MpOpenPassage - Bad syntax", ch ); return; } if( is_number(arg3) ) exit_num = atoi(arg3); else exit_num = get_dir(arg3); if( (exit_num < 0) || (exit_num >= MAX_REXITS) ) { progbug( "MpOpenPassage - Bad syntax", ch ); return; } if( (pexit = get_exit( fromRoom, exit_num )) != NULL ) { if( !IS_SET( pexit->exit_info, EX_PASSAGE) ) return; progbug( "MpOpenPassage - Exit exists", ch ); return; } if (argument) { int value; while ( argument[0] != '\0' ) { argument = one_argument( argument, arg1 ); value = get_exflag( arg1 ); if ( value < 0 || value > MAX_EXFLAG ) progbug( "MpOpenPassage - Unknown exit flag", ch ); else TOGGLE_BIT( flags, 1 << value ); } } pexit = make_exit( fromRoom, targetRoom, exit_num ); pexit->keyword = STRALLOC( "" ); pexit->description = STRALLOC( "" ); pexit->key = 0; pexit->exit_info = flags; /* act( AT_PLAIN, "A passage opens!", ch, NULL, NULL, TO_CHAR ); */ /* act( AT_PLAIN, "A passage opens!", ch, NULL, NULL, TO_ROOM ); */ return; } /* * Syntax mp_close_passage x y * * closes a passage in room x leading in direction y * * the exit must have EX_PASSAGE set */ void do_mp_close_passage( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char arg3[ MAX_INPUT_LENGTH ]; ROOM_INDEX_DATA *fromRoom; int fromRoomVnum, exit_num; EXIT_DATA *pexit; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ( ch->desc && get_trust( ch ) < LEVEL_IMMORTAL ) ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); if ( arg1[0] == '\0' || arg2[0] == '\0' || arg2[0] == '\0' ) { progbug( "MpClosePassage - Bad syntax", ch ); return; } if( !is_number(arg1) ) { progbug( "MpClosePassage - Bad syntax", ch ); return; } fromRoomVnum = atoi(arg1); if( (fromRoom = get_room_index( fromRoomVnum ) ) ==NULL) { progbug( "MpClosePassage - Bad syntax", ch ); return; } if( is_number(arg2) ) exit_num = atoi(arg2); else exit_num = get_dir(arg2); if( (exit_num < 0) || (exit_num >= MAX_REXITS) ) { progbug( "MpClosePassage - Bad syntax", ch ); return; } if( ( pexit = get_exit(fromRoom, exit_num) ) == NULL ) { return; /* already closed, ignore... so rand_progs */ /* can close without spam */ } if( !IS_SET( pexit->exit_info, EX_PASSAGE) ) { progbug( "MpClosePassage - Exit not a passage", ch ); return; } extract_exit( fromRoom, pexit ); /* act( AT_PLAIN, "A passage closes!", ch, NULL, NULL, TO_CHAR ); */ /* act( AT_PLAIN, "A passage closes!", ch, NULL, NULL, TO_ROOM ); */ return; } /* * Does nothing. Used for scripts. */ void do_mpnothing( CHAR_DATA *ch, char *argument ) { if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ( ch->desc && get_trust( ch ) < LEVEL_IMMORTAL ) ) { send_to_char( "Huh?\n\r", ch ); return; } return; } /* * Sends a message to sleeping character. Should be fun * with room sleep_progs * */ void do_mpdream( CHAR_DATA *ch, char *argument ) { char arg1[MAX_STRING_LENGTH]; CHAR_DATA *vict; if ( charm_order_check( ch ) ) return; if ( !IS_NPC( ch ) || ( ch->desc && get_trust( ch ) < LEVEL_IMMORTAL ) ) { send_to_char( "Huh?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); if ( (vict =get_char_world(ch, arg1)) == NULL ) { progbug( "Mpdream: No such character", ch ); return; } if( vict->position <= POS_SLEEPING) { send_to_char(argument, vict); send_to_char("\n\r", vict); } return; } void do_mpapply( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } if ( charm_order_check( ch ) ) return; if (argument[0] == '\0') { progbug("Mpapply - bad syntax", ch ); return; } if ( (victim = get_char_room( ch, argument ) ) == NULL ) { progbug("Mpapply - no such player in room.", ch ); return; } if ( !victim->desc ) { send_to_char( "Not on linkdeads.\n\r", ch ); return; } if( !NOT_AUTHED(victim) ) return; if( victim->pcdata->auth_state >= 1 ) return; sprintf( log_buf, "%s@%s new %s %s applying for authorization...", victim->name, victim->desc->host, race_table[victim->race].race_name, GetClassString(victim) ); log_string_plus( log_buf,LOG_MONITOR,LEVEL_IMMORTAL,SEV_ALERT); victim->pcdata->auth_state = 1; return; } void do_mpapplyb( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if ( !IS_NPC( ch ) || (ch->desc)) { send_to_char( "Huh?\n\r", ch ); return; } if ( charm_order_check( ch ) ) return; if (argument[0] == '\0') { progbug("Mpapplyb - bad syntax", ch ); return; } if ( (victim = get_char_room( ch, argument ) ) == NULL ) { progbug("Mpapplyb - no such player in room.", ch ); return; } if ( !victim->desc ) { send_to_char( "Not on linkdeads.\n\r", ch ); return; } if( !NOT_AUTHED(victim) ) return; if ( get_timer(victim, TIMER_APPLIED) >= 1) return; switch( victim->pcdata->auth_state ) { case 0: case 1: default: send_to_char( "You attempt to regain the gods' attention.\n\r", victim); sprintf( log_buf, "%s@%s new %s %s applying for authorization...", victim->name, victim->desc->host, race_table[victim->race].race_name, GetClassString(victim) ); log_string_plus( log_buf,LOG_MONITOR,LEVEL_IMMORTAL,SEV_ALERT); add_timer(victim, TIMER_APPLIED, 10, NULL, 0); victim->pcdata->auth_state = 1; break; case 2: send_to_char("Your name has been deemed unsuitable by the gods. Please choose a more medieval name with the 'name' command.\n\r", victim); add_timer(victim, TIMER_APPLIED, 10, NULL, 0); break; case 3: { char buf[MAX_INPUT_LENGTH]; sprintf(buf, "The gods permit you to enter the %s.\n\r", MUD_NAME); send_to_char(buf,victim); REMOVE_BIT(victim->pcdata->flags, PCFLAG_UNAUTHED); if ( victim->fighting ) stop_fighting( victim, TRUE ); char_from_room(victim); char_to_room(victim, get_room_index(ROOM_VNUM_SCHOOL)); act( AT_WHITE, "$n enters this world from within a column of blinding light!", victim, NULL, NULL, TO_ROOM ); do_look(victim, "auto"); } break; } return; } /* * Deposit some gold into the current area's economy -Thoric */ void do_mp_deposit( CHAR_DATA *ch, char *argument ) { char arg[MAX_STRING_LENGTH]; int money; if ( !IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; one_argument(argument, arg); if ( arg[0] == '\0' ) { progbug("Mpdeposit - bad syntax", ch ); return; } money = atoi( arg ); if ( money <= GET_MONEY(ch,DEFAULT_CURR) && ch->in_room ) { GET_MONEY(ch,DEFAULT_CURR) -= money; boost_economy( ch->in_room->area, money, DEFAULT_CURR ); } } /* * Withdraw some money from the current area's economy -Thoric */ void do_mp_withdraw( CHAR_DATA *ch, char *argument ) { char arg[MAX_STRING_LENGTH]; int money; if ( !IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; one_argument(argument, arg); if ( arg[0] == '\0' ) { progbug("Mpwithdraw - bad syntax", ch ); return; } money = atoi( arg ); if ( GET_MONEY(ch,DEFAULT_CURR) < 1000000000 && money < 1000000000 && ch->in_room && economy_has( ch->in_room->area, money, DEFAULT_CURR ) ) { GET_MONEY(ch,DEFAULT_CURR) += money; lower_economy( ch->in_room->area, money, DEFAULT_CURR ); } } void do_mppkset( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; char arg[MAX_STRING_LENGTH]; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; argument = one_argument(argument, arg); if (argument[0] == '\0' || arg[0] == '\0') { progbug("Mppkset - bad syntax", ch ); return; } if ( (victim = get_char_room( ch, arg ) ) == NULL ) { progbug("Mppkset - no such player in room.", ch ); return; } if (!str_cmp(argument, "yes") || !str_cmp(argument, "y")) { if(!IS_SET(victim->pcdata->flags, PCFLAG_DEADLY)) SET_BIT(victim->pcdata->flags, PCFLAG_DEADLY); } else if (!str_cmp(argument, "no") || !str_cmp(argument, "n")) { if(IS_SET(victim->pcdata->flags, PCFLAG_DEADLY)) REMOVE_BIT(victim->pcdata->flags, PCFLAG_DEADLY); } else { progbug("Mppkset - bad syntax", ch); return; } } /* * Inflict damage from a mudprogram * * note: should be careful about using victim afterwards */ ch_ret simple_damage( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt ) { sh_int dameq; bool npcvict; OBJ_DATA *damobj; ch_ret retcode; retcode = rNONE; if ( !ch ) { bug( "Damage: null ch!" ); return rERROR; } if ( !victim ) { progbug( "Damage: null victim!", ch ); return rVICT_DIED; } if ( victim->position == POS_DEAD ) { return rVICT_DIED; } npcvict = IS_NPC(victim); if ( dam ) { if ( IS_FIRE(dt) ) dam = ris_damage(victim, dam, RIS_FIRE); else if ( IS_COLD(dt) ) dam = ris_damage(victim, dam, RIS_COLD); else if ( IS_ACID(dt) ) dam = ris_damage(victim, dam, RIS_ACID); else if ( IS_ELECTRICITY(dt) ) dam = ris_damage(victim, dam, RIS_ELECTRICITY); else if ( IS_ENERGY(dt) ) dam = ris_damage(victim, dam, RIS_ENERGY); else if ( dt == gsn_poison ) dam = ris_damage(victim, dam, RIS_POISON); else if ( dt == (TYPE_HIT + 7) || dt == (TYPE_HIT + 8) ) dam = ris_damage(victim, dam, RIS_BLUNT); else if ( dt == (TYPE_HIT + 2) || dt == (TYPE_HIT + 11) ) dam = ris_damage(victim, dam, RIS_PIERCE); else if ( dt == (TYPE_HIT + 1) || dt == (TYPE_HIT + 3) ) dam = ris_damage(victim, dam, RIS_SLASH); if ( dam < 0 ) dam = 0; } if ( victim != ch ) { /* * Damage modifiers. */ if ( IS_AFFECTED(victim, AFF_SANCTUARY) ) dam /= 2; if ( IS_AFFECTED(victim, AFF_PROTECT) && IS_EVIL(ch) ) dam -= (int) (dam / 4); if ( dam < 0 ) dam = 0; /* dam_message( ch, victim, dam, dt ); */ } /* * Check for EQ damage.... ;) */ if (dam > 10) { /* get a random body eq part */ dameq = number_range(WEAR_LIGHT, MAX_WEAR-1); damobj = get_eq_char(victim, dameq); if ( damobj ) { if ( dam > get_obj_resistance(damobj) ) { damage_obj(damobj); } } } /* * Hurt the victim. * Inform the victim of his new state. */ GET_HIT(victim) -= dam; if ( !IS_NPC(victim) && GetMaxLevel(victim) >= LEVEL_IMMORTAL && GET_HIT(victim) < 1 ) GET_HIT(victim) = GET_MAX_HIT(victim); if ( !npcvict && get_trust(victim) >= LEVEL_IMMORTAL && get_trust(ch) >= LEVEL_IMMORTAL && GET_HIT(victim) < 1 ) GET_HIT(victim) = GET_MAX_HIT(victim); update_pos( victim ); switch( victim->position ) { case POS_MORTAL: act( AT_DYING, "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM ); act( AT_DANGER, "You are mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_CHAR ); break; case POS_INCAP: act( AT_DYING, "$n is incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_ROOM ); act( AT_DANGER, "You are incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_CHAR ); break; case POS_STUNNED: if ( !IS_AFFECTED( victim, AFF_PARALYSIS ) ) { act( AT_ACTION, "$n is stunned, but will probably recover.", victim, NULL, NULL, TO_ROOM ); act( AT_HURT, "You are stunned, but will probably recover.", victim, NULL, NULL, TO_CHAR ); } break; case POS_DEAD: act( AT_DEAD, "$n is DEAD!!", victim, 0, 0, TO_ROOM ); act( AT_DEAD, "You have been KILLED!!\n\r", victim, 0, 0, TO_CHAR ); break; default: if ( dam > GET_MAX_HIT(victim) / 4 ) act( AT_HURT, "That really did HURT!", victim, 0, 0, TO_CHAR ); if ( GET_HIT(victim) < GET_MAX_HIT(victim) / 4 ) act( AT_DANGER, "You wish that your wounds would stop BLEEDING so much!", victim, 0, 0, TO_CHAR ); break; } /* * Payoff for killing things. */ if ( victim->position == POS_DEAD ) { if ( !npcvict ) { sprintf( log_buf, "%s killed by %s at %d", victim->name, (IS_NPC(ch) ? ch->short_descr : ch->name), victim->in_room->vnum ); log_string_plus( log_buf,LOG_MONITOR,LEVEL_IMMORTAL,SEV_CRIT); /* * Dying penalty: * 1/2 way back to previous level. */ if ( victim->exp > exp_level(victim, GetMaxLevel(victim), GetMaxClass(victim)) ) gain_exp( victim, (exp_level(victim, GetMaxLevel(victim), GetMaxClass(victim)) - victim->exp)/2 ); } set_cur_char(victim); raw_kill( ch, victim, dt ); victim = NULL; return rVICT_DIED; } if ( victim == ch ) return rNONE; /* * Take care of link dead people. */ if ( !npcvict && !victim->desc ) { if ( number_range( 0, victim->wait ) == 0 ) { do_recall( victim, "" ); return rNONE; } } /* * Wimp out? */ if ( npcvict && dam > 0 ) { if ( ( IS_SET(victim->act, ACT_WIMPY) && number_bits( 1 ) == 0 && GET_HIT(victim) < GET_MAX_HIT(victim) / 2 ) || ( IS_AFFECTED(victim, AFF_CHARM) && victim->master && victim->master->in_room != victim->in_room ) ) { start_fearing( victim, ch ); stop_hunting( victim ); do_flee( victim, "" ); } } if ( !npcvict && GET_HIT(victim) > 0 && GET_HIT(victim) <= victim->wimpy && victim->wait == 0 ) do_flee( victim, "" ); else if ( !npcvict && IS_SET( victim->act, PLR_FLEE ) ) do_flee( victim, "" ); tail_chain( ); return rNONE; } void do_mppeace( CHAR_DATA *ch, char *argument ) { CHAR_DATA *rch; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; for ( rch = ch->in_room->first_person; rch; rch = rch->next_in_room ) { if ( rch->fighting ) { stop_fighting( rch, TRUE ); do_sit( rch, "" ); } /* Added by Narn, Nov 28/95 */ stop_hating( rch ); stop_hunting( rch ); stop_fearing( rch ); } return; } void do_mpdispel( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; AFFECT_DATA *paf; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; if ( !*argument ) { progbug( "Mpdispel whom?", ch ); return; } if ( ( victim = get_char_world( ch, argument ) ) == NULL ) { progbug( "Mpdispel - No such person", ch ); return; } while ((paf = victim->first_affect)) affect_remove(victim, paf); } void do_mpexp( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int gain; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; argument = one_argument( argument, arg ); if ( arg[0] == '\0' ) { progbug( "Mpexp whom?", ch ); return; } if ( ( victim = get_char_world( ch, arg ) ) == NULL ) { progbug( "Mpexp - No such person", ch ); return; } gain = atoi(argument); if (gain == 0) { progbug( "Mpexp - gain is zero", ch ); return; } gain_exp(victim, gain); } void do_mpsetvar( CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH]; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; argument = one_argument(argument, arg); if ( arg[0] == '\0' ) { progbug( "Mpsetvar whom?", ch ); return; } if ( !argument || !*argument ) { progbug( "Mpsetvar what variable?", ch ); return; } sprintf(buf, "\"%s\" set %s", arg, argument); do_variables(ch, buf); } void do_mpdelvar( CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH]; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; argument = one_argument(argument, arg); if ( arg[0] == '\0' ) { progbug( "Mpdelvar whom?", ch ); return; } if ( !argument || !*argument ) { progbug( "Mpdelvar what variable?", ch ); return; } sprintf(buf, "\"%s\" del %s", arg, argument); do_variables(ch, buf); } void do_mpmodvar( CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH]; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; argument = one_argument(argument, arg); if ( arg[0] == '\0' ) { progbug( "Mpmodvar whom?", ch ); return; } if ( !argument || !*argument ) { progbug( "Mpdelvar what variable and how?", ch ); return; } sprintf(buf, "\"%s\" mod %s", arg, argument); do_variables(ch, buf); } void do_mpmtransform( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim, *newmob; OBJ_DATA *obj; sh_int loc; char arg[MAX_INPUT_LENGTH]; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; argument = one_argument(argument, arg); if ( arg[0] == '\0' ) { progbug( "Mpmtransform whom?", ch ); return; } if ((victim = get_char_world(ch, arg)) == NULL) { progbug( "Mpmtransform - No such person", ch ); return; } if (!IS_NPC(victim) || IS_ACT_FLAG(victim, ACT_POLYMORPHED)) { progbug( "Mpmtrnasform - Can't do this to a PC", ch ); return; } if (!(newmob = create_mobile(atoi(argument)))) { progbug( "Mpmtransform - Bad mob vnum", ch ); return; } while ((obj = victim->first_carrying)) { loc = obj->wear_loc; obj_from_char(obj); obj_to_char(obj, newmob); if (loc && obj->carried_by == newmob) equip_char(newmob, obj, loc); if (obj->carried_by != newmob) progbug( "Mpmtransform - obj not carried by new mob", ch ); } newmob->leader = victim->leader; newmob->master = victim->master; if (IS_ACT_FLAG(victim, ACT_PET)) SET_ACT_FLAG(victim, ACT_PET); if (IS_ACT_FLAG(victim, ACT_MOUNTED)) { CHAR_DATA *mounter; for (mounter = first_char; mounter; mounter = mounter->next) if (mounter->mount == victim) { mounter->mount = newmob; SET_ACT_FLAG(newmob, ACT_MOUNTED); break; } if (!IS_ACT_FLAG(newmob, ACT_MOUNTED)) progbug( "Mpmtransform - could not find mounter for new mob", ch ); } victim->leader = NULL; victim->master = NULL; char_to_room(newmob, victim->in_room); extract_char(victim, TRUE); } void do_mpotransform( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; char arg[MAX_INPUT_LENGTH]; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; argument = one_argument(argument, arg); if ( arg[0] == '\0' ) { progbug( "Mpotransform what?", ch ); return; } if ( ( obj = get_obj_world( ch, arg ) ) == NULL ) { progbug( "Mpotransform - No such object", ch ); return; } } void do_mphate( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; if ( !argument || argument[0] == '\0' ) { progbug( "Mphate whom?", ch ); return; } if ( !str_cmp(argument, "nobody") ) { if (ch->hating) stop_hating(ch); return; } if ( ( victim = get_char_world( ch, argument ) ) == NULL ) { progbug( "Mphate - No such person", ch ); return; } if (ch->hating) stop_hating(ch); start_hating(ch, victim); } void do_mpfear( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; if ( !argument || argument[0] == '\0' ) { progbug( "Mpfear whom?", ch ); return; } if ( !str_cmp(argument, "nobody") ) { if (ch->fearing) stop_fearing(ch); return; } if ( ( victim = get_char_world( ch, argument ) ) == NULL ) { progbug( "Mpfear - No such person", ch ); return; } if (ch->fearing) stop_fearing(ch); start_fearing(ch, victim); } void do_mphunt( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if (!IS_NPC(ch) || (ch->desc)) { send_to_char("Huh?\n\r", ch); return; } if ( charm_order_check( ch ) ) return; if ( !argument || argument[0] == '\0' ) { progbug( "Mphunt whom?", ch ); return; } if ( !str_cmp(argument, "nobody") ) { if (ch->hunting) stop_hunting(ch); return; } if ( ( victim = get_char_world( ch, argument ) ) == NULL ) { progbug( "Mphunt - No such person", ch ); return; } if (ch->hunting) stop_hunting(ch); start_hunting(ch, victim); }