cm3/
cm3/clans/
cm3/mudprogs/
cm3/player/a/
/****************************************************************************
 * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame      |   \\._.//   *
 * -----------------------------------------------------------|   (0...0)   *
 * SMAUG 1.4 (C) 1994, 1995, 1996, 1998  by Derek Snider      |    ).:.(    *
 * -----------------------------------------------------------|    {o o}    *
 * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,      |   / ' ' \   *
 * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek,      |~'~.VxvxV.~'~*
 * Tricops and Fireblade                                      |             *
 * ------------------------------------------------------------------------ *
 * 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 St{rfeldt, Tom Madsen, and Katja Nyboe.     *
 * ------------------------------------------------------------------------ *
 *			Specific object creation module			    *
 ****************************************************************************/
/* Now handles random mob generation also -keo */

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mud.h"

/* from handler.c */
extern MATERIAL_DATA *material_lookup( int number );
extern SPECIES_DATA *find_species( char *name );
extern void learn_noncombat(CHAR_DATA *ch, int i);
extern NATION_DATA *find_nation( char *name );

extern int top_affect;

AREA_DATA *stockobj;

/* Turn an ordinary item into a powerful artifact! */
void make_randart(CHAR_DATA *ch, OBJ_DATA *obj) {
    char buf[MAX_STRING_LENGTH];
    AFFECT_DATA *paf;
    AFFECT_DATA *naf;
    char name[MAX_STRING_LENGTH];
    int bane;
    int power = 200 - obj->material->magic;

    bane = number_range(1,17);
    strcpy(buf, obj->short_descr);
    strcat(buf, " of ");    
    if (obj->item_type == ITEM_CONTAINER
    ||  obj->item_type == ITEM_DRINK_CON) {
	switch (number_range(1,5)) {
	case 1:
		strcat(buf, "holding");
		obj->value[0] += number_range(power,power*10);
		obj->cost += obj->value[0] * 100;
		xSET_BIT(obj->extra_flags, ITEM_MAGIC);
		break;
	case 2:
		strcat(buf, "light");
		obj->cost += 10000;
		xSET_BIT(obj->extra_flags, ITEM_GLOW);
		break;
	case 3:
		strcat(buf, "darkness");
		obj->cost += 10000;
		xSET_BIT(obj->extra_flags, ITEM_DARK);
		break;
	case 4:
		strcat(buf, "levitation");
		obj->cost += 10000;
		xSET_BIT(obj->extra_flags, ITEM_HOVER);
		break;
	case 5:
		strcat(buf, "loyalty");
		obj->cost += 500000;
		xSET_BIT(obj->extra_flags, ITEM_LOYAL);
		break;
	}
    } else if (obj->item_type == ITEM_FURNITURE
    ||         obj->item_type == ITEM_VEHICLE) {
	switch (number_range(1,5)) {
	case 1:
		strcat(buf, "durability");
		obj->value[0] += number_range(power,power*10);
		obj->cost += obj->value[0] * 100;
		xSET_BIT(obj->extra_flags, ITEM_MAGIC);
		break;
	case 2:
		strcat(buf, "loyalty");
		xSET_BIT(obj->extra_flags, ITEM_LOYAL);
		break;
	case 3:
		strcat(buf, "darkness");
		xSET_BIT(obj->extra_flags, ITEM_DARK);
		break;
	case 4:
		strcat(buf, "levitation");
		xSET_BIT(obj->extra_flags, ITEM_HOVER);
		break;
	case 5:
		strcat(buf, "light");
		xSET_BIT(obj->extra_flags, ITEM_GLOW);
		break;
	}
    } else if (obj->item_type == ITEM_BOOK) {
	switch (number_range(1,8)) {
	case 1:
		strcat(buf, "knowledge");
		break;
	case 2:
		strcat(buf, "loyalty");
		xSET_BIT(obj->extra_flags, ITEM_LOYAL);
		break;
	case 3:
		strcat(buf, "darkness");
		xSET_BIT(obj->extra_flags, ITEM_DARK);
		break;
	case 4:
		strcat(buf, "levitation");
		xSET_BIT(obj->extra_flags, ITEM_HOVER);
		break;
	case 5:
		strcat(buf, "light");
		xSET_BIT(obj->extra_flags, ITEM_GLOW);
		break;
	case 6:
		strcat(buf, "wisdom");
		break;
	case 7:
		strcat(buf, "intelligence");
		break;
	case 8:
		strcat(buf, "learning");
		break;
	case 9:
		strcat(buf, "magic");
		xSET_BIT(obj->extra_flags, ITEM_MAGIC);
		break;
	case 10:
		strcat(buf, "spells");
		xSET_BIT(obj->extra_flags, ITEM_MAGIC);
		break;
	case 11:
		strcat(buf, "power");
		xSET_BIT(obj->extra_flags, ITEM_HUM);
		xSET_BIT(obj->extra_flags, ITEM_MAGIC);
		xSET_BIT(obj->extra_flags, ITEM_GLOW);
		break;
	}
    } else if (obj->item_type == ITEM_WEAPON
    && number_range(1,3) == 1) {
        xSET_BIT(obj->extra_flags, ITEM_MAGIC);
        obj->value[0] = bane;
        obj->value[6] = number_range(power,power*10);
    switch(bane) {
	case 1:
		strcat(buf, "undead slaying");
                break;
	case 2:
		strcat(buf, "demon slaying");
		break;
	case 3:
		strcat(buf, "elf slaying");
		break;
	case 4:
		strcat(buf, "orc slaying");
		break;
	case 5:
		strcat(buf, "dragon slaying");
		break;
	case 6:
		strcat(buf, "human slaying");
		break;
	case 7:
		strcat(buf, "dwarf slaying");
		break;
	case 8:
		strcat(buf, "faerie slaying");
		break;
	case 9:
		strcat(buf, "giant slaying");
		break;
	case 10:
		strcat(buf, "minotaur slaying");
		break;
	case 11:
		strcat(buf, "troll slaying");
		break;
	case 12:
		strcat(buf, "halfling slaying");
		break;
	case 13:
		strcat(buf, "animal slaying");
		break;
	case 14:
		strcat(buf, "feline slaying");
		break;
	case 15:
		strcat(buf, "equine slaying");
		break;
	case 16:
		strcat(buf, "construct slaying");
		break;
	case 17:
		strcat(buf, "angel slaying");
		break;
    }
    } else {
    CREATE(paf, AFFECT_DATA, 1);
    paf->type = -1;
    paf->duration = -1;
    xCLEAR_BITS(paf->bitvector);
    switch(number_range(0,45)) {
	default:
		strcat(buf, "power");
		paf->location = APPLY_STR;
		paf->modifier = number_range(1,(int)power/3);
            CREATE(naf, AFFECT_DATA, 1);
            naf->type = -1;
            naf->duration = -1;
            naf->location = APPLY_INT;
            naf->modifier = number_range(1,(int)power/3);
            xCLEAR_BITS(naf->bitvector);
            naf->next = NULL;
            LINK(naf, obj->first_affect, obj->last_affect, next, prev);
		break;
	case 1:
		strcat(buf, "thievery");
		paf->location = APPLY_DEX;
		paf->modifier = number_range(1,(int)power/3);
            CREATE(naf, AFFECT_DATA, 1);
            naf->type = -1;
            naf->duration = -1;
            naf->location = APPLY_CHA;
            naf->modifier = number_range(1,(int)power/3);
            xCLEAR_BITS(naf->bitvector);
            naf->next = NULL;
            LINK(naf, obj->first_affect, obj->last_affect, next, prev);
		break;
	case 2:
		strcat(buf, "wizardry");
		paf->location = APPLY_INT;
		paf->modifier = number_range(1,(int)power/3);
            CREATE(naf, AFFECT_DATA, 1);
            naf->type = -1;
            naf->duration = -1;
            naf->location = APPLY_WIS;
            naf->modifier = number_range(1,(int)power/3);
            xCLEAR_BITS(naf->bitvector);
            naf->next = NULL;
            LINK(naf, obj->first_affect, obj->last_affect, next, prev);
		break;
	case 3:
		strcat(buf, "might");
		paf->location = APPLY_CON;
		paf->modifier = number_range(1,(int)power/3);
            CREATE(naf, AFFECT_DATA, 1);
            naf->type = -1;
            naf->duration = -1;
            naf->location = APPLY_STR;
            naf->modifier = number_range(1,(int)power/3);
            xCLEAR_BITS(naf->bitvector);
            naf->next = NULL;
            LINK(naf, obj->first_affect, obj->last_affect, next, prev);
		break;
	case 4:
		strcat(buf, "sight");
		paf->location = APPLY_CHA;
		paf->modifier = number_range(1,(int)power/3);
		break;
	case 5:
		strcat(buf, "endurance");
		paf->location = APPLY_LCK;
		paf->modifier = number_range(1,(int)power/3);
		break;
	case 6:
		strcat(buf, "will");
		paf->location = APPLY_WIS;
		paf->modifier = number_range(1,(int)power/3);
		break;
	case 7:
		strcat(buf, "fire");
		paf->location = APPLY_FIRE_MAGIC;
		paf->modifier = 1;
		obj->cost += 500000;
		if (obj->item_type == ITEM_WEAPON)
			obj->value[4] = BRAND_FLAMING;
		break;
	case 8:
		strcat(buf, "protection");
		paf->location = APPLY_AC;
		paf->modifier = number_range(1,power);
		xSET_BIT(obj->extra_flags, ITEM_SHIELD);
		if (obj->item_type == ITEM_ARMOR)
			obj->value[0] += number_range(1,(int)power/3);
		obj->cost += obj->value[0] * 1000;
		break;
	case 9:
		strcat(buf, "ice");
		paf->location = APPLY_FROST_MAGIC;
		paf->modifier = 1;
		obj->cost += 500000;
		if (obj->item_type == ITEM_WEAPON)
			obj->value[4] = BRAND_FROZEN;
		break;
	case 10:
		strcat(buf, "lightning");
		paf->location = APPLY_LIGHTNING_MAGIC;
		paf->modifier = 1;
		obj->cost += 500000;
		if (obj->item_type == ITEM_WEAPON)
			obj->value[4] = BRAND_ELEC;
		break;
	case 11:
		strcat(buf, "levitation");
	        paf->location = APPLY_AFFECT;
                SET_BIT(paf->modifier, 1 << AFF_FLYING);
		break;
	case 12:
		strcat(buf, "breathing");
                paf->location = APPLY_AFFECT;
		obj->cost += 100000;
                SET_BIT(paf->modifier, 1 << AFF_AQUA_BREATH);
		break;
	case 13:
		strcat(buf, "nightvision");
                paf->location = APPLY_AFFECT;
                SET_BIT(paf->modifier, 1 << AFF_INFRARED);
		break;
	case 14:
		strcat(buf, "light");
		xSET_BIT(obj->extra_flags, ITEM_GLOW);
                paf->location = APPLY_HITROLL;
		paf->modifier = number_range(1,(int)power/4);
		xSET_BIT(paf->bitvector, AFF_GLOW);
		break;
	case 15:
		strcat(buf, "darkness");
		xSET_BIT(obj->extra_flags, ITEM_DARK);
                paf->location = APPLY_DAMROLL;
		paf->modifier = number_range(1,(int)power/4);
		xSET_BIT(paf->bitvector, AFF_DARK);
		break;
	case 16:
		strcat(buf, "true sight");
                paf->location = APPLY_CHA;
		obj->cost += 100000;
		paf->modifier = number_range(1,(int)power/3);
                xSET_BIT(paf->bitvector, AFF_TRUESIGHT);
		break;
	case 17:
		strcat(buf, "feather fall");
                paf->location = APPLY_AFFECT;
		obj->cost += 5000;
                SET_BIT(paf->modifier, 1 << AFF_FLOATING);
		break;
	case 18:
		strcat(buf, "doom");
                paf->location = APPLY_AFFECT;
                SET_BIT(paf->modifier, 1 << AFF_CURSE);
		break;
	case 19:
		strcat(buf, "pass door");
                paf->location = APPLY_AFFECT;
		obj->cost += 10000;
                SET_BIT(paf->modifier, 1 << AFF_PASS_DOOR);
		break;
	case 20:
                strcat(buf, "mind");
                paf->location = APPLY_MIND_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
                if (obj->item_type == ITEM_WEAPON)
                        obj->value[4] = BRAND_PSIONIC;
                break;
	case 21:
                strcat(buf, "radiance");
                paf->location = APPLY_ILLUSION_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
                if (obj->item_type == ITEM_WEAPON)
                        obj->value[4] = BRAND_RADIANT;
                break;
	case 22:
                strcat(buf, "stealth");
                paf->location = APPLY_AFFECT;
                SET_BIT(paf->modifier, 1 << AFF_SNEAK);
                break;
	case 23:
                strcat(buf, "shadows");
                paf->location = APPLY_AFFECT;
                SET_BIT(paf->modifier, 1 << AFF_HIDE);
                break;
	case 24:
                strcat(buf, "seeking");
                paf->location = APPLY_SEEKING_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
		break;
	case 25:
                strcat(buf, "storms");
                paf->location = APPLY_WIND_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
                if (obj->item_type == ITEM_WEAPON)
                        obj->value[4] = BRAND_STORM;
                break;
	case 26:
                strcat(buf, "sound");
                paf->location = APPLY_SPEECH_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
                if (obj->item_type == ITEM_WEAPON)
                        obj->value[4] = BRAND_SONIC;
                break;
	case 27:
                strcat(buf, "draining");
                paf->location = APPLY_DEATH_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
                if (obj->item_type == ITEM_WEAPON)
                        obj->value[4] = BRAND_DRAIN;
                break;
	case 28:
                strcat(buf, "distortion");
                paf->location = APPLY_CHANGE_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
                if (obj->item_type == ITEM_WEAPON)
                        obj->value[4] = BRAND_DISTORT;
                break;
	case 29:
                strcat(buf, "earth");
                paf->location = APPLY_EARTH_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
                if (obj->item_type == ITEM_WEAPON)
                        obj->value[4] = BRAND_CRUSH;
                break;
	case 30:
                strcat(buf, "anti-matter");
                paf->location = APPLY_VOID_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
                if (obj->item_type == ITEM_WEAPON)
                        obj->value[4] = BRAND_ANTI_MATTER;
                break;
	case 31:
		strcat(buf, "strength");
		paf->location = APPLY_STR;
		paf->modifier = number_range(1,(int)power/3);
		break;
	case 32:
		strcat(buf, "mana");
		paf->location = APPLY_INT;
		paf->modifier = number_range(1,(int)power/3);
		break;
	case 33:
		strcat(buf, "agility");
		paf->location = APPLY_DEX;
		paf->modifier = number_range(1,(int)power/3);
		break;
	case 34:
		strcat(buf, "vigor");
		paf->location = APPLY_CON;
		paf->modifier = number_range(1,(int)power/3);
		break;
	case 35:
		strcat(buf, "dream");
                paf->location = APPLY_DREAM_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
		break;
	case 36:
		strcat(buf, "warding");
                paf->location = APPLY_SECURITY_MAGIC;
                paf->modifier = 1;
                obj->cost += 500000;
		break;
	case 37:
		strcat(buf, "water");
		paf->location = APPLY_WATER_MAGIC;
		paf->modifier = 1;
		obj->cost += 600000;
		xSET_BIT(paf->bitvector, AFF_AQUA_BREATH);
		break;
	case 38:
                strcat(buf, "accuracy");
                paf->location = APPLY_HITROLL;
                paf->modifier = number_range(1,(int)power/3);
                break;
	case 39:
                strcat(buf, "damage");
                paf->location = APPLY_DAMROLL;
                paf->modifier = number_range(1,(int)power/3);
                break;
	case 40:
		strcat(buf, "time");
		paf->location = APPLY_TIME_MAGIC;
		paf->modifier = 1;
		obj->cost += 500000;
		break;
	case 41:
		strcat(buf, "flight");
		paf->location = APPLY_DEX;
		paf->modifier = number_range(1,(int)power/4);
		xSET_BIT(paf->bitvector, AFF_FLYING);
		break;
	case 42:
                strcat(buf, "the cat");
                paf->location = APPLY_DEX;
                paf->modifier = number_range(1,(int)power/2);
            CREATE(naf, AFFECT_DATA, 1);
            naf->type = -1;
            naf->duration = -1;
            naf->location = APPLY_CHA;
            naf->modifier = number_range(1,(int)power/2);
            xCLEAR_BITS(naf->bitvector);
	    xSET_BIT(naf->bitvector, AFF_FELINE);
            naf->next = NULL;
            LINK(naf, obj->first_affect, obj->last_affect, next, prev);
                break;
        case 43:
                strcat(buf, "the snake");
                paf->location = APPLY_DEX;
                paf->modifier = number_range(1,(int)power/2);
                break;
	case 44:
                strcat(buf, "the dragon");
                paf->location = APPLY_STR;
                paf->modifier = number_range(1,(int)power/2);
            CREATE(naf, AFFECT_DATA, 1);
            naf->type = -1;
            naf->duration = -1;
            naf->location = APPLY_CON;
            naf->modifier = number_range(1,(int)power/2);
            xCLEAR_BITS(naf->bitvector);
            xSET_BIT(naf->bitvector, AFF_COLDBLOOD);
            naf->next = NULL;
            LINK(naf, obj->first_affect, obj->last_affect, next, prev);
                break;
	case 45:
		strcat(buf, "loyalty");
		xSET_BIT(obj->extra_flags, ITEM_LOYAL);
            paf->location = APPLY_WIS;
		paf->modifier = number_range(1,(int)power/5);
		break;
    }
    if (number_range(1,10) == 1
    &&  number_range(1,50)*100 > numobjsloaded) {
	if (obj->last_affect && obj->last_affect->location != APPLY_AFFECT)
		obj->last_affect->modifier += number_range(1,(int)power/3);
	if (paf->location != APPLY_AFFECT)
		paf->modifier += number_range(1,(int)power/3);
	strcat(buf, " named ");
	if (ch->nation && !str_cmp(ch->nation->name, "drow"))
		strcat(buf, random_name(name, LANG_DROW));
	else if (ch->race == 1
	||  ch->race == 4)
		strcat(buf, random_name(name, LANG_ELVEN));
	else if (ch->race == 2)
		strcat(buf, random_name(name, LANG_DWARVEN));
	else if (ch->race == 35)
		strcat(buf, random_name(name, LANG_DRAGON));
	else
		strcat(buf, random_name(name, LANG_KALORESE));
	if (obj->item_type == ITEM_WEAPON
	&& number_range(1,2) == 1) {
		xSET_BIT(obj->extra_flags, ITEM_MAGIC);
		obj->value[0] = bane;
		obj->value[6] = number_range(power*2,power*20);
	}
	xSET_BIT(obj->extra_flags, ITEM_ARTIFACT);
    }
    if (paf->location != APPLY_AFFECT)
        obj->cost += paf->modifier * 1000;
    paf->next = NULL;
    LINK(paf, obj->first_affect, obj->last_affect, next, prev);
    }
    STRFREE(obj->short_descr);
    obj->short_descr = STRALLOC(buf);
    STRFREE(obj->name);
    obj->name = STRALLOC(buf);
}

