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