Пример #1
0
/*
 * Favorite weapons
 */
bool object_is_favorite(object_type *o_ptr)
{
    /* Only melee weapons match */
    if (!(o_ptr->tval == TV_POLEARM ||
            o_ptr->tval == TV_SWORD ||
            o_ptr->tval == TV_DIGGING ||
            o_ptr->tval == TV_HAFTED))
    {
        return FALSE;
    }

    /* Favorite weapons are varied depend on the class */
    switch (p_ptr->pclass)
    {
    case CLASS_PRIEST:
    {
        u32b flgs[TR_FLAG_SIZE];
        object_flags_known(o_ptr, flgs);

        if (!have_flag(flgs, TR_BLESSED) &&
                !(o_ptr->tval == TV_HAFTED))
            return FALSE;
        break;
    }

    case CLASS_MONK:
    case CLASS_FORCETRAINER:
        /* Icky to wield? */
        if (!(s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_WEAPON_BEGIN][o_ptr->sval]))
            return FALSE;
        break;

    case CLASS_BEASTMASTER:
    case CLASS_CAVALRY:
    {
        u32b flgs[TR_FLAG_SIZE];
        object_flags_known(o_ptr, flgs);

        /* Is it known to be suitable to using while riding? */
        if (!(have_flag(flgs, TR_RIDING)))
            return FALSE;

        break;
    }

    case CLASS_NINJA:
        /* Icky to wield? */
        if (s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_WEAPON_BEGIN][o_ptr->sval] <= WEAPON_EXP_BEGINNER)
            return FALSE;
        break;

    default:
        /* All weapons are okay for non-special classes */
        return TRUE;
    }

    return TRUE;
}
Пример #2
0
static size_t obj_desc_inscrip(const object_type *o_ptr, char *buf, size_t max, size_t end)
{
	const char *u[4] = { 0, 0, 0, 0 };
	int n = 0;
	int feel = object_pseudo(o_ptr);
	bitflag flags_known[OF_SIZE];

	object_flags_known(o_ptr, flags_known);

	/* Get inscription */
	if (o_ptr->note)
		u[n++] = quark_str(o_ptr->note);

	/* Use special inscription, if any */
	if (!object_is_known(o_ptr) && feel)
	{
		/* cannot tell excellent vs strange vs splendid until wield */
		if (!object_was_worn(o_ptr) && ego_item_p(o_ptr))
			u[n++] = "ego";
		else
			u[n++] = inscrip_text[feel];
	}
	else if ((o_ptr->ident & IDENT_EMPTY) && !object_is_known(o_ptr))
		u[n++] = "empty";
	else if (!object_is_known(o_ptr) && object_was_worn(o_ptr))
	{
		if (wield_slot(o_ptr) == INVEN_WIELD || wield_slot(o_ptr) == INVEN_BOW)
			u[n++] = "wielded";
		else u[n++] = "worn";
	}
	else if (!object_is_known(o_ptr) && object_was_fired(o_ptr))
		u[n++] = "fired";
	else if (!object_flavor_is_aware(o_ptr) && object_flavor_was_tried(o_ptr))
		u[n++] = "tried";

	/* Note curses */
	if (flags_test(flags_known, OF_SIZE, OF_CURSE_MASK, FLAG_END))
		u[n++] = "cursed";

	/* Note squelch */
	if (squelch_item_ok(o_ptr))
		u[n++] = "squelch";

	if (n)
	{
		int i;
		for (i = 0; i < n; i++)
		{
			if (i == 0)
				strnfcat(buf, max, &end, " {");
			strnfcat(buf, max, &end, "%s", u[i]);
			if (i < n-1)
				strnfcat(buf, max, &end, ", ");
		}

		strnfcat(buf, max, &end, "}");
	}

	return end;
}
Пример #3
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;
}
Пример #4
0
/**
 * \returns whether the object's pval is known to the player
 */
bool object_pval_is_visible(const object_type *o_ptr)
{
	bitflag f[OF_SIZE];

	if (o_ptr->ident & IDENT_STORE)
		return TRUE;

	/* Aware jewelry with non-variable pvals */
	if (object_is_jewelry(o_ptr) && object_flavor_is_aware(o_ptr))
	{
		const object_kind *k_ptr = &k_info[o_ptr->k_idx];

		if (!randcalc_varies(k_ptr->pval))
			return TRUE;
	}

	if (object_was_worn(o_ptr))
	{
		object_flags_known(o_ptr, f);

		if (flags_test(f, OF_SIZE, OF_PVAL_MASK, FLAG_END))
			return TRUE;
	}

	return FALSE;
}
Пример #5
0
int res_ct_known(int which)
{
    int ct = p_ptr->resist[which];
    int hidden = 0;
    int flg = res_get_object_flag(which);
    int i;

    /* Life is a bit hard at the moment since "player flags"
       may account for multiple resistances. Really, the entire
       flag based approach to resistance is just wrong, but I'm
       too lazy to fix ...
    */
    for (i = 0; i < equip_count(); i++)
    {
        int          slot = EQUIP_BEGIN + i;
        object_type *o_ptr = equip_obj(slot);
        u32b         flgs[TR_FLAG_SIZE];
        u32b         flgs_known[TR_FLAG_SIZE];

        if (!o_ptr) continue;
        object_flags(o_ptr, flgs);
        object_flags_known(o_ptr, flgs_known);

        if (have_flag(flgs, flg) && !have_flag(flgs_known, flg))
            hidden++;
    }

    ct -= hidden;
    return ct;
}
Пример #6
0
/**
 * \returns whether the object is known to be blessed
 */
bool object_is_known_blessed(const object_type *o_ptr)
{
	bitflag f[OF_SIZE];

	object_flags_known(o_ptr, f);

	return (of_has(f, OF_BLESSED)) ? true : false;
}
Пример #7
0
/**
 * Add player-defined inscriptions or game-defined descriptions
 */
static size_t obj_desc_inscrip(const struct object *obj, char *buf,
							   size_t max, size_t end)
{
	const char *u[4] = { 0, 0, 0, 0 };
	int n = 0;
	int feel = object_pseudo(obj);
	bitflag flags_known[OF_SIZE], f2[OF_SIZE];

	object_flags_known(obj, flags_known);

	/* Get inscription */
	if (obj->note)
		u[n++] = quark_str(obj->note);

	/* Use special inscription, if any */
	if (!object_is_known(obj)) {
		if (feel) {
			/* cannot tell excellent vs strange vs splendid until wield */
			if (!object_was_worn(obj) && obj->ego)
				u[n++] = "ego";
			else
				u[n++] = inscrip_text[feel];
		} 
		else if (tval_can_have_charges(obj) && (obj->pval == 0))
			u[n++] = "empty";
		else if (object_was_worn(obj))
			u[n++] = (tval_is_weapon(obj)) ? "wielded" : "worn";
		else if (!object_flavor_is_aware(obj) &&
				 object_flavor_was_tried(obj))
			u[n++] = "tried";
	}

	/* Note curses */
	create_mask(f2, FALSE, OFT_CURSE, OFT_MAX);
	if (of_is_inter(flags_known, f2))
		u[n++] = "cursed";

	/* Note ignore */
	if (ignore_item_ok(obj))
		u[n++] = "ignore";

	if (n)
	{
		int i;
		for (i = 0; i < n; i++)
		{
			if (i == 0)
				strnfcat(buf, max, &end, " {");
			strnfcat(buf, max, &end, "%s", u[i]);
			if (i < n-1)
				strnfcat(buf, max, &end, ", ");
		}

		strnfcat(buf, max, &end, "}");
	}

	return end;
}
Пример #8
0
/**
 * 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;
		}
	}
}
Пример #9
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;
}
Пример #10
0
/**
 * Add power for non-derived flags (derived flags have flag_power 0)
 */
