/* * Checks for additional knowledge implied by what the player already knows. * * \param o_ptr is the object to check * * returns whether it calls object_notice_everyting */ bool object_check_for_ident(object_type *o_ptr) { bitflag flags[OF_SIZE], known_flags[OF_SIZE]; object_flags(o_ptr, flags); object_flags_known(o_ptr, known_flags); /* Some flags are irrelevant or never learned or too hard to learn */ flags_clear(flags, OF_SIZE, OF_OBJ_ONLY_MASK, FLAG_END); flags_clear(known_flags, OF_SIZE, OF_OBJ_ONLY_MASK, FLAG_END); if (!of_is_equal(flags, known_flags)) return FALSE; /* If we know attack bonuses, and defence bonuses, and effect, then * we effectively know everything, so mark as such */ if ((object_attack_plusses_are_visible(o_ptr) || (object_was_sensed(o_ptr) && o_ptr->to_h == 0 && o_ptr->to_d == 0)) && (object_defence_plusses_are_visible(o_ptr) || (object_was_sensed(o_ptr) && o_ptr->to_a == 0)) && (object_effect_is_known(o_ptr) || !object_effect(o_ptr))) { object_notice_everything(o_ptr); return TRUE; } /* We still know all the flags, so we still know if it's an ego */ else if (ego_item_p(o_ptr)) { /* require worn status so you don't learn launcher of accuracy or gloves of slaying before wield */ if (object_was_worn(o_ptr)) object_notice_ego(o_ptr); } return FALSE; }
static size_t obj_desc_combat(const object_type *o_ptr, char *buf, size_t max, size_t end, bool spoil) { bitflag flags[OF_SIZE]; bitflag flags_known[OF_SIZE]; object_flags(o_ptr, flags); object_flags_known(o_ptr, flags_known); if (of_has(flags, OF_SHOW_DICE)) { /* Only display the real damage dice if the combat stats are known */ if (spoil || object_attack_plusses_are_visible(o_ptr)) strnfcat(buf, max, &end, " (%dd%d)", o_ptr->dd, o_ptr->ds); else strnfcat(buf, max, &end, " (%dd%d)", o_ptr->kind->dd, o_ptr->kind->ds); } if (of_has(flags, OF_SHOW_MULT)) { /* Display shooting power as part of the multiplier */ if (of_has(flags, OF_MIGHT) && (spoil || object_flag_is_known(o_ptr, OF_MIGHT))) strnfcat(buf, max, &end, " (x%d)", (o_ptr->sval % 10) + o_ptr->pval[which_pval(o_ptr, OF_MIGHT)]); else strnfcat(buf, max, &end, " (x%d)", o_ptr->sval % 10); } /* Show weapon bonuses */ if (spoil || object_attack_plusses_are_visible(o_ptr)) { if (wield_slot(o_ptr) == INVEN_WIELD || wield_slot(o_ptr) == INVEN_BOW || obj_is_ammo(o_ptr) || o_ptr->to_d || o_ptr->to_h) { /* Make an exception for body armor with only a to-hit penalty */ if (o_ptr->to_h < 0 && o_ptr->to_d == 0 && (o_ptr->tval == TV_SOFT_ARMOR || o_ptr->tval == TV_HARD_ARMOR || o_ptr->tval == TV_DRAG_ARMOR)) strnfcat(buf, max, &end, " (%+d)", o_ptr->to_h); /* Otherwise, always use the full tuple */ else strnfcat(buf, max, &end, " (%+d,%+d)", o_ptr->to_h, o_ptr->to_d); } } /* Show armor bonuses */ if (spoil || object_defence_plusses_are_visible(o_ptr)) { if (obj_desc_show_armor(o_ptr)) strnfcat(buf, max, &end, " [%d,%+d]", o_ptr->ac, o_ptr->to_a); else if (o_ptr->to_a) strnfcat(buf, max, &end, " [%+d]", o_ptr->to_a); } else if (obj_desc_show_armor(o_ptr)) strnfcat(buf, max, &end, " [%d]", object_was_sensed(o_ptr) ? o_ptr->ac : o_ptr->kind->ac); return end; }
/** * Describe combat properties of an item - damage dice, to-hit, to-dam, armor * class, missile multipler */ static size_t obj_desc_combat(const struct object *obj, char *buf, size_t max, size_t end, bool spoil) { bitflag flags_known[OF_SIZE]; object_flags_known(obj, flags_known); if (kf_has(obj->kind->kind_flags, KF_SHOW_DICE)) { /* Only display the real damage dice if the combat stats are known */ if (spoil || object_attack_plusses_are_visible(obj)) strnfcat(buf, max, &end, " (%dd%d)", obj->dd, obj->ds); else strnfcat(buf, max, &end, " (%dd%d)", obj->kind->dd, obj->kind->ds); } if (kf_has(obj->kind->kind_flags, KF_SHOW_MULT)) { /* Display shooting power as part of the multiplier */ if ((obj->modifiers[OBJ_MOD_MIGHT] > 0) && (spoil || object_this_mod_is_visible(obj, OBJ_MOD_MIGHT))) strnfcat(buf, max, &end, " (x%d)", obj->pval + obj->modifiers[OBJ_MOD_MIGHT]); else strnfcat(buf, max, &end, " (x%d)", obj->pval); } /* Show weapon bonuses */ if (spoil || object_attack_plusses_are_visible(obj)) { if (tval_is_weapon(obj) || obj->to_d || obj->to_h) { /* Make an exception for body armor with only a to-hit penalty */ if (obj->to_h < 0 && obj->to_d == 0 && tval_is_body_armor(obj)) strnfcat(buf, max, &end, " (%+d)", obj->to_h); /* Otherwise, always use the full tuple */ else strnfcat(buf, max, &end, " (%+d,%+d)", obj->to_h, obj->to_d); } } /* Show armor bonuses */ if (spoil || object_defence_plusses_are_visible(obj)) { if (obj_desc_show_armor(obj)) strnfcat(buf, max, &end, " [%d,%+d]", obj->ac, obj->to_a); else if (obj->to_a) strnfcat(buf, max, &end, " [%+d]", obj->to_a); } else if (obj_desc_show_armor(obj)) strnfcat(buf, max, &end, " [%d]", object_was_sensed(obj) ? obj->ac : obj->kind->ac); return end; }
static void object_notice_defence_plusses(object_type *o_ptr) { if (!o_ptr->k_idx) return; if (object_defence_plusses_are_visible(o_ptr)) return; if (object_add_ident_flags(o_ptr, IDENT_DEFENCE)) object_check_for_ident(o_ptr); if (o_ptr->ac || o_ptr->to_a) { char o_name[80]; object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE); message_format(MSG_PSEUDOID, 0, "You know more about the %s you are wearing.", o_name); } p_ptr->update |= (PU_BONUS); event_signal(EVENT_INVENTORY); event_signal(EVENT_EQUIPMENT); }
/** * Return the price of an item including plusses (and charges). * * This function returns the "value" of the given item (qty one). * * Never notice unknown bonuses or properties, including curses, * since that would give the player information they did not have. */ s32b object_value(const object_type *obj, int qty, int verbose) { s32b value; /* Known items use the actual value */ if (object_is_known(obj)) { if (cursed_p((bitflag *)obj->flags)) return (0L); value = object_value_real(obj, qty, verbose, TRUE); } else if (tval_has_variable_power(obj)) { /* Variable power items are assessed by what is known about them */ object_type object_type_body; object_type *j_ptr = &object_type_body; /* Hack -- Felt cursed items */ if (object_was_sensed(obj) && cursed_p((bitflag *)obj->flags)) return (0L); memcpy(j_ptr, obj, sizeof(object_type)); /* give j_ptr only the flags known to be in obj */ object_flags_known(obj, j_ptr->flags); if (!object_attack_plusses_are_visible(obj)) j_ptr->to_h = j_ptr->to_d = 0; if (!object_defence_plusses_are_visible(obj)) j_ptr->to_a = 0; value = object_value_real(j_ptr, qty, verbose, FALSE); } else /* Unknown constant-price items just get a base value */ value = object_value_base(obj) * qty; /* Return the final value */ return (value); }
/* * Determine the squelch level of an object, which is similar to its pseudo. * * The main point is when the value is undetermined given current info, * return the maximum possible value. */ byte squelch_level_of(const object_type *o_ptr) { byte value; bitflag f[OF_SIZE], f2[OF_SIZE]; int i; object_flags_known(o_ptr, f); /* Deal with jewelry specially. */ if (object_is_jewelry(o_ptr)) { /* CC: average jewelry has at least one known positive pval */ for (i = 0; i < o_ptr->num_pvals; i++) if ((object_this_pval_is_visible(o_ptr, i)) && (o_ptr->pval[i] > 0)) return SQUELCH_AVERAGE; if ((o_ptr->to_h > 0) || (o_ptr->to_d > 0) || (o_ptr->to_a > 0)) return SQUELCH_AVERAGE; if ((object_attack_plusses_are_visible(o_ptr) && ((o_ptr->to_h < 0) || (o_ptr->to_d < 0))) || (object_defence_plusses_are_visible(o_ptr) && o_ptr->to_a < 0)) return SQUELCH_BAD; return SQUELCH_AVERAGE; } /* And lights */ if (o_ptr->tval == TV_LIGHT) { create_mask(f2, TRUE, OFID_WIELD, OFT_MAX); if (of_is_inter(f, f2)) return SQUELCH_ALL; if ((o_ptr->to_h > 0) || (o_ptr->to_d > 0) || (o_ptr->to_a > 0)) return SQUELCH_GOOD; if ((o_ptr->to_h < 0) || (o_ptr->to_d < 0) || (o_ptr->to_a < 0)) return SQUELCH_BAD; return SQUELCH_AVERAGE; } /* CC: we need to redefine "bad" with multiple pvals * At the moment we use "all pvals known and negative" */ for (i = 0; i < o_ptr->num_pvals; i++) { if (!object_this_pval_is_visible(o_ptr, i) || (o_ptr->pval[i] > 0)) break; if (i == (o_ptr->num_pvals - 1)) return SQUELCH_BAD; } if (object_was_sensed(o_ptr)) { obj_pseudo_t pseudo = object_pseudo(o_ptr); switch (pseudo) { case INSCRIP_AVERAGE: { value = SQUELCH_AVERAGE; break; } case INSCRIP_EXCELLENT: { /* have to assume splendid until you have tested it */ if (object_was_worn(o_ptr)) { if (object_high_resist_is_possible(o_ptr)) value = SQUELCH_EXCELLENT_NO_SPL; else value = SQUELCH_EXCELLENT_NO_HI; } else { value = SQUELCH_ALL; } break; } case INSCRIP_SPLENDID: value = SQUELCH_ALL; break; case INSCRIP_NULL: case INSCRIP_SPECIAL: value = SQUELCH_MAX; break; /* This is the interesting case */ case INSCRIP_STRANGE: case INSCRIP_MAGICAL: { value = SQUELCH_GOOD; if ((object_attack_plusses_are_visible(o_ptr) || randcalc_valid(o_ptr->kind->to_h, o_ptr->to_h) || randcalc_valid(o_ptr->kind->to_d, o_ptr->to_d)) && (object_defence_plusses_are_visible(o_ptr) || randcalc_valid(o_ptr->kind->to_a, o_ptr->to_a))) { int isgood = is_object_good(o_ptr); if (isgood > 0) { value = SQUELCH_GOOD; } else if (isgood < 0) { value = SQUELCH_BAD; } else { value = SQUELCH_AVERAGE; } } break; } default: /* do not handle any other possible pseudo values */ assert(0); } } else { if (object_was_worn(o_ptr)) value = SQUELCH_EXCELLENT_NO_SPL; /* object would be sensed if it were splendid */ else if (object_is_known_not_artifact(o_ptr)) value = SQUELCH_ALL; else value = SQUELCH_MAX; } return value; }
/** * Determine the ignore level of an object, which is similar to its pseudo. * * The main point is when the value is undetermined given current info, * return the maximum possible value. */ byte ignore_level_of(const struct object *obj) { byte value = 0; bitflag f[OF_SIZE], f2[OF_SIZE]; int i; bool negative_mod = FALSE; object_flags_known(obj, f); /* Deal with jewelry specially. */ if (tval_is_jewelry(obj)) { /* CC: average jewelry has at least one known positive modifier */ for (i = 0; i < OBJ_MOD_MAX; i++) if ((object_this_mod_is_visible(obj, i)) && (obj->modifiers[i] > 0)) return IGNORE_AVERAGE; if ((obj->to_h > 0) || (obj->to_d > 0) || (obj->to_a > 0)) return IGNORE_AVERAGE; if ((object_attack_plusses_are_visible(obj) && ((obj->to_h < 0) || (obj->to_d < 0))) || (object_defence_plusses_are_visible(obj) && obj->to_a < 0)) return IGNORE_BAD; return IGNORE_AVERAGE; } /* And lights */ if (tval_is_light(obj)) { create_mask(f2, TRUE, OFID_WIELD, OFT_MAX); if (of_is_inter(f, f2)) return IGNORE_ALL; if ((obj->to_h > 0) || (obj->to_d > 0) || (obj->to_a > 0)) return IGNORE_GOOD; if ((obj->to_h < 0) || (obj->to_d < 0) || (obj->to_a < 0)) return IGNORE_BAD; return IGNORE_AVERAGE; } /* We need to redefine "bad" * At the moment we use "all modifiers known and negative" */ for (i = 0; i < OBJ_MOD_MAX; i++) { if (!object_this_mod_is_visible(obj, i) || (obj->modifiers[i] > 0)) break; if (obj->modifiers[i] < 0) negative_mod = TRUE; } if ((i == OBJ_MOD_MAX) && negative_mod) return IGNORE_BAD; if (object_was_sensed(obj)) { obj_pseudo_t pseudo = object_pseudo(obj); switch (pseudo) { case INSCRIP_AVERAGE: { value = IGNORE_AVERAGE; break; } case INSCRIP_EXCELLENT: { /* have to assume splendid until you have tested it */ if (object_was_worn(obj)) { if (object_high_resist_is_possible(obj)) value = IGNORE_EXCELLENT_NO_SPL; else value = IGNORE_EXCELLENT_NO_HI; } else { value = IGNORE_ALL; } break; } case INSCRIP_SPLENDID: value = IGNORE_ALL; break; case INSCRIP_NULL: case INSCRIP_SPECIAL: value = IGNORE_MAX; break; /* This is the interesting case */ case INSCRIP_STRANGE: case INSCRIP_MAGICAL: { value = IGNORE_GOOD; if ((object_attack_plusses_are_visible(obj) || randcalc_valid(obj->kind->to_h, obj->to_h) || randcalc_valid(obj->kind->to_d, obj->to_d)) && (object_defence_plusses_are_visible(obj) || randcalc_valid(obj->kind->to_a, obj->to_a))) { int isgood = is_object_good(obj); if (isgood > 0) { value = IGNORE_GOOD; } else if (isgood < 0) { value = IGNORE_BAD; } else { value = IGNORE_AVERAGE; } } break; } default: /* do not handle any other possible pseudo values */ assert(0); } } else { if (object_was_worn(obj)) value = IGNORE_EXCELLENT_NO_SPL; /* object would be sensed if it were splendid */ else if (object_is_known_not_artifact(obj)) value = IGNORE_ALL; else value = IGNORE_MAX; } return value; }
static size_t obj_desc_combat(const object_type *o_ptr, char *buf, size_t max, size_t end, bool spoil) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; bitflag flags[OF_SIZE]; bitflag flags_known[OF_SIZE]; object_flags(o_ptr, flags); object_flags_known(o_ptr, flags_known); /* Dump base weapon info */ switch (o_ptr->tval) { /* Weapons */ case TV_SHOT: case TV_BOLT: case TV_ARROW: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING: { /* Only display the real damage dice if the combat stats are known */ if (spoil || object_attack_plusses_are_visible(o_ptr)) strnfcat(buf, max, &end, " (%dd%d)", o_ptr->dd, o_ptr->ds); else strnfcat(buf, max, &end, " (%dd%d)", k_ptr->dd, k_ptr->ds); break; } /* Missile launchers */ case TV_BOW: { /* Display shooting power as part of the multiplier */ if (of_has(flags, OF_MIGHT) && (spoil || object_flag_is_known(o_ptr, OF_MIGHT))) strnfcat(buf, max, &end, " (x%d)", (o_ptr->sval % 10) + o_ptr->pval); else strnfcat(buf, max, &end, " (x%d)", o_ptr->sval % 10); break; } } /* Show weapon bonuses */ if (spoil || object_attack_plusses_are_visible(o_ptr)) { if (obj_desc_show_weapon(o_ptr) || o_ptr->to_d || o_ptr->to_h) { /* Make an exception for body armor with only a to-hit penalty */ if (o_ptr->to_h < 0 && o_ptr->to_d == 0 && (o_ptr->tval == TV_SOFT_ARMOR || o_ptr->tval == TV_HARD_ARMOR || o_ptr->tval == TV_DRAG_ARMOR)) strnfcat(buf, max, &end, " (%+d)", o_ptr->to_h); /* Otherwise, always use the full tuple */ else strnfcat(buf, max, &end, " (%+d,%+d)", o_ptr->to_h, o_ptr->to_d); } } /* Show armor bonuses */ if (spoil || object_defence_plusses_are_visible(o_ptr)) { if (obj_desc_show_armor(o_ptr)) strnfcat(buf, max, &end, " [%d,%+d]", o_ptr->ac, o_ptr->to_a); else if (o_ptr->to_a) strnfcat(buf, max, &end, " [%+d]", o_ptr->to_a); } else if (obj_desc_show_armor(o_ptr)) { strnfcat(buf, max, &end, " [%d]", o_ptr->ac); } return end; }
/* * Calculate the players current "state", taking into account * not only race/class intrinsics, but also objects being worn * and temporary spell effects. * * See also calc_mana() and calc_hitpoints(). * * Take note of the new "speed code", in particular, a very strong * player will start slowing down as soon as he reaches 150 pounds, * but not until he reaches 450 pounds will he be half as fast as * a normal kobold. This both hurts and helps the player, hurts * because in the old days a player could just avoid 300 pounds, * and helps because now carrying 300 pounds is not very painful. * * The "weapon" and "bow" do *not* add to the bonuses to hit or to * damage, since that would affect non-combat things. These values * are actually added in later, at the appropriate place. * * If id_only is true, calc_bonuses() will only use the known * information of objects; thus it returns what the player _knows_ * the character state to be. */ void calc_bonuses(object_type inventory[], player_state *state, bool id_only) { int i, j, hold; int extra_blows = 0; int extra_shots = 0; int extra_might = 0; object_type *o_ptr; bitflag f[OF_SIZE]; bitflag collect_f[OF_SIZE]; /*** Reset ***/ memset(state, 0, sizeof *state); /* Set various defaults */ state->speed = 110; state->num_blow = 1; /*** Extract race/class info ***/ /* Base infravision (purely racial) */ state->see_infra = rp_ptr->infra; /* Base skills */ for (i = 0; i < SKILL_MAX; i++) state->skills[i] = rp_ptr->r_skills[i] + cp_ptr->c_skills[i]; /*** Analyze player ***/ /* Extract the player flags */ player_flags(collect_f); /*** Analyze equipment ***/ /* Scan the equipment */ for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) { o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Extract the item flags */ if (id_only) object_flags_known(o_ptr, f); else object_flags(o_ptr, f); of_union(collect_f, f); /* Affect stats */ if (of_has(f, OF_STR)) state->stat_add[A_STR] += o_ptr->pval; if (of_has(f, OF_INT)) state->stat_add[A_INT] += o_ptr->pval; if (of_has(f, OF_WIS)) state->stat_add[A_WIS] += o_ptr->pval; if (of_has(f, OF_DEX)) state->stat_add[A_DEX] += o_ptr->pval; if (of_has(f, OF_CON)) state->stat_add[A_CON] += o_ptr->pval; if (of_has(f, OF_CHR)) state->stat_add[A_CHR] += o_ptr->pval; /* Affect stealth */ if (of_has(f, OF_STEALTH)) state->skills[SKILL_STEALTH] += o_ptr->pval; /* Affect searching ability (factor of five) */ if (of_has(f, OF_SEARCH)) state->skills[SKILL_SEARCH] += (o_ptr->pval * 5); /* Affect searching frequency (factor of five) */ if (of_has(f, OF_SEARCH)) state->skills[SKILL_SEARCH_FREQUENCY] += (o_ptr->pval * 5); /* Affect infravision */ if (of_has(f, OF_INFRA)) state->see_infra += o_ptr->pval; /* Affect digging (factor of 20) */ if (of_has(f, OF_TUNNEL)) state->skills[SKILL_DIGGING] += (o_ptr->pval * 20); /* Affect speed */ if (of_has(f, OF_SPEED)) state->speed += o_ptr->pval; /* Affect blows */ if (of_has(f, OF_BLOWS)) extra_blows += o_ptr->pval; /* Affect shots */ if (of_has(f, OF_SHOTS)) extra_shots += o_ptr->pval; /* Affect Might */ if (of_has(f, OF_MIGHT)) extra_might += o_ptr->pval; /* Modify the base armor class */ state->ac += o_ptr->ac; /* The base armor class is always known */ state->dis_ac += o_ptr->ac; /* Apply the bonuses to armor class */ if (!id_only || object_is_known(o_ptr)) state->to_a += o_ptr->to_a; /* Apply the mental bonuses to armor class, if known */ if (object_defence_plusses_are_visible(o_ptr)) state->dis_to_a += o_ptr->to_a; /* Hack -- do not apply "weapon" bonuses */ if (i == INVEN_WIELD) continue; /* Hack -- do not apply "bow" bonuses */ if (i == INVEN_BOW) continue; /* Apply the bonuses to hit/damage */ if (!id_only || object_is_known(o_ptr)) { state->to_h += o_ptr->to_h; state->to_d += o_ptr->to_d; } /* Apply the mental bonuses tp hit/damage, if known */ if (object_attack_plusses_are_visible(o_ptr)) { state->dis_to_h += o_ptr->to_h; state->dis_to_d += o_ptr->to_d; } } /*** Update all flags ***/ /* Good flags */ if (of_has(collect_f, OF_SLOW_DIGEST)) state->slow_digest = TRUE; if (of_has(collect_f, OF_FEATHER)) state->ffall = TRUE; if (of_has(collect_f, OF_REGEN)) state->regenerate = TRUE; if (of_has(collect_f, OF_TELEPATHY)) state->telepathy = TRUE; if (of_has(collect_f, OF_SEE_INVIS)) state->see_inv = TRUE; if (of_has(collect_f, OF_FREE_ACT)) state->free_act = TRUE; if (of_has(collect_f, OF_HOLD_LIFE)) state->hold_life = TRUE; /* Weird flags */ if (of_has(collect_f, OF_BLESSED)) state->bless_blade = TRUE; /* Bad flags */ if (of_has(collect_f, OF_IMPACT)) state->impact = TRUE; if (of_has(collect_f, OF_AGGRAVATE)) state->aggravate = TRUE; if (of_has(collect_f, OF_TELEPORT)) state->teleport = TRUE; if (of_has(collect_f, OF_DRAIN_EXP)) state->exp_drain = TRUE; if (of_has(collect_f, OF_IMPAIR_HP)) state->impair_hp = TRUE; if (of_has(collect_f, OF_IMPAIR_MANA)) state->impair_mana = TRUE; if (of_has(collect_f, OF_AFRAID)) state->afraid = TRUE; /* Vulnerability flags */ if (of_has(collect_f, OF_VULN_FIRE)) state->vuln_fire = TRUE; if (of_has(collect_f, OF_VULN_ACID)) state->vuln_acid = TRUE; if (of_has(collect_f, OF_VULN_COLD)) state->vuln_cold = TRUE; if (of_has(collect_f, OF_VULN_ELEC)) state->vuln_elec = TRUE; /* Immunity flags */ if (of_has(collect_f, OF_IM_FIRE)) state->immune_fire = TRUE; if (of_has(collect_f, OF_IM_ACID)) state->immune_acid = TRUE; if (of_has(collect_f, OF_IM_COLD)) state->immune_cold = TRUE; if (of_has(collect_f, OF_IM_ELEC)) state->immune_elec = TRUE; /* Resistance flags */ if (of_has(collect_f, OF_RES_ACID)) state->resist_acid = TRUE; if (of_has(collect_f, OF_RES_ELEC)) state->resist_elec = TRUE; if (of_has(collect_f, OF_RES_FIRE)) state->resist_fire = TRUE; if (of_has(collect_f, OF_RES_COLD)) state->resist_cold = TRUE; if (of_has(collect_f, OF_RES_POIS)) state->resist_pois = TRUE; if (of_has(collect_f, OF_RES_FEAR)) state->resist_fear = TRUE; if (of_has(collect_f, OF_RES_LIGHT)) state->resist_light = TRUE; if (of_has(collect_f, OF_RES_DARK)) state->resist_dark = TRUE; if (of_has(collect_f, OF_RES_BLIND)) state->resist_blind = TRUE; if (of_has(collect_f, OF_RES_CONFU)) state->resist_confu = TRUE; if (of_has(collect_f, OF_RES_SOUND)) state->resist_sound = TRUE; if (of_has(collect_f, OF_RES_SHARD)) state->resist_shard = TRUE; if (of_has(collect_f, OF_RES_NEXUS)) state->resist_nexus = TRUE; if (of_has(collect_f, OF_RES_NETHR)) state->resist_nethr = TRUE; if (of_has(collect_f, OF_RES_CHAOS)) state->resist_chaos = TRUE; if (of_has(collect_f, OF_RES_DISEN)) state->resist_disen = TRUE; /* Sustain flags */ if (of_has(collect_f, OF_SUST_STR)) state->sustain_str = TRUE; if (of_has(collect_f, OF_SUST_INT)) state->sustain_int = TRUE; if (of_has(collect_f, OF_SUST_WIS)) state->sustain_wis = TRUE; if (of_has(collect_f, OF_SUST_DEX)) state->sustain_dex = TRUE; if (of_has(collect_f, OF_SUST_CON)) state->sustain_con = TRUE; if (of_has(collect_f, OF_SUST_CHR)) state->sustain_chr = TRUE; /*** Handle stats ***/ /* Calculate stats */ for (i = 0; i < A_MAX; i++) { int add, top, use, ind; /* Extract modifier */ add = state->stat_add[i]; /* Maximize mode */ if (OPT(adult_maximize)) { /* Modify the stats for race/class */ add += (rp_ptr->r_adj[i] + cp_ptr->c_adj[i]); } /* Extract the new "stat_top" value for the stat */ top = modify_stat_value(p_ptr->stat_max[i], add); /* Save the new value */ state->stat_top[i] = top; /* Extract the new "stat_use" value for the stat */ use = modify_stat_value(p_ptr->stat_cur[i], add); /* Save the new value */ state->stat_use[i] = use; /* Values: n/a */ if (use <= 3) ind = 0; /* Values: 3, 4, ..., 18 */ else if (use <= 18) ind = (use - 3); /* Ranges: 18/00-18/09, ..., 18/210-18/219 */ else if (use <= 18+219) ind = (15 + (use - 18) / 10); /* Range: 18/220+ */ else ind = (37); assert((0 <= ind) && (ind < STAT_RANGE)); /* Save the new index */ state->stat_ind[i] = ind; } /*** Temporary flags ***/ /* Apply temporary "stun" */ if (p_ptr->timed[TMD_STUN] > 50) { state->to_h -= 20; state->dis_to_h -= 20; state->to_d -= 20; state->dis_to_d -= 20; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 8 / 10; } else if (p_ptr->timed[TMD_STUN]) { state->to_h -= 5; state->dis_to_h -= 5; state->to_d -= 5; state->dis_to_d -= 5; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 9 / 10; } /* Invulnerability */ if (p_ptr->timed[TMD_INVULN]) { state->to_a += 100; state->dis_to_a += 100; } /* Temporary blessing */ if (p_ptr->timed[TMD_BLESSED]) { state->to_a += 5; state->dis_to_a += 5; state->to_h += 10; state->dis_to_h += 10; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 105 / 100; } /* Temporary shield */ if (p_ptr->timed[TMD_SHIELD]) { state->to_a += 50; state->dis_to_a += 50; } /* Temporary stoneskin */ if (p_ptr->timed[TMD_STONESKIN]) { state->to_a += 40; state->dis_to_a += 40; state->speed -= 5; } /* Temporary "Hero" */ if (p_ptr->timed[TMD_HERO]) { state->to_h += 12; state->dis_to_h += 12; state->resist_fear = TRUE; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 105 / 100; } /* Temporary "Berserk" */ if (p_ptr->timed[TMD_SHERO]) { state->to_h += 24; state->dis_to_h += 24; state->to_a -= 10; state->dis_to_a -= 10; state->resist_fear = TRUE; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 9 / 10; } /* Temporary "fast" */ if (p_ptr->timed[TMD_FAST] || p_ptr->timed[TMD_SPRINT]) state->speed += 10; /* Temporary "slow" */ if (p_ptr->timed[TMD_SLOW]) state->speed -= 10; /* Temporary see invisible */ if (p_ptr->timed[TMD_SINVIS]) state->see_inv = TRUE; /* Temporary infravision boost */ if (p_ptr->timed[TMD_SINFRA]) state->see_infra += 5; /* Temporary telepathy */ if (p_ptr->timed[TMD_TELEPATHY]) state->telepathy = TRUE; /* Temporary resist confusion */ if (p_ptr->timed[TMD_OPP_CONF]) state->resist_confu = TRUE; /* Fear */ if (p_ptr->timed[TMD_AFRAID] || p_ptr->timed[TMD_TERROR]) state->afraid = TRUE; if (p_ptr->timed[TMD_TERROR]) state->speed += 5; /* Fear can come from item flags too */ if (state->afraid) { state->to_h -= 20; state->dis_to_h -= 20; state->to_a += 8; state->dis_to_a += 8; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 95 / 100; } /* Confusion */ if (p_ptr->timed[TMD_CONFUSED]) state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 75 / 100; /* Amnesia */ if (p_ptr->timed[TMD_AMNESIA]) state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 8 / 10; /* Poison */ if (p_ptr->timed[TMD_POISONED]) state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 95 / 100; /* Hallucination */ if (p_ptr->timed[TMD_IMAGE]) state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 8 / 10; /*** Analyze weight ***/ /* Extract the current weight (in tenth pounds) */ j = p_ptr->total_weight; /* Extract the "weight limit" (in tenth pounds) */ i = weight_limit(state); /* Apply "encumbrance" from weight */ if (j > i / 2) state->speed -= ((j - (i / 2)) / (i / 10)); /* Bloating slows the player down (a little) */ if (p_ptr->food >= PY_FOOD_MAX) state->speed -= 10; /* Searching slows the player down */ if (p_ptr->searching) state->speed -= 10; /* Sanity check on extreme speeds */ if (state->speed < 0) state->speed = 0; if (state->speed > 199) state->speed = 199; /*** Apply modifier bonuses ***/ /* Actual Modifier Bonuses (Un-inflate stat bonuses) */ state->to_a += ((int)(adj_dex_ta[state->stat_ind[A_DEX]]) - 128); state->to_d += ((int)(adj_str_td[state->stat_ind[A_STR]]) - 128); state->to_h += ((int)(adj_dex_th[state->stat_ind[A_DEX]]) - 128); state->to_h += ((int)(adj_str_th[state->stat_ind[A_STR]]) - 128); /* Displayed Modifier Bonuses (Un-inflate stat bonuses) */ state->dis_to_a += ((int)(adj_dex_ta[state->stat_ind[A_DEX]]) - 128); state->dis_to_d += ((int)(adj_str_td[state->stat_ind[A_STR]]) - 128); state->dis_to_h += ((int)(adj_dex_th[state->stat_ind[A_DEX]]) - 128); state->dis_to_h += ((int)(adj_str_th[state->stat_ind[A_STR]]) - 128); /*** Modify skills ***/ /* Affect Skill -- stealth (bonus one) */ state->skills[SKILL_STEALTH] += 1; /* Affect Skill -- disarming (DEX and INT) */ state->skills[SKILL_DISARM] += adj_dex_dis[state->stat_ind[A_DEX]]; state->skills[SKILL_DISARM] += adj_int_dis[state->stat_ind[A_INT]]; /* Affect Skill -- magic devices (INT) */ state->skills[SKILL_DEVICE] += adj_int_dev[state->stat_ind[A_INT]]; /* Affect Skill -- saving throw (WIS) */ state->skills[SKILL_SAVE] += adj_wis_sav[state->stat_ind[A_WIS]]; /* Affect Skill -- digging (STR) */ state->skills[SKILL_DIGGING] += adj_str_dig[state->stat_ind[A_STR]]; /* Affect Skills (Level, by Class) */ for (i = 0; i < SKILL_MAX; i++) state->skills[i] += (cp_ptr->x_skills[i] * p_ptr->lev / 10); /* Limit Skill -- digging from 1 up */ if (state->skills[SKILL_DIGGING] < 1) state->skills[SKILL_DIGGING] = 1; /* Limit Skill -- stealth from 0 to 30 */ if (state->skills[SKILL_STEALTH] > 30) state->skills[SKILL_STEALTH] = 30; if (state->skills[SKILL_STEALTH] < 0) state->skills[SKILL_STEALTH] = 0; /* Apply Skill -- Extract noise from stealth */ state->noise = (1L << (30 - state->skills[SKILL_STEALTH])); /* Obtain the "hold" value */ hold = adj_str_hold[state->stat_ind[A_STR]]; /*** Analyze current bow ***/ /* Examine the "current bow" */ o_ptr = &inventory[INVEN_BOW]; /* Assume not heavy */ state->heavy_shoot = FALSE; /* It is hard to carholdry a heavy bow */ if (hold < o_ptr->weight / 10) { /* Hard to wield a heavy bow */ state->to_h += 2 * (hold - o_ptr->weight / 10); state->dis_to_h += 2 * (hold - o_ptr->weight / 10); /* Heavy Bow */ state->heavy_shoot = TRUE; } /* Analyze launcher */ if (o_ptr->k_idx) { /* Get to shoot */ state->num_fire = 1; /* Analyze the launcher */ switch (o_ptr->sval) { /* Sling and ammo */ case SV_SLING: { state->ammo_tval = TV_SHOT; state->ammo_mult = 2; break; } /* Short Bow and Arrow */ case SV_SHORT_BOW: { state->ammo_tval = TV_ARROW; state->ammo_mult = 2; break; } /* Long Bow and Arrow */ case SV_LONG_BOW: { state->ammo_tval = TV_ARROW; state->ammo_mult = 3; break; } /* Light Crossbow and Bolt */ case SV_LIGHT_XBOW: { state->ammo_tval = TV_BOLT; state->ammo_mult = 3; break; } /* Heavy Crossbow and Bolt */ case SV_HEAVY_XBOW: { state->ammo_tval = TV_BOLT; state->ammo_mult = 4; break; } } /* Apply special flags */ if (o_ptr->k_idx && !state->heavy_shoot) { /* Extra shots */ state->num_fire += extra_shots; /* Extra might */ state->ammo_mult += extra_might; /* Hack -- Rangers love Bows */ if (player_has(PF_EXTRA_SHOT) && (state->ammo_tval == TV_ARROW)) { /* Extra shot at level 20 */ if (p_ptr->lev >= 20) state->num_fire++; /* Extra shot at level 40 */ if (p_ptr->lev >= 40) state->num_fire++; } } /* Require at least one shot */ if (state->num_fire < 1) state->num_fire = 1; } /*** Analyze weapon ***/ /* Examine the "current weapon" */ o_ptr = &inventory[INVEN_WIELD]; /* Assume not heavy */ state->heavy_wield = FALSE; /* It is hard to hold a heavy weapon */ if (hold < o_ptr->weight / 10) { /* Hard to wield a heavy weapon */ state->to_h += 2 * (hold - o_ptr->weight / 10); state->dis_to_h += 2 * (hold - o_ptr->weight / 10); /* Heavy weapon */ state->heavy_wield = TRUE; } /* Non-object means barehanded attacks */ if (!o_ptr->k_idx) assert(o_ptr->weight == 0); /* Normal weapons */ if (!state->heavy_wield) { /* Calculate number of blows */ state->num_blow = calc_blows(o_ptr, state) + extra_blows; /* Boost digging skill by weapon weight */ state->skills[SKILL_DIGGING] += (o_ptr->weight / 10); } /* Assume okay */ state->icky_wield = FALSE; /* Priest weapon penalty for non-blessed edged weapons */ if (player_has(PF_BLESS_WEAPON) && (!state->bless_blade) && ((o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM))) { /* Reduce the real bonuses */ state->to_h -= 2; state->to_d -= 2; /* Reduce the mental bonuses */ state->dis_to_h -= 2; state->dis_to_d -= 2; /* Icky weapon */ state->icky_wield = TRUE; } return; }
/* * Determine the squelch level of an object, which is similar to its pseudo. * * The main point is when the value is undetermined given current info, * return the maximum possible value. */ static byte squelch_level_of(const object_type *o_ptr) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; byte value; bitflag f[OF_SIZE]; object_flags_known(o_ptr, f); if ((object_pval_is_visible(o_ptr)) && (o_ptr->pval < 0)) return SQUELCH_BAD; /* Deal with jewelry specially. */ if (object_is_jewelry(o_ptr)) { if ((object_pval_is_visible(o_ptr)) && (o_ptr->pval > 0)) return SQUELCH_AVERAGE; if ((o_ptr->to_h > 0) || (o_ptr->to_d > 0) || (o_ptr->to_a > 0)) return SQUELCH_AVERAGE; if ((o_ptr->to_h < 0) || (o_ptr->to_d < 0) || (o_ptr->to_a < 0)) return SQUELCH_BAD; return SQUELCH_AVERAGE; } /* And lights */ if (o_ptr->tval == TV_LIGHT) { if (flags_test(f, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END)) return SQUELCH_ALL; if ((o_ptr->to_h > 0) || (o_ptr->to_d > 0) || (o_ptr->to_a > 0)) return SQUELCH_GOOD; if ((o_ptr->to_h < 0) || (o_ptr->to_d < 0) || (o_ptr->to_a < 0)) return SQUELCH_BAD; return SQUELCH_AVERAGE; } if (object_was_sensed(o_ptr)) { obj_pseudo_t pseudo = object_pseudo(o_ptr); switch (pseudo) { case INSCRIP_AVERAGE: value = SQUELCH_AVERAGE; break; case INSCRIP_EXCELLENT: /* have to assume splendid until you have tested it */ if (object_was_worn(o_ptr)) { if (object_high_resist_is_possible(o_ptr)) value = SQUELCH_EXCELLENT_NO_SPL; else value = SQUELCH_EXCELLENT_NO_HI; } else { value = SQUELCH_ALL; } break; case INSCRIP_STRANGE: /* XXX Eddie perhaps some strange count as something else */ case INSCRIP_SPLENDID: value = SQUELCH_ALL; break; case INSCRIP_NULL: case INSCRIP_SPECIAL: value = SQUELCH_MAX; break; /* This is the interesting case */ case INSCRIP_MAGICAL: value = SQUELCH_GOOD; if ((object_attack_plusses_are_visible(o_ptr) || (randcalc_valid(k_ptr->to_h, o_ptr->to_h) && randcalc_valid(k_ptr->to_d, o_ptr->to_d))) && (object_defence_plusses_are_visible(o_ptr) || (randcalc_valid(k_ptr->to_a, o_ptr->to_a))) && (o_ptr->to_h <= randcalc(k_ptr->to_h, 0, MINIMISE)) && (o_ptr->to_d <= randcalc(k_ptr->to_d, 0, MINIMISE)) && (o_ptr->to_a <= randcalc(k_ptr->to_a, 0, MINIMISE))) value = SQUELCH_BAD; break; default: /* do not handle any other possible pseudo values */ assert(0); } } else { if (object_was_worn(o_ptr)) value = SQUELCH_EXCELLENT_NO_SPL; /* object would be sensed if it were splendid */ else if (object_is_known_not_artifact(o_ptr)) value = SQUELCH_ALL; else value = SQUELCH_MAX; } return value; }