wileymud-1.187b/
wileymud-1.187b/attic/
wileymud-1.187b/attic/bin/
wileymud-1.187b/attic/lib/
wileymud-1.187b/attic/lib/adm/
wileymud-1.187b/attic/lib/man/
wileymud-1.187b/attic/lib/new-wld/
wileymud-1.187b/attic/lib/new-wld/default/
wileymud-1.187b/attic/lib/old/
wileymud-1.187b/attic/lib/wld/
wileymud-1.187b/attic/public_html/
wileymud-1.187b/attic/public_html/gfx/
wileymud-1.187b/attic/src/bin/
wileymud-1.187b/attic/src/etc/
wileymud-1.187b/attic/src/libauth-4.0-p5/
wileymud-1.187b/attic/src/sedna/
wileymud-1.187b/backups/
wileymud-1.187b/bin/
wileymud-1.187b/docs/
wileymud-1.187b/etc/
wileymud-1.187b/lib/
wileymud-1.187b/lib/adm/
wileymud-1.187b/lib/boards/
wileymud-1.187b/lib/log/
wileymud-1.187b/lib/man/
wileymud-1.187b/lib/ply/
wileymud-1.187b/lib/ply/a/
wileymud-1.187b/lib/ply/b/
wileymud-1.187b/lib/ply/c/
wileymud-1.187b/lib/ply/d/
wileymud-1.187b/lib/ply/g/
wileymud-1.187b/lib/ply/k/
wileymud-1.187b/lib/ply/m/
wileymud-1.187b/lib/ply/s/
wileymud-1.187b/lib/ply/t/
wileymud-1.187b/public_html/gfx/
wileymud-1.187b/src/bin/
wileymud-1.187b/src/convert/attic/
wileymud-1.187b/src/convert/obj/
wileymud-1.187b/src/convert/perl/
wileymud-1.187b/src/convert/perl/MudConvert/
wileymud-1.187b/src/convert/perl/MudConvert/DUMP/
wileymud-1.187b/src/convert/perl/MudConvert/Report/
wileymud-1.187b/src/convert/perl/MudConvert/WileyMUD/
wileymud-1.187b/src/convert/perl/output/
wileymud-1.187b/src/convert/perl/output/DUMP/
wileymud-1.187b/src/convert/perl/output/Report/
wileymud-1.187b/src/convert/perl/output/WileyMUD/
wileymud-1.187b/src/etc/
wileymud-1.187b/src/etc/init.d/
wileymud-1.187b/src/etc/rc.d/
wileymud-1.187b/src/etc/rc.d/init.d/
wileymud-1.187b/src/lib/
wileymud-1.187b/src/lib/adm/
wileymud-1.187b/src/lib/boards/
wileymud-1.187b/src/lib/log/
wileymud-1.187b/src/lib/man/
wileymud-1.187b/src/lib/ply/
wileymud-1.187b/src/lib/ply/a/
wileymud-1.187b/src/lib/ply/b/
wileymud-1.187b/src/lib/ply/c/
wileymud-1.187b/src/lib/ply/d/
wileymud-1.187b/src/lib/ply/e/
wileymud-1.187b/src/lib/ply/f/
wileymud-1.187b/src/lib/ply/g/
wileymud-1.187b/src/lib/ply/h/
wileymud-1.187b/src/lib/ply/i/
wileymud-1.187b/src/lib/ply/j/
wileymud-1.187b/src/lib/ply/k/
wileymud-1.187b/src/lib/ply/l/
wileymud-1.187b/src/lib/ply/m/
wileymud-1.187b/src/lib/ply/n/
wileymud-1.187b/src/lib/ply/o/
wileymud-1.187b/src/lib/ply/p/
wileymud-1.187b/src/lib/ply/q/
wileymud-1.187b/src/lib/ply/r/
wileymud-1.187b/src/lib/ply/s/
wileymud-1.187b/src/lib/ply/t/
wileymud-1.187b/src/lib/ply/u/
wileymud-1.187b/src/lib/ply/v/
wileymud-1.187b/src/lib/ply/w/
wileymud-1.187b/src/lib/ply/x/
wileymud-1.187b/src/lib/ply/y/
wileymud-1.187b/src/lib/ply/z/
wileymud-1.187b/src/obj/
wileymud-1.187b/src/utils/
wileymud-1.187b/src/utils/mobmaker/
/*
 * events.c - special events that whizzes might want to do sometimes.
 */

