/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************/
/***************************************************************************
* The MOBprograms have been contributed by N'Atas-ha. Any support for *
* these routines should not be expected from Merc Industries. However, *
* under no circumstances should the blame for bugs, etc be placed on *
* Merc Industries. They are not guaranteed to work on all systems due *
* to their frequent use of strxxx functions. They are also not the most *
* efficient way to perform their tasks, but hopefully should be in the *
* easiest possible way to install and begin using. Documentation for *
* such installation can be found in INSTALL. Enjoy........ N'Atas-Ha *
***************************************************************************/
/***************************************************************************
* do_mpremember(), do_mpforget(), and do_mptrack() added by Zak of the *
* EmberMUD coding team. EmberMUD improvements on ROM 2.3 base code are *
* Copyright 1996 by the EmberMUD development team. See EmberMUD.license. *
***************************************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "interp.h"
/*
* Local functions.
*/
char * mprog_type_to_name args( ( int type ) );
/* This routine transfers between alpha and numeric forms of the
* mud_prog bitvector types. It allows the words to show up in mpstat to
* make it just a hair bit easier to see what a mob should be doing.
*/
char *mprog_type_to_name( 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 FIGHTGROUP_PROG: return "fightgroup_prog";
case HIT_PROG: return "hit_prog";
case HITPRCNT_PROG: return "hitprcnt_prog";
case DEATH_PROG: return "death_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 LEAVE_PROG: return "leave_prog";
case SLEEP_PROG: return "sleep_prog";
case REST_PROG: return "rest_prog";
case WEAR_PROG: return "wear_prog";
case REMOVE_PROG: return "remove_prog";
case SAC_PROG: return "sac_prog";
case EXA_PROG: return "examine_prog";
case LOOK_PROG: return "look_prog";
case ZAP_PROG: return "zap_prog";
case GET_PROG: return "get_prog";
case DROP_PROG: return "drop_prog";
case USE_PROG: return "use_prog";
case COMMAND_PROG: return "command_prog";
default: return "ERROR_PROG";
}
}
/* do_mobstat: Show the mudprogs on a given mob.
* argument can be a vnum or a mob name. */
void do_mobstat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
MPROG_LIST *pList;
MPROG_LIST *pInnerList;
MPROG_GROUP_LIST *pGroupList;
MPROG_DATA *mprg;
MOB_INDEX_DATA *pMob = NULL;
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim = NULL;
int iFound;
*buf = '\0';
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "MudProg stat whom?\n\r", ch );
return;
}
if( !is_number(arg) )
{
victim = get_char_world(ch,argument);
if (victim)
pMob = victim->pIndexData;
else
{
send_to_char("No such creature.\n\r", ch);
return;
}
}
else if( ( pMob = get_mob_index( atoi(arg) ) ) == NULL )
{
send_to_char( "No such creature.\n\r", ch );
return;
}
if ( pMob )
{
if (!(pMob->progtypes))
{
send_to_char( "That Mobile has no Programs set.\n\r", ch);
return;
}
sprintf(buf,"`WName: `w%s`w. `WVnum: `w%d`w.\n\r",
pMob->player_name,pMob->vnum);
strcat(buf,"`K------------------------------------------------------`w\n\r");
send_to_char(buf, ch);
for ( pGroupList = pMob->mprog_groups; pGroupList; pGroupList = pGroupList->next )
show_mpgroup(ch, pGroupList->mprog_group);
for ( pList = pMob->mudprogs; pList; pList = pList->next )
{
mprg = pList->mudprog;
iFound = 0;
for ( pGroupList = pMob->mprog_groups; pGroupList; pGroupList = pGroupList->next )
for ( pInnerList = pGroupList->mprog_group->mudprogs; pInnerList;
pInnerList = pInnerList->next )
if ( pInnerList->mudprog->vnum == mprg->vnum )
iFound = 1;
if ( !iFound )
show_mprog(ch, mprg);
}
}
else
{
send_to_char("No such creature.\n\r",ch);
return;
}
}
void do_roomstat( CHAR_DATA *ch, char *argument )
{
char buf [MAX_STRING_LENGTH];
char arg [MAX_INPUT_LENGTH];
MPROG_DATA *mprg;
MPROG_LIST *pList;
MPROG_LIST *pInnerList;
MPROG_GROUP_LIST *pGroupList;
ROOM_INDEX_DATA *location = NULL;
int iFound;
one_argument( argument, arg );
location = ( !arg[0] ) ? ch->in_room : find_location( ch, arg );
if ( !location )
{
send_to_char( "No such location.\n\r", ch );
return;
}
if ( ch->in_room != location
&& room_is_private( location )
&& get_trust(ch) < MAX_LEVEL )
{
send_to_char( "That room is private right now.\n\r", ch );
return;
}
if ( !location->progtypes )
{
send_to_char( "That Room has no Programs set.\n\r", ch);
return;
}
sprintf(buf,"`WName: `w%s`w.\n\r`WArea: `w%s.\n\r",
location->name, location->area->name);
send_to_char(buf,ch);
sprintf(buf,"`WVnum: `w%d. `WSector: `w%d. `WLight: `w%d.\n\r",
location->vnum, location->sector_type, location->light);
send_to_char(buf,ch);
sprintf(buf,"`WRoom Flags: `w%d.\n\r",
location->room_flags);
send_to_char(buf,ch);
send_to_char("`K-------------------------------------------------------------------------------`w\n\r",ch);
*buf = '\0';
for ( pGroupList = location->mprog_groups; pGroupList; pGroupList = pGroupList->next )
show_mpgroup(ch, pGroupList->mprog_group);
for ( pList = location->mudprogs; pList; pList = pList->next )
{
mprg = pList->mudprog;
iFound = 0;
for ( pGroupList = location->mprog_groups; pGroupList; pGroupList = pGroupList->next )
for ( pInnerList = pGroupList->mprog_group->mudprogs; pInnerList;
pInnerList = pInnerList->next )
if ( pInnerList->mudprog->vnum == mprg->vnum )
iFound = 1;
if ( !iFound )
show_mprog(ch, mprg);
}
return;
}
void do_objstat( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
MPROG_DATA *mprg;
MPROG_LIST *pList;
MPROG_LIST *pInnerList;
MPROG_GROUP_LIST *pGroupList;
OBJ_DATA *obj = NULL;
OBJ_INDEX_DATA *oIndex = NULL;
int iFound;
*buf = '\0';
one_argument( argument, arg );
if ( !arg[0] )
{
send_to_char( "OProg stat what?\n\r", ch );
return;
}
if ( !is_number(arg) )
{
obj = get_obj_world(ch,argument);
if (obj)
oIndex = obj->pIndexData;
else
{
send_to_char("No such object.\n\r",ch);
return;
}
}
else
{
if ( (oIndex=get_obj_index( atoi(arg) ) ) == NULL )
{
send_to_char( "No such object.\n\r",ch );
return;
}
}
if (oIndex)
{
if (!oIndex->progtypes)
{
send_to_char("That object has no programs set.\n\r",ch);
return;
}
sprintf(buf,"`WName: `w%s`w. `WVnum: `w%d`w.\n\r",
oIndex->name, oIndex->vnum);
strcat(buf,"`K--------------------------------------------------------------------------------`w\n\r");
send_to_char(buf, ch);
for ( pGroupList = oIndex->mprog_groups; pGroupList; pGroupList = pGroupList->next )
show_mpgroup(ch, pGroupList->mprog_group);
for ( pList = oIndex->mudprogs; pList; pList = pList->next )
{
mprg = pList->mudprog;
iFound = 0;
for ( pGroupList = oIndex->mprog_groups; pGroupList; pGroupList = pGroupList->next )
for ( pInnerList = pGroupList->mprog_group->mudprogs; pInnerList;
pInnerList = pInnerList->next )
if ( pInnerList->mudprog->vnum == mprg->vnum )
iFound = 1;
if ( !iFound )
show_mprog(ch, mprg);
}
}
else
{
send_to_char("No such object.\n\r",ch);
return;
}
}
void do_mpstat( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
char *string;
OBJ_DATA *obj = NULL;
ROOM_INDEX_DATA *location = NULL;
CHAR_DATA *victim = NULL;
string = one_argument( argument, arg );
if ( !arg[0] )
{
send_to_char( "Syntax:\n\r", ch );
send_to_char( " mpstat obj <name> OR mpstat obj <vnum>\n\r", ch );
send_to_char( " mpstat mob <name> OR mpstat mob <vnum>\n\r", ch );
send_to_char( " mpstat room OR mpstat room <vnum>\n\r", ch );
return;
}
/* view a mob prog */
if ( !str_cmp( arg, "mob" ) )
{
do_mobstat( ch, string );
return;
}
/* view a room prog */
if ( !str_cmp( arg, "room" ) )
{
do_roomstat( ch, string );
return;
}
/* view an obj prog */
if ( !str_cmp( arg, "obj" ) )
{
do_objstat( ch, string );
return;
}
/* do it the old way */
victim = get_char_world(ch,argument);
if (victim != NULL)
{
do_mobstat(ch,argument);
return;
}
obj = get_obj_world(ch,argument);
if (obj != NULL)
{
do_objstat(ch,argument);
return;
}
location = find_location(ch,argument);
if (location != NULL)
{
do_roomstat(ch,argument);
return;
}
send_to_char("Nothing by that name found anywhere.\n\r",ch);
}
/* prints the argument to all the rooms aroud the mobile */
void do_mpasound( CHAR_DATA *ch, char *argument )
{
ROOM_INDEX_DATA *was_in_room;
int door;
if ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
if ( argument[0] == '\0' )
{
bug( "Mpasound - No argument: vnum %d.", ch->pIndexData->vnum );
return;
}
was_in_room = ch->in_room;
for ( door = 0; door <= 5; door++ )
{
EXIT_DATA *pexit;
if ( ( pexit = was_in_room->exit[door] ) != NULL
&& pexit->u1.to_room != NULL
&& pexit->u1.to_room != was_in_room )
{
ch->in_room = pexit->u1.to_room;
MOBtrigger = FALSE;
act( argument, ch, NULL, NULL, TO_ROOM );
}
}
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 ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
bug( "MpKill - no argument: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
bug( "MpKill - Victim not in room: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( victim == ch )
{
bug( "MpKill - Bad victim to attack: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim )
{
bug( "MpKill - Charmed mob attacking master: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( ch->position == POS_FIGHTING )
{
bug( "MpKill - Already fighting: vnum %d",
ch->pIndexData->vnum );
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 ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0')
{
bug( "Mpjunk - No argument: vnum %d.", ch->pIndexData->vnum );
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->carrying; obj != NULL; 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;
}
/* 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;
if ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
bug( "Mpechoaround - No argument: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( !( victim=get_char_room( ch, arg ) ) )
{
bug( "Mpechoaround - victim does not exist: vnum %d.",
ch->pIndexData->vnum );
return;
}
act( argument, ch, NULL, victim, TO_NOTVICT );
return;
}
/* prints the message to only the victim */
void do_mpechoat( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
if ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' || argument[0] == '\0' )
{
bug( "Mpechoat - No argument: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( !( victim = get_char_room( ch, arg ) ) )
{
bug( "Mpechoat - victim does not exist: vnum %d.",
ch->pIndexData->vnum );
return;
}
act( argument, ch, NULL, victim, TO_VICT );
return;
}
/* prints the message to the room at large */
void do_mpecho( CHAR_DATA *ch, char *argument )
{
if ( !IS_NPC(ch) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
if ( argument[0] == '\0' )
{
bug( "Mpecho - called w/o argument: vnum %d.",
ch->pIndexData->vnum );
return;
}
act( argument, ch, NULL, NULL, TO_ROOM );
return;
}
/* 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];
MOB_INDEX_DATA *pMobIndex;
CHAR_DATA *victim;
if ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' || !is_number(arg) )
{
bug( "Mpmload - Bad vnum as arg: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( ( pMobIndex = get_mob_index( atoi( arg ) ) ) == NULL )
{
bug( "Mpmload - Bad mob vnum: vnum %d.", ch->pIndexData->vnum );
return;
}
victim = create_mobile( pMobIndex );
char_to_room( victim, ch->in_room );
return;
}
void do_mpoload( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
char arg2[ MAX_INPUT_LENGTH ];
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *obj;
int level;
if ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
argument = one_argument( argument, arg2 );
if ( arg[0] == '\0' || !is_number( arg ) )
{
bug( "Mpoload - Bad syntax: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( arg2[0] == '\0' )
{
level = get_trust( ch );
}
else
{
/*
* New feature from Alander.
*/
if ( !is_number( arg2 ) )
{
bug( "Mpoload - Bad syntax: vnum %d.", ch->pIndexData->vnum );
return;
}
level = atoi( arg2 );
if ( level < 0 || level > get_trust( ch ) )
{
bug( "Mpoload - Bad level: vnum %d.", ch->pIndexData->vnum );
return;
}
}
if ( ( pObjIndex = get_obj_index( atoi( arg ) ) ) == NULL )
{
bug( "Mpoload - Bad vnum arg: vnum %d.", ch->pIndexData->vnum );
return;
}
obj = create_object( pObjIndex, level );
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 MudProg
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 ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
/* 'purge' */
CHAR_DATA *vnext;
OBJ_DATA *obj_next;
for ( victim = ch->in_room->people; victim != NULL; victim = vnext )
{
vnext = victim->next_in_room;
if ( IS_NPC( victim ) && victim != ch )
extract_char( victim, TRUE );
}
for ( obj = ch->in_room->contents; obj != NULL; obj = obj_next )
{
obj_next = obj->next_content;
extract_obj( obj );
}
return;
}
if ( !( victim = get_char_room( ch, arg ) ) == '\0' )
{
if ( ( obj = get_obj_here( ch, arg ) ) )
{
extract_obj( obj );
}
else
{
bug( "Mppurge - Bad argument: vnum %d.", ch->pIndexData->vnum );
}
return;
}
if ( !IS_NPC( victim ) )
{
bug( "Mppurge - Purging a PC: vnum %d.", ch->pIndexData->vnum );
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))
{
send_to_char( "Huh?\n\r", ch);
return;
}
argument = one_argument( argument, arg );
if ( arg && arg[0] != '\0' )
{
if ( !is_number( arg ) )
{
bug( "Mpinvis - Non numeric argument ", ch );
return;
}
level = atoi( arg );
if ( level < 2 || level > MAX_LEVEL )
{
bug( "MPinvis - Invalid level ", ch );
return;
}
ch->mobinvis = level;
printf_to_char( ch, "Mobinvis level set to %d.\n\r", level );
return;
}
if ( ch->mobinvis < 2 )
ch->mobinvis = ch->level;
if ( IS_SET(ch->act, ACT_MOBINVIS) )
{
REMOVE_BIT(ch->act, ACT_MOBINVIS);
act("$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( "$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 ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
bug( "Mpgoto - No argument: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( ( location = find_location( ch, arg ) ) == NULL )
{
bug( "Mpgoto - No such location: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( ch->fighting != NULL )
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 ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' || argument[0] == '\0' )
{
bug( "Mpat - Bad argument: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( ( location = find_location( ch, arg ) ) == NULL )
{
bug( "Mpat - No such location: vnum %d.", ch->pIndexData->vnum );
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 = char_list; wch != NULL; wch = wch->next )
{
if ( wch == ch )
{
char_from_room( ch );
char_to_room( ch, original );
break;
}
}
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 arg[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
char arg2[ MAX_INPUT_LENGTH ];
ROOM_INDEX_DATA *location;
DESCRIPTOR_DATA *d;
CHAR_DATA *victim;
if ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
argument = one_argument( argument, arg2 );
if ( arg[0] == '\0' )
{
bug( "Mptransfer - Bad syntax: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( !str_cmp( arg, "all" ) )
{
for ( d = descriptor_list; d != NULL; d = d->next )
{
if ( d->connected == CON_PLAYING
&& d->character != ch
&& d->character->in_room != NULL
&& can_see( ch, d->character ) )
{
sprintf( buf, "%s %s", d->character->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 )
{
bug( "Mptransfer - No such location: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( room_is_private( location ) )
{
bug( "Mptransfer - Private room: vnum %d.",
ch->pIndexData->vnum );
return;
}
}
if ( ( victim = get_char_world( ch, arg ) ) == NULL )
{
bug( "Mptransfer - No such person: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( victim->in_room == NULL )
{
bug( "Mptransfer - Victim in Limbo: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( victim->fighting != NULL )
stop_fighting( victim, TRUE );
char_from_room( victim );
char_to_room( victim, location );
return;
}
/* Adds get_char_world(argument) to the mob's memory for later use in
* do_mptrack, etc. */
void do_mpremember( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
CHAR_DATA *vict;
if (!IS_NPC(ch)) { send_to_char("Huh?\n\r",ch); return; }
one_argument(argument,arg);
if ((vict=get_char_world(ch,arg))==NULL)
{
sprintf(buf,"mpremember - %s doesn't exist! Called by mobile vnum %d.",
arg,ch->pIndexData->vnum);
bug(buf,0);
return;
}
else ch->memory = vict;
return;
}
/* Erases a mob's memory. */
void do_mpforget( CHAR_DATA *ch, char *argument )
{
if (!IS_NPC(ch)) { send_to_char("Huh?\n\r",ch); return; }
ch->memory = NULL;
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 ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' || argument[0] == '\0' )
{
bug( "Mpforce - Bad syntax: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( !str_cmp( arg, "all" ) )
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
for ( vch = char_list; vch != NULL; vch = vch_next )
{
vch_next = vch->next;
if ( vch->in_room == ch->in_room
&& 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 )
{
bug( "Mpforce - No such victim: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( victim == ch )
{
bug( "Mpforce - Forcing oneself: vnum %d.",
ch->pIndexData->vnum );
return;
}
interpret( victim, argument );
}
return;
}
void do_mpsilentforce( CHAR_DATA *ch, char *argument )
{
extern bool silentmode;
char arg[MAX_INPUT_LENGTH];
if ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' || argument[0] == '\0' )
{
bug( "Mpsilentforce - Bad syntax: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( !str_cmp( arg, "all" ) )
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
for ( vch = char_list; vch != NULL; vch = vch_next )
{
vch_next = vch->next;
/* Don't allow forcing commands over MAX_LEVEL - 9 */
if (cmd_level(argument)>=MAX_LEVEL-9)
{
bug("mpsilentforce - mob vnum %d",ch->pIndexData->vnum);
bug("mpsilentforce - cannot force commands above level %d",
MAX_LEVEL-9);
return;
}
if ( vch->in_room == ch->in_room
&& get_trust( vch ) < get_trust( ch )
&& can_see( ch, vch ) )
{
silentmode = TRUE;
interpret( vch, argument );
silentmode = FALSE;
}
}
}
else
{
CHAR_DATA *victim;
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
bug( "Mpsilentforce - No such victim: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( victim == ch )
{
bug( "Mpsilentforce - Forcing oneself: vnum %d.",
ch->pIndexData->vnum );
return;
}
/* Don't allow forcing commands over MAX_LEVEL - 9 */
if (cmd_level(argument)>=MAX_LEVEL-9)
{
bug("mpsilentforce - mob vnum %d",ch->pIndexData->vnum);
bug("mpsilentforce - cannot force commands above level %d",
MAX_LEVEL-9);
return;
}
silentmode = TRUE;
interpret( victim, argument );
silentmode = FALSE;
}
return;
}
void do_mpdosilent( CHAR_DATA *ch, char *argument )
{
extern bool silentmode;
silentmode = TRUE;
interpret( ch, argument );
silentmode = FALSE;
return;
}
void do_mpdefault( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
if ( !IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' || argument[0] == '\0' )
{
bug( "Mpdefault - Bad syntax: vnum %d.", ch->pIndexData->vnum );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
bug( "Mpdefault - No such victim: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( victim == ch )
{
bug( "Mpdefault - to oneself: vnum %d.",
ch->pIndexData->vnum );
return;
}
if ( IS_NPC(victim) )
{
bug( "Mpdefault - npc victim: vnum %d.",
ch->pIndexData->vnum );
return;
}
mpinterpret( victim, argument );
return;
}
/* one_argumnet ruins the case so I do some funky stuff. -Zane */
void do_mpfollowpath( CHAR_DATA *ch, char *argument )
{
MOB_INDEX_DATA *pMob;
char arg[MAX_STRING_LENGTH];
char *arg2;
if ( ( pMob = ch->pIndexData ) == NULL )
return;
arg2 = one_argument(argument, arg);
if ( strlen(arg) < 1 )
return;
if ( !str_cmp(arg2, "restart") && !pMob->path_move )
{
pMob->path_move = TRUE;
pMob->path_pos = 0;
}
/* If we're fighting, unconcious(or worse) or not moving at all just exit */
if ( ch->fighting != NULL || !pMob->path_move || ch->position < POS_SLEEPING )
return;
switch ( argument[pMob->path_pos] )
{
case '0':
case '1':
case '2':
case '3':
move_char( ch, argument[pMob->path_pos] - '0', FALSE );
break;
case 'W':
ch->position = POS_STANDING;
act( "$n awakens and groans loudly.", ch, NULL, NULL, TO_ROOM );
break;
case 'S':
ch->position = POS_SLEEPING;
act( "$n lies down and falls asleep.", ch, NULL, NULL, TO_ROOM );
break;
case 'a':
act( "$n says 'Hello Honey!'", ch, NULL, NULL, TO_ROOM );
break;
case 'b':
act( "$n says 'What a view! I must do something about that dump!'",
ch, NULL, NULL, TO_ROOM );
break;
case 'c':
act( "$n says 'Vandals! Youngsters have no respect for anything!'",
ch, NULL, NULL, TO_ROOM );
break;
case 'd':
act( "$n says 'Good day, citizens!'", ch, NULL, NULL, TO_ROOM );
break;
case 'e':
act( "$n says 'I hereby declare the city of Midgaard open!'",
ch, NULL, NULL, TO_ROOM );
break;
case 'E':
act( "$n says 'I hereby declare the city of Midgaard closed!'",
ch, NULL, NULL, TO_ROOM );
break;
case 'O':
/* do_unlock( ch, "gate" ); */
do_open( ch, "gate" );
break;
case 'C':
do_close( ch, "gate" );
/* do_lock( ch, "gate" ); */
break;
case '.' :
pMob->path_move = FALSE;
break;
}
pMob->path_pos++;
if ( pMob->path_pos >= strlen(arg) )
{
pMob->path_move = FALSE;
pMob->path_pos = 0;
}
return;
}
void do_mpeatcorpse( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *corpse;
OBJ_DATA *c_next;
OBJ_DATA *obj;
OBJ_DATA *obj_next;
if ( !IS_AWAKE(ch) )
return;
for ( corpse = ch->in_room->contents; corpse != NULL; corpse = c_next )
{
c_next = corpse->next_content;
if ( corpse->item_type != ITEM_CORPSE_NPC )
continue;
act( "$n savagely devours a corpse.", ch, NULL, NULL, TO_ROOM );
for ( obj = corpse->contains; obj; obj = obj_next )
{
obj_next = obj->next_content;
obj_from_obj( obj );
obj_to_room( obj, ch->in_room );
}
extract_obj( corpse );
return;
}
return;
}
void do_mpclean( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *trash;
OBJ_DATA *trash_next;
int value;
value = atoi(argument);
if ( value < 1 || strlen(argument) == 0 )
value = 10;
if ( !IS_AWAKE(ch) )
return;
for ( trash = ch->in_room->contents; trash != NULL; trash = trash_next )
{
trash_next = trash->next_content;
if ( !IS_SET( trash->wear_flags, ITEM_TAKE ) || !can_loot(ch,trash))
continue;
if ( trash->item_type == ITEM_DRINK_CON
|| trash->item_type == ITEM_TRASH
|| trash->cost < value )
{
act( "$n picks up some trash.", ch, NULL, NULL, TO_ROOM );
obj_from_room( trash );
obj_to_char( trash, ch );
return;
}
}
return;
}
/* RT does socials */
void do_mprandomsocial(CHAR_DATA *ch, char *argument)
{
CHAR_DATA *victim = NULL;
int random = 0;
int iSocial;
for (iSocial = 0; social_table[iSocial].name[0] != '\0'; iSocial++)
;
random = number_range(0, iSocial-1);
if ( argument[0] == '\0' )
{
act( social_table[random].others_no_arg, ch, NULL, victim, TO_ROOM );
act( social_table[random].char_no_arg, ch, NULL, victim, TO_CHAR );
}
else if ( ( victim = get_char_room( ch, argument ) ) == NULL )
{
send_to_char( "They aren't here.\n\r", ch );
}
else if ( victim == ch )
{
act( social_table[random].others_auto, ch, NULL, victim, TO_ROOM );
act( social_table[random].char_auto, ch, NULL, victim, TO_CHAR );
}
else
{
act( social_table[random].others_found, ch, NULL, victim, TO_NOTVICT );
act( social_table[random].char_found, ch, NULL, victim, TO_CHAR );
act( social_table[random].vict_found, ch, NULL, victim, TO_VICT );
if ( IS_NPC(victim)
&& !IS_AFFECTED(victim, AFF_CHARM)
&& IS_AWAKE(victim)
&& victim->desc == NULL)
{
switch ( number_bits( 4 ) )
{
case 0:
case 1: case 2: case 3: case 4:
case 5: case 6: case 7: case 8:
act( social_table[random].others_found,
victim, NULL, ch, TO_NOTVICT );
act( social_table[random].char_found,
victim, NULL, ch, TO_CHAR );
act( social_table[random].vict_found,
victim, NULL, ch, TO_VICT );
break;
case 9: case 10: case 11: case 12:
act( "$n slaps $N.", victim, NULL, ch, TO_NOTVICT );
act( "You slap $N.", victim, NULL, ch, TO_CHAR );
act( "$n slaps you.", victim, NULL, ch, TO_VICT );
break;
}
}
}
}