/** * Apply generation magic to an ego-item. */ void ego_apply_magic(struct object *obj, int level) { int i, x, resist = 0; bitflag newf[OF_SIZE]; /* Extra powers */ if (kf_has(obj->ego->kind_flags, KF_RAND_SUSTAIN)) { create_mask(newf, false, OFT_SUST, OFT_MAX); of_on(obj->flags, get_new_attr(obj->flags, newf)); } else if (kf_has(obj->ego->kind_flags, KF_RAND_POWER)) { create_mask(newf, false, OFT_PROT, OFT_MISC, OFT_MAX); of_on(obj->flags, get_new_attr(obj->flags, newf)); } else if (kf_has(obj->ego->kind_flags, KF_RAND_HI_RES)) /* Get a high resist if available, mark it as random */ if (random_high_resist(obj, &resist)) { obj->el_info[resist].res_level = 1; obj->el_info[resist].flags |= EL_INFO_RANDOM; } /* Apply extra obj->ego bonuses */ obj->to_h += randcalc(obj->ego->to_h, level, RANDOMISE); obj->to_d += randcalc(obj->ego->to_d, level, RANDOMISE); obj->to_a += randcalc(obj->ego->to_a, level, RANDOMISE); /* Apply modifiers */ for (i = 0; i < OBJ_MOD_MAX; i++) { x = randcalc(obj->ego->modifiers[i], level, RANDOMISE); obj->modifiers[i] += x; } /* Apply flags */ of_union(obj->flags, obj->ego->flags); of_diff(obj->flags, obj->ego->flags_off); /* Add slays and brands */ copy_slay(&obj->slays, obj->ego->slays); copy_brand(&obj->brands, obj->ego->brands); /* Add resists */ for (i = 0; i < ELEM_MAX; i++) { /* Take the larger of ego and base object resist levels */ obj->el_info[i].res_level = MAX(obj->ego->el_info[i].res_level, obj->el_info[i].res_level); /* Union of flags so as to know when ignoring is notable */ obj->el_info[i].flags |= obj->ego->el_info[i].flags; } /* Add effect (ego effect will trump object effect, when there are any) */ if (obj->ego->effect) { obj->effect = obj->ego->effect; obj->time = obj->ego->time; } return; }
void set_ego_xtra_power(bitflag flags[OF_SIZE]) { size_t i; for (i = 0; i < N_ELEMENTS(ego_powers); i++) of_on(flags, ego_powers[i]); }
void set_ego_xtra_resist(bitflag flags[OF_SIZE]) { size_t i; for (i = 0; i < N_ELEMENTS(ego_resists); i++) of_on(flags, ego_resists[i]); }
/** * Notice object flags */ void notice_obj(int obj_flag, int item) { object_type *o_ptr; int i; bool already_ego = FALSE; if (item) { if (item > 0) o_ptr = &p_ptr->inventory[item - 1]; else o_ptr = &o_list[0 - item]; already_ego = has_ego_properties(o_ptr); /* Add properties */ if (of_has(o_ptr->flags_obj, obj_flag)) of_on(o_ptr->id_obj, obj_flag); /* Ego item? */ if (already_ego != has_ego_properties(o_ptr)) label_as_ego(o_ptr, item); /* Fully identified now? */ if (known_really(o_ptr)) identify_object(o_ptr); return; } for (i = INVEN_WIELD; i <= INVEN_FEET; i++) { o_ptr = &p_ptr->inventory[i]; already_ego = has_ego_properties(o_ptr); /* Add properties */ if (of_has(o_ptr->flags_obj, obj_flag)) of_on(o_ptr->id_obj, obj_flag); /* Ego item? */ if (already_ego != has_ego_properties(o_ptr)) label_as_ego(o_ptr, item); /* Fully identified now? */ if (known_really(o_ptr)) identify_object(o_ptr); } }
static void refuel_torch(object_type *j_ptr, object_type *o_ptr, int item) { bitflag f[OF_SIZE]; bitflag g[OF_SIZE]; /* Refuel */ j_ptr->timeout += o_ptr->timeout + 5; /* Message */ msg("You combine the torches."); /* Transfer the LIGHT flag if refuelling from a torch with it to one without it */ object_flags(o_ptr, f); object_flags(j_ptr, g); if (of_has(f, OF_LIGHT) && !of_has(g, OF_LIGHT)) { of_on(j_ptr->flags, OF_LIGHT); if (!j_ptr->ego && o_ptr->ego) j_ptr->ego = o_ptr->ego; msg("Your torch shines further!"); } /* Over-fuel message */ if (j_ptr->timeout >= FUEL_TORCH) { j_ptr->timeout = FUEL_TORCH; msg("Your torch is fully fueled."); } /* Refuel message */ else { msg("Your torch glows more brightly."); } /* Decrease the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); } /* Decrease the item (from the floor) */ else { floor_item_increase(0 - item, -1); floor_item_describe(0 - item); floor_item_optimize(0 - item); } /* Recalculate torch */ p_ptr->update |= (PU_TORCH); /* Redraw stuff */ p_ptr->redraw |= (PR_EQUIP); }
void set_ego_xtra_sustain(bitflag flags[OF_SIZE]) { size_t i; of_wipe(flags); for (i = 0; i < N_ELEMENTS(ego_sustains); i++) of_on(flags, ego_sustains[i]); }
/* * Obtain the "flags" for the player as if he was an item */ void player_flags(bitflag f[OF_SIZE]) { /* Add racial flags */ memcpy(f, p_ptr->race->flags, sizeof(p_ptr->race->flags)); /* Some classes become immune to fear at a certain plevel */ if (player_has(PF_BRAVERY_30) && p_ptr->lev >= 30) of_on(f, OF_RES_FEAR); }
/** * Obtain object flags for the player */ void player_flags(struct player *p, bitflag f[OF_SIZE]) { /* Add racial flags */ memcpy(f, p->race->flags, sizeof(p->race->flags)); /* Some classes become immune to fear at a certain plevel */ if (player_has(p, PF_BRAVERY_30) && p->lev >= 30) of_on(f, OF_PROT_FEAR); }
/** * Extract the multiplier from a given object hitting a given monster. * * \param o_ptr is the object being used to attack * \param m_ptr is the monster being attacked * \param best_s_ptr is the best applicable slay_table entry, or NULL if no * slay already known * \param real is whether this is a real attack (where we update lore) or a * simulation (where we don't) * \param known_only is whether we are using all the object flags, or only * the ones we *already* know about */ void improve_attack_modifier(object_type *o_ptr, const monster_type *m_ptr, const struct slay **best_s_ptr, bool real, bool known_only) { monster_race *r_ptr = &r_info[m_ptr->r_idx]; monster_lore *l_ptr = &l_list[m_ptr->r_idx]; bitflag f[OF_SIZE], known_f[OF_SIZE], note_f[OF_SIZE]; int i; object_flags(o_ptr, f); object_flags_known(o_ptr, known_f); for (i = 0; i < SL_MAX; i++) { const struct slay *s_ptr = &slay_table[i]; if ((known_only && !of_has(known_f, s_ptr->object_flag)) || (!known_only && !of_has(f, s_ptr->object_flag))) continue; /* Disallow forbidden off-weapon slays/brands */ if (wield_slot(o_ptr) > INVEN_BOW && wield_slot(o_ptr) < INVEN_TOTAL && !s_ptr->nonweap) continue; /* In a real attack, learn about monster resistance or slay match if: * EITHER the slay flag on the object is known, * OR the monster is vulnerable to the slay/brand */ if (real && (of_has(known_f, s_ptr->object_flag) || (s_ptr->monster_flag && rf_has(r_ptr->flags, s_ptr->monster_flag)) || (s_ptr->resist_flag && !rf_has(r_ptr->flags, s_ptr->resist_flag)) || (s_ptr->vuln_flag && rf_has(r_ptr->flags, s_ptr->vuln_flag)))) { /* notice any brand or slay that would affect monster */ of_wipe(note_f); of_on(note_f, s_ptr->object_flag); object_notice_slays(o_ptr, note_f); if (m_ptr->ml && s_ptr->monster_flag) rf_on(l_ptr->flags, s_ptr->monster_flag); if (m_ptr->ml && s_ptr->resist_flag) rf_on(l_ptr->flags, s_ptr->resist_flag); if (m_ptr->ml && s_ptr->vuln_flag) rf_on(l_ptr->flags, s_ptr->vuln_flag); } /* If the monster doesn't resist or the slay flag matches */ if ((s_ptr->brand && !rf_has(r_ptr->flags, s_ptr->resist_flag)) || (s_ptr->monster_flag && rf_has(r_ptr->flags, s_ptr->monster_flag)) || (s_ptr->vuln_flag && rf_has(r_ptr->flags, s_ptr->vuln_flag))) { /* compare multipliers to determine best attack */ if ((*best_s_ptr == NULL) || ((*best_s_ptr)->mult < s_ptr->mult)) *best_s_ptr = s_ptr; } } }
/* * Hack -- Create a "forged" artifact */ bool make_fake_artifact(object_type *o_ptr, struct artifact *artifact) { int j; object_kind *kind; /* Don't bother with empty artifacts */ if (!artifact->tval) return FALSE; /* Get the "kind" index */ kind = lookup_kind(artifact->tval, artifact->sval); if (!kind) return FALSE; /* Create the artifact */ object_prep(o_ptr, kind, 0, MAXIMISE); /* Save the name */ o_ptr->artifact = artifact; /* Extract the fields */ for (j = 0; j < o_ptr->artifact->num_pvals; j++) o_ptr->pval[j] = o_ptr->artifact->pval[j]; o_ptr->num_pvals = o_ptr->artifact->num_pvals; o_ptr->ac = o_ptr->artifact->ac; o_ptr->dd = o_ptr->artifact->dd; o_ptr->ds = o_ptr->artifact->ds; o_ptr->to_a = o_ptr->artifact->to_a; o_ptr->to_h = o_ptr->artifact->to_h; o_ptr->to_d = o_ptr->artifact->to_d; o_ptr->weight = o_ptr->artifact->weight; /* Hack -- extract the "cursed" flags */ if (of_has(o_ptr->artifact->flags, OF_LIGHT_CURSE)) of_on(o_ptr->flags, OF_LIGHT_CURSE); if (of_has(o_ptr->artifact->flags, OF_HEAVY_CURSE)) of_on(o_ptr->flags, OF_HEAVY_CURSE); if (of_has(o_ptr->artifact->flags, OF_PERMA_CURSE)) of_on(o_ptr->flags, OF_PERMA_CURSE); /* Success */ o_ptr->ident |= IDENT_FAKE; return (TRUE); }
/* * Notice a single flag - returns TRUE if anything new was learned */ bool object_notice_flag(object_type *o_ptr, int flag) { if (!of_has(o_ptr->known_flags, flag)) { of_on(o_ptr->known_flags, flag); /* XXX Eddie don't want infinite recursion if object_check_for_ident sets more flags, * but maybe this will interfere with savefile repair */ object_check_for_ident(o_ptr); event_signal(EVENT_INVENTORY); event_signal(EVENT_EQUIPMENT); return TRUE; } return FALSE; }
/** * 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; }
/* * Prepare an object based on an object kind. * Use the specified randomization aspect */ void object_prep(object_type *o_ptr, int k_idx, int lev, aspect rand_aspect) { object_kind *k_ptr = &k_info[k_idx]; /* Clear the record */ (void)WIPE(o_ptr, object_type); /* Save the kind index */ o_ptr->k_idx = k_idx; /* Efficiency -- tval/sval */ o_ptr->tval = k_ptr->tval; o_ptr->sval = k_ptr->sval; /* Default number */ o_ptr->number = 1; /* Default "pval" */ o_ptr->pval = randcalc(k_ptr->pval, lev, rand_aspect); /* Default weight */ o_ptr->weight = k_ptr->weight; /* Assign charges (wands/staves only) */ if (o_ptr->tval == TV_WAND || o_ptr->tval == TV_STAFF) o_ptr->pval = randcalc(k_ptr->charge, lev, rand_aspect); /* Default magic */ o_ptr->to_h = randcalc(k_ptr->to_h, lev, rand_aspect); o_ptr->to_d = randcalc(k_ptr->to_d, lev, rand_aspect); o_ptr->to_a = randcalc(k_ptr->to_a, lev, rand_aspect); /* Default power */ o_ptr->ac = k_ptr->ac; o_ptr->dd = k_ptr->dd; o_ptr->ds = k_ptr->ds; /* Hack -- cursed items are always "cursed" */ if (of_has(k_ptr->flags, OF_LIGHT_CURSE)) of_on(o_ptr->flags, OF_LIGHT_CURSE); }
/** * Create a "mask" of flags of a specific type or ID threshold. * * \param f is the flag array we're filling * \param id is whether we're masking by ID level * \param ... is the list of flags or ID types we're looking for * * N.B. OFT_MAX must be the last item in the ... list */ void create_mask(bitflag *f, bool id, ...) { const struct object_flag *of_ptr; int i; va_list args; of_wipe(f); va_start(args, id); /* Process each type in the va_args */ for (i = va_arg(args, int); i != OFT_MAX; i = va_arg(args, int)) { for (of_ptr = object_flag_table; of_ptr->index < OF_MAX; of_ptr++) if ((id && of_ptr->id == i) || (!id && of_ptr->type == i)) of_on(f, of_ptr->index); } va_end(args); return; }
/** * Create a "mask" of object flags of a specific type or ID threshold. * * \param f is the flag array we're filling * \param id is whether we're masking by ID level * \param ... is the list of flags or ID types we're looking for * * N.B. OFT_MAX must be the last item in the ... list */ void create_obj_flag_mask(bitflag *f, bool id, ...) { int i, j; va_list args; of_wipe(f); va_start(args, id); /* Process each type in the va_args */ for (i = va_arg(args, int); i != OFT_MAX; i = va_arg(args, int)) { for (j = 1; j < z_info->property_max; j++) { struct obj_property *prop = &obj_properties[j]; if (prop->type != OBJ_PROPERTY_FLAG) continue; if ((id && prop->id_type == i) || (!id && prop->subtype == i)) { of_on(f, prop->index); } } } va_end(args); return; }
static void display_resistance_panel(const struct player_flag_record *resists, size_t size, const region *bounds) { size_t i; int j; int col = bounds->col; int row = bounds->row; Term_putstr(col, row++, RES_COLS, TERM_WHITE, " @abcdefghijklmnopqrstuvwxyz{|}"); for (i = 0; i < size-3; i++, row++) { byte name_attr = TERM_WHITE; Term_gotoxy(col+6, row); /* repeated extraction of flags is inefficient but more natural */ for (j = INVEN_WIELD - 1; j < INVEN_TOTAL; j++) { if (((j >= INVEN_WIELD) && (j < INVEN_WIELD + rp_ptr->melee_slots)) || ((j >= INVEN_BOW) && (j < INVEN_BOW + rp_ptr->range_slots)) || ((j >= INVEN_FINGER) && (j < INVEN_FINGER + rp_ptr->ring_slots)) || ((j >= INVEN_NECK) && (j < INVEN_NECK + rp_ptr->amulet_slots)) || ((j >= INVEN_LIGHT) && (j < INVEN_LIGHT + rp_ptr->light_slots)) || ((j >= INVEN_BODY) && (j < INVEN_BODY + rp_ptr->body_slots)) || ((j >= INVEN_OUTER) && (j < INVEN_OUTER + rp_ptr->cloak_slots)) || ((j >= INVEN_ARM) && (j < INVEN_ARM + rp_ptr->shield_slots)) || ((j >= INVEN_HEAD) && (j < INVEN_HEAD + rp_ptr->helm_slots)) || ((j >= INVEN_HANDS) && (j < INVEN_HANDS + rp_ptr->glove_slots)) || ((j >= INVEN_FEET) && (j < INVEN_FEET + rp_ptr->boot_slots)) || (j == INVEN_WIELD - 1)) { object_type *o_ptr = &p_ptr->inventory[j]; bitflag f[OF_SIZE]; byte attr = TERM_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res, imm, vuln; /* Wipe flagset */ of_wipe(f); if (j < INVEN_WIELD) { player_flags(f); /* If the race has innate infravision/digging, force the corresponding flag here. If we set it in player_flags(), then all callers of that function will think the infravision is caused by equipment. */ if (rp_ptr->infra > 0) of_on(f, OF_INFRA); if (rp_ptr->r_skills[SKILL_DIGGING] > 0) of_on(f, OF_TUNNEL); } else if (j < INVEN_TOTAL && o_ptr->k_idx) { object_flags_known(o_ptr, f); } res = of_has(f, resists[i].res_flag); imm = of_has(f, resists[i].im_flag); vuln = of_has(f, resists[i].vuln_flag); if (imm) name_attr = TERM_GREEN; else if (res && name_attr == TERM_WHITE) name_attr = TERM_L_BLUE; if (vuln) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if ((j < INVEN_TOTAL) && o_ptr->k_idx && !object_flag_is_known(o_ptr, resists[i].res_flag)) sym = '?'; Term_addch(attr, sym); } } Term_putstr(col, row, 6, name_attr, format("%5s:", resists[i].name)); } Term_putstr(col, row++, RES_COLS, TERM_WHITE, " @abcdefghijklmnopqrstuvwxyz{|}"); /* Equippy */ display_player_equippy(row++, col+7); }
/* XXX Eddie should messages be adhoc all over the place? perhaps the main * loop should check for change in inventory/wieldeds and all messages be * printed from one place */ void object_notice_on_wield(object_type *o_ptr) { bitflag f[OF_SIZE], obvious_mask[OF_SIZE]; bool obvious = FALSE; const slay_t *s_ptr; flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); /* Save time of wield for later */ object_last_wield = turn; /* Only deal with un-ID'd items */ if (object_is_known(o_ptr)) return; /* Wear it */ object_flavor_tried(o_ptr); if (object_add_ident_flags(o_ptr, IDENT_WORN)) object_check_for_ident(o_ptr); if (obj_is_light(o_ptr) && ego_item_p(o_ptr)) object_notice_ego(o_ptr); if (object_flavor_is_aware(o_ptr) && easy_know(o_ptr)) { object_notice_everything(o_ptr); return; } /* Automatically sense artifacts upon wield */ object_sense_artifact(o_ptr); /* Note artifacts when found */ if (artifact_p(o_ptr)) history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE); /* special case FA, needed at least for mages wielding gloves */ if (object_FA_would_be_obvious(o_ptr)) of_on(obvious_mask, OF_FREE_ACT); /* Learn about obvious flags */ of_union(o_ptr->known_flags, obvious_mask); /* Extract the flags */ object_flags(o_ptr, f); /* Find obvious things (disregarding curses) */ flags_clear(obvious_mask, OF_SIZE, OF_CURSE_MASK, FLAG_END); if (of_is_inter(f, obvious_mask)) obvious = TRUE; flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); /* XXX Eddie should these next NOT call object_check_for_ident due to worries about repairing? */ /* XXX Eddie this is a small hack, but jewelry with anything noticeable really is obvious */ /* XXX Eddie learn =soulkeeping vs =bodykeeping when notice sustain_str */ if (object_is_jewelry(o_ptr)) { /* Learn the flavor of jewelry with obvious flags */ if (EASY_LEARN && obvious) object_flavor_aware(o_ptr); /* Learn all flags on any aware non-artifact jewelry */ if (object_flavor_is_aware(o_ptr) && !artifact_p(o_ptr)) object_know_all_flags(o_ptr); } object_check_for_ident(o_ptr); if (!obvious) return; /* Messages */ for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++) { if (of_has(f, s_ptr->slay_flag) && s_ptr->brand) { char o_name[40]; object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE); msg_format("Your %s %s!", o_name, s_ptr->active_verb); } } /* XXX Eddie need to add stealth here, also need to assert/double-check everything is covered */ if (of_has(f, OF_STR)) msg_format("You feel %s!", o_ptr->pval > 0 ? "stronger" : "weaker"); if (of_has(f, OF_INT)) msg_format("You feel %s!", o_ptr->pval > 0 ? "smarter" : "more stupid"); if (of_has(f, OF_WIS)) msg_format("You feel %s!", o_ptr->pval > 0 ? "wiser" : "more naive"); if (of_has(f, OF_DEX)) msg_format("You feel %s!", o_ptr->pval > 0 ? "more dextrous" : "clumsier"); if (of_has(f, OF_CON)) msg_format("You feel %s!", o_ptr->pval > 0 ? "healthier" : "sicklier"); if (of_has(f, OF_CHR)) msg_format("You feel %s!", o_ptr->pval > 0 ? "cuter" : "uglier"); if (of_has(f, OF_SPEED)) msg_format("You feel strangely %s.", o_ptr->pval > 0 ? "quick" : "sluggish"); if (flags_test(f, OF_SIZE, OF_BLOWS, OF_SHOTS, FLAG_END)) msg_format("Your hands %s", o_ptr->pval > 0 ? "tingle!" : "ache."); if (of_has(f, OF_INFRA)) msg_format("Your eyes tingle."); if (of_has(f, OF_LIGHT)) msg_print("It glows!"); if (of_has(f, OF_TELEPATHY)) msg_print("Your mind feels strangely sharper!"); /* WARNING -- masking f by obvious mask -- this should be at the end of this function */ flags_mask(f, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); /* learn the ego on any obvious brand or slay */ if (EASY_LEARN && ego_item_p(o_ptr) && obvious && flags_test(f, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END)) object_notice_ego(o_ptr); /* Remember the flags */ object_notice_sensing(o_ptr); /* XXX Eddie should we check_for_ident here? */ }
/** * 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; }
static void display_resistance_panel(const struct player_flag_record *resists, size_t size, const region *bounds) { size_t i, j; int col = bounds->col; int row = bounds->row; Term_putstr(col, row++, RES_COLS, TERM_WHITE, " abcdefghijkl@"); for (i = 0; i < size-3; i++, row++) { byte name_attr = TERM_WHITE; Term_gotoxy(col+6, row); /* repeated extraction of flags is inefficient but more natural */ for (j = INVEN_WIELD; j <= INVEN_TOTAL; j++) { object_type *o_ptr = &p_ptr->inventory[j]; bitflag f[OF_SIZE]; byte attr = TERM_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res, imm, vuln; /* Wipe flagset */ of_wipe(f); if (j < INVEN_TOTAL && o_ptr->kind) { object_flags_known(o_ptr, f); } else if (j == INVEN_TOTAL) { player_flags(f); /* If the race has innate infravision/digging, force the corresponding flag here. If we set it in player_flags(), then all callers of that function will think the infravision is caused by equipment. */ if (p_ptr->race->infra > 0) of_on(f, OF_INFRA); if (p_ptr->race->r_skills[SKILL_DIGGING] > 0) of_on(f, OF_TUNNEL); } res = of_has(f, resists[i].res_flag); imm = of_has(f, resists[i].im_flag); vuln = of_has(f, resists[i].vuln_flag); if (imm) name_attr = TERM_GREEN; else if (res && name_attr == TERM_WHITE) name_attr = TERM_L_BLUE; if (vuln) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if ((j < INVEN_TOTAL) && o_ptr->kind && !object_flag_is_known(o_ptr, resists[i].res_flag)) sym = '?'; Term_addch(attr, sym); } Term_putstr(col, row, 6, name_attr, format("%5s:", resists[i].name)); } Term_putstr(col, row++, RES_COLS, TERM_WHITE, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col+6); }
/** * 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 magic to an item known to be a "ring" or "amulet" * * Hack -- note special rating boost for ring of speed * Hack -- note special rating boost for certain amulets * Hack -- note special "pval boost" code for ring of speed * Hack -- note that some items must be cursed (or blessed) */ static void a_m_aux_3(object_type *o_ptr, int level, int power) { /* Apply curses */ if (power < 0) { /* Rings */ if (o_ptr->tval == TV_RING) { switch (o_ptr->sval) { case SV_RING_STRENGTH: case SV_RING_CONSTITUTION: case SV_RING_DEXTERITY: case SV_RING_INTELLIGENCE: case SV_RING_SEARCHING: case SV_RING_DAMAGE: case SV_RING_ACCURACY: case SV_RING_PROTECTION: case SV_RING_SLAYING: { o_ptr->pval = -o_ptr->pval; o_ptr->to_h = -o_ptr->to_h; o_ptr->to_d = -o_ptr->to_d; o_ptr->to_a = -o_ptr->to_a; of_on(o_ptr->flags, OF_LIGHT_CURSE); break; } } } /* Amulets */ else if (o_ptr->tval == TV_AMULET) { switch (o_ptr->sval) { case SV_AMULET_WISDOM: case SV_AMULET_CHARISMA: case SV_AMULET_INFRAVISION: case SV_AMULET_SEARCHING: { o_ptr->pval = -o_ptr->pval; o_ptr->to_h = -o_ptr->to_h; o_ptr->to_d = -o_ptr->to_d; o_ptr->to_a = -o_ptr->to_a; of_on(o_ptr->flags, OF_LIGHT_CURSE); break; } } } } /* Apply magic (good or bad) according to type */ switch (o_ptr->tval) { case TV_RING: { /* Analyze */ switch (o_ptr->sval) { case SV_RING_SPEED: { /* Super-charge the ring */ while (randint0(100) < 50) o_ptr->pval++; if (power >= 0) { /* Rating boost */ rating += 25; /* Mention the item */ if (OPT(cheat_peek)) object_mention(o_ptr); } break; } } break; } case TV_AMULET: { /* Analyze */ switch (o_ptr->sval) { case SV_AMULET_THE_MAGI: case SV_AMULET_DEVOTION: case SV_AMULET_WEAPONMASTERY: case SV_AMULET_TRICKERY: { /* Boost the rating */ rating += 25; /* Mention the item */ if (OPT(cheat_peek)) object_mention(o_ptr); break; } } break; } } }