示例#1
0
int mon_spell_lore_damage(int spell, const monster_race *race, bool know_hp)
{
	int hp;

	if (!mon_spell_is_valid(spell) || !mon_spell_has_damage(spell))
		return 0;

	hp = (know_hp) ? race->avg_hp : 0;
	return mon_spell_dam(spell, hp, race->level, MAXIMISE);
}
示例#2
0
/**
 * Calculate a monster's maximum spell power.
 *
 * \param r_ptr is the monster we're studying
 * \param resist is the degree of resistance we're assuming to any
 *   attack type (-1 = vulnerable ... 3 = immune)
 */
int best_spell_power(const monster_race *r_ptr, int resist)
{
	const struct mon_spell *rs_ptr;
	const struct spell_effect *re_ptr;
	int dam = 0, best_dam = 0; 

	/* Extract the monster level */
	int rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);

	for (rs_ptr = mon_spell_table; rs_ptr->index < RSF_MAX; rs_ptr++) {
		if (rsf_has(r_ptr->spell_flags, rs_ptr->index)) {

			/* Get the maximum basic damage output of the spell (could be 0) */
			dam = mon_spell_dam(rs_ptr->index, mon_hp(r_ptr, MAXIMISE), rlev,
				MAXIMISE);

			/* For all attack forms the player can save against, damage
			 * is halved */
			if (rs_ptr->save)
				dam /= 2;

			/* Adjust the real damage by the assumed resistance (if it is a
			 * resistable type) */
			if (rs_ptr->gf)
				dam = adjust_dam(p_ptr, rs_ptr->gf, dam, MAXIMISE, resist);

			/* Add the power ratings assigned to the various possible spell
			 * effects (which is crucial for non-damaging spells) */
			for (re_ptr = spell_effect_table; re_ptr->index < RSE_MAX; re_ptr++) {
				if ((re_ptr->method && (re_ptr->method == rs_ptr->index)) ||
						(re_ptr->gf && (re_ptr->gf == rs_ptr->gf))) {

					/* First we adjust the real damage if necessary */
					if (re_ptr->power.dice)
						dam = (dam * re_ptr->power.dice) / 100;

					/* Then we add any flat rating for this effect */
					dam += re_ptr->power.base;

					/* Then we add any rlev-dependent rating */
					if (re_ptr->power.m_bonus < 0)
						dam += re_ptr->power.sides / (rlev + 1);
					else if (re_ptr->power.m_bonus > 0)
						dam += (re_ptr->power.sides * rlev) / 100;
				}
			}

			/* Update the best_dam tracker */
			if (dam > best_dam)
				best_dam = dam;
		}
	}

	return best_dam;
}
示例#3
0
int mon_spell_lore_damage(int index, const struct monster_race *race,
						  bool know_hp)
{
	int hp;

	if (!mon_spell_is_valid(index) || !mon_spell_has_damage(index))
		return 0;

	hp = (know_hp) ? race->avg_hp : 0;
	return mon_spell_dam(index, hp, race, MAXIMISE);
}
示例#4
0
/**
 * Calculate a monster's maximum spell power.
 *
 * \param race is the monster we're studying
 * \param resist is the degree of resistance we're assuming to any
 *   attack type (-1 = vulnerable ... 3 = immune)
 */
