Пример #1
0
/*
 * Inquire whether the player wishes to squelch items similar to an object
 *
 * Returns whether the item is now squelched.
 */
bool squelch_interactive(const object_type *o_ptr)
{
	char out_val[70];

	if (squelch_tval(o_ptr->tval))
	{
		char sval_name[50];

		/* Obtain plural form without a quantity */
		object_desc(sval_name, sizeof sval_name, o_ptr,
					ODESC_BASE | ODESC_PLURAL);
		/* XXX Eddie while correct in a sense, to squelch all torches on torch of brightness you get the message "Ignore Wooden Torches of Brightness in future? " */
		strnfmt(out_val, sizeof out_val, "Ignore %s in future? ",
				sval_name);

		if (!artifact_p(o_ptr) || !object_flavor_is_aware(o_ptr))
		{
			if (get_check(out_val))
			{
				object_squelch_flavor_of(o_ptr);
				msg_format("Ignoring %s from now on.", sval_name);
				return TRUE;
			}
		}
		/* XXX Eddie need to add generalized squelching, e.g. con rings with pval < 3 */
		if (!object_is_jewelry(o_ptr) || (squelch_level_of(o_ptr) != SQUELCH_BAD))
			return FALSE;
	}

	if (object_was_sensed(o_ptr) || object_was_worn(o_ptr) || object_is_known_not_artifact(o_ptr))
	{
		byte value = squelch_level_of(o_ptr);
		int type = squelch_type_of(o_ptr);

/* XXX Eddie on pseudoed cursed artifact, only showed {cursed}, asked to ignore artifacts */
		if ((value != SQUELCH_MAX) && ((value == SQUELCH_BAD) || !object_is_jewelry(o_ptr)))
		{

			strnfmt(out_val, sizeof out_val, "Ignore all %s that are %s in future? ",
				quality_choices[type].name, quality_values[value].name);

			if (get_check(out_val))
			{
				squelch_level[type] = value;
				return TRUE;
			}
		}

	}
	return FALSE;
}
Пример #2
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;
}
Пример #3
0
/**
 * Notice things about an object that would be noticed in time.
 */
static void object_notice_after_time(void)
{
	int i;
	int flag;

	object_type *o_ptr;
	char o_name[80];

	bitflag f[OF_SIZE], timed_mask[OF_SIZE];

	flags_init(timed_mask, OF_SIZE, OF_NOTICE_TIMED_MASK, FLAG_END);

	/* Check every item the player is wearing */
	for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++)
	{
		o_ptr = &p_ptr->inventory[i];

		if (!o_ptr->k_idx || object_is_known(o_ptr)) continue;

		/* Check for timed notice flags */
		object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
		object_flags(o_ptr, f);
		of_inter(f, timed_mask);

		for (flag = of_next(f, FLAG_START); flag != FLAG_END; flag = of_next(f, flag + 1))
		{
			if (!of_has(o_ptr->known_flags, flag))
			{
				/* Message */
				if (!streq(msgs[flag], ""))
					msg_format(msgs[flag], o_name);

				/* Notice the flag */
				object_notice_flag(o_ptr, flag);

				if (object_is_jewelry(o_ptr) &&
					 (!object_effect(o_ptr) || object_effect_is_known(o_ptr)))
				{
					/* XXX this is a small hack, but jewelry with anything noticeable really is obvious */
					/* XXX except, wait until learn activation if that is only clue */
					object_flavor_aware(o_ptr);
					object_check_for_ident(o_ptr);
				}
			}
			else
			{
				/* Notice the flag is absent */
				object_notice_flag(o_ptr, flag);
			}
		}

		/* XXX Is this necessary? */
		object_check_for_ident(o_ptr);
	}
}
Пример #4
0
/**
 * Notice a given special flag on wielded items.
 *
 * \param flag is the flag to notice
 */
