コード例 #1
0
ファイル: gen-util.c プロジェクト: datatypevoid/angband
/**
 * Allocates a single random object in the dungeon.
 * \param c the current chunk
 * \param set where the entity is placed (corridor, room or either)
 * \param typ what is placed (rubble, trap, gold, item)
 * \param depth generation depth
 * \param origin item origin (if appropriate)
 *
 * 'set' controls where the object is placed (corridor, room, either).
 * 'typ' conrols the kind of object (rubble, trap, gold, item).
 */
bool alloc_object(struct chunk *c, int set, int typ, int depth, byte origin)
{
    int x = 0, y = 0;
    int tries = 0;

    /* Pick a "legal" spot */
    while (tries < 2000) {
		tries++;

		find_empty(c, &y, &x);

		/* If we are ok with a corridor and we're in one, we're done */
		if (set & SET_CORR && !square_isroom(c, y, x)) break;

		/* If we are ok with a room and we're in one, we're done */
		if (set & SET_ROOM && square_isroom(c, y, x)) break;
    }

    if (tries == 2000) return false;

    /* Place something */
    switch (typ) {
    case TYP_RUBBLE: place_rubble(c, y, x); break;
    case TYP_TRAP: place_trap(c, y, x, -1, depth); break;
    case TYP_GOLD: place_gold(c, y, x, depth, origin); break;
    case TYP_OBJECT: place_object(c, y, x, depth, false, false, origin, 0); break;
    case TYP_GOOD: place_object(c, y, x, depth, true, false, origin, 0); break;
    case TYP_GREAT: place_object(c, y, x, depth, true, true, origin, 0); break;
    }
    return true;
}
コード例 #2
0
ファイル: cave-map.c プロジェクト: pnd10/angband
/*
 * Aux function -- see below
 */
static void cave_room_aux(struct point_set *seen, int y, int x)
{
	if (point_set_contains(seen, y, x))
		return;

	if (!square_isroom(cave, y, x))
		return;

	/* Add it to the "seen" set */
	add_to_point_set(seen, y, x);
}
コード例 #3
0
ファイル: mon-move.c プロジェクト: BardurArantsson/angband
/**
 * Choose "logical" directions for monster movement
 */
static bool get_moves(struct chunk *c, struct monster *mon, int *dir)
{
	int py = player->py;
	int px = player->px;

	int y, x;

	/* Monsters will run up to z_info->flee_range grids out of sight */
	int flee_range = z_info->max_sight + z_info->flee_range;

	bool done = false;

	/* Calculate range */
	find_range(mon);

	/* Flow towards the player */
	if (get_moves_flow(c, mon)) {
		/* Extract the "pseudo-direction" */
		y = mon->ty - mon->fy;
		x = mon->tx - mon->fx;
	} else {
		/* Head straight for the player */
		y = player->py - mon->fy;
		x = player->px - mon->fx;
	}

	/* Normal animal packs try to get the player out of corridors. */
	if (rf_has(mon->race->flags, RF_GROUP_AI) &&
	    !flags_test(mon->race->flags, RF_SIZE, RF_PASS_WALL, RF_KILL_WALL,
					FLAG_END)) {
		int i, open = 0;

		/* Count empty grids next to player */
		for (i = 0; i < 8; i++) {
			int ry = py + ddy_ddd[i];
			int rx = px + ddx_ddd[i];
			/* Check grid around the player for room interior (room walls count)
			 * or other empty space */
			if (square_ispassable(c, ry, rx) || square_isroom(c, ry, rx)) {
				/* One more open grid */
				open++;
			}
		}

		/* Not in an empty space and strong player */
		if ((open < 7) && (player->chp > player->mhp / 2)) {
			/* Find hiding place */
			if (find_hiding(c, mon)) {
				done = true;
				y = mon->ty - mon->fy;
				x = mon->tx - mon->fx;
			}
		}
	}

	/* Apply fear */
	if (!done && (mon->min_range == flee_range)) {
		/* Try to find safe place */
		if (!find_safety(c, mon)) {
			/* Just leg it away from the player */
			y = (-y);
			x = (-x);
		} else {
			/* Set a course for the safe place */
			get_moves_fear(c, mon);
			y = mon->ty - mon->fy;
			x = mon->tx - mon->fx;
		}

		done = true;
	}

	/* Monster groups try to surround the player */
	if (!done && rf_has(mon->race->flags, RF_GROUP_AI)) {
		int i, yy = mon->ty, xx = mon->tx;

		/* If we are not already adjacent */
		if (mon->cdis > 1) {
			/* Find an empty square near the player to fill */
			int tmp = randint0(8);
			for (i = 0; i < 8; i++) {
				/* Pick squares near player (pseudo-randomly) */
				yy = py + ddy_ddd[(tmp + i) & 7];
				xx = px + ddx_ddd[(tmp + i) & 7];

				/* Ignore filled grids */
				if (!square_isempty(cave, yy, xx)) continue;

				/* Try to fill this hole */
				break;
			}
		}

		/* Extract the new "pseudo-direction" */
		y = yy - mon->fy;
		x = xx - mon->fx;
	}

	/* Check for no move */
	if (!x && !y) return (false);

	/* Pick the correct direction */
	*dir = choose_direction(y, x);

	/* Want to move */
	return (true);
}
コード例 #4
0
ファイル: mon-move.c プロジェクト: magnate/angband
/**
 * Choose "logical" directions for monster movement
 */