static int flags_power(const object_type *obj, int p, int verbose,
					   ang_file *log_file, bool known)
{
	size_t i, j;
	int q;
	bitflag flags[OF_SIZE];

	/* Extract the flags */
	if (known)
		object_flags(obj, flags);
	else
		object_flags_known(obj, flags);

	/* Log the flags in human-readable form */
	if (verbose)
		log_flags(flags, log_file);

	/* Zero the flag counts */
	for (i = 0; i < N_ELEMENTS(flag_sets); i++)
		flag_sets[i].count = 0;

	for (i = of_next(flags, FLAG_START); i != FLAG_END; 
		 i = of_next(flags, i + 1)) {
		if (flag_power(i)) {
			q = (flag_power(i) * flag_slot_mult(i, wield_slot(obj)));
			p += q;
			log_obj(format("Add %d power for %s, total is %d\n", 
						   q, flag_name(i), p));
		}

		/* Track combinations of flag types */
		for (j = 0; j < N_ELEMENTS(flag_sets); j++)
			if (flag_sets[j].type == obj_flag_type(i))
				flag_sets[j].count++;
	}

	/* Add extra power for multiple flags of the same type */
	for (i = 0; i < N_ELEMENTS(flag_sets); i++) {
		if (flag_sets[i].count > 1) {
			q = (flag_sets[i].factor * flag_sets[i].count * flag_sets[i].count);
			p += q;
			log_obj(format("Add %d power for multiple %s, total is %d\n",
						   q, flag_sets[i].desc, p));
		}

		/* Add bonus if item has a full set of these flags */
		if (flag_sets[i].count == flag_sets[i].size) {
			q = flag_sets[i].bonus;
			p += q;
			log_obj(format("Add %d power for full set of %s, total is %d\n", 
						   q, flag_sets[i].desc, p));
		}
	}

	return p;
}
Пример #11
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;
}
Пример #12
0
/**
 * \returns whether the object is known to be cursed
 */
bool object_is_known_cursed(const object_type *o_ptr)
{
	bitflag f[OF_SIZE];

	object_flags_known(o_ptr, f);

	/* Know whatever curse flags there are to know */
	flags_mask(f, OF_SIZE, OF_CURSE_MASK, FLAG_END);

	return !of_is_empty(f);
}
Пример #13
0
/**
 * \returns whether the object is known to be cursed
 */
bool object_is_known_cursed(const object_type *o_ptr)
{
	bitflag f[OF_SIZE], f2[OF_SIZE];

	object_flags_known(o_ptr, f);

	/* Gather whatever curse flags there are to know */
	create_mask(f2, false, OFT_CURSE, OFT_MAX);

	return of_is_inter(f, f2);
}
Пример #14
0
/**
 * Get the object flags the player should know about for the given object/
 * viewing mode combination.
 */
static void get_known_flags(const struct object *obj, const oinfo_detail_t mode,
							bitflag flags[OF_SIZE])
{
	/* Grab the object flags */
	if (mode & OINFO_EGO) {
			object_flags(obj, flags);
	} else {
		object_flags_known(obj, flags);

		/* Don't include base flags when terse */
		if (mode & OINFO_TERSE)
			of_diff(flags, obj->kind->base->flags);
	}
}
Пример #15
0
/**
 * Extract the multiplier from a given object hitting a given monster.
 *
 * If there is a slay or brand in effect, change the verb for hitting
 * to something interesting ('burn', 'smite', etc.).  Also, note which
 * flags had an effect in o_ptr->known_flags[].
 *
 * \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
 *
 */
void improve_attack_modifier(object_type *o_ptr, const monster_type *m_ptr, const slay_t **best_s_ptr)
{
	const slay_t *s_ptr;

	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];
	object_flags(o_ptr, f);
	object_flags_known(o_ptr, known_f);

	for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++)
	{
		if (!of_has(f, s_ptr->slay_flag)) continue;

		/* Learn about monster resistance/vulnerability IF:
		 * 1) The slay flag on the object is known OR
		 * 2) The monster does not possess the appropriate resistance flag OR
		 * 3) The monster does possess the appropriate vulnerability flag
		 */
		if (of_has(known_f, s_ptr->slay_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)))
		{
			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 the monster doesn't match or the slay flag does */
		if ((s_ptr->brand && !rf_has(r_ptr->flags, s_ptr->resist_flag)) || 
		    rf_has(r_ptr->flags, s_ptr->monster_flag))
		{
			/* notice any brand or slay that would affect the monster */
			object_notice_slay(o_ptr, s_ptr->slay_flag);

			/* compare multipliers to determine best attack, would be more complex for O-style brands */
			if ((*best_s_ptr == NULL) || ((*best_s_ptr)->mult < s_ptr->mult))
				*best_s_ptr = s_ptr;
		}
	}
}
Пример #16
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);
}
Пример #17
0
/*
 * Output object information
 */
static textblock *object_info_out(const object_type *o_ptr, oinfo_detail_t mode)
{
	bitflag flags[OF_SIZE];
	bitflag pval_flags[MAX_PVALS][OF_SIZE];
	bool something = FALSE;
	bool known = object_is_known(o_ptr);

	bool full = mode & OINFO_FULL;
	bool terse = mode & OINFO_TERSE;
	bool subjective = mode & OINFO_SUBJ;
	bool ego = mode & OINFO_EGO;

	textblock *tb = textblock_new();

	/* Grab the object flags */
	if (full) {
		object_flags(o_ptr, flags);
		object_pval_flags(o_ptr, pval_flags);
	} else {
		object_flags_known(o_ptr, flags);
		object_pval_flags_known(o_ptr, pval_flags);
	}

	if (subjective) describe_origin(tb, o_ptr);
	if (!terse) describe_flavor_text(tb, o_ptr, mode);

	if (!full && !known)
	{
		textblock_append(tb, "You do not know the full extent of this item's powers.\n");
		something = TRUE;
	}

	if (describe_curses(tb, o_ptr, flags)) something = TRUE;
	if (describe_stats(tb, o_ptr, pval_flags, mode)) something = TRUE;
	if (describe_slays(tb, flags, o_ptr->tval)) something = TRUE;
	if (describe_immune(tb, flags)) something = TRUE;
	if (describe_ignores(tb, flags)) something = TRUE;
	dedup_hates_flags(flags);
	if (describe_hates(tb, flags)) something = TRUE;
	if (describe_sustains(tb, flags)) something = TRUE;
	if (describe_misc_magic(tb, flags)) something = TRUE;
	if (ego && describe_ego(tb, o_ptr->ego)) something = TRUE;
	if (something) textblock_append(tb, "\n");

	if (!ego && describe_effect(tb, o_ptr, full, terse, subjective)) {
		something = TRUE;
		textblock_append(tb, "\n");
	}

	if (subjective && describe_combat(tb, o_ptr, mode)) {
		something = TRUE;
		textblock_append(tb, "\n");
	}

	if (!terse && describe_food(tb, o_ptr, subjective, full)) something = TRUE;
	if (describe_light(tb, o_ptr, flags, mode)) something = TRUE;
	if (!terse && subjective && describe_digger(tb, o_ptr, mode)) something = TRUE;

	if (!something)
		textblock_append(tb, "\n\nThis item does not seem to possess any special abilities.");

	return tb;
}
Пример #18
0
/*
 * Describe objects that can be used for digging.
 */