void wieldeds_notice_flag(int flag)
{
	int i;

	/* XXX Eddie need different naming conventions for starting wieldeds at INVEN_WIELD vs INVEN_WIELD+2 */
	for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++)
	{
		object_type *o_ptr = &p_ptr->inventory[i];
		bitflag f[OF_SIZE];

		if (!o_ptr->k_idx) continue;

		object_flags(o_ptr, f);

		if (of_has(f, flag) && !of_has(o_ptr->known_flags, flag))
		{
			char o_name[80];
			object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);

			/* Notice the flag */
			object_notice_flag(o_ptr, flag);

			/* XXX Eddie should this go before noticing the flag to avoid learning twice? */
			if (EASY_LEARN && object_is_jewelry(o_ptr))
			{
				/* XXX Eddie EASY_LEARN Possible concern: gets =teleportation just from +2 speed */
				object_flavor_aware(o_ptr);
				object_check_for_ident(o_ptr);
			}

			/* Message */
			if (!streq(msgs[flag], ""))
				msg_format(msgs[flag], o_name);
		}
		else
		{
			/* Notice that flag is absent */
			object_notice_flag(o_ptr, flag);
		}

		/* XXX Eddie should not need this, should be done in noticing, but will remove later */
		object_check_for_ident(o_ptr);

	}

	return;
}
Пример #5
0
/**
 * \returns whether the object's defence bonuses are known
 */
bool object_defence_plusses_are_visible(const object_type *o_ptr)
{
	/* Bonuses have been revealed or for sale */
	if ((o_ptr->ident & IDENT_DEFENCE) || (o_ptr->ident & IDENT_STORE))
		return TRUE;

	/* Aware jewelry with non-variable bonuses */
	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->to_a))
			return TRUE;
	}

	return FALSE;
}
Пример #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;
}
Пример #7
0
/*
 * Destroy an item
 */
