/**************************************************************************** * [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 <math.h> #include "mud.h" extern int top_affect; int affectLocation1 = 0; int affectLocation2 = 0; #define MAX_ARMOR_TYPE 8 /* Armor types for Armor Generator */ struct armorgenT { int type; /* Armor type */ char *name; /* Descriptive name */ int weight; /* Base weight */ double armorMod; /* armor */ int cost; /* Base value or cost */ int mlevel; /* Minimun mob level before this item will drop */ }; const struct armorgenT armor_type[] = { /* Type, Name, Base Weight, Armor Mod, Base Cost, Min Rank */ { 0, "Not Defined", 0, 0, 0, 0}, { 1, "Padded", 2, 0.70, 500, 0}, { 2, "Leather", 3, 0.80, 1000, 2}, { 3, "Riot", 8, 0.90, 2500, 3}, { 4, "Combat", 9, 1.00, 5000, 4}, { 5, "Battle", 7, 1.05, 10000, 5}, { 6, "Assault", 7, 1.10, 25000, 6}, { 7, "Ancient", 10, 1.15, 50000, 7}, { 8, "Dark Wave", 20, 1.25, 100000, 8} }; const double armor_mods[8]= { 0.35, // Body Armor 0.25, // Shields 0.20, // Sleeves 0.20, // Leggings 0.20, // Helmets 0.15, // Gloves 0.15, // Boots 0.10 // Belts }; const char *armor_wearLoc[8]= { "Armor", "Shield", "Sleeves", "Leggings", "Helmet", "Gauntlets", "Boots", "Belt" }; const char *magic_prefix[8]= { "", "Mighty ", "Fast ", "Wise ", "Sturdy ", "Fortune ", "Glorious ", "Brilliant " }; const char *magic_suffix[8]= { "", " of Strength", " of Speed", " of Mind", " of Fortitude", " of Chance", " of Perfection", " of Energy" }; struct magicA { int location; /* Apply type */ double mod; /* How much to affect user (mod*level) or sn lookup */ int mlevel; /* Minimun mob level before this item will drop */ int bitvector; /* Affect placed on user */ int maxmod; /* The max value of mod*level. 0 = unlimited */ bool larmor; /* Will the affect load on Body Armor */ bool lshield; /* Will the affect load on Shields */ bool lsleeve; /* Will the affect load on Sleeves */ bool llegging; /* Will the affect load on Leggings */ bool lhelmet; /* Will the affect load on Helmets */ bool lglove; /* Will the affect load on Gloves */ bool lboot; /* Will the affect load on Boots */ bool lbelt; /* Will the affect load on Belts */ bool lring; /* Will the affect load on Rings */ bool lamulet; /* Will the affect load on Amulets */ char *prefix; char *suffix; }; const struct magicA item_affect[] = { /* Location, Mod, Min Level, Affect Flag, Max Mod, * Load on: Body Armor, Shields, Sleeves, Leggings, Helmets, * Gloves, Boots, Belts, Rings, Amulets * Prefix, Suffix */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "" }, { APPLY_STR, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Mighty ", "of Strength" }, { APPLY_DEX, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Fast ", "of Speed" }, { APPLY_INT, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Wise ", "of Mind" }, { APPLY_CON, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Sturdy ", "of Fortitude" }, { APPLY_LCK, 0.25, 4, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Fortune ", "of Chance" }, { APPLY_ALLSTATS, 0.25, 4, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Glorious ", "of Perfection" }, { APPLY_MANA, 10, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Brilliant ", "of Energy"} }; int get_total_armor( long double level ) { long double chklvl = 0; int zeros = 0; int i; int armorBase = 0; int prevArmor = 0; int armor = 0; double ratio = 0.00; for(i=0; i < 100; i++) // i'm "cheeping" out and caping this at 1 googol -Goku 10.05.04 { if( level / pow( 10, i ) < 10 ) { break; } } chklvl = pow(10,i); zeros = i; switch (zeros) { case 0: // 10 case 1: // 10 armorBase = 10; prevArmor = 1; break; case 2: // 100 armorBase = 100; prevArmor = 10; break; case 3: // 1000 armorBase = 500; prevArmor = 100; break; case 4: // 10k armorBase = 1000; prevArmor = 500; break; case 5: // 100k armorBase = 2000; prevArmor = 1000; break; default: armorBase = 2000 + ((zeros - 5) * 1000); prevArmor = 1000 + ((zeros - 5) * 1000); break; } ratio = level/chklvl; armor = prevArmor + ((armorBase - prevArmor) * ratio); armor = armor * (double)number_range(500, 1200)/1000; return armor; } int get_rank_by_pl( long double level ) { if (level < 5000) return 1; else if (level < 100000) return 2; else if (level < 1000000) return 3; else if (level < 10000000) return 4; else if (level < 100000000) return 5; else if (level < 1000000000) return 6; else if (level < 10000000000ULL) return 7; else if (level < 50000000000ULL) return 8; else if (level < 100000000000ULL) return 9; else if (level < 300000000000ULL) return 10; else if (level < 600000000000ULL) return 11; else if (level < 1000000000000ULL) return 12; else if (level < 10000000000000ULL) return 13; else if (level < 50000000000000ULL) return 14; else if (level < 100000000000000ULL) return 15; else return 16; return 0; } int calc_zeni( long double level, CHAR_DATA *killer ) { long double chklvl = 0; int zeros = 0; int i; int zeniBase = 0; int prevZeni = 0; int zeni = 0; double ratio = 0.00; long double chklvl2 = 0; for(i=0; i < 100; i++) // i'm "cheeping" out and caping this at 1 googol -Goku 10.05.04 { if( level / pow( 10, i ) < 10 ) { break; } } chklvl = pow(10,i); chklvl2 = pow(10,i-1); /* double zero count to smooth out increase -Goku 10.05.04 */ if (level < chklvl - chklvl2 + chklvl2) zeros = i*2-1; else zeros = i*2; switch (zeros) { case 0: // 0 case 1: // 1 zeniBase = 1; prevZeni = 1; break; case 2: // 5 zeniBase = 5; prevZeni = 1; break; case 3: // 10 zeniBase = 10; prevZeni = 5; break; case 4: // 50 zeniBase = 20; prevZeni = 10; break; case 5: // 100 case 6: // 500 zeniBase = 30; prevZeni = 20; break; case 7: // 1000 case 8: // 5000 zeniBase = 40; prevZeni = 30; break; case 9: // 10k zeniBase = 60; prevZeni = 40; break; case 10: // 50k zeniBase = 90; prevZeni = 60; break; case 11: // 100k zeniBase = 150; prevZeni = 90; break; case 12: // 500k zeniBase = 170; prevZeni = 150; break; case 13: // 1m zeniBase = 200; prevZeni = 170; break; case 14: // 5m zeniBase = 300; prevZeni = 200; break; case 15: // 10m zeniBase = 400; prevZeni = 300; break; default: zeniBase = 500 + ((zeros - 15) * 100); prevZeni = 400 + ((zeros - 15) * 100); break; } ratio = level/chklvl; zeni = prevZeni + ((zeniBase - prevZeni) * ratio); zeni = (dice(get_rank_by_pl(level), zeni) + (dice(get_rank_by_pl(level), zeni) / 10 + dice(get_curr_lck(killer), zeni / 3) ) ); return zeni/4; } void magicAffectGen( OBJ_DATA *obj, int affects, int armorType ) { int i; int affect = 0; int type; bool armor = FALSE; AFFECT_DATA *paf; int justincase = 0; if (obj->item_type == ITEM_ARMOR) { type = obj->value[3]; armor = TRUE; } else return; xSET_BIT(obj->extra_flags, ITEM_MAGIC); for (i = 0; i < affects; i++) { justincase++; if (justincase > 1000) break; affect = number_range( 1, 7 ); if (item_affect[affect].mlevel > get_rank_by_pl(obj->level)) { i = UMIN(0, i-1); /* Going back in time! */ continue; } switch (armorType) { case 0: if (!item_affect[affect].larmor) { i = UMIN(0, i-1); /* Going back in time! */ continue; } case 1: if (!item_affect[affect].lshield) { i = UMIN(0, i-1); /* Going back in time! */ continue; } case 2: if (!item_affect[affect].lsleeve) { i = UMIN(0, i-1); /* Going back in time! */ continue; } case 3: if (!item_affect[affect].llegging) { i = UMIN(0, i-1); /* Going back in time! */ continue; } case 4: if (!item_affect[affect].lhelmet) { i = UMIN(0, i-1); /* Going back in time! */ continue; } case 5: if (!item_affect[affect].lglove) { i = UMIN(0, i-1); /* Going back in time! */ continue; } case 6: if (!item_affect[affect].lboot) { i = UMIN(0, i-1); /* Going back in time! */ continue; } case 7: if (!item_affect[affect].lbelt) { i = UMIN(0, i-1); /* Going back in time! */ continue; } default: break; } if (!affectLocation1) affectLocation1 = affect; else if (!affectLocation2) affectLocation2 = affect; CREATE( paf, AFFECT_DATA, 1 ); paf->type = -1; paf->duration = -1; paf->location = item_affect[affect].location; if (item_affect[affect].maxmod > 0) paf->modifier = number_range(1,(int) UMAX(item_affect[affect].mod * (get_rank_by_pl(obj->level) - item_affect[affect].mlevel), item_affect[affect].maxmod)); else paf->modifier = number_range(1,(int) (item_affect[affect].mod * (get_rank_by_pl(obj->level) - item_affect[affect].mlevel))); xCLEAR_BITS( paf->bitvector ); if (item_affect[affect].bitvector) xSET_BIT( paf->bitvector, item_affect[affect].bitvector ); LINK( paf, obj->first_affect, obj->last_affect, next, prev ); ++top_affect; } } void finalize_cost( OBJ_DATA *obj ) { AFFECT_DATA *iaf; int mod = 0; for( iaf = obj->first_affect; iaf; iaf = iaf->next ) { if (!iaf) break; if (iaf->location == APPLY_STR || iaf->location == APPLY_DEX || iaf->location == APPLY_INT || iaf->location == APPLY_CON) mod += iaf->modifier * 2500; else if (iaf->location == APPLY_LCK) mod += iaf->modifier * 5000; else if (iaf->location == APPLY_ALLSTATS) mod += iaf->modifier * 10000; else if (iaf->location == APPLY_MANA) mod += iaf->modifier * 500; } mod += obj->value[5] * 50; obj->cost += mod; return; } OBJ_DATA *generate_item( long double pl, long double killerpl ) { OBJ_DATA *newitem = NULL; int wearLoc; int armor; int armorType; int x; char buf[MAX_STRING_LENGTH]; long double max = 0; long double min = 0; if( killerpl > pl ) { max = killerpl; min = pl; } else { max = pl; min = killerpl; } affectLocation1 = 0; affectLocation2 = 0; if( !( newitem = create_object( get_obj_index( OBJ_VNUM_TREASURE ), pl ) ) ) { bug( "create_object: %s:%s, line %d.", __FILE__, __FUNCTION__, __LINE__ ); return NULL; } /* Hey look, if it takes more than 50000 iterations to find something.... */ for( x = 0; x < 50000; x++ ) { armorType = number_range(1,MAX_ARMOR_TYPE); if (armor_type[armorType].mlevel <= get_rank_by_pl(pl)) break; } newitem->weight = armor_type[armorType].weight; armor = get_total_armor(pl); newitem->cost = armor_type[armorType].cost; // newitem->level = pl; // newitem->level = number_range( min, max ); newitem->level = min + ( ( min + max ) / 3 ); if( number_range( 1, 5 ) == 5 ) newitem->level -= ( min + max ) / 5; if( number_range( 1, 75 ) == 23 ) newitem->level -= ( max - min ) / 3; if( number_range( 1, 300 ) == 59 ) newitem->level = min; newitem->level = UMIN( newitem->level, killerpl * 2 ); wearLoc = number_range(0,7); newitem->value[4] = newitem->value[5] = armor * armor_type[armorType].armorMod * armor_mods[wearLoc]; switch (wearLoc) { default: bug("Invalid armor wear location generated"); case 0: SET_BIT( newitem->wear_flags, ITEM_WEAR_BODY ); break; case 1: SET_BIT( newitem->wear_flags, ITEM_WEAR_SHIELD ); break; case 2: SET_BIT( newitem->wear_flags, ITEM_WEAR_ARMS ); break; case 3: SET_BIT( newitem->wear_flags, ITEM_WEAR_LEGS ); break; case 4: SET_BIT( newitem->wear_flags, ITEM_WEAR_HEAD ); break; case 5: SET_BIT( newitem->wear_flags, ITEM_WEAR_HANDS ); break; case 6: SET_BIT( newitem->wear_flags, ITEM_WEAR_FEET ); break; case 7: SET_BIT( newitem->wear_flags, ITEM_WEAR_WAIST ); break; } if (number_range(1,4) == 4) // 75% chance to get a magic item magicAffectGen(newitem, number_range(1,2), wearLoc); finalize_cost(newitem); sprintf(buf, "%s%s %s%s", magic_prefix[affectLocation1], armor_type[armorType].name, armor_wearLoc[wearLoc], magic_suffix[affectLocation2]); STRFREE( newitem->name ); newitem->name = STRALLOC( buf ); sprintf(buf, "%s%s %s%s", magic_prefix[affectLocation1],armor_type[armorType].name, armor_wearLoc[wearLoc], magic_suffix[affectLocation2]); STRFREE( newitem->short_descr ); newitem->short_descr = STRALLOC( buf ); sprintf(buf, "A %s%s %s%s lies here in a heap.", magic_prefix[affectLocation1],armor_type[armorType].name, armor_wearLoc[wearLoc], magic_suffix[affectLocation2]); STRFREE( newitem->description ); newitem->description = STRALLOC( buf ); affectLocation1 = 0; affectLocation2 = 0; return (newitem); } void generate_treasure( CHAR_DATA *killer, CHAR_DATA *ch, OBJ_DATA *corpse ) { int tchance; int zeni; char buf[MAX_STRING_LENGTH]; char originText[MAX_STRING_LENGTH]; /* Rolling for the initial check to see if we should be generating anything at all */ tchance = number_range( 1, 100 ); if (tchance <= 30) { return; } else if (tchance <= 80) { zeni = calc_zeni(ch->exp, killer); if (zeni < 1) { bug("RTG Made less than 1 zeni: PC(%s) Mob(%d) Room(%d) Zeni(%d)", killer->name, ch->pIndexData->vnum, ch->in_room->vnum, zeni); return; } if ( ch->in_room ) { ch->in_room->area->gold_looted += zeni; sysdata.global_looted += zeni/100; } if (economy_has(ch->in_room->area, zeni)) { lower_economy(ch->in_room->area, zeni); obj_to_obj( create_money( zeni ), corpse ); } return; } else { if( killer->pl / ch->pl > 7 ) return; // make items yo OBJ_DATA *item = generate_item( ch->exp, killer->exp ); if( !item ) { bug( "%s", "generate_treasure: Item object failed to create!" ); return; } sprintf(buf, "killer:%sMob%d",killer->name, ch->pIndexData->vnum); sprintf(originText, "%d, %s", ORIGIN_RTG, buf); STRFREE( item->origin ); item->origin = STRALLOC( originText ); obj_to_obj( item, corpse ); return; } } /* * 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; } /* * 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; 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 ); } OBJ_DATA *make_deathCertificate( CHAR_DATA *ch, CHAR_DATA *killer ) { char buf[MAX_STRING_LENGTH]; OBJ_DATA *dc; EXTRA_DESCR_DATA *ed; dc = create_object(get_obj_index(610),1); sprintf( buf, "%s death certificate", ch->name ); STRFREE( dc->name ); dc->name = STRALLOC( buf ); sprintf( buf, "%s's death certificate", ch->name ); STRFREE( dc->short_descr ); dc->short_descr = STRALLOC( buf ); ed = SetOExtra(dc, dc->name); sprintf( buf, "Certificate of Death\n\r" "--------------------\n\r" "Name: &W%s&w\n\r" "Rank: &W%s&w\n\r" "Sex : &W%s&w Race: &W%s&w\n\r" "Cause of Death: &WHomicide&w\n\r" "Time of Death : &W%s&w\r" "Area of the Crime : &W%s&w\n\r" "Scene of the Crime: &W%s&w\n\r" "Suspect Information\n\r" "-------------------\n\r" "Name: &W%s&w\n\r" "Rank: &W%s&w\n\r" "Sex : &W%s&w Race: &W%s&w\n\r" "Reason for Involvement:\n\r" " &W'Possible' Self Defense&w\n\r", ch->name, get_rank(ch), ch->sex == SEX_MALE ? "Male" : ch->sex == SEX_FEMALE ? "Female" : "Neutral", capitalize(get_race(ch)), ctime(¤t_time), killer->in_room->area->name, killer->in_room->name, killer->name, get_rank(killer), killer->sex == SEX_MALE ? "Male" : killer->sex == SEX_FEMALE ? "Female" : "Neutral", capitalize(get_race(killer)) ); STRFREE( ed->description ); ed->description = STRALLOC( buf ); return dc; } /* * Goku's global drop code. Checks if a mob will drop any of * the items defined when it's killed. -Goku 07.28.04 */ #define GLOBAL_DROP_OBJ_TOKEN 613 void global_drop_check( OBJ_DATA *corpse, CHAR_DATA *ch, CHAR_DATA *killer ) { int luckMod; luckMod = get_curr_lck(killer); /* if luck is lower than 0, no drops */ if (luckMod < 1) return; if (number_range(luckMod, 10000) <= 1) { obj_to_obj( create_object(get_obj_index(GLOBAL_DROP_OBJ_TOKEN), 0), corpse); } return; } #undef GLOBAL_DROP_OBJ_TOKEN /* * 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 ( !ch ) { if (!killer) bug( "make_corpse: NULL TARGET and NULL KILLER", 0 ); else bug( "make_corpse: NULL TARGET, %s is the KILLER", killer->name, 0 ); return; } if ( !killer ) { if (!ch) bug( "make_corpse: NULL KILLER and NULL TARGET", 0 ); else bug( "make_corpse: NULL KILLER, %s as TARGET", ch->name, 0 ); 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; sysdata.global_looted += ch->gold/100; } obj_to_obj( create_money( ch->gold ), corpse ); ch->gold = 0; } else if (ch->gold < 0 && !IS_NPC( killer )) generate_treasure( killer, ch, corpse); /* 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 = 30; else corpse->timer = 15; 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) ) 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; if (!IS_NPC(ch) && obj->wear_loc != -1) continue; obj_from_char( obj ); if( obj->item_type == ITEM_DRAGONBALL ) { obj_to_room(obj,ch->in_room); continue; } if ( (!IS_NPC(ch) && IS_OBJ_STAT( obj, ITEM_INVENTORY )) || IS_OBJ_STAT( obj, ITEM_DEATHROT ) ) extract_obj( obj ); else obj_to_obj( obj, corpse ); } /* global drop? -Goku 07.28.04 */ if (!IS_NPC(killer) && IS_NPC(ch) && !xIS_SET(ch->affected_by, AFF_NO_GLOBAL_DROP) && killer->pl/ch->exp <= 5 ) global_drop_check(corpse, ch, killer); /* disabled untill a more efficant way to make these things can be implimented -Goku if (!IS_NPC(ch) && !IS_NPC(killer)) { act( AT_SOCIAL, "The Coroner materializes before the corpse of $N.", killer, NULL, ch, TO_CHAR ); act( AT_SAY, "The Coroner says 'Yep, $E's dead.'", killer, NULL, ch, TO_CHAR ); act( AT_SOCIAL, "The Coroner stamps a sheet of paper and places it on the corpse.", killer, NULL, ch, TO_CHAR ); act( AT_SAY, "The Coroner says 'I'll just leave this for the police to take care of.'", killer, NULL, ch, TO_CHAR ); act( AT_SOCIAL, "The Coroner materializes before the corpse of $N.", killer, NULL, ch, TO_NOTVICT ); act( AT_SAY, "The Coroner says 'Yep, $E's dead.'", killer, NULL, ch, TO_NOTVICT ); act( AT_SOCIAL, "The Coroner stamps a sheet of paper and places it on the corpse.", killer, NULL, ch, TO_NOTVICT ); act( AT_SAY, "The Coroner says 'I'll just leave this for the police to take care of.'", killer, NULL, ch, TO_NOTVICT ); obj_to_obj( make_deathCertificate(ch, killer), corpse ); } */ if (spaceDeath) obj_to_room( corpse, get_room_index(ROOM_CORPSE_DROPOFF) ); else obj_to_room( corpse, ch->in_room ); spaceDeath = FALSE; 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; }