static bool describe_digger(textblock *tb, const object_type *o_ptr,
		oinfo_detail_t mode)
{
	bool full = mode & OINFO_FULL;

	player_state st;

	object_type inven[INVEN_TOTAL];

	int sl = wield_slot(o_ptr);
	int i;

	bitflag f[OF_SIZE];

	int chances[4]; /* These are out of 1600 */
	static const char *names[4] = { "rubble", "magma veins", "quartz veins", "granite" };

	/* abort if we are a dummy object */
	if (mode & OINFO_DUMMY) return FALSE;

	if (full)
		object_flags(o_ptr, f);
	else
		object_flags_known(o_ptr, f);

	if (sl < 0 || (sl != INVEN_WIELD && !of_has(f, OF_TUNNEL)))
		return FALSE;

	memcpy(inven, p_ptr->inventory, INVEN_TOTAL * sizeof(object_type));

	/*
	 * Hack -- if we examine a ring that is worn on the right finger,
	 * we shouldn't put a copy of it on the left finger before calculating
	 * digging skills.
	 */
	if (o_ptr != &p_ptr->inventory[INVEN_RIGHT])
		inven[sl] = *o_ptr;

	calc_bonuses(inven, &st, TRUE);

	chances[0] = st.skills[SKILL_DIGGING] * 8;
	chances[1] = (st.skills[SKILL_DIGGING] - 10) * 4;
	chances[2] = (st.skills[SKILL_DIGGING] - 20) * 2;
	chances[3] = (st.skills[SKILL_DIGGING] - 40) * 1;

	for (i = 0; i < 4; i++)
	{
		int chance = MAX(0, MIN(1600, chances[i]));
		int decis = chance ? (16000 / chance) : 0;

		if (i == 0 && chance > 0) {
			if (sl == INVEN_WIELD)
				textblock_append(tb, "Clears ");
			else
				textblock_append(tb, "With this item, your current weapon clears ");
		}

		if (i == 3 || (i != 0 && chance == 0))
			textblock_append(tb, "and ");

		if (chance == 0) {
			textblock_append_c(tb, TERM_L_RED, "doesn't affect ");
			textblock_append(tb, "%s.\n", names[i]);
			break;
		}

		textblock_append(tb, "%s in ", names[i]);

		if (chance == 1600) {
			textblock_append_c(tb, TERM_L_GREEN, "1 ");
		} else if (decis < 100) {
			textblock_append_c(tb, TERM_GREEN, "%d.%d ", decis/10, decis%10);
		} else {
			textblock_append_c(tb, (decis < 1000) ? TERM_YELLOW : TERM_RED,
			           "%d ", (decis+5)/10);
		}

		textblock_append(tb, "turn%s%s", decis == 10 ? "" : "s",
				(i == 3) ? ".\n" : ", ");
	}

	return TRUE;
}
Пример #19
0
/*
 * Describe combat advantages.
 */
