/* * This will generate a random item (5% container, 35% weapon / 65% armor) with randomized stats based on mob level. * The item will be give a quality name based on the total stats it has, and further named based on slot * and the highest stat on it. You can adjust how much level affects the stat bonuses by looking at a few * of the loops used. There is also a modifier you can adjust based on mob flags or other criteria (I used * elite and boss mobs). This should plug straight into probably any Dystopia with very minor modification, * and was developed on Dystopia X-Mas Edition. * * Add the following to fight.c in hurt_person() directly above the call to raw_kill(victim). * if( IS_NPC(victim) ) mob_rand_drop(victim,victim->level); * * In your object_data struct (mud.h, merc.h, or similar) add the following: * bool has_aff; * * In your create_object() function make sure to initialize has_aff to FALSE, just to be safe. * * Also in your primary header (mud.h, merc.h, or similar) add the following: * enum { QUALITY_NONE, QUALITY_POOR, QUALITY_COMMON, QUALITY_UNCOMMON, QUALITY_SUPERIOR, QUALITY_EPIC, QUALITY_LEGENDARY }; * * If you want object quality to display like an item flag, add the folowing to the top of format_obj_to_char(), * directly after the buffer declaration and clearing. * switch( obj->quality ) * { * case QUALITY_NONE: break; * case QUALITY_POOR: strcat(buf, "#9(#0Poor#9)#n "); break; * case QUALITY_COMMON: strcat(buf, "#9(#7Common#9)#n "); break; * case QUALITY_UNCOMMON: strcat(buf, "#9(#GUncommon#9)#n "); break; * case QUALITY_SUPERIOR: strcat(buf, "#9(#LSuperior#9)#n "); break; * case QUALITY_EPIC: strcat(buf, "#9(#PEpic#9)#n "); break; * case QUALITY_LEGENDARY: strcat(buf, "#9(#RLegendary#9)#n "); break; * } * * Feel free to modify this code to suit your needs, and if you have a great improvement I wouldn't mind if you * shared it with me either, if you're so inclined :D. All I ask is to give me credit for the code if you do * choose to use it. * * Updated to add random spell affects to items, too, and fixed a few minor bugs. * One more fix to how spell affects save, after I realized how bastardized GodWars handles them. * * --Kline (Matt Goff) */ #define MAX_AFFECT_NAME 12 char *const affect_name[] = { "#9Invisibility#n", "#0Detect #9Invisibility#n", "#9Detect Hidden#n", "#LSanctuary#n", "#rNight Sight#n", "#gProtection #nfrom #REvil#n", "#oSneak#n", "#lFlying#n", "#pPass Door#n", "#gProtection #nfrom #CGood#n" }; #define MAX_WEAPON_NAME 13 char *const weapon_name[] = { "", "Slicer", "Spear", "Blade", "Whip", "Claw", "Blaster", "Hammer", "Mace", "Grepper", "Biter", "Dagger", "Sucker" }; #define MAX_QUALITY_NAME 6 char *const quality_name[] = { " Poor", " Common", " Uncommon", " Superior", " Epic", " Legendary" }; #define MAX_CONTAINER_NAME 5 char *const container_name[] = { "Bag", "Satchel", "Sack", "Pouch", "Backpack" }; #define MAX_FINGER_NAME 1 char *const finger_name[] = { "Ring" }; #define MAX_NECK_NAME 4 char *const neck_name[] = { "Necklace", "Amulet", "Choker", "Gorget" }; #define MAX_BODY_NAME 4 char *const body_name[] = { "Chest Guard", "Breastplate", "Robe", "Dress" }; #define MAX_HEAD_NAME 5 char *const head_name[] = { "Helmet", "Skullcap", "Hat", "Hood", "Cowl" }; #define MAX_LEGS_NAME 5 char *const legs_name[] = { "Leggings", "Leg Guards", "Pants", "Skirt", "Stockings" }; #define MAX_FEET_NAME 4 char *const feet_name[] = { "Boots", "Shoes", "Sandals", "Slippers" }; #define MAX_HANDS_NAME 4 char *const hands_name[] = { "Gloves", "Gauntlets", "Knuckles", "Mittens" }; #define MAX_ARMS_NAME 2 char *const arms_name[] = { "Arm Guards", "Sleeves" }; #define MAX_SHIELD_NAME 5 char *const shield_name[] = { "Buckler", "Tower Shield", "Shield", "Round Shield", "Skull Shield" }; #define MAX_ABOUT_NAME 3 char *const about_name[] = { "Cloak", "Cape", "Shawl" }; #define MAX_WAIST_NAME 3 char *const waist_name[] = { "Belt", "Cord", "Waistband" }; #define MAX_WRIST_NAME 3 char *const wrist_name[] = { "Bracer", "Wrist Guard", "Bracelet" }; #define MAX_FACE_NAME 6 char *const face_name[] = { "Mask", "Face Guard", "Goggles", "Glasses", "Visor", "Monacle" }; #define MAX_SPECIAL_NAME 4 char *const special_name[] = { "Sigil", "Charm", "Rune", "Emblem" }; #define MAX_BODYART_NAME 3 char *const bodyart_name[] = { "Tattoo", "Drawing", "Sketch" }; #define MAX_MEDAL_NAME 2 char *const medal_name[] = { "Medal", "Commendation" }; #define MAX_FLOAT_NAME 4 char *const float_name[] = { "Gem", "Spirit", "Orb", "Sprite" }; void mob_rand_drop( CHAR_DATA *mob, int level ) { char output[MSL], slot[MSL], best_stat[MSL], quality[MSL], aff_name[MSL]; OBJ_DATA *obj; AFFECT_DATA *paf; float mod = 1.0; int value = 0, affect = 0, i = 0, num_aff = 0, seed = 0, chance = 0, bitvector = 0; int add_str = 0, add_dex = 0, add_int = 0, add_wis = 0, add_con = 0, add_mana = 0, add_hit = 0, add_move = 0, add_ac = 0, add_hr = 0, add_dr = 0, add_save = 0, add_best = 0, add_tot = 0; output[0] = '\0'; slot[0] = '\0'; best_stat[0] = '\0'; quality[0] = '\0'; aff_name[0] = '\0'; seed = number_percent(); chance = 5; if( IS_SET(mob->act,ACT_ELITE) ) chance += 25; if( IS_SET(mob->act,ACT_BOSS) ) chance += 100; if( number_percent() >= chance ) return; if( IS_SET(mob->act,ACT_ELITE) ) { mod += 0.10; num_aff -= 1; } if( IS_SET(mob->act,ACT_BOSS) ) { mod += 0.20; num_aff -= 2; } obj = create_object(get_obj_index(OBJ_VNUM_PROTOPLASM),0); obj->weight = number_range((level * 0.02),(level * 0.04)); SET_BIT(obj->wear_flags,ITEM_TAKE); if( seed <= 5 ) obj->item_type = ITEM_CONTAINER; else if( seed > 5 && seed <= 40 ) obj->item_type = ITEM_WEAPON; else obj->item_type = ITEM_ARMOR; if( obj->item_type == ITEM_CONTAINER ) { obj->value[0] = (number_range((level * 0.10),(level * 0.20)) * 5); obj->value[0] *= mod; add_tot = obj->value[0]; sprintf(slot,"%s",container_name[number_range(0,MAX_CONTAINER_NAME-1)]); } else if( obj->item_type == ITEM_WEAPON ) { SET_BIT(obj->wear_flags,ITEM_WIELD); obj->value[1] = number_range((level * 0.06),(level * 0.08)); if( obj->value[1] < 1 ) obj->value[1] = 1; obj->value[1] *= mod; obj->value[2] = number_range((level * 0.08),(level * 0.12)); if( obj->value[2] < 1 ) obj->value[2] = 1; obj->value[2] *= mod; obj->value[3] = number_range(1,12); sprintf(slot,"%s",weapon_name[obj->value[3]]); } else { switch( number_range(1,21) ) { default: extract_obj(obj); return; case 1: SET_BIT(obj->wear_flags,ITEM_WEAR_FINGER); sprintf(slot,"%s",finger_name[number_range(0,MAX_FINGER_NAME-1)]); break; case 2: SET_BIT(obj->wear_flags,ITEM_WEAR_FINGER); sprintf(slot,"%s",finger_name[number_range(0,MAX_FINGER_NAME-1)]); break; case 3: SET_BIT(obj->wear_flags,ITEM_WEAR_NECK); sprintf(slot,"%s",neck_name[number_range(0,MAX_NECK_NAME-1)]); break; case 4: SET_BIT(obj->wear_flags,ITEM_WEAR_NECK); sprintf(slot,"%s",neck_name[number_range(0,MAX_NECK_NAME-1)]); break; case 5: SET_BIT(obj->wear_flags,ITEM_WEAR_BODY); sprintf(slot,"%s",body_name[number_range(0,MAX_BODY_NAME-1)]); break; case 6: SET_BIT(obj->wear_flags,ITEM_WEAR_HEAD); sprintf(slot,"%s",head_name[number_range(0,MAX_HEAD_NAME-1)]); break; case 7: SET_BIT(obj->wear_flags,ITEM_WEAR_LEGS); sprintf(slot,"%s",legs_name[number_range(0,MAX_LEGS_NAME-1)]); break; case 8: SET_BIT(obj->wear_flags,ITEM_WEAR_FEET); sprintf(slot,"%s",feet_name[number_range(0,MAX_FEET_NAME-1)]); break; case 9: SET_BIT(obj->wear_flags,ITEM_WEAR_HANDS); sprintf(slot,"%s",hands_name[number_range(0,MAX_HANDS_NAME-1)]); break; case 10: SET_BIT(obj->wear_flags,ITEM_WEAR_ARMS); sprintf(slot,"%s",arms_name[number_range(0,MAX_ARMS_NAME-1)]); break; case 11: SET_BIT(obj->wear_flags,ITEM_WEAR_SHIELD); sprintf(slot,"%s",shield_name[number_range(0,MAX_SHIELD_NAME-1)]); break; case 12: SET_BIT(obj->wear_flags,ITEM_WEAR_ABOUT); sprintf(slot,"%s",about_name[number_range(0,MAX_ABOUT_NAME-1)]); break; case 13: SET_BIT(obj->wear_flags,ITEM_WEAR_WAIST); sprintf(slot,"%s",waist_name[number_range(0,MAX_WAIST_NAME-1)]); break; case 14: SET_BIT(obj->wear_flags,ITEM_WEAR_WRIST); sprintf(slot,"%s",wrist_name[number_range(0,MAX_WRIST_NAME-1)]); break; case 15: SET_BIT(obj->wear_flags,ITEM_WEAR_WRIST); sprintf(slot,"%s",wrist_name[number_range(0,MAX_WRIST_NAME-1)]); break; case 16: SET_BIT(obj->wear_flags,ITEM_WEAR_FACE); sprintf(slot,"%s",face_name[number_range(0,MAX_FACE_NAME-1)]); break; case 17: SET_BIT(obj->wear_flags,ITEM_WEAR_SPECIAL); sprintf(slot,"%s",special_name[number_range(0,MAX_SPECIAL_NAME-1)]); break; case 19: SET_BIT(obj->wear_flags,ITEM_WEAR_BODYART); sprintf(slot,"%s",bodyart_name[number_range(0,MAX_BODYART_NAME-1)]); break; case 20: SET_BIT(obj->wear_flags,ITEM_WEAR_MEDAL); sprintf(slot,"%s",medal_name[number_range(0,MAX_MEDAL_NAME-1)]); break; case 21: SET_BIT(obj->wear_flags,ITEM_WEAR_FLOAT); sprintf(slot,"%s",float_name[number_range(0,MAX_FLOAT_NAME-1)]); break; } obj->value[0] = number_range((level * 0.13),(level * 0.23)); if( obj->value[0] < 1 ) obj->value[0] = 1; obj->value[0] *= mod; } if( obj->item_type != ITEM_CONTAINER ) { for( i = 0; i < 6; i++ ) { if( number_percent() >= (num_aff * 10) ) { num_aff++; value = number_range((level * 0.08),(level * 0.13)); if( value < 1 ) value = 1; value *= mod; add_tot += value; switch( number_range(1,12) ) { default: extract_obj(obj); return; //Number_range seems to return out of range at random; handle it. case 1: add_str += value; break; case 2: add_dex += value; break; case 3: add_int += value; break; case 4: add_wis += value; break; case 5: add_con += value; break; case 6: add_mana += value; break; case 7: add_hit += value; break; case 8: add_move += value; break; case 9: add_ac += (value * -1); break; case 10: add_hr += value; break; case 11: add_dr += value; break; case 12: add_save += (value * -1); break; } } } for( i = 0; i < 12; i++ ) { affect = APPLY_NONE; switch( i ) { case 1: if( add_str > 0 ) { affect = APPLY_STR; value = add_str; add_best = add_str; sprintf(best_stat,"#oStrength#n"); } break; case 2: if( add_dex > 0 ) { affect = APPLY_DEX; value = add_dex; if( add_dex > add_best ) { add_best = add_dex; sprintf(best_stat,"#gDexterity#n"); } } break; case 3: if( add_int > 0 ) { affect = APPLY_INT; value = add_int; if( add_int > add_best ) { add_best = add_int; sprintf(best_stat,"#cIntellect#n"); } } break; case 4: if( add_wis > 0 ) { affect = APPLY_WIS; value = add_wis; if( add_wis > add_best ) { add_best = add_wis; sprintf(best_stat,"#lWisdom#n"); } } break; case 5: if( add_con > 0 ) { affect = APPLY_CON; value = add_con; if( add_con > add_best ) { add_best = add_con; sprintf(best_stat,"#rConstitution#n"); } } break; case 6: if( add_mana > 0 ) { affect = APPLY_MANA; value = add_mana; if( add_mana > add_best ) { add_best = add_mana; sprintf(best_stat,"#CMana#n"); } } break; case 7: if( add_hit > 0 ) { affect = APPLY_HIT; value = add_hit; if( add_hit > add_best ) { add_best = add_hit; sprintf(best_stat,"#RHealth#n"); } } break; case 8: if( add_move > 0 ) { affect = APPLY_MOVE; value = add_move; if( add_move > add_best ) { add_best = add_move; sprintf(best_stat,"#GMovement#n"); } } break; case 9: if( add_ac < 0 ) { affect = APPLY_AC; value = add_ac; if( (add_ac * -1) > add_best ) { add_best = (add_ac * -1); sprintf(best_stat,"#yProtection#n"); } } break; case 10: if( add_hr > 0 ) { affect = APPLY_HITROLL; value = add_hr; if( add_hr > add_best ) { add_best = add_hr; sprintf(best_stat,"#9Striking#n"); } } break; case 11: if( add_dr > 0 ) { affect = APPLY_DAMROLL; value = add_dr; if( add_dr > add_best ) { add_best = add_dr; sprintf(best_stat,"#0Damage#n"); } } break; case 12: if( add_save < 0 ) { affect = APPLY_SAVING_SPELL; value = add_save; if( (add_save * -1) > add_best ) { add_best = (add_save * -1); sprintf(best_stat,"#PResistance#n"); } } break; } if( affect ) { if( affect_free == NULL ) paf = alloc_perm(sizeof(*paf)); else { paf = affect_free; affect_free = affect_free->next; } if( obj->item_type == ITEM_ARMOR && number_percent() <= 10 && !obj->has_aff ) { seed = number_range(1,10); switch( seed ) { case 1: bitvector = 5; break; /* Invisible */ case 2: bitvector = 2; break; /* Detect Invis */ case 3: bitvector = 10; break; /* Detect Hidden */ case 4: bitvector = 9; break; /* Sanctuary */ case 5: bitvector = 4; break; /* Infrared */ case 6: bitvector = 7; break; /* Protection vs Evil */ case 7: bitvector = 11; break; /* Sneak */ case 8: bitvector = 3; break; /* Flying */ case 9: bitvector = 6; break; /* Pass Door */ case 10: bitvector = 8; break; /* Protection vs Good */ } sprintf(aff_name,"%s",affect_name[seed-1]); obj->has_aff = TRUE; obj->value[3] = bitvector; } paf->type = 0; paf->duration = -1; paf->location = affect; paf->modifier = value; paf->bitvector = 0; paf->next = obj->affected; obj->affected = paf; } } } if( add_tot < 100 ) obj->quality = QUALITY_POOR; else if( add_tot >= 100 && add_tot < 200 ) obj->quality = QUALITY_COMMON; else if( add_tot >= 200 && add_tot < 300 ) obj->quality = QUALITY_UNCOMMON; else if( add_tot >= 300 && add_tot < 400 ) obj->quality = QUALITY_SUPERIOR; else if( add_tot >= 400 && add_tot < 500 ) obj->quality = QUALITY_EPIC; else if( add_tot >= 500 ) obj->quality = QUALITY_LEGENDARY; sprintf(quality,"%s",quality_name[obj->quality]); free_string(obj->name); free_string(obj->short_descr); free_string(obj->description); if( obj->item_type != ITEM_CONTAINER ) sprintf(output,"%s of %s",slot,best_stat); else sprintf(output,"%s",slot); if( bitvector > 0 ) { strcat(output," and "); strcat(output,aff_name); } obj->short_descr = str_dup(output); obj->description = str_dup(output); strcat(output,quality); obj->name = str_dup(strip_ansi(output)); obj_to_char(obj,mob); return; }