int best_spell_power(const struct monster_race *race, int resist)
{
	const struct mon_spell_info *info;
	int dam = 0, best_dam = 0; 

	/* Extract the monster level */
	int rlev = ((race->level >= 1) ? race->level : 1);

	for (info = mon_spell_types; info->index < RSF_MAX; info++) {
		if (rsf_has(race->spell_flags, info->index)) {
			/* Get the spell */
			const struct monster_spell *spell =
				monster_spell_by_index(info->index);
			if (!spell) continue;

			/* Get the maximum basic damage output of the spell (could be 0) */
			dam = mon_spell_dam(info->index, mon_hp(race, MAXIMISE), race,
				MAXIMISE);

			/* For all attack forms the player can save against, damage
			 * is halved */
			if (spell->save_message)
				dam /= 2;

			/* Adjust the real damage by the assumed resistance (if it is a
			 * resistable type) */
			if (monster_spell_is_projectable(info->index))
				dam = adjust_dam(player, spell->effect->params[0], dam,
								 MAXIMISE, 1);

			/* Add the power rating (crucial for non-damaging spells) */

			/* First we adjust the real damage if necessary */
			if (spell->power.dice)
				dam = (dam * spell->power.dice) / 100;

			/* Then we add any flat rating for this effect */
			dam += spell->power.base;

			/* Then we add any rlev-dependent rating */
			if (spell->power.m_bonus == 1)
				dam += (spell->power.sides * rlev) / 100;
			else if (spell->power.m_bonus == 2)
				dam += spell->power.sides / (rlev + 1);
		}

		/* Update the best_dam tracker */
		if (dam > best_dam)
			best_dam = dam;
	}

	return best_dam;
}
示例#5
0
/**
 * Process a monster spell 
 *
 * \param spell is the monster spell flag (RSF_FOO)
 * \param m_idx is the attacking monster
 * \param seen is whether the player can see the monster at this moment
 */
void do_mon_spell(int spell, int m_idx, bool seen)
{
	const struct mon_spell *rs_ptr = &mon_spell_table[spell];

	monster_type *m_ptr = cave_monster(cave, m_idx);
	monster_race *r_ptr = &r_info[m_ptr->r_idx];

	char m_name[80], ddesc[80];

	bool hits = FALSE;

	int dam = 0, flag = 0, rad = 0;

	/* Extract the monster level */
	int rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);

	/* Get the monster name (or "it") */
	monster_desc(m_name, sizeof(m_name), m_ptr, 0x00);

	/* See if it hits */
	if (rs_ptr->hit == 100) 
		hits = TRUE;
	else if (rs_ptr->hit == 0)
		hits = FALSE;
	else
		hits = check_hit(p_ptr, rs_ptr->hit, rlev);

	/* Tell the player what's going on */
	disturb(p_ptr, 1,0);

	if (!seen)
		msg("Something %s.", rs_ptr->blind_verb);
	else if (!hits) {
		msg("%^s %s %s, but misses.", m_name, rs_ptr->verb,	rs_ptr->desc);
		return;
	} else if (rs_ptr->msgt)
		msgt(rs_ptr->msgt, "%^s %s %s.", m_name, rs_ptr->verb, rs_ptr->desc);
	else 
		msg("%^s %s %s.", m_name, rs_ptr->verb, rs_ptr->desc);


	/* Try a saving throw if available */
	if (rs_ptr->save && randint0(100) < p_ptr->state.skills[SKILL_SAVE]) {
		msg("You avoid the effects!");
		return;
	}

	/* Calculate the damage */
	dam = mon_spell_dam(spell, m_ptr->hp, rlev, RANDOMISE);

	/* Get the "died from" name in case this attack kills @ */
	monster_desc(ddesc, sizeof(ddesc), m_ptr, MDESC_SHOW | MDESC_IND2);

	/* Display the attack, adjust for resists and apply effects */
	if (rs_ptr->type & RST_BOLT)
		flag = PROJECT_STOP | PROJECT_KILL;
	else if (rs_ptr->type & (RST_BALL | RST_BREATH)) {
		flag = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
		rad = rf_has(r_ptr->flags, RF_POWERFUL) ? 3 : 2;
	}

	if (rs_ptr->gf) {
		(void)project(m_idx, rad, p_ptr->py, p_ptr->px, dam, rs_ptr->gf, flag);
		monster_learn_resists(m_ptr, p_ptr, rs_ptr->gf);
	}
	else /* Note that non-projectable attacks are unresistable */
		take_hit(p_ptr, dam, ddesc);

	do_side_effects(spell, dam, m_idx, seen);

	return;
}