/*** ITEMS.C - Randomly Generated Items ***/ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #define OBJMOD_MAX 54 // Number of Mods in the Table #define OBJMOD_ALL 0 // Can Modify Any Item #define OBJMOD_WEAPON 1 // Only Modifies Weapons #define OBJMOD_ARMOR 2 // Only Modifies Armor // Modifier List // +Hitroll #define OMOD_BRONZE 101 #define OMOD_GOLD 102 #define OMOD_VISIONARY 103 // +% Dam (WEAPON) #define OMOD_VICIOUS 201 #define OMOD_BRUTAL 202 #define OMOD_MERCILESS 203 #define OMOD_CRUEL 204 // +% AC (ARMOR) #define OMOD_STURDY 301 #define OMOD_BLESSED 302 #define OMOD_SAINTLY 303 #define OMOD_GODLY 304 // +Mana #define OMOD_LIZARDS 401 #define OMOD_SERPENTS 402 #define OMOD_WYRMS 403 // +Move #define OMOD_RUGGED 501 #define OMOD_TIRELESS 502 // +Str #define OMOD_OX 601 #define OMOD_ATLAS 602 // +Dex #define OMOD_ACCURACY 701 #define OMOD_PRECISION 702 // +Damroll #define OMOD_MAIMING 801 #define OMOD_GORE 802 #define OMOD_BUTCHERING 803 // +HP #define OMOD_JACKAL 901 #define OMOD_MAMMOTH 902 #define OMOD_WHALE 903 // +Wis/Int #define OMOD_MIND 1001 #define OMOD_BRILLIANCE 1002 #define OMOD_WIZARDRY 1003 // Item Spells (ARMOR) #define OMOD_GARNET 1101 // FireShield #define OMOD_COBALT 1102 // IceShield #define OMOD_CORAL 1103 // ShockShield #define OMOD_JADE 1104 // AcidShield #define OMOD_RAINBOW 1105 // ChaosShield #define OMOD_SWIFTNESS 1106 // Speed #define OMOD_REGROWTH 1107 // Regenerate #define OMOD_ABSORPTION 1108 // Sanctuary #define OMOD_LIGHT 1109 // Infravision #define OMOD_RADIANCE 1110 // DetectInvis #define OMOD_SHADOW 1111 // Sneak #define OMOD_SENSEI 1112 // Flying #define OMOD_TRANSPORT 1113 // PassDoor // -Saves #define OMOD_WARDING 1201 #define OMOD_NEGATION 1202 // Weapon Spells (WEAPON) #define OMOD_PIERCING 1301 // Vorpal #define OMOD_WINTER 1302 // FrostBreath #define OMOD_FLAME 1303 // Fireball #define OMOD_SHOCK 1304 // LightningBolt #define OMOD_VENOM 1305 // Poison #define OMOD_LOCUST 1306 // EnergyDrain // -AC #define OMOD_FAITHFUL 1401 // +Hitroll & +Damroll #define OMOD_KNIGHTS 1501 #define OMOD_LORDS 1502 #define OMOD_KINGS 1503 struct objmod_type { int mod_num; // OMOD_??? Number int mod_type; // OBJMOD_ALL | OBJMOD_WEAPON | OBJMOD_ARMOR int level; // Level Required for Mob to pop Mod char magic_fmt[100]; // Format used for Magic Creation char rare_adj[50]; // Adjective Used for Rare Creation }; const struct objmod_type obj_mod[OBJMOD_MAX] = { { OMOD_BRONZE, OBJMOD_ALL, 0, "#oBronze#n %s", "#oHawkeye#n" }, { OMOD_GOLD, OBJMOD_ALL, 25, "#yGold#n %s", "#oHawkeye#n" }, { OMOD_VISIONARY, OBJMOD_ALL, 50, "#wVisionary#n %s", "#oHawkeye#n" }, { OMOD_VICIOUS, OBJMOD_WEAPON, 15, "#rVicious#n %s", "#rSavage#n" }, { OMOD_BRUTAL, OBJMOD_WEAPON, 25, "#rBrutal#n %s", "#rSavage#n" }, { OMOD_MERCILESS, OBJMOD_WEAPON, 50, "#rMerciless#n %s", "#rSavage#n" }, { OMOD_CRUEL, OBJMOD_WEAPON, 75, "#RCruel#n %s", "#rSavage#n" }, { OMOD_STURDY, OBJMOD_ARMOR, 10, "#cSturdy#n %s", "#wHoly#n" }, { OMOD_BLESSED, OBJMOD_ARMOR, 20, "#CBlessed#n %s", "#wHoly#n" }, { OMOD_SAINTLY, OBJMOD_ARMOR, 30, "#wSaintly#n %s", "#wHoly#n" }, { OMOD_GODLY, OBJMOD_ARMOR, 50, "#wGodly#n %s", "#wHoly#n" }, { OMOD_LIZARDS, OBJMOD_ALL, 0, "#gLizard's#n %s", "#gDragon#n" }, { OMOD_SERPENTS, OBJMOD_ALL, 15, "#gSerpent's#n %s", "#gDragon#n" }, { OMOD_WYRMS, OBJMOD_ALL, 30, "#gWyrm's#n %s", "#gDragon#n" }, { OMOD_RUGGED, OBJMOD_ALL, 0, "#oRugged#n %s", "#cVigor#n" }, { OMOD_TIRELESS, OBJMOD_ALL, 20, "#cTireless#n %s", "#cVigor#n" }, { OMOD_OX, OBJMOD_ALL, 0, "%s of the #wOx#n", "#oTitan#n" }, { OMOD_ATLAS, OBJMOD_ALL, 25, "%s of #oAtlas#n", "#oTitan#n" }, { OMOD_ACCURACY, OBJMOD_ALL, 0, "%s of #CAccuracy#n", "#CNirvana#n" }, { OMOD_PRECISION, OBJMOD_ALL, 25, "%s of #CPrecision#n", "#CNirvana#n" }, { OMOD_MAIMING, OBJMOD_ALL, 0, "%s of #rMaiming#n", "#rCarnage#n" }, { OMOD_GORE, OBJMOD_ALL, 25, "%s of #rGore#n", "#rCarnage#n" }, { OMOD_BUTCHERING, OBJMOD_ALL, 50, "%s of #rButchering#n", "#rCarnage#n" }, { OMOD_JACKAL, OBJMOD_ALL, 0, "%s of the #oJackal#n", "#oTiger#n" }, { OMOD_MAMMOTH, OBJMOD_ALL, 15, "%s of the #rMammoth#n", "#oTiger#n" }, { OMOD_WHALE, OBJMOD_ALL, 30, "%s of the #bWhale#n", "#oTiger#n" }, { OMOD_MIND, OBJMOD_ALL, 0, "%s of the #BMind#n", "#BSorcery#n" }, { OMOD_BRILLIANCE, OBJMOD_ALL, 10, "%s of #BBrilliance#n", "#BSorcery#n" }, { OMOD_WIZARDRY, OBJMOD_ALL, 30, "%s of #BWizardry#n", "#BSorcery#n" }, { OMOD_GARNET, OBJMOD_ARMOR, 25, "#rGarnet#n %s", "#rGarnet#n" }, { OMOD_COBALT, OBJMOD_ARMOR, 25, "#CCobalt#n %s", "#CCobalt#n" }, { OMOD_CORAL, OBJMOD_ARMOR, 25, "#oCoral#n %s", "#yCoral#n" }, { OMOD_JADE, OBJMOD_ARMOR, 25, "#gJade#n %s", "#gJade#n" }, { OMOD_RAINBOW, OBJMOD_ARMOR, 75, "#PRainbow#n %s", "#PRainbow#n" }, { OMOD_SWIFTNESS, OBJMOD_ARMOR, 75, "%s of #wSwiftness#n", "#wSwift#n" }, { OMOD_REGROWTH, OBJMOD_ARMOR, 50, "%s of #GRegrowth#n", "#GRegrowth#n" }, { OMOD_ABSORPTION, OBJMOD_ARMOR, 25, "%s of #wAbsorption#n", "#wAbsorb#n" }, { OMOD_LIGHT, OBJMOD_ARMOR, 10, "%s of #wLight#n", "#ySun#n" }, { OMOD_RADIANCE, OBJMOD_ARMOR, 25, "%s of #yRadiance#n", "#ySun#n" }, { OMOD_SHADOW, OBJMOD_ARMOR, 20, "#eShadow#n %s", "#eShadow#n" }, { OMOD_SENSEI, OBJMOD_ARMOR, 15, "#cSensei#n %s", "#cSensei#n" }, { OMOD_TRANSPORT, OBJMOD_ARMOR, 20, "%s of #CTransportation#n", "#CTransport#n" }, { OMOD_WARDING, OBJMOD_ALL, 15, "%s of #bWarding#n", "#wSentinel#n" }, { OMOD_NEGATION, OBJMOD_ALL, 40, "%s of #bNegation#n", "#wSentinel#n" }, { OMOD_PIERCING, OBJMOD_WEAPON, 90, "%s of #RPiercing#n", "#RVorpal#n" }, { OMOD_WINTER, OBJMOD_WEAPON, 50, "%s of #CWinter#n", "#CWinter#n" }, { OMOD_FLAME, OBJMOD_WEAPON, 35, "%s of #rFlame#n", "#rFlame#n" }, { OMOD_SHOCK, OBJMOD_WEAPON, 30, "%s of #yShock#n", "#yShock#n" }, { OMOD_VENOM, OBJMOD_WEAPON, 20, "%s of #gVenom#n", "#gVenom#n" }, { OMOD_LOCUST, OBJMOD_WEAPON, 40, "%s of the #bLocust#n", "#bLocust#n" }, { OMOD_FAITHFUL, OBJMOD_ALL, 25, "#wFaithful#n %s", "#wFaithful#n" }, { OMOD_KNIGHTS, OBJMOD_ALL, 25, "#pKnight's#n %s", "#pFine#n" }, { OMOD_LORDS, OBJMOD_ALL, 50, "#pLord's#n %s", "#pFine#n" }, { OMOD_KINGS, OBJMOD_ALL, 75, "#pKing's#n %s", "#pFine#n" } }; OBJ_DATA *add_oaff(OBJ_DATA *obj, int aff, int mod) { AFFECT_DATA *paf; if ( affect_free == NULL ) { paf = alloc_perm( sizeof(*paf) ); } else { paf = affect_free; affect_free = affect_free->next; } paf->type = -1; paf->duration = -1; paf->location = aff; paf->modifier = mod; paf->bitvector = 0; paf->next = obj->affected; obj->affected = paf; return obj; } OBJ_DATA *add_omod(OBJ_DATA *obj, int omod) { // The World's Biggest Switch Statement switch (omod) { case OMOD_BRONZE: add_oaff(obj,APPLY_HITROLL,10); break; case OMOD_GOLD: add_oaff(obj,APPLY_HITROLL,20); break; case OMOD_VISIONARY: add_oaff(obj,APPLY_HITROLL,30); break; case OMOD_VICIOUS: obj->value[1] *= 1.2; obj->value[2] *= 1.2; break; case OMOD_BRUTAL: obj->value[1] *= 1.4; obj->value[2] *= 1.4; break; case OMOD_MERCILESS: obj->value[1] *= 1.6; obj->value[2] *= 1.6; break; case OMOD_CRUEL: obj->value[1] *= 1.8; obj->value[2] *= 1.8; break; case OMOD_STURDY: obj->value[0] *= 1.5; break; case OMOD_BLESSED: obj->value[0] *= 1.6; break; case OMOD_SAINTLY: obj->value[0] *= 1.7; break; case OMOD_GODLY: obj->value[0] *= 1.8; break; case OMOD_LIZARDS: add_oaff(obj,APPLY_MANA,500); break; case OMOD_SERPENTS: add_oaff(obj,APPLY_MANA,750); break; case OMOD_WYRMS: add_oaff(obj,APPLY_MANA,1000); break; case OMOD_RUGGED: add_oaff(obj,APPLY_MOVE,200); break; case OMOD_TIRELESS: add_oaff(obj,APPLY_MOVE,600); break; case OMOD_OX: add_oaff(obj,APPLY_STR,5); break; case OMOD_ATLAS: add_oaff(obj,APPLY_STR,10); break; case OMOD_ACCURACY: add_oaff(obj,APPLY_DEX,5); break; case OMOD_PRECISION: add_oaff(obj,APPLY_DEX,10); break; case OMOD_MAIMING: add_oaff(obj,APPLY_DAMROLL,10); break; case OMOD_GORE: add_oaff(obj,APPLY_DAMROLL,20); break; case OMOD_BUTCHERING: add_oaff(obj,APPLY_DAMROLL,30); break; case OMOD_JACKAL: add_oaff(obj,APPLY_HIT,500); break; case OMOD_MAMMOTH: add_oaff(obj,APPLY_HIT,750); break; case OMOD_WHALE: add_oaff(obj,APPLY_HIT,1000); break; case OMOD_MIND: add_oaff(obj,APPLY_WIS,5); add_oaff(obj,APPLY_INT,5); break; case OMOD_BRILLIANCE: add_oaff(obj,APPLY_WIS,5); add_oaff(obj,APPLY_INT,5); break; case OMOD_WIZARDRY: add_oaff(obj,APPLY_WIS,5); add_oaff(obj,APPLY_INT,5); break; case OMOD_GARNET: obj->value[3] = 11; break; case OMOD_COBALT: obj->value[3] = 12; break; case OMOD_CORAL: obj->value[3] = 10; break; case OMOD_JADE: obj->value[3] = 13; break; case OMOD_RAINBOW: obj->value[3] = 15; break; case OMOD_SWIFTNESS: obj->value[3] = 17; break; case OMOD_REGROWTH: obj->value[3] = 16; break; case OMOD_ABSORPTION: obj->value[3] = 57; break; case OMOD_LIGHT: obj->value[3] = 1; break; case OMOD_RADIANCE: obj->value[3] = 2; break; case OMOD_SHADOW: obj->value[3] = 9; break; case OMOD_SENSEI: obj->value[3] = 3; break; case OMOD_TRANSPORT: obj->value[3] = 6; break; case OMOD_WARDING: add_oaff(obj,APPLY_SAVING_SPELL,-1); break; case OMOD_NEGATION: add_oaff(obj,APPLY_SAVING_SPELL,-3); break; case OMOD_PIERCING: obj->value[0] += 18000; break; case OMOD_WINTER: obj->value[0] += 69; obj->level = 50; break; case OMOD_FLAME: obj->value[0] += 37; obj->level = 50; break; case OMOD_SHOCK: obj->value[0] += 48; obj->level = 50; break; case OMOD_VENOM: obj->value[0] += 53; obj->level = 50; break; case OMOD_LOCUST: obj->value[0] += 34; obj->level = 50; break; case OMOD_FAITHFUL: add_oaff(obj,APPLY_AC,-10); break; case OMOD_KNIGHTS: add_oaff(obj,APPLY_HITROLL,5); add_oaff(obj,APPLY_DAMROLL,5); break; case OMOD_LORDS: add_oaff(obj,APPLY_HITROLL,10); add_oaff(obj,APPLY_DAMROLL,10); break; case OMOD_KINGS: add_oaff(obj,APPLY_HITROLL,15); add_oaff(obj,APPLY_DAMROLL,15); break; default: perror("add_omod: invalid omod"); } return obj; } // CREATE_MAGIC() - makes an object magical OBJ_DATA *create_magic(OBJ_DATA *obj, int level) { char buf[MAX_STRING_LENGTH]; char proper[MAX_STRING_LENGTH]; int mod = -1; int num = (obj->pIndexData->vnum - 26000); obj->item_ver = IV_MAGIC; // Fetch a Mod while (mod < 0) { mod = number_range(0,OBJMOD_MAX-1); if (obj_mod[mod].mod_type == OBJMOD_WEAPON && obj->item_type != ITEM_WEAPON) mod = -1; if (obj_mod[mod].mod_type == OBJMOD_ARMOR && obj->item_type != ITEM_ARMOR) mod = -1; if (obj_mod[mod].level > level) // Mod Too High mod = -1; } // Cost Up if Mod Level > Obj Level if (obj_mod[mod].level > obj->cost) obj->cost = obj_mod[mod].level; // Generate Description sprintf(buf, obj_mod[mod].magic_fmt, obj->name); free_string(obj->name); obj->name = str_dup(bash_color(buf)); sprintf(proper, obj_mod[mod].magic_fmt, obj->short_descr); free_string(obj->short_descr); obj->short_descr = str_dup(proper); switch (num) { default: sprintf(buf, "A "); break; case 1: sprintf(buf, "An "); break; case 4: case 5: case 6: case 7: sprintf(buf, "Some "); break; } strcat(buf, proper); switch (num) { default: strcat(buf, "#0 is lying here.#n"); break; case 4: case 6: strcat(buf, "#0 are lying here.#n"); break; case 5: case 7: strcat(buf, "#0 lie here.#n"); break; case 9: strcat(buf, "#0 lies here.#n"); break; case 10: strcat(buf, "#0 is discarded on the ground.#n"); break; case 12: strcat(buf, "#0 is lying on the ground.#n"); break; case 16: strcat(buf, "#0 is sitting on the ground.#n"); break; } free_string(obj->description); obj->description = str_dup(buf); free_string(obj->questmaker); obj->questmaker = str_dup("The Magic Moogle"); // Add the Mod obj = add_omod(obj,obj_mod[mod].mod_num); return obj; } // CREATE_RARE() - makes an object rare OBJ_DATA *create_rare(OBJ_DATA *obj, int level) { char buf[MAX_STRING_LENGTH]; char proper[MAX_STRING_LENGTH]; int num = (obj->pIndexData->vnum - 26000); int mods[3] = {-1, -1, -1}; obj->item_ver = IV_RARE; // Fetch Mods while (mods[0] < 0) { mods[0] = number_range(0,OBJMOD_MAX-1); if (obj_mod[mods[0]].mod_type == OBJMOD_WEAPON && obj->item_type != ITEM_WEAPON) mods[0] = -1; else if (obj_mod[mods[0]].mod_type == OBJMOD_ARMOR && obj->item_type != ITEM_ARMOR) mods[0] = -1; else if (obj_mod[mods[0]].level > level) // Mod Too High mods[0] = -1; } // Cost Up if ModLevel > ObjLevel if (obj_mod[mods[0]].level > obj->cost) obj->cost = obj_mod[mods[0]].level; // Fetch Mods while (mods[1] < 0) { mods[1] = number_range(0,OBJMOD_MAX-1); if (obj_mod[mods[1]].mod_num/100 == obj_mod[mods[0]].mod_num/100) mods[1] = -1; else if (obj_mod[mods[1]].mod_type == OBJMOD_WEAPON && obj->item_type != ITEM_WEAPON) mods[1] = -1; else if (obj_mod[mods[1]].mod_type == OBJMOD_ARMOR && obj->item_type != ITEM_ARMOR) mods[1] = -1; else if (obj_mod[mods[1]].level > level) // Mod Too High mods[1] = -1; } // Cost Up if ModLevel > ObjLevel if (obj_mod[mods[1]].level > obj->cost) obj->cost = obj_mod[mods[1]].level; // Fetch Mods while (mods[2] < 0) { mods[2] = number_range(0,OBJMOD_MAX-1); if (obj_mod[mods[2]].mod_num/100 == obj_mod[mods[0]].mod_num/100) mods[2] = -1; else if (obj_mod[mods[2]].mod_num/100 == obj_mod[mods[1]].mod_num/100) mods[2] = -1; else if (obj_mod[mods[2]].mod_type == OBJMOD_WEAPON && obj->item_type != ITEM_WEAPON) mods[2] = -1; else if (obj_mod[mods[2]].mod_type == OBJMOD_ARMOR && obj->item_type != ITEM_ARMOR) mods[2] = -1; else if (obj_mod[mods[2]].level > level) // Mod Too High mods[2] = -1; } // Cost Up if ModLevel > ObjLevel if (obj_mod[mods[2]].level > obj->cost) obj->cost = obj_mod[mods[2]].level; // No breaking... SET_BIT (obj->quest2, QUEST2_INDEST); // Generate Description sprintf(buf,"%s %s %s", obj_mod[mods[1]].rare_adj, obj_mod[mods[2]].rare_adj, obj->name); free_string(obj->name); obj->name = str_dup(bash_color(buf)); sprintf(proper,"%s %s %s", obj_mod[mods[1]].rare_adj, obj_mod[mods[2]].rare_adj, obj->short_descr); free_string(obj->short_descr); obj->short_descr = str_dup(proper); switch (num) { default: sprintf(buf, "A "); break; case 1: sprintf(buf, "An "); break; case 4: case 5: case 6: case 7: sprintf(buf, "Some "); break; } strcat(buf, proper); switch (num) { default: strcat(buf, "#0 is lying here.#n"); break; case 4: case 6: strcat(buf, "#0 are lying here.#n"); break; case 5: case 7: strcat(buf, "#0 lie here.#n"); break; case 9: strcat(buf, "#0 lies here.#n"); break; case 10: strcat(buf, "#0 is discarded on the ground.#n"); break; case 12: strcat(buf, "#0 is lying on the ground.#n"); break; case 16: strcat(buf, "#0 is sitting on the ground.#n"); break; } free_string(obj->description); obj->description = str_dup(buf); free_string(obj->questmaker); obj->questmaker = str_dup("The Rare Fairy"); // Add Mods obj = add_omod(obj,obj_mod[mods[0]].mod_num); obj = add_omod(obj,obj_mod[mods[1]].mod_num); obj = add_omod(obj,obj_mod[mods[2]].mod_num); obj->condition = 100; obj->toughness = 100; obj->resistance = 1; return obj; } // CREATE_NORMAL() - makes a normal object OBJ_DATA *create_normal(OBJ_DATA *obj, int level) { char buf[MAX_STRING_LENGTH]; obj->item_ver = IV_NORMAL; sprintf(buf,"%s", bash_color(obj->short_descr)); free_string(obj->short_descr); obj->short_descr = str_dup(buf); free_string(obj->questmaker); obj->questmaker = str_dup("The BlackSmith"); return obj; } // POP_ITEM() - creates an item OBJ_DATA *pop_item(int level) { OBJ_DATA *obj; int ver = number_range(1, 1000); int mod = 0; if (level < 0) level = 0; level = number_range(level * 0.8, level * 1.0); if (ver == 1 ) // POP RARE! (1% chance) ver = IV_RARE; else if (ver < 5 ) // POP MAGIC! (3% chance) ver = IV_MAGIC; else if (ver < 20 ) // POP NORMAL! (15% chance) ver = IV_NORMAL; else // NO POP :( return NULL; if ((obj = create_object(get_obj_index(number_range(MIN_OBJ_VNUM, MAX_OBJ_VNUM)), 0)) == NULL) { perror("pop_item: invalid item"); return NULL; } // Item Too Good! if (obj->cost > level) { extract_obj(obj); return NULL; } // Added this to change armor/avg dam instead of diff objs if (obj->item_type == ITEM_ARMOR) { mod = number_range(10,level); obj->value[0] *= mod/10; if (mod > obj->cost) obj->cost = mod; } else if (obj->item_type == ITEM_WEAPON) { mod = number_range(10,level); obj->value[1] *= mod/10; obj->value[2] *= mod/10; if (mod > obj->cost) obj->cost = mod; } switch (ver) { case IV_NORMAL: return create_normal(obj,level); break; case IV_MAGIC: return create_magic(obj,level); break; case IV_RARE: return create_rare(obj,level); break; default: perror("pop_item: invalid version"); return NULL; } return NULL; } // Test Function to generate items on command void do_popitem(CHAR_DATA *ch, char *argument) { OBJ_DATA *obj; char buf[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; int level; if (IS_NPC(ch)) return; argument = one_argument(argument,arg); level = atoi(arg); // if (arg[0] == '\0' || level < 0 || level > 99) if (arg[0] == '\0' || level < 0) level = 99; obj = pop_item(level); if (obj == NULL) { send_to_char("You didn't pop anything!\n\r", ch); return; } sprintf(buf,"You just popped %s!!!\n\r", obj->short_descr); send_to_char(buf,ch); obj_to_char(obj,ch); return; }