Major refactoring & cleanup

This commit is contained in:
s1lent 2017-10-12 21:50:56 +07:00 committed by Dmitry Novikov
parent 48ebd5c96f
commit b25e3505d3
461 changed files with 12814 additions and 40802 deletions

View File

@ -2,7 +2,7 @@ import org.doomedsociety.gradlecpp.GradleCppUtils
import org.apache.commons.io.FilenameUtils
void _copyFileToDir(String from, String to) {
def dst = new File(project.file(to), FilenameUtils.getName(from))
def dst = new File(project.file(to), FilenameUtils.getName(from))
GradleCppUtils.copyFile(project.file(from), dst, false)
}

View File

@ -105,7 +105,7 @@ void setupToolchain(NativeBinarySpec b)
b.lib LazyNativeDepSet.create(dep_cppunitlite, 'cppunitlite', b.buildType.name, true)
}
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'REGAMEDLL_SELF', 'REGAMEDLL_API', 'CLIENT_WEAPONS'
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'REGAMEDLL_SELF', 'REGAMEDLL_API', 'CLIENT_WEAPONS', 'USE_QSTRING'
if (cfg instanceof MsvcToolchainConfig)
{
@ -140,7 +140,7 @@ void setupToolchain(NativeBinarySpec b)
pchSourceSet: 'regamedll_pch'
);
cfg.compilerOptions.languageStandard = 'c++0x'
cfg.compilerOptions.languageStandard = 'c++14'
cfg.defines([
'_stricmp': 'strcasecmp',
'_strnicmp': 'strncasecmp',

View File

@ -283,13 +283,7 @@
// volume values
#define VOL_NORM 1.0
// plats
#define PLAT_LOW_TRIGGER 1
// Trains
#define SF_TRAIN_WAIT_RETRIGGER 1
#define SF_TRAIN_START_ON 4 // Train is initially moving
#define SF_TRAIN_PASSABLE 8 // Train is not solid -- used to make water trains
// Break Model Defines
#define BREAK_TYPEMASK 0x4F

View File

@ -91,20 +91,20 @@ const T& clamp(const T& a, const T& min, const T& max) { return (a > max) ? max
#endif // __cplusplus
// bitwise operators templates
template<class T, class type=typename std::underlying_type<T>::type>
inline T operator~ (T a) { return (T)~(type)a; }
template<class T, class type=typename std::underlying_type<T>::type>
inline T operator| (T a, T b) { return (T)((type)a | (type)b); }
template<class T, class type=typename std::underlying_type<T>::type>
inline T operator& (T a, T b) { return (T)((type)a & (type)b); }
template<class T, class type=typename std::underlying_type<T>::type>
inline T operator^ (T a, T b) { return (T)((type)a ^ (type)b); }
template<class T, class type=typename std::underlying_type<T>::type>
inline T& operator|= (T& a, T b) { return (T&)((type&)a |= (type)b); }
template<class T, class type=typename std::underlying_type<T>::type>
inline T& operator&= (T& a, T b) { return (T&)((type&)a &= (type)b); }
template<class T, class type=typename std::underlying_type<T>::type>
inline T& operator^= (T& a, T b) { return (T&)((type&)a ^= (type)b); }
//template<class T, class type=typename std::underlying_type<T>::type>
//inline T operator~ (T a) { return (T)~(type)a; }
//template<class T, class type=typename std::underlying_type<T>::type>
//inline T operator| (T a, T b) { return (T)((type)a | (type)b); }
//template<class T, class type=typename std::underlying_type<T>::type>
//inline T operator& (T a, T b) { return (T)((type)a & (type)b); }
//template<class T, class type=typename std::underlying_type<T>::type>
//inline T operator^ (T a, T b) { return (T)((type)a ^ (type)b); }
//template<class T, class type=typename std::underlying_type<T>::type>
//inline T& operator|= (T& a, T b) { return (T&)((type&)a |= (type)b); }
//template<class T, class type=typename std::underlying_type<T>::type>
//inline T& operator&= (T& a, T b) { return (T&)((type&)a &= (type)b); }
//template<class T, class type=typename std::underlying_type<T>::type>
//inline T& operator^= (T& a, T b) { return (T&)((type&)a ^= (type)b); }
inline float M_sqrt(float value) {
return _mm_cvtss_f32(_mm_sqrt_ss(_mm_load_ss(&value)));

View File

@ -26,11 +26,7 @@
*
*/
#ifndef ACTIVITY_H
#define ACTIVITY_H
#ifdef _WIN32
#pragma once
#endif
typedef enum Activity_s
{
@ -41,21 +37,21 @@ typedef enum Activity_s
ACT_GUARD,
ACT_WALK,
ACT_RUN,
ACT_FLY,
ACT_FLY, // Fly (and flap if appropriate)
ACT_SWIM,
ACT_HOP,
ACT_LEAP,
ACT_HOP, // vertical jump
ACT_LEAP, // long forward jump
ACT_FALL,
ACT_LAND,
ACT_STRAFE_LEFT,
ACT_STRAFE_RIGHT,
ACT_ROLL_LEFT,
ACT_ROLL_RIGHT,
ACT_TURN_LEFT,
ACT_TURN_RIGHT,
ACT_CROUCH,
ACT_CROUCHIDLE,
ACT_STAND,
ACT_ROLL_LEFT, // tuck and roll, left
ACT_ROLL_RIGHT, // tuck and roll, right
ACT_TURN_LEFT, // turn quickly left (stationary)
ACT_TURN_RIGHT, // turn quickly right (stationary)
ACT_CROUCH, // the act of crouching down from a standing position
ACT_CROUCHIDLE, // holding body in crouched position (loops)
ACT_STAND, // the act of standing from a crouched position
ACT_USE,
ACT_SIGNAL1,
ACT_SIGNAL2,
@ -69,43 +65,43 @@ typedef enum Activity_s
ACT_MELEE_ATTACK1,
ACT_MELEE_ATTACK2,
ACT_RELOAD,
ACT_ARM,
ACT_DISARM,
ACT_EAT,
ACT_ARM, // pull out gun, for instance
ACT_DISARM, // reholster gun
ACT_EAT, // monster chowing on a large food item (loop)
ACT_DIESIMPLE,
ACT_DIEBACKWARD,
ACT_DIEFORWARD,
ACT_DIEVIOLENT,
ACT_BARNACLE_HIT,
ACT_BARNACLE_PULL,
ACT_BARNACLE_CHOMP,
ACT_BARNACLE_CHEW,
ACT_BARNACLE_HIT, // barnacle tongue hits a monster
ACT_BARNACLE_PULL, // barnacle is lifting the monster ( loop )
ACT_BARNACLE_CHOMP, // barnacle latches on to the monster
ACT_BARNACLE_CHEW, // barnacle is holding the monster in its mouth ( loop )
ACT_SLEEP,
ACT_INSPECT_FLOOR,
ACT_INSPECT_WALL,
ACT_IDLE_ANGRY,
ACT_WALK_HURT,
ACT_RUN_HURT,
ACT_HOVER,
ACT_GLIDE,
ACT_FLY_LEFT,
ACT_FLY_RIGHT,
ACT_DETECT_SCENT,
ACT_SNIFF,
ACT_BITE,
ACT_THREAT_DISPLAY,
ACT_FEAR_DISPLAY,
ACT_EXCITED,
ACT_SPECIAL_ATTACK1,
ACT_INSPECT_FLOOR, // for active idles, look at something on or near the floor
ACT_INSPECT_WALL, // for active idles, look at something directly ahead of you ( doesn't HAVE to be a wall or on a wall )
ACT_IDLE_ANGRY, // alternate idle animation in which the monster is clearly agitated. (loop)
ACT_WALK_HURT, // limp (loop)
ACT_RUN_HURT, // limp (loop)
ACT_HOVER, // Idle while in flight
ACT_GLIDE, // Fly (don't flap)
ACT_FLY_LEFT, // Turn left in flight
ACT_FLY_RIGHT, // Turn right in flight
ACT_DETECT_SCENT, // this means the monster smells a scent carried by the air
ACT_SNIFF, // this is the act of actually sniffing an item in front of the monster
ACT_BITE, // some large monsters can eat small things in one bite. This plays one time, EAT loops.
ACT_THREAT_DISPLAY, // without attacking, monster demonstrates that it is angry. (Yell, stick out chest, etc )
ACT_FEAR_DISPLAY, // monster just saw something that it is afraid of
ACT_EXCITED, // for some reason, monster is excited. Sees something he really likes to eat, or whatever.
ACT_SPECIAL_ATTACK1, // very monster specific special attacks.
ACT_SPECIAL_ATTACK2,
ACT_COMBAT_IDLE,
ACT_COMBAT_IDLE, // agitated idle.
ACT_WALK_SCARED,
ACT_RUN_SCARED,
ACT_VICTORY_DANCE,
ACT_DIE_HEADSHOT,
ACT_DIE_CHESTSHOT,
ACT_DIE_GUTSHOT,
ACT_DIE_BACKSHOT,
ACT_VICTORY_DANCE, // killed a player, do a victory dance.
ACT_DIE_HEADSHOT, // die, hit in head.
ACT_DIE_CHESTSHOT, // die, hit in chest
ACT_DIE_GUTSHOT, // die, hit in gut
ACT_DIE_BACKSHOT, // die, hit in back
ACT_FLINCH_HEAD,
ACT_FLINCH_CHEST,
ACT_FLINCH_STOMACH,
@ -148,5 +144,3 @@ typedef struct
} activity_map_t;
extern activity_map_t activity_map[];
#endif // ACTIVITY_H

View File

@ -107,5 +107,5 @@ activity_map_t activity_map[] =
_A(ACT_FLINCH_RIGHTARM),
_A(ACT_FLINCH_LEFTLEG),
_A(ACT_FLINCH_RIGHTLEG),
0, NULL
0, nullptr
};

View File

@ -26,11 +26,7 @@
*
*/
#ifndef AIRTANK_H
#define AIRTANK_H
#ifdef _WIN32
#pragma once
#endif
class CAirtank: public CGrenade
{
@ -52,5 +48,3 @@ public:
private:
int m_state;
};
#endif // AIRTANK_H

View File

@ -26,11 +26,7 @@
*
*/
#ifndef AMMO_H
#define AMMO_H
#ifdef _WIN32
#pragma once
#endif
class C9MMAmmo: public CBasePlayerAmmo
{
@ -111,5 +107,3 @@ public:
virtual void Precache();
virtual BOOL AddAmmo(CBaseEntity *pOther);
};
#endif // AMMO_H

View File

@ -157,8 +157,7 @@ NOXREF void CBaseAnimating::GetAttachment(int iAttachment, Vector &origin, Vecto
NOXREF int CBaseAnimating::FindTransition(int iEndingSequence, int iGoalSequence, int *piDir)
{
void *pmodel = GET_MODEL_PTR(ENT(pev));
if (piDir == NULL)
if (!piDir)
{
int iDir;
int sequence = ::FindTransition(pmodel, iEndingSequence, iGoalSequence, &iDir);

View File

@ -5,7 +5,7 @@
*/
#ifndef HOOK_GAMEDLL
void SV_StudioSetupBones(model_t *pModel, float frame, int sequence, const vec_t *angles, const vec_t *origin, const byte *pcontroller, const byte *pblending, int iBone, const edict_t *pEdict);
void EXT_FUNC SV_StudioSetupBones(model_t *pModel, float frame, int sequence, const vec_t *angles, const vec_t *origin, const byte *pcontroller, const byte *pblending, int iBone, const edict_t *pEdict);
sv_blending_interface_t svBlending =
{
@ -687,7 +687,7 @@ mstudioanim_t *StudioGetAnim(model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc)
paSequences = (cache_user_t *)m_pSubModel->submodels;
if (paSequences == NULL)
if (!paSequences)
{
paSequences = (cache_user_t *)IEngineStudio.Mem_Calloc(16, sizeof(cache_user_t)); // UNDONE: leak!
m_pSubModel->submodels = (dmodel_t *)paSequences;
@ -1140,7 +1140,6 @@ void SV_StudioSetupBones(model_t *pModel, float frame, int sequence, const vec_t
gaitsequence = 0;
pseqdesc = (mstudioseqdesc_t *)((byte *)g_pstudiohdr + g_pstudiohdr->seqindex) + gaitsequence;
panim = StudioGetAnim(pModel, pseqdesc);
StudioCalcRotations(pbones, chain, chainlength, adj, pos2, q2, pseqdesc, panim, 0, 0);

View File

@ -26,11 +26,7 @@
*
*/
#ifndef ANIMATION_H
#define ANIMATION_H
#ifdef _WIN32
#pragma once
#endif
#define NUM_BLENDING 9
@ -57,5 +53,3 @@ int GetBodygroup(void *pmodel, entvars_t *pev, int iGroup);
int GetAnimationEvent(void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index);
int ExtractBbox(void *pmodel, int sequence, float *mins, float *maxs);
#endif // ANIMATION_H

File diff suppressed because it is too large Load Diff

View File

@ -26,11 +26,24 @@
*
*/
#ifndef BASEMONSTER_H
#define BASEMONSTER_H
#ifdef _WIN32
#pragma once
#endif
#include "gib.h"
#include "combat.h"
#include "activity.h"
enum
{
ITBD_PARALLYZE = 0,
ITBD_NERVE_GAS,
ITBD_POISON,
ITBD_RADIATION,
ITBD_DROWN_RECOVER,
ITBD_ACID,
ITBD_SLOW_BURN,
ITBD_SLOW_FREEZE,
ITBD_END
};
enum MONSTERSTATE
{
@ -45,10 +58,6 @@ enum MONSTERSTATE
MONSTERSTATE_DEAD
};
void RadiusFlash(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore = 0, int bitsDamageType = 0);
void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);
void RadiusDamage2(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);
class CBaseMonster: public CBaseToggle
{
public:
@ -112,20 +121,18 @@ public:
Activity m_IdealActivity; // monster should switch to this activity
int m_LastHitGroup; // the last body region that took damage
int m_bitsDamageType; // what types of damage has monster (player) taken
byte m_rgbTimeBasedDamage[8];
byte m_rgbTimeBasedDamage[ITBD_END];
MONSTERSTATE m_MonsterState; // monster's current state
MONSTERSTATE m_IdealMonsterState; // monster should change to this state
int m_afConditions;
int m_afMemory;
float m_flNextAttack; // cannot attack again until this time
EHANDLE m_hEnemy; // the entity that the monster is fighting.
EHANDLE m_hTargetEnt; // the entity that the monster is trying to reach
float m_flFieldOfView; // width of monster's field of view ( dot product )
int m_bloodColor; // color of blood particless
Vector m_HackedGunPos; // HACK until we can query end of gun
Vector m_vecEnemyLKP; // last known position of enemy. (enemy's origin)
float m_flNextAttack; // cannot attack again until this time
EHANDLE m_hEnemy; // the entity that the monster is fighting.
EHANDLE m_hTargetEnt; // the entity that the monster is trying to reach
float m_flFieldOfView; // width of monster's field of view (dot product)
int m_bloodColor; // color of blood particless
Vector m_HackedGunPos; // HACK until we can query end of gun
Vector m_vecEnemyLKP; // last known position of enemy. (enemy's origin)
};
#endif // BASEMONSTER_H

View File

@ -64,13 +64,13 @@ void CFuncWallToggle::Spawn()
{
CFuncWall::Spawn();
if (pev->spawnflags & SF_WALL_START_OFF)
if (pev->spawnflags & SF_WALL_TOOGLE_START_OFF)
{
TurnOff();
}
#ifdef REGAMEDLL_ADD
if (pev->spawnflags & SF_WALL_NOTSOLID)
if (pev->spawnflags & SF_WALL_TOOGLE_NOTSOLID)
{
pev->solid = SOLID_NOT;
}
@ -83,7 +83,7 @@ void CFuncWallToggle::Restart()
{
CFuncWall::Spawn();
if (pev->spawnflags & SF_WALL_START_OFF)
if (pev->spawnflags & SF_WALL_TOOGLE_START_OFF)
{
TurnOff();
return;
@ -188,7 +188,9 @@ void CFuncIllusionary::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseToggle::KeyValue(pkvd);
}
}
void CFuncIllusionary::Spawn()
@ -231,7 +233,11 @@ void CFuncRotating::KeyValue(KeyValueData *pkvd)
m_flFanFriction = Q_atof(pkvd->szValue) / 100;
pkvd->fHandled = TRUE;
}
#ifdef REGAMEDLL_FIXES
else if (FStrEq(pkvd->szKeyName, "volume"))
#else
else if (FStrEq(pkvd->szKeyName, "Volume"))
#endif
{
m_flVolume = Q_atof(pkvd->szValue) / 10.0;
@ -259,7 +265,9 @@ void CFuncRotating::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseEntity::KeyValue(pkvd);
}
}
// QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS
@ -330,7 +338,7 @@ void CFuncRotating::Spawn()
}
// some rotating objects like fake volumetric lights will not be solid.
if (pev->spawnflags & SF_ROTATING_NOT_SOLID)
if (pev->spawnflags & SF_BRUSH_ROTATE_NOT_SOLID)
{
pev->solid = SOLID_NOT;
pev->skin = CONTENTS_EMPTY;
@ -358,12 +366,12 @@ void CFuncRotating::Spawn()
// pev->dmg = 2;
// instant-use brush?
if (pev->spawnflags & SF_BRUSH_ROTATE_INSTANT)
if (pev->spawnflags & SF_BRUSH_ROTATE_START_ON)
{
SetThink(&CFuncRotating::SUB_CallUseToggle);
// leave a magic delay for client to start up
pev->nextthink = pev->ltime + 1.5;
pev->nextthink = pev->ltime + 1.5f;
}
// can this brush inflict pain?
@ -378,16 +386,15 @@ void CFuncRotating::Spawn()
#ifdef REGAMEDLL_FIXES
void CFuncRotating::Restart()
{
// fan is spinning, so stop it.
SetThink(&CFuncRotating::SpinDown);
pev->nextthink = pev->ltime + 0.1;
// stop sound, we're done
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), 0, ATTN_NONE, SND_STOP, m_pitch);
// restore angles
pev->angles = m_angles;
pev->avelocity = g_vecZero;
// some rotating objects like fake volumetric lights will not be solid.
if (pev->spawnflags & SF_ROTATING_NOT_SOLID)
if (pev->spawnflags & SF_BRUSH_ROTATE_NOT_SOLID)
{
pev->solid = SOLID_NOT;
pev->skin = CONTENTS_EMPTY;
@ -411,12 +418,12 @@ void CFuncRotating::Restart()
}
// instant-use brush?
if (pev->spawnflags & SF_BRUSH_ROTATE_INSTANT)
if (pev->spawnflags & SF_BRUSH_ROTATE_START_ON)
{
SetThink(&CFuncRotating::SUB_CallUseToggle);
// leave a magic delay for client to start up
pev->nextthink = pev->ltime + 0.1;
pev->nextthink = pev->ltime + 0.1f;
}
// can this brush inflict pain?
@ -485,7 +492,7 @@ void CFuncRotating::Precache()
// if fan was spinning, and we went through transition or save/restore,
// make sure we restart the sound. 1.5 sec delay is magic number. KDB
SetThink(&CFuncRotating::SpinUp);
pev->nextthink = pev->ltime + 1.5;
pev->nextthink = pev->ltime + 1.5f;
}
}
@ -508,8 +515,7 @@ void CFuncRotating::HurtTouch(CBaseEntity *pOther)
// RampPitchVol - ramp pitch and volume up to final values, based on difference
// between how fast we're going vs how fast we plan to go
void CFuncRotating::RampPitchVol(int fUp)
void CFuncRotating::RampPitchVol(BOOL fUp)
{
Vector vecAVel = pev->avelocity;
float_precision vecCur;
@ -541,7 +547,7 @@ void CFuncRotating::RampPitchVol(int fUp)
fvol = m_flVolume * fpct;
}
fpitch = FANPITCHMIN + (FANPITCHMAX - FANPITCHMIN) * fpct;
fpitch = MIN_FANPITCH + (MAX_FANPITCH - MIN_FANPITCH) * fpct;
pitch = int(fpitch);
if (pitch == PITCH_NORM)
@ -556,7 +562,7 @@ void CFuncRotating::RampPitchVol(int fUp)
// SpinUp - accelerates a non-moving func_rotating up to it's speed
void CFuncRotating::SpinUp()
{
//rotational velocity
// rotational velocity
Vector vecAVel;
pev->nextthink = pev->ltime + 0.1;
@ -572,7 +578,7 @@ void CFuncRotating::SpinUp()
{
// set speed in case we overshot
pev->avelocity = pev->movedir * pev->speed;
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), m_flVolume, m_flAttenuation, (SND_CHANGE_PITCH | SND_CHANGE_VOL), FANPITCHMAX);
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), m_flVolume, m_flAttenuation, (SND_CHANGE_PITCH | SND_CHANGE_VOL), MAX_FANPITCH);
SetThink(&CFuncRotating::Rotate);
Rotate();
@ -585,13 +591,13 @@ void CFuncRotating::SpinUp()
void CFuncRotating::SpinDown()
{
//rotational velocity
// rotational velocity
Vector vecAVel;
vec_t vecdir;
pev->nextthink = pev->ltime + 0.1;
pev->nextthink = pev->ltime + 0.1f;
//spin down slower than spinup
// spin down slower than spinup
pev->avelocity = pev->avelocity - (pev->movedir * (pev->speed * m_flFanFriction));
// cache entity's rotational velocity
@ -641,12 +647,13 @@ void CFuncRotating::RotatingUse(CBaseEntity *pActivator, CBaseEntity *pCaller, U
SetThink(&CFuncRotating::SpinDown);
//EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop), m_flVolume, m_flAttenuation, 0, m_pitch);
pev->nextthink = pev->ltime + 0.1;
pev->nextthink = pev->ltime + 0.1f;
}
else // fan is not moving, so start it
// fan is not moving, so start it
else
{
SetThink(&CFuncRotating::SpinUp);
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), 0.01, m_flAttenuation, 0, FANPITCHMIN);
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), 0.01, m_flAttenuation, 0, MIN_FANPITCH);
pev->nextthink = pev->ltime + 0.1;
}
@ -660,12 +667,12 @@ void CFuncRotating::RotatingUse(CBaseEntity *pActivator, CBaseEntity *pCaller, U
// EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop), m_flVolume, m_flAttenuation, 0, m_pitch);
pev->nextthink = pev->ltime + 0.1;
pev->nextthink = pev->ltime + 0.1f;
// pev->avelocity = g_vecZero;
}
else
{
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), m_flVolume, m_flAttenuation, 0, FANPITCHMAX);
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), m_flVolume, m_flAttenuation, 0, MAX_FANPITCH);
pev->avelocity = pev->movedir * pev->speed;
SetThink(&CFuncRotating::Rotate);
@ -696,7 +703,9 @@ void CPendulum::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseEntity::KeyValue(pkvd);
}
}
void CPendulum::Spawn()
@ -704,7 +713,7 @@ void CPendulum::Spawn()
// set the axis of rotation
CBaseToggle::AxisDir(pev);
if (pev->spawnflags & SF_DOOR_PASSABLE)
if (pev->spawnflags & SF_PENDULUM_PASSABLE)
pev->solid = SOLID_NOT;
else
pev->solid = SOLID_BSP;
@ -725,18 +734,22 @@ void CPendulum::Spawn()
m_start = pev->angles;
m_center = pev->angles + (m_distance * 0.5) * pev->movedir;
if (pev->spawnflags & SF_BRUSH_ROTATE_INSTANT)
// instant-use brush?
if (pev->spawnflags & SF_PENDULUM_START_ON)
{
SetThink(&CPendulum::SUB_CallUseToggle);
// leave a magic delay for client to start up
pev->nextthink = gpGlobals->time + 0.1f;
}
pev->speed = 0;
SetUse(&CPendulum::PendulumUse);
// this brush makes a pendulum a rope swing
if (pev->spawnflags & SF_PENDULUM_SWING)
{
SetTouch (&CPendulum::RopeTouch);
SetTouch(&CPendulum::RopeTouch);
}
}
@ -818,7 +831,7 @@ void CPendulum::Swing()
pev->avelocity = pev->speed * pev->movedir;
// Call this again
pev->nextthink = pev->ltime + 0.1;
pev->nextthink = pev->ltime + 0.1f;
if (m_damp)
{

View File

@ -26,48 +26,12 @@
*
*/
#ifndef BMODELS_H
#define BMODELS_H
#ifdef _WIN32
#pragma once
#endif
// func_rotating
#define SF_BRUSH_ROTATE_Y_AXIS 0
#define SF_BRUSH_ROTATE_INSTANT 1
#define SF_BRUSH_ROTATE_BACKWARDS 2
#define SF_BRUSH_ROTATE_Z_AXIS 4
#define SF_BRUSH_ROTATE_X_AXIS 8
#define SF_BRUSH_ACCDCC 16 // brush should accelerate and decelerate when toggled
#define SF_BRUSH_HURT 32 // rotating brush that inflicts pain based on rotation speed
#define SF_ROTATING_NOT_SOLID 64 // some special rotating objects are not solid.
#define SF_BRUSH_ROTATE_SMALLRADIUS 128
#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256
#define SF_BRUSH_ROTATE_LARGERADIUS 512
#define FANPITCHMIN 30
#define FANPITCHMAX 100
// func_pendulum
#define SF_PENDULUM_SWING 2 // spawnflag that makes a pendulum a rope swing.
#define SF_PENDULUM_AUTO_RETURN 16
#define SF_PENDULUM_PASSABLE 32
// func_wall_toggle
#define SF_WALL_START_OFF 0x0001
#define SF_WALL_NOTSOLID 0x0008
// func_conveyor
#define SF_CONVEYOR_VISUAL 0x0001
#define SF_CONVEYOR_NOTSOLID 0x0002
// covering cheesy noise1, noise2, & noise3 fields so they make more sense (for rotating fans)
#define noiseStart noise1
#define noiseStop noise2
#define noiseRunning noise3
#define noiseStart noise1
#define noiseStop noise2
#define noiseRunning noise3
// This is just a solid wall if not inhibited
class CFuncWall: public CBaseEntity
@ -80,6 +44,9 @@ public:
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
};
#define SF_WALL_TOOGLE_START_OFF BIT(0)
#define SF_WALL_TOOGLE_NOTSOLID BIT(3)
class CFuncWallToggle: public CFuncWall
{
public:
@ -97,6 +64,9 @@ public:
BOOL IsOn();
};
#define SF_CONVEYOR_VISUAL BIT(0)
#define SF_CONVEYOR_NOTSOLID BIT(1)
class CFuncConveyor: public CFuncWall
{
public:
@ -135,6 +105,20 @@ public:
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) {}
};
#define SF_BRUSH_ROTATE_START_ON BIT(0)
#define SF_BRUSH_ROTATE_BACKWARDS BIT(1)
#define SF_BRUSH_ROTATE_Z_AXIS BIT(2)
#define SF_BRUSH_ROTATE_X_AXIS BIT(3)
#define SF_BRUSH_ACCDCC BIT(4) // Brush should accelerate and decelerate when toggled
#define SF_BRUSH_HURT BIT(5) // Rotating brush that inflicts pain based on rotation speed
#define SF_BRUSH_ROTATE_NOT_SOLID BIT(6) // Some special rotating objects are not solid.
#define SF_BRUSH_ROTATE_SMALLRADIUS BIT(7)
#define SF_BRUSH_ROTATE_MEDIUMRADIUS BIT(8)
#define SF_BRUSH_ROTATE_LARGERADIUS BIT(9)
const int MAX_FANPITCH = 100;
const int MIN_FANPITCH = 30;
class CFuncRotating: public CBaseEntity
{
public:
@ -157,7 +141,7 @@ public:
void EXPORT HurtTouch(CBaseEntity *pOther);
void EXPORT RotatingUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void EXPORT Rotate();
void RampPitchVol(int fUp);
void RampPitchVol(BOOL fUp);
public:
static TYPEDESCRIPTION IMPL(m_SaveData)[5];
@ -174,6 +158,11 @@ public:
};
#define SF_PENDULUM_START_ON BIT(0)
#define SF_PENDULUM_SWING BIT(1) // Spawnflag that makes a pendulum a rope swing
#define SF_PENDULUM_PASSABLE BIT(3)
#define SF_PENDULUM_AUTO_RETURN BIT(4)
class CPendulum: public CBaseEntity
{
public:
@ -208,5 +197,3 @@ public:
};
Vector VecBModelOrigin(entvars_t *pevBModel);
#endif // BMODELS_H

View File

@ -11,7 +11,7 @@ LINK_ENTITY_TO_CLASS(bot, CCSBot, CAPI_CSBot)
int GetBotFollowCount(CBasePlayer *leader)
{
int count = 0;
for (int i = 1; i <= gpGlobals->maxClients; ++i)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *player = UTIL_PlayerByIndex(i);
@ -32,7 +32,7 @@ int GetBotFollowCount(CBasePlayer *leader)
CCSBot *bot = reinterpret_cast<CCSBot *>(player);
if (bot->IsBot() && bot->GetFollowLeader() == leader)
++count;
count++;
}
return count;
@ -72,71 +72,69 @@ bool CCSBot::Jump(bool mustJump)
// NOTE: We dont want to directly call Attack() here, or the bots will have super-human reaction times when injured
BOOL CCSBot::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
{
CBaseEntity *attacker = GetClassPtr<CCSEntity>((CBaseEntity *)pevInflictor);
CBaseEntity *pAttacker = GetClassPtr<CCSEntity>((CBaseEntity *)pevInflictor);
// if we were attacked by a teammate, rebuke
if (attacker->IsPlayer())
if (pAttacker->IsPlayer())
{
CBasePlayer *player = static_cast<CBasePlayer *>(attacker);
if (BotRelationship(player) == BOT_TEAMMATE && !player->IsBot())
CBasePlayer *pPlayer = static_cast<CBasePlayer *>(pAttacker);
if (BotRelationship(pPlayer) == BOT_TEAMMATE && !pPlayer->IsBot())
{
GetChatter()->FriendlyFire();
}
}
if (attacker->IsPlayer() && IsEnemy(attacker))
{
// Track previous attacker so we don't try to panic multiple times for a shotgun blast
CBasePlayer *lastAttacker = m_attacker;
float lastAttackedTimestamp = m_attackedTimestamp;
// keep track of our last attacker
m_attacker = static_cast<CBasePlayer *>(attacker);
m_attackedTimestamp = gpGlobals->time;
// no longer safe
AdjustSafeTime();
if (!IsSurprised() && (m_attacker != lastAttacker || m_attackedTimestamp != lastAttackedTimestamp))
if (IsEnemy(pPlayer))
{
CBasePlayer *enemy = static_cast<CBasePlayer *>(attacker);
// Track previous attacker so we don't try to panic multiple times for a shotgun blast
CBasePlayer *lastAttacker = m_attacker;
float lastAttackedTimestamp = m_attackedTimestamp;
// being hurt by an enemy we can't see causes panic
if (!IsVisible(enemy, CHECK_FOV))
// keep track of our last attacker
m_attacker = pPlayer;
m_attackedTimestamp = gpGlobals->time;
// no longer safe
AdjustSafeTime();
if (!IsSurprised() && (m_attacker != lastAttacker || m_attackedTimestamp != lastAttackedTimestamp))
{
bool bPanic = false;
// being hurt by an enemy we can't see causes panic
if (!IsVisible(pPlayer, CHECK_FOV))
{
bool bPanic = false;
// if not attacking anything, look around to try to find attacker
if (!IsAttacking())
{
bPanic = true;
}
else
{
// we are attacking
if (!IsEnemyVisible())
// if not attacking anything, look around to try to find attacker
if (!IsAttacking())
{
bPanic = true;
}
else
{
// we are attacking
if (!IsEnemyVisible())
{
// can't see our current enemy, panic to acquire new attacker
bPanic = true;
}
}
if (!bPanic)
{
float invSkill = 1.0f - GetProfile()->GetSkill();
float panicChance = invSkill * invSkill * 50.0f;
if (panicChance > RANDOM_FLOAT(0, 100))
{
bPanic = true;
}
}
if (bPanic)
{
// can't see our current enemy, panic to acquire new attacker
bPanic = true;
Panic(m_attacker);
}
}
if (!bPanic)
{
float invSkill = 1.0f - GetProfile()->GetSkill();
float panicChance = invSkill * invSkill * 50.0f;
if (panicChance > RANDOM_FLOAT(0, 100))
{
bPanic = true;
}
}
if (bPanic)
{
// can't see our current enemy, panic to acquire new attacker
Panic(m_attacker);
}
}
}
}
@ -164,6 +162,13 @@ void CCSBot::Killed(entvars_t *pevAttacker, int iGib)
CBasePlayer::Killed(pevAttacker, iGib);
}
#define HI_X 0x01
#define LO_X 0x02
#define HI_Y 0x04
#define LO_Y 0x08
#define HI_Z 0x10
#define LO_Z 0x20
// Return true if line segment intersects rectagular volume
bool IsIntersectingBox(const Vector *start, const Vector *end, const Vector *boxMin, const Vector *boxMax)
{
@ -234,9 +239,9 @@ void CCSBot::BotTouch(CBaseEntity *other)
return;
// they are higher priority - make way, unless we're already making way for someone more important
if (m_avoid != NULL)
if (m_avoid)
{
unsigned int avoidPri = TheCSBots()->GetPlayerPriority(static_cast<CBasePlayer *>(m_avoid));
unsigned int avoidPri = TheCSBots()->GetPlayerPriority(m_avoid);
if (avoidPri < otherPri)
{
// ignore 'other' because we're already avoiding someone better
@ -244,7 +249,7 @@ void CCSBot::BotTouch(CBaseEntity *other)
}
}
m_avoid = other;
m_avoid = static_cast<CBasePlayer *>(other);
m_avoidTimestamp = gpGlobals->time;
return;
@ -307,11 +312,11 @@ void CCSBot::BotDeathThink()
CBasePlayer *CCSBot::FindNearbyPlayer()
{
CBaseEntity *pEntity = NULL;
CBaseEntity *pEntity = nullptr;
Vector vecSrc = pev->origin;
const float flRadius = 800.0f;
while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecSrc, flRadius)) != NULL)
while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecSrc, flRadius)))
{
if (!pEntity->IsPlayer())
continue;
@ -322,7 +327,7 @@ CBasePlayer *CCSBot::FindNearbyPlayer()
return static_cast<CBasePlayer *>(pEntity);
}
return NULL;
return nullptr;
}
// Assign given player as our current enemy to attack
@ -335,12 +340,12 @@ void CCSBot::SetEnemy(CBasePlayer *enemy)
}
}
// If we are not on the navigation mesh (m_currentArea == NULL),
// If we are not on the navigation mesh (m_currentArea == nullptr),
// move towards last known area.
// Return false if off mesh.
bool CCSBot::StayOnNavMesh()
{
if (m_currentArea != NULL)
if (m_currentArea)
return true;
// move back onto the area map
@ -359,7 +364,7 @@ bool CCSBot::StayOnNavMesh()
PrintIfWatched("Getting out of NULL area...\n");
}
if (goalArea != NULL)
if (goalArea)
{
Vector pos;
goalArea->GetClosestPointOnArea(&pev->origin, &pos);
@ -461,8 +466,7 @@ bool CCSBot::NoticeLooseBomb() const
return false;
CBaseEntity *bomb = TheCSBots()->GetLooseBomb();
if (bomb != NULL)
if (bomb)
{
// T's can always see bomb on their radar
return true;
@ -478,8 +482,7 @@ bool CCSBot::CanSeeLooseBomb() const
return false;
CBaseEntity *bomb = TheCSBots()->GetLooseBomb();
if (bomb != NULL)
if (bomb)
{
if (IsVisible(&bomb->pev->origin, CHECK_FOV))
return true;
@ -498,8 +501,7 @@ bool CCSBot::CanSeePlantedBomb() const
return false;
const Vector *bombPos = GetGameState()->GetBombPosition();
if (bombPos != NULL && IsVisible(bombPos, CHECK_FOV))
if (bombPos && IsVisible(bombPos, CHECK_FOV))
return true;
return false;
@ -508,10 +510,10 @@ bool CCSBot::CanSeePlantedBomb() const
// Return last enemy that hurt us
CBasePlayer *CCSBot::GetAttacker() const
{
if (m_attacker != NULL && m_attacker->IsAlive())
if (m_attacker && m_attacker->IsAlive())
return m_attacker;
return NULL;
return nullptr;
}
// Immediately jump off of our ladder, if we're on one
@ -527,7 +529,7 @@ void CCSBot::GetOffLadder()
// Return time when given spot was last checked
float CCSBot::GetHidingSpotCheckTimestamp(HidingSpot *spot) const
{
for (int i = 0; i < m_checkedHidingSpotCount; ++i)
for (int i = 0; i < m_checkedHidingSpotCount; i++)
{
if (m_checkedHidingSpot[i].spot->GetID() == spot->GetID())
return m_checkedHidingSpot[i].timestamp;
@ -543,7 +545,7 @@ void CCSBot::SetHidingSpotCheckTimestamp(HidingSpot *spot)
int leastRecent = 0;
float leastRecentTime = gpGlobals->time + 1.0f;
for (int i = 0; i < m_checkedHidingSpotCount; ++i)
for (int i = 0; i < m_checkedHidingSpotCount; i++)
{
// if spot is in the set, just update its timestamp
if (m_checkedHidingSpot[i].spot->GetID() == spot->GetID())
@ -565,7 +567,7 @@ void CCSBot::SetHidingSpotCheckTimestamp(HidingSpot *spot)
{
m_checkedHidingSpot[ m_checkedHidingSpotCount ].spot = spot;
m_checkedHidingSpot[ m_checkedHidingSpotCount ].timestamp = gpGlobals->time;
++m_checkedHidingSpotCount;
m_checkedHidingSpotCount++;
}
else
{
@ -587,8 +589,8 @@ void CCSBot::UpdateHostageEscortCount()
// recount the hostages in case we lost some
m_hostageEscortCount = 0;
CHostage *hostage = NULL;
while ((hostage = static_cast<CHostage *>(UTIL_FindEntityByClassname(hostage, "hostage_entity"))))
CHostage *hostage = nullptr;
while ((hostage = UTIL_FindEntityByClassname(hostage, "hostage_entity")))
{
if (FNullEnt(hostage->edict()))
break;
@ -599,7 +601,7 @@ void CCSBot::UpdateHostageEscortCount()
// check if hostage has targeted us, and is following
if (hostage->IsFollowing(this))
++m_hostageEscortCount;
m_hostageEscortCount++;
}
}
@ -623,14 +625,14 @@ int CCSBot::OutnumberedCount() const
// Return the closest "important" enemy for the given scenario (bomb carrier, VIP, hostage escorter)
CBasePlayer *CCSBot::GetImportantEnemy(bool checkVisibility) const
{
CBasePlayer *nearEnemy = NULL;
CBasePlayer *nearEnemy = nullptr;
float nearDist = 999999999.9f;
for (int i = 1; i <= gpGlobals->maxClients; ++i)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *player = UTIL_PlayerByIndex(i);
if (player == NULL)
if (!player)
continue;
if (FNullEnt(player->pev))
@ -808,11 +810,10 @@ bool CCSBot::HasNotSeenEnemyForLongTime() const
bool CCSBot::GuardRandomZone(float range)
{
const CCSBotManager::Zone *zone = TheCSBots()->GetRandomZone();
if (zone != NULL)
if (zone)
{
CNavArea *rescueArea = TheCSBots()->GetRandomAreaInZone(zone);
if (rescueArea != NULL)
if (rescueArea)
{
Hide(rescueArea, -1.0f, range);
return true;
@ -827,15 +828,15 @@ bool CCSBot::GuardRandomZone(float range)
const Vector *FindNearbyRetreatSpot(CCSBot *me, float maxRange)
{
CNavArea *area = me->GetLastKnownArea();
if (area == NULL)
return NULL;
if (!area)
return nullptr;
// collect spots that enemies cannot see
CollectRetreatSpotsFunctor collector(me, maxRange);
SearchSurroundingAreas(area, &me->pev->origin, collector, maxRange);
if (collector.m_count == 0)
return NULL;
return nullptr;
// select a hiding spot at random
int which = RANDOM_LONG(0, collector.m_count - 1);

View File

@ -26,41 +26,30 @@
*
*/
#ifndef CS_BOT_H
#define CS_BOT_H
#ifdef _WIN32
#pragma once
#endif
#include "bot/cs_gamestate.h"
#include "bot/cs_bot_manager.h"
#include "bot/cs_bot_chatter.h"
#define CSBOT_VERSION_MAJOR 1
#define CSBOT_VERSION_MINOR 50
const int MAX_BUY_WEAPON_PRIMARY = 13;
const int MAX_BUY_WEAPON_SECONDARY = 3;
#define PRIMARY_WEAPON_BUY_COUNT 13
#define SECONDARY_WEAPON_BUY_COUNT 3
#define FLAG_PROGRESS_DRAW 0x0 // draw status bar progress
#define FLAG_PROGRESS_START 0x1 // init status bar progress
#define FLAG_PROGRESS_HIDE 0x2 // hide status bar progress
#define HI_X 0x01
#define LO_X 0x02
#define HI_Y 0x04
#define LO_Y 0x08
#define HI_Z 0x10
#define LO_Z 0x20
enum
{
BOT_PROGGRESS_DRAW = 0, // draw status bar progress
BOT_PROGGRESS_START, // init status bar progress
BOT_PROGGRESS_HIDE, // hide status bar progress
};
extern int _navAreaCount;
extern int _currentIndex;
extern struct BuyInfo primaryWeaponBuyInfoCT[PRIMARY_WEAPON_BUY_COUNT];
extern struct BuyInfo secondaryWeaponBuyInfoCT[SECONDARY_WEAPON_BUY_COUNT];
extern struct BuyInfo primaryWeaponBuyInfoCT[MAX_BUY_WEAPON_PRIMARY];
extern struct BuyInfo secondaryWeaponBuyInfoCT[MAX_BUY_WEAPON_SECONDARY];
extern struct BuyInfo primaryWeaponBuyInfoT[PRIMARY_WEAPON_BUY_COUNT];
extern struct BuyInfo secondaryWeaponBuyInfoT[SECONDARY_WEAPON_BUY_COUNT];
extern struct BuyInfo primaryWeaponBuyInfoT[MAX_BUY_WEAPON_PRIMARY];
extern struct BuyInfo secondaryWeaponBuyInfoT[MAX_BUY_WEAPON_SECONDARY];
class CCSBot;
class BotChatterInterface;
@ -90,7 +79,7 @@ public:
virtual void OnExit(CCSBot *me);
virtual const char *GetName() const { return "Hunt"; }
void ClearHuntArea() { m_huntArea = NULL; }
void ClearHuntArea() { m_huntArea = nullptr; }
private:
CNavArea *m_huntArea;
@ -264,12 +253,12 @@ public:
virtual void OnExit(CCSBot *me);
virtual const char *GetName() const { return "Follow"; }
void SetLeader(CBaseEntity *leader) { m_leader = leader; }
void SetLeader(CBasePlayer *leader) { m_leader = leader; }
private:
void ComputeLeaderMotionState(float leaderSpeed);
EHANDLE m_leader;
EntityHandle<CBasePlayer> m_leader;
Vector m_lastLeaderPos;
bool m_isStopped;
float m_stoppedTimestamp;
@ -307,14 +296,14 @@ public:
void SetEntity(CBaseEntity *entity) { m_entity = entity; }
private:
EHANDLE m_entity;
EntityHandle<CBaseEntity> m_entity;
};
// The Counter-strike Bot
class CCSBot: public CBot
{
public:
CCSBot(); // constructor initializes all values to zero
CCSBot(); // constructor initializes all values to zero
virtual BOOL TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType); // invoked when injured by something (EXTEND) - returns the amount of damage inflicted
virtual void Killed(entvars_t *pevAttacker, int iGib); // invoked when killed (EXTEND)
virtual void RoundRespawn();
@ -330,11 +319,11 @@ public:
virtual void Walk();
virtual bool Jump(bool mustJump = false); // returns true if jump was started
virtual void OnEvent(GameEventType event, CBaseEntity *entity = NULL, CBaseEntity *other = NULL); // invoked when event occurs in the game (some events have NULL entity)
virtual void OnEvent(GameEventType event, CBaseEntity *entity = nullptr, CBaseEntity *other = nullptr); // invoked when event occurs in the game (some events have NULL entity)
#define CHECK_FOV true
virtual bool IsVisible(const Vector *pos, bool testFOV = false) const; // return true if we can see the point
virtual bool IsVisible(CBasePlayer *player, bool testFOV = false, unsigned char *visParts = NULL) const; // return true if we can see any part of the player
virtual bool IsVisible(CBasePlayer *player, bool testFOV = false, unsigned char *visParts = nullptr) const; // return true if we can see any part of the player
virtual bool IsEnemyPartVisible(VisiblePartType part) const; // if enemy is visible, return the part we see for our current enemy
@ -348,19 +337,19 @@ public:
bool IsHurrying() const; // return true if we are in a hurry
void Hurry(float duration); // force bot to hurry
bool IsSafe() const; // return true if we are in a safe region
bool IsWellPastSafe() const; // return true if it is well past the early, "safe", part of the round
bool IsEndOfSafeTime() const; // return true if we were in the safe time last update, but not now
float GetSafeTimeRemaining() const; // return the amount of "safe time" we have left
bool IsWellPastSafe() const; // return true if it is well past the early, "safe", part of the round
bool IsEndOfSafeTime() const; // return true if we were in the safe time last update, but not now
float GetSafeTimeRemaining() const; // return the amount of "safe time" we have left
float GetSafeTime() const; // return what we think the total "safe time" for this map is
//bool IsUnhealthy() const; // returns true if bot is low on health
// behaviors
void Idle();
void Hide(CNavArea *searchFromArea = NULL, float duration = -1.0f, float hideRange = 750.0f, bool holdPosition = false); // DEPRECATED: Use TryToHide() instead
void Hide(CNavArea *searchFromArea = nullptr, float duration = -1.0f, float hideRange = 750.0f, bool holdPosition = false); // DEPRECATED: Use TryToHide() instead
#define USE_NEAREST true
bool TryToHide(CNavArea *searchFromArea = NULL, float duration = -1.0f, float hideRange = 750.0f, bool holdPosition = false, bool useNearest = false); // try to hide nearby, return false if cannot
bool TryToHide(CNavArea *searchFromArea = nullptr, float duration = -1.0f, float hideRange = 750.0f, bool holdPosition = false, bool useNearest = false); // try to hide nearby, return false if cannot
void Hide(const Vector *hidingSpot, float duration = -1.0f, bool holdPosition = false); // move to the given hiding place
void Hide(const Vector *hidingSpot, float duration = -1.0f, bool holdPosition = false); // move to the given hiding place
bool IsHiding() const; // returns true if bot is currently hiding
bool IsAtHidingSpot() const; // return true if we are hiding and at our hiding spot
bool TryToRetreat(); // retreat to a nearby hiding spot, away from enemies
@ -454,7 +443,7 @@ public:
NUM_TASKS
};
void SetTask(TaskType task, CBaseEntity *entity = NULL); // set our current "task"
void SetTask(TaskType task, CBaseEntity *entity = nullptr); // set our current "task"
TaskType GetTask() const;
CBaseEntity *GetTaskEntity();
@ -491,7 +480,7 @@ public:
// listening for noises
bool IsNoiseHeard() const; // return true if we have heard a noise
bool ShouldInvestigateNoise(float *retNoiseDist = NULL);
bool ShouldInvestigateNoise(float *retNoiseDist = nullptr);
void InvestigateNoise(); // investigate recent enemy noise
const Vector *GetNoisePosition() const; // return position of last heard noise, or NULL if none heard
CNavArea *GetNoiseArea() const; // return area where noise was heard
@ -573,7 +562,7 @@ public:
void ResetStuckMonitor();
bool IsAreaVisible(CNavArea *area) const; // is any portion of the area visible to this bot
const Vector &GetPathPosition(int numpath) const;
bool GetSimpleGroundHeightWithFloor(const Vector *pos, float *height, Vector *normal = NULL); // find "simple" ground height, treating current nav area as part of the floor
bool GetSimpleGroundHeightWithFloor(const Vector *pos, float *height, Vector *normal = nullptr); // find "simple" ground height, treating current nav area as part of the floor
Place GetPlace() const; // get our current radio chatter place
@ -581,7 +570,9 @@ public:
void GetOffLadder();
void SetGoalEntity(CBaseEntity *entity);
CBaseEntity *GetGoalEntity();
template <typename T = CBaseEntity>
T *GetGoalEntity();
bool IsNearJump() const; // return true if nearing a jump in the path
float GetApproximateFallDamage(float height) const; // return how much damage will will take from the given fall height
@ -614,6 +605,7 @@ public:
return m_eyePos;
}
float ComputeWeaponSightRange(); // return line-of-sight distance to obstacle along weapon fire ray
bool IsSignificantlyCloser(const CBasePlayer *testPlayer, const CBasePlayer *referencePlayer) const; // return true if testPlayer is significantly closer than referencePlayer
// approach points
void ComputeApproachPoints(); // determine the set of "approach points" representing where the enemy can enter this region
@ -696,7 +688,7 @@ private:
float m_surpriseTimestamp;
bool m_isFollowing; // true if we are following someone
EHANDLE m_leader; // the ID of who we are following
EntityHandle<CBasePlayer> m_leader; // the ID of who we are following
float m_followTimestamp; // when we started following
float m_allowAutoFollowTime; // time when we can auto follow
@ -724,11 +716,11 @@ private:
bool m_isAttacking; // if true, special Attack state is overriding the state machine
TaskType m_task; // our current task
EHANDLE m_taskEntity; // an entity used for our task
EntityHandle<CBaseEntity> m_taskEntity; // an entity used for our task
// navigation
Vector m_goalPosition;
EHANDLE m_goalEntity;
EHandle m_goalEntity;
void MoveTowardsPosition(const Vector *pos); // move towards position, independant of view angle
void MoveAwayFromPosition(const Vector *pos); // move away from position, independant of view angle
void StrafeAwayFromPosition(const Vector *pos); // strafe (sidestep) away from position, independant of view angle
@ -736,7 +728,7 @@ private:
CNavArea *m_currentArea; // the nav area we are standing on
CNavArea *m_lastKnownArea; // the last area we were in
EHANDLE m_avoid; // higher priority player we need to make way for
EntityHandle<CBasePlayer> m_avoid; // higher priority player we need to make way for
float m_avoidTimestamp;
bool m_isJumpCrouching;
bool m_isJumpCrouched;
@ -765,7 +757,7 @@ private:
void SetPathIndex(int newIndex); // set the current index along the path
void DrawPath();
int FindOurPositionOnPath(Vector *close, bool local = false) const; // compute the closest point to our current position on our path
int FindPathPoint(float aheadRange, Vector *point, int *prevIndex = NULL); // compute a point a fixed distance ahead along our path.
int FindPathPoint(float aheadRange, Vector *point, int *prevIndex = nullptr); // compute a point a fixed distance ahead along our path.
bool FindClosestPointOnPath(const Vector *worldPos, int startIndex, int endIndex, Vector *close) const; // compute closest point on path to given point
bool IsStraightLinePathWalkable(const Vector *goal) const; // test for un-jumpable height change, or unrecoverable fall
@ -890,12 +882,12 @@ private:
Vector m_aimSpot; // the spot we are currently aiming to fire at
// attack state data
DispositionType m_disposition; // how we will react to enemies
CountdownTimer m_ignoreEnemiesTimer; // how long will we ignore enemies
mutable EHANDLE m_enemy; // our current enemy
bool m_isEnemyVisible; // result of last visibility test on enemy
unsigned char m_visibleEnemyParts; // which parts of the visible enemy do we see
Vector m_lastEnemyPosition; // last place we saw the enemy
DispositionType m_disposition; // how we will react to enemies
CountdownTimer m_ignoreEnemiesTimer; // how long will we ignore enemies
mutable EntityHandle<CBasePlayer> m_enemy; // our current enemy
bool m_isEnemyVisible; // result of last visibility test on enemy
unsigned char m_visibleEnemyParts; // which parts of the visible enemy do we see
Vector m_lastEnemyPosition; // last place we saw the enemy
float m_lastSawEnemyTimestamp;
float m_firstSawEnemyTimestamp;
float m_currentEnemyAcquireTimestamp;
@ -910,11 +902,15 @@ private:
bool isEnemy;
}
m_watchInfo[MAX_CLIENTS];
mutable EHANDLE m_bomber; // points to bomber if we can see him
mutable EntityHandle<CBasePlayer> m_bomber; // points to bomber if we can see him
int m_nearbyFriendCount; // number of nearby teammates
mutable EHANDLE m_closestVisibleFriend; // the closest friend we can see
mutable EHANDLE m_closestVisibleHumanFriend; // the closest human friend we can see
int m_nearbyFriendCount; // number of nearby teammates
mutable EntityHandle<CBasePlayer> m_closestVisibleFriend; // the closest friend we can see
mutable EntityHandle<CBasePlayer> m_closestVisibleHumanFriend; // the closest human friend we can see
#ifdef REGAMEDLL_ADD
IntervalTimer m_attentionInterval; // time between attention checks
#endif
CBasePlayer *m_attacker; // last enemy that hurt us (may not be same as m_enemy)
float m_attackedTimestamp; // when we were hurt by the m_attacker
@ -923,7 +919,7 @@ private:
bool m_isAimingAtEnemy; // if true, we are trying to aim at our enemy
bool m_isRapidFiring; // if true, RunUpkeep() will toggle our primary attack as fast as it can
IntervalTimer m_equipTimer; // how long have we had our current weapon equipped
bool DoEquip(CBasePlayerWeapon *gun); // equip the given item
bool DoEquip(CBasePlayerWeapon *pWeapon); // equip the given item
void ReloadCheck(); // reload our weapon if we must
void SilencerCheck(); // use silencer
@ -935,7 +931,7 @@ private:
struct ReactionState
{
// NOTE: player position & orientation is not currently stored separately
EHANDLE player;
EntityHandle<CBasePlayer> player;
bool isReloading;
bool isProtectedByShield;
}
@ -962,7 +958,7 @@ private:
Vector m_lastOrigin;
// chatter mechanism
GameEventType m_lastRadioCommand; // last radio command we recieved
GameEventType m_lastRadioCommand; // last radio command we recieved
void RespondToRadioCommands();
bool IsRadioCommand(GameEventType event) const; // returns true if the radio message is an order to do something
@ -970,7 +966,7 @@ private:
void EndVoiceFeedback(bool force = true);
float m_lastRadioRecievedTimestamp; // time we recieved a radio message
float m_lastRadioSentTimestamp; // time when we send a radio message
EHANDLE m_radioSubject; // who issued the radio message
EntityHandle<CBasePlayer> m_radioSubject; // who issued the radio message
Vector m_radioPosition; // position referred to in radio message
float m_voiceFeedbackStartTimestamp;
float m_voiceFeedbackEndTimestamp; // new-style "voice" chatter gets voice feedback
@ -1008,6 +1004,10 @@ private:
void StartSaveProcess();
void UpdateSaveProcess();
void StartNormalProcess();
#ifdef REGAMEDLL_ADD
bool IsNoticable(const CBasePlayer *player, unsigned char visibleParts) const; // return true if we "notice" given player
#endif
};
// Inlines
@ -1188,7 +1188,7 @@ inline unsigned int CCSBot::GetEnemyPlace() const
inline bool CCSBot::CanSeeBomber() const
{
return (m_bomber == NULL) ? false : true;
return m_bomber.IsValid();
}
inline CBasePlayer *CCSBot::GetBomber() const
@ -1264,7 +1264,7 @@ inline bool CCSBot::HasPath() const
inline void CCSBot::DestroyPath()
{
m_pathLength = 0;
m_pathLadder = NULL;
m_pathLadder = nullptr;
}
inline CNavArea *CCSBot::GetLastKnownArea() const
@ -1284,7 +1284,7 @@ inline const Vector &CCSBot::GetPathPosition(int numpath) const
inline bool CCSBot::IsUsingLadder() const
{
return m_pathLadder != NULL;
return m_pathLadder != nullptr;
}
inline void CCSBot::SetGoalEntity(CBaseEntity *entity)
@ -1292,9 +1292,10 @@ inline void CCSBot::SetGoalEntity(CBaseEntity *entity)
m_goalEntity = entity;
}
inline CBaseEntity *CCSBot::GetGoalEntity()
template <typename T>
inline T *CCSBot::GetGoalEntity()
{
return m_goalEntity;
return m_goalEntity.Get<T>();
}
inline void CCSBot::ForceRun(float duration)
@ -1323,7 +1324,7 @@ inline void CCSBot::ClearLookAt()
{
//PrintIfWatched("ClearLookAt()\n");
m_lookAtSpotState = NOT_LOOKING_AT_SPOT;
m_lookAtDesc = NULL;
m_lookAtDesc = nullptr;
}
inline bool CCSBot::IsLookingAtSpot(PriorityType pri) const
@ -1345,6 +1346,21 @@ inline bool CCSBot::IsViewMoving(float angleVelThreshold) const
return true;
}
inline bool CCSBot::IsSignificantlyCloser(const CBasePlayer *testPlayer, const CBasePlayer *referencePlayer) const
{
if (!referencePlayer || !testPlayer)
return true;
float testDist = (pev->origin - testPlayer->pev->origin).Length();
float referenceDist = (pev->origin - referencePlayer->pev->origin).Length();
const float significantRangeFraction = 0.7f;
if (testDist < referenceDist * significantRangeFraction)
return true;
return false;
}
inline void CCSBot::ClearApproachPoints()
{
m_approachPointCount = 0;
@ -1411,7 +1427,7 @@ inline const Vector *CCSBot::GetNoisePosition() const
if (m_noiseTimestamp > 0.0f)
return &m_noisePosition;
return NULL;
return nullptr;
}
inline bool CCSBot::IsAwareOfEnemyDeath() const
@ -1419,7 +1435,7 @@ inline bool CCSBot::IsAwareOfEnemyDeath() const
if (GetEnemyDeathTimestamp() == 0.0f)
return false;
if (m_enemy == NULL)
if (!m_enemy.IsValid())
return true;
if (!m_enemy->IsAlive() && gpGlobals->time - GetEnemyDeathTimestamp() > (1.0f - GetProfile()->GetSkill()))
@ -1484,7 +1500,7 @@ public:
// don't select spot if it is closest to an enemy
CBasePlayer *owner = UTIL_GetClosestPlayer(spot->GetPosition());
if (owner != NULL && m_me->m_iTeam != owner->m_iTeam)
if (owner && m_me->m_iTeam != owner->m_iTeam)
continue;
m_spot[m_count++] = spot->GetPosition();
@ -1547,7 +1563,7 @@ public:
// respond to the danger modulated by our aggression (even super-aggressives pay SOME attention to danger)
float dangerFactor = (1.0f - (0.95f * m_bot->GetProfile()->GetAggression())) * baseDangerFactor;
if (fromArea == NULL)
if (fromArea == nullptr)
{
if (m_route == FASTEST_ROUTE)
return 0.0f;
@ -1753,5 +1769,3 @@ void hideProgressMeter();
bool isSniperRifle(CBasePlayerItem *item);
float StayOnLadderLine(CCSBot *me, const CNavLadder *ladder);
#endif // CS_BOT_H

View File

@ -6,8 +6,7 @@
*/
#ifndef HOOK_GAMEDLL
BotPhraseManager *TheBotPhrases = NULL;
CBaseEntity *g_pSelectedZombieSpawn = NULL;
BotPhraseManager *TheBotPhrases = nullptr;
CountdownTimer BotChatterInterface::m_encourageTimer;
IntervalTimer BotChatterInterface::m_radioSilenceInterval[ 2 ];
@ -16,37 +15,32 @@ IntervalTimer BotChatterInterface::m_radioSilenceInterval[ 2 ];
const Vector *GetRandomSpotAtPlace(Place place)
{
int count = 0;
NavAreaList::iterator iter;
int which;
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
for (auto area : TheNavAreaList)
{
CNavArea *area = (*iter);
if (area->GetPlace() == place)
++count;
count++;
}
if (count == 0)
return NULL;
return nullptr;
which = RANDOM_LONG(0, count - 1);
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
for (auto area : TheNavAreaList)
{
CNavArea *area = (*iter);
if (area->GetPlace() == place && which == 0)
return area->GetCenter();
}
return NULL;
return nullptr;
}
// Transmit meme to other bots
void BotMeme::Transmit(CCSBot *sender) const
{
for (int i = 1; i <= gpGlobals->maxClients; ++i)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *player = UTIL_PlayerByIndex(i);
@ -235,7 +229,7 @@ void BotHostageBeingTakenMeme::Interpret(CCSBot *sender, CCSBot *receiver) const
BotSpeakable::BotSpeakable()
{
m_phrase = NULL;
m_phrase = nullptr;
}
BotSpeakable::~BotSpeakable()
@ -243,13 +237,13 @@ BotSpeakable::~BotSpeakable()
if (m_phrase)
{
delete[] m_phrase;
m_phrase = NULL;
m_phrase = nullptr;
}
}
BotPhrase::BotPhrase(unsigned int id, bool isPlace)
{
m_name = NULL;
m_name = nullptr;
m_id = id;
m_isPlace = isPlace;
m_radioEvent = EVENT_INVALID;
@ -263,19 +257,20 @@ BotPhrase::BotPhrase(unsigned int id, bool isPlace)
BotPhrase::~BotPhrase()
{
for (size_t bank = 0; bank < m_voiceBank.size(); ++bank)
for (size_t bank = 0; bank < m_voiceBank.size(); bank++)
{
for (size_t speakable = 0; speakable < m_voiceBank[bank]->size(); ++speakable)
for (size_t speakable = 0; speakable < m_voiceBank[bank]->size(); speakable++)
{
delete (*m_voiceBank[bank])[speakable];
}
delete m_voiceBank[bank];
}
if (m_name)
{
delete[] m_name;
m_name = NULL;
m_name = nullptr;
}
}
@ -286,7 +281,7 @@ void BotPhrase::InitVoiceBank(int bankIndex)
m_count.push_back(0);
m_index.push_back(0);
m_voiceBank.push_back(new BotSpeakableVector);
++m_numVoiceBanks;
m_numVoiceBanks++;
}
}
@ -298,7 +293,7 @@ char *BotPhrase::GetSpeakable(int bankIndex, float *duration) const
if (duration)
*duration = 0.0f;
return NULL;
return nullptr;
}
// find phrase that meets the current criteria
@ -338,18 +333,18 @@ char *BotPhrase::GetSpeakable(int bankIndex, float *duration) const
if (duration)
*duration = 0.0f;
return NULL;
return nullptr;
}
}
return NULL;
return nullptr;
}
// Randomly shuffle the speakable order
#ifndef HOOK_GAMEDLL
void BotPhrase::Randomize()
{
for (size_t i = 0; i < m_voiceBank.size(); ++i)
for (size_t i = 0; i < m_voiceBank.size(); i++)
{
std::random_shuffle(m_voiceBank[i]->begin(), m_voiceBank[i]->end());
}
@ -358,7 +353,7 @@ void BotPhrase::Randomize()
BotPhraseManager::BotPhraseManager()
{
for (int i = 0; i < MAX_PLACES_PER_MAP; ++i)
for (int i = 0; i < MAX_PLACES_PER_MAP; i++)
m_placeStatementHistory[i].timer.Invalidate();
m_placeCount = 0;
@ -375,18 +370,13 @@ void BotPhraseManager::OnRoundRestart()
{
// effectively reset all interval timers
m_placeCount = 0;
BotPhraseList::const_iterator iter;
// shuffle all the speakables
for (iter = m_placeList.begin(); iter != m_placeList.end(); ++iter)
{
(*iter)->Randomize();
}
for (auto phrase : m_placeList)
phrase->Randomize();
for (iter = m_list.begin(); iter != m_list.end(); ++iter)
{
(*iter)->Randomize();
}
for (auto phrase : m_list)
phrase->Randomize();
}
// Initialize phrase system from database file
@ -396,7 +386,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
int phraseDataLength;
char *phraseDataFile = (char *)LOAD_FILE_FOR_ME((char *)filename, &phraseDataLength);
if (phraseDataFile == NULL)
if (!phraseDataFile)
{
if (AreBotsAllowed())
{
@ -406,6 +396,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false;
}
char *token;
char *phraseData = phraseDataFile;
unsigned int nextID = 1;
@ -425,16 +416,15 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
// Parse the BotChatter.db into BotPhrase collections
while (true)
{
phraseData = MP_COM_Parse(phraseData);
phraseData = SharedParse(phraseData);
if (!phraseData)
break;
char *token = MP_COM_GetToken();
token = SharedGetToken();
if (!Q_stricmp(token, "BaseDir"))
{
// get name of this output device
phraseData = MP_COM_Parse(phraseData);
phraseData = SharedParse(phraseData);
if (!phraseData)
{
CONSOLE_ECHO("Error parsing '%s' - expected identifier\n", filename);
@ -442,7 +432,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false;
}
char *token = MP_COM_GetToken();
token = SharedGetToken();
Q_strncpy(baseDir, token, RadioPathLen);
baseDir[RadioPathLen - 1] = '\0';
}
@ -451,14 +441,14 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
bool isPlace = (Q_stricmp(token, "Place") == 0);
// encountered a new phrase collection
BotPhrase *phrase = NULL;
BotPhrase *phrase = nullptr;
if (isDefault)
{
phrase = new BotPhrase(nextID++, isPlace);
}
// get name of this phrase
phraseData = MP_COM_Parse(phraseData);
phraseData = SharedParse(phraseData);
if (!phraseData)
{
CONSOLE_ECHO("Error parsing '%s' - expected identifier\n", filename);
@ -466,25 +456,26 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false;
}
token = SharedGetToken();
if (isDefault)
{
phrase->m_name = CloneString(MP_COM_GetToken());
phrase->m_name = CloneString(token);
}
// look up the existing phrase
else
{
if (isPlace)
{
phrase = const_cast<BotPhrase *>(GetPlace(MP_COM_GetToken()));
phrase = const_cast<BotPhrase *>(GetPlace(token));
}
else
{
phrase = const_cast<BotPhrase *>(GetPhrase(MP_COM_GetToken()));
phrase = const_cast<BotPhrase *>(GetPhrase(token));
}
if (!phrase)
{
CONSOLE_ECHO("Error parsing '%s' - phrase '%s' is invalid\n", filename, MP_COM_GetToken());
CONSOLE_ECHO("Error parsing '%s' - phrase '%s' is invalid\n", filename, token);
FREE_FILE(phraseDataFile);
return false;
}
@ -501,7 +492,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
while (true)
{
// get next token
phraseData = MP_COM_Parse(phraseData);
phraseData = SharedParse(phraseData);
if (!phraseData)
{
CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename);
@ -509,12 +500,12 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false;
}
token = MP_COM_GetToken();
token = SharedGetToken();
// check for Place criteria
if (!Q_stricmp(token, "Place"))
{
phraseData = MP_COM_Parse(phraseData);
phraseData = SharedParse(phraseData);
if (!phraseData)
{
CONSOLE_ECHO("Error parsing %s - expected Place name\n", filename);
@ -522,7 +513,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false;
}
token = MP_COM_GetToken();
token = SharedGetToken();
// update place criteria for subsequent speak lines
// NOTE: this assumes places must be first in the chatter database
@ -541,7 +532,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
// check for Count criteria
if (!Q_stricmp(token, "Count"))
{
phraseData = MP_COM_Parse(phraseData);
phraseData = SharedParse(phraseData);
if (!phraseData)
{
CONSOLE_ECHO("Error parsing %s - expected Count value\n", filename);
@ -549,7 +540,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false;
}
token = MP_COM_GetToken();
token = SharedGetToken();
// update count criteria for subsequent speak lines
if (!Q_stricmp(token, "Many"))
@ -563,7 +554,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
// check for radio equivalent
if (!Q_stricmp(token, "Radio"))
{
phraseData = MP_COM_Parse(phraseData);
phraseData = SharedParse(phraseData);
if (!phraseData)
{
CONSOLE_ECHO("Error parsing %s - expected radio event\n", filename);
@ -571,7 +562,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false;
}
token = MP_COM_GetToken();
token = SharedGetToken();
GameEventType event = NameToGameEvent(token);
if (event <= EVENT_START_RADIO_1 || event >= EVENT_END_RADIO)
{
@ -598,7 +589,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
#ifdef REGAMEDLL_ADD
Q_snprintf(filePath, sizeof(filePath), "%s%s%s", soundDir, baseDir, token);
if (Q_access(filePath, 0) != 0)
if (_access(filePath, 0) != 0)
continue;
#endif
@ -629,7 +620,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
BotSpeakableVector *speakables = phrase->m_voiceBank[ bankIndex ];
speakables->push_back(speak);
++phrase->m_count[ bankIndex ];
phrase->m_count[ bankIndex ]++;
}
if (isDefault)
@ -652,12 +643,11 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
BotPhraseManager::~BotPhraseManager()
{
BotPhraseList::iterator iter;
for (iter = m_list.begin(); iter != m_list.end(); ++iter)
delete (*iter);
for (auto phrase : m_list)
delete phrase;
for (iter = m_placeList.begin(); iter != m_placeList.end(); ++iter)
delete (*iter);
for (auto phrase : m_placeList)
delete phrase;
m_list.clear();
m_placeList.clear();
@ -665,125 +655,107 @@ BotPhraseManager::~BotPhraseManager()
Place BotPhraseManager::NameToID(const char *name) const
{
for (BotPhraseList::const_iterator iter = m_placeList.begin(); iter != m_placeList.end(); ++iter)
for (auto phrase : m_placeList)
{
const BotPhrase *phrase = (*iter);
if (!Q_stricmp(phrase->m_name, name))
return phrase->m_id;
}
for (BotPhraseList::const_iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
for (auto phrase : m_list)
{
const BotPhrase *phrase = (*iter);
if (!Q_stricmp(phrase->m_name, name))
return phrase->m_id;
}
return 0;
return UNDEFINED_PLACE;
}
const char *BotPhraseManager::IDToName(Place id) const
{
for (BotPhraseList::const_iterator iter = m_placeList.begin(); iter != m_placeList.end(); ++iter)
for (auto phrase : m_placeList)
{
const BotPhrase *phrase = (*iter);
if (phrase->m_id == id)
return phrase->m_name;
}
for (BotPhraseList::const_iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
for (auto phrase : m_list)
{
const BotPhrase *phrase = (*iter);
if (phrase->m_id == id)
return phrase->m_name;
}
return NULL;
return nullptr;
}
// Given a name, return the associated phrase collection
const BotPhrase *BotPhraseManager::GetPhrase(const char *name) const
{
for (BotPhraseList::const_iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
for (auto phrase : m_list)
{
const BotPhrase *phrase = (*iter);
if (!Q_stricmp(phrase->m_name, name))
return phrase;
}
//CONSOLE_ECHO("GetPhrase: ERROR - Invalid phrase '%s'\n", name);
return NULL;
return nullptr;
}
/*
// Given an id, return the associated phrase collection
// TODO: Store phrases in a vector to make this fast
const BotPhrase *BotPhraseManager::GetPhrase(unsigned int id) const
{
for (BotPhraseList::const_iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
for (auto phrase : m_list)
{
const BotPhrase *phrase = (*iter);
if (phrase->m_id == id)
return phrase;
}
CONSOLE_ECHO("GetPhrase: ERROR - Invalid phrase id #%d\n", id);
return NULL;
return nullptr;
}
*/
// Given a name, return the associated Place phrase collection
const BotPhrase *BotPhraseManager::GetPlace(const char *name) const
{
if (name == NULL)
return NULL;
if (!name)
return nullptr;
for (BotPhraseList::const_iterator iter = m_placeList.begin(); iter != m_placeList.end(); ++iter)
for (auto phrase : m_placeList)
{
const BotPhrase *phrase = (*iter);
if (!Q_stricmp(phrase->m_name, name))
return phrase;
}
return NULL;
return nullptr;
}
// Given a place, return the associated Place phrase collection
const BotPhrase *BotPhraseManager::GetPlace(PlaceCriteria place) const
{
if (place == UNDEFINED_PLACE)
return NULL;
return nullptr;
for (BotPhraseList::const_iterator iter = m_placeList.begin(); iter != m_placeList.end(); ++iter)
for (auto phrase : m_placeList)
{
const BotPhrase *phrase = (*iter);
if (phrase->m_id == place)
return phrase;
}
return NULL;
return nullptr;
}
BotStatement::BotStatement(BotChatterInterface *chatter, BotStatementType type, float expireDuration)
{
m_chatter = chatter;
m_prev = m_next = NULL;
m_prev = m_next = nullptr;
m_timestamp = gpGlobals->time;
m_speakTimestamp = 0.0f;
m_type = type;
m_subject = UNDEFINED_SUBJECT;
m_place = UNDEFINED_PLACE;
m_meme = NULL;
m_meme = nullptr;
m_startTime = gpGlobals->time;
m_expireTime = gpGlobals->time + expireDuration;
@ -801,7 +773,7 @@ BotStatement::~BotStatement()
if (m_meme)
{
delete m_meme;
m_meme = NULL;
m_meme = nullptr;
}
}
@ -827,7 +799,7 @@ void BotStatement::AddCondition(ConditionType condition)
bool BotStatement::IsImportant() const
{
// if a statement contains any important phrases, it is important
for (int i = 0; i < m_count; ++i)
for (int i = 0; i < m_count; i++)
{
if (m_statement[i].isPhrase && m_statement[i].phrase->IsImportant())
return true;
@ -843,7 +815,7 @@ bool BotStatement::IsImportant() const
// Verify all attached conditions
bool BotStatement::IsValid() const
{
for (int i = 0; i < m_conditionCount; ++i)
for (int i = 0; i < m_conditionCount; i++)
{
switch (m_condition[i])
{
@ -961,7 +933,7 @@ void BotStatement::Convert(const BotStatement *say)
void BotStatement::AppendPhrase(const BotPhrase *phrase)
{
if (phrase == NULL)
if (!phrase)
return;
if (m_count < MAX_BOT_PHRASES)
@ -1025,7 +997,7 @@ bool BotStatement::Update()
// start next part of statement
float duration = 0.0f;
const BotPhrase *phrase = NULL;
const BotPhrase *phrase = nullptr;
if (m_statement[ m_index ].isPhrase)
{
@ -1071,7 +1043,7 @@ bool BotStatement::Update()
// dont report if there are lots of enemies left
if (enemyCount < 0 || enemyCount > 3)
{
phrase = NULL;
phrase = nullptr;
}
else
{
@ -1144,7 +1116,7 @@ bool BotStatement::Update()
if (sayIt)
{
if (filename == NULL)
if (!filename)
{
GameEventType radioEvent = phrase->GetRadioEquivalent();
if (radioEvent == EVENT_INVALID)
@ -1161,7 +1133,7 @@ bool BotStatement::Update()
}
else
{
me->Radio(filename, NULL, me->GetProfile()->GetVoicePitch(), false);
me->Radio(filename, nullptr, me->GetProfile()->GetVoicePitch(), false);
me->GetChatter()->ResetRadioSilenceDuration();
me->StartVoiceFeedback(duration + 1.0f);
}
@ -1190,7 +1162,7 @@ Place BotStatement::GetPlace() const
return m_place;
// look for an implicit place in our statement
for (int i = 0; i < m_count; ++i)
for (int i = 0; i < m_count; i++)
{
if (m_statement[i].isPhrase && m_statement[i].phrase->IsPlace())
return m_statement[i].phrase->GetID();
@ -1202,7 +1174,7 @@ Place BotStatement::GetPlace() const
// Return true if this statement has an associated count
bool BotStatement::HasCount() const
{
for (int i = 0; i < m_count; ++i)
for (int i = 0; i < m_count; i++)
{
if (!m_statement[i].isPhrase && m_statement[i].context == CURRENT_ENEMY_COUNT)
return true;
@ -1218,7 +1190,7 @@ static int nextPitch = P_HI;
BotChatterInterface::BotChatterInterface(CCSBot *me)
{
m_me = me;
m_statementList = NULL;
m_statementList = nullptr;
switch (nextPitch)
{
@ -1325,10 +1297,10 @@ void BotChatterInterface::AddStatement(BotStatement *statement, bool mustAdd)
// keep statements in order of start time
// check list is empty
if (m_statementList == NULL)
if (!m_statementList)
{
statement->m_next = NULL;
statement->m_prev = NULL;
statement->m_next = nullptr;
statement->m_prev = nullptr;
m_statementList = statement;
return;
}
@ -1336,7 +1308,7 @@ void BotChatterInterface::AddStatement(BotStatement *statement, bool mustAdd)
// list has at least one statement on it
// insert into list in order
BotStatement *earlier = NULL;
BotStatement *earlier = nullptr;
for (s = m_statementList; s; s = s->m_next)
{
if (s->GetStartTime() > statement->GetStartTime())
@ -1359,7 +1331,7 @@ void BotChatterInterface::AddStatement(BotStatement *statement, bool mustAdd)
else
{
// insert at head
statement->m_prev = NULL;
statement->m_prev = nullptr;
statement->m_next = m_statementList;
m_statementList->m_prev = statement;
m_statementList = statement;
@ -1430,7 +1402,7 @@ void BotChatterInterface::OnDeath()
if (pain)
{
m_me->Radio(pain->GetSpeakable(m_me->GetProfile()->GetVoiceBank()), NULL, m_me->GetProfile()->GetVoicePitch());
m_me->Radio(pain->GetSpeakable(m_me->GetProfile()->GetVoiceBank()), nullptr, m_me->GetProfile()->GetVoicePitch());
m_me->GetChatter()->ResetRadioSilenceDuration();
}
}
@ -1476,7 +1448,7 @@ void BotChatterInterface::Update()
// Remove redundant statements (ie: our teammates already said them)
const BotStatement *friendSay = GetActiveStatement();
if (friendSay && friendSay->GetOwner() == m_me)
friendSay = NULL;
friendSay = nullptr;
BotStatement *nextSay;
for (say = m_statementList; say; say = nextSay)
@ -1526,7 +1498,7 @@ BotStatement *BotChatterInterface::GetActiveStatement()
BotStatement *earliest = nullptr;
float earlyTime = 999999999.9f;
for (int i = 1; i <= gpGlobals->maxClients; ++i)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *player = UTIL_PlayerByIndex(i);
@ -2027,7 +1999,7 @@ void BotChatterInterface::RequestBombLocation()
void BotChatterInterface::BombsiteClear(int zoneIndex)
{
const CCSBotManager::Zone *zone = TheCSBots()->GetZone(zoneIndex);
if (zone == NULL)
if (!zone)
return;
BotStatement *say = new BotStatement(this, REPORT_INFORMATION, 10.0f);
@ -2041,7 +2013,7 @@ void BotChatterInterface::BombsiteClear(int zoneIndex)
void BotChatterInterface::FoundPlantedBomb(int zoneIndex)
{
const CCSBotManager::Zone *zone = TheCSBots()->GetZone(zoneIndex);
if (zone == NULL)
if (!zone)
return;
BotStatement *say = new BotStatement(this, REPORT_INFORMATION, 3.0f);

View File

@ -26,11 +26,7 @@
*
*/
#ifndef CS_BOT_CHATTER_H
#define CS_BOT_CHATTER_H
#ifdef _WIN32
#pragma once
#endif
#define UNDEFINED_COUNT 0xFFFF
#define MAX_PLACES_PER_MAP 64
@ -262,6 +258,9 @@ public:
// given a name, return the associated phrase collection
const BotPhrase *GetPhrase(const char *name) const;
// given an id, return the associated phrase collection
const BotPhrase *GetPhrase(unsigned int id) const;
// given a name, return the associated Place phrase collection
const BotPhrase *GetPlace(const char *name) const;
@ -585,7 +584,6 @@ inline BotStatement *BotChatterInterface::GetStatement() const
}
extern BotPhraseManager *TheBotPhrases;
extern CBaseEntity *g_pSelectedZombieSpawn;
inline void BotChatterInterface::Say(const char *phraseName, float lifetime, float delay)
{
@ -600,5 +598,3 @@ inline void BotChatterInterface::Say(const char *phraseName, float lifetime, flo
}
const Vector *GetRandomSpotAtPlace(Place place);
#endif // CS_BOT_CHATTER_H

View File

@ -33,7 +33,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
if (!IsAlive())
return;
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
CBasePlayer *pPlayer = static_cast<CBasePlayer *>(entity);
// If we just saw a nearby friend die, and we haven't yet acquired an enemy
// automatically acquire our dead friend's killer
@ -41,16 +41,16 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
{
if (event == EVENT_PLAYER_DIED)
{
if (BotRelationship(player) == BOT_TEAMMATE)
if (BotRelationship(pPlayer) == BOT_TEAMMATE)
{
CBasePlayer *killer = static_cast<CBasePlayer *>(other);
CBasePlayer *pKiller = static_cast<CBasePlayer *>(other);
// check that attacker is an enemy (for friendly fire, etc)
if (killer != NULL && killer->IsPlayer())
if (pKiller && pKiller->IsPlayer())
{
// check if we saw our friend die - dont check FOV - assume we're aware of our surroundings in combat
// snipers stay put
if (!IsSniper() && IsVisible(&player->pev->origin))
if (!IsSniper() && IsVisible(&pPlayer->pev->origin))
{
// people are dying - we should hurry
Hurry(RANDOM_FLOAT(10.0f, 15.0f));
@ -60,7 +60,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
if (!IsHiding() || !IsUsingKnife() || RANDOM_FLOAT(0, 100) < knifeAmbushChance)
{
PrintIfWatched("Attacking our friend's killer!\n");
Attack(killer);
Attack(pKiller);
return;
}
}
@ -73,26 +73,26 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
{
case EVENT_PLAYER_DIED:
{
CBasePlayer *victim = player;
CBasePlayer *killer = (other != NULL && other->IsPlayer()) ? static_cast<CBasePlayer *>(other) : NULL;
CBasePlayer *pVictim = pPlayer;
CBasePlayer *pKiller = (other && other->IsPlayer()) ? static_cast<CBasePlayer *>(other) : nullptr;
// if the human player died in the single player game, tell the team
if (CSGameRules()->IsCareer() && !victim->IsBot() && BotRelationship(victim) == BOT_TEAMMATE)
if (CSGameRules()->IsCareer() && !pVictim->IsBot() && BotRelationship(pVictim) == BOT_TEAMMATE)
{
GetChatter()->Say("CommanderDown", 20.0f);
}
// keep track of the last player we killed
if (killer == this)
if (pKiller == this)
{
m_lastVictimID = victim->entindex();
m_lastVictimID = pVictim->entindex();
}
// react to teammate death
if (BotRelationship(victim) == BOT_TEAMMATE)
if (BotRelationship(pVictim) == BOT_TEAMMATE)
{
// chastise friendly fire from humans
if (killer != NULL && !killer->IsBot() && BotRelationship(killer) == BOT_TEAMMATE && killer != this)
if (pKiller && !pKiller->IsBot() && BotRelationship(pKiller) == BOT_TEAMMATE && pKiller != this)
{
GetChatter()->KilledFriend();
}
@ -124,7 +124,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
// an enemy was killed
else
{
if (killer != NULL && BotRelationship(killer) == BOT_TEAMMATE)
if (pKiller && BotRelationship(pKiller) == BOT_TEAMMATE)
{
// only chatter about enemy kills if we see them occur, and they were the last one we see
if (GetNearbyEnemyCount() <= 1)
@ -132,13 +132,13 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
// report if number of enemies left is few and we killed the last one we saw locally
GetChatter()->EnemiesRemaining();
if (IsVisible(&victim->pev->origin, CHECK_FOV))
if (IsVisible(&pVictim->pev->origin, CHECK_FOV))
{
// congratulate teammates on their kills
if (killer != this)
if (pKiller != this)
{
float delay = RANDOM_FLOAT(2.0f, 3.0f);
if (killer->IsBot())
if (pKiller->IsBot())
{
if (RANDOM_FLOAT(0.0f, 100.0f) < 40.0f)
GetChatter()->Say("NiceShot", 3.0f, delay);
@ -172,11 +172,11 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
return;
case EVENT_BOMB_PICKED_UP:
{
if (m_iTeam == CT && player != NULL)
if (m_iTeam == CT && pPlayer)
{
// check if we're close enough to hear it
const float bombPickupHearRangeSq = 1000.0f * 1000.0f;
if ((pev->origin - player->pev->origin).LengthSquared() < bombPickupHearRangeSq)
if ((pev->origin - pPlayer->pev->origin).LengthSquared() < bombPickupHearRangeSq)
{
GetChatter()->TheyPickedUpTheBomb();
}
@ -196,8 +196,10 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
if (m_iTeam == CT && GetGameState()->GetPlantedBombsite() == CSGameState::UNKNOWN)
{
const CCSBotManager::Zone *zone = TheCSBots()->GetZone(&entity->pev->origin);
if (zone != NULL)
if (zone)
{
GetChatter()->FoundPlantedBomb(zone->m_index);
}
}
// remember where the bomb is
@ -240,20 +242,20 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
}
// Process radio events from our team
if (player != NULL && BotRelationship(player) == BOT_TEAMMATE && event > EVENT_START_RADIO_1 && event < EVENT_END_RADIO)
if (pPlayer && BotRelationship(pPlayer) == BOT_TEAMMATE && event > EVENT_START_RADIO_1 && event < EVENT_END_RADIO)
{
// TODO: Distinguish between radio commands and responses
if (event != EVENT_RADIO_AFFIRMATIVE && event != EVENT_RADIO_NEGATIVE && event != EVENT_RADIO_REPORTING_IN)
{
m_lastRadioCommand = event;
m_lastRadioRecievedTimestamp = gpGlobals->time;
m_radioSubject = player;
m_radioPosition = player->pev->origin;
m_radioSubject = pPlayer;
m_radioPosition = pPlayer->pev->origin;
}
}
// player_follows needs a player
if (player == NULL)
if (!pPlayer)
return;
if (!IsRogue() && event == EVENT_HOSTAGE_CALLED_FOR_HELP && m_iTeam == CT && IsHunting())
@ -264,7 +266,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
if (IsVisible(&entity->Center()))
{
m_task = COLLECT_HOSTAGES;
m_taskEntity = NULL;
m_taskEntity = nullptr;
Run();
m_goalEntity = entity;
@ -277,7 +279,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
}
// don't pay attention to noise that friends make
if (!IsEnemy(player))
if (!IsEnemy(pPlayer))
return;
float range;
@ -300,7 +302,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
if (!GetGameState()->GetNearestVisibleFreeHostage() && m_task != GUARD_HOSTAGE_RESCUE_ZONE && GuardRandomZone())
{
m_task = GUARD_HOSTAGE_RESCUE_ZONE;
m_taskEntity = NULL;
m_taskEntity = nullptr;
SetDisposition(OPPORTUNITY_FIRE);
PrintIfWatched("Trying to beat them to an escape zone!\n");
@ -308,7 +310,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
}
// check if noise is close enough for us to hear
const Vector *newNoisePosition = &player->pev->origin;
const Vector *newNoisePosition = &pPlayer->pev->origin;
float newNoiseDist = (pev->origin - *newNoisePosition).Length();
if (newNoiseDist < range)
{
@ -317,7 +319,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
{
PrintIfWatched("Heard noise (%s from %s, pri %s, time %3.1f)\n",
(event == EVENT_WEAPON_FIRED) ? "Weapon fire " : "",
STRING(player->pev->netname),
STRING(pPlayer->pev->netname),
(priority == PRIORITY_HIGH) ? "HIGH" : ((priority == PRIORITY_MEDIUM) ? "MEDIUM" : "LOW"),
gpGlobals->time);
}
@ -343,16 +345,15 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
}
}
// find the area in which the noise occured
// TODO: Better handle when noise occurs off the nav mesh
// TODO: Make sure noise area is not through a wall or ceiling from source of noise
// TODO: Change GetNavTravelTime to better deal with NULL destination areas
CNavArea *noiseArea = TheNavAreaGrid.GetNavArea(newNoisePosition);
if (noiseArea == NULL)
if (!noiseArea)
noiseArea = TheNavAreaGrid.GetNearestNavArea(newNoisePosition);
if (noiseArea == NULL)
if (!noiseArea)
{
PrintIfWatched(" *** Noise occurred off the nav mesh - ignoring!\n");
return;
@ -377,6 +378,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
m_noiseArea->GetClosestPointOnArea(&m_noisePosition, &m_noisePosition);
m_isNoiseTravelRangeChecked = false;
// note when we heard the noise
m_noiseTimestamp = gpGlobals->time;
}

View File

@ -5,46 +5,46 @@
*/
#ifndef HOOK_GAMEDLL
cvar_t cv_bot_traceview = { "bot_traceview", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_stop = { "bot_stop", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_show_nav = { "bot_show_nav", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_show_danger = { "bot_show_danger", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_nav_edit = { "bot_nav_edit", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_nav_zdraw = { "bot_nav_zdraw", "4", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_walk = { "bot_walk", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_difficulty = { "bot_difficulty", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_debug = { "bot_debug", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_quicksave = { "bot_quicksave", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_quota = { "bot_quota", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_quota_match = { "bot_quota_match", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_prefix = { "bot_prefix", "", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_rogues = { "bot_allow_rogues", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_pistols = { "bot_allow_pistols", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_shotguns = { "bot_allow_shotguns", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_sub_machine_guns = { "bot_allow_sub_machine_guns", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_rifles = { "bot_allow_rifles", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_machine_guns = { "bot_allow_machine_guns", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_grenades = { "bot_allow_grenades", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_snipers = { "bot_allow_snipers", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_allow_shield = { "bot_allow_shield", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_join_team = { "bot_join_team", "any", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_join_after_player = { "bot_join_after_player", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_auto_vacate = { "bot_auto_vacate", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_zombie = { "bot_zombie", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_defer_to_human = { "bot_defer_to_human", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_chatter = { "bot_chatter", "normal", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_profile_db = { "bot_profile_db", "BotProfile.db", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_traceview = { "bot_traceview", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_stop = { "bot_stop", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_show_nav = { "bot_show_nav", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_show_danger = { "bot_show_danger", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_nav_edit = { "bot_nav_edit", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_nav_zdraw = { "bot_nav_zdraw", "4", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_walk = { "bot_walk", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_difficulty = { "bot_difficulty", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_debug = { "bot_debug", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_quicksave = { "bot_quicksave", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_quota = { "bot_quota", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_quota_match = { "bot_quota_match", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_prefix = { "bot_prefix", "", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_rogues = { "bot_allow_rogues", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_pistols = { "bot_allow_pistols", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_shotguns = { "bot_allow_shotguns", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_sub_machine_guns = { "bot_allow_sub_machine_guns", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_rifles = { "bot_allow_rifles", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_machine_guns = { "bot_allow_machine_guns", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_grenades = { "bot_allow_grenades", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_snipers = { "bot_allow_snipers", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_allow_shield = { "bot_allow_shield", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_join_team = { "bot_join_team", "any", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_join_after_player = { "bot_join_after_player", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_auto_vacate = { "bot_auto_vacate", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_zombie = { "bot_zombie", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_defer_to_human = { "bot_defer_to_human", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_chatter = { "bot_chatter", "normal", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_profile_db = { "bot_profile_db", "BotProfile.db", FCVAR_SERVER, 0.0f, nullptr };
#endif
#ifdef REGAMEDLL_ADD
cvar_t cv_bot_deathmatch = { "bot_deathmatch", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_quota_mode = { "bot_quota_mode", "normal", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_bot_deathmatch = { "bot_deathmatch", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_quota_mode = { "bot_quota_mode", "normal", FCVAR_SERVER, 0.0f, nullptr };
#endif
void InstallBotControl()
{
if (TheBots != NULL)
if (TheBots)
{
delete TheBots;
}
@ -55,7 +55,7 @@ void InstallBotControl()
// Engine callback for custom server commands
void Bot_ServerCommand()
{
if (TheBots != NULL)
if (TheBots)
{
const char *pcmd = CMD_ARGV(0);
TheBots->ServerCommand(pcmd);
@ -122,8 +122,8 @@ bool CCSBot::Initialize(const BotProfile *profile)
m_combatRange = RANDOM_FLOAT(325, 425);
m_navNodeList = NULL;
m_currentNode = NULL;
m_navNodeList = nullptr;
m_currentNode = nullptr;
// set initial safe time guess for this map
m_safeTime = 15.0f + 5.0f * GetProfile()->GetAggression();
@ -142,7 +142,7 @@ void CCSBot::ResetValues()
m_chatter.Reset();
m_gameState.Reset();
m_avoid = NULL;
m_avoid = nullptr;
m_avoidTimestamp = 0.0f;
m_hurryTimer.Invalidate();
@ -155,8 +155,8 @@ void CCSBot::ResetValues()
m_pathLength = 0;
m_pathIndex = 0;
m_areaEnteredTimestamp = 0.0f;
m_currentArea = NULL;
m_lastKnownArea = NULL;
m_currentArea = nullptr;
m_lastKnownArea = nullptr;
m_avoidFriendTimer.Invalidate();
m_isFriendInTheWay = false;
@ -164,7 +164,7 @@ void CCSBot::ResetValues()
m_disposition = ENGAGE_AND_INVESTIGATE;
m_enemy = NULL;
m_enemy = nullptr;
m_isWaitingToTossGrenade = false;
m_wasSafe = true;
@ -172,10 +172,10 @@ void CCSBot::ResetValues()
m_nearbyEnemyCount = 0;
m_enemyPlace = 0;
m_nearbyFriendCount = 0;
m_closestVisibleFriend = NULL;
m_closestVisibleHumanFriend = NULL;
m_closestVisibleFriend = nullptr;
m_closestVisibleHumanFriend = nullptr;
for (int w = 0; w < ARRAYSIZE(m_watchInfo); ++w)
for (int w = 0; w < ARRAYSIZE(m_watchInfo); w++)
{
m_watchInfo[w].timestamp = 0.0f;
m_watchInfo[w].isEnemy = false;
@ -187,7 +187,7 @@ void CCSBot::ResetValues()
m_firstSawEnemyTimestamp = 0.0f;
m_currentEnemyAcquireTimestamp = 0.0f;
m_isLastEnemyDead = true;
m_attacker = NULL;
m_attacker = nullptr;
m_attackedTimestamp = 0.0f;
m_enemyDeathTimestamp = 0.0f;
m_lastVictimID = 0;
@ -196,14 +196,14 @@ void CCSBot::ResetValues()
m_equipTimer.Invalidate();
m_isFollowing = false;
m_leader = NULL;
m_leader = nullptr;
m_followTimestamp = 0.0f;
m_allowAutoFollowTime = 0.0f;
m_enemyQueueIndex = 0;
m_enemyQueueCount = 0;
m_enemyQueueAttendIndex = 0;
m_bomber = NULL;
m_bomber = nullptr;
m_lookAroundStateTimestamp = 0.0f;
m_inhibitLookAroundTimestamp = 0.0f;
@ -217,19 +217,19 @@ void CCSBot::ResetValues()
m_aimSpreadTimestamp = 0.0f;
m_lookAtSpotState = NOT_LOOKING_AT_SPOT;
m_spotEncounter = NULL;
m_spotEncounter = nullptr;
m_spotCheckTimestamp = 0.0f;
m_peripheralTimestamp = 0.0f;
m_avgVelIndex = 0;
m_avgVelCount = 0;
m_lastOrigin = (pev != NULL) ? pev->origin : Vector(0, 0, 0);
m_lastOrigin = pev ? pev->origin : Vector(0, 0, 0);
m_lastRadioCommand = EVENT_INVALID;
m_lastRadioRecievedTimestamp = 0.0f;
m_lastRadioSentTimestamp = 0.0f;
m_radioSubject = NULL;
m_radioSubject = nullptr;
m_voiceFeedbackEndTimestamp = 0.0f;
m_hostageEscortCount = 0;
@ -242,7 +242,7 @@ void CCSBot::ResetValues()
m_stateTimestamp = 0.0f;
m_task = SEEK_AND_DESTROY;
m_taskEntity = NULL;
m_taskEntity = nullptr;
m_approachPointCount = 0;
m_approachPointViewPosition = Vector(0, 0, 0);
@ -254,7 +254,7 @@ void CCSBot::ResetValues()
Run();
m_mustRunTimer.Invalidate();
m_repathTimer.Invalidate();
m_pathLadder = NULL;
m_pathLadder = nullptr;
m_huntState.ClearHuntArea();
@ -272,14 +272,14 @@ void CCSBot::ResetValues()
m_surpriseTimestamp = 0.0f;
// even though these are EHANDLEs, they need to be NULL-ed
m_goalEntity = NULL;
m_avoid = NULL;
m_enemy = NULL;
m_goalEntity = nullptr;
m_avoid = nullptr;
m_enemy = nullptr;
#ifdef REGAMEDLL_FIXES
for (int i = 0; i < MAX_ENEMY_QUEUE; ++i)
for (int i = 0; i < MAX_ENEMY_QUEUE; i++)
{
m_enemyQueue[i].player = NULL;
m_enemyQueue[i].player = nullptr;
m_enemyQueue[i].isReloading = false;
m_enemyQueue[i].isProtectedByShield = false;
}

View File

@ -42,13 +42,13 @@ inline CNavNode *LadderEndSearch(CBaseEntity *entity, const Vector *pos, NavDirT
continue;
// if no node exists here, create one and continue the search
if (CNavNode::GetNode(&tryPos) == NULL)
if (!CNavNode::GetNode(&tryPos))
{
return new CNavNode(&tryPos, &tryNormal, NULL);
return new CNavNode(&tryPos, &tryNormal, nullptr);
}
}
return NULL;
return nullptr;
}
CNavNode *CCSBot::AddNode(const Vector *destPos, const Vector *normal, NavDirType dir, CNavNode *source)
@ -58,7 +58,7 @@ CNavNode *CCSBot::AddNode(const Vector *destPos, const Vector *normal, NavDirTyp
// if no node exists, create one
bool useNew = false;
if (node == NULL)
if (!node)
{
node = new CNavNode(destPos, normal, source);
useNew = true;
@ -118,7 +118,7 @@ CNavNode *CCSBot::AddNode(const Vector *destPos, const Vector *normal, NavDirTyp
void drawProgressMeter(float progress, char *title)
{
MESSAGE_BEGIN(MSG_ALL, gmsgBotProgress);
WRITE_BYTE(FLAG_PROGRESS_DRAW);
WRITE_BYTE(BOT_PROGGRESS_DRAW);
WRITE_BYTE(int(progress * 100.0f));
WRITE_STRING(title);
MESSAGE_END();
@ -127,7 +127,7 @@ void drawProgressMeter(float progress, char *title)
void startProgressMeter(const char *title)
{
MESSAGE_BEGIN(MSG_ALL, gmsgBotProgress);
WRITE_BYTE(FLAG_PROGRESS_START);
WRITE_BYTE(BOT_PROGGRESS_START);
WRITE_STRING(title);
MESSAGE_END();
}
@ -135,7 +135,7 @@ void startProgressMeter(const char *title)
void hideProgressMeter()
{
MESSAGE_BEGIN(MSG_ALL, gmsgBotProgress);
WRITE_BYTE(FLAG_PROGRESS_HIDE);
WRITE_BYTE(BOT_PROGGRESS_HIDE);
MESSAGE_END();
}
@ -173,14 +173,11 @@ bool CCSBot::LearnStep()
// take a step
while (true)
{
if (m_currentNode == NULL)
if (!m_currentNode)
{
// search is exhausted - continue search from ends of ladders
NavLadderList::iterator iter;
for (iter = TheNavLadderList.begin(); iter != TheNavLadderList.end(); ++iter)
for (auto ladder : TheNavLadderList)
{
CNavLadder *ladder = (*iter);
// check ladder bottom
if ((m_currentNode = LadderEndSearch(ladder->m_entity, &ladder->m_bottom, ladder->m_dir)) != 0)
break;
@ -190,7 +187,7 @@ bool CCSBot::LearnStep()
break;
}
if (m_currentNode == NULL)
if (!m_currentNode)
{
// all seeds exhausted, sampling complete
GenerateNavigationAreaMesh();
@ -215,10 +212,10 @@ bool CCSBot::LearnStep()
// attempt to move to adjacent node
switch (dir)
{
case NORTH: cy -= GenerationStepSize; break;
case SOUTH: cy += GenerationStepSize; break;
case EAST: cx += GenerationStepSize; break;
case WEST: cx -= GenerationStepSize; break;
case NORTH: cy -= GenerationStepSize; break;
case SOUTH: cy += GenerationStepSize; break;
case EAST: cx += GenerationStepSize; break;
case WEST: cx -= GenerationStepSize; break;
}
pos.x = cx;
@ -324,7 +321,7 @@ bool CCSBot::LearnStep()
#ifdef REGAMEDLL_FIXES
// if we're incrementally generating, don't overlap existing nav areas
CNavArea *overlap = TheNavAreaGrid.GetNavArea(&to, HumanHeight);
if (overlap != NULL)
if (overlap)
{
walkable = false;
}
@ -375,14 +372,14 @@ void CCSBot::StartAnalyzeAlphaProcess()
bool CCSBot::AnalyzeAlphaStep()
{
++_currentIndex;
_currentIndex++;
if (m_analyzeIter == TheNavAreaList.end())
return false;
CNavArea *area = (*m_analyzeIter);
area->ComputeHidingSpots();
area->ComputeApproachAreas();
++m_analyzeIter;
m_analyzeIter++;
return true;
}
@ -416,14 +413,14 @@ void CCSBot::StartAnalyzeBetaProcess()
bool CCSBot::AnalyzeBetaStep()
{
++_currentIndex;
_currentIndex++;
if (m_analyzeIter == TheNavAreaList.end())
return false;
CNavArea *area = (*m_analyzeIter);
area->ComputeSpotEncounters();
area->ComputeSniperSpots();
++m_analyzeIter;
m_analyzeIter++;
return true;
}
@ -473,7 +470,7 @@ void CCSBot::UpdateSaveProcess()
#ifndef REGAMEDLL_FIXES
Q_sprintf(cmd, "map %s\n", STRING(gpGlobals->mapname));
#else
Q_sprintf(cmd, "changelevel %s\n", STRING(gpGlobals->mapname));
Q_snprintf(cmd, sizeof(cmd), "changelevel %s\n", STRING(gpGlobals->mapname));
#endif
SERVER_COMMAND(cmd);

View File

@ -88,7 +88,7 @@ bool CCSBot::CanHearNearbyEnemyGunfire(float range) const
if (!CanSeeNoisePosition())
return false;
if (IsAttacking() && m_enemy != NULL)
if (IsAttacking() && m_enemy)
{
// gunfire is only threatening if it is closer than our current enemy
float gunfireDistSq = (m_noisePosition - pev->origin).LengthSquared();
@ -148,14 +148,13 @@ bool CCSBot::UpdateLookAtNoise()
else
{
// line of sight is blocked, bend it
if (m_approachPointCount == 0)
return false;
int nearIdx = -1;
float nearRangeSq = 9.9999998e10f;
for (int i = 0; i < m_approachPointCount; ++i)
for (int i = 0; i < m_approachPointCount; i++)
{
float distanceSq = (m_approachPoint[i] - m_noisePosition).LengthSquared();

View File

@ -5,7 +5,7 @@
*/
#ifndef HOOK_GAMEDLL
CBotManager *TheBots = NULL;
CBotManager *TheBots = nullptr;
float CCSBotManager::m_flNextCVarCheck = 0.0f;
bool CCSBotManager::m_isMapDataLoaded = false;
@ -20,10 +20,10 @@ CCSBotManager::CCSBotManager()
IMPL(m_flNextCVarCheck) = 0.0f;
m_zoneCount = 0;
SetLooseBomb(NULL);
SetLooseBomb(nullptr);
m_isBombPlanted = false;
m_bombDefuser = NULL;
m_bombDefuser = nullptr;
IMPL(m_isLearningMap) = false;
IMPL(m_isAnalysisRequested) = false;
@ -55,15 +55,14 @@ CCSBotManager::CCSBotManager()
// read in the list of bot profile DBs
int dataLength;
char *dataPointer = (char *)LOAD_FILE_FOR_ME((char *)filename, &dataLength);
if (dataPointer == NULL)
if (!dataPointer)
{
TheBotProfiles->Init("BotProfile.db");
}
else
{
const char *dataFile = SharedParse(dataPointer);
const char *token;
char *dataFile = SharedParse(dataPointer);
char *token;
while (dataFile)
{
@ -80,7 +79,7 @@ CCSBotManager::CCSBotManager()
// Now that we've parsed all the profiles, we have a list of the voice banks they're using.
// Go back and parse the custom voice speakables.
const BotProfileManager::VoiceBankList *pVoiceBanks = TheBotProfiles->GetVoiceBanks();
for (uint32 i = 1; i < pVoiceBanks->size(); ++i)
for (uint32 i = 1; i < pVoiceBanks->size(); i++)
{
TheBotPhrases->Initialize((*pVoiceBanks)[i], i);
}
@ -92,10 +91,10 @@ void CCSBotManager::RestartRound()
// extend
CBotManager::RestartRound();
SetLooseBomb(NULL);
SetLooseBomb(nullptr);
m_isBombPlanted = false;
m_earliestBombPlantTimestamp = gpGlobals->time + RANDOM_FLOAT(10.0f, 30.0f);
m_bombDefuser = NULL;
m_bombDefuser = nullptr;
IMPL(m_editCmd) = EDIT_NONE;
@ -141,7 +140,7 @@ void UTIL_DrawBox(Extent *extent, int lifetime, int red, int green, int blue)
Vector from, to;
bool restart = true;
for (int i = 0; edge[i] != 0; ++i)
for (int i = 0; edge[i] != 0; i++)
{
if (restart)
{
@ -177,7 +176,7 @@ void CCSBotManager::StartFrame()
// debug zone extent visualization
if (cv_bot_debug.value == 5.0f)
{
for (int z = 0; z < m_zoneCount; ++z)
for (int z = 0; z < m_zoneCount; z++)
{
Zone *zone = &m_zone[z];
UTIL_DrawBox(&zone->m_extent, 1, 255, 100, 0);
@ -188,7 +187,7 @@ void CCSBotManager::StartFrame()
// Return true if the bot can use this weapon
bool CCSBotManager::IsWeaponUseable(CBasePlayerItem *item) const
{
if (item == NULL)
if (!item)
{
return false;
}
@ -351,7 +350,7 @@ void CCSBotManager::ClientDisconnect(CBasePlayer *pPlayer)
void PrintAllEntities()
{
for (int i = 1; i < gpGlobals->maxEntities; ++i)
for (int i = 1; i < gpGlobals->maxEntities; i++)
{
edict_t *edict = INDEXENT(i);
@ -396,11 +395,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
else
killThemAll = false;
for (int iIndex = 1; iIndex <= gpGlobals->maxClients; ++iIndex)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex(iIndex);
if (pPlayer == NULL)
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
if (!pPlayer)
continue;
if (FNullEnt(pPlayer->pev))
@ -431,11 +429,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
else
kickThemAll = false;
for (int iIndex = 1; iIndex <= gpGlobals->maxClients; ++iIndex)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex(iIndex);
if (pPlayer == NULL)
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
if (!pPlayer)
continue;
if (FNullEnt(pPlayer->pev))
@ -593,10 +590,8 @@ void CCSBotManager::ServerCommand(const char *pcmd)
// no arguments = list all available places
int i = 0;
const BotPhraseList *placeList = TheBotPhrases->GetPlaceList();
for (BotPhraseList::const_iterator iter = placeList->begin(); iter != placeList->end(); ++iter, ++i)
for (auto phrase : *placeList)
{
const BotPhrase *phrase = (*iter);
if (phrase->GetID() == GetNavPlace())
CONSOLE_ECHO("--> %-26s", phrase->GetName());
else
@ -604,6 +599,7 @@ void CCSBotManager::ServerCommand(const char *pcmd)
if (!(i % 3))
CONSOLE_ECHO("\n");
i++;
}
CONSOLE_ECHO("\n");
}
@ -611,12 +607,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
{
// single argument = set current place
const BotPhraseList *placeList = TheBotPhrases->GetPlaceList();
const BotPhrase *found = NULL;
const BotPhrase *found = nullptr;
bool isAmbiguous = false;
for (BotPhraseList::const_iterator iter = placeList->begin(); iter != placeList->end(); ++iter)
for (auto phrase : *placeList)
{
const BotPhrase *phrase = (*iter);
if (!Q_strnicmp(phrase->GetName(), msg, Q_strlen(msg)))
{
// check for exact match in case of subsets of other strings
@ -671,7 +665,7 @@ void CCSBotManager::ServerCommand(const char *pcmd)
CNavArea *area = GetMarkedArea();
if (area)
{
CBaseEntity *pEntity = NULL;
CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
{
if (!pEntity->IsPlayer())
@ -709,14 +703,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
sizeof(HidingSpot) * TheHidingSpotList.size());
unsigned int encounterMem = 0;
for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
for (auto area : TheNavAreaList)
{
CNavArea *area = (*iter);
for (SpotEncounterList::iterator siter = area->m_spotEncounterList.begin(); siter != area->m_spotEncounterList.end(); ++siter)
for (auto se : area->m_spotEncounterList)
{
SpotEncounter se = (*siter);
encounterMem += sizeof(SpotEncounter);
encounterMem += sizeof(SpotOrder) * se.spotList.size();
}
@ -775,7 +765,7 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
if (IMPL(m_isLearningMap))
return false;
const BotProfile *profile = NULL;
const BotProfile *profile = nullptr;
if (!isFromConsole || CMD_ARGC() < 2)
{
@ -800,8 +790,7 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
// try to add a bot by name
profile = TheBotProfiles->GetRandomProfile(GetDifficultyLevel(), team);
if (profile == NULL)
if (!profile)
{
CONSOLE_ECHO("All bot profiles at this difficulty level are in use.\n");
return true;
@ -821,7 +810,7 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
}
profile = TheBotProfiles->GetProfile(CMD_ARGV(1), team);
if (profile == NULL)
if (!profile)
{
CONSOLE_ECHO("Error - no profile for '%s' exists.\n", CMD_ARGV(1));
return true;
@ -1038,50 +1027,48 @@ void CCSBotManager::ValidateMapData()
m_gameScenario = SCENARIO_DEATHMATCH;
// Search all entities in the map and set the game type and store all zones (bomb target, etc).
CBaseEntity *entity = NULL;
int i;
for (i = 1; i < gpGlobals->maxEntities; ++i)
CBaseEntity *pEntity = nullptr;
for (int i = 1; i < gpGlobals->maxEntities; i++)
{
entity = CBaseEntity::Instance(INDEXENT(i));
if (entity == NULL)
pEntity = CBaseEntity::Instance(INDEXENT(i));
if (!pEntity)
continue;
bool found = false;
bool isLegacy = false;
if (FClassnameIs(entity->pev, "func_bomb_target"))
if (FClassnameIs(pEntity->pev, "func_bomb_target"))
{
m_gameScenario = SCENARIO_DEFUSE_BOMB;
found = true;
isLegacy = false;
}
else if (FClassnameIs(entity->pev, "info_bomb_target"))
else if (FClassnameIs(pEntity->pev, "info_bomb_target"))
{
m_gameScenario = SCENARIO_DEFUSE_BOMB;
found = true;
isLegacy = true;
}
else if (FClassnameIs(entity->pev, "func_hostage_rescue"))
else if (FClassnameIs(pEntity->pev, "func_hostage_rescue"))
{
m_gameScenario = SCENARIO_RESCUE_HOSTAGES;
found = true;
isLegacy = false;
}
else if (FClassnameIs(entity->pev, "info_hostage_rescue"))
else if (FClassnameIs(pEntity->pev, "info_hostage_rescue"))
{
m_gameScenario = SCENARIO_RESCUE_HOSTAGES;
found = true;
isLegacy = true;
}
else if (FClassnameIs(entity->pev, "hostage_entity"))
else if (FClassnameIs(pEntity->pev, "hostage_entity"))
{
// some very old maps (ie: cs_assault) use info_player_start
// as rescue zones, so set the scenario if there are hostages
// in the map
m_gameScenario = SCENARIO_RESCUE_HOSTAGES;
}
else if (FClassnameIs(entity->pev, "func_vip_safetyzone"))
else if (FClassnameIs(pEntity->pev, "func_vip_safetyzone"))
{
m_gameScenario = SCENARIO_ESCORT_VIP;
found = true;
@ -1092,14 +1079,16 @@ void CCSBotManager::ValidateMapData()
{
if (m_zoneCount < MAX_ZONES)
{
m_zone[ m_zoneCount ].m_center = (isLegacy) ? entity->pev->origin : (entity->pev->absmax + entity->pev->absmin) / 2.0f;
m_zone[ m_zoneCount ].m_center = isLegacy ? pEntity->pev->origin : (pEntity->pev->absmax + pEntity->pev->absmin) / 2.0f;
m_zone[ m_zoneCount ].m_isLegacy = isLegacy;
m_zone[ m_zoneCount ].m_index = m_zoneCount;
m_zone[ m_zoneCount ].m_entity = entity;
m_zone[ m_zoneCount ].m_entity = pEntity;
m_zoneCount++;
}
else
{
CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n");
}
}
}
@ -1107,33 +1096,35 @@ void CCSBotManager::ValidateMapData()
// use the info_player_start entities as rescue zones.
if (m_zoneCount == 0 && m_gameScenario == SCENARIO_RESCUE_HOSTAGES)
{
entity = NULL;
pEntity = nullptr;
while ((entity = UTIL_FindEntityByClassname(entity, "info_player_start")))
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "info_player_start")))
{
#ifdef REGAMEDLL_FIXES
if (m_zoneCount >= MAX_ZONES)
break;
#endif
if (FNullEnt(entity->edict()))
if (FNullEnt(pEntity->edict()))
break;
if (m_zoneCount < MAX_ZONES)
{
m_zone[ m_zoneCount ].m_center = entity->pev->origin;
m_zone[ m_zoneCount ].m_center = pEntity->pev->origin;
m_zone[ m_zoneCount ].m_isLegacy = true;
m_zone[ m_zoneCount ].m_index = m_zoneCount;
m_zone[ m_zoneCount ].m_entity = entity;
m_zone[ m_zoneCount ].m_entity = pEntity;
m_zoneCount++;
}
else
{
CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n");
}
}
}
// Collect nav areas that overlap each zone
for (i = 0; i < m_zoneCount; ++i)
for (int i = 0; i < m_zoneCount; i++)
{
Zone *zone = &m_zone[i];
@ -1203,7 +1194,7 @@ bool CCSBotManager::AddBot(const BotProfile *profile, BotProfileTeamType team)
}
CCSBot *pBot = CreateBot<CCSBot, CAPI_CSBot>(profile);
if (pBot == NULL)
if (!pBot)
{
return false;
}
@ -1233,14 +1224,13 @@ bool CCSBotManager::AddBot(const BotProfile *profile, BotProfileTeamType team)
SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", STRING(pBot->pev->netname)));
CONSOLE_ECHO("Could not add bot to the game.\n");
return false;
}
// Return the zone that contains the given position
const CCSBotManager::Zone *CCSBotManager::GetZone(const Vector *pos) const
{
for (int z = 0; z < m_zoneCount; ++z)
for (int z = 0; z < m_zoneCount; z++)
{
if (m_zone[z].m_extent.Contains(pos))
{
@ -1248,16 +1238,16 @@ const CCSBotManager::Zone *CCSBotManager::GetZone(const Vector *pos) const
}
}
return NULL;
return nullptr;
}
// Return the closest zone to the given position
const CCSBotManager::Zone *CCSBotManager::GetClosestZone(const Vector *pos) const
{
const Zone *close = NULL;
const Zone *close = nullptr;
float closeRangeSq = 1e9f;
for (int z = 0; z < m_zoneCount; ++z)
for (int z = 0; z < m_zoneCount; z++)
{
float rangeSq = (m_zone[z].m_center - (*pos)).LengthSquared();
@ -1276,11 +1266,11 @@ const Vector *CCSBotManager::GetRandomPositionInZone(const Zone *zone) const
{
static Vector pos;
if (zone == NULL)
return NULL;
if (!zone)
return nullptr;
if (zone->m_areaCount == 0)
return NULL;
return nullptr;
// pick a random overlapping area
CNavArea *area = GetRandomAreaInZone(zone);
@ -1314,7 +1304,7 @@ CNavArea *CCSBotManager::GetRandomAreaInZone(const Zone *zone) const
{
// TODO: improvement is needed
if (!zone->m_areaCount)
return NULL;
return nullptr;
return zone->m_area[ RANDOM_LONG(0, zone->m_areaCount - 1) ];
}
@ -1333,12 +1323,12 @@ void CCSBotManager::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntit
break;
case EVENT_BOMB_DEFUSE_ABORTED:
m_bombDefuser = NULL;
m_bombDefuser = nullptr;
break;
case EVENT_BOMB_DEFUSED:
m_isBombPlanted = false;
m_bombDefuser = NULL;
m_bombDefuser = nullptr;
break;
case EVENT_TERRORISTS_WIN:
@ -1375,7 +1365,7 @@ void CCSBotManager::SetLooseBomb(CBaseEntity *bomb)
}
else
{
m_looseBombArea = NULL;
m_looseBombArea = nullptr;
}
}
@ -1492,13 +1482,7 @@ void CCSBotManager::SetRadioMessageTimestamp(GameEventType event, int teamID)
// Reset all radio message timestamps
void CCSBotManager::ResetRadioMessageTimestamps()
{
for (int t = 0; t < ARRAYSIZE(m_radioMsgTimestamp[0]); ++t)
{
for (int m = 0; m < ARRAYSIZE(m_radioMsgTimestamp); ++m)
{
m_radioMsgTimestamp[m][t] = 0.0f;
}
}
Q_memset(m_radioMsgTimestamp, 0, sizeof(m_radioMsgTimestamp));
}
void CCSBotManager::OnFreeEntPrivateData(CBaseEntity *pEntity)
@ -1513,10 +1497,10 @@ void CCSBotManager::OnFreeEntPrivateData(CBaseEntity *pEntity)
{
CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
if (pBot->m_attacker == pEntity)
pBot->m_attacker = NULL;
pBot->m_attacker = nullptr;
if (pBot->m_bomber == pEntity)
pBot->m_bomber = NULL;
pBot->m_bomber = nullptr;
}
}
}

View File

@ -26,11 +26,7 @@
*
*/
#ifndef CS_BOT_MANAGER_H
#define CS_BOT_MANAGER_H
#ifdef _WIN32
#pragma once
#endif
extern CBotManager *TheBots;
@ -134,7 +130,7 @@ public:
if (startArea == nullptr)
return nullptr;
for (int i = 0; i < m_zoneCount; ++i)
for (int i = 0; i < m_zoneCount; i++)
{
if (m_zone[i].m_areaCount == 0)
continue;
@ -269,5 +265,3 @@ inline bool AreBotsAllowed()
void PrintAllEntities();
void UTIL_DrawBox(Extent *extent, int lifetime, int red, int green, int blue);
#endif // CS_BOT_MANAGER_H

View File

@ -64,7 +64,7 @@ void CCSBot::StuckCheck()
{
// we have enough samples to know if we're stuck
float avgVel = 0.0f;
for (int t = 0; t < m_avgVelCount; ++t)
for (int t = 0; t < m_avgVelCount; t++)
avgVel += m_avgVel[t];
avgVel /= m_avgVelCount;
@ -140,7 +140,7 @@ bool CCSBot::GetSimpleGroundHeightWithFloor(const Vector *pos, float *height, Ve
if (GetSimpleGroundHeight(pos, height, normal))
{
// our current nav area also serves as a ground polygon
if (m_lastKnownArea != NULL && m_lastKnownArea->IsOverlapping(pos))
if (m_lastKnownArea && m_lastKnownArea->IsOverlapping(pos))
{
*height = Q_max((*height), m_lastKnownArea->GetZ(pos));
}
@ -153,8 +153,10 @@ bool CCSBot::GetSimpleGroundHeightWithFloor(const Vector *pos, float *height, Ve
Place CCSBot::GetPlace() const
{
if (m_lastKnownArea != NULL)
if (m_lastKnownArea)
{
return m_lastKnownArea->GetPlace();
}
return UNDEFINED_PLACE;
}
@ -169,7 +171,7 @@ void CCSBot::MoveTowardsPosition(const Vector *pos)
// NOTE: We need to do this frequently to catch edges at the right time
// TODO: Look ahead *along path* instead of straight line
if ((m_lastKnownArea == NULL || !(m_lastKnownArea->GetAttributes() & NAV_NO_JUMP))
if ((!m_lastKnownArea || !(m_lastKnownArea->GetAttributes() & NAV_NO_JUMP))
&& !IsOnLadder() && !m_isJumpCrouching)
{
float ground;
@ -243,7 +245,7 @@ void CCSBot::MoveTowardsPosition(const Vector *pos)
MoveBackward();
// if we are avoiding someone via strafing, don't override
if (m_avoid != NULL)
if (m_avoid)
return;
if (latProj >= c)
@ -294,12 +296,27 @@ void CCSBot::StrafeAwayFromPosition(const Vector *pos)
Vector2D to(pos->x - pev->origin.x, pos->y - pev->origin.y);
to.NormalizeInPlace();
// move away from the position independant of our view direction
float toProj = to.x * dir.x + to.y * dir.y;
float latProj = to.x * lat.x + to.y * lat.y;
#ifdef REGAMEDLL_FIXES
const float c = 0.5f;
if (toProj > c)
MoveBackward();
else if (toProj < -c)
MoveForward();
if (latProj >= c)
StrafeRight();
else if (latProj <= -c)
StrafeLeft();
#else
if (latProj >= 0.0f)
StrafeRight();
else
StrafeLeft();
#endif
}
// For getting un-stuck
@ -349,7 +366,7 @@ void CCSBot::ComputeApproachPoints()
{
m_approachPointCount = 0;
if (m_lastKnownArea == NULL)
if (!m_lastKnownArea)
{
return;
}
@ -359,11 +376,10 @@ void CCSBot::ComputeApproachPoints()
Vector ap;
float halfWidth;
for (int i = 0; i < m_lastKnownArea->GetApproachInfoCount() && m_approachPointCount < MAX_APPROACH_POINTS; ++i)
for (int i = 0; i < m_lastKnownArea->GetApproachInfoCount() && m_approachPointCount < MAX_APPROACH_POINTS; i++)
{
const CNavArea::ApproachInfo *info = m_lastKnownArea->GetApproachInfo(i);
if (info->here.area == NULL || info->prev.area == NULL)
if (!info->here.area || !info->prev.area)
{
continue;
}
@ -391,7 +407,7 @@ void CCSBot::ComputeApproachPoints()
void CCSBot::DrawApproachPoints()
{
for (int i = 0; i < m_approachPointCount; ++i)
for (int i = 0; i < m_approachPointCount; i++)
{
UTIL_DrawBeamPoints(m_approachPoint[i], m_approachPoint[i] + Vector(0, 0, 50), 3, 0, 255, 255);
}
@ -420,7 +436,7 @@ NOXREF bool CCSBot::FindApproachPointNearestPath(Vector *pos)
// from us that is near our path
const float nearPathSq = 10000.0f;
for (int i = 0; i < m_approachPointCount; ++i)
for (int i = 0; i < m_approachPointCount; i++)
{
if (FindClosestPointOnPath(&m_approachPoint[i], start, end, &close) == false)
continue;

View File

@ -8,10 +8,10 @@ bool CCSBot::ComputePathPositions()
// start in first area's center
m_path[0].pos = *m_path[0].area->GetCenter();
m_path[0].ladder = NULL;
m_path[0].ladder = nullptr;
m_path[0].how = NUM_TRAVERSE_TYPES;
for (int i = 1; i < m_pathLength; ++i)
for (int i = 1; i < m_pathLength; i++)
{
const ConnectInfo *from = &m_path[i - 1];
ConnectInfo *to = &m_path[ i ];
@ -19,7 +19,7 @@ bool CCSBot::ComputePathPositions()
// walk along the floor to the next area
if (to->how <= GO_WEST)
{
to->ladder = NULL;
to->ladder = nullptr;
// compute next point, keeping path as straight as possible
from->area->ComputeClosestPointInPortal(to->area, (NavDirType)to->how, &from->pos, &to->pos);
@ -49,14 +49,14 @@ bool CCSBot::ComputePathPositions()
if (m_pathLength < MAX_PATH_LENGTH - 1)
{
// copy nodes down
for (int j = m_pathLength; j > i; --j)
for (int j = m_pathLength; j > i; j--)
m_path[j] = m_path[j - 1];
// path is one node longer
++m_pathLength;
m_pathLength++;
// move index ahead into the new node we just duplicated
++i;
i++;
m_path[i].pos.x = to->pos.x + pushDist * dir.x;
m_path[i].pos.y = to->pos.y + pushDist * dir.y;
@ -72,7 +72,7 @@ bool CCSBot::ComputePathPositions()
// find our ladder
const NavLadderList *list = from->area->GetLadderList(LADDER_UP);
NavLadderList::const_iterator iter;
for (iter = list->begin(); iter != list->end(); ++iter)
for (iter = list->begin(); iter != list->end(); iter++)
{
CNavLadder *ladder = (*iter);
@ -98,7 +98,7 @@ bool CCSBot::ComputePathPositions()
// find our ladder
const NavLadderList *list = from->area->GetLadderList(LADDER_DOWN);
NavLadderList::const_iterator iter;
for (iter = list->begin(); iter != list->end(); ++iter)
for (iter = list->begin(); iter != list->end(); iter++)
{
CNavLadder *ladder = (*iter);
@ -130,9 +130,9 @@ void CCSBot::SetupLadderMovement()
const ConnectInfo *to = &m_path[ m_pathIndex ];
if (to->ladder != NULL)
if (to->ladder)
{
m_spotEncounter = NULL;
m_spotEncounter = nullptr;
m_areaEnteredTimestamp = gpGlobals->time;
m_pathLadder = to->ladder;
@ -217,7 +217,7 @@ void CCSBot::ComputeLadderEndpoint(bool isAscending)
// TODO: Need Push() and Pop() for run/walk context to keep ladder speed contained.
bool CCSBot::UpdateLadderMovement()
{
if (m_pathLadder == NULL)
if (!m_pathLadder)
return false;
bool giveUp = false;
@ -556,7 +556,7 @@ bool CCSBot::UpdateLadderMovement()
// successfully traversed ladder and reached destination area
// exit ladder state machine
PrintIfWatched("Ladder traversed.\n");
m_pathLadder = NULL;
m_pathLadder = nullptr;
// incrememnt path index to next step beyond this ladder
SetPathIndex(m_pathIndex + 1);
@ -576,7 +576,7 @@ bool CCSBot::UpdateLadderMovement()
// NOTE: This does not do line-of-sight tests, so closest point may be thru the floor, etc
bool CCSBot::FindClosestPointOnPath(const Vector *worldPos, int startIndex, int endIndex, Vector *close) const
{
if (!HasPath() || close == NULL)
if (!HasPath() || !close)
return false;
Vector along, toWorldPos;
@ -587,7 +587,7 @@ bool CCSBot::FindClosestPointOnPath(const Vector *worldPos, int startIndex, int
float closeDistSq = 9999999999.9f;
float distSq;
for (int i = startIndex; i <= endIndex; ++i)
for (int i = startIndex; i <= endIndex; i++)
{
from = &m_path[i - 1].pos;
to = &m_path[i].pos;
@ -661,7 +661,7 @@ int CCSBot::FindOurPositionOnPath(Vector *close, bool local) const
end = m_pathLength;
}
for (int i = start; i < end; ++i)
for (int i = start; i < end; i++)
{
from = &m_path[i - 1].pos;
to = &m_path[i].pos;
@ -803,7 +803,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
const float closeEpsilon = 20.0f; // 10.0f
while ((*point - close).Make2D().IsLengthLessThan(closeEpsilon))
{
++index;
index++;
if (index >= m_pathLength)
{
@ -826,7 +826,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
const float closeEpsilon = 20.0f;
if ((pos - close).Make2D().IsLengthLessThan(closeEpsilon))
{
++startIndex;
startIndex++;
}
else
{
@ -836,7 +836,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
// if we hit a ladder, stop, or jump area, must stop (dont use ladder behind us)
if (startIndex > m_pathIndex && startIndex < m_pathLength
&& (m_path[ startIndex ].ladder != NULL || (m_path[ startIndex ].area->GetAttributes() & NAV_JUMP)))
&& (m_path[ startIndex ].ladder || (m_path[ startIndex ].area->GetAttributes() & NAV_JUMP)))
{
*point = m_path[ startIndex ].pos;
return startIndex;
@ -847,7 +847,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
startIndex = m_pathLength - 1;
// if we hit a ladder, stop, or jump area, must stop
if (startIndex < m_pathLength && (m_path[ startIndex ].ladder != NULL || (m_path[ startIndex ].area->GetAttributes() & NAV_JUMP)))
if (startIndex < m_pathLength && (m_path[ startIndex ].ladder || (m_path[ startIndex ].area->GetAttributes() & NAV_JUMP)))
{
*point = m_path[ startIndex ].pos;
return startIndex;
@ -868,7 +868,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
// step along the path until we pass aheadRange
bool isCorner = false;
int i;
for (i = startIndex; i < m_pathLength; ++i)
for (i = startIndex; i < m_pathLength; i++)
{
Vector pos = m_path[i].pos;
Vector to = pos - m_path[i - 1].pos;
@ -878,7 +878,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
// don't allow path to double-back from our starting direction (going upstairs, down curved passages, etc)
if (DotProduct(dir, initDir) < 0.0f) // -0.25f
{
--i;
i--;
break;
}
@ -886,7 +886,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
if (DotProduct(dir, prevDir) < 0.5f)
{
isCorner = true;
--i;
i--;
break;
}
@ -902,14 +902,14 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
}
// if we encounter a ladder or jump area, we must stop
if (i < m_pathLength && (m_path[ i ].ladder != NULL || (m_path[ i ].area->GetAttributes() & NAV_JUMP)))
if (i < m_pathLength && (m_path[ i ].ladder || (m_path[ i ].area->GetAttributes() & NAV_JUMP)))
break;
// Check straight-line path from our current position to this position
// Test for un-jumpable height change, or unrecoverable fall
if (!IsStraightLinePathWalkable(&pos))
{
--i;
i--;
break;
}
@ -979,11 +979,11 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
if (DotProduct(toPoint, initDir.Make2D()) < 0.0f || toPoint.IsLengthLessThan(epsilon))
{
int i;
for (i = startIndex; i < m_pathLength; ++i)
for (i = startIndex; i < m_pathLength; i++)
{
toPoint.x = m_path[i].pos.x - pev->origin.x;
toPoint.y = m_path[i].pos.y - pev->origin.y;
if (m_path[i].ladder != NULL || (m_path[i].area->GetAttributes() & NAV_JUMP) || toPoint.IsLengthGreaterThan(epsilon))
if (m_path[i].ladder || (m_path[i].area->GetAttributes() & NAV_JUMP) || toPoint.IsLengthGreaterThan(epsilon))
{
*point = m_path[i].pos;
startIndex = i;
@ -1019,9 +1019,9 @@ void CCSBot::SetPathIndex(int newIndex)
if (m_pathIndex < m_pathLength && m_pathIndex >= 2)
m_spotEncounter = m_path[ m_pathIndex - 1 ].area->GetSpotEncounter(m_path[ m_pathIndex - 2 ].area, m_path[ m_pathIndex ].area);
else
m_spotEncounter = NULL;
m_spotEncounter = nullptr;
m_pathLadder = NULL;
m_pathLadder = nullptr;
}
}
@ -1031,14 +1031,15 @@ bool CCSBot::IsNearJump() const
if (m_pathIndex == 0 || m_pathIndex >= m_pathLength)
return false;
for (int i = m_pathIndex - 1; i < m_pathIndex; ++i)
for (int i = m_pathIndex - 1; i < m_pathIndex; i++)
{
if (m_path[ i ].area->GetAttributes() & NAV_JUMP)
{
float dz = m_path[ i + 1 ].pos.z - m_path[ i ].pos.z;
if (dz > 0.0f)
{
return true;
}
}
}
@ -1081,11 +1082,11 @@ bool CCSBot::IsFriendInTheWay(const Vector *goalPos) const
m_isFriendInTheWay = false;
// check if any friends are overlapping this linear path
for (int i = 1; i <= gpGlobals->maxClients; ++i)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *player = UTIL_PlayerByIndex(i);
if (player == NULL)
if (!player)
continue;
if (FNullEnt(player->pev))
@ -1140,7 +1141,7 @@ bool CCSBot::IsFriendInTheWay(const Vector *goalPos) const
void CCSBot::FeelerReflexAdjustment(Vector *goalPosition)
{
// if we are in a "precise" area, do not do feeler adjustments
if (m_lastKnownArea != NULL && (m_lastKnownArea->GetAttributes() & NAV_PRECISE))
if (m_lastKnownArea && (m_lastKnownArea->GetAttributes() & NAV_PRECISE))
return;
Vector dir(BotCOS(m_forwardAngle), BotSIN(m_forwardAngle), 0.0f);
@ -1330,7 +1331,7 @@ CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
// if there are no crouch areas coming up, stand
const float crouchRange = 50.0f;
bool didCrouch = false;
for (int i = prevIndex; i < m_pathLength; ++i)
for (int i = prevIndex; i < m_pathLength; i++)
{
const CNavArea *to = m_path[i].area;
@ -1381,7 +1382,7 @@ CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
{
float along = toGoal.Length2D();
int i;
for (i = m_pathIndex + 1; i < m_pathLength; ++i)
for (i = m_pathIndex + 1; i < m_pathLength; i++)
{
Vector delta = m_path[i].pos - m_path[i - 1].pos;
float segmentLength = delta.Length2D();
@ -1414,7 +1415,9 @@ CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
}
if (i == m_pathLength)
{
toGoal = GetPathEndpoint() - pev->origin;
}
}
}
else
@ -1554,18 +1557,18 @@ void CCSBot::BuildTrivialPath(const Vector *goal)
m_path[0].area = m_lastKnownArea;
m_path[0].pos = pev->origin;
m_path[0].pos.z = m_lastKnownArea->GetZ(&pev->origin);
m_path[0].ladder = NULL;
m_path[0].ladder = nullptr;
m_path[0].how = NUM_TRAVERSE_TYPES;
m_path[1].area = m_lastKnownArea;
m_path[1].pos = *goal;
m_path[1].pos.z = m_lastKnownArea->GetZ(goal);
m_path[1].ladder = NULL;
m_path[1].ladder = nullptr;
m_path[1].how = NUM_TRAVERSE_TYPES;
m_areaEnteredTimestamp = gpGlobals->time;
m_spotEncounter = NULL;
m_pathLadder = NULL;
m_spotEncounter = nullptr;
m_pathLadder = nullptr;
m_goalPosition = *goal;
}
@ -1590,16 +1593,16 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
// note final specific position
Vector pathEndPosition;
if (goal == NULL && goalArea == NULL)
if (!goal && !goalArea)
return false;
if (goal == NULL)
if (!goal)
pathEndPosition = *goalArea->GetCenter();
else
pathEndPosition = *goal;
// make sure path end position is on the ground
if (goalArea != NULL)
if (goalArea)
pathEndPosition.z = goalArea->GetZ(&pathEndPosition);
else
GetGroundHeight(&pathEndPosition, &pathEndPosition.z);
@ -1612,7 +1615,7 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
}
// Compute shortest path to goal
CNavArea *closestArea = NULL;
CNavArea *closestArea = nullptr;
PathCost pathCost(this, route);
bool pathToGoalExists = NavAreaBuildPath(startArea, goalArea, goal, pathCost, &closestArea);
@ -1624,7 +1627,7 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
CNavArea *area;
for (area = effectiveGoalArea; area; area = area->GetParent())
{
++count;
count++;
}
// save room for endpoint
@ -1644,7 +1647,7 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
m_pathLength = count;
for (area = effectiveGoalArea; count && area; area = area->GetParent())
{
--count;
count--;
m_path[ count ].area = area;
m_path[ count ].how = area->GetParentHow();
}
@ -1657,7 +1660,7 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
return false;
}
if (goal == NULL)
if (!goal)
{
switch (m_path[m_pathLength - 1].how)
{
@ -1680,20 +1683,20 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
// append path end position
m_path[ m_pathLength ].area = effectiveGoalArea;
m_path[ m_pathLength ].pos = pathEndPosition;
m_path[ m_pathLength ].ladder = NULL;
m_path[ m_pathLength ].ladder = nullptr;
m_path[ m_pathLength ].how = NUM_TRAVERSE_TYPES;
++m_pathLength;
m_pathLength++;
// do movement setup
m_pathIndex = 1;
m_areaEnteredTimestamp = gpGlobals->time;
m_spotEncounter = NULL;
m_spotEncounter = nullptr;
m_goalPosition = m_path[1].pos;
if (m_path[1].ladder != NULL)
if (m_path[1].ladder)
SetupLadderMovement();
else
m_pathLadder = NULL;
m_pathLadder = nullptr;
return true;
}
@ -1709,7 +1712,7 @@ float CCSBot::GetPathDistanceRemaining() const
float dist = 0.0f;
const Vector *prevCenter = m_path[m_pathIndex].area->GetCenter();
for (int i = idx + 1; i < m_pathLength; ++i)
for (int i = idx + 1; i < m_pathLength; i++)
{
dist += (*m_path[i].area->GetCenter() - *prevCenter).Length();
prevCenter = m_path[i].area->GetCenter();
@ -1724,7 +1727,7 @@ void CCSBot::DrawPath()
if (!HasPath())
return;
for (int i = 1; i < m_pathLength; ++i)
for (int i = 1; i < m_pathLength; i++)
{
UTIL_DrawBeamPoints(m_path[i - 1].pos, m_path[i].pos, 2, 255, 75, 0);
}

View File

@ -20,10 +20,9 @@ bool CCSBot::IsRadioCommand(GameEventType event) const
void CCSBot::RespondToRadioCommands()
{
// bots use the chatter system to respond to each other
if (m_radioSubject != NULL && m_radioSubject->IsPlayer())
if (m_radioSubject.IsValid() && m_radioSubject->IsPlayer())
{
CBasePlayer *player = m_radioSubject;
if (player->IsBot())
if (m_radioSubject->IsBot())
{
m_lastRadioCommand = EVENT_INVALID;
return;
@ -71,8 +70,7 @@ void CCSBot::RespondToRadioCommands()
return;
}
CBasePlayer *player = m_radioSubject;
if (player == NULL)
if (!m_radioSubject)
return;
// respond to command
@ -92,8 +90,8 @@ void CCSBot::RespondToRadioCommands()
{
if (!IsFollowing())
{
Follow(player);
player->AllowAutoFollow();
Follow(m_radioSubject);
m_radioSubject->AllowAutoFollow();
canDo = true;
}
break;
@ -104,9 +102,9 @@ void CCSBot::RespondToRadioCommands()
{
if (!IsFollowing())
{
Follow(player);
Follow(m_radioSubject);
GetChatter()->Say("OnMyWay");
player->AllowAutoFollow();
m_radioSubject->AllowAutoFollow();
canDo = false;
}
break;
@ -122,7 +120,7 @@ void CCSBot::RespondToRadioCommands()
// find the leader's area
SetTask(HOLD_POSITION);
StopFollowing();
player->InhibitAutoFollow(inhibitAutoFollowDuration);
m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
Hide(TheNavAreaGrid.GetNearestNavArea(&m_radioPosition));
canDo = true;
break;
@ -133,7 +131,7 @@ void CCSBot::RespondToRadioCommands()
StopFollowing();
Hunt();
canDo = true;
player->InhibitAutoFollow(inhibitAutoFollowDuration);
m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
break;
}
case EVENT_RADIO_GET_OUT_OF_THERE:
@ -141,7 +139,7 @@ void CCSBot::RespondToRadioCommands()
if (TheCSBots()->IsBombPlanted())
{
EscapeFromBomb();
player->InhibitAutoFollow(inhibitAutoFollowDuration);
m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
canDo = true;
}
break;
@ -154,9 +152,8 @@ void CCSBot::RespondToRadioCommands()
{
if (m_iTeam == CT && TheCSBots()->IsBombPlanted())
{
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(player);
if (zone != NULL)
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(m_radioSubject);
if (zone)
{
GetGameState()->ClearBombsite(zone->m_index);
@ -197,11 +194,11 @@ void CCSBot::StartVoiceFeedback(float duration)
m_voiceFeedbackStartTimestamp = gpGlobals->time;
m_voiceFeedbackEndTimestamp = duration + gpGlobals->time;
CBasePlayer *pPlayer = NULL;
while ((pPlayer = GetNextRadioRecipient(pPlayer)) != NULL)
CBasePlayer *pPlayer = nullptr;
while ((pPlayer = GetNextRadioRecipient(pPlayer)))
{
MESSAGE_BEGIN(MSG_ONE, gmsgBotVoice, NULL, pPlayer->pev);
WRITE_BYTE(1); // active is talking
MESSAGE_BEGIN(MSG_ONE, gmsgBotVoice, nullptr, pPlayer->pev);
WRITE_BYTE(1); // active is talking
WRITE_BYTE(entindex()); // client index speaking
MESSAGE_END();
}
@ -264,7 +261,7 @@ bool CCSBot::RespondToHelpRequest(CBasePlayer *them, Place place, float maxRange
// go to where help is needed
const Vector *pos = GetRandomSpotAtPlace(place);
if (pos != NULL)
if (pos)
{
MoveTo(pos, FASTEST_ROUTE);
}

View File

@ -3,13 +3,13 @@
// This method is the ONLY legal way to change a bot's current state
void CCSBot::SetState(BotState *state)
{
PrintIfWatched("SetState: %s -> %s\n", (m_state != NULL) ? m_state->GetName() : "NULL", state->GetName());
PrintIfWatched("SetState: %s -> %s\n", m_state ? m_state->GetName() : "NULL", state->GetName());
// if we changed state from within the special Attack state, we are no longer attacking
if (m_isAttacking)
StopAttacking();
if (m_state != NULL)
if (m_state)
m_state->OnExit(this);
state->OnEnter(this);
@ -32,7 +32,7 @@ void CCSBot::EscapeFromBomb()
void CCSBot::Follow(CBasePlayer *player)
{
if (player == NULL)
if (!player)
return;
// note when we began following
@ -59,7 +59,7 @@ void CCSBot::ContinueFollowing()
void CCSBot::StopFollowing()
{
m_isFollowing = false;
m_leader = NULL;
m_leader = nullptr;
m_allowAutoFollowTime = gpGlobals->time + 10.0f;
}
@ -96,7 +96,7 @@ void CCSBot::Hide(CNavArea *searchFromArea, float duration, float hideRange, boo
sourcePos = pev->origin;
}
if (source == NULL)
if (!source)
{
PrintIfWatched("Hide from area is NULL.\n");
Idle();
@ -112,7 +112,7 @@ void CCSBot::Hide(CNavArea *searchFromArea, float duration, float hideRange, boo
Vector useSpot;
const Vector *pos = FindNearbyHidingSpot(this, &sourcePos, source, hideRange, IsSniper());
if (pos == NULL)
if (!pos)
{
PrintIfWatched("No available hiding spots.\n");
// hide at our current position
@ -140,7 +140,7 @@ void CCSBot::Hide(CNavArea *searchFromArea, float duration, float hideRange, boo
void CCSBot::Hide(const Vector *hidingSpot, float duration, bool holdPosition)
{
CNavArea *hideArea = TheNavAreaGrid.GetNearestNavArea(hidingSpot);
if (hideArea == NULL)
if (!hideArea)
{
PrintIfWatched("Hiding spot off nav mesh\n");
Idle();
@ -183,7 +183,7 @@ bool CCSBot::TryToHide(CNavArea *searchFromArea, float duration, float hideRange
sourcePos = pev->origin;
}
if (source == NULL)
if (!source)
{
PrintIfWatched("Hide from area is NULL.\n");
return false;
@ -196,7 +196,7 @@ bool CCSBot::TryToHide(CNavArea *searchFromArea, float duration, float hideRange
// search around source area for a good hiding spot
const Vector *pos = FindNearbyHidingSpot(this, &sourcePos, source, hideRange, IsSniper(), useNearest);
if (pos == NULL)
if (!pos)
{
PrintIfWatched("No available hiding spots.\n");
return false;
@ -221,7 +221,7 @@ bool CCSBot::TryToRetreat()
const float maxRange = 1000.0f;
const Vector *spot = FindNearbyRetreatSpot(this, maxRange);
if (spot != NULL)
if (spot)
{
// ignore enemies for a second to give us time to hide
// reaching our hiding spot clears our disposition
@ -249,7 +249,7 @@ void CCSBot::Hunt()
// NOTE: Attacking does not change our task.
void CCSBot::Attack(CBasePlayer *victim)
{
if (victim == NULL)
if (!victim)
return;
// zombies never attack

View File

@ -15,7 +15,7 @@ void CCSBot::Upkeep()
UpdateAimOffset();
// aim at enemy, if he's still alive
if (m_enemy != NULL)
if (m_enemy.IsValid())
{
float feetOffset = pev->origin.z - GetFeetZ();
@ -70,11 +70,15 @@ void CCSBot::Upkeep()
m_aimSpot.z -= feetOffset * 0.5f;
}
else // FEET
{
m_aimSpot.z -= (feetOffset + feetOffset);
}
}
}
else
{
m_aimSpot = m_lastEnemyPosition;
}
// add in aim error
m_aimSpot.x += m_aimOffset.x;
@ -157,10 +161,10 @@ void CCSBot::Update()
switch (m_processMode)
{
case PROCESS_LEARN: UpdateLearnProcess(); return;
case PROCESS_LEARN: UpdateLearnProcess(); return;
case PROCESS_ANALYZE_ALPHA: UpdateAnalyzeAlphaProcess(); return;
case PROCESS_ANALYZE_BETA: UpdateAnalyzeBetaProcess(); return;
case PROCESS_SAVE: UpdateSaveProcess(); return;
case PROCESS_ANALYZE_BETA: UpdateAnalyzeBetaProcess(); return;
case PROCESS_SAVE: UpdateSaveProcess(); return;
}
// update our radio chatter
@ -210,23 +214,15 @@ void CCSBot::Update()
// show encounter spot data
if ((cv_bot_traceview.value == 4.0f && IsLocalPlayerWatchingMe()) || cv_bot_traceview.value == 5.0f)
{
if (m_spotEncounter != NULL)
if (m_spotEncounter)
{
UTIL_DrawBeamPoints(m_spotEncounter->path.from, m_spotEncounter->path.to, 3, 0, 0, 255);
Vector dir = m_spotEncounter->path.to - m_spotEncounter->path.from;
float length = dir.NormalizeInPlace();
const SpotOrder *order;
Vector along;
for (SpotOrderList::const_iterator iter = m_spotEncounter->spotList.begin(); iter != m_spotEncounter->spotList.end(); ++iter)
{
order = &(*iter);
along = m_spotEncounter->path.from + order->t * length * dir;
UTIL_DrawBeamPoints(along, *order->spot->GetPosition(), 3, 0, 255, 255);
for (auto &order : m_spotEncounter->spotList) {
UTIL_DrawBeamPoints(m_spotEncounter->path.from + order.t * length * dir, *order.spot->GetPosition(), 3, 0, 255, 255);
}
}
}
@ -261,7 +257,7 @@ void CCSBot::Update()
}
// track the last known area we were in
if (m_currentArea != NULL && m_currentArea != m_lastKnownArea)
if (m_currentArea && m_currentArea != m_lastKnownArea)
{
m_lastKnownArea = m_currentArea;
// assume that we "clear" an area of enemies when we enter it
@ -276,7 +272,7 @@ void CCSBot::Update()
m_approachPointViewPosition = pev->origin;
}
if (cv_bot_show_nav.value > 0.0f && m_lastKnownArea != NULL)
if (cv_bot_show_nav.value > 0.0f && m_lastKnownArea)
{
m_lastKnownArea->DrawConnectedAreas();
}
@ -310,7 +306,7 @@ void CCSBot::Update()
// "threat" may be the same as our current enemy
CBasePlayer *threat = GetRecognizedEnemy();
if (threat != NULL)
if (threat)
{
// adjust our personal "safe" time
AdjustSafeTime();
@ -355,7 +351,7 @@ void CCSBot::Update()
if (doAttack)
{
if (GetEnemy() == NULL || threat != GetEnemy() || !IsAttacking())
if (!GetEnemy() || threat != GetEnemy() || !IsAttacking())
{
if (IsUsingKnife() && IsHiding())
{
@ -397,12 +393,12 @@ void CCSBot::Update()
}
// Validate existing enemy, if any
if (m_enemy != NULL)
if (m_enemy.IsValid())
{
if (IsAwareOfEnemyDeath())
{
// we have noticed that our enemy has died
m_enemy = NULL;
m_enemy = nullptr;
m_isEnemyVisible = false;
}
else
@ -442,7 +438,7 @@ void CCSBot::Update()
// if we have seen an enemy recently, keep an eye on him if we can
const float seenRecentTime = 3.0f;
if (m_enemy != NULL && GetTimeSinceLastSawEnemy() < seenRecentTime)
if (m_enemy.IsValid() && GetTimeSinceLastSawEnemy() < seenRecentTime)
{
AimAtEnemy();
}
@ -523,13 +519,13 @@ void CCSBot::Update()
// make way
const float avoidTime = 0.33f;
if (gpGlobals->time - m_avoidTimestamp < avoidTime && m_avoid != NULL)
if (gpGlobals->time - m_avoidTimestamp < avoidTime && m_avoid)
{
StrafeAwayFromPosition(&m_avoid->pev->origin);
}
else
{
m_avoid = NULL;
m_avoid = nullptr;
}
if (m_isJumpCrouching)
@ -559,11 +555,15 @@ void CCSBot::Update()
UpdatePeripheralVision();
// Update gamestate
if (m_bomber != NULL)
if (m_bomber)
{
GetChatter()->SpottedBomber(GetBomber());
}
if (CanSeeLooseBomb())
{
GetChatter()->SpottedLooseBomb(TheCSBots()->GetLooseBomb());
}
// Scenario interrupts
switch (TheCSBots()->GetScenario())
@ -632,7 +632,7 @@ void CCSBot::Update()
if (GetProfile()->GetTeamwork() > RANDOM_FLOAT(0.0f, 1.0f))
{
CBasePlayer *leader = GetClosestVisibleHumanFriend();
if (leader != NULL && leader->IsAutoFollowAllowed())
if (leader && leader->IsAutoFollowAllowed())
{
// count how many bots are already following this player
const float maxFollowCount = 2;
@ -642,7 +642,7 @@ void CCSBot::Update()
if ((leader->pev->origin - pev->origin).IsLengthLessThan(autoFollowRange))
{
CNavArea *leaderArea = TheNavAreaGrid.GetNavArea(&leader->pev->origin);
if (leaderArea != NULL)
if (leaderArea)
{
PathCost cost(this, FASTEST_ROUTE);
float travelRange = NavAreaTravelDistance(GetLastKnownArea(), leaderArea, cost);
@ -676,8 +676,8 @@ void CCSBot::Update()
if (IsFollowing())
{
// if we are following someone, make sure they are still alive
CBaseEntity *leader = m_leader;
if (leader == NULL || !leader->IsAlive())
CBaseEntity *pLeader = m_leader;
if (!pLeader || !pLeader->IsAlive())
{
StopFollowing();
}

View File

@ -224,7 +224,7 @@ bool CCSBot::IsVisible(const Vector *pos, bool testFOV) const
bool CCSBot::IsVisible(CBasePlayer *player, bool testFOV, unsigned char *visParts) const
{
Vector spot = player->pev->origin;
VisiblePartType testVisParts = NONE;
unsigned char testVisParts = NONE;
// finish chest check
if (IsVisible(&spot, testFOV))
@ -266,7 +266,7 @@ bool CCSBot::IsVisible(CBasePlayer *player, bool testFOV, unsigned char *visPart
if (IsVisible(&spot, testFOV))
testVisParts |= RIGHT_SIDE;
if (visParts != NULL)
if (visParts)
*visParts = testVisParts;
if (testVisParts != NONE)
@ -295,7 +295,7 @@ void CCSBot::UpdateLookAt()
// Look at the given point in space for the given duration (-1 means forever)
void CCSBot::SetLookAt(const char *desc, const Vector *pos, PriorityType pri, float duration, bool clearIfClose, float angleTolerance)
{
if (pos == NULL)
if (!pos)
return;
// if currently looking at a point in space with higher priority, ignore this request
@ -344,14 +344,10 @@ void CCSBot::UpdatePeripheralVision()
if (m_spotEncounter)
{
// check LOS to all spots in case we see them with our "peripheral vision"
const SpotOrder *spotOrder = NULL;
Vector pos;
for (SpotOrderList::const_iterator iter = m_spotEncounter->spotList.begin(); iter != m_spotEncounter->spotList.end(); ++iter)
for (auto &spotOrder : m_spotEncounter->spotList)
{
spotOrder = &(*iter);
const Vector *spotPos = spotOrder->spot->GetPosition();
const Vector *spotPos = spotOrder.spot->GetPosition();
pos.x = spotPos->x;
pos.y = spotPos->y;
@ -361,7 +357,7 @@ void CCSBot::UpdatePeripheralVision()
continue;
// can see hiding spot, remember when we saw it last
SetHidingSpotCheckTimestamp(spotOrder->spot);
SetHidingSpotCheckTimestamp(spotOrder.spot);
}
}
}
@ -434,7 +430,7 @@ void CCSBot::UpdateLookAround(bool updateNow)
}
}
if (m_lastKnownArea == NULL)
if (!m_lastKnownArea)
return;
if (gpGlobals->time < m_lookAroundStateTimestamp)
@ -453,14 +449,12 @@ void CCSBot::UpdateLookAround(bool updateNow)
}
int which = RANDOM_LONG(0, m_approachPointCount - 1);
Vector spot = m_approachPoint[ which ];
Vector spot = m_approachPoint[which];
// don't look at the floor, look roughly at chest level
// TODO: If this approach point is very near, this will cause us to aim up in the air if were crouching
spot.z += HalfHumanHeight;
SetLookAt("Approach Point (Hiding)", &spot, PRIORITY_LOW);
return;
}
@ -511,24 +505,22 @@ void CCSBot::UpdateLookAround(bool updateNow)
int dangerIndex = 0;
const float checkTime = 10.0f;
const SpotOrder *spotOrder;
for (SpotOrderList::iterator iter = m_spotEncounter->spotList.begin(); iter != m_spotEncounter->spotList.end(); ++iter)
for (auto &spotOrder : m_spotEncounter->spotList)
{
spotOrder = &(*iter);
// if we have seen this spot recently, we don't need to look at it
if (gpGlobals->time - GetHidingSpotCheckTimestamp(spotOrder->spot) <= checkTime)
if (gpGlobals->time - GetHidingSpotCheckTimestamp(spotOrder.spot) <= checkTime)
continue;
if (spotOrder->t > t)
if (spotOrder.t > t)
break;
dangerSpot[ dangerIndex++ ] = spotOrder->spot;
dangerSpot[dangerIndex++] = spotOrder.spot;
if (dangerIndex >= MAX_DANGER_SPOTS)
dangerIndex = 0;
if (dangerSpotCount < MAX_DANGER_SPOTS)
++dangerSpotCount;
dangerSpotCount++;
}
if (dangerSpotCount)
@ -536,7 +528,7 @@ void CCSBot::UpdateLookAround(bool updateNow)
// pick one of the spots at random
int which = RANDOM_LONG(0, dangerSpotCount - 1);
const Vector *checkSpot = dangerSpot[ which ]->GetPosition();
const Vector *checkSpot = dangerSpot[which]->GetPosition();
Vector pos = *checkSpot;
pos.z += HalfHumanHeight;
@ -576,9 +568,9 @@ bool CCSBot::BendLineOfSight(const Vector *eye, const Vector *point, Vector *ben
for (float angle = angleInc; angle <= 135.0f; angle += angleInc)
{
// check both sides at this angle offset
for (int side = 0; side < 2; ++side)
for (int side = 0; side < 2; side++)
{
float actualAngle = (side) ? (startAngle + angle) : (startAngle - angle);
float actualAngle = side ? (startAngle + angle) : (startAngle - angle);
float dx = BotCOS(actualAngle);
float dy = BotSIN(actualAngle);
@ -635,31 +627,44 @@ bool CCSBot::BendLineOfSight(const Vector *eye, const Vector *point, Vector *ben
CBasePlayer *CCSBot::FindMostDangerousThreat()
{
// maximum number of simulataneously attendable threats
enum { MAX_THREATS = 16 };
#ifdef REGAMEDLL_FIXES
const int MAX_THREATS = MAX_CLIENTS;
#else
const int MAX_THREATS = 16;
#endif
struct CloseInfo
{
CBasePlayer *enemy;
float range;
}
threat[ MAX_THREATS ];
};
CloseInfo threat[MAX_THREATS];
int threatCount = 0;
m_bomber = NULL;
#ifdef REGAMEDLL_ADD
int prevIndex = m_enemyQueueIndex - 1;
if (prevIndex < 0)
prevIndex = MAX_ENEMY_QUEUE - 1;
CBasePlayer *currentThreat = m_enemyQueue[ prevIndex ].player;
#endif
m_bomber = nullptr;
m_closestVisibleFriend = nullptr;
m_closestVisibleHumanFriend = nullptr;
m_closestVisibleFriend = NULL;
float closeFriendRange = 99999999999.9f;
m_closestVisibleHumanFriend = NULL;
float closeHumanFriendRange = 99999999999.9f;
int i;
{
for (i = 1; i <= gpGlobals->maxClients; ++i)
for (i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *player = UTIL_PlayerByIndex(i);
if (player == NULL)
if (!player)
continue;
if (FNullEnt(player->pev))
@ -710,9 +715,21 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
}
// check if this enemy is fully
if (!IsVisible(player, CHECK_FOV))
unsigned char visParts;
if (!IsVisible(player, CHECK_FOV, &visParts))
continue;
#ifdef REGAMEDLL_ADD
// do we notice this enemy? (always notice current enemy)
if (player != currentThreat)
{
if (!IsNoticable(player, visParts))
{
continue;
}
}
#endif
// update watch timestamp
int idx = player->entindex() - 1;
m_watchInfo[idx].timestamp = gpGlobals->time;
@ -739,13 +756,12 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
{
// find insertion point
int j;
for (j = 0; j < threatCount; ++j)
for (j = 0; j < threatCount; j++)
{
if (distSq < threat[j].range)
break;
}
// shift lower half down a notch
for (int k = threatCount - 1; k >= j; --k)
threat[k + 1] = threat[k];
@ -755,7 +771,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
threat[j].range = distSq;
if (threatCount < MAX_THREATS)
++threatCount;
threatCount++;
}
}
}
@ -766,7 +782,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
m_nearbyEnemyCount = 0;
m_nearbyFriendCount = 0;
for (i = 0; i < MAX_CLIENTS; ++i)
for (i = 0; i < MAX_CLIENTS; i++)
{
if (m_watchInfo[i].timestamp <= 0.0f)
continue;
@ -775,9 +791,9 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
if (gpGlobals->time - m_watchInfo[i].timestamp < recentTime)
{
if (m_watchInfo[i].isEnemy)
++m_nearbyEnemyCount;
m_nearbyEnemyCount++;
else
++m_nearbyFriendCount;
m_nearbyFriendCount++;
}
}
@ -799,14 +815,14 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
unsigned int place;
int count;
};
static PlaceRank placeRank[ MAX_PLACES_PER_MAP ];
static PlaceRank placeRank[MAX_PLACES_PER_MAP];
int locCount = 0;
PlaceRank common;
common.place = 0;
common.count = 0;
for (i = 0; i < threatCount; ++i)
for (i = 0; i < threatCount; i++)
{
// find the area the player/bot is standing on
CNavArea *area;
@ -821,7 +837,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
area = TheNavAreaGrid.GetNearestNavArea(&threat[i].enemy->pev->origin);
}
if (area == NULL)
if (!area)
continue;
unsigned int threatLoc = area->GetPlace();
@ -830,7 +846,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
// if place is already in set, increment count
int j;
for (j = 0; j < locCount; ++j)
for (j = 0; j < locCount; j++)
{
if (placeRank[j].place == threatLoc)
break;
@ -841,19 +857,19 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
// new place
if (locCount < MAX_PLACES_PER_MAP)
{
placeRank[ locCount ].place = threatLoc;
placeRank[ locCount ].count = 1;
placeRank[locCount].place = threatLoc;
placeRank[locCount].count = 1;
if (common.count == 0)
common = placeRank[locCount];
++locCount;
locCount++;
}
}
else
{
// others are in that place, increment
++placeRank[j].count;
placeRank[j].count++;
// keep track of the most common place
if (placeRank[j].count > common.count)
@ -867,11 +883,33 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
{
if (threatCount == 0)
return NULL;
return nullptr;
int t;
#ifdef REGAMEDLL_ADD
bool sawCloserThreat = false;
bool sawCurrentThreat = false;
for (t = 0; t < threatCount; t++)
{
if (threat[t].enemy == currentThreat)
{
sawCurrentThreat = true;
}
else if (threat[t].enemy != currentThreat && IsSignificantlyCloser(threat[t].enemy, currentThreat))
{
sawCloserThreat = true;
}
}
if (sawCurrentThreat && !sawCloserThreat)
{
return currentThreat;
}
#endif
// otherwise, find the closest threat that without using shield
int t;
for (t = 0; t < threatCount; ++t)
for (t = 0; t < threatCount; t++)
{
if (!threat[t].enemy->IsProtectedByShield())
{
@ -896,18 +934,23 @@ void CCSBot::UpdateReactionQueue()
int now = m_enemyQueueIndex;
#ifdef REGAMEDLL_ADD
// reset timer
m_attentionInterval.Start();
#endif
// store a snapshot of its state at the end of the reaction time queue
if (threat != NULL)
if (threat)
{
m_enemyQueue[ now ].player = threat;
m_enemyQueue[ now ].isReloading = threat->IsReloading();
m_enemyQueue[ now ].isProtectedByShield = threat->IsProtectedByShield();
m_enemyQueue[now].player = threat;
m_enemyQueue[now].isReloading = threat->IsReloading();
m_enemyQueue[now].isProtectedByShield = threat->IsProtectedByShield();
}
else
{
m_enemyQueue[ now ].player = NULL;
m_enemyQueue[ now ].isReloading = false;
m_enemyQueue[ now ].isProtectedByShield = false;
m_enemyQueue[now].player = nullptr;
m_enemyQueue[now].isReloading = false;
m_enemyQueue[now].isProtectedByShield = false;
}
// queue is round-robin
@ -915,7 +958,7 @@ void CCSBot::UpdateReactionQueue()
m_enemyQueueIndex = 0;
if (m_enemyQueueCount < MAX_ENEMY_QUEUE)
++m_enemyQueueCount;
m_enemyQueueCount++;
// clamp reaction time to enemy queue size
float reactionTime = GetProfile()->GetReactionTime();
@ -937,9 +980,9 @@ void CCSBot::UpdateReactionQueue()
CBasePlayer *CCSBot::GetRecognizedEnemy()
{
if (m_enemyQueueAttendIndex >= m_enemyQueueCount)
return NULL;
return nullptr;
return (CBasePlayer *)m_enemyQueue[ m_enemyQueueAttendIndex ].player;
return m_enemyQueue[m_enemyQueueAttendIndex].player;
}
// Return true if the enemy we are "conscious" of is reloading
@ -948,7 +991,7 @@ bool CCSBot::IsRecognizedEnemyReloading()
if (m_enemyQueueAttendIndex >= m_enemyQueueCount)
return false;
return m_enemyQueue[ m_enemyQueueAttendIndex ].isReloading;
return m_enemyQueue[m_enemyQueueAttendIndex].isReloading;
}
// Return true if the enemy we are "conscious" of is hiding behind a shield
@ -957,17 +1000,17 @@ bool CCSBot::IsRecognizedEnemyProtectedByShield()
if (m_enemyQueueAttendIndex >= m_enemyQueueCount)
return false;
return m_enemyQueue[ m_enemyQueueAttendIndex ].isProtectedByShield;
return m_enemyQueue[m_enemyQueueAttendIndex].isProtectedByShield;
}
// Return distance to closest enemy we are "conscious" of
float CCSBot::GetRangeToNearestRecognizedEnemy()
{
const CBasePlayer *enemy = GetRecognizedEnemy();
const CBasePlayer *pEnemy = GetRecognizedEnemy();
if (enemy != NULL)
if (pEnemy)
{
return (pev->origin - enemy->pev->origin).Length();
return (pev->origin - pEnemy->pev->origin).Length();
}
return 99999999.9f;
@ -995,3 +1038,139 @@ void CCSBot::Blind(float duration, float holdTime, float fadeTime, int alpha)
// no longer safe
AdjustSafeTime();
}
#ifdef REGAMEDLL_ADD
bool CCSBot::IsNoticable(const CBasePlayer *player, unsigned char visibleParts) const
{
float deltaT = m_attentionInterval.GetElapsedTime();
// all chances are specified in terms of a standard "quantum" of time
// in which a normal person would notice something
const float noticeQuantum = 0.25f;
// determine percentage of player that is visible
float coverRatio = 0.0f;
if (visibleParts & CHEST)
{
const float chance = 40.0f;
coverRatio += chance;
}
if (visibleParts & HEAD)
{
const float chance = 10.0f;
coverRatio += chance;
}
if (visibleParts & LEFT_SIDE)
{
const float chance = 20.0f;
coverRatio += chance;
}
if (visibleParts & RIGHT_SIDE)
{
const float chance = 20.0f;
coverRatio += chance;
}
if (visibleParts & FEET)
{
const float chance = 10.0f;
coverRatio += chance;
}
// compute range modifier - farther away players are harder to notice, depeding on what they are doing
float range = (player->pev->origin - pev->origin).Length();
const float closeRange = 300.0f;
const float farRange = 1000.0f;
float rangeModifier;
if (range < closeRange)
{
rangeModifier = 0.0f;
}
else if (range > farRange)
{
rangeModifier = 1.0f;
}
else
{
rangeModifier = (range - closeRange) / (farRange - closeRange);
}
// harder to notice when crouched
bool isCrouching = (player->pev->flags & FL_DUCKING) == FL_DUCKING;
// moving players are easier to spot
float playerSpeedSq = player->pev->velocity.LengthSquared();
const float runSpeed = 200.0f;
const float walkSpeed = 30.0f;
float farChance, closeChance;
if (playerSpeedSq > runSpeed * runSpeed)
{
// running players are always easy to spot (must be standing to run)
return true;
}
else if (playerSpeedSq > walkSpeed * walkSpeed)
{
// walking players are less noticable far away
if (isCrouching)
{
closeChance = 90.0f;
farChance = 60.0f;
}
// standing
else
{
closeChance = 100.0f;
farChance = 75.0f;
}
}
else
{
// motionless players are hard to notice
if (isCrouching)
{
// crouching and motionless - very tough to notice
closeChance = 80.0f;
farChance = 5.0f; // takes about three seconds to notice (50% chance)
}
// standing
else
{
closeChance = 100.0f;
farChance = 10.0f;
}
}
// combine posture, speed, and range chances
float dispositionChance = closeChance + (farChance - closeChance) * rangeModifier;
// determine actual chance of noticing player
float noticeChance = dispositionChance * coverRatio/100.0f;
// scale by skill level
noticeChance *= (0.5f + 0.5f * GetProfile()->GetSkill());
// if we are alert, our chance of noticing is much higher
//if (IsAlert())
//{
// const float alertBonus = 50.0f;
// noticeChance += alertBonus;
//}
// scale by time quantum
noticeChance *= deltaT / noticeQuantum;
// there must always be a chance of detecting the enemy
const float minChance = 0.1f;
if (noticeChance < minChance)
{
noticeChance = minChance;
}
//PrintIfWatched("Notice chance = %3.2f\n", noticeChance);
return (RANDOM_FLOAT(0.0f, 100.0f) < noticeChance);
}
#endif

View File

@ -4,8 +4,8 @@
// NOTE: Aiming our weapon is handled in RunBotUpkeep()
void CCSBot::FireWeaponAtEnemy()
{
CBasePlayer *enemy = GetEnemy();
if (enemy == NULL)
CBasePlayer *pEnemy = GetEnemy();
if (!pEnemy)
{
StopRapidFire();
return;
@ -24,7 +24,7 @@ void CCSBot::FireWeaponAtEnemy()
{
ClearSurpriseDelay();
if (!(IsRecognizedEnemyProtectedByShield() && IsPlayerFacingMe(enemy)) // dont shoot at enemies behind shields
if (!(IsRecognizedEnemyProtectedByShield() && IsPlayerFacingMe(pEnemy)) // dont shoot at enemies behind shields
&& !IsActiveWeaponReloading()
&& !IsActiveWeaponClipEmpty()
&& IsEnemyVisible())
@ -76,7 +76,7 @@ void CCSBot::FireWeaponAtEnemy()
ForceRun(5.0f);
// if our prey is facing away, backstab him!
if (!IsPlayerFacingMe(enemy))
if (!IsPlayerFacingMe(pEnemy))
{
SecondaryAttack();
}
@ -278,9 +278,8 @@ bool isSniperRifle(CBasePlayerItem *item)
bool CCSBot::IsUsingAWP() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
if (weapon != NULL && weapon->m_iId == WEAPON_AWP)
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == WEAPON_AWP)
return true;
return false;
@ -289,12 +288,11 @@ bool CCSBot::IsUsingAWP() const
// Returns true if we are using a weapon with a removable silencer
bool CCSBot::DoesActiveWeaponHaveSilencer() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
if (weapon == NULL)
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (!pCurrentWeapon)
return false;
if (weapon->m_iId == WEAPON_M4A1 || weapon->m_iId == WEAPON_USP)
if (pCurrentWeapon->m_iId == WEAPON_M4A1 || pCurrentWeapon->m_iId == WEAPON_USP)
return true;
return false;
@ -303,9 +301,8 @@ bool CCSBot::DoesActiveWeaponHaveSilencer() const
// Return true if we are using a sniper rifle
bool CCSBot::IsUsingSniperRifle() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
if (weapon != NULL && isSniperRifle(weapon))
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && isSniperRifle(pCurrentWeapon))
return true;
return false;
@ -314,20 +311,11 @@ bool CCSBot::IsUsingSniperRifle() const
// Return true if we have a sniper rifle in our inventory
bool CCSBot::IsSniper() const
{
for (int i = 0; i < MAX_ITEM_TYPES; ++i)
{
CBasePlayerItem *item = m_rgpPlayerItems[i];
auto sniperItem = this->ForEachItem([](CBasePlayerItem *pItem) {
return isSniperRifle(pItem);
});
while (item != NULL)
{
if (isSniperRifle(item))
return true;
item = item->m_pNext;
}
}
return false;
return sniperItem ? true : false;
}
// Return true if we are actively sniping (moving to sniper spot or settled in)
@ -342,12 +330,11 @@ bool CCSBot::IsSniping() const
// Return true if we are using a shotgun
bool CCSBot::IsUsingShotgun() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
if (weapon == NULL)
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (!pCurrentWeapon)
return false;
if (weapon->m_iId == WEAPON_XM1014 || weapon->m_iId == WEAPON_M3)
if (pCurrentWeapon->m_iId == WEAPON_XM1014 || pCurrentWeapon->m_iId == WEAPON_M3)
return true;
return false;
@ -356,9 +343,8 @@ bool CCSBot::IsUsingShotgun() const
// Returns true if using the big 'ol machinegun
bool CCSBot::IsUsingMachinegun() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
if (weapon != NULL && weapon->m_iId == WEAPON_M249)
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == WEAPON_M249)
return true;
return false;
@ -367,13 +353,12 @@ bool CCSBot::IsUsingMachinegun() const
// Return true if primary weapon doesn't exist or is totally out of ammo
bool CCSBot::IsPrimaryWeaponEmpty() const
{
CBasePlayerWeapon *weapon = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PRIMARY_WEAPON_SLOT ]);
if (weapon == NULL)
CBasePlayerWeapon *pCurrentWeapon = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]);
if (!pCurrentWeapon)
return true;
// check if gun has any ammo left
if (HasAnyAmmo(weapon))
if (HasAnyAmmo(pCurrentWeapon))
return false;
return true;
@ -382,13 +367,12 @@ bool CCSBot::IsPrimaryWeaponEmpty() const
// Return true if pistol doesn't exist or is totally out of ammo
bool CCSBot::IsPistolEmpty() const
{
CBasePlayerWeapon *weapon = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PISTOL_SLOT ]);
if (weapon == NULL)
CBasePlayerWeapon *pCurrentWeapon = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PISTOL_SLOT ]);
if (!pCurrentWeapon)
return true;
// check if gun has any ammo left
if (HasAnyAmmo(weapon))
if (HasAnyAmmo(pCurrentWeapon))
{
return false;
}
@ -397,17 +381,17 @@ bool CCSBot::IsPistolEmpty() const
}
// Equip the given item
bool CCSBot::DoEquip(CBasePlayerWeapon *gun)
bool CCSBot::DoEquip(CBasePlayerWeapon *pWeapon)
{
if (gun == NULL)
if (!pWeapon)
return false;
// check if weapon has any ammo left
if (!HasAnyAmmo(gun))
if (!HasAnyAmmo(pWeapon))
return false;
// equip it
SelectItem(STRING(gun->pev->classname));
SelectItem(STRING(pWeapon->pev->classname));
m_equipTimer.Start();
return true;
@ -423,11 +407,10 @@ void CCSBot::EquipBestWeapon(bool mustEquip)
if (!mustEquip && m_equipTimer.GetElapsedTime() < minEquipInterval)
return;
CBasePlayerWeapon *primary = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PRIMARY_WEAPON_SLOT ]);
if (primary != NULL)
CBasePlayerWeapon *pPrimary = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PRIMARY_WEAPON_SLOT ]);
if (pPrimary)
{
WeaponClassType weaponClass = WeaponIDToWeaponClass(primary->m_iId);
WeaponClassType weaponClass = WeaponIDToWeaponClass(pPrimary->m_iId);
if ((TheCSBots()->AllowShotguns() && weaponClass == WEAPONCLASS_SHOTGUN)
|| (TheCSBots()->AllowMachineGuns() && weaponClass == WEAPONCLASS_MACHINEGUN)
@ -438,9 +421,9 @@ void CCSBot::EquipBestWeapon(bool mustEquip)
#endif
|| (TheCSBots()->AllowSnipers() && weaponClass == WEAPONCLASS_SNIPERRIFLE)
|| (TheCSBots()->AllowSubMachineGuns() && weaponClass == WEAPONCLASS_SUBMACHINEGUN)
|| (TheCSBots()->AllowTacticalShield() && primary->m_iId == WEAPON_SHIELDGUN))
|| (TheCSBots()->AllowTacticalShield() && pPrimary->m_iId == WEAPON_SHIELDGUN))
{
if (DoEquip(primary))
if (DoEquip(pPrimary))
return;
}
}
@ -474,10 +457,10 @@ void CCSBot::EquipKnife()
{
if (!IsUsingKnife())
{
CBasePlayerWeapon *knife = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ KNIFE_SLOT ]);
if (knife != NULL)
CBasePlayerWeapon *pKnife = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ KNIFE_SLOT ]);
if (pKnife)
{
SelectItem(STRING(knife->pev->classname));
SelectItem(STRING(pKnife->pev->classname));
}
}
}
@ -485,8 +468,8 @@ void CCSBot::EquipKnife()
// Return true if we have a grenade in our inventory
bool CCSBot::HasGrenade() const
{
CBasePlayerWeapon *grenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ GRENADE_SLOT ]);
return grenade != NULL;
CBasePlayerWeapon *pGrenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ GRENADE_SLOT ]);
return pGrenade != nullptr;
}
// Equip a grenade, return false if we cant
@ -501,14 +484,13 @@ bool CCSBot::EquipGrenade(bool noSmoke)
if (HasGrenade())
{
CBasePlayerWeapon *grenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ GRENADE_SLOT ]);
if (grenade != NULL)
CBasePlayerWeapon *pGrenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ GRENADE_SLOT ]);
if (pGrenade)
{
if (noSmoke && grenade->m_iId == WEAPON_SMOKEGRENADE)
if (noSmoke && pGrenade->m_iId == WEAPON_SMOKEGRENADE)
return false;
SelectItem(STRING(grenade->pev->classname));
SelectItem(STRING(pGrenade->pev->classname));
return true;
}
}
@ -519,9 +501,8 @@ bool CCSBot::EquipGrenade(bool noSmoke)
// Returns true if we have knife equipped
bool CCSBot::IsUsingKnife() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
if (weapon != NULL && weapon->m_iId == WEAPON_KNIFE)
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == WEAPON_KNIFE)
return true;
return false;
@ -530,9 +511,8 @@ bool CCSBot::IsUsingKnife() const
// Returns true if we have pistol equipped
bool CCSBot::IsUsingPistol() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
if (weapon != NULL && weapon->IsPistol())
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->IsPistol())
return true;
return false;
@ -541,14 +521,14 @@ bool CCSBot::IsUsingPistol() const
// Returns true if we have a grenade equipped
bool CCSBot::IsUsingGrenade() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (weapon == NULL)
if (!pCurrentWeapon)
return false;
if (weapon->m_iId == WEAPON_SMOKEGRENADE
|| weapon->m_iId == WEAPON_FLASHBANG
|| weapon->m_iId == WEAPON_HEGRENADE)
if (pCurrentWeapon->m_iId == WEAPON_SMOKEGRENADE
|| pCurrentWeapon->m_iId == WEAPON_FLASHBANG
|| pCurrentWeapon->m_iId == WEAPON_HEGRENADE)
return true;
return false;
@ -556,9 +536,8 @@ bool CCSBot::IsUsingGrenade() const
bool CCSBot::IsUsingHEGrenade() const
{
CBasePlayerWeapon *weapon = GetActiveWeapon();
if (weapon != NULL && weapon->m_iId == WEAPON_HEGRENADE)
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == WEAPON_HEGRENADE)
return true;
return false;
@ -586,7 +565,7 @@ bool CCSBot::FindGrenadeTossPathTarget(Vector *pos)
// find farthest point we can see on the path
int i;
for (i = m_pathIndex; i < m_pathLength; ++i)
for (i = m_pathIndex; i < m_pathLength; i++)
{
if (!FVisible(m_path[i].pos + Vector(0, 0, HalfHumanHeight)))
break;
@ -733,7 +712,7 @@ void CCSBot::ReloadCheck()
{
PrintIfWatched("Retreating to a safe spot to reload!\n");
const Vector *spot = FindNearbyRetreatSpot(this, 1000.0f);
if (spot != NULL)
if (spot)
{
// ignore enemies for a second to give us time to hide
// reaching our hiding spot clears our disposition
@ -769,17 +748,17 @@ void CCSBot::SilencerCheck()
// don't touch the silencer if there are enemies nearby
if (GetNearbyEnemyCount() == 0)
{
CBasePlayerWeapon *myGun = GetActiveWeapon();
if (myGun == NULL)
CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (!pCurrentWeapon)
return;
bool isSilencerOn = (myGun->m_iWeaponState & (WPNSTATE_M4A1_SILENCED | WPNSTATE_USP_SILENCED)) != 0;
bool isSilencerOn = (pCurrentWeapon->m_iWeaponState & (WPNSTATE_M4A1_SILENCED | WPNSTATE_USP_SILENCED)) != 0;
#ifndef REGAMEDLL_FIXES
if (isSilencerOn != GetProfile()->PrefersSilencer() && !HasShield())
#else
if (myGun->m_flNextSecondaryAttack >= gpGlobals->time)
if (pCurrentWeapon->m_flNextSecondaryAttack >= gpGlobals->time)
return;
// equip silencer if we want to and we don't have a shield.
@ -787,7 +766,7 @@ void CCSBot::SilencerCheck()
#endif
{
PrintIfWatched("%s silencer!\n", (isSilencerOn) ? "Unequipping" : "Equipping");
myGun->SecondaryAttack();
pCurrentWeapon->SecondaryAttack();
}
}
}
@ -813,7 +792,7 @@ void CCSBot::OnTouchingWeapon(CWeaponBox *box)
if (GetTimeSinceLastSawEnemy() >= safeTime)
{
// we have a primary weapon - drop it if the one on the ground is better
for (int i = 0; i < GetProfile()->GetWeaponPreferenceCount(); ++i)
for (int i = 0; i < GetProfile()->GetWeaponPreferenceCount(); i++)
{
int prefID = GetProfile()->GetWeaponPreference(i);
if (!IsPrimaryWeapon(prefID))
@ -853,15 +832,12 @@ bool CCSBot::IsFriendInLineOfFire()
TraceResult result;
UTIL_TraceLine(GetGunPosition(), target + 10000.0f * aimDir, dont_ignore_monsters, ignore_glass, ENT(pev), &result);
if (result.pHit != NULL)
if (result.pHit)
{
CBaseEntity *victim = CBaseEntity::Instance(result.pHit);
if (victim != NULL && victim->IsPlayer() && victim->IsAlive())
CBasePlayer *pVictim = CBasePlayer::Instance(result.pHit);
if (pVictim && pVictim->IsPlayer() && pVictim->IsAlive())
{
CBasePlayer *player = static_cast<CBasePlayer *>(victim);
if (BotRelationship(player) == BOT_TEAMMATE)
if (BotRelationship(pVictim) == BOT_TEAMMATE)
return true;
}
}

View File

@ -15,11 +15,11 @@ CSGameState::CSGameState(CCSBot *owner)
m_bombsiteCount = 0;
m_bombsiteSearchIndex = 0;
for (int i = 0; i < MAX_HOSTAGES; ++i)
for (int i = 0; i < MAX_HOSTAGES; i++)
{
HostageInfo *info = &m_hostage[i];
info->hostage = NULL;
info->hostage = nullptr;
info->knownPos = Vector(0, 0, 0);
info->isValid = false;
info->isAlive = false;
@ -42,7 +42,7 @@ void CSGameState::Reset()
m_isPlantedBombPosKnown = false;
m_plantedBombsite = UNKNOWN;
for (i = 0; i < m_bombsiteCount; ++i)
for (i = 0; i < m_bombsiteCount; i++)
{
m_isBombsiteClear[i] = false;
m_bombsiteSearchOrder[i] = i;
@ -51,7 +51,7 @@ void CSGameState::Reset()
// shuffle the bombsite search order
// allows T's to plant at random site, and TEAM_CT's to search in a random order
// NOTE: VS6 std::random_shuffle() doesn't work well with an array of two elements (most maps)
for (i = 0; i < m_bombsiteCount; ++i)
for (i = 0; i < m_bombsiteCount; i++)
{
int swap = m_bombsiteSearchOrder[i];
int rnd = RANDOM_LONG(i, m_bombsiteCount - 1);
@ -176,7 +176,7 @@ bool CSGameState::IsAtPlantedBombsite() const
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(&m_owner->pev->origin);
if (zone != NULL)
if (zone)
{
return (m_plantedBombsite == zone->m_index);
}
@ -192,7 +192,7 @@ int CSGameState::GetNextBombsiteToSearch()
int i;
// return next non-cleared bombsite index
for (i = m_bombsiteSearchIndex; i < m_bombsiteCount; ++i)
for (i = m_bombsiteSearchIndex; i < m_bombsiteCount; i++)
{
int z = m_bombsiteSearchOrder[i];
if (!m_isBombsiteClear[z])
@ -203,7 +203,7 @@ int CSGameState::GetNextBombsiteToSearch()
}
// all the bombsites are clear, someone must have been mistaken - start search over
for (i = 0; i < m_bombsiteCount; ++i)
for (i = 0; i < m_bombsiteCount; i++)
{
m_isBombsiteClear[i] = false;
}
@ -221,7 +221,7 @@ const Vector *CSGameState::GetBombPosition() const
case MOVING:
{
if (!m_lastSawBomber.HasStarted())
return NULL;
return nullptr;
return &m_bomberPos;
}
@ -230,18 +230,18 @@ const Vector *CSGameState::GetBombPosition() const
if (IsLooseBombLocationKnown())
return &m_looseBombPos;
return NULL;
return nullptr;
}
case PLANTED:
{
if (IsPlantedBombLocationKnown())
return &m_plantedBombPos;
return NULL;
return nullptr;
}
}
return NULL;
return nullptr;
}
// We see the planted bomb at 'pos'
@ -249,7 +249,7 @@ void CSGameState::UpdatePlantedBomb(const Vector *pos)
{
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(pos);
if (zone == NULL)
if (!zone)
{
CONSOLE_ECHO("ERROR: Bomb planted outside of a zone!\n");
m_plantedBombsite = UNKNOWN;
@ -292,21 +292,21 @@ void CSGameState::InitializeHostageInfo()
m_allHostagesRescued = false;
m_haveSomeHostagesBeenTaken = false;
CBaseEntity *hostage = NULL;
while ((hostage = UTIL_FindEntityByClassname(hostage, "hostage_entity")))
CHostage *pHostage = nullptr;
while ((pHostage = UTIL_FindEntityByClassname(pHostage, "hostage_entity")))
{
if (m_hostageCount >= MAX_HOSTAGES)
break;
if (!hostage->IsAlive())
if (!pHostage->IsAlive())
continue;
m_hostage[m_hostageCount].hostage = static_cast<CHostage *>(hostage);
m_hostage[m_hostageCount].knownPos = hostage->pev->origin;
m_hostage[m_hostageCount].hostage = pHostage;
m_hostage[m_hostageCount].knownPos = pHostage->pev->origin;
m_hostage[m_hostageCount].isValid = true;
m_hostage[m_hostageCount].isAlive = true;
m_hostage[m_hostageCount].isFree = true;
++m_hostageCount;
m_hostageCount++;
}
}
@ -318,22 +318,21 @@ void CSGameState::InitializeHostageInfo()
// returned, since CHostages get deleted when they die.
CHostage *CSGameState::GetNearestFreeHostage(Vector *knowPos) const
{
if (m_owner == NULL)
return NULL;
if (!m_owner)
return nullptr;
CNavArea *startArea = m_owner->GetLastKnownArea();
if (!startArea)
return nullptr;
if (startArea == NULL)
return NULL;
CHostage *close = NULL;
const Vector *closePos = NULL;
CHostage *close = nullptr;
const Vector *closePos = nullptr;
float closeDistance = 9999999999.9f;
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
CHostage *hostage = m_hostage[i].hostage;
const Vector *hostagePos = NULL;
CHostage *pHostage = m_hostage[i].hostage;
const Vector *hostagePos = nullptr;
if (m_owner->m_iTeam == CT)
{
@ -344,7 +343,7 @@ CHostage *CSGameState::GetNearestFreeHostage(Vector *knowPos) const
if (m_hostage[i].hostage->IsFollowingSomeone())
continue;
hostagePos = &hostage->pev->origin;
hostagePos = &pHostage->pev->origin;
}
else
{
@ -356,8 +355,7 @@ CHostage *CSGameState::GetNearestFreeHostage(Vector *knowPos) const
}
CNavArea *hostageArea = TheNavAreaGrid.GetNearestNavArea(hostagePos);
if (hostageArea != NULL)
if (hostageArea)
{
ShortestPathCost pc;
float travelDistance = NavAreaTravelDistance(startArea, hostageArea, pc);
@ -366,13 +364,13 @@ CHostage *CSGameState::GetNearestFreeHostage(Vector *knowPos) const
{
closePos = hostagePos;
closeDistance = travelDistance;
close = hostage;
close = pHostage;
}
}
}
// return where we think the hostage is
if (knowPos != NULL && closePos != NULL)
if (knowPos && closePos)
{
knowPos = const_cast<Vector *>(closePos);
}
@ -387,13 +385,13 @@ const Vector *CSGameState::GetRandomFreeHostagePosition()
const Vector *freePos[MAX_HOSTAGES];
int freeCount = 0;
if (m_owner == NULL)
return NULL;
if (!m_owner)
return nullptr;
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
const HostageInfo *info = &m_hostage[i];
const Vector *hostagePos = NULL;
const Vector *hostagePos = nullptr;
if (m_owner->m_iTeam == CT)
{
@ -422,7 +420,7 @@ const Vector *CSGameState::GetRandomFreeHostagePosition()
return freePos[RANDOM_LONG(0, freeCount - 1)];
}
return NULL;
return nullptr;
}
// If we can see any of the positions where we think a hostage is, validate it
@ -437,17 +435,17 @@ CSGameState::ValidateStatusType CSGameState::ValidateHostagePositions()
m_validateInterval.Start(validateInterval);
// check the status of hostages
ValidateStatusType status = NO_CHANGE;
unsigned char status = NO_CHANGE;
int i;
int startValidCount = 0;
for (i = 0; i < m_hostageCount; ++i)
for (i = 0; i < m_hostageCount; i++)
{
if (m_hostage[i].isValid)
++startValidCount;
startValidCount++;
}
for (i = 0; i < m_hostageCount; ++i)
for (i = 0; i < m_hostageCount; i++)
{
HostageInfo *info = &m_hostage[i];
@ -525,10 +523,10 @@ CSGameState::ValidateStatusType CSGameState::ValidateHostagePositions()
}
int endValidCount = 0;
for (i = 0; i < m_hostageCount; ++i)
for (i = 0; i < m_hostageCount; i++)
{
if (m_hostage[i].isValid)
++endValidCount;
endValidCount++;
}
if (endValidCount == 0 && startValidCount > 0)
@ -538,20 +536,20 @@ CSGameState::ValidateStatusType CSGameState::ValidateHostagePositions()
status |= HOSTAGES_ALL_GONE;
}
return status;
return static_cast<ValidateStatusType>(status);
}
// Return the nearest visible free hostage
// Since we can actually see any hostage we return, we know its actual position
CHostage *CSGameState::GetNearestVisibleFreeHostage() const
{
CHostage *close = NULL;
CHostage *close = nullptr;
float closeRangeSq = 999999999.9f;
float rangeSq;
Vector pos;
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
const HostageInfo *info = &m_hostage[i];
@ -591,7 +589,7 @@ bool CSGameState::AreAllHostagesBeingRescued() const
return false;
bool isAllDead = true;
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
const HostageInfo *info = &m_hostage[i];
@ -630,7 +628,7 @@ bool CSGameState::AreAllHostagesGone() const
return true;
// do we know that all the hostages are dead
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
const HostageInfo *info = &m_hostage[i];
@ -653,6 +651,6 @@ bool CSGameState::AreAllHostagesGone() const
// Someone told us all the hostages are gone
void CSGameState::AllHostagesGone()
{
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
m_hostage[i].isValid = false;
}

View File

@ -26,11 +26,7 @@
*
*/
#ifndef CS_GAMESTATE_H
#define CS_GAMESTATE_H
#ifdef _WIN32
#pragma once
#endif
class CCSBot;
@ -94,7 +90,7 @@ public:
CHostage *GetNearestVisibleFreeHostage() const;
// hostage rescue scenario
enum ValidateStatusType:uint8
enum ValidateStatusType : uint8
{
NO_CHANGE = 0x00,
HOSTAGE_DIED = 0x01,
@ -147,5 +143,3 @@ private:
bool m_allHostagesRescued; // if true, so every hostages been is rescued
bool m_haveSomeHostagesBeenTaken; // true if a hostage has been moved by a CT (and we've seen it)
};
#endif // CS_GAMESTATE_H

View File

@ -3,14 +3,14 @@
// Begin attacking
void AttackState::OnEnter(CCSBot *me)
{
CBasePlayer *enemy = me->GetEnemy();
CBasePlayer *pEnemy = me->GetEnemy();
// store our posture when the attack began
me->PushPostureContext();
me->DestroyPath();
// if we are using a knife, try to sneak up on the enemy
if (enemy != NULL && me->IsUsingKnife() && !me->IsPlayerFacingMe(enemy))
if (pEnemy && me->IsUsingKnife() && !me->IsPlayerFacingMe(pEnemy))
me->Walk();
else
me->Run();
@ -44,7 +44,7 @@ void AttackState::OnEnter(CCSBot *me)
// decide whether to crouch where we are, or run and gun (if we havent already - see CCSBot::Attack())
if (!m_crouchAndHold)
{
if (enemy != NULL)
if (pEnemy)
{
const float crouchFarRange = 750.0f;
float crouchChance;
@ -52,7 +52,7 @@ void AttackState::OnEnter(CCSBot *me)
// more likely to crouch if using sniper rifle or if enemy is far away
if (me->IsUsingSniperRifle())
crouchChance = 50.0f;
else if ((me->pev->origin - enemy->pev->origin).IsLengthGreaterThan(crouchFarRange))
else if ((me->pev->origin - pEnemy->pev->origin).IsLengthGreaterThan(crouchFarRange))
crouchChance = 50.0f;
else
crouchChance = 20.0f * (1.0f - me->GetProfile()->GetAggression());
@ -69,7 +69,7 @@ void AttackState::OnEnter(CCSBot *me)
origin.z -= 20.0f;
}
UTIL_TraceLine(origin, enemy->EyePosition(), ignore_monsters, ignore_glass, ENT(me->pev), &result);
UTIL_TraceLine(origin, pEnemy->EyePosition(), ignore_monsters, ignore_glass, ENT(me->pev), &result);
if (result.flFraction == 1.0f)
{
@ -131,20 +131,20 @@ void AttackState::OnUpdate(CCSBot *me)
me->ResetStuckMonitor();
me->StopRapidFire();
CBasePlayerWeapon *weapon = me->GetActiveWeapon();
if (weapon != NULL)
CBasePlayerWeapon *pWeapon = me->GetActiveWeapon();
if (pWeapon)
{
if (weapon->m_iId == WEAPON_C4 ||
weapon->m_iId == WEAPON_HEGRENADE ||
weapon->m_iId == WEAPON_FLASHBANG ||
weapon->m_iId == WEAPON_SMOKEGRENADE)
if (pWeapon->m_iId == WEAPON_C4 ||
pWeapon->m_iId == WEAPON_HEGRENADE ||
pWeapon->m_iId == WEAPON_FLASHBANG ||
pWeapon->m_iId == WEAPON_SMOKEGRENADE)
{
me->EquipBestWeapon();
}
}
CBasePlayer *enemy = me->GetEnemy();
if (enemy == NULL)
CBasePlayer *pEnemy = me->GetEnemy();
if (!pEnemy)
{
StopAttacking(me);
return;
@ -200,7 +200,7 @@ void AttackState::OnUpdate(CCSBot *me)
me->StandUp();
// if we are using a knife and our prey is looking towards us, run at him
if (me->IsPlayerFacingMe(enemy))
if (me->IsPlayerFacingMe(pEnemy))
{
me->ForceRun(5.0f);
me->Hurry(10.0f);
@ -218,7 +218,7 @@ void AttackState::OnUpdate(CCSBot *me)
if (me->HasPath())
{
const float repathRange = 100.0f;
if ((me->GetPathEndpoint() - enemy->pev->origin).IsLengthGreaterThan(repathRange))
if ((me->GetPathEndpoint() - pEnemy->pev->origin).IsLengthGreaterThan(repathRange))
{
repath = true;
}
@ -230,7 +230,7 @@ void AttackState::OnUpdate(CCSBot *me)
if (repath && m_repathTimer.IsElapsed())
{
me->ComputePath(TheNavAreaGrid.GetNearestNavArea(&enemy->pev->origin), &enemy->pev->origin, FASTEST_ROUTE);
me->ComputePath(TheNavAreaGrid.GetNearestNavArea(&pEnemy->pev->origin), &pEnemy->pev->origin, FASTEST_ROUTE);
const float repathInterval = 0.5f;
m_repathTimer.Start(repathInterval);
@ -250,7 +250,7 @@ void AttackState::OnUpdate(CCSBot *me)
{
if (me->IsEnemyVisible() && !m_shieldForceOpen)
{
if (!me->IsRecognizedEnemyReloading() && !me->IsReloading() && me->IsPlayerLookingAtMe(enemy))
if (!me->IsRecognizedEnemyReloading() && !me->IsReloading() && me->IsPlayerLookingAtMe(pEnemy))
{
// close up - enemy is pointing his gun at us
if (!me->IsProtectedByShield())
@ -285,14 +285,14 @@ void AttackState::OnUpdate(CCSBot *me)
// if we have a sniper rifle and our enemy is too close, switch to pistol
// NOTE: Must be larger than NO_ZOOM range in AdjustZoom()
const float sniperMinRange = 310.0f;
if ((enemy->pev->origin - me->pev->origin).IsLengthLessThan(sniperMinRange))
if ((pEnemy->pev->origin - me->pev->origin).IsLengthLessThan(sniperMinRange))
me->EquipPistol();
}
else if (me->IsUsingShotgun())
{
// if we have a shotgun equipped and enemy is too far away, switch to pistol
const float shotgunMaxRange = 1000.0f;
if ((enemy->pev->origin - me->pev->origin).IsLengthGreaterThan(shotgunMaxRange))
if ((pEnemy->pev->origin - me->pev->origin).IsLengthGreaterThan(shotgunMaxRange))
me->EquipPistol();
}
@ -325,9 +325,9 @@ void AttackState::OnUpdate(CCSBot *me)
if (me->IsAwareOfEnemyDeath())
{
// let team know if we killed the last enemy
if (me->GetLastVictimID() == enemy->entindex() && me->GetNearbyEnemyCount() <= 1)
if (me->GetLastVictimID() == pEnemy->entindex() && me->GetNearbyEnemyCount() <= 1)
{
me->GetChatter()->KilledMyEnemy(enemy->entindex());
me->GetChatter()->KilledMyEnemy(pEnemy->entindex());
}
StopAttacking(me);
@ -372,7 +372,7 @@ void AttackState::OnUpdate(CCSBot *me)
// hide in ambush nearby
// TODO: look towards where we know enemy is
const Vector *spot = FindNearbyRetreatSpot(me, 200.0f);
if (spot != NULL)
if (spot)
{
me->IgnoreEnemies(1.0f);
me->Run();
@ -430,7 +430,7 @@ void AttackState::OnUpdate(CCSBot *me)
else
{
// move to last known position of enemy
me->SetTask(CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION, enemy);
me->SetTask(CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION, pEnemy);
me->MoveTo(&me->GetLastKnownEnemyPosition());
return;
}
@ -441,7 +441,7 @@ void AttackState::OnUpdate(CCSBot *me)
const float hurtRecentlyTime = 3.0f;
if (!me->IsEnemyVisible() &&
me->GetTimeSinceAttacked() < hurtRecentlyTime &&
me->GetAttacker() != NULL &&
me->GetAttacker() &&
me->GetAttacker() != me->GetEnemy())
{
// if we can see them, attack, otherwise panic
@ -460,7 +460,7 @@ void AttackState::OnUpdate(CCSBot *me)
// If sniping or crouching, stand still.
if (m_dodge && !me->IsUsingSniperRifle() && !m_crouchAndHold)
{
Vector toEnemy = enemy->pev->origin - me->pev->origin;
Vector toEnemy = pEnemy->pev->origin - me->pev->origin;
float range = toEnemy.Length2D();
const float hysterisRange = 125.0f; // (+/-) m_combatRange
@ -479,7 +479,7 @@ void AttackState::OnUpdate(CCSBot *me)
// don't dodge if enemy is facing away
const float dodgeRange = 2000.0f;
if (range > dodgeRange || !me->IsPlayerFacingMe(enemy))
if (range > dodgeRange || !me->IsPlayerFacingMe(pEnemy))
{
m_dodgeState = STEADY_ON;
m_nextDodgeStateTimestamp = 0.0f;

View File

@ -2,15 +2,15 @@
bool HasDefaultPistol(CCSBot *me)
{
CBasePlayerWeapon *pistol = static_cast<CBasePlayerWeapon *>(me->m_rgpPlayerItems[ PISTOL_SLOT ]);
CBasePlayerWeapon *pSecondary = static_cast<CBasePlayerWeapon *>(me->m_rgpPlayerItems[ PISTOL_SLOT ]);
if (pistol == NULL)
if (!pSecondary)
return false;
if (me->m_iTeam == TERRORIST && pistol->m_iId == WEAPON_GLOCK18)
if (me->m_iTeam == TERRORIST && pSecondary->m_iId == WEAPON_GLOCK18)
return true;
if (me->m_iTeam == CT && pistol->m_iId == WEAPON_USP)
if (me->m_iTeam == CT && pSecondary->m_iId == WEAPON_USP)
return true;
return false;
@ -73,21 +73,21 @@ void BuyState::OnEnter(CCSBot *me)
if (TheCSBots()->AllowPistols())
{
CBasePlayerWeapon *pistol = static_cast<CBasePlayerWeapon *>(me->m_rgpPlayerItems[ PISTOL_SLOT ]);
CBasePlayerWeapon *pSecondary = static_cast<CBasePlayerWeapon *>(me->m_rgpPlayerItems[ PISTOL_SLOT ]);
// check if we have a pistol
if (pistol != NULL)
if (pSecondary)
{
// if we have our default pistol, think about buying a different one
if (HasDefaultPistol(me))
{
// if everything other than pistols is disallowed, buy a pistol
if (TheCSBots()->AllowShotguns() == false &&
TheCSBots()->AllowSubMachineGuns() == false &&
TheCSBots()->AllowRifles() == false &&
TheCSBots()->AllowMachineGuns() == false &&
TheCSBots()->AllowTacticalShield() == false &&
TheCSBots()->AllowSnipers() == false)
if (!TheCSBots()->AllowShotguns()
&& !TheCSBots()->AllowSubMachineGuns()
&& !TheCSBots()->AllowRifles()
&& !TheCSBots()->AllowMachineGuns()
&& !TheCSBots()->AllowTacticalShield()
&& !TheCSBots()->AllowSnipers())
{
m_buyPistol = (RANDOM_FLOAT(0, 100) < 75.0f);
}
@ -133,7 +133,7 @@ struct BuyInfo
#ifndef HOOK_GAMEDLL
BuyInfo primaryWeaponBuyInfoCT[ PRIMARY_WEAPON_BUY_COUNT ] =
BuyInfo primaryWeaponBuyInfoCT[ MAX_BUY_WEAPON_PRIMARY ] =
{
{ SHOTGUN, false, "m3" }, // WEAPON_M3
{ SHOTGUN, false, "xm1014" }, // WEAPON_XM1014
@ -150,7 +150,7 @@ BuyInfo primaryWeaponBuyInfoCT[ PRIMARY_WEAPON_BUY_COUNT ] =
{ MACHINE_GUN, false, "m249" }, // WEAPON_M249
};
BuyInfo secondaryWeaponBuyInfoCT[ SECONDARY_WEAPON_BUY_COUNT ] =
BuyInfo secondaryWeaponBuyInfoCT[ MAX_BUY_WEAPON_SECONDARY ] =
{
// { PISTOL, false, "glock" },
// { PISTOL, false, "usp" },
@ -159,7 +159,7 @@ BuyInfo secondaryWeaponBuyInfoCT[ SECONDARY_WEAPON_BUY_COUNT ] =
{ PISTOL, true, "fn57" },
};
BuyInfo primaryWeaponBuyInfoT[ PRIMARY_WEAPON_BUY_COUNT ] =
BuyInfo primaryWeaponBuyInfoT[ MAX_BUY_WEAPON_PRIMARY ] =
{
{ SHOTGUN, false, "m3" }, // WEAPON_M3
{ SHOTGUN, false, "xm1014" }, // WEAPON_XM1014
@ -176,7 +176,7 @@ BuyInfo primaryWeaponBuyInfoT[ PRIMARY_WEAPON_BUY_COUNT ] =
{ MACHINE_GUN, false, "m249" }, // WEAPON_M249
};
BuyInfo secondaryWeaponBuyInfoT[ SECONDARY_WEAPON_BUY_COUNT ] =
BuyInfo secondaryWeaponBuyInfoT[ MAX_BUY_WEAPON_SECONDARY ] =
{
// { PISTOL, false, "glock" },
// { PISTOL, false, "usp" },
@ -187,11 +187,11 @@ BuyInfo secondaryWeaponBuyInfoT[ SECONDARY_WEAPON_BUY_COUNT ] =
#else // HOOK_GAMEDLL
BuyInfo primaryWeaponBuyInfoCT[ PRIMARY_WEAPON_BUY_COUNT ];
BuyInfo secondaryWeaponBuyInfoCT[ SECONDARY_WEAPON_BUY_COUNT];
BuyInfo primaryWeaponBuyInfoCT[ MAX_BUY_WEAPON_PRIMARY ];
BuyInfo secondaryWeaponBuyInfoCT[ MAX_BUY_WEAPON_SECONDARY];
BuyInfo primaryWeaponBuyInfoT[ PRIMARY_WEAPON_BUY_COUNT ];
BuyInfo secondaryWeaponBuyInfoT[ SECONDARY_WEAPON_BUY_COUNT ];
BuyInfo primaryWeaponBuyInfoT[ MAX_BUY_WEAPON_PRIMARY ];
BuyInfo secondaryWeaponBuyInfoT[ MAX_BUY_WEAPON_SECONDARY ];
#endif // HOOK_GAMEDLL
@ -199,7 +199,7 @@ BuyInfo secondaryWeaponBuyInfoT[ SECONDARY_WEAPON_BUY_COUNT ];
inline WeaponType GetWeaponType(const char *alias)
{
int i;
for (i = 0; i < PRIMARY_WEAPON_BUY_COUNT; ++i)
for (i = 0; i < MAX_BUY_WEAPON_PRIMARY; i++)
{
if (!Q_stricmp(alias, primaryWeaponBuyInfoCT[i].buyAlias))
return primaryWeaponBuyInfoCT[i].type;
@ -208,7 +208,7 @@ inline WeaponType GetWeaponType(const char *alias)
return primaryWeaponBuyInfoT[i].type;
}
for (i = 0; i < SECONDARY_WEAPON_BUY_COUNT; ++i)
for (i = 0; i < MAX_BUY_WEAPON_SECONDARY; i++)
{
if (!Q_stricmp(alias, secondaryWeaponBuyInfoCT[i].buyAlias))
return secondaryWeaponBuyInfoCT[i].type;
@ -281,7 +281,7 @@ void BuyState::OnUpdate(CCSBot *me)
if (m_prefRetries >= maxPrefRetries)
{
// try to buy next preferred weapon
++m_prefIndex;
m_prefIndex++;
m_prefRetries = 0;
return;
}
@ -289,8 +289,8 @@ void BuyState::OnUpdate(CCSBot *me)
int weaponPreference = me->GetProfile()->GetWeaponPreference(m_prefIndex);
// don't buy it again if we still have one from last round
CBasePlayerWeapon *weapon = me->GetActiveWeapon();
if (weapon != NULL && weapon->m_iId == weaponPreference)
CBasePlayerWeapon *pCurrentWeapon = me->GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == weaponPreference)
{
// done with buying preferred weapon
m_prefIndex = 9999;
@ -304,8 +304,7 @@ void BuyState::OnUpdate(CCSBot *me)
return;
}
const char *buyAlias = NULL;
const char *buyAlias = nullptr;
if (weaponPreference == WEAPON_SHIELDGUN)
{
if (TheCSBots()->AllowTacticalShield())
@ -320,27 +319,27 @@ void BuyState::OnUpdate(CCSBot *me)
{
case PISTOL:
if (!TheCSBots()->AllowPistols())
buyAlias = NULL;
buyAlias = nullptr;
break;
case SHOTGUN:
if (!TheCSBots()->AllowShotguns())
buyAlias = NULL;
buyAlias = nullptr;
break;
case SUB_MACHINE_GUN:
if (!TheCSBots()->AllowSubMachineGuns())
buyAlias = NULL;
buyAlias = nullptr;
break;
case RIFLE:
if (!TheCSBots()->AllowRifles())
buyAlias = NULL;
buyAlias = nullptr;
break;
case MACHINE_GUN:
if (!TheCSBots()->AllowMachineGuns())
buyAlias = NULL;
buyAlias = nullptr;
break;
case SNIPER_RIFLE:
if (!TheCSBots()->AllowSnipers())
buyAlias = NULL;
buyAlias = nullptr;
break;
}
}
@ -353,7 +352,7 @@ void BuyState::OnUpdate(CCSBot *me)
isPreferredAllDisallowed = false;
}
++m_prefRetries;
m_prefRetries++;
// bail out so we dont waste money on other equipment
// unless everything we prefer has been disallowed, then buy at random
@ -374,14 +373,14 @@ void BuyState::OnUpdate(CCSBot *me)
{
// build list of allowable weapons to buy
BuyInfo *masterPrimary = (me->m_iTeam == TERRORIST) ? primaryWeaponBuyInfoT : primaryWeaponBuyInfoCT;
BuyInfo *stockPrimary[ PRIMARY_WEAPON_BUY_COUNT ];
BuyInfo *stockPrimary[ MAX_BUY_WEAPON_PRIMARY ];
int stockPrimaryCount = 0;
// dont choose sniper rifles as often
const float sniperRifleChance = 50.0f;
bool wantSniper = (RANDOM_FLOAT(0, 100) < sniperRifleChance) ? true : false;
for (int i = 0; i < PRIMARY_WEAPON_BUY_COUNT; ++i)
for (int i = 0; i < MAX_BUY_WEAPON_PRIMARY; i++)
{
if ((masterPrimary[i].type == SHOTGUN && TheCSBots()->AllowShotguns()) ||
(masterPrimary[i].type == SUB_MACHINE_GUN && TheCSBots()->AllowSubMachineGuns()) ||
@ -403,16 +402,16 @@ void BuyState::OnUpdate(CCSBot *me)
{
// count up available preferred weapons
int prefCount = 0;
for (which = 0; which < stockPrimaryCount; ++which)
for (which = 0; which < stockPrimaryCount; which++)
{
if (stockPrimary[which]->preferred)
++prefCount;
prefCount++;
}
if (prefCount)
{
int whichPref = RANDOM_LONG(0, prefCount - 1);
for (which = 0; which < stockPrimaryCount; ++which)
for (which = 0; which < stockPrimaryCount; which++)
{
if (stockPrimary[which]->preferred && whichPref-- == 0)
break;
@ -453,7 +452,7 @@ void BuyState::OnUpdate(CCSBot *me)
{
if (m_buyPistol)
{
int which = RANDOM_LONG(0, SECONDARY_WEAPON_BUY_COUNT - 1);
int which = RANDOM_LONG(0, MAX_BUY_WEAPON_SECONDARY - 1);
if (me->m_iTeam == TERRORIST)
me->ClientCommand(secondaryWeaponBuyInfoT[ which ].buyAlias);

View File

@ -14,7 +14,7 @@ void EscapeFromBombState::OnUpdate(CCSBot *me)
const Vector *bombPos = me->GetGameState()->GetBombPosition();
// if we don't know where the bomb is, we shouldn't be in this state
if (bombPos == NULL)
if (!bombPos)
{
me->Idle();
return;
@ -33,7 +33,7 @@ void EscapeFromBombState::OnUpdate(CCSBot *me)
CNavArea *goalArea = FindMinimumCostArea(me->GetLastKnownArea(), func);
// if this fails, we'll try again next time
me->ComputePath(goalArea, NULL, FASTEST_ROUTE);
me->ComputePath(goalArea, nullptr, FASTEST_ROUTE);
}
}

View File

@ -16,13 +16,13 @@ void FetchBombState::OnUpdate(CCSBot *me)
return;
}
CBaseEntity *bomb = TheCSBots()->GetLooseBomb();
if (bomb != NULL)
CBaseEntity *pBomb = TheCSBots()->GetLooseBomb();
if (pBomb)
{
if (!me->HasPath())
{
// build a path to the bomb
if (me->ComputePath(TheNavAreaGrid.GetNavArea(&bomb->pev->origin), &bomb->pev->origin, SAFEST_ROUTE) == false)
if (me->ComputePath(TheNavAreaGrid.GetNavArea(&pBomb->pev->origin), &pBomb->pev->origin, SAFEST_ROUTE) == false)
{
me->PrintIfWatched("Fetch bomb pathfind failed\n");

View File

@ -75,7 +75,7 @@ void FollowState::ComputeLeaderMotionState(float leaderSpeed)
void FollowState::OnUpdate(CCSBot *me)
{
// if we lost our leader, give up
if (m_leader == NULL || !m_leader->IsAlive())
if (!m_leader || !m_leader->IsAlive())
{
me->Idle();
return;
@ -159,7 +159,7 @@ void FollowState::OnUpdate(CCSBot *me)
if ((m_leader->pev->origin - me->pev->origin).IsLengthLessThan(nearLeaderRange))
{
const float hideRange = 250.0f;
if (me->TryToHide(NULL, -1.0f, hideRange, false, USE_NEAREST))
if (me->TryToHide(nullptr, -1.0f, hideRange, false, USE_NEAREST))
{
me->ResetStuckMonitor();
return;
@ -203,14 +203,14 @@ void FollowState::OnUpdate(CCSBot *me)
if (cv_bot_debug.value > 0.0f)
{
for (int i = 0; i < collector.m_targetAreaCount; ++i)
for (int i = 0; i < collector.m_targetAreaCount; i++)
collector.m_targetArea[i]->Draw(255, 0, 0, 2);
}
// move to one of the collected areas
if (collector.m_targetAreaCount)
{
CNavArea *target = NULL;
CNavArea *target = nullptr;
Vector targetPos;
// if we are idle, pick a random area
@ -229,7 +229,7 @@ void FollowState::OnUpdate(CCSBot *me)
float closeRangeSq = 9999999999.9f;
Vector close;
for (int a = 0; a < collector.m_targetAreaCount; ++a)
for (int a = 0; a < collector.m_targetAreaCount; a++)
{
area = collector.m_targetArea[a];
area->GetClosestPointOnArea(&me->pev->origin, &close);
@ -244,8 +244,10 @@ void FollowState::OnUpdate(CCSBot *me)
}
}
if (me->ComputePath(target, NULL, FASTEST_ROUTE) == NULL)
if (!me->ComputePath(target, nullptr, FASTEST_ROUTE))
{
me->PrintIfWatched("Pathfind to leader failed.\n");
}
// throttle how often we repath
m_repathInterval.Start(0.5f);

View File

@ -57,10 +57,10 @@ void HideState::OnUpdate(CCSBot *me)
{
// if we're guarding a bombsite, continue to guard it but pick a new spot
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(&me->pev->origin);
if (zone != NULL)
if (zone)
{
CNavArea *area = TheCSBots()->GetRandomAreaInZone(zone);
if (area != NULL)
if (area)
{
me->Hide(area);
return;
@ -127,14 +127,14 @@ void HideState::OnUpdate(CCSBot *me)
}
// if we are guarding the defuser and he dies/gives up, stop hiding (to choose another defuser)
if (me->GetTask() == CCSBot::GUARD_BOMB_DEFUSER && TheCSBots()->GetBombDefuser() == NULL)
if (me->GetTask() == CCSBot::GUARD_BOMB_DEFUSER && !TheCSBots()->GetBombDefuser())
{
me->Idle();
return;
}
// if we are guarding the loose bomb and it is picked up, stop hiding
if (me->GetTask() == CCSBot::GUARD_LOOSE_BOMB && TheCSBots()->GetLooseBomb() == NULL)
if (me->GetTask() == CCSBot::GUARD_LOOSE_BOMB && !TheCSBots()->GetLooseBomb())
{
me->GetChatter()->TheyPickedUpTheBomb();
me->Idle();
@ -197,12 +197,12 @@ void HideState::OnUpdate(CCSBot *me)
else if (me->GetTask() == CCSBot::GUARD_HOSTAGE_RESCUE_ZONE)
{
// if we stumble across a hostage, guard it
CHostage *hostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (hostage != NULL)
CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (pHostage)
{
// we see a free hostage, guard it
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin);
if (area != NULL)
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area)
{
me->SetTask(CCSBot::GUARD_HOSTAGES);
me->Hide(area);
@ -300,8 +300,8 @@ void HideState::OnUpdate(CCSBot *me)
{
if (me->GetNearbyEnemyCount() == 0)
{
CHostage *hostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (hostage != NULL)
CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (pHostage)
{
me->GetChatter()->Encourage("WaitingForHumanToRescueHostages", RANDOM_FLOAT(10.0f, 15.0f));
}
@ -314,10 +314,10 @@ void HideState::OnUpdate(CCSBot *me)
{
// if a Player is using this hiding spot, give up
float range;
CBasePlayer *camper = UTIL_GetClosestPlayer(&m_hidingSpot, &range);
CBasePlayer *pCamper = UTIL_GetClosestPlayer(&m_hidingSpot, &range);
const float closeRange = 75.0f;
if (camper != NULL && camper != me && range < closeRange && me->IsVisible(camper, CHECK_FOV))
if (pCamper && pCamper != me && range < closeRange && me->IsVisible(pCamper, CHECK_FOV))
{
// player is in our hiding spot
me->PrintIfWatched("Someone's in my hiding spot - picking another...\n");
@ -389,7 +389,7 @@ void HideState::OnUpdate(CCSBot *me)
// search from hiding spot, since we know it was valid
const Vector *pos = FindNearbyHidingSpot(me, &m_hidingSpot, m_searchFromArea, m_range, me->IsSniper());
if (pos == NULL)
if (!pos)
{
// no available hiding spots
me->PrintIfWatched("No available hiding spots - hiding where I'm at.\n");

View File

@ -55,7 +55,7 @@ void HuntState::OnUpdate(CCSBot *me)
// if bomb has been planted, and we hear it, move to a hiding spot near the bomb and watch it
const Vector *bombPos = me->GetGameState()->GetBombPosition();
if (!me->IsRogue() && me->GetGameState()->IsBombPlanted() && bombPos != NULL)
if (!me->IsRogue() && me->GetGameState()->IsBombPlanted() && bombPos)
{
me->SetTask(CCSBot::GUARD_TICKING_BOMB);
me->Hide(TheNavAreaGrid.GetNavArea(bombPos));
@ -105,11 +105,11 @@ void HuntState::OnUpdate(CCSBot *me)
// if safe time is up, and we stumble across a hostage, guard it
if (!me->IsRogue() && !me->IsSafe())
{
CHostage *hostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (hostage != NULL)
CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (pHostage)
{
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin);
if (area != NULL)
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area)
{
// we see a free hostage, guard it
me->SetTask(CCSBot::GUARD_HOSTAGES);
@ -137,19 +137,14 @@ void HuntState::OnUpdate(CCSBot *me)
// if our path fails, pick a new one
if (me->GetLastKnownArea() == m_huntArea || me->UpdatePathMovement() != CCSBot::PROGRESSING)
{
m_huntArea = NULL;
m_huntArea = nullptr;
float oldest = 0.0f;
int areaCount = 0;
const float minSize = 150.0f;
NavAreaList::iterator iter;
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
for (auto area : TheNavAreaList)
{
CNavArea *area = (*iter);
++areaCount;
areaCount++;
// skip the small areas
const Extent *extent = area->GetExtent();
@ -169,20 +164,20 @@ void HuntState::OnUpdate(CCSBot *me)
int which = RANDOM_LONG(0, areaCount - 1);
areaCount = 0;
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
for (auto area : TheNavAreaList)
{
m_huntArea = (*iter);
m_huntArea = area;
if (which == areaCount)
break;
--which;
which--;
}
if (m_huntArea != NULL)
if (m_huntArea)
{
// create a new path to a far away area of the map
me->ComputePath(m_huntArea, NULL, SAFEST_ROUTE);
me->ComputePath(m_huntArea, nullptr, SAFEST_ROUTE);
}
}
}

View File

@ -9,7 +9,7 @@ const float sniperHideRange = 2000.0f;
void IdleState::OnEnter(CCSBot *me)
{
me->DestroyPath();
me->SetEnemy(NULL);
me->SetEnemy(nullptr);
// lurking death
if (me->IsUsingKnife() && me->IsWellPastSafe() && !me->IsHurrying())
@ -192,7 +192,7 @@ void IdleState::OnUpdate(CCSBot *me)
}
// if bomb has been planted, and we hear it, move to a hiding spot near the bomb and guard it
if (!me->IsRogue() && me->GetGameState()->IsBombPlanted() && me->GetGameState()->GetBombPosition() != NULL)
if (!me->IsRogue() && me->GetGameState()->IsBombPlanted() && me->GetGameState()->GetBombPosition())
{
const Vector *bombPos = me->GetGameState()->GetBombPosition();
@ -271,7 +271,7 @@ void IdleState::OnUpdate(CCSBot *me)
const CCSBotManager::Zone *zone = nullptr;
float travelDistance = 9999999.9f;
for (int z = 0; z < TheCSBots()->GetZoneCount(); ++z)
for (int z = 0; z < TheCSBots()->GetZoneCount(); z++)
{
if (TheCSBots()->GetZone(z)->m_areaCount == 0)
continue;
@ -333,7 +333,7 @@ void IdleState::OnUpdate(CCSBot *me)
{
if (RANDOM_FLOAT(0, 100) <= defenseSniperCampChance)
{
CNavArea *snipingArea = NULL;
CNavArea *snipingArea = nullptr;
// if the bomb is loose, snipe near it
if (me->GetGameState()->IsLooseBombLocationKnown())
@ -463,7 +463,7 @@ void IdleState::OnUpdate(CCSBot *me)
{
// if early in round, pick a random zone, otherwise pick closest zone
const float earlyTime = 20.0f;
const CCSBotManager::Zone *zone = NULL;
const CCSBotManager::Zone *zone = nullptr;
if (TheCSBots()->GetElapsedRoundTime() < earlyTime)
{
@ -563,11 +563,11 @@ void IdleState::OnUpdate(CCSBot *me)
// if safe time is up, and we stumble across a hostage, guard it
if (!me->IsSafe() && !me->IsRogue())
{
CBaseEntity *hostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (hostage)
CBaseEntity *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (pHostage)
{
// we see a free hostage, guard it
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin);
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area)
{
me->SetTask(CCSBot::GUARD_HOSTAGES);
@ -655,14 +655,14 @@ void IdleState::OnUpdate(CCSBot *me)
}
// look for free hostages - CT's have radar so they know where hostages are at all times
CHostage *hostage = me->GetGameState()->GetNearestFreeHostage();
CHostage *pHostage = me->GetGameState()->GetNearestFreeHostage();
// if we are not allowed to do the scenario, guard the hostages to clear the area for the human(s)
if (!me->IsDoingScenario())
{
if (hostage)
if (pHostage)
{
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin);
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area)
{
me->SetTask(CCSBot::GUARD_HOSTAGES);
@ -678,8 +678,8 @@ void IdleState::OnUpdate(CCSBot *me)
bool fetchHostages = false;
bool rescueHostages = false;
const CCSBotManager::Zone *zone = NULL;
me->SetGoalEntity(NULL);
const CCSBotManager::Zone *zone = nullptr;
me->SetGoalEntity(nullptr);
// if we are escorting hostages, determine where to take them
if (me->GetHostageEscortCount())
@ -687,13 +687,13 @@ void IdleState::OnUpdate(CCSBot *me)
// if we are escorting hostages and there are more hostages to rescue,
// determine whether it's faster to rescue the ones we have, or go get the remaining ones
if (hostage)
if (pHostage)
{
if (zone)
{
PathCost pathCost(me, FASTEST_ROUTE);
float toZone = NavAreaTravelDistance(me->GetLastKnownArea(), zone->m_area[0], pathCost);
float toHostage = NavAreaTravelDistance(me->GetLastKnownArea(), TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin), pathCost);
float toHostage = NavAreaTravelDistance(me->GetLastKnownArea(), TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin), pathCost);
if (toHostage < 0.0f)
{
@ -722,12 +722,12 @@ void IdleState::OnUpdate(CCSBot *me)
// go get hostages
me->SetTask(CCSBot::COLLECT_HOSTAGES);
me->Run();
me->SetGoalEntity(hostage);
me->SetGoalEntity(pHostage);
me->ResetWaitForHostagePatience();
// if we already have some hostages, move to the others by the quickest route
RouteType route = (me->GetHostageEscortCount()) ? FASTEST_ROUTE : SAFEST_ROUTE;
me->MoveTo(&hostage->pev->origin, route);
me->MoveTo(&pHostage->pev->origin, route);
me->PrintIfWatched("I'm collecting hostages\n");
return;
}

View File

@ -41,8 +41,8 @@ void MoveToState::OnUpdate(CCSBot *me)
if (me->GetTask() == CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION)
{
// TODO: Account for reaction time so we take some time to realized the enemy is dead
CBasePlayer *victim = static_cast<CBasePlayer *>(me->GetTaskEntity());
if (victim == NULL || !victim->IsAlive())
CBaseEntity *pVictim = me->GetTaskEntity();
if (!pVictim || !pVictim->IsAlive())
{
me->PrintIfWatched("The enemy I was chasing was killed - giving up.\n");
me->Idle();
@ -77,7 +77,7 @@ void MoveToState::OnUpdate(CCSBot *me)
}
// check off bombsites that we explore or happen to stumble into
for (int z = 0; z < TheCSBots()->GetZoneCount(); ++z)
for (int z = 0; z < TheCSBots()->GetZoneCount(); z++)
{
// don't re-check zones
if (me->GetGameState()->IsBombsiteClear(z))
@ -171,8 +171,8 @@ void MoveToState::OnUpdate(CCSBot *me)
{
// Since CT's have a radar, they can directly look at the actual hostage state
// check if someone else collected our hostage, or the hostage died or was rescued
CHostage *hostage = static_cast<CHostage *>(me->GetGoalEntity());
if (!hostage || !hostage->IsAlive() || hostage->IsFollowingSomeone())
CHostage *pHostage = me->GetGoalEntity<CHostage>();
if (!pHostage || !pHostage->IsAlive() || pHostage->IsFollowingSomeone())
{
me->Idle();
return;
@ -180,17 +180,17 @@ void MoveToState::OnUpdate(CCSBot *me)
// if our hostage has moved, repath
const float repathToleranceSq = 75.0f * 75.0f;
float error = (hostage->pev->origin - m_goalPosition).LengthSquared();
float error = (pHostage->pev->origin - m_goalPosition).LengthSquared();
if (error > repathToleranceSq)
{
m_goalPosition = hostage->pev->origin;
m_goalPosition = pHostage->pev->origin;
me->ComputePath(TheNavAreaGrid.GetNavArea(&m_goalPosition), &m_goalPosition, SAFEST_ROUTE);
}
// TODO: Generalize ladder priorities over other tasks
if (!me->IsUsingLadder())
{
Vector pos = hostage->pev->origin + Vector(0, 0, HumanHeight * 0.75f);
Vector pos = pHostage->pev->origin + Vector(0, 0, HumanHeight * 0.75f);
Vector to = pos - me->pev->origin;
// look at the hostage as we approach
@ -210,7 +210,7 @@ void MoveToState::OnUpdate(CCSBot *me)
}
// check if we are close enough to the hostage to talk to him
const float useRange = PLAYER_USE_RADIUS - 14.0f; // shave off a fudge factor to make sure we're within range
const float useRange = MAX_PLAYER_USE_RADIUS - 14.0f; // shave off a fudge factor to make sure we're within range
if (to.IsLengthLessThan(useRange))
{
me->UseEntity(me->GetGoalEntity());
@ -254,7 +254,7 @@ void MoveToState::OnUpdate(CCSBot *me)
{
// if we are near the bomb, defuse it (if we are reloading, don't try to defuse until we finish)
const Vector *bombPos = me->GetGameState()->GetBombPosition();
if (bombPos != NULL)
if (bombPos)
{
const float defuseRange = 100.0f;
Vector toBomb = *bombPos - me->pev->origin;
@ -271,8 +271,8 @@ void MoveToState::OnUpdate(CCSBot *me)
}
case CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION:
{
CBasePlayer *victim = static_cast<CBasePlayer *>(me->GetTaskEntity());
if (victim != NULL && victim->IsAlive())
CBaseEntity *pVictim = me->GetTaskEntity();
if (pVictim && pVictim->IsAlive())
{
// if we got here and haven't re-acquired the enemy, we lost him
me->GetChatter()->Say("LostEnemy");

View File

@ -16,11 +16,11 @@ void PlantBombState::OnEnter(CCSBot *me)
// Plant the bomb.
void PlantBombState::OnUpdate(CCSBot *me)
{
CBasePlayerWeapon *gun = me->GetActiveWeapon();
CBasePlayerWeapon *pCurrentWeapon = me->GetActiveWeapon();
bool holdingC4 = false;
if (gun != NULL)
if (pCurrentWeapon)
{
if (FStrEq(STRING(gun->pev->classname), "weapon_c4"))
if (FClassnameIs(pCurrentWeapon->pev, "weapon_c4"))
holdingC4 = true;
}

View File

@ -15,8 +15,8 @@ TYPEDESCRIPTION CEnvGlobal::m_SaveData[] =
TYPEDESCRIPTION CMultiSource::m_SaveData[] =
{
// BUGBUG FIX
DEFINE_ARRAY(CMultiSource, m_rgEntities, FIELD_EHANDLE, MS_MAX_TARGETS),
DEFINE_ARRAY(CMultiSource, m_rgTriggered, FIELD_INTEGER, MS_MAX_TARGETS),
DEFINE_ARRAY(CMultiSource, m_rgEntities, FIELD_EHANDLE, MAX_MS_TARGETS),
DEFINE_ARRAY(CMultiSource, m_rgTriggered, FIELD_INTEGER, MAX_MS_TARGETS),
DEFINE_FIELD(CMultiSource, m_iTotal, FIELD_INTEGER),
DEFINE_FIELD(CMultiSource, m_globalstate, FIELD_STRING),
};
@ -73,7 +73,9 @@ void CEnvGlobal::KeyValue(KeyValueData *pkvd)
m_initialstate = Q_atoi(pkvd->szValue);
}
else
{
CPointEntity::KeyValue(pkvd);
}
}
void CEnvGlobal::Spawn()
@ -154,7 +156,9 @@ void CMultiSource::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CPointEntity::KeyValue(pkvd);
}
}
void CMultiSource::Spawn()
@ -244,32 +248,32 @@ BOOL CMultiSource::IsTriggered(CBaseEntity *)
void CMultiSource::Register()
{
m_iTotal = 0;
Q_memset(m_rgEntities, 0, MS_MAX_TARGETS * sizeof(EHANDLE));
Q_memset(m_rgEntities, 0, MAX_MS_TARGETS * sizeof(EHANDLE));
SetThink(&CMultiSource::SUB_DoNothing);
// search for all entities which target this multisource (pev->targetname)
#ifdef REGAMEDLL_FIXES
CBaseEntity *pTarget = nullptr;
while (m_iTotal < MS_MAX_TARGETS && (pTarget = UTIL_FindEntityByString(pTarget, "target", STRING(pev->targetname)))) {
while (m_iTotal < MAX_MS_TARGETS && (pTarget = UTIL_FindEntityByString(pTarget, "target", STRING(pev->targetname)))) {
m_rgEntities[m_iTotal++] = pTarget;
}
pTarget = nullptr;
while (m_iTotal < MS_MAX_TARGETS && (pTarget = UTIL_FindEntityByClassname(pTarget, "multi_manager")))
while (m_iTotal < MAX_MS_TARGETS && (pTarget = UTIL_FindEntityByClassname(pTarget, "multi_manager")))
{
if (pTarget->HasTarget(pev->targetname)) {
m_rgEntities[m_iTotal++] = pTarget;
}
}
#else
edict_t *pentTarget = FIND_ENTITY_BY_STRING(NULL, "target", STRING(pev->targetname));
edict_t *pentTarget = FIND_ENTITY_BY_STRING(nullptr, "target", STRING(pev->targetname));
while (!FNullEnt(pentTarget) && m_iTotal < MS_MAX_TARGETS)
while (!FNullEnt(pentTarget) && m_iTotal < MAX_MS_TARGETS)
{
CBaseEntity *pTarget = CBaseEntity::Instance(pentTarget);
if (pTarget != NULL)
if (pTarget)
{
m_rgEntities[m_iTotal++] = pTarget;
}
@ -277,12 +281,12 @@ void CMultiSource::Register()
pentTarget = FIND_ENTITY_BY_STRING(pentTarget, "target", STRING(pev->targetname));
}
pentTarget = FIND_ENTITY_BY_STRING(NULL, "classname", "multi_manager");
pentTarget = FIND_ENTITY_BY_STRING(nullptr, "classname", "multi_manager");
while (!FNullEnt(pentTarget) && m_iTotal < MS_MAX_TARGETS)
while (!FNullEnt(pentTarget) && m_iTotal < MAX_MS_TARGETS)
{
CBaseEntity *pTarget = CBaseEntity::Instance(pentTarget);
if (pTarget != NULL && pTarget->HasTarget(pev->targetname))
if (pTarget && pTarget->HasTarget(pev->targetname))
{
m_rgEntities[m_iTotal++] = pTarget;
}
@ -388,7 +392,9 @@ void CBaseButton::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseToggle::KeyValue(pkvd);
}
}
// ButtonShot
@ -405,7 +411,7 @@ BOOL CBaseButton::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, fl
SetTouch(NULL);
m_hActivator = CBaseEntity::Instance(pevAttacker);
if (m_hActivator == NULL)
if (!m_hActivator)
return FALSE;
if (code == BUTTON_RETURN)
@ -759,7 +765,7 @@ void CBaseButton::ButtonReturn()
#ifdef REGAMEDLL_FIXES
void CBaseButton::Restart()
{
m_hActivator = NULL;
m_hActivator = nullptr;
SetMovedir(pev);
ButtonReturn();
@ -793,9 +799,8 @@ void CBaseButton::ButtonBackHome()
if (!FStringNull(pev->target))
{
edict_t *pentTarget = NULL;
while ((pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target))) != NULL)
edict_t *pentTarget = nullptr;
while ((pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target))))
{
if (FNullEnt(pentTarget))
break;
@ -805,7 +810,7 @@ void CBaseButton::ButtonBackHome()
CBaseEntity *pTarget = CBaseEntity::Instance(pentTarget);
if (pTarget != NULL)
if (pTarget)
{
pTarget->Use(m_hActivator, this, USE_TOGGLE, 0);
}
@ -859,7 +864,7 @@ void CRotButton::Spawn()
CBaseToggle::AxisDir(pev);
// check for clockwise rotation
if (pev->spawnflags & SF_DOOR_ROTATE_BACKWARDS)
if (pev->spawnflags & SF_ROTBUTTON_BACKWARDS)
{
pev->movedir = pev->movedir * -1;
}
@ -973,7 +978,9 @@ void CMomentaryRotButton::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseToggle::KeyValue(pkvd);
}
}
void CMomentaryRotButton::PlaySound()
@ -1002,7 +1009,7 @@ void CMomentaryRotButton::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE
void CMomentaryRotButton::UpdateAllButtons(float value, int start)
{
// Update all rot buttons attached to the same target
edict_t *pentTarget = NULL;
edict_t *pentTarget = nullptr;
while (true)
{
@ -1015,7 +1022,7 @@ void CMomentaryRotButton::UpdateAllButtons(float value, int start)
{
CMomentaryRotButton *pEntity = CMomentaryRotButton::Instance(pentTarget);
if (pEntity != NULL)
if (pEntity)
{
if (start)
pEntity->UpdateSelf(value);
@ -1071,16 +1078,14 @@ void CMomentaryRotButton::UpdateTarget(float value)
{
if (!FStringNull(pev->target))
{
edict_t *pentTarget = NULL;
while ((pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target))) != NULL)
edict_t *pentTarget = nullptr;
while ((pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target))))
{
if (FNullEnt(pentTarget))
break;
CBaseEntity *pEntity = CBaseEntity::Instance(pentTarget);
if (pEntity != NULL)
if (pEntity)
{
pEntity->Use(this, this, USE_SET, value);
}
@ -1194,7 +1199,9 @@ void CEnvSpark::KeyValue(KeyValueData *pkvd)
|| FStrEq(pkvd->szKeyName, "value3"))
pkvd->fHandled = TRUE;
else
{
CBaseEntity::KeyValue(pkvd);
}
}
void CEnvSpark::SparkThink()

View File

@ -26,33 +26,9 @@
*
*/
#ifndef BUTTON_H
#define BUTTON_H
#ifdef _WIN32
#pragma once
#endif
#define SF_BUTTON_DONTMOVE 1
#define SF_ROTBUTTON_NOTSOLID 1
#define SF_BUTTON_TOGGLE 32 // button stays pushed until reactivated
#define SF_BUTTON_SPARK_IF_OFF 64 // button sparks in OFF state
#define SF_BUTTON_TOUCH_ONLY 256 // button only fires as a result of USE key.
#define SF_GLOBAL_SET 1 // Set global state to initial state on spawn
#define SF_MULTI_INIT 1
// Make this button behave like a door (HACKHACK)
// This will disable use and make the button solid
// rotating buttons were made SOLID_NOT by default since their were some
// collision problems with them...
#define SF_MOMENTARY_DOOR 0x0001
#define SF_SPARK_TOOGLE 32
#define SF_SPARK_IF_OFF 64
#define SF_BTARGET_USE 0x0001
#define SF_BTARGET_ON 0x0002
#define SF_GLOBAL_SET BIT(0) // Set global state to initial state on spawn
class CEnvGlobal: public CPointEntity
{
@ -71,6 +47,9 @@ public:
int m_initialstate;
};
#define SF_ROTBUTTON_NOTSOLID BIT(0)
#define SF_ROTBUTTON_BACKWARDS BIT(1)
class CRotButton: public CBaseButton
{
public:
@ -87,6 +66,12 @@ public:
};
// Make this button behave like a door (HACKHACK)
// This will disable use and make the button solid
// rotating buttons were made SOLID_NOT by default since their were some
// collision problems with them...
#define SF_MOMENTARY_DOOR BIT(0)
class CMomentaryRotButton: public CBaseToggle
{
public:
@ -128,6 +113,9 @@ public:
int m_sounds;
};
#define SF_SPARK_TOOGLE BIT(5)
#define SF_SPARK_IF_OFF BIT(6)
class CEnvSpark: public CBaseEntity
{
public:
@ -147,6 +135,9 @@ public:
float m_flDelay;
};
#define SF_BTARGET_USE BIT(0)
#define SF_BTARGET_ON BIT(1)
class CButtonTarget: public CBaseEntity
{
public:
@ -158,5 +149,3 @@ public:
char *ButtonSound(int sound);
void DoSpark(entvars_t *pev, const Vector &location);
#endif // BUTTON_H

View File

@ -5,11 +5,11 @@
*/
#ifndef HOOK_GAMEDLL
CCareerTaskManager *TheCareerTasks = NULL;
CCareerTaskManager *TheCareerTasks = nullptr;
const TaskInfo taskInfo[] =
{
{ "defuse", EVENT_BOMB_DEFUSED, &CCareerTask::NewTask },
{ "defuse", EVENT_BOMB_DEFUSED, &CCareerTask::NewTask },
{ "plant", EVENT_BOMB_PLANTED, &CCareerTask::NewTask },
{ "rescue", EVENT_HOSTAGE_RESCUED, &CCareerTask::NewTask },
{ "killall", EVENT_KILL_ALL, &CCareerTask::NewTask },
@ -20,8 +20,8 @@ const TaskInfo taskInfo[] =
{ "headshot", EVENT_HEADSHOT, &CCareerTask::NewTask },
{ "headshotwith", EVENT_HEADSHOT, &CCareerTask::NewTask },
{ "winfast", EVENT_ROUND_WIN, &CCareerTask::NewTask },
{ "rescue", EVENT_HOSTAGE_RESCUED, &CCareerTask::NewTask },
{ "rescueall", EVENT_ALL_HOSTAGES_RESCUED, &CCareerTask::NewTask },
{ "rescue", EVENT_HOSTAGE_RESCUED, &CCareerTask::NewTask },
{ "rescueall", EVENT_ALL_HOSTAGES_RESCUED, &CCareerTask::NewTask },
{ "injure", EVENT_PLAYER_TOOK_DAMAGE, &CCareerTask::NewTask },
{ "injurewith", EVENT_PLAYER_TOOK_DAMAGE, &CCareerTask::NewTask },
{ "killdefuser", EVENT_KILL, &CCareerTask::NewTask },
@ -162,7 +162,7 @@ void CCareerTask::OnWeaponKill(int weaponId, int weaponClassId, bool headshot, b
if (m_rescuer)
{
int hostages_ = 0;
CHostage *hostageEntity = NULL;
CHostage *hostageEntity = nullptr;
while ((hostageEntity = (CHostage *)UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")))
{
@ -238,7 +238,7 @@ void CCareerTask::OnEvent(GameEventType event, CBasePlayer *pVictim, CBasePlayer
if (m_rescuer)
{
int hostages_ = 0;
CHostage *hostageEntity = NULL;
CHostage *hostageEntity = nullptr;
while ((hostageEntity = (CHostage *)UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")))
{
@ -267,7 +267,7 @@ void CCareerTask::OnEvent(GameEventType event, CBasePlayer *pVictim, CBasePlayer
if (!Q_strcmp(m_name, "defendhostages"))
{
int hostages_ = 0;
CHostage *hostageEntity = NULL;
CHostage *hostageEntity = nullptr;
while ((hostageEntity = (CHostage *)UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")))
{
@ -284,7 +284,7 @@ void CCareerTask::OnEvent(GameEventType event, CBasePlayer *pVictim, CBasePlayer
else if (!Q_strcmp(m_name, "hostagessurvive"))
{
int hostages_ = 0;
CHostage *hostageEntity = NULL;
CHostage *hostageEntity = nullptr;
while ((hostageEntity = (CHostage *)UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")))
{

View File

@ -26,11 +26,7 @@
*
*/
#ifndef CAREER_TASK_H
#define CAREER_TASK_H
#ifdef _WIN32
#pragma once
#endif
#include <list>
@ -148,5 +144,3 @@ struct TaskInfo
};
extern CCareerTaskManager *TheCareerTasks;
#endif // CAREER_TASK_H

View File

@ -62,10 +62,10 @@ DLL_FUNCTIONS gFunctionTable =
NEW_DLL_FUNCTIONS gNewDLLFunctions =
{
&OnFreeEntPrivateData,
NULL,
NULL,
NULL,
NULL
nullptr,
nullptr,
nullptr,
nullptr
};
// Global Savedata for Delay
@ -112,10 +112,10 @@ void EmptyEntityHashTable()
item = &stringsHashTable[i];
temp = item->next;
item->pev = NULL;
item->pev = nullptr;
item->pevIndex = 0;
item->lastHash = 0;
item->next = NULL;
item->next = nullptr;
while (temp)
{
@ -126,7 +126,7 @@ void EmptyEntityHashTable()
}
}
void EXT_FUNC AddEntityHashValue(entvars_t *pev, const char *value, hash_types_e fieldType)
void AddEntityHashValue(entvars_t *pev, const char *value, hash_types_e fieldType)
{
int count;
hash_item_t *item, *next, *temp, *newp;
@ -167,7 +167,7 @@ void EXT_FUNC AddEntityHashValue(entvars_t *pev, const char *value, hash_types_e
{
pevtemp = item->pev;
item->pev = pev;
item->lastHash = NULL;
item->lastHash = nullptr;
item->pevIndex = pevIndex;
pevIndex = ENTINDEX(ENT(pevtemp));
@ -182,24 +182,24 @@ void EXT_FUNC AddEntityHashValue(entvars_t *pev, const char *value, hash_types_e
item->next = newp;
newp->pev = pevtemp;
newp->lastHash = NULL;
newp->lastHash = nullptr;
newp->pevIndex = pevIndex;
if (next)
newp->next = temp;
else
newp->next = NULL;
newp->next = nullptr;
}
}
else
{
item->pev = pev;
item->lastHash = NULL;
item->lastHash = nullptr;
item->pevIndex = ENTINDEX(ENT(pev));
}
}
void EXT_FUNC RemoveEntityHashValue(entvars_t *pev, const char *value, hash_types_e fieldType)
void RemoveEntityHashValue(entvars_t *pev, const char *value, hash_types_e fieldType)
{
int hash;
hash_item_t *item;
@ -244,20 +244,20 @@ void EXT_FUNC RemoveEntityHashValue(entvars_t *pev, const char *value, hash_type
{
item->pev = item->next->pev;
item->pevIndex = item->next->pevIndex;
item->lastHash = NULL;
item->lastHash = nullptr;
item->next = item->next->next;
}
else
{
item->pev = NULL;
item->lastHash = NULL;
item->pev = nullptr;
item->lastHash = nullptr;
item->pevIndex = 0;
}
}
else
{
if (stringsHashTable[hash].lastHash == item)
stringsHashTable[hash].lastHash = NULL;
stringsHashTable[hash].lastHash = nullptr;
last->next = item->next;
hashItemMemPool.Free(item);
@ -266,25 +266,7 @@ void EXT_FUNC RemoveEntityHashValue(entvars_t *pev, const char *value, hash_type
}
}
void printEntities()
{
for (int i = 0; i < stringsHashTable.Count(); ++i)
{
hash_item_t *item = &stringsHashTable[i];
if (item->pev)
{
UTIL_LogPrintf("Print: %s %i %p\n", STRING(stringsHashTable[i].pev->classname), ENTINDEX(ENT(item->pev)), item->pev);
}
for (item = stringsHashTable[i].next; item; item = item->next)
{
UTIL_LogPrintf("Print: %s %i %p\n", STRING(item->pev->classname), ENTINDEX(ENT(item->pev)), item->pev);
}
}
}
NOINLINE edict_t *EXT_FUNC CREATE_NAMED_ENTITY(string_t iClass)
NOINLINE edict_t *CREATE_NAMED_ENTITY(string_t iClass)
{
edict_t *named = g_engfuncs.pfnCreateNamedEntity(iClass);
if (named)
@ -303,58 +285,6 @@ void REMOVE_ENTITY(edict_t *pEntity)
}
}
void loopPerformance()
{
CCounter loopCounter;
loopCounter.Init();
double start, end;
int i;
start = loopCounter.GetCurTime();
for (i = 0; i < 100; ++i)
{
CBaseEntity *pSpot;
for (pSpot = UTIL_FindEntityByString_Old(NULL, "classname", "info_player_start"); pSpot; pSpot = UTIL_FindEntityByString_Old(pSpot, "classname", "info_player_start"))
;
for (pSpot = UTIL_FindEntityByString_Old(NULL, "classname", "info_player_deathmatch"); pSpot; pSpot = UTIL_FindEntityByString_Old(pSpot, "classname", "info_player_deathmatch"))
;
for (pSpot = UTIL_FindEntityByString_Old(NULL, "classname", "player"); pSpot; pSpot = UTIL_FindEntityByString_Old(pSpot, "classname", "player"))
;
for (pSpot = UTIL_FindEntityByString_Old(NULL, "classname", "bodyque"); pSpot; pSpot = UTIL_FindEntityByString_Old(pSpot, "classname", "bodyque"))
;
}
end = loopCounter.GetCurTime();
CONSOLE_ECHO(" Time in old search loop %.4f\n", (end - start) * 1000.0);
// check time new search loop
start = loopCounter.GetCurTime();
for (i = 0; i < 100; ++i)
{
CBaseEntity *pSpot;
for (pSpot = UTIL_FindEntityByString(NULL, "classname", "info_player_start"); pSpot; pSpot = UTIL_FindEntityByString(pSpot, "classname", "info_player_start"))
;
for (pSpot = UTIL_FindEntityByString(NULL, "classname", "info_player_deathmatch"); pSpot; pSpot = UTIL_FindEntityByString(pSpot, "classname", "info_player_deathmatch"))
;
for (pSpot = UTIL_FindEntityByString(NULL, "classname", "player"); pSpot; pSpot = UTIL_FindEntityByString(pSpot, "classname", "player"))
;
for (pSpot = UTIL_FindEntityByString(NULL, "classname", "bodyque"); pSpot; pSpot = UTIL_FindEntityByString(pSpot, "classname", "bodyque"))
;
}
end = loopCounter.GetCurTime();
CONSOLE_ECHO(" Time in new search loop %.4f\n", (end - start) * 1000.0);
}
C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion)
{
if (!pFunctionTable || interfaceVersion != INTERFACE_VERSION)
@ -364,7 +294,7 @@ C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion
stringsHashTable.AddMultipleToTail(2048);
for (int i = 0; i < stringsHashTable.Count(); ++i)
{
stringsHashTable[i].next = NULL;
stringsHashTable[i].next = nullptr;
}
EmptyEntityHashTable();
@ -395,10 +325,9 @@ C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pFunctionTable, int *inter
return 1;
}
int EXT_FUNC DispatchSpawn(edict_t *pent)
int DispatchSpawn(edict_t *pent)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
CBaseEntity *pEntity = GET_PRIVATE<CBaseEntity>(pent);
if (pEntity)
{
// Initialize these or entities who don't link to the world won't have anything in here
@ -455,7 +384,7 @@ int EXT_FUNC DispatchSpawn(edict_t *pent)
return 0;
}
void EXT_FUNC DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
void DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
{
if (!pkvd || !pentKeyvalue)
return;
@ -477,7 +406,7 @@ void EXT_FUNC DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
// HACKHACK -- this is a hack to keep the node graph entity from "touching" things (like triggers)
// while it builds the graph
void EXT_FUNC DispatchTouch(edict_t *pentTouched, edict_t *pentOther)
void DispatchTouch(edict_t *pentTouched, edict_t *pentOther)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentTouched);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther);
@ -486,7 +415,7 @@ void EXT_FUNC DispatchTouch(edict_t *pentTouched, edict_t *pentOther)
pEntity->Touch(pOther);
}
void EXT_FUNC DispatchUse(edict_t *pentUsed, edict_t *pentOther)
void DispatchUse(edict_t *pentUsed, edict_t *pentOther)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentUsed);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther);
@ -495,7 +424,7 @@ void EXT_FUNC DispatchUse(edict_t *pentUsed, edict_t *pentOther)
pEntity->Use(pOther, pOther, USE_TOGGLE, 0);
}
void EXT_FUNC DispatchThink(edict_t *pent)
void DispatchThink(edict_t *pent)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
@ -510,7 +439,7 @@ void EXT_FUNC DispatchThink(edict_t *pent)
}
}
void EXT_FUNC DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther)
void DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentBlocked);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther);
@ -521,7 +450,7 @@ void EXT_FUNC DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther)
}
}
void EXT_FUNC DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData)
void DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
@ -563,7 +492,7 @@ void EXT_FUNC DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData)
// different classes with the same global name
CBaseEntity *FindGlobalEntity(string_t classname, string_t globalname)
{
edict_t *pent = FIND_ENTITY_BY_STRING(NULL, "globalname", STRING(globalname));
edict_t *pent = FIND_ENTITY_BY_STRING(nullptr, "globalname", STRING(globalname));
CBaseEntity *pReturn = CBaseEntity::Instance(pent);
if (pReturn)
@ -571,14 +500,14 @@ CBaseEntity *FindGlobalEntity(string_t classname, string_t globalname)
if (!FClassnameIs(pReturn->pev, STRING(classname)))
{
ALERT(at_console, "Global entity found %s, wrong class %s\n", STRING(globalname), STRING(pReturn->pev->classname));
pReturn = NULL;
pReturn = nullptr;
}
}
return pReturn;
}
int EXT_FUNC DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity)
int DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
@ -692,7 +621,7 @@ int EXT_FUNC DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int glob
return 0;
}
void EXT_FUNC DispatchObjectCollsionBox(edict_t *pent)
void DispatchObjectCollsionBox(edict_t *pent)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if (pEntity)
@ -704,67 +633,18 @@ void EXT_FUNC DispatchObjectCollsionBox(edict_t *pent)
}
void EXT_FUNC SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount)
void SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount)
{
CSave saveHelper(pSaveData);
saveHelper.WriteFields(pname, pBaseData, pFields, fieldCount);
}
void EXT_FUNC SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount)
void SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount)
{
CRestore restoreHelper(pSaveData);
restoreHelper.ReadFields(pname, pBaseData, pFields, fieldCount);
}
edict_t *EHANDLE::Get()
{
if (!m_pent || m_pent->serialnumber != m_serialnumber)
return NULL;
return m_pent;
}
edict_t *EHANDLE::Set(edict_t *pent)
{
m_pent = pent;
if (pent)
m_serialnumber = pent->serialnumber;
return pent;
}
EHANDLE::operator CBaseEntity *()
{
return (CBaseEntity *)GET_PRIVATE(Get());
}
CBaseEntity *EHANDLE::operator=(CBaseEntity *pEntity)
{
if (pEntity)
{
m_pent = ENT(pEntity->pev);
if (m_pent)
m_serialnumber = m_pent->serialnumber;
}
else
{
m_pent = NULL;
m_serialnumber = 0;
}
return pEntity;
}
EHANDLE::operator int()
{
return Get() != NULL;
}
CBaseEntity *EHANDLE::operator->()
{
return (CBaseEntity *)GET_PRIVATE(Get());
}
BOOL CBaseEntity::TakeHealth(float flHealth, int bitsDamageType)
{
if (pev->takedamage == DAMAGE_NO)
@ -844,12 +724,12 @@ void CBaseEntity::Killed(entvars_t *pevAttacker, int iGib)
CBaseEntity *CBaseEntity::GetNextTarget()
{
if (FStringNull(pev->target))
return NULL;
return nullptr;
edict_t *pTarget = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(pev->target));
edict_t *pTarget = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(pev->target));
if (FNullEnt(pTarget))
{
return NULL;
return nullptr;
}
return Instance(pTarget);
@ -941,16 +821,24 @@ void CBaseEntity::SetObjectCollisionBox()
::SetObjectCollisionBox(pev);
}
int CBaseEntity::Intersects(CBaseEntity *pOther)
bool CBaseEntity::Intersects(CBaseEntity *pOther)
{
if (pOther->pev->absmin.x > pev->absmax.x
|| pOther->pev->absmin.y > pev->absmax.y
|| pOther->pev->absmin.z > pev->absmax.z
|| pOther->pev->absmax.x < pev->absmin.x
|| pOther->pev->absmax.y < pev->absmin.y
|| pOther->pev->absmax.z < pev->absmin.z)
return 0;
return 1;
return Intersects(pOther->pev->absmin, pOther->pev->absmax);
}
bool CBaseEntity::Intersects(const Vector &mins, const Vector &maxs)
{
if (mins.x > pev->absmax.x
|| mins.y > pev->absmax.y
|| mins.z > pev->absmax.z
|| maxs.x < pev->absmin.x
|| maxs.y < pev->absmin.y
|| maxs.z < pev->absmin.z)
{
return false;
}
return true;
}
void CBaseEntity::MakeDormant()
@ -1025,7 +913,7 @@ CBaseEntity *CBaseEntity::Create(char *szName, const Vector &vecOrigin, const Ve
if (FNullEnt(pent))
{
ALERT(at_console, "NULL Ent in Create!\n");
return NULL;
return nullptr;
}
CBaseEntity *pEntity = Instance(pent);
@ -1039,13 +927,534 @@ CBaseEntity *CBaseEntity::Create(char *szName, const Vector &vecOrigin, const Ve
return pEntity;
}
void EXT_FUNC OnFreeEntPrivateData(edict_t *pEnt)
// Returns true if a line can be traced from the caller's eyes to the target
BOOL CBaseEntity::FVisible(CBaseEntity *pEntity)
{
CBaseEntity *pEntity = CBaseEntity::Instance(pEnt);
TraceResult tr;
Vector vecLookerOrigin;
Vector vecTargetOrigin;
if (pEntity->pev->flags & FL_NOTARGET)
return FALSE;
// don't look through water
if ((pev->waterlevel != 3 && pEntity->pev->waterlevel == 3) || (pev->waterlevel == 3 && pEntity->pev->waterlevel == 0))
return FALSE;
//look through the caller's 'eyes'
vecLookerOrigin = pev->origin + pev->view_ofs;
vecTargetOrigin = pEntity->EyePosition();
UTIL_TraceLine(vecLookerOrigin, vecTargetOrigin, ignore_monsters, ignore_glass, ENT(pev), &tr);
if (tr.flFraction != 1.0f)
{
// Line of sight is not established
return FALSE;
}
else
{
// line of sight is valid.
return TRUE;
}
}
// Returns true if a line can be traced from the caller's eyes to the target vector
BOOL CBaseEntity::FVisible(const Vector &vecOrigin)
{
TraceResult tr;
Vector vecLookerOrigin;
//look through the caller's 'eyes'
vecLookerOrigin = EyePosition();
UTIL_TraceLine(vecLookerOrigin, vecOrigin, ignore_monsters, ignore_glass, ENT(pev), &tr);
if (tr.flFraction != 1.0f)
{
// Line of sight is not established
return FALSE;
}
else
{
// line of sight is valid.
return TRUE;
}
}
void CBaseEntity::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{
Vector vecOrigin = ptr->vecEndPos - vecDir * 4;
if (pev->takedamage != DAMAGE_NO)
{
AddMultiDamage(pevAttacker, this, flDamage, bitsDamageType);
int blood = BloodColor();
if (blood != DONT_BLEED)
{
// a little surface blood.
SpawnBlood(vecOrigin, blood, flDamage);
TraceBleed(flDamage, vecDir, ptr, bitsDamageType);
}
}
}
void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker)
{
static int tracerCount;
int tracer;
TraceResult tr;
Vector vecRight, vecUp;
bool m_bCreatedShotgunSpark = true;
vecRight = gpGlobals->v_right;
vecUp = gpGlobals->v_up;
if (!pevAttacker)
{
// the default attacker is ourselves
pevAttacker = pev;
}
ClearMultiDamage();
gMultiDamage.type = (DMG_BULLET | DMG_NEVERGIB);
for (ULONG iShot = 1; iShot <= cShots; ++iShot)
{
int spark = 0;
// get circular gaussian spread
float x, y, z;
do
{
x = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
y = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
z = x * x + y * y;
}
while (z > 1);
Vector vecDir, vecEnd;
vecDir = vecDirShooting + x * vecSpread.x * vecRight + y * vecSpread.y * vecUp;
vecEnd = vecSrc + vecDir * flDistance;
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr);
tracer = 0;
if (iTracerFreq != 0 && !(tracerCount++ % iTracerFreq))
{
Vector vecTracerSrc;
if (IsPlayer())
{
// adjust tracer position for player
vecTracerSrc = vecSrc + Vector(0, 0, -4) + gpGlobals->v_right * 2 + gpGlobals->v_forward * 16;
}
else
{
vecTracerSrc = vecSrc;
}
// guns that always trace also always decal
if (iTracerFreq != 1)
tracer = 1;
MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, vecTracerSrc);
WRITE_BYTE(TE_TRACER);
WRITE_COORD(vecTracerSrc.x);
WRITE_COORD(vecTracerSrc.y);
WRITE_COORD(vecTracerSrc.z);
WRITE_COORD(tr.vecEndPos.x);
WRITE_COORD(tr.vecEndPos.y);
WRITE_COORD(tr.vecEndPos.z);
MESSAGE_END();
}
// do damage, paint decals
if (tr.flFraction != 1.0f)
{
CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
if (iDamage)
{
pEntity->TraceAttack(pevAttacker, iDamage, vecDir, &tr, DMG_BULLET | ((iDamage > 16) ? DMG_ALWAYSGIB : DMG_NEVERGIB));
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot(&tr, iBulletType, false, pev, false);
}
else
{
float flDamage;
switch (iBulletType)
{
case BULLET_PLAYER_MP5:
pEntity->TraceAttack(pevAttacker, gSkillData.plrDmgMP5, vecDir, &tr, DMG_BULLET);
break;
case BULLET_PLAYER_BUCKSHOT:
flDamage = ((1 - tr.flFraction) * 20);
pEntity->TraceAttack(pevAttacker, int(flDamage), vecDir, &tr, DMG_BULLET);
break;
case BULLET_PLAYER_357:
pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg357, vecDir, &tr, DMG_BULLET);
break;
case BULLET_MONSTER_9MM:
pEntity->TraceAttack(pevAttacker, gSkillData.monDmg9MM, vecDir, &tr, DMG_BULLET);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot(&tr, iBulletType, false, pev, false);
break;
case BULLET_MONSTER_MP5:
pEntity->TraceAttack(pevAttacker, gSkillData.monDmgMP5, vecDir, &tr, DMG_BULLET);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot(&tr, iBulletType, false, pev, false);
break;
case BULLET_MONSTER_12MM:
pEntity->TraceAttack(pevAttacker, gSkillData.monDmg12MM, vecDir, &tr, DMG_BULLET);
if (!tracer)
{
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot(&tr, iBulletType, false, pev, false);
}
break;
case BULLET_NONE:
flDamage = 50;
pEntity->TraceAttack(pevAttacker, flDamage, vecDir, &tr, DMG_CLUB);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
// only decal glass
if (!FNullEnt(tr.pHit) && VARS(tr.pHit)->rendermode != kRenderNormal)
{
UTIL_DecalTrace(&tr, DECAL_GLASSBREAK1 + RANDOM_LONG(0, 2));
}
break;
default:
pEntity->TraceAttack(pevAttacker, gSkillData.monDmg9MM, vecDir, &tr, DMG_BULLET);
break;
}
}
}
// make bullet trails
UTIL_BubbleTrail(vecSrc, tr.vecEndPos, int((flDistance * tr.flFraction) / 64));
}
ApplyMultiDamage(pev, pevAttacker);
}
// Go to the trouble of combining multiple pellets into a single damage call.
// This version is used by Players, uses the random seed generator to sync client and server side shots.
Vector CBaseEntity::FireBullets3(Vector vecSrc, Vector vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand)
{
int iOriginalPenetration = iPenetration;
int iPenetrationPower;
float flPenetrationDistance;
int iCurrentDamage = iDamage;
float flCurrentDistance;
TraceResult tr, tr2;
Vector vecRight, vecUp;
bool bHitMetal = false;
int iSparksAmount = 1;
vecRight = gpGlobals->v_right;
vecUp = gpGlobals->v_up;
switch (iBulletType)
{
case BULLET_PLAYER_9MM:
iPenetrationPower = 21;
flPenetrationDistance = 800;
break;
case BULLET_PLAYER_45ACP:
iPenetrationPower = 15;
flPenetrationDistance = 500;
break;
case BULLET_PLAYER_50AE:
iPenetrationPower = 30;
flPenetrationDistance = 1000;
break;
case BULLET_PLAYER_762MM:
iPenetrationPower = 39;
flPenetrationDistance = 5000;
break;
case BULLET_PLAYER_556MM:
iPenetrationPower = 35;
flPenetrationDistance = 4000;
break;
case BULLET_PLAYER_338MAG:
iPenetrationPower = 45;
flPenetrationDistance = 8000;
break;
case BULLET_PLAYER_57MM:
iPenetrationPower = 30;
flPenetrationDistance = 2000;
break;
case BULLET_PLAYER_357SIG:
iPenetrationPower = 25;
flPenetrationDistance = 800;
break;
default:
iPenetrationPower = 0;
flPenetrationDistance = 0;
break;
}
if (!pevAttacker)
{
// the default attacker is ourselves
pevAttacker = pev;
}
gMultiDamage.type = (DMG_BULLET | DMG_NEVERGIB);
float x, y, z;
if (IsPlayer())
{
// Use player's random seed.
// get circular gaussian spread
x = UTIL_SharedRandomFloat(shared_rand, -0.5, 0.5) + UTIL_SharedRandomFloat(shared_rand + 1, -0.5, 0.5);
y = UTIL_SharedRandomFloat(shared_rand + 2, -0.5, 0.5) + UTIL_SharedRandomFloat(shared_rand + 3, -0.5, 0.5);
}
else
{
do
{
x = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
y = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
z = x * x + y * y;
}
while (z > 1);
}
Vector vecDir, vecEnd;
Vector vecOldSrc, vecNewSrc;
vecDir = vecDirShooting + x * vecSpread * vecRight + y * vecSpread * vecUp;
vecEnd = vecSrc + vecDir * flDistance;
float flDamageModifier = 0.5;
while (iPenetration != 0)
{
ClearMultiDamage();
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr);
if (TheBots && tr.flFraction != 1.0f)
{
TheBots->OnEvent(EVENT_BULLET_IMPACT, this, (CBaseEntity *)&tr.vecEndPos);
}
char cTextureType = UTIL_TextureHit(&tr, vecSrc, vecEnd);
bool bSparks = false;
switch (cTextureType)
{
case CHAR_TEX_METAL:
bHitMetal = true;
bSparks = true;
iPenetrationPower *= 0.15;
flDamageModifier = 0.2;
break;
case CHAR_TEX_CONCRETE:
iPenetrationPower *= 0.25;
break;
case CHAR_TEX_GRATE:
bHitMetal = true;
bSparks = true;
iPenetrationPower *= 0.5;
flDamageModifier = 0.4;
break;
case CHAR_TEX_VENT:
bHitMetal = true;
bSparks = true;
iPenetrationPower *= 0.5;
flDamageModifier = 0.45;
break;
case CHAR_TEX_TILE:
iPenetrationPower *= 0.65;
flDamageModifier = 0.3;
break;
case CHAR_TEX_COMPUTER:
bHitMetal = true;
bSparks = true;
iPenetrationPower *= 0.4;
flDamageModifier = 0.45;
break;
case CHAR_TEX_WOOD:
flDamageModifier = 0.6;
break;
default:
break;
}
if (tr.flFraction != 1.0f)
{
CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
iPenetration--;
flCurrentDistance = tr.flFraction * flDistance;
iCurrentDamage *= Q_pow(flRangeModifier, flCurrentDistance / 500);
if (flCurrentDistance > flPenetrationDistance)
{
iPenetration = 0;
}
if (tr.iHitgroup == HITGROUP_SHIELD)
{
EMIT_SOUND(pEntity->edict(), CHAN_VOICE, (RANDOM_LONG(0, 1) == 1) ? "weapons/ric_metal-1.wav" : "weapons/ric_metal-2.wav", VOL_NORM, ATTN_NORM);
UTIL_Sparks(tr.vecEndPos);
pEntity->pev->punchangle.x = iCurrentDamage * RANDOM_FLOAT(-0.15, 0.15);
pEntity->pev->punchangle.z = iCurrentDamage * RANDOM_FLOAT(-0.15, 0.15);
if (pEntity->pev->punchangle.x < 4)
{
pEntity->pev->punchangle.x = -4;
}
if (pEntity->pev->punchangle.z < -5)
{
pEntity->pev->punchangle.z = -5;
}
else if (pEntity->pev->punchangle.z > 5)
{
pEntity->pev->punchangle.z = 5;
}
break;
}
float flDistanceModifier;
if (VARS(tr.pHit)->solid != SOLID_BSP || !iPenetration)
{
iPenetrationPower = 42;
flDamageModifier = 0.75;
flDistanceModifier = 0.75;
}
else
flDistanceModifier = 0.5;
DecalGunshot(&tr, iBulletType, (!bPistol && RANDOM_LONG(0, 3)), pev, bHitMetal);
vecSrc = tr.vecEndPos + (vecDir * iPenetrationPower);
flDistance = (flDistance - flCurrentDistance) * flDistanceModifier;
vecEnd = vecSrc + (vecDir * flDistance);
pEntity->TraceAttack(pevAttacker, iCurrentDamage, vecDir, &tr, (DMG_BULLET | DMG_NEVERGIB));
iCurrentDamage *= flDamageModifier;
}
else
iPenetration = 0;
ApplyMultiDamage(pev, pevAttacker);
}
return Vector(x * vecSpread, y * vecSpread, 0);
}
void CBaseEntity::TraceBleed(float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{
if (BloodColor() == DONT_BLEED)
return;
if (!flDamage)
return;
if (!(bitsDamageType & (DMG_CRUSH | DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB | DMG_MORTAR)))
return;
// make blood decal on the wall!
TraceResult Bloodtr;
Vector vecTraceDir;
float flNoise;
int cCount;
int i;
if (flDamage < 10.0f)
{
flNoise = 0.1f;
cCount = 1;
}
else if (flDamage < 25.0f)
{
flNoise = 0.2f;
cCount = 2;
}
else
{
flNoise = 0.3f;
cCount = 4;
}
for (i = 0; i < cCount; ++i)
{
// trace in the opposite direction the shot came from (the direction the shot is going)
vecTraceDir = vecDir * -1.0f;
vecTraceDir.x += RANDOM_FLOAT(-flNoise, flNoise);
vecTraceDir.y += RANDOM_FLOAT(-flNoise, flNoise);
vecTraceDir.z += RANDOM_FLOAT(-flNoise, flNoise);
UTIL_TraceLine(ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * -172.0f, ignore_monsters, ENT(pev), &Bloodtr);
if (Bloodtr.flFraction != 1.0f)
{
if (!RANDOM_LONG(0, 2))
{
UTIL_BloodDecalTrace(&Bloodtr, BloodColor());
}
}
}
}
void CBaseEntity::SUB_StartFadeOut()
{
if (pev->rendermode == kRenderNormal)
{
pev->renderamt = 255.0f;
pev->rendermode = kRenderTransTexture;
}
pev->solid = SOLID_NOT;
pev->avelocity = g_vecZero;
pev->nextthink = gpGlobals->time + 0.1f;
SetThink(&CBaseEntity::SUB_FadeOut);
}
void CBaseEntity::SUB_FadeOut()
{
if (pev->renderamt > 7)
{
pev->renderamt -= 7.0f;
pev->nextthink = gpGlobals->time + 0.1f;
}
else
{
pev->renderamt = 0.0f;
pev->nextthink = gpGlobals->time + 0.2f;
SetThink(&CBaseEntity::SUB_Remove);
}
}
void OnFreeEntPrivateData(edict_t *pEnt)
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pEnt);
if (!pEntity)
return;
pEntity->UpdateOnRemove();
#ifdef REGAMEDLL_API
pEntity->OnDestroy();
#endif
RemoveEntityHashValue(pEntity->pev, STRING(pEntity->pev->classname), CLASSNAME);
#ifdef REGAMEDLL_API
@ -1061,3 +1470,14 @@ void EXT_FUNC OnFreeEntPrivateData(edict_t *pEnt)
}
#endif
}
#ifdef REGAMEDLL_API
void CBaseEntity::OnCreate()
{
}
void CBaseEntity::OnDestroy()
{
UpdateOnRemove();
}
#endif

View File

@ -26,202 +26,25 @@
*
*/
#ifndef CBASE_H
#define CBASE_H
#ifdef _WIN32
#pragma once
#endif
#include "saverestore.h"
#include "util.h"
#include "schedule.h"
#include "saverestore.h"
#include "scriptevent.h"
#include "monsterevent.h"
#undef CREATE_NAMED_ENTITY
#undef REMOVE_ENTITY
// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions)
#define FCAP_CUSTOMSAVE 0x00000001
#define FCAP_ACROSS_TRANSITION 0x00000002 // should transfer between transitions
#define FCAP_MUST_SPAWN 0x00000004 // Spawn after restore
#define FCAP_DONT_SAVE 0x80000000 // Don't save this
#define FCAP_IMPULSE_USE 0x00000008 // can be used by the player
#define FCAP_CONTINUOUS_USE 0x00000010 // can be used by the player
#define FCAP_ONOFF_USE 0x00000020 // can be used by the player
#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains)
#define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource)
#define FCAP_MUST_RESET 0x00000100 // should reset on the new round
#define FCAP_MUST_RELEASE 0x00000200 // should release on the new round
// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!!
#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions
#define SetThink(a)\
m_pfnThink = static_cast<void (CBaseEntity::*)()>(a)
#define SetTouch(a)\
m_pfnTouch = static_cast<void (CBaseEntity::*)(CBaseEntity *)>(a)
#define SetUse(a)\
m_pfnUse = static_cast<void (CBaseEntity::*)(CBaseEntity *, CBaseEntity *, USE_TYPE, float)>(a)
#define SetBlocked(a)\
m_pfnBlocked = static_cast<void (CBaseEntity::*)(CBaseEntity *)>(a)
#define SetMoveDone(a)\
m_pfnCallWhenMoveDone = static_cast<void (CBaseToggle::*)()>(a)
// for Classify
#define CLASS_NONE 0
#define CLASS_MACHINE 1
#define CLASS_PLAYER 2
#define CLASS_HUMAN_PASSIVE 3
#define CLASS_HUMAN_MILITARY 4
#define CLASS_ALIEN_MILITARY 5
#define CLASS_ALIEN_PASSIVE 6
#define CLASS_ALIEN_MONSTER 7
#define CLASS_ALIEN_PREY 8
#define CLASS_ALIEN_PREDATOR 9
#define CLASS_INSECT 10
#define CLASS_PLAYER_ALLY 11
#define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks.launched by players
#define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace
#define CLASS_VEHICLE 14
#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures.
#define ROUTE_SIZE 8
#define MAX_OLD_ENEMIES 4
#define bits_CAP_DUCK (1<<0)
#define bits_CAP_JUMP (1<<1)
#define bits_CAP_STRAFE (1<<2)
#define bits_CAP_SQUAD (1<<3)
#define bits_CAP_SWIM (1<<4)
#define bits_CAP_CLIMB (1<<5)
#define bits_CAP_USE (1<<6)
#define bits_CAP_HEAR (1<<7)
#define bits_CAP_AUTO_DOORS (1<<8)
#define bits_CAP_OPEN_DOORS (1<<9)
#define bits_CAP_TURN_HEAD (1<<10)
#define bits_CAP_RANGE_ATTACK1 (1<<11)
#define bits_CAP_RANGE_ATTACK2 (1<<12)
#define bits_CAP_MELEE_ATTACK1 (1<<13)
#define bits_CAP_MELEE_ATTACK2 (1<<14)
#define bits_CAP_FLY (1<<15)
#define bits_CAP_DOORS_GROUP (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS)
#define SF_NORESPAWN (1<<30) // set this bit on guns and stuff that should never respawn.
#define DMG_GENERIC 0 // generic damage was done
#define DMG_CRUSH (1<<0) // crushed by falling or moving object
#define DMG_BULLET (1<<1) // shot
#define DMG_SLASH (1<<2) // cut, clawed, stabbed
#define DMG_BURN (1<<3) // heat burned
#define DMG_FREEZE (1<<4) // frozen
#define DMG_FALL (1<<5) // fell too far
#define DMG_BLAST (1<<6) // explosive blast damage
#define DMG_CLUB (1<<7) // crowbar, punch, headbutt
#define DMG_SHOCK (1<<8) // electric shock
#define DMG_SONIC (1<<9) // sound pulse shockwave
#define DMG_ENERGYBEAM (1<<10) // laser or other high energy beam
#define DMG_NEVERGIB (1<<12) // with this bit OR'd in, no damage type will be able to gib victims upon death
#define DMG_ALWAYSGIB (1<<13) // with this bit OR'd in, any damage type can be made to gib victims upon death
#define DMG_DROWN (1<<14) // Drowning
// time-based damage
#define DMG_TIMEBASED (~(0x3FFF)) // mask for time-based damage
#define DMG_PARALYZE (1<<15) // slows affected creature down
#define DMG_NERVEGAS (1<<16) // nerve toxins, very bad
#define DMG_POISON (1<<17) // blood poisioning
#define DMG_RADIATION (1<<18) // radiation exposure
#define DMG_DROWNRECOVER (1<<19) // drowning recovery
#define DMG_ACID (1<<20) // toxic chemicals or acid burns
#define DMG_SLOWBURN (1<<21) // in an oven
#define DMG_SLOWFREEZE (1<<22) // in a subzero freezer
#define DMG_MORTAR (1<<23) // Hit by air raid (done to distinguish grenade from mortar)
#define DMG_EXPLOSION (1<<24)
// these are the damage types that are allowed to gib corpses
#define DMG_GIB_CORPSE (DMG_CRUSH | DMG_FALL | DMG_BLAST | DMG_SONIC | DMG_CLUB)
// these are the damage types that have client hud art
#define DMG_SHOWNHUD (DMG_POISON | DMG_ACID | DMG_FREEZE | DMG_SLOWFREEZE | DMG_DROWN | DMG_BURN | DMG_SLOWBURN | DMG_NERVEGAS | DMG_RADIATION | DMG_SHOCK)
#define AIRTIME 12 // lung full of air lasts this many seconds
#define PARALYZE_DURATION 2 // number of 2 second intervals to take damage
#define PARALYZE_DAMAGE 1.0f // damage to take each 2 second interval
#define NERVEGAS_DURATION 2
#define NERVEGAS_DAMAGE 5.0f
#define POISON_DURATION 5
#define POISON_DAMAGE 2.0f
#define RADIATION_DURATION 2
#define RADIATION_DAMAGE 1.0f
#define ACID_DURATION 2
#define ACID_DAMAGE 5.0f
#define SLOWBURN_DURATION 2
#define SLOWBURN_DAMAGE 1.0f
#define SLOWFREEZE_DURATION 2
#define SLOWFREEZE_DAMAGE 1.0f
#define itbd_Paralyze 0
#define itbd_NerveGas 1
#define itbd_Poison 2
#define itbd_Radiation 3
#define itbd_DrownRecover 4
#define itbd_Acid 5
#define itbd_SlowBurn 6
#define itbd_SlowFreeze 7
#define CDMG_TIMEBASED 8
// when calling KILLED(), a value that governs gib behavior is expected to be
// one of these three values
#define GIB_NORMAL 0 // gib if entity was overkilled
#define GIB_NEVER 1 // never gib, no matter how much death damage is done ( freezing, etc )
#define GIB_ALWAYS 2 // always gib ( Houndeye Shock, Barnacle Bite )
#define GIB_HEALTH_VALUE -30
#define SF_ITEM_USE_ONLY 256
#define MAX_MULTI_TARGETS 16
#define MS_MAX_TARGETS 32
#ifdef _WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT /**/
#endif // _WIN32
class CGrenade;
class CSave;
class CRestore;
class CBasePlayer;
class CBaseEntity;
class CBaseMonster;
class CBasePlayerItem;
class CBasePlayerWeapon;
class CSquadMonster;
class CCSEntity;
class CCineMonster;
class CSound;
// EHANDLE. Safe way to point to CBaseEntities who may die between frames
class EHANDLE {
public:
edict_t *Get();
edict_t *Set(edict_t *pent);
operator int();
operator CBaseEntity*();
operator CBasePlayer*() { return static_cast<CBasePlayer *>(GET_PRIVATE(Get())); }
CBaseEntity *operator=(CBaseEntity *pEntity);
CBaseEntity *operator->();
private:
edict_t *m_pent;
int m_serialnumber;
};
#undef CREATE_NAMED_ENTITY
#undef REMOVE_ENTITY
// Base Entity. All entity types derive from this
class CBaseEntity {
@ -234,8 +57,14 @@ public:
virtual int Restore(CRestore &restore);
virtual int ObjectCaps() { return FCAP_ACROSS_TRANSITION; }
virtual void Activate() {}
// Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box)
virtual void SetObjectCollisionBox();
// Classify - returns the type of group (i.e, "houndeye", or "human military" so that monsters with different classnames
// still realize that they are teammates. (overridden for monsters that form groups)
virtual int Classify() { return CLASS_NONE; }
virtual void DeathNotice(entvars_t *pevChild) {}
virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
virtual BOOL TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType);
@ -244,8 +73,8 @@ public:
virtual int BloodColor() { return DONT_BLEED; }
virtual void TraceBleed(float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
virtual BOOL IsTriggered(CBaseEntity *pActivator) { return TRUE; }
virtual CBaseMonster *MyMonsterPointer() { return NULL; }
virtual CSquadMonster *MySquadMonsterPointer() { return NULL; }
virtual CBaseMonster *MyMonsterPointer() { return nullptr; }
virtual CSquadMonster *MySquadMonsterPointer() { return nullptr; }
virtual int GetToggleState() { return TS_AT_TOP; }
virtual void AddPoints(int score, BOOL bAllowNegativeScore) {}
virtual void AddPointsToTeam(int score, BOOL bAllowNegativeScore) {}
@ -256,13 +85,16 @@ public:
virtual int IsMoving() { return (pev->velocity != g_vecZero); }
virtual void OverrideReset() {}
virtual int DamageDecal(int bitsDamageType);
virtual void SetToggleState(int state) {}
virtual void StartSneaking() {}
#ifndef REGAMEDLL_FIXES
// This is ONLY used by the node graph to test movement through a door
virtual void SetToggleState(int state) {}
#ifndef REGAMEDLL_API
virtual void StartSneaking() {}
virtual void StopSneaking() {}
#else
virtual void UpdateOnRemove();
virtual void OnCreate();
virtual void OnDestroy();
#endif
virtual BOOL OnControls(entvars_t *onpev) { return FALSE; }
@ -280,15 +112,17 @@ public:
virtual void Touch(CBaseEntity *pOther) { if (m_pfnTouch) (this->*m_pfnTouch)(pOther); }
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType = USE_OFF, float value = 0.0f) { if (m_pfnUse) (this->*m_pfnUse)(pActivator, pCaller, useType, value); }
virtual void Blocked(CBaseEntity *pOther) { if (m_pfnBlocked) (this->*m_pfnBlocked)(pOther); }
virtual CBaseEntity *Respawn() { return NULL; }
virtual CBaseEntity *Respawn() { return nullptr; }
// used by monsters that are created by the MonsterMaker
virtual void UpdateOwner() {}
virtual BOOL FBecomeProne() { return FALSE; }
virtual Vector Center() { return (pev->absmax + pev->absmin) * 0.5f; }
virtual Vector EyePosition() { return (pev->origin + pev->view_ofs); }
virtual Vector EarPosition() { return (pev->origin + pev->view_ofs); }
virtual Vector BodyTarget(const Vector &posSrc) { return Center(); }
virtual Vector Center() { return (pev->absmax + pev->absmin) * 0.5f; } // center point of entity
virtual Vector EyePosition() { return (pev->origin + pev->view_ofs); } // position of eyes
virtual Vector EarPosition() { return (pev->origin + pev->view_ofs); } // position of ears
virtual Vector BodyTarget(const Vector &posSrc) { return Center(); } // position to shoot at
virtual int Illumination() { return GETENTITYILLUM(ENT(pev)); }
virtual BOOL FVisible(CBaseEntity *pEntity);
@ -303,9 +137,7 @@ public:
void operator delete(void *pMem, entvars_t *pevnew) { pevnew->flags |= FL_KILLME; }
#endif
#ifndef REGAMEDLL_FIXES
void UpdateOnRemove();
#endif
void EXPORT SUB_Remove();
void EXPORT SUB_DoNothing();
@ -313,10 +145,11 @@ public:
void EXPORT SUB_FadeOut();
void EXPORT SUB_CallUseToggle() { Use(this, this, USE_TOGGLE, 0); }
int ShouldToggle(USE_TYPE useType, BOOL currentState);
void FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = NULL);
void FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = nullptr);
Vector FireBullets3(Vector vecSrc, Vector vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand = 0);
void SUB_UseTargets(CBaseEntity *pActivator, USE_TYPE useType, float value);
int Intersects(CBaseEntity *pOther);
bool Intersects(CBaseEntity *pOther);
bool Intersects(const Vector &mins, const Vector &maxs);
void MakeDormant();
int IsDormant();
BOOL IsLockedByMaster() { return FALSE; }
@ -337,26 +170,30 @@ public:
CBaseMonster *GetMonsterPointer(entvars_t *pevMonster)
{
CBaseEntity *pEntity = Instance(pevMonster);
if (pEntity != NULL)
if (pEntity) {
return pEntity->MyMonsterPointer();
}
return NULL;
return nullptr;
}
CBaseMonster *GetMonsterPointer(edict_t *pentMonster)
{
CBaseEntity *pEntity = Instance(pentMonster);
if (pEntity != NULL)
if (pEntity) {
return pEntity->MyMonsterPointer();
}
return NULL;
return nullptr;
}
static CBaseEntity *Create(char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = NULL);
static CBaseEntity *Create(char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = nullptr);
edict_t *edict() { return ENT(pev); }
EOFFSET eoffset() { return OFFSET(pev); }
int entindex() { return ENTINDEX(edict()); }
public:
entvars_t *pev; // Don't need to save/restore this pointer, the engine resets it
// Constructor. Set engine to use C/C++ callback functions
// pointers to engine data
entvars_t *pev; // Don't need to save/restore this pointer, the engine resets it
// path corners
CBaseEntity *m_pGoalEnt; // path corner we are heading towards
@ -364,11 +201,32 @@ public:
static TYPEDESCRIPTION IMPL(m_SaveData)[5];
// fundamental callbacks
void (CBaseEntity::*m_pfnThink)();
void (CBaseEntity::*m_pfnTouch)(CBaseEntity *pOther);
void (CBaseEntity::*m_pfnUse)(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void (CBaseEntity::*m_pfnBlocked)(CBaseEntity *pOther);
using thinkfn_t = decltype(m_pfnThink);
template <typename T>
void SetThink(void (T::*pfn)());
void SetThink(std::nullptr_t);
using touchfn_t = decltype(m_pfnTouch);
template <typename T>
void SetTouch(void (T::*pfn)(CBaseEntity *pOther));
void SetTouch(std::nullptr_t);
using usefn_t = decltype(m_pfnUse);
template <typename T>
void SetUse(void (T::*pfn)(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value));
void SetUse(std::nullptr_t);
using blockedfn_t = decltype(m_pfnBlocked);
template <typename T>
void SetBlocked(void (T::*pfn)(CBaseEntity *pOther));
void SetBlocked(std::nullptr_t);
#ifdef REGAMEDLL_API
CCSEntity *m_pEntity;
#else
@ -408,8 +266,52 @@ public:
bool has_disconnected;
};
inline int FNullEnt(CBaseEntity *ent) { return (ent == NULL || FNullEnt(ent->edict())); }
inline int FNullEnt(EHANDLE hent) { return (hent == NULL || FNullEnt(OFFSET(hent.Get()))); }
// Inlines
inline BOOL FNullEnt(CBaseEntity *ent) { return (ent == NULL || FNullEnt(ent->edict())); }
template <typename T>
inline void CBaseEntity::SetThink(void (T::*pfn)())
{
m_pfnThink = static_cast<thinkfn_t>(pfn);
}
inline void CBaseEntity::SetThink(std::nullptr_t)
{
m_pfnThink = nullptr;
}
template <typename T>
inline void CBaseEntity::SetTouch(void (T::*pfn)(CBaseEntity *pOther))
{
m_pfnTouch = static_cast<touchfn_t>(pfn);
}
inline void CBaseEntity::SetTouch(std::nullptr_t)
{
m_pfnTouch = nullptr;
}
template <typename T>
inline void CBaseEntity::SetUse(void (T::*pfn)(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value))
{
m_pfnUse = static_cast<usefn_t>(pfn);
}
inline void CBaseEntity::SetUse(std::nullptr_t)
{
m_pfnUse = nullptr;
}
template <typename T>
inline void CBaseEntity::SetBlocked(void (T::*pfn)(CBaseEntity *pOther))
{
m_pfnBlocked = static_cast<blockedfn_t>(pfn);
}
inline void CBaseEntity::SetBlocked(std::nullptr_t)
{
m_pfnBlocked = nullptr;
}
class CPointEntity: public CBaseEntity {
public:
@ -417,33 +319,6 @@ public:
virtual int ObjectCaps() { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); }
};
// MultiSouce
class CMultiSource: public CPointEntity {
public:
virtual void Spawn();
virtual void KeyValue(KeyValueData *pkvd);
virtual int Save(CSave &save);
virtual int Restore(CRestore &restore);
virtual int ObjectCaps() { return (CPointEntity::ObjectCaps() | FCAP_MASTER); }
virtual BOOL IsTriggered(CBaseEntity *pActivator);
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
#ifdef REGAMEDLL_FIXES
virtual void Restart();
#endif
public:
void EXPORT Register();
public:
static TYPEDESCRIPTION IMPL(m_SaveData)[4];
EHANDLE m_rgEntities[MS_MAX_TARGETS];
int m_rgTriggered[MS_MAX_TARGETS];
int m_iTotal;
string_t m_globalstate;
};
// generic Delay entity.
class CBaseDelay: public CBaseEntity {
public:
@ -458,7 +333,7 @@ public:
static TYPEDESCRIPTION IMPL(m_SaveData)[2];
float m_flDelay;
int m_iszKillTarget;
string_t m_iszKillTarget;
};
class CBaseAnimating: public CBaseDelay {
@ -469,7 +344,7 @@ public:
public:
// Basic Monster Animation functions
float StudioFrameAdvance(float flInterval = 0.0f); // accumulate animation frame time from last time called until now
float StudioFrameAdvance(float flInterval = 0.0f); // accumulate animation frame time from last time called until now
int GetSequenceFlags();
int LookupActivity(int activity);
int LookupActivityHeaviest(int activity);
@ -498,11 +373,11 @@ public:
static TYPEDESCRIPTION IMPL(m_SaveData)[5];
// animation needs
float m_flFrameRate; // computed FPS for current sequence
float m_flGroundSpeed; // computed linear movement rate for current sequence
float m_flLastEventCheck; // last time the event list was checked
BOOL m_fSequenceFinished; // flag set when StudioAdvanceFrame moves across a frame boundry
BOOL m_fSequenceLoops; // true if the sequence loops
float m_flFrameRate; // computed FPS for current sequence
float m_flGroundSpeed; // computed linear movement rate for current sequence
float m_flLastEventCheck; // last time the event list was checked
BOOL m_fSequenceFinished; // flag set when StudioAdvanceFrame moves across a frame boundry
BOOL m_fSequenceLoops; // true if the sequence loops
};
// generic Toggle entity.
@ -534,8 +409,8 @@ public:
float m_flMoveDistance; // how far a door should slide or rotate
float m_flWait;
float m_flLip;
float m_flTWidth; // for plats
float m_flTLength; // for plats
float m_flTWidth; // for plats
float m_flTLength; // for plats
Vector m_vecPosition1;
Vector m_vecPosition2;
@ -544,8 +419,14 @@ public:
int m_cTriggersLeft; // trigger_counter only, # of activations remaining
float m_flHeight;
EHANDLE m_hActivator;
EHandle m_hActivator;
void (CBaseToggle::*m_pfnCallWhenMoveDone)();
using movedonefn_t = decltype(m_pfnCallWhenMoveDone);
template <typename T>
void SetMoveDone(void (T::*pfn)());
void SetMoveDone(std::nullptr_t);
Vector m_vecFinalDest;
Vector m_vecFinalAngle;
@ -558,7 +439,25 @@ public:
// deactivated.
};
template <typename T>
inline void CBaseToggle::SetMoveDone(void (T::*pfn)())
{
m_pfnCallWhenMoveDone = static_cast<movedonefn_t>(pfn);
}
inline void CBaseToggle::SetMoveDone(std::nullptr_t)
{
m_pfnCallWhenMoveDone = nullptr;
}
#include "world.h"
#include "basemonster.h"
#include "player.h"
#define SF_BUTTON_DONTMOVE BIT(0)
#define SF_BUTTON_TOGGLE BIT(5) // button stays pushed until reactivated
#define SF_BUTTON_SPARK_IF_OFF BIT(6) // button sparks in OFF state
#define SF_BUTTON_TOUCH_ONLY BIT(8) // button only fires as a result of USE key.
// Generic Button
class CBaseButton: public CBaseToggle {
@ -569,6 +468,8 @@ public:
virtual BOOL TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType);
virtual int Save(CSave &save);
virtual int Restore(CRestore &restore);
// Buttons that don't take damage can be IMPULSE used
virtual int ObjectCaps()
{
if (pev->takedamage == DAMAGE_NO)
@ -602,27 +503,50 @@ public:
public:
static TYPEDESCRIPTION IMPL(m_SaveData)[8];
BOOL m_fStayPushed;
BOOL m_fRotating;
string_t m_strChangeTarget;
locksound_t m_ls;
byte m_bLockedSound;
BOOL m_fStayPushed; // button stays pushed in until touched again?
BOOL m_fRotating; // a rotating button? default is a sliding button.
string_t m_strChangeTarget; // if this field is not null, this is an index into the engine string array.
// when this button is touched, it's target entity's TARGET field will be set
// to the button's ChangeTarget. This allows you to make a func_train switch paths, etc.
locksound_t m_ls; // door lock sounds
byte m_bLockedSound; // ordinals from entity selection
byte m_bLockedSentence;
byte m_bUnlockedSound;
byte m_bUnlockedSentence;
int m_sounds;
};
#define SF_WORLD_DARK 0x0001 // Fade from black at startup
#define SF_WORLD_TITLE 0x0002 // Display game title at startup
#define SF_WORLD_FORCETEAM 0x0004 // Force teams
// MultiSouce
#define MAX_MS_TARGETS 32 // maximum number of targets a single multisource entity may be assigned.
#define SF_MULTI_INIT BIT(0)
// This spawns first when each level begins.
class CWorld: public CBaseEntity {
class CMultiSource: public CPointEntity {
public:
virtual void Spawn();
virtual void Precache();
virtual void KeyValue(KeyValueData *pkvd);
virtual int Save(CSave &save);
virtual int Restore(CRestore &restore);
virtual int ObjectCaps() { return (CPointEntity::ObjectCaps() | FCAP_MASTER); }
virtual BOOL IsTriggered(CBaseEntity *pActivator);
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
#ifdef REGAMEDLL_FIXES
virtual void Restart();
#endif
public:
void EXPORT Register();
public:
static TYPEDESCRIPTION IMPL(m_SaveData)[4];
EHandle m_rgEntities[MAX_MS_TARGETS];
int m_rgTriggered[MAX_MS_TARGETS];
int m_iTotal;
string_t m_globalstate;
};
// Converts a entvars_t * to a class pointer
@ -646,6 +570,7 @@ T *GetClassPtr(T *a)
a->pev = pev;
#ifdef REGAMEDLL_API
a->OnCreate();
a->m_pEntity = new W();
a->m_pEntity->m_pContainingEntity = a;
#endif
@ -663,27 +588,27 @@ extern CUtlVector<hash_item_t> stringsHashTable;
C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion);
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion);
void REMOVE_ENTITY(edict_t *pEntity);
int CaseInsensitiveHash(const char *string, int iBounds);
void EmptyEntityHashTable();
void AddEntityHashValue(entvars_t *pev, const char *value, hash_types_e fieldType);
void RemoveEntityHashValue(entvars_t *pev, const char *value, hash_types_e fieldType);
void printEntities();
edict_t *CREATE_NAMED_ENTITY(string_t iClass);
void REMOVE_ENTITY(edict_t *pEntity);
void loopPerformance();
int DispatchSpawn(edict_t *pent);
void DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd);
void DispatchTouch(edict_t *pentTouched, edict_t *pentOther);
void DispatchUse(edict_t *pentUsed, edict_t *pentOther);
void DispatchThink(edict_t *pent);
void DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther);
void DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData);
int DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity);
CBaseEntity *FindGlobalEntity(string_t classname, string_t globalname);
void DispatchObjectCollsionBox(edict_t *pent);
void SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
void SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
void SetObjectCollisionBox(entvars_t *pev);
void OnFreeEntPrivateData(edict_t *pEnt);
#endif // CBASE_H
EXT_FUNC edict_t *CREATE_NAMED_ENTITY(string_t iClass);
EXT_FUNC void AddEntityHashValue(entvars_t *pev, const char *value, hash_types_e fieldType);
EXT_FUNC void RemoveEntityHashValue(entvars_t *pev, const char *value, hash_types_e fieldType);
EXT_FUNC int DispatchSpawn(edict_t *pent);
EXT_FUNC void DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd);
EXT_FUNC void DispatchTouch(edict_t *pentTouched, edict_t *pentOther);
EXT_FUNC void DispatchUse(edict_t *pentUsed, edict_t *pentOther);
EXT_FUNC void DispatchThink(edict_t *pent);
EXT_FUNC void DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther);
EXT_FUNC void DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData);
EXT_FUNC int DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity);
EXT_FUNC void DispatchObjectCollsionBox(edict_t *pent);
EXT_FUNC void SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
EXT_FUNC void SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
EXT_FUNC void OnFreeEntPrivateData(edict_t *pEnt);
void SetObjectCollisionBox(entvars_t *pev);
CBaseEntity *FindGlobalEntity(string_t classname, string_t globalname);

View File

@ -26,80 +26,68 @@
*
*/
#ifndef CDLL_DLL_H
#define CDLL_DLL_H
#ifdef _WIN32
#pragma once
#endif
#define MAX_WEAPON_SLOTS 5 // hud item selection slots
#define MAX_ITEM_TYPES 6 // hud item selection slots
const int MAX_WEAPON_SLOTS = 5; // hud item selection slots
const int MAX_ITEM_TYPES = 6; // hud item selection slots
const int MAX_AMMO_SLOTS = 32; // not really slots
const int MAX_ITEMS = 4; // hard coded item types
#define MAX_ITEMS 4 // hard coded item types
const int DEFAULT_FOV = 90; // the default field of view
#define DEFAULT_FOV 90 // the default field of view
#define HIDEHUD_WEAPONS BIT(0)
#define HIDEHUD_FLASHLIGHT BIT(1)
#define HIDEHUD_ALL BIT(2)
#define HIDEHUD_HEALTH BIT(3)
#define HIDEHUD_TIMER BIT(4)
#define HIDEHUD_MONEY BIT(5)
#define HIDEHUD_CROSSHAIR BIT(6)
#define HIDEHUD_OBSERVER_CROSSHAIR BIT(7)
#define HIDEHUD_WEAPONS (1<<0)
#define HIDEHUD_FLASHLIGHT (1<<1)
#define HIDEHUD_ALL (1<<2)
#define HIDEHUD_HEALTH (1<<3)
#define HIDEHUD_TIMER (1<<4)
#define HIDEHUD_MONEY (1<<5)
#define HIDEHUD_CROSSHAIR (1<<6)
#define HIDEHUD_OBSERVER_CROSSHAIR (1<<7)
#define STATUSICON_HIDE 0
#define STATUSICON_SHOW 1
#define STATUSICON_FLASH 2
#define STATUSICON_HIDE 0
#define STATUSICON_SHOW 1
#define STATUSICON_FLASH 2
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define HUD_PRINTRADIO 5
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define HUD_PRINTRADIO 5
#define STATUS_NIGHTVISION_ON 1
#define STATUS_NIGHTVISION_OFF 0
#define STATUS_NIGHTVISION_ON 1
#define STATUS_NIGHTVISION_OFF 0
#define ITEM_STATUS_NIGHTVISION BIT(0)
#define ITEM_STATUS_DEFUSER BIT(1)
#define ITEM_STATUS_NIGHTVISION (1<<0)
#define ITEM_STATUS_DEFUSER (1<<1)
#define SCORE_STATUS_DEAD (1<<0)
#define SCORE_STATUS_BOMB (1<<1)
#define SCORE_STATUS_VIP (1<<2)
#define SIGNAL_BUY (1<<0)
#define SIGNAL_BOMB (1<<1)
#define SIGNAL_RESCUE (1<<2)
#define SIGNAL_ESCAPE (1<<3)
#define SIGNAL_VIPSAFETY (1<<4)
#define SCORE_STATUS_DEAD BIT(0)
#define SCORE_STATUS_BOMB BIT(1)
#define SCORE_STATUS_VIP BIT(2)
// player data iuser3
#define PLAYER_CAN_SHOOT (1<<0)
#define PLAYER_FREEZE_TIME_OVER (1<<1)
#define PLAYER_IN_BOMB_ZONE (1<<2)
#define PLAYER_HOLDING_SHIELD (1<<3)
#define PLAYER_CAN_SHOOT BIT(0)
#define PLAYER_FREEZE_TIME_OVER BIT(1)
#define PLAYER_IN_BOMB_ZONE BIT(2)
#define PLAYER_HOLDING_SHIELD BIT(3)
#define MENU_KEY_1 (1<<0)
#define MENU_KEY_2 (1<<1)
#define MENU_KEY_3 (1<<2)
#define MENU_KEY_4 (1<<3)
#define MENU_KEY_5 (1<<4)
#define MENU_KEY_6 (1<<5)
#define MENU_KEY_7 (1<<6)
#define MENU_KEY_8 (1<<7)
#define MENU_KEY_9 (1<<8)
#define MENU_KEY_0 (1<<9)
#define MENU_KEY_1 BIT(0)
#define MENU_KEY_2 BIT(1)
#define MENU_KEY_3 BIT(2)
#define MENU_KEY_4 BIT(3)
#define MENU_KEY_5 BIT(4)
#define MENU_KEY_6 BIT(5)
#define MENU_KEY_7 BIT(6)
#define MENU_KEY_8 BIT(7)
#define MENU_KEY_9 BIT(8)
#define MENU_KEY_0 BIT(9)
#define MAX_AMMO_SLOTS 32 // not really slots
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define WEAPON_SUIT 31
#define WEAPON_ALLWEAPONS (~(1 << WEAPON_SUIT))
#define WEAPON_SUIT 31
#define WEAPON_ALLWEAPONS (~(1<<WEAPON_SUIT))
// custom enum
enum VGUIMenu
@ -130,5 +118,3 @@ enum VGUIMenuSlot
VGUI_MenuSlot_Buy_SecAmmo,
VGUI_MenuSlot_Buy_Item,
};
#endif // CDLL_DLL_H

View File

@ -5,6 +5,88 @@
*/
#ifndef HOOK_GAMEDLL
int giPrecacheGrunt = 0;
int gmsgWeapPickup = 0;
int gmsgHudText = 0;
int gmsgHudTextArgs = 0;
int gmsgShake = 0;
int gmsgFade = 0;
int gmsgFlashlight = 0;
int gmsgFlashBattery = 0;
int gmsgResetHUD = 0;
int gmsgInitHUD = 0;
int gmsgViewMode = 0;
int gmsgShowGameTitle = 0;
int gmsgCurWeapon = 0;
int gmsgHealth = 0;
int gmsgDamage = 0;
int gmsgBattery = 0;
int gmsgTrain = 0;
int gmsgLogo = 0;
int gmsgWeaponList = 0;
int gmsgAmmoX = 0;
int gmsgDeathMsg = 0;
int gmsgScoreAttrib = 0;
int gmsgScoreInfo = 0;
int gmsgTeamInfo = 0;
int gmsgTeamScore = 0;
int gmsgGameMode = 0;
int gmsgMOTD = 0;
int gmsgServerName = 0;
int gmsgAmmoPickup = 0;
int gmsgItemPickup = 0;
int gmsgHideWeapon = 0;
int gmsgSayText = 0;
int gmsgTextMsg = 0;
int gmsgSetFOV = 0;
int gmsgShowMenu = 0;
int gmsgSendAudio = 0;
int gmsgRoundTime = 0;
int gmsgMoney = 0;
int gmsgBlinkAcct = 0;
int gmsgArmorType = 0;
int gmsgStatusValue = 0;
int gmsgStatusText = 0;
int gmsgStatusIcon = 0;
int gmsgBarTime = 0;
int gmsgReloadSound = 0;
int gmsgCrosshair = 0;
int gmsgNVGToggle = 0;
int gmsgRadar = 0;
int gmsgSpectator = 0;
int gmsgVGUIMenu = 0;
int gmsgCZCareer = 0;
int gmsgCZCareerHUD = 0;
int gmsgTaskTime = 0;
int gmsgTutorText = 0;
int gmsgTutorLine = 0;
int gmsgShadowIdx = 0;
int gmsgTutorState = 0;
int gmsgTutorClose = 0;
int gmsgAllowSpec = 0;
int gmsgBombDrop = 0;
int gmsgBombPickup = 0;
int gmsgHostagePos = 0;
int gmsgHostageK = 0;
int gmsgGeigerRange = 0;
int gmsgSendCorpse = 0;
int gmsgHLTV = 0;
int gmsgSpecHealth = 0;
int gmsgForceCam = 0;
int gmsgADStop = 0;
int gmsgReceiveW = 0;
int gmsgScenarioIcon = 0;
int gmsgBotVoice = 0;
int gmsgBuyClose = 0;
int gmsgItemStatus = 0;
int gmsgLocation = 0;
int gmsgSpecHealth2 = 0;
int gmsgBarTime2 = 0;
int gmsgBotProgress = 0;
int gmsgBrass = 0;
int gmsgFog = 0;
int gmsgShowTimer = 0;
bool g_bClientPrintEnable = true;
char *sPlayerModelFiles[] =
@ -19,40 +101,40 @@ char *sPlayerModelFiles[] =
"models/player/sas/sas.mdl",
"models/player/terror/terror.mdl",
"models/player/urban/urban.mdl",
"models/player/spetsnaz/spetsnaz.mdl", // CZ
"models/player/militia/militia.mdl" // CZ
"models/player/spetsnaz/spetsnaz.mdl", // CZ
"models/player/militia/militia.mdl" // CZ
};
bool g_skipCareerInitialSpawn = false;
static entity_field_alias_t entity_field_alias[] =
{
{ "origin[0]", 0 },
{ "origin[1]", 0 },
{ "origin[2]", 0 },
{ "angles[0]", 0 },
{ "angles[1]", 0 },
{ "angles[2]", 0 },
{ "origin[0]", 0 },
{ "origin[1]", 0 },
{ "origin[2]", 0 },
{ "angles[0]", 0 },
{ "angles[1]", 0 },
{ "angles[2]", 0 },
};
static entity_field_alias_t player_field_alias[] =
{
{ "origin[0]", 0 },
{ "origin[1]", 0 },
{ "origin[2]", 0 },
{ "origin[0]", 0 },
{ "origin[1]", 0 },
{ "origin[2]", 0 },
};
static entity_field_alias_t custom_entity_field_alias[] =
{
{ "origin[0]", 0 },
{ "origin[1]", 0 },
{ "origin[2]", 0 },
{ "angles[0]", 0 },
{ "angles[1]", 0 },
{ "angles[2]", 0 },
{ "skin", 0 },
{ "sequence", 0 },
{ "animtime", 0 },
{ "origin[0]", 0 },
{ "origin[1]", 0 },
{ "origin[2]", 0 },
{ "angles[0]", 0 },
{ "angles[1]", 0 },
{ "angles[2]", 0 },
{ "skin", 0 },
{ "sequence", 0 },
{ "animtime", 0 },
};
#endif // HOOK_GAMEDLL
@ -62,15 +144,130 @@ PLAYERPVSSTATUS g_PVSStatus[MAX_CLIENTS];
unsigned short m_usResetDecals;
unsigned short g_iShadowSprite;
void LinkUserMessages()
{
if (gmsgCurWeapon)
return;
gmsgCurWeapon = REG_USER_MSG("CurWeapon", 3);
gmsgGeigerRange = REG_USER_MSG("Geiger", 1);
gmsgFlashlight = REG_USER_MSG("Flashlight", 2);
gmsgFlashBattery = REG_USER_MSG("FlashBat", 1);
gmsgHealth = REG_USER_MSG("Health", 1);
gmsgDamage = REG_USER_MSG("Damage", 12);
gmsgBattery = REG_USER_MSG("Battery", 2);
gmsgTrain = REG_USER_MSG("Train", 1);
gmsgHudText = REG_USER_MSG("HudTextPro", -1);
REG_USER_MSG("HudText", -1);
gmsgSayText = REG_USER_MSG("SayText", -1);
gmsgTextMsg = REG_USER_MSG("TextMsg", -1);
gmsgWeaponList = REG_USER_MSG("WeaponList", -1);
gmsgResetHUD = REG_USER_MSG("ResetHUD", 0);
gmsgInitHUD = REG_USER_MSG("InitHUD", 0);
gmsgViewMode = REG_USER_MSG("ViewMode", 0);
gmsgShowGameTitle = REG_USER_MSG("GameTitle", 1);
gmsgDeathMsg = REG_USER_MSG("DeathMsg", -1);
gmsgScoreAttrib = REG_USER_MSG("ScoreAttrib", 2);
gmsgScoreInfo = REG_USER_MSG("ScoreInfo", 9);
gmsgTeamInfo = REG_USER_MSG("TeamInfo", -1);
gmsgTeamScore = REG_USER_MSG("TeamScore", -1);
gmsgGameMode = REG_USER_MSG("GameMode", 1);
gmsgMOTD = REG_USER_MSG("MOTD", -1);
gmsgServerName = REG_USER_MSG("ServerName", -1);
gmsgAmmoPickup = REG_USER_MSG("AmmoPickup", 2);
gmsgWeapPickup = REG_USER_MSG("WeapPickup", 1);
gmsgItemPickup = REG_USER_MSG("ItemPickup", -1);
gmsgHideWeapon = REG_USER_MSG("HideWeapon", 1);
gmsgSetFOV = REG_USER_MSG("SetFOV", 1);
gmsgShowMenu = REG_USER_MSG("ShowMenu", -1);
gmsgShake = REG_USER_MSG("ScreenShake", 6);
gmsgFade = REG_USER_MSG("ScreenFade", 10);
gmsgAmmoX = REG_USER_MSG("AmmoX", 2);
gmsgSendAudio = REG_USER_MSG("SendAudio", -1);
gmsgRoundTime = REG_USER_MSG("RoundTime", 2);
gmsgMoney = REG_USER_MSG("Money", 5);
gmsgArmorType = REG_USER_MSG("ArmorType", 1);
gmsgBlinkAcct = REG_USER_MSG("BlinkAcct", 1);
gmsgStatusValue = REG_USER_MSG("StatusValue", -1);
gmsgStatusText = REG_USER_MSG("StatusText", -1);
gmsgStatusIcon = REG_USER_MSG("StatusIcon", -1);
gmsgBarTime = REG_USER_MSG("BarTime", 2);
gmsgReloadSound = REG_USER_MSG("ReloadSound", 2);
gmsgCrosshair = REG_USER_MSG("Crosshair", 1);
gmsgNVGToggle = REG_USER_MSG("NVGToggle", 1);
gmsgRadar = REG_USER_MSG("Radar", 7);
gmsgSpectator = REG_USER_MSG("Spectator", 2);
gmsgVGUIMenu = REG_USER_MSG("VGUIMenu", -1);
gmsgTutorText = REG_USER_MSG("TutorText", -1);
gmsgTutorLine = REG_USER_MSG("TutorLine", -1);
gmsgTutorState = REG_USER_MSG("TutorState", -1);
gmsgTutorClose = REG_USER_MSG("TutorClose", -1);
gmsgAllowSpec = REG_USER_MSG("AllowSpec", 1);
gmsgBombDrop = REG_USER_MSG("BombDrop", 7);
gmsgBombPickup = REG_USER_MSG("BombPickup", 0);
gmsgSendCorpse = REG_USER_MSG("ClCorpse", -1);
gmsgHostagePos = REG_USER_MSG("HostagePos", 8);
gmsgHostageK = REG_USER_MSG("HostageK", 1);
gmsgHLTV = REG_USER_MSG("HLTV", 2);
gmsgSpecHealth = REG_USER_MSG("SpecHealth", 1);
gmsgForceCam = REG_USER_MSG("ForceCam", 3);
gmsgADStop = REG_USER_MSG("ADStop", 0);
gmsgReceiveW = REG_USER_MSG("ReceiveW", 1);
gmsgCZCareer = REG_USER_MSG("CZCareer", -1);
gmsgCZCareerHUD = REG_USER_MSG("CZCareerHUD", -1);
gmsgShadowIdx = REG_USER_MSG("ShadowIdx", 4);
gmsgTaskTime = REG_USER_MSG("TaskTime", 4);
gmsgScenarioIcon = REG_USER_MSG("Scenario", -1);
gmsgBotVoice = REG_USER_MSG("BotVoice", 2);
gmsgBuyClose = REG_USER_MSG("BuyClose", 0);
gmsgSpecHealth2 = REG_USER_MSG("SpecHealth2", 2);
gmsgBarTime2 = REG_USER_MSG("BarTime2", 4);
gmsgItemStatus = REG_USER_MSG("ItemStatus", 1);
gmsgLocation = REG_USER_MSG("Location", -1);
gmsgBotProgress = REG_USER_MSG("BotProgress", -1);
gmsgBrass = REG_USER_MSG("Brass", -1);
gmsgFog = REG_USER_MSG("Fog", 7);
gmsgShowTimer = REG_USER_MSG("ShowTimer", 0);
gmsgHudTextArgs = REG_USER_MSG("HudTextArgs", -1);
}
void WriteSigonMessages()
{
for (int i = 0; i < MAX_WEAPONS; ++i)
{
ItemInfo &II = IMPL_CLASS(CBasePlayerItem, ItemInfoArray)[i];
if (!II.iId)
continue;
const char *pszName;
if (!II.pszName)
pszName = "Empty";
else
pszName = II.pszName;
MESSAGE_BEGIN(MSG_INIT, gmsgWeaponList);
WRITE_STRING(pszName);
WRITE_BYTE(CBasePlayer::GetAmmoIndex(II.pszAmmo1));
WRITE_BYTE(II.iMaxAmmo1);
WRITE_BYTE(CBasePlayer::GetAmmoIndex(II.pszAmmo2));
WRITE_BYTE(II.iMaxAmmo2);
WRITE_BYTE(II.iSlot);
WRITE_BYTE(II.iPosition);
WRITE_BYTE(II.iId);
WRITE_BYTE(II.iFlags);
MESSAGE_END();
}
}
int CMD_ARGC_()
{
if (!UseBotArgs)
return CMD_ARGC();
int i = 0;
while (BotArgs[i])
++i;
i++;
return i;
}
@ -83,7 +280,7 @@ const char *CMD_ARGV_(int i)
if (i < 4)
return BotArgs[i];
return NULL;
return nullptr;
}
NOXREF void set_suicide_frame(entvars_t *pev)
@ -99,7 +296,7 @@ NOXREF void set_suicide_frame(entvars_t *pev)
void BlinkAccount(CBasePlayer *player, int numBlinks)
{
MESSAGE_BEGIN(MSG_ONE, gmsgBlinkAcct, NULL, player->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgBlinkAcct, nullptr, player->pev);
WRITE_BYTE(numBlinks);
MESSAGE_END();
}
@ -127,7 +324,9 @@ void EXT_FUNC ClientDisconnect(edict_t *pEntity)
pEntity->v.flags = FL_DORMANT;
if (pPlayer)
{
pPlayer->Disconnect();
}
UTIL_SetOrigin(&pEntity->v, pEntity->v.origin);
g_pGameRules->ClientDisconnected(pEntity);
@ -199,7 +398,7 @@ LINK_HOOK_VOID_CHAIN(ShowMenu, (CBasePlayer *pPlayer, int bitsValidSlots, int nD
void EXT_FUNC __API_HOOK(ShowMenu)(CBasePlayer *pPlayer, int bitsValidSlots, int nDisplayTime, BOOL fNeedMore, char *pszText)
{
MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pPlayer->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, nullptr, pPlayer->pev);
WRITE_SHORT(bitsValidSlots);
WRITE_CHAR(nDisplayTime);
WRITE_BYTE(fNeedMore);
@ -227,7 +426,7 @@ void EXT_FUNC __API_HOOK(ShowVGUIMenu)(CBasePlayer *pPlayer, int MenuType, int B
if (pPlayer->m_bVGUIMenus || MenuType > VGUI_Menu_Buy_Item)
{
MESSAGE_BEGIN(MSG_ONE, gmsgVGUIMenu, NULL, pPlayer->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgVGUIMenu, nullptr, pPlayer->pev);
WRITE_BYTE(MenuType);
WRITE_SHORT(BitMask);
WRITE_CHAR(-1);
@ -242,28 +441,28 @@ void EXT_FUNC __API_HOOK(ShowVGUIMenu)(CBasePlayer *pPlayer, int MenuType, int B
NOXREF int CountTeams()
{
int iNumCT = 0, iNumTerrorist = 0;
CBaseEntity *pPlayer = NULL;
CBaseEntity *pEntity = nullptr;
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")))
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
{
if (FNullEnt(pPlayer->edict()))
if (FNullEnt(pEntity->edict()))
break;
CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pPlayer->pev);
CBasePlayer *pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
if (player->m_iTeam == UNASSIGNED)
if (pPlayer->m_iTeam == UNASSIGNED)
continue;
if (player->pev->flags & FL_DORMANT)
if (pPlayer->pev->flags & FL_DORMANT)
continue;
if (player->m_iTeam == SPECTATOR)
if (pPlayer->m_iTeam == SPECTATOR)
continue;
if (player->m_iTeam == CT)
if (pPlayer->m_iTeam == CT)
iNumCT++;
else if (player->m_iTeam == TERRORIST)
else if (pPlayer->m_iTeam == TERRORIST)
iNumTerrorist++;
}
@ -274,23 +473,23 @@ void ListPlayers(CBasePlayer *current)
{
char message[120] = "", cNumber[12];
CBaseEntity *pPlayer = NULL;
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")))
CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
{
if (FNullEnt(pPlayer->edict()))
if (FNullEnt(pEntity->edict()))
break;
if (pPlayer->pev->flags & FL_DORMANT)
if (pEntity->pev->flags & FL_DORMANT)
continue;
CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pPlayer->pev);
int iUserID = GETPLAYERUSERID(ENT(player->pev));
CBasePlayer *pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
int iUserID = GETPLAYERUSERID(ENT(pPlayer->pev));
Q_sprintf(cNumber, "%d", iUserID);
Q_strcpy(message, "\n");
Q_strcat(message, cNumber);
Q_strcat(message, " : ");
Q_strcat(message, STRING(player->pev->netname));
Q_strcat(message, STRING(pPlayer->pev->netname));
ClientPrint(current->pev, HUD_PRINTCONSOLE, message);
}
@ -300,22 +499,23 @@ void ListPlayers(CBasePlayer *current)
int CountTeamPlayers(int iTeam)
{
CBaseEntity *pPlayer = NULL;
int i = 0;
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")))
int nCount = 0;
CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
{
if (FNullEnt(pPlayer->edict()))
if (FNullEnt(pEntity->edict()))
break;
if (pPlayer->pev->flags & FL_DORMANT)
if (pEntity->pev->flags & FL_DORMANT)
continue;
if (GetClassPtr<CCSPlayer>((CBasePlayer *)pPlayer->pev)->m_iTeam == iTeam)
++i;
if (GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev)->m_iTeam == iTeam)
{
nCount++;
}
}
return i;
return nCount;
}
void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer)
@ -336,7 +536,7 @@ void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer)
return;
iValidVotes = 0;
pTempEntity = NULL;
pTempEntity = nullptr;
iVoteID = pVotingPlayer->m_iCurrentKickVote;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")))
@ -366,7 +566,7 @@ void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer)
{
UTIL_ClientPrintAll(HUD_PRINTCENTER, "#Game_kicked", STRING(pKickPlayer->pev->netname));
SERVER_COMMAND(UTIL_VarArgs("kick # %d\n", iVoteID));
pTempEntity = NULL;
pTempEntity = nullptr;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")))
{
@ -457,25 +657,25 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
pPlayer->has_disconnected = false;
pPlayer->m_iMenu = Menu_OFF;
pPlayer->ClearAutoBuyData();
pPlayer->m_rebuyString = NULL;
pPlayer->m_rebuyString = nullptr;
SET_CLIENT_MAXSPEED(ENT(pPlayer->pev), 1);
SET_MODEL(ENT(pPlayer->pev), "models/player.mdl");
pPlayer->SetThink(NULL);
CBaseEntity *pTarget = NULL;
pPlayer->m_pIntroCamera = UTIL_FindEntityByClassname(NULL, "trigger_camera");
CBaseEntity *pTarget = nullptr;
pPlayer->m_pIntroCamera = UTIL_FindEntityByClassname(nullptr, "trigger_camera");
if (g_pGameRules && g_pGameRules->IsMultiplayer())
{
CSGameRules()->m_bMapHasCameras = (pPlayer->m_pIntroCamera != NULL);
CSGameRules()->m_bMapHasCameras = (pPlayer->m_pIntroCamera != nullptr);
}
if (pPlayer->m_pIntroCamera)
{
// find the target (by default info_target) for the camera view direction.
pTarget = UTIL_FindEntityByTargetname(NULL, STRING(pPlayer->m_pIntroCamera->pev->target));
pTarget = UTIL_FindEntityByTargetname(nullptr, STRING(pPlayer->m_pIntroCamera->pev->target));
}
if (pPlayer->m_pIntroCamera && pTarget)
@ -599,15 +799,15 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
if (Q_strlen(p) <= 0)
return;
const char *placeName = NULL;
char *pszFormat = NULL;
char *pszConsoleFormat = NULL;
const char *placeName = nullptr;
char *pszFormat = nullptr;
char *pszConsoleFormat = nullptr;
bool consoleUsesPlaceName = false;
// team only
if (teamonly)
{
if (g_bIsCzeroGame && (player->m_iTeam == CT || player->m_iTeam == TERRORIST))
if (AreRunningCZero() && (player->m_iTeam == CT || player->m_iTeam == TERRORIST))
{
// search the place name where is located the player
Place playerPlace = TheNavAreaGrid.GetPlace(&player->pev->origin);
@ -722,7 +922,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
// This may return the world in single player if the client types something between levels or during spawn
// so check it, or it will infinite loop
client = NULL;
client = nullptr;
while ((client = (CBasePlayer *)UTIL_FindEntityByClassname(client, "player")))
{
if (FNullEnt(client->edict()))
@ -754,7 +954,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
if ((client->m_iIgnoreGlobalChat == IGNOREMSG_ENEMY && client->m_iTeam == player->m_iTeam)
|| client->m_iIgnoreGlobalChat == IGNOREMSG_NONE)
{
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, NULL, client->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, nullptr, client->pev);
WRITE_BYTE(ENTINDEX(pEntity));
WRITE_STRING(pszFormat);
WRITE_STRING("");
@ -772,7 +972,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
char *fullText = p;
// print to the sending client
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, NULL, &pEntity->v);
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, nullptr, &pEntity->v);
WRITE_BYTE(ENTINDEX(pEntity));
WRITE_STRING(pszFormat);
WRITE_STRING("");
@ -968,7 +1168,7 @@ void BuyMachineGun(CBasePlayer *pPlayer, int iSlot)
void BuyItem(CBasePlayer *pPlayer, int iSlot)
{
int iItemPrice = 0;
const char *pszItem = NULL;
const char *pszItem = nullptr;
if (!pPlayer->CanPlayerBuy(true))
return;
@ -1208,7 +1408,7 @@ void BuyItem(CBasePlayer *pPlayer, int iSlot)
bEnoughMoney = true;
pPlayer->m_bHasDefuser = true;
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pPlayer->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pPlayer->pev);
WRITE_BYTE(STATUSICON_SHOW);
WRITE_STRING("defuser");
WRITE_BYTE(0);
@ -1331,7 +1531,7 @@ LINK_HOOK_VOID_CHAIN(HandleMenu_ChooseAppearance, (CBasePlayer *player, int slot
void EXT_FUNC __API_HOOK(HandleMenu_ChooseAppearance)(CBasePlayer *player, int slot)
{
int numSkins = g_bIsCzeroGame ? CZ_NUM_SKIN : CS_NUM_SKIN;
int numSkins = AreRunningCZero() ? CZ_NUM_SKIN : CS_NUM_SKIN;
struct
{
@ -1369,7 +1569,7 @@ void EXT_FUNC __API_HOOK(HandleMenu_ChooseAppearance)(CBasePlayer *player, int s
appearance.model_name = "guerilla";
break;
case 5:
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
appearance.model_id = MODEL_MILITIA;
appearance.model_name = "militia";
@ -1418,7 +1618,7 @@ void EXT_FUNC __API_HOOK(HandleMenu_ChooseAppearance)(CBasePlayer *player, int s
appearance.model_name = "gign";
break;
case 5:
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
appearance.model_id = MODEL_SPETSNAZ;
appearance.model_name = "spetsnaz";
@ -1613,7 +1813,7 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *player, int slot)
#else
player->m_iAccount = 0;
MESSAGE_BEGIN(MSG_ONE, gmsgMoney, NULL, player->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgMoney, nullptr, player->pev);
WRITE_LONG(player->m_iAccount);
WRITE_BYTE(0);
MESSAGE_END();
@ -1631,7 +1831,7 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *player, int slot)
WRITE_SHORT(0);
MESSAGE_END();
player->m_pIntroCamera = NULL;
player->m_pIntroCamera = nullptr;
player->m_bTeamChanged = true;
if (TheBots)
@ -1792,14 +1992,14 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *player, int slot)
switch (team)
{
case CT:
if (g_bIsCzeroGame)
if (AreRunningCZero())
ShowVGUIMenu(player, VGUI_Menu_Class_CT, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6), "#CT_Select");
else
ShowVGUIMenu(player, VGUI_Menu_Class_CT, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5), "#CT_Select");
break;
case TERRORIST:
if (g_bIsCzeroGame)
if (AreRunningCZero())
ShowVGUIMenu(player, VGUI_Menu_Class_T, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6), "#Terrorist_Select");
else
ShowVGUIMenu(player, VGUI_Menu_Class_T, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5), "#Terrorist_Select");
@ -2056,7 +2256,7 @@ bool BuyAmmo(CBasePlayer *player, int nSlot, bool bBlinkMoney)
CBaseEntity *EntityFromUserID(int userID)
{
CBaseEntity *pTempEntity = NULL;
CBaseEntity *pTempEntity = nullptr;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")))
{
@ -2071,13 +2271,13 @@ CBaseEntity *EntityFromUserID(int userID)
}
}
return NULL;
return nullptr;
}
NOXREF int CountPlayersInServer()
{
int count = 0;
CBaseEntity *pTempEntity = NULL;
CBaseEntity *pTempEntity = nullptr;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")))
{
@ -2102,7 +2302,7 @@ BOOL HandleBuyAliasCommands(CBasePlayer *pPlayer, const char *pszCommand)
{
// Let them buy it if it's got a weapon data string.
BOOL bRetVal = FALSE;
const char *pszFailItem = NULL;
const char *pszFailItem = nullptr;
WeaponIdType weaponID = WEAPON_NONE;
const char *weaponFailName = BuyAliasToWeaponID(pszCommand, weaponID);
@ -2289,7 +2489,7 @@ BOOL HandleRadioAliasCommands(CBasePlayer *pPlayer, const char *pszCommand)
void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *parg1)
{
const char *pstr = NULL;
const char *pstr = nullptr;
entvars_t *pev = &pEntity->v;
CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pev);
@ -2530,7 +2730,7 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
}
else
{
MESSAGE_BEGIN(MSG_ONE, gmsgBuyClose, NULL, player->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgBuyClose, nullptr, player->pev);
MESSAGE_END();
}
}
@ -2892,7 +3092,7 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
if (mode == OBS_CHASE_FREE)
{
MESSAGE_BEGIN(MSG_ONE, gmsgADStop, NULL, player->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgADStop, nullptr, player->pev);
MESSAGE_END();
}
}
@ -2989,7 +3189,7 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
{
EMIT_SOUND(ENT(player->pev), CHAN_ITEM, "items/nvg_off.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, player->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, nullptr, player->pev);
WRITE_BYTE(0); // disable nightvision
MESSAGE_END();
@ -3002,7 +3202,7 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
{
EMIT_SOUND(ENT(pObserver->pev), CHAN_ITEM, "items/nvg_off.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, pObserver->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, nullptr, pObserver->pev);
WRITE_BYTE(0); // disable nightvision
MESSAGE_END();
@ -3014,7 +3214,7 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
{
EMIT_SOUND(ENT(player->pev), CHAN_ITEM, "items/nvg_on.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, player->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, nullptr, player->pev);
WRITE_BYTE(1); // enable nightvision
MESSAGE_END();
@ -3027,7 +3227,7 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
{
EMIT_SOUND(ENT(pObserver->pev), CHAN_ITEM, "items/nvg_on.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, pObserver->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, nullptr, pObserver->pev);
WRITE_BYTE(1); // enable nightvision
MESSAGE_END();
@ -3370,7 +3570,6 @@ void EXT_FUNC ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
#ifdef REGAMEDLL_ADD
CSGameRules()->ServerActivate();
#endif
}
void EXT_FUNC PlayerPreThink(edict_t *pEntity)
@ -3422,7 +3621,7 @@ void EXT_FUNC StartFrame()
CLocalNav::Think();
static cvar_t *skill = NULL;
static cvar_t *skill = nullptr;
if (!skill)
{
skill = CVAR_GET_POINTER("skill");
@ -3443,11 +3642,6 @@ void EXT_FUNC StartFrame()
if (TheTutor) {
TheTutor->StartFrame(gpGlobals->time);
}
#ifndef REGAMEDLL_FIXES
// it is noxref
++g_ulFrameCount;
#endif
}
void ClientPrecache()
@ -3557,8 +3751,8 @@ void ClientPrecache()
PRECACHE_SOUND("debris/glass1.wav");
PRECACHE_SOUND("debris/glass2.wav");
PRECACHE_SOUND("debris/glass3.wav");
PRECACHE_SOUND("items/flashlight1.wav");
PRECACHE_SOUND("items/flashlight1.wav");
PRECACHE_SOUND(SOUND_FLASHLIGHT_ON);
PRECACHE_SOUND(SOUND_FLASHLIGHT_OFF);
PRECACHE_SOUND("common/bodysplat.wav");
PRECACHE_SOUND("player/pl_pain2.wav");
PRECACHE_SOUND("player/pl_pain4.wav");
@ -3567,7 +3761,7 @@ void ClientPrecache()
PRECACHE_SOUND("player/pl_pain7.wav");
int numPlayerModels;
if (g_bIsCzeroGame)
if (AreRunningCZero())
numPlayerModels = ARRAYSIZE(sPlayerModelFiles);
else
numPlayerModels = ARRAYSIZE(sPlayerModelFiles) - 2;
@ -3575,7 +3769,7 @@ void ClientPrecache()
for (i = 0; i < numPlayerModels; ++i)
PRECACHE_MODEL(sPlayerModelFiles[i]);
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
for (i = FirstCustomSkin; i <= LastCustomSkin; ++i)
{
@ -3640,7 +3834,7 @@ void ClientPrecache()
for (i = 0; i < numPlayerModels; ++i)
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, sPlayerModelFiles[i]);
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
for (i = FirstCustomSkin; i <= LastCustomSkin; ++i)
{
@ -3664,7 +3858,7 @@ void ClientPrecache()
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_ne.tga");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_sw.tga");
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
vMin = Vector(-13, -6, -22);
vMax = Vector(13, 6, 22);
@ -3682,7 +3876,7 @@ void ClientPrecache()
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_fiveseven.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_glock18.mdl");
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
vMin = Vector(-26, -19, -21);
vMax = Vector(26, 23, 21);
@ -3696,7 +3890,7 @@ void ClientPrecache()
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_xm1014.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_m3.mdl");
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
vMin = Vector(-23, -9, -20);
vMax = Vector(23, 17, 20);
@ -3713,7 +3907,7 @@ void ClientPrecache()
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_tmp.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_p90.mdl");
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
vMin = Vector(-38, -33, -22);
vMax = Vector(38, 15, 35);
@ -3735,7 +3929,7 @@ void ClientPrecache()
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_famas.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_galil.mdl");
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
vMin = Vector(-30, -10, -20);
vMax = Vector(30, 11, 20);
@ -3756,7 +3950,7 @@ void ClientPrecache()
vMin = Vector(-4, -8, -3);
vMax = Vector(3, 7, 3);
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
vMin = Vector(-17, -8, -3);
vMax = Vector(17, 7, 3);
@ -3769,7 +3963,7 @@ void ClientPrecache()
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/w_c4.mdl");
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
vMin = Vector(-7, -3, -18);
vMax = Vector(7, 2, 18);
@ -3784,7 +3978,7 @@ void ClientPrecache()
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_hegrenade.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_smokegrenade.mdl");
if (g_bIsCzeroGame)
if (AreRunningCZero())
vMin = Vector(-5, -5, -7);
else
vMin = Vector(-5, -5, -5);
@ -3800,7 +3994,7 @@ void ClientPrecache()
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_knife.mdl");
if (g_bIsCzeroGame)
if (AreRunningCZero())
{
vMin = Vector(-21, -25, -54);
vMax = Vector(21, 23, 24);
@ -3867,7 +4061,7 @@ const char *EXT_FUNC GetGameDescription()
return CSGameRules()->GetGameDescription();
}
#else
if (g_bIsCzeroGame) {
if (AreRunningCZero()) {
return "Condition Zero";
}
#endif
@ -4045,7 +4239,6 @@ int EXT_FUNC AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, ed
int i;
int hostnum = ENTINDEX(host) - 1;
if (CheckPlayerPVSLeafChanged(host, hostnum))
ResetPlayerPVS(host, hostnum);
@ -4400,10 +4593,10 @@ int EXT_FUNC GetWeaponData(edict_t *player, struct weapon_data_s *info)
return 1;
// go through all of the weapons and make a list of the ones to pack
for (int i = 0; i < MAX_ITEM_TYPES; ++i)
for (int i = 0; i < MAX_ITEM_TYPES; i++)
{
auto pPlayerItem = pPlayer->m_rgpPlayerItems[i];
while (pPlayerItem != nullptr)
while (pPlayerItem)
{
// there's a weapon here. Should I pack it?
auto weapon = (CBasePlayerWeapon *)pPlayerItem->GetWeaponPtr();

View File

@ -26,11 +26,7 @@
*
*/
#ifndef CLIENT_H
#define CLIENT_H
#ifdef _WIN32
#pragma once
#endif
// custom enum
enum ChooseTeamMenuSlot
@ -58,8 +54,8 @@ enum BuyItemMenuSlot
MENU_SLOT_ITEM_SHIELD,
};
#define CS_NUM_SKIN 4
#define CZ_NUM_SKIN 5
#define CS_NUM_SKIN 4
#define CZ_NUM_SKIN 5
#define FIELD_ORIGIN0 0
#define FIELD_ORIGIN1 1
@ -78,8 +74,8 @@ enum BuyItemMenuSlot
#define CUSTOMFIELD_ANGLES2 5
#define CUSTOMFIELD_SKIN 6
#define CUSTOMFIELD_SEQUENCE 7
#define CUSTOMFIELD_ANIMTIME 8
#define CUSTOMFIELD_SEQUENCE 7
#define CUSTOMFIELD_ANIMTIME 8
typedef struct
{
@ -87,12 +83,13 @@ typedef struct
} ENTITYPVSSTATUS;
const int MAX_ENTITIES = 1380;
struct PLAYERPVSSTATUS
{
ENTITYPVSSTATUS m_Status[1380];
ENTITYPVSSTATUS m_Status[MAX_ENTITIES];
int headnode;
int num_leafs;
short int leafnums[ MAX_ENT_LEAFS ];
short int leafnums[MAX_ENT_LEAFS];
};
struct entity_field_alias_t
@ -119,6 +116,9 @@ void ShowMenu_OrigFunc(CBasePlayer *pPlayer, int bitsValidSlots, int nDisplayTim
void ShowVGUIMenu_OrigFunc(CBasePlayer *pPlayer, int MenuType, int BitMask, char *szOldMenu);
#endif
void LinkUserMessages();
void WriteSigonMessages();
int CMD_ARGC_();
const char *CMD_ARGV_(int i);
void set_suicide_frame(entvars_t *pev);
@ -199,11 +199,91 @@ inline const char *GetTeamName(int team)
{
switch (team)
{
case CT: return "CT";
case TERRORIST: return "TERRORIST";
case SPECTATOR: return "SPECTATOR";
default: return "UNASSIGNED";
case CT: return "CT";
case TERRORIST: return "TERRORIST";
case SPECTATOR: return "SPECTATOR";
default: return "UNASSIGNED";
}
}
#endif // CLIENT_H
extern int giPrecacheGrunt;
extern int gmsgWeapPickup;
extern int gmsgHudText;
extern int gmsgHudTextArgs;
extern int gmsgShake;
extern int gmsgFade;
extern int gmsgFlashlight;
extern int gmsgFlashBattery;
extern int gmsgResetHUD;
extern int gmsgInitHUD;
extern int gmsgViewMode;
extern int gmsgShowGameTitle;
extern int gmsgCurWeapon;
extern int gmsgHealth;
extern int gmsgDamage;
extern int gmsgBattery;
extern int gmsgTrain;
extern int gmsgLogo;
extern int gmsgWeaponList;
extern int gmsgAmmoX;
extern int gmsgDeathMsg;
extern int gmsgScoreAttrib;
extern int gmsgScoreInfo;
extern int gmsgTeamInfo;
extern int gmsgTeamScore;
extern int gmsgGameMode;
extern int gmsgMOTD;
extern int gmsgServerName;
extern int gmsgAmmoPickup;
extern int gmsgItemPickup;
extern int gmsgHideWeapon;
extern int gmsgSayText;
extern int gmsgTextMsg;
extern int gmsgSetFOV;
extern int gmsgShowMenu;
extern int gmsgSendAudio;
extern int gmsgRoundTime;
extern int gmsgMoney;
extern int gmsgBlinkAcct;
extern int gmsgArmorType;
extern int gmsgStatusValue;
extern int gmsgStatusText;
extern int gmsgStatusIcon;
extern int gmsgBarTime;
extern int gmsgReloadSound;
extern int gmsgCrosshair;
extern int gmsgNVGToggle;
extern int gmsgRadar;
extern int gmsgSpectator;
extern int gmsgVGUIMenu;
extern int gmsgCZCareer;
extern int gmsgCZCareerHUD;
extern int gmsgTaskTime;
extern int gmsgTutorText;
extern int gmsgTutorLine;
extern int gmsgShadowIdx;
extern int gmsgTutorState;
extern int gmsgTutorClose;
extern int gmsgAllowSpec;
extern int gmsgBombDrop;
extern int gmsgBombPickup;
extern int gmsgHostagePos;
extern int gmsgHostageK;
extern int gmsgGeigerRange;
extern int gmsgSendCorpse;
extern int gmsgHLTV;
extern int gmsgSpecHealth;
extern int gmsgForceCam;
extern int gmsgADStop;
extern int gmsgReceiveW;
extern int gmsgScenarioIcon;
extern int gmsgBotVoice;
extern int gmsgBuyClose;
extern int gmsgItemStatus;
extern int gmsgLocation;
extern int gmsgSpecHealth2;
extern int gmsgBarTime2;
extern int gmsgBotProgress;
extern int gmsgBrass;
extern int gmsgFog;
extern int gmsgShowTimer;

View File

@ -0,0 +1,191 @@
#include "precompiled.h"
void InstallCommands()
{
static bool installedCommands = false;
if (installedCommands)
return;
if (AreRunningCZero())
{
ADD_SERVER_COMMAND("career_continue", SV_Continue_f);
ADD_SERVER_COMMAND("career_matchlimit", SV_CareerMatchLimit_f);
ADD_SERVER_COMMAND("career_add_task", SV_CareerAddTask_f);
ADD_SERVER_COMMAND("career_endround", SV_Career_EndRound_f);
ADD_SERVER_COMMAND("career_restart", SV_Career_Restart_f);
ADD_SERVER_COMMAND("tutor_toggle", SV_Tutor_Toggle_f);
}
ADD_SERVER_COMMAND("perf_test", SV_LoopPerformance_f);
ADD_SERVER_COMMAND("print_ent", SV_PrintEntities_f);
installedCommands = true;
}
void SV_Continue_f()
{
if (CSGameRules()->IsCareer() && CSGameRules()->m_flRestartRoundTime > 100000.0)
{
CSGameRules()->m_flRestartRoundTime = gpGlobals->time;
// go continue
MESSAGE_BEGIN(MSG_ALL, gmsgCZCareer);
WRITE_STRING("GOGOGO");
MESSAGE_END();
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
if (pPlayer && !pPlayer->IsBot())
{
// at the end of the round is showed window with the proposal surrender or continue
// now of this time HUD is completely hidden
// we must to restore HUD after entered continued
pPlayer->m_iHideHUD &= ~HIDEHUD_ALL;
}
}
}
}
void SV_CareerMatchLimit_f()
{
if (CMD_ARGC() != 3)
{
return;
}
if (CSGameRules()->IsCareer())
{
CSGameRules()->SetCareerMatchLimit(Q_atoi(CMD_ARGV(1)), Q_atoi(CMD_ARGV(2)));
}
}
void SV_CareerAddTask_f()
{
if (CMD_ARGC() != 7)
return;
const char *taskName = CMD_ARGV(1);
const char *weaponName = CMD_ARGV(2);
int reps = Q_atoi(CMD_ARGV(3));
bool mustLive = Q_atoi(CMD_ARGV(4)) != 0;
bool crossRounds = Q_atoi(CMD_ARGV(5)) != 0;
bool isComplete = Q_atoi(CMD_ARGV(6)) != 0;
if (TheCareerTasks)
{
TheCareerTasks->AddTask(taskName, weaponName, reps, mustLive, crossRounds, isComplete);
}
}
void SV_Career_EndRound_f()
{
if (!CSGameRules()->IsCareer() || !CSGameRules()->IsInCareerRound())
{
return;
}
CBasePlayer *pLocalPlayer = UTIL_GetLocalPlayer();
if (pLocalPlayer)
{
SERVER_COMMAND("kill\n");
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *player = UTIL_PlayerByIndex(i);
if (!player || FNullEnt(player->pev))
continue;
if (player->IsBot() && player->m_iTeam == pLocalPlayer->m_iTeam)
{
SERVER_COMMAND(UTIL_VarArgs("bot_kill \"%s\"\n", STRING(player->pev->netname)));
}
}
}
}
void SV_Career_Restart_f()
{
if (CSGameRules()->IsCareer())
{
CSGameRules()->CareerRestart();
}
}
void SV_Tutor_Toggle_f()
{
CVAR_SET_FLOAT("tutor_enable", (CVAR_GET_FLOAT("tutor_enable") <= 0.0));
}
void SV_LoopPerformance_f()
{
CCounter loopCounter;
loopCounter.Init();
double start, end;
int i;
start = loopCounter.GetCurTime();
for (i = 0; i < 100; ++i)
{
CBaseEntity *pSpot;
for (pSpot = UTIL_FindEntityByString_Old(nullptr, "classname", "info_player_start"); pSpot; pSpot = UTIL_FindEntityByString_Old(pSpot, "classname", "info_player_start"))
;
for (pSpot = UTIL_FindEntityByString_Old(nullptr, "classname", "info_player_deathmatch"); pSpot; pSpot = UTIL_FindEntityByString_Old(pSpot, "classname", "info_player_deathmatch"))
;
for (pSpot = UTIL_FindEntityByString_Old(nullptr, "classname", "player"); pSpot; pSpot = UTIL_FindEntityByString_Old(pSpot, "classname", "player"))
;
for (pSpot = UTIL_FindEntityByString_Old(nullptr, "classname", "bodyque"); pSpot; pSpot = UTIL_FindEntityByString_Old(pSpot, "classname", "bodyque"))
;
}
end = loopCounter.GetCurTime();
CONSOLE_ECHO(" Time in old search loop %.4f\n", (end - start) * 1000.0);
// check time new search loop
start = loopCounter.GetCurTime();
for (i = 0; i < 100; ++i)
{
CBaseEntity *pSpot;
for (pSpot = UTIL_FindEntityByString(nullptr, "classname", "info_player_start"); pSpot; pSpot = UTIL_FindEntityByString(pSpot, "classname", "info_player_start"))
;
for (pSpot = UTIL_FindEntityByString(nullptr, "classname", "info_player_deathmatch"); pSpot; pSpot = UTIL_FindEntityByString(pSpot, "classname", "info_player_deathmatch"))
;
for (pSpot = UTIL_FindEntityByString(nullptr, "classname", "player"); pSpot; pSpot = UTIL_FindEntityByString(pSpot, "classname", "player"))
;
for (pSpot = UTIL_FindEntityByString(nullptr, "classname", "bodyque"); pSpot; pSpot = UTIL_FindEntityByString(pSpot, "classname", "bodyque"))
;
}
end = loopCounter.GetCurTime();
CONSOLE_ECHO(" Time in new search loop %.4f\n", (end - start) * 1000.0);
}
void SV_PrintEntities_f()
{
for (int i = 0; i < stringsHashTable.Count(); ++i)
{
hash_item_t *item = &stringsHashTable[i];
if (item->pev)
{
UTIL_LogPrintf("Print: %s %i %p\n", STRING(stringsHashTable[i].pev->classname), ENTINDEX(ENT(item->pev)), item->pev);
}
for (item = stringsHashTable[i].next; item; item = item->next)
{
UTIL_LogPrintf("Print: %s %i %p\n", STRING(item->pev->classname), ENTINDEX(ENT(item->pev)), item->pev);
}
}
}

View File

@ -28,13 +28,14 @@
#pragma once
class CNullEntity: public CBaseEntity {
public:
virtual void Spawn() = 0;
};
void InstallCommands();
class CBaseDMStart: public CPointEntity {
public:
virtual void KeyValue(KeyValueData *pkvd) = 0;
virtual BOOL IsTriggered(CBaseEntity *pEntity) = 0;
};
EXT_FUNC void SV_Continue_f();
EXT_FUNC void SV_CareerMatchLimit_f();
EXT_FUNC void SV_CareerAddTask_f();
EXT_FUNC void SV_Career_EndRound_f();
EXT_FUNC void SV_Career_Restart_f();
EXT_FUNC void SV_Tutor_Toggle_f();
EXT_FUNC void SV_LoopPerformance_f();
EXT_FUNC void SV_PrintEntities_f();

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +1,36 @@
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef H_AI_H
#define H_AI_H
#ifdef _WIN32
#pragma once
#endif
#define NUM_LATERAL_CHECKS 13 // how many checks are made on each side of a monster looking for lateral cover
#define NUM_LATERAL_LOS_CHECKS 6 // how many checks are made on each side of a monster looking for lateral cover
BOOL FBoxVisible(entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize);
Vector VecCheckToss(entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj);
Vector VecCheckThrow(entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj);
#endif // H_AI_H
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
EXT_FUNC void PlayerBlind(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, float fadeTime, float fadeHold, int alpha, Vector &color);
EXT_FUNC void RadiusFlash_TraceLine_hook(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, Vector &vecSrc, Vector &vecSpot, TraceResult *tr);
void RadiusFlash(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore = 0, int bitsDamageType = 0);
void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);
void RadiusDamage2(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);

View File

@ -5,18 +5,18 @@
*/
#ifndef HOOK_GAMEDLL
DebugOutputLevel outputLevel[ NUM_LEVELS ] =
DebugOutputLevel outputLevel[] =
{
{ "bot", DEBUG_BOT },
{ "career", DEBUG_CAREER },
{ "tutor", DEBUG_TUTOR },
{ "stats", DEBUG_STATS },
{ "bot", DEBUG_BOT },
{ "career", DEBUG_CAREER },
{ "tutor", DEBUG_TUTOR },
{ "stats", DEBUG_STATS },
{ "hostage", DEBUG_HOSTAGE },
{ "all", DEBUG_ALL }
{ "all", DEBUG_ALL },
};
unsigned int theDebugOutputTypes;
static char theDebugBuffer[ DebugBufferSize ];
static char theDebugBuffer[MAX_DEBUG_BUFF_SIZE];
#endif
@ -57,7 +57,7 @@ void UTIL_DPrintf(char *pszMsg, ...)
void PrintDebugFlags()
{
char *tmp;
int remainder = DebugBufferSize;
int remainder = MAX_DEBUG_BUFF_SIZE;
theDebugBuffer[0] = '\0';
tmp = BufPrintf(theDebugBuffer, remainder, "mp_debug:\n");

View File

@ -26,26 +26,18 @@
*
*/
#ifndef DEBUG_H
#define DEBUG_H
#ifdef _WIN32
#pragma once
#endif
const int NUM_LEVELS = 6;
const int DebugBufferSize = 1024;
typedef enum
enum DebugOutputType
{
DEBUG_NONE = 0,
DEBUG_BOT = (1 << 0),
DEBUG_CAREER = (1 << 1),
DEBUG_TUTOR = (1 << 2),
DEBUG_STATS = (1 << 3),
DEBUG_HOSTAGE = (1 << 4),
DEBUG_ALL = 0xFFFFFFFF,
} DebugOutputType;
DEBUG_NONE = 0,
DEBUG_BOT = BIT(0),
DEBUG_CAREER = BIT(1),
DEBUG_TUTOR = BIT(2),
DEBUG_STATS = BIT(3),
DEBUG_HOSTAGE = BIT(4),
DEBUG_ALL = 0xFFFFFFFF,
};
struct DebugOutputLevel
{
@ -53,6 +45,8 @@ struct DebugOutputLevel
DebugOutputType value;
};
const int MAX_DEBUG_BUFF_SIZE = 1024;
bool IsDeveloper();
void UTIL_DPrintf(DebugOutputType outputType, char *pszMsg, ...);
void UTIL_DPrintf(char *pszMsg, ...);
@ -67,5 +61,3 @@ void UTIL_CareerDPrintf(char *pszMsg, ...);
void UTIL_TutorDPrintf(char *pszMsg, ...);
void UTIL_StatsDPrintf(char *pszMsg, ...);
void UTIL_HostageDPrintf(char *pszMsg, ...);
#endif // DEBUG_H

View File

@ -26,11 +26,10 @@
*
*/
#ifndef DECALS_H
#define DECALS_H
#ifdef _WIN32
#pragma once
#endif
#define DEFINE_DECAL(name)\
{ name, 0 }
enum decal_e
{
@ -69,13 +68,14 @@ enum decal_e
DECAL_BIGSHOT5,
DECAL_SPIT1,
DECAL_SPIT2,
DECAL_BPROOF1, // Bulletproof glass decal
DECAL_GARGSTOMP1, // Gargantua stomp crack
DECAL_SMALLSCORCH1, // Small scorch mark
DECAL_SMALLSCORCH2, // Small scorch mark
DECAL_SMALLSCORCH3, // Small scorch mark
DECAL_MOMMABIRTH, // Big momma birth splatter
DECAL_BPROOF1, // Bulletproof glass decal
DECAL_GARGSTOMP1, // Gargantua stomp crack
DECAL_SMALLSCORCH1, // Small scorch mark
DECAL_SMALLSCORCH2, // Small scorch mark
DECAL_SMALLSCORCH3, // Small scorch mark
DECAL_MOMMABIRTH, // Big momma birth splatter
DECAL_MOMMASPLAT,
DECAL_END
};
typedef struct
@ -85,6 +85,4 @@ typedef struct
} DLL_DECALLIST;
extern DLL_DECALLIST gDecals[42];
#endif // DECALS_H
extern DLL_DECALLIST gDecals[DECAL_END];

View File

@ -162,7 +162,9 @@ void CBaseDoor::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseToggle::KeyValue(pkvd);
}
}
// QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK TOGGLE
@ -210,7 +212,7 @@ void CBaseDoor::Spawn()
pev->solid = SOLID_NOT;
// water is silent for now
pev->spawnflags |= SF_DOOR_SILENT;
pev->spawnflags |= SF_DOOR_ACTUALLY_WATER;
}
pev->movetype = MOVETYPE_PUSH;
@ -482,7 +484,7 @@ int CBaseDoor::DoorActivate()
else // door should open
{
// give health if player opened the door (medikit)
if (m_hActivator != NULL && m_hActivator->IsPlayer())
if (m_hActivator && m_hActivator->IsPlayer())
{
// VARS(m_eoActivator)->health += m_bHealthValue;
m_hActivator->TakeHealth(m_bHealthValue, DMG_GENERIC);
@ -510,14 +512,15 @@ void CBaseDoor::DoorGoUp()
// filter them out and leave a client stuck with looping door sounds!
if (!isReversing)
{
if (!(pev->spawnflags & SF_DOOR_SILENT))
// water is silent
if (!(pev->spawnflags & SF_DOOR_ACTUALLY_WATER))
{
if (m_toggle_state != TS_GOING_UP && m_toggle_state != TS_GOING_DOWN)
{
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving), VOL_NORM, ATTN_NORM);
}
if (TheBots != NULL)
if (TheBots)
{
TheBots->OnEvent(EVENT_DOOR, m_hActivator);
}
@ -533,12 +536,12 @@ void CBaseDoor::DoorGoUp()
{
float sign = 1.0;
if (m_hActivator != NULL)
if (m_hActivator)
{
pevActivator = m_hActivator->pev;
// Y axis rotation, move away from the player
if (!(pev->spawnflags & SF_DOOR_ONEWAY) && pev->movedir.y)
if (!(pev->spawnflags & SF_DOOR_ROTATE_ONEWAY) && pev->movedir.y)
{
Vector2D toActivator = pevActivator->origin.Make2D();
@ -613,7 +616,8 @@ void CBaseDoor::DoorGoUp()
// The door has reached the "up" position. Either go back down, or wait for another activation.
void CBaseDoor::DoorHitTop()
{
if (!(pev->spawnflags & SF_DOOR_SILENT))
// water is silent
if (!(pev->spawnflags & SF_DOOR_ACTUALLY_WATER))
{
STOP_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving));
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), VOL_NORM, ATTN_NORM);
@ -660,14 +664,15 @@ void CBaseDoor::DoorGoDown()
if (!isReversing)
{
if (!(pev->spawnflags & SF_DOOR_SILENT))
// water is silent
if (!(pev->spawnflags & SF_DOOR_ACTUALLY_WATER))
{
if (m_toggle_state != TS_GOING_UP && m_toggle_state != TS_GOING_DOWN)
{
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving), VOL_NORM, ATTN_NORM);
}
if (TheBots != NULL)
if (TheBots)
{
TheBots->OnEvent(EVENT_DOOR, m_hActivator);
}
@ -694,7 +699,8 @@ void CBaseDoor::DoorGoDown()
// The door has reached the "down" position. Back to quiescence.
void CBaseDoor::DoorHitBottom()
{
if (!(pev->spawnflags & SF_DOOR_SILENT))
// water is silent
if (!(pev->spawnflags & SF_DOOR_ACTUALLY_WATER))
{
STOP_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving));
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), VOL_NORM, ATTN_NORM);
@ -727,8 +733,8 @@ void CBaseDoor::DoorHitBottom()
void CBaseDoor::Blocked(CBaseEntity *pOther)
{
edict_t *pentTarget = NULL;
CBaseDoor *pDoor = NULL;
edict_t *pentTarget = nullptr;
CBaseDoor *pDoor = nullptr;
const float checkBlockedInterval = 0.25f;
// Hurt the blocker a little.
@ -795,7 +801,7 @@ void CBaseDoor::Blocked(CBaseEntity *pOther)
}
}
if (!(pev->spawnflags & SF_DOOR_SILENT))
if (!(pev->spawnflags & SF_DOOR_ACTUALLY_WATER))
{
STOP_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving));
}

View File

@ -26,28 +26,18 @@
*
*/
#ifndef DOORS_H
#define DOORS_H
#ifdef _WIN32
#pragma once
#endif
#define DOOR_SENTENCEWAIT 6
#define DOOR_SOUNDWAIT 3
#define BUTTON_SOUNDWAIT 0.5
const float DOOR_SENTENCEWAIT = 6.0f;
const float DOOR_SOUNDWAIT = 3.0f;
const float BUTTON_SOUNDWAIT = 0.5f;
#define SF_DOOR_ROTATE_Y 0
#define SF_DOOR_START_OPEN 1
#define SF_DOOR_ROTATE_BACKWARDS 2
#define SF_DOOR_PASSABLE 8
#define SF_DOOR_ONEWAY 16
#define SF_DOOR_NO_AUTO_RETURN 32
#define SF_DOOR_ROTATE_Z 64
#define SF_DOOR_ROTATE_X 128
#define SF_DOOR_USE_ONLY 256 // door must be opened by player's use button.
#define SF_DOOR_NOMONSTERS 512 // Monster can't open
#define SF_DOOR_TOUCH_ONLY_CLIENTS 1024 // Only clients can touch
#define SF_DOOR_SILENT 0x80000000
#define SF_DOOR_START_OPEN BIT(0)
#define SF_DOOR_PASSABLE BIT(3)
#define SF_DOOR_NO_AUTO_RETURN BIT(5)
#define SF_DOOR_USE_ONLY BIT(8) // Door must be opened by player's use button.
#define SF_DOOR_TOUCH_ONLY_CLIENTS BIT(10) // Only clients can touch
#define SF_DOOR_ACTUALLY_WATER BIT(31) // This bit marks that func_door are actually func_water
class CBaseDoor: public CBaseToggle
{
@ -60,7 +50,7 @@ public:
virtual int Restore(CRestore &restore);
virtual int ObjectCaps()
{
if (pev->spawnflags & SF_ITEM_USE_ONLY)
if (pev->spawnflags & SF_DOOR_USE_ONLY)
return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE;
else
return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION);
@ -82,7 +72,6 @@ public:
public:
byte m_bHealthValue; // some doors are medi-kit doors, they give players health
byte m_bMoveSnd; // sound a door makes while moving
byte m_bStopSnd; // sound a door makes when it stops
@ -96,6 +85,11 @@ public:
float m_lastBlockedTimestamp;
};
#define SF_DOOR_ROTATE_BACKWARDS BIT(1)
#define SF_DOOR_ROTATE_ONEWAY BIT(4)
#define SF_DOOR_ROTATE_Z BIT(6)
#define SF_DOOR_ROTATE_X BIT(7)
class CRotDoor: public CBaseDoor
{
public:
@ -122,5 +116,3 @@ public:
};
void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton);
#endif // DOORS_H

View File

@ -136,7 +136,9 @@ void CBubbling::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseEntity::KeyValue(pkvd);
}
}
void CBubbling::FizzThink()
@ -207,7 +209,7 @@ const Vector &CBeam::GetEndPos()
}
edict_t *pent = INDEXENT(GetEndEntity());
if (pent != NULL)
if (pent)
{
return pent->v.origin;
}
@ -218,7 +220,7 @@ const Vector &CBeam::GetEndPos()
CBeam *CBeam::BeamCreate(const char *pSpriteName, int width)
{
// Create a new entity with CBeam private data
CBeam *pBeam = GetClassPtr<CCSBeam>((CBeam *)NULL);
CBeam *pBeam = GetClassPtr<CCSBeam>((CBeam *)nullptr);
MAKE_STRING_CLASS("beam", pBeam->pev);
pBeam->BeamInit(pSpriteName, width);
@ -321,10 +323,10 @@ CBaseEntity *CBeam::RandomTargetname(const char *szName)
{
int total = 0;
CBaseEntity *pEntity = NULL;
CBaseEntity *pNewEntity = NULL;
CBaseEntity *pEntity = nullptr;
CBaseEntity *pNewEntity = nullptr;
while ((pNewEntity = UTIL_FindEntityByTargetname(pNewEntity, szName)) != NULL)
while ((pNewEntity = UTIL_FindEntityByTargetname(pNewEntity, szName)))
{
total++;
@ -475,7 +477,9 @@ void CLightning::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBeam::KeyValue(pkvd);
}
}
void CLightning::ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
@ -557,7 +561,7 @@ void CLightning::StrikeThink()
else
{
CBaseEntity *pStart = RandomTargetname(STRING(m_iszStartEntity));
if (pStart != NULL)
if (pStart)
RandomPoint(pStart->pev->origin);
else
ALERT(at_console, "env_beam: unknown entity \"%s\"\n", STRING(m_iszStartEntity));
@ -568,7 +572,7 @@ void CLightning::StrikeThink()
CBaseEntity *pStart = RandomTargetname(STRING(m_iszStartEntity));
CBaseEntity *pEnd = RandomTargetname(STRING(m_iszEndEntity));
if (pStart != NULL && pEnd != NULL)
if (pStart && pEnd)
{
if (IsPointEntity(pStart) || IsPointEntity(pEnd))
{
@ -642,7 +646,7 @@ void CLightning::StrikeThink()
if (pev->dmg > 0)
{
TraceResult tr;
UTIL_TraceLine(pStart->pev->origin, pEnd->pev->origin, dont_ignore_monsters, NULL, &tr);
UTIL_TraceLine(pStart->pev->origin, pEnd->pev->origin, dont_ignore_monsters, nullptr, &tr);
BeamDamageInstant(&tr, pev->dmg);
}
}
@ -652,11 +656,11 @@ void CBeam::BeamDamage(TraceResult *ptr)
{
RelinkBeam();
if (ptr->flFraction != 1.0f && ptr->pHit != NULL)
if (ptr->flFraction != 1.0f && ptr->pHit)
{
CBaseEntity *pHit = CBaseEntity::Instance(ptr->pHit);
if (pHit != NULL)
if (pHit)
{
ClearMultiDamage();
pHit->TraceAttack(pev, pev->dmg * (gpGlobals->time - pev->dmgtime), (ptr->vecEndPos - pev->origin).Normalize(), ptr, DMG_ENERGYBEAM);
@ -680,7 +684,7 @@ void CLightning::DamageThink()
pev->nextthink = gpGlobals->time + 0.1f;
TraceResult tr;
UTIL_TraceLine(GetStartPos(), GetEndPos(), dont_ignore_monsters, NULL, &tr);
UTIL_TraceLine(GetStartPos(), GetEndPos(), dont_ignore_monsters, nullptr, &tr);
BeamDamage(&tr);
}
@ -778,8 +782,8 @@ void CLightning::BeamUpdateVars()
int beamType;
int pointStart, pointEnd;
edict_t *pStart = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszStartEntity));
edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszEndEntity));
edict_t *pStart = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(m_iszStartEntity));
edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(m_iszEndEntity));
pointStart = IsPointEntity(CBaseEntity::Instance(pStart));
pointEnd = IsPointEntity(CBaseEntity::Instance(pEnd));
@ -869,7 +873,7 @@ void CLaser::Spawn()
if (!m_pSprite && m_iszSpriteName)
m_pSprite = CSprite::SpriteCreate(STRING(m_iszSpriteName), pev->origin, TRUE);
else
m_pSprite = NULL;
m_pSprite = nullptr;
if (m_pSprite)
m_pSprite->SetTransparency(kRenderGlow, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, pev->renderamt, pev->renderfx);
@ -933,7 +937,9 @@ void CLaser::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBeam::KeyValue(pkvd);
}
}
int CLaser::IsOn()
@ -1000,7 +1006,7 @@ void CLaser::StrikeThink()
m_firePosition = pEnd->pev->origin;
TraceResult tr;
UTIL_TraceLine(pev->origin, m_firePosition, dont_ignore_monsters, NULL, &tr);
UTIL_TraceLine(pev->origin, m_firePosition, dont_ignore_monsters, nullptr, &tr);
FireAtPoint(tr);
pev->nextthink = gpGlobals->time + 0.1f;
}
@ -1160,7 +1166,7 @@ void CSprite::SpriteInit(const char *pSpriteName, const Vector &origin)
CSprite *CSprite::SpriteCreate(const char *pSpriteName, const Vector &origin, BOOL animate)
{
CSprite *pSprite = GetClassPtr<CCSSprite>((CSprite *)NULL);
CSprite *pSprite = GetClassPtr<CCSSprite>((CSprite *)nullptr);
pSprite->SpriteInit(pSpriteName, origin);
MAKE_STRING_CLASS("env_sprite", pSprite->pev);
@ -1310,7 +1316,9 @@ void CGibShooter::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseDelay::KeyValue(pkvd);
}
}
void CGibShooter::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
@ -1343,9 +1351,9 @@ void CGibShooter::Spawn()
CGib *CGibShooter::CreateGib()
{
if (CVAR_GET_FLOAT("violence_hgibs") == 0)
return NULL;
return nullptr;
CGib *pGib = GetClassPtr<CCSGib>((CGib *)NULL);
CGib *pGib = GetClassPtr<CCSGib>((CGib *)nullptr);
pGib->Spawn("models/hgibs.mdl");
pGib->m_bloodColor = BLOOD_COLOR_RED;
@ -1463,7 +1471,9 @@ void CEnvShooter::KeyValue(KeyValueData *pkvd)
}
}
else
{
CGibShooter::KeyValue(pkvd);
}
}
void CEnvShooter::Precache()
@ -1474,7 +1484,7 @@ void CEnvShooter::Precache()
CGib *CEnvShooter::CreateGib()
{
CGib *pGib = GetClassPtr<CCSGib>((CGib *)NULL);
CGib *pGib = GetClassPtr<CCSGib>((CGib *)nullptr);
pGib->Spawn(STRING(pev->model));
@ -1606,7 +1616,9 @@ void CBlood::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CPointEntity::KeyValue(pkvd);
}
}
Vector CBlood::Direction()
@ -1628,7 +1640,7 @@ Vector CBlood::BloodPosition(CBaseEntity *pActivator)
else
pPlayer = INDEXENT(1);
if (pPlayer != NULL)
if (pPlayer)
{
return (pPlayer->v.origin + pPlayer->v.view_ofs) + Vector(RANDOM_FLOAT(-10, 10), RANDOM_FLOAT(-10, 10), RANDOM_FLOAT(-10, 10));
}
@ -1650,7 +1662,7 @@ void CBlood::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType
Vector start = BloodPosition(pActivator);
TraceResult tr;
UTIL_TraceLine(start, start + forward * BloodAmount() * 2, ignore_monsters, NULL, &tr);
UTIL_TraceLine(start, start + forward * BloodAmount() * 2, ignore_monsters, nullptr, &tr);
if (tr.flFraction != 1.0f)
{
@ -1695,7 +1707,9 @@ void CShake::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CPointEntity::KeyValue(pkvd);
}
}
void CShake::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
@ -1726,7 +1740,9 @@ void CFade::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CPointEntity::KeyValue(pkvd);
}
}
void CFade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
@ -1813,12 +1829,14 @@ void CMessage::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CPointEntity::KeyValue(pkvd);
}
}
void CMessage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
CBaseEntity *pPlayer = NULL;
CBaseEntity *pPlayer = nullptr;
if (pev->spawnflags & SF_MESSAGE_ALL)
UTIL_ShowMessageAll(STRING(pev->message));
@ -1831,7 +1849,7 @@ void CMessage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
pPlayer = CBaseEntity::Instance(INDEXENT(1));
}
if (pPlayer != NULL)
if (pPlayer)
UTIL_ShowMessage(STRING(pev->message), pPlayer);
}

View File

@ -26,47 +26,11 @@
*
*/
#ifndef EFFECTS_H
#define EFFECTS_H
#ifdef _WIN32
#pragma once
#endif
#define SF_BEAM_STARTON 0x0001
#define SF_BEAM_TOGGLE 0x0002
#define SF_BEAM_RANDOM 0x0004
#define SF_BEAM_RING 0x0008
#define SF_BEAM_SPARKSTART 0x0010
#define SF_BEAM_SPARKEND 0x0020
#define SF_BEAM_DECALS 0x0040
#define SF_BEAM_SHADEIN 0x0080
#define SF_BEAM_SHADEOUT 0x0100
#define SF_BEAM_TEMPORARY 0x8000
#define SF_GIBSHOOTER_REPEATABLE 1
#define SF_FUNNEL_REVERSE 1
#define SF_BUBBLES_STARTOFF 0x0001
#define SF_BLOOD_RANDOM 0x0001
#define SF_BLOOD_STREAM 0x0002
#define SF_BLOOD_PLAYER 0x0004
#define SF_BLOOD_DECAL 0x0008
#define SF_SHAKE_EVERYONE 0x0001
#define SF_SHAKE_DISRUPT 0x0002
#define SF_SHAKE_INAIR 0x0004
#define SF_FADE_IN 0x0001
#define SF_FADE_MODULATE 0x0002
#define SF_FADE_ONLYONE 0x0004
#define SF_SPRITE_STARTON 0x0001
#define SF_SPRITE_ONCE 0x0002
#define SF_SPRITE_TEMPORARY 0x8000
#define SF_MESSAGE_ONCE 0x0001 // Fade in, not out
#define SF_MESSAGE_ALL 0x0002 // Send to all clients
#define SF_SPRITE_STARTON BIT(0)
#define SF_SPRITE_ONCE BIT(1)
#define SF_SPRITE_TEMPORARY BIT(15)
class CSprite: public CPointEntity
{
@ -96,7 +60,7 @@ public:
void SetAttachment(edict_t *pEntity, int attachment)
{
if (pEntity != NULL)
if (pEntity)
{
pev->skin = ENTINDEX(pEntity);
pev->body = attachment;
@ -142,6 +106,17 @@ private:
float m_maxFrame;
};
#define SF_BEAM_STARTON BIT(0)
#define SF_BEAM_TOGGLE BIT(1)
#define SF_BEAM_RANDOM BIT(2)
#define SF_BEAM_RING BIT(3)
#define SF_BEAM_SPARKSTART BIT(4)
#define SF_BEAM_SPARKEND BIT(5)
#define SF_BEAM_DECALS BIT(6)
#define SF_BEAM_SHADEIN BIT(7)
#define SF_BEAM_SHADEOUT BIT(8)
#define SF_BEAM_TEMPORARY BIT(15)
class CBeam: public CBaseEntity
{
public:
@ -243,6 +218,8 @@ public:
Vector m_firePosition;
};
#define SF_BUBBLES_STARTOFF BIT(0)
class CBubbling: public CBaseEntity
{
public:
@ -341,6 +318,8 @@ public:
bool m_bSetModel;
};
#define SF_GIBSHOOTER_REPEATABLE BIT(0) // Allows a gibshooter to be refired
class CGibShooter: public CBaseDelay
{
public:
@ -376,7 +355,7 @@ public:
virtual CGib *CreateGib();
};
#define MAX_BEAM 24
const int MAX_BEAM = 24;
class CTestEffect: public CBaseDelay
{
@ -392,12 +371,17 @@ public:
int m_iLoop;
int m_iBeam;
CBeam *m_pBeam[ MAX_BEAM ];
CBeam *m_pBeam[MAX_BEAM];
float m_flBeamTime[ MAX_BEAM ];
float m_flBeamTime[MAX_BEAM];
float m_flStartTime;
};
#define SF_BLOOD_RANDOM BIT(0)
#define SF_BLOOD_STREAM BIT(1)
#define SF_BLOOD_PLAYER BIT(2)
#define SF_BLOOD_DECAL BIT(3)
class CBlood: public CPointEntity
{
public:
@ -417,6 +401,10 @@ public:
Vector BloodPosition(CBaseEntity *pActivator);
};
#define SF_SHAKE_EVERYONE BIT(0) // Don't check radius
#define SF_SHAKE_DISRUPT BIT(1) // Disrupt controls
#define SF_SHAKE_INAIR BIT(2) // Shake players in air
class CShake: public CPointEntity
{
public:
@ -436,6 +424,10 @@ public:
void SetRadius(float radius) { pev->dmg = radius; }
};
#define SF_FADE_IN BIT(0) // Fade in, not out
#define SF_FADE_MODULATE BIT(1) // Modulate, don't blend
#define SF_FADE_ONLYONE BIT(2)
class CFade: public CPointEntity
{
public:
@ -451,6 +443,9 @@ public:
void SetHoldTime(float hold) { pev->dmg_save = hold; }
};
#define SF_MESSAGE_ONCE BIT(0) // Fade in, not out
#define SF_MESSAGE_ALL BIT(1) // Send to all clients
class CMessage: public CPointEntity
{
public:
@ -460,6 +455,8 @@ public:
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
};
#define SF_FUNNEL_REVERSE BIT(0) // Funnel effect repels particles instead of attracting them
class CEnvFunnel: public CBaseDelay
{
public:
@ -491,5 +488,3 @@ public:
};
int IsPointEntity(CBaseEntity *pEnt);
#endif // EFFECTS_H

226
regamedll/dlls/ehandle.h Normal file
View File

@ -0,0 +1,226 @@
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
// Safe way to point to CBaseEntities who may die between frames.
template <typename T = CBaseEntity>
class EntityHandle
{
public:
EntityHandle() : m_edict(nullptr), m_serialnumber(0) {}
EntityHandle(const EntityHandle<T> &other);
EntityHandle(const T *pEntity);
EntityHandle(const edict_t *pEdict);
// cast to base class
// NOTE: this is a unsafe method
template <typename R>
R *Get() const;
edict_t *Get() const;
edict_t *Set(edict_t *pEdict);
bool IsValid() const;
int GetSerialNumber() const;
bool operator==(T *pEntity) const;
operator bool() const;
operator T *() const;
T *operator=(T *pEntity);
T *operator->();
// Copy the ehandle.
EntityHandle<T>& operator=(const EntityHandle<T> &other);
private:
edict_t *m_edict;
int m_serialnumber;
};
// Short alias
using EHandle = EntityHandle<>;
using EHANDLE = EHandle;
// Inlines
template <typename T>
inline bool FNullEnt(EntityHandle<T> &hent)
{
return (!hent || FNullEnt(OFFSET(hent.Get())));
}
// Copy constructor
template <typename T>
EntityHandle<T>::EntityHandle(const EntityHandle<T> &other)
{
m_edict = other.m_edict;
m_serialnumber = other.m_serialnumber;
}
template <typename T>
EntityHandle<T>::EntityHandle(const T *pEntity)
{
if (pEntity)
{
Set(ENT(pEntity->pev));
}
else
{
m_edict = nullptr;
m_serialnumber = 0;
}
}
template <typename T>
EntityHandle<T>::EntityHandle(const edict_t *pEdict)
{
Set(const_cast<edict_t *>(pEdict));
}
template <typename T>
template <typename R>
inline R *EntityHandle<T>::Get() const
{
return GET_PRIVATE<R>(Get());
}
template <typename T>
inline edict_t *EntityHandle<T>::Get() const
{
if (!m_edict || m_edict->serialnumber != m_serialnumber || m_edict->free)
{
return nullptr;
}
return m_edict;
}
template <typename T>
inline edict_t *EntityHandle<T>::Set(edict_t *pEdict)
{
m_edict = pEdict;
if (pEdict)
{
m_serialnumber = pEdict->serialnumber;
}
return pEdict;
}
// Returns whether this handle is valid.
template <typename T>
inline bool EntityHandle<T>::IsValid() const
{
edict_t *pEdict = Get();
if (!pEdict)
{
return false;
}
CBaseEntity *pEntity = GET_PRIVATE<CBaseEntity>(pEdict);
if (!pEntity)
{
return false;
}
return true;
}
// CBaseEntity serial number.
// Used to determine if the entity is still valid.
template <typename T>
inline int EntityHandle<T>::GetSerialNumber() const
{
return m_serialnumber;
}
template <typename T>
inline bool EntityHandle<T>::operator==(T *pEntity) const
{
assert(("EntityHandle<T>::operator==: got a nullptr pointer!", pEntity != nullptr));
if (m_serialnumber != pEntity->edict()->serialnumber)
{
return false;
}
return m_edict == pEntity->edict();
}
template <typename T>
inline EntityHandle<T>::operator bool() const
{
return Get() != nullptr;
}
// Gets the Entity this handle refers to.
// Returns null if invalid.
template <typename T>
inline EntityHandle<T>::operator T *() const
{
return GET_PRIVATE<T>(Get());
}
// Assigns the given entity to this handle.
template <typename T>
inline T *EntityHandle<T>::operator=(T *pEntity)
{
if (pEntity)
{
Set(ENT(pEntity->pev));
}
else
{
m_edict = nullptr;
m_serialnumber = 0;
}
return static_cast<T *>(pEntity);
}
template <typename T>
inline T *EntityHandle<T>::operator->()
{
edict_t *pEdict = Get();
assert(("EntityHandle<T>::operator->: pointer is nullptr!", pEdict != nullptr));
T *pEntity = GET_PRIVATE<T>(pEdict);
assert(("EntityHandle<T>::operator->: pvPrivateData is nullptr!", pEntity != nullptr));
return pEntity;
}
// Makes this handle refer to the same entity as the given handle.
template <typename T>
inline EntityHandle<T>& EntityHandle<T>::operator=(const EntityHandle<T> &other)
{
m_edict = other.m_edict;
m_serialnumber = other.m_serialnumber;
return (*this);
}

View File

@ -26,161 +26,161 @@
*
*/
#ifndef ENGINECALLBACK_H
#define ENGINECALLBACK_H
#ifdef _WIN32
#pragma once
#endif
#include "event_flags.h"
// Must be provided by user of this code
extern enginefuncs_t g_engfuncs;
#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId)
#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel)
#define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound)
#define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric)
#define SET_MODEL (*g_engfuncs.pfnSetModel)
#define MODEL_INDEX (*g_engfuncs.pfnModelIndex)
#define MODEL_FRAMES (*g_engfuncs.pfnModelFrames)
#define SET_SIZE (*g_engfuncs.pfnSetSize)
#define CHANGE_LEVEL (*g_engfuncs.pfnChangeLevel)
#define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms)
#define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms)
#define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw)
#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles)
#define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin)
#define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw)
#define CHANGE_PITCH (*g_engfuncs.pfnChangePitch)
#define MAKE_VECTORS (*g_engfuncs.pfnMakeVectors)
#define CREATE_ENTITY (*g_engfuncs.pfnCreateEntity)
#define REMOVE_ENTITY (*g_engfuncs.pfnRemoveEntity)
#define CREATE_NAMED_ENTITY (*g_engfuncs.pfnCreateNamedEntity)
#define MAKE_STATIC (*g_engfuncs.pfnMakeStatic)
#define ENT_IS_ON_FLOOR (*g_engfuncs.pfnEntIsOnFloor)
#define DROP_TO_FLOOR (*g_engfuncs.pfnDropToFloor)
#define WALK_MOVE (*g_engfuncs.pfnWalkMove)
#define SET_ORIGIN (*g_engfuncs.pfnSetOrigin)
#define EMIT_SOUND_DYN2 (*g_engfuncs.pfnEmitSound)
#define BUILD_SOUND_MSG (*g_engfuncs.pfnBuildSoundMsg)
#define TRACE_LINE (*g_engfuncs.pfnTraceLine)
#define TRACE_TOSS (*g_engfuncs.pfnTraceToss)
#define TRACE_MONSTER_HULL (*g_engfuncs.pfnTraceMonsterHull)
#define TRACE_HULL (*g_engfuncs.pfnTraceHull)
#define TRACE_MODEL (*g_engfuncs.pfnTraceModel)
#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector)
#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand)
#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute)
#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand)
#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect)
#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle)
#define DECAL_INDEX (*g_engfuncs.pfnDecalIndex)
#define POINT_CONTENTS (*g_engfuncs.pfnPointContents)
#define CRC32_INIT (*g_engfuncs.pfnCRC32_Init)
#define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC32_ProcessBuffer)
#define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC32_ProcessByte)
#define CRC32_FINAL (*g_engfuncs.pfnCRC32_Final)
#define RANDOM_LONG (*g_engfuncs.pfnRandomLong)
#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat)
#define ADD_SERVER_COMMAND (*g_engfuncs.pfnAddServerCommand)
#define SET_CLIENT_LISTENING (*g_engfuncs.pfnVoice_SetClientListening)
#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId)
#define GET_FILE_SIZE (*g_engfuncs.pfnGetFileSize)
#define GET_APPROX_WAVE_PLAY_LEN (*g_engfuncs.pfnGetApproxWavePlayLen)
#define IS_CAREER_MATCH (*g_engfuncs.pfnIsCareerMatch)
#define GET_LOCALIZED_STRING_LENGTH (*g_engfuncs.pfnGetLocalizedStringLength)
// The actual engine callbacks
#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId)
#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel)
#define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound)
#define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric)
#define SET_MODEL (*g_engfuncs.pfnSetModel)
#define MODEL_INDEX (*g_engfuncs.pfnModelIndex)
#define MODEL_FRAMES (*g_engfuncs.pfnModelFrames)
#define SET_SIZE (*g_engfuncs.pfnSetSize)
#define CHANGE_LEVEL (*g_engfuncs.pfnChangeLevel)
#define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms)
#define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms)
#define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw)
#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles)
#define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin)
#define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw)
#define CHANGE_PITCH (*g_engfuncs.pfnChangePitch)
#define MAKE_VECTORS (*g_engfuncs.pfnMakeVectors)
#define CREATE_ENTITY (*g_engfuncs.pfnCreateEntity)
#define REMOVE_ENTITY (*g_engfuncs.pfnRemoveEntity)
#define CREATE_NAMED_ENTITY (*g_engfuncs.pfnCreateNamedEntity)
#define MAKE_STATIC (*g_engfuncs.pfnMakeStatic)
#define ENT_IS_ON_FLOOR (*g_engfuncs.pfnEntIsOnFloor)
#define DROP_TO_FLOOR (*g_engfuncs.pfnDropToFloor)
#define WALK_MOVE (*g_engfuncs.pfnWalkMove)
#define SET_ORIGIN (*g_engfuncs.pfnSetOrigin)
#define EMIT_SOUND_DYN2 (*g_engfuncs.pfnEmitSound)
#define BUILD_SOUND_MSG (*g_engfuncs.pfnBuildSoundMsg)
#define TRACE_LINE (*g_engfuncs.pfnTraceLine)
#define TRACE_TOSS (*g_engfuncs.pfnTraceToss)
#define TRACE_MONSTER_HULL (*g_engfuncs.pfnTraceMonsterHull)
#define TRACE_HULL (*g_engfuncs.pfnTraceHull)
#define TRACE_MODEL (*g_engfuncs.pfnTraceModel)
#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector)
#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand)
#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute)
#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand)
#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect)
#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle)
#define DECAL_INDEX (*g_engfuncs.pfnDecalIndex)
#define POINT_CONTENTS (*g_engfuncs.pfnPointContents)
#define CRC32_INIT (*g_engfuncs.pfnCRC32_Init)
#define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC32_ProcessBuffer)
#define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC32_ProcessByte)
#define CRC32_FINAL (*g_engfuncs.pfnCRC32_Final)
#define RANDOM_LONG (*g_engfuncs.pfnRandomLong)
#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat)
#define ADD_SERVER_COMMAND (*g_engfuncs.pfnAddServerCommand)
#define SET_CLIENT_LISTENING (*g_engfuncs.pfnVoice_SetClientListening)
#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId)
#define GET_FILE_SIZE (*g_engfuncs.pfnGetFileSize)
#define GET_APPROX_WAVE_PLAY_LEN (*g_engfuncs.pfnGetApproxWavePlayLen)
#define IS_CAREER_MATCH (*g_engfuncs.pfnIsCareerMatch)
#define GET_LOCALIZED_STRING_LENGTH (*g_engfuncs.pfnGetLocalizedStringLength)
#define REGISTER_TUTOR_MESSAGE_SHOWN (*g_engfuncs.pfnRegisterTutorMessageShown)
#define GET_TIMES_TUTOR_MESSAGE_SHOWN (*g_engfuncs.pfnGetTimesTutorMessageShown)
#define ENG_CHECK_PARM (*g_engfuncs.pfnEngCheckParm)
#define ENG_CHECK_PARM (*g_engfuncs.pfnEngCheckParm)
inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float *pOrigin = NULL, edict_t *ed = NULL)
inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float *pOrigin = nullptr, edict_t *ed = nullptr)
{
(*g_engfuncs.pfnMessageBegin)(msg_dest,msg_type,pOrigin,ed);
(*g_engfuncs.pfnMessageBegin)(msg_dest, msg_type, pOrigin, ed);
}
inline void *GET_PRIVATE(edict_t *pent)
template <typename T = void>
inline T *GET_PRIVATE(edict_t *pEdict)
{
if (pent)
return pent->pvPrivateData;
return NULL;
if (pEdict)
{
return static_cast<T *>(pEdict->pvPrivateData);
}
return nullptr;
}
#define MESSAGE_END (*g_engfuncs.pfnMessageEnd)
#define WRITE_BYTE (*g_engfuncs.pfnWriteByte)
#define WRITE_CHAR (*g_engfuncs.pfnWriteChar)
#define WRITE_SHORT (*g_engfuncs.pfnWriteShort)
#define WRITE_LONG (*g_engfuncs.pfnWriteLong)
#define WRITE_ANGLE (*g_engfuncs.pfnWriteAngle)
#define WRITE_COORD (*g_engfuncs.pfnWriteCoord)
#define WRITE_STRING (*g_engfuncs.pfnWriteString)
#define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity)
#define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister)
#define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat)
#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString)
#define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat)
#define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString)
#define CVAR_GET_POINTER (*g_engfuncs.pfnCVarGetPointer)
#define ALERT (*g_engfuncs.pfnAlertMessage)
#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf)
#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData)
#define FREE_PRIVATE (*g_engfuncs.pfnFreeEntPrivateData)
//#define STRING (*g_engfuncs.pfnSzFromIndex)
#define ALLOC_STRING (*g_engfuncs.pfnAllocString)
#define MESSAGE_END (*g_engfuncs.pfnMessageEnd)
#define WRITE_BYTE (*g_engfuncs.pfnWriteByte)
#define WRITE_CHAR (*g_engfuncs.pfnWriteChar)
#define WRITE_SHORT (*g_engfuncs.pfnWriteShort)
#define WRITE_LONG (*g_engfuncs.pfnWriteLong)
#define WRITE_ANGLE (*g_engfuncs.pfnWriteAngle)
#define WRITE_COORD (*g_engfuncs.pfnWriteCoord)
#define WRITE_STRING (*g_engfuncs.pfnWriteString)
#define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity)
#define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister)
#define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat)
#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString)
#define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat)
#define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString)
#define CVAR_GET_POINTER (*g_engfuncs.pfnCVarGetPointer)
#define ALERT (*g_engfuncs.pfnAlertMessage)
#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf)
#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData)
#define FREE_PRIVATE (*g_engfuncs.pfnFreeEntPrivateData)
//#define STRING (*g_engfuncs.pfnSzFromIndex)
#define ALLOC_STRING (*g_engfuncs.pfnAllocString)
#define FIND_ENTITY_BY_STRING (*g_engfuncs.pfnFindEntityByString)
#define GETENTITYILLUM (*g_engfuncs.pfnGetEntityIllum)
#define GETENTITYILLUM (*g_engfuncs.pfnGetEntityIllum)
#define FIND_ENTITY_IN_SPHERE (*g_engfuncs.pfnFindEntityInSphere)
#define FIND_CLIENT_IN_PVS (*g_engfuncs.pfnFindClientInPVS)
#define FIND_ENTITY_IN_PVS (*g_engfuncs.pfnEntitiesInPVS)
#define EMIT_AMBIENT_SOUND (*g_engfuncs.pfnEmitAmbientSound)
#define GET_MODEL_PTR (*g_engfuncs.pfnGetModelPtr)
#define REG_USER_MSG (*g_engfuncs.pfnRegUserMsg)
#define GET_BONE_POSITION (*g_engfuncs.pfnGetBonePosition)
#define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName)
#define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction)
#define TRACE_TEXTURE (*g_engfuncs.pfnTraceTexture)
#define CLIENT_PRINTF (*g_engfuncs.pfnClientPrintf)
#define SERVER_PRINT (*g_engfuncs.pfnServerPrint)
#define CMD_ARGS (*g_engfuncs.pfnCmd_Args)
#define CMD_ARGC (*g_engfuncs.pfnCmd_Argc)
#define CMD_ARGV (*g_engfuncs.pfnCmd_Argv)
#define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment)
#define SET_VIEW (*g_engfuncs.pfnSetView)
#define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle)
#define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFileForMe)
#define FREE_FILE (*g_engfuncs.pfnFreeFile)
#define END_SECTION (*g_engfuncs.pfnEndSection)
#define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime)
#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir)
#define SET_CLIENT_MAXSPEED (*g_engfuncs.pfnSetClientMaxspeed)
#define CREATE_FAKE_CLIENT (*g_engfuncs.pfnCreateFakeClient)
#define PLAYER_RUN_MOVE (*g_engfuncs.pfnRunPlayerMove)
#define NUMBER_OF_ENTITIES (*g_engfuncs.pfnNumberOfEntities)
#define GET_INFO_BUFFER (*g_engfuncs.pfnGetInfoKeyBuffer)
#define GET_KEY_VALUE (*g_engfuncs.pfnInfoKeyValue)
#define SET_KEY_VALUE (*g_engfuncs.pfnSetKeyValue)
#define FIND_CLIENT_IN_PVS (*g_engfuncs.pfnFindClientInPVS)
#define FIND_ENTITY_IN_PVS (*g_engfuncs.pfnEntitiesInPVS)
#define EMIT_AMBIENT_SOUND (*g_engfuncs.pfnEmitAmbientSound)
#define GET_MODEL_PTR (*g_engfuncs.pfnGetModelPtr)
#define REG_USER_MSG (*g_engfuncs.pfnRegUserMsg)
#define GET_BONE_POSITION (*g_engfuncs.pfnGetBonePosition)
#define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName)
#define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction)
#define TRACE_TEXTURE (*g_engfuncs.pfnTraceTexture)
#define CLIENT_PRINTF (*g_engfuncs.pfnClientPrintf)
#define SERVER_PRINT (*g_engfuncs.pfnServerPrint)
#define CMD_ARGS (*g_engfuncs.pfnCmd_Args)
#define CMD_ARGC (*g_engfuncs.pfnCmd_Argc)
#define CMD_ARGV (*g_engfuncs.pfnCmd_Argv)
#define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment)
#define SET_VIEW (*g_engfuncs.pfnSetView)
#define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle)
#define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFileForMe)
#define FREE_FILE (*g_engfuncs.pfnFreeFile)
#define END_SECTION (*g_engfuncs.pfnEndSection)
#define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime)
#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir)
#define SET_CLIENT_MAXSPEED (*g_engfuncs.pfnSetClientMaxspeed)
#define CREATE_FAKE_CLIENT (*g_engfuncs.pfnCreateFakeClient)
#define PLAYER_RUN_MOVE (*g_engfuncs.pfnRunPlayerMove)
#define NUMBER_OF_ENTITIES (*g_engfuncs.pfnNumberOfEntities)
#define GET_INFO_BUFFER (*g_engfuncs.pfnGetInfoKeyBuffer)
#define GET_KEY_VALUE (*g_engfuncs.pfnInfoKeyValue)
#define SET_KEY_VALUE (*g_engfuncs.pfnSetKeyValue)
#define SET_CLIENT_KEY_VALUE (*g_engfuncs.pfnSetClientKeyValue)
#define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid)
#define STATIC_DECAL (*g_engfuncs.pfnStaticDecal)
#define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer)
#define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent)
#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent)
#define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS)
#define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS)
#define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid)
#define STATIC_DECAL (*g_engfuncs.pfnStaticDecal)
#define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer)
#define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent)
#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent)
#define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS)
#define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS)
#define ENGINE_CHECK_VISIBILITY (*g_engfuncs.pfnCheckVisibility)
#define DELTA_SET (*g_engfuncs.pfnDeltaSetField)
#define DELTA_UNSET (*g_engfuncs.pfnDeltaUnsetField)
#define DELTA_ADDENCODER (*g_engfuncs.pfnDeltaAddEncoder)
#define DELTA_SET (*g_engfuncs.pfnDeltaSetField)
#define DELTA_UNSET (*g_engfuncs.pfnDeltaUnsetField)
#define DELTA_ADDENCODER (*g_engfuncs.pfnDeltaAddEncoder)
#define ENGINE_CURRENT_PLAYER (*g_engfuncs.pfnGetCurrentPlayer)
#define ENGINE_CANSKIP (*g_engfuncs.pfnCanSkipPlayer)
#define DELTA_FINDFIELD (*g_engfuncs.pfnDeltaFindField)
#define DELTA_SETBYINDEX (*g_engfuncs.pfnDeltaSetFieldByIndex)
#define DELTA_UNSETBYINDEX (*g_engfuncs.pfnDeltaUnsetFieldByIndex)
#define REMOVE_KEY_VALUE (*g_engfuncs.pfnInfo_RemoveKey)
#define ENGINE_CANSKIP (*g_engfuncs.pfnCanSkipPlayer)
#define DELTA_FINDFIELD (*g_engfuncs.pfnDeltaFindField)
#define DELTA_SETBYINDEX (*g_engfuncs.pfnDeltaSetFieldByIndex)
#define DELTA_UNSETBYINDEX (*g_engfuncs.pfnDeltaUnsetFieldByIndex)
#define REMOVE_KEY_VALUE (*g_engfuncs.pfnInfo_RemoveKey)
#define SET_PHYSICS_KEY_VALUE (*g_engfuncs.pfnSetPhysicsKeyValue)
#define ENGINE_GETPHYSINFO (*g_engfuncs.pfnGetPhysicsInfoString)
#define ENGINE_SETGROUPMASK (*g_engfuncs.pfnSetGroupMask)
#define ENGINE_GETPHYSINFO (*g_engfuncs.pfnGetPhysicsInfoString)
#define ENGINE_SETGROUPMASK (*g_engfuncs.pfnSetGroupMask)
#define ENGINE_INSTANCE_BASELINE (*g_engfuncs.pfnCreateInstancedBaseline)
#define ENGINE_FORCE_UNMODIFIED (*g_engfuncs.pfnForceUnmodified)
#define PLAYER_CNX_STATS (*g_engfuncs.pfnGetPlayerStats)
#endif // ENGINECALLBACK_H
#define PLAYER_CNX_STATS (*g_engfuncs.pfnGetPlayerStats)

View File

@ -78,7 +78,9 @@ void CEnvExplosion::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseEntity::KeyValue(pkvd);
}
}
void CEnvExplosion::Spawn()
@ -173,7 +175,7 @@ void CEnvExplosion::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
for (int i = 0; i < sparkCount; ++i)
{
Create("spark_shower", pev->origin, tr.vecPlaneNormal, NULL);
Create("spark_shower", pev->origin, tr.vecPlaneNormal, nullptr);
}
}
}
@ -220,5 +222,5 @@ void ExplosionCreate(const Vector &center, Vector &angles, edict_t *pOwner, int
}
pExplosion->Spawn();
pExplosion->Use(NULL, NULL, USE_TOGGLE, 0);
pExplosion->Use(nullptr, nullptr, USE_TOGGLE, 0);
}

View File

@ -26,18 +26,7 @@
*
*/
#ifndef EXPLODE_H
#define EXPLODE_H
#ifdef _WIN32
#pragma once
#endif
#define SF_ENVEXPLOSION_NODAMAGE (1<<0) // when set, ENV_EXPLOSION will not actually inflict damage
#define SF_ENVEXPLOSION_REPEATABLE (1<<1) // can this entity be refired?
#define SF_ENVEXPLOSION_NOFIREBALL (1<<2) // don't draw the fireball
#define SF_ENVEXPLOSION_NOSMOKE (1<<3) // don't draw the smoke
#define SF_ENVEXPLOSION_NODECAL (1<<4) // don't make a scorch mark
#define SF_ENVEXPLOSION_NOSPARKS (1<<5) // don't make a scorch mark
class CShower: public CBaseEntity
{
@ -48,6 +37,13 @@ public:
virtual void Touch(CBaseEntity *pOther);
};
#define SF_ENVEXPLOSION_NODAMAGE BIT(0) // when set, ENV_EXPLOSION will not actually inflict damage
#define SF_ENVEXPLOSION_REPEATABLE BIT(1) // can this entity be refired?
#define SF_ENVEXPLOSION_NOFIREBALL BIT(2) // don't draw the fireball
#define SF_ENVEXPLOSION_NOSMOKE BIT(3) // don't draw the smoke
#define SF_ENVEXPLOSION_NODECAL BIT(4) // don't make a scorch mark
#define SF_ENVEXPLOSION_NOSPARKS BIT(5) // don't make a scorch mark
class CEnvExplosion: public CBaseMonster
{
public:
@ -68,5 +64,3 @@ public:
};
void ExplosionCreate(const Vector &center, Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage);
#endif // EXPLODE_H

View File

@ -25,8 +25,11 @@
* version.
*
*/
#pragma once
#include "regamedll_const.h"
#undef DLLEXPORT
#ifdef _WIN32
// Attributes to specify an "exported" function, visible from outside the
@ -51,6 +54,8 @@
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
const int MAX_MAPNAME_LENGHT = 32;
// Simplified macro for declaring/defining exported DLL functions. They
// need to be 'extern "C"' so that the C++ compiler enforces parameter
// type-matching, rather than considering routines with mis-matched
@ -105,7 +110,6 @@ typedef struct hudtextparms_s
} hudtextparms_t;
enum USE_TYPE { USE_OFF, USE_ON, USE_SET, USE_TOGGLE };
enum TRAIN_CODE { TRAIN_SAFE, TRAIN_BLOCKING, TRAIN_FOLLOWING };
enum IGNORE_MONSTERS { ignore_monsters = 1, dont_ignore_monsters = 0, missile = 2 };
enum IGNORE_GLASS { ignore_glass = 1, dont_ignore_glass = 0 };
enum { point_hull = 0, human_hull = 1, large_hull = 2, head_hull = 3 };

View File

@ -36,7 +36,7 @@
#include "archtypes.h"
#include "maintypes.h"
#include "regamedll_common.h"
#include "strtools.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
@ -61,15 +61,17 @@
// Header file containing definition of globalvars_t and entvars_t
typedef unsigned int func_t;
typedef unsigned int string_t; // from engine's pr_comp.h;
typedef float vec_t; // needed before including progdefs.h
// Vector class
#include "vector.h"
// Defining it as a (bogus) struct helps enforce type-checking
#define vec3_t Vector
// Shared engine/DLL constants
// QString class
#include "qstring.h"
// Shared engine/DLL constants
#include "const.h"
#include "edict.h"

View File

@ -10,7 +10,7 @@
// be spawned, and still remain fairly flexible
const char *CBreakable::pSpawnObjects[] =
{
NULL,
nullptr,
"item_battery",
"item_healthkit",
"weapon_9mmhandgun",
@ -126,7 +126,6 @@ void CBreakable::KeyValue(KeyValueData *pkvd)
Materials type = (Materials)Q_atoi(pkvd->szValue);
// 0:glass, 1:wood, 2:metal, 3:flesh etc
if (type < 0 || type >= matLastMaterial)
m_Material = matWood;
else
@ -164,9 +163,13 @@ void CBreakable::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "lip"))
{
pkvd->fHandled = TRUE;
}
else
{
CBaseDelay::KeyValue(pkvd);
}
}
LINK_ENTITY_TO_CLASS(func_breakable, CBreakable, CCSBreakable)
@ -318,7 +321,7 @@ void CBreakable::MaterialSoundRandom(edict_t *pEdict, Materials soundMaterial, f
void CBreakable::Precache()
{
const char *pGibName = NULL;
const char *pGibName = nullptr;
switch (m_Material)
{
@ -658,7 +661,7 @@ void CBreakable::Die()
{
Vector vecSpot; // shard origin
Vector vecVelocity; // shard velocity
CBaseEntity *pEntity = NULL;
CBaseEntity *pEntity = nullptr;
char cFlag = 0;
int pitch;
float fvol;
@ -798,11 +801,11 @@ void CBreakable::Die()
WRITE_COORD(vecVelocity.x); // velocity
WRITE_COORD(vecVelocity.y);
WRITE_COORD(vecVelocity.z);
WRITE_BYTE(10); // randomization
WRITE_BYTE(10); // randomization
WRITE_SHORT(m_idShard); // model id#
WRITE_BYTE(0); // # of shards, let client decide
WRITE_BYTE(25); // duration, 2.5 seconds
WRITE_BYTE(cFlag); // flags
WRITE_BYTE(0); // # of shards, let client decide
WRITE_BYTE(25); // duration, 2.5 seconds
WRITE_BYTE(cFlag); // flags
MESSAGE_END();
float size = pev->size.x;
@ -824,7 +827,7 @@ void CBreakable::Die()
for (int i = 0; i < count; ++i)
{
pList[i]->pev->flags &= ~FL_ONGROUND;
pList[i]->pev->groundentity = NULL;
pList[i]->pev->groundentity = nullptr;
}
pev->solid = SOLID_NOT;
@ -968,7 +971,9 @@ void CPushable::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBreakable::KeyValue(pkvd);
}
}
// Pull the func_pushable

View File

@ -26,32 +26,15 @@
*
*/
#ifndef FUNC_BREAK_H
#define FUNC_BREAK_H
#ifdef _WIN32
#pragma once
#endif
// this many shards spawned when breakable objects break;
#define NUM_SHARDS 6
// func breakable
#define SF_BREAK_TRIGGER_ONLY 1 // may only be broken by trigger
#define SF_BREAK_TOUCH 2 // can be 'crashed through' by running player (plate glass)
#define SF_BREAK_PRESSURE 4 // can be broken by a player standing on it
#define SF_BREAK_CROWBAR 256 // instant break if hit with crowbar
// func_pushable (it's also func_breakable, so don't collide with those flags)
#define SF_PUSH_BREAKABLE 128
typedef enum
enum Explosions
{
expRandom = 0,
expDirected,
};
} Explosions;
typedef enum
enum Materials
{
matGlass = 0,
matWood,
@ -64,8 +47,16 @@ typedef enum
matRocks,
matNone,
matLastMaterial,
};
} Materials;
// this many shards spawned when breakable objects break
#define NUM_SHARDS 6 // this many shards spawned when breakable objects break
// func breakable
#define SF_BREAK_TRIGGER_ONLY BIT(0) // may only be broken by trigger
#define SF_BREAK_TOUCH BIT(1) // can be 'crashed through' by running player (plate glass)
#define SF_BREAK_PRESSURE BIT(2) // can be broken by a player standing on it
#define SF_BREAK_CROWBAR BIT(8) // instant break if hit with crowbar
class CBreakable: public CBaseDelay
{
@ -125,6 +116,8 @@ public:
float m_flHealth;
};
#define SF_PUSH_BREAKABLE BIT(7) // func_pushable (it's also func_breakable, so don't collide with those flags)
class CPushable: public CBreakable
{
public:
@ -163,5 +156,3 @@ public:
float m_maxSpeed;
float m_soundTime;
};
#endif // FUNC_BREAK_H

View File

@ -48,11 +48,11 @@ TYPEDESCRIPTION CFuncTankControls::m_SaveData[] =
Vector gTankSpread[] =
{
Vector(0, 0, 0), // perfect
Vector(0, 0, 0), // perfect
Vector(0.025, 0.025, 0.025), // small cone
Vector(0.05, 0.05, 0.05), // medium cone
Vector(0.1, 0.1, 0.1), // large cone
Vector(0.25, 0.25, 0.25), // extra-large cone
Vector(0.05, 0.05, 0.05), // medium cone
Vector(0.1, 0.1, 0.1), // large cone
Vector(0.25, 0.25, 0.25), // extra-large cone
};
#endif // HOOK_GAMEDLL
@ -216,7 +216,9 @@ void CFuncTank::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseEntity::KeyValue(pkvd);
}
}
BOOL CFuncTank::OnControls(entvars_t *pevTest)
@ -225,7 +227,6 @@ BOOL CFuncTank::OnControls(entvars_t *pevTest)
return FALSE;
Vector offset = pevTest->origin - pev->origin;
if ((m_vecControllerUsePos - pevTest->origin).Length() < 30.0f)
{
return TRUE;
@ -236,7 +237,7 @@ BOOL CFuncTank::OnControls(entvars_t *pevTest)
BOOL CFuncTank::StartControl(CBasePlayer *pController)
{
if (m_pController != NULL)
if (m_pController)
return FALSE;
// Team only or disabled?
@ -252,7 +253,7 @@ BOOL CFuncTank::StartControl(CBasePlayer *pController)
m_pController = pController;
if (m_pController->m_pActiveItem != NULL)
if (m_pController->m_pActiveItem)
{
m_pController->m_pActiveItem->Holster();
m_pController->pev->weaponmodel = 0;
@ -276,7 +277,7 @@ void CFuncTank::StopControl()
if (!m_pController)
return;
if (m_pController->m_pActiveItem != NULL)
if (m_pController->m_pActiveItem)
{
m_pController->m_pActiveItem->Deploy();
@ -291,7 +292,7 @@ void CFuncTank::StopControl()
m_pController->m_iHideHUD &= ~HIDEHUD_WEAPONS;
pev->nextthink = 0;
m_pController = NULL;
m_pController = nullptr;
if (IsActive())
{
@ -301,7 +302,7 @@ void CFuncTank::StopControl()
void CFuncTank::ControllerPostFrame()
{
assert(m_pController != NULL);
assert(m_pController != nullptr);
if (gpGlobals->time < m_flNextAttack)
return;
@ -309,7 +310,7 @@ void CFuncTank::ControllerPostFrame()
if (m_pController->pev->button & IN_ATTACK)
{
Vector vecForward;
UTIL_MakeVectorsPrivate(pev->angles, vecForward, NULL, NULL);
UTIL_MakeVectorsPrivate(pev->angles, vecForward, nullptr, nullptr);
m_fireLast = gpGlobals->time - (1.0f / m_fireRate) - 0.01f;
Fire(BarrelPosition(), vecForward, m_pController->pev);
@ -390,10 +391,10 @@ void CFuncTank::TrackTarget()
edict_t *pPlayer = FIND_CLIENT_IN_PVS(edict());
bool updateTime = false, lineOfSight = false;
Vector angles, direction, targetPosition, barrelEnd;
edict_t *pTarget = NULL;
edict_t *pTarget = nullptr;
// Get a position to aim for
if (m_pController != NULL)
if (m_pController)
{
// Tanks attempt to mirror the player's angles
angles = m_pController->pev->v_angle;
@ -520,7 +521,7 @@ void CFuncTank::TrackTarget()
pev->avelocity.x = -m_pitchRate;
}
if (m_pController != NULL)
if (m_pController)
{
return;
}
@ -529,7 +530,7 @@ void CFuncTank::TrackTarget()
{
bool fire = false;
Vector forward;
UTIL_MakeVectorsPrivate(pev->angles, forward, NULL, NULL);
UTIL_MakeVectorsPrivate(pev->angles, forward, nullptr, nullptr);
if (pev->spawnflags & SF_TANK_LINEOFSIGHT)
{
@ -603,7 +604,7 @@ void CFuncTank::Fire(const Vector &barrelEnd, const Vector &forward, entvars_t *
pSprite->SetScale(m_spriteScale);
// Hack Hack, make it stick around for at least 100 ms.
pSprite->pev->nextthink += 0.1;
pSprite->pev->nextthink += 0.1f;
}
SUB_UseTargets(this, USE_TOGGLE, 0);
@ -667,7 +668,7 @@ void CFuncTankGun::Fire(const Vector &barrelEnd, const Vector &forward, entvars_
if (bulletCount > 0)
{
for (int i = 0; i < bulletCount; ++i)
for (int i = 0; i < bulletCount; i++)
{
switch (m_bulletType)
{
@ -690,7 +691,9 @@ void CFuncTankGun::Fire(const Vector &barrelEnd, const Vector &forward, entvars_
}
}
else
{
CFuncTank::Fire(barrelEnd, forward, pevAttacker);
}
}
LINK_ENTITY_TO_CLASS(func_tanklaser, CFuncTankLaser, CCSFuncTankLaser)
@ -717,17 +720,19 @@ void CFuncTankLaser::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CFuncTank::KeyValue(pkvd);
}
}
CLaser *CFuncTankLaser::GetLaser()
{
if (m_pLaser != NULL)
if (m_pLaser)
{
return m_pLaser;
}
edict_t *pentLaser = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(pev->message));
edict_t *pentLaser = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(pev->message));
while (!FNullEnt(pentLaser))
{
@ -746,7 +751,7 @@ CLaser *CFuncTankLaser::GetLaser()
void CFuncTankLaser::Think()
{
if (m_pLaser != NULL && gpGlobals->time > m_laserTime)
if (m_pLaser && gpGlobals->time > m_laserTime)
{
m_pLaser->TurnOff();
}
@ -768,7 +773,7 @@ void CFuncTankLaser::Fire(const Vector &barrelEnd, const Vector &forward, entvar
if (bulletCount)
{
for (i = 0; i < bulletCount; ++i)
for (i = 0; i < bulletCount; i++)
{
m_pLaser->pev->origin = barrelEnd;
TankTrace(barrelEnd, forward, gTankSpread[m_spread], tr);
@ -804,10 +809,9 @@ void CFuncTankRocket::Fire(const Vector &barrelEnd, const Vector &forward, entva
if (m_fireLast != 0.0f)
{
int bulletCount = int((gpGlobals->time - m_fireLast) * m_fireRate);
if (bulletCount > 0)
{
for (i = 0; i < bulletCount; ++i)
for (i = 0; i < bulletCount; i++)
{
CBaseEntity *pRocket = CBaseEntity::Create("rpg_rocket", barrelEnd, pev->angles, edict());
}
@ -816,7 +820,9 @@ void CFuncTankRocket::Fire(const Vector &barrelEnd, const Vector &forward, entva
}
}
else
{
CFuncTank::Fire(barrelEnd, forward, pev);
}
}
LINK_ENTITY_TO_CLASS(func_tankmortar, CFuncTankMortar, CCSFuncTankMortar)
@ -829,7 +835,9 @@ void CFuncTankMortar::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CFuncTank::KeyValue(pkvd);
}
}
void CFuncTankMortar::Fire(const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker)
@ -852,7 +860,9 @@ void CFuncTankMortar::Fire(const Vector &barrelEnd, const Vector &forward, entva
}
}
else
{
CFuncTank::Fire(barrelEnd, forward, pev);
}
}
LINK_ENTITY_TO_CLASS(func_tankcontrols, CFuncTankControls, CCSFuncTankControls)
@ -861,18 +871,18 @@ IMPLEMENT_SAVERESTORE(CFuncTankControls, CBaseEntity)
void CFuncTankControls::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
// pass the Use command onto the controls
if (m_pTank != NULL)
if (m_pTank)
{
m_pTank->Use(pActivator, pCaller, useType, value);
}
// if this fails, most likely means save/restore hasn't worked properly
assert(m_pTank != NULL);
assert(m_pTank != nullptr);
}
void CFuncTankControls::Think()
{
edict_t *pTarget = NULL;
edict_t *pTarget = nullptr;
do
{

View File

@ -26,28 +26,25 @@
*
*/
#ifndef FUNC_TANK_H
#define FUNC_TANK_H
#ifdef _WIN32
#pragma once
#endif
#define SF_TANK_ACTIVE 0x0001
#define SF_TANK_PLAYER 0x0002
#define SF_TANK_HUMANS 0x0004
#define SF_TANK_ALIENS 0x0008
#define SF_TANK_LINEOFSIGHT 0x0010
#define SF_TANK_CANCONTROL 0x0020
#define SF_TANK_SOUNDON 0x8000
enum TANKBULLET
{
TANK_BULLET_NONE = 0, // Custom damage
TANK_BULLET_9MM, // env_laser (duration is 0.5 rate of fire)
TANK_BULLET_MP5, // rockets
TANK_BULLET_12MM, // explosion?
TANK_BULLET_9MM, // env_laser (duration is 0.5 rate of fire)
TANK_BULLET_MP5, // rockets
TANK_BULLET_12MM, // explosion?
};
#define SF_TANK_ACTIVE BIT(0)
#define SF_TANK_PLAYER BIT(1)
#define SF_TANK_HUMANS BIT(2)
#define SF_TANK_ALIENS BIT(3)
#define SF_TANK_LINEOFSIGHT BIT(4)
#define SF_TANK_CANCONTROL BIT(5)
#define SF_TANK_SOUNDON BIT(15)
class CFuncTank: public CBaseEntity
{
public:
@ -114,30 +111,30 @@ protected:
float m_yawCenter; // "Center" yaw
float m_yawRate; // Max turn rate to track targets
float m_yawRange; // Range of turning motion (one-sided: 30 is +/- 30 degress from center)
// Zero is full rotation
// Zero is full rotation
float m_yawTolerance; // Tolerance angle
float m_yawTolerance; // Tolerance angle
float m_pitchCenter; // "Center" pitch
float m_pitchCenter; // "Center" pitch
float m_pitchRate; // Max turn rate on pitch
float m_pitchRange; // Range of pitch motion as above
float m_pitchTolerance; // Tolerance angle
float m_pitchTolerance; // Tolerance angle
float m_fireLast; // Last time I fired
float m_fireRate; // How many rounds/second
float m_lastSightTime; // Last time I saw target
float m_lastSightTime; // Last time I saw target
float m_persist; // Persistence of firing (how long do I shoot when I can't see)
float m_minRange; // Minimum range to aim/track
float m_maxRange; // Max range to aim/track
Vector m_barrelPos; // Length of the freakin barrel
float m_spriteScale; // Scale of any sprites we shoot
float m_spriteScale; // Scale of any sprites we shoot
int m_iszSpriteSmoke;
int m_iszSpriteFlash;
TANKBULLET m_bulletType; // Bullet type
int m_iBulletDamage; // 0 means use Bullet type's default damage
TANKBULLET m_bulletType;// Bullet type
int m_iBulletDamage; // 0 means use Bullet type's default damage
Vector m_sightOrigin; // Last sight of target
Vector m_sightOrigin; // Last sight of target
int m_spread; // firing spread
int m_iszMaster; // Master entity (game_team_master or multisource)
};
@ -196,5 +193,3 @@ public:
static TYPEDESCRIPTION IMPL(m_SaveData)[1];
CFuncTank *m_pTank;
};
#endif // FUNC_TANK_H

View File

@ -111,8 +111,8 @@ cvar_t max_teamkills = { "mp_max_teamkills", "3", 0, 3.0f, nullptr };
cvar_t fraglimit = { "mp_fraglimit", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t round_restart_delay = { "mp_round_restart_delay", "5", FCVAR_SERVER, 0.0f, nullptr };
cvar_t showtriggers = { "showtriggers", "0", 0, 0.0f, nullptr }; // debug cvar shows triggers
// TODO: Maybe it's better to register in the engine?
cvar_t showtriggers = { "showtriggers", "0", 0, 0.0f, nullptr }; // debug cvar shows triggers
// TODO: Maybe it's better to register in the engine?
cvar_t hostagehurtable = { "mp_hostage_hurtable", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t roundover = { "mp_roundover", "0", FCVAR_SERVER, 0.0f, nullptr };

View File

@ -26,23 +26,19 @@
*
*/
#ifndef GAME_H
#define GAME_H
#ifdef _WIN32
#pragma once
#endif
#define LOG_ENEMYATTACK 1
#define LOG_TEAMMATEATTACK 2
#define LOG_ENEMYATTACK 1
#define LOG_TEAMMATEATTACK 2
// playerid
#define PLAYERID_MODE_EVERYONE 0
#define PLAYERID_MODE_TEAMONLY 1
#define PLAYERID_MODE_OFF 2
#define PLAYERID_MODE_EVERYONE 0
#define PLAYERID_MODE_TEAMONLY 1
#define PLAYERID_MODE_OFF 2
#define PLAYERID_EVERYONE 0
#define PLAYERID_TEAMONLY 1
#define PLAYERID_OFF 2
#define PLAYERID_EVERYONE 0
#define PLAYERID_TEAMONLY 1
#define PLAYERID_OFF 2
extern cvar_t *g_psv_gravity;
extern cvar_t *g_psv_aim;
@ -155,5 +151,3 @@ extern cvar_t show_radioicon;
#endif
void GameDLLInit();
#endif // GAME_H

View File

@ -5,7 +5,7 @@
*/
#ifndef HOOK_GAMEDLL
CGameRules *g_pGameRules = NULL;
CGameRules *g_pGameRules = nullptr;
#endif
@ -86,7 +86,7 @@ BOOL CGameRules::CanHavePlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pWeapo
return FALSE;
}
if (pPlayer->IsBot() && TheCSBots() != NULL && !TheCSBots()->IsWeaponUseable(pWeapon))
if (pPlayer->IsBot() && TheCSBots() && !TheCSBots()->IsWeaponUseable(pWeapon))
{
return FALSE;
}

View File

@ -26,49 +26,44 @@
*
*/
#ifndef GAMERULES_H
#define GAMERULES_H
#ifdef _WIN32
#pragma once
#endif
#include "game_shared/voice_gamemgr.h"
#include "cmdhandler.h"
#define MAX_RULE_BUFFER 1024
#define MAX_VOTE_MAPS 100
#define MAX_VIP_QUEUES 5
const int MAX_RULE_BUFFER = 1024;
const int MAX_VOTE_MAPS = 100;
const int MAX_VIP_QUEUES = 5;
#define MAX_BOMB_RADIUS 2048
const int MAX_MOTD_CHUNK = 60;
const int MAX_MOTD_LENGTH = 1536; // (MAX_MOTD_CHUNK * 4)
#define ITEM_RESPAWN_TIME 30
#define WEAPON_RESPAWN_TIME 20
#define AMMO_RESPAWN_TIME 20
#define ROUND_RESPAWN_TIME 20
#define ROUND_BEGIN_DELAY 5 // delay before beginning new round
const float ITEM_RESPAWN_TIME = 30;
const float WEAPON_RESPAWN_TIME = 20;
const float AMMO_RESPAWN_TIME = 20;
const float ROUND_RESPAWN_TIME = 20;
const float ROUND_BEGIN_DELAY = 5; // delay before beginning new round
// longest the intermission can last, in seconds
#define MAX_INTERMISSION_TIME 120
const int MAX_INTERMISSION_TIME = 120; // longest the intermission can last, in seconds
// when we are within this close to running out of entities, items
// when we are within this close to running out of entities, items
// marked with the ITEM_FLAG_LIMITINWORLD will delay their respawn
#define ENTITY_INTOLERANCE 100
#define MAX_MOTD_CHUNK 60
#define MAX_MOTD_LENGTH 1536 // (MAX_MOTD_CHUNK * 4)
const int ENTITY_INTOLERANCE = 100;
// custom enum
#define WINNER_NONE 0
#define WINNER_DRAW 1
#define WINNER_NONE 0
#define WINNER_DRAW 1
enum
{
WINSTATUS_CTS = 1,
WINSTATUS_NONE = 0,
WINSTATUS_CTS,
WINSTATUS_TERRORISTS,
WINSTATUS_DRAW,
};
// custom enum
// used for EndRoundMessage() logged messages
// Custom enum
// Used for EndRoundMessage() logged messages
enum ScenarioEventEndRound
{
ROUND_NONE,
@ -197,13 +192,13 @@ enum
// custom enum
enum
{
SCENARIO_BLOCK_TIME_EXPRIRED = (1 << 0), // flag "a"
SCENARIO_BLOCK_NEED_PLAYERS = (1 << 1), // flag "b"
SCENARIO_BLOCK_VIP_ESCAPE = (1 << 2), // flag "c"
SCENARIO_BLOCK_PRISON_ESCAPE = (1 << 3), // flag "d"
SCENARIO_BLOCK_BOMB = (1 << 4), // flag "e"
SCENARIO_BLOCK_TEAM_EXTERMINATION = (1 << 5), // flag "f"
SCENARIO_BLOCK_HOSTAGE_RESCUE = (1 << 6), // flag "g"
SCENARIO_BLOCK_TIME_EXPRIRED = BIT(0), // flag "a"
SCENARIO_BLOCK_NEED_PLAYERS = BIT(1), // flag "b"
SCENARIO_BLOCK_VIP_ESCAPE = BIT(2), // flag "c"
SCENARIO_BLOCK_PRISON_ESCAPE = BIT(3), // flag "d"
SCENARIO_BLOCK_BOMB = BIT(4), // flag "e"
SCENARIO_BLOCK_TEAM_EXTERMINATION = BIT(5), // flag "f"
SCENARIO_BLOCK_HOSTAGE_RESCUE = BIT(6), // flag "g"
};
// Player relationship return codes
@ -519,6 +514,7 @@ public:
// Teamplay stuff
virtual const char *GetTeamID(CBaseEntity *pEntity) { return ""; }
virtual int PlayerRelationship(CBasePlayer *pPlayer, CBaseEntity *pTarget);
virtual void ChangePlayerTeam(CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib);
virtual BOOL PlayTextureSounds() { return FALSE; }
@ -591,31 +587,33 @@ public:
// for internal functions API
void OnRoundFreezeEnd();
bool OnRoundEnd(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool OnRoundEnd_Intercept(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool RoundOver_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool NeededPlayersCheck_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool RestartRoundCheck_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool RoundOver(float tmDelay);
bool NeededPlayersCheck(float tmDelay);
bool RestartRoundCheck(float tmDelay);
bool VIP_Escaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool VIP_Died_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool VIP_NotEscaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool VIP_Escaped(float tmDelay);
bool VIP_Died(float tmDelay);
bool VIP_NotEscaped(float tmDelay);
bool Prison_Escaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Prison_PreventEscape_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Prison_NotEscaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Prison_Neutralized_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Prison_Escaped(float tmDelay);
bool Prison_PreventEscape(float tmDelay);
bool Prison_NotEscaped(float tmDelay);
bool Prison_Neutralized(float tmDelay);
bool Target_Bombed_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Target_Saved_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Target_Defused_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Target_Bombed(float tmDelay);
bool Target_Saved(float tmDelay);
bool Target_Defused(float tmDelay);
// Team extermination
bool Round_Cts_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Round_Ts_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Round_Draw_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Round_Cts(float tmDelay);
bool Round_Ts(float tmDelay);
bool Round_Draw(float tmDelay);
bool Hostage_Rescue_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Hostage_NotRescued_internal(int winStatus, ScenarioEventEndRound event, float tmDelay);
bool Hostage_Rescue(float tmDelay);
bool Hostage_NotRescued(float tmDelay);
// Check various conditions to end the map.
bool CheckGameOver();
@ -785,7 +783,7 @@ protected:
typedef struct mapcycle_item_s
{
struct mapcycle_item_s *next;
char mapname[32];
char mapname[MAX_MAPNAME_LENGHT];
int minplayers;
int maxplayers;
char rulebuffer[MAX_RULE_BUFFER];
@ -886,14 +884,7 @@ void Broadcast(const char *sentence);
char *GetTeam(int team);
void EndRoundMessage(const char *sentence, int event);
void DestroyMapCycle(mapcycle_t *cycle);
char *MP_COM_GetToken();
char *MP_COM_Parse(char *data);
int MP_COM_TokenWaiting(char *buffer);
int ReloadMapCycleFile(char *filename, mapcycle_t *cycle);
int CountPlayers();
void ExtractCommandString(char *s, char *szCommand);
int GetMapCount();
#endif // GAMERULES_H

View File

@ -41,7 +41,7 @@ void CGrenade::Explode(TraceResult *pTrace, int bitsDamageType)
float flRndSound; // sound randomizer
pev->model = iStringNull; // invisible
pev->solid = SOLID_NOT; // intangible
pev->solid = SOLID_NOT; // intangible
pev->takedamage = DAMAGE_NO;
// Pull out of the wall a bit
@ -63,7 +63,7 @@ void CGrenade::Explode(TraceResult *pTrace, int bitsDamageType)
}
// can't traceline attack owner if this is set
pev->owner = NULL;
pev->owner = nullptr;
RadiusFlash(pev->origin, pev, pevOwner, 4, CLASS_NONE, bitsDamageType);
@ -89,9 +89,10 @@ void CGrenade::Explode(TraceResult *pTrace, int bitsDamageType)
if (iContents != CONTENTS_WATER)
{
int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; ++i)
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL);
for (int i = 0; i < sparkCount; i++)
{
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, nullptr);
}
}
}
@ -100,7 +101,7 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
float flRndSound; // sound randomizer
pev->model = iStringNull; // invisible
pev->solid = SOLID_NOT; // intangible
pev->solid = SOLID_NOT; // intangible
pev->takedamage = DAMAGE_NO;
UTIL_ScreenShake(pTrace->vecEndPos, 25, 150, 1, 3000);
@ -174,7 +175,7 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
#endif
entvars_t *pevOwner = VARS(pev->owner);
pev->owner = NULL;
pev->owner = nullptr;
RadiusDamage(pev, pevOwner, CSGameRules()->m_flBombRadius, CLASS_NONE, bitsDamageType);
if (CSGameRules()->IsCareer())
@ -219,19 +220,19 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
if (iContents != CONTENTS_WATER)
{
int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; ++i)
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL);
for (int i = 0; i < sparkCount; i++)
{
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, nullptr);
}
}
}
void CGrenade::Explode3(TraceResult *pTrace, int bitsDamageType)
{
float flRndSound; // sound randomizer
//float damage;
pev->model = iStringNull; // invisible
pev->solid = SOLID_NOT; // intangible
pev->solid = SOLID_NOT; // intangible
pev->takedamage = DAMAGE_NO;
if (pTrace->flFraction != 1.0f)
@ -271,7 +272,7 @@ void CGrenade::Explode3(TraceResult *pTrace, int bitsDamageType)
TheBots->OnEvent(EVENT_HE_GRENADE_EXPLODED, CBaseEntity::Instance(pev->owner));
}
pev->owner = NULL;
pev->owner = nullptr;
RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType);
if (RANDOM_FLOAT(0, 1) < 0.5f)
@ -293,19 +294,20 @@ void CGrenade::Explode3(TraceResult *pTrace, int bitsDamageType)
SetThink(&CGrenade::Smoke3_C);
pev->velocity = g_vecZero;
pev->nextthink = gpGlobals->time + 0.55f;
int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; ++i)
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL);
int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; i++)
{
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, nullptr);
}
}
NOXREF void CGrenade::SG_Explode(TraceResult *pTrace, int bitsDamageType)
{
float flRndSound; // sound randomizer
//entvars_t *pevOwner;
pev->model = iStringNull; // invisible
pev->solid = SOLID_NOT; // intangible
pev->solid = SOLID_NOT; // intangible
pev->takedamage = DAMAGE_NO;
@ -321,7 +323,7 @@ NOXREF void CGrenade::SG_Explode(TraceResult *pTrace, int bitsDamageType)
#endif
// can't traceline attack owner if this is set
pev->owner = NULL;
pev->owner = nullptr;
if (RANDOM_FLOAT(0, 1) < 0.5f)
UTIL_DecalTrace(pTrace, DECAL_SCORCH1);
@ -346,8 +348,10 @@ NOXREF void CGrenade::SG_Explode(TraceResult *pTrace, int bitsDamageType)
{
int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; ++i)
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL);
for (int i = 0; i < sparkCount; i++)
{
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, nullptr);
}
}
}
@ -453,7 +457,7 @@ void CGrenade::Smoke()
WRITE_COORD(pev->origin.z);
WRITE_SHORT(g_sModelIndexSmoke);
WRITE_BYTE(25); // scale * 10
WRITE_BYTE(6); // framerate
WRITE_BYTE(6); // framerate
MESSAGE_END();
}
@ -490,14 +494,14 @@ void CGrenade::SG_Smoke()
m_angle = (m_angle + 30) % 360;
PLAYBACK_EVENT_FULL(0, NULL, m_usEvent, 0, pev->origin, m_vSmokeDetonate, angle.x, angle.y, flSmokeInterval, 4, m_bLightSmoke, 6);
PLAYBACK_EVENT_FULL(0, nullptr, m_usEvent, 0, pev->origin, m_vSmokeDetonate, angle.x, angle.y, flSmokeInterval, 4, m_bLightSmoke, 6);
}
if (m_SGSmoke <= 20)
{
pev->nextthink = gpGlobals->time + 1.0f;
SetThink(&CGrenade::SG_Smoke);
++m_SGSmoke;
m_SGSmoke++;
}
else
{
@ -547,7 +551,7 @@ void CGrenade::SG_Detonate()
{
TraceResult tr;
Vector vecSpot;
edict_t *pentFind = NULL;
edict_t *pentFind = nullptr;
vecSpot = pev->origin + Vector(0, 0, 8);
@ -570,7 +574,6 @@ void CGrenade::SG_Detonate()
if (pEnt)
{
float fDistance = (pEnt->pev->origin - pev->origin).Length();
if (fDistance != 0.0f && fDistance <= 250.0f)
{
if (gpGlobals->time > pEnt->pev->dmgtime)
@ -582,7 +585,7 @@ void CGrenade::SG_Detonate()
}
m_bDetonated = true;
PLAYBACK_EVENT_FULL(0, NULL, m_usEvent, 0, pev->origin, (float *)&g_vecZero, 0, 0, 0, 1, m_bLightSmoke, FALSE);
PLAYBACK_EVENT_FULL(0, nullptr, m_usEvent, 0, pev->origin, (float *)&g_vecZero, 0, 0, 0, 1, m_bLightSmoke, FALSE);
m_vSmokeDetonate = pev->origin;
pev->velocity.x = RANDOM_FLOAT(-175, 175);
@ -681,7 +684,7 @@ void CGrenade::BounceTouch(CBaseEntity *pOther)
{
// add a bit of static friction
pev->velocity = pev->velocity * 0.8f;
pev->sequence = RANDOM_LONG(1, 1); // TODO: what?
pev->sequence = RANDOM_LONG(1, 1); // TODO: what?
}
else
{
@ -698,7 +701,7 @@ void CGrenade::BounceTouch(CBaseEntity *pOther)
pev->velocity = g_vecZero;
}
++m_iBounceCount;
m_iBounceCount++;
}
pev->framerate = pev->velocity.Length() / 200.0f;
@ -771,7 +774,9 @@ void CGrenade::TumbleThink()
SetThink(&CGrenade::Detonate);
}
else
{
SetThink(&CGrenade::Detonate3);
}
}
if (pev->waterlevel != 0)
@ -838,11 +843,11 @@ void CGrenade::Spawn()
NOXREF CGrenade *CGrenade::ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity)
{
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)NULL);
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)nullptr);
pGrenade->Spawn();
// contact grenades arc lower
pGrenade->pev->gravity = 0.5f; // lower gravity since grenade is aerodynamic and engine doesn't know it.
pGrenade->pev->gravity = 0.5f; // lower gravity since grenade is aerodynamic and engine doesn't know it.
UTIL_SetOrigin(pGrenade->pev, vecStart);
pGrenade->pev->velocity = vecVelocity;
@ -866,7 +871,7 @@ NOXREF CGrenade *CGrenade::ShootContact(entvars_t *pevOwner, Vector vecStart, Ve
CGrenade *CGrenade::ShootTimed2(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time, int iTeam, unsigned short usEvent)
{
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)NULL);
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)nullptr);
pGrenade->Spawn();
UTIL_SetOrigin(pGrenade->pev, vecStart);
@ -900,7 +905,7 @@ CGrenade *CGrenade::ShootTimed2(entvars_t *pevOwner, Vector vecStart, Vector vec
CGrenade *CGrenade::ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time)
{
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)NULL);
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)nullptr);
pGrenade->Spawn();
UTIL_SetOrigin(pGrenade->pev, vecStart);
@ -944,6 +949,7 @@ void CGrenade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
if (!m_bIsC4)
return;
// TODO: We must be sure that the activator is a player.
CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pActivator->pev);
// For CTs to defuse the c4
@ -988,7 +994,7 @@ void CGrenade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
#endif
player->m_bIsDefusing = true;
m_pBombDefuser = pActivator;
m_pBombDefuser = static_cast<CBasePlayer *>(pActivator);
m_bStartDefuse = true;
m_flDefuseCountDown = gpGlobals->time + 5.0f;
m_fNextDefuse = gpGlobals->time + 0.5f;
@ -1007,10 +1013,10 @@ void CGrenade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
ClientPrint(player->pev, HUD_PRINTCENTER, "#Defusing_Bomb_Without_Defuse_Kit");
#ifndef REGAMEDLL_FIXES
EMIT_SOUND(ENT(player->pev), CHAN_ITEM, "weapons/c4_disarm.wav", VOL_NORM, ATTN_NORM);
#endif
#endif
player->m_bIsDefusing = true;
m_pBombDefuser = pActivator;
m_pBombDefuser = static_cast<CBasePlayer *>(pActivator);
m_bStartDefuse = true;
m_flDefuseCountDown = gpGlobals->time + 10.0f;
m_fNextDefuse = gpGlobals->time + 0.5f;
@ -1026,7 +1032,7 @@ void CGrenade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
CGrenade *CGrenade::ShootSatchelCharge(entvars_t *pevOwner, Vector vecStart, Vector vecAngles)
{
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)NULL);
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)nullptr);
pGrenade->pev->movetype = MOVETYPE_TOSS;
MAKE_STRING_CLASS("grenade", pGrenade->pev);
@ -1056,7 +1062,7 @@ CGrenade *CGrenade::ShootSatchelCharge(entvars_t *pevOwner, Vector vecStart, Vec
pGrenade->m_iCurWave = 0;
pGrenade->m_fAttenu = 0;
pGrenade->m_sBeepName = NULL;
pGrenade->m_sBeepName = nullptr;
pGrenade->m_flNextBeep = gpGlobals->time + 0.5f;
pGrenade->m_bIsC4 = true;
pGrenade->m_fNextDefuse = 0;
@ -1072,14 +1078,16 @@ CGrenade *CGrenade::ShootSatchelCharge(entvars_t *pevOwner, Vector vecStart, Vec
pGrenade->m_pentCurBombTarget = pOwner->m_pentCurBombTarget;
}
else
pGrenade->m_pentCurBombTarget = NULL;
{
pGrenade->m_pentCurBombTarget = nullptr;
}
return pGrenade;
}
CGrenade *CGrenade::ShootSmokeGrenade(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time, unsigned short usEvent)
{
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)NULL);
CGrenade *pGrenade = GetClassPtr<CCSGrenade>((CGrenade *)nullptr);
pGrenade->Spawn();
UTIL_SetOrigin(pGrenade->pev, vecStart);
@ -1115,7 +1123,7 @@ CGrenade *CGrenade::ShootSmokeGrenade(entvars_t *pevOwner, Vector vecStart, Vect
void AnnounceFlashInterval(float interval, float offset)
{
if (!g_bIsCzeroGame)
if (!AreRunningCZero())
return;
MESSAGE_BEGIN(MSG_ALL, gmsgScenarioIcon);
@ -1176,7 +1184,7 @@ void CGrenade::C4Think()
break;
}
++m_iCurWave;
m_iCurWave++;
}
if (gpGlobals->time >= m_flNextBeep)
@ -1258,7 +1266,7 @@ void CGrenade::C4Think()
// if the defusing process has started
if (m_bStartDefuse && m_pBombDefuser)
{
CBasePlayer *pPlayer = (CBasePlayer *)m_pBombDefuser;
CBasePlayer *pPlayer = m_pBombDefuser;
// if the defusing process has not ended yet
if (gpGlobals->time < m_flDefuseCountDown)
@ -1279,7 +1287,7 @@ void CGrenade::C4Think()
// cancel the progress bar
pPlayer->SetProgressBarTime(0);
m_pBombDefuser = NULL;
m_pBombDefuser = nullptr;
m_bStartDefuse = false;
m_flDefuseCountDown = 0;
@ -1345,7 +1353,7 @@ void CGrenade::C4Think()
MESSAGE_END();
g_pGameRules->m_bBombDropped = FALSE;
m_pBombDefuser = NULL;
m_pBombDefuser = nullptr;
m_bStartDefuse = false;
}
else
@ -1356,7 +1364,7 @@ void CGrenade::C4Think()
pPlayer->m_bIsDefusing = false;
m_bStartDefuse = false;
m_pBombDefuser = NULL;
m_pBombDefuser = nullptr;
// tell the bots someone has aborted defusing
if (TheBots)
@ -1377,7 +1385,7 @@ NOXREF void CGrenade::UseSatchelCharges(entvars_t *pevOwner, SATCHELCODE code)
if (!pevOwner)
return;
edict_t *pentFind = NULL;
edict_t *pentFind = nullptr;
CBaseEntity *pOwner = CBaseEntity::Instance(pevOwner);
while ((pentFind = FIND_ENTITY_BY_CLASSNAME(pentFind, "grenade")))
@ -1395,7 +1403,7 @@ NOXREF void CGrenade::UseSatchelCharges(entvars_t *pevOwner, SATCHELCODE code)
else
{
// SATCHEL_RELEASE
pEnt->pev->owner = NULL;
pEnt->pev->owner = nullptr;
}
}
}

295
regamedll/dlls/gib.cpp Normal file
View File

@ -0,0 +1,295 @@
#include "precompiled.h"
void CGib::LimitVelocity()
{
float length = pev->velocity.Length();
// ceiling at 1500. The gib velocity equation is not bounded properly. Rather than tune it
// in 3 separate places again, I'll just limit it here.
if (length > 1500.0)
{
// This should really be sv_maxvelocity * 0.75 or something
pev->velocity = pev->velocity.Normalize() * 1500;
}
}
NOXREF void CGib::SpawnStickyGibs(entvars_t *pevVictim, Vector vecOrigin, int cGibs)
{
if (g_Language == LANGUAGE_GERMAN)
{
// no sticky gibs in germany right now!
return;
}
for (int i = 0; i < cGibs; ++i)
{
CGib *pGib = GetClassPtr<CCSGib>((CGib *)nullptr);
pGib->Spawn("models/stickygib.mdl");
pGib->pev->body = RANDOM_LONG(0, 2);
if (pevVictim)
{
pGib->pev->origin.x = vecOrigin.x + RANDOM_FLOAT(-3, 3);
pGib->pev->origin.y = vecOrigin.y + RANDOM_FLOAT(-3, 3);
pGib->pev->origin.z = vecOrigin.z + RANDOM_FLOAT(-3, 3);
// make the gib fly away from the attack vector
pGib->pev->velocity = g_vecAttackDir * -1;
// mix in some noise
pGib->pev->velocity.x += RANDOM_FLOAT(-0.15, 0.15);
pGib->pev->velocity.y += RANDOM_FLOAT(-0.15, 0.15);
pGib->pev->velocity.z += RANDOM_FLOAT(-0.15, 0.15);
pGib->pev->velocity = pGib->pev->velocity * 900;
pGib->pev->avelocity.x = RANDOM_FLOAT(250, 400);
pGib->pev->avelocity.y = RANDOM_FLOAT(250, 400);
// copy owner's blood color
pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor();
if (pevVictim->health > -50)
{
pGib->pev->velocity = pGib->pev->velocity * 0.7;
}
else if (pevVictim->health > -200)
{
pGib->pev->velocity = pGib->pev->velocity * 2;
}
else
{
pGib->pev->velocity = pGib->pev->velocity * 4;
}
pGib->pev->movetype = MOVETYPE_TOSS;
pGib->pev->solid = SOLID_BBOX;
UTIL_SetSize(pGib->pev, Vector(0, 0,0), Vector(0, 0, 0));
pGib->SetTouch(&CGib::StickyGibTouch);
pGib->SetThink(NULL);
}
pGib->LimitVelocity();
}
}
void CGib::SpawnHeadGib(entvars_t *pevVictim)
{
CGib *pGib = GetClassPtr<CCSGib>((CGib *)nullptr);
if (g_Language == LANGUAGE_GERMAN)
{
// throw one head
pGib->Spawn("models/germangibs.mdl");
pGib->pev->body = 0;
}
else
{
// throw one head
pGib->Spawn("models/hgibs.mdl");
pGib->pev->body = 0;
}
if (pevVictim)
{
pGib->pev->origin = pevVictim->origin + pevVictim->view_ofs;
edict_t *pentPlayer = FIND_CLIENT_IN_PVS(pGib->edict());
if (RANDOM_LONG(0, 100) <= 5 && pentPlayer)
{
// 5% chance head will be thrown at player's face.
entvars_t *pevPlayer = VARS(pentPlayer);
pGib->pev->velocity = ((pevPlayer->origin + pevPlayer->view_ofs) - pGib->pev->origin).Normalize() * 300;
pGib->pev->velocity.z += 100;
}
else
{
// TODO: fix test demo
pGib->pev->velocity.z = RANDOM_FLOAT(200, 300);
pGib->pev->velocity.y = RANDOM_FLOAT(-100, 100);
pGib->pev->velocity.x = RANDOM_FLOAT(-100, 100);
}
pGib->pev->avelocity.x = RANDOM_FLOAT(100, 200);
pGib->pev->avelocity.y = RANDOM_FLOAT(100, 300);
// copy owner's blood color
pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor();
if (pevVictim->health > -50)
{
pGib->pev->velocity = pGib->pev->velocity * 0.7;
}
else if (pevVictim->health > -200)
{
pGib->pev->velocity = pGib->pev->velocity * 2;
}
else
pGib->pev->velocity = pGib->pev->velocity * 4;
}
pGib->LimitVelocity();
}
void CGib::SpawnRandomGibs(entvars_t *pevVictim, int cGibs, int human)
{
int cSplat;
for (cSplat = 0; cSplat < cGibs; ++cSplat)
{
CGib *pGib = GetClassPtr<CCSGib>((CGib *)nullptr);
if (g_Language == LANGUAGE_GERMAN)
{
pGib->Spawn("models/germangibs.mdl");
pGib->pev->body = RANDOM_LONG(0, GERMAN_GIB_COUNT - 1);
}
else
{
if (human)
{
// human pieces
pGib->Spawn("models/hgibs.mdl");
// start at one to avoid throwing random amounts of skulls (0th gib)
pGib->pev->body = RANDOM_LONG(1, HUMAN_GIB_COUNT - 1);
}
else
{
// aliens
pGib->Spawn("models/agibs.mdl");
pGib->pev->body = RANDOM_LONG(0, ALIEN_GIB_COUNT - 1);
}
}
if (pevVictim)
{
// spawn the gib somewhere in the monster's bounding volume
pGib->pev->origin.x = pevVictim->absmin.x + pevVictim->size.x * (RANDOM_FLOAT(0, 1));
pGib->pev->origin.y = pevVictim->absmin.y + pevVictim->size.y * (RANDOM_FLOAT(0, 1));
// absmin.z is in the floor because the engine subtracts 1 to enlarge the box
pGib->pev->origin.z = pevVictim->absmin.z + pevVictim->size.z * (RANDOM_FLOAT(0, 1)) + 1;
// make the gib fly away from the attack vector
pGib->pev->velocity = g_vecAttackDir * -1;
// mix in some noise
pGib->pev->velocity.x += RANDOM_FLOAT(-0.25, 0.25);
pGib->pev->velocity.y += RANDOM_FLOAT(-0.25, 0.25);
pGib->pev->velocity.z += RANDOM_FLOAT(-0.25, 0.25);
pGib->pev->velocity = pGib->pev->velocity * RANDOM_FLOAT(300, 400);
pGib->pev->avelocity.x = RANDOM_FLOAT(100, 200);
pGib->pev->avelocity.y = RANDOM_FLOAT(100, 300);
// copy owner's blood color
pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor();
if (pevVictim->health > -50)
pGib->pev->velocity = pGib->pev->velocity * 0.7;
else if (pevVictim->health > -200)
pGib->pev->velocity = pGib->pev->velocity * 2;
else
pGib->pev->velocity = pGib->pev->velocity * 4;
pGib->pev->solid = SOLID_BBOX;
UTIL_SetSize(pGib->pev, Vector(0, 0, 0), Vector(0, 0, 0));
}
pGib->LimitVelocity();
}
}
void CGib::BounceGibTouch(CBaseEntity *pOther)
{
if (pev->flags & FL_ONGROUND)
{
pev->velocity = pev->velocity * 0.9;
pev->angles.x = 0;
pev->angles.z = 0;
pev->avelocity.x = 0;
pev->avelocity.z = 0;
}
else
{
if (g_Language != LANGUAGE_GERMAN && m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED)
{
TraceResult tr;
Vector vecSpot = pev->origin + Vector(0, 0, 8);
UTIL_TraceLine(vecSpot, vecSpot + Vector(0, 0, -24), ignore_monsters, ENT(pev), &tr);
UTIL_BloodDecalTrace(&tr, m_bloodColor);
m_cBloodDecals--;
}
if (m_material != matNone && !RANDOM_LONG(0, 2))
{
float zvel = Q_fabs(pev->velocity.z);
float volume = 0.8 * Q_min(1.0f, zvel / 450);
CBreakable::MaterialSoundRandom(edict(), (Materials)m_material, volume);
}
}
}
// Sticky gib puts blood on the wall and stays put.
void CGib::StickyGibTouch(CBaseEntity *pOther)
{
Vector vecSpot;
TraceResult tr;
SetThink(&CBaseEntity::SUB_Remove);
pev->nextthink = gpGlobals->time + 10;
if (!FClassnameIs(pOther->pev, "worldspawn"))
{
pev->nextthink = gpGlobals->time;
return;
}
vecSpot = pev->origin + pev->velocity * 32;
UTIL_TraceLine(pev->origin, vecSpot, ignore_monsters, ENT(pev), &tr);
UTIL_BloodDecalTrace(&tr, m_bloodColor);
pev->velocity = tr.vecPlaneNormal * -1;
pev->angles = UTIL_VecToAngles(pev->velocity);
pev->velocity = g_vecZero;
pev->avelocity = g_vecZero;
pev->movetype = MOVETYPE_NONE;
}
void CGib::Spawn(const char *szGibModel)
{
pev->movetype = MOVETYPE_BOUNCE;
// deading the bounce a bit
pev->friction = 0.55;
// sometimes an entity inherits the edict from a former piece of glass,
// and will spawn using the same render FX or rendermode! bad!
pev->renderamt = 255.0;
pev->rendermode = kRenderNormal;
pev->renderfx = kRenderFxNone;
/// hopefully this will fix the VELOCITY TOO LOW crap
pev->solid = SOLID_SLIDEBOX;
MAKE_STRING_CLASS("gib", pev);
SET_MODEL(ENT(pev), szGibModel);
UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0));
pev->nextthink = gpGlobals->time + 4.0f;
m_lifeTime = 25.0f;
SetThink(&CGib::WaitTillLand);
SetTouch(&CGib::BounceGibTouch);
m_material = matNone;
// how many blood decals this gib can place (1 per bounce until none remain).
m_cBloodDecals = 5;
}

View File

@ -25,31 +25,29 @@
* version.
*
*/
#pragma once
class CFuncMortarField: public CBaseToggle {
class CGib: public CBaseEntity
{
public:
virtual void Spawn() = 0;
virtual void Precache() = 0;
virtual void KeyValue(KeyValueData *pkvd) = 0;
virtual int Save(CSave &save) = 0;
virtual int Restore(CRestore &restore) = 0;
virtual int ObjectCaps() { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; }
// Bmodels don't go across transitions
virtual int ObjectCaps() = 0;
public:
int m_iszXController;
int m_iszYController;
float m_flSpread;
float m_flDelay;
int m_iCount;
int m_fControl;
};
void Spawn(const char *szGibModel);
void EXPORT BounceGibTouch(CBaseEntity *pOther);
void EXPORT StickyGibTouch(CBaseEntity *pOther);
void EXPORT WaitTillLand();
void LimitVelocity();
class CMortar: public CGrenade {
public:
virtual void Spawn() = 0;
virtual void Precache() = 0;
static void SpawnHeadGib(entvars_t *pevVictim);
static void SpawnRandomGibs(entvars_t *pevVictim, int cGibs, int human);
static void SpawnStickyGibs(entvars_t *pevVictim, Vector vecOrigin, int cGibs);
public:
int m_spriteTexture;
int m_bloodColor;
int m_cBloodDecals;
int m_material;
float m_lifeTime;
};

View File

@ -6,16 +6,15 @@
#ifndef HOOK_GAMEDLL
const Vector g_vecZero(0, 0, 0);
NOXREF u_long g_ulFrameCount = 0;
#endif
int g_Language;
NOXREF u_long g_ulModelIndexEyes;
Vector g_vecAttackDir;
int g_iSkillLevel;
int gDisplayTitle;
Vector g_vecAttackDir;
BOOL gDisplayTitle;
bool g_bIsCzeroGame = false;
bool g_bAllowedCSBot = false;
bool g_bHostageImprov = false;

View File

@ -26,23 +26,15 @@
*
*/
#ifndef GLOBALS_H
#define GLOBALS_H
#ifdef _WIN32
#pragma once
#endif
extern const Vector g_vecZero;
extern int g_Language;
extern u_long g_ulFrameCount;
extern u_long g_ulModelIndexEyes;
extern int g_iSkillLevel;
extern Vector g_vecAttackDir;
extern int g_iSkillLevel;
extern int gDisplayTitle;
extern BOOL gDisplayTitle;
extern bool g_bIsCzeroGame;
extern bool g_bAllowedCSBot;
extern bool g_bHostageImprov;
#endif // GLOBALS_H

View File

@ -1,162 +0,0 @@
#include "precompiled.h"
BOOL g_fDrawLines = FALSE;
NOXREF BOOL FBoxVisible(entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize)
{
// don't look through water
if ((pevLooker->waterlevel != 3 && pevTarget->waterlevel == 3) || (pevLooker->waterlevel == 3 && pevTarget->waterlevel == 0))
{
return FALSE;
}
TraceResult tr;
//look through the monster's 'eyes'
Vector vecLookerOrigin = pevLooker->origin + pevLooker->view_ofs;
for (int i = 0; i < 5; ++i)
{
Vector vecTarget = pevTarget->origin;
vecTarget.x += RANDOM_FLOAT(pevTarget->mins.x + flSize, pevTarget->maxs.x - flSize);
vecTarget.y += RANDOM_FLOAT(pevTarget->mins.y + flSize, pevTarget->maxs.y - flSize);
vecTarget.z += RANDOM_FLOAT(pevTarget->mins.z + flSize, pevTarget->maxs.z - flSize);
UTIL_TraceLine(vecLookerOrigin, vecTarget, ignore_monsters, ignore_glass, ENT(pevLooker), &tr);
if (tr.flFraction == 1.0f)
{
vecTargetOrigin = vecTarget;
// line of sight is valid.
return TRUE;
}
}
// Line of sight is not established
return FALSE;
}
// VecCheckToss - returns the velocity at which an object should be lobbed from vecspot1 to land near vecspot2.
// returns g_vecZero if toss is not feasible.
NOXREF Vector VecCheckToss(entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj)
{
TraceResult tr;
Vector vecMidPoint; // halfway point between Spot1 and Spot2
Vector vecApex; // highest point
Vector vecScale;
Vector vecGrenadeVel;
Vector vecTemp;
float flGravity = g_psv_gravity->value * flGravityAdj;
if (vecSpot2.z - vecSpot1.z > 500)
{
// to high, fail
return g_vecZero;
}
UTIL_MakeVectors(pev->angles);
// toss a little bit to the left or right, not right down on the enemy's bean (head).
vecSpot2 = vecSpot2 + gpGlobals->v_right * (RANDOM_FLOAT(-8, 8) + RANDOM_FLOAT(-16, 16));
vecSpot2 = vecSpot2 + gpGlobals->v_forward * (RANDOM_FLOAT(-8, 8) + RANDOM_FLOAT(-16, 16));
// calculate the midpoint and apex of the 'triangle'
// UNDONE: normalize any Z position differences between spot1 and spot2 so that triangle is always RIGHT
// How much time does it take to get there?
// get a rough idea of how high it can be thrown
vecMidPoint = vecSpot1 + (vecSpot2 - vecSpot1) * 0.5f;
UTIL_TraceLine(vecMidPoint, vecMidPoint + Vector(0, 0, 500), ignore_monsters, ENT(pev), &tr);
vecMidPoint = tr.vecEndPos;
// (subtract 15 so the grenade doesn't hit the ceiling)
vecMidPoint.z -= 15;
if (vecMidPoint.z < vecSpot1.z || vecMidPoint.z < vecSpot2.z)
{
// to not enough space, fail
return g_vecZero;
}
// How high should the grenade travel to reach the apex
float distance1 = (vecMidPoint.z - vecSpot1.z);
float distance2 = (vecMidPoint.z - vecSpot2.z);
// How long will it take for the grenade to travel this distance
float time1 = Q_sqrt(distance1 / (0.5f * flGravity));
float time2 = Q_sqrt(distance2 / (0.5f * flGravity));
if (time1 < 0.1f)
{
// too close
return g_vecZero;
}
// how hard to throw sideways to get there in time.
vecGrenadeVel = (vecSpot2 - vecSpot1) / (time1 + time2);
// how hard upwards to reach the apex at the right time.
vecGrenadeVel.z = flGravity * time1;
// find the apex
vecApex = vecSpot1 + vecGrenadeVel * time1;
vecApex.z = vecMidPoint.z;
UTIL_TraceLine(vecSpot1, vecApex, dont_ignore_monsters, ENT(pev), &tr);
if (tr.flFraction != 1.0f)
{
// fail!
return g_vecZero;
}
// UNDONE: either ignore monsters or change it to not care if we hit our enemy
UTIL_TraceLine(vecSpot2, vecApex, ignore_monsters, ENT(pev), &tr);
if (tr.flFraction != 1.0)
{
// fail!
return g_vecZero;
}
return vecGrenadeVel;
}
// VecCheckThrow - returns the velocity vector at which an object should be thrown from vecspot1 to hit vecspot2.
// returns g_vecZero if throw is not feasible.
NOXREF Vector VecCheckThrow(entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj)
{
float flGravity = g_psv_gravity->value * flGravityAdj;
Vector vecGrenadeVel = (vecSpot2 - vecSpot1);
// throw at a constant time
float time = vecGrenadeVel.Length() / flSpeed;
vecGrenadeVel = vecGrenadeVel * (1.0f / time);
// adjust upward toss to compensate for gravity loss
vecGrenadeVel.z += flGravity * time * 0.5f;
Vector vecApex = vecSpot1 + (vecSpot2 - vecSpot1) * 0.5f;
vecApex.z += 0.5f * flGravity * (time * 0.5f) * (time * 0.5f);
TraceResult tr;
UTIL_TraceLine(vecSpot1, vecApex, dont_ignore_monsters, ENT(pev), &tr);
if (tr.flFraction != 1.0f)
{
// fail!
return g_vecZero;
}
UTIL_TraceLine(vecSpot2, vecApex, ignore_monsters, ENT(pev), &tr);
if (tr.flFraction != 1.0f)
{
// fail!
return g_vecZero;
}
return vecGrenadeVel;
}

View File

@ -35,7 +35,9 @@ void CRecharge::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseToggle::KeyValue(pkvd);
}
}
void CRecharge::Spawn()
@ -50,7 +52,14 @@ void CRecharge::Spawn()
UTIL_SetSize(pev, pev->mins, pev->maxs);
SET_MODEL(ENT(pev), STRING(pev->model));
m_iJuice = int(gSkillData.suitchargerCapacity);
int armorValue = (int)gSkillData.suitchargerCapacity;
#ifdef REGAMEDLL_FIXES
if (pev->armorvalue != 0.0f) {
armorValue = (int)pev->armorvalue;
}
#endif
m_iJuice = armorValue;
pev->frame = 0;
}
@ -120,6 +129,12 @@ void CRecharge::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT
// charge the player
if (m_hActivator->pev->armorvalue < 100)
{
#ifdef REGAMEDLL_FIXES
CBasePlayer *pPlayer = m_hActivator.Get<CBasePlayer>();
if (pPlayer->m_iKevlar == ARMOR_NONE)
pPlayer->m_iKevlar = ARMOR_KEVLAR;
#endif
m_iJuice--;
m_hActivator->pev->armorvalue += 1.0f;
@ -133,7 +148,15 @@ void CRecharge::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT
void CRecharge::Recharge()
{
m_iJuice = gSkillData.suitchargerCapacity;
int armorValue = (int)gSkillData.suitchargerCapacity;
#ifdef REGAMEDLL_FIXES
if (pev->armorvalue != 0.0f) {
armorValue = (int)pev->armorvalue;
}
#endif
m_iJuice = armorValue;
pev->frame = 0;
SetThink(&CRecharge::SUB_DoNothing);
}
@ -152,5 +175,7 @@ void CRecharge::Off()
SetThink(&CRecharge::Recharge);
}
else
{
SetThink(&CRecharge::SUB_DoNothing);
}
}

View File

@ -26,11 +26,7 @@
*
*/
#ifndef H_BATTERY_H
#define H_BATTERY_H
#ifdef _WIN32
#pragma once
#endif
class CRecharge: public CBaseToggle
{
@ -56,5 +52,3 @@ public:
int m_iOn;
float m_flSoundTime;
};
#endif // H_BATTERY_H

View File

@ -351,17 +351,16 @@ void CWreckage::Think()
}
}
Vector VecSrc;
Vector vecSrc;
vecSrc.x = RANDOM_FLOAT(pev->absmin.x, pev->absmax.x);
vecSrc.y = RANDOM_FLOAT(pev->absmin.y, pev->absmax.y);
vecSrc.z = RANDOM_FLOAT(pev->absmin.z, pev->absmax.z);
VecSrc.x = RANDOM_FLOAT(pev->absmin.x, pev->absmax.x);
VecSrc.y = RANDOM_FLOAT(pev->absmin.y, pev->absmax.y);
VecSrc.z = RANDOM_FLOAT(pev->absmin.z, pev->absmax.z);
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, VecSrc);
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, vecSrc);
WRITE_BYTE(TE_SMOKE);
WRITE_COORD(VecSrc.x);
WRITE_COORD(VecSrc.y);
WRITE_COORD(VecSrc.z);
WRITE_COORD(vecSrc.x);
WRITE_COORD(vecSrc.y);
WRITE_COORD(vecSrc.z);
WRITE_SHORT(g_sModelIndexSmoke);
WRITE_BYTE(RANDOM_LONG(0, 49) + 50); // scale * 10
WRITE_BYTE(RANDOM_LONG(0, 3) + 8); // framerate

View File

@ -26,11 +26,7 @@
*
*/
#ifndef H_CYCLER_H
#define H_CYCLER_H
#ifdef _WIN32
#pragma once
#endif
class CCycler: public CBaseMonster
{
@ -55,7 +51,7 @@ public:
int m_animate;
};
// we should get rid of all the other cyclers and replace them with this.
// We should get rid of all the other cyclers and replace them with this.
class CGenericCycler: public CCycler
{
public:
@ -128,5 +124,3 @@ public:
int m_flStartTime;
};
#endif // H_CYCLER_H

View File

@ -39,9 +39,17 @@ BOOL CHealthKit::MyTouch(CBasePlayer *pPlayer)
return FALSE;
#endif
if (pPlayer->TakeHealth(gSkillData.healthkitCapacity, DMG_GENERIC))
auto healthValue = gSkillData.healthkitCapacity;
#ifdef REGAMEDLL_FIXES
if (pev->health != 0.0f) {
healthValue = pev->health;
}
#endif
if (pPlayer->TakeHealth(healthValue, DMG_GENERIC))
{
MESSAGE_BEGIN(MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgItemPickup, nullptr, pPlayer->pev);
WRITE_STRING(STRING(pev->classname));
MESSAGE_END();
@ -73,7 +81,9 @@ void CWallHealth::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE;
}
else
{
CBaseToggle::KeyValue(pkvd);
}
}
void CWallHealth::Spawn()
@ -89,7 +99,14 @@ void CWallHealth::Spawn()
SET_MODEL(ENT(pev), STRING(pev->model));
m_iJuice = int(gSkillData.healthchargerCapacity);
int healthValue = (int)gSkillData.healthchargerCapacity;
#ifdef REGAMEDLL_FIXES
if (pev->health != 0.0f) {
healthValue = (int)pev->health;
}
#endif
m_iJuice = healthValue;
pev->frame = 0.0f;
}
@ -160,7 +177,16 @@ void CWallHealth::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us
void CWallHealth::Recharge()
{
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", VOL_NORM, ATTN_NORM);
m_iJuice = gSkillData.healthchargerCapacity;
int healthValue = (int)gSkillData.healthchargerCapacity;
#ifdef REGAMEDLL_FIXES
if (pev->health != 0.0f) {
healthValue = (int)pev->health;
}
#endif
m_iJuice = healthValue;
pev->frame = 0.0f;
SetThink(&CWallHealth::SUB_DoNothing);
}
@ -173,11 +199,13 @@ void CWallHealth::Off()
m_iOn = 0;
if (!m_iJuice && ((m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime()) > 0))
if (!m_iJuice && ((m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime()) > 0))
{
pev->nextthink = pev->ltime + m_iReactivate;
SetThink(&CWallHealth::Recharge);
}
else
{
SetThink(&CWallHealth::SUB_DoNothing);
}
}

View File

@ -26,11 +26,7 @@
*
*/
#ifndef HEALTKIT_H
#define HEALTKIT_H
#ifdef _WIN32
#pragma once
#endif
class CHealthKit: public CItem
{
@ -63,5 +59,3 @@ public:
int m_iOn;
float m_flSoundTime;
};
#endif // HEALTKIT_H

View File

@ -8,14 +8,14 @@ CHintMessage::CHintMessage(const char *hintString, bool isHint, CUtlVector<const
if (args)
{
for (int i = 0; i < args->Count(); ++i)
for (int i = 0; i < args->Count(); i++)
m_args.AddToTail(CloneString((*args)[i]));
}
}
CHintMessage::~CHintMessage()
{
for (int i = 0; i < m_args.Count(); ++i)
for (int i = 0; i < m_args.Count(); i++)
delete[] m_args[i];
m_args.RemoveAll();
@ -30,7 +30,7 @@ void CHintMessageQueue::Reset()
{
m_tmMessageEnd = 0;
for (int i = 0; i < m_messages.Count(); ++i)
for (int i = 0; i < m_messages.Count(); i++)
delete m_messages[i];
m_messages.RemoveAll();

View File

@ -26,35 +26,33 @@
*
*/
#ifndef HINTMESSAGE_H
#define HINTMESSAGE_H
#ifdef _WIN32
#pragma once
#endif
#define DHF_ROUND_STARTED (1<<1)
#define DHF_HOSTAGE_SEEN_FAR (1<<2)
#define DHF_HOSTAGE_SEEN_NEAR (1<<3)
#define DHF_HOSTAGE_USED (1<<4)
#define DHF_HOSTAGE_INJURED (1<<5)
#define DHF_HOSTAGE_KILLED (1<<6)
#define DHF_FRIEND_SEEN (1<<7)
#define DHF_ENEMY_SEEN (1<<8)
#define DHF_FRIEND_INJURED (1<<9)
#define DHF_FRIEND_KILLED (1<<10)
#define DHF_ENEMY_KILLED (1<<11)
#define DHF_BOMB_RETRIEVED (1<<12)
#define DHF_AMMO_EXHAUSTED (1<<15)
#define DHF_IN_TARGET_ZONE (1<<16)
#define DHF_IN_RESCUE_ZONE (1<<17)
#define DHF_IN_ESCAPE_ZONE (1<<18)
#define DHF_IN_VIPSAFETY_ZONE (1<<19)
#define DHF_NIGHTVISION (1<<20)
#define DHF_HOSTAGE_CTMOVE (1<<21)
#define DHF_SPEC_DUCK (1<<22)
#include "utlvector.h"
#define DHM_ROUND_CLEAR (DHF_ROUND_STARTED | DHF_HOSTAGE_KILLED | DHF_FRIEND_KILLED | DHF_BOMB_RETRIEVED)
#define DHM_CONNECT_CLEAR (DHF_HOSTAGE_SEEN_FAR | DHF_HOSTAGE_SEEN_NEAR | DHF_HOSTAGE_USED | DHF_HOSTAGE_INJURED | DHF_FRIEND_SEEN | DHF_ENEMY_SEEN | DHF_FRIEND_INJURED | DHF_ENEMY_KILLED | DHF_AMMO_EXHAUSTED | DHF_IN_TARGET_ZONE | DHF_IN_RESCUE_ZONE | DHF_IN_ESCAPE_ZONE | DHF_IN_VIPSAFETY_ZONE | DHF_HOSTAGE_CTMOVE | DHF_SPEC_DUCK)
#define DHF_ROUND_STARTED BIT(1)
#define DHF_HOSTAGE_SEEN_FAR BIT(2)
#define DHF_HOSTAGE_SEEN_NEAR BIT(3)
#define DHF_HOSTAGE_USED BIT(4)
#define DHF_HOSTAGE_INJURED BIT(5)
#define DHF_HOSTAGE_KILLED BIT(6)
#define DHF_FRIEND_SEEN BIT(7)
#define DHF_ENEMY_SEEN BIT(8)
#define DHF_FRIEND_INJURED BIT(9)
#define DHF_FRIEND_KILLED BIT(10)
#define DHF_ENEMY_KILLED BIT(11)
#define DHF_BOMB_RETRIEVED BIT(12)
#define DHF_AMMO_EXHAUSTED BIT(15)
#define DHF_IN_TARGET_ZONE BIT(16)
#define DHF_IN_RESCUE_ZONE BIT(17)
#define DHF_IN_ESCAPE_ZONE BIT(18)
#define DHF_IN_VIPSAFETY_ZONE BIT(19)
#define DHF_NIGHTVISION BIT(20)
#define DHF_HOSTAGE_CTMOVE BIT(21)
#define DHF_SPEC_DUCK BIT(22)
#define DHM_ROUND_CLEAR (DHF_ROUND_STARTED | DHF_HOSTAGE_KILLED | DHF_FRIEND_KILLED | DHF_BOMB_RETRIEVED)
#define DHM_CONNECT_CLEAR (DHF_HOSTAGE_SEEN_FAR | DHF_HOSTAGE_SEEN_NEAR | DHF_HOSTAGE_USED | DHF_HOSTAGE_INJURED | DHF_FRIEND_SEEN | DHF_ENEMY_SEEN | DHF_FRIEND_INJURED | DHF_ENEMY_KILLED | DHF_AMMO_EXHAUSTED | DHF_IN_TARGET_ZONE | DHF_IN_RESCUE_ZONE | DHF_IN_ESCAPE_ZONE | DHF_IN_VIPSAFETY_ZONE | DHF_HOSTAGE_CTMOVE | DHF_SPEC_DUCK)
class CHintMessage
{
@ -85,5 +83,3 @@ private:
float m_tmMessageEnd;
CUtlVector<CHintMessage *> m_messages;
};
#endif // HINTMESSAGE_H

View File

@ -5,10 +5,10 @@
*/
#ifndef HOOK_GAMEDLL
cvar_t cv_hostage_debug = { "hostage_debug", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_hostage_stop = { "hostage_stop", "0", FCVAR_SERVER, 0.0f, NULL };
cvar_t cv_hostage_debug = { "hostage_debug", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_hostage_stop = { "hostage_stop", "0", FCVAR_SERVER, 0.0f, nullptr };
CHostageManager *g_pHostages = NULL;
CHostageManager *g_pHostages = nullptr;
int g_iHostageNumber = 0;
#endif
@ -205,8 +205,8 @@ void CHostage::Spawn()
m_flNextChange = 0;
m_State = STAND;
m_hTargetEnt = NULL;
m_hStoppedTargetEnt = NULL;
m_hTargetEnt = nullptr;
m_hStoppedTargetEnt = nullptr;
m_vPathToFollow[0] = Vector(0, 0, 0);
m_flFlinchTime = 0;
m_bRescueMe = FALSE;
@ -242,7 +242,7 @@ void CHostage::Spawn()
m_LocalNav = new CLocalNav(this);
m_bStuck = FALSE;
m_flStuckTime = 0;
m_improv = NULL;
m_improv = nullptr;
}
void CHostage::Precache()
@ -332,10 +332,10 @@ void CHostage::IdleThink()
}
else
{
if (m_improv != NULL)
if (m_improv)
{
delete m_improv;
m_improv = NULL;
m_improv = nullptr;
}
}
@ -344,7 +344,7 @@ void CHostage::IdleThink()
flInterval = StudioFrameAdvance();
DispatchAnimEvents(flInterval);
if (m_improv != NULL)
if (m_improv)
{
m_improv->OnUpkeep(upkeepRate);
}
@ -362,36 +362,36 @@ void CHostage::IdleThink()
return;
}
if (m_hTargetEnt != NULL && (m_bStuck && gpGlobals->time - m_flStuckTime > 5.0f || m_hTargetEnt->pev->deadflag != DEAD_NO))
if (m_hTargetEnt && (m_bStuck && gpGlobals->time - m_flStuckTime > 5.0f || m_hTargetEnt->pev->deadflag != DEAD_NO))
{
m_State = STAND;
m_hTargetEnt = NULL;
m_hTargetEnt = nullptr;
m_bStuck = FALSE;
}
if (m_hTargetEnt != NULL || m_improv != NULL)
if (m_hTargetEnt || m_improv)
{
CBasePlayer *player = NULL;
CBasePlayer *pPlayer = nullptr;
if (m_improv != NULL)
if (m_improv)
{
if (m_improv->IsFollowing())
player = (CBasePlayer *)m_improv->GetFollowLeader();
pPlayer = m_improv->GetFollowLeader();
}
else
player = GetClassPtr<CCSPlayer>((CBasePlayer *)m_hTargetEnt->pev);
pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)m_hTargetEnt->pev);
if (player == NULL || player->m_iTeam == CT)
if (!pPlayer || pPlayer->m_iTeam == CT)
{
if (!CSGameRules()->m_bMapHasRescueZone)
{
bool bResHostagePt = false;
if (UTIL_FindEntityByClassname(NULL, "info_hostage_rescue"))
if (UTIL_FindEntityByClassname(nullptr, "info_hostage_rescue"))
bResHostagePt = true;
CBaseEntity *pSpot = NULL;
while ((pSpot = UTIL_FindEntityByClassname(pSpot, "info_hostage_rescue")) != NULL)
CBaseEntity *pSpot = nullptr;
while ((pSpot = UTIL_FindEntityByClassname(pSpot, "info_hostage_rescue")))
{
if ((pSpot->pev->origin - pev->origin).Length() < RESCUE_HOSTAGES_RADIUS)
{
@ -402,7 +402,7 @@ void CHostage::IdleThink()
if (!bResHostagePt)
{
pSpot = NULL;
pSpot = nullptr;
while ((pSpot = UTIL_FindEntityByClassname(pSpot, "info_player_start")))
{
@ -419,21 +419,21 @@ void CHostage::IdleThink()
{
if (TheBots)
{
TheBots->OnEvent(EVENT_HOSTAGE_RESCUED, player, this);
TheBots->OnEvent(EVENT_HOSTAGE_RESCUED, pPlayer, this);
}
if (TheCareerTasks && CSGameRules()->IsCareer() && player && !player->IsBot())
if (TheCareerTasks && CSGameRules()->IsCareer() && pPlayer && !pPlayer->IsBot())
{
TheCareerTasks->HandleEvent(EVENT_HOSTAGE_RESCUED, player);
TheCareerTasks->HandleEvent(EVENT_HOSTAGE_RESCUED, pPlayer);
}
pev->deadflag = DEAD_RESPAWNABLE;
if (player)
if (pPlayer)
{
player->AddAccount(REWARD_TAKEN_HOSTAGE, RT_HOSTAGE_RESCUED);
UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Rescued_A_Hostage\"\n", STRING(player->pev->netname),
GETPLAYERUSERID(player->edict()), GETPLAYERAUTHID(player->edict()));
pPlayer->AddAccount(REWARD_TAKEN_HOSTAGE, RT_HOSTAGE_RESCUED);
UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Rescued_A_Hostage\"\n", STRING(pPlayer->pev->netname),
GETPLAYERUSERID(pPlayer->edict()), GETPLAYERAUTHID(pPlayer->edict()));
}
SendHostageEventMsg();
@ -441,7 +441,7 @@ void CHostage::IdleThink()
MESSAGE_BEGIN(MSG_SPEC, SVC_DIRECTOR);
WRITE_BYTE(9);
WRITE_BYTE(DRC_CMD_EVENT);
WRITE_SHORT(player != NULL ? player->entindex() : 0);
WRITE_SHORT(pPlayer ? pPlayer->entindex() : 0);
WRITE_SHORT(entindex());
WRITE_LONG(15);
MESSAGE_END();
@ -452,12 +452,12 @@ void CHostage::IdleThink()
CSGameRules()->m_iHostagesRescued++;
CSGameRules()->CheckWinConditions();
Broadcast((player != NULL) ? "rescued" : "escaped");
Broadcast(pPlayer ? "rescued" : "escaped");
}
}
}
if (m_improv != NULL)
if (m_improv)
{
m_improv->OnUpdate(updateRate);
}
@ -529,8 +529,8 @@ void CHostage::RePosition()
pev->angles = m_vStartAngles;
pev->effects &= ~EF_NODRAW;
m_hTargetEnt = NULL;
m_hStoppedTargetEnt = NULL;
m_hTargetEnt = nullptr;
m_hStoppedTargetEnt = nullptr;
m_bTouched = FALSE;
m_bRescueMe = FALSE;
@ -587,7 +587,7 @@ BOOL CHostage::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float
PlayPainSound();
CBasePlayer *pAttacker = NULL;
CBasePlayer *pAttacker = nullptr;
if (pevAttacker)
{
CBaseEntity *pAttackingEnt = GetClassPtr<CCSEntity>((CBaseEntity *)pevAttacker);
@ -704,7 +704,7 @@ void CHostage::SetFlinchActivity()
{
Activity activity = ACT_SMALL_FLINCH;
if (m_improv != NULL)
if (m_improv)
{
m_improv->Flinch(activity);
return;
@ -715,7 +715,7 @@ void CHostage::SetFlinchActivity()
void CHostage::SetDeathActivity()
{
if (m_improv != NULL && m_improv->IsCrouching())
if (m_improv && m_improv->IsCrouching())
{
m_improv->CrouchDie();
return;
@ -809,11 +809,11 @@ void CHostage::ApplyHostagePenalty(CBasePlayer *pAttacker)
}
else if (pAttacker->m_iHostagesKilled >= iHostagePenalty)
{
#ifdef REGAMEDLL_FIXES
#ifdef REGAMEDLL_FIXES
SERVER_COMMAND(UTIL_VarArgs("kick #%d\n", GETPLAYERUSERID(pAttacker->edict())));
#else
#else
CLIENT_COMMAND(pAttacker->edict(), "disconnect\n");
#endif
#endif
}
}
}
@ -832,7 +832,6 @@ void CHostage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
#endif
CBasePlayer *pPlayer = (CBasePlayer *)pActivator;
if (pPlayer->m_iTeam != CT)
{
if (!(pPlayer->m_flDisplayHistory & DHF_HOSTAGE_CTMOVE))
@ -848,7 +847,7 @@ void CHostage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
{
m_flNextChange = gpGlobals->time + 1.0f;
if (m_improv != NULL)
if (m_improv)
{
if (m_improv->IsFollowing() && pActivator == m_improv->GetFollowLeader())
{
@ -860,7 +859,7 @@ void CHostage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
{
m_improv->Follow(pPlayer);
if (TheBots != NULL)
if (TheBots)
{
TheBots->OnEvent(EVENT_HOSTAGE_USED, pActivator);
}
@ -874,12 +873,12 @@ void CHostage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
{
m_State = FOLLOW;
m_hTargetEnt = pActivator;
m_hStoppedTargetEnt = NULL;
m_hStoppedTargetEnt = nullptr;
}
else if (m_State == FOLLOW)
{
m_State = STAND;
m_hTargetEnt = NULL;
m_hTargetEnt = nullptr;
m_hStoppedTargetEnt = pActivator;
}
else
@ -888,7 +887,7 @@ void CHostage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
if (m_State == FOLLOW)
{
PlayFollowRescueSound();
if (TheBots != NULL)
if (TheBots)
{
TheBots->OnEvent(EVENT_HOSTAGE_USED, pActivator);
}
@ -934,7 +933,7 @@ void CHostage::Touch(CBaseEntity *pOther)
Vector2D vPush;
const float pushForce = 50.0f;
if (m_improv != NULL)
if (m_improv)
{
m_improv->OnTouch(pOther);
return;
@ -972,14 +971,14 @@ void CHostage::DoFollow()
float flRadius = 0;
float flDistToDest;
if (m_hTargetEnt == NULL)
if (!m_hTargetEnt)
return;
if (cv_hostage_stop.value > 0.0f)
{
m_State = STAND;
m_hTargetEnt = NULL;
m_hStoppedTargetEnt = NULL;
m_hTargetEnt = nullptr;
m_hStoppedTargetEnt = nullptr;
return;
}
@ -1079,7 +1078,7 @@ void CHostage::MoveToward(const Vector &vecLoc)
vecMove = vecLoc - pev->origin;
Vector vecAng(0, UTIL_VecToAngles(vecMove).y, 0);
UTIL_MakeVectorsPrivate(vecAng, vecFwd, NULL, NULL);
UTIL_MakeVectorsPrivate(vecAng, vecFwd, nullptr, nullptr);
if ((vecFwd * s_flStepSize_LocalNav).Length2D() <= (vecLoc - pev->origin).Length2D())
flDist = (vecFwd * s_flStepSize_LocalNav).Length2D();
@ -1184,8 +1183,8 @@ void CHostage::NavReady()
void CHostage::SendHostagePositionMsg()
{
CBaseEntity *pEntity = NULL;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")) != NULL)
CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
{
if (FNullEnt(pEntity->edict()))
break;
@ -1200,7 +1199,7 @@ void CHostage::SendHostagePositionMsg()
if (pTempPlayer->pev->deadflag == DEAD_NO && pTempPlayer->m_iTeam == CT)
{
MESSAGE_BEGIN(MSG_ONE, gmsgHostagePos, NULL, pTempPlayer->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgHostagePos, nullptr, pTempPlayer->pev);
WRITE_BYTE(0);
WRITE_BYTE(m_iHostageIndex);
WRITE_COORD(pev->origin.x);
@ -1213,8 +1212,8 @@ void CHostage::SendHostagePositionMsg()
void CHostage::SendHostageEventMsg()
{
CBaseEntity *pEntity = NULL;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")) != NULL)
CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
{
if (FNullEnt(pEntity->edict()))
break;
@ -1229,7 +1228,7 @@ void CHostage::SendHostageEventMsg()
if (pTempPlayer->pev->deadflag == DEAD_NO && pTempPlayer->m_iTeam == CT)
{
MESSAGE_BEGIN(MSG_ONE, gmsgHostageK, NULL, pTempPlayer->pev);
MESSAGE_BEGIN(MSG_ONE, gmsgHostageK, nullptr, pTempPlayer->pev);
WRITE_BYTE(m_iHostageIndex);
MESSAGE_END();
}
@ -1281,7 +1280,7 @@ void CHostage::PreThink()
float flRaisedDist;
float flInterval;
if (m_improv != NULL)
if (m_improv)
{
return;
}
@ -1358,10 +1357,10 @@ void Hostage_RegisterCVars()
void InstallHostageManager()
{
if (g_pHostages != NULL)
if (g_pHostages)
{
delete g_pHostages;
g_pHostages = NULL;
g_pHostages = nullptr;
}
g_pHostages = new CHostageManager;
@ -1377,7 +1376,7 @@ void CHostageManager::ServerActivate()
{
m_hostageCount = 0;
CBaseEntity *pEntity = NULL;
CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "hostage_entity")))
{
AddHostage((CHostage *)pEntity);
@ -1403,9 +1402,9 @@ void CHostageManager::ServerDeactivate()
void CHostageManager::RestartRound()
{
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
if (m_hostage[i]->m_improv != NULL)
if (m_hostage[i]->m_improv)
{
m_hostage[i]->m_improv->OnReset();
}
@ -1418,7 +1417,7 @@ void CHostageManager::AddHostage(CHostage *hostage)
return;
int i;
for (i = 0; i < m_hostageCount; ++i)
for (i = 0; i < m_hostageCount; i++)
{
if (m_hostage[i] == hostage)
{
@ -1435,12 +1434,12 @@ void CHostageManager::AddHostage(CHostage *hostage)
bool CHostageManager::IsNearbyHostageTalking(CHostageImprov *improv)
{
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
const float closeRange = 500.0f;
const CHostageImprov *other = m_hostage[i]->m_improv;
if (other == NULL)
if (!other)
continue;
if (!other->IsAlive() || other == improv)
@ -1457,11 +1456,11 @@ bool CHostageManager::IsNearbyHostageTalking(CHostageImprov *improv)
bool CHostageManager::IsNearbyHostageJumping(CHostageImprov *improv)
{
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
const CHostageImprov *other = m_hostage[i]->m_improv;
if (other == NULL)
if (!other)
continue;
if (!other->IsAlive() || other == improv)
@ -1479,11 +1478,10 @@ bool CHostageManager::IsNearbyHostageJumping(CHostageImprov *improv)
void CHostageManager::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *other)
{
for (int i = 0; i < m_hostageCount; ++i)
for (int i = 0; i < m_hostageCount; i++)
{
CHostageImprov *improv = m_hostage[ i ]->m_improv;
if (improv != NULL)
if (improv)
{
improv->OnGameEvent(event, entity, other);
}
@ -1533,7 +1531,7 @@ void SimpleChatter::Shuffle(ChatterSet *chatter)
if (!chatter->needsShuffle)
return;
for (int i = 1; i < chatter->count; ++i)
for (int i = 1; i < chatter->count; i++)
{
for (int j = i; j < chatter->count; j++)
{
@ -1581,7 +1579,7 @@ float SimpleChatter::PlaySound(CBaseEntity *entity, HostageChatterType type)
sound = GetSound(type, &duration);
hostage = static_cast<CHostage *>(entity);
if (sound == NULL)
if (!sound)
{
return 0;
}
@ -1607,7 +1605,7 @@ float SimpleChatter::PlaySound(CBaseEntity *entity, HostageChatterType type)
if (type == HOSTAGE_CHATTER_CALL_TO_RESCUER)
{
if (TheBots != NULL)
if (TheBots)
{
TheBots->OnEvent(EVENT_HOSTAGE_CALLED_FOR_HELP, hostage);
}

View File

@ -26,11 +26,7 @@
*
*/
#ifndef HOSTAGE_H
#define HOSTAGE_H
#ifdef _WIN32
#pragma once
#endif
#define MAX_NODES 100
#define MAX_HOSTAGES 12
@ -298,5 +294,3 @@ inline bool AreImprovAllowed()
void Hostage_RegisterCVars();
void InstallHostageManager();
#endif // HOSTAGE_H

View File

@ -112,7 +112,7 @@ void CHostageImprov::MoveTowards(const Vector &pos, float deltaT)
// TODO: Look ahead *along path* instead of straight line
ClearPath();
if ((m_lastKnownArea == NULL || !(m_lastKnownArea->GetAttributes() & NAV_NO_JUMP))
if ((!m_lastKnownArea || !(m_lastKnownArea->GetAttributes() & NAV_NO_JUMP))
&& !IsUsingLadder() && !IsJumping() && IsOnGround() && !IsCrouching())
{
float ground;
@ -540,16 +540,16 @@ CBasePlayer *CHostageImprov::IsAnyPlayerLookingAtMe(int team, float cosTolerance
}
}
return NULL;
return nullptr;
}
CBasePlayer *CHostageImprov::GetClosestPlayerByTravelDistance(int team, float *range) const
{
CBasePlayer *close = NULL;
CBasePlayer *close = nullptr;
float closeRange = 9.9999998e10f;
if (GetLastKnownArea() == NULL)
return NULL;
if (!GetLastKnownArea())
return nullptr;
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
@ -591,7 +591,7 @@ void CHostageImprov::OnReset()
m_actualVel = Vector(0, 0, 0);
m_checkNearbyTerroristTimer.Invalidate();
m_lastKnownArea = NULL;
m_lastKnownArea = nullptr;
m_hasKnownGoodPos = false;
m_hasPriorKnownGoodPos = false;
m_isTerroristNearby = false;
@ -1038,29 +1038,31 @@ void CHostageImprov::UpdateGrenadeReactions()
if (m_grenadeTimer.IsElapsed())
{
CBaseEntity *entity = NULL;
CBaseEntity *pEntity = nullptr;
const float watchGrenadeRadius = 500.0f;
m_grenadeTimer.Start(RANDOM_FLOAT(0.4f, 0.6f));
while ((entity = UTIL_FindEntityInSphere(entity, GetCentroid(), watchGrenadeRadius)))
while ((pEntity = UTIL_FindEntityInSphere(pEntity, GetCentroid(), watchGrenadeRadius)))
{
CGrenade *grenade = static_cast<CGrenade *>(entity);
CGrenade *pGrenade = static_cast<CGrenade *>(pEntity);
if (!FClassnameIs(grenade->pev, "grenade") || grenade->m_SGSmoke > 1)
if (!FClassnameIs(pGrenade->pev, "grenade") || pGrenade->m_SGSmoke > 1)
continue;
if (IsVisible(grenade->Center()))
if (IsVisible(pGrenade->Center()))
{
Chatter(HOSTAGE_CHATTER_SAW_HE_GRENADE);
if (grenade->pev->dmg > 50.0f)
if (pGrenade->pev->dmg > 50.0f)
{
m_idleState.OnInjury();
Frighten(TERRIFIED);
}
else
{
Frighten(SCARED);
}
m_grenadeTimer.Start(10);
break;
@ -1480,22 +1482,22 @@ bool CHostageImprov::CanSeeRescueZone() const
CBasePlayer *CHostageImprov::GetClosestVisiblePlayer(int team)
{
CBasePlayer *close = NULL;
CBasePlayer *close = nullptr;
float closeRangeSq = 1e8f;
for (int i = 0; i < m_visiblePlayerCount; ++i)
{
CBasePlayer *player = (CBasePlayer *)m_visiblePlayer[i];
CBasePlayer *pPlayer = m_visiblePlayer[i];
if (player == NULL || (team > 0 && player->m_iTeam != team))
if (!pPlayer || (team > 0 && pPlayer->m_iTeam != team))
continue;
float_precision rangeSq = (GetCentroid() - player->pev->origin).LengthSquared();
float_precision rangeSq = (GetCentroid() - pPlayer->pev->origin).LengthSquared();
if (rangeSq < closeRangeSq)
{
closeRangeSq = rangeSq;
close = player;
close = pPlayer;
}
}

View File

@ -26,11 +26,7 @@
*
*/
#ifndef HOSTAGE_IMPROV_H
#define HOSTAGE_IMPROV_H
#ifdef _WIN32
#pragma once
#endif
#include "hostage/hostage.h"
#include "hostage/hostage_states.h"
@ -152,7 +148,7 @@ public:
bool IsAtHome() const;
bool CanSeeRescueZone() const;
CBaseEntity *GetFollowLeader() const { return m_followState.GetLeader(); }
CBasePlayer *GetFollowLeader() const { return m_followState.GetLeader(); }
CBasePlayer *GetClosestVisiblePlayer(int team);
float GetTimeSinceLastSawPlayer(int team);
float GetTimeSinceLastInjury();
@ -261,7 +257,7 @@ private:
Vector m_jumpTarget;
CountdownTimer m_clearPathTimer;
bool m_traversingLadder;
EHANDLE m_visiblePlayer[MAX_CLIENTS];
EntityHandle<CBasePlayer> m_visiblePlayer[MAX_CLIENTS];
int m_visiblePlayerCount;
CountdownTimer m_visionTimer;
};
@ -445,6 +441,7 @@ inline void CHostageImprov::ApplyForce2(float_precision x, float_precision y)
m_vel.y += y;
}
#endif
inline void CHostageImprov::ResetJump()
{
if (m_hasJumpedIntoAir)
@ -459,5 +456,3 @@ inline void CHostageImprov::ResetJump()
m_hasJumpedIntoAir = true;
}
}
#endif // HOSTAGE_IMPROV_H

View File

@ -20,7 +20,7 @@ int CLocalNav::tot_hostages;
CLocalNav::CLocalNav(CHostage *pOwner)
{
m_pOwner = pOwner;
m_pTargetEnt = NULL;
m_pTargetEnt = nullptr;
m_nodeArr = new localnode_t[MAX_NODES];
if (tot_hostages >= MAX_HOSTAGES_NAV)
@ -33,8 +33,11 @@ CLocalNav::CLocalNav(CHostage *pOwner)
CLocalNav::~CLocalNav()
{
delete[] m_nodeArr;
m_nodeArr = NULL;
if (m_nodeArr)
{
delete[] m_nodeArr;
m_nodeArr = nullptr;
}
}
node_index_t CLocalNav::AddNode(node_index_t nindexParent, Vector &vecLoc, int offsetX, int offsetY, byte bDepth)
@ -654,11 +657,8 @@ BOOL CLocalNav::StepJumpable(Vector &vecSource, Vector &vecDest, int fNoMonsters
{
Vector vecStepStart;
Vector vecStepDest;
//BOOL fFwdTrace = FALSE; // unused?
float flFwdFraction;
float flJumpHeight = s_flStepSize + 1.0f;
//BOOL fJumpClear = FALSE; // unused?
//edict_t *hit = NULL; // unused?
vecStepStart = vecSource;
vecStepStart.z += flJumpHeight;
@ -747,11 +747,11 @@ BOOL CLocalNav::LadderHit(Vector &vecSource, Vector &vecDest, TraceResult &tr)
void CLocalNav::Think()
{
EHANDLE hCallback;
static cvar_t *sv_stepsize = NULL;
static cvar_t *sv_stepsize = nullptr;
if (gpGlobals->time >= flNextCvarCheck)
{
if (sv_stepsize != NULL)
if (sv_stepsize)
s_flStepSize = sv_stepsize->value;
else
{
@ -788,7 +788,7 @@ void CLocalNav::Think()
tot_inqueue--;
if (!tot_inqueue)
{
hCallback = NULL;
hCallback = nullptr;
break;
}
@ -857,7 +857,7 @@ void CLocalNav::HostagePrethink()
{
for (int iCount = 0; iCount < tot_hostages; ++iCount)
{
if (hostages[ iCount ] != NULL)
if (hostages[ iCount ])
{
GetClassPtr<CCSHostage>((CHostage *)hostages[ iCount ]->pev)->PreThink();
}

View File

@ -26,18 +26,14 @@
*
*/
#ifndef HOSTAGE_LOCALNAV_H
#define HOSTAGE_LOCALNAV_H
#ifdef _WIN32
#pragma once
#endif
#define NODE_INVALID_EMPTY -1
#define NODE_INVALID_EMPTY -1
#define PATH_TRAVERSABLE_EMPTY 0
#define PATH_TRAVERSABLE_SLOPE 1
#define PATH_TRAVERSABLE_STEP 2
#define PATH_TRAVERSABLE_STEPJUMPABLE 3
#define PATH_TRAVERSABLE_EMPTY 0
#define PATH_TRAVERSABLE_SLOPE 1
#define PATH_TRAVERSABLE_STEP 2
#define PATH_TRAVERSABLE_STEPJUMPABLE 3
typedef int node_index_t;
@ -64,10 +60,10 @@ public:
void SetTargetEnt(CBaseEntity *pTarget)
{
if (pTarget != NULL)
if (pTarget)
m_pTargetEnt = pTarget->edict();
else
m_pTargetEnt = NULL;
m_pTargetEnt = nullptr;
}
node_index_t FindPath(Vector &vecStart, Vector &vecDest, float flTargetRadius, int fNoMonsters);
@ -116,5 +112,3 @@ private:
node_index_t m_nindexAvailableNode;
Vector m_vecStartingLoc;
};
#endif // HOSTAGE_LOCALNAV_H

View File

@ -26,11 +26,7 @@
*
*/
#ifndef HOSTAGE_STATES_H
#define HOSTAGE_STATES_H
#ifdef _WIN32
#pragma once
#endif
class CHostageImprov;
@ -185,11 +181,11 @@ public:
virtual void UpdateStationaryAnimation(CHostageImprov *improv);
public:
void SetLeader(CBaseEntity *leader) { m_leader = leader; }
CBaseEntity *GetLeader() const { return m_leader; }
void SetLeader(CBasePlayer *leader) { m_leader = leader; }
CBasePlayer *GetLeader() const { return m_leader; }
private:
mutable EHANDLE m_leader;
mutable EntityHandle<CBasePlayer> m_leader;
Vector m_lastLeaderPos;
bool m_isWaiting;
float m_stopRange;
@ -259,5 +255,3 @@ private:
bool m_isHolding;
CountdownTimer m_holdTimer;
};
#endif // HOSTAGE_STATES_H

View File

@ -30,14 +30,16 @@ void HostageAnimateState::AddSequence(CHostageImprov *improv, const char *seqNam
if (m_sequenceCount >= MAX_SEQUENCES)
return;
if (seqName != NULL)
if (seqName)
seqIndex = hostage->LookupSequence(seqName);
else
seqIndex = -1;
m_sequence[m_sequenceCount].seqID = seqIndex;
m_sequence[m_sequenceCount].holdTime = holdTime;
m_sequence[m_sequenceCount++].rate = rate;
m_sequence[m_sequenceCount].rate = rate;
m_sequenceCount++;
m_currentSequence = 0;
StartSequence(improv, m_sequence);
@ -46,13 +48,15 @@ void HostageAnimateState::AddSequence(CHostageImprov *improv, const char *seqNam
void HostageAnimateState::AddSequence(CHostageImprov *improv, int activity, float holdTime, float rate)
{
CHostage *hostage = improv->GetEntity();
void *model = GET_MODEL_PTR(hostage->edict());
if (model != NULL)
void *model = GET_MODEL_PTR(hostage->edict());
if (model)
{
m_sequence[m_sequenceCount].seqID = LookupActivity(model, hostage->pev, activity);
m_sequence[m_sequenceCount].holdTime = holdTime;
m_sequence[m_sequenceCount++].rate = rate;
m_sequence[m_sequenceCount].rate = rate;
m_sequenceCount++;
m_currentSequence = 0;
}

Some files were not shown because too many files have changed in this diff Show More