/***************************************************************************** * 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, 2007, 2008, 2009 by: the LoP team. * *---------------------------------------------------------------------------* * Specific object creation module * *****************************************************************************/ #include <stdio.h> #include "h/mud.h" void oprog_scrap_trigger( CHAR_DATA *ch, OBJ_DATA *obj ); void handle_mwreset( OBJ_DATA *corpse ); /* Make a trap. */ OBJ_DATA *make_trap( int v0, int v1, int v2, int v3 ) { OBJ_DATA *trap; if( !( trap = create_object( get_obj_index( OBJ_VNUM_TRAP ), 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 bill = 0, 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; bill = ch->bgold; ch->bgold = 0; rest = ch->gold; ch->gold = 0; obj_to_obj( create_money( rest, bill ), corpse ); corpse->cost = ( -( int )ch->pIndexData->vnum ); corpse->value[2] = corpse->timer; 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( can_pkill( ch ) && can_pkill( killer ) && 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 ) ) 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 ) ) xREMOVE_BIT( obj->extra_flags, ITEM_LODGED ); obj_to_obj( obj, corpse ); } } 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 ); } void make_bloodstain( ROOM_INDEX_DATA *room ) { OBJ_DATA *obj; if( !room ) { bug( "%s: NULL room", __FUNCTION__ ); return; } if( !( obj = create_object( get_obj_index( OBJ_VNUM_BLOODSTAIN ), 0 ) ) ) { bug( "%s: couldn't create object vnum %d", __FUNCTION__, OBJ_VNUM_BLOODSTAIN ); return; } obj->timer = number_range( 1, 3 ); obj_to_room( obj, room ); } void set_money( OBJ_DATA *obj, int bamount, int amount ) { char buf[MSL], *bignum; bignum = show_big_nums( bamount, 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; obj->value[1] = bamount; } /* make some coinage */ OBJ_DATA *create_money( int amount, int bill ) { OBJ_DATA *obj; if( amount == 0 && bill == 0 ) /* No point in creating nothing */ return NULL; if( amount < 0 || bill < 0 ) { bug( "%s: negative money (Billions)%d (Reset)%d.", __FUNCTION__, bill, amount ); amount = 1; } if( amount == 1 && bill == 0 ) { 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; } while( amount >= 1000000000 ) { amount -= 1000000000; bill++; } set_money( obj, bill, amount ); } return obj; }