static bool describe_combat(textblock *tb, const object_type *o_ptr,
		oinfo_detail_t mode)
{
	bool full = mode & OINFO_FULL;

	const char *desc[SL_MAX] = { 0 };
	int i;
	int mult[SL_MAX];
	int cnt, dam, total_dam, plus = 0;
	int xtra_postcrit = 0, xtra_precrit = 0;
	int crit_mult, crit_div, crit_add;
	int str_plus, dex_plus, old_blows = 0, new_blows, extra_blows;
	int str_faster = -1, str_done = -1;
	object_type *bow = &p_ptr->inventory[INVEN_BOW];

	bitflag f[OF_SIZE], tmp_f[OF_SIZE], mask[OF_SIZE];

	bool weapon = (wield_slot(o_ptr) == INVEN_WIELD);
	bool ammo   = (p_ptr->state.ammo_tval == o_ptr->tval) &&
	              (bow->kind);
	int multiplier = 1;

	/* Create the "all slays" mask */
	create_mask(mask, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX);

	/* Abort if we've nothing to say */
	if (mode & OINFO_DUMMY) return FALSE;

	if (!weapon && !ammo)
	{
		/* Potions can have special text */
		if (o_ptr->tval != TV_POTION ||
				o_ptr->dd == 0 || o_ptr->ds == 0 ||
				!object_flavor_is_aware(o_ptr))
			return FALSE;

		textblock_append(tb, "It can be thrown at creatures with damaging effect.\n");
		return TRUE;
	}

	if (full) {
		object_flags(o_ptr, f);
	} else {
		object_flags_known(o_ptr, f);
	}

	textblock_append_c(tb, TERM_L_WHITE, "Combat info:\n");

	if (weapon)
	{
		/*
		 * Get the player's hypothetical state, were they to be
		 * wielding this item.
		 */
		player_state state;
		int dex_plus_bound;
		int str_plus_bound;

		object_type inven[INVEN_TOTAL];

		memcpy(inven, p_ptr->inventory, INVEN_TOTAL * sizeof(object_type));
		inven[INVEN_WIELD] = *o_ptr;

		if (full) object_know_all_flags(&inven[INVEN_WIELD]);

		calc_bonuses(inven, &state, TRUE);
		dex_plus_bound = STAT_RANGE - state.stat_ind[A_DEX];
		str_plus_bound = STAT_RANGE - state.stat_ind[A_STR];

		dam = ((o_ptr->ds + 1) * o_ptr->dd * 5);

		xtra_postcrit = state.dis_to_d * 10;
		if (object_attack_plusses_are_visible(o_ptr))
		{
			xtra_precrit += o_ptr->to_d * 10;
			plus += o_ptr->to_h;
		}

		calculate_melee_crits(&state, o_ptr->weight, plus,
				&crit_mult, &crit_add, &crit_div);

		/* Warn about heavy weapons */
		if (adj_str_hold[state.stat_ind[A_STR]] < o_ptr->weight / 10)
			textblock_append_c(tb, TERM_L_RED, "You are too weak to use this weapon.\n");

		textblock_append_c(tb, TERM_L_GREEN, "%d.%d ",
				state.num_blows / 100, (state.num_blows / 10) % 10);
		textblock_append(tb, "blow%s/round.\n",
				(state.num_blows > 100) ? "s" : "");

		/* Check to see if extra STR or DEX would yield extra blows */
		old_blows = state.num_blows;
		extra_blows = 0;

		/* First we need to look for extra blows on other items, as
		 * state does not track these */
		for (i = INVEN_BOW; i < INVEN_TOTAL; i++)
		{
			if (!p_ptr->inventory[i].kind)
				continue;
			object_flags_known(&p_ptr->inventory[i], tmp_f);

			if (of_has(tmp_f, OF_BLOWS))
				extra_blows += p_ptr->inventory[i].pval[which_pval(&p_ptr->inventory[i], OF_BLOWS)];
		}

		/* Then we add blows from the weapon being examined */
		if (of_has(f, OF_BLOWS))
			extra_blows += o_ptr->pval[which_pval(o_ptr, OF_BLOWS)];

		/* Then we check for extra "real" blows */
		for (dex_plus = 0; dex_plus < dex_plus_bound; dex_plus++)
		{
			for (str_plus = 0; str_plus < str_plus_bound; str_plus++)
	        {
				state.stat_ind[A_STR] += str_plus;
				state.stat_ind[A_DEX] += dex_plus;
				new_blows = calc_blows(o_ptr, &state, extra_blows);

				/* Test to make sure that this extra blow is a
				 * new str/dex combination, not a repeat
				 */
				if ((new_blows - new_blows % 10) > (old_blows - old_blows % 10) &&
					(str_plus < str_done ||
					str_done == -1))
				{
					textblock_append(tb, "With +%d STR and +%d DEX you would get %d.%d blows\n",
						str_plus, dex_plus, (new_blows / 100),
						(new_blows / 10) % 10);
					state.stat_ind[A_STR] -= str_plus;
					state.stat_ind[A_DEX] -= dex_plus;
					str_done = str_plus;
					break;
				}

				/* If the combination doesn't increment
				 * the displayed blows number, it might still
				 * take a little less energy
				 */
				if (new_blows > old_blows &&
					(str_plus < str_faster ||
					str_faster == -1) &&
					(str_plus < str_done ||
					str_done == -1))
				{
					textblock_append(tb, "With +%d STR and +%d DEX you would attack a bit faster\n",
						str_plus, dex_plus);
					state.stat_ind[A_STR] -= str_plus;
					state.stat_ind[A_DEX] -= dex_plus;
					str_faster = str_plus;
					continue;
				}

				state.stat_ind[A_STR] -= str_plus;
				state.stat_ind[A_DEX] -= dex_plus;
			}
		}
	}
	else
	{
		int tdis = 6 + 2 * p_ptr->state.ammo_mult;

		if (object_attack_plusses_are_visible(o_ptr))
			plus += o_ptr->to_h;

		calculate_missile_crits(&p_ptr->state, o_ptr->weight, plus,
				&crit_mult, &crit_add, &crit_div);

		/* Calculate damage */
		dam = ((o_ptr->ds + 1) * o_ptr->dd * 5);

		if (object_attack_plusses_are_visible(o_ptr))
			dam += (o_ptr->to_d * 10);
		if (object_attack_plusses_are_visible(bow))
			dam += (bow->to_d * 10);

		/* Apply brands/slays from the shooter to the ammo, but only if known
		 * Note that this is not dependent on mode, so that viewing shop-held
		 * ammo (fully known) does not leak information about launcher */
		object_flags_known(bow, tmp_f);
		of_union(f, tmp_f);

		textblock_append(tb, "Hits targets up to ");
		textblock_append_c(tb, TERM_L_GREEN, format("%d", tdis * 10));
		textblock_append(tb, " feet away.\n");
	}

	/* Collect slays */
	/* Melee weapons get slays and brands from other items now */
	if (weapon)
	{
		bool nonweap = FALSE;

		for (i = INVEN_LEFT; i < INVEN_TOTAL; i++)
		{
			if (!p_ptr->inventory[i].kind)
				continue;
			object_flags_known(&p_ptr->inventory[i], tmp_f);

			of_inter(tmp_f, mask); /* strip out non-slays */

			if (of_union(f, tmp_f))
				nonweap = TRUE;
		}

		if (nonweap)
			textblock_append(tb, "This weapon may benefit from one or more off-weapon brands or slays.\n");
	}

	textblock_append(tb, "Average damage/round: ");

	if (ammo) multiplier = p_ptr->state.ammo_mult;

	cnt = list_slays(f, mask, desc, NULL, mult, TRUE);
	for (i = 0; i < cnt; i++)
	{
		int melee_adj_mult = ammo ? 0 : 1; /* ammo mult adds fully, melee mult is times 1, so adds 1 less */
		/* Include bonus damage and slay in stated average */
		total_dam = dam * (multiplier + mult[i] - melee_adj_mult) + xtra_precrit;
		total_dam = (total_dam * crit_mult + crit_add) / crit_div;
		total_dam += xtra_postcrit;
		if (weapon) 
			total_dam = (total_dam * old_blows) / 100;
		else
			total_dam *= p_ptr->state.num_shots;
		

		if (total_dam <= 0)
			textblock_append_c(tb, TERM_L_RED, "%d", 0);
		else if (total_dam % 10)
			textblock_append_c(tb, TERM_L_GREEN, "%d.%d",
					total_dam / 10, total_dam % 10);
		else
			textblock_append_c(tb, TERM_L_GREEN, "%d", total_dam / 10);


		textblock_append(tb, " vs. %s, ", desc[i]);
	}

	if (cnt) textblock_append(tb, "and ");

	/* Include bonus damage in stated average */
	total_dam = dam * multiplier + xtra_precrit;
	total_dam = (total_dam * crit_mult + crit_add) / crit_div;
	total_dam += xtra_postcrit;
	if (weapon)
		total_dam = (total_dam * old_blows) / 100;
	else
		total_dam *= p_ptr->state.num_shots;

	if (total_dam <= 0)
		textblock_append_c(tb, TERM_L_RED, "%d", 0);
	else if (total_dam % 10)
		textblock_append_c(tb, TERM_L_GREEN, "%d.%d",
				total_dam / 10, total_dam % 10);
	else
		textblock_append_c(tb, TERM_L_GREEN, "%d", total_dam / 10);

	if (cnt) textblock_append(tb, " vs. others");
	textblock_append(tb, ".\n");

	/* Note the impact flag */
	if (of_has(f, OF_IMPACT))
		textblock_append(tb, "Sometimes creates earthquakes on impact.\n");

	/* Add breakage chance */
	if (ammo)
	{
		int chance = breakage_chance(o_ptr, TRUE);
		textblock_append_c(tb, TERM_L_GREEN, "%d%%", chance);
		textblock_append(tb, " chance of breaking upon contact.\n");
	}

	/* You always have something to say... */
	return TRUE;
}
Пример #20
0
/*
 * Output object information
 */
static textblock *object_info_out(const object_type *o_ptr, oinfo_detail_t mode)
{
	bitflag flags[OF_SIZE];
	bitflag pval_flags[MAX_PVALS][OF_SIZE];
	bool something = FALSE;
	bool known = object_is_known(o_ptr);

	bool full = mode & OINFO_FULL;
	bool terse = mode & OINFO_TERSE;
	bool subjective = mode & OINFO_SUBJ;
	bool ego = mode & OINFO_EGO;

	textblock *tb = textblock_new();

	/* Grab the object flags */
	if (full) {
		object_flags(o_ptr, flags);
		object_pval_flags(o_ptr, pval_flags);
	} else {
		object_flags_known(o_ptr, flags);
		object_pval_flags_known(o_ptr, pval_flags);
	}

	if (subjective) describe_origin(tb, o_ptr);
	if (!terse) describe_flavor_text(tb, o_ptr);

	if (!full && !known)
	{
		textblock_append(tb, "You do not know the full extent of this item's powers.\n");
		if (SENSING_REVEALS_FLAG_COUNT) {
			if (object_was_sensed(o_ptr)) {
				int unlearned = object_num_unlearned_flags(o_ptr);
				switch(unlearned) {
					case 0:
						textblock_append(tb, "It has no unknown flags.\n");
						break;
					case 1:
						textblock_append(tb, "It has 1 unknown flag.\n", unlearned);
						break;
					default:
						textblock_append(tb, "It has %d unknown flags.\n", unlearned);
						break;
				}
			}
		}

		something = TRUE;
	}

	if (describe_curses(tb, o_ptr, flags)) something = TRUE;
	if (describe_stats(tb, o_ptr, pval_flags, mode)) something = TRUE;
	if (describe_slays(tb, flags, o_ptr->tval)) something = TRUE;
	if (describe_immune(tb, flags)) something = TRUE;
	if (describe_ignores(tb, flags)) something = TRUE;
	if (describe_sustains(tb, flags)) something = TRUE;
	if (describe_misc_magic(tb, flags)) something = TRUE;
	if (ego && describe_ego(tb, o_ptr->ego)) something = TRUE;
	if (something) textblock_append(tb, "\n");

	if (describe_effect(tb, o_ptr, full, terse, subjective))
	{
		something = TRUE;
		textblock_append(tb, "\n");
	}

	if (subjective && describe_combat(tb, o_ptr, mode))
	{
		something = TRUE;
		textblock_append(tb, "\n");
	}

	if (!terse && describe_food(tb, o_ptr, subjective, full)) something = TRUE;
	if (describe_light(tb, o_ptr, flags, terse)) something = TRUE;
	if (!terse && subjective && describe_digger(tb, o_ptr, mode)) something = TRUE;

	if (!something)
		textblock_append(tb, "\n\nThis item does not seem to possess any special abilities.");

	return tb;
}
Пример #21
0
/**
 * Special display, part 2c
 *
 * How to print out the modifications and sustains.
 * Positive mods with no sustain will be light green.
 * Positive mods with a sustain will be dark green.
 * Sustains (with no modification) will be a dark green 's'.
 * Negative mods (from a curse) will be red.
 * Huge mods (>9), like from MICoMorgoth, will be a '*'
 * No mod, no sustain, will be a slate '.'
 */
