/****************************************************************************
* [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 *
****************************************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mud.h"
/* from handler.c -- Scion */
extern MATERIAL_DATA *material_lookup( int number );
/*
* 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 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;
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;
}
for ( area = first_area; area; area = area->next ) {
if ( !str_cmp( area->filename, "stockobj.are" ) ) {
hi_vnum=area->hi_o_vnum;
break;
} else {
hi_vnum=2;
}
}
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 );
obj->name=STRALLOC(material->name);
strcat(obj->name, " _material_\0");
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->magic_flags=material->magic_flags;
obj->value[0]=material->number;
for (paf=material->first_affect; paf; paf=paf->next) {
}
xSET_BIT(obj->extra_flags, ITEM_PLRBLD);
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;
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *obj;
OBJ_DATA *ore;
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];
char buf3[MAX_STRING_LENGTH];
extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
argument = one_argument(argument, arg);
for ( area = first_area; area; area = area->next ) {
if ( !str_cmp( area->filename, "stockobj.are" ) ) {
lo_vnum=area->low_o_vnum;
hi_vnum=area->hi_o_vnum;
break;
} else {
lo_vnum=2;
hi_vnum=2;
}
}
if (lo_vnum==hi_vnum) {
send_to_char("You cannot seem to 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;
}
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;
}
ore=get_obj_vnum(ch, hi_vnum);
material=material_lookup(ore->value[0]);
if (obj->pIndexData->vnum == ore->pIndexData->vnum) {
send_to_char("You cannot make a raw material from a raw material.\r\n",ch);
return;
}
if (!material) {
send_to_char("You cannot seem to identify the type of material you have.\r\n",ch);
return;
}
if (!ore) {
send_to_char("You do not seem to have the proper materials.\r\n",ch);
return;
}
if ((IS_OBJ_STAT(obj, ITEM_METAL)) && (!IS_OBJ_STAT(ore, ITEM_METAL))) {
send_to_char("You cannot make that with the materials you have.\r\n",ch);
return;
}
else if ((IS_OBJ_STAT(obj, ITEM_ORGANIC)) && (!IS_OBJ_STAT(ore, ITEM_ORGANIC))) {
send_to_char("You cannot make that with the materials you have.\r\n",ch);
return;
}
separate_obj(ore);
obj_from_char(ore);
obj->material=material;
extract_obj(ore);
strcpy(buf, material->name);
one_argument((char *)buf, buf3);
sprintf(arg, obj->short_descr, buf3);
STRFREE(obj->short_descr);
obj->short_descr = STRALLOC(aoran(arg));
sprintf(arg, obj->description, buf);
STRFREE(obj->description);
obj->description = STRALLOC(capitalize(aoran(arg)));
strcpy(arg, obj->name);
STRFREE(obj->name);
strcat(arg, " ");
strcat(arg, buf);
obj->name=STRALLOC(arg);
xSET_BIT(obj->extra_flags, ITEM_PLRBLD);
obj_to_char(obj,ch);
sprintf(buf, "You fashion $p from %s.", buf3);
sprintf(buf2, "$n fashions $p from %s.", buf3);
act( AT_SKILL, buf, ch, obj, NULL, TO_CHAR);
act( AT_SKILL, buf2, ch, obj, NULL, TO_ROOM);
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 ((obj->carried_by && IS_IMMORTAL(obj->carried_by)) || IS_OBJ_STAT(obj, ITEM_ARTIFACT))
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_WIELD )
&& (tmpobj = get_eq_char( obj->carried_by, WEAR_DUAL_WIELD)) != NULL )
tmpobj->wear_loc = WEAR_WIELD;
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_DATA *killer )
{
char buf[MAX_STRING_LENGTH];
OBJ_DATA *corpse;
OBJ_DATA *obj;
OBJ_DATA *obj_next;
char *name;
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;
sysdata.global_looted += ch->gold/100;
}
obj_to_obj( create_money( ch->gold ), corpse );
ch->gold = 0;
}
/* Cannot use these! They are used.
corpse->value[0] = (int)ch->pIndexData->vnum;
corpse->value[1] = (int)ch->max_hit;
*/
/* Using corpse cost to cheat, since corpses not sellable */
corpse->cost = (-(int)ch->pIndexData->vnum);
corpse->value[2] = corpse->timer;
}
else
{
name = ch->name;
corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_PC), 0);
if ( in_arena( ch ) )
corpse->timer = 0;
else
corpse->timer = 40;
corpse->value[2] = (int)(corpse->timer/8);
corpse->value[4] = ch->level;
if ( CAN_PKILL( ch ) )
xSET_BIT( corpse->extra_flags, ITEM_CLANCORPSE );
/* Pkill corpses get save timers, in ticks (approx 70 seconds)
This should be anough for the killer to type 'get all corpse'. */
if ( !IS_NPC(ch) && !IS_NPC(killer) )
corpse->value[3] = 1;
else
corpse->value[3] = 0;
}
if ( CAN_PKILL( ch ) && CAN_PKILL( killer ) && ch != killer )
{
sprintf( buf, "%s", killer->name );
STRFREE( corpse->action_desc );
corpse->action_desc = STRALLOC( buf );
}
/* Added corpse name - make locate easier , other skills */
sprintf( buf, "corpse %s", 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, name );
STRFREE( corpse->description );
corpse->description = STRALLOC( buf );
for ( obj = ch->first_carrying; obj; obj = obj_next )
{
obj_next = obj->next_content;
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 );
}
obj_to_room( corpse, ch->in_room );
return;
}
void make_blood( CHAR_DATA *ch )
{
OBJ_DATA *obj;
obj = create_object( get_obj_index( OBJ_VNUM_BLOOD ), 0 );
obj->timer = number_range( 2, 4 );
obj->value[1] = number_range( 3, UMIN(5, ch->level) );
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;
}