void do_cmd_destroy(void)
{
    int          item, amt = 1;
    int          old_number;
    bool         force = FALSE;
    object_type *o_ptr;
    object_type  forge;
    object_type *q_ptr = &forge;
    bool         is_equipped = FALSE;
    char         o_name[MAX_NLEN];
    char         out_val[MAX_NLEN+40];

    cptr q, s;
    int mode = USE_INVEN | USE_FLOOR;

    if (p_ptr->pclass == CLASS_RUNE_KNIGHT)
        mode |= USE_EQUIP;

    if (p_ptr->special_defense & KATA_MUSOU)
    {
        set_action(ACTION_NONE);
    }

    /* Hack -- force destruction */
    if (command_arg > 0) force = TRUE;


    /* Get an item */
    q = "Destroy which item? ";
    s = "You have nothing to destroy.";

    if (!get_item(&item, q, s, mode)) return;

    /* Get the item (in the pack) */
    if (item >= 0)
    {
        o_ptr = &inventory[item];
        is_equipped = equip_is_valid_slot(item);
    }

    /* Get the item (on the floor) */
    else
    {
        o_ptr = &o_list[0 - item];
    }

    /* Hack for Rune Knight: They can destroy worn equipment, but only
       if it has the Sacrifice rune.  get_item() is not smart enough
       to handle this restriction ... */
    if (is_equipped && o_ptr->rune != RUNE_SACRIFICE)
    {
        msg_print("You must first remove that item before destroying it.");
        return;
    }

    /* Verify unless quantity given beforehand */
    if (!force && (confirm_destroy || (object_value(o_ptr) > 0)))
    {
        object_desc(o_name, o_ptr, OD_OMIT_PREFIX);

        /* Make a verification */
        sprintf(out_val, 
            "Really destroy %s? [y/n/Auto]",
            o_name);

        msg_print(NULL);

        /* HACK : Add the line to message buffer */
        message_add(out_val);
        p_ptr->window |= (PW_MESSAGE);
        window_stuff();

        /* Get an acceptable answer */
        while (TRUE)
        {
            char i;

            /* Prompt */
            prt(out_val, 0, 0);

            i = inkey();

            /* Erase the prompt */
            prt("", 0, 0);


            if (i == 'y' || i == 'Y')
            {
                break;
            }
            if (i == ESCAPE || i == 'n' || i == 'N')
            {
                /* Cancel */
                return;
            }
            if (i == 'A')
            {
                /* Add an auto-destroy preference line */
                if (autopick_autoregister(o_ptr))
                {
                    /* Auto-destroy it */
                    autopick_alter_item(item, TRUE);
                }

                /* The object is already destroyed. */
                return;
            }
        } /* while (TRUE) */
    }

    /* See how many items */
    if (o_ptr->number > 1)
    {
        /* Get a quantity */
        amt = get_quantity(NULL, o_ptr->number);

        /* Allow user abort */
        if (amt <= 0) return;
    }


    /* Describe the object */
    old_number = o_ptr->number;
    o_ptr->number = amt;
    object_desc(o_name, o_ptr, 0);
    o_ptr->number = old_number;

    /* Take a turn */
    energy_use = 100;

    /* Artifacts cannot be destroyed */
    if (!can_player_destroy_object(o_ptr))
    {
        energy_use = 0;

        /* Message */
        msg_format("You cannot destroy %s.", o_name);

        /* Done */
        return;
    }

    object_copy(q_ptr, o_ptr);

    stats_on_p_destroy(o_ptr, amt);

    if (prace_is_(RACE_MON_JELLY))
        jelly_eat_object(o_ptr);
    else if (prace_is_(RACE_MON_SWORD) && object_is_melee_weapon(o_ptr))
        sword_absorb_object(o_ptr);
    else if (prace_is_(RACE_MON_RING) && object_is_jewelry(o_ptr))
        ring_absorb_object(o_ptr);
    else
        msg_format("You destroy %s.", o_name);

    if (o_ptr->rune == RUNE_SACRIFICE)
    {
        int add_hp = is_equipped ? p_ptr->mhp : p_ptr->mhp/3;
        int add_sp = is_equipped ? p_ptr->msp : p_ptr->msp/3;

        msg_print("You feel a surge of wondrous power enter your body.");
        
        p_ptr->chp = MIN(p_ptr->mhp, p_ptr->chp + add_hp);
        p_ptr->chp_frac = 0;
        p_ptr->csp = MIN(p_ptr->msp, p_ptr->csp + add_sp);
        p_ptr->csp_frac = 0;

        p_ptr->redraw |= (PR_MANA);
        p_ptr->window |= (PW_PLAYER);
        p_ptr->window |= (PW_SPELL);
        p_ptr->redraw |= (PR_HP);

        if (is_equipped)
        {
            blast_object(o_ptr);
            o_ptr->curse_flags = TRC_HEAVY_CURSE;
        }
    }
    else if (is_equipped)
        blast_object(o_ptr);

    sound(SOUND_DESTITEM);

    /* Reduce the charges of rods/wands */
    reduce_charges(o_ptr, amt);

    /* Eliminate the item (from the pack) */
    if (item >= 0)
    {
        if (!is_equipped)
        {
            inven_item_increase(item, -amt);
            inven_item_describe(item);
            inven_item_optimize(item);
        }
    }

    /* Eliminate the item (from the floor) */
    else
    {
        floor_item_increase(0 - item, -amt);
        floor_item_describe(0 - item);
        floor_item_optimize(0 - item);
    }

    if ( p_ptr->pclass == CLASS_NECROMANCER
      && (q_ptr->tval == TV_LIFE_BOOK || q_ptr->tval == TV_CRUSADE_BOOK) )
    {
        int sp = 0;
        int osp = p_ptr->csp;
        switch (q_ptr->sval)
        {
        case 0: sp = 10; break;
        case 1: sp = 25; break;
        case 2: sp = 100; break;
        case 3: sp = 666; break;
        }

        p_ptr->csp += sp;
        if (p_ptr->csp >= p_ptr->msp)
        {
            p_ptr->csp = p_ptr->msp;
            p_ptr->csp_frac = 0;
        }

        if (p_ptr->csp > osp)
            msg_print("You feel your head clear.");

        p_ptr->redraw |= (PR_MANA);
    }

    if (high_level_book(q_ptr))
    {
        bool gain_expr = FALSE;

        if (p_ptr->prace == RACE_ANDROID)
        {
        }
        else if ((p_ptr->pclass == CLASS_WARRIOR) || (p_ptr->pclass == CLASS_BERSERKER))
        {
            gain_expr = TRUE;
        }
        else if (p_ptr->pclass == CLASS_PALADIN)
        {
            if (is_good_realm(p_ptr->realm1))
            {
                if (!is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE;
            }
            else
            {
                if (is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE;
            }
        }

        if (gain_expr && (p_ptr->exp < PY_MAX_EXP))
        {
            s32b tester_exp = p_ptr->max_exp / 20;
            if (tester_exp > 10000) tester_exp = 10000;
            if (q_ptr->sval < 3) tester_exp /= 4;
            if (tester_exp<1) tester_exp = 1;

            msg_print("You feel more experienced.");
            gain_exp(tester_exp * amt);
        }
    }

    if (high_level_book(q_ptr) && q_ptr->tval == TV_LIFE_BOOK)
    {
        virtue_add(VIRTUE_UNLIFE, 1);
        virtue_add(VIRTUE_VITALITY, -1);
    }
    else if ( high_level_book(q_ptr) 
           && (q_ptr->tval == TV_DEATH_BOOK || q_ptr->tval == TV_NECROMANCY_BOOK) )
    {
        virtue_add(VIRTUE_UNLIFE, -1);
        virtue_add(VIRTUE_VITALITY, 1);
    }    

    if (q_ptr->to_a || q_ptr->to_h || q_ptr->to_d)
        virtue_add(VIRTUE_ENCHANTMENT, -1);
    
    if (object_value_real(q_ptr) > 30000)
        virtue_add(VIRTUE_SACRIFICE, 2);
    
    else if (object_value_real(q_ptr) > 10000)
        virtue_add(VIRTUE_SACRIFICE, 1);

    if (q_ptr->to_a != 0 || q_ptr->to_d != 0 || q_ptr->to_h != 0)
        virtue_add(VIRTUE_HARMONY, 1);

    if (equip_is_valid_slot(item)) 
        calc_android_exp();
}
Пример #8
0
/*
 * Evaluate the object's overall power level.
 */
s32b object_power(const object_type* o_ptr, int verbose, ang_file *log_file,
	bool known)
{
	s32b p = 0, q = 0, slay_pwr = 0;
	unsigned int i, j;
	int extra_stat_bonus = 0, mult = 1, num_slays = 0, k = 1;
	bitflag flags[OF_SIZE], mask[OF_SIZE];

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

	/* Extract the flags */
	if (known) {
		file_putf(log_file, "Object is deemed known\n");
		object_flags(o_ptr, flags);
	} else {
		file_putf(log_file, "Object may not be fully known\n");
		object_flags_known(o_ptr, flags);
	}

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

	/* Get the slay power and number of slay/brand types */
	create_mask(mask, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX);
	num_slays = list_slays(flags, mask, NULL, NULL, NULL, TRUE);
	if (num_slays)
		slay_pwr = slay_power(o_ptr, verbose, log_file, known);

	/* Start with any damage boost from the item itself */
	p += (o_ptr->to_d * DAMAGE_POWER / 2);
	file_putf(log_file, "Adding power from to_dam, total is %d\n", p);

	/* Add damage from dice for any wieldable weapon or ammo */
	if (wield_slot(o_ptr) == INVEN_WIELD || obj_is_ammo(o_ptr)) {
		p += (o_ptr->dd * (o_ptr->ds + 1) * DAMAGE_POWER / 4);
		file_putf(log_file, "Adding power for dam dice, total is %d\n", p);
	/* Add 2nd lot of damage power for nonweapons */
	} else if (wield_slot(o_ptr) != INVEN_BOW) {
		p += (o_ptr->to_d * DAMAGE_POWER);
		file_putf(log_file, "Adding power from nonweap to_dam, total is %d\n", p);
		/* Add power boost for nonweapons with combat flags */
		if (num_slays || of_has(flags, OF_BLOWS) || of_has(flags, OF_SHOTS) ||
				of_has(flags, OF_MIGHT)) {
			p += (WEAP_DAMAGE * DAMAGE_POWER);
			file_putf(log_file, "Adding power for nonweap combat flags, total is %d\n", p);
		}
	}

	/* Add ammo damage for launchers, get multiplier and rescale */
	if (wield_slot(o_ptr) == INVEN_BOW) {
		p += (archery[o_ptr->sval / 10].ammo_dam * DAMAGE_POWER / 2);
		file_putf(log_file, "Adding power from ammo, total is %d\n", p);

		mult = bow_multiplier(o_ptr->sval);
		file_putf(log_file, "Base mult for this weapon is %d\n", mult);
	}

	/* Add launcher bonus for ego ammo, multiply for launcher and rescale */
	if (obj_is_ammo(o_ptr)) {
		if (o_ptr->ego)
			p += (archery[o_ptr->tval - TV_SHOT].launch_dam * DAMAGE_POWER / 2);
		p = p * archery[o_ptr->tval - TV_SHOT].launch_mult / (2 * MAX_BLOWS);
		file_putf(log_file, "After multiplying ammo and rescaling, power is %d\n", p);
	}

	/* Add power for extra blows */
	if (of_has(flags, OF_BLOWS)) {
		j = which_pval(o_ptr, OF_BLOWS);
		if (known || object_this_pval_is_visible(o_ptr, j)) {
			if (o_ptr->pval[j] >= INHIBIT_BLOWS) {
				p += INHIBIT_POWER;
				file_putf(log_file, "INHIBITING - too many extra blows\n");
			} else {
				p = p * (MAX_BLOWS + o_ptr->pval[j]) / MAX_BLOWS;
				/* Add boost for assumed off-weapon damage */
				p += (NONWEAP_DAMAGE * o_ptr->pval[j] * DAMAGE_POWER / 2);
				file_putf(log_file, "Adding power for extra blows, total is %d\n", p);
			}
		}
	}

	/* Add power for extra shots - note that we cannot handle negative shots */
	if (of_has(flags, OF_SHOTS)) {
		j = which_pval(o_ptr, OF_SHOTS);
		if (known || object_this_pval_is_visible(o_ptr, j)) {
			if (o_ptr->pval[j] >= INHIBIT_SHOTS) {
				p += INHIBIT_POWER;
				file_putf(log_file, "INHIBITING - too many extra shots\n");
			} else if (o_ptr->pval[j] > 0) {
				p = (p * (1 + o_ptr->pval[j]));
				file_putf(log_file, "Extra shots: multiplying power by 1 + %d, total is %d\n", o_ptr->pval[j], p);
			}
		}
	}

	/* Add power for extra might */
	if (of_has(flags, OF_MIGHT)) {
		j = which_pval(o_ptr, OF_MIGHT);
		if (known || object_this_pval_is_visible(o_ptr, j)) {
			if (o_ptr->pval[j] >= INHIBIT_MIGHT) {
				p += INHIBIT_POWER;
				mult = 1;	/* don't overflow */
				file_putf(log_file, "INHIBITING - too much extra might\n");
			} else
				mult += o_ptr->pval[j];
			file_putf(log_file, "Mult after extra might is %d\n", mult);
		}
	}
	p *= mult;
	file_putf(log_file, "After multiplying power for might, total is %d\n", p);

	/* Apply the correct slay multiplier */
	if (slay_pwr) {
		p = (p * (slay_pwr / 10)) / (tot_mon_power / 10);
		file_putf(log_file, "Adjusted for slay power, total is %d\n", p);
	}

	/* Melee weapons assume MAX_BLOWS per turn, so we must divide by MAX_BLOWS
     * to get equal ratings for launchers. */
	if (wield_slot(o_ptr) == INVEN_BOW) {
		p /= MAX_BLOWS;
		file_putf(log_file, "Rescaling bow power, total is %d\n", p);
	}

	/* Add power for +to_hit */
	p += (o_ptr->to_h * TO_HIT_POWER / 2);
	file_putf(log_file, "Adding power for to hit, total is %d\n", p);

	/* Add power for base AC and adjust for weight */
	if (o_ptr->ac) {
		q += BASE_ARMOUR_POWER;
		q += (o_ptr->ac * BASE_AC_POWER / 2);
		file_putf(log_file, "Adding %d power for base AC value\n", q);

		/* Add power for AC per unit weight */
		if (o_ptr->weight > 0) {
			i = 800 * (o_ptr->ac + o_ptr->to_a) / o_ptr->weight;

			/* Avoid overpricing Elven Cloaks */
			if (i > 450) i = 450;

			q *= i;
			q /= 100;

		/* Weightless (ethereal) armour items get fixed boost */
		} else
			q *= 5;
		p += q;
		file_putf(log_file, "Adding power for AC per unit weight, now %d\n", p);
	}
	/* Add power for +to_ac */
	p += (o_ptr->to_a * TO_AC_POWER / 2);
	file_putf(log_file, "Adding power for to_ac of %d, total is %d\n", o_ptr->to_a, p);
	if (o_ptr->to_a > HIGH_TO_AC) {
		p += ((o_ptr->to_a - (HIGH_TO_AC - 1)) * TO_AC_POWER);
		file_putf(log_file, "Adding power for high to_ac value, total is %d\n", p);
	}
	if (o_ptr->to_a > VERYHIGH_TO_AC) {
		p += ((o_ptr->to_a - (VERYHIGH_TO_AC -1)) * TO_AC_POWER * 2);
		file_putf(log_file, "Adding power for very high to_ac value, total is %d\n", p);
	}
	if (o_ptr->to_a >= INHIBIT_AC) {
		p += INHIBIT_POWER;
		file_putf(log_file, "INHIBITING: AC bonus too high\n");
	}


	/* Add power for light sources by radius XXX Hack - rewrite calc_torch! */
	if (wield_slot(o_ptr) == INVEN_LIGHT) {
		p += BASE_LIGHT_POWER;

		/* Artifact lights have larger radius so add more */
		if (o_ptr->artifact)
			p += BASE_LIGHT_POWER;

		file_putf(log_file, "Adding power for light radius, total is %d\n", p);
	}

	/* Add base power for jewelry */
	if (object_is_jewelry(o_ptr)) {
		p += BASE_JEWELRY_POWER;
		file_putf(log_file, "Adding power for jewelry, total is %d\n", p);
	}

	/* Add power for non-derived flags (derived flags have flag_power 0) */
	for (i = 0; i < OF_MAX; i++) {
		if (of_has(flags, i)) {
			if (flag_uses_pval(i)) {
				j = which_pval(o_ptr, i);
				if (known || object_this_pval_is_visible(o_ptr, j)) {
					k = o_ptr->pval[j];
					extra_stat_bonus += (k * pval_mult(i));
				}
			} else
				k = 1;

			if (flag_power(i)) {
				p += (k * flag_power(i) * slot_mult(i, wield_slot(o_ptr)));
				file_putf(log_file, "Adding power for %s, total is %d\n", flag_name(i), p);
			}

			/* Track combinations of flag types - note we ignore SUST_CHR */
			for (j = 0; j < N_ELEMENTS(sets); j++)
				if ((sets[j].type == obj_flag_type(i)) && (i != OF_SUST_CHR))
					sets[j].count++;
		}
	}

	/* Add extra power term if there are a lot of ability bonuses */
	if (extra_stat_bonus > 249) {
		file_putf(log_file, "Inhibiting!  (Total ability bonus of %d is too high)\n", extra_stat_bonus);
		p += INHIBIT_POWER;
	} else {
		p += ability_power[extra_stat_bonus / 10];
		file_putf(log_file, "Adding power for pval total of %d, total is %d\n", extra_stat_bonus, p);
	}

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

		/* Add bonus if item has a full set of these flags */
		if (sets[i].count == sets[i].size) {
			p += sets[i].bonus;
			file_putf(log_file, "Adding power for full set of type %d, total is %d\n", i, p);
		}
	}

	/* add power for effect */
	if (known || object_effect_is_known(o_ptr))	{
		if (o_ptr->artifact && o_ptr->artifact->effect) {
			p += effect_power(o_ptr->artifact->effect);
			file_putf(log_file, "Adding power for artifact activation, total is %d\n", p);
		} else {
			p += effect_power(o_ptr->kind->effect);
			file_putf(log_file, "Adding power for item activation, total is %d\n", p);
		}
	}

	file_putf(log_file, "FINAL POWER IS %d\n", p);

	return p;
}
Пример #9
0
/* XXX Eddie should messages be adhoc all over the place?  perhaps the main
 * loop should check for change in inventory/wieldeds and all messages be
 * printed from one place
 */
void object_notice_on_wield(object_type *o_ptr)
{
	bitflag f[OF_SIZE], obvious_mask[OF_SIZE];
	bool obvious = FALSE;
	const slay_t *s_ptr;

	flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);

	/* Save time of wield for later */
	object_last_wield = turn;

	/* Only deal with un-ID'd items */
	if (object_is_known(o_ptr)) return;

	/* Wear it */
	object_flavor_tried(o_ptr);
	if (object_add_ident_flags(o_ptr, IDENT_WORN))
		object_check_for_ident(o_ptr);

	if (obj_is_light(o_ptr) && ego_item_p(o_ptr))
		object_notice_ego(o_ptr);

	if (object_flavor_is_aware(o_ptr) && easy_know(o_ptr))
	{
		object_notice_everything(o_ptr);
		return;
	}

	/* Automatically sense artifacts upon wield */
	object_sense_artifact(o_ptr);

	/* Note artifacts when found */
	if (artifact_p(o_ptr))
		history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE);

	/* special case FA, needed at least for mages wielding gloves */
	if (object_FA_would_be_obvious(o_ptr))
		of_on(obvious_mask, OF_FREE_ACT);

	/* Learn about obvious flags */
	of_union(o_ptr->known_flags, obvious_mask);

	/* Extract the flags */
	object_flags(o_ptr, f);

	/* Find obvious things (disregarding curses) */
	flags_clear(obvious_mask, OF_SIZE, OF_CURSE_MASK, FLAG_END);
	if (of_is_inter(f, obvious_mask)) obvious = TRUE;
	flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);

	/* XXX Eddie should these next NOT call object_check_for_ident due to worries about repairing? */


	/* XXX Eddie this is a small hack, but jewelry with anything noticeable really is obvious */
	/* XXX Eddie learn =soulkeeping vs =bodykeeping when notice sustain_str */
	if (object_is_jewelry(o_ptr))
	{
		/* Learn the flavor of jewelry with obvious flags */
		if (EASY_LEARN && obvious)
			object_flavor_aware(o_ptr);

		/* Learn all flags on any aware non-artifact jewelry */
		if (object_flavor_is_aware(o_ptr) && !artifact_p(o_ptr))
			object_know_all_flags(o_ptr);
	}

	object_check_for_ident(o_ptr);

	if (!obvious) return;

	/* Messages */
	for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++)
	{
		if (of_has(f, s_ptr->slay_flag) && s_ptr->brand)
		{
			char o_name[40];
			object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
			msg_format("Your %s %s!", o_name, s_ptr->active_verb);
		}
	}

	/* XXX Eddie need to add stealth here, also need to assert/double-check everything is covered */
	if (of_has(f, OF_STR))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "stronger" : "weaker");
	if (of_has(f, OF_INT))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "smarter" : "more stupid");
	if (of_has(f, OF_WIS))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "wiser" : "more naive");
	if (of_has(f, OF_DEX))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "more dextrous" : "clumsier");
	if (of_has(f, OF_CON))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "healthier" : "sicklier");
	if (of_has(f, OF_CHR))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "cuter" : "uglier");
	if (of_has(f, OF_SPEED))
		msg_format("You feel strangely %s.", o_ptr->pval > 0 ? "quick" : "sluggish");
	if (flags_test(f, OF_SIZE, OF_BLOWS, OF_SHOTS, FLAG_END))
		msg_format("Your hands %s", o_ptr->pval > 0 ? "tingle!" : "ache.");
	if (of_has(f, OF_INFRA))
		msg_format("Your eyes tingle.");
	if (of_has(f, OF_LIGHT))
		msg_print("It glows!");
	if (of_has(f, OF_TELEPATHY))
		msg_print("Your mind feels strangely sharper!");

	/* WARNING -- masking f by obvious mask -- this should be at the end of this function */
	flags_mask(f, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);

	/* learn the ego on any obvious brand or slay */
	if (EASY_LEARN && ego_item_p(o_ptr) && obvious &&
	    flags_test(f, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END))
		object_notice_ego(o_ptr);

	/* Remember the flags */
	object_notice_sensing(o_ptr);

	/* XXX Eddie should we check_for_ident here? */
}
Пример #10
0
/*
 * Given an object, return a short identifier which gives some idea of what
 * the item is.
 */