static void display_player_sust_info(void)
{
	int i, row, col, stat;

	struct object *obj;
	bitflag f[OF_SIZE];

	byte a;
	char c;


	/* Row */
	row = 2;

	/* Column */
	col = 26;

	/* Header */
	c_put_str(COLOUR_WHITE, "abcdefghijkl@", row-1, col);

	/* Process equipment */
	for (i = 0; i < player->body.count; ++i) {
		/* Get the object */
		obj = slot_object(player, i);

		if (!obj) {
			col++;
			continue;
		}

		/* Get the "known" flags */
		object_flags_known(obj, f);

		/* Initialize color based on sign of modifier. */
		for (stat = OBJ_MOD_MIN_STAT; stat < OBJ_MOD_MIN_STAT + STAT_MAX;
			 stat++) {
			/* Default */
			a = COLOUR_SLATE;
			c = '.';

			/* Boosted or reduced */
			if (obj->modifiers[stat] > 0) {
				/* Good */
				a = COLOUR_L_GREEN;

				/* Label boost */
				if (obj->modifiers[stat] < 10)
						c = I2D(obj->modifiers[stat]);
			} else if (obj->modifiers[stat] < 0) {
				/* Bad */
				a = COLOUR_RED;

				/* Label boost */
				if (obj->modifiers[stat] > -10)
					c = I2D(-(obj->modifiers[stat]));
			}

			/* Sustain */
			if (of_has(f, sustain_flag(stat))) {
				/* Dark green */
				a = COLOUR_GREEN;

				/* Convert '.' to 's' */
				if (c == '.') c = 's';
			}

			if ((c == '.') && obj && 
				!object_flag_is_known(obj, sustain_flag(stat)))
				c = '?';

			/* Dump proper character */
			Term_putch(col, row+stat, a, c);
		}

		/* Advance */
		col++;
	}

	/* Player flags */
	player_flags(player, f);

	/* Check stats */
	for (stat = 0; stat < STAT_MAX; ++stat) {
		/* Default */
		a = COLOUR_SLATE;
		c = '.';

		/* Sustain */
		if (of_has(f, sustain_flag(stat))) {
			/* Dark green "s" */
			a = COLOUR_GREEN;
			c = 's';
		}

		/* Dump */
		Term_putch(col, row+stat, a, c);
	}

	/* Column */
	col = 26;

	/* Footer */
	c_put_str(COLOUR_WHITE, "abcdefghijkl@", row+6, col);

	/* Equippy */
	display_player_equippy(row+7, col);
}
Пример #22
0
static void display_resistance_panel(const struct player_flag_record *rec,
									size_t size, const region *bounds) 
{
	size_t i;
	int j;
	int col = bounds->col;
	int row = bounds->row;
	int res_cols = 5 + 2 + player->body.count;

	Term_putstr(col, row++, res_cols, COLOUR_WHITE, "      abcdefghijkl@");
	for (i = 0; i < size - 3; i++, row++) {
		byte name_attr = COLOUR_WHITE;
		Term_gotoxy(col + 6, row);

		/* Repeated extraction of flags is inefficient but more natural */
		for (j = 0; j <= player->body.count; j++) {
			bitflag f[OF_SIZE];
			byte attr = COLOUR_WHITE | (j % 2) * 8; /* alternating columns */
			char sym = '.';
			bool res = false, imm = false, vul = false, rune = false;
			bool timed = false;
			bool known = false;

			/* Object or player info? */
			if (j < player->body.count) {
				int index = 0;
				struct object *obj = slot_object(player, j);
				struct curse_data *curse = obj ? obj->curses : NULL;

				while (obj) {
					/* Wipe flagset */
					of_wipe(f);

					/* Get known properties */
					object_flags_known(obj, f);
					if (rec[i].element != -1) {
						known = object_element_is_known(obj, rec[i].element);
					} else if (rec[i].flag != -1) {
						known = object_flag_is_known(obj, rec[i].flag);
					} else {
						known = true;
					}

					/* Get resistance, immunity and vulnerability info */
					if (rec[i].mod != -1) {
						if (obj->modifiers[rec[i].mod] != 0) {
							res = true;
						}
						rune = (player->obj_k->modifiers[rec[i].mod] == 1);
					} else if (rec[i].flag != -1) {
						if (of_has(f, rec[i].flag)) {
							res = true;
						}
						rune = of_has(player->obj_k->flags, rec[i].flag);
					} else if (rec[i].element != -1) {
						if (known) {
							if (obj->el_info[rec[i].element].res_level == 3) {
								imm = true;
							}
							if (obj->el_info[rec[i].element].res_level == 1) {
								res = true;
							}
							if (obj->el_info[rec[i].element].res_level == -1) {
								vul = true;
							}
						}
						rune = (player->obj_k->el_info[rec[i].element].res_level == 1);
					}

					/* Move to any unprocessed curse object */
					if (curse) {
						index++;
						obj = NULL;
						while (index < z_info->curse_max) {
							if (curse[index].power) {
								obj = curses[index].obj;
								break;
							} else {
								index++;
							}
						}
					} else {
						obj = NULL;
					}
				}
			} else {
				player_flags(player, f);
				known = true;

				/* Timed flags only in the player column */
				if (rec[i].tmd_flag >= 0) {
	 				timed = player->timed[rec[i].tmd_flag] ? true : false;
					/* There has to be one special case... */
					if ((rec[i].tmd_flag == TMD_AFRAID) &&
						(player->timed[TMD_TERROR]))
						timed = true;
				}

				/* Set which (if any) symbol and color are used */
				if (rec[i].mod != -1) {
					int k;

					/* Shape modifiers */
					for (k = 0; k < OBJ_MOD_MAX; k++) {
						res = (player->shape->modifiers[i] > 0);
						vul = (player->shape->modifiers[i] > 0);
					}

					/* Messy special cases */
					if (rec[i].mod == OBJ_MOD_INFRA)
						res |= (player->race->infra > 0);
					if (rec[i].mod == OBJ_MOD_TUNNEL)
						res |= (player->race->r_skills[SKILL_DIGGING] > 0);
				} else if (rec[i].flag != -1) {
					res = of_has(f, rec[i].flag);
					res |= (of_has(player->shape->flags, rec[i].flag) &&
							of_has(player->obj_k->flags, rec[i].flag));
				} else if (rec[i].element != -1) {
					int el = rec[i].element;
					imm = (player->race->el_info[el].res_level == 3) ||
						((player->shape->el_info[el].res_level == 3) &&
						 (player->obj_k->el_info[el].res_level));
					res = (player->race->el_info[el].res_level == 1) ||
						((player->shape->el_info[el].res_level == 1) &&
						 (player->obj_k->el_info[el].res_level));
					vul = (player->race->el_info[el].res_level == -1) ||
						((player->shape->el_info[el].res_level == -1) &&
						 (player->obj_k->el_info[el].res_level));
				}
			}

			/* Colour the name appropriately */
			if (imm) {
				name_attr = COLOUR_GREEN;
			} else if (res && (name_attr != COLOUR_GREEN)) {
				name_attr = COLOUR_L_BLUE;
			} else if (vul && (name_attr != COLOUR_GREEN)) {
				name_attr = COLOUR_RED;
			}

			/* Set the symbols and print them */
			if (vul) {
				sym = '-';
			} else if (imm) {
				sym = '*';
			} else if (res) {
				sym = '+';
			} else if (timed) {
				sym = '!';
				attr = COLOUR_L_GREEN;
			} else if ((j < player->body.count) && slot_object(player, j) &&
					   !known && !rune) {
				sym = '?';
			}

			Term_addch(attr, sym);
		}

		/* Check if the rune is known */
		if (((rec[i].mod >= 0) &&
			 (player->obj_k->modifiers[rec[i].mod] == 0))
			|| ((rec[i].flag >= 0) &&
				!of_has(player->obj_k->flags, rec[i].flag))
			|| ((rec[i].element >= 0) &&
				(player->obj_k->el_info[rec[i].element].res_level == 0))) {
			name_attr = COLOUR_SLATE;
		}

		Term_putstr(col, row, 6, name_attr, format("%5s:", rec[i].name));
	}
	Term_putstr(col, row++, res_cols, COLOUR_WHITE, "      abcdefghijkl@");

	/* Equippy */
	display_player_equippy(row++, col + 6);
}
Пример #23
0
/*
 * Describe combat advantages.
 */
