UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
g_reaction.cpp File Reference

Reaction fire code. More...

#include "g_reaction.h"
#include "g_actor.h"
#include "g_client.h"
#include "g_combat.h"
#include "g_edicts.h"
#include "g_match.h"
#include "g_vis.h"

Go to the source code of this file.

Data Structures

class  ReactionFireTarget
 A single relation between a shooter and his target. More...
 
class  ReactionFireTargetList
 A list of relations between a shooter and all his targets. More...
 
class  ReactionFireTargets
 A table with all the relations between all shooters and all their targets. More...
 
class  ReactionFire
 

Macros

#define MAX_RF_TARGETS   10
 
#define MAX_RF_DATA   128
 
#define DEBUG_RF   0
 
#define RF_NO_ENTNUM   -1
 

Functions

void G_ReactionFireTargetsInit (void)
 free function to initialize the reaction fire table for all entities. More...
 
void G_ReactionFireTargetsCreate (const Edict *shooter)
 free function to create a table of reaction fire targets for the given edict. More...
 
void G_ReactionFireTargetsDestroy (const Edict *shooter)
 free function to destroy the table of reaction fire targets for the given edict. More...
 
static int G_ReactionFireGetTUsForItem (const Actor *shooter, const Edict *target)
 Get the weapon firing TUs of the item in the hand of the shooter. More...
 
static bool G_ActorHasWorkingFireModeSet (const Edict *actor)
 Checks if the currently selected firemode is usable with the defined weapon. More...
 
void G_ReactionFireSettingsUpdate (Actor *actor, fireDefIndex_t fmIdx, actorHands_t hand, const objDef_t *od)
 Updates the reaction fire settings in case something was moved into a hand or from a hand that would make the current settings invalid. More...
 
static bool G_ActorHasEnoughTUsReactionFire (const Edict *ent)
 Checks whether an actor has enough TUs left to activate reaction fire. More...
 
static bool G_ReactionFireSettingsSetDefault (Edict *ent)
 
static bool G_ReactionFireCanBeEnabled (const Edict *ent)
 Checks whether the actor is allowed to activate reaction fire and will informs the player about the reason if this would not work. More...
 
bool G_ReactionFireSettingsReserveTUs (Actor *ent)
 Set the reaction fire TU reservation for an actor. More...
 
bool G_ReactionFireOnMovement (Actor *target, int step)
 Called when 'target' moves, possibly triggering or resolving reaction fire. More...
 
static void G_ReactionFireNotifyClientStartShot (const Edict *target)
 
static void G_ReactionFireNotifyClientEndShot (const Edict *target)
 
void G_ReactionFirePreShot (const Actor *target, const int fdTime)
 Called when 'target' is about to shoot, this forces a 'draw' to decide who gets the first shot. More...
 
void G_ReactionFireOnDead (const Actor *target)
 Removes the given target from the reaction fire lists. More...
 
void G_ReactionFirePostShot (Actor *target)
 Called after 'target' has fired, this might trigger more reaction fire or resolve outstanding reaction fire (because target is out of time) More...
 
void G_ReactionFireOnEndTurn (void)
 Called at the end of turn, all outstanding reaction fire is resolved. More...
 
void G_ReactionFireReset (int team)
 Guess! Reset all "shaken" states on end of turn? More...
 
void G_ReactionFireNotifyClientStartMove (const Actor *target)
 
void G_ReactionFireNotifyClientEndMove (const Actor *target)
 
void G_ReactionFireNotifyClientRFAborted (const Actor *shooter, const Edict *target, int step)
 

Variables

static ReactionFireTargets rft
 
static ReactionFire rf
 

Detailed Description

Reaction fire code.

Note that in a turn-based game, reaction fire is a design bug in the first place, causing several logic problems. But we want it and we need it, so we'll have to work around those problems.

Imagine the following situations: One of your soldiers is standing next to a house by a street. There is an alien down the street with a gun in snap shot mode (8 TUs). The soldier steps out on street, trying to cross it (and entering the line of sight of that alien). After 4 more paces or spending 8 TUs, your soldier is shot by the alien. Sounds reasonable? Fine. That's the basic idea of reaction fire.

