38#define MAX_WALL_THICKNESS_FOR_SHOOTING_THROUGH 8
55 Actor* from =
nullptr;
100 Actor* actor =
nullptr;
118 if (attacker !=
nullptr && actor->
isSameTeamAs(attacker)) {
132 if (attacker !=
nullptr) {
153 else if (newMorale < 0)
177 Actor* check =
nullptr;
181 if (check == shooter)
194 if (dot / (len1 * len2) < 0.7f)
198 <= minDist * minDist)
259 if (!attacker || !target)
291 }
else if (target->
isDead()) {
306 if (!attacker || !target || !fd)
367 const short armourProtection = armourDef->
protection[dmgWeight];
368 const short totalProtection = armourProtection + naturalProtection;
369 damage = std::min(std::max(0, damage - armourProtection), std::max(1, damage - totalProtection));
371 damage = std::max(1, damage - naturalProtection);
393 const bool stunEl = (fd->
obj->dmgtype ==
gi.csi->damStunElectro);
394 const bool stunGas = (fd->
obj->dmgtype ==
gi.csi->damStunGas);
395 const bool shock = (fd->
obj->dmgtype ==
gi.csi->damShock);
396 const bool smoke = (fd->
obj->dmgtype ==
gi.csi->damSmoke);
401 if (stunEl || stunGas || shock || mock || smoke)
404 if (damage >= target->
HP) {
434 }
else if (damage < 0) {
458 }
else if (stunGas) {
486 if (!mock && damage > 0 && fd->
splrad)
502 target->
HP = std::min(std::max(target->
HP, 0), target->
chr.
maxHP);
504 if (target->
HP == 0 || target->
HP <= target->
getStun()) {
544 if (fd->
obj->dmgtype ==
gi.csi->damIncendiary || fd->
obj->dmgtype ==
gi.csi->damFire || fd->
obj->dmgtype ==
gi.csi->damBlast)
560 assert(fd->
splrad > 0.0f);
562 const bool shock = (fd->
obj->dmgtype ==
gi.csi->damShock);
564 Edict* check =
nullptr;
609 const int damage = shock ? 0 : fd->
spldmg[0] * (1.0f - dist / fd->
splrad);
614 if (
G_Damage(check, fd, damage, ent, mock,
nullptr) && isActor
628 VectorMA(impact, 1,
tr->plane.normal, impact);
641 if (floor ==
nullptr) {
652 if (actor !=
nullptr)
681 effSpread[
YAW] = fd->
spread[1] * commonfactor;
690#define GRENADE_DT 0.1f
691#define GRENADE_STOPSPEED 60.0f
720 target[2] -= z_align;
749 angles[
PITCH] += gauss1 * effSpread[0];
750 angles[
YAW] += gauss2 * effSpread[1];
769 if (
tr.fraction < 1.0f) {
786 if (
tr.fraction < 1.0f || time + dt > 4.0f) {
789 const float bounceFraction =
tr.surface ?
gi.GetBounceFraction(
tr.surface->name) : 1.0f;
796 if (
tr.fraction < 1.0f)
811 byte impactFlags = flags;
820 if (
tr.fraction > 1.0f)
823 tr.endpos[2] += 10.0f;
878 (
int)start[0], (
int)start[1], (
int)start[2],
879 (
int)
tr.endpos[0], (
int)
tr.endpos[1], (
int)
tr.endpos[2]);
881 tr.allsolid ?
"true" :
"false",
882 tr.startsolid ?
"true" :
"false",
883 tr.fraction,
tr.contentFlags);
886 trEnt ?
"yes" :
"no",
888 trEnt ? trEnt->
HP : 0);
894static void DumpAllEntities (
void)
897 Edict* check =
nullptr;
905 check->
inuse ?
"in use" :
"unused",
942 impact[2] -= z_align;
963 angles[
PITCH] += gauss1 * effSpread[0];
964 angles[
YAW] += gauss2 * effSpread[1];
972 float range = fd->
range;
985 const Edict* passEnt = ent;
1001 VectorMA(cur_loc, range, dir, impact);
1010 DumpTrace(tracefrom,
tr);
1021 if (
tr.fraction < 1.0f) {
1026 else if (bounce < fd->bounce)
1038 const bool firstShot = (
i == 0);
1039 G_EventShoot(*ent, mask, fd, firstShot, shootType, flags, &
tr, tracefrom, impact);
1052 if (
tr.fraction < 1.0f && !fd->
bounce) {
1060 damage /= sqrt(fd->
throughWall - throughWall + 1.0f);
1076 if (hitEnt || bounce > fd->
bounce ||
tr.fraction >= 1.0f) {
1096 G_Damage(trEnt, fd, damage, ent, mock, impact);
1105 if (
tr.fraction >= 1.0f && fd->
splrad > 0.0f) {
1112 range -=
tr.fraction * range;
1135 gi.Error(
"G_GetShotFromType: unknown shoot type %i.\n", shootType);
1157 if (fdArray ==
nullptr)
1162 assert(firemode >= 0);
1163 *fd = &fdArray[firemode];
1188 const bool quiet = (mock !=
nullptr) ||
G_IsAIPlayer(&player);
1190 Item* weapon =
nullptr;
1193 if (!
G_PrepareShot(actor, shootType, firemode, &weapon, &container, &fd)) {
1194 if (!weapon && !quiet)
1203 if (allowReaction) {
1214 const Actor* targetEnt =
nullptr;
1274 int shots = fd->
shots;
1284 if (ammo < fd->ammo) {
1298 const int prevDir = mock ? actor->
dir : 0;
1313 target[2] -= z_align;
1324 if (allowReaction) {
1331 if (targetEnt !=
nullptr && (targetEnt->
isDead() && !targetEnt->
isStunned()))
1341 bool itemAlreadyRemoved =
false;
1344 if (ammo > 0 || !weapon->
def()->
thrown) {
1350 itemAlreadyRemoved =
true;
1360 if (itemAlreadyRemoved)
1361 gi.Error(
"Item %s is already removed", weapon->
def()->
id);
1376 for (
int i = 0;
i < shots; ++
i) {
1378 G_ShootGrenade(player, actor, fd, shotOrigin, at, mask, weapon, mock, z_align, impact);
1380 G_ShootSingle(actor, fd, shotOrigin, at, mask, weapon, mock, z_align,
i, shootType, impact);
1387 const bool smoke = fd->
obj->dmgtype ==
gi.csi->damSmoke;
1388 const bool incendiary = fd->
obj->dmgtype ==
gi.csi->damIncendiary;
1389 const bool stunGas = fd->
obj->dmgtype ==
gi.csi->damStunGas;
1391 if (
gi.isOnMap(impact)) {
1394 const int rounds = std::max(2, fd->
rounds);
1396 }
else if (incendiary) {
1398 const int rounds = std::max(2, fd->
rounds);
1400 }
else if (stunGas) {
1402 const int rounds = std::max(2, fd->
rounds);
1408 if (smoke || incendiary || stunGas) {
1410 Edict* closeActor =
nullptr;
1434 actor->
dir = prevDir;
bool CHRSH_IsTeamDefRobot(const teamDef_t *const td)
Check if a team definition is a robot.
#define INVDEF(containerID)
void asIntString(char *str, size_t len)
Prints a representation of the box.
void getCenter(vec3_t center) const
Calculates the center of the bounding box.
bool isSameTeamAs(const Edict *other) const
bool isSameAs(const Edict *other) const
Item * getRightHandItem() const
actorSizeEnum_t fieldSize
Item * getLeftHandItem() const
bool(* destroy)(Edict *self)
bool isSamePosAs(const pos3_t cmpPos)
Check whether the edict is on the given position.
actorHands_t getHand() const
const objDef_t * getWeapon() const
Item * getHeadgear() const
item instance data, with linked list capability
const objDef_t * ammoDef(void) const
const objDef_t * def(void) const
const fireDef_t * getFiredefs() const
Returns the firedefinitions for a given weapon/ammo.
void setAmmoLeft(int value)
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
void G_ActorReserveTUs(Edict *ent, int resReaction, int resShot, int resCrouch)
Reserves TUs for different actor actions.
bool G_ActorDieOrStun(Actor *actor, Edict *attacker)
Reports and handles death or stun of an actor. If the HP of an actor is zero the actor will die,...
void G_ActorSetTU(Edict *ent, int tus)
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_ActorGetEyeVector(const Edict *actor, vec3_t eye)
Fills a vector with the eye position of a given actor.
#define G_IsCrouched(ent)
playermask_t G_TeamToPM(int team)
Generates the player bit mask for a given team.
bool G_ActionCheckForCurrentTeam(const Player &player, Actor *ent, int TU)
Checks whether the requested action is possible for the current active team.
static chrScoreMission_t scoreMission[MAX_EDICTS]
void G_AppearPerishEvent(playermask_t playerMask, bool appear, Edict &check, const Edict *ent)
Send the appear or perish event to the affected clients.
void G_ClientPrintf(const Player &player, int printLevel, const char *fmt,...)
bool G_ActionCheckForReaction(const Player &player, Actor *actor, int TU)
Checks whether the requested action is possible.
teammask_t G_PMToVis(playermask_t playerMask)
Converts player mask to vis mask.
playermask_t G_VisToPM(teammask_t teamMask)
Converts vis mask to player mask.
Interface for g_client.cpp.
static void G_ShotMorale(const Actor *shooter, const fireDef_t *fd, const vec3_t from, const Item *weapon, const vec3_t impact)
Applies morale changes to actors who find themselves in the general direction of a shot.
void G_CalcEffectiveSpread(const Actor *shooter, const fireDef_t *fd, vec2_t effSpread)
Calculate the effective spread for the given actor and firemode.
static void G_ShootGrenade(const Player &player, Actor *shooter, const fireDef_t *fd, const vec3_t from, const pos3_t at, int mask, const Item *weapon, shot_mock_t *mock, int z_align, vec3_t impact)
A parabola-type shoot (grenade, throw).
#define MAX_WALL_THICKNESS_FOR_SHOOTING_THROUGH
static void G_SpawnItemOnFloor(const pos3_t pos, const Item *item)
Spawn an item on the floor. A new ET_ITEM edict is created if needed.
static void G_UpdateHitScore(Edict *attacker, const Edict *target, const fireDef_t *fd, const int splashDamage)
Increases the 'hit' score by one for all affected teams/skills by one (except splash damage,...
static void G_ShootSingle(Actor *ent, const fireDef_t *fd, const vec3_t from, const pos3_t at, int mask, const Item *weapon, shot_mock_t *mock, int z_align, int i, shoot_types_t shootType, vec3_t impact)
Fires straight shots.
static bool G_TeamPointVis(int team, const vec3_t point)
Test if point is "visible" from team.
static void G_UpdateCharacterBodycount(Edict *attacker, const fireDef_t *fd, const Actor *target)
Update character stats for this mission after successful shoot.
static bool G_Damage(Edict *target, const fireDef_t *fd, int damage, Actor *attacker, shot_mock_t *mock, const vec3_t impact)
Deals damage of a give type and amount to a target.
int G_ApplyProtection(const Edict *target, const byte dmgWeight, int damage)
Reduces damage by armour and natural protection.
#define GRENADE_STOPSPEED
static void G_Morale(morale_modifiers type, const Edict *victim, const Edict *attacker, int param)
Applies morale changes to actors around a wounded or killed actor.
void G_CheckDeathOrKnockout(Actor *target, Actor *attacker, const fireDef_t *fd, int damage)
static bool G_PrepareShot(Edict *ent, shoot_types_t shootType, fireDefIndex_t firemode, Item **weapon, containerIndex_t *container, const fireDef_t **fd)
Prepares weapon, firemode and container used for shoot.
static void G_SplashDamage(Actor *ent, const fireDef_t *fd, vec3_t impact, shot_mock_t *mock, const trace_t *tr)
Deals splash damage to a target and its surroundings.
static bool G_FireAffectedSurface(const cBspSurface_t *surface, const fireDef_t *fd)
Checks surface vulnerability for firedefinition damagetype.
static void G_UpdateShotMock(shot_mock_t *mock, const Edict *shooter, const Edict *struck, int damage)
Function to calculate possible damages for mock pseudoaction.
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 * makeActor(Edict *ent)
Convert an Edict pointer into an Actor pointer.
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_EdictsGetNext(Edict *lastEnt)
Iterate through the list of entities.
Edict * G_EdictsGetNextInUse(Edict *lastEnt)
Iterate through the entities that are in use.
Actor * G_EdictsGetLivingActorFromPos(const pos3_t pos)
Searches an actor at the given grid location.
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_EventStartShoot(const Edict &ent, teammask_t teamMask, shoot_types_t shootType, const pos3_t at)
Start the shooting event.
void G_EventInventoryDelete(const Edict &ent, playermask_t playerMask, const containerIndex_t containerId, int x, int y)
Tell the client to remove the item from the container.
void G_EventActorTurn(const Edict &ent)
Send the turn event for the given entity.
void G_EventInventoryAmmo(const Edict &ent, const objDef_t *ammo, int amount, shoot_types_t shootType)
Change the amount of available ammo for the given entity.
void G_EventThrow(teammask_t teamMask, const fireDef_t *fd, float dt, byte flags, const vec3_t position, const vec3_t velocity)
void G_EventEndShoot(const Edict &ent, teammask_t teamMask)
Ends the shooting event.
void G_EventShootHidden(teammask_t teamMask, const fireDef_t *fd, bool firstShoot, const vec3_t impact, int flags, const Edict *targetEdict)
Start the shooting event for hidden actors.
void G_EventSpawnSound(playermask_t playerMask, const Edict &ent, const vec3_t origin, const char *sound)
Spawns a sound (that will be spatialized on the client side).
void G_EventPerish(const Edict &ent)
Send an event to all clients that are seeing the given edict, that it just has disappeared.
void G_EventSendState(playermask_t playerMask, const Edict &ent)
void G_EventShoot(const Edict &ent, teammask_t teamMask, const fireDef_t *fd, bool firstShoot, shoot_types_t shootType, int flags, const trace_t *trace, const vec3_t from, const vec3_t impact)
Do the shooting.
void G_DamageActor(Edict *target, const int damage, const vec3_t impact)
Deals damage and causes wounds.
float G_ActorGetInjuryPenalty(const Edict *const ent, const modifier_types_t type)
Returns the penalty to the given stat caused by the actor wounds.
void G_TreatActor(Actor *target, const fireDef_t *const fd, const int heal, const int healerTeam)
Heals a target and treats wounds.
bool G_IsActorWounded(const Edict *ent, bool serious)
Edict * G_GetFloorItems(Edict *ent)
Prepares a list of items on the floor at given entity position.
Edict * G_GetFloorItemFromPos(const pos3_t pos)
Callback to G_GetEdictFromPos() for given position, used to get items from position.
#define MORALE_RANDOM(mod)
#define G_IsBreakable(ent)
#define G_IsVisibleForTeam(ent, team)
#define G_TeamToVisMask(team)
void G_SendStats(Edict &ent)
Send stats to network buffer.
#define G_IsCivilian(ent)
#define G_IsAIPlayer(player)
#define G_IsSinglePlayer()
#define G_IsBrushModel(ent)
void G_MatchEndCheck(void)
Checks whether there are still actors to fight with left. If none are the match end will be triggered...
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 ...
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_ReactionFirePostShot(Actor *target)
Called after 'target' has fired, this might trigger more reaction fire or resolve outstanding reactio...
void G_SpawnSmokeField(const vec3_t vec, const char *particle, int rounds, int damage, vec_t radius)
Spawns a smoke field that is available for some rounds.
void G_SpawnFireField(const vec3_t vec, const char *particle, int rounds, int damage, vec_t radius)
Edict * G_SpawnFloor(const pos3_t pos)
Spawns a new entity at the floor.
void G_SpawnStunSmokeField(const vec3_t vec, const char *particle, int rounds, int damage, vec_t radius)
Edict * G_SpawnParticle(const vec3_t origin, int spawnflags, const char *particle)
Brings new objects into the world.
trace_t G_Trace(const Line &trLine, const Edict *passent, int contentmask)
collision detection - this version is more accurate and includes entity tests
void G_TakeDamage(Edict *ent, int damage)
Applies the given damage value to an edict that is either an actor or has the FL_DESTROYABLE flag set...
bool G_TestLine(const vec3_t start, const vec3_t end)
fast version of a line trace but without including entities
void G_FreeEdict(Edict *ent)
Marks the edict as free.
int G_TouchTriggers(Edict *ent, const entity_type_t type)
Check the world against triggers for the current entity.
void G_PrintActorStats(const Edict *victim, const Edict *attacker, const fireDef_t *fd)
Prints stats about who killed who with what and how.
Edict * G_FindRadius(Edict *from, const vec3_t org, float rad, entity_type_t type)
Returns entities that have origins within a spherical area.
Misc utility functions for game module.
void G_VisFlagsAdd(Edict &ent, teammask_t teamMask)
bool G_FrustumVis(const Edict *from, const vec3_t point)
Checks whether a point is "visible" from the edicts position.
int G_CheckVisTeamAll(const int team, const vischeckflags_t visFlags, const Edict *ent)
Do G_CheckVisTeam for all entities ent is the one that is looking at the others.
void G_VisFlagsReset(Edict &ent)
bool G_SmokeVis(const vec3_t from, const Edict *check)
tests for smoke interference
void G_CheckVis(Edict *check, const vischeckflags_t visFlags)
Check if the edict appears/perishes for the other teams. If they appear for other teams,...
float G_ActorVis(const Edict *ent, const Edict *check, bool full)
calculate how much check is "visible" by ent
#define FIRESH_IsMedikit(firedef)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
void gaussrand(float *gauss1, float *gauss2)
generate two gaussian distributed random numbers with median at 0 and stdev of 1
vec_t VectorLength(const vec3_t v)
Calculate the length of a vector.
void VectorMA(const vec3_t veca, const float scale, const vec3_t vecb, vec3_t outVector)
Sets vector_out (vc) to vevtor1 (va) + scale * vector2 (vb).
float crand(void)
Return random values between -1 and 1.
bool RayIntersectAABB(const vec3_t start, const vec3_t end, const AABB &aabb)
void AngleVectors(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Create the rotation matrix in order to rotate something.
int AngleToDir(int angle)
Returns the index of array directionAngles[DIRECTIONS] whose value is the closest to angle.
void VecToAngles(const vec3_t value1, vec3_t angles)
Converts a vector to an angle vector.
void VectorNormalizeFast(vec3_t v)
fast vector normalize routine that does not check to make sure that length != 0, nor does it return l...
#define VecToPos(v, p)
Map boundary is +/- MAX_WORLD_WIDTH - to get into the positive area we add the possible max negative ...
#define IS_SHOT_RIGHT(x)
Determine whether the selected shoot type is for the item in the right hand, either shooting or react...
#define IS_SHOT_HEADGEAR(x)
Determine whether the selected shoot type is for the item in the headgear slot.
#define ST_NUM_SHOOT_TYPES
Amount of shoottypes available.
int32_t shoot_types_t
Available shoot types - also see the ST_ constants.
#define GET_ACC(ab, sk, pn)
QGL_EXTERN GLint GLenum type
chrReservations_t reservedTus
const teamDef_t * teamDef
chrScoreMission_t * scoreMission
Structure of all stats collected for an actor over time.
int stuns[KILLED_NUM_TYPES]
int kills[KILLED_NUM_TYPES]
int skills[SKILL_NUM_TYPES]
Structure of all stats collected in a mission.
int hitsSplashDamage[SKILL_NUM_TYPES][KILLED_NUM_TYPES]
int fired[SKILL_NUM_TYPES]
int firedSplash[SKILL_NUM_TYPES]
bool firedHit[KILLED_NUM_TYPES]
int hitsSplash[SKILL_NUM_TYPES][KILLED_NUM_TYPES]
int hits[SKILL_NUM_TYPES][KILLED_NUM_TYPES]
int firedTUs[SKILL_NUM_TYPES]
bool firedSplashHit[KILLED_NUM_TYPES]
int firedSplashTUs[SKILL_NUM_TYPES]
this is a fire definition for our weapons/ammo
const struct objDef_s * obj
void getShotOrigin(const vec3_t from, const vec3_t dir, bool crouching, vec3_t shotOrigin) const
inventory definition for our menus
Defines all attributes of objects used in the inventory.
short protection[MAX_DAMAGETYPES]
used in shot probability calculations (pseudo shots)
short resistance[MAX_DAMAGETYPES]
const char * getActorSound(int gender, actorSound_t soundType) const
#define VectorSubtract(a, b, dest)
#define VectorCopy(src, dest)
#define VectorCompare(a, b)
#define VectorDistSqr(a, b)
#define VectorAdd(a, b, dest)
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
#define VectorScale(in, scale, out)
#define VectorLengthSqr(a)