/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | * * -----------------------------------------------------------| \\._.// * * SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version) | (0...0) * * -----------------------------------------------------------| ).:.( * * SMAUG (C) 1994, 1995, 1996 by Derek Snider | {o o} * * -----------------------------------------------------------| / ' ' \ * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, |~'~.VxvxV.~'~* * Scryn, Swordbearer, Rennard, Tricops, and Gorog. | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe. * **************************************************************************** * The MUDprograms are heavily based on the original MOBprogram code that * * was written by N'Atas-ha. * ****************************************************************************/ #include "stdafx.h" #include "smaug.h" #include "SysData.h" #include "area.h" #include "skill.h" #include "mobiles.h" #include "objects.h" #include "rooms.h" #include "races.h" #include "class.h" #include "Exits.h" #include "SmaugWizDoc.h" #include "descriptor.h" #include "character.h" char *mprog_type_to_name (int type); ch_ret simple_damage (CCharacter *ch, CCharacter *victim, int dam, int dt); char *mprog_type_to_name (int type) { switch (type) { case IN_FILE_PROG: return "in_file_prog"; case ACT_PROG: return "act_prog"; case SPEECH_PROG: return "speech_prog"; case RAND_PROG: return "rand_prog"; case FIGHT_PROG: return "fight_prog"; case HITPRCNT_PROG: return "hitprcnt_prog"; case DEATH_PROG: return "death_prog"; case ENTRY_PROG: return "entry_prog"; case GREET_PROG: return "greet_prog"; case ALL_GREET_PROG: return "all_greet_prog"; case GIVE_PROG: return "give_prog"; case BRIBE_PROG: return "bribe_prog"; case HOUR_PROG: return "hour_prog"; case TIME_PROG: return "time_prog"; case WEAR_PROG: return "wear_prog"; case REMOVE_PROG: return "remove_prog"; case SAC_PROG : return "sac_prog"; case LOOK_PROG: return "look_prog"; case EXA_PROG: return "exa_prog"; case ZAP_PROG: return "zap_prog"; case GET_PROG: return "get_prog"; case DROP_PROG: return "drop_prog"; case REPAIR_PROG: return "repair_prog"; case DAMAGE_PROG: return "damage_prog"; case PULL_PROG: return "pull_prog"; case PUSH_PROG: return "push_prog"; case SCRIPT_PROG: return "script_prog"; case SLEEP_PROG: return "sleep_prog"; case REST_PROG: return "rest_prog"; case LEAVE_PROG: return "leave_prog"; case USE_PROG: return "use_prog"; default: return "ERROR_PROG"; } } // A trivial rehack of do_mstat. This doesnt show all the data, but just // enough to identify the mob and give its basic condition. It does however, // show the MUDprograms which are set. void do_mpstat (CCharacter *ch, char *argument) { char arg [MAX_INPUT_LENGTH]; CCharacter *victim; one_argument (argument, arg); if (arg [0] == '\0') { ch->SendText ("MProg stat whom?\n\r"); return; } if ((victim = get_char_world (ch, arg)) == NULL) { ch->SendText ("They aren't here.\n\r"); return; } if (! victim->IsNpc ()) { ch->SendText ("Only Mobiles can have MobPrograms!\n\r"); return; } if (victim->GetMobIndex ()->m_Progtypes.IsEmpty ()) { ch->SendText ("That Mobile has no Programs set.\n\r"); return; } ch->SendTextf ("Name: %s. Vnum: %d.\n\r", victim->GetName (), victim->GetMobIndex ()->vnum); ch->SendTextf ("Short description: %s.\n\rLong description: %s", victim->GetShortDescr (), victim->HasLongDescription () ? victim->GetLongDescr () : "(none).\n\r"); ch->SendTextf ("Hp: %d/%d. Mana: %d/%d. Move: %d/%d. \n\r", victim->GetHp (), victim->GetMaxHp (), victim->GetMana (), victim->GetMaxMana (), victim->GetMove (), victim->GetMaxMove ()); ch->SendTextf ( "Lv: %d. Class: %d. Align: %d. AC: %d. Gold: %d. Exp: %d.\n\r", victim->GetLevel (), victim->GetClass (), victim->GetAlignment (), victim->GetAc (), victim->GetGold (), victim->GetExp ()); CPtrList &PList = victim->GetMobIndex ()->MobPrgList; POSITION pos = PList.GetHeadPosition (); while (pos) { CMobProgData &Mprg = *(CMobProgData*) PList.GetNext (pos); ch->SendTextf (">%s %s\n\r%s\n\r", mprog_type_to_name (Mprg.type), Mprg.arglist, Mprg.comlist); } return; } /* Opstat - Scryn 8/12*/ void do_opstat (CCharacter *ch, char *argument) { char arg [MAX_INPUT_LENGTH]; CObjData *obj; one_argument (argument, arg); if (arg[0] == '\0') { ch->SendText ("OProg stat what?\n\r"); return; } if ((obj = get_obj_world (ch, arg)) == NULL) { ch->SendText ("You cannot find that.\n\r"); return; } if (obj->pIndexData->m_Progtypes.IsEmpty ()) { ch->SendText ("That object has no programs set.\n\r"); return; } ch->SendTextf ("Name: %s. Vnum: %d.\n\r", obj->GetName (), obj->pIndexData->vnum); ch->SendColorf ("Short description: %s.\n\r", obj->GetShortDescr ()); CPtrList &PList = obj->pIndexData->ObjPrgList; POSITION pos = PList.GetHeadPosition (); while (pos) { CMobProgData &Oprg = *(CMobProgData*) PList.GetNext (pos); ch->SendTextf (">%s %s\n\r%s\n\r", mprog_type_to_name (Oprg.type), Oprg.arglist, Oprg.comlist); } return; } /* Rpstat - Scryn 8/12 */ void do_rpstat (CCharacter *ch, char *argument) { if (ch->GetInRoom ()->m_Progtypes.IsEmpty ()) { ch->SendText ("This room has no programs set.\n\r"); return; } ch->SendTextf ("Name: %s. Vnum: %d.\n\r", ch->GetInRoom ()->GetName (), ch->GetInRoom ()->vnum); CPtrList &PList = ch->GetInRoom ()->RoomPrgList; POSITION pos = PList.GetHeadPosition (); while (pos) { CMobProgData &Rprg = *(CMobProgData*) PList.GetNext (pos); ch->SendColorf (">%s %s\n\r%s\n\r", mprog_type_to_name (Rprg.type), Rprg.arglist, Rprg.comlist); } } // Prints the argument to all the rooms around the mobile void do_mpasound (CCharacter *ch, char *argument) { CRoomIndexData *was_in_room; CExitData *pexit; if (! ch) { bug ("Nonexistent ch in do_mpasound!"); return; } if (ch->IsCharmed ()) return; if (! ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } if (argument [0] == '\0') { progbug ("Mpasound - No argument", ch); return; } CActFlags actflags = ch->GetActFlags (); // save act flags ch->ClrSecretive (); was_in_room = ch->GetInRoom (); for (pexit = was_in_room->first_exit; pexit; pexit = pexit->GetNext ()) { if (pexit->GetToRoom () && pexit->GetToRoom () != was_in_room) { ch->SetInRoom (pexit->GetToRoom ()); MOBtrigger = FALSE; act (AT_SAY, argument, ch, NULL, NULL, TO_ROOM); } } ch->SetActFlags (actflags); // restore act flags ch->SetInRoom (was_in_room); } // Woowoo - Blodkai, November 1997 void do_mpasupress (CCharacter* ch, char* argument) { char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; CCharacter *victim; int rnds; if (! ch->IsNpc () || ch->IsCharmed ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); if (arg1 [0] == '\0') { ch->SendText ("Mpasupress who?\n\r"); progbug ("Mpasupress: invalid argument", ch ); return; } if (arg2 [0] == '\0') { ch->SendText ("Supress their attacks for how many rounds?\n\r"); progbug ("Mpasupress: invalid argument", ch); return; } if ((victim = get_char_room (ch, arg1)) == NULL) { ch->SendText ("No such victim in the room.\n\r"); progbug ("Mpasupress: victim not present", ch); return; } rnds = atoi (arg2); if (rnds < 0 || rnds > 32000) { ch->SendText ("Invalid number of rounds to supress attacks.\n\r"); progbug ("Mpsupress: invalid argument", ch); return; } add_timer (victim, TIMER_ASUPRESSED, rnds, NULL, 0); } // lets the mobile kill any player or mobile without murder void do_mpkill (CCharacter *ch, char *argument) { char arg [MAX_INPUT_LENGTH]; CCharacter *victim; if (! ch->IsNpc () || ch->IsCharmed ()) { ch->SendText ("Huh?\n\r"); return; } if (! ch) { bug ("Nonexistent ch in do_mpkill!"); return; } one_argument (argument, arg); if (arg [0] == '\0') { progbug ("MpKill - no argument", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { progbug ("MpKill - Victim not in room", ch); return; } if (victim == ch) { progbug ("MpKill - Bad victim to attack", ch); return; } if (ch->IsCharmed () && ch->GetMaster () == victim) { progbug ("MpKill - Charmed mob attacking master", ch); return; } if (ch->IsFightPosition ()) { progbug ("MpKill - Already fighting", ch); return; } multi_hit (ch, victim, TYPE_UNDEFINED); } // lets the mobile destroy an object in its inventory // it can also destroy a worn object and it can destroy // items using all.xxxxx or just plain all of them void do_mpjunk (CCharacter *ch, char *argument) { char arg [MAX_INPUT_LENGTH]; CObjData *obj; if (ch->IsCharmed ()) return; if (! ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } one_argument (argument, arg); if (arg [0] == '\0') { progbug ("Mpjunk - No argument", ch); return; } if (str_cmp (arg, "all") && str_prefix ("all.", arg)) { if (obj = get_obj_wear (ch, arg)) { unequip_char (ch, obj); extract_obj (obj); return; } if ((obj = get_obj_carry (ch, arg)) == NULL) return; extract_obj (obj); } else { POSITION pos = ch->GetHeadCarryPos (); while (obj = ch->GetNextCarrying (pos)) { if (arg [3] == '\0' || is_name (&arg [4], obj->GetName ())) { if (obj->wear_loc != WEAR_NONE) unequip_char (ch, obj); extract_obj (obj); } } } } /* * This function examines a text string to see if the first "word" is a * color indicator (e.g. _red, _whi_, _blu). - Gorog */ int get_color (char *argument) /* get color code from command string */ { char color[MAX_INPUT_LENGTH]; const char *cptr; static char const * color_list= "_bla_red_dgr_bro_dbl_pur_cya_cha_dch_ora_gre_yel_blu_pin_lbl_whi"; static char const * blink_list= "*bla*red*dgr*bro*dbl*pur*cya*cha*dch*ora*gre*yel*blu*pin*lbl*whi"; one_argument (argument, color); if (color[0]!='_' && color[0]!='*') return 0; if ((cptr = strstr (color_list, color))) return (cptr - color_list) / 4; if ((cptr = strstr (blink_list, color))) return (cptr - blink_list) / 4 + AT_BLINK; return 0; } // prints the message to everyone in the room other than the mob and victim void do_mpechoaround (CCharacter *ch, char *argument) { char arg[ MAX_INPUT_LENGTH ]; CCharacter *victim; short color; if (ch->IsCharmed ()) return; if (! ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg); if (arg [0] == '\0') { progbug ("Mpechoaround - No argument", ch); return; } if (! (victim = get_char_room (ch, arg))) { progbug ("Mpechoaround - victim does not exist", ch); return; } CActFlags actflags = ch->GetActFlags (); ch->ClrSecretive (); if ((color = get_color (argument))) { argument = one_argument (argument, arg); act (color, argument, ch, NULL, victim, TO_NOTVICT); } else act (AT_ACTION, argument, ch, NULL, victim, TO_NOTVICT); ch->SetActFlags (actflags); } // prints message only to victim void do_mpechoat (CCharacter *ch, char *argument) { char arg[ MAX_INPUT_LENGTH ]; CCharacter *victim; short color; if (ch->IsCharmed ()) return; if (! ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg); if (arg [0] == '\0' || argument [0] == '\0') { progbug ("Mpechoat - No argument", ch); return; } if (! (victim = get_char_room (ch, arg))) { CString s; s.Format ("Mpechoat - victim does not exist: %s", arg); progbug (s, ch); return; } CActFlags actflags = ch->GetActFlags (); ch->ClrSecretive (); if ((color = get_color (argument))) { argument = one_argument (argument, arg); act (color, argument, ch, NULL, victim, TO_VICT); } else act (AT_ACTION, argument, ch, NULL, victim, TO_VICT); ch->SetActFlags (actflags); } // prints message to room at large. void do_mpecho (CCharacter *ch, char *argument) { char arg1 [MAX_INPUT_LENGTH]; short color; if (ch->IsCharmed ()) return; if (! ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } if (argument [0] == '\0') { progbug ("Mpecho - called w/o argument", ch); return; } CActFlags actflags = ch->GetActFlags (); ch->ClrSecretive (); if ((color = get_color (argument))) { argument = one_argument (argument, arg1); act (color, argument, ch, NULL, NULL, TO_ROOM); } else act (AT_ACTION, argument, ch, NULL, NULL, TO_ROOM); ch->SetActFlags (actflags); } /* lets the mobile load an item or mobile. All items are loaded into inventory. you can specify a level with the load object portion as well. */ void do_mpmload (CCharacter *ch, char *argument) { char arg[ MAX_INPUT_LENGTH ]; CMobIndexData *pMobIndex; CCharacter *victim; if (ch->IsCharmed ()) return; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } one_argument (argument, arg); if (arg[0] == '\0' || !is_number (arg)) { progbug ("Mpmload - Bad vnum as arg", ch); return; } if ((pMobIndex = MobTable.GetMob (atoi (arg))) == NULL) { progbug ("Mpmload - Bad mob vnum", ch); return; } victim = create_mobile (pMobIndex); victim->SendToRoom (ch->GetInRoom ()); return; } void do_mpoload (CCharacter *ch, char *argument) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CObjIndexData *pObjIndex; CObjData *obj; int level; int timer = 0; if (ch->IsCharmed ()) return; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); if (arg1[0] == '\0' || !is_number (arg1)) { progbug ("Mpoload - Bad syntax", ch); return; } if (arg2[0] == '\0') level = ch->GetTrustLevel (); else { /* * New feature from Alander. */ if (!is_number (arg2)) { progbug ("Mpoload - Bad level syntax", ch); return; } level = atoi (arg2); if (level < 0 || level > ch->GetTrustLevel ()) { progbug ("Mpoload - Bad level", ch); return; } /* * New feature from Thoric. */ timer = atoi (argument); if (timer < 0) { progbug ("Mpoload - Bad timer", ch); return; } } if ((pObjIndex = OIdxTable.GetObj (atoi (arg1))) == NULL) { progbug ("Mpoload - Bad vnum arg", ch); return; } obj = create_object (pObjIndex, level); obj->timer = timer; if (obj->CanWear (ITEM_TAKE)) obj_to_char (obj, ch); else obj_to_room (obj, ch->GetInRoom ()); return; } // Just a hack of do_pardon from act_wiz.c -- Blodkai, 6/15/97 void do_mppardon (CCharacter* ch, char* argument) { char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; CCharacter *victim; if (ch->IsNpc () || ch->IsCharmed ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); if (arg1 [0] == '\0' || arg2 [0] == '\0') { progbug ("Mppardon: missing argument", ch); ch->SendText ("Mppardon who for what?\n\r"); return; } if ((victim = get_char_room (ch, arg1)) == NULL) { progbug ("Mppardon: offender not present", ch); ch->SendText ("They aren't here.\n\r"); return; } if (victim->IsNpc ()) { progbug ("Mppardon: trying to pardon NPC", ch); ch->SendText ("Not on NPC's.\n\r"); return; } if (! str_cmp (arg2, "attacker")) { if (victim->IsAttacker ()) { victim->ClrAttacker (); ch->SendText ("Attacker flag removed.\n\r"); victim->SendText ("Your crime of attack has been pardoned.\n\r"); } return; } if (! str_cmp (arg2, "killer")) { if (victim->IsKiller ()) { victim->ClrKiller (); ch->SendText ("Killer flag removed.\n\r"); victim->SendText ("Your crime of murder has been pardoned.\n\r"); } return; } if (! str_cmp (arg2, "litterbug")) { if (victim->IsLitterBug ()) { victim->ClrLitterBug (); ch->SendText ("Litterbug flag removed.\n\r"); victim->SendText ("Your crime of littering has been pardoned./n/r"); } return; } if (! str_cmp (arg2, "thief")) { if (victim->IsThief ()) { victim->ClrThief (); ch->SendText ("Thief flag removed.\n\r"); victim->SendText ("Your crime of theft has been pardoned.\n\r"); } return; } ch->SendText ("Pardon who for what?\n\r"); progbug ("Mppardon: Invalid argument", ch); } /* lets the mobile purge all objects and other npcs in the room, or purge a specified object or mob in the room. It can purge itself, but this had best be the last command in the MUDprogram otherwise ugly stuff will happen */ void do_mppurge (CCharacter *ch, char *argument) { char arg[ MAX_INPUT_LENGTH ]; CCharacter *victim; CObjData *obj; if (ch->IsCharmed ()) return; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } one_argument (argument, arg); if (arg[0] == '\0') { /* 'purge' */ CCharacter *vnext; for (victim = ch->GetInRoom ()->first_person; victim; victim = vnext) { vnext = victim->GetNextInRoom (); if (victim->IsNpc () && victim != ch) extract_char (victim, TRUE); } while (! ch->GetInRoom ()->IsEmpty ()) extract_obj (ch->GetInRoom ()->GetFirstContent ()); return; } if ((victim = get_char_room (ch, arg)) == NULL) { if ((obj = get_obj_here (ch, arg)) != NULL) extract_obj (obj); else progbug ("Mppurge - Bad argument", ch); return; } if (!victim->IsNpc ()) { progbug ("Mppurge - Trying to purge a PC", ch); return; } if (victim == ch) { progbug ("Mppurge - Trying to purge oneself", ch); return; } if (victim->IsNpc () && victim->GetMobIndex ()->vnum == 3) { progbug ("Mppurge: trying to purge supermob", ch); return; } extract_char (victim, TRUE); return; } /* Allow mobiles to go wizinvis with programs -- SB */ void do_mpinvis (CCharacter *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; short level; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg); if (arg && arg[0] != '\0') { if (!is_number (arg)) { progbug ("Mpinvis - Non numeric argument ", ch); return; } level = atoi (arg); if (level < 2 || level > 51) { progbug ("MPinvis - Invalid level ", ch); return; } ch->SetMobInvisLevel (level); ch->SendTextf ("Mobinvis level set to %d.\n\r", level); return; } if (ch->GetMobInvisLevel () < 2) ch->SetMobInvisLevel (ch->GetLevel ()); if (ch->IsAction (ACT_MOBINVIS)) { ch->ClrActBit (ACT_MOBINVIS); act (AT_IMMORT, "$n slowly fades into existence.", ch, NULL, NULL,TO_ROOM); ch->SendText ("You slowly fade back into existence.\n\r"); } else { ch->SetActBit (ACT_MOBINVIS); act (AT_IMMORT, "$n slowly fades into thin air.", ch, NULL, NULL, TO_ROOM); ch->SendText ("You slowly vanish into thin air.\n\r"); } return; } /* lets the mobile goto any location it wishes that is not private */ void do_mpgoto (CCharacter *ch, char *argument) { char arg[ MAX_INPUT_LENGTH ]; CRoomIndexData *location; if (ch->IsCharmed ()) return; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } one_argument (argument, arg); if (arg[0] == '\0') { progbug ("Mpgoto - No argument", ch); return; } if ((location = find_location (ch, arg)) == NULL) { progbug ("Mpgoto - No such location", ch); return; } if (ch->GetFightData ()) stop_fighting (ch, TRUE); ch->RemoveFromRoom (); ch->SendToRoom (location); return; } /* lets the mobile do a command at another location. Very useful */ void do_mpat (CCharacter *ch, char *argument) { char arg[ MAX_INPUT_LENGTH ]; CRoomIndexData *location; CRoomIndexData *original; CCharacter *wch; if (ch->IsCharmed ()) return; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg); if (arg[0] == '\0' || argument[0] == '\0') { progbug ("Mpat - Bad argument", ch); return; } if ((location = find_location (ch, arg)) == NULL) { progbug ("Mpat - No such location", ch); return; } original = ch->GetInRoom (); ch->RemoveFromRoom (); ch->SendToRoom (location); interpret (ch, argument); /* * See if 'ch' still exists before continuing! * Handles 'at XXXX quit' case. */ for (wch = first_char; wch; wch = wch->GetNext ()) if (wch == ch) { ch->RemoveFromRoom (); ch->SendToRoom (original); break; } return; } /* allow a mobile to advance a player's level... very dangerous */ void do_mpadvance (CCharacter *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; CCharacter *victim; int level; int iLevel; if (ch->IsCharmed ()) return; if (!ch->IsNpc () || ch->GetDesc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg); if (arg[0] == '\0') { progbug ("Mpadvance - Bad syntax", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { progbug ("Mpadvance - Victim not there", ch); return; } if (victim->IsNpc ()) { progbug ("Mpadvance - Victim is NPC", ch); return; } if (victim->GetLevel () >= LEVEL_AVATAR) return; level = victim->GetLevel () + 1; if (victim->GetLevel () > ch->GetLevel ()) { act (AT_TELL, "$n tells you, 'Sorry... you must seek someone more powerful than I.'", ch, NULL, victim, TO_VICT); return; } if (victim->GetLevel () >= LEVEL_AVATAR) { set_char_color (AT_IMMORT, victim); act (AT_IMMORT, "$n makes some arcane gestures with $s hands, then points $s fingers at you!", ch, NULL, victim, TO_VICT); act (AT_IMMORT, "$n makes some arcane gestures with $s hands, then points $s fingers at $N!", ch, NULL, victim, TO_NOTVICT); set_char_color (AT_WHITE, victim); victim->SendText ("You suddenly feel very strange...\n\r\n\r"); set_char_color (AT_LBLUE, victim); } switch (level) { default: victim->SendText ("You feel more powerful!\n\r"); break; case LEVEL_IMMORTAL: do_help (victim, "M_GODLVL1_"); set_char_color (AT_WHITE, victim); victim->SendText ("You awake... all your possessions are gone.\n\r"); while (victim->IsCarrying ()) extract_obj (victim->GetFirstCarrying ()); break; case LEVEL_ACOLYTE: do_help (victim, "M_GODLVL2_"); break; case LEVEL_CREATOR: do_help (victim, "M_GODLVL3_"); break; case LEVEL_SAVIOR: do_help (victim, "M_GODLVL4_"); break; case LEVEL_DEMI: do_help (victim, "M_GODLVL5_"); break; case LEVEL_TRUEIMM: do_help (victim, "M_GODLVL6_"); break; case LEVEL_LESSER: do_help (victim, "M_GODLVL7_"); break; case LEVEL_GOD: do_help (victim, "M_GODLVL8_"); break; case LEVEL_GREATER: do_help (victim, "M_GODLVL9_"); break; case LEVEL_ASCENDANT: do_help (victim, "M_GODLVL10_"); break; case LEVEL_SUB_IMPLEM: do_help (victim, "M_GODLVL11_"); break; case LEVEL_IMPLEMENTOR: do_help (victim, "M_GODLVL12_"); break; case LEVEL_ETERNAL: do_help (victim, "M_GODLVL13_"); break; case LEVEL_INFINITE: do_help (victim, "M_GODLVL14_"); break; case LEVEL_SUPREME: do_help (victim, "M_GODLVL15_"); } for (iLevel = victim->GetLevel () ; iLevel < level; iLevel++) { if (level < LEVEL_IMMORTAL) victim->SendText ("You raise a level!! "); victim->AddLevel (1); advance_level (victim); } victim->SetExp (1000 * UMAX (1, victim->GetLevel ())); victim->SetTrust (0); } /* lets the mobile transfer people. the all argument transfers everyone in the current room to the specified location */ void do_mptransfer (CCharacter *ch, char *argument) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char buf[MAX_STRING_LENGTH]; CRoomIndexData *location; CCharacter *victim; CCharacter *nextinroom; if (ch->IsCharmed ()) return; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); if (arg1[0] == '\0') { progbug ("Mptransfer - Bad syntax", ch); return; } /* Put in the variable nextinroom to make this work right. -Narn */ if (!str_cmp (arg1, "all")) { for (victim = ch->GetInRoom ()->first_person; victim; victim = nextinroom) { nextinroom = victim->GetNextInRoom (); if (victim != ch && victim->IsAuthed () && can_see (ch, victim)) { sprintf (buf, "%s %s", victim->GetName (), arg2); do_mptransfer (ch, buf); } } return; } // Thanks to Grodyn for the optional location parameter. CString s; if (arg2 [0] == '\0') location = ch->GetInRoom (); else { s.Format ("Mptransfer - No such location: %s", arg2); if ((location = find_location (ch, arg2)) == NULL) { progbug (s, ch); return; } if (room_is_private (location)) { progbug ("Mptransfer - Private room", ch); return; } } if ((victim = get_char_world (ch, arg1)) == NULL) { s.Format ("Mptransfer - No such person: %s", arg1); progbug (s, ch); return; } if (! victim->GetInRoom ()) { progbug ("Mptransfer - Victim in Limbo", ch); return; } if (! victim->IsAuthed () && location->GetArea () != victim->GetInRoom ()->GetArea ()) { s.Format ("Mptransfer - transferring unauthorized player: %s", arg1); progbug (s, ch); return; } // If victim not in area's level range, do not transfer if (!in_hard_range (victim, location->GetArea ()) && ! location->IsPrototype ()) return; if (victim->GetFightData ()) stop_fighting (victim, TRUE); victim->RemoveFromRoom (); victim->SendToRoom (location); } // lets the mobile force someone to do something. must be mortal level // and the all argument only affects those in the room with the mobile void do_mpforce (CCharacter *ch, char *argument) { char arg [MAX_INPUT_LENGTH]; CString s; if (ch->IsCharmed ()) return; if (! ch->IsNpc () || ch->GetDesc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg); if (arg [0] == '\0' || argument [0] == '\0') { progbug ("Mpforce - Bad syntax, no argument", ch); return; } if (! str_cmp (arg, "all")) { CCharacter *vch = ch->GetInRoom ()->first_person; for ( ; vch; vch = vch->GetNextInRoom ()) if (vch->GetTrustLevel () < ch->GetTrustLevel () && can_see (ch, vch)) interpret (vch, argument); } else { CCharacter *victim; if ((victim = get_char_room (ch, arg)) == NULL) { s.Format ("Mpforce - No such victim: %s", arg); progbug (s, ch); return; } if (victim == ch) { progbug ("Mpforce - Forcing oneself", ch); return; } if (! victim->IsNpc () && (! victim->GetDesc ()) && victim->IsImmortal ()) { s.Format ("Mpforce - Attempting to force link dead immortal: %s", arg); progbug (s, ch); return; } interpret (victim, argument); } } // mpbodybag for mobs to do cr's --Shaddai void do_mpbodybag (CCharacter* ch, char* argument) { CCharacter *victim; CObjData *obj; char arg [MAX_STRING_LENGTH]; char buf2 [MAX_STRING_LENGTH]; char buf3 [MAX_STRING_LENGTH]; if (! ch->IsNpc () || ch->GetDesc () || ch->IsCharmed ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg); if (arg [0] == '\0') { progbug ("Mpbodybag - called w/o enough arguments", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { ch->SendText ("Victim must be in room.\n\r"); progbug ("Mpbodybag: victim not in room", ch); return; } if (victim->IsNpc ()) { progbug ("Mpbodybag: bodybagging a npc corpse", ch); return; } sprintf (buf2, "the corpse of %s", arg); int count = 0; CObjIndexData &Idx = *OIdxTable.Find (OBJ_VNUM_CORPSE_PC); if (! &Idx) bug ("do_bodybag: No object index for OBJ_VNUM_CORPSE_PC."); else { POSITION pos = Idx.m_ObjList.GetHeadPosition (); while (pos) { obj = Idx.m_ObjList.GetNext (pos); if (obj->in_room && !str_cmp (buf2, obj->GetShortDescr ())) { obj_from_room (obj); obj = obj_to_char (obj, ch); obj->timer = -1; ++count; } } } // Maybe should just make the command logged... Shrug I am not sure // --Shaddai if (count) { sprintf (buf3, "Mpbodybag: Grabbed %s (%d)", buf2, count); progbug (buf3, ch); } } // syntax: mppractice victim spell_name max% void do_mp_practice (CCharacter *ch, char *argument) { char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; char arg3 [MAX_INPUT_LENGTH]; char buf [MAX_INPUT_LENGTH]; CCharacter *victim; int sn, max, tmp, adept; char *skill_name; if (ch->IsCharmed ()) return; if (! ch->IsNpc ()) { // security breach, i guess ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); argument = one_argument (argument, arg3); if (arg1 [0] == '\0' || arg2 [0] == '\0' || arg3 [0] == '\0') { ch->SendText ("Mppractice: bad syntax"); progbug ("Mppractice - Bad syntax", ch); return; } if ((victim = get_char_room (ch, arg1)) == NULL) { ch->SendText ("Mppractice: Student not in room? Invis?"); progbug ("Mppractice: Invalid student not in room", ch); return; } if ((sn = SkillTable.Lookup (arg2)) < 0) { ch->SendText ("Mppractice: Invalid spell/skill name"); progbug ("Mppractice: Invalid spell/skill name", ch); return; } if (victim->IsNpc ()) { ch->SendText ("Mppractice: Can't train a mob"); progbug ("Mppractice: Can't train a mob", ch); return; } skill_name = SkillTable.GetName (sn); max = atoi (arg3); if ((max<0) || (max>100)) { sprintf (log_buf, "mp_practice: Invalid maxpercent: %d", max); ch->SendText (log_buf); progbug (log_buf, ch); return; } if (victim->GetLevel () < SkillTable.GetClassLevel (sn, victim->GetClass ())) { sprintf (buf, "$n attempts to tutor you in %s, but it's beyond " "your comprehension.", skill_name); act (AT_TELL, buf, ch, NULL, victim, TO_VICT); return; } // adept is how high the player can learn it adept = SkillTable.GetClassAdept (sn, victim->GetClass ()); if ((victim->GetPcData ()->learned[sn] >= adept) || (victim->GetPcData ()->learned[sn] >= max)) { sprintf (buf, "$n shows some knowledge of %s, but yours is " "clearly superior.", skill_name); act (AT_TELL, buf, ch, NULL, victim, TO_VICT); return; } // past here, victim learns something tmp = UMIN (victim->GetPcData ()->learned[sn] + int_app [victim->GetIntelligence ()].learn, max); act (AT_ACTION, "$N demonstrates $t to you. You feel more learned " "in this subject.", victim, SkillTable.GetName (sn), ch,TO_CHAR); victim->GetPcData ()->learned [sn] = max; if (victim->GetPcData ()->learned[sn] >= adept) { victim->GetPcData ()->learned[sn] = adept; act (AT_TELL, "$n tells you, 'You have learned all I know on this subject...'", ch, NULL, victim, TO_VICT); } } /* * syntax: mpslay (character) */ void do_mp_slay (CCharacter *ch, char *argument) { char arg1[ MAX_INPUT_LENGTH ]; CCharacter *victim; if (ch->IsCharmed ()) return; if (!ch->IsNpc () || ch->GetDesc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); if (arg1[0] == '\0') { ch->SendText ("mpslay whom?\n\r"); progbug ("Mpslay: invalid (nonexistent?) argument", ch); return; } if ((victim = get_char_room (ch, arg1)) == NULL) { ch->SendText ("Victim must be in room.\n\r"); progbug ("Mpslay: victim not in room", ch); return; } if (victim == ch) { ch->SendText ("You try to slay yourself. You fail.\n\r"); progbug ("Mpslay: trying to slay self", ch); return; } if (victim->IsNpc () && victim->GetMobIndex ()->vnum == 3) { ch->SendText ("You cannot slay supermob!\n\r"); progbug ("Mpslay: trying to slay supermob", ch); return; } if (victim->GetLevel () < LEVEL_IMMORTAL) { act (AT_IMMORT, "You slay $M in cold blood!", ch, NULL, victim, TO_CHAR); act (AT_IMMORT, "$n slays you in cold blood!", ch, NULL, victim, TO_VICT); act (AT_IMMORT, "$n slays $N in cold blood!", ch, NULL, victim, TO_NOTVICT); set_cur_char (victim); raw_kill (ch, victim); stop_fighting (ch, FALSE); stop_hating (ch); stop_fearing (ch); stop_hunting (ch); } else { act (AT_IMMORT, "You attempt to slay $M and fail!", ch, NULL, victim, TO_CHAR); act (AT_IMMORT, "$n attempts to slay you. What a kneebiter!", ch, NULL, victim, TO_VICT); act (AT_IMMORT, "$n attempts to slay $N. Needless to say $e fails.", ch, NULL, victim, TO_NOTVICT); } return; } /* * syntax: mpdamage (character) (#hps) */ void do_mp_damage (CCharacter *ch, char *argument) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CCharacter *victim; int dam; if (ch->IsCharmed ()) return; if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) ) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); if (arg1[0] == '\0') { ch->SendText ("mpdamage whom?\n\r"); progbug ("Mpdamage: invalid argument1", ch); return; } if (arg2[0] == '\0') { ch->SendText ("mpdamage inflict how many hps?\n\r"); progbug ("Mpdamage: invalid argument2", ch); return; } if ((victim = get_char_room (ch, arg1)) == NULL) { ch->SendText ("Victim must be in room.\n\r"); progbug ("Mpdamage: victim not in room", ch); return; } if (victim == ch) { ch->SendText ("You can't mpdamage yourself.\n\r"); progbug ("Mpdamage: trying to damage self", ch); return; } dam = atoi (arg2); if ((dam<0) || (dam>32000)) { ch->SendText ("Mpdamage how much?\n\r"); progbug ("Mpdamage: invalid (nonexistent?) argument", ch); return; } /* this is kinda begging for trouble */ /* * Note from Thoric to whoever put this in... * Wouldn't it be better to call damage (ch, ch, dam, dt)? * I hate redundant code */ if (simple_damage (ch, victim, dam, TYPE_UNDEFINED) == rVICT_DIED) { stop_fighting (ch, FALSE); stop_hating (ch); stop_fearing (ch); stop_hunting (ch); } return; } /* * syntax: mprestore (character) (#hps) Gorog */ void do_mp_restore (CCharacter *ch, char *argument) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CCharacter *victim; int hp; if (ch->IsCharmed ()) return; if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) ) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); if (arg1[0] == '\0') { ch->SendText ("mprestore whom?\n\r"); progbug ("Mprestore: invalid argument1", ch); return; } if (arg2[0] == '\0') { ch->SendText ("mprestore how many hps?\n\r"); progbug ("Mprestore: invalid argument2", ch); return; } if ((victim = get_char_room (ch, arg1)) == NULL) { ch->SendText ("Victim must be in room.\n\r"); progbug ("Mprestore: victim not in room", ch); return; } hp = atoi (arg2); if ((hp<0) || (hp>32000)) { ch->SendText ("Mprestore how much?\n\r"); progbug ("Mprestore: invalid (nonexistent?) argument", ch); return; } hp += victim->GetHp (); victim->SetHp ((hp > 32000 || hp < 0 || hp > victim->GetMaxHp ()) ? victim->GetMaxHp () : hp); } /* * Syntax mpfavor target number * Raise a player's favor in progs. */ void do_mpfavor (CCharacter *ch, char *argument) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CCharacter *victim; int favor; if (ch->IsCharmed ()) return; if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) ) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); if (arg1[0] == '\0') { ch->SendText ("mpfavor whom?\n\r"); progbug ("Mpfavor: invalid argument1", ch); return; } if (arg2[0] == '\0') { ch->SendText ("mpfavor how much favor?\n\r"); progbug ("Mpfavor: invalid argument2", ch); return; } if ((victim = get_char_room (ch, arg1)) == NULL) { ch->SendText ("Victim must be in room.\n\r"); progbug ("Mpfavor: victim not in room", ch); return; } favor = atoi (arg2); victim->GetPcData ()->favor = URANGE (-1000, victim->GetPcData ()->favor + favor, 1000); } /* * Syntax mp_open_passage x y z * * opens a 1-way passage from room x to room y in direction z * * won't mess with existing exits */ void do_mp_open_passage (CCharacter *ch, char *argument) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char arg3[ MAX_INPUT_LENGTH ]; CRoomIndexData *targetRoom, *fromRoom; int targetRoomVnum, fromRoomVnum, exit_num; CExitData *pexit; if (ch->IsCharmed ()) return; if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) ) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); argument = one_argument (argument, arg3); if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0') { progbug ("MpOpenPassage - Bad syntax", ch); return; } if (!is_number (arg1)) { progbug ("MpOpenPassage - Bad syntax", ch); return; } fromRoomVnum = atoi (arg1); if ( (fromRoom = RoomTable.GetRoom (fromRoomVnum)) ==NULL) { progbug ("MpOpenPassage - Bad syntax", ch); return; } if (!is_number (arg2)) { progbug ("MpOpenPassage - Bad syntax", ch); return; } targetRoomVnum = atoi (arg2); if ( (targetRoom = RoomTable.GetRoom (targetRoomVnum)) ==NULL) { progbug ("MpOpenPassage - Bad syntax", ch); return; } if (!is_number (arg3)) { progbug ("MpOpenPassage - Bad syntax", ch); return; } exit_num = atoi (arg3); if ((exit_num < 0) || (exit_num > MAX_DIR)) { progbug ("MpOpenPassage - Bad syntax", ch); return; } if ((pexit = get_exit (fromRoom, exit_num)) != NULL) { if (! pexit->IsPassage ()) return; progbug ("MpOpenPassage - Exit exists", ch); return; } pexit = make_exit (fromRoom, targetRoom, exit_num); pexit->keyword = STRALLOC (""); pexit->description = STRALLOC (""); pexit->key = -1; pexit->SetPassage (); /* act (AT_PLAIN, "A passage opens!", ch, NULL, NULL, TO_CHAR); */ /* act (AT_PLAIN, "A passage opens!", ch, NULL, NULL, TO_ROOM); */ return; } /* * Syntax mp_close_passage x y * * closes a passage in room x leading in direction y * * the exit must have EX_PASSAGE set */ void do_mp_close_passage (CCharacter *ch, char *argument) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char arg3[ MAX_INPUT_LENGTH ]; CRoomIndexData *fromRoom; int fromRoomVnum, exit_num; CExitData *pexit; if (ch->IsCharmed ()) return; if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) ) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); argument = one_argument (argument, arg3); if (arg1[0] == '\0' || arg2[0] == '\0' || arg2[0] == '\0') { progbug ("MpClosePassage - Bad syntax", ch); return; } if (!is_number (arg1)) { progbug ("MpClosePassage - Bad syntax", ch); return; } fromRoomVnum = atoi (arg1); if ( (fromRoom = RoomTable.GetRoom (fromRoomVnum)) ==NULL) { progbug ("MpClosePassage - Bad syntax", ch); return; } if (!is_number (arg2)) { progbug ("MpClosePassage - Bad syntax", ch); return; } exit_num = atoi (arg2); if ((exit_num < 0) || (exit_num > MAX_DIR)) { progbug ("MpClosePassage - Bad syntax", ch); return; } if ((pexit = get_exit (fromRoom, exit_num)) == NULL) { return; /* already closed, ignore... so rand_progs */ /* can close without spam */ } if (! pexit->IsPassage ()) { progbug ("MpClosePassage - Exit not a passage", ch); return; } extract_exit (fromRoom, pexit); /* act (AT_PLAIN, "A passage closes!", ch, NULL, NULL, TO_CHAR); */ /* act (AT_PLAIN, "A passage closes!", ch, NULL, NULL, TO_ROOM); */ return; } /* * Does nothing. Used for scripts. */ void do_mpnothing (CCharacter *ch, char *argument) { if (ch->IsCharmed ()) return; if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) ) { ch->SendText ("Huh?\n\r"); return; } return; } /* * Sends a message to sleeping character. Should be fun * with room sleep_progs * */ void do_mpdream (CCharacter *ch, char *argument) { char arg1[MAX_STRING_LENGTH]; CCharacter *vict; if (ch->IsCharmed ()) return; if (!ch->IsNpc () || (ch->GetDesc () && ch->GetTrustLevel () < LEVEL_IMMORTAL) ) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg1); if ( (vict =get_char_world (ch, arg1)) == NULL) { progbug ("Mpdream: No such character", ch); return; } if (vict->GetPosition () <= POS_SLEEPING) { vict->SendText (argument); vict->SendText ("\n\r"); } return; } void do_mpapply (CCharacter *ch, char *argument) { CCharacter *victim; if (! ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } if (argument [0] == '\0') { progbug ("Mpapply - bad syntax", ch); return; } if ((victim = get_char_room (ch, argument)) == NULL) { progbug ("Mpapply - no such player in room.", ch); return; } if (! victim->GetDesc ()) { ch->SendText ("Not on linkdeads.\n\r"); return; } if (victim->IsAuthed ()) return; if (victim->GetPcData ()->auth_state >= 1) return; sprintf (log_buf, "%s%s new %s %s applying for authorization...", victim->GetName (), victim->GetDesc ()->m_pHost, RaceTable.GetName (victim->GetRace ()), ClassTable.GetName (victim->GetClass ())); gpDoc->LogString (log_buf); to_channel (log_buf, CHANNEL_MONITOR, "Monitor", LEVEL_IMMORTAL); victim->GetPcData ()->auth_state = 1; } void do_mpapplyb (CCharacter *ch, char *argument) { CCharacter *victim; if (! ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } if (argument [0] == '\0') { progbug ("Mpapplyb - bad syntax", ch); return; } if ((victim = get_char_room (ch, argument)) == NULL) { progbug ("Mpapplyb - no such player in room.", ch); return; } if (! victim->GetDesc ()) { ch->SendText ("Not on linkdeads.\n\r"); return; } if (victim->IsAuthed ()) return; if (get_timer (victim, TIMER_AUTH) >= 1) return; int delay = SysData.m_AuthDelay / 3; switch (victim->GetPcData ()->auth_state) { case 0: case 1: default: victim->SendTextf ("You attempt to regain the gods' attention.\n\r"); sprintf (log_buf, "%s%s new %s %s applying for authorization...", victim->GetName (), victim->GetDesc ()->m_pHost, RaceTable.GetName (victim->GetRace ()), ClassTable.GetName (victim->GetClass ())); gpDoc->LogString (log_buf); to_channel (log_buf, CHANNEL_MONITOR, "Monitor", LEVEL_IMMORTAL); if (SysData.IsAutoAuth ()) add_timer (victim, TIMER_DO_FUN, delay, do_AutoAuthorize, 0); else add_timer (victim, TIMER_AUTH, delay, NULL, 0); victim->GetPcData ()->auth_state = 1; break; case 2: victim->SendText ("Your name has been deemed unsuitable by the gods. Please choose a more medieval name with the 'name' command.\n\r"); add_timer (victim, TIMER_AUTH, delay, NULL, 0); break; case 3: victim->SendTextf ("The gods permit you to enter the %s.\n\r", SysData.GetLongTitle ()); victim->ClrUnauthed (); if (victim->GetFightData ()) stop_fighting (victim, TRUE); victim->RemoveFromRoom (); victim->SendToRoom (RoomTable.GetRoom (SysData.m_RoomSchool)); act (AT_WHITE, "$n enters this world from within a column of blinding light!", victim, NULL, NULL, TO_ROOM); do_look (victim, "auto"); break; } } /* * Deposit some gold into the current area's economy -Thoric */ void do_mp_deposit (CCharacter *ch, char *argument) { char arg[MAX_STRING_LENGTH]; int gold; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } one_argument (argument, arg); if (arg[0] == '\0') { progbug ("Mpdeposit - bad syntax", ch); return; } gold = atoi (arg); if (gold <= ch->GetGold () && ch->GetInRoom ()) { ch->AddGold (-gold); ch->GetInRoom ()->GetArea ()->BoostEconomy (gold); } } /* * Withdraw some gold from the current area's economy -Thoric */ void do_mp_withdraw (CCharacter *ch, char *argument) { char arg[MAX_STRING_LENGTH]; int gold; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } one_argument (argument, arg); if (arg[0] == '\0') { progbug ("Mpwithdraw - bad syntax", ch); return; } gold = atoi (arg); if (ch->GetGold () < 1000000000 && gold < 1000000000 && ch->GetInRoom () && ch->GetInRoom ()->GetArea ()->CheckGold (gold)) { ch->AddGold (gold); ch->GetInRoom ()->GetArea ()->LowerEconomy (gold); } } void do_mppkset (CCharacter *ch, char *argument) { CCharacter *victim; char arg[MAX_STRING_LENGTH]; if (!ch->IsNpc ()) { ch->SendText ("Huh?\n\r"); return; } argument = one_argument (argument, arg); if (argument[0] == '\0' || arg[0] == '\0') { progbug ("Mppkset - bad syntax", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { progbug ("Mppkset - no such player in room.", ch); return; } if (!str_cmp (argument, "yes") || !str_cmp (argument, "y")) { if (! victim->IsPkiller ()) victim->SetPkiller (); } else if (!str_cmp (argument, "no") || !str_cmp (argument, "n")) { if (victim->IsPkiller ()) victim->ClrPkiller (); } else progbug ("Mppkset - bad syntax", ch); } /* * Inflict damage from a mudprogram * * note: should be careful about using victim afterwards */ ch_ret simple_damage (CCharacter *ch, CCharacter *victim, int dam, int dt) { short dameq; BOOL npcvict; CObjData *damobj; ch_ret retcode; retcode = rNONE; if (!ch) { bug ("Damage: null ch!", 0); return rERROR; } if (!victim) { progbug ("Damage: null victim!", ch); return rVICT_DIED; } if (victim->GetPosition () == POS_DEAD) { return rVICT_DIED; } npcvict = victim->IsNpc (); if (dam) { if (IS_FIRE (dt)) dam = ris_damage (victim, dam, RIS_FIRE); else if (IS_COLD (dt)) dam = ris_damage (victim, dam, RIS_COLD); else if (IS_ACID (dt)) dam = ris_damage (victim, dam, RIS_ACID); else if (IS_ELECTRICITY (dt)) dam = ris_damage (victim, dam, RIS_ELECTRICITY); else if (IS_ENERGY (dt)) dam = ris_damage (victim, dam, RIS_ENERGY); else if (dt == gsn_poison) dam = ris_damage (victim, dam, RIS_POISON); else if (dt == (TYPE_HIT + 7) || dt == (TYPE_HIT + 8)) dam = ris_damage (victim, dam, RIS_BLUNT); else if (dt == (TYPE_HIT + 2) || dt == (TYPE_HIT + 11)) dam = ris_damage (victim, dam, RIS_PIERCE); else if (dt == (TYPE_HIT + 1) || dt == (TYPE_HIT + 3)) dam = ris_damage (victim, dam, RIS_SLASH); if (dam < 0) dam = 0; } if (victim != ch) { /* * Damage modifiers. */ if (victim->HasSanctuary ()) dam /= 2; if (victim->IsAffected (AFF_PROTECT) && ch->IsEvil ()) dam -= (int) (dam / 4); if (dam < 0) dam = 0; /* dam_message (ch, victim, dam, dt); */ } /* * Check for EQ damage.... ;) */ if (dam > 10) { /* get a random body eq part */ dameq = number_range (WEAR_LIGHT, WEAR_EYES); damobj = get_eq_char (victim, dameq); if (damobj) { if (dam > get_obj_resistance (damobj)) { set_cur_obj (damobj); damage_obj (damobj); } } } /* * Hurt the victim. * Inform the victim of his new state. */ victim->AddHp (-dam); if (!victim->IsNpc () && victim->GetLevel () >= LEVEL_IMMORTAL && victim->GetHp () < 1) victim->SetHp (1); if (!npcvict && victim->GetTrustLevel () >= LEVEL_IMMORTAL && ch->GetTrustLevel () >= LEVEL_IMMORTAL && victim->GetHp () < 1) victim->SetHp (1); update_pos (victim); switch (victim->GetPosition ()) { case POS_MORTAL: act (AT_DYING, "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM); act (AT_DANGER, "You are mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_CHAR); break; case POS_INCAP: act (AT_DYING, "$n is incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_ROOM); act (AT_DANGER, "You are incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_CHAR); break; case POS_STUNNED: if (! victim->IsParalysed ()) { act (AT_ACTION, "$n is stunned, but will probably recover.", victim, NULL, NULL, TO_ROOM); act (AT_HURT, "You are stunned, but will probably recover.", victim, NULL, NULL, TO_CHAR); } break; case POS_DEAD: act (AT_DEAD, "$n is DEAD!!", victim, 0, 0, TO_ROOM); act (AT_DEAD, "You have been KILLED!!\n\r", victim, 0, 0, TO_CHAR); break; default: if (dam > victim->GetMaxHp () / 4) act (AT_HURT, "That really did HURT!", victim, 0, 0, TO_CHAR); if (victim->GetHp () < victim->GetMaxHp () / 4) act (AT_DANGER, "You wish that your wounds would stop BLEEDING so much!", victim, 0, 0, TO_CHAR); break; } /* * Payoff for killing things. */ if (victim->GetPosition () == POS_DEAD) { if (!npcvict) { sprintf (log_buf, "%s killed by %s at %d", victim->GetName (), (ch->IsNpc () ? ch->GetShortDescr () : ch->GetName ()), victim->GetInRoom ()->vnum); gpDoc->LogString (log_buf); to_channel (log_buf, CHANNEL_MONITOR, "Monitor", LEVEL_IMMORTAL); /* * Dying penalty: * 1/2 way back to previous level. */ if (victim->GetExp () > exp_level (victim, victim->GetLevel ())) gain_exp (victim, (exp_level (victim, victim->GetLevel ()) - victim->GetExp ())/2); /* * New penalty... go back to the beginning of current level. victim->GetExp () = exp_level (victim, victim->GetLevel ()); */ } set_cur_char (victim); raw_kill (ch, victim); victim = NULL; return rVICT_DIED; } if (victim == ch) return rNONE; /* * Take care of link dead people. */ if (!npcvict && !victim->GetDesc ()) { if (number_range (0, victim->GetWait ()) == 0) { do_recall (victim, ""); return rNONE; } } /* * Wimp out? */ if (npcvict && dam > 0) { if ((victim->IsWimpy () && number_bits (1) == 0 && victim->GetHp () < victim->GetMaxHp () / 2) || (victim->IsCharmed () && victim->GetMaster () && victim->GetMaster ()->GetInRoom () != victim->GetInRoom ())) { start_fearing (victim, ch); stop_hunting (victim); do_flee (victim, ""); } } if (!npcvict && victim->GetHp () > 0 && victim->GetHp () <= victim->GetWimpLevel () && victim->GetWait () == 0) do_flee (victim, ""); else if (!npcvict && victim->IsAction (PLR_FLEE)) do_flee (victim, ""); return rNONE; }