82#define MAX_RF_TARGETS 10
83#define MAX_RF_DATA 128
95#define RF_NO_ENTNUM -1
125 void add(
const Edict* shooter,
const Edict* target,
const int tusForShot);
173 for (
int j = 0; j < rfts->
count; j++) {
190 for (
int j = 0; j < rfts->
count; j++) {
194 const int tus = std::max(0, target->
TU - tusTarget - t.
triggerTUs);
207 for (
int j = 0; j < rfts->
count; j++) {
225 for (
int i = 0;
i < rfts->
count;
i++) {
258 gi.Error(
"Entity already has rfData");
268 gi.Error(
"Not enough rfData");
280 gi.DPrintf(
"Entity doesn't have rfData");
330 for (
int i = 0;
i < rfts->
count;
i++) {
336 if (
i != rfts->
count - 1) {
352 for (
int i = rfts->
count - 1;
i >= 0; --
i)
373 for (
int i = 0;
i < rfts->
count;
i++) {
398 for (
int i = 0;
i < rfts->
count;
i++) {
418 for (
int i = 0;
i < rfts->
count;
i++) {
447 rft.destroy(shooter);
485 if (fdArray ==
nullptr)
489 return &fdArray[fmIdx];
515 if (tus <= shooter->TU &&
rf.isInWeaponRange(shooter, target, fd)) {
691 if (shooter == target)
729 gi.DPrintf(
"Reaction fire enabled but no weapon for hand (name=%s,entnum=%i,hand=%i,fmIdx=%i)\n",
756 const float actorVis =
G_ActorVis(shooter, target,
true);
769 Actor* shooter =
nullptr;
778 rft.add(shooter, target, TUs);
780 rft.remove(shooter, target);
787 rft.resetTargetList(shooter);
801 const Item* weapon =
nullptr;
818 const int shotsPerFD = fdArray[firemode].
shots;
819 const int samples = std::max(1, 100 / shotsPerFD);
820 const Player& player = shooter->
getPlayer();
822 for (
int i = 0;
i < samples; ++
i)
827 const int maxShots = samples * shotsPerFD;
832 maxff = maxShots * 2 / 3;
834 maxff = maxShots / 3;
836 maxff = maxShots / 6;
838 maxff = maxShots / 20;
844 if (ff <= maxff && hits > 0)
864 rft.remove(shooter, target);
884 rft.notifyClientOnShot(target, tusTarget);
889 rft.notifyClientOnStep(target, step);
902 Actor* shooter =
nullptr;
911 if (!
rft.hasExpired(shooter, target, 0))
913 if (!
rf.tryToShoot(shooter, target)) {
917 rft.advance(shooter, tus);
928static void G_ReactionFirePrintSituation (
Edict* target)
935 Actor* shooter =
nullptr;
941 Com_sprintf(msgHdr,
sizeof(msgHdr),
"S%i: at %i/%i/%i RF: ", shooter->
number, shooter->
pos[0], shooter->
pos[1], shooter->
pos[2]);
942 int ttus =
rft.getTriggerTUs(shooter, target);
947 else if (
rft.hasExpired(shooter, target, 0))
965 G_ReactionFirePrintSituation(target);
967 rf.notifyClientOnStep(target, step);
970 const bool fired =
rf.checkExecution(target, step);
973 rf.updateAllTargets(target);
1000 rf.updateAllTargets(target);
1001 rf.notifyClientOnShot(target, fdTime);
1006 Actor* shooter =
nullptr;
1014 if (!
rft.hasExpired(shooter, target, fdTime))
1016 if (!
rf.tryToShoot(shooter, target)) {
1021 rft.advance(shooter, entTUs);
1033 rf.updateAllTargets(target);
1034 rf.resetTargets(target);
1045 rf.notifyClientOnShot(target, 0);
1068 Actor* actor =
nullptr;
1088 rft.notifyClientRFAborted(shooter, target, step);
bool isSameTeamAs(const Edict *other) const
Item * getRightHandItem() const
Item * getLeftHandItem() const
Player & getPlayer() const
Item * getHandItem(actorHands_t hand) const
void set(const actorHands_t hand, const fireDefIndex_t fmIdx, const objDef_t *weapon)
actorHands_t getHand() const
const objDef_t * getWeapon() const
bool isSaneFiremode() const
bool holdsReactionFireWeapon() const
Checks if there is a weapon in the hands that can be used for reaction fire.
item instance data, with linked list capability
const objDef_t * ammoDef(void) const
const fireDef_t * getFiredefs() const
Returns the firedefinitions for a given weapon/ammo.
const objDef_t * getReactionFireWeaponType() const
Checks whether this item is a reaction fire enabled weapon.
const fireDef_t * getFireDef(const Actor *shooter) const
Get the fireDef for the RF settings of the shooter.
void resetTargets(const Edict *shooter)
bool tryToShoot(Actor *shooter, const Edict *target)
Resolve the reaction fire for an entity, this checks that the entity can fire and then takes the shot...
void notifyClientOnStep(const Edict *target, int step)
void notifyClientOnShot(const Edict *target, int tusTarget)
bool isInWeaponRange(const Actor *shooter, const Edict *target, const fireDef_t *fd) const
bool canReact(Actor *shooter, const Edict *target) const
Check whether shooter can reaction fire at target at all.
bool isPossible(Actor *shooter, const Edict *target) const
bool isEnemy(const Actor *shooter, const Edict *target) const
Check whether we want to shoot at the target.
bool canSee(const Actor *shooter, const Edict *target) const
Check whether shooter can see his target well enough.
bool shoot(Actor *shooter, const pos3_t at, shoot_types_t type, fireDefIndex_t firemode)
Perform the reaction fire shot.
void updateAllTargets(const Edict *target)
Check whether 'target' has just triggered any new reaction fire.
bool checkExecution(const Edict *target, int step)
Check all entities to see whether target has caused reaction fire to resolve.
A single relation between a shooter and his target.
A list of relations between a shooter and all his targets.
ReactionFireTarget targets[MAX_RF_TARGETS]
A table with all the relations between all shooters and all their targets.
void create(const Edict *shooter)
Create a table of reaction fire targets for the given edict.
void advance(const Edict *shooter, const int tusShot)
Increase the triggertime for the next RF shot for all targets of the shooter (after a reaction fire).
void notifyClientOnShot(const Edict *target, int step)
void remove(const Edict *shooter, const Edict *target)
Remove a reaction fire target for the given shooter.
int getTriggerTUs(const Edict *shooter, const Edict *target)
Check if the given shooter is ready to reaction fire at the given target.
void resetTargetList(const Edict *shooter)
void notifyClientOnStep(const Edict *target, int step)
bool hasExpired(const Edict *shooter, const Edict *target, const int tusTarget)
Check if the given shooter is ready to reaction fire at the given target.
ReactionFireTargetList * find(const Edict *shooter)
Find the given edict's table of reaction fire targets.
ReactionFireTargetList rfData[MAX_RF_DATA]
void add(const Edict *shooter, const Edict *target, const int tusForShot)
Add a reaction fire target for the given shooter.
void destroy(const Edict *shooter)
Destroys the table of reaction fire targets for the given edict.
void notifyClientRFAborted(const Edict *shooter, const Edict *target, int step)
void reset()
Reset the target count in the reaction fire table for all entities.
void init()
Initialize the reaction fire table for all entities.
void notifyClientMove(const Edict *target, int step, bool startMove)
void Com_Printf(const char *const fmt,...)
void G_ActorReserveTUs(Edict *ent, int resReaction, int resShot, int resCrouch)
Reserves TUs for different actor actions.
int G_ActorGetTUForReactionFire(const Edict *ent)
Calculates the amount of TUs that are needed for the current selected reaction fire mode.
int G_ActorGetModifiedTimeForFiredef(const Edict *const ent, const fireDef_t *const fd, const bool reaction)
bool G_IsLivingActor(const Edict *ent)
Checks whether the given edict is a living actor.
void G_ClientStateChange(const Player &player, Actor *actor, int reqState, bool checkaction)
Changes the state of a player/soldier.
void G_ClientPrintf(const Player &player, int printLevel, const char *fmt,...)
playermask_t G_VisToPM(teammask_t teamMask)
Converts vis mask to player mask.
Interface for g_client.cpp.
bool G_ClientShoot(const Player &player, Actor *actor, const pos3_t at, shoot_types_t shootType, fireDefIndex_t firemode, shot_mock_t *mock, bool allowReaction, int z_align)
Setup for shooting, either real or mock.
All parts of the main game logic that are combat related.
Actor * G_EdictsGetNextLivingActorOfTeam(Actor *lastEnt, const int team)
Iterate through the living actor entities of the given team.
Actor * G_EdictsGetNextLivingActor(Actor *lastEnt)
Iterate through the living actor entities.
Edict * G_EdictsGetByNum(const int num)
Get an entity by it's number.
functions to handle the storage and lifecycle of all edicts in the game module.
void G_EventReactionFireChange(const Edict &ent)
void G_EventReactionFireRemoveTarget(const Edict &shooter, const Edict &target, int step)
void G_EventSendState(playermask_t playerMask, const Edict &ent)
void G_EventReactionFireTargetUpdate(const Edict &shooter, const Edict &target, int tus, int step)
void G_EventReactionFireAbortShot(const Edict &shooter, const Edict &target, int step)
void G_EventReactionFireAddTarget(const Edict &shooter, const Edict &target, int tus, int step)
#define G_IsVisibleForTeam(ent, team)
#define G_IsCivilian(ent)
bool G_MatchIsRunning(void)
Checks whether the game is running (active team and no intermission time).
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 ...
static bool G_ReactionFireCanBeEnabled(const Edict *ent)
Checks whether the actor is allowed to activate reaction fire and will informs the player about the r...
void G_ReactionFireTargetsInit(void)
free function to initialize the reaction fire table for all entities.
bool G_ReactionFireOnMovement(Actor *target, int step)
Called when 'target' moves, possibly triggering or resolving reaction fire.
void G_ReactionFireNotifyClientEndMove(const Actor *target)
void G_ReactionFireTargetsCreate(const Edict *shooter)
free function to create a table of reaction fire targets for the given edict.
void G_ReactionFireNotifyClientRFAborted(const Actor *shooter, const Edict *target, int step)
static int G_ReactionFireGetTUsForItem(const Actor *shooter, const Edict *target)
Get the weapon firing TUs of the item in the hand of the shooter.
void G_ReactionFireNotifyClientStartMove(const Actor *target)
static bool G_ActorHasEnoughTUsReactionFire(const Edict *ent)
Checks whether an actor has enough TUs left to activate reaction fire.
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.
void G_ReactionFireOnEndTurn(void)
Called at the end of turn, all outstanding reaction fire is resolved.
void G_ReactionFireTargetsDestroy(const Edict *shooter)
free function to destroy the table of reaction fire targets for the given edict.
static bool G_ActorHasWorkingFireModeSet(const Edict *actor)
Checks if the currently selected firemode is usable with the defined weapon.
static void G_ReactionFireNotifyClientStartShot(const Edict *target)
static bool G_ReactionFireSettingsSetDefault(Edict *ent)
static ReactionFireTargets rft
void G_ReactionFirePostShot(Actor *target)
Called after 'target' has fired, this might trigger more reaction fire or resolve outstanding reactio...
static void G_ReactionFireNotifyClientEndShot(const Edict *target)
void G_ReactionFireReset(int team)
Guess! Reset all "shaken" states on end of turn?
bool G_ReactionFireSettingsReserveTUs(Actor *ent)
Set the reaction fire TU reservation for an actor.
void G_ReactionFireOnDead(const Actor *target)
Removes the given target from the reaction fire lists.
bool G_FrustumVis(const Edict *from, const vec3_t point)
Checks whether a point is "visible" from the edicts position.
int G_VisCheckDist(const Edict *const ent)
float G_ActorVis(const Edict *ent, const Edict *check, bool full)
calculate how much check is "visible" by ent
float frand(void)
Return random values between 0 and 1.
#define IS_SHOT_RIGHT(x)
Determine whether the selected shoot type is for the item in the right hand, either shooting or react...
#define ST_RIGHT_REACTION
The right hand reaction fire should be used for shooting.
#define ST_LEFT_REACTION
The left hand reaction fire should be used for shooting.
#define ST_NUM_SHOOT_TYPES
Amount of shoottypes available.
int32_t shoot_types_t
Available shoot types - also see the ST_ constants.
QGL_EXTERN GLsizei const GLvoid * data
QGL_EXTERN GLint GLenum type
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
chrReservations_t reservedTus
const teamDef_t * teamDef
How many TUs (and of what type) did a player reserve for a unit?
this is a fire definition for our weapons/ammo
const struct objDef_s * obj
weaponFireDefIndex_t weapFdsIdx
Defines all attributes of objects used in the inventory.
used in shot probability calculations (pseudo shots)
const objDef_t * onlyWeapon
#define VectorDistSqr(a, b)