/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "magic.h" #include "tables.h" #include "lookup.h" #include "olc.h" #include "const.h" #define MAX_ARMOR_SUFFIX 25 #define MAX_WEAPON_SUFFIX 15 #define MAX_PREFIX 18 CHAR_DATA *random_mob args( (void) ); void format_obj args( (OBJ_DATA *obj) ); void format_obj_weapon args( (OBJ_DATA *obj) ); void format_obj_armor args( (OBJ_DATA *obj) ); int wear_bit args( (int loc) ); void name_obj args( (CHAR_DATA *mob,OBJ_DATA *obj) ); char *weapon_type_name args( (OBJ_DATA *obj) ); char *armor_type_name args( (OBJ_DATA *obj) ); int which_location args( (void) ); void apply_good_affect args( (OBJ_DATA *obj,bool positive) ); DECLARE_DO_FUN(do_wear ); struct unique_attrib_table unique_table_armor_suffix[MAX_ARMOR_SUFFIX] = { { "" }, { "taste" }, { "protection" }, { "value" }, { "power" }, { "dark power" }, { "holiness" }, { "desecration" }, { "hope" }, { "hopelessness" }, { "care" }, { "invunlerability" }, { "Ferric" }, { "Dagda" }, { "Chele" }, { "Khain" }, { "Keogh" }, { "Svartalfar" }, { "Makaruda" }, { "Moirai" }, { "Diku" }, { "the fallen" }, { "the gods" }, { "the Shrike" }, { "mystery" }, }; struct unique_attrib_table unique_table_weapon_suffix[MAX_WEAPON_SUFFIX] = { { "" }, { "destruction" }, { "sharpness" }, { "power" }, { "maiming" }, { "killing" }, { "slaying" }, { "havok" }, { "crushing" }, { "cutting" }, { "fear" }, { "pillage" }, { "slashing"}, { "annoyance" }, { "striking" }, }; struct unique_attrib_table unique_table_prefix[MAX_PREFIX] = { { "" }, { "flashing" }, { "dull" }, { "well crafted" }, { "finely crafted" }, { "shiny" }, { "fine" }, { "fantastic" }, { "scuffed" }, { "brilliant" }, { "hewn" }, { "scratched" }, { "dark" }, { "intense" }, { "battered" }, { "polished" }, { "faded" }, { "enigmatic" }, }; void create_unique(void) { int x; int i; OBJ_DATA *obj; char buf[MSL]; CHAR_DATA *mob; if ( (obj = create_object( get_obj_index( OBJ_UNIQUE_DUMMY), 0) ) == NULL) { log_string( "Bug with OBJ_UNIQUE_DUMMY"); return; } free_string(obj->short_descr); free_string(obj->description); mob = random_mob(); if ( IS_SET( mob->in_room->area->area_flags , NO_UNIQUE ) ) return; SET_BIT(obj->wear_flags,ITEM_TAKE); obj->level = mob->level; format_obj(obj); name_obj(mob,obj); SET_BIT( obj->extra2_flags, ITEM_UNIQUE ); SET_BIT( obj->extra2_flags, ITEM_RELIC ); obj->xp_tolevel = MIN_XP; i = ( (mob->level-10)/10); if(i ==0) i++; for(x = 0; x < i; x++) apply_good_affect(obj,TRUE); if(mob->level > 20) { i = (mob->level - 20) / 10; if(i == 0) i++; for(x = 0; x < i; x++) apply_good_affect(obj,FALSE); } obj_to_char(obj,mob); do_wear(mob,obj->name); sprintf(buf,"The unique object, %s, loaded to %s in room %d\n\r", obj->short_descr,mob->name,mob->in_room->vnum); log_string( buf ); } void do_tally(CHAR_DATA *ch, char *argument) { OBJ_DATA *obj; int tally = 0; bool show = FALSE; if (!str_cmp(argument, "shadow" ) ) show = TRUE; for(obj = object_list; obj != NULL; obj = obj->next ) { CHAR_DATA *vch; if( (vch = obj->carried_by) == NULL) continue; if(!IS_NPC(vch)) continue; if(IS_SET(obj->extra2_flags,ITEM_UNIQUE) ) { tally++; if(show) printf_to_char(ch, "{D%d{r){W %s {r({DOn{r:{W %d{r)[{DIn{r:{W %d{r]{x\n\r", tally, obj->name, obj->carried_by && obj->carried_by->pIndexData ? obj->carried_by->pIndexData->vnum : 0, obj->carried_by ? obj->carried_by->in_room->vnum : 0 ); } } printf_to_char( ch, "{CTheir are currently %d unique items in the wilderness.{x\n\r", tally ); return; } int which_location() { int i; int location = 0; i = number_range(1,11); switch(i) { case 1: location = APPLY_STR; break; case 2: location = APPLY_DEX; break; case 3: location = APPLY_INT; break; case 4: location = APPLY_WIS; break; case 5: location = APPLY_CON; break; case 6: location = APPLY_MANA; break; case 7: location = APPLY_HIT; break; case 8: location = APPLY_MOVE; break; case 9: location = APPLY_HITROLL; break; case 10: location = APPLY_DAMROLL; break; case 11: location = APPLY_SAVES; break; } return location; } /*Lets apply some nice affects.*/ void apply_good_affect(OBJ_DATA *obj,bool positive) { int location; AFFECT_DATA *af; int mult; int value; int max,min; location = which_location(); switch(location) { default: mult = 10; break; case(APPLY_HIT): mult = 20; break; case(APPLY_MOVE): mult = 20; break; case(APPLY_MANA): mult = 20; break; } value = (1+(obj->level/10)) * mult; max = value*2; min = value/2; if(min == 0) min++; /*apply a negative affect*/ if(!positive) { value = value*-1; max = value/2; min = value*2; } af = new_affect(); af->location = location; af->modifier = number_range(min,max); af->where = 0; af->type = -1; af->duration = -1; af->bitvector = 0; af->level = obj->level; af->next = obj->affected; obj->affected = af; } /*the fido's armor of taste*/ void name_obj(CHAR_DATA *mob,OBJ_DATA *obj) { char buf[MSL]; char buf2[MSL]; char buf3[MSL]; int i = number_range(1,MAX_PREFIX-1); int x = number_range(1,MAX_WEAPON_SUFFIX-1); int y = number_range(1,MAX_ARMOR_SUFFIX-1); sprintf(buf,"the %s %s of %s", unique_table_prefix[i].descriptive, obj->item_type == ITEM_WEAPON ? weapon_type_name(obj) : armor_type_name(obj), obj->item_type == ITEM_WEAPON ? unique_table_weapon_suffix[x].descriptive : unique_table_armor_suffix[y].descriptive); sprintf(buf2,"%s is laying here on the ground.",buf); sprintf(buf3,"%s",buf); free_string(obj->name); free_string(obj->short_descr); free_string(obj->description); obj->name = str_dup(buf3); obj->short_descr = str_dup(buf); obj->description = str_dup(buf2); } void format_obj_weapon(OBJ_DATA *obj) { int i; int size,dice; double avg; /*What type of weapon?*/ i = number_range(0,8); obj->value[0] = i; /*Set it to wield*/ SET_BIT(obj->wear_flags,ITEM_WIELD); avg = obj->level; dice = (obj->level/10+1); size = dice/2; for (size=dice/2 ; dice * (size +2)/2 < avg ; size++ ) { } dice = UMAX(1, dice); size = UMAX(2, size); obj->value[1] = dice; obj->value[2] = size; /*End autodamage routine.*/ } char *weapon_type_name(OBJ_DATA *obj) { char *buf; buf = '\0'; switch(obj->value[0]) { case(WEAPON_EXOTIC) : buf = str_dup("exotic weapon"); break; case(WEAPON_SWORD): buf = str_dup("sword"); break; case(WEAPON_DAGGER): buf = str_dup("dagger"); break; case(WEAPON_SPEAR): buf = str_dup("spear"); break; case(WEAPON_MACE): buf = str_dup("mace"); break; case(WEAPON_AXE): buf = str_dup("axe"); break; case(WEAPON_FLAIL): buf = str_dup("flail"); break; case(WEAPON_WHIP): buf = str_dup("whip"); break; case(WEAPON_POLEARM): buf = str_dup("polearm"); break; } return buf; } char *armor_type_name(OBJ_DATA *obj) { int i; char *buf; buf = '\0'; switch(obj->wear_loc) { case 0: buf = str_dup("light"); break; case 1: case 2: buf = str_dup("ring"); break; case 3: case 4: i = number_range(1,3); if(i == 1) buf = str_dup("necklace"); else if(i == 2) buf = str_dup("pendant"); else buf = str_dup("neck guard"); break; case 5: i = number_range(1,3); if(i == 1) buf = str_dup("armor"); else if(i == 2) buf = str_dup("breastplate"); else buf = str_dup("chain mail"); break; case 6: i = number_range(1,3); if(i == 1) buf = str_dup("skullcap"); else if(i == 2) buf = str_dup("helmet"); else buf = str_dup("helm"); break; case 7: i = number_range(1,3); if(i == 1) buf = str_dup("leggings"); else if(i == 2) buf = str_dup("leg plates"); else buf = str_dup("pants"); break; case 8: i = number_range(1,3); if(i == 1) buf = str_dup("sandals"); else if(i == 2) buf = str_dup("boots"); else buf = str_dup("clogs"); break; case 9: i = number_range(1,3); if(i == 1) buf = str_dup("gloves"); else if(i == 2) buf = str_dup("gauntlets"); else buf = str_dup("sap gloves"); break; case 10: buf = str_dup("arm plates"); break; case 11: buf = str_dup("shield"); break; case 12: i = number_range(1,3); if(i == 1) buf = str_dup("cloak"); else if(i == 2) buf = str_dup("cape"); else buf = str_dup("coat"); break; case 13: i = number_range(1,3); if( i == 1) buf = str_dup("belt"); else if(i == 2) buf = str_dup("girdle"); else buf = str_dup("chain"); break; case 14: case 15: i = number_range(1,3); if( i == 1) buf = str_dup("bracelet"); else if(i == 2) buf = str_dup("wrist band"); else buf = str_dup("band"); break; } return buf; } void format_obj_armor(OBJ_DATA *obj) { /*Objects of ARMOR type can be ring, boots, shield, etc. Lets assign a random wear location to decide what this will be.*/ obj->wear_loc = number_range(0,15); /*Ok, we have a type now. Lets go through and set a wear bit.*/ switch(obj->wear_loc) { case 0: obj->item_type = ITEM_LIGHT; break; case 1: case 2: SET_BIT(obj->wear_flags,ITEM_WEAR_FINGER); break; case 3: case 4: SET_BIT(obj->wear_flags,ITEM_WEAR_NECK); break; case 5: SET_BIT(obj->wear_flags,ITEM_WEAR_BODY); break; case 6: SET_BIT(obj->wear_flags,ITEM_WEAR_HEAD); break; case 7: SET_BIT(obj->wear_flags,ITEM_WEAR_LEGS); break; case 8: SET_BIT(obj->wear_flags,ITEM_WEAR_FEET); break; case 9: SET_BIT(obj->wear_flags,ITEM_WEAR_HANDS); break; case 10: SET_BIT(obj->wear_flags,ITEM_WEAR_ARMS); break; case 11: SET_BIT(obj->wear_flags,ITEM_WEAR_SHIELD); break; case 12: SET_BIT(obj->wear_flags,ITEM_WEAR_ABOUT); break; case 13: SET_BIT(obj->wear_flags,ITEM_WEAR_WAIST); break; case 14: case 15: SET_BIT(obj->wear_flags,ITEM_WEAR_WRIST); break; } /*Ok, we've determined what type of armor it is, set appropriate wear.*/ /*Now, lets set it's armor values*/ obj->value[0] = number_range( (obj->level/2)-1 , (obj->level/2)+2); obj->value[1] = number_range( (obj->level/2)-1 , (obj->level/2)+2); obj->value[2] = number_range( (obj->level/2)-1 , (obj->level/2)+2); obj->value[3] = number_range( (obj->level/2)-1 , (obj->level/2)+2); } void format_obj(OBJ_DATA *obj) { int i; /* Weapon, Armor? */ i = number_range(0,1); switch(i) { case 0: obj->item_type = ITEM_WEAPON; format_obj_weapon(obj); break; case 1: obj->item_type = ITEM_ARMOR; format_obj_armor(obj); break; } } CHAR_DATA *random_mob() { CHAR_DATA *mob; CHAR_DATA *vch; CHAR_DATA *vch_next; char buf[MSL]; int i,x; mob = NULL; i = (number_range(1,top_mob_index)); x = 0; for(vch = char_list; vch != NULL; vch = vch_next) { vch_next = vch->next; if(!IS_NPC(vch) || (vch->pIndexData == NULL || vch->name == NULL || vch->short_descr == NULL || vch->in_room == NULL ) || vch->pIndexData->vnum < 100 || vch->in_room->clan > 0 || IS_SET( vch->act, ACT_TRAIN | ACT_PRACTICE | ACT_IS_HEALER | ACT_PET | ACT_GAIN | ACT_BOUNTY | ACT_MOUNT | ACT_FORGER | ACT_IS_CHANGER ) || IS_SET( vch->imm_flags, IMM_WEAPON | IMM_MAGIC ) || IS_SET( vch->affected_by, AFF_CHARM ) || IS_SET( vch->in_room->room_flags, ROOM_PET_SHOP) ) continue; x++; if ( i == 0 || x == 0 || vch == NULL ) { sprintf(buf,"RANDOM_MOB: Null mob, i is 0, or x is 0. I: %d, X: %d, Vch: %s", i, x, vch->name ); log_string(buf); } if(x == i) mob = vch; if(x >= top_mob_index) break; } return mob; }