#include <stdio.h>
#include <stdlib.h>
/* #include <unistd.h> */
#include <sys/types.h>
#include <string.h>
#include <ctype.h>

#include "global.h"
#include "bug.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
#include "mudlimits.h"
#include "constants.h"
#include "spell_parser.h"
#include "fight.h"
#include "spec_procs.h"
#include "opinion.h"
#include "hash.h"
#define _DIKU_EVENTS_C
#include "events.h"

static int                              mob_count = 0;
static int                              obj_count = 0;
static int                              gold_count = 0;

static void                             event_fill_zone_with_mobs(int rnum,
								  struct room_data *rp,
								  struct event_mob_in_zone
								  *mobs);
static void                             event_rats_invade_zone(struct char_data *ch, char *arg);
static void                             event_undead_invade_zone(struct char_data *ch,
								 char *arg);
static void                             event_zombie_master(struct char_data *ch, char *arg);
static void                             event_scatter_goodies_zone(int rnum,
								   struct room_data *rp,
								   struct event_goodies *stuff);
static void                             event_scatter_goodies(struct char_data *ch, char *arg);

void do_event(struct char_data *ch, const char *argument, int cmd)
{
    static const char                      *event_list[] = {
	NULL,
	"rats - Rats invade whatever zone you are standing in. [1+]",
	"undead - The undead rise and devour the zone you are in. [4-10]",
	"xenthia - The Lady of the Dead rises and enters the world. [10-15]",
	"goodies - Goodies fall to earth, with a few bandits too. [2-15]",
	NULL
    };
    static const funcp                      event_code[] = {
	NULL,
	(funcp)event_rats_invade_zone,
	(funcp)event_undead_invade_zone,
	(funcp)event_zombie_master,
	(funcp)event_scatter_goodies,
	NULL
    };
    int                                     i = 0;
    char                                    buf[MAX_INPUT_LENGTH] = "\0\0\0\0\0\0\0";
    int                                     found = FALSE;

    if (DEBUG)
	log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch),
		 VNULL(argument), cmd);

    if (IS_NPC(ch))
	return;
    only_argument(argument, buf);
    if (!*buf) {
	cprintf(ch, "usage:  event { list | <event name> }\r\n");
	return;
    }
    if (!strcasecmp(buf, "list")) {
	cprintf(ch, "The following events are defined:\r\n");
	for (i = 1; event_list[i]; i++) {
	    cprintf(ch, "    %s\r\n", event_list[i]);
	}
	return;
    }
    for (i = 1; event_list[i]; i++) {
	if (!strncasecmp(buf, event_list[i], strlen(buf))) {
	    found = i;
	    break;
	}
    }
    if (!found)
	return;
    cprintf(ch, "Doing Event [#%d] %s\r\n", found, event_list[found]);
    log_info("%s does Event [#%d] %s", GET_NAME(ch), found, event_list[found]);
    event_code[found] (ch, argument);
}

static void event_scatter_goodies_zone(int rnum, struct room_data *rp,
				       struct event_goodies *stuff)
{
    int                                     i = 0;
    int                                     exit_found = 0;
    int                                     gold = 0;
    struct char_data                       *monster = NULL;
    struct obj_data                        *object = NULL;
    struct obj_data                        *coins = NULL;

    if (DEBUG > 1)
	log_info("called %s with %d, %08zx, %08zx", __PRETTY_FUNCTION__, rnum, (size_t) rp,
		 (size_t) stuff);