static bool describe_combat(textblock *tb, const object_type *o_ptr,
		oinfo_detail_t mode)
{
	bool full = mode & OINFO_FULL;

	object_type *bow = &p_ptr->inventory[INVEN_BOW];

	bitflag f[OF_SIZE];

	bool weapon = (wield_slot(o_ptr) == INVEN_WIELD);
	bool ammo   = (p_ptr->state.ammo_tval == o_ptr->tval) &&
	              (bow->kind);

	/* The player's hypothetical state, were they to wield this item */
	player_state state;

	/* Abort if we've nothing to say */
	if (mode & OINFO_DUMMY) return FALSE;

	if (!weapon && !ammo) {
		/* Potions can have special text */
		if (o_ptr->tval != TV_POTION ||
				o_ptr->dd == 0 || o_ptr->ds == 0 ||
				!object_flavor_is_aware(o_ptr))
			return FALSE;

		textblock_append(tb, "It can be thrown at creatures with damaging effect.\n");
		return TRUE;
	}

	if (full)
		object_flags(o_ptr, f);
	else
		object_flags_known(o_ptr, f);

	textblock_append_c(tb, TERM_L_WHITE, "Combat info:\n");

	if (weapon)	{
		object_type inven[INVEN_TOTAL];

		memcpy(inven, p_ptr->inventory, INVEN_TOTAL * sizeof(object_type));
		inven[INVEN_WIELD] = *o_ptr;

		if (full) object_know_all_flags(&inven[INVEN_WIELD]);

		/* Calculate the player's hypothetical state */
		calc_bonuses(inven, &state, TRUE);

		/* Warn about heavy weapons */
		if (adj_str_hold[state.stat_ind[A_STR]] < o_ptr->weight / 10)
			textblock_append_c(tb, TERM_L_RED, "You are too weak to use this weapon.\n");

		/* Describe blows */
		describe_blows(tb, o_ptr, state, f);
	} else { /* Ammo */
		/* Range of the weapon */
		int tdis = 6 + 2 * p_ptr->state.ammo_mult;

		/* Output the range */
		textblock_append(tb, "Hits targets up to ");
		textblock_append_c(tb, TERM_L_GREEN, format("%d", tdis * 10));
		textblock_append(tb, " feet away.\n");
	}

	/* Describe damage */
	describe_damage(tb, o_ptr, state, f, mode);

	/* Note the impact flag */
	if (of_has(f, OF_IMPACT))
		textblock_append(tb, "Sometimes creates earthquakes on impact.\n");

	/* Add breakage chance */
	if (ammo) {
		int chance = breakage_chance(o_ptr, TRUE);
		textblock_append_c(tb, TERM_L_GREEN, "%d%%", chance);
		textblock_append(tb, " chance of breaking upon contact.\n");
	}

	/* Something has been said */
	return TRUE;
}
Пример #24
0
/*
 * Describe damage.
 */
static bool describe_damage(textblock *tb, const object_type *o_ptr,
		player_state state, bitflag f[OF_SIZE], oinfo_detail_t mode)
{
	const char *desc[SL_MAX] = { 0 };
	size_t i, cnt;
	int mult[SL_MAX];
	int dice, sides, dam, total_dam, plus = 0;
	int xtra_postcrit = 0, xtra_precrit = 0;
	int crit_mult, crit_div, crit_add;
	int old_blows = 0;
	object_type *bow = &p_ptr->inventory[INVEN_BOW];

	bitflag tmp_f[OF_SIZE], mask[OF_SIZE];

	bool weapon = (wield_slot(o_ptr) == INVEN_WIELD);
	bool ammo   = (p_ptr->state.ammo_tval == o_ptr->tval) &&
	              (bow->kind);
	int multiplier = 1;
	bool full = mode & OINFO_FULL;

	/* Create the "all slays" mask */
	create_mask(mask, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX);

	/* Use displayed dice if real dice not known */
	if (full || object_attack_plusses_are_visible(o_ptr)) {
		dice = o_ptr->dd;
		sides = o_ptr->ds;
	} else {
		dice = o_ptr->kind->dd;
		sides = o_ptr->kind->ds;
	}

	/* Calculate damage */
	dam = ((sides + 1) * dice * 5);

	if (weapon)	{
		xtra_postcrit = state.dis_to_d * 10;
		if (object_attack_plusses_are_visible(o_ptr) || full) {
			xtra_precrit += o_ptr->to_d * 10;
			plus += o_ptr->to_h;
		}

		calculate_melee_crits(&state, o_ptr->weight, plus,
				&crit_mult, &crit_add, &crit_div);

		old_blows = state.num_blows;
	} else { /* Ammo */
		if (object_attack_plusses_are_visible(o_ptr) || full)
			plus += o_ptr->to_h;

		calculate_missile_crits(&p_ptr->state, o_ptr->weight, plus,
				&crit_mult, &crit_add, &crit_div);

		if (object_attack_plusses_are_visible(o_ptr) || full)
			dam += (o_ptr->to_d * 10);
		if (object_attack_plusses_are_visible(bow))
			dam += (bow->to_d * 10);

		/* Apply brands/slays from the shooter to the ammo, but only if known
		 * Note that this is not dependent on mode, so that viewing shop-held
		 * ammo (fully known) does not leak information about launcher */
		object_flags_known(bow, tmp_f);
		of_union(f, tmp_f);
	}

	/* Collect slays */
	/* Melee weapons get slays and brands from other items now */
	if (weapon)	{
		bool nonweap_slay = FALSE;

		for (i = INVEN_LEFT; i < INVEN_TOTAL; i++) {
			if (!p_ptr->inventory[i].kind)
				continue;

			object_flags_known(&p_ptr->inventory[i], tmp_f);

			/* Strip out non-slays */
			of_inter(tmp_f, mask);

			if (of_union(f, tmp_f))
				nonweap_slay = TRUE;
		}

		if (nonweap_slay)
			textblock_append(tb, "This weapon may benefit from one or more off-weapon brands or slays.\n");
	}

	textblock_append(tb, "Average damage/round: ");

	if (ammo) multiplier = p_ptr->state.ammo_mult;

	/* Output damage for creatures effected by the brands or slays */
	cnt = list_slays(f, mask, desc, NULL, mult, TRUE);
	for (i = 0; i < cnt; i++) {
		/* ammo mult adds fully, melee mult is times 1, so adds 1 less */
		int melee_adj_mult = ammo ? 0 : 1;

		/* Include bonus damage and slay in stated average */
		total_dam = dam * (multiplier + mult[i] - melee_adj_mult) + xtra_precrit;
		total_dam = (total_dam * crit_mult + crit_add) / crit_div;
		total_dam += xtra_postcrit;

		if (weapon)
			total_dam = (total_dam * old_blows) / 100;
		else
			total_dam *= p_ptr->state.num_shots;

		if (total_dam <= 0)
			textblock_append_c(tb, TERM_L_RED, "%d", 0);
		else if (total_dam % 10)
			textblock_append_c(tb, TERM_L_GREEN, "%d.%d",
					total_dam / 10, total_dam % 10);
		else
			textblock_append_c(tb, TERM_L_GREEN, "%d", total_dam / 10);

		textblock_append(tb, " vs. %s, ", desc[i]);
	}

	if (cnt) textblock_append(tb, "and ");

	/* Include bonus damage in stated average */
	total_dam = dam * multiplier + xtra_precrit;
	total_dam = (total_dam * crit_mult + crit_add) / crit_div;
	total_dam += xtra_postcrit;

	/* Normal damage, not considering brands or slays */
	if (weapon)
		total_dam = (total_dam * old_blows) / 100;
	else
		total_dam *= p_ptr->state.num_shots;

	if (total_dam <= 0)
		textblock_append_c(tb, TERM_L_RED, "%d", 0);
	else if (total_dam % 10)
		textblock_append_c(tb, TERM_L_GREEN, "%d.%d",
				total_dam / 10, total_dam % 10);
	else
		textblock_append_c(tb, TERM_L_GREEN, "%d", total_dam / 10);

	if (cnt) textblock_append(tb, " vs. others");
	textblock_append(tb, ".\n");

	return TRUE;
}
Пример #25
0
/*
 * Describe blows.
 */
