/** * Wipe an object clean and make it a standard object of the specified kind. */ void object_prep(object_type *o_ptr, struct object_kind *k, int lev, aspect rand_aspect) { int i, flag, pval; bitflag flags[OF_SIZE], f2[OF_SIZE]; /* Clean slate */ WIPE(o_ptr, object_type); /* Assign the kind and copy across data */ o_ptr->kind = k; o_ptr->tval = k->tval; o_ptr->sval = k->sval; o_ptr->ac = k->ac; o_ptr->dd = k->dd; o_ptr->ds = k->ds; o_ptr->weight = k->weight; /* Default number */ o_ptr->number = 1; /* Apply pvals and then copy flags */ of_copy(f2, k->flags); for (i = 0; i < k->num_pvals; i++) { of_copy(flags, k->pval_flags[i]); pval = randcalc(k->pval[i], lev, rand_aspect); for (flag = of_next(flags, FLAG_START); flag != FLAG_END; flag = of_next(flags, flag + 1)) /* Prevent phantom flags */ if (pval) object_add_pval(o_ptr, pval, flag); else of_off(f2, flag); } of_copy(o_ptr->flags, k->base->flags); of_union(o_ptr->flags, f2); /* Assign charges (wands/staves only) */ if (o_ptr->tval == TV_WAND || o_ptr->tval == TV_STAFF) o_ptr->pval[DEFAULT_PVAL] = randcalc(k->charge, lev, rand_aspect); /* Assign flagless pval for food or oil */ if (o_ptr->tval == TV_FOOD || o_ptr->tval == TV_POTION || o_ptr->tval == TV_FLASK) o_ptr->pval[DEFAULT_PVAL] = randcalc(k->pval[DEFAULT_PVAL], lev, rand_aspect); /* Default fuel for lamps */ if (o_ptr->tval == TV_LIGHT) { if (o_ptr->sval == SV_LIGHT_TORCH) o_ptr->timeout = DEFAULT_TORCH; else if (o_ptr->sval == SV_LIGHT_LANTERN) o_ptr->timeout = DEFAULT_LAMP; } /* Default magic */ o_ptr->to_h = randcalc(k->to_h, lev, rand_aspect); o_ptr->to_d = randcalc(k->to_d, lev, rand_aspect); o_ptr->to_a = randcalc(k->to_a, lev, rand_aspect); }
/** * Create a cache of slay combinations found on ego items, and the values of * these combinations. This is to speed up slay_power(), which will be called * many times for ego items during the game. * * \param items is the set of ego types from which we are extracting slay * combinations */ errr create_slay_cache(struct ego_item *items) { int i; int j; int count = 0; bitflag cacheme[OF_SIZE]; bitflag slay_mask[OF_SIZE]; bitflag **dupcheck; ego_item_type *e_ptr; /* Build the slay mask */ create_mask(slay_mask, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX); /* Calculate necessary size of slay_cache */ dupcheck = C_ZNEW(z_info->e_max, bitflag *); for (i = 0; i < z_info->e_max; i++) { dupcheck[i] = C_ZNEW(OF_SIZE, bitflag); e_ptr = items + i; /* Find the slay flags on this ego */ of_copy(cacheme, e_ptr->flags); of_inter(cacheme, slay_mask); /* Only consider non-empty combinations of slay flags */ if (!of_is_empty(cacheme)) { /* Skip previously scanned combinations */ for (j = 0; j < i; j++) if (of_is_equal(cacheme, dupcheck[j])) continue; /* msg("Found a new slay combo on an ego item"); */ count++; of_copy(dupcheck[i], cacheme); } } /* Allocate slay_cache with an extra empty element for an iteration stop */ slay_cache = C_ZNEW((count + 1), struct flag_cache); count = 0; /* Populate the slay_cache */ for (i = 0; i < z_info->e_max; i++) { if (!of_is_empty(dupcheck[i])) { of_copy(slay_cache[count].flags, dupcheck[i]); slay_cache[count].value = 0; count++; /*msg("Cached a slay combination");*/ } } for (i = 0; i < z_info->e_max; i++) FREE(dupcheck[i]); FREE(dupcheck); /* Success */ return 0; }
/** * Match slays in flags against a chosen flag mask * * count is the number of matches * \param flags is the flagset to analyse for matches * \param mask is the flagset against which to test * \param desc is the array of descriptions of matching slays - can be null * \param brand is the array of descriptions of brands - can be null * \param mult is the array of multipliers of those slays - can be null * \param dedup is whether or not to remove duplicates * * desc[], brand[] and mult[] must be >= SL_MAX in size */ int list_slays(const bitflag flags[OF_SIZE], const bitflag mask[OF_SIZE], const char *desc[], const char *brand[], int mult[], bool dedup) { int i, count = 0; bitflag f[OF_SIZE]; /* We are only interested in the flags specified in mask */ of_copy(f, flags); of_inter(f, mask); /* Remove "duplicate" flags if desired */ if (dedup) dedup_slays(f); /* Collect slays */ for (i = 0; i < SL_MAX; i++) { const struct slay *s_ptr = &slay_table[i]; if (of_has(f, s_ptr->object_flag)) { if (mult) mult[count] = s_ptr->mult; if (brand) brand[count] = s_ptr->brand; if (desc) desc[count] = s_ptr->desc; count++; } } return count; }
/** * Copy artifact data to a normal object, and set various slightly hacky * globals. */ void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr) { int i; /* Extract the data */ for (i = 0; i < a_ptr->num_pvals; i++) if (a_ptr->pval[i]) { o_ptr->pval[i] = a_ptr->pval[i]; of_copy(o_ptr->pval_flags[i], a_ptr->pval_flags[i]); } o_ptr->num_pvals = a_ptr->num_pvals; o_ptr->ac = a_ptr->ac; o_ptr->dd = a_ptr->dd; o_ptr->ds = a_ptr->ds; o_ptr->to_a = a_ptr->to_a; o_ptr->to_h = a_ptr->to_h; o_ptr->to_d = a_ptr->to_d; o_ptr->weight = a_ptr->weight; of_union(o_ptr->flags, a_ptr->flags); /* Set the prefix or suffix, if the artifact has an affix */ if (a_ptr->affix && affix_is_prefix(a_ptr->affix->eidx)) o_ptr->prefix = a_ptr->affix; if (a_ptr->affix && affix_is_suffix(a_ptr->affix->eidx)) o_ptr->suffix = a_ptr->affix; /* Set the theme, if it has one */ if (a_ptr->theme) o_ptr->theme = a_ptr->theme; }
/* * Create the artifact with the specified number */ static void wiz_create_artifact(int a_idx) { object_type *i_ptr; object_type object_type_body; int k_idx; artifact_type *a_ptr = &a_info[a_idx]; /* Ignore "empty" artifacts */ if (!a_ptr->name) return; /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* Acquire the "kind" index */ k_idx = lookup_kind(a_ptr->tval, a_ptr->sval); /* Oops */ if (!k_idx) return; /* Create the artifact */ object_prep(i_ptr, &k_info[k_idx], a_ptr->alloc_min, RANDOMISE); /* Save the name */ i_ptr->name1 = a_idx; /* Extract the fields */ i_ptr->pval = a_ptr->pval; i_ptr->ac = a_ptr->ac; i_ptr->dd = a_ptr->dd; i_ptr->ds = a_ptr->ds; i_ptr->to_a = a_ptr->to_a; i_ptr->to_h = a_ptr->to_h; i_ptr->to_d = a_ptr->to_d; i_ptr->weight = a_ptr->weight; /* Hack -- extract the "cursed" flags */ if (cursed_p(a_ptr)) { bitflag curse_flags[OF_SIZE]; of_copy(curse_flags, a_ptr->flags); flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END); of_union(i_ptr->flags, curse_flags); } /* Mark that the artifact has been created. */ a_ptr->created = TRUE; /* Mark as cheat */ i_ptr->origin = ORIGIN_CHEAT; /* Drop the artifact from heaven */ drop_near(i_ptr, 0, p_ptr->py, p_ptr->px, TRUE); /* All done */ msg_print("Allocated."); }
/** * Known is true when the "attributes" of an object are "known". * These include tohit, todam, toac, cost, and pval (charges, bonuses, etc.). * * Note that "knowing" an object gives you everything that an "awareness" * gives you, and much more. In fact, the player is always "aware" of any * item of which he has full "knowledge". * * This routine also removes any inscriptions generated by "feelings". */ void object_known(object_type * o_ptr) { artifact_type *a_ptr = artifact_of(o_ptr); /* Forget the feeling */ o_ptr->feel = FEEL_NONE; /* Clear the "Felt" info */ o_ptr->ident &= ~(IDENT_SENSE); /* Clear the "Empty" info */ o_ptr->ident &= ~(IDENT_EMPTY); /* Now we know about the item */ o_ptr->ident |= (IDENT_KNOWN); /* ID knowledge is better than wearing knowledge */ o_ptr->ident |= (IDENT_WORN); /* Artifact has now been seen */ if (a_ptr) { history_add_artifact(o_ptr->name1, TRUE, TRUE); } /* Get all the id flags */ of_copy(o_ptr->id_obj, o_ptr->flags_obj); flags_other(o_ptr, o_ptr->id_other); }
/** * Copy artifact data to a normal object, and set various slightly hacky * globals. */ static void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr) { /* Extract the other fields */ o_ptr->pval = a_ptr->pval; o_ptr->ac = a_ptr->ac; o_ptr->dd = a_ptr->dd; o_ptr->ds = a_ptr->ds; o_ptr->to_a = a_ptr->to_a; o_ptr->to_h = a_ptr->to_h; o_ptr->to_d = a_ptr->to_d; o_ptr->weight = a_ptr->weight; /* Hack -- extract the "cursed" flags */ if (cursed_p(a_ptr)) { bitflag curse_flags[OF_SIZE]; of_copy(curse_flags, a_ptr->flags); flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END); of_union(o_ptr->flags, curse_flags); } /* Mega-Hack -- increase the level rating * - a sizeable increase for any artifact (c.f. up to 30 for ego items) * - a bigger increase for more powerful artifacts */ rating += 30; rating += object_power(o_ptr, FALSE, NULL, TRUE) / 25; /* Set the good item flag */ good_item_flag = TRUE; /* Cheat -- peek at the item */ if (OPT(cheat_peek)) object_mention(o_ptr); }
/* * Describe miscellaneous powers. */ static bool describe_misc_magic(textblock * tb, const object_type * o_ptr, oinfo_detail_t mode) { bool full = mode & OINFO_FULL; size_t i; bool printed = FALSE; bitflag objflags[OF_SIZE]; of_wipe(objflags); of_copy(objflags, o_ptr->flags_obj); if (!full) of_inter(objflags, o_ptr->id_obj); for (i = 0; i < N_ELEMENTS(misc_flags); i++) { if (of_has(objflags, misc_flags[i].flag)) { if (!printed) textblock_append(tb, "\nPowers: "); textblock_append(tb, "%s. ", misc_flags[i].name); printed = TRUE; } } if (printed) textblock_append(tb, "\n"); return printed; }
/** * Copy artifact data to a normal object, and set various slightly hacky * globals. */ static void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr) { /* Extract the other fields */ o_ptr->pval = a_ptr->pval; o_ptr->ac = a_ptr->ac; o_ptr->dd = a_ptr->dd; o_ptr->ds = a_ptr->ds; o_ptr->to_a = a_ptr->to_a; o_ptr->to_h = a_ptr->to_h; o_ptr->to_d = a_ptr->to_d; o_ptr->weight = a_ptr->weight; /* Hack -- extract the "cursed" flags */ if (cursed_p(a_ptr)) { bitflag curse_flags[OF_SIZE]; of_copy(curse_flags, a_ptr->flags); flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END); of_union(o_ptr->flags, curse_flags); } /* Mega-Hack -- increase the rating */ rating += 10; /* Mega-Hack -- increase the rating again */ if (a_ptr->cost > 50000L) rating += 10; /* Set the good item flag */ good_item_flag = TRUE; /* Cheat -- peek at the item */ if (OPT(cheat_peek)) object_mention(o_ptr); }
/** * Prepare an object based on an object kind. */ void object_prep(object_type * o_ptr, int k_idx, aspect rand_aspect) { int i; object_kind *k_ptr = &k_info[k_idx]; /* Clear the record */ (void) WIPE(o_ptr, object_type); /* Save the kind */ o_ptr->k_idx = k_idx; o_ptr->kind = k_ptr; /* Efficiency -- tval/sval */ o_ptr->tval = k_ptr->tval; o_ptr->sval = k_ptr->sval; /* Default "pval" */ o_ptr->pval = randcalc(k_ptr->pval, k_ptr->level, rand_aspect); /* Default number */ o_ptr->number = 1; /* Default weight */ o_ptr->weight = k_ptr->weight; /* Default magic */ o_ptr->to_h = randcalc(k_ptr->to_h, k_ptr->level, rand_aspect); o_ptr->to_d = randcalc(k_ptr->to_d, k_ptr->level, rand_aspect); o_ptr->to_a = randcalc(k_ptr->to_a, k_ptr->level, rand_aspect); /* Default power */ o_ptr->ac = k_ptr->ac; o_ptr->dd = k_ptr->dd; o_ptr->ds = k_ptr->ds; /* Default effect and time */ o_ptr->effect = k_ptr->effect; o_ptr->time = k_ptr->time; /* Default flags */ of_copy(o_ptr->flags_obj, k_ptr->flags_obj); cf_copy(o_ptr->flags_curse, k_ptr->flags_curse); /* Default resists, bonuses, multiples */ for (i = 0; i < MAX_P_RES; i++) o_ptr->percent_res[i] = k_ptr->percent_res[i]; for (i = 0; i < A_MAX; i++) o_ptr->bonus_stat[i] = k_ptr->bonus_stat[i]; for (i = 0; i < MAX_P_BONUS; i++) o_ptr->bonus_other[i] = k_ptr->bonus_other[i]; for (i = 0; i < MAX_P_SLAY; i++) o_ptr->multiple_slay[i] = k_ptr->multiple_slay[i]; for (i = 0; i < MAX_P_BRAND; i++) o_ptr->multiple_brand[i] = k_ptr->multiple_brand[i]; }
/** * Remove the "bad" spells from a spell list */ static void remove_bad_spells(struct monster *mon, bitflag f[RSF_SIZE]) { bitflag f2[RSF_SIZE], ai_flags[OF_SIZE], ai_pflags[PF_SIZE]; struct element_info el[ELEM_MAX]; bool know_something = false; /* Stupid monsters act randomly */ if (rf_has(mon->race->flags, RF_STUPID)) return; /* Take working copy of spell flags */ rsf_copy(f2, f); /* Don't heal if full */ if (mon->hp >= mon->maxhp) rsf_off(f2, RSF_HEAL); /* Don't haste if hasted with time remaining */ if (mon->m_timed[MON_TMD_FAST] > 10) rsf_off(f2, RSF_HASTE); /* Don't teleport to if the player is already next to us */ if (mon->cdis == 1) rsf_off(f2, RSF_TELE_TO); /* Update acquired knowledge */ of_wipe(ai_flags); pf_wipe(ai_pflags); if (OPT(birth_ai_learn)) { size_t i; /* Occasionally forget player status */ if (one_in_(100)) { of_wipe(mon->known_pstate.flags); pf_wipe(mon->known_pstate.pflags); for (i = 0; i < ELEM_MAX; i++) mon->known_pstate.el_info[i].res_level = 0; } /* Use the memorized info */ of_copy(ai_flags, mon->known_pstate.flags); pf_copy(ai_pflags, mon->known_pstate.pflags); if (!of_is_empty(ai_flags) || !pf_is_empty(ai_pflags)) know_something = true; for (i = 0; i < ELEM_MAX; i++) { el[i].res_level = mon->known_pstate.el_info[i].res_level; if (el[i].res_level != 0) know_something = true; } } /* Cancel out certain flags based on knowledge */ if (know_something) unset_spells(f2, ai_flags, ai_pflags, el, mon->race); /* use working copy of spell flags */ rsf_copy(f, f2); }
/** * Apply generation magic to an ego-item. */ void ego_apply_magic(object_type *o_ptr, int level) { int i, flag, x; bitflag flags[OF_SIZE], newf[OF_SIZE], f2[OF_SIZE]; object_flags(o_ptr, flags); /* Extra powers */ if (o_ptr->ego->xtra == OBJECT_XTRA_TYPE_SUSTAIN) create_mask(newf, FALSE, OFT_SUST, OFT_MAX); else if (o_ptr->ego->xtra == OBJECT_XTRA_TYPE_RESIST) create_mask(newf, FALSE, OFT_HRES, OFT_MAX); else if (o_ptr->ego->xtra == OBJECT_XTRA_TYPE_POWER) create_mask(newf, FALSE, OFT_PROT, OFT_MISC, OFT_MAX); if (o_ptr->ego->xtra) of_on(o_ptr->flags, get_new_attr(flags, newf)); /* Apply extra o_ptr->ego bonuses */ o_ptr->to_h += randcalc(o_ptr->ego->to_h, level, RANDOMISE); o_ptr->to_d += randcalc(o_ptr->ego->to_d, level, RANDOMISE); o_ptr->to_a += randcalc(o_ptr->ego->to_a, level, RANDOMISE); /* Apply pvals */ of_copy(f2, o_ptr->ego->flags); for (i = 0; i < o_ptr->ego->num_pvals; i++) { of_copy(flags, o_ptr->ego->pval_flags[i]); x = randcalc(o_ptr->ego->pval[i], level, RANDOMISE); for (flag = of_next(flags, FLAG_START); flag != FLAG_END; flag = of_next(flags, flag + 1)) /* Prevent phantom flags */ if (x) object_add_pval(o_ptr, x, flag); else of_off(f2, flag); } /* Apply remaining flags */ of_union(o_ptr->flags, f2); return; }
/** * Copy artifact data to a normal object, and set various slightly hacky * globals. */ void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr) { int i; /* Extract the data */ for (i = 0; i < a_ptr->num_pvals; i++) if (a_ptr->pval[i]) { o_ptr->pval[i] = a_ptr->pval[i]; of_copy(o_ptr->pval_flags[i], a_ptr->pval_flags[i]); } o_ptr->num_pvals = a_ptr->num_pvals; o_ptr->ac = a_ptr->ac; o_ptr->dd = a_ptr->dd; o_ptr->ds = a_ptr->ds; o_ptr->to_a = a_ptr->to_a; o_ptr->to_h = a_ptr->to_h; o_ptr->to_d = a_ptr->to_d; o_ptr->weight = a_ptr->weight; of_union(o_ptr->flags, a_ptr->flags); }
/* * Calculate the rating for a given slay combination */ static s32b slay_power(const object_type *o_ptr, int verbose, ang_file* log_file, const bitflag flags[OF_SIZE]) { bitflag s_index[OF_SIZE]; s32b sv = 0; int i; int mult; const slay_t *s_ptr; /* Combine the slay bytes into an index value */ of_copy(s_index, flags); flags_mask(s_index, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END); /* Look in the cache to see if we know this one yet */ for (i = 0; !of_is_empty(slay_cache[i].flags); i++) { if (of_is_equal(s_index, slay_cache[i].flags)) break; } sv = slay_cache[i].value; /* If it's cached (or there are no slays), return the value */ if (sv) { LOG_PRINT("Slay cache hit\n"); return sv; } /* * Otherwise we need to calculate the expected average multiplier * for this combination (multiplied by the total number of * monsters, which we'll divide out later). */ for (i = 0; i < z_info->r_max; i++) { monster_race *r_ptr = &r_info[i]; mult = 1; /* * Do the following in ascending order so that the best * multiple is retained */ for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++) { if (!of_has(flags, s_ptr->slay_flag)) continue; if (rf_has(r_ptr->flags, s_ptr->monster_flag) || (s_ptr->resist_flag && !rf_has(r_ptr->flags, s_ptr->resist_flag))) { mult = s_ptr->mult; } } /* Add the multiple to sv */ sv += mult * r_ptr->power; } /* * To get the expected damage for this weapon, multiply the * average damage from base dice by sv, and divide by the * total number of monsters. */ if (verbose) { /* Write info about the slay combination and multiplier */ file_putf(log_file,"Slay multiplier for:"); if (of_has(flags, OF_SLAY_EVIL)) file_putf(log_file,"Evl "); if (of_has(flags, OF_KILL_DRAGON)) file_putf(log_file,"XDr "); if (of_has(flags, OF_KILL_DEMON)) file_putf(log_file,"XDm "); if (of_has(flags, OF_KILL_UNDEAD)) file_putf(log_file,"XUn "); if (of_has(flags, OF_SLAY_ANIMAL)) file_putf(log_file,"Ani "); if (of_has(flags, OF_SLAY_UNDEAD)) file_putf(log_file,"Und "); if (of_has(flags, OF_SLAY_DRAGON)) file_putf(log_file,"Drg "); if (of_has(flags, OF_SLAY_DEMON)) file_putf(log_file,"Dmn "); if (of_has(flags, OF_SLAY_TROLL)) file_putf(log_file,"Tro "); if (of_has(flags, OF_SLAY_ORC)) file_putf(log_file,"Orc "); if (of_has(flags, OF_SLAY_GIANT)) file_putf(log_file,"Gia "); if (of_has(flags, OF_BRAND_ACID)) file_putf(log_file,"Acd "); if (of_has(flags, OF_BRAND_ELEC)) file_putf(log_file,"Elc "); if (of_has(flags, OF_BRAND_FIRE)) file_putf(log_file,"Fir "); if (of_has(flags, OF_BRAND_COLD)) file_putf(log_file,"Cld "); if (of_has(flags, OF_BRAND_POIS)) file_putf(log_file,"Poi "); file_putf(log_file,"sv is: %d\n", sv); file_putf(log_file," and t_m_p is: %d \n", tot_mon_power); file_putf(log_file,"times 1000 is: %d\n", (1000 * sv) / tot_mon_power); } /* Add to the cache */ for (i = 0; !of_is_empty(slay_cache[i].flags); i++) { if (of_is_equal(s_index, slay_cache[i].flags)) { slay_cache[i].value = sv; LOG_PRINT("Added to slay cache\n"); break; } } return sv; }
/** * Wipe an object clean and make it a standard object of the specified kind. */ void object_prep(struct object *obj, struct object_kind *k, int lev, aspect rand_aspect) { int i; /* Clean slate */ memset(obj, 0, sizeof(*obj)); /* Assign the kind and copy across data */ obj->kind = k; obj->tval = k->tval; obj->sval = k->sval; obj->ac = k->ac; obj->dd = k->dd; obj->ds = k->ds; obj->weight = k->weight; obj->effect = k->effect; obj->time = k->time; /* Default number */ obj->number = 1; /* Copy flags */ of_copy(obj->flags, k->base->flags); of_copy(obj->flags, k->flags); /* Assign modifiers */ for (i = 0; i < OBJ_MOD_MAX; i++) obj->modifiers[i] = randcalc(k->modifiers[i], lev, rand_aspect); /* Assign charges (wands/staves only) */ if (tval_can_have_charges(obj)) obj->pval = randcalc(k->charge, lev, rand_aspect); /* Assign pval for food, oil and launchers */ if (tval_is_edible(obj) || tval_is_potion(obj) || tval_is_fuel(obj) || tval_is_launcher(obj)) obj->pval = randcalc(k->pval, lev, rand_aspect); /* Default fuel */ if (tval_is_light(obj)) { if (of_has(obj->flags, OF_BURNS_OUT)) obj->timeout = z_info->fuel_torch; else if (of_has(obj->flags, OF_TAKES_FUEL)) obj->timeout = z_info->default_lamp; } /* Default magic */ obj->to_h = randcalc(k->to_h, lev, rand_aspect); obj->to_d = randcalc(k->to_d, lev, rand_aspect); obj->to_a = randcalc(k->to_a, lev, rand_aspect); /* Default slays and brands */ copy_slay(&obj->slays, k->slays); copy_brand(&obj->brands, k->brands); /* Default resists */ for (i = 0; i < ELEM_MAX; i++) { obj->el_info[i].res_level = k->el_info[i].res_level; obj->el_info[i].flags = k->el_info[i].flags; obj->el_info[i].flags |= k->base->el_info[i].flags; } }
/** * For a string describing the player's intrinsic racial flags. */ static void view_abilities_aux(char *desc) { bitflag flags[OF_SIZE]; int attr_num, attr_listed, j; int max = 100; bool res = FALSE, vul = FALSE; char buf[10] = ""; of_copy(flags, rp_ptr->flags_obj); /* Sustain stats. */ if ((of_has(flags, OF_SUSTAIN_STR)) || (of_has(flags, OF_SUSTAIN_INT)) || (of_has(flags, OF_SUSTAIN_WIS)) || (of_has(flags, OF_SUSTAIN_DEX)) || (of_has(flags, OF_SUSTAIN_CON)) || (of_has(flags, OF_SUSTAIN_CHR))) { /* Clear number of items to list, and items listed. */ attr_num = 0; attr_listed = 0; /* How many attributes need to be listed? */ if (of_has(flags, OF_SUSTAIN_STR)) attr_num++; if (of_has(flags, OF_SUSTAIN_INT)) attr_num++; if (of_has(flags, OF_SUSTAIN_WIS)) attr_num++; if (of_has(flags, OF_SUSTAIN_DEX)) attr_num++; if (of_has(flags, OF_SUSTAIN_CON)) attr_num++; if (of_has(flags, OF_SUSTAIN_CHR)) attr_num++; /* Special case: sustain all stats */ if (attr_num == 6) { my_strcat(desc, "Your stats are all sustained. ", max); } else { my_strcat(desc, "Your", max); /* Loop for number of attributes in this group. */ for (j = 0; j < 6; j++) { bool list_ok = FALSE; if ((j == 0) && (of_has(flags, OF_SUSTAIN_STR))) list_ok = TRUE; if ((j == 1) && (of_has(flags, OF_SUSTAIN_INT))) list_ok = TRUE; if ((j == 2) && (of_has(flags, OF_SUSTAIN_WIS))) list_ok = TRUE; if ((j == 3) && (of_has(flags, OF_SUSTAIN_DEX))) list_ok = TRUE; if ((j == 4) && (of_has(flags, OF_SUSTAIN_CON))) list_ok = TRUE; if ((j == 5) && (of_has(flags, OF_SUSTAIN_CHR))) list_ok = TRUE; if (!list_ok) continue; /* Listing another attribute. */ attr_listed++; /* Commas separate members of a list of more than two. */ if ((attr_num > 2) && (attr_listed > 1)) my_strcat(desc, ",", max); /* "and" before final member of a list of more than one. */ if ((attr_num > 1) && (j != 0)) { if (attr_num == attr_listed) my_strcat(desc, " and", max); } /* List the attribute description, in its proper place. */ if (j == 0) my_strcat(desc, " strength", max); if (j == 1) my_strcat(desc, " intelligence", max); if (j == 2) my_strcat(desc, " wisdom", max); if (j == 3) my_strcat(desc, " dexterity", max); if (j == 4) my_strcat(desc, " constitution", max); if (j == 5) my_strcat(desc, " charisma", max); } } /* Pluralize the verb. */ if (attr_num > 1) my_strcat(desc, " are", max); else my_strcat(desc, " is", max); /* End sentence. Go to next line. */ my_strcat(desc, " sustained. ", max); } /* Clear number of items to list, and items listed. */ attr_num = 0; attr_listed = 0; /* Elemental immunities. */ for (j = 0; j < 4; j++) if (rp_ptr->percent_res[j] == RES_BOOST_IMMUNE) attr_num++; if (attr_num > 0) { my_strcat(desc, "You are immune to ", max); /* Loop for number of attributes in this group. */ for (j = 0; j < 4; j++) { if (rp_ptr->percent_res[j] > RES_BOOST_IMMUNE) continue; /* List the attribute description, in its proper place. */ if (j == 0) my_strcat(desc, "acid", max); if (j == 1) my_strcat(desc, "electricity", max); if (j == 2) my_strcat(desc, "fire", max); if (j == 3) my_strcat(desc, "frost", max); if (attr_num >= 3) my_strcat(desc, ", ", max); if (attr_num == 2) my_strcat(desc, " and ", max); if (attr_num == 1) my_strcat(desc, ". ", max); attr_num--; } /* End sentence. Go to next line. */ my_strcat(desc, ". ", max); } /* Check for resists and vulnerabilities */ for (j = 0; j < MAX_P_RES; j++) { if ((rp_ptr->percent_res[j] < 100) && (rp_ptr->percent_res[j] > 0)) res = TRUE; else if (rp_ptr->percent_res[j] > 100) vul = TRUE; } /* Resistances. */ if (res) { /* Clear number of items to list, and items listed. */ attr_num = 0; attr_listed = 0; for (j = 0; j < MAX_P_RES; j++) { if ((rp_ptr->percent_res[j] < 100) && (rp_ptr->percent_res[j] > 0)) attr_num++; } /* How many attributes need to be listed? */ my_strcat(desc, "You resist", max); /* Loop for number of attributes in this group. */ for (j = 0; j < MAX_P_RES; j++) { bool list_ok = FALSE; if ((rp_ptr->percent_res[j] < 100) && (rp_ptr->percent_res[j] > 0)) list_ok = TRUE; if (!list_ok) continue; /* Listing another attribute. */ attr_listed++; /* Commas separate members of a list of more than two. */ if ((attr_num > 2) && (attr_listed > 1)) my_strcat(desc, ",", max); /* "and" before final member of a list of more than one. */ if ((attr_num > 1) && (j != 0)) { if (attr_num == attr_listed) my_strcat(desc, " and", max); } /* List the attribute description, in its proper place. */ if (j == P_RES_ACID) my_strcat(desc, " acid", max); if (j == P_RES_ELEC) my_strcat(desc, " electricity", max); if (j == P_RES_FIRE) my_strcat(desc, " fire", max); if (j == P_RES_COLD) my_strcat(desc, " frost", max); if (j == P_RES_POIS) my_strcat(desc, " poison", max); if (j == P_RES_LIGHT) my_strcat(desc, " light", max); if (j == P_RES_DARK) my_strcat(desc, " darkness", max); if (j == P_RES_CONFU) my_strcat(desc, " confusion", max); if (j == P_RES_SOUND) my_strcat(desc, " sound", max); if (j == P_RES_SHARD) my_strcat(desc, " shards", max); if (j == P_RES_NEXUS) my_strcat(desc, " nexus", max); if (j == P_RES_NETHR) my_strcat(desc, " nether", max); if (j == P_RES_CHAOS) my_strcat(desc, " chaos", max); if (j == P_RES_DISEN) my_strcat(desc, " disenchantment", max); sprintf(buf, "(%d%%)", 100 - rp_ptr->percent_res[j]); my_strcat(desc, buf, max); } /* End sentence. Go to next line. */ my_strcat(desc, ". ", max); } /* Vulnerabilities. */ if (vul) { /* Clear number of items to list, and items listed. */ attr_num = 0; attr_listed = 0; for (j = 0; j < MAX_P_RES; j++) { if (rp_ptr->percent_res[j] > 100) attr_num++; } my_strcat(desc, "You are vulnerable to", max); /* Loop for number of attributes in this group. */ for (j = 0; j < MAX_P_RES; j++) { bool list_ok = FALSE; if (rp_ptr->percent_res[j] > 100) list_ok = TRUE; if (!list_ok) continue; /* Listing another attribute. */ attr_listed++; /* Commas separate members of a list of more than two. */ if ((attr_num > 2) && (attr_listed > 1)) my_strcat(desc, ",", max); /* "and" before final member of a list of more than one. */ if ((attr_num > 1) && (j != 0)) { if (attr_num == attr_listed) my_strcat(desc, " and", max); } /* List the attribute description, in its proper place. */ if (j == P_RES_ACID) my_strcat(desc, " acid", max); if (j == P_RES_ELEC) my_strcat(desc, " electricity", max); if (j == P_RES_FIRE) my_strcat(desc, " fire", max); if (j == P_RES_COLD) my_strcat(desc, " frost", max); if (j == P_RES_POIS) my_strcat(desc, " poison", max); if (j == P_RES_LIGHT) my_strcat(desc, " light", max); if (j == P_RES_DARK) my_strcat(desc, " darkness", max); if (j == P_RES_SOUND) my_strcat(desc, " sound", max); if (j == P_RES_SHARD) my_strcat(desc, " shards", max); if (j == P_RES_NEXUS) my_strcat(desc, " nexus", max); if (j == P_RES_NETHR) my_strcat(desc, " nether", max); if (j == P_RES_CHAOS) my_strcat(desc, " chaos", max); if (j == P_RES_DISEN) my_strcat(desc, " disenchantment", max); sprintf(buf, "(%d%%)", rp_ptr->percent_res[j] - 100); my_strcat(desc, buf, max); } /* End sentence. Go to next line. */ my_strcat(desc, ". ", max); } /* Clear a listing variable. */ attr_num = 0; /* Special processing for two "survival resists" */ if (of_has(flags, OF_FEARLESS)) attr_num++; if (of_has(flags, OF_SEEING)) attr_num++; if (of_has(flags, OF_FEARLESS)) { my_strcat(desc, "You are fearless", max); if (attr_num == 1) my_strcat(desc, ". ", max); else my_strcat(desc, ", and", max); } if (of_has(flags, OF_SEEING)) { if ((attr_num > 1) && (of_has(flags, OF_FEARLESS))) my_strcat(desc, " can not be blinded. ", max); else my_strcat(desc, "You can not be blinded. ", max); } /* Miscellaneous abilities. */ if ((of_has(flags, OF_SLOW_DIGEST)) || (of_has(flags, OF_FEATHER)) || (of_has(flags, OF_LIGHT)) || (of_has(flags, OF_REGEN)) || (of_has(flags, OF_TELEPATHY)) || (of_has(flags, OF_SEE_INVIS)) || (of_has(flags, OF_FREE_ACT)) || (of_has(flags, OF_HOLD_LIFE))) { /* Clear number of items to list, and items listed. */ attr_num = 0; attr_listed = 0; /* How many attributes need to be listed? */ if (of_has(flags, OF_SLOW_DIGEST)) attr_num++; if (of_has(flags, OF_FEATHER)) attr_num++; if (of_has(flags, OF_LIGHT)) attr_num++; if (of_has(flags, OF_REGEN)) attr_num++; if (of_has(flags, OF_TELEPATHY)) attr_num++; if (of_has(flags, OF_SEE_INVIS)) attr_num++; if (of_has(flags, OF_FREE_ACT)) attr_num++; if (of_has(flags, OF_HOLD_LIFE)) attr_num++; my_strcat(desc, "You", max); /* Loop for number of attributes in this group. */ for (j = 0; j < 8; j++) { bool list_ok = FALSE; if ((j == 0) && (of_has(flags, OF_SLOW_DIGEST))) list_ok = TRUE; if ((j == 1) && (of_has(flags, OF_FEATHER))) list_ok = TRUE; if ((j == 2) && (of_has(flags, OF_LIGHT))) list_ok = TRUE; if ((j == 3) && (of_has(flags, OF_REGEN))) list_ok = TRUE; if ((j == 4) && (of_has(flags, OF_TELEPATHY))) list_ok = TRUE; if ((j == 5) && (of_has(flags, OF_SEE_INVIS))) list_ok = TRUE; if ((j == 6) && (of_has(flags, OF_FREE_ACT))) list_ok = TRUE; if ((j == 7) && (of_has(flags, OF_HOLD_LIFE))) list_ok = TRUE; if (!list_ok) continue; /* Listing another attribute. */ attr_listed++; /* Commas separate members of a list of more than two. */ if ((attr_num > 2) && (attr_listed > 1)) my_strcat(desc, ",", max); /* "and" before final member of a list of more than one. */ if ((attr_num > 1) && (j != 0)) { if (attr_num == attr_listed) my_strcat(desc, " and", max); } /* List the attribute description, in its proper place. */ if (j == 0) my_strcat(desc, " digest slowly", max); if (j == 1) my_strcat(desc, " falling gently", max); if (j == 2) my_strcat(desc, " glow with permanent light", max); if (j == 3) my_strcat(desc, " regenerative quickly", max); if (j == 4) my_strcat(desc, " have telepathic powers", max); if (j == 5) my_strcat(desc, " can see invisible monsters", max); if (j == 6) my_strcat(desc, " are immune to paralysis", max); if (j == 7) my_strcat(desc, " are resistant to life draining", max); } /* End sentence. Go to next line. */ my_strcat(desc, ".", max); } }
/** * Carry an object and delete it. */ extern void py_pickup_aux(int o_idx, bool msg) { int slot, quiver_slot = 0; char o_name[120]; object_type *o_ptr = &o_list[o_idx]; object_type *i_ptr = &p_ptr->inventory[INVEN_LIGHT]; bitflag f[OF_SIZE], obvious_mask[OF_SIZE]; flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); of_copy(f, o_ptr->flags_obj); /* Carry the object */ slot = inven_carry(p_ptr, o_ptr); /* Handle errors (paranoia) */ if (slot < 0) return; /* If we have picked up ammo which matches something in the quiver, note * that it so that we can wield it later (and suppress pick up message) */ if (obj_is_quiver_obj(o_ptr)) { int i; for (i = QUIVER_START; i < QUIVER_END; i++) { if (!p_ptr->inventory[i].k_idx) continue; if (!object_similar(&p_ptr->inventory[i], o_ptr, OSTACK_QUIVER)) continue; quiver_slot = i; break; } } /* Get the object again */ o_ptr = &p_ptr->inventory[slot]; /* Set squelch status */ p_ptr->notice |= PN_SQUELCH; /* Stone of Lore gives id on pickup */ if (!object_known_p(o_ptr)) { if (i_ptr->sval == SV_STONE_LORE) identify_object(o_ptr); /* Otherwise pseudo-ID */ else { bool heavy = FALSE; int feel; /* Heavy sensing */ heavy = (player_has(PF_PSEUDO_ID_HEAVY)); /* Type of feeling */ feel = (heavy ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr)); /* We have "felt" it */ o_ptr->ident |= (IDENT_SENSE); /* Inscribe it textually */ o_ptr->feel = feel; /* Set squelch flag as appropriate */ p_ptr->notice |= PN_SQUELCH; } } /* Log artifacts if found */ if (artifact_p(o_ptr)) history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE); /* Notice dice and other obvious stuff */ notice_other(IF_DD_DS, slot + 1); (void) of_inter(f, obvious_mask); of_union(o_ptr->id_obj, f); /* Average things are average */ if ((o_ptr->feel == FEEL_AVERAGE) && (is_weapon(o_ptr) || is_armour(o_ptr))){ notice_other(IF_AC, slot + 1); notice_other(IF_TO_A, slot + 1); notice_other(IF_TO_H, slot + 1); notice_other(IF_TO_D, slot + 1); } /* Recalculate the bonuses */ p_ptr->update |= (PU_BONUS); /* Optionally, display a message */ if (msg && !quiver_slot) { /* Describe the object */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Message */ msg_format("You have %s (%c).", o_name, index_to_label(slot)); } /* Delete the object */ delete_object_idx(o_idx); /* If we have a quiver slot that this item matches, use it */ if (quiver_slot) wield_item(o_ptr, slot, quiver_slot); }
/** * Complete object creation by applying magic to it. * * Magic includes rolling for random bonuses, applying flags to ego-items, * charging charged items, fuelling lights, and trapping chests. * * The `good` argument forces the item to be at least `good`, and the `great` * argument does likewise. Setting `allow_artifacts` to TRUE allows artifacts * to be created here. * * If `good` or `great` are not set, then the `lev` argument controls the * quality of item. See the function itself for the specifics of the * calculations involved. */ void apply_magic(object_type *o_ptr, int lev, bool allow_artifacts, bool good, bool great) { int power = 0; /*u32b xtra = 0;*/ /*bool new = FALSE;*/ /* Chance of being `good` and `great` */ int good_chance = (lev+2) * 3; int great_chance = MIN(lev/4 + lev, 50); /* Limit depth */ if (lev > MAX_DEPTH - 1) lev = MAX_DEPTH - 1; /* Roll for "good" */ if (good || (randint0(100) < good_chance)) { /* Assume "good" */ power = 1; /* Roll for "great" */ if (great || (randint0(100) < great_chance)) power = 2; } /* Roll for "cursed" */ else if (randint0(100) < good_chance) { /* Assume "cursed" */ power = -1; /* Roll for "broken" */ if (randint0(100) < great_chance) power = -2; } /* Roll for artifact creation */ if (allow_artifacts) { int i; int rolls = 0; /* Get one roll if excellent */ if (power >= 2) rolls = 1; /* Get four rolls if forced great */ if (great) rolls = 4; /* Roll for artifacts if allowed */ for (i = 0; i < rolls; i++) { if (make_artifact(o_ptr)) return; } } /* Apply magic */ switch (o_ptr->tval) { case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_BOW: case TV_SHOT: case TV_ARROW: case TV_BOLT: { if (power == 2 || power == -2) { int ego_power; ego_power = make_ego_item(o_ptr, lev, (bool)(power > 0)); if (ego_power) power = ego_power; } if (power) a_m_aux_1(o_ptr, lev, power); break; } case TV_DRAG_ARMOR: case TV_HARD_ARMOR: case TV_SOFT_ARMOR: case TV_SHIELD: case TV_HELM: case TV_CROWN: case TV_CLOAK: case TV_GLOVES: case TV_BOOTS: { if (power == 2 || power == -2) { int ego_power; ego_power = make_ego_item(o_ptr, lev, (bool)(power > 0)); if (ego_power) power = ego_power; } if (power) a_m_aux_2(o_ptr, lev, power); break; } case TV_RING: case TV_AMULET: { if (!power && (randint0(100) < 50)) power = -1; a_m_aux_3(o_ptr, lev, power); break; } case TV_LIGHT: { if (power == 2 || power == -2) make_ego_item(o_ptr, lev, (bool)(power > 0)); /* Fuel it */ a_m_aux_4(o_ptr, lev, power); break; } default: { a_m_aux_4(o_ptr, lev, power); break; } } /* Hack -- analyze ego-items */ if (o_ptr->name2) { ego_item_type *e_ptr = &e_info[o_ptr->name2]; bitflag flags[OF_SIZE]; object_flags(o_ptr, flags); /* Extra powers */ if (e_ptr->xtra == OBJECT_XTRA_TYPE_SUSTAIN) of_on(o_ptr->flags, get_new_attr(flags, ego_sustains, N_ELEMENTS(ego_sustains))); else if (e_ptr->xtra == OBJECT_XTRA_TYPE_RESIST) of_on(o_ptr->flags, get_new_attr(flags, ego_resists, N_ELEMENTS(ego_resists))); else if (e_ptr->xtra == OBJECT_XTRA_TYPE_POWER) of_on(o_ptr->flags, get_new_attr(flags, ego_powers, N_ELEMENTS(ego_powers))); /* Hack -- acquire "cursed" flags */ if (cursed_p(e_ptr)) { bitflag curse_flags[OF_SIZE]; of_copy(curse_flags, e_ptr->flags); flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END); of_union(o_ptr->flags, curse_flags); } /* Hack -- apply extra penalties if needed */ if (cursed_p(o_ptr)) { /* Apply extra ego bonuses */ o_ptr->to_h -= randcalc(e_ptr->to_h, lev, RANDOMISE); o_ptr->to_d -= randcalc(e_ptr->to_d, lev, RANDOMISE); o_ptr->to_a -= randcalc(e_ptr->to_a, lev, RANDOMISE); /* Apply ego pval */ o_ptr->pval -= randcalc(e_ptr->pval, lev, RANDOMISE); /* Apply minimums */ if (o_ptr->to_h > -1 * e_ptr->min_to_h) o_ptr->to_h = -1 * e_ptr->min_to_h; if (o_ptr->to_d > -1 * e_ptr->min_to_d) o_ptr->to_d = -1 * e_ptr->min_to_d; if (o_ptr->to_a > -1 * e_ptr->min_to_a) o_ptr->to_a = -1 * e_ptr->min_to_a; if (o_ptr->pval > -1 * e_ptr->min_pval) o_ptr->pval = -1 * e_ptr->min_pval; } /* Hack -- apply extra bonuses if needed */ else { /* Apply extra ego bonuses */ o_ptr->to_h += randcalc(e_ptr->to_h, lev, RANDOMISE); o_ptr->to_d += randcalc(e_ptr->to_d, lev, RANDOMISE); o_ptr->to_a += randcalc(e_ptr->to_a, lev, RANDOMISE); /* Apply ego pval */ o_ptr->pval += randcalc(e_ptr->pval, lev, RANDOMISE); /* Apply minimums */ if (o_ptr->to_h < e_ptr->min_to_h) o_ptr->to_h = e_ptr->min_to_h; if (o_ptr->to_d < e_ptr->min_to_d) o_ptr->to_d = e_ptr->min_to_d; if (o_ptr->to_a < e_ptr->min_to_a) o_ptr->to_a = e_ptr->min_to_a; if (o_ptr->pval < e_ptr->min_pval) o_ptr->pval = e_ptr->min_pval; } /* Hack -- apply rating bonus */ rating += e_ptr->rating; /* Cheat -- describe the item */ if (OPT(cheat_peek)) object_mention(o_ptr); /* Done */ return; } /* Examine real objects */ if (o_ptr->k_idx) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; /* Hack -- acquire "cursed" flag */ if (cursed_p(k_ptr)) { bitflag curse_flags[OF_SIZE]; of_copy(curse_flags, k_ptr->flags); flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END); of_union(o_ptr->flags, curse_flags); } } }
/** * Apply an affix to an ego-item, checking minima as we go. * * \param o_ptr is the object we're modifying * \param level is the generation level * \param affix is the affix we're applying */ void ego_apply_magic(object_type *o_ptr, int level, int affix) { int i, j, flag, pval, amt; bitflag flags[OF_SIZE], f2[OF_SIZE]; ego_item_type *ego; ego = &e_info[affix]; /* Random powers */ for (i = 0; i < ego->num_randlines; i++) for (j = 0; j < ego->num_randflags[i]; j++) of_on(o_ptr->flags, get_new_attr(o_ptr->flags, ego->randmask[i])); /* Apply extra combat bonuses */ amt = randcalc(ego->to_h, level, RANDOMISE); o_ptr->to_h += amt; if (ego->min_to_h != NO_MINIMUM) { if (amt < ego->min_to_h) o_ptr->to_h += ego->min_to_h - amt; if (o_ptr->to_h < ego->min_to_h) o_ptr->to_h = ego->min_to_h; } amt = randcalc(ego->to_d, level, RANDOMISE); o_ptr->to_d += amt; if (ego->min_to_d != NO_MINIMUM) { if (amt < ego->min_to_d) o_ptr->to_d += ego->min_to_d - amt; if (o_ptr->to_d < ego->min_to_d) o_ptr->to_d = ego->min_to_d; } amt = randcalc(ego->to_a, level, RANDOMISE); o_ptr->to_a += amt; if (ego->min_to_a != NO_MINIMUM) { if (amt < ego->min_to_a) o_ptr->to_a += ego->min_to_a - amt; if (o_ptr->to_a < ego->min_to_a) o_ptr->to_a = ego->min_to_a; } /* Apply pvals */ of_copy(f2, ego->flags); for (i = 0; i < ego->num_pvals; i++) { of_copy(flags, ego->pval_flags[i]); pval = randcalc(ego->pval[i], level, RANDOMISE); if (ego->min_pval[i] != NO_MINIMUM && pval < ego->min_pval[i]) pval = ego->min_pval[i]; for (flag = of_next(flags, FLAG_START); flag != FLAG_END; flag = of_next(flags, flag + 1)) /* Prevent phantom flags, and check minima after adding */ if (pval) { object_add_pval(o_ptr, pval, flag); if (ego->min_pval[i] != NO_MINIMUM && of_has(o_ptr->flags, flag)) if (o_ptr->pval[which_pval(o_ptr, flag)] < ego->min_pval[i]) object_add_pval(o_ptr, ego->min_pval[i] - o_ptr->pval[which_pval(o_ptr, flag)], flag); } else of_off(f2, flag); } /* Apply remaining flags */ of_union(o_ptr->flags, f2); /* Adjust AC, weight, dice and sides */ if (o_ptr->ac && ego->ac_mod) o_ptr->ac = ((100 + ego->ac_mod) * o_ptr->ac) / 100; o_ptr->weight = ((100 + ego->wgt_mod) * o_ptr->weight) / 100; o_ptr->dd += ego->dd; if (o_ptr->dd < 1) o_ptr->dd = 1; o_ptr->ds += ego->ds; if (o_ptr->ds < 1) o_ptr->ds = 1; /* Tidy up and de-duplicate flags, and set the correct prefix/suffix */ check_flags(o_ptr); obj_affix_names(o_ptr); return; }
bool wiz_create_item_subaction(menu_type * m, const ui_event * e, int oid) { int *choices = menu_priv(m); object_type *i_ptr; object_type object_type_body; /* Artifacts */ if (choose_artifact) { int i; int o_idx; artifact_type *a_ptr = &a_info[choices[oid]]; /* Get the artifact info */ //a_ptr = &a_info[choices[oid]]; /* Ignore "empty" artifacts */ if (!a_ptr->name) return TRUE; /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* Acquire the "kind" index */ o_idx = lookup_kind(a_ptr->tval, a_ptr->sval); /* Create the base object */ object_prep(i_ptr, o_idx, RANDOMISE); /* Mark the object as an artifact. */ i_ptr->name1 = choices[oid]; /* Extract the fields */ i_ptr->pval = a_ptr->pval; i_ptr->ac = a_ptr->ac; i_ptr->dd = a_ptr->dd; i_ptr->ds = a_ptr->ds; i_ptr->to_a = a_ptr->to_a; i_ptr->to_h = a_ptr->to_h; i_ptr->to_d = a_ptr->to_d; i_ptr->weight = a_ptr->weight; of_copy(i_ptr->flags_obj, a_ptr->flags_obj); cf_copy(i_ptr->flags_curse, a_ptr->flags_curse); for (i = 0; i < MAX_P_RES; i++) i_ptr->percent_res[i] = a_ptr->percent_res[i]; for (i = 0; i < A_MAX; i++) i_ptr->bonus_stat[i] = a_ptr->bonus_stat[i]; for (i = 0; i < MAX_P_BONUS; i++) i_ptr->bonus_other[i] = a_ptr->bonus_other[i]; for (i = 0; i < MAX_P_SLAY; i++) i_ptr->multiple_slay[i] = a_ptr->multiple_slay[i]; for (i = 0; i < MAX_P_BRAND; i++) i_ptr->multiple_brand[i] = a_ptr->multiple_brand[i]; /* Transfer the activation information. */ if (a_ptr->effect) i_ptr->effect = a_ptr->effect; } /* Regular objects */ else { object_kind *kind = &k_info[choices[oid]]; if (e->type != EVT_SELECT) return TRUE; /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* Create the item */ object_prep(i_ptr, kind->kidx, RANDOMISE); /* Apply magic (no messages, no artifacts) */ apply_magic(i_ptr, p_ptr->danger, FALSE, FALSE, FALSE); /* Hack -- Since treasure objects are not effected by apply_magic, they * need special processing. */ if (i_ptr->tval == TV_GOLD) { i_ptr->pval = kind->cost / 2 + randint1((kind->cost + 1) / 2); } /* Mark as cheat, and where created */ i_ptr->origin = ORIGIN_CHEAT; i_ptr->origin_z = chunk_list[p_ptr->stage].z_pos; i_ptr->origin_y = chunk_list[p_ptr->stage].y_pos; i_ptr->origin_x = chunk_list[p_ptr->stage].x_pos; } /* Drop from heaven */ drop_near(i_ptr, -1, p_ptr->py, p_ptr->px, TRUE); /* All done */ msg("Allocated."); return FALSE; }
/** * Calculate the rating for a given slay combination */ static s32b slay_power(const object_type *o_ptr, int verbose, ang_file* log_file, bool known) { bitflag s_index[OF_SIZE], f[OF_SIZE], f2[OF_SIZE]; u32b sv = 0; int i, j; int mult; const struct slay *best_s_ptr = NULL; monster_race *r_ptr; monster_type *m_ptr; monster_type monster_type_body; const char *desc[SL_MAX] = { 0 }, *brand[SL_MAX] = { 0 }; int s_mult[SL_MAX] = { 0 }; if (known) object_flags(o_ptr, f); else object_flags_known(o_ptr, f); /* Combine the slay bytes into an index value, return if there are none */ of_copy(s_index, f); create_mask(f2, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX); if (!of_is_inter(s_index, f2)) return tot_mon_power; else of_inter(s_index, f2); /* Look in the cache to see if we know this one yet */ sv = check_slay_cache(s_index); /* If it's cached (or there are no slays), return the value */ if (sv) { file_putf(log_file, "Slay cache hit\n"); return sv; } /* * Otherwise we need to calculate the expected average multiplier * for this combination (multiplied by the total number of * monsters, which we'll divide out later). */ for (i = 0; i < z_info->r_max; i++) { best_s_ptr = NULL; mult = 1; r_ptr = &r_info[i]; m_ptr = &monster_type_body; m_ptr->r_idx = i; /* Find the best multiplier against this monster */ improve_attack_modifier((object_type *)o_ptr, m_ptr, &best_s_ptr, FALSE, !known); if (best_s_ptr) mult = best_s_ptr->mult; /* Add the multiple to sv */ sv += mult * r_ptr->scaled_power; } /* * To get the expected damage for this weapon, multiply the * average damage from base dice by sv, and divide by the * total number of monsters. */ if (verbose) { /* Write info about the slay combination and multiplier */ file_putf(log_file, "Slay multiplier for: "); j = list_slays(s_index, s_index, desc, brand, s_mult, FALSE); for (i = 0; i < j; i++) { if (brand[i]) { file_putf(log_file, brand[i]); } else { file_putf(log_file, desc[i]); } file_putf(log_file, "x%d ", s_mult[i]); } file_putf(log_file, "\nsv is: %d\n", sv); file_putf(log_file, " and t_m_p is: %d \n", tot_mon_power); file_putf(log_file, "times 1000 is: %d\n", (1000 * sv) / tot_mon_power); } /* Add to the cache */ if (fill_slay_cache(s_index, sv)) file_putf(log_file, "Added to slay cache\n"); return sv; }