Beispiel #1
0
/**
 * @brief Called when 'target' is about to shoot, this forces a 'draw' to decide who gets the first shot
 * @param[in] target The entity about to shoot
 * @param[in] fdTime The TU of the shot
 * @sa G_ClientShoot
 */
void G_ReactionFirePreShot (const Actor* target, const int fdTime)
{
	bool repeat = true;

	/* Check to see whether this triggers any reaction fire */
	G_ReactionFireNotifyClientStartShot(target);
	rf.updateAllTargets(target);
	rf.notifyClientOnShot(target, fdTime);

	/* if any reaction fire occurs, we have to loop through all entities again to allow
	 * multiple (fast) RF snap shots before a (slow) aimed shot from the target occurs. */
	while (repeat) {
		Actor* shooter = nullptr;
		repeat = false;
		/* check all ents to see who wins and who loses a draw */
		while ((shooter = G_EdictsGetNextLivingActor(shooter))) {
			const int entTUs = G_ReactionFireGetTUsForItem(shooter, target);
			/* indicates an RF weapon is there */
			if (entTUs <= 1)
				continue;
			if (!rft.hasExpired(shooter, target, fdTime))
				continue;
			if (!rf.tryToShoot(shooter, target)) {
				G_ReactionFireNotifyClientRFAborted(shooter, target, MAX_ROUTE);
				continue;
			}
			repeat = true;
			rft.advance(shooter, fdTime);
		}
	}
}
Beispiel #2
0
/**
 * @brief Prints some reaction fire data to the console
 * @param[in] target The target entity
 */
static void G_ReactionFirePrintSituation (Edict* target)
{
	if (!G_IsAlien(target))
		return;

	Com_Printf("Alien %i at %i/%i/%i TU:%i\n", target->number, target->pos[0], target->pos[1], target->pos[2], target->TU);

	Actor* shooter = nullptr;
	/* check all possible shooters */
	while ((shooter = G_EdictsGetNextLivingActor(shooter))) {
		if (G_IsAlien(shooter) || G_IsCivilian(shooter))
			continue;
		char msgHdr[100];
		Com_sprintf(msgHdr, sizeof(msgHdr), "S%i: at %i/%i/%i RF: ", shooter->number, shooter->pos[0], shooter->pos[1], shooter->pos[2]);
		int ttus = rft.getTriggerTUs(shooter, target);
		if (ttus == -2)
			Com_Printf("%s not initialized\n", msgHdr);
		if (ttus == -1)
			Com_Printf("%s not aiming\n", msgHdr);
		else if (rft.hasExpired(shooter, target, 0))
			Com_Printf("expired\n", msgHdr);
		else
			Com_Printf("%s not yet: %i\n", msgHdr, ttus);
	}
}
Beispiel #3
0
/**
 * @brief Called when 'target' is about to shoot, this forces a 'draw' to decide who gets the first shot
 * @param[in] target The entity about to shoot
 * @param[in] fdTime The TU of the shot
 * @sa G_ClientShoot
 */
void G_ReactionFirePreShot (const Edict *target, const int fdTime)
{
	bool repeat = true;

	/* Check to see whether this triggers any reaction fire */
	G_ReactionFireTargetsUpdateAll(target);

	/* if any reaction fire occurs, we have to loop through all entities again to allow
	 * multiple (fast) RF snap shots before a (slow) aimed shot from the target occurs. */
	while (repeat) {
		Edict *shooter = nullptr;
		repeat = false;
		/* check all ents to see who wins and who loses a draw */
		while ((shooter = G_EdictsGetNextLivingActor(shooter))) {
			const int entTUs = G_ReactionFireGetTUsForItem(shooter, target);
			if (entTUs > 1) {	/* indicates an RF weapon is there */
				if (rft.hasExpired(shooter, target, fdTime)) {
					if (G_ReactionFireTryToShoot(shooter, target)) {
						repeat = true;
						rft.advance(shooter, fdTime);
					}
				}
			}
		}
	}
}
Beispiel #4
0
/**
 * @brief Check all entities to see whether target has caused reaction fire to resolve.
 * @param[in] target The entity that might be resolving reaction fire
 * @returns whether any entity fired (or would fire) upon target
 * @sa G_ReactionFireOnMovement
 * @sa G_ReactionFirePostShot
 */
static bool G_ReactionFireCheckExecution (const Edict *target)
{
	Edict *shooter = nullptr;
	bool fired = false;

	/* check all possible shooters */
	while ((shooter = G_EdictsGetNextLivingActor(shooter))) {
		const int tus = G_ReactionFireGetTUsForItem(shooter, target);
		if (tus > 1) {	/* indicates an RF weapon is there */
			if (rft.hasExpired(shooter, target, 0)) {
				if (G_ReactionFireTryToShoot(shooter, target)) {
					rft.advance(shooter, tus);
					fired |= true;
				}
			}
		}
	}
	return fired;
}
Beispiel #5
0
/**
 * @brief Check all entities to see whether target has caused reaction fire to resolve.
 * @param[in] target The entity that might be resolving reaction fire
 * @param[in] step The number of the step in the move we are checking reactions for
 * @returns whether any entity fired (or would fire) upon target
 * @sa G_ReactionFireOnMovement
 * @sa G_ReactionFirePostShot
 */
bool ReactionFire::checkExecution (const Edict* target, int step)
{
	Actor* shooter = nullptr;
	bool fired = false;

	/* check all possible shooters */
	while ((shooter = G_EdictsGetNextLivingActor(shooter))) {
		const int tus = G_ReactionFireGetTUsForItem(shooter, target);
		/* indicates an RF weapon is there */
		if (tus <= 1)
			continue;
		if (!rft.hasExpired(shooter, target, 0))
			continue;
		if (!rf.tryToShoot(shooter, target)) {
			G_ReactionFireNotifyClientRFAborted(shooter, target, step);
			continue;
		}
		rft.advance(shooter, tus);
		fired |= true;
	}
	return fired;
}