Esempio n. 1
0
/**
 * @brief test if @c check is visible by team (or if visibility changed?)
 * @sa G_CheckVisTeam
 * @param[in] team the team the edict may become visible for or perish from
 * their view
 * @param[in] check the edict we are talking about - which may become visible
 * or perish
 * @param[in] flags if you want to check whether the edict may also perish from
 * other players view, you should use the @c VT_PERISH bits
 * @note If the edict is already visible and flags doesn't contain the
 * bits of @c VT_PERISH, no further checks are performed - only the
 * @c VIS_YES bits are returned
 */
int G_TestVis (const int team, edict_t * check, int flags)
{
	edict_t *from = NULL;
	/* store old flag */
	const int old = G_IsVisibleForTeam(check, team) ? VIS_CHANGE : 0;

	if (g_aidebug->integer)
		return VIS_YES | !old;

	if (!(flags & VT_PERISH) && old)
		return VIS_YES;

	/* test if check is visible */
	while ((from = G_EdictsGetNextInUse(from)))
		if (G_Vis(team, from, check, flags))
			/* visible */
			return VIS_YES | !old;

	/* just return the old state */
	return old;
}
Esempio n. 2
0
/**
 * @brief test if @c check is visible by team (or if visibility changed?)
 * @sa G_CheckVisTeam
 * @param[in] team the team the edict may become visible for or perish from
 * their view
 * @param[in] check the edict we are talking about - which may become visible
 * or perish
 * @param[in] flags if you want to check whether the edict may also perish from
 * other players view, you should use the @c VT_PERISHCHK bits
 * @note If the edict is already visible and flags doesn't contain the
 * bits of @c VT_PERISHCHK, no further checks are performed - only the
 * @c VS_YES bits are returned
 * @return VS_CHANGE is added to the bit mask if the edict flipped its visibility
 * (invisible to visible or vice versa) VS_YES means the edict is visible for the
 * given team
 */
int G_TestVis (const int team, Edict* check, const vischeckflags_t flags)
{
	/* store old flag */
	const int old = G_IsVisibleForTeam(check, team) ? VS_CHANGE : 0;

	if (g_aidebug->integer)
		return VS_YES | !old;

	if (!(flags & VT_PERISHCHK) && old)
		return VS_YES;

	/* test if check is visible */
	Edict* from = nullptr;
	while ((from = G_EdictsGetNextInUse(from)))
		if (G_Vis(team, from, check, flags))
			/* visible */
			return VS_YES | !old;

	/* just return the old state */
	return old;
}
Esempio n. 3
0
/**
 * @brief Returns what the actor can see.
 */
static int AIL_see (lua_State *L)
{
	int vision, team;
	int i, j, k, n, cur;
	edict_t *check = NULL;
	aiActor_t target;
	edict_t *sorted[MAX_EDICTS], *unsorted[MAX_EDICTS];
	float distLookup[MAX_EDICTS];

	/* Defaults. */
	team = TEAM_ALL;
	vision = 0;

	/* Handle parameters. */
	if ((lua_gettop(L) > 0)) {
		/* Get what to "see" with. */
		if (lua_isstring(L, 1)) {
			const char *s = lua_tostring(L, 1);
			/** @todo Properly implement at edict level, get rid of magic numbers.
			 * These are only "placeholders". */
			if (Q_streq(s, "all"))
				vision = 0;
			else if (Q_streq(s, "sight"))
				vision = 1;
			else if (Q_streq(s, "psionic"))
				vision = 2;
			else if (Q_streq(s, "infrared"))
				vision = 3;
			else
				AIL_invalidparameter(1);
		} else
			AIL_invalidparameter(1);

		/* We now check for different teams. */
		if ((lua_gettop(L) > 1)) {
			if (lua_isstring(L, 2)) {
				const char *s = lua_tostring(L, 2);
				team = AIL_toTeamInt(s);
			} else
				AIL_invalidparameter(2);
		}
	}

	n = 0;
	/* Get visible things. */
	while ((check = G_EdictsGetNextLivingActor(check))) {
		if (AIL_ent == check)
			continue;
		if (vision == 0 && (team == TEAM_ALL || check->team == team) /* Check for team match if needed. */
		 && G_Vis(AIL_ent->team, AIL_ent, check, VT_NOFRUSTUM)) {
			distLookup[n] = VectorDistSqr(AIL_ent->pos, check->pos);
			unsorted[n++] = check;
		}
	}

	/* Sort by distance - nearest first. */
	for (i = 0; i < n; i++) { /* Until we fill sorted */
		cur = -1;
		for (j = 0; j < n; j++) { /* Check for closest */
			/* Is shorter then current minimum? */
			if (cur < 0 || distLookup[j] < distLookup[cur]) {
				/* Check if not already in sorted. */
				for (k = 0; k < i; k++)
					if (sorted[k] == unsorted[j])
						break;

				/* Not already sorted and is new minimum. */
				if (k == i)
					cur = j;
			}
		}

		sorted[i] = unsorted[cur];
	}

	/* Now save it in a Lua table. */
	lua_newtable(L);
	for (i = 0; i < n; i++) {
		lua_pushnumber(L, i + 1); /* index, starts with 1 */
		target.ent = sorted[i];
		lua_pushactor(L, &target); /* value */
		lua_rawset(L, -3); /* store the value in the table */
	}
	return 1; /* Returns the table of actors. */
}