Example #1
0
/*
 * 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;
}
Example #2
0
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;
}
Example #3
0
/**
 * 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;
}
Example #4
0
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);
}
Example #5
0
/**
 * 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);
}
Example #6
0
/*
 * 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;
}
Example #7
0
/**
 * 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;
}
Example #8
0
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;
}
Example #9
0
/*
 * 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;
}
Example #10
0
/*
 * 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;
}