示例#1
0
static void spell_wonder(int Ind, int dir)
{
/* This spell should become more useful (more
   controlled) as the player gains experience levels.
   Thus, add 1/5 of the player's level to the die roll.
   This eliminates the worst effects later on, while
   keeping the results quite random.  It also allows
   some potent effects only at high level. */

	player_type *p_ptr = Players[Ind];
	
	int py = p_ptr->py;
	int px = p_ptr->px;
	int Depth = p_ptr->dun_depth;
	int plev = p_ptr->lev;
	int die = randint(100) + plev / 5;
	int beam = beam_chance(Ind);

	if (die > 100)
		msg_print(Ind, "You feel a surge of power!");
	if (die < 8) clone_monster(Ind, dir);
	else if (die < 14) speed_monster(Ind, dir);
	else if (die < 26) heal_monster(Ind, dir);
	else if (die < 31) poly_monster(Ind, dir);
	else if (die < 36)
		fire_bolt_or_beam(Ind, beam - 10, GF_MISSILE, dir,
		                  damroll(3 + ((plev - 1) / 5), 4));
	else if (die < 41) confuse_monster(Ind, dir, plev);
	else if (die < 46) fire_ball(Ind, GF_POIS, dir, 20 + (plev / 2), 3);
	else if (die < 51) lite_line(Ind, dir);
	else if (die < 56)
		fire_beam(Ind, GF_ELEC, dir, damroll(3+((plev-5)/6), 6));
	else if (die < 61)
		fire_bolt_or_beam(Ind, beam-10, GF_COLD, dir,
		                  damroll(5+((plev-5)/4), 8));
	else if (die < 66)
		fire_bolt_or_beam(Ind, beam, GF_ACID, dir,
		                  damroll(6+((plev-5)/4), 8));
	else if (die < 71)
		fire_bolt_or_beam(Ind, beam, GF_FIRE, dir,
		                  damroll(8+((plev-5)/4), 8));
	else if (die < 76) drain_life(Ind, dir, 75);
	else if (die < 81) fire_ball(Ind, GF_ELEC, dir, 30 + plev / 2, 2);
	else if (die < 86) fire_ball(Ind, GF_ACID, dir, 40 + plev, 2);
	else if (die < 91) fire_ball(Ind, GF_ICE, dir, 70 + plev, 3);
	else if (die < 96) fire_ball(Ind, GF_FIRE, dir, 80 + plev, 3);
	else if (die < 101) drain_life(Ind, dir, 100 + plev);
	else if (die < 104) earthquake(Depth, py, px, 12);
	else if (die < 106) destroy_area(Depth, py, px, 15, TRUE);
	else if (die < 108) banishment(Ind);
	else if (die < 110) dispel_monsters(Ind, 120);
	else /* RARE */
	{
		dispel_monsters(Ind, 150);
		slow_monsters(Ind);
		sleep_monsters(Ind);
		hp_player(Ind, 300);
	}
}
示例#2
0
static bool cast_mage_spell(int Ind, int spell)
{
	player_type 	*p_ptr = Players[Ind];
	object_type		*o_ptr;
	int py = p_ptr->py;
	int px = p_ptr->px;
	int Depth = p_ptr->dun_depth;

	int dir;

	int plev = p_ptr->lev;

	/* Hack -- chance of "beam" instead of "bolt" */
	int beam = beam_chance(Ind);

	/* MAngband-specific: Projected */
	if (spell >= SPELL_PROJECTED)
	{
		if (!get_aim_dir(Ind, &dir)) return (FALSE);
		(void)project_spell_ball(Ind, dir, spell - SPELL_PROJECTED);
		return (TRUE);
	}

	/* Spells. */
	switch (spell)
	{
		case SPELL_MAGIC_MISSILE:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s fires a magic missile.");
			fire_bolt_or_beam(Ind, beam-10, GF_MISSILE, dir,
			                  damroll(3 + ((plev - 1) / 5), 4));
			break;
		}

		case SPELL_DETECT_MONSTERS:
		{
			(void)detect_creatures(Ind, TRUE);
			break;
		}

		case SPELL_PHASE_DOOR:
		{
			msg_spell("%s blinks away!");
			teleport_player(Ind, 10);
			break;
		}

		case SPELL_LIGHT_AREA:
		{
			(void)lite_area(Ind, damroll(2, (plev / 2)), (plev / 10) + 1);
			break;
		}

		case SPELL_TREASURE_DETECTION:
		{
			(void)detect_treasure(Ind);
			//(void)detect_objects_gold(Ind);
			break;
		}

		case SPELL_CURE_LIGHT_WOUNDS:
		{

			(void)hp_player(Ind, damroll(2, 8));
			(void)set_cut(Ind, p_ptr->cut - 15);
			break;
		}

		case SPELL_OBJECT_DETECTION:
		{
			(void)detect_objects_normal(Ind);
			break;
		}

		case SPELL_FIND_TRAPS_DOORS:
		{
			(void)detect_trap(Ind);//detect_traps(Ind);
			(void)detect_sdoor(Ind);//detect_doors(Ind);
			//(void)detect_stairs(Ind);
			break;
		}

		case SPELL_STINKING_CLOUD:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a stinking cloud.");
			fire_ball(Ind, GF_POIS, dir, 10 + (plev / 2), 2);
			break;
		}

		case SPELL_CONFUSE_MONSTER:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s makes a complicated gesture.");
			(void)confuse_monster(Ind, dir, plev);
			break;
		}

		case SPELL_LIGHTNING_BOLT:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a lightning bolt.");
			fire_beam(Ind, GF_ELEC, dir,
			          damroll(3+((plev-5)/6), 6));
			break;
		}

		case SPELL_TRAP_DOOR_DESTRUCTION:
		{
			(void)destroy_doors_touch(Ind);
			break;
		}

		case SPELL_SLEEP_MONSTER:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s gestures and mumbles calmly.");
			(void)sleep_monster(Ind, dir);
			break;
		}

		case SPELL_CURE_POISON:
		{
			(void)set_poisoned(Ind, 0);
			break;
		}

		case SPELL_TELEPORT_SELF:
		{
			msg_spell("%s teleports away!");
			teleport_player(Ind, plev * 5);
			break;
		}

		case SPELL_SPEAR_OF_LIGHT: /* spear of light */
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_print(Ind, "A line of blue shimmering light appears.");
			msg_spell("A line of blue shimmering light appears out of %s's hands.");
			lite_line(Ind, dir);
			break;
		}

		case SPELL_FROST_BOLT:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a frost bolt.");
			fire_bolt_or_beam(Ind, beam-10, GF_COLD, dir,
			                  damroll(5+((plev-5)/4), 8));
			break;
		}

		case SPELL_TURN_STONE_TO_MUD:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s makes a moving gesture.");
			(void)wall_to_mud(Ind, dir);
			break;
		}

		case SPELL_SATISFY_HUNGER:
		{
			(void)set_food(Ind, PY_FOOD_MAX - 1);
			break;
		}

		case SPELL_RECHARGE_ITEM_I:
		{
			return recharge(Ind, 2 + plev / 5);
		}

		case SPELL_WONDER: /* wonder */
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			(void)spell_wonder(Ind, dir);
			break;
		}

		case SPELL_POLYMORPH_OTHER:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s discharges an everchanging blast of energy.");
			(void)poly_monster(Ind, dir);
			break;
		}

		case SPELL_IDENTIFY:
		{
			return ident_spell(Ind);
		}

		case SPELL_MASS_SLEEP:
		{
			(void)sleep_monsters(Ind);
			break;
		}

		case SPELL_FIRE_BOLT:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a fire bolt.");
			fire_bolt_or_beam(Ind, beam, GF_FIRE, dir,
			                  damroll(6+((plev-5)/4), 8));
			break;
		}

		case SPELL_SLOW_MONSTER:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s makes a lengthy gesture.");
			(void)slow_monster(Ind, dir);
			break;
		}

		case SPELL_FROST_BALL:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a frost ball.");
			fire_ball(Ind, GF_COLD, dir, 30 + (plev), 2);
			break;
		}

		case SPELL_RECHARGE_ITEM_II: /* greater recharging */
		{
			return recharge(Ind, 50 + plev);
		}

		case SPELL_TELEPORT_OTHER:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s makes a rush gesture.");
			(void)teleport_monster(Ind, dir);
			break;
		}

		case SPELL_BEDLAM:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s creates confusion.");
			fire_ball(Ind, GF_OLD_CONF, dir, plev, 4);
			break;
		}

		case SPELL_FIRE_BALL:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a fire ball.");
			fire_ball(Ind, GF_FIRE, dir, 55 + (plev), 2);
			break;
		}

		case SPELL_WORD_OF_DESTRUCTION:
		{
			msg_spell("%s unleashes great power!"); 
			destroy_area(Depth, py, px, 15, TRUE);
			break;
		}

		case SPELL_BANISHMENT:
		{
			return banishment(Ind);
			break;
		}

		case SPELL_DOOR_CREATION:
		{
			(void)door_creation(Ind);
			break;
		}

		case SPELL_STAIR_CREATION:
		{
			(void)stair_creation(Ind);
			break;
		}

		case SPELL_TELEPORT_LEVEL:
		{
			(void)teleport_player_level(Ind);
			break;
		}

		case SPELL_EARTHQUAKE:
		{
		  	msg_spell("%s casts a spell, and the ground shakes!"); 
			earthquake(Depth, py, px, 10);
			break;
		}

		case SPELL_WORD_OF_RECALL:
		{
			o_ptr = &p_ptr->inventory[get_spell_book(Ind, spell)];
			set_recall(Ind, o_ptr);
			break;
		}

		case SPELL_ACID_BOLT:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts an acid bolt.");
			fire_bolt_or_beam(Ind, beam, GF_ACID, dir, damroll(8+((plev-5)/4), 8));
			break;
		}

		case SPELL_CLOUD_KILL:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a cloud of death.");
			fire_ball(Ind, GF_POIS, dir, 40 + (plev / 2), 3);
			break;
		}

		case SPELL_ACID_BALL:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts an acid ball.");
			fire_ball(Ind, GF_ACID, dir, 40 + (plev), 2);
			break;
		}

		case SPELL_ICE_STORM:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s invokes an ice storm.");
			fire_ball(Ind, GF_ICE, dir, 50 + (plev * 2), 3);
			break;
		}

		case SPELL_METEOR_SWARM:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a meteor shower.");
			fire_swarm(Ind, 2 + plev / 20, GF_METEOR, dir, 30 + plev / 2, 1);
			break;
		}

		case SPELL_MANA_STORM:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a mana ball.");
			fire_ball(Ind, GF_MANA, dir, 300 + (plev * 2), 3);
			break;
		}
		case SPELL_DETECT_INVISIBLE:
		{
			(void)detect_invisible(Ind, TRUE);
			break;
		}

		case SPELL_DETECT_ENCHANTMENT:
		{
			(void)detect_objects_magic(Ind);
			break;
		}

		case SPELL_SHOCK_WAVE:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a shock wave.");
			fire_ball(Ind, GF_SOUND, dir, 10 + plev, 2);
			break;
		}

		case SPELL_EXPLOSION:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts an explosion.");
			fire_ball(Ind, GF_SHARDS, dir, 20 + (plev * 2), 2);
			break;
		}

		case SPELL_MASS_BANISHMENT:
		{
			(void)mass_banishment(Ind);
			break;
		}

		case SPELL_RESIST_FIRE:
		{
			(void)set_oppose_fire(Ind, p_ptr->oppose_fire + randint(20) + 20);
			break;
		}

		case SPELL_RESIST_COLD:
		{
			(void)set_oppose_cold(Ind, p_ptr->oppose_cold + randint(20) + 20);
			break;
		}

		case SPELL_ELEMENTAL_BRAND: /* elemental brand */
		{
			if (!get_item(Ind, &dir, item_test(AMMO))) return (FALSE);
			(void)brand_ammo(Ind, dir);
			break;
		}

		case SPELL_RESIST_POISON:
		{
			(void)set_oppose_pois(Ind, p_ptr->oppose_pois + randint(20) + 20);
			break;
		}

		case SPELL_RESISTANCE:
		{
			int time = randint(20) + 20;
			(void)set_oppose_acid(Ind, p_ptr->oppose_acid + time);
			(void)set_oppose_elec(Ind, p_ptr->oppose_elec + time);
			(void)set_oppose_fire(Ind, p_ptr->oppose_fire + time);
			(void)set_oppose_cold(Ind, p_ptr->oppose_cold + time);
			(void)set_oppose_pois(Ind, p_ptr->oppose_pois + time);
			break;
		}

		case SPELL_HEROISM:
		{
			(void)hp_player(Ind, 10);
			(void)set_hero(Ind, p_ptr->hero + randint(25) + 25);
			(void)set_afraid(Ind, 0);
			break;
		}

		case SPELL_SHIELD:
		{
			msg_spell("%s forms a mystic shield."); 
			(void)set_shield(Ind, p_ptr->shield + randint(20) + 30);
			break;
		}

		case SPELL_BERSERKER:
		{
			msg_spell("%s enters a battle rage!");
			(void)hp_player(Ind, 30);
			(void)set_shero(Ind, p_ptr->shero + randint(25) + 25);
			(void)set_afraid(Ind, 0);
			break;
		}

		case SPELL_HASTE_SELF:
		{
			msg_spell("%s starts moving faster."); 
			if (!p_ptr->fast)
			{
				(void)set_fast(Ind, randint(20) + plev);
			}
			else
			{
				(void)set_fast(Ind, p_ptr->fast + randint(5));
			}
			break;
		}

		case SPELL_RIFT:
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("Space warps in a beam from %s.");
			fire_beam(Ind, GF_GRAVITY, dir,	40 + damroll(plev, 7));
			break;
		}

		case SPELL_REND_SOUL: /* rend soul */
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a nether ball.");
			fire_bolt_or_beam(Ind, beam / 4, GF_NETHER, dir, damroll(11, plev));
			break;
		}

		case SPELL_CHAOS_STRIKE: /* chaos strike */
		{
			if (!get_aim_dir(Ind, &dir)) return (FALSE);
			msg_spell("%s casts a ball of chaos.");
			fire_bolt_or_beam(Ind, beam, GF_CHAOS, dir, damroll(13, plev));
			break;
		}

		case SPELL_RUNE_OF_PROTECTION: /* rune of protection */
		{
			if (warding_glyph(Ind))
			{
				msg_spell("%s lays down a rune of protection."); 
			}
			break;
		}

		case SPELL_ENCHANT_ARMOR: /* enchant armor */
		{
			return enchant_spell(Ind, 0, 0, rand_int(3) + plev / 20);
		}

		case SPELL_ENCHANT_WEAPON: /* enchant weapon */
		{
			return enchant_spell(Ind, rand_int(4) + plev / 20,
			                          rand_int(4) + plev / 20, 0);
		}
	}
	
	/* Success */
	return (TRUE);
}
示例#3
0
static bool zap_rod(object_type *o_ptr, bool *ident)
{
	int chance, dir, lev;

	/* Get a direction (unless KNOWN not to need it) */
	if ((o_ptr->sval >= SV_ROD_MIN_DIRECTION) || !object_aware_p(o_ptr))
	{
		/* Get a direction, allow cancel */
		if (!get_aim_dir(&dir)) return FALSE;
	}


	/* Take a turn */
	p_ptr->energy_use = 100;

	/* Not identified yet */
	*ident = FALSE;

	/* Extract the item level */
	lev = k_info[o_ptr->k_idx].level;

	/* Base chance of success */
	chance = p_ptr->skill_dev;

	/* Confusion hurts skill */
	if (p_ptr->confused) chance = chance / 2;

	/* High level objects are harder */
	chance = chance - ((lev > 50) ? 50 : lev);

	/* Give everyone a (slight) chance */
	if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0))
	{
		chance = USE_DEVICE;
	}

	/* Roll for usage */
	if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE))
	{
		if (flush_failure) flush();
		msg_print("You failed to use the rod properly.");
		return FALSE;
	}

	/* Still charging */
	if (o_ptr->pval)
	{
		if (flush_failure) flush();
		msg_print("The rod is still charging.");
		return FALSE;
	}


	/* Sound */
	sound(MSG_ZAP);


	/* Analyze the rod */
	switch (o_ptr->sval)
	{
		case SV_ROD_DETECT_TRAP:
		{
			if (detect_traps()) *ident = TRUE;
			o_ptr->pval = 50;
			break;
		}

		case SV_ROD_DETECT_DOOR:
		{
			if (detect_doors()) *ident = TRUE;
			if (detect_stairs()) *ident = TRUE;
			o_ptr->pval = 70;
			break;
		}

		case SV_ROD_IDENTIFY:
		{
			*ident = TRUE;
			if (ident_spell()) o_ptr->pval = 10;
			break;
		}

		case SV_ROD_RECALL:
		{
			set_recall();
			*ident = TRUE;
			o_ptr->pval = 60;
			break;
		}

		case SV_ROD_ILLUMINATION:
		{
			if (lite_area(damroll(2, 8), 2)) *ident = TRUE;
			o_ptr->pval = 30;
			break;
		}

		case SV_ROD_MAPPING:
		{
			map_area();
			*ident = TRUE;
			o_ptr->pval = 99;
			break;
		}

		case SV_ROD_DETECTION:
		{
			detect_all();
			*ident = TRUE;
			o_ptr->pval = 99;
			break;
		}

		case SV_ROD_PROBING:
		{
			probing();
			*ident = TRUE;
			o_ptr->pval = 50;
			break;
		}

		case SV_ROD_CURING:
		{
			if (set_blind(0)) *ident = TRUE;
			if (set_poisoned(0)) *ident = TRUE;
			if (set_confused(0)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			o_ptr->pval = 999;
			break;
		}

		case SV_ROD_HEALING:
		{
			if (hp_player(500)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			o_ptr->pval = 999;
			break;
		}

		case SV_ROD_RESTORATION:
		{
			if (restore_level()) *ident = TRUE;
			if (do_res_stat(A_STR)) *ident = TRUE;
			if (do_res_stat(A_INT)) *ident = TRUE;
			if (do_res_stat(A_WIS)) *ident = TRUE;
			if (do_res_stat(A_DEX)) *ident = TRUE;
			if (do_res_stat(A_CON)) *ident = TRUE;
			if (do_res_stat(A_CHR)) *ident = TRUE;
			o_ptr->pval = 999;
			break;
		}

		case SV_ROD_SPEED:
		{
			if (!p_ptr->fast)
			{
				if (set_fast(randint(30) + 15)) *ident = TRUE;
			}
			else
			{
				(void)set_fast(p_ptr->fast + 5);
			}
			o_ptr->pval = 99;
			break;
		}

		case SV_ROD_TELEPORT_AWAY:
		{
			if (teleport_monster(dir)) *ident = TRUE;
			o_ptr->pval = 25;
			break;
		}

		case SV_ROD_DISARMING:
		{
			if (disarm_trap(dir)) *ident = TRUE;
			o_ptr->pval = 30;
			break;
		}

		case SV_ROD_LITE:
		{
			msg_print("A line of blue shimmering light appears.");
			lite_line(dir);
			*ident = TRUE;
			o_ptr->pval = 9;
			break;
		}

		case SV_ROD_SLEEP_MONSTER:
		{
			if (sleep_monster(dir)) *ident = TRUE;
			o_ptr->pval = 18;
			break;
		}

		case SV_ROD_SLOW_MONSTER:
		{
			if (slow_monster(dir)) *ident = TRUE;
			o_ptr->pval = 20;
			break;
		}

		case SV_ROD_DRAIN_LIFE:
		{
			if (drain_life(dir, 150)) *ident = TRUE;
			o_ptr->pval = 23;
			break;
		}

		case SV_ROD_POLYMORPH:
		{
			if (poly_monster(dir)) *ident = TRUE;
			o_ptr->pval = 25;
			break;
		}

		case SV_ROD_ACID_BOLT:
		{
			fire_bolt_or_beam(10, GF_ACID, dir, damroll(12, 8));
			*ident = TRUE;
			o_ptr->pval = 12;
			break;
		}

		case SV_ROD_ELEC_BOLT:
		{
			fire_bolt_or_beam(10, GF_ELEC, dir, damroll(6, 6));
			*ident = TRUE;
			o_ptr->pval = 11;
			break;
		}

		case SV_ROD_FIRE_BOLT:
		{
			fire_bolt_or_beam(10, GF_FIRE, dir, damroll(16, 8));
			*ident = TRUE;
			o_ptr->pval = 15;
			break;
		}

		case SV_ROD_COLD_BOLT:
		{
			fire_bolt_or_beam(10, GF_COLD, dir, damroll(10, 8));
			*ident = TRUE;
			o_ptr->pval = 13;
			break;
		}

		case SV_ROD_ACID_BALL:
		{
			fire_ball(GF_ACID, dir, 120, 2);
			*ident = TRUE;
			o_ptr->pval = 27;
			break;
		}

		case SV_ROD_ELEC_BALL:
		{
			fire_ball(GF_ELEC, dir, 64, 2);
			*ident = TRUE;
			o_ptr->pval = 23;
			break;
		}

		case SV_ROD_FIRE_BALL:
		{
			fire_ball(GF_FIRE, dir, 144, 2);
			*ident = TRUE;
			o_ptr->pval = 30;
			break;
		}

		case SV_ROD_COLD_BALL:
		{
			fire_ball(GF_COLD, dir, 96, 2);
			*ident = TRUE;
			o_ptr->pval = 25;
			break;
		}
	}

	return TRUE;
}
示例#4
0
static bool aim_wand(object_type *o_ptr, bool *ident)
{
	int lev, chance, dir, sval;


	/* Allow direction to be cancelled for free */
	if (!get_aim_dir(&dir)) return (FALSE);

	/* Take a turn */
	p_ptr->energy_use = 100;

	/* Not identified yet */
	*ident = FALSE;

	/* Get the level */
	lev = k_info[o_ptr->k_idx].level;

	/* Base chance of success */
	chance = p_ptr->skill_dev;

	/* Confusion hurts skill */
	if (p_ptr->confused) chance = chance / 2;

	/* High level objects are harder */
	chance = chance - ((lev > 50) ? 50 : lev);

	/* Give everyone a (slight) chance */
	if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0))
	{
		chance = USE_DEVICE;
	}

	/* Roll for usage */
	if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE))
	{
		if (flush_failure) flush();
		msg_print("You failed to use the wand properly.");
		return (FALSE);
	}

	/* The wand is already empty! */
	if (o_ptr->pval <= 0)
	{
		if (flush_failure) flush();
		msg_print("The wand has no charges left.");
		o_ptr->ident |= (IDENT_EMPTY);
		p_ptr->notice |= (PN_COMBINE | PN_REORDER);
		p_ptr->window |= (PW_INVEN);
		return (FALSE);
	}


	/* Sound */
	sound(MSG_ZAP);


	/* XXX Hack -- Extract the "sval" effect */
	sval = o_ptr->sval;

	/* XXX Hack -- Wand of wonder can do anything before it */
	if (sval == SV_WAND_WONDER) sval = rand_int(SV_WAND_WONDER);

	/* Analyze the wand */
	switch (sval)
	{
		case SV_WAND_HEAL_MONSTER:
		{
			if (heal_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_HASTE_MONSTER:
		{
			if (speed_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_CLONE_MONSTER:
		{
			if (clone_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_TELEPORT_AWAY:
		{
			if (teleport_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_DISARMING:
		{
			if (disarm_trap(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_TRAP_DOOR_DEST:
		{
			if (destroy_door(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_STONE_TO_MUD:
		{
			if (wall_to_mud(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_LITE:
		{
			msg_print("A line of blue shimmering light appears.");
			lite_line(dir);
			*ident = TRUE;
			break;
		}

		case SV_WAND_SLEEP_MONSTER:
		{
			if (sleep_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_SLOW_MONSTER:
		{
			if (slow_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_CONFUSE_MONSTER:
		{
			if (confuse_monster(dir, 10)) *ident = TRUE;
			break;
		}

		case SV_WAND_FEAR_MONSTER:
		{
			if (fear_monster(dir, 10)) *ident = TRUE;
			break;
		}

		case SV_WAND_DRAIN_LIFE:
		{
			if (drain_life(dir, 150)) *ident = TRUE;
			break;
		}

		case SV_WAND_POLYMORPH:
		{
			if (poly_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_WAND_STINKING_CLOUD:
		{
			fire_ball(GF_POIS, dir, 12, 2);
			*ident = TRUE;
			break;
		}

		case SV_WAND_MAGIC_MISSILE:
		{
			fire_bolt_or_beam(20, GF_MISSILE, dir, damroll(3, 4));
			*ident = TRUE;
			break;
		}

		case SV_WAND_ACID_BOLT:
		{
			fire_bolt_or_beam(20, GF_ACID, dir, damroll(10, 8));
			*ident = TRUE;
			break;
		}

		case SV_WAND_ELEC_BOLT:
		{
			fire_bolt_or_beam(20, GF_ELEC, dir, damroll(6, 6));
			*ident = TRUE;
			break;
		}

		case SV_WAND_FIRE_BOLT:
		{
			fire_bolt_or_beam(20, GF_FIRE, dir, damroll(12, 8));
			*ident = TRUE;
			break;
		}

		case SV_WAND_COLD_BOLT:
		{
			fire_bolt_or_beam(20, GF_COLD, dir, damroll(6, 8));
			*ident = TRUE;
			break;
		}

		case SV_WAND_ACID_BALL:
		{
			fire_ball(GF_ACID, dir, 120, 2);
			*ident = TRUE;
			break;
		}

		case SV_WAND_ELEC_BALL:
		{
			fire_ball(GF_ELEC, dir, 64, 2);
			*ident = TRUE;
			break;
		}

		case SV_WAND_FIRE_BALL:
		{
			fire_ball(GF_FIRE, dir, 144, 2);
			*ident = TRUE;
			break;
		}

		case SV_WAND_COLD_BALL:
		{
			fire_ball(GF_COLD, dir, 96, 2);
			*ident = TRUE;
			break;
		}

		case SV_WAND_WONDER:
		{
			msg_print("Oops.  Wand of wonder activated.");
			break;
		}

		case SV_WAND_DRAGON_FIRE:
		{
			fire_ball(GF_FIRE, dir, 200, 3);
			*ident = TRUE;
			break;
		}

		case SV_WAND_DRAGON_COLD:
		{
			fire_ball(GF_COLD, dir, 160, 3);
			*ident = TRUE;
			break;
		}

		case SV_WAND_DRAGON_BREATH:
		{
			switch (randint(5))
			{
				case 1:
				{
					fire_ball(GF_ACID, dir, 200, 3);
					break;
				}

				case 2:
				{
					fire_ball(GF_ELEC, dir, 160, 3);
					break;
				}

				case 3:
				{
					fire_ball(GF_FIRE, dir, 200, 3);
					break;
				}

				case 4:
				{
					fire_ball(GF_COLD, dir, 160, 3);
					break;
				}

				default:
				{
					fire_ball(GF_POIS, dir, 120, 3);
					break;
				}
			}

			*ident = TRUE;
			break;
		}

		case SV_WAND_ANNIHILATION:
		{
			if (drain_life(dir, 250)) *ident = TRUE;
			break;
		}
	}

	return (TRUE);
}
示例#5
0
static bool use_staff(object_type *o_ptr, bool *ident)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int k;

	bool use_charge = TRUE;

	/* Analyze the staff */
	switch (o_ptr->sval)
	{
		case SV_STAFF_DARKNESS:
		{
			if (!p_ptr->resist_blind)
			{
				if (set_blind(p_ptr->blind + 3 + randint(5))) *ident = TRUE;
			}
			if (unlite_area(10, 3)) *ident = TRUE;
			break;
		}

		case SV_STAFF_SLOWNESS:
		{
			if (set_slow(p_ptr->slow + randint(30) + 15)) *ident = TRUE;
			break;
		}

		case SV_STAFF_HASTE_MONSTERS:
		{
			if (speed_monsters()) *ident = TRUE;
			break;
		}

		case SV_STAFF_SUMMONING:
		{
			for (k = 0; k < randint(4); k++)
			{
				if (summon_specific(py, px, p_ptr->depth, 0))
				{
					*ident = TRUE;
				}
			}
			break;
		}

		case SV_STAFF_TELEPORTATION:
		{
			teleport_player(100);
			*ident = TRUE;
			break;
		}

		case SV_STAFF_IDENTIFY:
		{
			if (!ident_spell()) use_charge = FALSE;
			*ident = TRUE;
			break;
		}

		case SV_STAFF_REMOVE_CURSE:
		{
			if (remove_curse())
			{
				if (!p_ptr->blind)
				{
					msg_print("The staff glows blue for a moment...");
				}
				*ident = TRUE;
			}
			break;
		}

		case SV_STAFF_STARLITE:
		{
			if (!p_ptr->blind)
			{
				msg_print("The end of the staff glows brightly...");
			}
			for (k = 0; k < 8; k++) lite_line(ddd[k]);
			*ident = TRUE;
			break;
		}

		case SV_STAFF_LITE:
		{
			if (lite_area(damroll(2, 8), 2)) *ident = TRUE;
			break;
		}

		case SV_STAFF_MAPPING:
		{
			map_area();
			*ident = TRUE;
			break;
		}

		case SV_STAFF_DETECT_GOLD:
		{
			if (detect_treasure()) *ident = TRUE;
			if (detect_objects_gold()) *ident = TRUE;
			break;
		}

		case SV_STAFF_DETECT_ITEM:
		{
			if (detect_objects_normal()) *ident = TRUE;
			break;
		}

		case SV_STAFF_DETECT_TRAP:
		{
			if (detect_traps()) *ident = TRUE;
			break;
		}

		case SV_STAFF_DETECT_DOOR:
		{
			if (detect_doors()) *ident = TRUE;
			if (detect_stairs()) *ident = TRUE;
			break;
		}

		case SV_STAFF_DETECT_INVIS:
		{
			if (detect_monsters_invis()) *ident = TRUE;
			break;
		}

		case SV_STAFF_DETECT_EVIL:
		{
			if (detect_monsters_evil()) *ident = TRUE;
			break;
		}

		case SV_STAFF_CURE_LIGHT:
		{
			if (hp_player(randint(8))) *ident = TRUE;
			break;
		}

		case SV_STAFF_CURING:
		{
			if (set_blind(0)) *ident = TRUE;
			if (set_poisoned(0)) *ident = TRUE;
			if (set_confused(0)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			break;
		}

		case SV_STAFF_HEALING:
		{
			if (hp_player(300)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			break;
		}

		case SV_STAFF_THE_MAGI:
		{
			if (do_res_stat(A_INT)) *ident = TRUE;
			if (p_ptr->csp < p_ptr->msp)
			{
				p_ptr->csp = p_ptr->msp;
				p_ptr->csp_frac = 0;
				*ident = TRUE;
				msg_print("Your feel your head clear.");
				p_ptr->redraw |= (PR_MANA);
				p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1);
			}
			break;
		}

		case SV_STAFF_SLEEP_MONSTERS:
		{
			if (sleep_monsters()) *ident = TRUE;
			break;
		}

		case SV_STAFF_SLOW_MONSTERS:
		{
			if (slow_monsters()) *ident = TRUE;
			break;
		}

		case SV_STAFF_SPEED:
		{
			if (!p_ptr->fast)
			{
				if (set_fast(randint(30) + 15)) *ident = TRUE;
			}
			else
			{
				(void)set_fast(p_ptr->fast + 5);
			}
			break;
		}

		case SV_STAFF_PROBING:
		{
			probing();
			*ident = TRUE;
			break;
		}

		case SV_STAFF_DISPEL_EVIL:
		{
			if (dispel_evil(60)) *ident = TRUE;
			break;
		}

		case SV_STAFF_POWER:
		{
			if (dispel_monsters(120)) *ident = TRUE;
			break;
		}

		case SV_STAFF_HOLINESS:
		{
			if (dispel_evil(120)) *ident = TRUE;
			k = 3 * p_ptr->lev;
			if (set_protevil(p_ptr->protevil + randint(25) + k)) *ident = TRUE;
			if (set_poisoned(0)) *ident = TRUE;
			if (set_afraid(0)) *ident = TRUE;
			if (hp_player(50)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			break;
		}

		case SV_STAFF_BANISHMENT:
		{
			(void)banishment();
			*ident = TRUE;
			break;
		}

		case SV_STAFF_EARTHQUAKES:
		{
			earthquake(py, px, 10);
			*ident = TRUE;
			break;
		}

		case SV_STAFF_DESTRUCTION:
		{
			destroy_area(py, px, 15, TRUE);
			*ident = TRUE;
			break;
		}
	}

	return (use_charge);
}
示例#6
0
/*
 * do_cmd_mind calls this function if the player's class
 * is 'Naturalist'.
 */
static bool cast_nature_spell(int spell)
{
	/* this will vary based on the spells, and what they depend on */
	int             plev = p_ptr->lev;
	int 			dir;
	int 			px = p_ptr->px;
	int				py = p_ptr->py;
	
	/* spell code */
	switch (spell)
	{
	case 0: /* Detect Creatures */
		(void)detect_monsters_normal();
		break;
	case 1: /* First Aid */
		(void)hp_player(damroll(2, 8));
		(void)set_cut(p_ptr->cut - 15);
		break;
	case 2: /* Detect Doors + Traps */
		(void)detect_traps();
		(void)detect_doors();
		(void)detect_stairs();
		break;
	case 3: /* Produce Food */
		(void)set_food(PY_FOOD_MAX - 1);
		break;
	case 4: /* Daylight */
		(void)lite_area(damroll(2, (plev / 2)), (plev / 10) + 1);
		break;
	case 5: /* Animal Taming */
		if (!get_aim_dir(&dir)) return FALSE;
		(void)charm_animal(dir, plev);
		break;
	case 6: /* Resist Environment */
		(void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
		(void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
		(void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20);
		break;
	case 7: /* Cure Wounds + Poison */
		(void)hp_player(damroll(plev, 8));
		(void)set_cut(0);
		(void)set_poisoned(0);
		break;
	case 8: /* Stone to Mud */
		if (!get_aim_dir(&dir)) return FALSE;
		(void)wall_to_mud(dir);
		break;
	case 9: /* Lightning Bolt */
		if (!get_aim_dir(&dir)) return FALSE;
		fire_bolt_or_beam(100, GF_ELEC, dir,
			damroll(3 + ((plev - 5) / 4), 8));
		break;
	case 10: /* Ray of Sunlight */
		if (!get_aim_dir(&dir)) return FALSE;
		msg_print("A line of sunlight appears.");
		(void)lite_line(dir);
		break;
	case 11: /* Entangle */
		slow_monsters();
		break;
	case 12: /* Stone Skin */
		(void)set_shield(p_ptr->shield + randint(20) + 30);
		break;
	case 13: /* Resistance True */
		(void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20);
		(void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20);
		(void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
		(void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
		(void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20);
		break;
	case 14: /* Stone Tell */
		return identify_fully();
	case 15: /* Earthquake */
		earthquake(py, px, 10);
		break;
	case 16: /* Blizzard */
		if (!get_aim_dir(&dir)) return FALSE;
		fire_ball(GF_COLD, dir, 70 + plev, (plev / 12) + 1);
		break;
	case 17: /* Lightning Storm */
		if (!get_aim_dir(&dir)) return FALSE;
		fire_ball(GF_ELEC, dir, 90 + plev, (plev / 12) + 1);
		break;
	case 18: /* Whirlpool */
		if (!get_aim_dir(&dir)) return FALSE;
		fire_ball(GF_WATER, dir, 100 + plev, (plev / 12) + 1);
		break;
	case 19: /* Call Sunlight */
		fire_ball(GF_LITE, 0, 150, 8);
		wiz_lite();
		break;
	case 20: /* Nature's Wrath */
		(void)dispel_monsters(plev * 4);
		earthquake(py, px, 20 + (plev / 2));
		project(0, 1 + plev / 12, py, px,
			100 + plev, GF_DISINTEGRATE, PROJECT_KILL | PROJECT_ITEM);
		break;
	default:
		msg_format("You cast an unknown Nature spell: %d.", spell);
		msg_print(NULL);
	}

	return TRUE;
}
static bool zap_rod(object_type *o_ptr, bool *ident)
{
	int chance, dir, lev;
	bool used_charge = TRUE;
	object_kind *k_ptr = &k_info[o_ptr->k_idx];


	/* Get a direction (unless KNOWN not to need it) */
	if ((o_ptr->sval >= SV_ROD_MIN_DIRECTION) || !object_aware_p(o_ptr))
	{
		/* Get a direction, allow cancel */
		if (!get_aim_dir(&dir)) return FALSE;
	}


	/* Take a turn */
	p_ptr->energy_use = 100;

	/* Not identified yet */
	*ident = FALSE;

	/* Extract the item level */
	lev = k_info[o_ptr->k_idx].level;

	/* Base chance of success */
	chance = p_ptr->skill_dev;

	/* Confusion hurts skill */
	if (p_ptr->confused) chance = chance / 2;

	/* High level objects are harder */
	chance = chance - ((lev > 50) ? 50 : lev);

	/* Give everyone a (slight) chance */
	if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0))
	{
		chance = USE_DEVICE;
	}

	/* Roll for usage */
	if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE))
	{
		if (flush_failure) flush();
		msg_print("Вы не смогли использовать жезл.");
		return FALSE;
	}

	/* Still charging? */
	if (o_ptr->timeout > (o_ptr->pval - k_ptr->pval))
	{
		if (flush_failure) flush();
		
		if (o_ptr->number == 1)
			msg_print("Жезл все еще заряжается.");
		else
			msg_print("Все жезлы все еще заряжаются.");

		return FALSE;
	}


	/* Sound */
	sound(MSG_ZAP);


	/* Analyze the rod */
	switch (o_ptr->sval)
	{
		case SV_ROD_DETECT_TRAP:
		{
			if (detect_traps()) *ident = TRUE;
			break;
		}

		case SV_ROD_DETECT_DOOR:
		{
			if (detect_doors()) *ident = TRUE;
			if (detect_stairs()) *ident = TRUE;
			break;
		}

		case SV_ROD_IDENTIFY:
		{
			*ident = TRUE;
			if (ident_spell()) used_charge = FALSE;
			break;
		}

		case SV_ROD_RECALL:
		{
			set_recall();
			*ident = TRUE;
			break;
		}

		case SV_ROD_ILLUMINATION:
		{
			if (lite_area(damroll(2, 8), 2)) *ident = TRUE;
			break;
		}

		case SV_ROD_MAPPING:
		{
			map_area();
			*ident = TRUE;
			break;
		}

		case SV_ROD_DETECTION:
		{
			detect_all();
			*ident = TRUE;
			break;
		}

		case SV_ROD_PROBING:
		{
			probing();
			*ident = TRUE;
			break;
		}

		case SV_ROD_CURING:
		{
			if (set_blind(0)) *ident = TRUE;
			if (set_poisoned(0)) *ident = TRUE;
			if (set_confused(0)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			break;
		}

		case SV_ROD_HEALING:
		{
			if (hp_player(500)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			break;
		}

		case SV_ROD_RESTORATION:
		{
			if (restore_level()) *ident = TRUE;
			if (do_res_stat(A_STR)) *ident = TRUE;
			if (do_res_stat(A_INT)) *ident = TRUE;
			if (do_res_stat(A_WIS)) *ident = TRUE;
			if (do_res_stat(A_DEX)) *ident = TRUE;
			if (do_res_stat(A_CON)) *ident = TRUE;
			if (do_res_stat(A_CHR)) *ident = TRUE;
			break;
		}

		case SV_ROD_SPEED:
		{
			if (!p_ptr->fast)
			{
				if (set_fast(randint(30) + 15)) *ident = TRUE;
			}
			else
			{
				(void)set_fast(p_ptr->fast + 5);
			}
			break;
		}

		case SV_ROD_TELEPORT_AWAY:
		{
			if (teleport_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_ROD_DISARMING:
		{
			if (disarm_trap(dir)) *ident = TRUE;
			break;
		}

		case SV_ROD_LITE:
		{
			msg_print("Появляется коридор синего мерцающего света.");
			lite_line(dir);
			*ident = TRUE;
			break;
		}

		case SV_ROD_SLEEP_MONSTER:
		{
			if (sleep_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_ROD_SLOW_MONSTER:
		{
			if (slow_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_ROD_DRAIN_LIFE:
		{
			if (drain_life(dir, 150)) *ident = TRUE;
			break;
		}

		case SV_ROD_POLYMORPH:
		{
			if (poly_monster(dir)) *ident = TRUE;
			break;
		}

		case SV_ROD_ACID_BOLT:
		{
			fire_bolt_or_beam(10, GF_ACID, dir, damroll(12, 8));
			*ident = TRUE;
			break;
		}

		case SV_ROD_ELEC_BOLT:
		{
			fire_bolt_or_beam(10, GF_ELEC, dir, damroll(6, 6));
			*ident = TRUE;
			break;
		}

		case SV_ROD_FIRE_BOLT:
		{
			fire_bolt_or_beam(10, GF_FIRE, dir, damroll(16, 8));
			*ident = TRUE;
			break;
		}

		case SV_ROD_COLD_BOLT:
		{
			fire_bolt_or_beam(10, GF_COLD, dir, damroll(10, 8));
			*ident = TRUE;
			break;
		}

		case SV_ROD_ACID_BALL:
		{
			fire_ball(GF_ACID, dir, 120, 2);
			*ident = TRUE;
			break;
		}

		case SV_ROD_ELEC_BALL:
		{
			fire_ball(GF_ELEC, dir, 64, 2);
			*ident = TRUE;
			break;
		}

		case SV_ROD_FIRE_BALL:
		{
			fire_ball(GF_FIRE, dir, 144, 2);
			*ident = TRUE;
			break;
		}

		case SV_ROD_COLD_BALL:
		{
			fire_ball(GF_COLD, dir, 96, 2);
			*ident = TRUE;
			break;
		}
	}

	/* Drain the charge */
	if (used_charge) o_ptr->timeout += k_ptr->pval;

	return TRUE;
}