/****************************************************************************
* [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. *
****************************************************************************/
#include "stdafx.h"
#include "smaug.h"
#include "language.h"
#include "ActFlags.h"
#include "SysData.h"
#include "skill.h"
#include "mobiles.h"
#include "affect.h"
#include "objects.h"
#include "rooms.h"
#include "races.h"
#include "deity.h"
#include "area.h"
#include "class.h"
#include "SmaugWizDoc.h"
#include "SmaugFiles.h"
#include "descriptor.h"
#include "character.h"
#include "Exits.h"
extern BOOL fBootDb;
char* const r_flags [] = {
"dark", "death", "nomob", "indoors", "lawful", "neutral", "chaotic",
"nomagic", "tunnel", "private", "safe", "solitary", "petshop", "norecall",
"donation", "nodropall", "silence", "logspeech", "nodrop", "clanstoreroom",
"nosummon", "noastral", "teleport", "teleshowdesc", "nofloor",
"nosupplicate", "arena", "nomissile", "r4", "r5", "prototype", "r6"
};
char * const mag_flags [] =
{
"returning", "backstabber", "bane", "loyal", "haste", "drain",
"lightning_blade"
};
char * const w_flags [] =
{
"take", "finger", "neck", "body", "head", "legs", "feet", "hands", "arms",
"shield", "about", "waist", "wrist", "wield", "hold", "_dual_", "ears", "eyes",
"missile", "r1","r2","r3","r4","r5","r6",
"r7","r8","r9","r10","r11","r12","r13"
};
char * const area_flags [] =
{
"nopkill", "freekill", "noteleport", "r3", "r4", "r5", "r6", "r7", "r8",
"r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
"r18", "r19","r20","r21","r22","r23","r24",
"r25","r26","r27","r28","r29","r30","r31"
};
char * const o_types [] =
{
"none", "light", "scroll", "wand", "staff", "weapon", "_fireweapon", "_missile",
"treasure", "armor", "potion", "_worn", "furniture", "trash", "_oldtrap",
"container", "_note", "drinkcon", "key", "food", "money", "pen", "boat",
"corpse", "corpse_pc", "fountain", "pill", "blood", "bloodstain",
"scraps", "pipe", "herbcon", "herb", "incense", "fire", "book", "switch",
"lever", "pullchain", "button", "dial", "rune", "runepouch", "match", "trap",
"map", "portal", "paper", "tinder", "lockpick", "spike", "disease", "oil",
"fuel", "shortbow", "longbow", "crossbow", "projectile", "quiver", "shovel",
"salve", "cook", "keyring", "odor"
};
char * const a_types [] =
{
"none", "strength", "dexterity", "intelligence", "wisdom", "constitution",
"sex", "class", "level", "age", "height", "weight", "mana", "hit", "move",
"gold", "experience", "armor", "hitroll", "damroll", "save_poison", "save_rod",
"save_para", "save_breath", "save_spell", "charisma", "affected", "resistant",
"immune", "susceptible", "weaponspell", "luck", "backstab", "pick", "track",
"steal", "sneak", "hide", "palm", "detrap", "dodge", "peek", "scan", "gouge",
"search", "mount", "disarm", "kick", "parry", "bash", "stun", "punch", "climb",
"grip", "scribe", "brew", "wearspell", "removespell", "mentalstate", "emotion",
"stripsn", "remove", "dig", "full", "thirst", "drunk", "blood", "cook",
"recurringspell", "contagious", "xaffected", "odor", "roomflag", "sectortype",
"roomlight", "televnum", "teledelay"
};
char * const pc_flags [] =
{
"r1", "deadly", "unauthed", "norecall", "nointro", "gag", "retired", "guest",
"nosummon", "pager", "notitled", "groupwho", "diagnose", "highgag", "r8",
"nstart", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18",
"r19", "r20", "r21", "r22", "r23", "r24", "r25"
};
char * const trap_flags [] =
{
"room", "obj", "enter", "leave", "open", "close", "get", "put", "pick",
"unlock", "north", "south", "east", "r1", "west", "up", "down", "examine",
"r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13",
"r14", "r15"
};
char * const wear_locs [] =
{
"light", "finger1", "finger2", "neck1", "neck2", "body", "head", "legs",
"feet", "hands", "arms", "shield", "about", "waist", "wrist1", "wrist2",
"wield", "hold", "dual_wield", "ears", "eyes", "missile_wield", "back",
"face", "ankle1", "ankle2"
};
char * const ris_flags [] =
{
"fire", "cold", "electricity", "energy", "blunt", "pierce", "slash", "acid",
"poison", "drain", "sleep", "charm", "hold", "nonmagic", "plus1", "plus2",
"plus3", "plus4", "plus5", "plus6", "magic", "paralysis", "r1", "r2", "r3",
"r4", "r5", "r6", "r7", "r8", "r9", "r10"
};
char * const trig_flags [] =
{
"up", "unlock", "lock", "d_north", "d_south", "d_east", "d_west", "d_up",
"d_down", "door", "container", "open", "close", "passage", "oload", "mload",
"teleport", "teleportall", "teleportplus", "death", "cast", "fakeblade",
"rand4", "rand6", "trapdoor", "anotherroom", "usedial", "absolutevnum",
"showroomdesc", "autoreturn", "r2", "r3"
};
char * const part_flags [] =
{
"head", "arms", "legs", "heart", "brains", "guts", "hands", "feet", "fingers",
"ear", "eye", "long_tongue", "eyestalks", "tentacles", "fins", "wings",
"tail", "scales", "claws", "fangs", "horns", "tusks", "tailattack",
"sharpscales", "beak", "haunches", "hooves", "paws", "forelegs", "feathers",
"r1", "r2"
};
/*
* Note: I put them all in one big set of flags since almost all of these
* can be shared between mobs, objs and rooms for the exception of
* bribe and hitprcnt, which will probably only be used on mobs.
* ie: drop -- for an object, it would be triggered when that object is
* dropped; -- for a room, it would be triggered when anything is dropped
* -- for a mob, it would be triggered when anything is dropped
*
* Something to consider: some of these triggers can be grouped together,
* and differentiated by different arguments... for example:
* hour and time, rand and randiw, speech and speechiw
*
*/
char * const mprog_flags [] =
{
"act", "speech", "rand", "fight", "death", "hitprcnt", "entry", "greet",
"allgreet", "give", "bribe", "hour", "time", "wear", "remove", "sac",
"look", "exa", "zap", "get", "drop", "damage", "repair", "randiw",
"speechiw", "pull", "push", "sleep", "rest", "leave", "script", "use"
};
char *flag_string (int bitvector, char* const flagarray [])
{
static char buf [MAX_STRING_LENGTH];
int x;
buf [0] = '\0';
for (x = 0; x < 32 ; x++)
if (IS_SET (bitvector, 1 << x)) {
strcat (buf, flagarray[x]);
strcat (buf, " ");
}
if ((x=strlen (buf)) > 0)
buf [--x] = '\0';
return buf;
}
BOOL can_rmodify (CCharacter *ch, CRoomIndexData *room)
{
int vnum = room->vnum;
if (ch->IsNpc ())
return FALSE;
if (ch->GetTrustLevel () >= SysData.ModifyProtoLevel)
return TRUE;
if (! room->IsPrototype ()) {
ch->SendText ("You cannot modify this room.\n\r");
return FALSE;
}
CAreaData &Area = *ch->GetArea ();
if (! &Area) {
ch->SendText ("You must have an assigned area to modify this room.\n\r");
return FALSE;
}
if (vnum >= Area.low_r_vnum && vnum <= Area.hi_r_vnum)
return TRUE;
ch->SendText ("That room is not in your allocated range.\n\r");
return FALSE;
}
BOOL can_omodify (CCharacter *ch, CObjData *obj)
{
int vnum = obj->pIndexData->vnum;
if (ch->IsNpc ())
return FALSE;
if (ch->GetTrustLevel () >= SysData.ModifyProtoLevel)
return TRUE;
if (! obj->IsPrototype ()) {
ch->SendText ("You cannot modify this object.\n\r");
return FALSE;
}
CAreaData &Area = *ch->GetArea ();
if (! &Area) {
ch->SendText ("You must have an assigned area to modify this object.\n\r");
return FALSE;
}
if (vnum >= Area.low_o_vnum && vnum <= Area.hi_o_vnum)
return TRUE;
ch->SendText ("That object is not in your allocated range.\n\r");
return FALSE;
}
BOOL can_oedit (CCharacter *ch, CObjIndexData *obj)
{
int vnum = obj->vnum;
if (ch->IsNpc ())
return FALSE;
if (ch->GetTrustLevel () >= LEVEL_GOD)
return TRUE;
if (! obj->IsPrototype ()) {
ch->SendText ("You cannot modify this object.\n\r");
return FALSE;
}
CAreaData &Area = *ch->GetArea ();
if (! &Area) {
ch->SendText ("You must have an assigned area to modify this object.\n\r");
return FALSE;
}
if (vnum >= Area.low_o_vnum && vnum <= Area.hi_o_vnum)
return TRUE;
ch->SendText ("That object is not in your allocated range.\n\r");
return FALSE;
}
BOOL can_mmodify (CCharacter *ch, CCharacter *mob)
{
int vnum;
if (mob == ch)
return TRUE;
if (!mob->IsNpc ()) {
if (ch->GetTrustLevel () >= SysData.ModifyProtoLevel
&& ch->GetTrustLevel () > mob->GetTrustLevel ())
return TRUE;
else
ch->SendText ("You can't do that.\n\r");
return FALSE;
}
vnum = mob->GetMobIndex ()->vnum;
if (ch->IsNpc ())
return FALSE;
if (ch->GetTrustLevel () >= SysData.ModifyProtoLevel)
return TRUE;
if (! mob->IsAction (ACT_PROTOTYPE)) {
ch->SendText ("You cannot modify this mobile.\n\r");
return FALSE;
}
CAreaData &Area = *ch->GetArea ();
if (! &Area) {
ch->SendText ("You must have an assigned area to modify this mobile.\n\r");
return FALSE;
}
if (vnum >= Area.low_m_vnum && vnum <= Area.hi_m_vnum)
return TRUE;
ch->SendText ("That mobile is not in your allocated range.\n\r");
return FALSE;
}
BOOL can_medit (CCharacter *ch, CMobIndexData *mob)
{
int vnum = mob->vnum;
if (ch->IsNpc ())
return FALSE;
if (ch->GetTrustLevel () >= LEVEL_GOD)
return TRUE;
if (! mob->IsPrototype ()) {
ch->SendText ("You cannot modify this mobile.\n\r");
return FALSE;
}
CAreaData &Area = *ch->GetArea ();
if (! &Area) {
ch->SendText ("You must have an assigned area to modify this mobile.\n\r");
return FALSE;
}
if (vnum >= Area.low_m_vnum && vnum <= Area.hi_m_vnum)
return TRUE;
ch->SendText ("That mobile is not in your allocated range.\n\r");
return FALSE;
}
int get_otype (const char *type)
{
int x;
for (x = 0; x < DIM (o_types); ++x)
if (! str_cmp (type, o_types [x]))
return x;
return -1;
}
int get_aflag (const char *flag)
{
int x;
for (x = 0; x < MAX_AFFECTED_BY; ++x)
if (! str_cmp (flag, AffectNames [x]))
return x;
return -1;
}
int get_trapflag (char *flag)
{
int x;
for (x = 0; x < DIM (trap_flags); ++x)
if (! str_cmp (flag, trap_flags [x]))
return x;
return -1;
}
int get_atype (const char *type)
{
int x;
for (x = 0; x < MAX_APPLY_TYPE; ++x)
if (!str_cmp (type, a_types [x]))
return x;
return -1;
}
int get_wearloc (char *type)
{
int x;
for (x = 0; x < MAX_WEAR; ++x)
if (! str_cmp (type, wear_locs [x]))
return x;
return -1;
}
int get_exflag (const char *flag)
{
ASSERT (EX_MAX < 32);
for (int x = 0; x < EX_MAX; ++x)
if (! str_cmp (flag, ExitTypeNames [x]))
return x;
return -1;
}
int get_rflag (const char *flag)
{
int x;
for (x = 0; x < DIM (r_flags); ++x)
if (! str_cmp (flag, r_flags [x]))
return x;
return -1;
}
int get_mpflag (char *flag)
{
int x;
for (x = 0; x < DIM (mprog_flags); ++x)
if (! str_cmp (flag, mprog_flags [x]))
return x;
return -1;
}
int get_oflag (const char *flag)
{
int x;
for (x = 0; x < DIM (ItemFlagNames); ++x)
if (! str_cmp (flag, ItemFlagNames [x]))
return x;
return -1;
}
int get_areaflag (char *flag)
{
int x;
for (x = 0; x < DIM (area_flags); ++x)
if (! str_cmp (flag, area_flags [x]))
return x;
return -1;
}
int get_wflag (const char *flag)
{
int x;
for (x = 0; x < DIM (w_flags); ++x)
if (! str_cmp (flag, w_flags [x]))
return x;
return -1;
}
int get_actflag (char *flag)
{
int x;
for (x = 0; x < DIM (MobActNames); ++x)
if (! str_cmp (flag, MobActNames [x]))
return x;
return -1;
}
int get_pcflag (char *flag)
{
int x;
for (x = 0; x < DIM (pc_flags); ++x)
if (! str_cmp (flag, pc_flags [x]))
return x;
return -1;
}
int get_plrflag (char *flag)
{
int x;
for (x = 0; x < PLR_MAX; ++x)
if (! str_cmp (flag, PlrActNames [x]))
return x;
return -1;
}
int get_risflag (const char *flag)
{
int x;
for (x = 0; x < DIM (ris_flags); ++x)
if (! str_cmp (flag, ris_flags [x]))
return x;
return -1;
}
int get_trigflag (char *flag)
{
int x;
for (x = 0; x < DIM (trig_flags); ++x)
if (! str_cmp (flag, trig_flags [x]))
return x;
return -1;
}
int get_partflag (char *flag)
{
int x;
for (x = 0; x < DIM (part_flags); ++x)
if (! str_cmp (flag, part_flags [x]))
return x;
return -1;
}
int get_attackflag (const char *flag)
{
int x;
for (x = 0; x < DIM (AttackNames); ++x)
if (! str_cmp (flag, AttackNames [x]))
return x;
return -1;
}
int get_defenseflag (const char *flag)
{
int x;
for (x = 0; x < DIM (DefenseNames); ++x)
if (! str_cmp (flag, DefenseNames [x]))
return x;
return -1;
}
// Remove carriage returns from a line
char *strip_cr (const char *str)
{
static char newstr [MAX_STRING_LENGTH];
int i, j;
for (i=j=0; str [i] != '\0'; i++)
if (str [i] != '\r') {
newstr [j++] = str [i];
}
newstr [j] = '\0';
return newstr;
}
// Removes the tildes from a line, except if it's the last character.
void smush_tilde (char *str)
{
int len;
char last;
char *strptr;
strptr = str;
len = strlen (str);
if (len)
last = strptr [len-1];
else
last = '\0';
for (; *str != '\0'; str++) {
if (*str == '~')
*str = '-';
}
if (len)
strptr [len-1] = last;
}
void do_goto (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
CRoomIndexData *location;
CCharacter *fch;
CCharacter *fch_next;
CRoomIndexData *in_room;
CAreaData *pArea;
int vnum;
one_argument (argument, arg);
if (arg [0] == '\0') {
ch->SendText ("Goto where?\n\r");
return;
}
if ((location = find_location (ch, arg)) == NULL) {
vnum = atoi (arg);
if (vnum < 0 || RoomTable.GetRoom (vnum)) {
ch->SendText ("You cannot find that...\n\r");
return;
}
pArea = ch->GetArea ();
if (ch->GetTrustLevel () < LEVEL_CREATOR
|| vnum < 1 || ch->IsNpc () || ! pArea) {
ch->SendText ("No such location.\n\r");
return;
}
// I don't see why anyone should be able to create rooms unless
// then have an assigned area - Rustry
// if (ch->GetTrustLevel () < SysData.ModifyProtoLevel) {
if (! pArea) {
ch->SendText ("You must have an assigned area to create "
"rooms.\n\r");
return;
}
if (vnum < pArea->low_r_vnum || vnum > pArea->hi_r_vnum) {
ch->SendText ("That room is not within your assigned "
"range.\n\r");
return;
}
// }
if (FileTable.Exists (FileTable.MakeBuildName (pArea->m_Filename))
&& ! pArea->IsLoaded ()) {
ch->SendText ("Your area is not loaded.\n\r"); // Rustry
return;
}
location = make_room (vnum);
if (! location) {
bug ("Goto: make_room failed", 0);
return;
}
location->SetArea (pArea);
set_char_color (AT_WHITE, ch);
ch->SendText ("Waving your hand, you form order from swirling "
"chaos,\n\rand step into a new reality...\n\r");
}
if (room_is_private (location))
{
if (ch->GetTrustLevel () < SysData.OverridePrivateLev) {
ch->SendText ("That room is private right now.\n\r");
return;
}
else ch->SendText ("Overriding private flag!\n\r");
}
in_room = ch->GetInRoom ();
if (ch->GetFightData ())
stop_fighting (ch, TRUE);
if (! ch->IsWizInvis ())
act (AT_IMMORT, "$n $T", ch, NULL,
(ch->GetPcData () && ch->GetPcData ()->HasBamfout ())
? ch->GetPcData ()->GetBamfout () : "leaves in a swirling mist.",
TO_ROOM);
ch->regoto = ch->GetInRoom ()->vnum;
ch->RemoveFromRoom ();
if (ch->mount) {
ch->mount->RemoveFromRoom ();
ch->mount->SendToRoom (location);
}
ch->SendToRoom (location);
if (! ch->IsWizInvis ())
act (AT_IMMORT, "$n $T", ch, NULL,
(ch->GetPcData () && ch->GetPcData ()->HasBamfin ())
? ch->GetPcData ()->GetBamfin () : "appears in a swirling mist.",
TO_ROOM);
do_look (ch, "auto");
if (ch->GetInRoom () == in_room)
return;
for (fch = in_room->first_person; fch; fch = fch_next) {
fch_next = fch->GetNextInRoom ();
if (fch->GetMaster () == ch && fch->IsImmortal ()) {
act (AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR);
do_goto (fch, argument);
}
}
}
void do_mset (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char buf [MAX_STRING_LENGTH];
char outbuf[MAX_STRING_LENGTH];
int num, size, plus;
char char1,char2;
CCharacter *victim;
int value;
int minattr, maxattr;
BOOL lockvictim;
char *origarg = argument;
set_char_color (AT_PLAIN, ch);
if (ch->IsNpc ()) {
ch->SendText ("Mob's can't mset\n\r");
return;
}
pc_data &Cpc = *ch->GetPcData ();
switch (ch->GetSubstate ()) {
default:
break;
case SUB_MOB_DESC:
if (! ch->dest_buf) {
ch->SendText ("Fatal error: report to an Immortal.\n\r");
bug ("do_mset: sub_mob_desc: NULL ch->dest_buf");
ch->SetSubstate (SUB_NONE);
return;
}
victim = (CCharacter*) ch->dest_buf;
if (char_died (victim)) {
ch->SendText ("Your victim died!\n\r");
ch->StopEditing ();
return;
}
victim->SetDescriptionNA (ch->GetEditBuffer ());
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE)) {
STRFREE (victim->GetMobIndex ()->GetDescription ());
victim->GetMobIndex ()->SetDescription (
QUICKLINK (victim->GetDescription ()));
}
ch->StopEditing ();
ch->SetSubstate (ch->tempnum);
return;
}
victim = NULL;
lockvictim = FALSE;
smash_tilde (argument);
if (ch->GetSubstate () == SUB_REPEATCMD) {
victim = (CCharacter*) ch->dest_buf;
if (char_died (victim)) {
ch->SendText ("Your victim died!\n\r");
victim = NULL;
argument = "done";
}
if (argument [0] == '\0' || ! str_cmp (argument, " ")
|| ! str_cmp (argument, "stat")) {
if (victim)
do_mstat (ch, NCCP victim->GetName ());
else
ch->SendText ("No victim selected. Type '?' for help.\n\r");
return;
}
if (! str_cmp (argument, "done") || !str_cmp (argument, "off")) {
ch->SendText ("Mset mode off.\n\r");
ch->SetSubstate (SUB_NONE);
ch->dest_buf = NULL;
if (&Cpc && Cpc.HasSubPrompt ()) {
STRFREE (Cpc.GetSubPrompt ());
Cpc.SetSubPrompt (NULL);
}
return;
}
}
if (victim) {
lockvictim = TRUE;
strcpy (arg1, victim->GetName ());
argument = one_argument (argument, arg2);
strcpy (arg3, argument);
} else {
lockvictim = FALSE;
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
strcpy (arg3, argument);
}
if (! str_cmp (arg1, "on")) {
ch->SendText ("Syntax: mset <victim|vnum> on.\n\r");
return;
}
if (arg1 [0] == '\0' || (arg2 [0] == '\0'
&& ch->GetSubstate () != SUB_REPEATCMD)
|| ! str_cmp (arg1, "?")) {
if (ch->GetSubstate () == SUB_REPEATCMD) {
if (victim)
ch->SendText ("Syntax: <field> <value>\n\r");
else
ch->SendText ("Syntax: <victim> <field> <value>\n\r");
}
else
ch->SendText ("Syntax: mset <victim> <field> <value>\n\r");
ch->SendText ("\n\r");
ch->SendText ("Field being one of:\n\r");
ch->SendText (" str int wis dex con cha lck sex class\n\r");
ch->SendText (" gold maxhp maxmana maxmove practice align race\n\r");
ch->SendText (" hitroll damroll armor affected level\n\r");
ch->SendText (" thirst drunk full blood flags mobinvislevel\n\r");
ch->SendText (" pos defpos part (see BODYPARTS)\n\r");
ch->SendText (" sav1 sav2 sav4 sav4 sav5 (see SAVINGTHROWS)\n\r");
ch->SendText (" resistant immune susceptible (see RIS)\n\r");
ch->SendText (" attack defense numattacks\n\r");
ch->SendText (" speaking speaks (see LANGUAGES)\n\r");
ch->SendText (" name short long description title spec clan\n\r");
ch->SendText (" council quest qp qpa favor deity\n\r");
ch->SendText (" rank mentalstate emotion\n\r");
ch->SendText ("\n\r");
ch->SendText ("For editing index/prototype mobiles:\n\r");
ch->SendText (" hitnumdie hitsizedie hitplus (hit points)\n\r");
ch->SendText (" damnumdie damsizedie damplus (damage roll)\n\r");
ch->SendText ("To toggle area flag: aloaded\n\r");
ch->SendText ("To toggle pkill flag: pkill\n\r");
return;
}
if (! victim && ch->GetTrustLevel () < LEVEL_GOD) {
if ((victim = get_char_room (ch, arg1)) == NULL) {
ch->SendText ("They aren't here.\n\r");
return;
}
}
else if (! victim) {
if ((victim = get_char_world (ch, arg1)) == NULL) {
ch->SendTextf ("No one like that in all the %s.\n\r",
SysData.GetShortTitle ());
return;
}
}
pc_data &Vpc = *victim->GetPcData ();
if (ch->GetTrustLevel () < victim->GetTrustLevel () && !victim->IsNpc ()){
ch->SendText ("You can't do that!\n\r");
ch->dest_buf = NULL;
return;
}
if (lockvictim)
ch->dest_buf = victim;
if (victim->IsNpc ()) {
minattr = 1;
maxattr = 25;
} else {
minattr = 3;
maxattr = 18;
}
if (! str_cmp (arg2, "on")) {
if (ch->CheckSubrestricted ())
return;
ch->SendTextf ("Mset mode on. (Editing %s).\n\r",
victim->GetName ());
ch->SetSubstate (SUB_REPEATCMD);
ch->dest_buf = victim;
if (&Cpc) {
if (Cpc.HasSubPrompt ())
STRFREE (Cpc.GetSubPrompt ());
if (victim->IsNpc ())
sprintf (buf, "<&CMset &W#%d&w> %%i", victim->GetMobIndex ()->vnum);
else
sprintf (buf, "<&CMset &W%s&w> %%i", victim->GetName ());
Cpc.SetSubPrompt (STRALLOC (buf));
}
return;
}
value = is_number (arg3) ? atoi (arg3) : -1;
if (atoi (arg3) < -1 && value == -1)
value = atoi (arg3);
if (! str_cmp (arg2, "str")) {
if (! can_mmodify (ch, victim))
return;
if (value < minattr || value > maxattr) {
ch->SendTextf ("Strength range is %d to %d.\n\r", minattr, maxattr);
return;
}
victim->perm_str = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->perm_str = value;
return;
}
if (! str_cmp (arg2, "int")) {
if (! can_mmodify (ch, victim))
return;
if (value < minattr || value > maxattr) {
ch->SendTextf ("Intelligence range is %d to %d.\n\r", minattr, maxattr);
return;
}
victim->perm_int = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->perm_int = value;
return;
}
if (! str_cmp (arg2, "wis")) {
if (! can_mmodify (ch, victim))
return;
if (value < minattr || value > maxattr) {
ch->SendTextf ("Wisdom range is %d to %d.\n\r", minattr, maxattr);
return;
}
victim->perm_wis = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->perm_wis = value;
return;
}
if (! str_cmp (arg2, "dex")) {
if (! can_mmodify (ch, victim))
return;
if (value < minattr || value > maxattr) {
ch->SendTextf ("Dexterity range is %d to %d.\n\r", minattr, maxattr);
return;
}
victim->perm_dex = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->perm_dex = value;
return;
}
if (! str_cmp (arg2, "con")) {
if (! can_mmodify (ch, victim))
return;
if (value < minattr || value > maxattr) {
ch->SendTextf ("Constitution range is %d to %d.\n\r", minattr, maxattr);
return;
}
victim->perm_con = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->perm_con = value;
return;
}
if (! str_cmp (arg2, "cha")) {
if (! can_mmodify (ch, victim))
return;
if (value < minattr || value > maxattr) {
ch->SendTextf ("Charisma range is %d to %d.\n\r", minattr, maxattr);
return;
}
victim->perm_cha = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->perm_cha = value;
return;
}
if (! str_cmp (arg2, "lck")) {
if (! can_mmodify (ch, victim))
return;
if (value < minattr || value > maxattr) {
ch->SendTextf ("Luck range is %d to %d.\n\r", minattr, maxattr);
return;
}
victim->perm_lck = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->perm_lck = value;
return;
}
if (! str_cmp (arg2, "sav1")) {
if (! can_mmodify (ch, victim))
return;
if (value < -30 || value > 30) {
ch->SendText ("Saving throw range is -30 to 30.\n\r");
return;
}
victim->saving_poison_death = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->saving_poison_death = value;
return;
}
if (! str_cmp (arg2, "sav2")) {
if (! can_mmodify (ch, victim))
return;
if (value < -30 || value > 30) {
ch->SendText ("Saving throw range is -30 to 30.\n\r");
return;
}
victim->saving_wand = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->saving_wand = value;
return;
}
if (! str_cmp (arg2, "sav3")) {
if (! can_mmodify (ch, victim))
return;
if (value < -30 || value > 30) {
ch->SendText ("Saving throw range is -30 to 30.\n\r");
return;
}
victim->saving_para_petri = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->saving_para_petri = value;
return;
}
if (! str_cmp (arg2, "sav4")) {
if (! can_mmodify (ch, victim))
return;
if (value < -30 || value > 30) {
ch->SendText ("Saving throw range is -30 to 30.\n\r");
return;
}
victim->saving_breath = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->saving_breath = value;
return;
}
if (! str_cmp (arg2, "sav5")) {
if (! can_mmodify (ch, victim))
return;
if (value < -30 || value > 30) {
ch->SendText ("Saving throw range is -30 to 30.\n\r");
return;
}
victim->saving_spell_staff = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->saving_spell_staff = value;
return;
}
if (! str_cmp (arg2, "sex")) {
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 2) {
ch->SendText ("Sex range is 0 to 2.\n\r");
return;
}
victim->SetSex (value);
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->sex = value;
return;
}
if (! str_cmp (arg2, "class")) {
if (! can_mmodify (ch, victim))
return;
if (victim->IsNpc ()) {
if (value > MAX_NPC_CLASS || value < 0) {
ch->SendTextf ("NPC Class range is 0 to %d.\n",
MAX_NPC_CLASS-1);
return;
}
victim->SetClass (value);
if (victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->m_Class = value;
return;
}
if (value < 0 || value >= ClassTable.GetCount ()) {
ch->SendTextf ("Class range is 0 to %d.\n",
ClassTable.GetCount ()-1);
return;
}
victim->SetClass (value);
return;
}
if (! str_cmp (arg2, "race")) {
if (! can_mmodify (ch, victim))
return;
if (! victim->IsNpc ()) {
CRaceData *pRace = RaceTable.Find (arg3);
if (! pRace) {
ch->SendTextf ("Unknown Race: %s.\n", arg3);
return;
}
else value = pRace->GetRace ();
} else {
value = is_number (arg3) ? atoi (arg3) :
RaceTable.GetNpcRace (arg3);
if (value < 0 || value >= MAX_NPC_RACE) {
ch->SendTextf ("Race range is 0 to %d.\n", MAX_NPC_RACE-1);
return;
}
}
victim->SetRace (value);
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->race = value;
return;
}
if (! str_cmp (arg2, "armor")) {
if (! can_mmodify (ch, victim))
return;
if (value < -300 || value > 300) {
ch->SendText ("AC range is -300 to 300.\n\r");
return;
}
victim->SetArmor (value);
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->ac = value;
return;
}
if (! str_cmp (arg2, "level")) {
if (! can_mmodify (ch, victim))
return;
if (! victim->IsNpc ()) {
ch->SendText ("Not on PC's.\n\r");
return;
}
if (value < 0 || value > LEVEL_AVATAR + 5) {
ch->SendTextf ("Level range is 0 to %d.\n\r", LEVEL_AVATAR + 5);
return;
}
victim->SetLevel (value);
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->level = value;
return;
}
if (! str_cmp (arg2, "numattacks")) {
if (! can_mmodify (ch, victim))
return;
if (! victim->IsNpc ()) {
ch->SendText ("Not on PC's.\n\r");
return;
}
if (value < 0 || value > 20) {
ch->SendText ("Attacks range is 0 to 20.\n\r");
return;
}
victim->numattacks = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->numattacks = value;
return;
}
if (! str_cmp (arg2, "gold")) {
if (! can_mmodify (ch, victim))
return;
victim->SetGold (value);
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->gold = value;
return;
}
if (! str_cmp (arg2, "hitroll")) {
if (! can_mmodify (ch, victim))
return;
victim->SetHitroll (URANGE (0, value, 85));
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->hitroll = victim->GetHitroll ();
return;
}
if (! str_cmp (arg2, "damroll")) {
if (! can_mmodify (ch, victim))
return;
victim->SetDamroll (URANGE (0, value, 65));
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->damroll = victim->GetDamroll ();
return;
}
if (! str_cmp (arg2, "maxhp")) {
if (! can_mmodify (ch, victim))
return;
if (value < 1 || value > 32700) {
ch->SendText ("Max Hp range is 1 to 32,700 hit points.\n\r");
return;
}
victim->SetMaxHp (value);
return;
}
if (! str_cmp (arg2, "maxmana")) {
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 30000) {
ch->SendText ("Mana range is 0 to 30,000 mana points.\n\r");
return;
}
victim->SetMaxMana (value);
return;
}
if (! str_cmp (arg2, "maxmove")) {
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 30000) {
ch->SendText ("Move range is 0 to 30,000 move points.\n\r");
return;
}
victim->SetMaxMove (value);
return;
}
if (! str_cmp (arg2, "practice")) {
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 100) {
ch->SendText ("Practice range is 0 to 100 sessions.\n\r");
return;
}
victim->SetPractices (value);
return;
}
if (! str_cmp (arg2, "align")) {
if (! can_mmodify (ch, victim))
return;
if (value < -1000 || value > 1000) {
ch->SendText ("Alignment range is -1000 to 1000.\n\r");
return;
}
victim->SetAlignment (value);
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->alignment = value;
return;
}
if (! str_cmp (arg2, "password")) {
if (ch->GetTrustLevel () < LEVEL_SUB_IMPLEM) {
ch->SendText ("You can't do that.\n\r");
return;
}
if (victim->IsNpc ()) {
ch->SendText ("Mobs don't have passwords.\n\r");
return;
}
if (strlen (arg3) < 5) {
ch->SendText (
"New password must be at least five characters long.\n\r");
return;
}
// No tilde allowed because of player file format.
CString NewPwd = Crypt (arg3, victim->GetName ());
if (NewPwd.Find ('~') > -1) {
ch->SendText ("New password not acceptable, try again.\n\r");
return;
}
delete Vpc.GetPassWord ();
Vpc.SetPassWord (str_dup (NewPwd));
if (SysData.IsSavePasswordOnChange ())
save_char_obj (victim);
ch->SendText ("Ok.\n\r");
victim->SendTextf ("Your password has been changed by %s.\n\r",
ch->GetName ());
return;
}
if (! str_cmp (arg2, "rank")) {
if (ch->GetTrustLevel () < LEVEL_GOD) {
ch->SendText ("You can't do that.\n\r");
return;
}
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
smash_tilde (argument);
delete Vpc.GetRank ();
if (! argument || argument [0] == '\0' || ! str_cmp (argument, "none"))
Vpc.SetRank (str_dup (""));
else
Vpc.SetRank (str_dup (argument));
ch->SendText ("Ok.\n\r");
return;
}
if (! str_cmp (arg2, "quest")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (value < 0 || value > 500) {
ch->SendText ("The current quest range is 0 to 500.\n\r");
return;
}
Vpc.quest_number = value;
return;
}
if (! str_cmp (arg2, "qpa")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
Vpc.quest_accum = value;
return;
}
if (! str_cmp (arg2, "qp")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (value < 0 || value > 5000) {
ch->SendText ("The current quest point range is 0 to 5000.\n\r");
return;
}
Vpc.quest_curr = value;
return;
}
if (! str_cmp (arg2, "favor")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (value < -1500 || value > 1500) {
ch->SendText ("Range is from -1500 to 1500.\n\r");
return;
}
Vpc.favor = value;
return;
}
if (! str_cmp (arg2, "mentalstate")) {
if (value < -100 || value > 100) {
ch->SendText ("Value must be in range -100 to +100.\n\r");
return;
}
victim->SetMentalState (value);
return;
}
if (! str_cmp (arg2, "emotion")) {
if (value < -100 || value > 100) {
ch->SendText ("Value must be in range -100 to +100.\n\r");
return;
}
victim->emotional_state = value;
return;
}
if (! str_cmp (arg2, "thirst")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (value < 0 || value > 100) {
ch->SendText ("Thirst range is 0 to 100.\n\r");
return;
}
Vpc.condition[COND_THIRST] = value;
return;
}
if (! str_cmp (arg2, "drunk")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (value < 0 || value > 100) {
ch->SendText ("Drunk range is 0 to 100.\n\r");
return;
}
Vpc.condition[COND_DRUNK] = value;
return;
}
if (! strcmp (arg2, "full")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (value < 0 || value > 100) {
ch->SendText ("Full range is 0 to 100.\n\r");
return;
}
Vpc.condition[COND_FULL] = value;
return;
}
if (! str_cmp (arg2, "blood")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (value < 0 || value > MAX_LEVEL+10) {
ch->SendTextf ("Blood range is 0 to %d.\n\r", MAX_LEVEL+10);
return;
}
Vpc.condition [COND_BLOODTHIRST] = value;
return;
}
if (! str_cmp (arg2, "name")) {
if (! can_mmodify (ch, victim))
return;
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_SUB_IMPLEM) {
ch->SendText ("Not on PC's.\n\r");
return;
}
victim->SetName (arg3);
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE)) {
STRFREE (victim->GetMobIndex ()->GetPlayerName ());
victim->GetMobIndex ()->SetPlayerName (
QUICKLINK (victim->GetName ()));
}
return;
}
if (! str_cmp (arg2, "minsnoop")) {
if (ch->GetTrustLevel () < LEVEL_SUB_IMPLEM) {
ch->SendText ("You can't do that.\n\r");
return;
}
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (&Vpc) {
Vpc.min_snoop = value;
return;
}
}
if (! str_cmp (arg2, "clan")) {
if (ch->GetTrustLevel () < LEVEL_GREATER) {
ch->SendText ("You can't do that.\n\r");
return;
}
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (! arg3 || arg3 [0] == '\0') {
STRFREE (Vpc.GetClanName ());
Vpc.SetClanName (STRALLOC (""));
CClanData &Clan = *Vpc.GetClan ();
if (&Clan) {
Vpc.SetClan (NULL);
Clan.AddMembers (-1);
Clan.Save ();
ch->SendTextf ("Removed %s from %s.\n\r",
victim->GetName (), Clan.GetName ());
}
return;
}
CClanData &Clan = *ClanList.Find (arg3, CLAN_ALL);
if (! &Clan) {
ch->SendText ("No such clan.\n\r");
return;
}
STRFREE (Vpc.GetClanName ());
Vpc.SetClanName (QUICKLINK (Clan.GetName ()));
Vpc.SetClan (&Clan);
Clan.AddMembers (1);
Clan.Save ();
ch->SendTextf ("Added %s to %s.\n\r", victim->GetName (),
Clan.GetName ());
return;
}
if (! str_cmp (arg2, "deity")) {
CDeityData *deity;
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (! arg3 || arg3 [0] == '\0') {
STRFREE (Vpc.GetDeityName ());
Vpc.SetDeityName (STRALLOC (""));
Vpc.deity = NULL;
ch->SendText ("Deity removed.\n\r");
return;
}
deity = get_deity (arg3);
if (! deity) {
ch->SendText ("No such deity.\n\r");
return;
}
STRFREE (Vpc.GetDeityName ());
Vpc.SetDeityName (QUICKLINK (deity->GetName ()));
Vpc.deity = deity;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "council")) {
if (ch->GetTrustLevel () < LEVEL_SUB_IMPLEM) {
ch->SendText ("You can't do that.\n\r");
return;
}
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
if (! arg3 || arg3 [0] == '\0') {
STRFREE (Vpc.GetCouncilName ());
Vpc.SetCouncilName (STRALLOC (""));
CCouncilData &Council = *Vpc.council;
if (&Council) {
Vpc.council = NULL;
Council.AddMembers (-1);
save_council (&Council);
ch->SendTextf ("Removed %s from %s.\n\r", victim->GetName (),
Council.GetName ());
}
return;
}
CCouncilData &Council = *get_council (arg3);
if (! &Council) {
ch->SendText ("No such council.\n\r");
return;
}
STRFREE (Vpc.GetCouncilName ());
Vpc.SetCouncilName (QUICKLINK (Council.GetName ()));
Vpc.council = &Council;
Council.AddMembers (1);
save_council (&Council);
ch->SendTextf ("Added %s to %s.\n\r", victim->GetName (),
Council.GetName ());
return;
}
if (! str_cmp (arg2, "short")) {
victim->SetShortDescr (arg3);
if (victim->IsNpc () && victim->IsPrototype ()) {
STRFREE (victim->GetMobIndex ()->GetShortDescr ());
victim->GetMobIndex ()->SetShortDescr (
QUICKLINK (victim->GetShortDescr ()));
}
return;
}
if (! str_cmp (arg2, "long")) {
strcpy (buf, arg3);
strcat (buf, "\n\r");
victim->SetLongDescr (buf);
if (victim->IsNpc () && victim->IsPrototype ()) {
STRFREE (victim->GetMobIndex ()->GetLongDescr ());
victim->GetMobIndex ()->SetLongDescr (
QUICKLINK (victim->GetLongDescr ()));
}
return;
}
if (! str_cmp (arg2, "description")) {
if (arg3 [0]) {
victim->SetDescription (arg3);
if (victim->IsNpc () && victim->IsPrototype ()) {
STRFREE (victim->GetMobIndex ()->GetDescription ());
victim->GetMobIndex ()->SetDescription (
QUICKLINK (victim->GetDescription ()));
}
return;
}
ch->CheckSubrestricted ();
if (ch->GetSubstate () == SUB_REPEATCMD)
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
ch->SetSubstate (SUB_MOB_DESC);
ch->dest_buf = victim;
start_editing (ch, victim->GetDescription ());
return;
}
if (! str_cmp (arg2, "title")) {
if (victim->IsNpc ()) {
ch->SendText ("Not on NPC's.\n\r");
return;
}
set_title (victim, arg3);
return;
}
if (! str_cmp (arg2, "spec")) {
if (! can_mmodify (ch, victim))
return;
if (! victim->IsNpc ()) {
ch->SendText ("Not on PC's.\n\r");
return;
}
if (! str_cmp (arg3, "none")) {
victim->SetSpecialMobFunction (NULL);
ch->SendText ("Special function removed.\n\r");
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->spec_fun =
victim->GetSpecialMobFunction ();
return;
}
victim->SetSpecialMobFunction (spec_lookup (arg3));
if (victim->GetSpecialMobFunction () == NULL) {
ch->SendText ("No such spec fun.\n\r");
return;
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->spec_fun =
victim->GetSpecialMobFunction ();
return;
}
if (! str_cmp (arg2, "flags")) {
BOOL pcflag;
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_GREATER) {
ch->SendText ("You can only modify a mobile's flags.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: mset <victim> flags <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
pcflag = FALSE;
argument = one_argument (argument, arg3);
value = victim->IsNpc () ?
get_actflag (arg3) : get_plrflag (arg3);
if (! victim->IsNpc () && value < 0) {
pcflag = TRUE;
value = get_pcflag (arg3);
}
if (value < 0) {
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
return;
}
if (victim->IsNpc ()
&& value == ACT_PROTOTYPE
&& ch->GetTrustLevel () < LEVEL_GREATER
&& !is_name ("protoflag", Cpc.GetBestowments ()))
ch->SendText ("You cannot change the prototype flag.\n\r");
else
if (victim->IsNpc () && value == ACT_IS_NPC)
ch->SendText ("If that could be changed, it would "
"cause many problems.\n\r");
else
if (victim->IsNpc () && value == ACT_POLYMORPHED)
ch->SendText ("Changing that would be a _bad_ thing.\n\r");
else {
if (pcflag)
victim->TogglePcFlag (value);
else {
victim->ToggleActBit (value);
// NPC check added by Gorog
if (victim->IsNpc () && (value == ACT_PROTOTYPE))
victim->GetMobIndex ()->SetActFlags (
victim->GetActFlags ());
}
}
}
if (victim->IsNpc () && victim->IsPrototype ())
victim->GetMobIndex ()->SetActFlags (victim->GetActFlags ());
return;
}
if (! str_cmp (arg2, "mobinvislevel")) {
if (! victim->IsNpc ()) {
ch->SendText ("PC's cannot be mobinvis./r/n");
return;
}
victim->SetMobInvisLevel (atoi (argument));
if (victim->IsPrototype ())
victim->GetMobIndex ()->SetMobInvisLevel (atoi (argument));
return;
}
if (! str_cmp (arg2, "affected")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's flags.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument[0] == '\0') {
ch->SendText ("Usage: mset <victim> affected <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_aflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
victim->ToggleAffect (value);
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->SetAffectFlags (victim->GetAffectFlags ());
return;
}
// save some more finger-leather for setting RIS stuff
if (! str_cmp (arg2, "r")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's ris.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
sprintf (outbuf,"%s resistant %s",arg1, arg3);
do_mset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "i")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's ris.\n\r");
return;
}
if (!can_mmodify (ch, victim))
return;
sprintf (outbuf,"%s immune %s",arg1, arg3);
do_mset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "s")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's ris.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
sprintf (outbuf,"%s susceptible %s",arg1, arg3);
do_mset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "ri")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's ris.\n\r");
return;
}
if (!can_mmodify (ch, victim))
return;
sprintf (outbuf,"%s resistant %s",arg1, arg3);
do_mset (ch, outbuf);
sprintf (outbuf,"%s immune %s",arg1, arg3);
do_mset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "rs")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's ris.\n\r");
return;
}
if (!can_mmodify (ch, victim))
return;
sprintf (outbuf,"%s resistant %s",arg1, arg3);
do_mset (ch, outbuf);
sprintf (outbuf,"%s susceptible %s",arg1, arg3);
do_mset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "is")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's ris.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
sprintf (outbuf,"%s immune %s",arg1, arg3);
do_mset (ch, outbuf);
sprintf (outbuf,"%s susceptible %s",arg1, arg3);
do_mset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "ris")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's ris.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
sprintf (outbuf,"%s resistant %s",arg1, arg3);
do_mset (ch, outbuf);
sprintf (outbuf,"%s immune %s",arg1, arg3);
do_mset (ch, outbuf);
sprintf (outbuf,"%s susceptible %s",arg1, arg3);
do_mset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "resistant")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's resistances.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument[0] == '\0') {
ch->SendText ("Usage: mset <victim> resistant <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_risflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
victim->ToggleResist (1 << value);
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->resistant = victim->GetResistFlags ();
return;
}
if (! str_cmp (arg2, "immune")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's immunities.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument[0] == '\0') {
ch->SendText ("Usage: mset <victim> immune <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_risflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
victim->ToggleImmune (1 << value);
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->immune = victim->GetImmuneFlags ();
return;
}
if (! str_cmp (arg2, "susceptible")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's susceptibilities.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument[0] == '\0') {
ch->SendText ("Usage: mset <victim> susceptible <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_risflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
victim->ToggleSuscept (1 << value);
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->susceptible = victim->GetSusceptFlags ();
return;
}
if (! str_cmp (arg2, "part")) {
if (! victim->IsNpc () && ch->GetTrustLevel () < LEVEL_LESSER) {
ch->SendText ("You can only modify a mobile's parts.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument[0] == '\0') {
ch->SendText ("Usage: mset <victim> part <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_partflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
victim->ToggleXFlag (1 << value);
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->xflags = victim->GetXFlags ();
return;
}
if (! str_cmp (arg2, "attack")) {
if (! victim->IsNpc ()) {
ch->SendText ("You can only modify a mobile's attacks.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: mset <victim> attack <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_attackflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
victim->ToggleAttack (value);
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->SetAttackFlags (victim->GetAttackFlags ());
return;
}
if (! str_cmp (arg2, "defense")) {
if (! victim->IsNpc ()) {
ch->SendText ("You can only modify a mobile's defenses.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: mset <victim> defense <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_defenseflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
victim->ToggleDefense (value);
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->SetDefenseFlags (victim->GetDefenseFlags ());
return;
}
if (! str_cmp (arg2, "pos")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > POS_STANDING) {
ch->SendTextf ("Position range is 0 to %d.\n\r", POS_STANDING);
return;
}
victim->SetPosition (value);
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->position = victim->GetPosition ();
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "defpos")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > POS_STANDING) {
ch->SendTextf ("Position range is 0 to %d.\n\r", POS_STANDING);
return;
}
victim->defposition = value;
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->defposition = victim->defposition;
ch->SendText ("Done.\n\r");
return;
}
// save some finger-leather
if (! str_cmp (arg2, "hitdie")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
sscanf (arg3,"%d %c %d %c %d",&num,&char1,&size,&char2,&plus);
sprintf (outbuf,"%s hitnumdie %d",arg1, num);
do_mset (ch, outbuf);
sprintf (outbuf,"%s hitsizedie %d",arg1, size);
do_mset (ch, outbuf);
sprintf (outbuf,"%s hitplus %d",arg1, plus);
do_mset (ch, outbuf);
return;
}
// save some more finger-leather
if (! str_cmp (arg2, "damdie")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
sscanf (arg3,"%d %c %d %c %d",&num,&char1,&size,&char2,&plus);
sprintf (outbuf,"%s damnumdie %d",arg1, num);
do_mset (ch, outbuf);
sprintf (outbuf,"%s damsizedie %d",arg1, size);
do_mset (ch, outbuf);
sprintf (outbuf,"%s damplus %d",arg1, plus);
do_mset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "hitnumdie")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 32767) {
ch->SendText ("Number of hitpoint dice range is 0 to 30000.\n\r");
return;
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->hitnodice = value;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "hitsizedie")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 32767) {
ch->SendText ("Hitpoint dice size range is 0 to 30000.\n\r");
return;
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->hitsizedice = value;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "hitplus")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 32767) {
ch->SendText ("Hitpoint bonus range is 0 to 30000.\n\r");
return;
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->hitplus = value;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "damnumdie")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 100) {
ch->SendText ("Number of damage dice range is 0 to 100.\n\r");
return;
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->damnodice = value;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "damsizedie")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 100) {
ch->SendText ("Damage dice size range is 0 to 100.\n\r");
return;
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->damsizedice = value;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "damplus")) {
if (! victim->IsNpc ()) {
ch->SendText ("Mobiles only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (value < 0 || value > 1000) {
ch->SendText ("Damage bonus range is 0 to 1000.\n\r");
return;
}
if (victim->IsNpc () && victim->IsAction (ACT_PROTOTYPE))
victim->GetMobIndex ()->damplus = value;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "aloaded")) {
if (victim->IsNpc ()) {
ch->SendText ("Player Characters only.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
CAreaData &Area = *victim->GetArea ();
if (! Area.IsLoaded ()) {
Area.SetLoaded ();
victim->SendText ("Your area set to LOADED!\n\r");
if (ch != victim)
ch->SendText ("Area set to LOADED!\n\r");
return;
} else {
Area.ClrLoaded ();
victim->SendText ("Your area set to NOT-LOADED!\n\r");
if (ch != victim)
ch->SendText ("Area set to NON-LOADED!\n\r");
return;
}
}
if (! str_cmp (arg2, "pkill")) {
if (victim->IsNpc ()) {
ch->SendText ("Player Characters only.\n\r");
return;
}
if (! can_mmodify (ch, victim)) {
ch->SendText ("You can't do that.\n\r");
return;
}
if (victim->IsPkiller ()) {
victim->ClrPkiller ();
victim->SendText ("You are now a NON-PKILL player.\n\r");
if (ch != victim)
ch->SendText ("That player is now non-pkill.\n\r");
return;
} else {
victim->SetPkiller ();
victim->SendText ("You are now a PKILL player.\n\r");
if (ch != victim)
ch->SendText ("That player is now pkill.\n\r");
return;
}
}
if (! str_cmp (arg2, "speaks")) {
if (! can_mmodify (ch, victim))
return;
if (! argument || argument [0] == '\0') {
ch->SendText (
"Usage: mset <victim> speaks <language> [language] ...\n\r");
return;
}
bool bLangFound = FALSE;
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
CLanguage &La = *LanguageTable.Find (arg3);
if (! &La) {
ch->SendTextf ("Unknown language: %s\n\r", arg3);
continue;
}
else if (! victim->IsNpc ()) {
if (! La.CanLearn ()) {
ch->SendTextf ("Players may not know %s.\n\r", La.GetName ());
continue;
}
}
victim->SetSpeaks (La.GetLanguage ());
bLangFound = TRUE;
}
if (bLangFound) {
if (! victim->IsNpc ()) {
// Again, don't see why racial language not in speaks vector,
// Removed clearing of the bits - Rustry
// REMOVE_BIT (victim->speaks,
// RaceTable.GetLanguages (victim->GetRace ()));
if (! knows_language (victim, victim->GetSpeaking (), victim))
victim->SetSpeaksFlags (RaceTable.GetLanguages (
victim->GetRace ()));
}
else
if (victim->IsPrototype ())
victim->GetMobIndex ()->SetSpeaksFlags (
victim->GetSpeaksFlags ());
ch->SendText ("Done.\n\r");
}
return;
}
if (! str_cmp (arg2, "speaking")) {
if (! victim->IsNpc ()) {
ch->SendText ("Players must choose the language they speak "
"themselves.\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: mset <victim> speaking <language>\n\r");
return;
}
argument = one_argument (argument, arg3);
CLanguage &La = *LanguageTable.Find (arg3);
if (&La) {
victim->SetSpeaking (La.GetLanguage ());
if (victim->IsNpc () && victim->IsPrototype ())
victim->GetMobIndex ()->SetSpeaking (victim->GetSpeaking ());
ch->SendText ("Done.\n\r");
}
else
ch->SendTextf ("Unknown language: %s\n\r", arg3);
return;
}
// Generate usage message.
if (ch->GetSubstate () == SUB_REPEATCMD) {
ch->SetSubstate (SUB_RESTRICTED);
interpret (ch, origarg);
ch->SetSubstate (SUB_REPEATCMD);
ch->last_cmd = do_mset;
}
else do_mset (ch, "");
}
void do_oset (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char buf [MAX_STRING_LENGTH];
char outbuf [MAX_STRING_LENGTH];
CObjData *obj, *tmpobj;
CExtraDescrData *ed;
BOOL lockobj;
char *origarg = argument;
int value, tmp;
if (ch->IsNpc ()) {
ch->SendText ("Mob's can't oset\n\r");
return;
}
if (! ch->GetDesc ()) {
ch->SendText ("You have no descriptor\n\r");
return;
}
switch (ch->GetSubstate ()) {
default:
break;
case SUB_OBJ_EXTRA:
if (! ch->dest_buf) {
ch->SendTextf ("Fatal error: report to %s.\n\r",
SysData.GetSupremeEntity ());
bug ("do_oset: sub_obj_extra: NULL ch->dest_buf");
ch->SetSubstate (SUB_NONE);
return;
}
// hopefully the object didn't get extracted...
// if you're REALLY paranoid, you could always go through
// the object and index-object lists, searching through the
// extra_descr lists for a matching pointer...
ed = (CExtraDescrData *) ch->dest_buf;
STRFREE (ed->description);
ed->description = ch->GetEditBuffer ();
tmpobj = (CObjData*) ch->spare_ptr;
ch->StopEditing ();
ch->dest_buf = tmpobj;
ch->SetSubstate (ch->tempnum);
return;
case SUB_OBJ_LONG:
if (! ch->dest_buf) {
ch->SendTextf ("Fatal error: report to %s.\n\r",
SysData.GetSupremeEntity ());
bug ("do_oset: sub_obj_long: NULL ch->dest_buf");
ch->SetSubstate (SUB_NONE);
return;
}
obj = (CObjData*) ch->dest_buf;
if (obj && obj_extracted (obj)) {
ch->SendText ("Your object was extracted!\n\r");
ch->StopEditing ();
return;
}
obj->SetDescriptionNA (ch->GetEditBuffer ());
if (obj->IsPrototype () && can_omodify (ch, obj))
obj->pIndexData->SetDescription (obj->GetDescription ());
tmpobj = (CObjData*) ch->spare_ptr;
ch->StopEditing ();
ch->SetSubstate (ch->tempnum);
ch->dest_buf = tmpobj;
return;
}
obj = NULL;
smash_tilde (argument);
if (ch->GetSubstate () == SUB_REPEATCMD) {
obj = (CObjData*) ch->dest_buf;
if (obj && obj_extracted (obj)) {
ch->SendText ("Your object was extracted!\n\r");
obj = NULL;
argument = "done";
}
if (argument [0] == '\0' || !str_cmp (argument, " ")
|| ! str_cmp (argument, "stat")) {
if (obj)
do_ostat (ch, NCCP obj->GetName ());
else
ch->SendText ("No object selected. Type '?' for help.\n\r");
return;
}
if (! str_cmp (argument, "done") || !str_cmp (argument, "off")) {
ch->SendText ("Oset mode off.\n\r");
ch->SetSubstate (SUB_NONE);
ch->dest_buf = NULL;
if (ch->GetPcData () && ch->GetPcData ()->HasSubPrompt ()) {
STRFREE (ch->GetPcData ()->GetSubPrompt ());
ch->GetPcData ()->SetSubPrompt (NULL);
}
return;
}
}
if (obj) {
lockobj = TRUE;
strcpy (arg1, obj->GetName ());
argument = one_argument (argument, arg2);
strcpy (arg3, argument);
} else {
lockobj = FALSE;
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
strcpy (arg3, argument);
}
if (! str_cmp (arg1, "on")) {
ch->SendText ("Syntax: oset <object|vnum> on.\n\r");
return;
}
if (arg1 [0] == '\0' || arg2 [0] == '\0' || ! str_cmp (arg1, "?")) {
if (ch->GetSubstate () == SUB_REPEATCMD) {
if (obj)
ch->SendText ("Syntax: <field> <value>\n\r");
else
ch->SendText ("Syntax: <object> <field> <value>\n\r");
}
else
ch->SendText ("Syntax: oset <object> <field> <value>\n\r");
ch->SendText ("\n\r");
ch->SendText ("Field being one of: anticlass,\n\r");
ch->SendText (" flags wear level weight cost timer\n\r");
ch->SendText (" name short long ed rmed actiondesc\n\r");
ch->SendText (" type value0 value1 value2 value3 value4 value5\n\r");
ch->SendText (" affect rmaffect layers\n\r");
ch->SendText ("For weapons: For armor:\n\r");
ch->SendText (" weapontype condition ac condition\n\r");
ch->SendText ("For scrolls, potions and pills:\n\r");
ch->SendText (" slevel spell1 spell2 spell3\n\r");
ch->SendText ("For wands and staves:\n\r");
ch->SendText (" slevel spell maxcharges charges\n\r");
ch->SendText ("For containers: For levers and switches:\n\r");
ch->SendText (" cflags key capacity tflags\n\r");
return;
}
if (! obj && ch->GetTrustLevel () < LEVEL_GOD) {
if ((obj = get_obj_here (ch, arg1)) == NULL) {
ch->SendText ("You can't find that here.\n\r");
return;
}
}
else if (! obj) {
if ((obj = get_obj_world (ch, arg1)) == NULL) {
ch->SendTextf ("There is nothing like that in all the %s.\n\r",
SysData.GetShortTitle ());
return;
}
}
if (lockobj)
ch->dest_buf = obj;
else
ch->dest_buf = NULL;
separate_obj (obj);
value = atoi (arg3);
if (! str_cmp (arg2, "on")) {
ch->SendTextf ("Oset mode on. (Editing '%s' vnum %d).\n\r",
obj->GetName (), obj->pIndexData->vnum);
ch->SetSubstate (SUB_REPEATCMD);
ch->dest_buf = obj;
if (ch->GetPcData ()) {
if (ch->GetPcData ()->HasSubPrompt ())
STRFREE (ch->GetPcData ()->GetSubPrompt ());
sprintf (buf, "<&COset &W#%d&w> %%i", obj->pIndexData->vnum);
ch->GetPcData ()->SetSubPrompt (STRALLOC (buf));
}
return;
}
if (! str_cmp (arg2, "value0") || !str_cmp (arg2, "v0")) {
if (! can_omodify (ch, obj))
return;
obj->value [0] = value;
if (obj->IsPrototype ())
obj->pIndexData->value [0] = value;
return;
}
if (! str_cmp (arg2, "value1") || ! str_cmp (arg2, "v1")) {
if (! can_omodify (ch, obj))
return;
obj->value [1] = value;
if (obj->IsPrototype ())
obj->pIndexData->value [1] = value;
return;
}
if (! str_cmp (arg2, "value2") || ! str_cmp (arg2, "v2")) {
if (! can_omodify (ch, obj))
return;
obj->value [2] = value;
if (obj->IsPrototype ()) {
obj->pIndexData->value [2] = value;
if (obj->item_type == ITEM_WEAPON && value != 0)
obj->value [2] =
obj->pIndexData->value [1] * obj->pIndexData->value [2];
}
return;
}
if (! str_cmp (arg2, "value3") || ! str_cmp (arg2, "v3")) {
if (! can_omodify (ch, obj))
return;
obj->value [3] = value;
if (obj->IsPrototype ())
obj->pIndexData->value [3] = value;
return;
}
if (! str_cmp (arg2, "value4") || ! str_cmp (arg2, "v4")) {
if (! can_omodify (ch, obj))
return;
obj->value [4] = value;
if (obj->IsPrototype ())
obj->pIndexData->value [4] = value;
return;
}
if (! str_cmp (arg2, "value5") || ! str_cmp (arg2, "v5")) {
if (! can_omodify (ch, obj))
return;
obj->value [5] = value;
if (obj->IsPrototype ())
obj->pIndexData->value [5] = value;
return;
}
if (! str_cmp (arg2, "type")) {
if (! can_omodify (ch, obj))
return;
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: oset <object> type <type>\n\r");
return;
}
value = get_otype (argument);
if (value < 1) {
ch->SendTextf ("Unknown type: %s\n\r", arg3);
return;
}
obj->item_type = (short) value;
if (obj->IsPrototype ())
obj->pIndexData->item_type = obj->item_type;
return;
}
if (! str_cmp (arg2, "anticlass")) {
if (! can_omodify (ch, obj))
return;
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: oset <object> anticlass <classname> [classname]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
CClassData *pClass = ClassTable.Find (arg3);
if (! pClass)
ch->SendTextf ("Unknown class: %s\n\r", arg3);
else obj->ToggleAntiClass (pClass->GetClass ());
}
if (obj->IsPrototype ())
obj->pIndexData->SetAntiClassFlags (obj->GetAntiClassFlags ());
return;
}
if (! str_cmp (arg2, "flags")) {
if (! can_omodify (ch, obj))
return;
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: oset <object> flags <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_oflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else {
if (value == ITEM_PROTOTYPE
&& ch->GetTrustLevel () < LEVEL_GREATER
&& !is_name ("protoflag", ch->GetPcData ()->GetBestowments ()))
ch->SendText ("You cannot change the prototype flag.\n\r");
else {
obj->m_ExtraFlags.ToggleBit (value);
if (value == ITEM_PROTOTYPE)
obj->pIndexData->m_ExtraFlags = obj->m_ExtraFlags;
}
}
}
if (obj->IsPrototype ())
obj->pIndexData->m_ExtraFlags = obj->m_ExtraFlags;
return;
}
if (! str_cmp (arg2, "wear")) {
if (! can_omodify (ch, obj))
return;
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: oset <object> wear <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_wflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
TOGGLE_BIT (obj->wear_flags, 1 << value);
}
if (obj->IsPrototype ())
obj->pIndexData->wear_flags = obj->wear_flags;
return;
}
if (! str_cmp (arg2, "level")) {
if (can_omodify (ch, obj)) {
obj->level = value;
if (obj->IsPrototype ()) // Added 8/30/98 RCP
obj->pIndexData->level = value;
}
return;
}
if (! str_cmp (arg2, "weight")) {
if (can_omodify (ch, obj)) {
obj->weight = value;
if (obj->IsPrototype ())
obj->pIndexData->weight = value;
}
return;
}
if (! str_cmp (arg2, "cost")) {
if (can_omodify (ch, obj)) {
obj->cost = value;
if (obj->IsPrototype ())
obj->pIndexData->cost = value;
}
return;
}
if (! str_cmp (arg2, "layers")) {
if (can_omodify (ch, obj)) {
if (obj->IsPrototype ())
obj->pIndexData->layers = value;
else
ch->SendText (
"Item must have prototype flag to set this value.\n\r");
}
return;
}
if (! str_cmp (arg2, "timer")) {
if (can_omodify (ch, obj))
obj->timer = value;
return;
}
if (! str_cmp (arg2, "name")) {
if (can_omodify (ch, obj)) {
obj->SetName (arg3);
if (obj->IsPrototype ())
obj->pIndexData->SetName (arg3);
}
return;
}
if (! str_cmp (arg2, "short")) {
obj->SetShortDescr (arg3);
if (obj->IsPrototype ())
obj->pIndexData->SetShortDescr (arg3);
else {
// Feature added by Narn, Apr/96
// If the item is not proto, add the word 'rename' to the keywords
// if it is not already there.
if (str_infix ("rename", obj->GetName ())) {
sprintf (buf, "%s %s", obj->GetName (), "rename");
obj->SetName (buf);
}
}
return;
}
if (! str_cmp (arg2, "actiondesc")) {
if (strstr (arg3, "%n") || strstr (arg3, "%d")
|| strstr (arg3, "%l")) {
ch->SendText ("Illegal characters!\n\r");
return;
}
obj->SetActionDescr (arg3);
if (obj->IsPrototype ())
obj->pIndexData->SetActionDescr (arg3);
return;
}
if (! str_cmp (arg2, "long")) {
if (arg3 [0]) {
obj->SetDescription (arg3);
if (obj->IsPrototype ())
obj->pIndexData->SetDescription (arg3);
return;
}
ch->CheckSubrestricted ();
if (ch->GetSubstate () == SUB_REPEATCMD)
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
if (lockobj)
ch->spare_ptr = obj;
else
ch->spare_ptr = NULL;
ch->SetSubstate (SUB_OBJ_LONG);
ch->dest_buf = obj;
start_editing (ch, obj->GetDescription ());
return;
}
if (! str_cmp (arg2, "affect")) {
CAffectData *paf;
short loc;
int bitv;
argument = one_argument (argument, arg2);
if (! arg2 || arg2 [0] == '\0' || ! argument || argument [0] == 0) {
ch->SendText ("Usage: oset <object> affect <field> <value>\n\r");
return;
}
loc = get_atype (arg2);
if (loc < 1) {
ch->SendTextf ("Unknown field: %s\n\r", arg2);
return;
}
if (loc >= APPLY_AFFECT && loc < APPLY_WEAPONSPELL) {
bitv = 0;
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
if (loc == APPLY_AFFECT)
value = get_aflag (arg3);
else
value = get_risflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else
SET_BIT (bitv, 1 << value);
}
if (! bitv)
return;
value = bitv;
} else {
argument = one_argument (argument, arg3);
value = atoi (arg3);
}
paf = new CAffectData;
paf->location = loc;
paf->modifier = value;
if (obj->IsPrototype ())
obj->pIndexData->AddAffect (paf);
else
obj->AddAffect (paf);
++top_affect;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "rmaffect")) {
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: oset <object> rmaffect <affect#>\n\r");
return;
}
int loc = atoi (argument);
if (loc < 1) {
ch->SendText ("Invalid number.\n\r");
return;
}
// get the affect list from the index or the object
CAffectList *pList = &obj->pIndexData->AffList;
if (loc > pList->GetCount ()) {
loc -= pList->GetCount ();
pList = &obj->AffList;
}
POSITION apos = pList->FindIndex (loc-1);
if (apos) {
delete pList->GetAt (apos);
pList->RemoveAt (apos);
--top_affect;
ch->SendText ("Removed.\n\r");
}
else ch->SendText ("Not found.\n\r");
return;
}
if (! str_cmp (arg2, "ed")) {
if (! arg3 || arg3 [0] == '\0') {
ch->SendText ("Syntax: oset <object> ed <keywords>\n\r");
return;
}
if (ch->CheckSubrestricted ())
return;
if (obj->timer) {
ch->SendText ("It's not safe to edit an extra description on "
"an object with a timer.\n\rTurn it off first.\n\r");
return;
}
if (obj->item_type == ITEM_PAPER) {
ch->SendText ("You can not add an extra description to a "
"note paper at the moment.\n\r");
return;
}
if (obj->IsPrototype ())
ed = SetOExtraProto (obj->pIndexData, arg3);
else
ed = SetOExtra (obj, arg3);
if (ch->GetSubstate () == SUB_REPEATCMD)
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
if (lockobj)
ch->spare_ptr = obj;
else
ch->spare_ptr = NULL;
ch->SetSubstate (SUB_OBJ_EXTRA);
ch->dest_buf = ed;
start_editing (ch, ed->description);
return;
}
if (! str_cmp (arg2, "rmed")) {
if (! arg3 || arg3 [0] == '\0') {
ch->SendText ("Syntax: oset <object> rmed <keywords>\n\r");
return;
}
if (obj->IsPrototype ()) {
if (DelOExtraProto (obj->pIndexData, arg3))
ch->SendText ("Deleted.\n\r");
else
ch->SendText ("Not found.\n\r");
return;
}
if (DelOExtra (obj, arg3))
ch->SendText ("Deleted.\n\r");
else
ch->SendText ("Not found.\n\r");
return;
}
// save some finger-leather
if (! str_cmp (arg2, "ris")) {
sprintf (outbuf, "%s affect resistant %s", arg1, arg3);
do_oset (ch, outbuf);
sprintf (outbuf, "%s affect immune %s", arg1, arg3);
do_oset (ch, outbuf);
sprintf (outbuf, "%s affect susceptible %s", arg1, arg3);
do_oset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "r")) {
sprintf (outbuf, "%s affect resistant %s", arg1, arg3);
do_oset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "i")) {
sprintf (outbuf, "%s affect immune %s", arg1, arg3);
do_oset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "s")) {
sprintf (outbuf, "%s affect susceptible %s", arg1, arg3);
do_oset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "ri")) {
sprintf (outbuf, "%s affect resistant %s", arg1, arg3);
do_oset (ch, outbuf);
sprintf (outbuf, "%s affect immune %s", arg1, arg3);
do_oset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "rs")) {
sprintf (outbuf, "%s affect resistant %s", arg1, arg3);
do_oset (ch, outbuf);
sprintf (outbuf, "%s affect susceptible %s", arg1, arg3);
do_oset (ch, outbuf);
return;
}
if (! str_cmp (arg2, "is")) {
sprintf (outbuf, "%s affect immune %s", arg1, arg3);
do_oset (ch, outbuf);
sprintf (outbuf, "%s affect susceptible %s", arg1, arg3);
do_oset (ch, outbuf);
return;
}
// Make it easier to set special object values by name than number
// -Thoric
tmp = -1;
switch (obj->item_type) {
case ITEM_WEAPON:
if (!str_cmp (arg2, "weapontype")) {
int x;
value = -1;
for (x = 0; x < DIM (attack_table); ++x)
if (! str_cmp (arg3, attack_table [x]))
value = x;
if (value < 0) {
ch->SendText ("Unknown weapon type.\n\r");
return;
}
tmp = 3;
break;
}
if (! str_cmp (arg2, "condition")) then tmp = 0;
break;
case ITEM_ARMOR:
if (! str_cmp (arg2, "condition")) then tmp = 3;
if (!str_cmp (arg2, "ac")) then tmp = 1;
break;
case ITEM_SALVE:
if (!str_cmp (arg2, "slevel" )) then tmp = 0;
if (!str_cmp (arg2, "maxdoses")) then tmp = 1;
if (!str_cmp (arg2, "doses" )) then tmp = 2;
if (!str_cmp (arg2, "delay" )) then tmp = 3;
if (!str_cmp (arg2, "spell1" )) then tmp = 4;
if (!str_cmp (arg2, "spell2" )) then tmp = 5;
if (tmp >=4 && tmp <= 5) then value = SkillTable.Lookup (arg3);
break;
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
if (!str_cmp (arg2, "slevel")) then tmp = 0;
if (!str_cmp (arg2, "spell1")) then tmp = 1;
if (!str_cmp (arg2, "spell2")) then tmp = 2;
if (!str_cmp (arg2, "spell3")) then tmp = 3;
if (tmp >=1 && tmp <= 3) then value = SkillTable.Lookup (arg3);
break;
case ITEM_STAFF:
case ITEM_WAND:
if (! str_cmp (arg2, "slevel")) then tmp = 0;
if (! str_cmp (arg2, "spell")) {
tmp = 3;
value = SkillTable.Lookup (arg3);
}
if (! str_cmp (arg2, "maxcharges")) then tmp = 1;
if (! str_cmp (arg2, "charges")) then tmp = 2;
break;
case ITEM_CONTAINER:
if (! str_cmp (arg2, "capacity")) then tmp = 0;
if (! str_cmp (arg2, "cflags")) then tmp = 1;
if (! str_cmp (arg2, "key")) then tmp = 2;
break;
case ITEM_SWITCH:
case ITEM_LEVER:
case ITEM_PULLCHAIN:
case ITEM_BUTTON:
if (! str_cmp (arg2, "tflags")) {
tmp = 0;
value = get_trigflag (arg3);
}
break;
}
if (tmp >= 0 && tmp <= 3) {
if (! can_omodify (ch, obj))
return;
obj->value [tmp] = value;
if (obj->IsPrototype ())
obj->pIndexData->value [tmp] = value;
return;
}
// Generate usage message.
if (ch->GetSubstate () == SUB_REPEATCMD) {
ch->SetSubstate (SUB_RESTRICTED);
interpret (ch, origarg);
ch->SetSubstate (SUB_REPEATCMD);
ch->last_cmd = do_oset;
}
else
do_oset (ch, "");
}
// Obsolete Merc room editing routine
void do_rset (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
CRoomIndexData *location;
int value;
BOOL proto;
smash_tilde (argument);
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
strcpy (arg3, argument);
if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0') {
ch->SendText ("Syntax: rset <location> <field> value\n\r");
ch->SendText ("\n\r");
ch->SendText ("Field being one of:\n\r");
ch->SendText (" flags sector\n\r");
return;
}
if ((location = find_location (ch, arg1)) == NULL) {
ch->SendText ("No such location.\n\r");
return;
}
if (!can_rmodify (ch, location))
return;
if (!is_number (arg3)) {
ch->SendText ("Value must be numeric.\n\r");
return;
}
value = atoi (arg3);
// Set something.
if (!str_cmp (arg2, "flags")) {
// Protect from messing up prototype flag
proto = location->IsPrototype ();
location->SetRoomFlags (value);
if (proto)
location->SetPrototype ();
return;
}
if (!str_cmp (arg2, "sector")) {
location->sector_type = value;
return;
}
// Generate usage message.
do_rset (ch, "");
}
// Returns value 0 - 9 based on directional text.
int get_dir (char *txt)
{
int edir;
char c1, c2;
if (! str_cmp (txt, "northeast"))
return DIR_NORTHEAST;
if (! str_cmp (txt, "northwest"))
return DIR_NORTHWEST;
if (! str_cmp (txt, "southeast"))
return DIR_SOUTHEAST;
if (! str_cmp (txt, "southwest"))
return DIR_SOUTHWEST;
if (! str_cmp (txt, "somewhere"))
return 10;
c1 = txt [0];
if (c1 == '\0')
return 0;
c2 = txt [1];
edir = 0;
switch (c1) {
case 'n':
switch (c2) {
default:
edir = 0; break; // north
case 'e':
edir = 6; break; // ne
case 'w':
edir = 7; break; // nw
}
break;
case '0':
edir = 0; break; // north
case 'e':
case '1':
edir = 1; break; // east
case 's':
switch (c2) {
default:
edir = 2; break; // south
case 'e':
edir = 8; break; // se
case 'w':
edir = 9; break; // sw
}
break;
case '2':
edir = 2; break; // south
case 'w':
case '3':
edir = 3; break; // west
case 'u':
case '4':
edir = 4; break; // up
case 'd':
case '5':
edir = 5; break; // down
case '6':
edir = 6; break; // ne
case '7':
edir = 7; break; // nw
case '8':
edir = 8; break; // se
case '9':
edir = 9; break; // sw
case '?':
edir = 10; break; // somewhere
}
return edir;
}
void do_redit (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char buf [MAX_STRING_LENGTH];
CRoomIndexData *location, *tmp;
CExtraDescrData *ed;
char dir;
CExitData *xit, *texit;
int value;
int edir, ekey, evnum;
char *origarg = argument;
set_char_color (AT_PLAIN, ch);
switch (ch->GetSubstate ()) {
default:
break;
case SUB_ROOM_DESC:
location = (CRoomIndexData*) ch->dest_buf;
if (! location) {
bug ("redit: sub_room_desc: NULL ch->dest_buf");
location = ch->GetInRoom ();
}
location->SetDescriptionNA (ch->GetEditBuffer ());
ch->StopEditing ();
ch->SetSubstate (ch->tempnum);
return;
case SUB_ROOM_EXTRA:
ed = (CExtraDescrData *) ch->dest_buf;
if (! ed) {
bug ("redit: sub_room_extra: NULL ch->dest_buf");
ch->StopEditing ();
return;
}
STRFREE (ed->description);
ed->description = ch->GetEditBuffer ();
ch->StopEditing ();
ch->SetSubstate (ch->tempnum);
return;
}
location = ch->GetInRoom ();
smash_tilde (argument);
argument = one_argument (argument, arg);
if (ch->GetSubstate () == SUB_REPEATCMD) {
if (arg [0] == '\0') {
do_rstat (ch, "");
return;
}
if (! str_cmp (arg, "done") || ! str_cmp (arg, "off")) {
ch->SendText ("Redit mode off.\n\r");
if (ch->GetPcData () && ch->GetPcData ()->HasSubPrompt ()) {
STRFREE (ch->GetPcData ()->GetSubPrompt ());
ch->GetPcData ()->SetSubPrompt (NULL);
}
ch->SetSubstate (SUB_NONE);
return;
}
}
if (arg [0] == '\0' || ! str_cmp (arg, "?")) {
if (ch->GetSubstate () == SUB_REPEATCMD)
ch->SendText ("Syntax: <field> value\n\r");
else
ch->SendText ("Syntax: redit <field> value\n\r");
ch->SendText ("\n\r");
ch->SendText ("Field being one of:\n\r");
ch->SendText (" name desc ed rmed\n\r");
ch->SendText (" exit bexit exdesc exflags exname exkey\n\r");
ch->SendText (" flags sector teledelay televnum tunnel\n\r");
ch->SendText (" rlist exdistance\n\r");
return;
}
if (! can_rmodify (ch, location))
return;
if (! str_cmp (arg, "on")) {
ch->SendText ("Redit mode on.\n\r");
ch->SetSubstate (SUB_REPEATCMD);
if (ch->GetPcData ()) {
if (ch->GetPcData ()->HasSubPrompt ())
STRFREE (ch->GetPcData ()->GetSubPrompt ());
ch->GetPcData ()->SetSubPrompt (STRALLOC ("<&CRedit &W#%r&w> %i"));
}
return;
}
if (! str_cmp (arg, "substate")) {
argument = one_argument (argument, arg2);
if (! str_cmp (arg2, "north")) {
ch->SetSubstate (SUB_NORTH);
return;
}
if (! str_cmp (arg2, "east")) {
ch->SetSubstate (SUB_EAST);
return;
}
if (! str_cmp (arg2, "south")) {
ch->SetSubstate (SUB_SOUTH);
return;
}
if (! str_cmp (arg2, "west")) {
ch->SetSubstate (SUB_WEST);
return;
}
if (! str_cmp (arg2, "up")) {
ch->SetSubstate (SUB_UP);
return;
}
if (! str_cmp (arg2, "down")) {
ch->SetSubstate (SUB_DOWN);
return;
}
ch->SendText (" unrecognized substate in redit\n\r");
return;
}
if (! str_cmp (arg, "name")) {
if (argument [0] == '\0') {
ch->SendText ("Set the room name. A very brief single line "
"room description.\n\r");
ch->SendText ("Usage: redit name <Room summary>\n\r");
return;
}
location->SetName (STRALLOC (argument));
return;
}
if (! str_cmp (arg, "desc")) {
if (ch->GetSubstate () == SUB_REPEATCMD)
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
ch->SetSubstate (SUB_ROOM_DESC);
ch->dest_buf = location;
start_editing (ch, location->GetDescription ());
return;
}
if (! str_cmp (arg, "tunnel")) {
if (! argument || argument [0] == '\0') {
ch->SendText ("Set the maximum characters allowed in the "
"room at one time. (0 = unlimited).\n\r");
ch->SendText ("Usage: redit tunnel <value>\n\r");
return;
}
location->tunnel = URANGE (0, atoi (argument), 1000);
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg, "ed")) {
if (! argument || argument [0] == '\0') {
ch->SendText ("Create an extra description.\n\r");
ch->SendText ("You must supply keyword (s).\n\r");
return;
}
if (ch->CheckSubrestricted ())
return;
ed = SetRExtra (location, argument);
if (ch->GetSubstate () == SUB_REPEATCMD)
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
ch->SetSubstate (SUB_ROOM_EXTRA);
ch->dest_buf = ed;
start_editing (ch, ed->description);
return;
}
if (! str_cmp (arg, "rmed")) {
if (! argument || argument [0] == '\0') {
ch->SendText ("Remove an extra description.\n\r");
ch->SendText ("You must supply keyword (s).\n\r");
return;
}
if (DelRExtra (location, argument))
ch->SendText ("Deleted.\n\r");
else
ch->SendText ("Not found.\n\r");
return;
}
if (! str_cmp (arg, "flags")) {
if (! argument || argument [0] == '\0') {
ch->SendText ("Toggle the room flags.\n\r");
ch->SendText ("Usage: redit flags <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg2);
value = get_rflag (arg2);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg2);
else {
if (1 << value == ROOM_PROTOTYPE
&& ch->GetTrustLevel () < LEVEL_GREATER)
ch->SendText (
"You cannot change the prototype flag.\n\r");
else
location->ToggleRoomFlags (1 << value);
}
}
return;
}
if (!str_cmp (arg, "teledelay"))
{
if (!argument || argument[0] == '\0')
{
ch->SendText ("Set the delay of the teleport. (0 = off).\n\r");
ch->SendText ("Usage: redit teledelay <value>\n\r");
return;
}
location->tele_delay = atoi (argument);
ch->SendText ("Done.\n\r");
return;
}
if (!str_cmp (arg, "televnum"))
{
if (!argument || argument[0] == '\0')
{
ch->SendText ("Set the vnum of the room to teleport to.\n\r");
ch->SendText ("Usage: redit televnum <vnum>\n\r");
return;
}
location->tele_vnum = atoi (argument);
ch->SendText ("Done.\n\r");
return;
}
if (!str_cmp (arg, "sector"))
{
if (!argument || argument[0] == '\0')
{
ch->SendText ("Set the sector type.\n\r");
ch->SendText ("Usage: redit sector <value>\n\r");
return;
}
location->sector_type = atoi (argument);
if (location->sector_type < 0 || location->sector_type >= SECT_MAX)
{
location->sector_type = 1;
ch->SendText ("Out of range\n\r.");
}
else
ch->SendText ("Done.\n\r");
return;
}
if (!str_cmp (arg, "exkey"))
{
argument = one_argument (argument, arg2);
argument = one_argument (argument, arg3);
if (arg2[0] == '\0' || arg3[0] == '\0')
{
ch->SendText ("Usage: redit exkey <dir> <key vnum>\n\r");
return;
}
if (arg2[0] == '#')
{
edir = atoi (arg2+1);
xit = get_exit_num (location, edir);
}
else
{
edir = get_dir (arg2);
xit = get_exit (location, edir);
}
value = atoi (arg3);
if (!xit)
{
ch->SendText ("No exit in that direction. Use 'redit exit ...' first.\n\r");
return;
}
xit->key = value;
ch->SendText ("Done.\n\r");
return;
}
if (!str_cmp (arg, "exname"))
{
argument = one_argument (argument, arg2);
if (arg2[0] == '\0')
{
ch->SendText ("Change or clear exit keywords.\n\r");
ch->SendText ("Usage: redit exname <dir> [keywords]\n\r");
return;
}
if (arg2[0] == '#')
{
edir = atoi (arg2+1);
xit = get_exit_num (location, edir);
}
else
{
edir = get_dir (arg2);
xit = get_exit (location, edir);
}
if (!xit)
{
ch->SendText ("No exit in that direction. Use 'redit exit ...' first.\n\r");
return;
}
STRFREE (xit->keyword);
xit->keyword = STRALLOC (argument);
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg, "exflags")) {
if (! argument || argument [0] == '\0') {
ch->SendText ("Toggle or display exit flags.\n\r");
ch->SendText ("Usage: redit exflags <dir> <flag> [flag]...\n\r");
return;
}
argument = one_argument (argument, arg2);
if (arg2 [0] == '#') {
edir = atoi (arg2+1);
xit = get_exit_num (location, edir);
} else {
edir = get_dir (arg2);
xit = get_exit (location, edir);
}
if (! xit) {
ch->SendText ("No exit in that direction. Use 'redit "
"exit ...' first.\n\r");
return;
}
if (argument [0] == '\0') {
sprintf (buf, "Flags for exit direction: %d Keywords: %s "
"Key: %d\n\r[ ", xit->vdir, xit->keyword, xit->key);
for (value = 0; value < EX_MAX; ++value) {
if (xit->IsSet (value)) {
strcat (buf, ExitTypeNames [value]);
strcat (buf, " ");
}
}
strcat (buf, "]\n\r");
ch->SendText (buf);
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg2);
value = get_exflag (arg2);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg2);
else
xit->Toggle (value);
}
return;
}
if (! str_cmp (arg, "ex_flags")) {
argument = one_argument (argument, arg2);
switch (ch->GetSubstate ()) {
case SUB_EAST : dir = 'e'; edir = 1; break;
case SUB_WEST : dir = 'w'; edir = 3; break;
case SUB_SOUTH: dir = 's'; edir = 2; break;
case SUB_UP : dir = 'u'; edir = 4; break;
case SUB_DOWN : dir = 'd'; edir = 5; break;
default:
case SUB_NORTH: dir = 'n'; edir = 0; break;
}
value = get_exflag (arg2);
if (value < 0) {
ch->SendText ("Bad exit flag. \n\r");
return;
}
if ((xit = get_exit (location, edir)) == NULL) {
sprintf (buf,"exit %c 1",dir);
do_redit (ch,buf);
xit = get_exit (location,edir);
}
xit->Toggle (value);
return;
}
if (!str_cmp (arg, "ex_to_room"))
{
argument = one_argument (argument, arg2);
switch (ch->GetSubstate ())
{
case SUB_EAST : dir = 'e'; edir = 1; break;
case SUB_WEST : dir = 'w'; edir = 3; break;
case SUB_SOUTH: dir = 's'; edir = 2; break;
case SUB_UP : dir = 'u'; edir = 4; break;
case SUB_DOWN : dir = 'd'; edir = 5; break;
default:
case SUB_NORTH: dir = 'n'; edir = 0; break;
}
evnum = atoi (arg2);
if (evnum < 1 || evnum > 2097152000) // was 32766
{
ch->SendText ("Invalid room number.\n\r");
return;
}
if ((tmp = RoomTable.GetRoom (evnum)) == NULL)
{
ch->SendText ("Non-existant room.\n\r");
return;
}
if ((xit = get_exit (location,edir)) == NULL)
{
sprintf (buf,"exit %c 1",dir);
do_redit (ch,buf);
xit = get_exit (location,edir);
}
xit->vnum = evnum;
return;
}
if (!str_cmp (arg, "ex_key"))
{
argument = one_argument (argument, arg2);
switch (ch->GetSubstate ())
{
case SUB_EAST : dir = 'e'; edir = 1; break;
case SUB_WEST : dir = 'w'; edir = 3; break;
case SUB_SOUTH: dir = 's'; edir = 2; break;
case SUB_UP : dir = 'u'; edir = 4; break;
case SUB_DOWN : dir = 'd'; edir = 5; break;
default:
case SUB_NORTH: dir = 'n'; edir = 0; break;
}
if ((xit = get_exit (location,edir)) == NULL)
{
sprintf (buf,"exit %c 1",dir);
do_redit (ch,buf);
xit = get_exit (location,edir);
}
xit->key = atoi (arg2);
return;
}
if (!str_cmp (arg, "ex_exdesc"))
{
switch (ch->GetSubstate ())
{
case SUB_EAST : dir = 'e'; edir = 1; break;
case SUB_WEST : dir = 'w'; edir = 3; break;
case SUB_SOUTH: dir = 's'; edir = 2; break;
case SUB_UP : dir = 'u'; edir = 4; break;
case SUB_DOWN : dir = 'd'; edir = 5; break;
default:
case SUB_NORTH: dir = 'n'; edir = 0; break;
}
if ((xit = get_exit (location, edir)) == NULL)
{
sprintf (buf,"exit %c 1",dir);
do_redit (ch,buf);
}
sprintf (buf,"exdesc %c %s",dir,argument);
do_redit (ch,buf);
return;
}
if (!str_cmp (arg, "ex_keywords")) /* not called yet */
{
switch (ch->GetSubstate ())
{
case SUB_EAST : dir = 'e'; edir = 1; break;
case SUB_WEST : dir = 'w'; edir = 3; break;
case SUB_SOUTH: dir = 's'; edir = 2; break;
case SUB_UP : dir = 'u'; edir = 4; break;
case SUB_DOWN : dir = 'd'; edir = 5; break;
default:
case SUB_NORTH: dir = 'n'; edir = 0; break;
}
if ((xit = get_exit (location, edir)) == NULL)
{
sprintf (buf, "exit %c 1", dir);
do_redit (ch,buf);
if ((xit = get_exit (location, edir)) == NULL)
return;
}
sprintf (buf, "%s %s", xit->keyword, argument);
STRFREE (xit->keyword);
xit->keyword = STRALLOC (buf);
return;
}
if (!str_cmp (arg, "exit"))
{
BOOL addexit, numnotdir;
argument = one_argument (argument, arg2);
argument = one_argument (argument, arg3);
if (!arg2 || arg2[0] == '\0')
{
ch->SendText ("Create, change or remove an exit.\n\r");
ch->SendText ("Usage: redit exit <dir> [room] [flags] [key] [keywords]\n\r");
return;
}
addexit = numnotdir = FALSE;
switch (arg2[0])
{
default: edir = get_dir (arg2); break;
case '+': edir = get_dir (arg2+1); addexit = TRUE; break;
case '#': edir = atoi (arg2+1); numnotdir = TRUE; break;
}
if (!arg3 || arg3[0] == '\0')
evnum = 0;
else
evnum = atoi (arg3);
if (numnotdir)
{
if ((xit = get_exit_num (location, edir)) != NULL)
edir = xit->vdir;
}
else
xit = get_exit (location, edir);
if (!evnum)
{
if (xit)
{
extract_exit (location, xit);
ch->SendText ("Exit removed.\n\r");
return;
}
ch->SendText ("No exit in that direction.\n\r");
return;
}
if (evnum < 1 || evnum > 2097152000) // was 32766
{
ch->SendText ("Invalid room number.\n\r");
return;
}
if ((tmp = RoomTable.GetRoom (evnum)) == NULL)
{
ch->SendText ("Non-existant room.\n\r");
return;
}
if (addexit || ! xit) {
if (numnotdir) {
ch->SendText ("Cannot add an exit by number, sorry.\n\r");
return;
}
if (addexit && xit && get_exit_to (location, edir, tmp->vnum)) {
ch->SendText ("There is already an exit in that direction "
"leading to that location.\n\r");
return;
}
xit = make_exit (location, tmp, edir);
xit->keyword = STRALLOC ("");
xit->description = STRALLOC ("");
xit->key = -1;
act (AT_IMMORT, "$n reveals a hidden passage!", ch, NULL, NULL, TO_ROOM);
}
else
act (AT_IMMORT, "Something is different...", ch, NULL, NULL, TO_ROOM);
if (xit->GetToRoom () != tmp)
{
xit->SetToRoom (tmp);
xit->vnum = evnum;
texit = get_exit_to (xit->GetToRoom (), rev_dir[edir], location->vnum);
if (texit)
{
texit->rexit = xit;
xit->rexit = texit;
}
}
argument = one_argument (argument, arg3);
// Here we are setting flags by value. This allows the builder to set
// all the exit flags at once, if he knows the flag values and how to
// combine them properly. It would be better to change the code to set
// the flags individually by name - a project for another day - RCP.
if (arg3 && arg3 [0] != '\0')
xit->SetFlags (atoi (arg3));
if (argument && argument[0] != '\0') {
one_argument (argument, arg3);
ekey = atoi (arg3);
if (ekey != 0 || arg3[0] == '0') {
argument = one_argument (argument, arg3);
xit->key = ekey;
}
if (argument && argument[0] != '\0') {
STRFREE (xit->keyword);
xit->keyword = STRALLOC (argument);
}
}
ch->SendText ("Done.\n\r");
return;
}
/*
* Twisted and evil, but works -Thoric
* Makes an exit, and the reverse in one shot.
*/
if (!str_cmp (arg, "bexit"))
{
CExitData *xit, *rxit;
char tmpcmd[MAX_INPUT_LENGTH];
CRoomIndexData *tmploc;
int vnum, exnum;
char rvnum[MAX_INPUT_LENGTH];
BOOL numnotdir;
argument = one_argument (argument, arg2);
argument = one_argument (argument, arg3);
if (!arg2 || arg2[0] == '\0')
{
ch->SendText ("Create, change or remove a two-way exit.\n\r");
ch->SendText ("Usage: redit bexit <dir> [room] [flags] [key] [keywords]\n\r");
return;
}
numnotdir = FALSE;
switch (arg2[0])
{
default:
edir = get_dir (arg2);
break;
case '#':
numnotdir = TRUE;
edir = atoi (arg2+1);
break;
case '+':
edir = get_dir (arg2+1);
break;
}
tmploc = location;
exnum = edir;
if (numnotdir)
{
if ((xit = get_exit_num (tmploc, edir)) != NULL)
edir = xit->vdir;
}
else
xit = get_exit (tmploc, edir);
rxit = NULL;
vnum = 0;
rvnum[0] = '\0';
if (xit)
{
vnum = xit->vnum;
if (arg3[0] != '\0')
sprintf (rvnum, "%d", tmploc->vnum);
if (xit->GetToRoom ())
rxit = get_exit (xit->GetToRoom (), rev_dir [edir]);
else
rxit = NULL;
}
sprintf (tmpcmd, "exit %s %s %s", arg2, arg3, argument);
do_redit (ch, tmpcmd);
if (numnotdir)
xit = get_exit_num (tmploc, exnum);
else
xit = get_exit (tmploc, edir);
if (!rxit && xit)
{
vnum = xit->vnum;
if (arg3[0] != '\0')
sprintf (rvnum, "%d", tmploc->vnum);
if (xit->GetToRoom ())
rxit = get_exit (xit->GetToRoom (), rev_dir[edir]);
else
rxit = NULL;
}
if (vnum)
{
sprintf (tmpcmd, "%d redit exit %d %s %s",
vnum,
rev_dir[edir],
rvnum,
argument);
do_at (ch, tmpcmd);
}
return;
}
if (!str_cmp (arg, "exdistance"))
{
argument = one_argument (argument, arg2);
if (!arg2 || arg2[0] == '\0')
{
ch->SendText ("Set the distance (in rooms) between this room, and the destination room.\n\r");
ch->SendText ("Usage: redit exdistance <dir> [distance]\n\r");
return;
}
if (arg2[0] == '#')
{
edir = atoi (arg2+1);
xit = get_exit_num (location, edir);
}
else
{
edir = get_dir (arg2);
xit = get_exit (location, edir);
}
if (xit)
{
xit->distance = URANGE (1, atoi (argument), 50);
ch->SendText ("Done.\n\r");
return;
}
ch->SendText ("No exit in that direction. Use 'redit exit ...' first.\n\r");
return;
}
if (!str_cmp (arg, "exdesc"))
{
argument = one_argument (argument, arg2);
if (!arg2 || arg2[0] == '\0')
{
ch->SendText ("Create or clear a description for an exit.\n\r");
ch->SendText ("Usage: redit exdesc <dir> [description]\n\r");
return;
}
if (arg2[0] == '#')
{
edir = atoi (arg2+1);
xit = get_exit_num (location, edir);
}
else
{
edir = get_dir (arg2);
xit = get_exit (location, edir);
}
if (xit)
{
STRFREE (xit->description);
if (!argument || argument[0] == '\0')
xit->description = STRALLOC ("");
else
{
sprintf (buf, "%s\n\r", argument);
xit->description = STRALLOC (buf);
}
ch->SendText ("Done.\n\r");
return;
}
ch->SendText ("No exit in that direction. Use 'redit exit ...' first.\n\r");
return;
}
/*
* Generate usage message.
*/
if (ch->GetSubstate () == SUB_REPEATCMD)
{
ch->SetSubstate (SUB_RESTRICTED);
interpret (ch, origarg);
ch->SetSubstate (SUB_REPEATCMD);
ch->last_cmd = do_redit;
}
else
do_redit (ch, "");
return;
}
void do_ocreate (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
CObjIndexData *pObjIndex;
CObjData *obj;
int vnum, cvnum;
if (ch->IsNpc ()) {
ch->SendText ("Mobiles cannot create.\n\r");
return;
}
argument = one_argument (argument, arg);
vnum = is_number (arg) ? atoi (arg) : -1;
if (vnum == -1 || !argument || argument[0] == '\0') {
ch->SendText ("Usage: ocreate <vnum> [copy vnum] <item name>\n\r");
return;
}
if (vnum < 1 || vnum > 2097152000) { // was 32767
ch->SendText ("Vnum out of range.\n\r");
return;
}
one_argument (argument, arg2);
cvnum = atoi (arg2);
if (cvnum != 0)
argument = one_argument (argument, arg2);
if (cvnum < 1)
cvnum = 0;
if (OIdxTable.GetObj (vnum)) {
ch->SendText ("An object with that number already exists.\n\r");
return;
}
if (ch->IsNpc ())
return;
if (ch->GetTrustLevel () < LEVEL_LESSER) {
CAreaData &Area = *ch->GetArea ();
if (! &Area) {
ch->SendText ("You must have an assigned area to create objects.\n\r");
return;
}
if (vnum < Area.low_o_vnum && vnum > Area.hi_o_vnum) {
ch->SendText ("That number is not in your allocated range.\n\r");
return;
}
}
pObjIndex = make_object (vnum, cvnum, argument);
if (! pObjIndex) {
ch->SendText ("Error.\n\r");
gpDoc->LogString ("do_ocreate: make_object failed.", LOG_BUG);
return;
}
obj = create_object (pObjIndex, ch->GetTrustLevel ());
obj_to_char (obj, ch);
act (AT_IMMORT, "$n makes some ancient arcane gestures, and opens $s hands", ch, NULL, NULL, TO_ROOM);
act (AT_IMMORT, "to reveal $p!", ch, obj, NULL, TO_ROOM);
ch->SendColorf ("&YYou make arcane gestures, and open your hands "
"to reveal %s!\n\rObjVnum: &W%d &YKeywords: &W%s\n\r",
pObjIndex->GetShortDescr (), pObjIndex->vnum, pObjIndex->GetName ());
}
void do_mcreate (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
CMobIndexData *pMobIndex;
CCharacter *mob;
int vnum, cvnum;
if (ch->IsNpc ()) {
ch->SendText ("Mobiles cannot create.\n\r");
return;
}
argument = one_argument (argument, arg);
vnum = is_number (arg) ? atoi (arg) : -1;
if (vnum == -1 || !argument || argument[0] == '\0') {
ch->SendText ("Usage: mcreate <vnum> [cvnum] <mobile name>\n\r");
return;
}
if (vnum < 1 || vnum > 2097152000) { // was 32767
ch->SendText ("Vnum out of range.\n\r");
return;
}
one_argument (argument, arg2);
cvnum = atoi (arg2);
if (cvnum != 0)
argument = one_argument (argument, arg2);
if (cvnum < 1)
cvnum = 0;
if (MobTable.GetMob (vnum)) {
ch->SendText ("A mobile with that number already exists.\n\r");
return;
}
if (ch->IsNpc ())
return;
if (ch->GetTrustLevel () < LEVEL_LESSER) {
CAreaData &Area = *ch->GetArea ();
if (! &Area) {
ch->SendText ("You must have an assigned area to create mobiles.\n\r");
return;
}
if (vnum < Area.low_m_vnum && vnum > Area.hi_m_vnum) {
ch->SendText ("That number is not in your allocated range.\n\r");
return;
}
}
pMobIndex = make_mobile (vnum, cvnum, argument);
if (! pMobIndex) {
ch->SendText ("Error.\n\r");
gpDoc->LogString ("do_mcreate: make_mobile failed.", LOG_BUG);
return;
}
mob = create_mobile (pMobIndex);
mob->SendToRoom (ch->GetInRoom ());
act (AT_IMMORT, "$n waves $s arms about, and $N appears at $s command!", ch, NULL, mob, TO_ROOM);
ch->SendColorf ("&YYou wave your arms about, and %s appears at your "
"command!\n\rMobVnum: &W%d &YKeywords: &W%s\n\r",
pMobIndex->GetShortDescr (), pMobIndex->vnum,
pMobIndex->GetPlayerName ());
}
void assign_area (CCharacter *ch)
{
char buf [MAX_STRING_LENGTH];
char taf [1024];
BOOL created = FALSE;
if (ch->IsNpc ())
return;
CAreaData *pArea;
if (ch->GetTrustLevel () > LEVEL_IMMORTAL
&& ch->GetPcData ()->r_range_lo
&& ch->GetPcData ()->r_range_hi) {
pArea = ch->GetArea ();
if (! pArea) {
strcpy (taf, capitalize (ch->GetName ()));
pArea = BuildList.FindByAuthor (taf);
}
if (! pArea) {
sprintf (buf, "Creating area entry for %s", ch->GetName ());
gpDoc->LogString (buf, LOG_BUILD, ch->GetLevel ());
pArea = new CAreaData (ch->GetName (), "", SW_CURRENT_AV);
BuildList.AddTail (pArea);
sprintf (buf, "{PROTO} %s's area in progress", ch->GetName ());
pArea->SetName (buf);
pArea->m_Author = ch->GetName ();
pArea->hi_soft_range = MAX_LEVEL; // Rustry
pArea->hi_hard_range = MAX_LEVEL;
created = TRUE;
} else {
sprintf (buf, "Updating area entry for %s", ch->GetName ());
gpDoc->LogString (buf, LOG_BUILD, ch->GetLevel ());
}
pArea->low_r_vnum = ch->GetPcData ()->r_range_lo;
pArea->low_o_vnum = ch->GetPcData ()->o_range_lo;
pArea->low_m_vnum = ch->GetPcData ()->m_range_lo;
pArea->hi_r_vnum = ch->GetPcData ()->r_range_hi;
pArea->hi_o_vnum = ch->GetPcData ()->o_range_hi;
pArea->hi_m_vnum = ch->GetPcData ()->m_range_hi;
// If the area has never been saved (no file) then set the loaded
// flag, so it can be saved.
if (! FileTable.Exists (FileTable.MakeBuildName (pArea->m_Author)))
pArea->SetLoaded ();
ch->GetPcData ()->area = pArea;
if (created)
sort_area (pArea, TRUE);
}
}
void do_aassign (CCharacter *ch, char *argument)
{
char buf [MAX_STRING_LENGTH];
if (ch->IsNpc ())
return;
set_char_color (AT_IMMORT, ch);
if (argument [0] == '\0') {
ch->SendText ("Syntax: aassign <filename.are>\n\r");
return;
}
if (! str_cmp ("none", argument) || ! str_cmp ("null", argument)
|| !str_cmp ("clear", argument)) {
ch->GetPcData ()->area = NULL;
assign_area (ch);
if (! ch->GetArea ())
ch->SendText ("Area pointer cleared.\n\r");
else
ch->SendText ("Originally assigned area restored.\n\r");
return;
}
CAreaData *pArea;
if (ch->GetTrustLevel () >= LEVEL_SUB_IMPLEM
|| (is_name (buf, ch->GetPcData ()->GetBestowments ())
&& ch->GetTrustLevel () >= SysData.ModifyProtoLevel))
pArea = AreaList.FindByName (argument);
if (! pArea)
pArea = BuildList.FindByAuthor (argument);
if (pArea) {
if (ch->GetTrustLevel () < LEVEL_GREATER
&& !is_name (pArea->m_Filename,
ch->GetPcData ()->GetBestowments ())) {
ch->SendText ("You do not have permission to use that area.\n\r");
return;
}
}
if (! pArea) {
if (ch->GetTrustLevel () >= SysData.ModifyProtoLevel)
ch->SendText ("No such area. Use 'zones'.\n\r");
else
ch->SendText ("No such area. Use 'newzones'.\n\r");
return;
}
ch->GetPcData ()->area = pArea;
ch->SendTextf ("Assigning you: %s\n\r", NCCP pArea->GetName ());
}
CExtraDescrData *SetRExtra (CRoomIndexData *room, char *keywords)
{
CExtraDescrData *ed = NULL;
POSITION pos = room->ExDesList.GetHeadPosition ();
while (pos) {
ed = (CExtraDescrData*) room->ExDesList.GetNext (pos);
if (is_name (keywords, ed->keyword))
return ed;
}
ed = new CExtraDescrData;
room->ExDesList.AddTail (ed);
ed->keyword = STRALLOC (keywords);
ed->description = STRALLOC ("");
++top_ed;
return ed;
}
BOOL DelRExtra (CRoomIndexData *room, char *keywords)
{
CExtraDescrData *ed = NULL;
POSITION CurPos, pos = room->ExDesList.GetHeadPosition ();
while (pos) {
CurPos = pos;
ed = (CExtraDescrData*) room->ExDesList.GetNext (pos);
if (is_name (keywords, ed->keyword)) {
room->ExDesList.RemoveAt (CurPos);
delete ed;
return TRUE;
}
}
return FALSE;
}
CExtraDescrData *SetOExtra (CObjData *obj, char *keywords)
{
CExtraDescrData *ed = NULL;
POSITION pos = obj->ExDesList.GetHeadPosition ();
while (pos) {
ed = (CExtraDescrData*) obj->ExDesList.GetNext (pos);
if (is_name (keywords, ed->keyword))
return ed;
}
ed = new CExtraDescrData;
obj->ExDesList.AddTail (ed);
ed->keyword = STRALLOC (keywords);
ed->description = STRALLOC ("");
++top_ed;
return ed;
}
BOOL DelOExtra (CObjData *obj, char *keywords)
{
CExtraDescrData *ed = NULL;
POSITION CurPos, pos = obj->ExDesList.GetHeadPosition ();
while (pos) {
CurPos = pos;
ed = (CExtraDescrData*) obj->ExDesList.GetNext (pos);
if (is_name (keywords, ed->keyword)) {
obj->ExDesList.RemoveAt (CurPos);
delete ed;
return TRUE;
}
}
return FALSE;
}
CExtraDescrData *SetOExtraProto (CObjIndexData *obj, char *keywords)
{
CExtraDescrData *ed = NULL;
POSITION pos = obj->ExDesList.GetHeadPosition ();
while (pos) {
ed = (CExtraDescrData*) obj->ExDesList.GetNext (pos);
if (is_name (keywords, ed->keyword))
return ed;
}
ed = new CExtraDescrData;
obj->ExDesList.AddTail (ed);
ed->keyword = STRALLOC (keywords);
ed->description = STRALLOC ("");
++top_ed;
return ed;
}
BOOL DelOExtraProto (CObjIndexData *obj, char *keywords)
{
CExtraDescrData *ed = NULL;
POSITION CurPos, pos = obj->ExDesList.GetHeadPosition ();
while (pos) {
CurPos = pos;
ed = (CExtraDescrData*) obj->ExDesList.GetNext (pos);
if (is_name (keywords, ed->keyword)) {
obj->ExDesList.RemoveAt (CurPos);
delete ed;
return TRUE;
}
}
return FALSE;
}
void fold_area (CAreaData *tarea, int bType /* = FA_LIVE */,
BOOL bInstall /* = FALSE */)
{
CMobIndexData *pMobIndex;
CObjIndexData *pObjIndex;
CShopData *pShop;
CRepairShopData *pRepair;
FILE *fpout;
// If we are saving, and not installing, a build area, then tell
// MakeAreaName to give us a build name, otherwise a regular area name.
CString Aname;
if (bType == FA_BUILD && ! bInstall)
Aname = FileTable.MakeAreaName (tarea->m_Author, FA_INSTALL);
else
Aname = FileTable.MakeAreaName (tarea->m_Name);
gpDoc->LogStringf (LOG_BUILD, LEVEL_GREATER, "Writing %s...", NCCP Aname);
// Make a backup
CString Bname = FileTable.MakeBackupName (Aname);
remove (Bname);
rename (Aname, Bname);
fclose (fpReserve);
if ((fpout = fopen (Aname, "w")) == NULL) {
bug ("fold_area: fopen");
perror (Aname);
fpReserve = fopen (FileTable.GetName (SM_NULL_FILE), "r");
return;
}
fprintf (fpout, "#VERSION %d\n", SW_CURRENT_AV);
fprintf (fpout, "#AREA %s~\n", NCCP tarea->GetName ());
fprintf (fpout, "#AUTHOR %s~\n\n", NCCP tarea->m_Author);
fprintf (fpout, "#RANGES\n");
fprintf (fpout, "%d %d %d %d\n", tarea->low_soft_range,
tarea->hi_soft_range,
tarea->low_hard_range,
tarea->hi_hard_range);
fprintf (fpout, "$\n\n");
if (! tarea->m_Resetmsg.IsEmpty ()) // Rennard
fprintf (fpout, "#RESETMSG %s~\n\n", NCCP tarea->m_Resetmsg);
if (tarea->reset_frequency)
fprintf (fpout, "#FLAGS\n%d %d\n\n",
tarea->GetFlags (), tarea->reset_frequency);
else
fprintf (fpout, "#FLAGS\n%d\n\n", tarea->GetFlags ());
fprintf (fpout, "#ECONOMY %d %d\n\n", tarea->high_economy,
tarea->low_economy);
// save mobiles
int vnum;
fprintf (fpout, "#MOBILES\n");
for (vnum = tarea->low_m_vnum; vnum <= tarea->hi_m_vnum; vnum++) {
if ((pMobIndex = MobTable.GetMob (vnum)) == NULL)
continue;
if (bInstall)
pMobIndex->ClrPrototype ();
pMobIndex->Write (fpout);
}
fprintf (fpout, "#0\n\n\n");
if (bInstall && vnum < tarea->hi_m_vnum)
tarea->hi_m_vnum = vnum - 1;
// save objects
fprintf (fpout, "#OBJECTS\n");
for (vnum = tarea->low_o_vnum; vnum <= tarea->hi_o_vnum; vnum++) {
if ((pObjIndex = OIdxTable.GetObj (vnum)) == NULL)
continue;
if (bInstall)
pObjIndex->ClrPrototype ();
pObjIndex->Write (fpout);
}
fprintf (fpout, "#0\n\n\n");
if (bInstall && vnum < tarea->hi_o_vnum)
tarea->hi_o_vnum = vnum - 1;
// save rooms
CRoomIndexData *pRoom;
fprintf (fpout, "#ROOMS\n");
for (vnum = tarea->low_r_vnum; vnum <= tarea->hi_r_vnum; vnum++) {
if ((pRoom = RoomTable.GetRoom (vnum)) == NULL)
continue;
if (bInstall) {
CCharacter *victim, *vnext;
CObjData *obj;
// remove prototype flag from room
pRoom->ClrPrototype ();
// purge room of (prototyped) mobiles
for (victim = pRoom->first_person; victim; victim = vnext) {
vnext = victim->GetNextInRoom ();
if (victim->IsNpc ())
extract_char (victim, TRUE);
}
// purge room of (prototyped) objects
POSITION Rpos = pRoom->GetHeadContentPos ();
while (obj = pRoom->GetNextContent (Rpos))
extract_obj (obj);
}
pRoom->Write (fpout);
}
fprintf (fpout, "#0\n\n\n");
if (bInstall && vnum < tarea->hi_r_vnum)
tarea->hi_r_vnum = vnum - 1;
// save shops
fprintf (fpout, "#SHOPS\n");
for (vnum = tarea->low_m_vnum; vnum <= tarea->hi_m_vnum; vnum++) {
if ((pMobIndex = MobTable.GetMob (vnum)) == NULL)
continue;
if ((pShop = pMobIndex->pShop) == NULL)
continue;
fprintf (fpout, " %d %2d %2d %2d %2d %2d %3d %3d",
pShop->keeper, pShop->buy_type [0], pShop->buy_type [1],
pShop->buy_type [2], pShop->buy_type [3],
pShop->buy_type [4], pShop->profit_buy, pShop->profit_sell);
fprintf (fpout, " %2d %2d ; %s\n", pShop->open_hour,
pShop->close_hour, pMobIndex->GetShortDescr ());
}
fprintf (fpout, "0\n\n\n");
// save repair shops
fprintf (fpout, "#REPAIRS\n");
for (vnum = tarea->low_m_vnum; vnum <= tarea->hi_m_vnum; vnum++) {
if ((pMobIndex = MobTable.GetMob (vnum)) == NULL)
continue;
if ((pRepair = pMobIndex->rShop) == NULL)
continue;
fprintf (fpout, " %d %2d %2d %2d %3d %3d", pRepair->keeper,
pRepair->fix_type [0], pRepair->fix_type[1],
pRepair->fix_type [2], pRepair->profit_fix, pRepair->shop_type);
fprintf (fpout, " %2d %2d ; %s\n", pRepair->open_hour,
pRepair->close_hour, pMobIndex->GetShortDescr ());
}
fprintf (fpout, "0\n\n\n");
// save specials
fprintf (fpout, "#SPECIALS\n");
for (vnum = tarea->low_m_vnum; vnum <= tarea->hi_m_vnum; vnum++) {
if ((pMobIndex = MobTable.GetMob (vnum)) == NULL)
continue;
if (!pMobIndex->spec_fun)
continue;
fprintf (fpout, "M %d %s\n", pMobIndex->vnum,
lookup_spec (pMobIndex->spec_fun));
}
fprintf (fpout, "S\n\n\n");
// END
fprintf (fpout, "#$\n");
fclose (fpout);
fpReserve = fopen (FileTable.GetName (SM_NULL_FILE), "r");
}
void do_savearea (CCharacter *ch, char *argument)
{
if (ch->IsNpc () || ch->GetTrustLevel () < LEVEL_CREATOR
|| !ch->GetPcData ()
|| (argument[0] == '\0' && !ch->GetArea ())) {
ch->SendText ("You don't have an assigned area to save.\n\r");
return;
}
CAreaData *pArea;
if (argument [0]) {
if (ch->GetTrustLevel () < LEVEL_GOD) {
ch->SendText ("You can only save your own area.\n\r");
return;
}
pArea = BuildList.FindByAuthor (argument);
if (! pArea) {
ch->SendText ("Area not found.\n\r");
return;
}
}
else pArea = ch->GetArea ();
if (! pArea) {
ch->SendText ("No area to save.\n\r");
return;
}
// Ensure not wiping out their area with save before load - Scryn 8/11
if (! pArea->IsLoaded ()) {
ch->SendText ("Your area is not loaded!\n\r");
return;
}
fold_area (pArea, FA_BUILD);
ch->SendText ("Done.\n\r");
}
void do_loadarea (CCharacter *ch, char *argument)
{
int tmp;
if (ch->IsNpc () || ch->GetTrustLevel () < LEVEL_CREATOR
|| !ch->GetPcData ()
|| (argument [0] == '\0' && !ch->GetArea ())) {
ch->SendText ("You don't have an assigned area to load.\n\r");
return;
}
CAreaData *pArea = NULL;
if (argument [0]) {
if (ch->GetTrustLevel () < LEVEL_GOD) {
ch->SendText ("You can only load your own area.\n\r");
return;
}
pArea = BuildList.FindByAuthor (capitalize (argument));
if (! pArea) {
ch->SendText ("Area not found.\n\r");
return;
}
}
else pArea = ch->GetArea ();
if (! pArea) {
ch->SendText ("No area to load.\n\r");
return;
}
// Stops char from loading when already loaded - Scryn 8/11
if (pArea->IsLoaded ()) {
ch->SendText ("Your area is already loaded.\n\r");
return;
}
ch->SendText ("Loading...\n\r");
LoadAreaFile (pArea->m_Author, NOBOOT, pArea, BUILD);
if (pArea->IsLoaded ()) {
ch->SendText ("Linking exits...\n\r");
fix_area_exits (pArea);
tmp = pArea->nplayer;
pArea->nplayer = 0;
ch->SendText ("Resetting area...\n\r");
pArea->Reset ();
pArea->nplayer = tmp;
ch->SendText ("Done.\n\r");
}
else
ch->SendText ("Bad Area file\n\r");
}
// Dangerous command. Can be used to install an area that was either:
// (a) already installed but removed from area.lst
// (b) designed offline
// The mud will likely crash if:
// (a) this area is already loaded
// (b) it contains vnums that exist
// (c) the area has errors
//
// NOTE: Use of this command is not recommended. -Thoric
void do_unfoldarea (CCharacter *ch, char *argument)
{
}
void do_foldarea (CCharacter *ch, char *argument)
{
if (!argument || argument [0] == '\0') {
ch->SendText ("Fold what?\n\r");
return;
}
CAreaData *pArea = AreaList.FindByName (argument);
if (pArea) {
ch->SendText ("Folding...\n\r");
fold_area (pArea);
ch->SendText ("Done.\n\r");
return;
}
ch->SendText ("No such area exists.\n\r");
}
void write_area_list ()
{
FILE *fp;
fp = fopen (FileTable.GetName (SM_AREA_LIST), "w");
if (! fp) {
bug ("FATAL: cannot open area.lst for writing!\n\r");
return;
}
fprintf (fp, "help.are\n");
POSITION pos = AreaList.GetHeadPosition ();
while (pos)
fprintf (fp, "%s.are\n", NCCP AreaList.GetNext (pos)->GetName ());
fprintf (fp, "$\n");
fclose (fp);
}
// A complicated to use command as it currently exists. -Thoric
// Once area->author and area->name are cleaned up... it will be easier
void do_installarea (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
int num;
argument = one_argument (argument, arg);
if (arg [0] == 0) {
ch->SendText ("Syntax: installarea <Author> <Area Title>\n\r");
ch->SendText (" installarea <filename>\n\r");
return;
}
if (argument [0]) { // install by author
if (! str_cmp (arg, argument)) {
ch->SendText ("You cannot name an area after yourself.\n\r");
return;
}
CAreaData *pArea = BuildList.FindByAuthor (capitalize (arg));
if (pArea) {
if (! pArea->IsLoaded ()) {
ch->SendText ("The area must be loaded before it can be "
"installed.\n\r");
return;
}
pArea->SetName (capitalize (argument));
pArea->m_Filename = pArea->GetName ();
// Fold area with install flag -- auto-removes prototype flags
ch->SendText ("Saving and installing file...\n\r");
fold_area (pArea, FA_BUILD, FA_INSTALL);
// Remove from prototype area list
BuildList.Remove (pArea);
// Add to real area list
AreaList.AddTail (pArea);
// Fix up author if online
POSITION pos = DList.GetHeadPosition ();
while (pos) {
CDescriptor &Ds = *DList.GetNext (pos);
if (Ds.IsDisconnecting ())
continue;
if (Ds.m_pCharacter && Ds.m_pCharacter->GetPcData ()
&& Ds.m_pCharacter->GetArea () == pArea) {
pc_data &Pc = *Ds.m_pCharacter->GetPcData ();
// remove area from author
Pc.area = NULL;
// clear out author vnums
Pc.r_range_lo = 0;
Pc.r_range_hi = 0;
Pc.o_range_lo = 0;
Pc.o_range_hi = 0;
Pc.m_range_lo = 0;
Pc.m_range_hi = 0;
break;
}
}
ch->SendText ("Writing area.lst...\n\r");
write_area_list ();
ch->SendText ("Resetting new area.\n\r");
num = pArea->nplayer;
pArea->nplayer = 0;
pArea->Reset ();
pArea->nplayer = num;
ch->SendText ("Renaming author's building file.\n\r");
CString BuildName = FileTable.MakeBuildName (pArea->m_Author);
CString Iname = BuildName + ".Installed";
remove (Iname);
rename (BuildName, Iname);
ch->SendText ("Done.\n\r");
return;
}
} else { // install by filename
CString AName = FileTable.MakeAreaName (arg);
if (FileTable.Exists (AName)) {
CAreaData *pArea = NULL;
TRY pArea = LoadAreaFile (arg, BOOT);
CATCH (CException, ex) {
ch->SendText (
"Fatal Errors in Area File.\n\rUnable to Install.\n\r");
return;
}
END_CATCH
if (pArea) {
if (AreaList.FindByName (pArea->m_Name)) {
ch->SendTextf ("Area %s is already installed.\n\r",
NCCP pArea->m_Name);
delete pArea;
return;
}
ch->SendTextf ("Installing %s...\n\r", NCCP pArea->m_Name);
AreaList.AddTail (pArea);
sort_area (pArea, FALSE);
ch->SendText ("Writing area.lst...\n\r");
write_area_list ();
ch->SendText ("Fixing Exits...\n\r");
pArea->FixExits (TRUE); // True makes it log errors
ch->SendText ("Resetting new area.\n\r");
pArea->Reset ();
ch->SendText ("Done.\n\r");
return;
}
}
}
ch->SendText ("No such area exists.\n\r");
}
void do_astat (CCharacter *ch, char *argument)
{
CAreaData *pArea = NULL;
BOOL bProto = FALSE;
set_char_color (AT_PLAIN, ch);
if (argument && argument [0] != '\0') {
pArea = AreaList.FindByName (argument);
if (! pArea) {
pArea = BuildList.FindByAuthor (argument);
if (pArea)
bProto = TRUE;
}
if (! pArea) {
ch->SendText ("Area not found. Check 'zones'.\n\r");
return;
}
}
if (! pArea) {
pArea = ch->GetInRoom ()->GetArea ();
bProto = ch->GetInRoom ()->IsPrototype ();
}
ch->SendTextf ("Name: %s Prototype: %s\n\r",
NCCP pArea->GetName (), bProto ? "yes" : "no");
if (! bProto) {
ch->SendTextf ("Max players: %d IllegalPks: %d Gold Looted: %d\n\r",
pArea->max_players, pArea->illegal_pk, pArea->gold_looted);
if (pArea->high_economy)
ch->SendTextf ("Area economy: %d billion and %d gold coins.\n\r",
pArea->high_economy, pArea->low_economy);
else
ch->SendTextf ("Area economy: %d gold coins.\n\r",
pArea->low_economy);
ch->SendTextf ("Mdeaths: %d Mkills: %d Pdeaths: %d Pkills: %d\n\r",
pArea->mdeaths, pArea->mkills, pArea->pdeaths, pArea->pkills);
}
ch->SendTextf ("Author: %s\n\rAge: %d Number of players: %d\n\r",
NCCP pArea->m_Author, pArea->age, pArea->nplayer);
ch->SendTextf ("Area flags: %s\n\r",
flag_string (pArea->GetFlags (), area_flags));
ch->SendTextf ("low_room: %5d hi_room: %d\n\r", pArea->low_r_vnum,
pArea->hi_r_vnum);
ch->SendTextf ("low_obj : %5d hi_obj : %d\n\r", pArea->low_o_vnum,
pArea->hi_o_vnum);
ch->SendTextf ("low_mob : %5d hi_mob : %d\n\r", pArea->low_m_vnum,
pArea->hi_m_vnum);
ch->SendTextf ("soft range: %d - %d. hard range: %d - %d.\n\r",
pArea->low_soft_range, pArea->hi_soft_range,
pArea->low_hard_range, pArea->hi_hard_range);
ch->SendTextf ("Resetmsg: %s\n\r",
pArea->m_Resetmsg.IsEmpty () ? "(default)" : NCCP pArea->m_Resetmsg);
ch->SendTextf ("Reset frequency: %d minutes.\n\r",
pArea->reset_frequency ? pArea->reset_frequency : 15);
}
void do_aset (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
int vnum, value;
set_char_color (AT_IMMORT, ch);
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
vnum = atoi (argument);
if (arg1 [0] == '\0' || arg2 [0] == '\0') {
ch->SendText ("Usage: aset <area name> <field> <value>\n\r");
ch->SendText ("\n\rField being one of:\n\r");
ch->SendText (" low_room hi_room low_obj hi_obj low_mob hi_mob\n\r");
ch->SendText (" name low_soft hi_soft low_hard hi_hard\n\r");
ch->SendText (" author resetmsg resetfreq flags\n\r");
ch->SendText ("See HELP ASET for information on changing name.\n\r");
return;
}
BOOL bProto = FALSE;
CAreaData *pArea = AreaList.FindByName (arg1);
if (! pArea) {
pArea = BuildList.FindByAuthor (arg1);
if (pArea)
bProto = TRUE;
}
if (! pArea) {
ch->SendText ("Area not found.\n\r");
return;
}
if (! str_cmp (arg2, "name")) {
CString OldName = FileTable.MakeAreaName (pArea->GetName ());
if (pArea->GetName () != argument) {
pArea->SetName (argument);
if (! bProto) {
CString NewName = FileTable.MakeAreaName (argument);
rename (OldName, NewName);
fold_area (pArea);
write_area_list ();
}
}
ch->SendText ("Done.\n\r");
ch->SendText ("See HELP ASET for information on changing name.\n\r");
return;
}
if (! str_cmp (arg2, "low_economy")) {
pArea->low_economy = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "high_economy")) {
pArea->high_economy = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "low_room")) {
pArea->low_r_vnum = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "hi_room")) {
pArea->hi_r_vnum = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "low_obj")) {
pArea->low_o_vnum = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "hi_obj")) {
pArea->hi_o_vnum = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "low_mob")) {
pArea->low_m_vnum = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "hi_mob")) {
pArea->hi_m_vnum = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "low_soft")) {
if (vnum < 0 || vnum > MAX_LEVEL) {
ch->SendText ("That is not an acceptable value.\n\r");
return;
}
pArea->low_soft_range = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "hi_soft")) {
if (vnum < 0 || vnum > MAX_LEVEL) {
ch->SendText ("That is not an acceptable value.\n\r");
return;
}
pArea->hi_soft_range = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "low_hard")) {
if (vnum < 0 || vnum > MAX_LEVEL) {
ch->SendText ("That is not an acceptable value.\n\r");
return;
}
pArea->low_hard_range = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "hi_hard")) {
if (vnum < 0 || vnum > MAX_LEVEL) {
ch->SendText ("That is not an acceptable value.\n\r");
return;
}
pArea->hi_hard_range = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "author")) {
pArea->m_Author = argument;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "resetmsg")) {
pArea->m_Resetmsg.Empty ();
if (str_cmp (argument, "clear"))
pArea->m_Resetmsg = argument;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "resetfreq")) {
pArea->reset_frequency = vnum;
ch->SendText ("Done.\n\r");
return;
}
if (! str_cmp (arg2, "flags")) {
if (! argument || argument [0] == '\0') {
ch->SendText ("Usage: aset <filename> flags <flag> [flag]...\n\r");
return;
}
while (argument [0] != '\0') {
argument = one_argument (argument, arg3);
value = get_areaflag (arg3);
if (value < 0)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else {
if (pArea->TestFlag (1 << value))
pArea->ClrFlag (1 << value);
else
pArea->SetFlag (1 << value);
}
}
return;
}
do_aset (ch, "");
}
void do_rlist (CCharacter *ch, char *argument)
{
CRoomIndexData *room;
int vnum;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
CAreaData *tarea;
int lrange;
int trange;
set_pager_color (AT_PLAIN, ch);
if (ch->IsNpc () || ch->GetTrustLevel () < LEVEL_CREATOR || !ch->GetPcData ()
|| (! ch->GetArea () && ch->GetTrustLevel () < LEVEL_GREATER))
{
ch->SendText ("You don't have an assigned area.\n\r");
return;
}
tarea = ch->GetArea ();
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (tarea)
{
if (arg1[0] == '\0') /* cleaned a big scary mess */
lrange = tarea->low_r_vnum; /* here. -Thoric */
else
lrange = atoi (arg1);
if (arg2[0] == '\0')
trange = tarea->hi_r_vnum;
else
trange = atoi (arg2);
if ((lrange < tarea->low_r_vnum || trange > tarea->hi_r_vnum)
&& ch->GetTrustLevel () < LEVEL_GREATER)
{
ch->SendText ("That is out of your vnum range.\n\r");
return;
}
}
else
{
lrange = (is_number (arg1) ? atoi (arg1) : 1);
trange = (is_number (arg2) ? atoi (arg2) : 1);
}
for (vnum = lrange; vnum <= trange; vnum++)
{
if ((room = RoomTable.GetRoom (vnum)) == NULL)
continue;
ch->SendTextf ("%5d) %s\n\r", vnum, room->GetName ());
}
return;
}
void do_olist (CCharacter *ch, char *argument)
{
CObjIndexData *obj;
int vnum;
CAreaData *tarea;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int lrange;
int trange;
/*
* Greater+ can list out of assigned range - Tri (mlist/rlist as well)
*/
set_pager_color (AT_PLAIN, ch);
if (ch->IsNpc () || ch->GetTrustLevel () < LEVEL_CREATOR || !ch->GetPcData ()
|| (! ch->GetArea () && ch->GetTrustLevel () < LEVEL_GREATER))
{
ch->SendText ("You don't have an assigned area.\n\r");
return;
}
tarea = ch->GetArea ();
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (tarea)
{
if (arg1[0] == '\0') /* cleaned a big scary mess */
lrange = tarea->low_o_vnum; /* here. -Thoric */
else
lrange = atoi (arg1);
if (arg2[0] == '\0')
trange = tarea->hi_o_vnum;
else
trange = atoi (arg2);
if ((lrange < tarea->low_o_vnum || trange > tarea->hi_o_vnum)
&& ch->GetTrustLevel () < LEVEL_GREATER)
{
ch->SendText ("That is out of your vnum range.\n\r");
return;
}
}
else
{
lrange = (is_number (arg1) ? atoi (arg1) : 1);
trange = (is_number (arg2) ? atoi (arg2) : 3);
}
for (vnum = lrange; vnum <= trange; vnum++)
{
if ((obj = OIdxTable.GetObj (vnum)) == NULL)
continue;
ch->SendTextf ("%5d) %-20s (%s)\n\r", vnum, obj->GetName (),
obj->GetShortDescr ());
}
return;
}
void do_mlist (CCharacter *ch, char *argument)
{
CMobIndexData *mob;
int vnum;
CAreaData *tarea;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int lrange;
int trange;
set_pager_color (AT_PLAIN, ch);
if (ch->IsNpc () || ch->GetTrustLevel () < LEVEL_CREATOR || !ch->GetPcData ()
|| (! ch->GetArea () && ch->GetTrustLevel () < LEVEL_GREATER))
{
ch->SendText ("You don't have an assigned area.\n\r");
return;
}
tarea = ch->GetArea ();
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (tarea)
{
if (arg1[0] == '\0') /* cleaned a big scary mess */
lrange = tarea->low_m_vnum; /* here. -Thoric */
else
lrange = atoi (arg1);
if (arg2[0] == '\0')
trange = tarea->hi_m_vnum;
else
trange = atoi (arg2);
if ((lrange < tarea->low_m_vnum || trange > tarea->hi_m_vnum)
&& ch->GetTrustLevel () < LEVEL_GREATER)
{
ch->SendText ("That is out of your vnum range.\n\r");
return;
}
}
else
{
lrange = (is_number (arg1) ? atoi (arg1) : 1);
trange = (is_number (arg2) ? atoi (arg2) : 1);
}
for (vnum = lrange; vnum <= trange; vnum++)
{
if ((mob = MobTable.GetMob (vnum)) == NULL)
continue;
ch->SendTextf ("%5d) %-20s '%s'\n\r", vnum,
mob->GetPlayerName (), mob->GetShortDescr ());
}
}
void mpedit (CCharacter *ch, CMobProgData *mprg, int mptype, char *argument)
{
if (mptype != -1) {
mprg->type = mptype;
if (mprg->arglist)
STRFREE (mprg->arglist);
mprg->arglist = STRALLOC (argument);
}
ch->SetSubstate (SUB_MPROG_EDIT);
ch->dest_buf = mprg;
if (! mprg->comlist)
mprg->comlist = STRALLOC ("");
start_editing (ch, mprg->comlist);
}
// Mobprogram editing - cumbersome -Thoric
void do_mpedit (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char arg4 [MAX_INPUT_LENGTH];
int value, mptype;
CCharacter *victim;
CMobProgData *mprog;
set_char_color (AT_PLAIN, ch);
if (ch->IsNpc ()) {
ch->SendText ("Mob's can't mpedit\n\r");
return;
}
if (! ch->GetDesc ()) {
ch->SendText ("You have no descriptor\n\r");
return;
}
switch (ch->GetSubstate ()) {
default:
break;
case SUB_MPROG_EDIT:
if (! ch->dest_buf) {
ch->SendTextf ("Fatal error: report to %s.\n\r",
SysData.GetSupremeEntity ());
bug ("do_mpedit: sub_mprog_edit: NULL ch->dest_buf");
ch->SetSubstate (SUB_NONE);
return;
}
mprog = (CMobProgData*) ch->dest_buf;
if (mprog->comlist)
STRFREE (mprog->comlist);
mprog->comlist = ch->GetEditBuffer ();
ch->StopEditing ();
return;
}
smash_tilde (argument);
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
argument = one_argument (argument, arg3);
value = atoi (arg3);
if (arg1 [0] == '\0' || arg2 [0] == '\0') {
ch->SendText ("Syntax: mpedit <victim> <command> [number] <program>"
" <value>\n\r\n\r");
ch->SendText ("Command being one of:\n\r");
ch->SendText (" add delete insert edit list\n\r");
ch->SendText ("Program being one of:\n\r");
ch->SendText (" act speech rand fight hitprcnt greet allgreet\n\r");
ch->SendText (" entry give bribe death time hour script\n\r");
return;
}
if (ch->GetTrustLevel () < LEVEL_GOD) {
if ((victim = get_char_room (ch, arg1)) == NULL) {
ch->SendText ("They aren't here.\n\r");
return;
}
} else {
if ((victim = get_char_world (ch, arg1)) == NULL) {
ch->SendTextf ("No one like that in all the %s.\n\r",
SysData.GetShortTitle ());
return;
}
}
if (ch->GetTrustLevel () < victim->GetLevel () || ! victim->IsNpc ()) {
ch->SendText ("You can't do that!\n\r");
return;
}
if (! can_mmodify (ch, victim))
return;
if (! victim->IsAction (ACT_PROTOTYPE)) {
ch->SendText ("A mobile must have a prototype flag to be mpset.\n\r");
return;
}
set_char_color (AT_GREEN, ch);
CPtrList &PList = victim->GetMobIndex ()->MobPrgList;
if (! str_cmp (arg2, "list")) {
if (PList.IsEmpty ()) {
ch->SendText ("That mobile has no mob programs.\n\r");
return;
}
int cnt = 0;
POSITION pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Mprg = *(CMobProgData*) PList.GetNext (pos);
ch->SendTextf ("%d>%s %s\n\r%s\n\r", ++cnt,
mprog_type_to_name (Mprg.type), Mprg.arglist, Mprg.comlist);
}
return;
}
if (! str_cmp (arg2, "edit")) {
if (PList.IsEmpty ()) {
ch->SendText ("That mobile has no mob programs.\n\r");
return;
}
argument = one_argument (argument, arg4);
if (arg4 [0] != '\0') {
mptype = get_mpflag (arg4);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
}
else mptype = -1;
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// get the position of the prog to edit
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
CMobProgData &Mprg = *(CMobProgData*) PList.GetAt (pos);
mpedit (ch, &Mprg, mptype, argument);
victim->GetMobIndex ()->m_Progtypes.Empty ();
pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Mprg =
*(CMobProgData*) PList.GetNext (pos);
victim->GetMobIndex ()->m_Progtypes.SetBit (Mprg.type);
}
return;
}
if (! str_cmp (arg2, "delete")) {
if (PList.IsEmpty ()) {
ch->SendText ("That mobile has no mob programs.\n\r");
return;
}
argument = one_argument (argument, arg4);
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// Find the position of the prog to delete
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
// delete and remove it
CMobProgData *pMprg = (CMobProgData*) PList.GetAt (pos);
mptype = pMprg->type; // save the type
delete pMprg;
PList.RemoveAt (pos);
// now find out if any others have the same type as the removed prog
BOOL bRemoveType = TRUE;
pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Mprg = *(CMobProgData*) PList.GetNext (pos);
if (Mprg.type == mptype) {
bRemoveType = FALSE;
break;
}
}
if (bRemoveType)
victim->GetMobIndex ()->m_Progtypes.ClrBit (mptype);
ch->SendText ("Program removed.\n\r");
return;
}
if (! str_cmp (arg2, "insert")) {
if (PList.IsEmpty ()) {
ch->SendText ("That mobile has no mob programs.\n\r");
return;
}
argument = one_argument (argument, arg4);
mptype = get_mpflag (arg4);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// Get position of item to insert before
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
CMobProgData *pMprg = new CMobProgData;
victim->GetMobIndex ()->m_Progtypes.SetBit (mptype);
mpedit (ch, pMprg, mptype, argument);
PList.InsertBefore (pos, pMprg);
return;
}
if (! str_cmp (arg2, "add")) {
mptype = get_mpflag (arg3);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
CMobProgData *pMprg = new CMobProgData;
PList.AddTail (pMprg);
victim->GetMobIndex ()->m_Progtypes.SetBit (mptype);
mpedit (ch, pMprg, mptype, argument);
return;
}
do_mpedit (ch, "");
}
void do_opedit (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char arg4 [MAX_INPUT_LENGTH];
CObjData *obj;
CMobProgData *mprog;
int value, mptype;
set_char_color (AT_PLAIN, ch);
if (ch->IsNpc ())
{
ch->SendText ("Mob's can't opedit\n\r");
return;
}
if (!ch->GetDesc ())
{
ch->SendText ("You have no descriptor\n\r");
return;
}
switch (ch->GetSubstate ())
{
default:
break;
case SUB_MPROG_EDIT:
if (!ch->dest_buf)
{
ch->SendTextf ("Fatal error: report to %s.\n\r",
SysData.GetSupremeEntity ());
bug ("do_opedit: sub_oprog_edit: NULL ch->dest_buf");
ch->SetSubstate (SUB_NONE);
return;
}
mprog = (CMobProgData *) ch->dest_buf;
if (mprog->comlist)
STRFREE (mprog->comlist);
mprog->comlist = ch->GetEditBuffer ();
ch->StopEditing ();
return;
}
smash_tilde (argument);
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
argument = one_argument (argument, arg3);
value = atoi (arg3);
if (arg1[0] == '\0' || arg2[0] == '\0')
{
ch->SendText ("Syntax: opedit <object> <command> [number] <program> <value>\n\r");
ch->SendText ("\n\r");
ch->SendText ("Command being one of:\n\r");
ch->SendText (" add delete insert edit list\n\r");
ch->SendText ("Program being one of:\n\r");
ch->SendText (" act speech rand wear remove sac zap get\n\r");
ch->SendText (" drop damage repair greet exa use\n\r");
ch->SendText (" pull push (for levers,pullchains,buttons)\n\r");
ch->SendText ("\n\r");
ch->SendText ("Object should be in your inventory to edit.\n\r");
return;
}
if (ch->GetTrustLevel () < LEVEL_GOD)
{
if ((obj = get_obj_carry (ch, arg1)) == NULL)
{
ch->SendText ("You aren't carrying that.\n\r");
return;
}
}
else
{
if ((obj = get_obj_world (ch, arg1)) == NULL)
{
ch->SendTextf ("Nothing like that in all the %s.\n\r",
SysData.GetShortTitle ());
return;
}
}
if (!can_omodify (ch, obj))
return;
if (! obj->IsPrototype ()) {
ch->SendText ("An object must have a prototype flag to be opset.\n\r");
return;
}
set_char_color (AT_GREEN, ch);
CPtrList &PList = obj->pIndexData->ObjPrgList;
if (! str_cmp (arg2, "list")) {
if (PList.IsEmpty ()) {
ch->SendText ("That object has no obj programs.\n\r");
return;
}
int cnt = 0;
POSITION pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Oprg = *(CMobProgData*) PList.GetNext (pos);
ch->SendTextf ("%d>%s %s\n\r%s\n\r", ++cnt,
mprog_type_to_name (Oprg.type), Oprg.arglist, Oprg.comlist);
}
return;
}
if (! str_cmp (arg2, "edit")) {
if (PList.IsEmpty ()) {
ch->SendText ("That object has no obj programs.\n\r");
return;
}
argument = one_argument (argument, arg4);
if (arg4 [0] != '\0') {
mptype = get_mpflag (arg4);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
}
else mptype = -1;
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// get the position of the prog to edit
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
CMobProgData &Oprg = *(CMobProgData*) PList.GetAt (pos);
mpedit (ch, &Oprg, mptype, argument);
obj->pIndexData->m_Progtypes.Empty ();
pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Oprg =
*(CMobProgData*) PList.GetNext (pos);
obj->pIndexData->m_Progtypes.SetBit (Oprg.type);
}
return;
}
if (! str_cmp (arg2, "delete")) {
if (PList.IsEmpty ()) {
ch->SendText ("That object has no obj programs.\n\r");
return;
}
argument = one_argument (argument, arg4);
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// Find the position of the prog to delete
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
// delete and remove it
CMobProgData *pOprg = (CMobProgData*) PList.GetAt (pos);
mptype = pOprg->type; // save the type
delete pOprg;
PList.RemoveAt (pos);
// now find out if any others have the same type as the removed prog
BOOL bRemoveType = TRUE;
pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Oprg = *(CMobProgData*) PList.GetNext (pos);
if (Oprg.type == mptype) {
bRemoveType = FALSE;
break;
}
}
if (bRemoveType)
obj->pIndexData->m_Progtypes.ClrBit (mptype);
ch->SendText ("Program removed.\n\r");
return;
}
if (! str_cmp (arg2, "insert")) {
if (PList.IsEmpty ()) {
ch->SendText ("That object has no obj programs.\n\r");
return;
}
argument = one_argument (argument, arg4);
mptype = get_mpflag (arg4);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// Get position of item to insert before
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
CMobProgData *pOprg = new CMobProgData;
obj->pIndexData->m_Progtypes.SetBit (mptype);
mpedit (ch, pOprg, mptype, argument);
PList.InsertBefore (pos, pOprg);
return;
}
if (! str_cmp (arg2, "add")) {
mptype = get_mpflag (arg3);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
CMobProgData *pOprg = new CMobProgData;
PList.AddTail (pOprg);
obj->pIndexData->m_Progtypes.SetBit (mptype);
mpedit (ch, pOprg, mptype, argument);
return;
}
do_opedit (ch, "");
}
// RoomProg Support
void rpedit (CCharacter *ch, CMobProgData *mprg, int mptype, char *argument)
{
if (mptype != -1) {
mprg->type = mptype;
if (mprg->arglist)
STRFREE (mprg->arglist);
mprg->arglist = STRALLOC (argument);
}
ch->SetSubstate (SUB_MPROG_EDIT);
ch->dest_buf = mprg;
if (! mprg->comlist)
mprg->comlist = STRALLOC ("");
start_editing (ch, mprg->comlist);
}
void do_rpedit (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
int value, mptype;
CMobProgData *mprog;
set_char_color (AT_PLAIN, ch);
if (ch->IsNpc ()) {
ch->SendText ("Mob's can't rpedit\n\r");
return;
}
if (! ch->GetDesc ()) {
ch->SendText ("You have no descriptor\n\r");
return;
}
switch (ch->GetSubstate ()) {
default:
break;
case SUB_MPROG_EDIT:
if (! ch->dest_buf) {
ch->SendTextf ("Fatal error: report to %s.\n\r",
SysData.GetSupremeEntity ());
bug ("do_opedit: sub_oprog_edit: NULL ch->dest_buf");
ch->SetSubstate (SUB_NONE);
return;
}
mprog = (CMobProgData*) ch->dest_buf;
if (mprog->comlist)
STRFREE (mprog->comlist);
mprog->comlist = ch->GetEditBuffer ();
ch->StopEditing ();
return;
}
smash_tilde (argument);
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
value = atoi (arg2);
// argument = one_argument (argument, arg3);
if (arg1 [0] == '\0') {
ch->SendText ("Syntax: rpedit <command> [number] <program> <value>"
"\n\r\n\r");
ch->SendText ("Command being one of:\n\r");
ch->SendText (" add delete insert edit list\n\r");
ch->SendText ("Program being one of:\n\r");
ch->SendText (" act speech rand sleep rest rfight enter\n\r");
ch->SendText (" leave death\n\r");
ch->SendText ("\n\r");
ch->SendText ("You should be standing in room you wish to edit.\n\r");
return;
}
if (! can_rmodify (ch, ch->GetInRoom ()))
return;
set_char_color (AT_GREEN, ch);
CPtrList &PList = ch->GetInRoom ()->RoomPrgList;
if (! str_cmp (arg1, "list")) {
if (PList.IsEmpty ()) {
ch->SendText ("This room has no room programs.\n\r");
return;
}
int cnt = 0;
POSITION pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Rprg = *(CMobProgData*) PList.GetNext (pos);
ch->SendTextf ("%d>%s %s\n\r%s\n\r", ++cnt,
mprog_type_to_name (Rprg.type), Rprg.arglist, Rprg.comlist);
}
return;
}
if (! str_cmp (arg1, "edit")) {
if (PList.IsEmpty ()) {
ch->SendText ("This room has no room programs.\n\r");
return;
}
argument = one_argument (argument, arg3);
if (arg3 [0] != '\0') {
mptype = get_mpflag (arg3);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
}
else mptype = -1;
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// get the position of the prog to edit
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
CMobProgData &Rprg = *(CMobProgData*) PList.GetAt (pos);
mpedit (ch, &Rprg, mptype, argument);
ch->GetInRoom ()->m_Progtypes.Empty ();
pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Rprg =
*(CMobProgData*) PList.GetNext (pos);
ch->GetInRoom ()->m_Progtypes.SetBit (Rprg.type);
}
return;
}
if (! str_cmp (arg1, "delete")) {
if (PList.IsEmpty ()) {
ch->SendText ("That room has no room programs.\n\r");
return;
}
argument = one_argument (argument, arg3);
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// Find the position of the prog to delete
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
// delete and remove it
CMobProgData *pRprg = (CMobProgData*) PList.GetAt (pos);
mptype = pRprg->type; // save the type
delete pRprg;
PList.RemoveAt (pos);
// now find out if any others have the same type as the removed prog
BOOL bRemoveType = TRUE;
pos = PList.GetHeadPosition ();
while (pos) {
CMobProgData &Rprg = *(CMobProgData*) PList.GetNext (pos);
if (Rprg.type == mptype) {
bRemoveType = FALSE;
break;
}
}
if (bRemoveType)
ch->GetInRoom ()->m_Progtypes.ClrBit (mptype);
ch->SendText ("Program removed.\n\r");
return;
}
if (! str_cmp (arg2, "insert")) {
if (PList.IsEmpty ()) {
ch->SendText ("That room has no room programs.\n\r");
return;
}
argument = one_argument (argument, arg3);
mptype = get_mpflag (arg2);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
if (value < 1) {
ch->SendText ("Program not found.\n\r");
return;
}
// Get position of item to insert before
POSITION pos = PList.FindIndex (--value); // index is base 0
if (! pos) {
ch->SendText ("Program not found.\n\r");
return;
}
CMobProgData *pRprg = new CMobProgData;
ch->GetInRoom ()->m_Progtypes.SetBit (mptype);
mpedit (ch, pRprg, mptype, argument);
PList.InsertBefore (pos, pRprg);
return;
}
if (! str_cmp (arg1, "add")) {
mptype = get_mpflag (arg2);
if (mptype == -1) {
ch->SendText ("Unknown program type.\n\r");
return;
}
CMobProgData *pRprg = new CMobProgData;
PList.AddTail (pRprg);
ch->GetInRoom ()->m_Progtypes.SetBit (mptype);
mpedit (ch, pRprg, mptype, argument);
return;
}
do_rpedit (ch, "");
}
void do_rdelete (CCharacter *ch, char *argument)
{
char arg[MAX_INPUT_LENGTH];
CRoomIndexData *location;
argument = one_argument (argument, arg);
/* Temporarily disable this command. */
return;
if (arg[0] == '\0')
{
ch->SendText ("Delete which room?\n\r");
return;
}
/* Find the room. */
if ((location = find_location (ch, arg)) == NULL)
{
ch->SendText ("No such location.\n\r");
return;
}
/* Does the player have the right to delete this room? */
if (ch->GetTrustLevel () < SysData.ModifyProtoLevel
&& (location->vnum < ch->GetPcData ()->r_range_lo ||
location->vnum > ch->GetPcData ()->r_range_hi))
{
ch->SendText ("That room is not in your assigned range.\n\r");
return;
}
// We could go to the trouble of clearing out the room, but why?
if (location->first_person || location->IsEmpty ()) {
ch->SendText ("The room must be empty first.\n\r");
return;
}
// Ok, we've determined that the room exists, it is empty and the
// player has the authority to delete it, so let's dump the thing.
RoomTable.Remove (location);
delete location;
ch->SendText ("Room deleted.\n\r");
}
void do_odelete (CCharacter *ch, char *argument)
{
}
void do_mdelete (CCharacter *ch, char *argument)
{
}
void ClearAddrRange (void* start, void* end, UINT SizEnd)
{
memset (start, 0, (int) ((char*) end + SizEnd - (char*) start));
}