Пример #1
0
/**
 * Places a monster (of the specified "type") near the given
 * location.  Return true iff a monster was actually summoned.
 *
 * We will attempt to place the monster up to 10 times before giving up.
 *
 * Note: S_UNIQUE and S_WRAITH will summon Uniques
 * Note: S_ANY, S_HI_UNDEAD, S_HI_DEMON and S_HI_DRAGON may summon Uniques
 * Note: None of the other summon codes will ever summon Uniques.
 *
 * This function has been changed.  We now take the "monster level"
 * of the summoning monster as a parameter, and use that, along with
 * the current dungeon level, to help determine the level of the
 * desired monster.  Note that this is an upper bound, and also
 * tends to "prefer" monsters of that level.  Currently, we use
 * the average of the dungeon and monster levels, and then add
 * five to allow slight increases in monster power.
 *
 * Note that we use the new "monster allocation table" creation code
 * to restrict the "get_mon_num()" function to the set of "legal"
 * monsters, making this function much faster and more reliable.
 *
 * Note that this function may not succeed, though this is very rare.
 */
int summon_specific(int y1, int x1, int lev, int type, bool delay, bool call)
{
    int i, x = 0, y = 0;

    struct monster *mon;
    struct monster_race *race;

    /* Look for a location, allow up to 4 squares away */
    for (i = 0; i < 60; ++i) {
        /* Pick a distance */
        int d = (i / 15) + 1;

        /* Pick a location */
        scatter(cave, &y, &x, y1, x1, d, true);

        /* Require "empty" floor grid */
        if (!square_isempty(cave, y, x)) continue;

        /* Hack -- no summon on glyph of warding */
        if (square_iswarded(cave, y, x)) continue;

        /* Okay */
        break;
    }

    /* Failure */
    if (i == 60) return (0);

    /* Save the "summon" type */
    summon_specific_type = type;

    /* Use the new calling scheme if requested */
    if (call && (type != S_UNIQUE) && (type != S_WRAITH)) {
        return (call_monster(y, x));
    }

    /* Prepare allocation table */
    get_mon_num_prep(summon_specific_okay);

    /* Pick a monster, using the level calculation */
    race = get_mon_num((player->depth + lev) / 2 + 5);

    /* Prepare allocation table */
    get_mon_num_prep(NULL);

    /* Handle failure */
    if (!race) return (0);

    /* Attempt to place the monster (awake, don't allow groups) */
    if (!place_new_monster(cave, y, x, race, false, false, ORIGIN_DROP_SUMMON))
        return (0);

    /* Success, return the level of the monster */
    mon = square_monster(cave, y, x);

    /* If delay, try to let the player act before the summoned monsters,
     * including slowing down faster monsters for one turn */
    if (delay) {
        mon->energy = 0;
        if (mon->race->speed > player->state.speed)
            mon_inc_timed(mon, MON_TMD_SLOW, 1,
                          MON_TMD_FLG_NOMESSAGE, false);
    }

    return (mon->race->level);
}
Пример #2
0
/*
 * Build the wilderness area outside of the town.
 */
