示例#1
0
/**
 * Remove the "bad" spells from a spell list
 */
static void remove_bad_spells(struct monster *mon, bitflag f[RSF_SIZE])
{
	bitflag f2[RSF_SIZE], ai_flags[OF_SIZE], ai_pflags[PF_SIZE];
	struct element_info el[ELEM_MAX];

	bool know_something = false;

	/* Stupid monsters act randomly */
	if (rf_has(mon->race->flags, RF_STUPID)) return;

	/* Take working copy of spell flags */
	rsf_copy(f2, f);

	/* Don't heal if full */
	if (mon->hp >= mon->maxhp) rsf_off(f2, RSF_HEAL);
	
	/* Don't haste if hasted with time remaining */
	if (mon->m_timed[MON_TMD_FAST] > 10) rsf_off(f2, RSF_HASTE);

	/* Don't teleport to if the player is already next to us */
	if (mon->cdis == 1) rsf_off(f2, RSF_TELE_TO);

	/* Update acquired knowledge */
	of_wipe(ai_flags);
	pf_wipe(ai_pflags);
	if (OPT(birth_ai_learn)) {
		size_t i;

		/* Occasionally forget player status */
		if (one_in_(100)) {
			of_wipe(mon->known_pstate.flags);
			pf_wipe(mon->known_pstate.pflags);
			for (i = 0; i < ELEM_MAX; i++)
				mon->known_pstate.el_info[i].res_level = 0;
		}

		/* Use the memorized info */
		of_copy(ai_flags, mon->known_pstate.flags);
		pf_copy(ai_pflags, mon->known_pstate.pflags);
		if (!of_is_empty(ai_flags) || !pf_is_empty(ai_pflags))
			know_something = true;

		for (i = 0; i < ELEM_MAX; i++) {
			el[i].res_level = mon->known_pstate.el_info[i].res_level;
			if (el[i].res_level != 0)
				know_something = true;
		}
	}

	/* Cancel out certain flags based on knowledge */
	if (know_something)
		unset_spells(f2, ai_flags, ai_pflags, el, mon->race);

	/* use working copy of spell flags */
	rsf_copy(f, f2);
}
示例#2
0
/**
 * Turn off spells with a side effect or a gf_type that is resisted by
 * something in flags, subject to intelligence and chance.
 *
 * \param spells is the set of spells we're pruning
 * \param flags is the set of flags we're testing
 * \param r_ptr is the monster type we're operating on
 */
void unset_spells(bitflag *spells, bitflag *flags, const monster_race *r_ptr)
{
	const struct mon_spell *rs_ptr;
	const struct spell_effect *re_ptr;

	/* First we test the gf (projectable) spells */
	for (rs_ptr = mon_spell_table; rs_ptr->index < RSF_MAX; rs_ptr++)
		if (rs_ptr->gf && randint0(100) < check_for_resist(p_ptr, rs_ptr->gf, flags,
				FALSE) * (rf_has(r_ptr->flags, RF_SMART) ? 2 : 1) * 25)
			rsf_off(spells, rs_ptr->index);

	/* ... then we test the non-gf side effects */
	for (re_ptr = spell_effect_table; re_ptr->index < RSE_MAX; re_ptr++)
		if (re_ptr->method && re_ptr->res_flag && (rf_has(r_ptr->flags,
				RF_SMART) || !one_in_(3)) && of_has(flags, re_ptr->res_flag))
			rsf_off(spells, re_ptr->method);
}
示例#3
0
/**
 * Set a spell bitflag to allow only a specific set of spell types.
 *
 * \param f is the set of spell flags we're pruning
 * \param type is the spell type(s) we're allowing
 */
void set_spells(bitflag *f, enum mon_spell_type type)
{
	const struct mon_spell *rs_ptr;

	for (rs_ptr = mon_spell_table; rs_ptr->index < RSF_MAX; rs_ptr++)
		if (rsf_has(f, rs_ptr->index) && !(rs_ptr->type & type))
			rsf_off(f, rs_ptr->index);

	return;
}
示例#4
0
/**
 * Turn off spells with a side effect or a gf_type that is resisted by
 * something in flags, subject to intelligence and chance.
 *
 * \param spells is the set of spells we're pruning
 * \param flags is the set of object flags we're testing
 * \param pflags is the set of player flags we're testing
 * \param el is what we know about the monster's elemental resists
 * \param race is the monster type we're operating on
 */
void unset_spells(bitflag *spells, bitflag *flags, bitflag *pflags,
				  struct element_info *el, const struct monster_race *race)
{
	const struct mon_spell_info *info;
	bool smart = rf_has(race->flags, RF_SMART);

	for (info = mon_spell_types; info->index < RSF_MAX; info++) {
		const struct monster_spell *spell = monster_spell_by_index(info->index);
		const struct effect *effect;

		/* Ignore missing spells */
		if (!spell) continue;
		if (!rsf_has(spells, info->index)) continue;

		/* Get the effect */
		effect = spell->effect;

		/* First we test the elemental spells */
		if (info->type & (RST_BOLT | RST_BALL | RST_BREATH)) {
			int element = effect->params[0];
			int learn_chance = el[element].res_level * (smart ? 50 : 25);
			if (randint0(100) < learn_chance)
				rsf_off(spells, info->index);
		} else {
			/* Now others with resisted effects */
			while (effect) {
				/* Timed effects */
				if ((smart || !one_in_(3)) && (effect->index == EF_TIMED_INC) &&
					of_has(flags, timed_protect_flag(effect->params[0])))
					break;

				/* Mana drain */
				if ((smart || one_in_(2)) && (effect->index == EF_DRAIN_MANA) &&
					pf_has(pflags, PF_NO_MANA))
					break;

				effect = effect->next;
			}
			if (effect)
				rsf_off(spells, info->index);
		}
	}
}
示例#5
0
/**
 * Set a spell bitflag to ignore a specific set of spell types.
 *
 * \param f is the set of spell flags we're pruning
 * \param types is the spell type(s) we're ignoring
 */
void ignore_spells(bitflag *f, int types)
{
	const struct mon_spell_info *info;

	for (info = mon_spell_types; info->index < RSF_MAX; info++)
		if (rsf_has(f, info->index) && (info->type & types))
			rsf_off(f, info->index);

	return;
}