static bool describe_blows(textblock *tb, const object_type *o_ptr,
		player_state state, bitflag f[OF_SIZE])
{
	int str_plus, dex_plus, old_blows = 0, new_blows, extra_blows;
	int str_faster = -1, str_done = -1;
	int dex_plus_bound;
	int str_plus_bound;
	int i;

	bitflag tmp_f[OF_SIZE];

	dex_plus_bound = STAT_RANGE - state.stat_ind[A_DEX];
	str_plus_bound = STAT_RANGE - state.stat_ind[A_STR];

	/* Write to the text block */
	textblock_append_c(tb, TERM_L_GREEN, "%d.%d ",
			state.num_blows / 100, (state.num_blows / 10) % 10);
	textblock_append(tb, "blow%s/round.\n",
			(state.num_blows > 100) ? "s" : "");

	/* Check to see if extra STR or DEX would yield extra blows */
	old_blows = state.num_blows;
	extra_blows = 0;

	/* First we need to look for extra blows on other items, as
	 * state does not track these */
	for (i = INVEN_BOW; i < INVEN_TOTAL; i++)
	{
		if (!p_ptr->inventory[i].kind)
			continue;

		object_flags_known(&p_ptr->inventory[i], tmp_f);

		if (of_has(tmp_f, OF_BLOWS))
			extra_blows += p_ptr->inventory[i].pval[which_pval(&p_ptr->inventory[i], OF_BLOWS)];
	}

	/* Then we add blows from the weapon being examined */
	if (of_has(f, OF_BLOWS))
		extra_blows += o_ptr->pval[which_pval(o_ptr, OF_BLOWS)];

	/* Then we check for extra "real" blows */
	for (dex_plus = 0; dex_plus < dex_plus_bound; dex_plus++)
	{
		for (str_plus = 0; str_plus < str_plus_bound; str_plus++)
        {
			state.stat_ind[A_STR] += str_plus;
			state.stat_ind[A_DEX] += dex_plus;
			new_blows = calc_blows(o_ptr, &state, extra_blows);

			/* Test to make sure that this extra blow is a
			 * new str/dex combination, not a repeat
			 */
			if ((new_blows - new_blows % 10) > (old_blows - old_blows % 10) &&
				(str_plus < str_done ||
				str_done == -1))
			{
				textblock_append(tb, "With +%d STR and +%d DEX you would get %d.%d blows\n",
					str_plus, dex_plus, (new_blows / 100),
					(new_blows / 10) % 10);
				state.stat_ind[A_STR] -= str_plus;
				state.stat_ind[A_DEX] -= dex_plus;
				str_done = str_plus;
				break;
			}

			/* If the combination doesn't increment
			 * the displayed blows number, it might still
			 * take a little less energy
			 */
			if (new_blows > old_blows &&
				(str_plus < str_faster ||
				str_faster == -1) &&
				(str_plus < str_done ||
				str_done == -1))
			{
				textblock_append(tb, "With +%d STR and +%d DEX you would attack a bit faster\n",
					str_plus, dex_plus);
				state.stat_ind[A_STR] -= str_plus;
				state.stat_ind[A_DEX] -= dex_plus;
				str_faster = str_plus;
				continue;
			}

			state.stat_ind[A_STR] -= str_plus;
			state.stat_ind[A_DEX] -= dex_plus;
		}
	}

	return TRUE;
}
Пример #26
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;
}
Пример #27
0
static void display_resistance_panel(const struct player_flag_record *rec,
									size_t size, const region *bounds) 
{
	size_t i;
	int j;
	int col = bounds->col;
	int row = bounds->row;
	int res_cols = 5 + 2 + player->body.count;

	Term_putstr(col, row++, res_cols, COLOUR_WHITE, "      abcdefghijkl@");
	for (i = 0; i < size - 3; i++, row++) {
		byte name_attr = COLOUR_WHITE;
		Term_gotoxy(col + 6, row);

		/* Repeated extraction of flags is inefficient but more natural */
		for (j = 0; j <= player->body.count; j++) {
			struct object *obj;
			bitflag f[OF_SIZE];

			byte attr = COLOUR_WHITE | (j % 2) * 8; /* alternating columns */
			char sym = '.';

			bool res = false, imm = false, vul = false, rune = false;
			bool timed = false;
			bool known = false;

			/* Wipe flagset */
			of_wipe(f);

			/* Get the object or player info */
			obj = j < player->body.count ? slot_object(player, j) : NULL;
			if (j < player->body.count && obj) {
				/* Get known properties */
				object_flags_known(obj, f);
				if (rec[i].element != -1)
					known = object_element_is_known(obj, rec[i].element);
				else if (rec[i].flag != -1)
					known = object_flag_is_known(obj, rec[i].flag);
				else
					known = true;
			} else if (j == player->body.count) {
				player_flags(player, f);
				known = true;

				/* Timed flags only in the player column */
				if (rec[i].tmd_flag >= 0) {
	 				timed = player->timed[rec[i].tmd_flag] ? true : false;
					/* There has to be one special case... */
					if ((rec[i].tmd_flag == TMD_AFRAID) &&
						(player->timed[TMD_TERROR]))
						timed = true;
				}
			}

			/* Set which (if any) symbol and color are used */
			if (rec[i].mod != -1) {
				if (j != player->body.count)
					res = (obj && (obj->modifiers[rec[i].mod] != 0));
				else {
					/* Messy special cases */
					if (rec[i].mod == OBJ_MOD_INFRA)
						res = (player->race->infra > 0);
					if (rec[i].mod == OBJ_MOD_TUNNEL)
						res = (player->race->r_skills[SKILL_DIGGING] > 0);
				}
				rune = (player->obj_k->modifiers[rec[i].mod] == 1);
			} else if (rec[i].flag != -1) {
				res = of_has(f, rec[i].flag);
				rune = of_has(player->obj_k->flags, rec[i].flag);
			} else if (rec[i].element != -1) {
				if (j != player->body.count) {
					imm = obj && known &&
						(obj->el_info[rec[i].element].res_level == 3);
					res = obj && known &&
						(obj->el_info[rec[i].element].res_level == 1);
					vul = obj && known &&
						(obj->el_info[rec[i].element].res_level == -1);
				} else {
					imm = player->race->el_info[rec[i].element].res_level == 3;
					res = player->race->el_info[rec[i].element].res_level == 1;
					vul = player->race->el_info[rec[i].element].res_level == -1;
				}
				rune = (player->obj_k->el_info[rec[i].element].res_level == 1);
			}

			/* Set the symbols and print them */
			if (imm) name_attr = COLOUR_GREEN;
			else if (!rune) name_attr = COLOUR_SLATE;
			else if (res && (name_attr != COLOUR_GREEN))
				name_attr = COLOUR_L_BLUE;

			if (vul) sym = '-';
			else if (imm) sym = '*';
			else if (res) sym = '+';
			else if (timed) { sym = '!'; attr = COLOUR_L_GREEN; }
			else if ((j < player->body.count) && obj && !known && !rune)
				sym = '?';

			Term_addch(attr, sym);
		}
		Term_putstr(col, row, 6, name_attr, format("%5s:", rec[i].name));
	}
	Term_putstr(col, row++, res_cols, COLOUR_WHITE, "      abcdefghijkl@");

	/* Equippy */
	display_player_equippy(row++, col + 6);
}
Пример #28
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;
}
Пример #29
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];
	u32b f1, f2, f3, fn, knownf1, knownf2, knownf3, knownfn;
	object_flags(o_ptr, &f1, &f2, &f3, &fn);

	object_flags_known(o_ptr, &knownf1, &knownf2, &knownf3, &knownfn);

	/* 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_known_p(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 ((f1 & TR1_MIGHT) && (spoil || (knownf1 & TR1_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_known_p(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 ||
			     o_ptr->tval == TV_DRAG_SHIELD))
				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_known_p(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;
}
Пример #30
0
/*
 * Display an item's properties
 */
