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