Exemplo n.º 1
0
/*!
 * @brief モンスターにとって所定の地点が召還に相応しい地点かどうかを返す。 /
 * Determine if there is a space near the player in which a summoned creature can appear
 * @param y1 判定を行いたいマスのY座標
 * @param x1 判定を行いたいマスのX座標
 * @return 召還に相応しいならばTRUEを返す
 */
bool summon_possible(int y1, int x1)
{
	int y, x;

	/* Start at the player's location, and check 2 grids in each dir */
	for (y = y1 - 2; y <= y1 + 2; y++)
	{
		for (x = x1 - 2; x <= x1 + 2; x++)
		{
			/* Ignore illegal locations */
			if (!in_bounds(y, x)) continue;

			/* Only check a circular area */
			if (distance(y1, x1, y, x)>2) continue;

			/* ...nor on the Pattern */
			if (pattern_tile(y, x)) continue;

			/* Require empty floor grid in line of projection */
			if (cave_empty_bold(y, x) && projectable(y1, x1, y, x) && projectable(y, x, y1, x1)) return (TRUE);
		}
	}

	return FALSE;
}
Exemplo n.º 2
0
/* Handle the Terrifying Aura of Fear! */
void fear_process_p(void)
{
    int i, r_level;
    for (i = 1; i < m_max; i++)
    {
        monster_type *m_ptr = &m_list[i];
        monster_race *r_ptr;

        if (!m_ptr->r_idx) continue;
        if (!m_ptr->ml) continue;

        r_ptr = &r_info[m_ptr->ap_r_idx];

        if (!(r_ptr->flags2 & RF2_AURA_FEAR)) continue;
        if (is_pet(m_ptr) || is_friendly(m_ptr)) continue;
        if (!projectable(py, px, m_ptr->fy, m_ptr->fx)) continue;

        r_level = _r_level(r_ptr);
        if (!fear_save_p(r_level/MAX(1, m_ptr->cdis-2)))
        {
            char m_name[80];
            monster_desc(m_name, m_ptr, 0);
            msg_format("You behold the terrifying visage of %s!", m_name);
            mon_lore_2(m_ptr, RF2_AURA_FEAR);
            fear_add_p(r_level/MAX(1, m_ptr->cdis-2));
        }
    }
}
Exemplo n.º 3
0
/**
 * Determine if a monster makes a reasonable target
 *
 * The concept of "targetting" was stolen from "Morgul" (?)
 *
 * The player can target any location, or any "target-able" monster.
 *
 * Currently, a monster is "target_able" if it is visible, and if
 * the player can hit it with a projection, and the player is not
 * hallucinating.  This allows use of "use closest target" macros.
 */
bool target_able(struct monster *m)
{
	return m && m->race && mflag_has(m->mflag, MFLAG_VISIBLE) &&
		!mflag_has(m->mflag, MFLAG_UNAWARE) &&
		projectable(cave, player->py, player->px, m->fy, m->fx, PROJECT_NONE) &&
		!player->timed[TMD_IMAGE];
}
Exemplo n.º 4
0
/*
 * Determine is a monster makes a reasonable target
 *
 * The concept of "targetting" was stolen from "Morgul" (?)
 *
 * The player can target any location, or any "target-able" monster.
 *
 * Currently, a monster is "target_able" if it is visible, and if
 * the player can hit it with a projection, and the player is not
 * hallucinating.  This allows use of "use closest target" macros.
 *
 * Future versions may restrict the ability to target "trappers"
 * and "mimics", but the semantics is a little bit weird.
 */
bool target_able(int m_idx)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	monster_type *m_ptr;

	/* No monster */
	if (m_idx <= 0) return (FALSE);

	/* Get monster */
	m_ptr = cave_monster(cave, m_idx);

	/* Monster must be alive */
	if (!m_ptr->r_idx) return (FALSE);

	/* Monster must be visible */
	if (!m_ptr->ml) return (FALSE);
	
	/* Player must be aware this is a monster */
	if (m_ptr->unaware) return (FALSE);

	/* Monster must be projectable */
	if (!projectable(py, px, m_ptr->fy, m_ptr->fx, PROJECT_NONE))
		return (FALSE);

	/* Hack -- no targeting hallucinations */
	if (p_ptr->timed[TMD_IMAGE]) return (FALSE);

	/* Assume okay */
	return (TRUE);
}
Exemplo n.º 5
0
/*
 * Determine is a monster makes a reasonable target
 *
 * The concept of "targetting" was stolen from "Morgul" (?)
 *
 * The player can target any location, or any "target-able" monster.
 *
 * Currently, a monster is "target_able" if it is visible, and if
 * the player can hit it with a projection, and the player is not
 * hallucinating.  This allows use of "use closest target" macros.
 *
 * Future versions may restrict the ability to target "trappers"
 * and "mimics", but the semantics is a little bit weird.
 */
bool target_able(int m_idx)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	monster_type *m_ptr;

	/* No monster */
	if (m_idx <= 0) return (FALSE);

	/* Get monster */
	m_ptr = &mon_list[m_idx];

	/* Monster must be alive */
	if (!m_ptr->r_idx) return (FALSE);

	/* Monster must be visible */
	if (!m_ptr->ml) return (FALSE);

	/* Monster must be projectable */
	if (!projectable(py, px, m_ptr->fy, m_ptr->fx, PROJECT_NONE))
		return (FALSE);

	/* Hack -- no targeting hallucinations */
	if (p_ptr->timed[TMD_IMAGE]) return (FALSE);

	/* Hack -- Never target trappers XXX XXX XXX */
	/* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */

	/* Assume okay */
	return (TRUE);
}
Exemplo n.º 6
0
/**
 * Choose a good hiding place near a monster for it to run toward.
 *
 * Pack monsters will use this to "ambush" the player and lure him out
 * of corridors into open space so they can swarm him.
 *
 * Return true if a good location is available.
 */
static bool get_move_find_hiding(struct chunk *c, struct monster *mon)
{
	struct loc mon_grid = loc(mon->fx, mon->fy);
	struct loc player_grid = loc(player->px, player->py);

	int i, y, x, dy, dx, d, dis;
	int gy = 0, gx = 0, gdis = 999, min;

	const int *y_offsets, *x_offsets;

	/* Closest distance to get */
	min = distance(player_grid, mon_grid) * 3 / 4 + 2;

	/* Start with adjacent locations, spread further */
	for (d = 1; d < 10; d++) {
		/* Get the lists of points with a distance d from monster */
		y_offsets = dist_offsets_y[d];
		x_offsets = dist_offsets_x[d];

		/* Check the locations */
		for (i = 0, dx = x_offsets[0], dy = y_offsets[0];
		     dx != 0 || dy != 0;
		     i++, dx = x_offsets[i], dy = y_offsets[i]) {
			y = mon_grid.y + dy;
			x = mon_grid.x + dx;

			/* Skip illegal locations */
			if (!square_in_bounds_fully(c, y, x)) continue;

			/* Skip occupied locations */
			if (!square_isempty(c, y, x)) continue;

			/* Check for hidden, available grid */
			if (!square_isview(c, y, x) &&
				projectable(c, mon_grid.y, mon_grid.x, y, x, PROJECT_STOP)) {
				/* Calculate distance from player */
				dis = distance(loc(x, y), player_grid);

				/* Remember if closer than previous */
				if (dis < gdis && dis >= min) {
					gy = y;
					gx = x;
					gdis = dis;
				}
			}
		}

		/* Check for success */
		if (gdis < 999) {
			/* Good location */
			mon->target.grid = loc(gx, gy);
			return (true);
		}
	}

	/* No good place */
	return (false);
}
Exemplo n.º 7
0
void _grasp_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Vampiric Grasp");
        break;
    case SPELL_DESC:
        var_set_string(res, "Pulls a target creature to you.");
        break;
    case SPELL_CAST:
    {
        int           m_idx;
        bool          fear = FALSE;
        monster_type *m_ptr;
        monster_race *r_ptr;
        char m_name[MAX_NLEN];

        var_set_bool(res, FALSE);

        if (!target_set(TARGET_KILL)) break;
        if (!cave[target_row][target_col].m_idx) break;
        if (!player_has_los_bold(target_row, target_col)) break;
        if (!projectable(py, px, target_row, target_col)) break;

        var_set_bool(res, TRUE);

        m_idx = cave[target_row][target_col].m_idx;
        m_ptr = &m_list[m_idx];
        r_ptr = &r_info[m_ptr->r_idx];
        monster_desc(m_name, m_ptr, 0);
        if (r_ptr->flagsr & RFR_RES_TELE)
        {
            if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flagsr & RFR_RES_ALL))
            {
                if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
                msg_format("%s is unaffected!", m_name);
                break;
            }
            else if (r_ptr->level > randint1(100))
            {
                if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
                msg_format("%s resists!", m_name);
                break;
            }
        }
        msg_format("You grasp %s.", m_name);
        teleport_monster_to(m_idx, py, px, 100, TELEPORT_PASSIVE);
        mon_take_hit(m_idx, damroll(10, 10), &fear, extract_note_dies(real_r_ptr(m_ptr)));
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Exemplo n.º 8
0
static int _choose_mimic_form(void)
{
    int             r_idx = -1;
    int             i;
    _choice_array_t choices = {{{0}}};

    /* List Known Forms */
    for (i = 0; i < _MAX_FORMS; i++)
    {
        if (_forms[i])
        {
            int        j = choices.size++;
            _choice_t *choice = &choices.choices[j];

            choice->r_idx = _forms[i];
            choice->slot = i;
            choice->type = _TYPE_KNOWN;
            choice->key = I2A(j);
        }
    }

    /* List Visible Forms */
    for (i = 1; i < m_max; i++)
    {
        monster_type *m_ptr = &m_list[i];

        if (!m_ptr->r_idx) continue;
        if (!m_ptr->ml) continue;
        if (!projectable(py, px, m_ptr->fy, m_ptr->fx)) continue;
        if (!r_info[m_ptr->r_idx].body.life) continue; /* Form not implemented yet ... */

        _add_visible_form(&choices, m_ptr->r_idx);
    }

    /* Assign menu keys at the end due to insertion sort */
    for (i = 0; i < choices.size; i++)
    {
        _choice_t *choice = &choices.choices[i];
        
        if (choice->type == _TYPE_VISIBLE)
            choice->key = I2A(i);
    }

    if (choices.size)
    {
        choices.mode = _CHOOSE_MODE_MIMIC;
        if (_choose(&choices))
            r_idx = choices.choices[choices.current].r_idx;
        do_cmd_redraw();
    }
    else
        msg_print("You see nothing to mimic.");
    return r_idx;
}
Exemplo n.º 9
0
/*
 * do_cmd_cast calls this function if the player's class
 * is 'imitator'.
 */