obj_pseudo_t object_pseudo(const object_type *o_ptr)
{
	object_kind *k_ptr = &k_info[o_ptr->k_idx];
	bitflag flags[OF_SIZE];

	/* Get the known and obvious flags on the object,
	 * not including curses or properties of the kind
	 */
	object_flags_known(o_ptr, flags);

	/* MEGA-hack : there needs to be a table of what is obvious in each slot perhaps for each class */
	/* FA on gloves is obvious to mage casters */
	if (object_FA_would_be_obvious(o_ptr))
		flags_mask(flags, OF_SIZE, OF_OBVIOUS_MASK, OF_FREE_ACT, FLAG_END);
	else
		flags_mask(flags, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);

	flags_clear(flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
	of_diff(flags, k_ptr->flags);

	if (o_ptr->ident & IDENT_INDESTRUCT)
		return INSCRIP_SPECIAL;
	if ((object_was_sensed(o_ptr) || object_was_worn(o_ptr)) && artifact_p(o_ptr))
		return INSCRIP_SPECIAL;

	/* jewelry does not pseudo */
	if (object_is_jewelry(o_ptr))
		return INSCRIP_NULL;

	/* XXX Eddie should also check for flags with pvals where the pval exceeds
	 * the base pval for things like picks of digging, though for now acid brand gets those
	 */
	if (!of_is_empty(flags))
		return INSCRIP_SPLENDID;

	if (!object_is_known(o_ptr) && !object_was_sensed(o_ptr))
		return INSCRIP_NULL;

	if (ego_item_p(o_ptr))
	{
		/* uncursed bad egos are not excellent */
		if (flags_test(e_info[o_ptr->name2].flags, OF_SIZE, OF_CURSE_MASK, FLAG_END))
			return INSCRIP_STRANGE; /* XXX Eddie need something worse */
		else
			return INSCRIP_EXCELLENT;
	}

	if (o_ptr->to_a == randcalc(k_ptr->to_a, 0, MINIMISE) &&
	    o_ptr->to_h == randcalc(k_ptr->to_h, 0, MINIMISE) &&
		 o_ptr->to_d == randcalc(k_ptr->to_d, 0, MINIMISE))
		return INSCRIP_AVERAGE;

	if (o_ptr->to_a >= randcalc(k_ptr->to_a, 0, MINIMISE) &&
	    o_ptr->to_h >= randcalc(k_ptr->to_h, 0, MINIMISE) &&
	    o_ptr->to_d >= randcalc(k_ptr->to_d, 0, MINIMISE))
		return INSCRIP_MAGICAL;

	if (o_ptr->to_a <= randcalc(k_ptr->to_a, 0, MINIMISE) &&
	    o_ptr->to_h <= randcalc(k_ptr->to_h, 0, MINIMISE) &&
	    o_ptr->to_d <= randcalc(k_ptr->to_d, 0, MINIMISE))
		return INSCRIP_MAGICAL;

	return INSCRIP_STRANGE;
}
Пример #11
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;
}
Пример #12
0
void textui_cmd_destroy(void)
{
	int item;
	object_type *o_ptr;

	char out_val[160];

	menu_type *m;
	region r;
	int selected;

	/* Get an item */
	const char *q = "Ignore which item? ";
	const char *s = "You have nothing to ignore.";
	if (!get_item(&item, q, s, CMD_DESTROY, USE_INVEN | USE_EQUIP | USE_FLOOR))
		return;

	o_ptr = object_from_item_idx(item);

	m = menu_dynamic_new();
	m->selections = lower_case;

	/* Basic ignore option */
	if (!o_ptr->ignore) {
		menu_dynamic_add(m, "This item only", IGNORE_THIS_ITEM);
	} else {
		menu_dynamic_add(m, "Unignore this item", UNIGNORE_THIS_ITEM);
	}

	/* Flavour-aware squelch */
	if (squelch_tval(o_ptr->tval) &&
			(!o_ptr->artifact || !object_flavor_is_aware(o_ptr))) {
		bool squelched = kind_is_squelched_aware(o_ptr->kind) ||
				kind_is_squelched_unaware(o_ptr->kind);

		char tmp[70];
		object_desc(tmp, sizeof(tmp), o_ptr, ODESC_BASE | ODESC_PLURAL);
		if (!squelched) {
			strnfmt(out_val, sizeof out_val, "All %s", tmp);
			menu_dynamic_add(m, out_val, IGNORE_THIS_FLAVOR);
		} else {
			strnfmt(out_val, sizeof out_val, "Unignore all %s", tmp);
			menu_dynamic_add(m, out_val, UNIGNORE_THIS_FLAVOR);
		}
	}

	/* Quality squelching */
	if (object_was_sensed(o_ptr) || object_was_worn(o_ptr) ||
			object_is_known_not_artifact(o_ptr)) {
		byte value = squelch_level_of(o_ptr);
		int type = squelch_type_of(o_ptr);

		if (object_is_jewelry(o_ptr) &&
					squelch_level_of(o_ptr) != SQUELCH_BAD)
			value = SQUELCH_MAX;

		if (value != SQUELCH_MAX && type != TYPE_MAX) {
			strnfmt(out_val, sizeof out_val, "All %s %s",
					quality_values[value].name, quality_choices[type].name);

			menu_dynamic_add(m, out_val, IGNORE_THIS_QUALITY);
		}
	}

	/* work out display region */
	r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */
	r.col = 80 - r.width;
	r.row = 1;
	r.page_rows = m->count;

	screen_save();
	menu_layout(m, &r);
	region_erase_bordered(&r);

	prt("(Enter to select, ESC) Ignore:", 0, 0);
	selected = menu_dynamic_select(m);

	screen_load();

	if (selected == IGNORE_THIS_ITEM) {
		cmd_insert(CMD_DESTROY);
		cmd_set_arg_item(cmd_get_top(), 0, item);
	} else if (selected == UNIGNORE_THIS_ITEM) {
		o_ptr->ignore = FALSE;
	} else if (selected == IGNORE_THIS_FLAVOR) {
		object_squelch_flavor_of(o_ptr);
	} else if (selected == UNIGNORE_THIS_FLAVOR) {
		kind_squelch_clear(o_ptr->kind);
	} else if (selected == IGNORE_THIS_QUALITY) {
		byte value = squelch_level_of(o_ptr);
		int type = squelch_type_of(o_ptr);

		squelch_level[type] = value;
	}

	p_ptr->notice |= PN_SQUELCH;

	menu_dynamic_free(m);
}