/*****************************************************************************
* DikuMUD (C) 1990, 1991 by: *
* Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, *
* and Katja Nyboe. *
*---------------------------------------------------------------------------*
* MERC 2.1 (C) 1992, 1993 by: *
* Michael Chastain, Michael Quan, and Mitchell Tse. *
*---------------------------------------------------------------------------*
* SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. *
* Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, *
* gorog, Grishnakh, Nivek, Tricops, and Fireblade. *
*---------------------------------------------------------------------------*
* SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. *
* Their contributions are greatly appreciated. *
*---------------------------------------------------------------------------*
* LoP (C) 2006 - 2012 by: the LoP team. *
*---------------------------------------------------------------------------*
* Specific object creation module *
*****************************************************************************/
#include <stdio.h>
#include "h/mud.h"
/* Make a trap. */
OBJ_DATA *make_trap( int v0, int v1, int v2, int v3 )
{
OBJ_INDEX_DATA *otrap;
OBJ_DATA *trap;
if( !( otrap = get_obj_index( OBJ_VNUM_TRAP ) ) )
{
bug( "%s: object vnum %d doesn't exist.", __FUNCTION__, OBJ_VNUM_TRAP );
return NULL;
}
if( !( trap = create_object( otrap, 0 ) ) )
{
bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_TRAP );
return NULL;
}
trap->timer = 0;
trap->value[0] = v0;
trap->value[1] = v1;
trap->value[2] = v2;
trap->value[3] = v3;
return trap;
}
/* Turn an object into scraps. */
void make_scraps( OBJ_DATA *obj )
{
char buf[MSL];
OBJ_DATA *scraps;
CHAR_DATA *ch = NULL;
separate_obj( obj );
if( !( scraps = create_object( get_obj_index( OBJ_VNUM_SCRAPS ), 0 ) ) )
{
bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_SCRAPS );
return;
}
scraps->timer = number_range( 5, 15 );
/* don't make scraps of scraps of scraps of ... */
if( obj->pIndexData->vnum == OBJ_VNUM_SCRAPS )
{
STRSET( scraps->short_descr, "some debris" );
STRSET( scraps->description, "Bits of debris lie on the ground here." );
}
else
{
if( obj->short_descr )
{
if( scraps->short_descr )
{
snprintf( buf, sizeof( buf ), scraps->short_descr, obj->short_descr );
STRSET( scraps->short_descr, buf );
}
else
scraps->short_descr = STRALLOC( obj->short_descr );
if( scraps->description )
{
snprintf( buf, sizeof( buf ), scraps->description, obj->short_descr );
STRSET( scraps->description, buf );
}
else
scraps->description = STRALLOC( obj->short_descr );
}
}
if( obj->carried_by )
{
ch = obj->carried_by;
act( AT_OBJECT, "$p falls to the ground in scraps!", obj->carried_by, obj, NULL, TO_CHAR );
obj_to_room( scraps, obj->carried_by->in_room );
}
else if( obj->in_room )
{
if( ( ch = obj->in_room->first_person ) )
{
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 );
}
oprog_scrap_trigger( ch, obj );
extract_obj( obj );
}
/* Make a corpse out of a character. */
OBJ_DATA *make_corpse( CHAR_DATA *ch, CHAR_DATA *killer )
{
char buf[MSL], *name;
OBJ_DATA *corpse, *obj, *obj_next;
int rest = 0;
if( is_npc( ch ) )
{
name = ch->short_descr;
if( !( corpse = create_object( get_obj_index( OBJ_VNUM_CORPSE_NPC ), 0 ) ) )
{
bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_CORPSE_NPC );
return NULL;
}
handle_mwreset( corpse );
corpse->timer = 6;
rest = ch->gold;
ch->gold = 0;
obj_to_obj( create_money( rest ), corpse );
corpse->cost = ( -( int )ch->pIndexData->vnum );
corpse->value[2] = corpse->timer;
if( !xIS_SET( ch->act, ACT_NOSLICE ) )
corpse->value[0] = 1; /* How many slices do you wish to allow per corpse? */
corpse->value[1] = ch->pIndexData->vnum;
}
else
{
name = ch->name;
if( !( corpse = create_object( get_obj_index( OBJ_VNUM_CORPSE_PC ), 0 ) ) )
{
bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_CORPSE_PC );
return NULL;
}
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 ) && sysdata.pk_loot )
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 ) && ch != killer )
corpse->value[3] = 1;
else
corpse->value[3] = 0;
}
if( ch != killer )
{
snprintf( buf, sizeof( buf ), "%s", killer->name );
STRSET( corpse->action_desc, buf );
}
snprintf( buf, sizeof( buf ), "corpse %s", name );
STRSET( corpse->name, buf );
if( corpse->short_descr )
{
snprintf( buf, sizeof( buf ), corpse->short_descr, name );
STRSET( corpse->short_descr, buf );
}
else
corpse->short_descr = STRALLOC( name );
if( corpse->description )
{
snprintf( buf, sizeof( buf ), corpse->description, name );
STRSET( corpse->description, buf );
}
else
corpse->description = STRALLOC( name );
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 )
|| ( is_npc( ch ) && xIS_SET( ch->act, ACT_AUTOPURGE ) ) ) /* Instead of having to use programs to purge inventory on death */
extract_obj( obj );
else
{
if( is_obj_stat( obj, ITEM_PIERCED ) )
xREMOVE_BIT( obj->extra_flags, ITEM_PIERCED );
if( is_obj_stat( obj, ITEM_LODGED ) ) /* Probably better to remove these instead of unlodging and letting them get them */
{
xREMOVE_BIT( obj->extra_flags, ITEM_LODGED );
extract_obj( obj );
continue;
}
obj_to_obj( obj, corpse );
}
}
obj_to_char_cords( corpse, ch );
return obj_to_room( corpse, ch->in_room );
}
void make_blood( CHAR_DATA *ch )
{
OBJ_DATA *obj;
if( !( obj = create_object( get_obj_index( OBJ_VNUM_BLOOD ), 0 ) ) )
{
bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_BLOOD );
return;
}
obj->timer = number_range( 2, 4 );
obj->value[1] = number_range( 3, UMIN( 5, ch->level ) );
obj_to_room( obj, ch->in_room );
obj_to_char_cords( obj, ch );
}
void make_bloodstain( OBJ_DATA *obj, ROOM_INDEX_DATA *room )
{
OBJ_INDEX_DATA *bindex;
OBJ_DATA *bstain;
if( !room )
{
bug( "%s: NULL room", __FUNCTION__ );
return;
}
if( !( bindex = get_obj_index( OBJ_VNUM_BLOODSTAIN ) ) )
{
bug( "%s: couldn't find object vnum %d", __FUNCTION__, OBJ_VNUM_BLOODSTAIN );
return;
}
if( !( bstain = create_object( bindex, 0 ) ) )
{
bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_BLOODSTAIN );
return;
}
bstain->timer = number_range( 1, 3 );
obj_to_room( bstain, room );
if( obj && is_obj_stat( obj, ITEM_WILDERNESS ) )
{
xSET_BIT( bstain->extra_flags, ITEM_WILDERNESS );
bstain->cords[0] = obj->cords[0];
bstain->cords[1] = obj->cords[1];
}
}
void set_money( OBJ_DATA *obj, int amount )
{
char buf[MSL], *bignum;
bignum = num_punct( amount );
if( obj->pIndexData->short_descr )
{
snprintf( buf, sizeof( buf ), obj->pIndexData->short_descr, bignum );
STRSET( obj->short_descr, buf );
}
else
{
snprintf( buf, sizeof( buf ), "%s gold coins", bignum );
obj->short_descr = STRALLOC( buf );
}
if( obj->pIndexData->description )
{
snprintf( buf, sizeof( buf ), obj->pIndexData->description, bignum );
STRSET( obj->description, buf );
}
else
{
snprintf( buf, sizeof( buf ), "%s gold coins", bignum );
obj->description = STRALLOC( buf );
}
obj->value[0] = amount;
}
/* make some coinage */
OBJ_DATA *create_money( int amount )
{
OBJ_DATA *obj;
if( amount == 0 ) /* No point in creating nothing */
return NULL;
if( amount < 0 )
{
bug( "%s: negative money (Amount)%d.", __FUNCTION__, amount );
amount = 1;
}
if( amount == 1 )
{
if( !( obj = create_object( get_obj_index( OBJ_VNUM_MONEY_ONE ), 0 ) ) )
{
bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_MONEY_ONE );
return NULL;
}
}
else
{
if( !( obj = create_object( get_obj_index( OBJ_VNUM_MONEY_SOME ), 0 ) ) )
{
bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_MONEY_SOME );
return NULL;
}
set_money( obj, amount );
}
return obj;
}