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