Esempio n. 1
0
/**
 * Calculate the rating for a given slay combination
 */
static s32b slay_power(const object_type *obj, int p, int verbose,
					   int dice_pwr, bool known)
{
	u32b sv = 0;
	int i, q, num_brands = 0, num_slays = 0, num_kills = 0;
	int mult;
	int tot_mon_power = 0;
	struct brand *brands = obj->brands;
	struct slay *slays = obj->slays;

	/* Count the known brands and slays */
	while (brands) {
		if (known || brands->known)
			num_brands++;
		brands = brands->next;
	}
	while (slays) {
		if (known || slays->known) {
			if (slays->multiplier <= 3)
				num_slays++;
			else
				num_kills++;
		}
		slays = slays->next;
	}

	/* If there are no slays or brands return */
	if ((num_slays + num_brands + num_kills) == 0)
		return p;

	/* Look in the cache to see if we know this one yet */
	sv = check_slay_cache(obj);

	/* If it's cached (or there are no slays), return the value */
	if (sv)	{
		log_obj("Slay cache hit\n");
	} else {

		/*
		 * Otherwise we need to calculate the expected average multiplier
		 * for this combination (multiplied by the total number of
		 * monsters, which we'll divide out later).
		 */
		for (i = 0; i < z_info->r_max; i++)	{
			monster_type *mon = mem_zalloc(sizeof(*mon));
			const struct brand *b = NULL;
			const struct slay *s = NULL;
			char verb[20];

			mult = 1;
			mon->race = &r_info[i];

			/* Find the best multiplier against this monster */
			improve_attack_modifier((object_type *)obj, mon, &b, &s, 
									verb, FALSE, FALSE, !known);
			if (s)
				mult = s->multiplier;
			else if (b)
				mult = b->multiplier;

			/* Add up totals */
			tot_mon_power += mon->race->scaled_power;
			sv += mult * mon->race->scaled_power;
			mem_free(mon);
		}

		/*
		 * To get the expected damage for this weapon, multiply the
		 * average damage from base dice by sv, and divide by the
		 * total number of monsters.
		 */
		if (verbose) {
			struct brand *b, *brands = NULL;
			struct slay *s, *slays = NULL;

			/* Write info about the slay combination and multiplier */
			log_obj("Slay multiplier for: ");

			brands = brand_collect(obj->brands, NULL, !known);
			slays = slay_collect(obj->slays, NULL, !known);

			for (b = brands; b; b = b->next) {
				log_obj(format("%sx%d ", b->name, b->multiplier));
			}
			for (s = slays; s; s = s->next) {
				log_obj(format("%sx%d ", s->name, s->multiplier));
			}
			log_obj(format("\nsv is: %d\n", sv));
			log_obj(format(" and t_m_p is: %d \n", tot_mon_power));
			log_obj(format("times 1000 is: %d\n", (1000 * sv) / tot_mon_power));
			free_brand(brands);
			free_slay(slays);
		}

		/* Add to the cache */
		if (fill_slay_cache(obj, sv))
			log_obj("Added to slay cache\n");
	}

	q = (dice_pwr * (sv / 100)) / (tot_mon_power / 100);
	p += q;
	log_obj(format("Add %d for slay power, total is %d\n", q, p));

	/* Bonuses for multiple brands and slays */
	if (num_slays > 1) {
		q = (num_slays * num_slays * dice_pwr) / (DAMAGE_POWER * 5);
		p += q;
		log_obj(format("Add %d power for multiple slays, total is %d\n", q, p));
	}
	if (num_brands > 1) {
		q = (2 * num_brands * num_brands * dice_pwr) / (DAMAGE_POWER * 5);
		p += q;
		log_obj(format("Add %d power for multiple brands, total is %d\n",q, p));
	}
	if (num_kills > 1) {
		q = (3 * num_kills * num_kills * dice_pwr) / (DAMAGE_POWER * 5);
		p += q;
		log_obj(format("Add %d power for multiple kills, total is %d\n", q, p));
	}
	if (num_slays == 8) {
		p += 10;
		log_obj(format("Add 10 power for full set of slays, total is %d\n", p));
	}
	if (num_brands == 5) {
		p += 20;
		log_obj(format("Add 20 power for full set of brands, total is %d\n",p));
	}
	if (num_kills == 3) {
		p += 20;
		log_obj(format("Add 20 power for full set of kills, total is %d\n", p));
	}

	return p;
}
Esempio n. 2
0
/**
 * Calculate the rating for a given slay combination
 */
static s32b slay_power(const object_type *o_ptr, int verbose, ang_file*
	log_file, bool known)
{
	bitflag s_index[OF_SIZE], f[OF_SIZE], f2[OF_SIZE];
	u32b sv = 0;
	int i, j;
	int mult;
	const struct slay *best_s_ptr = NULL;
	monster_race *r_ptr;
	monster_type *m_ptr;
	monster_type monster_type_body;
	const char *desc[SL_MAX] = { 0 }, *brand[SL_MAX] = { 0 };
	int s_mult[SL_MAX] = { 0 };

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

	/* Combine the slay bytes into an index value, return if there are none */
	of_copy(s_index, f);
	create_mask(f2, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX);

	if (!of_is_inter(s_index, f2))
		return tot_mon_power;
	else
		of_inter(s_index, f2);

	/* Look in the cache to see if we know this one yet */
	sv = check_slay_cache(s_index);

	/* If it's cached (or there are no slays), return the value */
	if (sv)	{
		file_putf(log_file, "Slay cache hit\n");
		return sv;
	}

	/*
	 * Otherwise we need to calculate the expected average multiplier
	 * for this combination (multiplied by the total number of
	 * monsters, which we'll divide out later).
	 */
	for (i = 0; i < z_info->r_max; i++)	{
		best_s_ptr = NULL;
		mult = 1;
		r_ptr = &r_info[i];
		m_ptr = &monster_type_body;
		m_ptr->r_idx = i;

		/* Find the best multiplier against this monster */
		improve_attack_modifier((object_type *)o_ptr, m_ptr, &best_s_ptr,
				FALSE, !known);
		if (best_s_ptr)
			mult = best_s_ptr->mult;

		/* Add the multiple to sv */
		sv += mult * r_ptr->scaled_power;
	}

	/*
	 * To get the expected damage for this weapon, multiply the
	 * average damage from base dice by sv, and divide by the
	 * total number of monsters.
	 */
	if (verbose) {
		/* Write info about the slay combination and multiplier */
		file_putf(log_file, "Slay multiplier for: ");

		j = list_slays(s_index, s_index, desc, brand, s_mult, FALSE);

		for (i = 0; i < j; i++) {
			if (brand[i]) {
				file_putf(log_file, brand[i]);
			} else {
				file_putf(log_file, desc[i]);
			}
			file_putf(log_file, "x%d ", s_mult[i]); 
		}
		file_putf(log_file, "\nsv is: %d\n", sv);
		file_putf(log_file, " and t_m_p is: %d \n", tot_mon_power);
		file_putf(log_file, "times 1000 is: %d\n", (1000 * sv) / tot_mon_power);
	}

	/* Add to the cache */
	if (fill_slay_cache(s_index, sv))
		file_putf(log_file, "Added to slay cache\n");

	return sv;
}