void wilderness_gen(void)
{
	int i, y, x;
	bool daytime;
	cave_type *c_ptr;


	/* Big town */
	cur_hgt = MAX_HGT;
	cur_wid = MAX_WID;

	/* Assume illegal panel */
	panel_row_min = cur_hgt;
	panel_col_min = cur_wid;

	/* Init the wilderness */
	process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);

	x = p_ptr->wilderness_x;
	y = p_ptr->wilderness_y;

	/* Prepare allocation table */
	get_mon_num_prep(get_monster_hook(), NULL);

	/* North border */
	generate_area(y - 1, x, TRUE, FALSE);

	for (i = 1; i < MAX_WID - 1; i++)
	{
		border.north[i] = cave[MAX_HGT - 2][i].feat;
	}

	/* South border */
	generate_area(y + 1, x, TRUE, FALSE);

	for (i = 1; i < MAX_WID - 1; i++)
	{
		border.south[i] = cave[1][i].feat;
	}

	/* West border */
	generate_area(y, x - 1, TRUE, FALSE);

	for (i = 1; i < MAX_HGT - 1; i++)
	{
		border.west[i] = cave[i][MAX_WID - 2].feat;
	}

	/* East border */
	generate_area(y, x + 1, TRUE, FALSE);


	for (i = 1; i < MAX_HGT - 1; i++)
	{
		border.east[i] = cave[i][1].feat;
	}

	/* North west corner */
	generate_area(y - 1, x - 1, FALSE, TRUE);
	border.north_west = cave[MAX_HGT - 2][MAX_WID - 2].feat;

	/* North east corner */
	generate_area(y - 1, x + 1, FALSE, TRUE);
	border.north_east = cave[MAX_HGT - 2][1].feat;

	/* South west corner */
	generate_area(y + 1, x - 1, FALSE, TRUE);
	border.south_west = cave[1][MAX_WID - 2].feat;

	/* South east corner */
	generate_area(y + 1, x + 1, FALSE, TRUE);
	border.south_east = cave[1][1].feat;


	/* Leaving the dungeon by stairs */
	/* (needed before the town is loaded) */
	if (p_ptr->leaving_dungeon)
	{
		p_ptr->oldpy = 0;
		p_ptr->oldpx = 0;
	}



	/* Create terrain of the current area */
	generate_area(y, x, FALSE, FALSE);

	/* Special boundary walls -- North */
	for (i = 0; i < MAX_WID; i++)
	{
		cave[0][i].feat = FEAT_PERM_SOLID;
		cave[0][i].mimic = border.north[i];
	}

	/* Special boundary walls -- South */
	for (i = 0; i < MAX_WID; i++)
	{
		cave[MAX_HGT - 1][i].feat = FEAT_PERM_SOLID;
		cave[MAX_HGT - 1][i].mimic = border.south[i];
	}

	/* Special boundary walls -- West */
	for (i = 0; i < MAX_HGT; i++)
	{
		cave[i][0].feat = FEAT_PERM_SOLID;
		cave[i][0].mimic = border.west[i];
	}

	/* Special boundary walls -- East */
	for (i = 0; i < MAX_HGT; i++)
	{
		cave[i][MAX_WID - 1].feat = FEAT_PERM_SOLID;
		cave[i][MAX_WID - 1].mimic = border.east[i];
	}

	/* North west corner */
	cave[0][0].mimic = border.north_west;

	/* North east corner */
	cave[0][MAX_WID - 1].mimic = border.north_east;

	/* South west corner */
	cave[MAX_HGT - 1][0].mimic = border.south_west;

	/* South east corner */
	cave[MAX_HGT - 1][MAX_WID - 1].mimic = border.south_east;


	/* Day time */
	if ((turn % (10L * TOWN_DAWN)) < ((10L * TOWN_DAWN) / 2))
		daytime = TRUE;
	else
		daytime = FALSE;

	/* Light up or darken the area */
	for (y = 0; y < cur_hgt; y++)
	{
		for (x = 0; x < cur_wid; x++)
		{
			/* Get the cave grid */
			c_ptr = &cave[y][x];

			if (daytime)
			{
				/* Assume lit */
				c_ptr->info |= (CAVE_GLOW);

				/* Hack -- Memorize lit grids if allowed */
				if (view_perma_grids) c_ptr->info |= (CAVE_MARK);
			}
			else
			{
				/* Darken "boring" features */
				if ((c_ptr->feat <= FEAT_INVIS) ||
				    ((c_ptr->feat >= FEAT_DEEP_WATER) &&
				    (c_ptr->feat <= FEAT_MOUNTAIN)) ||
				    (x == 0) || (x == cur_wid - 1) ||
				    (y == 0) || (y == cur_hgt - 1))
				{
					/* Forget the grid */
					c_ptr->info &= ~(CAVE_GLOW | CAVE_MARK);
				}
			}
		}
	}

	player_place(p_ptr->oldpy, p_ptr->oldpx);
	p_ptr->leaving_dungeon = FALSE;

	/* Make some residents */
	for (i = 0; i < MIN_M_ALLOC_TN; i++)
	{
		/* Make a resident */
		(void)alloc_monster(3, TRUE);
	}

	/* Set rewarded quests to finished */
	for (i = 0; i < max_quests; i++)
	{
		if (quest[i].status == QUEST_STATUS_REWARDED)
			quest[i].status = QUEST_STATUS_FINISHED;
	}
}