static bool get_move(struct chunk *c, struct monster *mon, int *dir, bool *good)
{
	struct loc decoy = cave_find_decoy(c);
	struct loc target = (decoy.y && decoy.x) ? decoy :
		loc(player->px, player->py);

	int y, x;

	/* Monsters will run up to z_info->flee_range grids out of sight */
	int flee_range = z_info->max_sight + z_info->flee_range;

	bool done = false;

	/* Calculate range */
	get_move_find_range(mon);

	/* Assume we're heading towards the player */
	if (get_move_advance(c, mon)) {
		/* Extract the "pseudo-direction" */
		y = mon->target.grid.y - mon->fy;
		x = mon->target.grid.x - mon->fx;
		*good = true;
	} else {
		/* Head blindly straight for the "player" if there's no better idea */
		y = target.y - mon->fy;
		x = target.x - mon->fx;
	}

	/* Normal animal packs try to get the player out of corridors. */
	if (rf_has(mon->race->flags, RF_GROUP_AI) &&
	    !flags_test(mon->race->flags, RF_SIZE, RF_PASS_WALL, RF_KILL_WALL,
					FLAG_END)) {
		int i, open = 0;

		/* Count empty grids next to player */
		for (i = 0; i < 8; i++) {
			int ry = target.y + ddy_ddd[i];
			int rx = target.x + ddx_ddd[i];
			/* Check grid around the player for room interior (room walls count)
			 * or other empty space */
			if (square_ispassable(c, ry, rx) || square_isroom(c, ry, rx)) {
				/* One more open grid */
				open++;
			}
		}

		/* Not in an empty space and strong player */
		if ((open < 5) && (player->chp > player->mhp / 2)) {
			/* Find hiding place */
			if (get_move_find_hiding(c, mon)) {
				done = true;
				y = mon->target.grid.y - mon->fy;
				x = mon->target.grid.x - mon->fx;
			}
		}
	}

	/* Apply fear */
	if (!done && (mon->min_range == flee_range)) {
		/* Try to find safe place */
		if (!get_move_find_safety(c, mon)) {
			/* Just leg it away from the player */
			y = (-y);
			x = (-x);
		} else {
			/* Set a course for the safe place */
			get_move_flee(c, mon);
			y = mon->target.grid.y - mon->fy;
			x = mon->target.grid.x - mon->fx;
		}

		done = true;
	}

	/* Monster groups try to surround the player */
	if (!done && rf_has(mon->race->flags, RF_GROUP_AI) &&
		square_isview(c, mon->fy, mon->fx)) {
		int i, yy = mon->target.grid.y, xx = mon->target.grid.x;

		/* If we are not already adjacent */
		if (mon->cdis > 1) {
			/* Find an empty square near the player to fill */
			int tmp = randint0(8);
			for (i = 0; i < 8; i++) {
				/* Pick squares near player (pseudo-randomly) */
				yy = target.y + ddy_ddd[(tmp + i) & 7];
				xx = target.x + ddx_ddd[(tmp + i) & 7];

				/* Ignore filled grids */
				if (!square_isempty(c, yy, xx)) continue;

				/* Try to fill this hole */
				break;
			}
		}

		/* Extract the new "pseudo-direction" */
		y = yy - mon->fy;
		x = xx - mon->fx;
	}

	/* Check if the monster has already reached its target */
	if (!x && !y) return (false);

	/* Pick the correct direction */
	*dir = get_move_choose_direction(y, x);

	/* Want to move */
	return (true);
}