static bool use_mane(int spell)
{
	int             dir;
	int             plev = p_ptr->lev;
	u32b mode = (PM_ALLOW_GROUP | PM_FORCE_PET);
	u32b u_mode = 0L;

	if (randint1(50+plev) < plev/10) u_mode = PM_ALLOW_UNIQUE;


	/* spell code */
	switch (spell)
	{
	case MS_SHRIEK:
#ifdef JP
msg_print("かん高い金切り声をあげた。");
#else
		msg_print("You make a high pitched shriek.");
#endif

		aggravate_monsters(0);
		break;
	case MS_XXX1:
		break;
	case MS_DISPEL:
	{
		int m_idx;

		if (!target_set(TARGET_KILL)) return FALSE;
		m_idx = cave[target_row][target_col].m_idx;
		if (!m_idx) break;
		if (!player_has_los_bold(target_row, target_col)) break;
		if (!projectable(py, px, target_row, target_col)) break;
		dispel_monster_status(m_idx);
		break;
	}
	case MS_ROCKET:
		if (!get_aim_dir(&dir)) return FALSE;
#ifdef JP
else msg_print("ロケットを発射した。");
#else
			else msg_print("You fire a rocket.");
#endif
		
			fire_rocket(GF_ROCKET, dir, damage, 2);
		break;
	case MS_SHOOT:
		if (!get_aim_dir(&dir)) return FALSE;
#ifdef JP
else msg_print("矢を放った。");
#else
			else msg_print("You fire an arrow.");
Exemplo n.º 10
0
static bool _is_visible(int r_idx)
{
    int i;
    for (i = 1; i < m_max; i++)
    {
        monster_type *m_ptr = &m_list[i];

        if (m_ptr->r_idx != r_idx) continue;
        if (!projectable(py, px, m_ptr->fy, m_ptr->fx)) continue;
        return TRUE;
    }
    return FALSE;
}
Exemplo n.º 11
0
bool fear_save_m(monster_type *m_ptr)
{
    int           pl = _plev();
    monster_race *r_ptr = &r_info[m_ptr->r_idx];
    int           ml = _r_level(r_ptr);
    bool          result = FALSE;

    /* Player may not exert their force of will out of sight! */
    if (projectable(py, px, m_ptr->fy, m_ptr->fx))
        pl += adj_stat_save[p_ptr->stat_ind[A_CHR]];

    if (pl <= 1) return TRUE;

    if (randint1(pl) <= randint1(ml)) result = TRUE;

    return result;
}
Exemplo n.º 12
0
/* Effective threat level for player recovery */
int fear_threat_level(void)
{
    int dl = MIN(dun_level + 2, 127);
    int ml = 0;
    int i;

    for (i = 1; i < m_max; i++)
    {
        monster_type *m_ptr = &m_list[i];
        monster_race *r_ptr = &r_info[m_ptr->r_idx];

        if (!m_ptr->r_idx) continue;
        if (!m_ptr->ml) continue;
        if (!(r_ptr->flags2 & RF2_AURA_FEAR)) continue;
        if (!projectable(py, px, m_ptr->fy, m_ptr->fx)) continue;

        ml = MAX(ml, _r_level(r_ptr)/MAX(1, m_ptr->cdis - 2));
    }

    return MAX(dl, ml);
}
Exemplo n.º 13
0
/* From Will Asher in DJA:
 * Find whether a monster is near a permanent wall
 * this decides whether PASS_WALL & KILL_WALL monsters 
 * use the monster flow code
 */
static bool near_permwall(const struct monster *mon, struct chunk *c)
{
	int y, x;
	int my = mon->fy;
	int mx = mon->fx;
	
	/* if PC is in LOS, there's no need to go around walls */
    if (projectable(cave, my, mx, player->py, player->px, PROJECT_NONE)) 
		return false;
    
    /* PASS_WALL & KILL_WALL monsters occasionally flow for a turn anyway */
    if (randint0(99) < 5) return true;
    
	/* Search the nearby grids, which are always in bounds */
	for (y = (my - 2); y <= (my + 2); y++) {
		for (x = (mx - 2); x <= (mx + 2); x++) {
            if (!square_in_bounds_fully(c, y, x)) continue;
            if (square_isperm(c, y, x)) return true;
		}
	}
	return false;
}
Exemplo n.º 14
0
/*!
 * @brief モンスターにとって死者復活を行うべき状態かどうかを返す /
 * Determine if there is a space near the player in which a summoned creature can appear
 * @param m_ptr 判定を行いたいモンスターの構造体参照ポインタ
 * @return 死者復活が有効な状態ならばTRUEを返す。
 */
bool raise_possible(monster_type *m_ptr)
{
	int xx, yy;
	int y = m_ptr->fy;
	int x = m_ptr->fx;
	s16b this_o_idx, next_o_idx = 0;
	cave_type *c_ptr;

	for (xx = x - 5; xx <= x + 5; xx++)
	{
		for (yy = y - 5; yy <= y + 5; yy++)
		{
			if (distance(y, x, yy, xx) > 5) continue;
			if (!los(y, x, yy, xx)) continue;
			if (!projectable(y, x, yy, xx)) continue;

			c_ptr = &cave[yy][xx];
			/* Scan the pile of objects */
			for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
			{
				/* Acquire object */
				object_type *o_ptr = &o_list[this_o_idx];

				/* Acquire next object */
				next_o_idx = o_ptr->next_o_idx;

				/* Known to be worthless? */
				if (o_ptr->tval == TV_CORPSE)
				{
					if (!monster_has_hostile_align(m_ptr, 0, 0, &r_info[o_ptr->pval])) return TRUE;
				}
			}
		}
	}
	return FALSE;
}
Exemplo n.º 15
0
/*
 * Determine is a monster makes a reasonable target
 *
 * The concept of "targetting" was stolen from "Morgul" (?)
 *
 * The player can target any location, or any "target-able" monster.
 *
 * Currently, a monster is "target_able" if it is visible, and if
 * the player can hit it with a projection, and the player is not
 * hallucinating.  This allows use of "use closest target" macros.
 *
 * Future versions may restrict the ability to target "trappers"
 * and "mimics", but the semantics is a little bit weird.
 */
bool target_able(struct monster *m)
{
	return m && m->race && m->ml && !m->unaware &&
			projectable(p_ptr->py, p_ptr->px, m->fy, m->fx, PROJECT_NONE) &&
			!p_ptr->timed[TMD_IMAGE];
}
Exemplo n.º 16
0
/**
 * Format the object name so that the prefix is right aligned to a common
 * column.
 *
 * This uses the default logic of object_desc() in order to handle flavors,
 * artifacts, vowels and so on. It was easier to do this and then use strtok()
 * to break it up than to do anything else.
 *
 * \param entry is the object list entry that has a name to be formatted.
 * \param line_buffer is the buffer to format into.
 * \param size is the size of line_buffer.
 */
void object_list_format_name(const object_list_entry_t *entry,
							 char *line_buffer, size_t size)
{
	char name[80];
	const char *chunk;
	char *source;
	bool has_singular_prefix;
	bool los = false;
	int field;
	byte old_number;
	struct loc pgrid = player->grid;
	struct object *base_obj;
	struct loc grid;
	bool object_is_recognized_artifact;

	if (entry == NULL || entry->object == NULL || entry->object->kind == NULL)
		return;

	base_obj = cave->objects[entry->object->oidx];
	grid = entry->object->grid;
	object_is_recognized_artifact = object_is_known_artifact(base_obj);

	/* Hack - these don't have a prefix when there is only one, so just pad
	 * with a space. */
	switch (entry->object->kind->tval) {
		case TV_SOFT_ARMOR:
			if (object_is_recognized_artifact)
				has_singular_prefix = true;
			else if (base_obj->kind->sval == lookup_sval(TV_SOFT_ARMOR, "Robe"))
				has_singular_prefix = true;
			else
				has_singular_prefix = false;
			break;
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
			if (object_is_recognized_artifact)
				has_singular_prefix = true;
			else
				has_singular_prefix = false;
			break;
		default:
			has_singular_prefix = true;
			break;
	}

	if (entry->object->kind != base_obj->kind)
		has_singular_prefix = true;

	/* Work out if the object is in view */
	los = projectable(cave, pgrid, grid, PROJECT_NONE) || loc_eq(grid, pgrid);
	field = los ? OBJECT_LIST_SECTION_LOS : OBJECT_LIST_SECTION_NO_LOS;

	/*
	 * Because each entry points to a specific object and not something more
	 * general, the number of similar objects we counted has to be swapped in.
	 * This isn't an ideal way to do this, but it's the easiest way until
	 * object_desc is more flexible.
	 */
	old_number = entry->object->number;
	entry->object->number = entry->count[field];
	object_desc(name, sizeof(name), base_obj, ODESC_PREFIX | ODESC_FULL);
	entry->object->number = old_number;

	/* The source string for strtok() needs to be set properly, depending on
	 * when we use it. */
	if (!has_singular_prefix && entry->count[field] == 1) {
		chunk = " ";
		source = name;
	}
	else {
		chunk = strtok(name, " ");
		source = NULL;
	}

	/* Right alight the prefix and clip. */
	strnfmt(line_buffer, size, "%3.3s ", chunk);

	/* Get the rest of the name and clip it to fit the max width. */
	chunk = strtok(source, "\0");
	my_strcat(line_buffer, chunk, size);
}
Exemplo n.º 17
0
/**
 * Choose a good hiding place near a monster for it to run toward.
 *
 * Pack monsters will use this to "ambush" the player and lure him out
 * of corridors into open space so they can swarm him.
 *
 * Return true if a good location is available.
 */
static bool find_hiding(struct chunk *c, struct monster *mon)
{
	int fy = mon->fy;
	int fx = mon->fx;

	int py = player->py;
	int px = player->px;

	int i, y, x, dy, dx, d, dis;
	int gy = 0, gx = 0, gdis = 999, min;

	const int *y_offsets, *x_offsets;

	/* Closest distance to get */
	min = distance(py, px, fy, fx) * 3 / 4 + 2;

	/* Start with adjacent locations, spread further */
	for (d = 1; d < 10; d++) {
		/* Get the lists of points with a distance d from (fx, fy) */
		y_offsets = dist_offsets_y[d];
		x_offsets = dist_offsets_x[d];

		/* Check the locations */
		for (i = 0, dx = x_offsets[0], dy = y_offsets[0];
		     dx != 0 || dy != 0;
		     i++, dx = x_offsets[i], dy = y_offsets[i]) {
			y = fy + dy;
			x = fx + dx;

			/* Skip illegal locations */
			if (!square_in_bounds_fully(c, y, x)) continue;

			/* Skip occupied locations */
			if (!square_isempty(c, y, x)) continue;

			/* Check for hidden, available grid */
			if (!square_isview(c, y, x) &&
				projectable(c, fy, fx, y, x, PROJECT_STOP)) {
				/* Calculate distance from player */
				dis = distance(y, x, py, px);

				/* Remember if closer than previous */
				if (dis < gdis && dis >= min) {
					gy = y;
					gx = x;
					gdis = dis;
				}
			}
		}

		/* Check for success */
		if (gdis < 999) {
			/* Good location */
			mon->ty = gy;
			mon->tx = gx;

			/* Found good place */
			return (true);
		}
	}

	/* No good place */
	return (false);
}
Exemplo n.º 18
0
/**
 * Determine if a monster makes a reasonable target
 *
 * The concept of "targetting" was stolen from "Morgul" (?)
 *
 * The player can target any location, or any "target-able" monster.
 *
 * Currently, a monster is "target_able" if it is visible, and if
 * the player can hit it with a projection, and the player is not
 * hallucinating.  This allows use of "use closest target" macros.
 */
bool target_able(struct monster *m)
{
	return m && m->race && monster_is_obvious(m) &&
		projectable(cave, player->grid, m->grid, PROJECT_NONE) &&
		!player->timed[TMD_IMAGE];
}
Exemplo n.º 19
0
/**
 * Collect monster information from the current cave's monster list.
 */
void monster_list_collect(monster_list_t *list)
{
	int i;

	if (list == NULL || list->entries == NULL)
		return;

	/* Use cave_monster_max() here in case the monster list isn't compacted. */
	for (i = 1; i < cave_monster_max(cave); i++) {
		struct monster *mon = cave_monster(cave, i);
		monster_list_entry_t *entry = NULL;
		int j, field;
		bool los = FALSE;

		/* Only consider visible, known monsters */
		if (!mflag_has(mon->mflag, MFLAG_VISIBLE) ||
			mflag_has(mon->mflag, MFLAG_UNAWARE))
			continue;

		/* Find or add a list entry. */
		for (j = 0; j < (int)list->entries_size; j++) {
			if (list->entries[j].race == NULL) {
				/* We found an empty slot, so add this race here. */
				entry = &list->entries[j];
				memset(entry, 0, sizeof(monster_list_entry_t));
				entry->race = mon->race;

				break;
			}
			else if (list->entries[j].race == mon->race) {
				/* We found a matching race and we'll use that. */
				entry = &list->entries[j];
				break;
			}
		}

		if (entry == NULL)
			continue;

		/* Always collect the latest monster attribute so that flicker
		 * animation works. If this is 0, it needs to be replaced by 
		 * the standard glyph in the UI */
		entry->attr = mon->attr;

		/* Skip the projection and location checks if nothing has changed. */
		if (!monster_list_needs_update(list))
			continue;

		/*
		 * Check for LOS
		 * Hack - we should use (mon->mflag & (MFLAG_VIEW)) here,
		 * but this does not catch monsters detected by ESP which are
		 * targetable, so we cheat and use projectable() instead
		 */
		los = projectable(cave, player->py, player->px, mon->fy, mon->fx,
						  PROJECT_NONE);
		field = (los) ? MONSTER_LIST_SECTION_LOS : MONSTER_LIST_SECTION_ESP;
		entry->count[field]++;

		if (mon->m_timed[MON_TMD_SLEEP] > 0)
			entry->asleep[field]++;

		/* Store the location offset from the player; this is only used for
		 * monster counts of 1 */
		entry->dx = mon->fx - player->px;
		entry->dy = mon->fy - player->py;
	}

	/* Skip calculations if nothing has changed, otherwise this will yield
	 * incorrect numbers. */
	if (!monster_list_needs_update(list))
		return;

	/* Collect totals for easier calculations of the list. */
	for (i = 0; i < (int)list->entries_size; i++) {
		if (list->entries[i].race == NULL)
			continue;

		if (list->entries[i].count[MONSTER_LIST_SECTION_LOS] > 0)
			list->total_entries[MONSTER_LIST_SECTION_LOS]++;

		if (list->entries[i].count[MONSTER_LIST_SECTION_ESP] > 0)
			list->total_entries[MONSTER_LIST_SECTION_ESP]++;

		list->total_monsters[MONSTER_LIST_SECTION_LOS] +=
			list->entries[i].count[MONSTER_LIST_SECTION_LOS];
		list->total_monsters[MONSTER_LIST_SECTION_ESP] +=
			list->entries[i].count[MONSTER_LIST_SECTION_ESP];
		list->distinct_entries++;
	}

	list->creation_turn = turn;
	list->sorted = FALSE;
}
Exemplo n.º 20
0
/* Idea borrowed from Vanilla 3.5, but recoded from scratch ... */
void do_cmd_list_monsters(void)
{
    int         i, ct_types, ct_total = 0;
    int_map_ptr info = int_map_alloc(free);
    
    /* Collect */
    for (i = 0; i < max_m_idx; i++)
    {
        const monster_type *m_ptr = &m_list[i];
        _mon_list_info_ptr  info_ptr;
        
        if (!m_ptr->ap_r_idx) continue;
        if (!m_ptr->ml) continue;

        info_ptr = int_map_find(info, m_ptr->ap_r_idx);
        if (!info_ptr)
        {
            info_ptr = malloc(sizeof(_mon_list_info_t));
            info_ptr->r_idx = m_ptr->ap_r_idx;
            info_ptr->ct_total = 0;
            info_ptr->ct_awake = 0;
            info_ptr->ct_los = 0;
            
            int_map_add(info, m_ptr->ap_r_idx, info_ptr);
        }

        assert(info_ptr);
        info_ptr->ct_total++;
        ct_total++;

        if (!MON_CSLEEP(m_ptr)) info_ptr->ct_awake++;
        if (projectable(py, px, m_ptr->fy, m_ptr->fx)) info_ptr->ct_los++;
    }
    
    ct_types = int_map_count(info);
    if (ct_types)
    {
        int_map_iter_ptr  iter;
        int              *order;
        int               cx, cy, row = 1, col;

        /* Sort */
        C_MAKE(order, ct_types, int);

        i = 0;
        for (iter = int_map_iter_alloc(info); 
                int_map_iter_is_valid(iter); 
                int_map_iter_next(iter))
        {
            _mon_list_info_ptr info_ptr = int_map_iter_current(iter);
            order[i++] = info_ptr->r_idx;
        }
        int_map_iter_free(iter);

        ang_sort_comp = _compare_r_level;
        ang_sort_swap = _swap_int;
        ang_sort(order, NULL, ct_types);

        /* Display */
        Term_get_size(&cx, &cy);
        col = cx - 52;
        screen_save();
        c_prt(TERM_WHITE, format("You see %d monster%s", ct_total, ct_total != 1 ? "s" : ""), 0, col);
        for (i = 0; i < ct_types; i++)
        {
            int                 r_idx = order[i];
            const monster_race *r_ptr = &r_info[r_idx];
            byte                attr = TERM_WHITE;
            _mon_list_info_ptr  info_ptr = int_map_find(info, r_idx);
            char                buf[100];

            assert(info_ptr);

            Term_erase(col - 1, row, 53);

            if (row >= cy - 2) 
            {
                c_prt(TERM_YELLOW, "...", row++, col+2);
                break;
            }

            if (r_ptr->flags1 & RF1_UNIQUE)
                attr = TERM_VIOLET;
            else if (r_ptr->level > base_level)
                attr = TERM_RED;                
            else if (!info_ptr->ct_awake)
                attr = TERM_L_UMBER;

            if (info_ptr->ct_total == 1)
                sprintf(buf, "%s", r_name + r_ptr->name);
            else if (!info_ptr->ct_awake)
                sprintf(buf, "%s (%d sleeping)", r_name + r_ptr->name, info_ptr->ct_total);
            else if (info_ptr->ct_awake == info_ptr->ct_total)
                sprintf(buf, "%s (%d awake)", r_name + r_ptr->name, info_ptr->ct_total);
            else
                sprintf(buf, "%s (%d awake, %d sleeping)", r_name + r_ptr->name, 
                    info_ptr->ct_awake, info_ptr->ct_total - info_ptr->ct_awake);

            Term_queue_bigchar(col, row, r_ptr->x_attr, r_ptr->x_char, 0, 0);
            c_put_str(attr, format(" %-50.50s", buf), row++, col+1);
        }
        Term_erase(col - 1, row, 53);
        c_prt(TERM_YELLOW, "Hit any key.", row, col+2);
        inkey();
        prt("", 0, 0);

        screen_load();

        C_KILL(order, ct_types, int);
    }
    else
        msg_print("You see no visible monsters.");

    int_map_free(info);
}
Exemplo n.º 21
0
/* A special fetch(), that places item in player's inventory */
static bool _whip_fetch(int dir, int rng)
{
    int             ty, tx;
    cave_type      *c_ptr;
    object_type    *o_ptr;
    char            o_name[MAX_NLEN];

    /* Use a target */
    if (dir == 5 && target_okay())
    {
        tx = target_col;
        ty = target_row;

        if (distance(py, px, ty, tx) > rng)
        {
            msg_print("You can't fetch something that far away!");
            return FALSE;
        }

        c_ptr = &cave[ty][tx];

        /* We need an item to fetch */
        if (!c_ptr->o_idx)
        {
            msg_print("There is no object at this place.");
            return TRUE;  /* didn't work, but charge the player energy anyway */
        }

        /* Fetching from a vault is OK */

        /* Line of sight is required */
        if (!player_has_los_bold(ty, tx))
        {
            msg_print("You have no direct line of sight to that location.");
            return FALSE;
        }
        else if (!projectable(py, px, ty, tx))
        {
            msg_print("You have no direct line of sight to that location.");
            return FALSE;
        }
    }
    else
    {
        /* Use a direction */
        ty = py; /* Where to drop the item */
        tx = px;

        do
        {
            ty += ddy[dir];
            tx += ddx[dir];
            c_ptr = &cave[ty][tx];

            if ((distance(py, px, ty, tx) > MAX_RANGE) ||
                !in_bounds(ty, tx) ||
                !cave_have_flag_bold(ty, tx, FF_PROJECT))
            {
                return TRUE; /* didn't work, but charge the player energy anyway */
            }
        }
        while (!c_ptr->o_idx);
    }

    o_ptr = &o_list[c_ptr->o_idx];

    if (o_ptr->weight > p_ptr->lev * 15)
    {
        msg_print("The object is too heavy.");
        return TRUE; /* didn't work, but charge the player energy anyway */
    }

    object_desc(o_name, o_ptr, OD_NAME_ONLY);

    /* Get the object */
    if (!inven_carry_okay(o_ptr))
    {
        cmsg_format(TERM_VIOLET, "You fail to fetch %^s since your pack is full.", o_name);
        /* Leave the object where it is */
    }
    else
    {
        msg_format("You skillfully crack your whip and fetch %^s.", o_name);
        py_pickup_aux(c_ptr->o_idx);
    }

    return TRUE;
}
Exemplo n.º 22
0
/**
 * Collect object information from the current cave.
 */
void object_list_collect(object_list_t *list)
{
	int i;
	struct loc pgrid = player->grid;

	if (list == NULL || list->entries == NULL)
		return;

	if (!object_list_needs_update(list))
		return;

	/* Scan each object in the dungeon. */
	for (i = 1; i < player->cave->obj_max; i++) {
		object_list_entry_t *entry = NULL;
		int entry_index;
		int current_distance;
		int entry_distance;
		struct loc grid;
		int field;
		bool los = false;
		struct object *obj = player->cave->objects[i];

		/* Skip unfilled entries, unknown objects and monster-held objects */
		if (!obj) continue;
		if (loc_is_zero(obj->grid)) {
			continue;
		} else {
			grid = obj->grid;
		}

		/* Determine which section of the list the object entry is in */
		los = projectable(cave, pgrid, grid, PROJECT_NONE) ||
			loc_eq(grid, pgrid);
		field = (los) ? OBJECT_LIST_SECTION_LOS : OBJECT_LIST_SECTION_NO_LOS;

		if (object_list_should_ignore_object(obj)) continue;

		/* Find or add a list entry. */
		for (entry_index = 0; entry_index < (int)list->entries_size;
			 entry_index++) {
			int j;
			struct object *list_obj = list->entries[entry_index].object;

			if (list_obj == NULL) {
				/* We found an empty slot, so add this object here. */
				list->entries[entry_index].object = obj;
				for (j = 0; j < OBJECT_LIST_SECTION_MAX; j++)
					list->entries[entry_index].count[j] = 0;
				list->entries[entry_index].dy = grid.y - pgrid.y;
				list->entries[entry_index].dx = grid.x - pgrid.x;
				entry = &list->entries[entry_index];
				break;
			}
		}

		if (entry == NULL)
			return;

		/* We only know the number of objects we've actually seen */
		if (obj->kind == cave->objects[obj->oidx]->kind)
			entry->count[field] += obj->number;
		else
			entry->count[field] = 1;

		/* Store the distance to the object in the stack that is
		 * closest to the player. */
		current_distance = (grid.y - pgrid.y) * (grid.y - pgrid.y) +
			(grid.x - pgrid.x) * (grid.x - pgrid.x);
		entry_distance = entry->dy * entry->dy + entry->dx * entry->dx;

		if (current_distance < entry_distance) {
			entry->dy = grid.y - pgrid.y;
			entry->dx = grid.x - pgrid.x;
		}
	}

	/* Collect totals for easier calculations of the list. */
	for (i = 0; i < (int)list->entries_size; i++) {
		if (list->entries[i].object == NULL)
			continue;

		if (list->entries[i].count[OBJECT_LIST_SECTION_LOS] > 0)
			list->total_entries[OBJECT_LIST_SECTION_LOS]++;

		if (list->entries[i].count[OBJECT_LIST_SECTION_NO_LOS] > 0)
			list->total_entries[OBJECT_LIST_SECTION_NO_LOS]++;

		list->total_objects[OBJECT_LIST_SECTION_LOS] +=
			list->entries[i].count[OBJECT_LIST_SECTION_LOS];
		list->total_objects[OBJECT_LIST_SECTION_NO_LOS] +=
			list->entries[i].count[OBJECT_LIST_SECTION_NO_LOS];
		list->distinct_entries++;
	}

	list->creation_turn = turn;
	list->sorted = false;
}
Exemplo n.º 23
0
/*
 * do_cmd_cast calls this function if the player's class
 * is 'imitator'.
 */
static bool cast_learned_spell(int spell, bool success)
{
    int             dir;
    int             plev = pseudo_plev();
    int     summon_lev = p_ptr->lev * 2 / 3 + randint1(p_ptr->lev/2);
    int             hp = p_ptr->chp;
    int             damage = 0;
    bool   pet = success;
    bool   no_trump = FALSE;
    u32b p_mode, u_mode = 0L, g_mode;

    if (pet)
    {
        p_mode = PM_FORCE_PET;
        g_mode = 0;
    }
    else
    {
        p_mode = PM_NO_PET;
        g_mode = PM_ALLOW_GROUP;
    }

    if (!success || (randint1(50+plev) < plev/10)) u_mode = PM_ALLOW_UNIQUE;

    /* spell code */
    switch (spell)
    {
    case MS_SHRIEK:
        msg_print("You make a high pitched shriek.");

        aggravate_monsters(0);
        break;
    case MS_XXX1:
        break;
    case MS_DISPEL:
    {
        int m_idx;

        if (!target_set(TARGET_KILL)) return FALSE;
        m_idx = cave[target_row][target_col].m_idx;
        if (!m_idx) break;
        if (!player_has_los_bold(target_row, target_col)) break;
        if (!projectable(py, px, target_row, target_col)) break;
        dispel_monster_status(m_idx);
        break;
    }
    case MS_ROCKET:
        if (!get_aim_dir(&dir)) return FALSE;
        else
            msg_print("You fire a rocket.");
        damage = hp / 4;
        fire_rocket(GF_ROCKET, dir, spell_power(damage), 2);
        break;
    case MS_SHOOT:
    {
        int slot;
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print("You fire an arrow.");
        damage = 1;
        slot = equip_find_first(object_is_melee_weapon);
        if (slot)
        {
            object_type *o_ptr = equip_obj(slot);
            damage = damroll(o_ptr->dd, o_ptr->ds)+ o_ptr->to_d;
            if (damage < 1) damage = 1;
        }
        fire_bolt(GF_ARROW, dir, spell_power(damage));
        break;
    }
    case MS_XXX2:
        break;
    case MS_XXX3:
        break;
    case MS_BR_STORM:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe storm.");
        damage = MIN(hp / 3, 300);
        fire_ball(GF_STORM, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_ACID:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe acid.");
        damage = hp / 3;
        fire_ball(GF_ACID, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_ELEC:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe lightning.");
        damage = hp / 3;
        fire_ball(GF_ELEC, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_FIRE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe fire.");
        damage = hp / 3;
        fire_ball(GF_FIRE, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_COLD:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe frost.");
        damage = hp / 3;
        fire_ball(GF_COLD, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_POIS:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe gas.");
        damage = hp / 3;
        fire_ball(GF_POIS, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_NETHER:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe nether.");
        damage = hp / 6;
        fire_ball(GF_NETHER, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_LITE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe light.");
        damage = hp / 6;
        fire_ball(GF_LITE, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_DARK:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe darkness.");
        damage = hp / 6;
        fire_ball(GF_DARK, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_CONF:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe confusion.");
        damage = hp / 6;
        fire_ball(GF_CONFUSION, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_SOUND:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe sound.");
        damage = hp / 6;
        fire_ball(GF_SOUND, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_CHAOS:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe chaos.");
        damage = hp / 6;
        fire_ball(GF_CHAOS, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_DISEN:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe disenchantment.");
        damage = hp / 6;
        fire_ball(GF_DISENCHANT, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_NEXUS:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe nexus.");
        damage = MIN(hp / 3, 250);
        fire_ball(GF_NEXUS, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_TIME:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe time.");
        damage = MIN(hp / 3, 150);
        fire_ball(GF_TIME, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_INERTIA:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe inertia.");
        damage = MIN(hp / 6, 200);
        fire_ball(GF_INERT, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_GRAVITY:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe gravity.");
        damage = MIN(hp / 3, 200);
        fire_ball(GF_GRAVITY, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_SHARDS:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe shards.");
        damage = hp / 6;
        fire_ball(GF_SHARDS, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_PLASMA:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe plasma.");
        damage = MIN(hp / 6, 150);
        fire_ball(GF_PLASMA, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_FORCE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe force.");
        damage = MIN(hp / 6, 200);
        fire_ball(GF_FORCE, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BR_MANA:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe mana.");
        
        damage = MIN(hp / 3, 250);
        fire_ball(GF_MANA, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BALL_NUKE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a ball of radiation.");
        damage = plev * 2 + damroll(10, 6);
        fire_ball(GF_NUKE, dir, spell_power(damage), 2);
        break;
    case MS_BR_NUKE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe toxic waste.");
        damage = hp / 3;
        fire_ball(GF_NUKE, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BALL_CHAOS:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You invoke a raw Logrus.");
        damage = plev * 4 + damroll(10, 10);
        fire_ball(GF_CHAOS, dir, spell_power(damage), 4);
        break;
    case MS_BR_DISI:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You breathe disintegration.");
        damage = MIN(hp / 6, 150);
        fire_ball(GF_DISINTEGRATE, dir, spell_power(damage), (plev > 40 ? -3 : -2));
        break;
    case MS_BALL_ACID:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast an acid ball.");
        damage = randint1(plev * 6) + 15;
        fire_ball(GF_ACID, dir, spell_power(damage), 2);
        break;
    case MS_BALL_ELEC:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a lightning ball.");
        damage = randint1(plev * 3) + 8;
        fire_ball(GF_ELEC, dir, spell_power(damage), 2);
        break;
    case MS_BALL_FIRE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a fire ball.");
        damage = randint1(plev * 7) + 10;
        fire_ball(GF_FIRE, dir, spell_power(damage), 2);
        break;
    case MS_BALL_COLD:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a frost ball.");
        damage = randint1(plev * 3) + 10;
        fire_ball(GF_COLD, dir, spell_power(damage), 2);
        break;
    case MS_BALL_POIS:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a stinking cloud.");
        damage = damroll(12,2);
        fire_ball(GF_POIS, dir, spell_power(damage), 2);
        break;
    case MS_BALL_NETHER:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a nether ball.");
        damage = plev * 2 + 50 + damroll(10, 10);
        fire_ball(GF_NETHER, dir, spell_power(damage), 2);
        break;
    case MS_BALL_WATER:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You gesture fluidly.");
        damage = randint1(plev * 4) + 50;
        fire_ball(GF_WATER, dir, spell_power(damage), 4);
        break;
    case MS_BALL_MANA:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You invoke a mana storm.");
        damage = plev * 8 + 50 + damroll(10, 10);
        fire_ball(GF_MANA, dir, spell_power(damage), 4);
        break;
    case MS_BALL_DARK:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You invoke a darkness storm.");
        damage = plev * 8 + 50 + damroll(10, 10);
        fire_ball(GF_DARK, dir, spell_power(damage), 4);
        break;
    case MS_DRAIN_MANA:
        if (!get_aim_dir(&dir)) return FALSE;
        fire_ball_hide(GF_DRAIN_MANA, dir, spell_power(randint1(plev)+plev), 0);
        break;
    case MS_MIND_BLAST:
        if (!get_aim_dir(&dir)) return FALSE;
        damage = damroll(7, 7);
        fire_ball_hide(GF_MIND_BLAST, dir, spell_power(damage), 0);
        break;
    case MS_BRAIN_SMASH:
        if (!get_aim_dir(&dir)) return FALSE;
        damage = damroll(12, 12);
        fire_ball_hide(GF_BRAIN_SMASH, dir, spell_power(damage), 0);
        break;
    case MS_CAUSE_1:
        if (!get_aim_dir(&dir)) return FALSE;
        damage = damroll(3, 8);
        fire_ball_hide(GF_CAUSE_1, dir, spell_power(damage), 0);
        break;
    case MS_CAUSE_2:
        if (!get_aim_dir(&dir)) return FALSE;
        damage = damroll(8, 8);
        fire_ball_hide(GF_CAUSE_2, dir, spell_power(damage), 0);
        break;
    case MS_CAUSE_3:
        if (!get_aim_dir(&dir)) return FALSE;
        damage = damroll(10, 15);
        fire_ball_hide(GF_CAUSE_3, dir, spell_power(damage), 0);
        break;
    case MS_CAUSE_4:
        if (!get_aim_dir(&dir)) return FALSE;
        damage = damroll(15, 15);
        fire_ball_hide(GF_CAUSE_4, dir, spell_power(damage), 0);
        break;
    case MS_BOLT_ACID:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast an acid bolt.");
        damage = damroll(7, 8) + plev * 2 / 3;
        fire_bolt(GF_ACID, dir, spell_power(damage));
        break;
    case MS_BOLT_ELEC:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a lightning bolt.");
        damage = damroll(4, 8) + plev * 2 / 3;
        fire_bolt(GF_ELEC, dir, spell_power(damage));
        break;
    case MS_BOLT_FIRE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a fire bolt.");
        damage = damroll(9, 8) + plev * 2 / 3;
        fire_bolt(GF_FIRE, dir, spell_power(damage));
        break;
    case MS_BOLT_COLD:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a frost bolt.");
        damage = damroll(6, 8) + plev * 2 / 3;
        fire_bolt(GF_COLD, dir, spell_power(damage));
        break;
    case MS_STARBURST:
        if (!get_aim_dir(&dir)) return FALSE;
        else
            msg_print("You invoke a starburst.");
        damage = plev * 8 + 50 + damroll(10, 10);
        fire_ball(GF_LITE, dir, spell_power(damage), 4);
        break;
    case MS_BOLT_NETHER:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a nether bolt.");
        damage = 30 + damroll(5, 5) + plev * 8 / 3;
        fire_bolt(GF_NETHER, dir, spell_power(damage));
        break;
    case MS_BOLT_WATER:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a water bolt.");
        damage = damroll(10, 10) + plev * 2;
        fire_bolt(GF_WATER, dir, spell_power(damage));
        break;
    case MS_BOLT_MANA:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a mana bolt.");
        damage = randint1(plev * 7) + 50;
        fire_bolt(GF_MANA, dir, spell_power(damage));
        break;
    case MS_BOLT_PLASMA:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a plasma bolt.");
        damage = 10 + damroll(8, 7) + plev * 2;
        fire_bolt(GF_PLASMA, dir, spell_power(damage));
        break;
    case MS_BOLT_ICE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a ice bolt.");
        damage = damroll(6, 6) + plev * 2;
        fire_bolt(GF_ICE, dir, spell_power(damage));
        break;
    case MS_MAGIC_MISSILE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a magic missile.");
        damage = damroll(2, 6) + plev * 2 / 3;
        fire_bolt(GF_MISSILE, dir, spell_power(damage));
        break;
    case MS_SCARE:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a fearful illusion.");
        fear_monster(dir, spell_power(plev+10));
        break;
    case MS_BLIND:
        if (!get_aim_dir(&dir)) return FALSE;
        confuse_monster(dir, spell_power(plev * 2));
        break;
    case MS_CONF:
        if (!get_aim_dir(&dir)) return FALSE;
            else msg_print("You cast a mesmerizing illusion.");
        confuse_monster(dir, spell_power(plev * 2));
        break;
    case MS_SLOW:
        if (!get_aim_dir(&dir)) return FALSE;
        slow_monster(dir);
        break;
    case MS_SLEEP:
        if (!get_aim_dir(&dir)) return FALSE;
        sleep_monster(dir, plev*3);
        break;
    case MS_SPEED:
        (void)set_fast(randint1(20 + plev) + plev, FALSE);
        break;
    case MS_HAND_DOOM:
    {
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You invoke the Hand of Doom!");

        fire_ball_hide(GF_HAND_DOOM, dir, spell_power(plev * 3), 0);
        break;
    }
    case MS_HEAL:
            msg_print("You concentrate on your wounds!");
        (void)hp_player(spell_power(plev*4));
        (void)set_stun(0, TRUE);
        (void)set_cut(0, TRUE);
        break;
    case MS_INVULNER:
            msg_print("You cast a Globe of Invulnerability.");
        (void)set_invuln(spell_power(randint1(4) + 4), FALSE);
        break;
    case MS_BLINK:
        teleport_player(10, 0L);
        break;
    case MS_TELEPORT:
        teleport_player(plev * 5, 0L);
        break;
    case MS_WORLD:
        world_player = TRUE;
        msg_print("'Time!'");
        msg_print(NULL);

        /* Hack */
        p_ptr->energy_need -= 1000 + (100 + randint1(200)+200)*TURNS_PER_TICK/10;

        /* Redraw map */
        p_ptr->redraw |= (PR_MAP | PR_STATUS);

        /* Update monsters */
        p_ptr->update |= (PU_MONSTERS);

        /* Window stuff */
        p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);

        handle_stuff();
        break;
    case MS_SPECIAL:
        break;
    case MS_TELE_TO:
    {
        monster_type *m_ptr;
        monster_race *r_ptr;
        char m_name[80];

        if (!target_set(TARGET_KILL)) return FALSE;
        if (!cave[target_row][target_col].m_idx) break;
        if (!player_has_los_bold(target_row, target_col)) break;
        if (!projectable(py, px, target_row, target_col)) break;
        m_ptr = &m_list[cave[target_row][target_col].m_idx];
        r_ptr = &r_info[m_ptr->r_idx];
        monster_desc(m_name, m_ptr, 0);
        if (r_ptr->flagsr & RFR_RES_TELE)
        {
            if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL))
            {
                if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
                msg_format("%s is unaffected!", m_name);

                break;
            }
            else if (r_ptr->level > randint1(100))
            {
                if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
                msg_format("%s resists!", m_name);

                break;
            }
        }
        msg_format("You command %s to return.", m_name);

        teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100, TELEPORT_PASSIVE);
        break;
    }
    case MS_TELE_AWAY:
        if (!get_aim_dir(&dir)) return FALSE;

        (void)fire_beam(GF_AWAY_ALL, dir, spell_power(100));
        break;
    case MS_TELE_LEVEL:
    {
        int target_m_idx;
        monster_type *m_ptr;
        monster_race *r_ptr;
        char m_name[80];

        if (!target_set(TARGET_KILL)) return FALSE;
        target_m_idx = cave[target_row][target_col].m_idx;
        if (!target_m_idx) break;
        if (!player_has_los_bold(target_row, target_col)) break;
        if (!projectable(py, px, target_row, target_col)) break;
        m_ptr = &m_list[target_m_idx];
        r_ptr = &r_info[m_ptr->r_idx];
        monster_desc(m_name, m_ptr, 0);
        msg_format("You gesture at %^s's feet.", m_name);

        if ((r_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE)) ||
            (r_ptr->flags1 & RF1_QUESTOR) || (r_ptr->level + randint1(50) > plev + randint1(60)))
        {
            msg_format("%^s is unaffected!", m_name);
        }
        else teleport_level(target_m_idx);
        break;
    }
    case MS_PSY_SPEAR:
        if (!get_aim_dir(&dir)) return FALSE;

            else msg_print("You throw a psycho-spear.");
        damage = randint1(plev * 3) + 100;
        (void)fire_beam(GF_PSY_SPEAR, dir, spell_power(damage));
        break;
    case MS_DARKNESS:
            msg_print("You gesture in shadow.");
        (void)unlite_area(10, 3);
        break;
    case MS_MAKE_TRAP:
        if (!target_set(TARGET_KILL)) return FALSE;
            msg_print("You cast a spell and cackle evilly.");
        trap_creation(target_row, target_col);
        break;
    case MS_FORGET:
            msg_print("Nothing happen.");
        break;
    case MS_RAISE_DEAD:
        msg_print("You cast a animate dead.");
        (void)animate_dead(0, py, px);
        break;
    case MS_S_KIN:
    {
        int k;
            msg_print("You summon minions.");
        for (k = 0;k < 1; k++)
        {
            if (summon_kin_player(summon_lev, py, px, (pet ? PM_FORCE_PET : 0L)))
            {
                if (!pet)
msg_print("Summoned fellows are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        }
        break;
    }
    case MS_S_CYBER:
    {
        int k;
            msg_print("You summon a Cyberdemon!");
        for (k = 0 ;k < 1 ; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_CYBER, p_mode))
            {
                if (!pet)
msg_print("The summoned Cyberdemon are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_MONSTER:
    {
        int k;
            msg_print("You summon help.");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, 0, p_mode))
            {
                if (!pet)
msg_print("The summoned monster is angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_MONSTERS:
    {
        int k;
            msg_print("You summon monsters!");
        for (k = 0;k < plev / 15 + 2; k++)
            if(summon_specific((pet ? -1 : 0), py, px, summon_lev, 0, (p_mode | u_mode)))
            {
                if (!pet)
msg_print("Summoned monsters are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_ANT:
    {
        int k;
            msg_print("You summon ants.");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_ANT, (PM_ALLOW_GROUP | p_mode)))
            {
                if (!pet)
msg_print("Summoned ants are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_SPIDER:
    {
        int k;
            msg_print("You summon spiders.");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_SPIDER, (PM_ALLOW_GROUP | p_mode)))
            {
                if (!pet)
msg_print("Summoned spiders are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_HOUND:
    {
        int k;
            msg_print("You summon hounds.");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HOUND, (PM_ALLOW_GROUP | p_mode)))
            {
                if (!pet)
msg_print("Summoned hounds are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_HYDRA:
    {
        int k;
            msg_print("You summon a hydras.");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HYDRA, (g_mode | p_mode)))
            {
                if (!pet)
msg_print("Summoned hydras are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_ANGEL:
    {
        int k;
            msg_print("You summon an angel!");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_ANGEL, (g_mode | p_mode)))
            {
                if (!pet)
msg_print("Summoned angels are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_DEMON:
    {
        int k;
            msg_print("You summon a demon from the Courts of Chaos!");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_DEMON, (g_mode | p_mode)))
            {
                if (!pet)
msg_print("Summoned demons are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_UNDEAD:
    {
        int k;
            msg_print("You summon an undead adversary!");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_UNDEAD, (g_mode | p_mode)))
            {
                if (!pet)
msg_print("Summoned undeads are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_DRAGON:
    {
        int k;
            msg_print("You summon a dragon!");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_DRAGON, (g_mode | p_mode)))
            {
                if (!pet)
msg_print("Summoned dragons are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_HI_UNDEAD:
    {
        int k;
            msg_print("You summon a greater undead!");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | u_mode)))
            {
                if (!pet)
msg_print("Summoned greater undeads are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_HI_DRAGON:
    {
        int k;
            msg_print("You summon an ancient dragon!");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HI_DRAGON, (g_mode | p_mode | u_mode)))
            {
                if (!pet)
msg_print("Summoned ancient dragons are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_AMBERITE:
    {
        int k;
            msg_print("You summon a Lord of Amber!");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_AMBERITE, (g_mode | p_mode | u_mode)))
            {
                if (!pet)
msg_print("Summoned Lords of Amber are angry!");
            }
            else
            {
                no_trump = TRUE;
            }
        break;
    }
    case MS_S_UNIQUE:
    {
        int k, count = 0;
            msg_print("You summon a special opponent!");
        for (k = 0;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_UNIQUE, (g_mode | p_mode | PM_ALLOW_UNIQUE)))
            {
                count++;
                if (!pet)
msg_print("Summoned special opponents are angry!");
            }
        for (k = count;k < 1; k++)
            if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | PM_ALLOW_UNIQUE)))
            {
                count++;
                if (!pet)
msg_print("Summoned greater undeads are angry!");
            }
        if (!count)
        {
            no_trump = TRUE;
        }
        break;
    }
    default:
        msg_print("hoge?");
    }
    if (no_trump)
    {
msg_print("No one have appeared.");
    }

    return TRUE;
}
Exemplo n.º 24
0
/*!
 * @brief 青魔法の発動 /
 * do_cmd_cast calls this function if the player's class is 'blue-mage'.
 * @param spell 発動するモンスター攻撃のID
 * @param success TRUEは成功時、FALSEは失敗時の処理を行う
 * @return 処理を実行したらTRUE、キャンセルした場合FALSEを返す。
 */
static bool cast_learned_spell(int spell, bool success)
{
	int             dir;
	int             plev = pseudo_plev();
	int     summon_lev = p_ptr->lev * 2 / 3 + randint1(p_ptr->lev/2);
	int             damage = 0;
	bool   pet = success;
	bool   no_trump = FALSE;
	u32b p_mode, u_mode = 0L, g_mode;

	if (pet)
	{
		p_mode = PM_FORCE_PET;
		g_mode = 0;
	}
	else
	{
		p_mode = PM_NO_PET;
		g_mode = PM_ALLOW_GROUP;
	}

	if (!success || (randint1(50+plev) < plev/10)) u_mode = PM_ALLOW_UNIQUE;

	/* spell code */
	switch (spell)
	{
	case MS_SHRIEK:
        msg_print(_("かん高い金切り声をあげた。", "You make a high pitched shriek."));
		aggravate_monsters(0);
		break;
	case MS_XXX1:
		break;
	case MS_DISPEL:
	{
		int m_idx;

		if (!target_set(TARGET_KILL)) return FALSE;
		m_idx = cave[target_row][target_col].m_idx;
		if (!m_idx) break;
		if (!player_has_los_bold(target_row, target_col)) break;
		if (!projectable(p_ptr->y, p_ptr->x, target_row, target_col)) break;
		dispel_monster_status(m_idx);
		break;
	}
	case MS_ROCKET:
		if (!get_aim_dir(&dir)) return FALSE;
		
        msg_print(_("ロケットを発射した。", "You fire a rocket."));
        damage = monspell_bluemage_damage((MS_ROCKET), plev, DAM_ROLL);
		fire_rocket(GF_ROCKET, dir, damage, 2);
		break;
	case MS_SHOOT:
	{
		if (!get_aim_dir(&dir)) return FALSE;
		
        msg_print(_("矢を放った。", "You fire an arrow."));
        damage = monspell_bluemage_damage((MS_SHOOT), plev, DAM_ROLL);
		fire_bolt(GF_ARROW, dir, damage);
		break;
	}
	case MS_XXX2:
		break;
	case MS_XXX3:
		break;
	case MS_XXX4:
		break;
	case MS_BR_ACID:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("酸のブレスを吐いた。", "You breathe acid."));
        damage = monspell_bluemage_damage((MS_BR_ACID), plev, DAM_ROLL);
		fire_ball(GF_ACID, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_ELEC:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("稲妻のブレスを吐いた。", "You breathe lightning."));
        damage = monspell_bluemage_damage((MS_BR_ELEC), plev, DAM_ROLL);
		fire_ball(GF_ELEC, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_FIRE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("火炎のブレスを吐いた。", "You breathe fire."));
        damage = monspell_bluemage_damage((MS_BR_FIRE), plev, DAM_ROLL);
		fire_ball(GF_FIRE, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_COLD:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("冷気のブレスを吐いた。", "You breathe frost."));
        damage = monspell_bluemage_damage((MS_BR_COLD), plev, DAM_ROLL);
		fire_ball(GF_COLD, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_POIS:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("ガスのブレスを吐いた。", "You breathe gas."));
        damage = monspell_bluemage_damage((MS_BR_POIS), plev, DAM_ROLL);
		fire_ball(GF_POIS, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_NETHER:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("地獄のブレスを吐いた。", "You breathe nether."));
        damage = monspell_bluemage_damage((MS_BR_NETHER), plev, DAM_ROLL);
		fire_ball(GF_NETHER, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_LITE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("閃光のブレスを吐いた。", "You breathe light."));
        damage = monspell_bluemage_damage((MS_BR_LITE), plev, DAM_ROLL);
		fire_ball(GF_LITE, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_DARK:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("暗黒のブレスを吐いた。", "You breathe darkness."));
        damage = monspell_bluemage_damage((MS_BR_DARK), plev, DAM_ROLL);
		fire_ball(GF_DARK, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_CONF:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("混乱のブレスを吐いた。", "You breathe confusion."));
        damage = monspell_bluemage_damage((MS_BR_CONF), plev, DAM_ROLL);
		fire_ball(GF_CONFUSION, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_SOUND:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("轟音のブレスを吐いた。", "You breathe sound."));
        damage = monspell_bluemage_damage((MS_BR_SOUND), plev, DAM_ROLL);
		fire_ball(GF_SOUND, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_CHAOS:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("カオスのブレスを吐いた。", "You breathe chaos."));
        damage = monspell_bluemage_damage((MS_BR_CHAOS), plev, DAM_ROLL);
		fire_ball(GF_CHAOS, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_DISEN:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("劣化のブレスを吐いた。", "You breathe disenchantment."));
        damage = monspell_bluemage_damage((MS_BR_DISEN), plev, DAM_ROLL);
		fire_ball(GF_DISENCHANT, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_NEXUS:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("因果混乱のブレスを吐いた。", "You breathe nexus."));
        damage = monspell_bluemage_damage((MS_BR_NEXUS), plev, DAM_ROLL);
		fire_ball(GF_NEXUS, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_TIME:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("時間逆転のブレスを吐いた。", "You breathe time."));
        damage = monspell_bluemage_damage((MS_BR_TIME), plev, DAM_ROLL);
		fire_ball(GF_TIME, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_INERTIA:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("遅鈍のブレスを吐いた。", "You breathe inertia."));
        damage = monspell_bluemage_damage((MS_BR_INERTIA), plev, DAM_ROLL);
		fire_ball(GF_INERTIAL, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_GRAVITY:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("重力のブレスを吐いた。", "You breathe gravity."));
        damage = monspell_bluemage_damage((MS_BR_GRAVITY), plev, DAM_ROLL);
		fire_ball(GF_GRAVITY, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_SHARDS:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("破片のブレスを吐いた。", "You breathe shards."));
        damage = monspell_bluemage_damage((MS_BR_SHARDS), plev, DAM_ROLL);
		fire_ball(GF_SHARDS, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_PLASMA:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("プラズマのブレスを吐いた。", "You breathe plasma."));
        damage = monspell_bluemage_damage((MS_BR_PLASMA), plev, DAM_ROLL);
		fire_ball(GF_PLASMA, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_FORCE:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("フォースのブレスを吐いた。", "You breathe force."));
        damage = monspell_bluemage_damage((MS_BR_FORCE), plev, DAM_ROLL);
		fire_ball(GF_FORCE, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BR_MANA:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("魔力のブレスを吐いた。", "You breathe mana."));
        damage = monspell_bluemage_damage((MS_BR_MANA), plev, DAM_ROLL);
		fire_ball(GF_MANA, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BALL_NUKE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("放射能球を放った。", "You cast a ball of radiation."));
        damage = monspell_bluemage_damage((MS_BALL_NUKE), plev, DAM_ROLL);
		fire_ball(GF_NUKE, dir, damage, 2);
		break;
	case MS_BR_NUKE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("放射性廃棄物のブレスを吐いた。", "You breathe toxic waste."));
        damage = monspell_bluemage_damage((MS_BR_NUKE), plev, DAM_ROLL);
		fire_ball(GF_NUKE, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BALL_CHAOS:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("純ログルスを放った。", "You invoke a raw Logrus."));
        damage = monspell_bluemage_damage((MS_BALL_CHAOS), plev, DAM_ROLL);
		fire_ball(GF_CHAOS, dir, damage, 4);
		break;
	case MS_BR_DISI:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("分解のブレスを吐いた。", "You breathe disintegration."));
        damage = monspell_bluemage_damage((MS_BR_DISI), plev, DAM_ROLL);
		fire_ball(GF_DISINTEGRATE, dir, damage, (plev > 40 ? -3 : -2));
		break;
	case MS_BALL_ACID:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("アシッド・ボールの呪文を唱えた。", "You cast an acid ball."));
        damage = monspell_bluemage_damage((MS_BALL_ACID), plev, DAM_ROLL);
		fire_ball(GF_ACID, dir, damage, 2);
		break;
	case MS_BALL_ELEC:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("サンダー・ボールの呪文を唱えた。", "You cast a lightning ball."));
        damage = monspell_bluemage_damage((MS_BALL_ELEC), plev, DAM_ROLL);
		fire_ball(GF_ELEC, dir, damage, 2);
		break;
	case MS_BALL_FIRE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("ファイア・ボールの呪文を唱えた。", "You cast a fire ball."));
        damage = monspell_bluemage_damage((MS_BALL_FIRE), plev, DAM_ROLL);
		fire_ball(GF_FIRE, dir, damage, 2);
		break;
	case MS_BALL_COLD:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("アイス・ボールの呪文を唱えた。", "You cast a frost ball."));
        damage = monspell_bluemage_damage((MS_BALL_COLD), plev, DAM_ROLL);
		fire_ball(GF_COLD, dir, damage, 2);
		break;
	case MS_BALL_POIS:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("悪臭雲の呪文を唱えた。", "You cast a stinking cloud."));
        damage = monspell_bluemage_damage((MS_BALL_POIS), plev, DAM_ROLL);
		fire_ball(GF_POIS, dir, damage, 2);
		break;
	case MS_BALL_NETHER:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("地獄球の呪文を唱えた。", "You cast a nether ball."));
        damage = monspell_bluemage_damage((MS_BALL_NETHER), plev, DAM_ROLL);
		fire_ball(GF_NETHER, dir, damage, 2);
		break;
	case MS_BALL_WATER:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("流れるような身振りをした。", "You gesture fluidly."));
        damage = monspell_bluemage_damage((MS_BALL_WATER), plev, DAM_ROLL);
		fire_ball(GF_WATER, dir, damage, 4);
		break;
	case MS_BALL_MANA:
        if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("魔力の嵐の呪文を念じた。", "You invoke a mana storm."));
        damage = monspell_bluemage_damage((MS_BALL_MANA), plev, DAM_ROLL);
		fire_ball(GF_MANA, dir, damage, 4);
		break;
	case MS_BALL_DARK:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("暗黒の嵐の呪文を念じた。", "You invoke a darkness storm."));
        damage = monspell_bluemage_damage((MS_BALL_DARK), plev, DAM_ROLL);
		fire_ball(GF_DARK, dir, damage, 4);
		break;
	case MS_DRAIN_MANA:
		if (!get_aim_dir(&dir)) return FALSE;

        damage = monspell_bluemage_damage((MS_DRAIN_MANA), plev, DAM_ROLL);
        fire_ball_hide(GF_DRAIN_MANA, dir, damage, 0);
		break;
	case MS_MIND_BLAST:
		if (!get_aim_dir(&dir)) return FALSE;

        damage = monspell_bluemage_damage((MS_MIND_BLAST), plev, DAM_ROLL);
		fire_ball_hide(GF_MIND_BLAST, dir, damage, 0);
		break;
	case MS_BRAIN_SMASH:
        if (!get_aim_dir(&dir)) return FALSE;

        damage = monspell_bluemage_damage((MS_BRAIN_SMASH), plev, DAM_ROLL);
		fire_ball_hide(GF_BRAIN_SMASH, dir, damage, 0);
		break;
	case MS_CAUSE_1:
		if (!get_aim_dir(&dir)) return FALSE;

        damage = monspell_bluemage_damage((MS_CAUSE_1), plev, DAM_ROLL);
		fire_ball_hide(GF_CAUSE_1, dir, damage, 0);
		break;
	case MS_CAUSE_2:
		if (!get_aim_dir(&dir)) return FALSE;

        damage = monspell_bluemage_damage((MS_CAUSE_2), plev, DAM_ROLL);
		fire_ball_hide(GF_CAUSE_2, dir, damage, 0);
		break;
	case MS_CAUSE_3:
		if (!get_aim_dir(&dir)) return FALSE;

        damage = monspell_bluemage_damage((MS_CAUSE_3), plev, DAM_ROLL);
		fire_ball_hide(GF_CAUSE_3, dir, damage, 0);
		break;
	case MS_CAUSE_4:
		if (!get_aim_dir(&dir)) return FALSE;

        damage = monspell_bluemage_damage((MS_CAUSE_4), plev, DAM_ROLL);
		fire_ball_hide(GF_CAUSE_4, dir, damage, 0);
		break;
	case MS_BOLT_ACID:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("アシッド・ボルトの呪文を唱えた。", "You cast an acid bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_ACID), plev, DAM_ROLL);
        fire_bolt(GF_ACID, dir, damage);
		break;
	case MS_BOLT_ELEC:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("サンダー・ボルトの呪文を唱えた。", "You cast a lightning bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_ELEC), plev, DAM_ROLL);
		fire_bolt(GF_ELEC, dir, damage);
		break;
	case MS_BOLT_FIRE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("ファイア・ボルトの呪文を唱えた。", "You cast a fire bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_FIRE), plev, DAM_ROLL);
		fire_bolt(GF_FIRE, dir, damage);
		break;
	case MS_BOLT_COLD:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("アイス・ボルトの呪文を唱えた。", "You cast a frost bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_COLD), plev, DAM_ROLL);
		fire_bolt(GF_COLD, dir, damage);
		break;
	case MS_STARBURST:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("スターバーストの呪文を念じた。", "You invoke a starburst."));
        damage = monspell_bluemage_damage((MS_STARBURST), plev, DAM_ROLL);
		fire_ball(GF_LITE, dir, damage, 4);
		break;
	case MS_BOLT_NETHER:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("地獄の矢の呪文を唱えた。", "You cast a nether bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_NETHER), plev, DAM_ROLL);
		fire_bolt(GF_NETHER, dir, damage);
		break;
	case MS_BOLT_WATER:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("ウォーター・ボルトの呪文を唱えた。", "You cast a water bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_WATER), plev, DAM_ROLL);
		fire_bolt(GF_WATER, dir, damage);
		break;
	case MS_BOLT_MANA:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("魔力の矢の呪文を唱えた。", "You cast a mana bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_MANA), plev, DAM_ROLL);
		fire_bolt(GF_MANA, dir, damage);
		break;
	case MS_BOLT_PLASMA:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("プラズマ・ボルトの呪文を唱えた。", "You cast a plasma bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_PLASMA), plev, DAM_ROLL);
		fire_bolt(GF_PLASMA, dir, damage);
		break;
	case MS_BOLT_ICE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("極寒の矢の呪文を唱えた。", "You cast a ice bolt."));
        damage = monspell_bluemage_damage((MS_BOLT_ICE), plev, DAM_ROLL);
		fire_bolt(GF_ICE, dir, damage);
		break;
	case MS_MAGIC_MISSILE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("マジック・ミサイルの呪文を唱えた。", "You cast a magic missile."));
        damage = monspell_bluemage_damage((MS_MAGIC_MISSILE), plev, DAM_ROLL);
		fire_bolt(GF_MISSILE, dir, damage);
		break;
	case MS_SCARE:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("恐ろしげな幻覚を作り出した。", "You cast a fearful illusion."));
		fear_monster(dir, plev+10);
		break;
	case MS_BLIND:
		if (!get_aim_dir(&dir)) return FALSE;
		confuse_monster(dir, plev * 2);
		break;
	case MS_CONF:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("誘惑的な幻覚をつくり出した。", "You cast a mesmerizing illusion."));
		confuse_monster(dir, plev * 2);
		break;
	case MS_SLOW:
		if (!get_aim_dir(&dir)) return FALSE;
		slow_monster(dir, plev);
		break;
	case MS_SLEEP:
		if (!get_aim_dir(&dir)) return FALSE;
		sleep_monster(dir, plev);
		break;
	case MS_SPEED:
		(void)set_fast(randint1(20 + plev) + plev, FALSE);
		break;
	case MS_HAND_DOOM:
	{
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("<破滅の手>を放った!", "You invoke the Hand of Doom!"));
		fire_ball_hide(GF_HAND_DOOM, dir, plev * 3, 0);
		break;
	}
	case MS_HEAL:
        msg_print(_("自分の傷に念を集中した。", "You concentrate on your wounds!"));
		(void)hp_player(plev*4);
		(void)set_stun(0);
		(void)set_cut(0);
		break;
	case MS_INVULNER:
        msg_print(_("無傷の球の呪文を唱えた。", "You cast a Globe of Invulnerability."));
		(void)set_invuln(randint1(4) + 4, FALSE);
		break;
	case MS_BLINK:
		teleport_player(10, 0L);
		break;
	case MS_TELEPORT:
		teleport_player(plev * 5, 0L);
		break;
	case MS_WORLD:
        world_player = TRUE;
        msg_print(_("「時よ!」", "'Time!'"));
		msg_print(NULL);

		/* Hack */
		p_ptr->energy_need -= 1000 + (100 + randint1(200)+200)*TURNS_PER_TICK/10;

		/* Redraw map */
		p_ptr->redraw |= (PR_MAP);

		/* Update monsters */
		p_ptr->update |= (PU_MONSTERS);

		/* Window stuff */
		p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);

		handle_stuff();
		break;
	case MS_SPECIAL:
		break;
	case MS_TELE_TO:
	{
		monster_type *m_ptr;
		monster_race *r_ptr;
		char m_name[80];

		if (!target_set(TARGET_KILL)) return FALSE;
		if (!cave[target_row][target_col].m_idx) break;
		if (!player_has_los_bold(target_row, target_col)) break;
		if (!projectable(p_ptr->y, p_ptr->x, target_row, target_col)) break;
		m_ptr = &m_list[cave[target_row][target_col].m_idx];
		r_ptr = &r_info[m_ptr->r_idx];
		monster_desc(m_name, m_ptr, 0);
		if (r_ptr->flagsr & RFR_RES_TELE)
		{
			if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL))
			{
				if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
                msg_format(_("%sには効果がなかった!", "%s is unaffected!"), m_name);
				break;
			}
			else if (r_ptr->level > randint1(100))
			{
				if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
                msg_format(_("%sには耐性がある!", "%s resists!"), m_name);
				break;
			}
		}
        msg_format(_("%sを引き戻した。", "You command %s to return."), m_name);
		teleport_monster_to(cave[target_row][target_col].m_idx, p_ptr->y, p_ptr->x, 100, TELEPORT_PASSIVE);
		break;
	}
	case MS_TELE_AWAY:
		if (!get_aim_dir(&dir)) return FALSE;

		(void)fire_beam(GF_AWAY_ALL, dir, 100);
		break;
	case MS_TELE_LEVEL:
	{
		int target_m_idx;
		monster_type *m_ptr;
		monster_race *r_ptr;
		char m_name[80];

		if (!target_set(TARGET_KILL)) return FALSE;
		target_m_idx = cave[target_row][target_col].m_idx;
		if (!target_m_idx) break;
		if (!player_has_los_bold(target_row, target_col)) break;
		if (!projectable(p_ptr->y, p_ptr->x, target_row, target_col)) break;
		m_ptr = &m_list[target_m_idx];
		r_ptr = &r_info[m_ptr->r_idx];
		monster_desc(m_name, m_ptr, 0);
        msg_format(_("%^sの足を指さした。", "You gesture at %^s's feet."), m_name);

		if ((r_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE)) ||
			(r_ptr->flags1 & RF1_QUESTOR) || (r_ptr->level + randint1(50) > plev + randint1(60)))
		{
            msg_format(_("しかし効果がなかった!", "%^s is unaffected!"), m_name);
		}
		else teleport_level(target_m_idx);
		break;
	}
	case MS_PSY_SPEAR:
		if (!get_aim_dir(&dir)) return FALSE;

        msg_print(_("光の剣を放った。", "You throw a psycho-spear."));
        damage = monspell_bluemage_damage((MS_PSY_SPEAR), plev, DAM_ROLL);
		(void)fire_beam(GF_PSY_SPEAR, dir, damage);
		break;
	case MS_DARKNESS:

        msg_print(_("暗闇の中で手を振った。", "You gesture in shadow."));
		(void)unlite_area(10, 3);
		break;
	case MS_MAKE_TRAP:
		if (!target_set(TARGET_KILL)) return FALSE;

        msg_print(_("呪文を唱えて邪悪に微笑んだ。", "You cast a spell and cackle evilly."));
		trap_creation(target_row, target_col);
		break;
	case MS_FORGET:
        msg_print(_("しかし何も起きなかった。", "Nothing happen."));
		break;
    case MS_RAISE_DEAD:
        msg_print(_("死者復活の呪文を唱えた。", "You cast a animate dead."));
		(void)animate_dead(0, p_ptr->y, p_ptr->x);
		break;
	case MS_S_KIN:
	{
		int k;

        msg_print(_("援軍を召喚した。", "You summon minions."));
		for (k = 0;k < 1; k++)
		{
			if (summon_kin_player(summon_lev, p_ptr->y, p_ptr->x, (pet ? PM_FORCE_PET : 0L)))
			{
				if (!pet) msg_print(_("召喚された仲間は怒っている!", "Summoned fellows are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		}
		break;
	}
	case MS_S_CYBER:
	{
		int k;

        msg_print(_("サイバーデーモンを召喚した!", "You summon a Cyberdemon!"));
		for (k = 0 ;k < 1 ; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_CYBER, p_mode))
			{
                if (!pet)
                    msg_print(_("召喚されたサイバーデーモンは怒っている!", "The summoned Cyberdemon are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_MONSTER:
	{
		int k;
        msg_print(_("仲間を召喚した。", "You summon help."));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, 0, p_mode))
			{
                if (!pet)
                    msg_print(_("召喚されたモンスターは怒っている!", "The summoned monster is angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_MONSTERS:
	{
		int k;
        msg_print(_("モンスターを召喚した!", "You summon monsters!"));
		for (k = 0;k < plev / 15 + 2; k++)
			if(summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, 0, (p_mode | u_mode)))
			{
                if (!pet)
                    msg_print(_("召喚されたモンスターは怒っている!", "The summoned monsters are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_ANT:
	{
		int k;
        msg_print(_("アリを召喚した。", "You summon ants."));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_ANT, (PM_ALLOW_GROUP | p_mode)))
			{
                if (!pet)
                    msg_print(_("召喚されたアリは怒っている!", "The summoned ants are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_SPIDER:
	{
		int k;
        msg_print(_("蜘蛛を召喚した。", "You summon spiders."));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_SPIDER, (PM_ALLOW_GROUP | p_mode)))
			{
                if (!pet)
                    msg_print(_("召喚された蜘蛛は怒っている!", "Summoned spiders are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_HOUND:
	{
		int k;
        msg_print(_("ハウンドを召喚した。", "You summon hounds."));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HOUND, (PM_ALLOW_GROUP | p_mode)))
			{
                if (!pet)
                    msg_print(_("召喚されたハウンドは怒っている!", "Summoned hounds are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_HYDRA:
	{
		int k;
        msg_print(_("ヒドラを召喚した。", "You summon a hydras."));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HYDRA, (g_mode | p_mode)))
			{
                if (!pet)
                    msg_print(_("召喚されたヒドラは怒っている!", "Summoned hydras are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_ANGEL:
	{
		int k;
        msg_print(_("天使を召喚した!", "You summon an angel!"));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_ANGEL, (g_mode | p_mode)))
			{
                if (!pet)
                    msg_print(_("召喚された天使は怒っている!", "Summoned angels are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_DEMON:
	{
		int k;
        msg_print(_("混沌の宮廷から悪魔を召喚した!", "You summon a demon from the Courts of Chaos!"));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_DEMON, (g_mode | p_mode)))
			{
                if (!pet)
                    msg_print(_("召喚されたデーモンは怒っている!", "Summoned demons are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_UNDEAD:
	{
		int k;
        msg_print(_("アンデッドの強敵を召喚した!", "You summon an undead adversary!"));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_UNDEAD, (g_mode | p_mode)))
			{
                if (!pet)
                    msg_print(_("召喚されたアンデッドは怒っている!", "Summoned undeads are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_DRAGON:
	{
		int k;
        msg_print(_("ドラゴンを召喚した!", "You summon a dragon!"));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_DRAGON, (g_mode | p_mode)))
			{
                if (!pet)
                    msg_print(_("召喚されたドラゴンは怒っている!", "Summoned dragons are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_HI_UNDEAD:
	{
		int k;
        msg_print(_("強力なアンデッドを召喚した!", "You summon a greater undead!"));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | u_mode)))
			{
                if (!pet)
                    msg_print(_("召喚された上級アンデッドは怒っている!", "Summoned greater undeads are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_HI_DRAGON:
	{
		int k;
        msg_print(_("古代ドラゴンを召喚した!", "You summon an ancient dragon!"));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HI_DRAGON, (g_mode | p_mode | u_mode)))
			{
                if (!pet)
                    msg_print(_("召喚された古代ドラゴンは怒っている!", "Summoned ancient dragons are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_AMBERITE:
	{
		int k;
        msg_print(_("アンバーの王族を召喚した!", "You summon a Lord of Amber!"));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_AMBERITES, (g_mode | p_mode | u_mode)))
			{
                if (!pet)
                    msg_print(_("召喚されたアンバーの王族は怒っている!", "Summoned Lords of Amber are angry!"));
			}
			else
			{
				no_trump = TRUE;
			}
		break;
	}
	case MS_S_UNIQUE:
	{
		int k, count = 0;
		msg_print(_("特別な強敵を召喚した!", "You summon a special opponent!"));
		for (k = 0;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_UNIQUE, (g_mode | p_mode | PM_ALLOW_UNIQUE)))
			{
				count++;
				if (!pet)
					msg_print(_("召喚されたユニーク・モンスターは怒っている!", "Summoned special opponents are angry!"));
			}
		for (k = count;k < 1; k++)
			if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | PM_ALLOW_UNIQUE)))
			{
				count++;
				if (!pet)
					msg_print(_("召喚された上級アンデッドは怒っている!", "Summoned greater undeads are angry!"));
			}
		if (!count)
		{
			no_trump = TRUE;
		}
		break;
	}
	default:
		msg_print("hoge?");
	}
	if (no_trump)
    {
        msg_print(_("何も現れなかった。", "No one have appeared."));
	}

	return TRUE;
}
Exemplo n.º 25
0
/*
 * do_cmd_cast calls this function if the player's class
 * is 'imitator'.
 */
static bool use_mane(int spell)
{
    int             dir;
    int             plev = p_ptr->lev;
    u32b mode = (PM_ALLOW_GROUP | PM_FORCE_PET);
    u32b u_mode = 0L;

    if (randint1(50+plev) < plev/10) u_mode = PM_ALLOW_UNIQUE;

    /* spell code */
    switch (spell)
    {
    case MS_SHRIEK:
        msg_print("You make a high pitched shriek.");
        aggravate_monsters(0);
        break;
    case MS_XXX1:
        break;
    case MS_DISPEL:
    {
        int m_idx;

        if (!target_set(TARGET_KILL)) return FALSE;
        m_idx = cave[target_row][target_col].m_idx;
        if (!m_idx) break;
        if (!player_has_los_bold(target_row, target_col)) break;
        if (!projectable(py, px, target_row, target_col)) break;
        dispel_monster_status(m_idx);
        break;
    }
    case MS_ROCKET:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You fire a rocket.");
        fire_rocket(GF_ROCKET, dir, damage, 2);
        break;
    case MS_SHOOT:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You fire an arrow.");
        fire_bolt(GF_ARROW, dir, damage);
        break;
    case MS_XXX2:
        break;
    case MS_XXX3:
        break;
    case MS_BR_STORM:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe storm.");
        fire_ball(GF_STORM, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_ACID:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe acid.");
        fire_ball(GF_ACID, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_ELEC:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe lightning.");
        fire_ball(GF_ELEC, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_FIRE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe fire.");
        fire_ball(GF_FIRE, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_COLD:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe frost.");
        fire_ball(GF_COLD, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_POIS:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe gas.");
        fire_ball(GF_POIS, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_NETHER:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe nether.");
        fire_ball(GF_NETHER, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_LITE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe light.");
        fire_ball(GF_LITE, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_DARK:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe darkness.");
        fire_ball(GF_DARK, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_CONF:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe confusion.");
        fire_ball(GF_CONFUSION, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_SOUND:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe sound.");
        fire_ball(GF_SOUND, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_CHAOS:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe chaos.");
        fire_ball(GF_CHAOS, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_DISEN:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe disenchantment.");
        fire_ball(GF_DISENCHANT, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_NEXUS:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe nexus.");
        fire_ball(GF_NEXUS, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_TIME:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe time.");
        fire_ball(GF_TIME, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_INERTIA:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe inertia.");
        fire_ball(GF_INERT, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_GRAVITY:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe gravity.");
        fire_ball(GF_GRAVITY, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_SHARDS:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe shards.");
        fire_ball(GF_SHARDS, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_PLASMA:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe plasma.");
        fire_ball(GF_PLASMA, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_FORCE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe force.");
        fire_ball(GF_FORCE, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BR_MANA:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe mana.");
        fire_ball(GF_MANA, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BALL_NUKE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a ball of radiation.");
        fire_ball(GF_NUKE, dir, damage, 2);
        break;
    case MS_BR_NUKE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe toxic waste.");
        fire_ball(GF_NUKE, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BALL_CHAOS:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You invoke a raw Logrus.");
        fire_ball(GF_CHAOS, dir, damage, 4);
        break;
    case MS_BR_DISI:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You breathe disintegration.");
        fire_ball(GF_DISINTEGRATE, dir, damage, (plev > 35 ? -3 : -2));
        break;
    case MS_BALL_ACID:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast an acid ball.");
        fire_ball(GF_ACID, dir, damage, 2);
        break;
    case MS_BALL_ELEC:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a lightning ball.");
        fire_ball(GF_ELEC, dir, damage, 2);
        break;
    case MS_BALL_FIRE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a fire ball.");
        fire_ball(GF_FIRE, dir, damage, 2);
        break;
    case MS_BALL_COLD:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a frost ball.");
        fire_ball(GF_COLD, dir, damage, 2);
        break;
    case MS_BALL_POIS:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a stinking cloud.");
        fire_ball(GF_POIS, dir, damage, 2);
        break;
    case MS_BALL_NETHER:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a nether ball.");
        fire_ball(GF_NETHER, dir, damage, 2);
        break;
    case MS_BALL_WATER:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You gesture fluidly.");
        fire_ball(GF_WATER, dir, damage, 4);
        break;
    case MS_BALL_MANA:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You invoke a mana storm.");
        fire_ball(GF_MANA, dir, damage, 4);
        break;
    case MS_BALL_DARK:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You invoke a darkness storm.");
        fire_ball(GF_DARK, dir, damage, 4);
        break;
    case MS_DRAIN_MANA:
        if (!get_aim_dir(&dir)) return FALSE;
        fire_ball_hide(GF_DRAIN_MANA, dir, randint1(plev*3)+plev, 0);
        break;
    case MS_MIND_BLAST:
        if (!get_aim_dir(&dir)) return FALSE;
        fire_ball_hide(GF_MIND_BLAST, dir, damage, 0);
        break;
    case MS_BRAIN_SMASH:
        if (!get_aim_dir(&dir)) return FALSE;
        fire_ball_hide(GF_BRAIN_SMASH, dir, damage, 0);
        break;
    case MS_CAUSE_1:
        if (!get_aim_dir(&dir)) return FALSE;
        fire_ball_hide(GF_CAUSE_1, dir, damage, 0);
        break;
    case MS_CAUSE_2:
        if (!get_aim_dir(&dir)) return FALSE;
        fire_ball_hide(GF_CAUSE_2, dir, damage, 0);
        break;
    case MS_CAUSE_3:
        if (!get_aim_dir(&dir)) return FALSE;
        fire_ball_hide(GF_CAUSE_3, dir, damage, 0);
        break;
    case MS_CAUSE_4:
        if (!get_aim_dir(&dir)) return FALSE;
        fire_ball_hide(GF_CAUSE_4, dir, damage, 0);
        break;
    case MS_BOLT_ACID:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast an acid bolt.");
        fire_bolt(GF_ACID, dir, damage);
        break;
    case MS_BOLT_ELEC:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a lightning bolt.");
        fire_bolt(GF_ELEC, dir, damage);
        break;
    case MS_BOLT_FIRE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a fire bolt.");
        fire_bolt(GF_FIRE, dir, damage);
        break;
    case MS_BOLT_COLD:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a frost bolt.");
        fire_bolt(GF_COLD, dir, damage);
        break;
    case MS_STARBURST:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You invoke a starburst.");
        fire_ball(GF_LITE, dir, damage, 4);
        break;
    case MS_BOLT_NETHER:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a nether bolt.");
        fire_bolt(GF_NETHER, dir, damage);
        break;
    case MS_BOLT_WATER:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a water bolt.");
        fire_bolt(GF_WATER, dir, damage);
        break;
    case MS_BOLT_MANA:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a mana bolt.");
        fire_bolt(GF_MANA, dir, damage);
        break;
    case MS_BOLT_PLASMA:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a plasma bolt.");
        fire_bolt(GF_PLASMA, dir, damage);
        break;
    case MS_BOLT_ICE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a ice bolt.");
        fire_bolt(GF_ICE, dir, damage);
        break;
    case MS_MAGIC_MISSILE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a magic missile.");
        fire_bolt(GF_MISSILE, dir, damage);
        break;
    case MS_SCARE:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a fearful illusion.");
        fear_monster(dir, plev+10);
        break;
    case MS_BLIND:
        if (!get_aim_dir(&dir)) return FALSE;
        confuse_monster(dir, plev * 2);
        break;
    case MS_CONF:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You cast a mesmerizing illusion.");
        confuse_monster(dir, plev * 2);
        break;
    case MS_SLOW:
        if (!get_aim_dir(&dir)) return FALSE;
        slow_monster(dir);
        break;
    case MS_SLEEP:
        if (!get_aim_dir(&dir)) return FALSE;
        sleep_monster(dir, plev*3);
        break;
    case MS_SPEED:
        (void)set_fast(randint1(20 + plev) + plev, FALSE);
        break;
    case MS_HAND_DOOM:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You invoke the Hand of Doom!");
        fire_ball_hide(GF_HAND_DOOM, dir, 200, 0);
        break;
    case MS_HEAL:
        msg_print("You concentrate on your wounds!");
        (void)hp_player(plev*6);
        (void)set_stun(0, TRUE);
        (void)set_cut(0, TRUE);
        break;
    case MS_INVULNER:
        msg_print("You cast a Globe of Invulnerability.");
        (void)set_invuln(randint1(7) + 7, FALSE);
        break;
    case MS_BLINK:
        if (mut_present(MUT_ASTRAL_GUIDE))
            energy_use = 30;
        teleport_player(10, 0L);
        break;
    case MS_TELEPORT:
        if (mut_present(MUT_ASTRAL_GUIDE))
            energy_use = 30;
        teleport_player(plev * 5, 0L);
        break;
    case MS_WORLD:
        world_player = TRUE;
        if (damage == 1 || damage == 2)
            msg_print("You yell 'The World! Time has stopped!'");
        else if (damage == 3 || damage == 6)
            msg_print("You yell 'Time!'");
        else
            msg_print("hek!");
        msg_print(NULL);

        p_ptr->energy_need -= 1000 + (100 + randint1(200)+200)*TURNS_PER_TICK/10;
        p_ptr->redraw |= (PR_MAP);
        p_ptr->update |= (PU_MONSTERS);
        p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
        handle_stuff();
        break;
    case MS_SPECIAL:
        break;
    case MS_TELE_TO:
    {
        monster_type *m_ptr;
        monster_race *r_ptr;
        char m_name[80];

        if (!target_set(TARGET_KILL)) return FALSE;
        if (!cave[target_row][target_col].m_idx) break;
        if (!player_has_los_bold(target_row, target_col)) break;
        if (!projectable(py, px, target_row, target_col)) break;
        m_ptr = &m_list[cave[target_row][target_col].m_idx];
        r_ptr = &r_info[m_ptr->r_idx];
        monster_desc(m_name, m_ptr, 0);
        if (r_ptr->flagsr & RFR_RES_TELE)
        {
            if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL))
            {
                if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
                msg_format("%s is unaffected!", m_name);
                break;
            }
            else if (r_ptr->level > randint1(100))
            {
                if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
                msg_format("%s resists!", m_name);
                break;
            }
        }
        msg_format("You command %s to return.", m_name);
        teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100, TELEPORT_PASSIVE);
        break;
    }
    case MS_TELE_AWAY:
        if (!get_aim_dir(&dir)) return FALSE;
        (void)fire_beam(GF_AWAY_ALL, dir, plev);
        break;
    case MS_TELE_LEVEL:
    {
        int target_m_idx;
        monster_type *m_ptr;
        monster_race *r_ptr;
        char m_name[80];

        if (!target_set(TARGET_KILL)) return FALSE;
        target_m_idx = cave[target_row][target_col].m_idx;
        if (!target_m_idx) break;
        if (!player_has_los_bold(target_row, target_col)) break;
        if (!projectable(py, px, target_row, target_col)) break;
        m_ptr = &m_list[target_m_idx];
        r_ptr = &r_info[m_ptr->r_idx];
        monster_desc(m_name, m_ptr, 0);
        msg_format("You gesture at %^s's feet.", m_name);
        if ((r_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE)) ||
            (r_ptr->flags1 & RF1_QUESTOR) || (r_ptr->level + randint1(50) > plev + randint1(60)))
        {
            msg_format("%^s is unaffected!", m_name);
        }
        else teleport_level(target_m_idx);
        break;
    }
    case MS_PSY_SPEAR:
        if (!get_aim_dir(&dir)) return FALSE;
        else msg_print("You throw a psycho-spear.");
        fire_beam(GF_PSY_SPEAR, dir, damage);
        break;
    case MS_DARKNESS:
        msg_print("You gesture in shadow.");
        unlite_area(10, 3);
        break;
    case MS_MAKE_TRAP:
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You cast a spell and cackle evilly.");
        trap_creation(target_row, target_col);
        break;
    case MS_FORGET:
        msg_print("Nothing happens.");
        /* TODO: forget_spell(m_idx) ... */
        break;
    case MS_RAISE_DEAD:
        msg_print("You cast a animate dead.");
        animate_dead(0, py, px);
        break;
    case MS_S_KIN:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon minions.");
        for (k = 0;k < 4; k++)
        {
            (void)summon_kin_player(plev, target_row, target_col, (PM_FORCE_PET | PM_ALLOW_GROUP));
        }
        break;
    }
    case MS_S_CYBER:
    {
        int k;
        int max_cyber = (dun_level / 50) + randint1(3);
        if (!target_set(TARGET_KILL)) return FALSE;
            msg_print("You summon Cyberdemons!");
        if (max_cyber > 4) max_cyber = 4;
        for (k = 0;k < max_cyber; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_CYBER, mode);
        break;
    }
    case MS_S_MONSTER:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon help.");
        for (k = 0;k < 1; k++)
            summon_specific(-1, target_row, target_col, plev, 0, (mode | u_mode));
        break;
    }
    case MS_S_MONSTERS:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
            msg_print("You summon monsters!");
        for (k = 0;k < 6; k++)
            summon_specific(-1, target_row, target_col, plev, 0, (mode | u_mode));
        break;
    }
    case MS_S_ANT:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon ants.");
        for (k = 0;k < 6; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_ANT, mode);
        break;
    }
    case MS_S_SPIDER:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon spiders.");
        for (k = 0;k < 6; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_SPIDER, mode);
        break;
    }
    case MS_S_HOUND:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon hounds.");
        for (k = 0;k < 4; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_HOUND, mode);
        break;
    }
    case MS_S_HYDRA:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon hydras.");
        for (k = 0;k < 4; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_HYDRA, mode);
        break;
    }
    case MS_S_ANGEL:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon angel!");
        for (k = 0;k < 1; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_ANGEL, mode);
        break;
    }
    case MS_S_DEMON:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon a demon from the Courts of Chaos!");
        for (k = 0;k < 1; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_DEMON, (mode | u_mode));
        break;
    }
    case MS_S_UNDEAD:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon an undead adversary!");
        for (k = 0;k < 1; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_UNDEAD, (mode | u_mode));
        break;
    }
    case MS_S_DRAGON:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon dragon!");
        for (k = 0;k < 1; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_DRAGON, (mode | u_mode));
        break;
    }
    case MS_S_HI_UNDEAD:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon greater undead!");
        for (k = 0;k < 6; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode));
        break;
    }
    case MS_S_HI_DRAGON:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon ancient dragons!");
        for (k = 0;k < 4; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_HI_DRAGON, (mode | u_mode));
        break;
    }
    case MS_S_AMBERITE:
    {
        int k;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon Lords of Amber!");
        for (k = 0;k < 4; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_AMBERITE, (mode | PM_ALLOW_UNIQUE));
        break;
    }
    case MS_S_UNIQUE:
    {
        int k, count = 0;
        if (!target_set(TARGET_KILL)) return FALSE;
        msg_print("You summon special opponents!");
        for (k = 0;k < 4; k++)
            if (summon_specific(-1, target_row, target_col, plev, SUMMON_UNIQUE, (mode | PM_ALLOW_UNIQUE))) count++;
        for (k = count;k < 4; k++)
            summon_specific(-1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode));
        break;
    }
    default:
        msg_print("hoge?");
    }

    return TRUE;
}
Exemplo n.º 26
0
/*
 * Cast a chain of beams of the given type, jumping through nearby monsters. Monsters
 * must be inside the player's LOF.
 * max_hits is the maximum number of beams that will be casted.
 * decrement is a percentage of damage that is decreased with every beam. Use 0
 * to keep the damage constant.
 * Return TRUE if at least one monster was hit.
 */
bool beam_chain(int gf_type, int dam, int max_hits, int decrement)
{
    int yy, xx;

    /* Must be from from player's location */
    int py = p_ptr->py;
    int px = p_ptr->px;

    int y = py;
    int x = px;

    /* The indexes in mon_list of the reached monsters */
    QVector<u16b> hits;
    hits.clear();
    QVector<u16b> monsters;
    monsters.clear();

    bool flag = FALSE;

    /* Cast max_hits beams */
    for (int i = 0; i < max_hits; i++)
    {
        monsters.clear();

        int m_idx;

        /* Scan monsters as potential targets */

        for (m_idx = 0; m_idx < mon_max; m_idx++)
        {
            monster_type *m_ptr = &mon_list[m_idx];

            /* Paranoia -- Skip dead monsters */
            if (!m_ptr->r_idx) continue;

            /* It must be visible */
            if (!m_ptr->ml) continue;

            /* Get monster coordinates */
            yy = m_ptr->fy;
            xx = m_ptr->fx;

            /* It must be in the line of fire of the player */
            if(!m_ptr->project) continue;

            /* It must be in the line of fire of the previous location */
            if(!projectable(y, x, yy, xx, PROJECT_NONE)) continue;

            /* It must be close enough to the previous location */
            if (distance(y, x, yy, xx) > MAX_RANGE) continue;

            // Make sure we haven't hit this monster before;
            if (hits.contains(m_idx)) continue;

            /* Mark the monster as a possible candidate */
            monsters.append(m_idx);
        }

        /* No monsters. Done */
        if (monsters.size()) break;

        /* Select a random monster from the list */
        m_idx = monsters.at(randint0(monsters.size()));

        /* Get its location */
        yy = mon_list[m_idx].fy;
        xx = mon_list[m_idx].fx;

        /* Remember the monster */
        hits.append(m_idx);

        /* Cast the beam */
        project(SOURCE_PLAYER, 0, y, x, yy, xx, dam, gf_type,
            (PROJECT_KILL | PROJECT_BEAM), 0, 0);

        /* Success */
        flag = TRUE;

        /* Make the next beam weaker */
        dam -= (decrement * dam) / 100;

        /* No damage. Done */
        if (dam < 1) break;

        /* Remember the last location */
        y = yy;
        x = xx;
    }

    return (flag);
}
Exemplo n.º 27
0
static void _greater_whirlwind_attack_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Greater Ambush");
        break;
    case SPELL_DESC:
        var_set_string(res, "Perform a massive ambush on nearby monsters.");
        break;
    case SPELL_CAST:
    {
        int              i, x, y;
        cave_type       *c_ptr;
        monster_type    *m_ptr;

/*       cba
        d218l
        e3@7k
        f456j
         ghi  */

        typedef struct _offset_t { int dx; int dy; } _offset;
        static _offset offsets[] = {
            { 0, -1},
            {-1, -1},
            {-1,  0},
            {-1,  1},
            { 0,  1},
            { 1,  1},
            { 1,  0},
            { 1, -1},
            { 1, -2},
            { 0, -2},
            {-1, -2},
            {-2, -1},
            {-2,  0},
            {-2,  1},
            {-1,  2},
            { 0,  2},
            { 1,  2},
            { 2,  1},
            { 2,  0},
            { 2, -1},
            { 0,  0}, /* sentinel */
        };

        for (i = 0;; i++)
        {
            _offset offset = offsets[i];
            if (offset.dx == 0 && offset.dy == 0) break;

            y = py + offset.dy;
            x = px + offset.dx;

            if (!in_bounds(y, x)) continue;
            if (!projectable(py, px, y, x)) continue;

            c_ptr = &cave[y][x];

            if (!c_ptr->m_idx) continue;

            m_ptr = &m_list[c_ptr->m_idx];

            if (m_ptr->ml || cave_have_flag_bold(y, x, FF_PROJECT))
            {
                int msec = delay_factor * delay_factor * delay_factor;

                if (panel_contains(y, x) && player_can_see_bold(y, x))
                {
                    char c = 0x30;
                    byte a = TERM_WHITE;

                    print_rel(c, a, y, x);
                    move_cursor_relative(y, x);
                    Term_fresh();
                    Term_xtra(TERM_XTRA_DELAY, msec);
                    lite_spot(y, x);
                    Term_fresh();
                }
                else
                    Term_xtra(TERM_XTRA_DELAY, msec);

                py_attack(y, x, 0);
            }
        }
        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Exemplo n.º 28
0
/**
 * Creatures can cast spells, shoot missiles, and breathe.
 *
 * Returns "true" if a spell (or whatever) was (successfully) cast.
 *
 * XXX XXX XXX This function could use some work, but remember to
 * keep it as optimized as possible, while retaining generic code.
 *
 * Verify the various "blind-ness" checks in the code.
 *
 * XXX XXX XXX Note that several effects should really not be "seen"
 * if the player is blind.
 *
 * Perhaps monsters should breathe at locations *near* the player,
 * since this would allow them to inflict "partial" damage.
 *
 * Perhaps smart monsters should decline to use "bolt" spells if
 * there is a monster in the way, unless they wish to kill it.
 *
 * It will not be possible to "correctly" handle the case in which a
 * monster attempts to attack a location which is thought to contain
 * the player, but which in fact is nowhere near the player, since this
 * might induce all sorts of messages about the attack itself, and about
 * the effects of the attack, which the player might or might not be in
 * a position to observe.  Thus, for simplicity, it is probably best to
 * only allow "faulty" attacks by a monster if one of the important grids
 * (probably the initial or final grid) is in fact in view of the player.
 * It may be necessary to actually prevent spell attacks except when the
 * monster actually has line of sight to the player.  Note that a monster
 * could be left in a bizarre situation after the player ducked behind a
 * pillar and then teleported away, for example.
 *
 * Note that this function attempts to optimize the use of spells for the
 * cases in which the monster has no spells, or has spells but cannot use
 * them, or has spells but they will have no "useful" effect.  Note that
 * this function has been an efficiency bottleneck in the past.
 *
 * Note the special "MFLAG_NICE" flag, which prevents a monster from using
 * any spell attacks until the player has had a single chance to move.
 */
bool make_attack_spell(struct monster *mon)
{
	int chance, thrown_spell, rlev, failrate;

	bitflag f[RSF_SIZE];

	struct monster_lore *lore = get_lore(mon->race);

	char m_name[80], m_poss[80], ddesc[80];

	/* Player position */
	int px = player->px;
	int py = player->py;

	/* Extract the blind-ness */
	bool blind = (player->timed[TMD_BLIND] ? true : false);

	/* Extract the "see-able-ness" */
	bool seen = (!blind && mflag_has(mon->mflag, MFLAG_VISIBLE));

	/* Assume "normal" target */
	bool normal = true;

	/* Cannot cast spells when confused */
	if (mon->m_timed[MON_TMD_CONF]) return (false);

	/* Cannot cast spells when nice */
	if (mflag_has(mon->mflag, MFLAG_NICE)) return false;

	/* Hack -- Extract the spell probability */
	chance = (mon->race->freq_innate + mon->race->freq_spell) / 2;

	/* Not allowed to cast spells */
	if (!chance) return false;

	/* Only do spells occasionally */
	if (randint0(100) >= chance) return false;

	/* Hack -- require projectable player */
	if (normal) {
		/* Check range */
		if (mon->cdis > z_info->max_range)
			return false;

		/* Check path */
		if (!projectable(cave, mon->fy, mon->fx, py, px, PROJECT_NONE))
			return false;
	}

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

	/* Extract the racial spell flags */
	rsf_copy(f, mon->race->spell_flags);

	/* Allow "desperate" spells */
	if (rf_has(mon->race->flags, RF_SMART) &&
	    mon->hp < mon->maxhp / 10 &&
	    randint0(100) < 50)

		/* Require intelligent spells */
		ignore_spells(f, RST_BOLT | RST_BALL | RST_BREATH | RST_ATTACK | RST_INNATE);

	/* Remove the "ineffective" spells */
	remove_bad_spells(mon, f);

	/* Check whether summons and bolts are worth it. */
	if (!rf_has(mon->race->flags, RF_STUPID)) {
		/* Check for a clean bolt shot */
		if (test_spells(f, RST_BOLT) &&
			!projectable(cave, mon->fy, mon->fx, py, px, PROJECT_STOP))

			/* Remove spells that will only hurt friends */
			ignore_spells(f, RST_BOLT);

		/* Check for a possible summon */
		if (!(summon_possible(mon->fy, mon->fx)))

			/* Remove summoning spells */
			ignore_spells(f, RST_SUMMON);
	}

	/* No spells left */
	if (rsf_is_empty(f)) return false;

	/* Get the monster name (or "it") */
	monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);

	/* Get the monster possessive ("his"/"her"/"its") */
	monster_desc(m_poss, sizeof(m_poss), mon, MDESC_PRO_VIS | MDESC_POSS);

	/* Get the "died from" name */
	monster_desc(ddesc, sizeof(ddesc), mon, MDESC_DIED_FROM);

	/* Choose a spell to cast */
	thrown_spell = choose_attack_spell(f);

	/* Abort if no spell was chosen */
	if (!thrown_spell) return false;

	/* If we see an unaware monster try to cast a spell, become aware of it */
	if (mflag_has(mon->mflag, MFLAG_UNAWARE))
		become_aware(mon);

	/* Calculate spell failure rate */
	failrate = 25 - (rlev + 3) / 4;
	if (mon->m_timed[MON_TMD_FEAR])
		failrate += 20;

	/* Stupid monsters will never fail (for jellies and such) */
	if (rf_has(mon->race->flags, RF_STUPID))
		failrate = 0;

	/* Check for spell failure (innate attacks never fail) */
	if (!mon_spell_is_innate(thrown_spell) && (randint0(100) < failrate)) {
		/* Message */
		msg("%s tries to cast a spell, but fails.", m_name);

		return true;
	}

	/* Cast the spell. */
	disturb(player, 1);
	do_mon_spell(thrown_spell, mon, seen);

	/* Remember what the monster did to us */
	if (seen) {
		rsf_on(lore->spell_flags, thrown_spell);

		/* Innate spell */
		if (mon_spell_is_innate(thrown_spell)) {
			if (lore->cast_innate < UCHAR_MAX)
				lore->cast_innate++;
		} else {
			/* Bolt or Ball, or Special spell */
			if (lore->cast_spell < UCHAR_MAX)
				lore->cast_spell++;
		}
	}

	/* Always take note of monsters that kill you */
	if (player->is_dead && (lore->deaths < SHRT_MAX)) {
		lore->deaths++;
	}

	/* Record any new info */
	lore_update(mon->race, lore);

	/* A spell was cast */
	return true;
}
Exemplo n.º 29
0
/*!
 * @brief フロア移動時のペット保存処理 / Preserve_pets
 * @return なし
 */
static void preserve_pet(void)
{
	int num;
	MONSTER_IDX i;

	for (num = 0; num < MAX_PARTY_MON; num++)
	{
		party_mon[num].r_idx = 0;
	}

	if (p_ptr->riding)
	{
		monster_type *m_ptr = &m_list[p_ptr->riding];

		/* Pet of other pet don't follow. */
		if (m_ptr->parent_m_idx)
		{
			p_ptr->riding = 0;
			p_ptr->pet_extra_flags &= ~(PF_RYOUTE);
			p_ptr->riding_ryoute = p_ptr->old_riding_ryoute = FALSE;
		}
		else
		{
			/* Preserve the mount */
			(void)COPY(&party_mon[0], m_ptr, monster_type);

			/* Delete from this floor */
			delete_monster_idx(p_ptr->riding);
		}
	}

	/*
	 * If player is in wild mode, no pets are preserved
	 * except a monster whom player riding
	 */
	if (!p_ptr->wild_mode && !p_ptr->inside_arena && !p_ptr->inside_battle)
	{
		for (i = m_max - 1, num = 1; (i >= 1 && num < MAX_PARTY_MON); i--)
		{
			monster_type *m_ptr = &m_list[i];

			if (!m_ptr->r_idx) continue;
			if (!is_pet(m_ptr)) continue;
			if (i == p_ptr->riding) continue;

			if (reinit_wilderness)
			{
				/* Don't lose sight of pets when getting a Quest */
			}
			else
			{
				int dis = distance(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx);

				/* Confused (etc.) monsters don't follow. */
				if (MON_CONFUSED(m_ptr) || MON_STUNNED(m_ptr) || MON_CSLEEP(m_ptr)) continue;

				/* Pet of other pet don't follow. */
				if (m_ptr->parent_m_idx) continue;

				/*
				 * Pets with nickname will follow even from 3 blocks away
				 * when you or the pet can see the other.
				 */
				if (m_ptr->nickname && 
				    ((player_has_los_bold(m_ptr->fy, m_ptr->fx) && projectable(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx)) ||
				     (los(m_ptr->fy, m_ptr->fx, p_ptr->y, p_ptr->x) && projectable(m_ptr->fy, m_ptr->fx, p_ptr->y, p_ptr->x))))
				{
					if (dis > 3) continue;
				}
				else
				{
					if (dis > 1) continue;
				}
			}

			(void)COPY(&party_mon[num], &m_list[i], monster_type);

			num++;

			/* Delete from this floor */
			delete_monster_idx(i);
		}
	}

	if (record_named_pet)
	{
		for (i = m_max - 1; i >=1; i--)
		{
			monster_type *m_ptr = &m_list[i];
			char m_name[80];

			if (!m_ptr->r_idx) continue;
			if (!is_pet(m_ptr)) continue;
			if (!m_ptr->nickname) continue;
			if (p_ptr->riding == i) continue;

			monster_desc(m_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
			do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_MOVED, m_name);
		}
	}


	/* Pet of other pet may disappear. */
	for (i = m_max - 1; i >=1; i--)
	{
		monster_type *m_ptr = &m_list[i];

		/* Are there its parent? */
		if (m_ptr->parent_m_idx && !m_list[m_ptr->parent_m_idx].r_idx)
		{
			/* Its parent have gone, it also goes away. */

			if (is_seen(m_ptr))
			{
				char m_name[80];

				/* Acquire the monster name */
				monster_desc(m_name, m_ptr, 0);

#ifdef JP
				msg_format("%sは消え去った!", m_name);
#else
				msg_format("%^s disappears!", m_name);
#endif
			}

			/* Delete the monster */
			delete_monster_idx(i);
		}
	}
}
Exemplo n.º 30
0
/*!
 * @brief モンスターが敵対モンスターに直接ブレスを当てることが可能かを判定する /
 * Determine if a breath will hit the target.
 * @param y1 始点のY座標
 * @param x1 始点のX座標
 * @param y2 目標のY座標
 * @param x2 目標のX座標
 * @param rad 半径
 * @param typ 効果属性ID
 * @param is_friend TRUEならば、プレイヤーを巻き込む時にブレスの判定をFALSEにする。
 * @return ブレスを直接当てられるならばTRUEを返す
 */
static bool breath_direct(int y1, int x1, int y2, int x2, int rad, int typ, bool is_friend)
{
	/* Must be the same as projectable() */

	int i;

	/* Initial grid */
	int y = y1;
	int x = x1;

	int grid_n = 0;
	u16b grid_g[512];

	int grids = 0;
	byte gx[1024], gy[1024];
	byte gm[32];
	int gm_rad = rad;

	bool hit2 = FALSE;
	bool hityou = FALSE;

	int flg;

	switch (typ)
	{
	case GF_LITE:
	case GF_LITE_WEAK:
		flg = PROJECT_LOS;
		break;
	case GF_DISINTEGRATE:
		flg = PROJECT_DISI;
		break;
	default:
		flg = 0;
		break;
	}

	/* Check the projection path */
	grid_n = project_path(grid_g, MAX_RANGE, y1, x1, y2, x2, flg);

	/* Project along the path */
	for (i = 0; i < grid_n; ++i)
	{
		int ny = GRID_Y(grid_g[i]);
		int nx = GRID_X(grid_g[i]);

		if (flg & PROJECT_DISI)
		{
			/* Hack -- Balls explode before reaching walls */
			if (cave_stop_disintegration(ny, nx)) break;
		}
		else if (flg & PROJECT_LOS)
		{
			/* Hack -- Balls explode before reaching walls */
			if (!cave_los_bold(ny, nx)) break;
		}
		else
		{
			/* Hack -- Balls explode before reaching walls */
			if (!cave_have_flag_bold(ny, nx, FF_PROJECT)) break;
		}

		/* Save the "blast epicenter" */
		y = ny;
		x = nx;
	}

	grid_n = i;

	if (!grid_n)
	{
		if (flg & PROJECT_DISI)
		{
			if (in_disintegration_range(y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad)) hit2 = TRUE;
			if (in_disintegration_range(y1, x1, p_ptr->y, p_ptr->x) && (distance(y1, x1, p_ptr->y, p_ptr->x) <= rad)) hityou = TRUE;
		}
		else if (flg & PROJECT_LOS)
		{
			if (los(y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad)) hit2 = TRUE;
			if (los(y1, x1, p_ptr->y, p_ptr->x) && (distance(y1, x1, p_ptr->y, p_ptr->x) <= rad)) hityou = TRUE;
		}
		else
		{
			if (projectable(y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad)) hit2 = TRUE;
			if (projectable(y1, x1, p_ptr->y, p_ptr->x) && (distance(y1, x1, p_ptr->y, p_ptr->x) <= rad)) hityou = TRUE;
		}
	}
	else
	{
		breath_shape(grid_g, grid_n, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, y, x, typ);

		for (i = 0; i < grids; i++)
		{
			/* Extract the location */
			y = gy[i];
			x = gx[i];

			if ((y == y2) && (x == x2)) hit2 = TRUE;
			if (player_bold(y, x)) hityou = TRUE;
		}
	}

	if (!hit2) return FALSE;
	if (is_friend && hityou) return FALSE;

	return TRUE;
}