Now assume you have 5 soldiers next to that house. They all step out on the street. Nothing happens because they all just entered the line of sight of the alien. The first soldier starts walking and gets shot after 4 paces like above. The second soldier will walk 7 paces unharmed and get shot after 8 paces and the third soldier will be shot after 12 paces/24 TUs. This is because when the alien shoots at one target, all his other targets will receive a bonus equal to the amount of TUs the alien used for his shot. Still sounds reasonable? Fine.

A slight modification: only one of the 5 soldiers steps out and gets shot after 4 paces. Then the 2nd steps out and gets shot after 4 paces as well. Likewise the 3rd soldier. That's because the soldiers hidden behind the house are not among the targets of the alien and thus don't receive the bonus when the alien shoots,

There is also a problem at end of turn. Imagine your sniper is set to react with an aimed shot (18 Tus). An alien steps into his line of sight and fires two snap shots, totaling 16 TUs. Then the alien decides to do nothing for the rest of his round. You would love to see your sniper do his aimed shot, right ? But reaction fire rules don't allow that. On the other hand: if you (were stupid enough to) move one of your soldiers with his last 2 TUs out from cover and into the sight of an alien on RF with all his TUs still available, your soldier will receive no RF, due to the same RF rules. You love that, right ?

Reaction fire is involved in the following situations:

  1. G_ReactionFireOnMovement() calls G_ReactionFireCheckExecution() calls G_ReactionFireTryToShoot() calls G_ReactionFireTargetsUpdateAll()
  2. G_ClientShoot() calls G_ReactionFirePreShot() calls G_ReactionFireTargetsUpdateAll() calls G_ReactionFireTryToShoot() calls G_ReactionFirePostShot() calls G_ReactionFireCheckExecution() calls G_ReactionFireTryToShoot()
  3. G_ClientEndRound() calls G_ReactionFireOnEndTurn() calls G_ReactionFireTryToShoot() calls G_ReactionFireReset()

Definition in file g_reaction.cpp.

Macro Definition Documentation

#define DEBUG_RF   0

Definition at line 85 of file g_reaction.cpp.

#define MAX_RF_TARGETS   10

Definition at line 82 of file g_reaction.cpp.

Referenced by ReactionFireTargets::add().

Function Documentation

static bool G_ActorHasEnoughTUsReactionFire ( const Edict ent)
static

Checks whether an actor has enough TUs left to activate reaction fire.

Parameters
[in]entThe actors edict to check for TUs for
Returns
true if the given actor has enough TUs left to activate reaction fire, false otherwise.

Definition at line 580 of file g_reaction.cpp.

References Edict::chr, chrReservations_s::crouch, G_ActorGetTUForReactionFire(), character_s::reservedTus, chrReservations_s::shot, and Edict::TU.

Referenced by G_ReactionFireCanBeEnabled().

static bool G_ActorHasWorkingFireModeSet ( const Edict actor)
static
static bool G_ReactionFireCanBeEnabled ( const Edict ent)
static

Checks whether the actor is allowed to activate reaction fire and will informs the player about the reason if this would not work.

Parameters
[in]entThe actor to check
Returns
true if the actor is allowed to activate it, false otherwise

Definition at line 628 of file g_reaction.cpp.

References _, level_locals_s::activeTeam, Edict::chr, G_ActorHasEnoughTUsReactionFire(), G_ActorHasWorkingFireModeSet(), G_ClientPrintf(), G_IsLivingActor(), G_MatchIsRunning(), Edict::getPlayer(), Edict::getTeam(), Inventory::holdsReactionFireWeapon(), Edict::inuse, character_s::inv, level, teamDef_s::onlyWeapon, PRINT_HUD, character_s::teamDef, and teamDef_s::weapons.

Referenced by G_ReactionFireSettingsReserveTUs().

static int G_ReactionFireGetTUsForItem ( const Actor shooter,
const Edict target 
)
static