    if (!rp || rp->number < stuff->bottom || rp->number > stuff->top)
	return;
    if (IS_SET(rp->room_flags, (NO_MOB | PEACEFUL | PRIVATE)))
	return;
    exit_found = 0;
    for (i = 0; i < MAX_NUM_EXITS; i++)			       /* neswud */
	if (rp->dir_option[i]) {
	    exit_found = 1;
	    break;
	}
    if (!exit_found)
	return;
    if (number(0, 99) >= stuff->chance)
	return;
    gold = dice(stuff->gold_dice, stuff->gold_die) + stuff->gold_mod;
    gold_count += gold;
    coins = create_money(gold);
    obj_to_room(coins, rnum);
    rprintf(rnum,
	    "In a brilliant green flash, a pile of %s appears before you!\r\n",
	    coins->short_description);
    if (number(0, 99) < stuff->mob_chance) {
	i = number(1, stuff->mob_count) - 1;
	if ((monster = read_mobile(stuff->mob_vnum[i], VIRTUAL))) {
	    GET_GOLD(monster) = 0;
	    mob_count++;
	    char_to_room(monster, rnum);
	    act("A rift of red light rips open and $N rushes out!", FALSE,
		monster, 0, monster, TO_ROOM);
	}
    }
    if (number(0, 99) < stuff->obj_chance) {
	i = number(1, stuff->obj_count) - 1;
	if ((object = read_object(stuff->obj_vnum[i], VIRTUAL))) {
	    obj_count++;
	    obj_to_room(object, rnum);
	    rprintf(rnum, "In a shimmering of blue light, %s %s forms!\r\n",
		    SANA(object), object->short_description);
	}
    }
}

static void event_fill_zone_with_mobs(int rnum, struct room_data *rp,
				      struct event_mob_in_zone *mobs)
{
    int                                     i = 0;
    int                                     j = 0;
    int                                     couldbe = 0;
    int                                     exit_found = FALSE;
    struct char_data                       *monster = NULL;
    struct obj_data                        *object = NULL;

    if (DEBUG > 1)
	log_info("called %s with %d, %08zx, %08zx", __PRETTY_FUNCTION__, rnum, (size_t) rp,
		 (size_t) mobs);

    if (!rp || rp->number < mobs->bottom || rp->number > mobs->top)
	return;
    if (IS_SET(rp->room_flags, (NO_MOB | PEACEFUL | PRIVATE)))
	return;
    exit_found = 0;
    for (i = 0; i < MAX_NUM_EXITS; i++)			       /* neswud */
	if (rp->dir_option[i]) {
	    exit_found = 1;
	    break;
	}
    if (!exit_found)
	return;
    couldbe = number(mobs->atleast, mobs->atmost);
    for (j = 0; j < couldbe; j++) {
	if (number(0, 99) >= mobs->chance)
	    continue;
	i = number(1, mobs->count) - 1;
	if (!(monster = read_mobile(mobs->mobset[i].vnum, VIRTUAL)))
	    continue;
	monster->points.max_hit = dice(mobs->mobset[i].hp_dice,
				       mobs->mobset[i].hp_die) + mobs->mobset[i].hp_mod;
	GET_HIT(monster) = GET_MAX_HIT(monster);
	GET_EXP(monster) = (dice(mobs->mobset[i].exp_dice, mobs->mobset[i].exp_die)
			    + mobs->mobset[i].exp_mod) * GET_MAX_HIT(monster);
	GET_GOLD(monster) = number(mobs->mobset[i].gold_dice, mobs->mobset[i].gold_die)
	    + mobs->mobset[i].gold_mod;
	if (mobs->mobset[i].obj_vnum >= 0) {
	    if (number(0, 99) < mobs->mobset[i].obj_chance) {
		if ((object = read_object(mobs->mobset[i].obj_vnum, VIRTUAL)))
		    obj_to_char(object, monster);
	    }
	}
	char_to_room(monster, rnum);
	mob_count++;
	act("In a shimmering column of blue light, $N appears!", FALSE,
	    monster, 0, monster, TO_ROOM);
    }
}

