/****************************************************************************
* [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | *
* -----------------------------------------------------------| \\._.// *
* SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version) | (0...0) *
* -----------------------------------------------------------| ).:.( *
* SMAUG (C) 1994, 1995, 1996 by Derek Snider | {o o} *
* -----------------------------------------------------------| / ' ' \ *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, |~'~.VxvxV.~'~*
* Scryn, Swordbearer, Rennard, Tricops, and Gorog. | *
* ------------------------------------------------------------------------ *
* Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe. *
****************************************************************************
* The MUDprograms are heavily based on the original MOBprogram code that *
* was written by N'Atas-ha. *
****************************************************************************/
#include "stdafx.h"
#include "smaug.h"
#include "SysData.h"
#include "area.h"
#include "skill.h"
#include "mobiles.h"
#include "objects.h"
#include "rooms.h"
#include "races.h"
#include "class.h"
#include "Exits.h"
#include "SmaugWizDoc.h"
#include "descriptor.h"
#include "character.h"
char *mprog_type_to_name (int type);
ch_ret simple_damage (CCharacter *ch, CCharacter *victim, int dam, int dt);
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 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 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";
default: return "ERROR_PROG";
}
}
// 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 (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
CCharacter *victim;
one_argument (argument, arg);
if (arg [0] == '\0') {
ch->SendText ("MProg stat whom?\n\r");
return;
}
if ((victim = get_char_world (ch, arg)) == NULL) {
ch->SendText ("They aren't here.\n\r");
return;
}
if (! victim->IsNpc ()) {
ch->SendText ("Only Mobiles can have MobPrograms!\n\r");
return;
}
if (victim->GetMobIndex ()->m_Progtypes.IsEmpty ()) {
ch->SendText ("That Mobile has no Programs set.\n\r");
return;
}
ch->SendTextf ("Name: %s. Vnum: %d.\n\r",
victim->GetName (), victim->GetMobIndex ()->vnum);
ch->SendTextf ("Short description: %s.\n\rLong description: %s",
victim->GetShortDescr (),
victim->HasLongDescription () ?
victim->GetLongDescr () : "(none).\n\r");
ch->SendTextf ("Hp: %d/%d. Mana: %d/%d. Move: %d/%d. \n\r",
victim->GetHp (), victim->GetMaxHp (), victim->GetMana (),
victim->GetMaxMana (), victim->GetMove (), victim->GetMaxMove ());
ch->SendTextf (
"Lv: %d. Class: %d. Align: %d. AC: %d. Gold: %d. Exp: %d.\n\r",
victim->GetLevel (), victim->GetClass (), victim->GetAlignment (),
victim->GetAc (), victim->GetGold (), victim->GetExp ());
CPtrList &PList = victim->GetMobIndex ()->MobPrgList;
POSITION pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Mprg = *(CMobProgData*) PList.GetNext (pos);
ch->SendTextf (">%s %s\n\r%s\n\r",
mprog_type_to_name (Mprg.type), Mprg.arglist, Mprg.comlist);
}
return;
}
/* Opstat - Scryn 8/12*/
void do_opstat (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
CObjData *obj;
one_argument (argument, arg);
if (arg[0] == '\0')
{
ch->SendText ("OProg stat what?\n\r");
return;
}
if ((obj = get_obj_world (ch, arg)) == NULL)
{
ch->SendText ("You cannot find that.\n\r");
return;
}
if (obj->pIndexData->m_Progtypes.IsEmpty ())
{
ch->SendText ("That object has no programs set.\n\r");
return;
}
ch->SendTextf ("Name: %s. Vnum: %d.\n\r",
obj->GetName (), obj->pIndexData->vnum);
ch->SendColorf ("Short description: %s.\n\r",
obj->GetShortDescr ());
CPtrList &PList = obj->pIndexData->ObjPrgList;
POSITION pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Oprg = *(CMobProgData*) PList.GetNext (pos);
ch->SendTextf (">%s %s\n\r%s\n\r",
mprog_type_to_name (Oprg.type), Oprg.arglist, Oprg.comlist);
}
return;
}
/* Rpstat - Scryn 8/12 */
void do_rpstat (CCharacter *ch, char *argument)
{
if (ch->GetInRoom ()->m_Progtypes.IsEmpty ()) {
ch->SendText ("This room has no programs set.\n\r");
return;
}
ch->SendTextf ("Name: %s. Vnum: %d.\n\r",
ch->GetInRoom ()->GetName (), ch->GetInRoom ()->vnum);
CPtrList &PList = ch->GetInRoom ()->RoomPrgList;
POSITION pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Rprg = *(CMobProgData*) PList.GetNext (pos);
ch->SendColorf (">%s %s\n\r%s\n\r",
mprog_type_to_name (Rprg.type), Rprg.arglist, Rprg.comlist);
}
}
// Prints the argument to all the rooms around the mobile
void do_mpasound (CCharacter *ch, char *argument)
{
CRoomIndexData *was_in_room;
CExitData *pexit;
if (! ch) {
bug ("Nonexistent ch in do_mpasound!");
return;
}
if (ch->IsCharmed ())
return;
if (! ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
return;
}
if (argument [0] == '\0') {
progbug ("Mpasound - No argument", ch);
return;
}
CActFlags actflags = ch->GetActFlags (); // save act flags
ch->ClrSecretive ();
was_in_room = ch->GetInRoom ();
for (pexit = was_in_room->first_exit; pexit; pexit = pexit->GetNext ()) {
if (pexit->GetToRoom () && pexit->GetToRoom () != was_in_room) {
ch->SetInRoom (pexit->GetToRoom ());
MOBtrigger = FALSE;
act (AT_SAY, argument, ch, NULL, NULL, TO_ROOM);
}
}
ch->SetActFlags (actflags); // restore act flags
ch->SetInRoom (was_in_room);
}
// Woowoo - Blodkai, November 1997
void do_mpasupress (CCharacter* ch, char* argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
CCharacter *victim;
int rnds;
if (! ch->IsNpc () || ch->IsCharmed ()) {
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (arg1 [0] == '\0') {
ch->SendText ("Mpasupress who?\n\r");
progbug ("Mpasupress: invalid argument", ch );
return;
}
if (arg2 [0] == '\0') {
ch->SendText ("Supress their attacks for how many rounds?\n\r");
progbug ("Mpasupress: invalid argument", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL) {
ch->SendText ("No such victim in the room.\n\r");
progbug ("Mpasupress: victim not present", ch);
return;
}
rnds = atoi (arg2);
if (rnds < 0 || rnds > 32000) {
ch->SendText ("Invalid number of rounds to supress attacks.\n\r");
progbug ("Mpsupress: invalid argument", ch);
return;
}
add_timer (victim, TIMER_ASUPRESSED, rnds, NULL, 0);
}
// lets the mobile kill any player or mobile without murder
void do_mpkill (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
CCharacter *victim;
if (! ch->IsNpc () || ch->IsCharmed ()) {
ch->SendText ("Huh?\n\r");
return;
}
if (! ch) {
bug ("Nonexistent ch in do_mpkill!");
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 (ch->IsCharmed () && ch->GetMaster () == victim) {
progbug ("MpKill - Charmed mob attacking master", ch);
return;
}
if (ch->IsFightPosition ()) {
progbug ("MpKill - Already fighting", ch);
return;
}
multi_hit (ch, victim, TYPE_UNDEFINED);
}
// 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 (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
CObjData *obj;
if (ch->IsCharmed ())
return;
if (! ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
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)) {
unequip_char (ch, obj);
extract_obj (obj);
return;
}
if ((obj = get_obj_carry (ch, arg)) == NULL)
return;
extract_obj (obj);
} else {
POSITION pos = ch->GetHeadCarryPos ();
while (obj = ch->GetNextCarrying (pos)) {
if (arg [3] == '\0' || is_name (&arg [4], obj->GetName ())) {
if (obj->wear_loc != WEAR_NONE)
unequip_char (ch, obj);
extract_obj (obj);
}
}
}
}
/*
* 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];
const 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 in the room other than the mob and victim
void do_mpechoaround (CCharacter *ch, char *argument)
{
char arg[ MAX_INPUT_LENGTH ];
CCharacter *victim;
short color;
if (ch->IsCharmed ())
return;
if (! ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
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;
}
CActFlags actflags = ch->GetActFlags ();
ch->ClrSecretive ();
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->SetActFlags (actflags);
}
// prints message only to victim
void do_mpechoat (CCharacter *ch, char *argument)
{
char arg[ MAX_INPUT_LENGTH ];
CCharacter *victim;
short color;
if (ch->IsCharmed ())
return;
if (! ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
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))) {
CString s;
s.Format ("Mpechoat - victim does not exist: %s", arg);
progbug (s, ch);
return;
}
CActFlags actflags = ch->GetActFlags ();
ch->ClrSecretive ();
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->SetActFlags (actflags);
}
// prints message to room at large.
void do_mpecho (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
short color;
if (ch->IsCharmed ())
return;
if (! ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
return;
}
if (argument [0] == '\0') {
progbug ("Mpecho - called w/o argument", ch);
return;
}
CActFlags actflags = ch->GetActFlags ();
ch->ClrSecretive ();
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->SetActFlags (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 (CCharacter *ch, char *argument)
{
char arg[ MAX_INPUT_LENGTH ];
CMobIndexData *pMobIndex;
CCharacter *victim;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
return;
}
one_argument (argument, arg);
if (arg[0] == '\0' || !is_number (arg))
{
progbug ("Mpmload - Bad vnum as arg", ch);
return;
}
if ((pMobIndex = MobTable.GetMob (atoi (arg))) == NULL)
{
progbug ("Mpmload - Bad mob vnum", ch);
return;
}
victim = create_mobile (pMobIndex);
victim->SendToRoom (ch->GetInRoom ());
return;
}
void do_mpoload (CCharacter *ch, char *argument)
{
char arg1[ MAX_INPUT_LENGTH ];
char arg2[ MAX_INPUT_LENGTH ];
CObjIndexData *pObjIndex;
CObjData *obj;
int level;
int timer = 0;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (arg1[0] == '\0' || !is_number (arg1))
{
progbug ("Mpoload - Bad syntax", ch);
return;
}
if (arg2[0] == '\0')
level = ch->GetTrustLevel ();
else
{
/*
* New feature from Alander.
*/
if (!is_number (arg2))
{
progbug ("Mpoload - Bad level syntax", ch);
return;
}
level = atoi (arg2);
if (level < 0 || level > ch->GetTrustLevel ())
{
progbug ("Mpoload - Bad level", ch);
return;
}
/*
* New feature from Thoric.
*/
timer = atoi (argument);
if (timer < 0)
{
progbug ("Mpoload - Bad timer", ch);
return;
}
}
if ((pObjIndex = OIdxTable.GetObj (atoi (arg1))) == NULL)
{
progbug ("Mpoload - Bad vnum arg", ch);
return;
}
obj = create_object (pObjIndex, level);
obj->timer = timer;
if (obj->CanWear (ITEM_TAKE))
obj_to_char (obj, ch);
else
obj_to_room (obj, ch->GetInRoom ());
return;
}
// Just a hack of do_pardon from act_wiz.c -- Blodkai, 6/15/97
void do_mppardon (CCharacter* ch, char* argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
CCharacter *victim;
if (ch->IsNpc () || ch->IsCharmed ()) {
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (arg1 [0] == '\0' || arg2 [0] == '\0') {
progbug ("Mppardon: missing argument", ch);
ch->SendText ("Mppardon who for what?\n\r");
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL) {
progbug ("Mppardon: offender not present", ch);
ch->SendText ("They aren't here.\n\r");
return;
}
if (victim->IsNpc ()) {
progbug ("Mppardon: trying to pardon NPC", ch);
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (! str_cmp (arg2, "attacker")) {
if (victim->IsAttacker ()) {
victim->ClrAttacker ();
ch->SendText ("Attacker flag removed.\n\r");
victim->SendText ("Your crime of attack has been pardoned.\n\r");
}
return;
}
if (! str_cmp (arg2, "killer")) {
if (victim->IsKiller ()) {
victim->ClrKiller ();
ch->SendText ("Killer flag removed.\n\r");
victim->SendText ("Your crime of murder has been pardoned.\n\r");
}
return;
}
if (! str_cmp (arg2, "litterbug")) {
if (victim->IsLitterBug ()) {
victim->ClrLitterBug ();
ch->SendText ("Litterbug flag removed.\n\r");
victim->SendText ("Your crime of littering has been pardoned./n/r");
}
return;
}
if (! str_cmp (arg2, "thief")) {
if (victim->IsThief ()) {
victim->ClrThief ();
ch->SendText ("Thief flag removed.\n\r");
victim->SendText ("Your crime of theft has been pardoned.\n\r");
}
return;
}
ch->SendText ("Pardon who for what?\n\r");
progbug ("Mppardon: Invalid argument", ch);
}
/* 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 (CCharacter *ch, char *argument)
{
char arg[ MAX_INPUT_LENGTH ];
CCharacter *victim;
CObjData *obj;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
return;
}
one_argument (argument, arg);
if (arg[0] == '\0')
{
/* 'purge' */
CCharacter *vnext;
for (victim = ch->GetInRoom ()->first_person; victim; victim = vnext)
{
vnext = victim->GetNextInRoom ();
if (victim->IsNpc () && victim != ch)
extract_char (victim, TRUE);
}
while (! ch->GetInRoom ()->IsEmpty ())
extract_obj (ch->GetInRoom ()->GetFirstContent ());
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 (!victim->IsNpc ())
{
progbug ("Mppurge - Trying to purge a PC", ch);
return;
}
if (victim == ch)
{
progbug ("Mppurge - Trying to purge oneself", ch);
return;
}
if (victim->IsNpc () && victim->GetMobIndex ()->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 (CCharacter *ch, char *argument)
{
char arg[MAX_INPUT_LENGTH];
short level;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
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->SetMobInvisLevel (level);
ch->SendTextf ("Mobinvis level set to %d.\n\r", level);
return;
}
if (ch->GetMobInvisLevel () < 2)
ch->SetMobInvisLevel (ch->GetLevel ());
if (ch->IsAction (ACT_MOBINVIS))
{
ch->ClrActBit (ACT_MOBINVIS);
act (AT_IMMORT, "$n slowly fades into existence.", ch, NULL, NULL,TO_ROOM);
ch->SendText ("You slowly fade back into existence.\n\r");
}
else
{
ch->SetActBit (ACT_MOBINVIS);
act (AT_IMMORT, "$n slowly fades into thin air.", ch, NULL, NULL, TO_ROOM);
ch->SendText ("You slowly vanish into thin air.\n\r");
}
return;
}
/* lets the mobile goto any location it wishes that is not private */
void do_mpgoto (CCharacter *ch, char *argument)
{
char arg[ MAX_INPUT_LENGTH ];
CRoomIndexData *location;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
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->GetFightData ())
stop_fighting (ch, TRUE);
ch->RemoveFromRoom ();
ch->SendToRoom (location);
return;
}
/* lets the mobile do a command at another location. Very useful */
void do_mpat (CCharacter *ch, char *argument)
{
char arg[ MAX_INPUT_LENGTH ];
CRoomIndexData *location;
CRoomIndexData *original;
CCharacter *wch;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
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->GetInRoom ();
ch->RemoveFromRoom ();
ch->SendToRoom (location);
interpret (ch, argument);
/*
* See if 'ch' still exists before continuing!
* Handles 'at XXXX quit' case.
*/
for (wch = first_char; wch; wch = wch->GetNext ())
if (wch == ch)
{
ch->RemoveFromRoom ();
ch->SendToRoom (original);
break;
}
return;
}
/* allow a mobile to advance a player's level... very dangerous */
void do_mpadvance (CCharacter *ch, char *argument)
{
char arg[MAX_INPUT_LENGTH];
CCharacter *victim;
int level;
int iLevel;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || ch->GetDesc ())
{
ch->SendText ("Huh?\n\r");
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 (victim->IsNpc ())
{
progbug ("Mpadvance - Victim is NPC", ch);
return;
}
if (victim->GetLevel () >= LEVEL_AVATAR)
return;
level = victim->GetLevel () + 1;
if (victim->GetLevel () > ch->GetLevel ())
{
act (AT_TELL, "$n tells you, 'Sorry... you must seek someone more powerful than I.'",
ch, NULL, victim, TO_VICT);
return;
}
if (victim->GetLevel () >= 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);
victim->SendText ("You suddenly feel very strange...\n\r\n\r");
set_char_color (AT_LBLUE, victim);
}
switch (level)
{
default:
victim->SendText ("You feel more powerful!\n\r");
break;
case LEVEL_IMMORTAL:
do_help (victim, "M_GODLVL1_");
set_char_color (AT_WHITE, victim);
victim->SendText ("You awake... all your possessions are gone.\n\r");
while (victim->IsCarrying ())
extract_obj (victim->GetFirstCarrying ());
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 (iLevel = victim->GetLevel () ; iLevel < level; iLevel++)
{
if (level < LEVEL_IMMORTAL)
victim->SendText ("You raise a level!! ");
victim->AddLevel (1);
advance_level (victim);
}
victim->SetExp (1000 * UMAX (1, victim->GetLevel ()));
victim->SetTrust (0);
}
/* lets the mobile transfer people. the all argument transfers
everyone in the current room to the specified location */
void do_mptransfer (CCharacter *ch, char *argument)
{
char arg1[ MAX_INPUT_LENGTH ];
char arg2[ MAX_INPUT_LENGTH ];
char buf[MAX_STRING_LENGTH];
CRoomIndexData *location;
CCharacter *victim;
CCharacter *nextinroom;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
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->GetInRoom ()->first_person; victim; victim = nextinroom)
{
nextinroom = victim->GetNextInRoom ();
if (victim != ch
&& victim->IsAuthed ()
&& can_see (ch, victim))
{
sprintf (buf, "%s %s", victim->GetName (), arg2);
do_mptransfer (ch, buf);
}
}
return;
}
// Thanks to Grodyn for the optional location parameter.
CString s;
if (arg2 [0] == '\0')
location = ch->GetInRoom ();
else {
s.Format ("Mptransfer - No such location: %s", arg2);
if ((location = find_location (ch, arg2)) == NULL) {
progbug (s, ch);
return;
}
if (room_is_private (location)) {
progbug ("Mptransfer - Private room", ch);
return;
}
}
if ((victim = get_char_world (ch, arg1)) == NULL) {
s.Format ("Mptransfer - No such person: %s", arg1);
progbug (s, ch);
return;
}
if (! victim->GetInRoom ()) {
progbug ("Mptransfer - Victim in Limbo", ch);
return;
}
if (! victim->IsAuthed () && location->GetArea () != victim->GetInRoom ()->GetArea ()) {
s.Format ("Mptransfer - transferring unauthorized player: %s", arg1);
progbug (s, ch);
return;
}
// If victim not in area's level range, do not transfer
if (!in_hard_range (victim, location->GetArea ())
&& ! location->IsPrototype ())
return;
if (victim->GetFightData ())
stop_fighting (victim, TRUE);
victim->RemoveFromRoom ();
victim->SendToRoom (location);
}
// 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 (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
CString s;
if (ch->IsCharmed ())
return;
if (! ch->IsNpc () || ch->GetDesc ()) {
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg);
if (arg [0] == '\0' || argument [0] == '\0') {
progbug ("Mpforce - Bad syntax, no argument", ch);
return;
}
if (! str_cmp (arg, "all")) {
CCharacter *vch = ch->GetInRoom ()->first_person;
for ( ; vch; vch = vch->GetNextInRoom ())
if (vch->GetTrustLevel () < ch->GetTrustLevel ()
&& can_see (ch, vch))
interpret (vch, argument);
} else {
CCharacter *victim;
if ((victim = get_char_room (ch, arg)) == NULL) {
s.Format ("Mpforce - No such victim: %s", arg);
progbug (s, ch);
return;
}
if (victim == ch) {
progbug ("Mpforce - Forcing oneself", ch);
return;
}
if (! victim->IsNpc ()
&& (! victim->GetDesc ())
&& victim->IsImmortal ()) {
s.Format ("Mpforce - Attempting to force link dead immortal: %s", arg);
progbug (s, ch);
return;
}
interpret (victim, argument);
}
}
// mpbodybag for mobs to do cr's --Shaddai
void do_mpbodybag (CCharacter* ch, char* argument)
{
CCharacter *victim;
CObjData *obj;
char arg [MAX_STRING_LENGTH];
char buf2 [MAX_STRING_LENGTH];
char buf3 [MAX_STRING_LENGTH];
if (! ch->IsNpc () || ch->GetDesc () || ch->IsCharmed ()) {
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg);
if (arg [0] == '\0') {
progbug ("Mpbodybag - called w/o enough arguments", ch);
return;
}
if ((victim = get_char_room (ch, arg)) == NULL) {
ch->SendText ("Victim must be in room.\n\r");
progbug ("Mpbodybag: victim not in room", ch);
return;
}
if (victim->IsNpc ()) {
progbug ("Mpbodybag: bodybagging a npc corpse", ch);
return;
}
sprintf (buf2, "the corpse of %s", arg);
int count = 0;
CObjIndexData &Idx = *OIdxTable.Find (OBJ_VNUM_CORPSE_PC);
if (! &Idx)
bug ("do_bodybag: No object index for OBJ_VNUM_CORPSE_PC.");
else {
POSITION pos = Idx.m_ObjList.GetHeadPosition ();
while (pos) {
obj = Idx.m_ObjList.GetNext (pos);
if (obj->in_room && !str_cmp (buf2, obj->GetShortDescr ())) {
obj_from_room (obj);
obj = obj_to_char (obj, ch);
obj->timer = -1;
++count;
}
}
}
// Maybe should just make the command logged... Shrug I am not sure
// --Shaddai
if (count) {
sprintf (buf3, "Mpbodybag: Grabbed %s (%d)", buf2, count);
progbug (buf3, ch);
}
}
// syntax: mppractice victim spell_name max%
void do_mp_practice (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char buf [MAX_INPUT_LENGTH];
CCharacter *victim;
int sn, max, tmp, adept;
char *skill_name;
if (ch->IsCharmed ())
return;
if (! ch->IsNpc ()) { // security breach, i guess
ch->SendText ("Huh?\n\r");
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') {
ch->SendText ("Mppractice: bad syntax");
progbug ("Mppractice - Bad syntax", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL) {
ch->SendText ("Mppractice: Student not in room? Invis?");
progbug ("Mppractice: Invalid student not in room", ch);
return;
}
if ((sn = SkillTable.Lookup (arg2)) < 0) {
ch->SendText ("Mppractice: Invalid spell/skill name");
progbug ("Mppractice: Invalid spell/skill name", ch);
return;
}
if (victim->IsNpc ()) {
ch->SendText ("Mppractice: Can't train a mob");
progbug ("Mppractice: Can't train a mob", ch);
return;
}
skill_name = SkillTable.GetName (sn);
max = atoi (arg3);
if ((max<0) || (max>100)) {
sprintf (log_buf, "mp_practice: Invalid maxpercent: %d", max);
ch->SendText (log_buf);
progbug (log_buf, ch);
return;
}
if (victim->GetLevel () < SkillTable.GetClassLevel (sn,
victim->GetClass ())) {
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 = SkillTable.GetClassAdept (sn, victim->GetClass ());
if ((victim->GetPcData ()->learned[sn] >= adept)
|| (victim->GetPcData ()->learned[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 (victim->GetPcData ()->learned[sn] +
int_app [victim->GetIntelligence ()].learn, max);
act (AT_ACTION, "$N demonstrates $t to you. You feel more learned "
"in this subject.", victim, SkillTable.GetName (sn), ch,TO_CHAR);
victim->GetPcData ()->learned [sn] = max;
if (victim->GetPcData ()->learned[sn] >= adept) {
victim->GetPcData ()->learned[sn] = adept;
act (AT_TELL,
"$n tells you, 'You have learned all I know on this subject...'",
ch, NULL, victim, TO_VICT);
}
}
/*
* syntax: mpslay (character)
*/
void do_mp_slay (CCharacter *ch, char *argument)
{
char arg1[ MAX_INPUT_LENGTH ];
CCharacter *victim;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || ch->GetDesc ())
{
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg1);
if (arg1[0] == '\0')
{
ch->SendText ("mpslay whom?\n\r");
progbug ("Mpslay: invalid (nonexistent?) argument", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL)
{
ch->SendText ("Victim must be in room.\n\r");
progbug ("Mpslay: victim not in room", ch);
return;
}
if (victim == ch)
{
ch->SendText ("You try to slay yourself. You fail.\n\r");
progbug ("Mpslay: trying to slay self", ch);
return;
}
if (victim->IsNpc () && victim->GetMobIndex ()->vnum == 3)
{
ch->SendText ("You cannot slay supermob!\n\r");
progbug ("Mpslay: trying to slay supermob", ch);
return;
}
if (victim->GetLevel () < 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);
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 (CCharacter *ch, char *argument)
{
char arg1[ MAX_INPUT_LENGTH ];
char arg2[ MAX_INPUT_LENGTH ];
CCharacter *victim;
int dam;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) )
{
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (arg1[0] == '\0')
{
ch->SendText ("mpdamage whom?\n\r");
progbug ("Mpdamage: invalid argument1", ch);
return;
}
if (arg2[0] == '\0')
{
ch->SendText ("mpdamage inflict how many hps?\n\r");
progbug ("Mpdamage: invalid argument2", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL)
{
ch->SendText ("Victim must be in room.\n\r");
progbug ("Mpdamage: victim not in room", ch);
return;
}
if (victim == ch)
{
ch->SendText ("You can't mpdamage yourself.\n\r");
progbug ("Mpdamage: trying to damage self", ch);
return;
}
dam = atoi (arg2);
if ((dam<0) || (dam>32000))
{
ch->SendText ("Mpdamage how much?\n\r");
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 (CCharacter *ch, char *argument)
{
char arg1[ MAX_INPUT_LENGTH ];
char arg2[ MAX_INPUT_LENGTH ];
CCharacter *victim;
int hp;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) )
{
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (arg1[0] == '\0')
{
ch->SendText ("mprestore whom?\n\r");
progbug ("Mprestore: invalid argument1", ch);
return;
}
if (arg2[0] == '\0')
{
ch->SendText ("mprestore how many hps?\n\r");
progbug ("Mprestore: invalid argument2", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL)
{
ch->SendText ("Victim must be in room.\n\r");
progbug ("Mprestore: victim not in room", ch);
return;
}
hp = atoi (arg2);
if ((hp<0) || (hp>32000))
{
ch->SendText ("Mprestore how much?\n\r");
progbug ("Mprestore: invalid (nonexistent?) argument", ch);
return;
}
hp += victim->GetHp ();
victim->SetHp ((hp > 32000 || hp < 0 || hp > victim->GetMaxHp ()) ?
victim->GetMaxHp () : hp);
}
/*
* Syntax mpfavor target number
* Raise a player's favor in progs.
*/
void do_mpfavor (CCharacter *ch, char *argument)
{
char arg1[ MAX_INPUT_LENGTH ];
char arg2[ MAX_INPUT_LENGTH ];
CCharacter *victim;
int favor;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) )
{
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (arg1[0] == '\0')
{
ch->SendText ("mpfavor whom?\n\r");
progbug ("Mpfavor: invalid argument1", ch);
return;
}
if (arg2[0] == '\0')
{
ch->SendText ("mpfavor how much favor?\n\r");
progbug ("Mpfavor: invalid argument2", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL)
{
ch->SendText ("Victim must be in room.\n\r");
progbug ("Mpfavor: victim not in room", ch);
return;
}
favor = atoi (arg2);
victim->GetPcData ()->favor = URANGE (-1000, victim->GetPcData ()->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 (CCharacter *ch, char *argument)
{
char arg1[ MAX_INPUT_LENGTH ];
char arg2[ MAX_INPUT_LENGTH ];
char arg3[ MAX_INPUT_LENGTH ];
CRoomIndexData *targetRoom, *fromRoom;
int targetRoomVnum, fromRoomVnum, exit_num;
CExitData *pexit;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) )
{
ch->SendText ("Huh?\n\r");
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 = RoomTable.GetRoom (fromRoomVnum)) ==NULL)
{
progbug ("MpOpenPassage - Bad syntax", ch);
return;
}
if (!is_number (arg2))
{
progbug ("MpOpenPassage - Bad syntax", ch);
return;
}
targetRoomVnum = atoi (arg2);
if ( (targetRoom = RoomTable.GetRoom (targetRoomVnum)) ==NULL)
{
progbug ("MpOpenPassage - Bad syntax", ch);
return;
}
if (!is_number (arg3))
{
progbug ("MpOpenPassage - Bad syntax", ch);
return;
}
exit_num = atoi (arg3);
if ((exit_num < 0) || (exit_num > MAX_DIR))
{
progbug ("MpOpenPassage - Bad syntax", ch);
return;
}
if ((pexit = get_exit (fromRoom, exit_num)) != NULL)
{
if (! pexit->IsPassage ())
return;
progbug ("MpOpenPassage - Exit exists", ch);
return;
}
pexit = make_exit (fromRoom, targetRoom, exit_num);
pexit->keyword = STRALLOC ("");
pexit->description = STRALLOC ("");
pexit->key = -1;
pexit->SetPassage ();
/* 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 (CCharacter *ch, char *argument)
{
char arg1[ MAX_INPUT_LENGTH ];
char arg2[ MAX_INPUT_LENGTH ];
char arg3[ MAX_INPUT_LENGTH ];
CRoomIndexData *fromRoom;
int fromRoomVnum, exit_num;
CExitData *pexit;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) )
{
ch->SendText ("Huh?\n\r");
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 = RoomTable.GetRoom (fromRoomVnum)) ==NULL)
{
progbug ("MpClosePassage - Bad syntax", ch);
return;
}
if (!is_number (arg2))
{
progbug ("MpClosePassage - Bad syntax", ch);
return;
}
exit_num = atoi (arg2);
if ((exit_num < 0) || (exit_num > MAX_DIR))
{
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 (! pexit->IsPassage ())
{
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 (CCharacter *ch, char *argument)
{
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) )
{
ch->SendText ("Huh?\n\r");
return;
}
return;
}
/*
* Sends a message to sleeping character. Should be fun
* with room sleep_progs
*
*/
void do_mpdream (CCharacter *ch, char *argument)
{
char arg1[MAX_STRING_LENGTH];
CCharacter *vict;
if (ch->IsCharmed ())
return;
if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) )
{
ch->SendText ("Huh?\n\r");
return;
}
argument = one_argument (argument, arg1);
if ( (vict =get_char_world (ch, arg1)) == NULL)
{
progbug ("Mpdream: No such character", ch);
return;
}
if (vict->GetPosition () <= POS_SLEEPING)
{
vict->SendText (argument);
vict->SendText ("\n\r");
}
return;
}
void do_mpapply (CCharacter *ch, char *argument)
{
CCharacter *victim;
if (! ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
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->GetDesc ()) {
ch->SendText ("Not on linkdeads.\n\r");
return;
}
if (victim->IsAuthed ())
return;
if (victim->GetPcData ()->auth_state >= 1)
return;
sprintf (log_buf, "%s%s new %s %s applying for authorization...",
victim->GetName (), victim->GetDesc ()->m_pHost,
RaceTable.GetName (victim->GetRace ()),
ClassTable.GetName (victim->GetClass ()));
gpDoc->LogString (log_buf);
to_channel (log_buf, CHANNEL_MONITOR, "Monitor", LEVEL_IMMORTAL);
victim->GetPcData ()->auth_state = 1;
}
void do_mpapplyb (CCharacter *ch, char *argument)
{
CCharacter *victim;
if (! ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
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->GetDesc ()) {
ch->SendText ("Not on linkdeads.\n\r");
return;
}
if (victim->IsAuthed ())
return;
if (get_timer (victim, TIMER_AUTH) >= 1)
return;
int delay = SysData.m_AuthDelay / 3;
switch (victim->GetPcData ()->auth_state) {
case 0:
case 1:
default:
victim->SendTextf ("You attempt to regain the gods' attention.\n\r");
sprintf (log_buf, "%s%s new %s %s applying for authorization...",
victim->GetName (), victim->GetDesc ()->m_pHost,
RaceTable.GetName (victim->GetRace ()),
ClassTable.GetName (victim->GetClass ()));
gpDoc->LogString (log_buf);
to_channel (log_buf, CHANNEL_MONITOR, "Monitor", LEVEL_IMMORTAL);
if (SysData.IsAutoAuth ())
add_timer (victim, TIMER_DO_FUN, delay, do_AutoAuthorize, 0);
else
add_timer (victim, TIMER_AUTH, delay, NULL, 0);
victim->GetPcData ()->auth_state = 1;
break;
case 2:
victim->SendText ("Your name has been deemed unsuitable by the gods. Please choose a more medieval name with the 'name' command.\n\r");
add_timer (victim, TIMER_AUTH, delay, NULL, 0);
break;
case 3:
victim->SendTextf ("The gods permit you to enter the %s.\n\r",
SysData.GetLongTitle ());
victim->ClrUnauthed ();
if (victim->GetFightData ())
stop_fighting (victim, TRUE);
victim->RemoveFromRoom ();
victim->SendToRoom (RoomTable.GetRoom (SysData.m_RoomSchool));
act (AT_WHITE, "$n enters this world from within a column of blinding light!",
victim, NULL, NULL, TO_ROOM);
do_look (victim, "auto");
break;
}
}
/*
* Deposit some gold into the current area's economy -Thoric
*/
void do_mp_deposit (CCharacter *ch, char *argument)
{
char arg[MAX_STRING_LENGTH];
int gold;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
return;
}
one_argument (argument, arg);
if (arg[0] == '\0')
{
progbug ("Mpdeposit - bad syntax", ch);
return;
}
gold = atoi (arg);
if (gold <= ch->GetGold () && ch->GetInRoom ())
{
ch->AddGold (-gold);
ch->GetInRoom ()->GetArea ()->BoostEconomy (gold);
}
}
/*
* Withdraw some gold from the current area's economy -Thoric
*/
void do_mp_withdraw (CCharacter *ch, char *argument)
{
char arg[MAX_STRING_LENGTH];
int gold;
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
return;
}
one_argument (argument, arg);
if (arg[0] == '\0')
{
progbug ("Mpwithdraw - bad syntax", ch);
return;
}
gold = atoi (arg);
if (ch->GetGold () < 1000000000 && gold < 1000000000 && ch->GetInRoom ()
&& ch->GetInRoom ()->GetArea ()->CheckGold (gold))
{
ch->AddGold (gold);
ch->GetInRoom ()->GetArea ()->LowerEconomy (gold);
}
}
void do_mppkset (CCharacter *ch, char *argument)
{
CCharacter *victim;
char arg[MAX_STRING_LENGTH];
if (!ch->IsNpc ())
{
ch->SendText ("Huh?\n\r");
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 (! victim->IsPkiller ())
victim->SetPkiller ();
}
else if (!str_cmp (argument, "no") || !str_cmp (argument, "n")) {
if (victim->IsPkiller ())
victim->ClrPkiller ();
}
else progbug ("Mppkset - bad syntax", ch);
}
/*
* Inflict damage from a mudprogram
*
* note: should be careful about using victim afterwards
*/
ch_ret simple_damage (CCharacter *ch, CCharacter *victim, int dam, int dt)
{
short dameq;
BOOL npcvict;
CObjData *damobj;
ch_ret retcode;
retcode = rNONE;
if (!ch)
{
bug ("Damage: null ch!", 0);
return rERROR;
}
if (!victim)
{
progbug ("Damage: null victim!", ch);
return rVICT_DIED;
}
if (victim->GetPosition () == POS_DEAD)
{
return rVICT_DIED;
}
npcvict = victim->IsNpc ();
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 (victim->HasSanctuary ())
dam /= 2;
if (victim->IsAffected (AFF_PROTECT) && ch->IsEvil ())
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, WEAR_EYES);
damobj = get_eq_char (victim, dameq);
if (damobj)
{
if (dam > get_obj_resistance (damobj))
{
set_cur_obj (damobj);
damage_obj (damobj);
}
}
}
/*
* Hurt the victim.
* Inform the victim of his new state.
*/
victim->AddHp (-dam);
if (!victim->IsNpc ()
&& victim->GetLevel () >= LEVEL_IMMORTAL
&& victim->GetHp () < 1)
victim->SetHp (1);
if (!npcvict
&& victim->GetTrustLevel () >= LEVEL_IMMORTAL
&& ch->GetTrustLevel () >= LEVEL_IMMORTAL
&& victim->GetHp () < 1)
victim->SetHp (1);
update_pos (victim);
switch (victim->GetPosition ())
{
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 (! victim->IsParalysed ())
{
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 > victim->GetMaxHp () / 4)
act (AT_HURT, "That really did HURT!", victim, 0, 0, TO_CHAR);
if (victim->GetHp () < victim->GetMaxHp () / 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->GetPosition () == POS_DEAD)
{
if (!npcvict)
{
sprintf (log_buf, "%s killed by %s at %d",
victim->GetName (),
(ch->IsNpc () ? ch->GetShortDescr () : ch->GetName ()),
victim->GetInRoom ()->vnum);
gpDoc->LogString (log_buf);
to_channel (log_buf, CHANNEL_MONITOR, "Monitor", LEVEL_IMMORTAL);
/*
* Dying penalty:
* 1/2 way back to previous level.
*/
if (victim->GetExp () > exp_level (victim, victim->GetLevel ()))
gain_exp (victim, (exp_level (victim, victim->GetLevel ()) - victim->GetExp ())/2);
/*
* New penalty... go back to the beginning of current level.
victim->GetExp () = exp_level (victim, victim->GetLevel ());
*/
}
set_cur_char (victim);
raw_kill (ch, victim);
victim = NULL;
return rVICT_DIED;
}
if (victim == ch)
return rNONE;
/*
* Take care of link dead people.
*/
if (!npcvict && !victim->GetDesc ())
{
if (number_range (0, victim->GetWait ()) == 0)
{
do_recall (victim, "");
return rNONE;
}
}
/*
* Wimp out?
*/
if (npcvict && dam > 0)
{
if ((victim->IsWimpy () && number_bits (1) == 0
&& victim->GetHp () < victim->GetMaxHp () / 2)
|| (victim->IsCharmed () && victim->GetMaster ()
&& victim->GetMaster ()->GetInRoom () != victim->GetInRoom ()))
{
start_fearing (victim, ch);
stop_hunting (victim);
do_flee (victim, "");
}
}
if (!npcvict
&& victim->GetHp () > 0
&& victim->GetHp () <= victim->GetWimpLevel ()
&& victim->GetWait () == 0)
do_flee (victim, "");
else
if (!npcvict && victim->IsAction (PLR_FLEE))
do_flee (victim, "");
return rNONE;
}