Get the weapon firing TUs of the item in the hand of the shooter.

Returns
-1 if no firedef was found for the item or the reaction fire mode is not activated.
Parameters
[in]shooterThe reaction firing actor
[in]targetThe target to check reaction fire for (e.g. check whether the weapon that was marked for using in reaction fire situations can handle the distance between the shooter and the target)

Definition at line 507 of file g_reaction.cpp.

References G_ActorGetModifiedTimeForFiredef(), ReactionFire::getFireDef(), and ReactionFire::isInWeaponRange().

Referenced by ReactionFire::checkExecution(), G_ReactionFirePreShot(), and ReactionFire::updateAllTargets().

void G_ReactionFireNotifyClientEndMove ( const Actor target)
static void G_ReactionFireNotifyClientEndShot ( const Edict target)
static

Definition at line 983 of file g_reaction.cpp.

References MAX_ROUTE, and ReactionFireTargets::notifyClientMove().

Referenced by G_ReactionFirePostShot().

void G_ReactionFireNotifyClientRFAborted ( const Actor shooter,
const Edict target,
int  step 
)
void G_ReactionFireNotifyClientStartMove ( const Actor target)

Definition at line 1075 of file g_reaction.cpp.

References MAX_ROUTE, and ReactionFireTargets::notifyClientMove().

Referenced by G_ClientMove().

static void G_ReactionFireNotifyClientStartShot ( const Edict target)
static

Definition at line 978 of file g_reaction.cpp.

References MAX_ROUTE, and ReactionFireTargets::notifyClientMove().

Referenced by G_ReactionFirePreShot().

void G_ReactionFireOnDead ( const Actor target)

Removes the given target from the reaction fire lists.

Parameters
[in]targetThe target to remove from the lists

Definition at line 1030 of file g_reaction.cpp.

References G_IsDead, ReactionFire::resetTargets(), and ReactionFire::updateAllTargets().

Referenced by G_ActorDieOrStun().

void G_ReactionFireOnEndTurn ( void  )

Called at the end of turn, all outstanding reaction fire is resolved.

See also
G_ClientEndRound

Definition at line 1054 of file g_reaction.cpp.

References ReactionFireTargets::reset().

Referenced by G_ClientEndRound().

bool G_ReactionFireOnMovement ( Actor target,
int  step 
)

Called when 'target' moves, possibly triggering or resolving reaction fire.

Parameters
[in]targetThe target entity
[in]stepThe number of the step in the move we are checking reactions for
Returns
true If any shots were (or would be) taken
See also
G_ClientMove

Definition at line 962 of file g_reaction.cpp.

References ReactionFire::checkExecution(), ReactionFire::notifyClientOnStep(), and ReactionFire::updateAllTargets().

Referenced by G_ClientMove().

void G_ReactionFirePostShot ( Actor target)

Called after 'target' has fired, this might trigger more reaction fire or resolve outstanding reaction fire (because target is out of time)

Parameters
[in]targetThe entity that has just fired
See also
G_ClientShoot

Definition at line 1042 of file g_reaction.cpp.

References ReactionFire::checkExecution(), G_ReactionFireNotifyClientEndShot(), MAX_ROUTE, and ReactionFire::notifyClientOnShot().

Referenced by G_ClientShoot().

void G_ReactionFirePreShot ( const Actor target,
const int  fdTime 
)

Called when 'target' is about to shoot, this forces a 'draw' to decide who gets the first shot.

Parameters
[in]targetThe entity about to shoot
[in]fdTimeThe TU of the shot
See also
G_ClientShoot

Definition at line 994 of file g_reaction.cpp.

References ReactionFireTargets::advance(), G_EdictsGetNextLivingActor(), G_ReactionFireGetTUsForItem(), G_ReactionFireNotifyClientRFAborted(), G_ReactionFireNotifyClientStartShot(), ReactionFireTargets::hasExpired(), MAX_ROUTE, ReactionFire::notifyClientOnShot(), ReactionFire::tryToShoot(), and ReactionFire::updateAllTargets().