static void event_scatter_goodies(struct char_data *ch, char *arg)
{
    int                                     the_objects[] =
	{ 5023, 6131, 5932, 15011, 7010, 5937, 1901, 9015 };
    int                                     the_mobs[] =
	{ 1200, 9618, 1400, 5441, 5054, 5055, 15047, 9620, 1202, 9601 };
    struct event_goodies                    junk = {
	0, 0, 50, 4, 6, -3,
	7, 8, the_objects,
	11, 10, the_mobs
    };
    int                                     zone = 0;
    struct room_data                       *rp = NULL;

    if (DEBUG > 1)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg));

    if ((rp = real_roomp(ch->in_room)))
	zone = rp->zone;
    else
	return;

    junk.bottom = zone ? (zone_table[zone - 1].top + 1) : 0;
    junk.top = zone_table[zone].top;
    if (IS_SET(ch->specials.act, PLR_STEALTH))
	zprintf(zone,
		"\r\nSuddenly, you fell the winds HOWL into being!\r\nYou can hear the sounds of things FALLING all around you!\r\n\r\n");
    else
	zprintf(zone,
		"\r\nYou hear %s chanting, and suddenly a wind HOWLS in from %s direction!\r\nYou can hear the sounds of things FALLING all around you!\r\n\r\n",
		GET_NAME(ch), HSHR(ch));
    mob_count = obj_count = gold_count = 0;
    hash_iterate(&room_db, (funcp)event_scatter_goodies_zone, &junk);
    cprintf(ch, "You just added %d critters, %d things, and %d gold to %s [#%d].\r\n",
	    mob_count, obj_count, gold_count, zone_table[zone].name, zone);
    log_info("%s added %d critters, %d things, and %d gold to %s [#%d].\r\n", GET_NAME(ch),
	     mob_count, obj_count, gold_count, zone_table[zone].name, zone);
}

static void event_rats_invade_zone(struct char_data *ch, char *arg)
{
    struct event_mob_set                    mobset[11] = {
/* vnum, hp: xdy+z, exp: xdy+z, gold: xdy+z, object %, obj vnum */
	{4618, 6, 8, 8, 1, 6, 4, 2, 6, 0, 2, 4602},	       /* special large rat */
	{4618, 4, 6, 5, 1, 6, 4, 1, 6, 0, 0, -1},	       /* large rat */
	{4618, 4, 6, 3, 1, 6, 4, 1, 4, 0, 0, -1},	       /* large rat */
	{3432, 3, 6, 1, 1, 6, 4, 1, 2, -1, 0, -1},	       /* disgusting rat */
	{3432, 2, 6, 1, 1, 6, 4, 0, 0, 0, 0, -1},	       /* disgusting rat */
	{3432, 2, 6, 1, 1, 6, 4, 0, 0, 0, 0, -1},	       /* disgusting rat */
	{3432, 2, 6, 1, 1, 6, 4, 0, 0, 0, 0, -1},	       /* disgusting rat */
	{3433, 4, 6, 1, 1, 6, 4, 1, 4, -1, 0, -1},	       /* giant rat */
	{3433, 4, 6, 1, 1, 6, 4, 1, 4, -1, 0, -1},	       /* giant rat */
	{3433, 4, 6, 5, 1, 6, 4, 1, 4, -1, 0, -1},	       /* giant rat */
	{5056, 3, 8, 5, 2, 6, 10, 1, 2, -1, 0, -1}	       /* black cat */
    };
    struct event_mob_in_zone                mobs = { 0, 0, 60, 1, 8, 11, mobset };
    int                                     zone = 0;
    struct room_data                       *rp = NULL;

    if (DEBUG > 1)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg));

    if ((rp = real_roomp(ch->in_room)))
	zone = rp->zone;
    else
	return;

    mobs.bottom = zone ? (zone_table[zone - 1].top + 1) : 0;
    mobs.top = zone_table[zone].top;
    if (IS_SET(ch->specials.act, PLR_STEALTH))
	zprintf(zone,
		"\r\nYou feel a great surge of power!\r\nYou hear odd scurrying sounds all around you...\r\n\r\n");
    else
	zprintf(zone,
		"\r\nIn a puff of acrid smoke, you see %s snap %s fingers!\r\nYou hear odd scurrying sounds all around you...\r\n\r\n",
		GET_NAME(ch), HSHR(ch));
    mob_count = 0;
    hash_iterate(&room_db, (funcp)event_fill_zone_with_mobs, &mobs);
    cprintf(ch, "You just added %d rats to %s [#%d].\r\n", mob_count,
	    zone_table[zone].name, zone);
    log_info("%s added %d rats to %s [#%d].", GET_NAME(ch), mob_count, zone_table[zone].name,
	     zone);
}