/* Generate a mobile based on the nation passed in. */
CHAR_DATA *generate_mob_nation(char *argument) {
	NATION_DATA *nation = NULL;

	for (nation=first_nation;nation;nation=nation->next) {
		if (nifty_is_name(argument, nation->name))
			return generate_mob(nation);
	}
	return NULL;
}

/* Note: The random item generation WILL crash the mud if the item
 * does not exist that it is looking for! Please do not delete items in
 * stockobj.are unless you edit this file as well
 */
CHAR_DATA *generate_mob(NATION_DATA *nation) {
	SPECIES_DATA *species;
	CHAR_DATA *mob = NULL;
	char buf[MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	OBJ_DATA *obj = NULL;
	MATERIAL_DATA *mat;
	AFFECT_DATA *paf;
	char name[MAX_STRING_LENGTH];
	BOOK_DATA *book;
	EXTRA_DESCR_DATA *ed;
	int i, n;

	mob = create_mobile( get_mob_index(MOB_VNUM_GENERIC) );
	mob->nation = nation;
	species = find_species(nation->species);
	if (species)
		mob->race = species->skill_set;

	sprintf(buf, nation->name);

        mob->perm_str = 100 + nation->str_mod;
        mob->perm_int = 100 + nation->int_mod;
        mob->perm_wis = 100 + nation->wis_mod;
        mob->perm_dex = 100 + nation->dex_mod;
        mob->perm_con = 100 + nation->con_mod;
        mob->perm_cha = 100 + nation->cha_mod;
        mob->perm_lck = 100 + nation->lck_mod;

        mob->susceptible = nation->suscept;
        mob->speed = 100;
        mob->weight = nation->weight;
        mob->height = nation->height;

        mob->xflags = nation->parts;
        check_bodyparts(mob);
        mob->affected_by = nation->affected;
	if (IS_SET(mob->xflags, 1 << PART_WINGS))
		xSET_BIT(mob->affected_by, AFF_FLYING);
        mob->immune = nation->resist;

	if (IS_SET(mob->xflags, 1 << PART_HANDS)) {
	    if (number_range(1,25) == 1) {
		xSET_BIT(mob->act, ACT_NAMED);
		if (!str_cmp(mob->nation->name, "drow"))
			sprintf(buf2, "%s, the %s",
			random_name(name, LANG_DROW), buf);
		else if (mob->race == 1
		||  mob->race == 4)
        	        sprintf(buf2, "%s, the %s", 
			random_name(name, LANG_ELVEN), buf);
		else if (mob->race == 2)
			sprintf(buf2, "%s, the %s",
			random_name(name, LANG_DWARVEN), buf);
		else if (mob->race == 35)
			sprintf(buf2, "%s, the %s",
			random_name(name, LANG_DRAGON), buf);
		else
	                sprintf(buf2, "%s, the %s", 
			random_name(name, LANG_KALORESE), buf);
                strcpy(buf, buf2);
		mob->perm_str += 50;
		mob->perm_int += 50;
		mob->perm_wis += 50;
		mob->perm_dex += 50;
		mob->perm_con += 50;
		mob->perm_lck += 50;
		mob->perm_cha += 50;
	    }
	    switch (number_range(1,10)) {
		default:
			mob->gold += number_range(1,1000);
			switch(number_range(1,10)) {
                                case 1:
obj = create_object( get_obj_index( 28911 ), 0 ); /* shirt */
                                        break;
                                case 2:
obj = create_object( get_obj_index( 29109 ), 0 ); /* tunic */
                                        break;
                                case 3:
	if (IS_SET(mob->xflags, PART_LEGS))
obj = create_object( get_obj_index( 28910 ), 0 ); /* pants */
	else
obj = create_object( get_obj_index( 28917 ), 0 ); /* saddle */
                                        break;
                                case 4:
obj = create_object( get_obj_index( 29007 ), 0 ); /* belt */
                                        break;
                                case 5:
obj = create_object( get_obj_index( 29014 ), 0 ); /* cloak */
                                        break;
                                case 6:
obj = create_object( get_obj_index( 29072 ), 0 ); /* pouch */
                                        break;
                                case 7:
obj = create_object( get_obj_index( 29062 ), 0 ); /* pack */
                                        break;
                                case 8:
obj = create_object( get_obj_index( 28937 ), 0 ); /* codpiece */
                                        break;
                                case 9:
obj = create_object( get_obj_index( 29029 ), 0 ); /* knife */
                                        break;
                                case 10:
obj = create_object( get_obj_index( 29053 ), 0 ); /* cap */
                                        break;
			}
			break;
		case 1:
			switch (number_range(1,5)) {
				case 1:
					mob->perm_cha -= 50;
					mob->perm_int -= 50;
					mob->perm_wis -= 50;
					mob->gold += number_range(10,500);
					strcat(buf, " squire");
					break;
				case 2:
					mob->perm_str += 20;
					mob->perm_con += 20;
					mob->gold += number_range(100,1000);
					strcat(buf, " soldier");
					break;
				case 3:
					mob->perm_str += 50;
					mob->perm_con += 50;
					mob->perm_dex += 50;
					mob->gold += number_range(2000,20000);
					strcat(buf, " warrior");
					break;
				case 4:
					mob->perm_str += 100;
					mob->perm_con += 100;
					mob->perm_dex += 100;
					mob->perm_cha += 50;
					mob->gold += number_range(10000,50000);
					strcat(buf, " knight");
					break;
				case 5:
					mob->perm_str += 200;
					mob->perm_con += 200;
					mob->perm_dex += 100;
					mob->perm_cha += 50;
					mob->perm_lck += 50;
					mob->gold += number_range(20000,100000);
					strcat(buf, " blademaster");
					break;
			}
			switch (number_range(1,21)) {
				case 1:
obj = create_object( get_obj_index( 29033 ), 0 ); /* longsword */
					break;
				case 2:
obj = create_object( get_obj_index( 29000 ), 0 ); /* chainmail */
					break;
                                case 3:
obj = create_object( get_obj_index( 29039 ), 0 ); /* battle axe */
                                        break;
                                case 4:
                if (IS_SET(mob->xflags, 1 << PART_FEET))
obj = create_object( get_obj_index( 29009 ), 0 ); /* shod boots */
                else if (IS_SET(mob->xflags, 1 << PART_HOOVES))
obj = create_object( get_obj_index( 29085 ), 0 ); /* horseshoes */
                                        break;
                                case 5:
obj = create_object( get_obj_index( 29012 ), 0 ); /* gauntlets */
                                        break;
                                case 6:
obj = create_object( get_obj_index( 29018 ), 0 ); /* greaves */
                                        break;
                                case 7:
obj = create_object( get_obj_index( 29005 ), 0 ); /* greathelm */
                                        break;
				case 8:
obj = create_object( get_obj_index( 28905 ), 0 ); /* kite shield */
                                        break;
                                case 9:
obj = create_object( get_obj_index( 29041 ), 0 ); /* spear */
                                        break;
                                case 10:
obj = create_object( get_obj_index( 28942 ), 0 ); /* glaive */
                                        break;
                                case 11:
obj = create_object( get_obj_index( 29042 ), 0 ); /* halberd */
                                        break;
                                case 12:
obj = create_object( get_obj_index( 29035 ), 0 ); /* greatsword */
                                        break;
                                case 13:
obj = create_object( get_obj_index( 29001 ), 0 ); /* platemail */
                                        break;
                                case 14:
obj = create_object( get_obj_index( 29020 ), 0 ); /* ringmail */
                                        break;
                                case 15:
obj = create_object( get_obj_index( 29063 ), 0 ); /* broadsword */
                                        break;
                                case 16:
obj = create_object( get_obj_index( 29004 ), 0 ); /* helm */
                                        break;
                                case 17:
obj = create_object( get_obj_index( 29040 ), 0 ); /* greataxe */
                                        break;
                                case 18:
obj = create_object( get_obj_index( 29045 ), 0 ); /* crossbow */
                                        break;
                                case 19:
obj = create_object( get_obj_index( 28926 ), 0 ); /* club */
                                        break;
                                case 20:
obj = create_object( get_obj_index( 28936 ), 0 ); /* flail */
                                        break;
                                case 21:
obj = create_object( get_obj_index( 29025 ), 0 ); /* visor */
                                        break;
			}
			break;
		case 2:
			if (mob->perm_int < 0) break;
			switch (number_range(1,5)) {
				case 1:
					mob->perm_dex -= 50;
					mob->perm_str -= 50;
					mob->perm_con -= 50;
					mob->gold += number_range(10,500);
					strcat(buf, " apprentice");
					break;
				case 2:
					mob->perm_wis += 20;
					mob->perm_int += 20;
					mob->gold += number_range(100,1000);
					strcat(buf, " mage");
					break;
				case 3:
					mob->perm_wis += 50;
					mob->perm_int += 50;
					mob->perm_dex += 50;
					mob->gold += number_range(2000,20000);
					strcat(buf, " sorcerer");
					break;
				case 4:
					mob->perm_wis += 100;
					mob->perm_int += 100;
					mob->perm_cha += 100;
					mob->perm_con += 50;
					mob->gold += number_range(10000,50000);
					strcat(buf, " wizard");
					break;
				case 5:
					mob->perm_wis += 200;
					mob->perm_int += 200;
					mob->perm_cha += 100;
					mob->perm_con += 50;
					mob->perm_dex += 50;
					mob->perm_lck += 50;
					mob->gold += number_range(20000,100000);
					strcat(buf, " archmage");
					break;
			}
			if (IS_AFFECTED(mob, AFF_AQUA_BREATH))
				mob->spec_fun = spec_lookup("spec_cast_water");
			else if (IS_SET(mob->xflags, PART_WINGS))
				mob->spec_fun = spec_lookup("spec_cast_wind");
			else
				mob->spec_fun = spec_lookup("spec_cast_fire");
			switch(number_range(1,12)) {
				case 1:
obj = create_object( get_obj_index( 28955 ), 0 ); /* staff */
					break;
				case 2:
obj = create_object( get_obj_index( 29013 ), 0 ); /* robe */
					break;
                                case 3:
obj = create_object( get_obj_index( 29030 ), 0 ); /* dagger */
                                        break;
                                case 4:
obj = create_object( get_obj_index( 28916 ), 0 ); /* sash */
                                        break;
                                case 5:
                if (IS_SET(mob->xflags, 1 << PART_FEET))
obj = create_object( get_obj_index( 28931 ), 0 ); /* sandals */
                else if (IS_SET(mob->xflags, 1 << PART_HOOVES))
obj = create_object( get_obj_index( 29085 ), 0 ); /* horseshoes */
                                        break;
                                case 6:
obj = create_object( get_obj_index( 29055 ), 0 ); /* quarterstaff */
                                        break;
                                case 7:
obj = create_object( get_obj_index( 29002 ), 0 ); /* ring */
                                        break;
                                case 8:
obj = create_object( get_obj_index( 29064 ), 0 ); /* amulet */
                                        break;
                                case 9:
obj = create_object( get_obj_index( 29103 ), 0 ); /* glasses */
                                        break;
                                case 10:
obj = create_object( get_obj_index( 29072 ), 0 ); /* pouch */
                                        break;
                                case 11:
obj = create_object( get_obj_index( 29066 ), 0 ); /* wand */
                                        break;
                                case 12:
obj = create_object( get_obj_index( 28928 ), 0 ); /* book */
                                        break;
			}
			break;
		case 3:
			if (mob->perm_int < 0) break;
			/* Let's not have zombie healers */
			if (IS_AFFECTED(mob, AFF_UNDEAD)
			||  IS_AFFECTED(mob, AFF_DEMON)) {
			switch (number_range(1,4)) {
				case 1:
					mob->perm_dex -= 50;
					mob->perm_str -= 50;
					mob->perm_cha -= 50;
					mob->perm_con -= 50;
					mob->gold += number_range(1,10);
					strcat(buf, " leper");
					break;
				case 2:
					mob->perm_wis += 50;
					mob->perm_int += 20;
					mob->gold += number_range(100,1000);
					strcat(buf, " poison mage");
					break;
				case 3:
					mob->perm_wis += 50;
					mob->perm_int += 50;
					mob->gold += number_range(1500,5000);
					strcat(buf, " venom wizard");
					break;
				case 4:
					mob->perm_wis += 100;
					mob->perm_int += 100;
					mob->perm_cha += 100;
					mob->perm_con += 50;
					mob->perm_str += 50;
					mob->gold += number_range(1000,10000);
					strcat(buf, " plaguebringer");
					break;
			}
				mob->spec_fun = spec_lookup("spec_cast_poison");
			} else {
			switch (number_range(1,4)) {
				case 1:
					mob->perm_dex -= 20;
					mob->perm_str -= 50;
					mob->perm_con -= 50;
					mob->gold += number_range(1,5);
					strcat(buf, " treehugger");
					break;
				case 2:
					mob->perm_wis += 20;
					mob->perm_int += 20;
					mob->gold += number_range(10,100);
					strcat(buf, " druid");
					break;
				case 3:
					mob->perm_wis += 50;
					mob->perm_int += 50;
					mob->perm_str += 50;
					mob->perm_con += 50;
					mob->perm_dex += 50;
					mob->gold += number_range(1000,10000);
					strcat(buf, " ranger");
					break;
				case 4:
					mob->perm_wis += 100;
					mob->perm_int += 100;
					mob->perm_cha += 100;
					mob->perm_con += 50;
					mob->gold += number_range(1000,5000);
					strcat(buf, " earth warden");
					break;
			}
				mob->spec_fun = spec_lookup("spec_cast_earth");
			}
			switch(number_range(1,11)) {
				case 1:
obj = create_object( get_obj_index( 29013 ), 0 ); /* robe */
					break;
				case 2:
obj = create_object( get_obj_index( 29036 ), 0 ); /* mace */
					break;
                                case 3:
obj = create_object( get_obj_index( 28955 ), 0 ); /* staff */
                                        break;
                                case 4:
obj = create_object( get_obj_index( 29055 ), 0 ); /* quarterstaff */
                                        break;
                                case 5:
obj = create_object( get_obj_index( 28930 ), 0 ); /* hood */
                                        break;
                                case 6:
obj = create_object( get_obj_index( 29072 ), 0 ); /* pouch */
                                        break;
                                case 7:
obj = create_object( get_obj_index( 29065 ), 0 ); /* talisman */
                                        break;
                                case 8:
obj = create_object( get_obj_index( 29002 ), 0 ); /* ring */
                                        break;
                                case 9:
obj = create_object( get_obj_index( 29064 ), 0 ); /* amulet */
                                        break;
                                case 10:
obj = create_object( get_obj_index( 29014 ), 0 ); /* cloak */
                                        break;
                                case 11:
obj = create_object( get_obj_index( 28928 ), 0 ); /* book */
                                        break;
			}
			break;
		case 4:
			if (mob->perm_wis < 0) break;
			/* Let's not have zombie healers */
			if (IS_AFFECTED(mob, AFF_UNDEAD)
			||  IS_AFFECTED(mob, AFF_DEMON)) {
			switch (number_range(1,4)) {
				case 1:
					mob->perm_dex -= 50;
					mob->perm_str -= 50;
					mob->perm_cha -= 50;
					mob->perm_con -= 50;
					mob->gold += number_range(1,10);
					strcat(buf, " acolyte");
					break;
				case 2:
					mob->perm_wis += 50;
					mob->perm_int += 20;
					mob->gold += number_range(100,1000);
					strcat(buf, " dark priest");
					break;
				case 3:
					mob->perm_wis += 50;
					mob->perm_int += 50;
					mob->gold += number_range(1500,5000);
					strcat(buf, " necromancer");
					break;
				case 4:
					mob->perm_wis += 100;
					mob->perm_int += 100;
					mob->perm_cha += 100;
					mob->perm_con += 50;
					mob->perm_str += 50;
					mob->gold += number_range(1000,10000);
					strcat(buf, " soul reaver");
					break;
			}
				mob->spec_fun = spec_lookup("spec_cast_death");
			} else {
			switch (number_range(1,4)) {
				case 1:
					mob->perm_dex -= 20;
					mob->perm_str -= 50;
					mob->perm_con -= 50;
					mob->gold += number_range(1,5);
					strcat(buf, " healer");
					break;
				case 2:
					mob->perm_wis += 20;
					mob->perm_int += 20;
					mob->gold += number_range(10,100);
					strcat(buf, " cleric");
					break;
				case 3:
					mob->perm_wis += 50;
					mob->perm_int += 50;
					mob->gold += number_range(100,1000);
					strcat(buf, " priest");
					break;
				case 4:
					mob->perm_wis += 100;
					mob->perm_int += 100;
					mob->perm_cha += 100;
					mob->perm_con += 50;
					mob->gold += number_range(1000,5000);
					strcat(buf, " bishop");
					break;
			}
				mob->spec_fun = spec_lookup("spec_cast_healing");
			}
			switch(number_range(1,11)) {
				case 1:
obj = create_object( get_obj_index( 29013 ), 0 ); /* robe */
					break;
				case 2:
obj = create_object( get_obj_index( 29036 ), 0 ); /* mace */
					break;
                                case 3:
obj = create_object( get_obj_index( 28955 ), 0 ); /* staff */
                                        break;
                                case 4:
		if (IS_SET(mob->xflags, 1 << PART_FEET))
obj = create_object( get_obj_index( 28931 ), 0 ); /* sandals */
		else if (IS_SET(mob->xflags, 1 << PART_HOOVES))
obj = create_object( get_obj_index( 29085 ), 0 ); /* horseshoes */
                                        break;
                                case 5:
obj = create_object( get_obj_index( 29051 ), 0 ); /* hammer */
                                        break;
                                case 6:
obj = create_object( get_obj_index( 29065 ), 0 ); /* talisman */
                                        break;
                                case 7:
obj = create_object( get_obj_index( 28930 ), 0 ); /* hood */
                                        break;
                                case 8:
obj = create_object( get_obj_index( 29002 ), 0 ); /* ring */
                                        break;
                                case 9:
obj = create_object( get_obj_index( 28916 ), 0 ); /* sash */
                                        break;
                                case 10:
obj = create_object( get_obj_index( 29053 ), 0 ); /* cap */
                                        break;
                                case 11:
obj = create_object( get_obj_index( 28928 ), 0 ); /* book */
                                        break;
			}
			break;
		case 5:
			switch (number_range(1,5)) {
				case 1:
					mob->perm_dex -= 50;
					mob->perm_str -= 50;
					mob->perm_cha -= 50;
					mob->perm_con -= 50;
					mob->gold += number_range(1,5);
					strcat(buf, " beggar");
					break;
				case 2:
					mob->perm_dex += 20;
					mob->perm_str += 20;
					mob->gold += number_range(1000,3000);
					strcat(buf, " thief");
					break;
				case 3:
					mob->perm_dex += 50;
					mob->perm_str += 50;
					mob->gold += number_range(1500,10000);
					strcat(buf, " rogue");
					break;
				case 4:
					mob->perm_dex += 100;
					mob->perm_str += 100;
					mob->perm_cha += 100;
					mob->perm_con += 50;
					mob->gold += number_range(10000,30000);
					strcat(buf, " assassin");
					break;
				case 5:
					mob->perm_dex += 200;
					mob->perm_str += 100;
					mob->perm_cha += 200;
					mob->perm_con += 100;
					mob->perm_int += 50;
					mob->gold += number_range(20000,50000);
					strcat(buf, " ninja");
					break;
			}
			mob->spec_fun = spec_lookup("spec_thief");
			switch (number_range(1,12)) {
				case 1:
obj = create_object( get_obj_index( 29030 ), 0 ); /* dagger */
					break;
				case 2:
obj = create_object( get_obj_index( 29014 ), 0 ); /* cloak */
					break;
                                case 3:
obj = create_object( get_obj_index( 29031 ), 0 ); /* dirk */
                                        break;
                                case 4:
obj = create_object( get_obj_index( 29029 ), 0 ); /* knife */
                                        break;
                                case 5:
obj = create_object( get_obj_index( 29011 ), 0 ); /* gloves */
                                        break;
                                case 6:
obj = create_object( get_obj_index( 29109 ), 0 ); /* tunic */
                                        break;
                                case 7:
obj = create_object( get_obj_index( 28930 ), 0 ); /* hood */
                                        break;
                                case 8:
obj = create_object( get_obj_index( 29002 ), 0 ); /* ring */
                                        break;
                                case 9:
obj = create_object( get_obj_index( 29061 ), 0 ); /* necklace */
                                        break;
                                case 10:
obj = create_object( get_obj_index( 29054 ), 0 ); /* bracelet */
                                        break;
                                case 11:
obj = create_object( get_obj_index( 29043 ), 0 ); /* whip */
                                        break;
                                case 12:
obj = create_object( get_obj_index( 29032 ), 0 ); /* short sword */
                                        break;
			}
			break;
		case 6:
			mob->perm_str -= 50;
			mob->perm_int -= 50;
			mob->perm_wis -= 50;
			mob->perm_con -= 50;
			mob->perm_cha += 50;
			mob->perm_dex += 50;
			strcat(buf, " child");
			switch(number_range(1,6)) {
                                case 1:
obj = create_object( get_obj_index( 28929 ), 0 ); /* diaper */
                                        break;
                                case 2:
obj = create_object( get_obj_index( 29016 ), 0 ); /* pants */
                                        break;
                                case 3:
obj = create_object( get_obj_index( 28911 ), 0 ); /* shirt */
                                        break;
                                case 4:
obj = create_object( get_obj_index( 29053 ), 0 ); /* cap */
                                        break;
                                case 5:
obj = create_object( get_obj_index( 29109 ), 0 ); /* tunic */
                                        break;
                                case 6:
obj = create_object( get_obj_index( 29017 ), 0 ); /* socks */
                                        break;
			}
			break;
	    }
	} else {
		switch (number_range(1,10)) {
		   case 1:
			sprintf(buf2, "baby %s", buf);
			strcpy(buf, buf2);
			if (number_range(1,10) == 1)
obj = create_object( get_obj_index( 29019 ), 0 ); /* collar */
                        mob->perm_str -= 60;
                        mob->perm_int -= 50;
                        mob->perm_wis -= 50;
                        mob->perm_con -= 70;
                        mob->perm_dex -= 50;
			break;
		    case 2:
			sprintf(buf2, "young %s", buf);
			strcpy(buf, buf2);
			mob->perm_str -= 50;
			mob->perm_int -= 40;
			mob->perm_wis -= 50;
			mob->perm_con -= 50;
			mob->perm_dex -= 30;
			mob->weight /= 3;
			break;
		    case 3:
			sprintf(buf2, "small %s", buf);
			strcpy(buf, buf2);
			mob->perm_str -= 40;
			mob->perm_con -= 40;
			mob->perm_dex -= 20;
			mob->weight /= 2;
			break;
		    case 8:
			sprintf(buf2, "large %s", buf);
			strcpy(buf, buf2);
			mob->perm_str += 30;
			mob->perm_con += 30;
			mob->weight *= 1.3;
			break;
		    case 9:
			sprintf(buf2, "huge %s", buf);
			strcpy(buf, buf2);
			mob->perm_str += 50;
			mob->perm_con += 50;
			mob->weight *= 2;
			break;
		    case 10:
			sprintf(buf2, "giant %s", buf);
			strcpy(buf, buf2);
			mob->perm_str += 100;
			mob->perm_con += 100;
			mob->perm_dex += 50;
			mob->weight *= 10;
			break;
		}
		if (mob->race == 35) mob->gold += 50000;
		if (IS_SET(mob->immune, RIS_FIRE))
			mob->spec_fun = spec_lookup("spec_cast_fire");
		else if (IS_SET(mob->immune, RIS_COLD))
			mob->spec_fun = spec_lookup("spec_cast_frost");
		else if (IS_SET(mob->immune, RIS_POISON))
			mob->spec_fun = spec_lookup("spec_cast_poison");
		else if (IS_SET(mob->immune, RIS_DRAIN))
			mob->spec_fun = spec_lookup("spec_cast_drain");
		else if (IS_SET(mob->immune, RIS_PSIONIC))
			mob->spec_fun = spec_lookup("spec_cast_mind");
		else if (IS_SET(mob->immune, RIS_ELECTRICITY))
			mob->spec_fun = spec_lookup("spec_cast_lightning");
	}

	STRFREE(mob->short_descr);
	mob->short_descr = STRALLOC(buf);
	STRFREE(mob->name);
	mob->name = STRALLOC(buf);

	mob->max_hit = UMAX(100, mob->perm_con * nation->hit);
	mob->max_mana = UMAX(100, mob->perm_int * nation->mana);
	mob->max_move = mob->perm_lck * 50;
	mob->hit = mob->max_hit;
	mob->mana = mob->max_mana;
	mob->move = mob->max_move;

	/* If the mob has an object, determine its material */
	if (obj) {
		mat = first_material;
		while (mat) {
			if ((xIS_SET(obj->extra_flags, ITEM_METAL)
			&&   xIS_SET(mat->extra_flags, ITEM_METAL))
			||  (xIS_SET(obj->extra_flags, ITEM_ORGANIC)
			&&   xIS_SET(mat->extra_flags, ITEM_ORGANIC))) {

			if  (xIS_SET(obj->extra_flags, ITEM_FLAMMABLE)
			&&  !xIS_SET(mat->extra_flags, ITEM_FLAMMABLE)) {
				mat = mat->next;
				continue;
			}
				if (number_percent() < mat->rarity)
					break;
			}
			mat = mat->next;
		}
		/* If we didn't find a good material, forget it */
		if (!mat) {
			extract_obj(obj);
		} else {
			obj->material = mat;
                        strcpy(buf, species->adj);
                        strcat(buf, " ");
                        strcat(buf, mat->name);
                        sprintf(buf2, obj->short_descr, buf);
                        one_argument(buf2, buf);
                        STRFREE(obj->short_descr);
                        obj->short_descr = STRALLOC(buf2);

                        strcpy(buf, mat->name);
                        sprintf(buf2, obj->description, buf);
                        STRFREE(obj->description);
                        obj->description = STRALLOC(capitalize(buf2));

                        strcpy(buf, obj->name);
                        strcat(buf, " ");
                        strcat(buf, mat->name);
                        strcat(buf, " ");
                        strcat(buf, species->adj);
                        STRFREE(obj->name);
                        obj->name=STRALLOC(buf);

                        if (obj->item_type == ITEM_WEAPON)
                          obj->value[2] = mob->perm_str;

        		xSET_BITS(obj->extra_flags, mat->extra_flags);

                                obj->cost += number_fuzzy(mat->cost);
                                obj->size = mob->height;
		obj->weight = UMAX(obj->weight + (mob->height - 66) / 10,1);

                          for (paf = mat->first_affect; paf; paf = paf->next) {
                                        AFFECT_DATA *naf;

                                        CREATE(naf, AFFECT_DATA, 1);

                                        naf->type = paf->type;
                                        naf->duration = paf->duration;
                                        naf->location = paf->location;
                                        naf->modifier = paf->modifier;
				if (paf->location != APPLY_RESISTANT
				&& xIS_SET(mob->act, ACT_NAMED))
					naf->modifier += number_range(1,20);
                                        naf->bitvector = paf->bitvector;
                                        top_affect++;

                       LINK(naf, obj->first_affect, obj->last_affect, next, prev);
                            }

			if (number_range(1,100) * 1000 < get_exp_worth(mob)
			&&  obj->material->magic < number_range(1,200))
                              make_randart(mob, obj);
			/* Random texts for books */
			if (obj->item_type == ITEM_BOOK) {
				i = 0;
				for (book = first_book;book;book = book->next) {
					i++;
				}
				i = number_range(1, i);
				n = 0;
				for (book = first_book;book;book = book->next) {
					n++;
					if (n == i) {
						ed = SetOExtra(obj, "title");
						ed->description = STRALLOC(book->title);
						ed = SetOExtra(obj, "text");
						ed->description = STRALLOC(book->text);
						break;
					}
				}
			}
			xSET_BIT(obj->extra_flags, ITEM_NO_RESET);
			obj_to_char(obj, mob);
			if (xIS_EMPTY(obj->parts))
				mob->main_hand = obj;
			else
				equip_char(mob, obj);
		}
	}

	return mob;
}

void mob_to_area(CHAR_DATA *mob, AREA_DATA *tarea) {
	int vnum;
	int i;
	ROOM_INDEX_DATA *pRoomIndex;

	/* Try 100 times to get a valid room */
	for (i = 0;i < 100;i++) {
		vnum = number_range(tarea->low_r_vnum, tarea->hi_r_vnum);
		if ((pRoomIndex = get_room_index(vnum)) == NULL)
			continue;
		if (IS_SET(pRoomIndex->room_flags, ROOM_NO_MOB))
			continue;
		if (IS_SET(pRoomIndex->runes, RUNE_DISTRACT))
			continue;
		if (IS_SET(pRoomIndex->room_flags, ROOM_NOFLOOR)
		&& !IS_AFFECTED(mob, AFF_FLYING))
			continue;
		if (!IS_AFFECTED(mob, AFF_AQUA_BREATH)
		&&  !IS_AFFECTED(mob, AFF_AQUATIC)
		&&   pRoomIndex->curr_water > 20)
			continue;
		if (IS_AFFECTED(mob, AFF_AQUATIC)
		&& !IS_AFFECTED(mob, AFF_AQUA_BREATH)
		&&  pRoomIndex->curr_water < 20)
			continue;
		char_to_room(mob, pRoomIndex);
		act(AT_ACTION, "You notice $n here.", mob, NULL, NULL, TO_ROOM);
		return;
	}
	bug("Could not find room for %s in %s, extracting...",
		mob->name, tarea->name);
	extract_char(mob, TRUE);
}

/*
 * Make a fire.
 */
void make_fire(ROOM_INDEX_DATA *in_room, sh_int timer)
{
    OBJ_DATA *fire;

    fire = create_object( get_obj_index( OBJ_VNUM_FIRE ), 0 );
    fire->timer = number_fuzzy(timer);
    obj_to_room( fire, in_room );
    return;
}

/*
 * Make a trap.
 */
OBJ_DATA *make_trap(int v0, int v1, int v2, int v3)
{
    OBJ_DATA *trap;

    trap = create_object( get_obj_index( OBJ_VNUM_TRAP ), 0 );
    trap->timer = 0;
    trap->value[0] = v0;
    trap->value[1] = v1;
    trap->value[2] = v2;
    trap->value[3] = v3;
    return trap;
}

/* Load a piece of ore and return it -- Scion */
OBJ_DATA *make_ore( int number ) {
    MATERIAL_DATA *material;
    AREA_DATA *area;
    OBJ_DATA *obj;
	AFFECT_DATA *paf;
	AFFECT_DATA *oaf;
	char buf[MAX_STRING_LENGTH];
    int hi_vnum=2;

	if (!stockobj)
    for (area=first_area; area; area=area->next) {
        if (!str_cmp( area->filename, "stockobj.are" )) {
		stockobj = area;
            hi_vnum=area->hi_o_vnum;
            break;
        } else
            hi_vnum=2;
    }
	else {
		area = stockobj;
            hi_vnum=area->hi_o_vnum;
	}

    if (hi_vnum==2)
        return NULL;

    material=material_lookup(number);
    if (!material)
        return NULL;

    obj=create_object(get_obj_index(hi_vnum), 0);

	if (!obj)
        return NULL;

	strcpy(buf, material->name);
	strcat(buf, " _material_");
	obj->name = STRALLOC(buf);
    obj->short_descr = STRALLOC(material->short_descr);
    obj->description = STRALLOC(material->description);
    obj->weight = number_fuzzy(material->weight);
    obj->cost = number_fuzzy(material->cost);
    obj->extra_flags = material->extra_flags;
    obj->value[0] = material->number;
	obj->timer = 10;
	obj->material = material;

	xSET_BIT(obj->extra_flags, ITEM_GROUNDROT);

    for (paf = material->first_affect; paf; paf = paf->next) {
		CREATE(oaf, AFFECT_DATA, 1);
		oaf->type = paf->type;
		oaf->duration = paf->duration;
		oaf->location = paf->location;
		oaf->modifier = paf->modifier;
		xCLEAR_BITS(oaf->bitvector);
		oaf->next = NULL;
		LINK(oaf, obj->first_affect, obj->last_affect, next, prev);
		++top_affect;
    }

    return obj;
}

/* Shopkeepers can use this to stock their shops
 * Creates a random item appropriate to the shop.
 * Added by Keolah, September 17, 2002
 */
void do_mpmakeitem(CHAR_DATA *ch, char *argument) {
	OBJ_DATA *obj;
	int i, n, vnum, hi_vnum, low_vnum;
	SHOP_DATA *shop;
	AREA_DATA *area;
	MATERIAL_DATA *mat;
	AFFECT_DATA *paf;
	char buf[MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	EXTRA_DESCR_DATA *ed;
	BOOK_DATA *book;

	shop = ch->in_room->pShop;
	if (!shop) return;

	if (number_range(1,100) > shop->profit_buy) return;

	hi_vnum = 0;
	if (!stockobj) {
    for (area=first_area; area; area=area->next) {
      if (!str_cmp( area->filename, "stockobj.are" )) {
		stockobj = area;
		hi_vnum=area->hi_o_vnum;
		low_vnum=area->low_o_vnum;
		break;
	}
    }
	} else {
		area = stockobj;
            hi_vnum=area->hi_o_vnum;
		low_vnum=area->low_o_vnum;
	}
	if (hi_vnum == 0) return;

	/* Decrease this number if it produces too much lag */
	for (i = 0;i < 100;i++) {
		vnum = number_range(low_vnum, hi_vnum);
		if (get_obj_index(vnum)) {
			obj = create_object(get_obj_index(vnum), 0);
			if (IS_OBJ_STAT(obj, ITEM_PROTOTYPE)) {
				extract_obj(obj);
				obj = NULL;
				continue;
			}
			if (shop->type != -1 && obj->item_type != shop->type) {
				extract_obj(obj);
				obj = NULL;
				continue;
			}
			if (shop->flag != -1 && !IS_OBJ_STAT(obj, shop->flag)) {
				extract_obj(obj);
				obj = NULL;
				continue;
			}
			break;
		}
	}

	if (obj) {
		mat = first_material;
		/* Find a material to suit the item */
		while (mat) {
			if ((xIS_SET(obj->extra_flags, ITEM_METAL)
			&&   xIS_SET(mat->extra_flags, ITEM_METAL))
			||  (xIS_SET(obj->extra_flags, ITEM_ORGANIC)
			&&   xIS_SET(mat->extra_flags, ITEM_ORGANIC))) {

			if  (xIS_SET(obj->extra_flags, ITEM_FLAMMABLE)
			&&  !xIS_SET(mat->extra_flags, ITEM_FLAMMABLE)) {
				mat = mat->next;
				continue;
			}

				if (number_percent() < mat->rarity)
					break;
			}
			mat = mat->next;
		}
		/* If we didn't find a good material, forget it */
		if (!mat) {
			extract_obj(obj);
		} else {
			obj->material = mat;
                        strcpy(buf, mat->name);
                        sprintf(buf2, obj->short_descr, buf);
                        one_argument(buf2, buf);
                        STRFREE(obj->short_descr);
                        obj->short_descr = STRALLOC(buf2);

                        strcpy(buf, mat->name);
                        sprintf(buf2, obj->description, buf);
                        STRFREE(obj->description);
                        obj->description = STRALLOC(capitalize(buf2));

                        strcpy(buf, obj->name);
                        strcat(buf, " ");
                        strcat(buf, mat->name);
                        STRFREE(obj->name);
                        obj->name=STRALLOC(buf);

                        if (obj->item_type == ITEM_WEAPON)
                          obj->value[2] = number_range(30,300);

        		xSET_BITS(obj->extra_flags, mat->extra_flags);

                                obj->cost += number_fuzzy(mat->cost);
                                obj->size = number_range(30,80);
  
				for (paf = mat->first_affect; paf; paf = paf->next) {
					AFFECT_DATA *naf;

					CREATE(naf, AFFECT_DATA, 1);

					naf->type = paf->type;
					naf->duration = paf->duration;
					naf->location = paf->location;
					naf->modifier = paf->modifier;
					naf->bitvector = paf->bitvector;
					top_affect++;

					LINK(naf, obj->first_affect, obj->last_affect, next, prev);
				}
			/* Random texts for books */
			if (obj->item_type == ITEM_BOOK) {
				i = 0;
				for (book = first_book;book;book = book->next) {
					i++;
				}
				i = number_range(1, i);
				n = 0;
				for (book = first_book;book;book = book->next) {
					n++;
					if (n == i) {
						ed = SetOExtra(obj, "title");
						ed->description = STRALLOC(book->title);
						ed = SetOExtra(obj, "text");
						ed->description = STRALLOC(book->text);
						break;
					}
				}
			}
			if (obj->material->magic < number_range(1,200))
                              make_randart(ch, obj);
			xSET_BIT(obj->extra_flags, ITEM_NO_RESET);
			obj_to_room(obj, ch->in_room);
			act(AT_ACTION, "$n fashions $p and puts it out for sale.",
				ch, obj, NULL, TO_ROOM);
		}
	}
}

/* Load a raw material into the game -- Scion */
void do_makeore( CHAR_DATA *ch, char *argument) {
	OBJ_DATA *obj;
	MATERIAL_DATA *material;
	AREA_DATA *area;
	AFFECT_DATA *paf;
	AFFECT_DATA *oaf;
	char buf[MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	int hi_vnum=2;
	int i=-1;

	if (!is_number(argument)) {
		send_to_char("That is not a number.\r\n",ch);
		return;
	}

	i=atoi(argument);

	material=material_lookup(i);

	if (!material) {
		send_to_char("There is no such material.\r\n",ch);
		return;
	}

	if (!stockobj)
    for (area=first_area; area; area=area->next) {
        if (!str_cmp( area->filename, "stockobj.are" )) {
		stockobj = area;
			hi_vnum=area->hi_o_vnum;
			break;
		} else {
			hi_vnum=2;
		}
	}
	else {
		area = stockobj;
            hi_vnum=area->hi_o_vnum;
	}
	if (hi_vnum==2) {
		send_to_char("There does not seem to be a raw material object in the game.\r\n",ch);
		return;
	}

	obj = create_object( get_obj_index( hi_vnum ), 0 );

	sprintf(buf, "%s _material_", material->name);
	obj->name=STRALLOC(buf);
	obj->short_descr = STRALLOC(material->short_descr);
	obj->description = STRALLOC(material->description);
	obj->weight=number_fuzzy(material->weight);
	obj->cost=number_fuzzy(material->cost);
	obj->extra_flags=material->extra_flags;
	obj->value[0]=material->number;
	obj->material = material;

	for (paf = material->first_affect; paf; paf = paf->next) {
		CREATE(oaf, AFFECT_DATA, 1);
		oaf->type = paf->type;
		oaf->duration = paf->duration;
		oaf->location = paf->location;
		oaf->modifier = paf->modifier;
		xCLEAR_BITS(oaf->bitvector);
		oaf->next = NULL;
		LINK(oaf, obj->first_affect, obj->last_affect, next, prev);
		++top_affect;
    }

	xSET_BIT(obj->extra_flags, ITEM_PLRBLD);
	xSET_BIT(obj->extra_flags, ITEM_NO_RESET);
	obj_to_char(obj, ch);
	sprintf(buf, "You create $p!");
	sprintf(buf2, "$n creates $p!");
	act( AT_IMMORT, buf, ch, obj, NULL, TO_CHAR);
	act( AT_IMMORT, buf2, ch, obj, NULL, TO_ROOM);
	return;
}

/* Turn a raw material into a piece of equipment -- Scion */
void do_fashion( CHAR_DATA *ch, char *argument) {
	AREA_DATA *area;
	AFFECT_DATA *paf;
	OBJ_INDEX_DATA *pObjIndex;
	OBJ_DATA *obj;
	OBJ_DATA *ore;
	OBJ_DATA *fire;
	MATERIAL_DATA *material;
	int lo_vnum=2;
	int hi_vnum=2;
	int hash;
	char arg[MAX_INPUT_LENGTH];
	char buf[MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	bool found;
	extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
	extern sh_int gsn_fashion;
	SPECIES_DATA *species;

    if (!can_use_bodypart(ch, BP_RHAND)
    ||  !can_use_bodypart(ch, BP_LHAND)) {
        send_to_char("That would be hard without functional hands.\n\r", ch);
        return;
    }

	argument = one_argument(argument, arg);

	if (!stockobj)
    for (area=first_area; area; area=area->next) {
        if (!str_cmp( area->filename, "stockobj.are" )) {
		stockobj = area;
			lo_vnum=area->low_o_vnum;
			hi_vnum=area->hi_o_vnum;
			break;
		} else {
			lo_vnum=2;
			hi_vnum=2;
		}
	}
	else {
		area = stockobj;
            lo_vnum=area->low_o_vnum;
            hi_vnum=area->hi_o_vnum;
	}
	if (lo_vnum==hi_vnum) {
		send_to_char("You cannot figure out how to make anything right now.\r\n",ch);
		return;
	}

	if (!first_material) {
		bug("No materials exist, cannot use do_fashion.",0);
		send_to_char("You do not know how to make anything.\r\n",ch);
		return;
	}

	ore = get_obj_carry(ch, argument);
	if (!ore) {
		send_to_char("You don't have that.\n\r", ch);
		return;
	}

	if (ore->pIndexData->vnum != hi_vnum) {
		send_to_char("That isn't a raw material.\n\r", ch);
		return;
	}

	for ( hash = 0; hash < MAX_KEY_HASH; hash++ ) {
		for ( pObjIndex = obj_index_hash[hash]; pObjIndex; pObjIndex = pObjIndex->next ) {
		    if ( nifty_is_name( arg, pObjIndex->name )
			  && pObjIndex->vnum >= lo_vnum
			  && pObjIndex->vnum <= hi_vnum) {
				obj = create_object( pObjIndex, 0 );
				if (!obj) {
					send_to_char("You cannot recall exactly how to make one of those.\r\n",ch);
					return;
				}

				obj->obj_by = STRALLOC(ch->name);

				material=ore->material;

				if (obj->pIndexData->vnum == ore->pIndexData->vnum) {
					send_to_char("You cannot fashion a raw material from a raw material.\r\n",ch);
					extract_obj(obj);
					return;
				}
				if (!material) {
					send_to_char("You cannot seem to identify the type of material you have.\r\n",ch);
					extract_obj(obj);
					return;
				}
				if (!ore) {
					send_to_char("You do not seem to have the proper materials.\r\n",ch);
					extract_obj(obj);
					return;
				}
				if (IS_OBJ_STAT(obj, ITEM_GEM)) {
					send_to_char("Use AFFIX to affix gems to items.\n\r", ch);
					extract_obj(obj);
					return;
				}
				if (obj->pIndexData->tech > ch->pcdata->noncombat[SK_SMITH]) {
					send_to_char("You are not skilled enough to make that.\n\r", ch);
					return;
				}
				if (obj->weight > ore->weight + 2) {
					send_to_char("You need more ore to make that.\r\n", ch);
					send_to_char("Use COMBINE to add one piece of ore to another, for a bigger piece.\r\n", ch);
					extract_obj(obj);
					return;
				}
		if (IS_OBJ_STAT(obj, ITEM_METAL)) {
			if (!IS_OBJ_STAT(ore, ITEM_METAL)) {
				send_to_char("You need a metal ore to make that.\r\n",ch);
				extract_obj(obj);
				return;
			}
			found = FALSE;
			for (fire = ch->in_room->first_content; fire;
			fire = fire->next_content) {
				if (fire->item_type == ITEM_FIRE) {
					found = TRUE;
					break;
				}
			}
		if (IS_OBJ_STAT(ore, ITEM_FLAMMABLE))
			found = TRUE;
		else
			if (IS_OBJ_STAT(obj, ITEM_FLAMMABLE)) {
				send_to_char("You need some wood to make that.\r\n",ch);
				extract_obj(obj);
				return;
			}
			if (!found) {
				send_to_char(
	"There must be a fire in the room to forge metals.\n\r", ch);
		extract_obj(obj);
		return;
		}
	}
				else if ((IS_OBJ_STAT(obj, ITEM_ORGANIC)) && (!IS_OBJ_STAT(ore, ITEM_ORGANIC))) {
					send_to_char("You need cloth or leather to make that.\r\n",ch);
					extract_obj(obj);
					return;
				}

				if ((IS_OBJ_STAT(obj, ITEM_MAGIC)) && (!IS_OBJ_STAT(ore, ITEM_MAGIC))) {
					send_to_char("You need a magical raw material to build that object.\r\n", ch);
					extract_obj(obj);
					return;
				}

				separate_obj(ore);
				obj_from_char(ore);

				obj->material=material;


				species=find_species(ch->nation->species);
				strcpy(buf, species->adj);
				strcat(buf, " ");
				strcat(buf, material->name);
				sprintf(arg, obj->short_descr, buf);
				one_argument(arg, buf);
				STRFREE(obj->short_descr);
				obj->short_descr = STRALLOC(arg);

				strcpy(buf, material->name);
				sprintf(arg, obj->description, buf);
				STRFREE(obj->description);
				obj->description = STRALLOC(capitalize(arg));

				strcpy(buf, obj->name);
				strcat(buf, " ");
				strcat(buf, material->name);
				strcat(buf, " ");
				strcat(buf, species->adj);
				STRFREE(obj->name);
				obj->name=STRALLOC(buf);

				if (obj->item_type == ITEM_WEAPON
				||  obj->item_type == ITEM_MISSILE_WEAPON)
					obj->value[2] =
				    ch->pcdata->weapon[obj->value[5]]
				+   ch->pcdata->noncombat[SK_SMITH];

				xSET_BITS(obj->extra_flags, ore->extra_flags);
				xSET_BIT(obj->extra_flags, ITEM_PLRBLD);
				xREMOVE_BIT(obj->extra_flags, ITEM_GROUNDROT);
				xSET_BIT(obj->extra_flags, ITEM_NO_RESET);

				obj->cost += number_fuzzy(ore->cost);
				obj->size = ch->height;

		obj->weight = UMAX(obj->weight + (ch->height - 66) / 10,1);
		STRFREE(ch->last_taken);
		sprintf(buf, "fashioning the %s", myobj(obj));
		ch->last_taken = STRALLOC(buf);
		if (IS_OBJ_STAT(obj, ITEM_METAL)) {
			learn_noncombat(ch, SK_SMITH);
			WAIT_STATE(ch, (100 - ch->pcdata->noncombat[SK_SMITH]) / 5);
		} else {
			learn_noncombat(ch, SK_TAILOR);
			WAIT_STATE(ch, (100 - ch->pcdata->noncombat[SK_TAILOR]) / 5);
		}

		WAIT_STATE(ch, obj->pIndexData->tech);

				/* Roll some dice... */
		if (number_percent() > LEARNED(ch, gsn_fashion)) {
					send_to_char("You can't quite seem to get it right, and ruin your fashioned item.\r\n",ch);
					learn_from_failure(ch, gsn_fashion);
                                	if (ore->weight > obj->weight) {
                                	        ore->weight -= UMAX(1, obj->weight);
                        	                obj_to_char(ore, ch);
                	                } else {
        	                                extract_obj(ore);
	                                }
					extract_obj(obj);
					return;
				}

				for (paf = ore->first_affect; paf; paf = paf->next) {
					AFFECT_DATA *naf;

					CREATE(naf, AFFECT_DATA, 1);

					naf->type = paf->type;
					naf->duration = paf->duration;
					naf->location = paf->location;
					naf->modifier = paf->modifier;
					naf->bitvector = paf->bitvector;
					top_affect++;

					LINK(naf, obj->first_affect, obj->last_affect, next, prev);
			    }

				if (ore->weight > obj->weight) {
					ore->weight -= UMAX(1, obj->weight);
					obj_to_char(ore, ch);
				} else {
					extract_obj(ore);
				}

				obj_to_char(obj,ch);
				sprintf(buf, "You fashion $p from %s.", material->name);
				sprintf(buf2, "$n fashions $p from %s.", material->name);
				act( AT_SKILL, buf, ch, obj, NULL, TO_CHAR);
				act( AT_SKILL, buf2, ch, obj, NULL, TO_ROOM);
				learn_from_success(ch, gsn_fashion);
				return;
			}
		}
	}
	send_to_char( "You cannot figure out how to make that.\n\r", ch );
	return;

}

/*
 * Turn an object into scraps.		-Thoric
 */
void make_scraps( OBJ_DATA *obj )
{
  char buf[MAX_STRING_LENGTH];
  OBJ_DATA  *scraps, *tmpobj;
  CHAR_DATA *ch = NULL;

  if ( IS_OBJ_STAT(obj, ITEM_ARTIFACT)
  ||   IS_OBJ_STAT(obj, ITEM_DURABLE))
	  return;

  separate_obj( obj );
  scraps	= create_object( get_obj_index( OBJ_VNUM_SCRAPS ), 0 );
  scraps->timer = number_range( 5, 15 );

  /* don't make scraps of scraps of scraps of ... */
  if ( obj->pIndexData->vnum == OBJ_VNUM_SCRAPS )
  {
     STRFREE( scraps->short_descr );
     scraps->short_descr = STRALLOC( "some debris" );
     STRFREE( scraps->description );
     scraps->description = STRALLOC( "Bits of debris lie on the ground here." );
  }
  else
  {
     sprintf( buf, scraps->short_descr, obj->short_descr );
     STRFREE( scraps->short_descr );
     scraps->short_descr = STRALLOC( buf );
     sprintf( buf, scraps->description, obj->short_descr );
     STRFREE( scraps->description );
     scraps->description = STRALLOC( buf );
  }

  if ( obj->carried_by )
  {

	  act( AT_OBJECT, "$p falls to the ground in scraps!",
		  obj->carried_by, obj, NULL, TO_CHAR );
    if ( obj == get_eq_char( obj->carried_by, WEAR_HAND )
    &&  (tmpobj = get_eq_char( obj->carried_by, WEAR_HAND2)) != NULL )
       tmpobj->wear_loc = WEAR_HAND;

    obj_to_room( scraps, obj->carried_by->in_room);
  }
  else
  if ( obj->in_room )
  {
    if ( (ch = obj->in_room->first_person ) != NULL )
    {
      act( AT_OBJECT, "$p is reduced to little more than scraps.",
	   ch, obj, NULL, TO_ROOM );
      act( AT_OBJECT, "$p is reduced to little more than scraps.",
	   ch, obj, NULL, TO_CHAR );
    }
    obj_to_room( scraps, obj->in_room);
  }
  if ( (obj->item_type == ITEM_CONTAINER || obj->item_type == ITEM_KEYRING
  ||    obj->item_type == ITEM_QUIVER    || obj->item_type == ITEM_CORPSE_PC)
  &&    obj->first_content )
  {
    if ( ch && ch->in_room )
    {
	act( AT_OBJECT, "The contents of $p fall to the ground.",
	   ch, obj, NULL, TO_ROOM );
	act( AT_OBJECT, "The contents of $p fall to the ground.",
	   ch, obj, NULL, TO_CHAR );
    }
    if ( obj->carried_by )
	empty_obj( obj, NULL, obj->carried_by->in_room );
    else
    if ( obj->in_room )
	empty_obj( obj, NULL, obj->in_room );
    else
    if ( obj->in_obj )
	empty_obj( obj, obj->in_obj, NULL );
  }
  extract_obj( obj );
}


/*
 * Make a corpse out of a character.
 */
void make_corpse( CHAR_DATA *ch ) {
    char buf[MAX_STRING_LENGTH];
    OBJ_DATA *corpse;
    OBJ_DATA *cheese;
    OBJ_DATA *obj;
    OBJ_DATA *obj_next;
    MATERIAL_DATA *material;
    PART_DATA *part;
    char *name;

	if (IS_AFFECTED(ch, AFF_NO_CORPSE)) {
                if ( ch->gold > 0 ) {
                    if ( ch->in_room ) {
                           ch->in_room->area->gold_looted += ch->gold;
                    }
                    obj_to_room( create_money( ch->gold ), ch->in_room );
                    ch->gold = 0;
                }
		for ( obj = ch->first_carrying; obj; obj = obj_next ) {
        		obj_next = obj->next_content;
	        if (!IS_OBJ_STAT(obj, ITEM_LOYAL) || IS_NPC(ch)) {
        	        obj_from_char(obj);
                	if ( IS_OBJ_STAT( obj, ITEM_INVENTORY )
                	|| IS_OBJ_STAT(obj, ITEM_DEATHROT ) ) {
                        	extract_obj( obj );
                	} else {
                    		obj_to_room( obj, ch->in_room );
			}
		}
                }	
		return;
	}

	if (IS_NPC(ch)) {
		name		= ch->short_descr;
		corpse		= create_object(get_obj_index(OBJ_VNUM_CORPSE_NPC), 0);
		corpse->timer	= 6;
		if ( ch->gold > 0 ) {
		    if ( ch->in_room ) {
				ch->in_room->area->gold_looted += ch->gold;
			}
		    obj_to_obj( create_money( ch->gold ), corpse );
		    ch->gold = 0;
		}

		/*	Using corpse cost to cheat, since corpses not sellable */
		corpse->cost     = (-(int)ch->pIndexData->vnum);
    } else {
		name		= ch->name;
		corpse		= create_object(get_obj_index(OBJ_VNUM_CORPSE_PC), 0);
		corpse->cost	= ch->exp;
		corpse->timer	= 40;

		if (ch->gold > 0) {
			obj_to_obj(create_money(ch->gold), corpse);
			ch->gold=0;
		}
	}
	if (ch->nation) name = ch->nation->name;

	corpse->weight = ch->weight;
	corpse->material = NULL;

	corpse->value[0]	= ch->perm_str;
	corpse->value[1]	= ch->perm_int;
	corpse->value[2]	= ch->perm_wis;
	corpse->value[3]	= ch->perm_dex;
	corpse->value[4]	= ch->perm_con;
	corpse->value[5]	= ch->perm_cha;
	corpse->value[6]	= ch->perm_lck;

	for (part = ch->first_part;part;part = part->next) {
	    if (part->flags != PART_SEVERED)
		xSET_BIT(corpse->parts, part->loc);
	}

    /* Added corpse name - make locate easier , other skills */
    sprintf( buf, "corpse %s %s", name, ch->name );
    STRFREE( corpse->name );
    corpse->name = STRALLOC( buf );

    sprintf( buf, corpse->short_descr, name );
    STRFREE( corpse->short_descr );
    corpse->short_descr = STRALLOC( buf );

    sprintf( buf, corpse->description, IS_NPC(ch) ?
	aoran(ch->short_descr) : ch->name );
    STRFREE( corpse->description );
    corpse->description = STRALLOC( buf );

    STRFREE( corpse->obj_by );
    corpse->obj_by = STRALLOC( ch->nation ? ch->nation->name : "");

    for ( obj = ch->first_carrying; obj; obj = obj_next ) {
	obj_next = obj->next_content;
	if (!IS_OBJ_STAT(obj, ITEM_LOYAL) || IS_NPC(ch)) {

		obj_from_char(obj);
		if ( IS_OBJ_STAT( obj, ITEM_INVENTORY )
		|| IS_OBJ_STAT(obj, ITEM_DEATHROT ) ) {
			extract_obj( obj );
		}
		else {
		    obj_to_obj( obj, corpse );
		}
	}
    }

    if (IS_NPC(ch)) {
      for (material=first_material; material; material=material->next) {
		if ((material->race == ch->race) &&
		(number_percent() < material->rarity)) {
            obj=make_ore(material->number);
            if (obj)
                obj_to_obj(obj, corpse);
        }
      }
    } else {
	cheese = create_object( get_obj_index( OBJ_VNUM_CHAOS_CHEESE ), 0 );
	cheese->timer = 25;
	obj_to_room( cheese, ch->in_room );
    }

    obj_to_room( corpse, ch->in_room);
    return;
}



void make_blood( CHAR_DATA *ch, int amt )
{
	OBJ_DATA *obj;

	if (!ch->in_room) return;

	/* lets not create tons of pools of blood -keo */
	for (obj = ch->in_room->first_content;obj;obj = obj->next_content) {
		if (obj->item_type == ITEM_BLOOD) break;
	}
	if (obj) {
		obj->timer += number_range(1,2);
		obj->value[0] += number_fuzzy(amt);
		obj->value[1]   = obj->value[0];
		return;
	}

	obj		= create_object( get_obj_index( OBJ_VNUM_BLOOD ), 0 );
	obj->timer	= number_range( 2, 4 );
	obj->value[0]   = number_fuzzy(amt);
	obj->value[1]   = obj->value[0];
	obj_to_room( obj, ch->in_room );
}


void make_bloodstain( CHAR_DATA *ch )
{
	OBJ_DATA *obj;

	obj		= create_object( get_obj_index( OBJ_VNUM_BLOODSTAIN ), 0 );
	obj->timer	= number_range( 1, 2 );
	obj_to_room( obj, ch->in_room );
}


/*
 * make some coinage
 */
OBJ_DATA *create_money( int amount )
{
    char buf[MAX_STRING_LENGTH];
    OBJ_DATA *obj;

    if ( amount <= 0 )
    {
	bug( "Create_money: zero or negative money %d.", amount );
	amount = 1;
    }

    if ( amount == 1 )
    {
	obj = create_object( get_obj_index( OBJ_VNUM_MONEY_ONE ), 0 );
    }
    else
    {
	obj = create_object( get_obj_index( OBJ_VNUM_MONEY_SOME ), 0 );
	sprintf( buf, obj->short_descr, amount );
	STRFREE( obj->short_descr );
	obj->short_descr = STRALLOC( buf );
	obj->value[0]	 = amount;
    }

    return obj;
}