Referenced by G_ClientShoot().

void G_ReactionFireReset ( int  team)

Guess! Reset all "shaken" states on end of turn?

Note
Normally called on end of turn.
See also
G_ClientStateChange
Parameters
[in]teamIndex of team to loop through.

Definition at line 1066 of file g_reaction.cpp.

References G_EdictsGetNextLivingActorOfTeam(), and Actor::removeShaken().

Referenced by G_ClientEndRound().

bool G_ReactionFireSettingsReserveTUs ( Actor ent)

Set the reaction fire TU reservation for an actor.

Parameters
[in,out]entThe actor edict to set the TUs for
Returns
true if TUs for reaction fire were reserved, false if the reservation was set back to 0

Definition at line 665 of file g_reaction.cpp.

References Edict::chr, chrReservations_s::crouch, G_ActorGetTUForReactionFire(), G_ActorReserveTUs(), G_ReactionFireCanBeEnabled(), G_ReactionFireSettingsSetDefault(), character_s::reservedTus, and chrReservations_s::shot.

Referenced by G_ClientInitActorStates(), G_ClientStateChange(), and G_ReactionFireSettingsUpdate().

static bool G_ReactionFireSettingsSetDefault ( Edict ent)
static
Parameters
entThe actor to set the reaction fire for
Returns
true if the needed settings could have been made or settings are already valid, false otherwise.

Definition at line 592 of file g_reaction.cpp.

References ACTOR_HAND_LEFT, ACTOR_HAND_RIGHT, Edict::chr, G_ActorHasWorkingFireModeSet(), G_EventReactionFireChange(), G_IsAI, Edict::getHandItem(), Item::getReactionFireWeaponType(), character_s::RFmode, and FiremodeSettings::set().

Referenced by G_ReactionFireSettingsReserveTUs().

void G_ReactionFireSettingsUpdate ( Actor actor,
fireDefIndex_t  fmIdx,
actorHands_t  hand,
const objDef_t od 
)

Updates the reaction fire settings in case something was moved into a hand or from a hand that would make the current settings invalid.

Parameters
[in,out]actorThe actor edict to check the settings for
[in]fmIdxThe fire mode index that should be used for reaction fire
[in]handThe hand that should be used for reaction fire
[in]odThe object/weapon for the reaction fire

Definition at line 555 of file g_reaction.cpp.

References Edict::chr, G_ActorHasWorkingFireModeSet(), G_ClientStateChange(), G_EventReactionFireChange(), G_EventSendState(), G_ReactionFireSettingsReserveTUs(), G_VisToPM(), Edict::getPlayer(), Actor::isReaction(), character_s::RFmode, FiremodeSettings::set(), STATE_REACTION, and Edict::visflags.

Referenced by AI_TryToReloadWeapon(), G_ActorInvMove(), G_ClientAction(), G_ClientInitActorStates(), and G_ClientShoot().

void G_ReactionFireTargetsCreate ( const Edict shooter)

free function to create a table of reaction fire targets for the given edict.

Parameters
[in]shooterThe reaction firing actor

Definition at line 436 of file g_reaction.cpp.

References ReactionFireTargets::create().

Referenced by G_ClientGetFreeSpawnPointForActorSize().

void G_ReactionFireTargetsDestroy ( const Edict shooter)

free function to destroy the table of reaction fire targets for the given edict.

Parameters
[in]shooterThe reaction firing actor

Definition at line 445 of file g_reaction.cpp.

References ReactionFireTargets::destroy().

Referenced by G_ActorDieOrStun().

void G_ReactionFireTargetsInit ( void  )

free function to initialize the reaction fire table for all entities.

Definition at line 427 of file g_reaction.cpp.

References ReactionFireTargets::init().

Referenced by G_SpawnEntities().

Variable Documentation

ReactionFire rf
static

Definition at line 468 of file g_reaction.cpp.

ReactionFireTargets rft
static

Definition at line 144 of file g_reaction.cpp.