static void event_undead_invade_zone(struct char_data *ch, char *arg)
{
    struct event_mob_set                    mobset[64] = {
/* vnum, hp: xdy+z, exp: xdy+z, gold: xdy+z, object %, obj vnum */
	{9002, 9, 8, 40, 7, 8, 6, 0, 0, 0, 0, -1},	       /* ghoul */
	{9002, 8, 8, 30, 5, 8, 6, 0, 0, 0, 0, -1},	       /* ghoul */
	{9001, 8, 8, 20, 3, 6, 4, 0, 0, 0, 0, -1},	       /* juju zombie */
	{9001, 7, 8, 20, 2, 6, 4, 0, 0, 0, 0, -1},	       /* juju zombie */
	{9001, 7, 8, 20, 2, 6, 4, 0, 0, 0, 0, -1},	       /* juju zombie */
	{9001, 6, 8, 20, 2, 6, 4, 0, 0, 0, 0, -1},	       /* juju zombie */
	{9002, 5, 8, 20, 4, 8, 6, 0, 0, 0, 0, -1},	       /* ghoul */
	{9002, 5, 8, 0, 4, 8, 6, 0, 0, 0, 0, -1},	       /* ghoul */
	{9002, 4, 8, 20, 4, 8, 6, 0, 0, 0, 0, -1},	       /* ghoul */
	{9002, 4, 8, 20, 4, 8, 6, 0, 0, 0, 0, -1},	       /* ghoul */
	{4616, 7, 8, 20, 2, 6, 4, 0, 0, 0, 0, -1},	       /* banshee */
	{4616, 6, 8, 20, 2, 6, 4, 0, 0, 0, 0, -1},	       /* banshee */
	{4616, 6, 8, 20, 2, 6, 4, 0, 0, 0, 0, -1},	       /* banshee */
	{4616, 5, 8, 20, 2, 6, 4, 0, 0, 0, 0, -1},	       /* banshee */
	{4616, 5, 8, 20, 2, 6, 4, 0, 0, 0, 0, -1},	       /* banshee */
	{4615, 6, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* shadow */
	{4615, 6, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* shadow */
	{4615, 5, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* shadow */
	{4615, 5, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* shadow */
	{4615, 5, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* shadow */
	{4615, 5, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* shadow */
	{4615, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* shadow */
	{4613, 6, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* poltergeist */
	{4613, 5, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* poltergeist */
	{4613, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* poltergeist */
	{4613, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* poltergeist */
	{4613, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* poltergeist */
	{4613, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* poltergeist */
	{4613, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* poltergeist */
	{9003, 5, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* skeleton */
	{9003, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* skeleton */
	{9003, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* skeleton */
	{9003, 4, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* skeleton */
	{9003, 3, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* skeleton */
	{9003, 3, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* skeleton */
	{9003, 3, 8, 20, 1, 6, 4, 0, 0, 0, 0, -1},	       /* skeleton */
	{5300, 5, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 4, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 3, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 3, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{5300, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* sewer skeleton */
	{4603, 5, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 4, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 3, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 2, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1},	       /* small skeleton */
	{4603, 1, 8, 5, 1, 6, 4, 0, 0, 0, 0, -1}	       /* small skeleton */
    };
    struct event_mob_in_zone                mobs = { 0, 0, 50, 1, 3, 64, mobset };
    int                                     zone = 0;
    struct room_data                       *rp = NULL;

    if (DEBUG > 1)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg));

    if ((rp = real_roomp(ch->in_room)))
	zone = rp->zone;
    else
	return;
/* don't code things like this here.... if a whizz annoys people, it is his
 * job to make it up... but if there is a good reason, he should be able to
 * do ANYTHING.
 *
 *  if((rp->zone == 10)||(rp->zone == 11)) {
 *	cprintf(ch,"You may not load this event into the newbie area.\r\n");
 *	return; }
 *
 */
    mobs.bottom = zone ? (zone_table[zone - 1].top + 1) : 0;
    mobs.top = zone_table[zone].top;
    if (IS_SET(ch->specials.act, PLR_STEALTH))
	zprintf(zone,
		"\r\nSuddenly, the warmth is snatched from the air around you.\r\nYou feel the icy cold touch of the grave as you gasp in anticipation...\r\nThe wind begins to howl around you as things move about.\r\n\r\n");
    else
	zprintf(zone,
		"\r\n%s's voice booms all around you, \"Go forth ancient ones!\r\nKill the puny mortals and feast on their bones!\"\r\nThe air grows still and cold as you feel... things... begin to move.\r\n",
		GET_NAME(ch));
    mob_count = 0;
    hash_iterate(&room_db, (funcp)event_fill_zone_with_mobs, &mobs);
    cprintf(ch, "You just added %d undead spirits to %s [#%d].\r\n", mob_count,
	    zone_table[zone].name, zone);
    log_info("%s added %d undead to %s [#%d].", GET_NAME(ch), mob_count, zone_table[zone].name,
	     zone);
}

static void event_zombie_master(struct char_data *ch, char *arg)
{
    struct room_data                       *rp = NULL;
    struct char_data                       *master = NULL;
    struct char_data                       *mob = NULL;
    int                                     i = 0;
    int                                     j = 0;

    if (DEBUG > 1)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg));

    if ((rp = real_roomp(ch->in_room))) {
	master = read_mobile(666, VIRTUAL);		       /* xenthia, lady of the dead */
	j = dice(1, 4) + 3;
	if (IS_SET(ch->specials.act, PLR_STEALTH))
	    allprintf
		("\r\nYou feel a darkening of the land.\r\nYou hear a low moaning wind arise nearby...\r\n\r\n");
	else
	    allprintf
		("\r\n%s begins a low incantation, and a bolt of ebon lightning strikes %s upraised hands!\r\nYou hear a low moaning wind arise nearby...\r\n\r\n",
		 GET_NAME(ch), HSHR(ch));
	for (i = 0; i < j; i++) {
	    mob = read_mobile(100, VIRTUAL);		       /* zombie */
	    char_to_room(mob, ch->in_room);
	    SET_BIT(mob->specials.affected_by, AFF_CHARM);
	    GET_EXP(mob) = number(300, 500);
	    add_follower(mob, master);
	    mob->points.max_hit = dice(4, 10) + 10;
	    mob->points.hit = mob->points.max_hit;
	    AddHatred(master->followers->follower, OP_VNUM, ZM_NEMESIS);
	    SET_BIT(master->followers->follower->specials.act, ACT_GUARDIAN);
	    SET_BIT(master->followers->follower->specials.act, ACT_USE_ITEM);
	    SET_BIT(master->followers->follower->specials.affected_by, AFF_FLYING);
	}
	char_to_room(master, ch->in_room);
    }
}