static void wiz_display_item(const object_type *o_ptr, bool all)
{
	int j = 0;

	bitflag f[OF_SIZE];

	char buf[256];


	/* Extract the flags */
	if (all)
		object_flags(o_ptr, f);
	else
		object_flags_known(o_ptr, f);

	/* Clear screen */
	Term_clear();

	/* Describe fully */
	object_desc(buf, sizeof(buf), o_ptr,
				ODESC_PREFIX | ODESC_FULL | ODESC_SPOIL);

	prt(buf, 2, j);

	prt(format("combat = (%dd%d) (%+d,%+d) [%d,%+d]",
	           o_ptr->dd, o_ptr->ds, o_ptr->to_h, o_ptr->to_d, o_ptr->ac, o_ptr->to_a), 4, j);

	prt(format("kind = %-5d  tval = %-5d  sval = %-5d  wgt = %-3d     timeout = %-d",
	           o_ptr->kind->kidx, o_ptr->tval, o_ptr->sval, o_ptr->weight, o_ptr->timeout), 5, j);

	/* CC: multiple pvals not shown, pending #1290 */
	prt(format("number = %-3d  pval = %-5d  name1 = %-4d  egoidx = %-4d  cost = %ld",
			o_ptr->number, o_ptr->pval[DEFAULT_PVAL],
			o_ptr->artifact ? o_ptr->artifact->aidx : 0,
			o_ptr->ego ? o_ptr->ego->eidx : 0,
			(long)object_value(o_ptr, 1, FALSE)), 6, j);

	prt("+------------FLAGS0------------+", 8, j);
	prt("AFFECT..........SLAY.......BRAND", 9, j);
	prt("                ae      xxxpaefc", 10, j);
	prt("siwdcc  ssidsasmnvudotgddduoclio", 11, j);
	prt("tnieoh  trnipthgiinmrrnrrmniierl", 12, j);
	prt("rtsxna..lcfgdkttmldncltggndsdced", 13, j);
	prt_binary(f, 0, 14, j, '*', 32);
	prt_binary(o_ptr->known_flags, 0, 15, j, '+', 32);

	prt("+------------FLAGS1------------+", 16, j);
	prt("SUST........IMM.RESIST.........", 17, j);
	prt("            afecaefcpfldbc s n  ", 18, j);
	prt("siwdcc      cilocliooeialoshnecd", 19, j);
	prt("tnieoh      irelierliatrnnnrethi", 20, j);
	prt("rtsxna......decddcedsrekdfddxhss", 21, j);
	prt_binary(f, 32, 22, j, '*', 32);
	prt_binary(o_ptr->known_flags, 32, 23, j, '+', 32);

	prt("+------------FLAGS2------------+", 8, j+34);
	prt("s   ts hn    tadiiii   aiehs  hp", 9, j+34);
	prt("lf  eefoo    egrgggg  bcnaih  vr", 10, j+34);
	prt("we  lerlf   ilgannnn  ltssdo  ym", 11, j+34);	prt("da reiedu   merirrrr  eityew ccc", 12, j+34);
	prt("itlepnele   ppanaefc  svaktm uuu", 13, j+34);
	prt("ghigavail   aoveclio  saanyo rrr", 14, j+34);
	prt("seteticf    craxierl  etropd sss", 15, j+34);
	prt("trenhste    tttpdced  detwes eee", 16, j+34);
	prt_binary(f, 64, 17, j + 34, '*', 32);
	prt_binary(o_ptr->known_flags, 64, 18, j + 34, '+', 32);

	prt("o_ptr->ident:", 20, j+34);
	prt(format("sense  %c  worn   %c  empty   %c  known   %c",
		(o_ptr->ident & IDENT_SENSE) ? '+' : ' ',
		(o_ptr->ident & IDENT_WORN) ? '+' : ' ',
		(o_ptr->ident & IDENT_EMPTY) ? '+' : ' ',
		(o_ptr->ident & IDENT_KNOWN) ? '+' : ' '), 21, j+34);
	prt(format("store  %c  attack %c  defence %c  effect  %c",
		(o_ptr->ident & IDENT_STORE) ? '+' : ' ',
		(o_ptr->ident & IDENT_ATTACK) ? '+' : ' ',
		(o_ptr->ident & IDENT_DEFENCE) ? '+' : ' ',
		(o_ptr->ident & IDENT_EFFECT) ? '+' : ' '), 22, j+34);
	prt(format("indest %c  ego    %c",
		(o_ptr->ident & IDENT_INDESTRUCT) ? '+' : ' ',
		(o_ptr->ident & IDENT_NAME) ? '+' : ' '), 23, j+34);
}