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 import org.apache.commons.io.FilenameUtils
void _copyFileToDir(String from, String to) { 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) 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) 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) if (cfg instanceof MsvcToolchainConfig)
{ {
@ -140,7 +140,7 @@ void setupToolchain(NativeBinarySpec b)
pchSourceSet: 'regamedll_pch' pchSourceSet: 'regamedll_pch'
); );
cfg.compilerOptions.languageStandard = 'c++0x' cfg.compilerOptions.languageStandard = 'c++14'
cfg.defines([ cfg.defines([
'_stricmp': 'strcasecmp', '_stricmp': 'strcasecmp',
'_strnicmp': 'strncasecmp', '_strnicmp': 'strncasecmp',

View File

@ -283,13 +283,7 @@
// volume values // volume values
#define VOL_NORM 1.0 #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 // Break Model Defines
#define BREAK_TYPEMASK 0x4F #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 #endif // __cplusplus
// bitwise operators templates // bitwise operators templates
template<class T, class type=typename std::underlying_type<T>::type> //template<class T, class type=typename std::underlying_type<T>::type>
inline T operator~ (T a) { return (T)~(type)a; } //inline T operator~ (T a) { return (T)~(type)a; }
template<class T, class type=typename std::underlying_type<T>::type> //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 T operator| (T a, T b) { return (T)((type)a | (type)b); }
template<class T, class type=typename std::underlying_type<T>::type> //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 T operator& (T a, T b) { return (T)((type)a & (type)b); }
template<class T, class type=typename std::underlying_type<T>::type> //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 T operator^ (T a, T b) { return (T)((type)a ^ (type)b); }
template<class T, class type=typename std::underlying_type<T>::type> //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 T& operator|= (T& a, T b) { return (T&)((type&)a |= (type)b); }
template<class T, class type=typename std::underlying_type<T>::type> //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 T& operator&= (T& a, T b) { return (T&)((type&)a &= (type)b); }
template<class T, class type=typename std::underlying_type<T>::type> //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 T& operator^= (T& a, T b) { return (T&)((type&)a ^= (type)b); }
inline float M_sqrt(float value) { inline float M_sqrt(float value) {
return _mm_cvtss_f32(_mm_sqrt_ss(_mm_load_ss(&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 #pragma once
#endif
typedef enum Activity_s typedef enum Activity_s
{ {
@ -41,21 +37,21 @@ typedef enum Activity_s
ACT_GUARD, ACT_GUARD,
ACT_WALK, ACT_WALK,
ACT_RUN, ACT_RUN,
ACT_FLY, ACT_FLY, // Fly (and flap if appropriate)
ACT_SWIM, ACT_SWIM,
ACT_HOP, ACT_HOP, // vertical jump
ACT_LEAP, ACT_LEAP, // long forward jump
ACT_FALL, ACT_FALL,
ACT_LAND, ACT_LAND,
ACT_STRAFE_LEFT, ACT_STRAFE_LEFT,
ACT_STRAFE_RIGHT, ACT_STRAFE_RIGHT,
ACT_ROLL_LEFT, ACT_ROLL_LEFT, // tuck and roll, left
ACT_ROLL_RIGHT, ACT_ROLL_RIGHT, // tuck and roll, right
ACT_TURN_LEFT, ACT_TURN_LEFT, // turn quickly left (stationary)
ACT_TURN_RIGHT, ACT_TURN_RIGHT, // turn quickly right (stationary)
ACT_CROUCH, ACT_CROUCH, // the act of crouching down from a standing position
ACT_CROUCHIDLE, ACT_CROUCHIDLE, // holding body in crouched position (loops)
ACT_STAND, ACT_STAND, // the act of standing from a crouched position
ACT_USE, ACT_USE,
ACT_SIGNAL1, ACT_SIGNAL1,
ACT_SIGNAL2, ACT_SIGNAL2,
@ -69,43 +65,43 @@ typedef enum Activity_s
ACT_MELEE_ATTACK1, ACT_MELEE_ATTACK1,
ACT_MELEE_ATTACK2, ACT_MELEE_ATTACK2,
ACT_RELOAD, ACT_RELOAD,
ACT_ARM, ACT_ARM, // pull out gun, for instance
ACT_DISARM, ACT_DISARM, // reholster gun
ACT_EAT, ACT_EAT, // monster chowing on a large food item (loop)
ACT_DIESIMPLE, ACT_DIESIMPLE,
ACT_DIEBACKWARD, ACT_DIEBACKWARD,
ACT_DIEFORWARD, ACT_DIEFORWARD,
ACT_DIEVIOLENT, ACT_DIEVIOLENT,
ACT_BARNACLE_HIT, ACT_BARNACLE_HIT, // barnacle tongue hits a monster
ACT_BARNACLE_PULL, ACT_BARNACLE_PULL, // barnacle is lifting the monster ( loop )
ACT_BARNACLE_CHOMP, ACT_BARNACLE_CHOMP, // barnacle latches on to the monster
ACT_BARNACLE_CHEW, ACT_BARNACLE_CHEW, // barnacle is holding the monster in its mouth ( loop )
ACT_SLEEP, ACT_SLEEP,
ACT_INSPECT_FLOOR, ACT_INSPECT_FLOOR, // for active idles, look at something on or near the floor
ACT_INSPECT_WALL, 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, ACT_IDLE_ANGRY, // alternate idle animation in which the monster is clearly agitated. (loop)
ACT_WALK_HURT, ACT_WALK_HURT, // limp (loop)
ACT_RUN_HURT, ACT_RUN_HURT, // limp (loop)
ACT_HOVER, ACT_HOVER, // Idle while in flight
ACT_GLIDE, ACT_GLIDE, // Fly (don't flap)
ACT_FLY_LEFT, ACT_FLY_LEFT, // Turn left in flight
ACT_FLY_RIGHT, ACT_FLY_RIGHT, // Turn right in flight
ACT_DETECT_SCENT, ACT_DETECT_SCENT, // this means the monster smells a scent carried by the air
ACT_SNIFF, ACT_SNIFF, // this is the act of actually sniffing an item in front of the monster
ACT_BITE, ACT_BITE, // some large monsters can eat small things in one bite. This plays one time, EAT loops.
ACT_THREAT_DISPLAY, ACT_THREAT_DISPLAY, // without attacking, monster demonstrates that it is angry. (Yell, stick out chest, etc )
ACT_FEAR_DISPLAY, ACT_FEAR_DISPLAY, // monster just saw something that it is afraid of
ACT_EXCITED, ACT_EXCITED, // for some reason, monster is excited. Sees something he really likes to eat, or whatever.
ACT_SPECIAL_ATTACK1, ACT_SPECIAL_ATTACK1, // very monster specific special attacks.
ACT_SPECIAL_ATTACK2, ACT_SPECIAL_ATTACK2,
ACT_COMBAT_IDLE, ACT_COMBAT_IDLE, // agitated idle.
ACT_WALK_SCARED, ACT_WALK_SCARED,
ACT_RUN_SCARED, ACT_RUN_SCARED,
ACT_VICTORY_DANCE, ACT_VICTORY_DANCE, // killed a player, do a victory dance.
ACT_DIE_HEADSHOT, ACT_DIE_HEADSHOT, // die, hit in head.
ACT_DIE_CHESTSHOT, ACT_DIE_CHESTSHOT, // die, hit in chest
ACT_DIE_GUTSHOT, ACT_DIE_GUTSHOT, // die, hit in gut
ACT_DIE_BACKSHOT, ACT_DIE_BACKSHOT, // die, hit in back
ACT_FLINCH_HEAD, ACT_FLINCH_HEAD,
ACT_FLINCH_CHEST, ACT_FLINCH_CHEST,
ACT_FLINCH_STOMACH, ACT_FLINCH_STOMACH,
@ -148,5 +144,3 @@ typedef struct
} activity_map_t; } activity_map_t;
extern activity_map_t activity_map[]; 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_RIGHTARM),
_A(ACT_FLINCH_LEFTLEG), _A(ACT_FLINCH_LEFTLEG),
_A(ACT_FLINCH_RIGHTLEG), _A(ACT_FLINCH_RIGHTLEG),
0, NULL 0, nullptr
}; };

View File

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

View File

@ -26,11 +26,7 @@
* *
*/ */
#ifndef AMMO_H
#define AMMO_H
#ifdef _WIN32
#pragma once #pragma once
#endif
class C9MMAmmo: public CBasePlayerAmmo class C9MMAmmo: public CBasePlayerAmmo
{ {
@ -111,5 +107,3 @@ public:
virtual void Precache(); virtual void Precache();
virtual BOOL AddAmmo(CBaseEntity *pOther); 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) NOXREF int CBaseAnimating::FindTransition(int iEndingSequence, int iGoalSequence, int *piDir)
{ {
void *pmodel = GET_MODEL_PTR(ENT(pev)); void *pmodel = GET_MODEL_PTR(ENT(pev));
if (!piDir)
if (piDir == NULL)
{ {
int iDir; int iDir;
int sequence = ::FindTransition(pmodel, iEndingSequence, iGoalSequence, &iDir); int sequence = ::FindTransition(pmodel, iEndingSequence, iGoalSequence, &iDir);

View File

@ -5,7 +5,7 @@
*/ */
#ifndef HOOK_GAMEDLL #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 = 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; 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! paSequences = (cache_user_t *)IEngineStudio.Mem_Calloc(16, sizeof(cache_user_t)); // UNDONE: leak!
m_pSubModel->submodels = (dmodel_t *)paSequences; 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; gaitsequence = 0;
pseqdesc = (mstudioseqdesc_t *)((byte *)g_pstudiohdr + g_pstudiohdr->seqindex) + gaitsequence; pseqdesc = (mstudioseqdesc_t *)((byte *)g_pstudiohdr + g_pstudiohdr->seqindex) + gaitsequence;
panim = StudioGetAnim(pModel, pseqdesc); panim = StudioGetAnim(pModel, pseqdesc);
StudioCalcRotations(pbones, chain, chainlength, adj, pos2, q2, pseqdesc, panim, 0, 0); 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 #pragma once
#endif
#define NUM_BLENDING 9 #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 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); 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 #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 enum MONSTERSTATE
{ {
@ -45,10 +58,6 @@ enum MONSTERSTATE
MONSTERSTATE_DEAD 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 class CBaseMonster: public CBaseToggle
{ {
public: public:
@ -112,20 +121,18 @@ public:
Activity m_IdealActivity; // monster should switch to this activity Activity m_IdealActivity; // monster should switch to this activity
int m_LastHitGroup; // the last body region that took damage int m_LastHitGroup; // the last body region that took damage
int m_bitsDamageType; // what types of damage has monster (player) taken 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_MonsterState; // monster's current state
MONSTERSTATE m_IdealMonsterState; // monster should change to this state MONSTERSTATE m_IdealMonsterState; // monster should change to this state
int m_afConditions; int m_afConditions;
int m_afMemory; int m_afMemory;
float m_flNextAttack; // cannot attack again until this time float m_flNextAttack; // cannot attack again until this time
EHANDLE m_hEnemy; // the entity that the monster is fighting. EHANDLE m_hEnemy; // the entity that the monster is fighting.
EHANDLE m_hTargetEnt; // the entity that the monster is trying to reach EHANDLE m_hTargetEnt; // the entity that the monster is trying to reach
float m_flFieldOfView; // width of monster's field of view ( dot product ) float m_flFieldOfView; // width of monster's field of view (dot product)
int m_bloodColor; // color of blood particless int m_bloodColor; // color of blood particless
Vector m_HackedGunPos; // HACK until we can query end of gun Vector m_HackedGunPos; // HACK until we can query end of gun
Vector m_vecEnemyLKP; // last known position of enemy. (enemy's origin) 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(); CFuncWall::Spawn();
if (pev->spawnflags & SF_WALL_START_OFF) if (pev->spawnflags & SF_WALL_TOOGLE_START_OFF)
{ {
TurnOff(); TurnOff();
} }
#ifdef REGAMEDLL_ADD #ifdef REGAMEDLL_ADD
if (pev->spawnflags & SF_WALL_NOTSOLID) if (pev->spawnflags & SF_WALL_TOOGLE_NOTSOLID)
{ {
pev->solid = SOLID_NOT; pev->solid = SOLID_NOT;
} }
@ -83,7 +83,7 @@ void CFuncWallToggle::Restart()
{ {
CFuncWall::Spawn(); CFuncWall::Spawn();
if (pev->spawnflags & SF_WALL_START_OFF) if (pev->spawnflags & SF_WALL_TOOGLE_START_OFF)
{ {
TurnOff(); TurnOff();
return; return;
@ -188,7 +188,9 @@ void CFuncIllusionary::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CBaseToggle::KeyValue(pkvd); CBaseToggle::KeyValue(pkvd);
}
} }
void CFuncIllusionary::Spawn() void CFuncIllusionary::Spawn()
@ -231,7 +233,11 @@ void CFuncRotating::KeyValue(KeyValueData *pkvd)
m_flFanFriction = Q_atof(pkvd->szValue) / 100; m_flFanFriction = Q_atof(pkvd->szValue) / 100;
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
#ifdef REGAMEDLL_FIXES
else if (FStrEq(pkvd->szKeyName, "volume"))
#else
else if (FStrEq(pkvd->szKeyName, "Volume")) else if (FStrEq(pkvd->szKeyName, "Volume"))
#endif
{ {
m_flVolume = Q_atof(pkvd->szValue) / 10.0; m_flVolume = Q_atof(pkvd->szValue) / 10.0;
@ -259,7 +265,9 @@ void CFuncRotating::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CBaseEntity::KeyValue(pkvd); CBaseEntity::KeyValue(pkvd);
}
} }
// QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS // 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. // 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->solid = SOLID_NOT;
pev->skin = CONTENTS_EMPTY; pev->skin = CONTENTS_EMPTY;
@ -358,12 +366,12 @@ void CFuncRotating::Spawn()
// pev->dmg = 2; // pev->dmg = 2;
// instant-use brush? // instant-use brush?
if (pev->spawnflags & SF_BRUSH_ROTATE_INSTANT) if (pev->spawnflags & SF_BRUSH_ROTATE_START_ON)
{ {
SetThink(&CFuncRotating::SUB_CallUseToggle); SetThink(&CFuncRotating::SUB_CallUseToggle);
// leave a magic delay for client to start up // 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? // can this brush inflict pain?
@ -378,16 +386,15 @@ void CFuncRotating::Spawn()
#ifdef REGAMEDLL_FIXES #ifdef REGAMEDLL_FIXES
void CFuncRotating::Restart() void CFuncRotating::Restart()
{ {
// fan is spinning, so stop it. // stop sound, we're done
SetThink(&CFuncRotating::SpinDown); EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), 0, ATTN_NONE, SND_STOP, m_pitch);
pev->nextthink = pev->ltime + 0.1;
// restore angles // restore angles
pev->angles = m_angles; pev->angles = m_angles;
pev->avelocity = g_vecZero; pev->avelocity = g_vecZero;
// some rotating objects like fake volumetric lights will not be solid. // 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->solid = SOLID_NOT;
pev->skin = CONTENTS_EMPTY; pev->skin = CONTENTS_EMPTY;
@ -411,12 +418,12 @@ void CFuncRotating::Restart()
} }
// instant-use brush? // instant-use brush?
if (pev->spawnflags & SF_BRUSH_ROTATE_INSTANT) if (pev->spawnflags & SF_BRUSH_ROTATE_START_ON)
{ {
SetThink(&CFuncRotating::SUB_CallUseToggle); SetThink(&CFuncRotating::SUB_CallUseToggle);
// leave a magic delay for client to start up // 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? // can this brush inflict pain?
@ -485,7 +492,7 @@ void CFuncRotating::Precache()
// if fan was spinning, and we went through transition or save/restore, // 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 // make sure we restart the sound. 1.5 sec delay is magic number. KDB
SetThink(&CFuncRotating::SpinUp); 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 // 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 // between how fast we're going vs how fast we plan to go
void CFuncRotating::RampPitchVol(BOOL fUp)
void CFuncRotating::RampPitchVol(int fUp)
{ {
Vector vecAVel = pev->avelocity; Vector vecAVel = pev->avelocity;
float_precision vecCur; float_precision vecCur;
@ -541,7 +547,7 @@ void CFuncRotating::RampPitchVol(int fUp)
fvol = m_flVolume * fpct; fvol = m_flVolume * fpct;
} }
fpitch = FANPITCHMIN + (FANPITCHMAX - FANPITCHMIN) * fpct; fpitch = MIN_FANPITCH + (MAX_FANPITCH - MIN_FANPITCH) * fpct;
pitch = int(fpitch); pitch = int(fpitch);
if (pitch == PITCH_NORM) 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 // SpinUp - accelerates a non-moving func_rotating up to it's speed
void CFuncRotating::SpinUp() void CFuncRotating::SpinUp()
{ {
//rotational velocity // rotational velocity
Vector vecAVel; Vector vecAVel;
pev->nextthink = pev->ltime + 0.1; pev->nextthink = pev->ltime + 0.1;
@ -572,7 +578,7 @@ void CFuncRotating::SpinUp()
{ {
// set speed in case we overshot // set speed in case we overshot
pev->avelocity = pev->movedir * pev->speed; 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); SetThink(&CFuncRotating::Rotate);
Rotate(); Rotate();
@ -585,13 +591,13 @@ void CFuncRotating::SpinUp()
void CFuncRotating::SpinDown() void CFuncRotating::SpinDown()
{ {
//rotational velocity // rotational velocity
Vector vecAVel; Vector vecAVel;
vec_t vecdir; 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)); pev->avelocity = pev->avelocity - (pev->movedir * (pev->speed * m_flFanFriction));
// cache entity's rotational velocity // cache entity's rotational velocity
@ -641,12 +647,13 @@ void CFuncRotating::RotatingUse(CBaseEntity *pActivator, CBaseEntity *pCaller, U
SetThink(&CFuncRotating::SpinDown); SetThink(&CFuncRotating::SpinDown);
//EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop), m_flVolume, m_flAttenuation, 0, m_pitch); //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); 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; 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); // 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; // pev->avelocity = g_vecZero;
} }
else 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; pev->avelocity = pev->movedir * pev->speed;
SetThink(&CFuncRotating::Rotate); SetThink(&CFuncRotating::Rotate);
@ -696,7 +703,9 @@ void CPendulum::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CBaseEntity::KeyValue(pkvd); CBaseEntity::KeyValue(pkvd);
}
} }
void CPendulum::Spawn() void CPendulum::Spawn()
@ -704,7 +713,7 @@ void CPendulum::Spawn()
// set the axis of rotation // set the axis of rotation
CBaseToggle::AxisDir(pev); CBaseToggle::AxisDir(pev);
if (pev->spawnflags & SF_DOOR_PASSABLE) if (pev->spawnflags & SF_PENDULUM_PASSABLE)
pev->solid = SOLID_NOT; pev->solid = SOLID_NOT;
else else
pev->solid = SOLID_BSP; pev->solid = SOLID_BSP;
@ -725,18 +734,22 @@ void CPendulum::Spawn()
m_start = pev->angles; m_start = pev->angles;
m_center = pev->angles + (m_distance * 0.5) * pev->movedir; 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); SetThink(&CPendulum::SUB_CallUseToggle);
// leave a magic delay for client to start up
pev->nextthink = gpGlobals->time + 0.1f; pev->nextthink = gpGlobals->time + 0.1f;
} }
pev->speed = 0; pev->speed = 0;
SetUse(&CPendulum::PendulumUse); SetUse(&CPendulum::PendulumUse);
// this brush makes a pendulum a rope swing
if (pev->spawnflags & SF_PENDULUM_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; pev->avelocity = pev->speed * pev->movedir;
// Call this again // Call this again
pev->nextthink = pev->ltime + 0.1; pev->nextthink = pev->ltime + 0.1f;
if (m_damp) if (m_damp)
{ {

View File

@ -26,48 +26,12 @@
* *
*/ */
#ifndef BMODELS_H
#define BMODELS_H
#ifdef _WIN32
#pragma once #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) // covering cheesy noise1, noise2, & noise3 fields so they make more sense (for rotating fans)
#define noiseStart noise1 #define noiseStart noise1
#define noiseStop noise2 #define noiseStop noise2
#define noiseRunning noise3 #define noiseRunning noise3
// This is just a solid wall if not inhibited // This is just a solid wall if not inhibited
class CFuncWall: public CBaseEntity class CFuncWall: public CBaseEntity
@ -80,6 +44,9 @@ public:
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); 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 class CFuncWallToggle: public CFuncWall
{ {
public: public:
@ -97,6 +64,9 @@ public:
BOOL IsOn(); BOOL IsOn();
}; };
#define SF_CONVEYOR_VISUAL BIT(0)
#define SF_CONVEYOR_NOTSOLID BIT(1)
class CFuncConveyor: public CFuncWall class CFuncConveyor: public CFuncWall
{ {
public: public:
@ -135,6 +105,20 @@ public:
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) {} 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 class CFuncRotating: public CBaseEntity
{ {
public: public:
@ -157,7 +141,7 @@ public:
void EXPORT HurtTouch(CBaseEntity *pOther); void EXPORT HurtTouch(CBaseEntity *pOther);
void EXPORT RotatingUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); void EXPORT RotatingUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void EXPORT Rotate(); void EXPORT Rotate();
void RampPitchVol(int fUp); void RampPitchVol(BOOL fUp);
public: public:
static TYPEDESCRIPTION IMPL(m_SaveData)[5]; 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 class CPendulum: public CBaseEntity
{ {
public: public:
@ -208,5 +197,3 @@ public:
}; };
Vector VecBModelOrigin(entvars_t *pevBModel); 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 GetBotFollowCount(CBasePlayer *leader)
{ {
int count = 0; int count = 0;
for (int i = 1; i <= gpGlobals->maxClients; ++i) for (int i = 1; i <= gpGlobals->maxClients; i++)
{ {
CBasePlayer *player = UTIL_PlayerByIndex(i); CBasePlayer *player = UTIL_PlayerByIndex(i);
@ -32,7 +32,7 @@ int GetBotFollowCount(CBasePlayer *leader)
CCSBot *bot = reinterpret_cast<CCSBot *>(player); CCSBot *bot = reinterpret_cast<CCSBot *>(player);
if (bot->IsBot() && bot->GetFollowLeader() == leader) if (bot->IsBot() && bot->GetFollowLeader() == leader)
++count; count++;
} }
return 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 // 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) 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 we were attacked by a teammate, rebuke
if (attacker->IsPlayer()) if (pAttacker->IsPlayer())
{ {
CBasePlayer *player = static_cast<CBasePlayer *>(attacker); CBasePlayer *pPlayer = static_cast<CBasePlayer *>(pAttacker);
if (BotRelationship(player) == BOT_TEAMMATE && !player->IsBot()) if (BotRelationship(pPlayer) == BOT_TEAMMATE && !pPlayer->IsBot())
{ {
GetChatter()->FriendlyFire(); GetChatter()->FriendlyFire();
} }
}
if (attacker->IsPlayer() && IsEnemy(attacker)) if (IsEnemy(pPlayer))
{
// 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))
{ {
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 // keep track of our last attacker
if (!IsVisible(enemy, CHECK_FOV)) 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 not attacking anything, look around to try to find attacker
if (!IsAttacking()) if (!IsAttacking())
{ {
bPanic = true; bPanic = true;
} }
else else
{ {
// we are attacking // we are attacking
if (!IsEnemyVisible()) 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 // 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); 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 // Return true if line segment intersects rectagular volume
bool IsIntersectingBox(const Vector *start, const Vector *end, const Vector *boxMin, const Vector *boxMax) bool IsIntersectingBox(const Vector *start, const Vector *end, const Vector *boxMin, const Vector *boxMax)
{ {
@ -234,9 +239,9 @@ void CCSBot::BotTouch(CBaseEntity *other)
return; return;
// they are higher priority - make way, unless we're already making way for someone more important // 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) if (avoidPri < otherPri)
{ {
// ignore 'other' because we're already avoiding someone better // 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; m_avoidTimestamp = gpGlobals->time;
return; return;
@ -307,11 +312,11 @@ void CCSBot::BotDeathThink()
CBasePlayer *CCSBot::FindNearbyPlayer() CBasePlayer *CCSBot::FindNearbyPlayer()
{ {
CBaseEntity *pEntity = NULL; CBaseEntity *pEntity = nullptr;
Vector vecSrc = pev->origin; Vector vecSrc = pev->origin;
const float flRadius = 800.0f; const float flRadius = 800.0f;
while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecSrc, flRadius)) != NULL) while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecSrc, flRadius)))
{ {
if (!pEntity->IsPlayer()) if (!pEntity->IsPlayer())
continue; continue;
@ -322,7 +327,7 @@ CBasePlayer *CCSBot::FindNearbyPlayer()
return static_cast<CBasePlayer *>(pEntity); return static_cast<CBasePlayer *>(pEntity);
} }
return NULL; return nullptr;
} }
// Assign given player as our current enemy to attack // 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. // move towards last known area.
// Return false if off mesh. // Return false if off mesh.
bool CCSBot::StayOnNavMesh() bool CCSBot::StayOnNavMesh()
{ {
if (m_currentArea != NULL) if (m_currentArea)
return true; return true;
// move back onto the area map // move back onto the area map
@ -359,7 +364,7 @@ bool CCSBot::StayOnNavMesh()
PrintIfWatched("Getting out of NULL area...\n"); PrintIfWatched("Getting out of NULL area...\n");
} }
if (goalArea != NULL) if (goalArea)
{ {
Vector pos; Vector pos;
goalArea->GetClosestPointOnArea(&pev->origin, &pos); goalArea->GetClosestPointOnArea(&pev->origin, &pos);
@ -461,8 +466,7 @@ bool CCSBot::NoticeLooseBomb() const
return false; return false;
CBaseEntity *bomb = TheCSBots()->GetLooseBomb(); CBaseEntity *bomb = TheCSBots()->GetLooseBomb();
if (bomb)
if (bomb != NULL)
{ {
// T's can always see bomb on their radar // T's can always see bomb on their radar
return true; return true;
@ -478,8 +482,7 @@ bool CCSBot::CanSeeLooseBomb() const
return false; return false;
CBaseEntity *bomb = TheCSBots()->GetLooseBomb(); CBaseEntity *bomb = TheCSBots()->GetLooseBomb();
if (bomb)
if (bomb != NULL)
{ {
if (IsVisible(&bomb->pev->origin, CHECK_FOV)) if (IsVisible(&bomb->pev->origin, CHECK_FOV))
return true; return true;
@ -498,8 +501,7 @@ bool CCSBot::CanSeePlantedBomb() const
return false; return false;
const Vector *bombPos = GetGameState()->GetBombPosition(); const Vector *bombPos = GetGameState()->GetBombPosition();
if (bombPos && IsVisible(bombPos, CHECK_FOV))
if (bombPos != NULL && IsVisible(bombPos, CHECK_FOV))
return true; return true;
return false; return false;
@ -508,10 +510,10 @@ bool CCSBot::CanSeePlantedBomb() const
// Return last enemy that hurt us // Return last enemy that hurt us
CBasePlayer *CCSBot::GetAttacker() const CBasePlayer *CCSBot::GetAttacker() const
{ {
if (m_attacker != NULL && m_attacker->IsAlive()) if (m_attacker && m_attacker->IsAlive())
return m_attacker; return m_attacker;
return NULL; return nullptr;
} }
// Immediately jump off of our ladder, if we're on one // 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 // Return time when given spot was last checked
float CCSBot::GetHidingSpotCheckTimestamp(HidingSpot *spot) const 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()) if (m_checkedHidingSpot[i].spot->GetID() == spot->GetID())
return m_checkedHidingSpot[i].timestamp; return m_checkedHidingSpot[i].timestamp;
@ -543,7 +545,7 @@ void CCSBot::SetHidingSpotCheckTimestamp(HidingSpot *spot)
int leastRecent = 0; int leastRecent = 0;
float leastRecentTime = gpGlobals->time + 1.0f; 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 spot is in the set, just update its timestamp
if (m_checkedHidingSpot[i].spot->GetID() == spot->GetID()) 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 ].spot = spot;
m_checkedHidingSpot[ m_checkedHidingSpotCount ].timestamp = gpGlobals->time; m_checkedHidingSpot[ m_checkedHidingSpotCount ].timestamp = gpGlobals->time;
++m_checkedHidingSpotCount; m_checkedHidingSpotCount++;
} }
else else
{ {
@ -587,8 +589,8 @@ void CCSBot::UpdateHostageEscortCount()
// recount the hostages in case we lost some // recount the hostages in case we lost some
m_hostageEscortCount = 0; m_hostageEscortCount = 0;
CHostage *hostage = NULL; CHostage *hostage = nullptr;
while ((hostage = static_cast<CHostage *>(UTIL_FindEntityByClassname(hostage, "hostage_entity")))) while ((hostage = UTIL_FindEntityByClassname(hostage, "hostage_entity")))
{ {
if (FNullEnt(hostage->edict())) if (FNullEnt(hostage->edict()))
break; break;
@ -599,7 +601,7 @@ void CCSBot::UpdateHostageEscortCount()
// check if hostage has targeted us, and is following // check if hostage has targeted us, and is following
if (hostage->IsFollowing(this)) 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) // Return the closest "important" enemy for the given scenario (bomb carrier, VIP, hostage escorter)
CBasePlayer *CCSBot::GetImportantEnemy(bool checkVisibility) const CBasePlayer *CCSBot::GetImportantEnemy(bool checkVisibility) const
{ {
CBasePlayer *nearEnemy = NULL; CBasePlayer *nearEnemy = nullptr;
float nearDist = 999999999.9f; 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); CBasePlayer *player = UTIL_PlayerByIndex(i);
if (player == NULL) if (!player)
continue; continue;
if (FNullEnt(player->pev)) if (FNullEnt(player->pev))
@ -808,11 +810,10 @@ bool CCSBot::HasNotSeenEnemyForLongTime() const
bool CCSBot::GuardRandomZone(float range) bool CCSBot::GuardRandomZone(float range)
{ {
const CCSBotManager::Zone *zone = TheCSBots()->GetRandomZone(); const CCSBotManager::Zone *zone = TheCSBots()->GetRandomZone();
if (zone)
if (zone != NULL)
{ {
CNavArea *rescueArea = TheCSBots()->GetRandomAreaInZone(zone); CNavArea *rescueArea = TheCSBots()->GetRandomAreaInZone(zone);
if (rescueArea != NULL) if (rescueArea)
{ {
Hide(rescueArea, -1.0f, range); Hide(rescueArea, -1.0f, range);
return true; return true;
@ -827,15 +828,15 @@ bool CCSBot::GuardRandomZone(float range)
const Vector *FindNearbyRetreatSpot(CCSBot *me, float maxRange) const Vector *FindNearbyRetreatSpot(CCSBot *me, float maxRange)
{ {
CNavArea *area = me->GetLastKnownArea(); CNavArea *area = me->GetLastKnownArea();
if (area == NULL) if (!area)
return NULL; return nullptr;
// collect spots that enemies cannot see // collect spots that enemies cannot see
CollectRetreatSpotsFunctor collector(me, maxRange); CollectRetreatSpotsFunctor collector(me, maxRange);
SearchSurroundingAreas(area, &me->pev->origin, collector, maxRange); SearchSurroundingAreas(area, &me->pev->origin, collector, maxRange);
if (collector.m_count == 0) if (collector.m_count == 0)
return NULL; return nullptr;
// select a hiding spot at random // select a hiding spot at random
int which = RANDOM_LONG(0, collector.m_count - 1); 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 #pragma once
#endif
#include "bot/cs_gamestate.h" #include "bot/cs_gamestate.h"
#include "bot/cs_bot_manager.h" #include "bot/cs_bot_manager.h"
#include "bot/cs_bot_chatter.h" #include "bot/cs_bot_chatter.h"
#define CSBOT_VERSION_MAJOR 1 const int MAX_BUY_WEAPON_PRIMARY = 13;
#define CSBOT_VERSION_MINOR 50 const int MAX_BUY_WEAPON_SECONDARY = 3;
#define PRIMARY_WEAPON_BUY_COUNT 13 enum
#define SECONDARY_WEAPON_BUY_COUNT 3 {
BOT_PROGGRESS_DRAW = 0, // draw status bar progress
#define FLAG_PROGRESS_DRAW 0x0 // draw status bar progress BOT_PROGGRESS_START, // init status bar progress
#define FLAG_PROGRESS_START 0x1 // init status bar progress BOT_PROGGRESS_HIDE, // hide 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
extern int _navAreaCount; extern int _navAreaCount;
extern int _currentIndex; extern int _currentIndex;
extern struct BuyInfo primaryWeaponBuyInfoCT[PRIMARY_WEAPON_BUY_COUNT]; extern struct BuyInfo primaryWeaponBuyInfoCT[MAX_BUY_WEAPON_PRIMARY];
extern struct BuyInfo secondaryWeaponBuyInfoCT[SECONDARY_WEAPON_BUY_COUNT]; extern struct BuyInfo secondaryWeaponBuyInfoCT[MAX_BUY_WEAPON_SECONDARY];
extern struct BuyInfo primaryWeaponBuyInfoT[PRIMARY_WEAPON_BUY_COUNT]; extern struct BuyInfo primaryWeaponBuyInfoT[MAX_BUY_WEAPON_PRIMARY];
extern struct BuyInfo secondaryWeaponBuyInfoT[SECONDARY_WEAPON_BUY_COUNT]; extern struct BuyInfo secondaryWeaponBuyInfoT[MAX_BUY_WEAPON_SECONDARY];
class CCSBot; class CCSBot;
class BotChatterInterface; class BotChatterInterface;
@ -90,7 +79,7 @@ public:
virtual void OnExit(CCSBot *me); virtual void OnExit(CCSBot *me);
virtual const char *GetName() const { return "Hunt"; } virtual const char *GetName() const { return "Hunt"; }
void ClearHuntArea() { m_huntArea = NULL; } void ClearHuntArea() { m_huntArea = nullptr; }
private: private:
CNavArea *m_huntArea; CNavArea *m_huntArea;
@ -264,12 +253,12 @@ public:
virtual void OnExit(CCSBot *me); virtual void OnExit(CCSBot *me);
virtual const char *GetName() const { return "Follow"; } virtual const char *GetName() const { return "Follow"; }
void SetLeader(CBaseEntity *leader) { m_leader = leader; } void SetLeader(CBasePlayer *leader) { m_leader = leader; }
private: private:
void ComputeLeaderMotionState(float leaderSpeed); void ComputeLeaderMotionState(float leaderSpeed);
EHANDLE m_leader; EntityHandle<CBasePlayer> m_leader;
Vector m_lastLeaderPos; Vector m_lastLeaderPos;
bool m_isStopped; bool m_isStopped;
float m_stoppedTimestamp; float m_stoppedTimestamp;
@ -307,14 +296,14 @@ public:
void SetEntity(CBaseEntity *entity) { m_entity = entity; } void SetEntity(CBaseEntity *entity) { m_entity = entity; }
private: private:
EHANDLE m_entity; EntityHandle<CBaseEntity> m_entity;
}; };
// The Counter-strike Bot // The Counter-strike Bot
class CCSBot: public CBot class CCSBot: public CBot
{ {
public: 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 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 Killed(entvars_t *pevAttacker, int iGib); // invoked when killed (EXTEND)
virtual void RoundRespawn(); virtual void RoundRespawn();
@ -330,11 +319,11 @@ public:
virtual void Walk(); virtual void Walk();
virtual bool Jump(bool mustJump = false); // returns true if jump was started 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 #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(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 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 bool IsHurrying() const; // return true if we are in a hurry
void Hurry(float duration); // force bot to hurry void Hurry(float duration); // force bot to hurry
bool IsSafe() const; // return true if we are in a safe region 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 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 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 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 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 //bool IsUnhealthy() const; // returns true if bot is low on health
// behaviors // behaviors
void Idle(); 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 #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 IsHiding() const; // returns true if bot is currently hiding
bool IsAtHidingSpot() const; // return true if we are hiding and at our hiding spot 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 bool TryToRetreat(); // retreat to a nearby hiding spot, away from enemies
@ -454,7 +443,7 @@ public:
NUM_TASKS 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; TaskType GetTask() const;
CBaseEntity *GetTaskEntity(); CBaseEntity *GetTaskEntity();
@ -491,7 +480,7 @@ public:
// listening for noises // listening for noises
bool IsNoiseHeard() const; // return true if we have heard a noise 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 void InvestigateNoise(); // investigate recent enemy noise
const Vector *GetNoisePosition() const; // return position of last heard noise, or NULL if none heard const Vector *GetNoisePosition() const; // return position of last heard noise, or NULL if none heard
CNavArea *GetNoiseArea() const; // return area where noise was heard CNavArea *GetNoiseArea() const; // return area where noise was heard
@ -573,7 +562,7 @@ public:
void ResetStuckMonitor(); void ResetStuckMonitor();
bool IsAreaVisible(CNavArea *area) const; // is any portion of the area visible to this bot bool IsAreaVisible(CNavArea *area) const; // is any portion of the area visible to this bot
const Vector &GetPathPosition(int numpath) const; 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 Place GetPlace() const; // get our current radio chatter place
@ -581,7 +570,9 @@ public:
void GetOffLadder(); void GetOffLadder();
void SetGoalEntity(CBaseEntity *entity); void SetGoalEntity(CBaseEntity *entity);
CBaseEntity *GetGoalEntity();
template <typename T = CBaseEntity>
T *GetGoalEntity();
bool IsNearJump() const; // return true if nearing a jump in the path 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 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; return m_eyePos;
} }
float ComputeWeaponSightRange(); // return line-of-sight distance to obstacle along weapon fire ray 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 // approach points
void ComputeApproachPoints(); // determine the set of "approach points" representing where the enemy can enter this region void ComputeApproachPoints(); // determine the set of "approach points" representing where the enemy can enter this region
@ -696,7 +688,7 @@ private:
float m_surpriseTimestamp; float m_surpriseTimestamp;
bool m_isFollowing; // true if we are following someone 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_followTimestamp; // when we started following
float m_allowAutoFollowTime; // time when we can auto follow 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 bool m_isAttacking; // if true, special Attack state is overriding the state machine
TaskType m_task; // our current task 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 // navigation
Vector m_goalPosition; Vector m_goalPosition;
EHANDLE m_goalEntity; EHandle m_goalEntity;
void MoveTowardsPosition(const Vector *pos); // move towards position, independant of view angle 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 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 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_currentArea; // the nav area we are standing on
CNavArea *m_lastKnownArea; // the last area we were in 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; float m_avoidTimestamp;
bool m_isJumpCrouching; bool m_isJumpCrouching;
bool m_isJumpCrouched; bool m_isJumpCrouched;
@ -765,7 +757,7 @@ private:
void SetPathIndex(int newIndex); // set the current index along the path void SetPathIndex(int newIndex); // set the current index along the path
void DrawPath(); void DrawPath();
int FindOurPositionOnPath(Vector *close, bool local = false) const; // compute the closest point to our current position on our path 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 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 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 Vector m_aimSpot; // the spot we are currently aiming to fire at
// attack state data // attack state data
DispositionType m_disposition; // how we will react to enemies DispositionType m_disposition; // how we will react to enemies
CountdownTimer m_ignoreEnemiesTimer; // how long will we ignore enemies CountdownTimer m_ignoreEnemiesTimer; // how long will we ignore enemies
mutable EHANDLE m_enemy; // our current enemy mutable EntityHandle<CBasePlayer> m_enemy; // our current enemy
bool m_isEnemyVisible; // result of last visibility test on enemy bool m_isEnemyVisible; // result of last visibility test on enemy
unsigned char m_visibleEnemyParts; // which parts of the visible enemy do we see unsigned char m_visibleEnemyParts; // which parts of the visible enemy do we see
Vector m_lastEnemyPosition; // last place we saw the enemy Vector m_lastEnemyPosition; // last place we saw the enemy
float m_lastSawEnemyTimestamp; float m_lastSawEnemyTimestamp;
float m_firstSawEnemyTimestamp; float m_firstSawEnemyTimestamp;
float m_currentEnemyAcquireTimestamp; float m_currentEnemyAcquireTimestamp;
@ -910,11 +902,15 @@ private:
bool isEnemy; bool isEnemy;
} }
m_watchInfo[MAX_CLIENTS]; 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 int m_nearbyFriendCount; // number of nearby teammates
mutable EHANDLE m_closestVisibleFriend; // the closest friend we can see mutable EntityHandle<CBasePlayer> m_closestVisibleFriend; // the closest friend we can see
mutable EHANDLE m_closestVisibleHumanFriend; // the closest human 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) 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 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_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 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 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 ReloadCheck(); // reload our weapon if we must
void SilencerCheck(); // use silencer void SilencerCheck(); // use silencer
@ -935,7 +931,7 @@ private:
struct ReactionState struct ReactionState
{ {
// NOTE: player position & orientation is not currently stored separately // NOTE: player position & orientation is not currently stored separately
EHANDLE player; EntityHandle<CBasePlayer> player;
bool isReloading; bool isReloading;
bool isProtectedByShield; bool isProtectedByShield;
} }
@ -962,7 +958,7 @@ private:
Vector m_lastOrigin; Vector m_lastOrigin;
// chatter mechanism // chatter mechanism
GameEventType m_lastRadioCommand; // last radio command we recieved GameEventType m_lastRadioCommand; // last radio command we recieved
void RespondToRadioCommands(); void RespondToRadioCommands();
bool IsRadioCommand(GameEventType event) const; // returns true if the radio message is an order to do something 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); void EndVoiceFeedback(bool force = true);
float m_lastRadioRecievedTimestamp; // time we recieved a radio message float m_lastRadioRecievedTimestamp; // time we recieved a radio message
float m_lastRadioSentTimestamp; // time when we send 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 Vector m_radioPosition; // position referred to in radio message
float m_voiceFeedbackStartTimestamp; float m_voiceFeedbackStartTimestamp;
float m_voiceFeedbackEndTimestamp; // new-style "voice" chatter gets voice feedback float m_voiceFeedbackEndTimestamp; // new-style "voice" chatter gets voice feedback
@ -1008,6 +1004,10 @@ private:
void StartSaveProcess(); void StartSaveProcess();
void UpdateSaveProcess(); void UpdateSaveProcess();
void StartNormalProcess(); void StartNormalProcess();
#ifdef REGAMEDLL_ADD
bool IsNoticable(const CBasePlayer *player, unsigned char visibleParts) const; // return true if we "notice" given player
#endif
}; };
// Inlines // Inlines
@ -1188,7 +1188,7 @@ inline unsigned int CCSBot::GetEnemyPlace() const
inline bool CCSBot::CanSeeBomber() const inline bool CCSBot::CanSeeBomber() const
{ {
return (m_bomber == NULL) ? false : true; return m_bomber.IsValid();
} }
inline CBasePlayer *CCSBot::GetBomber() const inline CBasePlayer *CCSBot::GetBomber() const
@ -1264,7 +1264,7 @@ inline bool CCSBot::HasPath() const
inline void CCSBot::DestroyPath() inline void CCSBot::DestroyPath()
{ {
m_pathLength = 0; m_pathLength = 0;
m_pathLadder = NULL; m_pathLadder = nullptr;
} }
inline CNavArea *CCSBot::GetLastKnownArea() const inline CNavArea *CCSBot::GetLastKnownArea() const
@ -1284,7 +1284,7 @@ inline const Vector &CCSBot::GetPathPosition(int numpath) const
inline bool CCSBot::IsUsingLadder() const inline bool CCSBot::IsUsingLadder() const
{ {
return m_pathLadder != NULL; return m_pathLadder != nullptr;
} }
inline void CCSBot::SetGoalEntity(CBaseEntity *entity) inline void CCSBot::SetGoalEntity(CBaseEntity *entity)
@ -1292,9 +1292,10 @@ inline void CCSBot::SetGoalEntity(CBaseEntity *entity)
m_goalEntity = 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) inline void CCSBot::ForceRun(float duration)
@ -1323,7 +1324,7 @@ inline void CCSBot::ClearLookAt()
{ {
//PrintIfWatched("ClearLookAt()\n"); //PrintIfWatched("ClearLookAt()\n");
m_lookAtSpotState = NOT_LOOKING_AT_SPOT; m_lookAtSpotState = NOT_LOOKING_AT_SPOT;
m_lookAtDesc = NULL; m_lookAtDesc = nullptr;
} }
inline bool CCSBot::IsLookingAtSpot(PriorityType pri) const inline bool CCSBot::IsLookingAtSpot(PriorityType pri) const
@ -1345,6 +1346,21 @@ inline bool CCSBot::IsViewMoving(float angleVelThreshold) const
return true; 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() inline void CCSBot::ClearApproachPoints()
{ {
m_approachPointCount = 0; m_approachPointCount = 0;
@ -1411,7 +1427,7 @@ inline const Vector *CCSBot::GetNoisePosition() const
if (m_noiseTimestamp > 0.0f) if (m_noiseTimestamp > 0.0f)
return &m_noisePosition; return &m_noisePosition;
return NULL; return nullptr;
} }
inline bool CCSBot::IsAwareOfEnemyDeath() const inline bool CCSBot::IsAwareOfEnemyDeath() const
@ -1419,7 +1435,7 @@ inline bool CCSBot::IsAwareOfEnemyDeath() const
if (GetEnemyDeathTimestamp() == 0.0f) if (GetEnemyDeathTimestamp() == 0.0f)
return false; return false;
if (m_enemy == NULL) if (!m_enemy.IsValid())
return true; return true;
if (!m_enemy->IsAlive() && gpGlobals->time - GetEnemyDeathTimestamp() > (1.0f - GetProfile()->GetSkill())) 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 // don't select spot if it is closest to an enemy
CBasePlayer *owner = UTIL_GetClosestPlayer(spot->GetPosition()); 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; continue;
m_spot[m_count++] = spot->GetPosition(); 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) // 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; float dangerFactor = (1.0f - (0.95f * m_bot->GetProfile()->GetAggression())) * baseDangerFactor;
if (fromArea == NULL) if (fromArea == nullptr)
{ {
if (m_route == FASTEST_ROUTE) if (m_route == FASTEST_ROUTE)
return 0.0f; return 0.0f;
@ -1753,5 +1769,3 @@ void hideProgressMeter();
bool isSniperRifle(CBasePlayerItem *item); bool isSniperRifle(CBasePlayerItem *item);
float StayOnLadderLine(CCSBot *me, const CNavLadder *ladder); float StayOnLadderLine(CCSBot *me, const CNavLadder *ladder);
#endif // CS_BOT_H

View File

@ -6,8 +6,7 @@
*/ */
#ifndef HOOK_GAMEDLL #ifndef HOOK_GAMEDLL
BotPhraseManager *TheBotPhrases = NULL; BotPhraseManager *TheBotPhrases = nullptr;
CBaseEntity *g_pSelectedZombieSpawn = NULL;
CountdownTimer BotChatterInterface::m_encourageTimer; CountdownTimer BotChatterInterface::m_encourageTimer;
IntervalTimer BotChatterInterface::m_radioSilenceInterval[ 2 ]; IntervalTimer BotChatterInterface::m_radioSilenceInterval[ 2 ];
@ -16,37 +15,32 @@ IntervalTimer BotChatterInterface::m_radioSilenceInterval[ 2 ];
const Vector *GetRandomSpotAtPlace(Place place) const Vector *GetRandomSpotAtPlace(Place place)
{ {
int count = 0; int count = 0;
NavAreaList::iterator iter;
int which; int which;
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) for (auto area : TheNavAreaList)
{ {
CNavArea *area = (*iter);
if (area->GetPlace() == place) if (area->GetPlace() == place)
++count; count++;
} }
if (count == 0) if (count == 0)
return NULL; return nullptr;
which = RANDOM_LONG(0, count - 1); 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) if (area->GetPlace() == place && which == 0)
return area->GetCenter(); return area->GetCenter();
} }
return NULL; return nullptr;
} }
// Transmit meme to other bots // Transmit meme to other bots
void BotMeme::Transmit(CCSBot *sender) const 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); CBasePlayer *player = UTIL_PlayerByIndex(i);
@ -235,7 +229,7 @@ void BotHostageBeingTakenMeme::Interpret(CCSBot *sender, CCSBot *receiver) const
BotSpeakable::BotSpeakable() BotSpeakable::BotSpeakable()
{ {
m_phrase = NULL; m_phrase = nullptr;
} }
BotSpeakable::~BotSpeakable() BotSpeakable::~BotSpeakable()
@ -243,13 +237,13 @@ BotSpeakable::~BotSpeakable()
if (m_phrase) if (m_phrase)
{ {
delete[] m_phrase; delete[] m_phrase;
m_phrase = NULL; m_phrase = nullptr;
} }
} }
BotPhrase::BotPhrase(unsigned int id, bool isPlace) BotPhrase::BotPhrase(unsigned int id, bool isPlace)
{ {
m_name = NULL; m_name = nullptr;
m_id = id; m_id = id;
m_isPlace = isPlace; m_isPlace = isPlace;
m_radioEvent = EVENT_INVALID; m_radioEvent = EVENT_INVALID;
@ -263,19 +257,20 @@ BotPhrase::BotPhrase(unsigned int id, bool isPlace)
BotPhrase::~BotPhrase() 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])[speakable];
} }
delete m_voiceBank[bank]; delete m_voiceBank[bank];
} }
if (m_name) if (m_name)
{ {
delete[] 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_count.push_back(0);
m_index.push_back(0); m_index.push_back(0);
m_voiceBank.push_back(new BotSpeakableVector); m_voiceBank.push_back(new BotSpeakableVector);
++m_numVoiceBanks; m_numVoiceBanks++;
} }
} }
@ -298,7 +293,7 @@ char *BotPhrase::GetSpeakable(int bankIndex, float *duration) const
if (duration) if (duration)
*duration = 0.0f; *duration = 0.0f;
return NULL; return nullptr;
} }
// find phrase that meets the current criteria // find phrase that meets the current criteria
@ -338,18 +333,18 @@ char *BotPhrase::GetSpeakable(int bankIndex, float *duration) const
if (duration) if (duration)
*duration = 0.0f; *duration = 0.0f;
return NULL; return nullptr;
} }
} }
return NULL; return nullptr;
} }
// Randomly shuffle the speakable order // Randomly shuffle the speakable order
#ifndef HOOK_GAMEDLL #ifndef HOOK_GAMEDLL
void BotPhrase::Randomize() 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()); std::random_shuffle(m_voiceBank[i]->begin(), m_voiceBank[i]->end());
} }
@ -358,7 +353,7 @@ void BotPhrase::Randomize()
BotPhraseManager::BotPhraseManager() 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_placeStatementHistory[i].timer.Invalidate();
m_placeCount = 0; m_placeCount = 0;
@ -375,18 +370,13 @@ void BotPhraseManager::OnRoundRestart()
{ {
// effectively reset all interval timers // effectively reset all interval timers
m_placeCount = 0; m_placeCount = 0;
BotPhraseList::const_iterator iter;
// shuffle all the speakables // shuffle all the speakables
for (iter = m_placeList.begin(); iter != m_placeList.end(); ++iter) for (auto phrase : m_placeList)
{ phrase->Randomize();
(*iter)->Randomize();
}
for (iter = m_list.begin(); iter != m_list.end(); ++iter) for (auto phrase : m_list)
{ phrase->Randomize();
(*iter)->Randomize();
}
} }
// Initialize phrase system from database file // Initialize phrase system from database file
@ -396,7 +386,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
int phraseDataLength; int phraseDataLength;
char *phraseDataFile = (char *)LOAD_FILE_FOR_ME((char *)filename, &phraseDataLength); char *phraseDataFile = (char *)LOAD_FILE_FOR_ME((char *)filename, &phraseDataLength);
if (phraseDataFile == NULL) if (!phraseDataFile)
{ {
if (AreBotsAllowed()) if (AreBotsAllowed())
{ {
@ -406,6 +396,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false; return false;
} }
char *token;
char *phraseData = phraseDataFile; char *phraseData = phraseDataFile;
unsigned int nextID = 1; unsigned int nextID = 1;
@ -425,16 +416,15 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
// Parse the BotChatter.db into BotPhrase collections // Parse the BotChatter.db into BotPhrase collections
while (true) while (true)
{ {
phraseData = MP_COM_Parse(phraseData); phraseData = SharedParse(phraseData);
if (!phraseData) if (!phraseData)
break; break;
char *token = MP_COM_GetToken(); token = SharedGetToken();
if (!Q_stricmp(token, "BaseDir")) if (!Q_stricmp(token, "BaseDir"))
{ {
// get name of this output device // get name of this output device
phraseData = MP_COM_Parse(phraseData); phraseData = SharedParse(phraseData);
if (!phraseData) if (!phraseData)
{ {
CONSOLE_ECHO("Error parsing '%s' - expected identifier\n", filename); CONSOLE_ECHO("Error parsing '%s' - expected identifier\n", filename);
@ -442,7 +432,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false; return false;
} }
char *token = MP_COM_GetToken(); token = SharedGetToken();
Q_strncpy(baseDir, token, RadioPathLen); Q_strncpy(baseDir, token, RadioPathLen);
baseDir[RadioPathLen - 1] = '\0'; baseDir[RadioPathLen - 1] = '\0';
} }
@ -451,14 +441,14 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
bool isPlace = (Q_stricmp(token, "Place") == 0); bool isPlace = (Q_stricmp(token, "Place") == 0);
// encountered a new phrase collection // encountered a new phrase collection
BotPhrase *phrase = NULL; BotPhrase *phrase = nullptr;
if (isDefault) if (isDefault)
{ {
phrase = new BotPhrase(nextID++, isPlace); phrase = new BotPhrase(nextID++, isPlace);
} }
// get name of this phrase // get name of this phrase
phraseData = MP_COM_Parse(phraseData); phraseData = SharedParse(phraseData);
if (!phraseData) if (!phraseData)
{ {
CONSOLE_ECHO("Error parsing '%s' - expected identifier\n", filename); CONSOLE_ECHO("Error parsing '%s' - expected identifier\n", filename);
@ -466,25 +456,26 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false; return false;
} }
token = SharedGetToken();
if (isDefault) if (isDefault)
{ {
phrase->m_name = CloneString(MP_COM_GetToken()); phrase->m_name = CloneString(token);
} }
// look up the existing phrase // look up the existing phrase
else else
{ {
if (isPlace) if (isPlace)
{ {
phrase = const_cast<BotPhrase *>(GetPlace(MP_COM_GetToken())); phrase = const_cast<BotPhrase *>(GetPlace(token));
} }
else else
{ {
phrase = const_cast<BotPhrase *>(GetPhrase(MP_COM_GetToken())); phrase = const_cast<BotPhrase *>(GetPhrase(token));
} }
if (!phrase) 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); FREE_FILE(phraseDataFile);
return false; return false;
} }
@ -501,7 +492,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
while (true) while (true)
{ {
// get next token // get next token
phraseData = MP_COM_Parse(phraseData); phraseData = SharedParse(phraseData);
if (!phraseData) if (!phraseData)
{ {
CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename); CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename);
@ -509,12 +500,12 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false; return false;
} }
token = MP_COM_GetToken(); token = SharedGetToken();
// check for Place criteria // check for Place criteria
if (!Q_stricmp(token, "Place")) if (!Q_stricmp(token, "Place"))
{ {
phraseData = MP_COM_Parse(phraseData); phraseData = SharedParse(phraseData);
if (!phraseData) if (!phraseData)
{ {
CONSOLE_ECHO("Error parsing %s - expected Place name\n", filename); CONSOLE_ECHO("Error parsing %s - expected Place name\n", filename);
@ -522,7 +513,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false; return false;
} }
token = MP_COM_GetToken(); token = SharedGetToken();
// update place criteria for subsequent speak lines // update place criteria for subsequent speak lines
// NOTE: this assumes places must be first in the chatter database // 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 // check for Count criteria
if (!Q_stricmp(token, "Count")) if (!Q_stricmp(token, "Count"))
{ {
phraseData = MP_COM_Parse(phraseData); phraseData = SharedParse(phraseData);
if (!phraseData) if (!phraseData)
{ {
CONSOLE_ECHO("Error parsing %s - expected Count value\n", filename); CONSOLE_ECHO("Error parsing %s - expected Count value\n", filename);
@ -549,7 +540,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false; return false;
} }
token = MP_COM_GetToken(); token = SharedGetToken();
// update count criteria for subsequent speak lines // update count criteria for subsequent speak lines
if (!Q_stricmp(token, "Many")) if (!Q_stricmp(token, "Many"))
@ -563,7 +554,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
// check for radio equivalent // check for radio equivalent
if (!Q_stricmp(token, "Radio")) if (!Q_stricmp(token, "Radio"))
{ {
phraseData = MP_COM_Parse(phraseData); phraseData = SharedParse(phraseData);
if (!phraseData) if (!phraseData)
{ {
CONSOLE_ECHO("Error parsing %s - expected radio event\n", filename); CONSOLE_ECHO("Error parsing %s - expected radio event\n", filename);
@ -571,7 +562,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
return false; return false;
} }
token = MP_COM_GetToken(); token = SharedGetToken();
GameEventType event = NameToGameEvent(token); GameEventType event = NameToGameEvent(token);
if (event <= EVENT_START_RADIO_1 || event >= EVENT_END_RADIO) 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 #ifdef REGAMEDLL_ADD
Q_snprintf(filePath, sizeof(filePath), "%s%s%s", soundDir, baseDir, token); Q_snprintf(filePath, sizeof(filePath), "%s%s%s", soundDir, baseDir, token);
if (Q_access(filePath, 0) != 0) if (_access(filePath, 0) != 0)
continue; continue;
#endif #endif
@ -629,7 +620,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
BotSpeakableVector *speakables = phrase->m_voiceBank[ bankIndex ]; BotSpeakableVector *speakables = phrase->m_voiceBank[ bankIndex ];
speakables->push_back(speak); speakables->push_back(speak);
++phrase->m_count[ bankIndex ]; phrase->m_count[ bankIndex ]++;
} }
if (isDefault) if (isDefault)
@ -652,12 +643,11 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
BotPhraseManager::~BotPhraseManager() BotPhraseManager::~BotPhraseManager()
{ {
BotPhraseList::iterator iter; for (auto phrase : m_list)
for (iter = m_list.begin(); iter != m_list.end(); ++iter) delete phrase;
delete (*iter);
for (iter = m_placeList.begin(); iter != m_placeList.end(); ++iter) for (auto phrase : m_placeList)
delete (*iter); delete phrase;
m_list.clear(); m_list.clear();
m_placeList.clear(); m_placeList.clear();
@ -665,125 +655,107 @@ BotPhraseManager::~BotPhraseManager()
Place BotPhraseManager::NameToID(const char *name) const 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)) if (!Q_stricmp(phrase->m_name, name))
return phrase->m_id; 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)) if (!Q_stricmp(phrase->m_name, name))
return phrase->m_id; return phrase->m_id;
} }
return 0; return UNDEFINED_PLACE;
} }
const char *BotPhraseManager::IDToName(Place id) const 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) if (phrase->m_id == id)
return phrase->m_name; 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) if (phrase->m_id == id)
return phrase->m_name; return phrase->m_name;
} }
return NULL; return nullptr;
} }
// Given a name, return the associated phrase collection // Given a name, return the associated phrase collection
const BotPhrase *BotPhraseManager::GetPhrase(const char *name) const 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)) if (!Q_stricmp(phrase->m_name, name))
return phrase; return phrase;
} }
//CONSOLE_ECHO("GetPhrase: ERROR - Invalid phrase '%s'\n", name); //CONSOLE_ECHO("GetPhrase: ERROR - Invalid phrase '%s'\n", name);
return NULL; return nullptr;
} }
/*
// Given an id, return the associated phrase collection // Given an id, return the associated phrase collection
// TODO: Store phrases in a vector to make this fast // TODO: Store phrases in a vector to make this fast
const BotPhrase *BotPhraseManager::GetPhrase(unsigned int id) const 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) if (phrase->m_id == id)
return phrase; return phrase;
} }
CONSOLE_ECHO("GetPhrase: ERROR - Invalid phrase id #%d\n", id); CONSOLE_ECHO("GetPhrase: ERROR - Invalid phrase id #%d\n", id);
return NULL; return nullptr;
} }
*/
// Given a name, return the associated Place phrase collection // Given a name, return the associated Place phrase collection
const BotPhrase *BotPhraseManager::GetPlace(const char *name) const const BotPhrase *BotPhraseManager::GetPlace(const char *name) const
{ {
if (name == NULL) if (!name)
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 (!Q_stricmp(phrase->m_name, name)) if (!Q_stricmp(phrase->m_name, name))
return phrase; return phrase;
} }
return NULL; return nullptr;
} }
// Given a place, return the associated Place phrase collection // Given a place, return the associated Place phrase collection
const BotPhrase *BotPhraseManager::GetPlace(PlaceCriteria place) const const BotPhrase *BotPhraseManager::GetPlace(PlaceCriteria place) const
{ {
if (place == UNDEFINED_PLACE) 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) if (phrase->m_id == place)
return phrase; return phrase;
} }
return NULL; return nullptr;
} }
BotStatement::BotStatement(BotChatterInterface *chatter, BotStatementType type, float expireDuration) BotStatement::BotStatement(BotChatterInterface *chatter, BotStatementType type, float expireDuration)
{ {
m_chatter = chatter; m_chatter = chatter;
m_prev = m_next = NULL; m_prev = m_next = nullptr;
m_timestamp = gpGlobals->time; m_timestamp = gpGlobals->time;
m_speakTimestamp = 0.0f; m_speakTimestamp = 0.0f;
m_type = type; m_type = type;
m_subject = UNDEFINED_SUBJECT; m_subject = UNDEFINED_SUBJECT;
m_place = UNDEFINED_PLACE; m_place = UNDEFINED_PLACE;
m_meme = NULL; m_meme = nullptr;
m_startTime = gpGlobals->time; m_startTime = gpGlobals->time;
m_expireTime = gpGlobals->time + expireDuration; m_expireTime = gpGlobals->time + expireDuration;
@ -801,7 +773,7 @@ BotStatement::~BotStatement()
if (m_meme) if (m_meme)
{ {
delete m_meme; delete m_meme;
m_meme = NULL; m_meme = nullptr;
} }
} }
@ -827,7 +799,7 @@ void BotStatement::AddCondition(ConditionType condition)
bool BotStatement::IsImportant() const bool BotStatement::IsImportant() const
{ {
// if a statement contains any important phrases, it is important // 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()) if (m_statement[i].isPhrase && m_statement[i].phrase->IsImportant())
return true; return true;
@ -843,7 +815,7 @@ bool BotStatement::IsImportant() const
// Verify all attached conditions // Verify all attached conditions
bool BotStatement::IsValid() const bool BotStatement::IsValid() const
{ {
for (int i = 0; i < m_conditionCount; ++i) for (int i = 0; i < m_conditionCount; i++)
{ {
switch (m_condition[i]) switch (m_condition[i])
{ {
@ -961,7 +933,7 @@ void BotStatement::Convert(const BotStatement *say)
void BotStatement::AppendPhrase(const BotPhrase *phrase) void BotStatement::AppendPhrase(const BotPhrase *phrase)
{ {
if (phrase == NULL) if (!phrase)
return; return;
if (m_count < MAX_BOT_PHRASES) if (m_count < MAX_BOT_PHRASES)
@ -1025,7 +997,7 @@ bool BotStatement::Update()
// start next part of statement // start next part of statement
float duration = 0.0f; float duration = 0.0f;
const BotPhrase *phrase = NULL; const BotPhrase *phrase = nullptr;
if (m_statement[ m_index ].isPhrase) if (m_statement[ m_index ].isPhrase)
{ {
@ -1071,7 +1043,7 @@ bool BotStatement::Update()
// dont report if there are lots of enemies left // dont report if there are lots of enemies left
if (enemyCount < 0 || enemyCount > 3) if (enemyCount < 0 || enemyCount > 3)
{ {
phrase = NULL; phrase = nullptr;
} }
else else
{ {
@ -1144,7 +1116,7 @@ bool BotStatement::Update()
if (sayIt) if (sayIt)
{ {
if (filename == NULL) if (!filename)
{ {
GameEventType radioEvent = phrase->GetRadioEquivalent(); GameEventType radioEvent = phrase->GetRadioEquivalent();
if (radioEvent == EVENT_INVALID) if (radioEvent == EVENT_INVALID)
@ -1161,7 +1133,7 @@ bool BotStatement::Update()
} }
else else
{ {
me->Radio(filename, NULL, me->GetProfile()->GetVoicePitch(), false); me->Radio(filename, nullptr, me->GetProfile()->GetVoicePitch(), false);
me->GetChatter()->ResetRadioSilenceDuration(); me->GetChatter()->ResetRadioSilenceDuration();
me->StartVoiceFeedback(duration + 1.0f); me->StartVoiceFeedback(duration + 1.0f);
} }
@ -1190,7 +1162,7 @@ Place BotStatement::GetPlace() const
return m_place; return m_place;
// look for an implicit place in our statement // 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()) if (m_statement[i].isPhrase && m_statement[i].phrase->IsPlace())
return m_statement[i].phrase->GetID(); return m_statement[i].phrase->GetID();
@ -1202,7 +1174,7 @@ Place BotStatement::GetPlace() const
// Return true if this statement has an associated count // Return true if this statement has an associated count
bool BotStatement::HasCount() const 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) if (!m_statement[i].isPhrase && m_statement[i].context == CURRENT_ENEMY_COUNT)
return true; return true;
@ -1218,7 +1190,7 @@ static int nextPitch = P_HI;
BotChatterInterface::BotChatterInterface(CCSBot *me) BotChatterInterface::BotChatterInterface(CCSBot *me)
{ {
m_me = me; m_me = me;
m_statementList = NULL; m_statementList = nullptr;
switch (nextPitch) switch (nextPitch)
{ {
@ -1325,10 +1297,10 @@ void BotChatterInterface::AddStatement(BotStatement *statement, bool mustAdd)
// keep statements in order of start time // keep statements in order of start time
// check list is empty // check list is empty
if (m_statementList == NULL) if (!m_statementList)
{ {
statement->m_next = NULL; statement->m_next = nullptr;
statement->m_prev = NULL; statement->m_prev = nullptr;
m_statementList = statement; m_statementList = statement;
return; return;
} }
@ -1336,7 +1308,7 @@ void BotChatterInterface::AddStatement(BotStatement *statement, bool mustAdd)
// list has at least one statement on it // list has at least one statement on it
// insert into list in order // insert into list in order
BotStatement *earlier = NULL; BotStatement *earlier = nullptr;
for (s = m_statementList; s; s = s->m_next) for (s = m_statementList; s; s = s->m_next)
{ {
if (s->GetStartTime() > statement->GetStartTime()) if (s->GetStartTime() > statement->GetStartTime())
@ -1359,7 +1331,7 @@ void BotChatterInterface::AddStatement(BotStatement *statement, bool mustAdd)
else else
{ {
// insert at head // insert at head
statement->m_prev = NULL; statement->m_prev = nullptr;
statement->m_next = m_statementList; statement->m_next = m_statementList;
m_statementList->m_prev = statement; m_statementList->m_prev = statement;
m_statementList = statement; m_statementList = statement;
@ -1430,7 +1402,7 @@ void BotChatterInterface::OnDeath()
if (pain) 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(); m_me->GetChatter()->ResetRadioSilenceDuration();
} }
} }
@ -1476,7 +1448,7 @@ void BotChatterInterface::Update()
// Remove redundant statements (ie: our teammates already said them) // Remove redundant statements (ie: our teammates already said them)
const BotStatement *friendSay = GetActiveStatement(); const BotStatement *friendSay = GetActiveStatement();
if (friendSay && friendSay->GetOwner() == m_me) if (friendSay && friendSay->GetOwner() == m_me)
friendSay = NULL; friendSay = nullptr;
BotStatement *nextSay; BotStatement *nextSay;
for (say = m_statementList; say; say = nextSay) for (say = m_statementList; say; say = nextSay)
@ -1526,7 +1498,7 @@ BotStatement *BotChatterInterface::GetActiveStatement()
BotStatement *earliest = nullptr; BotStatement *earliest = nullptr;
float earlyTime = 999999999.9f; 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); CBasePlayer *player = UTIL_PlayerByIndex(i);
@ -2027,7 +1999,7 @@ void BotChatterInterface::RequestBombLocation()
void BotChatterInterface::BombsiteClear(int zoneIndex) void BotChatterInterface::BombsiteClear(int zoneIndex)
{ {
const CCSBotManager::Zone *zone = TheCSBots()->GetZone(zoneIndex); const CCSBotManager::Zone *zone = TheCSBots()->GetZone(zoneIndex);
if (zone == NULL) if (!zone)
return; return;
BotStatement *say = new BotStatement(this, REPORT_INFORMATION, 10.0f); BotStatement *say = new BotStatement(this, REPORT_INFORMATION, 10.0f);
@ -2041,7 +2013,7 @@ void BotChatterInterface::BombsiteClear(int zoneIndex)
void BotChatterInterface::FoundPlantedBomb(int zoneIndex) void BotChatterInterface::FoundPlantedBomb(int zoneIndex)
{ {
const CCSBotManager::Zone *zone = TheCSBots()->GetZone(zoneIndex); const CCSBotManager::Zone *zone = TheCSBots()->GetZone(zoneIndex);
if (zone == NULL) if (!zone)
return; return;
BotStatement *say = new BotStatement(this, REPORT_INFORMATION, 3.0f); 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 #pragma once
#endif
#define UNDEFINED_COUNT 0xFFFF #define UNDEFINED_COUNT 0xFFFF
#define MAX_PLACES_PER_MAP 64 #define MAX_PLACES_PER_MAP 64
@ -262,6 +258,9 @@ public:
// given a name, return the associated phrase collection // given a name, return the associated phrase collection
const BotPhrase *GetPhrase(const char *name) const; 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 // given a name, return the associated Place phrase collection
const BotPhrase *GetPlace(const char *name) const; const BotPhrase *GetPlace(const char *name) const;
@ -585,7 +584,6 @@ inline BotStatement *BotChatterInterface::GetStatement() const
} }
extern BotPhraseManager *TheBotPhrases; extern BotPhraseManager *TheBotPhrases;
extern CBaseEntity *g_pSelectedZombieSpawn;
inline void BotChatterInterface::Say(const char *phraseName, float lifetime, float delay) 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); 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()) if (!IsAlive())
return; 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 // If we just saw a nearby friend die, and we haven't yet acquired an enemy
// automatically acquire our dead friend's killer // 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 (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) // 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 // check if we saw our friend die - dont check FOV - assume we're aware of our surroundings in combat
// snipers stay put // snipers stay put
if (!IsSniper() && IsVisible(&player->pev->origin)) if (!IsSniper() && IsVisible(&pPlayer->pev->origin))
{ {
// people are dying - we should hurry // people are dying - we should hurry
Hurry(RANDOM_FLOAT(10.0f, 15.0f)); 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) if (!IsHiding() || !IsUsingKnife() || RANDOM_FLOAT(0, 100) < knifeAmbushChance)
{ {
PrintIfWatched("Attacking our friend's killer!\n"); PrintIfWatched("Attacking our friend's killer!\n");
Attack(killer); Attack(pKiller);
return; return;
} }
} }
@ -73,26 +73,26 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
{ {
case EVENT_PLAYER_DIED: case EVENT_PLAYER_DIED:
{ {
CBasePlayer *victim = player; CBasePlayer *pVictim = pPlayer;
CBasePlayer *killer = (other != NULL && other->IsPlayer()) ? static_cast<CBasePlayer *>(other) : NULL; CBasePlayer *pKiller = (other && other->IsPlayer()) ? static_cast<CBasePlayer *>(other) : nullptr;
// if the human player died in the single player game, tell the team // 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); GetChatter()->Say("CommanderDown", 20.0f);
} }
// keep track of the last player we killed // 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 // react to teammate death
if (BotRelationship(victim) == BOT_TEAMMATE) if (BotRelationship(pVictim) == BOT_TEAMMATE)
{ {
// chastise friendly fire from humans // 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(); GetChatter()->KilledFriend();
} }
@ -124,7 +124,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
// an enemy was killed // an enemy was killed
else 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 // only chatter about enemy kills if we see them occur, and they were the last one we see
if (GetNearbyEnemyCount() <= 1) 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 // report if number of enemies left is few and we killed the last one we saw locally
GetChatter()->EnemiesRemaining(); GetChatter()->EnemiesRemaining();
if (IsVisible(&victim->pev->origin, CHECK_FOV)) if (IsVisible(&pVictim->pev->origin, CHECK_FOV))
{ {
// congratulate teammates on their kills // congratulate teammates on their kills
if (killer != this) if (pKiller != this)
{ {
float delay = RANDOM_FLOAT(2.0f, 3.0f); float delay = RANDOM_FLOAT(2.0f, 3.0f);
if (killer->IsBot()) if (pKiller->IsBot())
{ {
if (RANDOM_FLOAT(0.0f, 100.0f) < 40.0f) if (RANDOM_FLOAT(0.0f, 100.0f) < 40.0f)
GetChatter()->Say("NiceShot", 3.0f, delay); GetChatter()->Say("NiceShot", 3.0f, delay);
@ -172,11 +172,11 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
return; return;
case EVENT_BOMB_PICKED_UP: 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 // check if we're close enough to hear it
const float bombPickupHearRangeSq = 1000.0f * 1000.0f; 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(); GetChatter()->TheyPickedUpTheBomb();
} }
@ -196,8 +196,10 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
if (m_iTeam == CT && GetGameState()->GetPlantedBombsite() == CSGameState::UNKNOWN) if (m_iTeam == CT && GetGameState()->GetPlantedBombsite() == CSGameState::UNKNOWN)
{ {
const CCSBotManager::Zone *zone = TheCSBots()->GetZone(&entity->pev->origin); const CCSBotManager::Zone *zone = TheCSBots()->GetZone(&entity->pev->origin);
if (zone != NULL) if (zone)
{
GetChatter()->FoundPlantedBomb(zone->m_index); GetChatter()->FoundPlantedBomb(zone->m_index);
}
} }
// remember where the bomb is // remember where the bomb is
@ -240,20 +242,20 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
} }
// Process radio events from our team // 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 // TODO: Distinguish between radio commands and responses
if (event != EVENT_RADIO_AFFIRMATIVE && event != EVENT_RADIO_NEGATIVE && event != EVENT_RADIO_REPORTING_IN) if (event != EVENT_RADIO_AFFIRMATIVE && event != EVENT_RADIO_NEGATIVE && event != EVENT_RADIO_REPORTING_IN)
{ {
m_lastRadioCommand = event; m_lastRadioCommand = event;
m_lastRadioRecievedTimestamp = gpGlobals->time; m_lastRadioRecievedTimestamp = gpGlobals->time;
m_radioSubject = player; m_radioSubject = pPlayer;
m_radioPosition = player->pev->origin; m_radioPosition = pPlayer->pev->origin;
} }
} }
// player_follows needs a player // player_follows needs a player
if (player == NULL) if (!pPlayer)
return; return;
if (!IsRogue() && event == EVENT_HOSTAGE_CALLED_FOR_HELP && m_iTeam == CT && IsHunting()) 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())) if (IsVisible(&entity->Center()))
{ {
m_task = COLLECT_HOSTAGES; m_task = COLLECT_HOSTAGES;
m_taskEntity = NULL; m_taskEntity = nullptr;
Run(); Run();
m_goalEntity = entity; 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 // don't pay attention to noise that friends make
if (!IsEnemy(player)) if (!IsEnemy(pPlayer))
return; return;
float range; 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()) if (!GetGameState()->GetNearestVisibleFreeHostage() && m_task != GUARD_HOSTAGE_RESCUE_ZONE && GuardRandomZone())
{ {
m_task = GUARD_HOSTAGE_RESCUE_ZONE; m_task = GUARD_HOSTAGE_RESCUE_ZONE;
m_taskEntity = NULL; m_taskEntity = nullptr;
SetDisposition(OPPORTUNITY_FIRE); SetDisposition(OPPORTUNITY_FIRE);
PrintIfWatched("Trying to beat them to an escape zone!\n"); 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 // 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(); float newNoiseDist = (pev->origin - *newNoisePosition).Length();
if (newNoiseDist < range) 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", PrintIfWatched("Heard noise (%s from %s, pri %s, time %3.1f)\n",
(event == EVENT_WEAPON_FIRED) ? "Weapon fire " : "", (event == EVENT_WEAPON_FIRED) ? "Weapon fire " : "",
STRING(player->pev->netname), STRING(pPlayer->pev->netname),
(priority == PRIORITY_HIGH) ? "HIGH" : ((priority == PRIORITY_MEDIUM) ? "MEDIUM" : "LOW"), (priority == PRIORITY_HIGH) ? "HIGH" : ((priority == PRIORITY_MEDIUM) ? "MEDIUM" : "LOW"),
gpGlobals->time); gpGlobals->time);
} }
@ -343,16 +345,15 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
} }
} }
// find the area in which the noise occured // find the area in which the noise occured
// TODO: Better handle when noise occurs off the nav mesh // 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: 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 // TODO: Change GetNavTravelTime to better deal with NULL destination areas
CNavArea *noiseArea = TheNavAreaGrid.GetNavArea(newNoisePosition); CNavArea *noiseArea = TheNavAreaGrid.GetNavArea(newNoisePosition);
if (noiseArea == NULL) if (!noiseArea)
noiseArea = TheNavAreaGrid.GetNearestNavArea(newNoisePosition); noiseArea = TheNavAreaGrid.GetNearestNavArea(newNoisePosition);
if (noiseArea == NULL) if (!noiseArea)
{ {
PrintIfWatched(" *** Noise occurred off the nav mesh - ignoring!\n"); PrintIfWatched(" *** Noise occurred off the nav mesh - ignoring!\n");
return; return;
@ -377,6 +378,7 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *othe
m_noiseArea->GetClosestPointOnArea(&m_noisePosition, &m_noisePosition); m_noiseArea->GetClosestPointOnArea(&m_noisePosition, &m_noisePosition);
m_isNoiseTravelRangeChecked = false; m_isNoiseTravelRangeChecked = false;
// note when we heard the noise // note when we heard the noise
m_noiseTimestamp = gpGlobals->time; m_noiseTimestamp = gpGlobals->time;
} }

View File

@ -5,46 +5,46 @@
*/ */
#ifndef HOOK_GAMEDLL #ifndef HOOK_GAMEDLL
cvar_t cv_bot_traceview = { "bot_traceview", "0", 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; 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, NULL }; cvar_t cv_bot_profile_db = { "bot_profile_db", "BotProfile.db", FCVAR_SERVER, 0.0f, nullptr };
#endif #endif
#ifdef REGAMEDLL_ADD #ifdef REGAMEDLL_ADD
cvar_t cv_bot_deathmatch = { "bot_deathmatch", "0", 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, NULL }; cvar_t cv_bot_quota_mode = { "bot_quota_mode", "normal", FCVAR_SERVER, 0.0f, nullptr };
#endif #endif
void InstallBotControl() void InstallBotControl()
{ {
if (TheBots != NULL) if (TheBots)
{ {
delete TheBots; delete TheBots;
} }
@ -55,7 +55,7 @@ void InstallBotControl()
// Engine callback for custom server commands // Engine callback for custom server commands
void Bot_ServerCommand() void Bot_ServerCommand()
{ {
if (TheBots != NULL) if (TheBots)
{ {
const char *pcmd = CMD_ARGV(0); const char *pcmd = CMD_ARGV(0);
TheBots->ServerCommand(pcmd); TheBots->ServerCommand(pcmd);
@ -122,8 +122,8 @@ bool CCSBot::Initialize(const BotProfile *profile)
m_combatRange = RANDOM_FLOAT(325, 425); m_combatRange = RANDOM_FLOAT(325, 425);
m_navNodeList = NULL; m_navNodeList = nullptr;
m_currentNode = NULL; m_currentNode = nullptr;
// set initial safe time guess for this map // set initial safe time guess for this map
m_safeTime = 15.0f + 5.0f * GetProfile()->GetAggression(); m_safeTime = 15.0f + 5.0f * GetProfile()->GetAggression();
@ -142,7 +142,7 @@ void CCSBot::ResetValues()
m_chatter.Reset(); m_chatter.Reset();
m_gameState.Reset(); m_gameState.Reset();
m_avoid = NULL; m_avoid = nullptr;
m_avoidTimestamp = 0.0f; m_avoidTimestamp = 0.0f;
m_hurryTimer.Invalidate(); m_hurryTimer.Invalidate();
@ -155,8 +155,8 @@ void CCSBot::ResetValues()
m_pathLength = 0; m_pathLength = 0;
m_pathIndex = 0; m_pathIndex = 0;
m_areaEnteredTimestamp = 0.0f; m_areaEnteredTimestamp = 0.0f;
m_currentArea = NULL; m_currentArea = nullptr;
m_lastKnownArea = NULL; m_lastKnownArea = nullptr;
m_avoidFriendTimer.Invalidate(); m_avoidFriendTimer.Invalidate();
m_isFriendInTheWay = false; m_isFriendInTheWay = false;
@ -164,7 +164,7 @@ void CCSBot::ResetValues()
m_disposition = ENGAGE_AND_INVESTIGATE; m_disposition = ENGAGE_AND_INVESTIGATE;
m_enemy = NULL; m_enemy = nullptr;
m_isWaitingToTossGrenade = false; m_isWaitingToTossGrenade = false;
m_wasSafe = true; m_wasSafe = true;
@ -172,10 +172,10 @@ void CCSBot::ResetValues()
m_nearbyEnemyCount = 0; m_nearbyEnemyCount = 0;
m_enemyPlace = 0; m_enemyPlace = 0;
m_nearbyFriendCount = 0; m_nearbyFriendCount = 0;
m_closestVisibleFriend = NULL; m_closestVisibleFriend = nullptr;
m_closestVisibleHumanFriend = NULL; 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].timestamp = 0.0f;
m_watchInfo[w].isEnemy = false; m_watchInfo[w].isEnemy = false;
@ -187,7 +187,7 @@ void CCSBot::ResetValues()
m_firstSawEnemyTimestamp = 0.0f; m_firstSawEnemyTimestamp = 0.0f;
m_currentEnemyAcquireTimestamp = 0.0f; m_currentEnemyAcquireTimestamp = 0.0f;
m_isLastEnemyDead = true; m_isLastEnemyDead = true;
m_attacker = NULL; m_attacker = nullptr;
m_attackedTimestamp = 0.0f; m_attackedTimestamp = 0.0f;
m_enemyDeathTimestamp = 0.0f; m_enemyDeathTimestamp = 0.0f;
m_lastVictimID = 0; m_lastVictimID = 0;
@ -196,14 +196,14 @@ void CCSBot::ResetValues()
m_equipTimer.Invalidate(); m_equipTimer.Invalidate();
m_isFollowing = false; m_isFollowing = false;
m_leader = NULL; m_leader = nullptr;
m_followTimestamp = 0.0f; m_followTimestamp = 0.0f;
m_allowAutoFollowTime = 0.0f; m_allowAutoFollowTime = 0.0f;
m_enemyQueueIndex = 0; m_enemyQueueIndex = 0;
m_enemyQueueCount = 0; m_enemyQueueCount = 0;
m_enemyQueueAttendIndex = 0; m_enemyQueueAttendIndex = 0;
m_bomber = NULL; m_bomber = nullptr;
m_lookAroundStateTimestamp = 0.0f; m_lookAroundStateTimestamp = 0.0f;
m_inhibitLookAroundTimestamp = 0.0f; m_inhibitLookAroundTimestamp = 0.0f;
@ -217,19 +217,19 @@ void CCSBot::ResetValues()
m_aimSpreadTimestamp = 0.0f; m_aimSpreadTimestamp = 0.0f;
m_lookAtSpotState = NOT_LOOKING_AT_SPOT; m_lookAtSpotState = NOT_LOOKING_AT_SPOT;
m_spotEncounter = NULL; m_spotEncounter = nullptr;
m_spotCheckTimestamp = 0.0f; m_spotCheckTimestamp = 0.0f;
m_peripheralTimestamp = 0.0f; m_peripheralTimestamp = 0.0f;
m_avgVelIndex = 0; m_avgVelIndex = 0;
m_avgVelCount = 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_lastRadioCommand = EVENT_INVALID;
m_lastRadioRecievedTimestamp = 0.0f; m_lastRadioRecievedTimestamp = 0.0f;
m_lastRadioSentTimestamp = 0.0f; m_lastRadioSentTimestamp = 0.0f;
m_radioSubject = NULL; m_radioSubject = nullptr;
m_voiceFeedbackEndTimestamp = 0.0f; m_voiceFeedbackEndTimestamp = 0.0f;
m_hostageEscortCount = 0; m_hostageEscortCount = 0;
@ -242,7 +242,7 @@ void CCSBot::ResetValues()
m_stateTimestamp = 0.0f; m_stateTimestamp = 0.0f;
m_task = SEEK_AND_DESTROY; m_task = SEEK_AND_DESTROY;
m_taskEntity = NULL; m_taskEntity = nullptr;
m_approachPointCount = 0; m_approachPointCount = 0;
m_approachPointViewPosition = Vector(0, 0, 0); m_approachPointViewPosition = Vector(0, 0, 0);
@ -254,7 +254,7 @@ void CCSBot::ResetValues()
Run(); Run();
m_mustRunTimer.Invalidate(); m_mustRunTimer.Invalidate();
m_repathTimer.Invalidate(); m_repathTimer.Invalidate();
m_pathLadder = NULL; m_pathLadder = nullptr;
m_huntState.ClearHuntArea(); m_huntState.ClearHuntArea();
@ -272,14 +272,14 @@ void CCSBot::ResetValues()
m_surpriseTimestamp = 0.0f; m_surpriseTimestamp = 0.0f;
// even though these are EHANDLEs, they need to be NULL-ed // even though these are EHANDLEs, they need to be NULL-ed
m_goalEntity = NULL; m_goalEntity = nullptr;
m_avoid = NULL; m_avoid = nullptr;
m_enemy = NULL; m_enemy = nullptr;
#ifdef REGAMEDLL_FIXES #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].isReloading = false;
m_enemyQueue[i].isProtectedByShield = false; m_enemyQueue[i].isProtectedByShield = false;
} }

View File

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

View File

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

View File

@ -5,7 +5,7 @@
*/ */
#ifndef HOOK_GAMEDLL #ifndef HOOK_GAMEDLL
CBotManager *TheBots = NULL; CBotManager *TheBots = nullptr;
float CCSBotManager::m_flNextCVarCheck = 0.0f; float CCSBotManager::m_flNextCVarCheck = 0.0f;
bool CCSBotManager::m_isMapDataLoaded = false; bool CCSBotManager::m_isMapDataLoaded = false;
@ -20,10 +20,10 @@ CCSBotManager::CCSBotManager()
IMPL(m_flNextCVarCheck) = 0.0f; IMPL(m_flNextCVarCheck) = 0.0f;
m_zoneCount = 0; m_zoneCount = 0;
SetLooseBomb(NULL); SetLooseBomb(nullptr);
m_isBombPlanted = false; m_isBombPlanted = false;
m_bombDefuser = NULL; m_bombDefuser = nullptr;
IMPL(m_isLearningMap) = false; IMPL(m_isLearningMap) = false;
IMPL(m_isAnalysisRequested) = false; IMPL(m_isAnalysisRequested) = false;
@ -55,15 +55,14 @@ CCSBotManager::CCSBotManager()
// read in the list of bot profile DBs // read in the list of bot profile DBs
int dataLength; int dataLength;
char *dataPointer = (char *)LOAD_FILE_FOR_ME((char *)filename, &dataLength); char *dataPointer = (char *)LOAD_FILE_FOR_ME((char *)filename, &dataLength);
if (!dataPointer)
if (dataPointer == NULL)
{ {
TheBotProfiles->Init("BotProfile.db"); TheBotProfiles->Init("BotProfile.db");
} }
else else
{ {
const char *dataFile = SharedParse(dataPointer); char *dataFile = SharedParse(dataPointer);
const char *token; char *token;
while (dataFile) 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. // 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. // Go back and parse the custom voice speakables.
const BotProfileManager::VoiceBankList *pVoiceBanks = TheBotProfiles->GetVoiceBanks(); 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); TheBotPhrases->Initialize((*pVoiceBanks)[i], i);
} }
@ -92,10 +91,10 @@ void CCSBotManager::RestartRound()
// extend // extend
CBotManager::RestartRound(); CBotManager::RestartRound();
SetLooseBomb(NULL); SetLooseBomb(nullptr);
m_isBombPlanted = false; m_isBombPlanted = false;
m_earliestBombPlantTimestamp = gpGlobals->time + RANDOM_FLOAT(10.0f, 30.0f); m_earliestBombPlantTimestamp = gpGlobals->time + RANDOM_FLOAT(10.0f, 30.0f);
m_bombDefuser = NULL; m_bombDefuser = nullptr;
IMPL(m_editCmd) = EDIT_NONE; 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; Vector from, to;
bool restart = true; bool restart = true;
for (int i = 0; edge[i] != 0; ++i) for (int i = 0; edge[i] != 0; i++)
{ {
if (restart) if (restart)
{ {
@ -177,7 +176,7 @@ void CCSBotManager::StartFrame()
// debug zone extent visualization // debug zone extent visualization
if (cv_bot_debug.value == 5.0f) 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]; Zone *zone = &m_zone[z];
UTIL_DrawBox(&zone->m_extent, 1, 255, 100, 0); 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 // Return true if the bot can use this weapon
bool CCSBotManager::IsWeaponUseable(CBasePlayerItem *item) const bool CCSBotManager::IsWeaponUseable(CBasePlayerItem *item) const
{ {
if (item == NULL) if (!item)
{ {
return false; return false;
} }
@ -351,7 +350,7 @@ void CCSBotManager::ClientDisconnect(CBasePlayer *pPlayer)
void PrintAllEntities() void PrintAllEntities()
{ {
for (int i = 1; i < gpGlobals->maxEntities; ++i) for (int i = 1; i < gpGlobals->maxEntities; i++)
{ {
edict_t *edict = INDEXENT(i); edict_t *edict = INDEXENT(i);
@ -396,11 +395,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
else else
killThemAll = false; killThemAll = false;
for (int iIndex = 1; iIndex <= gpGlobals->maxClients; ++iIndex) for (int i = 1; i <= gpGlobals->maxClients; i++)
{ {
CBasePlayer *pPlayer = UTIL_PlayerByIndex(iIndex); CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
if (!pPlayer)
if (pPlayer == NULL)
continue; continue;
if (FNullEnt(pPlayer->pev)) if (FNullEnt(pPlayer->pev))
@ -431,11 +429,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
else else
kickThemAll = false; kickThemAll = false;
for (int iIndex = 1; iIndex <= gpGlobals->maxClients; ++iIndex) for (int i = 1; i <= gpGlobals->maxClients; i++)
{ {
CBasePlayer *pPlayer = UTIL_PlayerByIndex(iIndex); CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
if (!pPlayer)
if (pPlayer == NULL)
continue; continue;
if (FNullEnt(pPlayer->pev)) if (FNullEnt(pPlayer->pev))
@ -593,10 +590,8 @@ void CCSBotManager::ServerCommand(const char *pcmd)
// no arguments = list all available places // no arguments = list all available places
int i = 0; int i = 0;
const BotPhraseList *placeList = TheBotPhrases->GetPlaceList(); 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()) if (phrase->GetID() == GetNavPlace())
CONSOLE_ECHO("--> %-26s", phrase->GetName()); CONSOLE_ECHO("--> %-26s", phrase->GetName());
else else
@ -604,6 +599,7 @@ void CCSBotManager::ServerCommand(const char *pcmd)
if (!(i % 3)) if (!(i % 3))
CONSOLE_ECHO("\n"); CONSOLE_ECHO("\n");
i++;
} }
CONSOLE_ECHO("\n"); CONSOLE_ECHO("\n");
} }
@ -611,12 +607,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
{ {
// single argument = set current place // single argument = set current place
const BotPhraseList *placeList = TheBotPhrases->GetPlaceList(); const BotPhraseList *placeList = TheBotPhrases->GetPlaceList();
const BotPhrase *found = NULL; const BotPhrase *found = nullptr;
bool isAmbiguous = false; 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))) if (!Q_strnicmp(phrase->GetName(), msg, Q_strlen(msg)))
{ {
// check for exact match in case of subsets of other strings // check for exact match in case of subsets of other strings
@ -671,7 +665,7 @@ void CCSBotManager::ServerCommand(const char *pcmd)
CNavArea *area = GetMarkedArea(); CNavArea *area = GetMarkedArea();
if (area) if (area)
{ {
CBaseEntity *pEntity = NULL; CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player"))) while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
{ {
if (!pEntity->IsPlayer()) if (!pEntity->IsPlayer())
@ -709,14 +703,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
sizeof(HidingSpot) * TheHidingSpotList.size()); sizeof(HidingSpot) * TheHidingSpotList.size());
unsigned int encounterMem = 0; unsigned int encounterMem = 0;
for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) for (auto area : TheNavAreaList)
{ {
CNavArea *area = (*iter); for (auto se : area->m_spotEncounterList)
for (SpotEncounterList::iterator siter = area->m_spotEncounterList.begin(); siter != area->m_spotEncounterList.end(); ++siter)
{ {
SpotEncounter se = (*siter);
encounterMem += sizeof(SpotEncounter); encounterMem += sizeof(SpotEncounter);
encounterMem += sizeof(SpotOrder) * se.spotList.size(); encounterMem += sizeof(SpotOrder) * se.spotList.size();
} }
@ -775,7 +765,7 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
if (IMPL(m_isLearningMap)) if (IMPL(m_isLearningMap))
return false; return false;
const BotProfile *profile = NULL; const BotProfile *profile = nullptr;
if (!isFromConsole || CMD_ARGC() < 2) if (!isFromConsole || CMD_ARGC() < 2)
{ {
@ -800,8 +790,7 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
// try to add a bot by name // try to add a bot by name
profile = TheBotProfiles->GetRandomProfile(GetDifficultyLevel(), team); profile = TheBotProfiles->GetRandomProfile(GetDifficultyLevel(), team);
if (!profile)
if (profile == NULL)
{ {
CONSOLE_ECHO("All bot profiles at this difficulty level are in use.\n"); CONSOLE_ECHO("All bot profiles at this difficulty level are in use.\n");
return true; return true;
@ -821,7 +810,7 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
} }
profile = TheBotProfiles->GetProfile(CMD_ARGV(1), team); profile = TheBotProfiles->GetProfile(CMD_ARGV(1), team);
if (profile == NULL) if (!profile)
{ {
CONSOLE_ECHO("Error - no profile for '%s' exists.\n", CMD_ARGV(1)); CONSOLE_ECHO("Error - no profile for '%s' exists.\n", CMD_ARGV(1));
return true; return true;
@ -1038,50 +1027,48 @@ void CCSBotManager::ValidateMapData()
m_gameScenario = SCENARIO_DEATHMATCH; m_gameScenario = SCENARIO_DEATHMATCH;
// Search all entities in the map and set the game type and store all zones (bomb target, etc). // Search all entities in the map and set the game type and store all zones (bomb target, etc).
CBaseEntity *entity = NULL; CBaseEntity *pEntity = nullptr;
int i; for (int i = 1; i < gpGlobals->maxEntities; i++)
for (i = 1; i < gpGlobals->maxEntities; ++i)
{ {
entity = CBaseEntity::Instance(INDEXENT(i)); pEntity = CBaseEntity::Instance(INDEXENT(i));
if (!pEntity)
if (entity == NULL)
continue; continue;
bool found = false; bool found = false;
bool isLegacy = false; bool isLegacy = false;
if (FClassnameIs(entity->pev, "func_bomb_target")) if (FClassnameIs(pEntity->pev, "func_bomb_target"))
{ {
m_gameScenario = SCENARIO_DEFUSE_BOMB; m_gameScenario = SCENARIO_DEFUSE_BOMB;
found = true; found = true;
isLegacy = false; isLegacy = false;
} }
else if (FClassnameIs(entity->pev, "info_bomb_target")) else if (FClassnameIs(pEntity->pev, "info_bomb_target"))
{ {
m_gameScenario = SCENARIO_DEFUSE_BOMB; m_gameScenario = SCENARIO_DEFUSE_BOMB;
found = true; found = true;
isLegacy = true; isLegacy = true;
} }
else if (FClassnameIs(entity->pev, "func_hostage_rescue")) else if (FClassnameIs(pEntity->pev, "func_hostage_rescue"))
{ {
m_gameScenario = SCENARIO_RESCUE_HOSTAGES; m_gameScenario = SCENARIO_RESCUE_HOSTAGES;
found = true; found = true;
isLegacy = false; isLegacy = false;
} }
else if (FClassnameIs(entity->pev, "info_hostage_rescue")) else if (FClassnameIs(pEntity->pev, "info_hostage_rescue"))
{ {
m_gameScenario = SCENARIO_RESCUE_HOSTAGES; m_gameScenario = SCENARIO_RESCUE_HOSTAGES;
found = true; found = true;
isLegacy = 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 // some very old maps (ie: cs_assault) use info_player_start
// as rescue zones, so set the scenario if there are hostages // as rescue zones, so set the scenario if there are hostages
// in the map // in the map
m_gameScenario = SCENARIO_RESCUE_HOSTAGES; 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; m_gameScenario = SCENARIO_ESCORT_VIP;
found = true; found = true;
@ -1092,14 +1079,16 @@ void CCSBotManager::ValidateMapData()
{ {
if (m_zoneCount < MAX_ZONES) 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_isLegacy = isLegacy;
m_zone[ m_zoneCount ].m_index = m_zoneCount; m_zone[ m_zoneCount ].m_index = m_zoneCount;
m_zone[ m_zoneCount ].m_entity = entity; m_zone[ m_zoneCount ].m_entity = pEntity;
m_zoneCount++; m_zoneCount++;
} }
else else
{
CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n"); 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. // use the info_player_start entities as rescue zones.
if (m_zoneCount == 0 && m_gameScenario == SCENARIO_RESCUE_HOSTAGES) 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 #ifdef REGAMEDLL_FIXES
if (m_zoneCount >= MAX_ZONES) if (m_zoneCount >= MAX_ZONES)
break; break;
#endif #endif
if (FNullEnt(entity->edict())) if (FNullEnt(pEntity->edict()))
break; break;
if (m_zoneCount < MAX_ZONES) 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_isLegacy = true;
m_zone[ m_zoneCount ].m_index = m_zoneCount; m_zone[ m_zoneCount ].m_index = m_zoneCount;
m_zone[ m_zoneCount ].m_entity = entity; m_zone[ m_zoneCount ].m_entity = pEntity;
m_zoneCount++; m_zoneCount++;
} }
else else
{
CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n"); CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n");
}
} }
} }
// Collect nav areas that overlap each zone // 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]; Zone *zone = &m_zone[i];
@ -1203,7 +1194,7 @@ bool CCSBotManager::AddBot(const BotProfile *profile, BotProfileTeamType team)
} }
CCSBot *pBot = CreateBot<CCSBot, CAPI_CSBot>(profile); CCSBot *pBot = CreateBot<CCSBot, CAPI_CSBot>(profile);
if (pBot == NULL) if (!pBot)
{ {
return false; 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))); SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", STRING(pBot->pev->netname)));
CONSOLE_ECHO("Could not add bot to the game.\n"); CONSOLE_ECHO("Could not add bot to the game.\n");
return false; return false;
} }
// Return the zone that contains the given position // Return the zone that contains the given position
const CCSBotManager::Zone *CCSBotManager::GetZone(const Vector *pos) const 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)) 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 // Return the closest zone to the given position
const CCSBotManager::Zone *CCSBotManager::GetClosestZone(const Vector *pos) const const CCSBotManager::Zone *CCSBotManager::GetClosestZone(const Vector *pos) const
{ {
const Zone *close = NULL; const Zone *close = nullptr;
float closeRangeSq = 1e9f; 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(); float rangeSq = (m_zone[z].m_center - (*pos)).LengthSquared();
@ -1276,11 +1266,11 @@ const Vector *CCSBotManager::GetRandomPositionInZone(const Zone *zone) const
{ {
static Vector pos; static Vector pos;
if (zone == NULL) if (!zone)
return NULL; return nullptr;
if (zone->m_areaCount == 0) if (zone->m_areaCount == 0)
return NULL; return nullptr;
// pick a random overlapping area // pick a random overlapping area
CNavArea *area = GetRandomAreaInZone(zone); CNavArea *area = GetRandomAreaInZone(zone);
@ -1314,7 +1304,7 @@ CNavArea *CCSBotManager::GetRandomAreaInZone(const Zone *zone) const
{ {
// TODO: improvement is needed // TODO: improvement is needed
if (!zone->m_areaCount) if (!zone->m_areaCount)
return NULL; return nullptr;
return zone->m_area[ RANDOM_LONG(0, zone->m_areaCount - 1) ]; return zone->m_area[ RANDOM_LONG(0, zone->m_areaCount - 1) ];
} }
@ -1333,12 +1323,12 @@ void CCSBotManager::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntit
break; break;
case EVENT_BOMB_DEFUSE_ABORTED: case EVENT_BOMB_DEFUSE_ABORTED:
m_bombDefuser = NULL; m_bombDefuser = nullptr;
break; break;
case EVENT_BOMB_DEFUSED: case EVENT_BOMB_DEFUSED:
m_isBombPlanted = false; m_isBombPlanted = false;
m_bombDefuser = NULL; m_bombDefuser = nullptr;
break; break;
case EVENT_TERRORISTS_WIN: case EVENT_TERRORISTS_WIN:
@ -1375,7 +1365,7 @@ void CCSBotManager::SetLooseBomb(CBaseEntity *bomb)
} }
else else
{ {
m_looseBombArea = NULL; m_looseBombArea = nullptr;
} }
} }
@ -1492,13 +1482,7 @@ void CCSBotManager::SetRadioMessageTimestamp(GameEventType event, int teamID)
// Reset all radio message timestamps // Reset all radio message timestamps
void CCSBotManager::ResetRadioMessageTimestamps() void CCSBotManager::ResetRadioMessageTimestamps()
{ {
for (int t = 0; t < ARRAYSIZE(m_radioMsgTimestamp[0]); ++t) Q_memset(m_radioMsgTimestamp, 0, sizeof(m_radioMsgTimestamp));
{
for (int m = 0; m < ARRAYSIZE(m_radioMsgTimestamp); ++m)
{
m_radioMsgTimestamp[m][t] = 0.0f;
}
}
} }
void CCSBotManager::OnFreeEntPrivateData(CBaseEntity *pEntity) void CCSBotManager::OnFreeEntPrivateData(CBaseEntity *pEntity)
@ -1513,10 +1497,10 @@ void CCSBotManager::OnFreeEntPrivateData(CBaseEntity *pEntity)
{ {
CCSBot *pBot = static_cast<CCSBot *>(pPlayer); CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
if (pBot->m_attacker == pEntity) if (pBot->m_attacker == pEntity)
pBot->m_attacker = NULL; pBot->m_attacker = nullptr;
if (pBot->m_bomber == pEntity) 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 #pragma once
#endif
extern CBotManager *TheBots; extern CBotManager *TheBots;
@ -134,7 +130,7 @@ public:
if (startArea == nullptr) if (startArea == nullptr)
return 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) if (m_zone[i].m_areaCount == 0)
continue; continue;
@ -269,5 +265,3 @@ inline bool AreBotsAllowed()
void PrintAllEntities(); void PrintAllEntities();
void UTIL_DrawBox(Extent *extent, int lifetime, int red, int green, int blue); 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 // we have enough samples to know if we're stuck
float avgVel = 0.0f; 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_avgVel[t];
avgVel /= m_avgVelCount; avgVel /= m_avgVelCount;
@ -140,7 +140,7 @@ bool CCSBot::GetSimpleGroundHeightWithFloor(const Vector *pos, float *height, Ve
if (GetSimpleGroundHeight(pos, height, normal)) if (GetSimpleGroundHeight(pos, height, normal))
{ {
// our current nav area also serves as a ground polygon // 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)); *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 Place CCSBot::GetPlace() const
{ {
if (m_lastKnownArea != NULL) if (m_lastKnownArea)
{
return m_lastKnownArea->GetPlace(); return m_lastKnownArea->GetPlace();
}
return UNDEFINED_PLACE; 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 // NOTE: We need to do this frequently to catch edges at the right time
// TODO: Look ahead *along path* instead of straight line // 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) && !IsOnLadder() && !m_isJumpCrouching)
{ {
float ground; float ground;
@ -243,7 +245,7 @@ void CCSBot::MoveTowardsPosition(const Vector *pos)
MoveBackward(); MoveBackward();
// if we are avoiding someone via strafing, don't override // if we are avoiding someone via strafing, don't override
if (m_avoid != NULL) if (m_avoid)
return; return;
if (latProj >= c) 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); Vector2D to(pos->x - pev->origin.x, pos->y - pev->origin.y);
to.NormalizeInPlace(); 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; 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) if (latProj >= 0.0f)
StrafeRight(); StrafeRight();
else else
StrafeLeft(); StrafeLeft();
#endif
} }
// For getting un-stuck // For getting un-stuck
@ -349,7 +366,7 @@ void CCSBot::ComputeApproachPoints()
{ {
m_approachPointCount = 0; m_approachPointCount = 0;
if (m_lastKnownArea == NULL) if (!m_lastKnownArea)
{ {
return; return;
} }
@ -359,11 +376,10 @@ void CCSBot::ComputeApproachPoints()
Vector ap; Vector ap;
float halfWidth; 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); const CNavArea::ApproachInfo *info = m_lastKnownArea->GetApproachInfo(i);
if (!info->here.area || !info->prev.area)
if (info->here.area == NULL || info->prev.area == NULL)
{ {
continue; continue;
} }
@ -391,7 +407,7 @@ void CCSBot::ComputeApproachPoints()
void CCSBot::DrawApproachPoints() 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); 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 // from us that is near our path
const float nearPathSq = 10000.0f; 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) if (FindClosestPointOnPath(&m_approachPoint[i], start, end, &close) == false)
continue; continue;

View File

@ -8,10 +8,10 @@ bool CCSBot::ComputePathPositions()
// start in first area's center // start in first area's center
m_path[0].pos = *m_path[0].area->GetCenter(); 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; 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]; const ConnectInfo *from = &m_path[i - 1];
ConnectInfo *to = &m_path[ i ]; ConnectInfo *to = &m_path[ i ];
@ -19,7 +19,7 @@ bool CCSBot::ComputePathPositions()
// walk along the floor to the next area // walk along the floor to the next area
if (to->how <= GO_WEST) if (to->how <= GO_WEST)
{ {
to->ladder = NULL; to->ladder = nullptr;
// compute next point, keeping path as straight as possible // compute next point, keeping path as straight as possible
from->area->ComputeClosestPointInPortal(to->area, (NavDirType)to->how, &from->pos, &to->pos); 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) if (m_pathLength < MAX_PATH_LENGTH - 1)
{ {
// copy nodes down // 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]; m_path[j] = m_path[j - 1];
// path is one node longer // path is one node longer
++m_pathLength; m_pathLength++;
// move index ahead into the new node we just duplicated // 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.x = to->pos.x + pushDist * dir.x;
m_path[i].pos.y = to->pos.y + pushDist * dir.y; m_path[i].pos.y = to->pos.y + pushDist * dir.y;
@ -72,7 +72,7 @@ bool CCSBot::ComputePathPositions()
// find our ladder // find our ladder
const NavLadderList *list = from->area->GetLadderList(LADDER_UP); const NavLadderList *list = from->area->GetLadderList(LADDER_UP);
NavLadderList::const_iterator iter; NavLadderList::const_iterator iter;
for (iter = list->begin(); iter != list->end(); ++iter) for (iter = list->begin(); iter != list->end(); iter++)
{ {
CNavLadder *ladder = (*iter); CNavLadder *ladder = (*iter);
@ -98,7 +98,7 @@ bool CCSBot::ComputePathPositions()
// find our ladder // find our ladder
const NavLadderList *list = from->area->GetLadderList(LADDER_DOWN); const NavLadderList *list = from->area->GetLadderList(LADDER_DOWN);
NavLadderList::const_iterator iter; NavLadderList::const_iterator iter;
for (iter = list->begin(); iter != list->end(); ++iter) for (iter = list->begin(); iter != list->end(); iter++)
{ {
CNavLadder *ladder = (*iter); CNavLadder *ladder = (*iter);
@ -130,9 +130,9 @@ void CCSBot::SetupLadderMovement()
const ConnectInfo *to = &m_path[ m_pathIndex ]; 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_areaEnteredTimestamp = gpGlobals->time;
m_pathLadder = to->ladder; 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. // TODO: Need Push() and Pop() for run/walk context to keep ladder speed contained.
bool CCSBot::UpdateLadderMovement() bool CCSBot::UpdateLadderMovement()
{ {
if (m_pathLadder == NULL) if (!m_pathLadder)
return false; return false;
bool giveUp = false; bool giveUp = false;
@ -556,7 +556,7 @@ bool CCSBot::UpdateLadderMovement()
// successfully traversed ladder and reached destination area // successfully traversed ladder and reached destination area
// exit ladder state machine // exit ladder state machine
PrintIfWatched("Ladder traversed.\n"); PrintIfWatched("Ladder traversed.\n");
m_pathLadder = NULL; m_pathLadder = nullptr;
// incrememnt path index to next step beyond this ladder // incrememnt path index to next step beyond this ladder
SetPathIndex(m_pathIndex + 1); 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 // 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 bool CCSBot::FindClosestPointOnPath(const Vector *worldPos, int startIndex, int endIndex, Vector *close) const
{ {
if (!HasPath() || close == NULL) if (!HasPath() || !close)
return false; return false;
Vector along, toWorldPos; Vector along, toWorldPos;
@ -587,7 +587,7 @@ bool CCSBot::FindClosestPointOnPath(const Vector *worldPos, int startIndex, int
float closeDistSq = 9999999999.9f; float closeDistSq = 9999999999.9f;
float distSq; float distSq;
for (int i = startIndex; i <= endIndex; ++i) for (int i = startIndex; i <= endIndex; i++)
{ {
from = &m_path[i - 1].pos; from = &m_path[i - 1].pos;
to = &m_path[i].pos; to = &m_path[i].pos;
@ -661,7 +661,7 @@ int CCSBot::FindOurPositionOnPath(Vector *close, bool local) const
end = m_pathLength; end = m_pathLength;
} }
for (int i = start; i < end; ++i) for (int i = start; i < end; i++)
{ {
from = &m_path[i - 1].pos; from = &m_path[i - 1].pos;
to = &m_path[i].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 const float closeEpsilon = 20.0f; // 10.0f
while ((*point - close).Make2D().IsLengthLessThan(closeEpsilon)) while ((*point - close).Make2D().IsLengthLessThan(closeEpsilon))
{ {
++index; index++;
if (index >= m_pathLength) if (index >= m_pathLength)
{ {
@ -826,7 +826,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
const float closeEpsilon = 20.0f; const float closeEpsilon = 20.0f;
if ((pos - close).Make2D().IsLengthLessThan(closeEpsilon)) if ((pos - close).Make2D().IsLengthLessThan(closeEpsilon))
{ {
++startIndex; startIndex++;
} }
else 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 we hit a ladder, stop, or jump area, must stop (dont use ladder behind us)
if (startIndex > m_pathIndex && startIndex < m_pathLength 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; *point = m_path[ startIndex ].pos;
return startIndex; return startIndex;
@ -847,7 +847,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
startIndex = m_pathLength - 1; startIndex = m_pathLength - 1;
// if we hit a ladder, stop, or jump area, must stop // 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; *point = m_path[ startIndex ].pos;
return startIndex; return startIndex;
@ -868,7 +868,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
// step along the path until we pass aheadRange // step along the path until we pass aheadRange
bool isCorner = false; bool isCorner = false;
int i; int i;
for (i = startIndex; i < m_pathLength; ++i) for (i = startIndex; i < m_pathLength; i++)
{ {
Vector pos = m_path[i].pos; Vector pos = m_path[i].pos;
Vector to = pos - m_path[i - 1].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) // 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 if (DotProduct(dir, initDir) < 0.0f) // -0.25f
{ {
--i; i--;
break; break;
} }
@ -886,7 +886,7 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
if (DotProduct(dir, prevDir) < 0.5f) if (DotProduct(dir, prevDir) < 0.5f)
{ {
isCorner = true; isCorner = true;
--i; i--;
break; 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 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; break;
// Check straight-line path from our current position to this position // Check straight-line path from our current position to this position
// Test for un-jumpable height change, or unrecoverable fall // Test for un-jumpable height change, or unrecoverable fall
if (!IsStraightLinePathWalkable(&pos)) if (!IsStraightLinePathWalkable(&pos))
{ {
--i; i--;
break; break;
} }
@ -979,11 +979,11 @@ int CCSBot::FindPathPoint(float aheadRange, Vector *point, int *prevIndex)
if (DotProduct(toPoint, initDir.Make2D()) < 0.0f || toPoint.IsLengthLessThan(epsilon)) if (DotProduct(toPoint, initDir.Make2D()) < 0.0f || toPoint.IsLengthLessThan(epsilon))
{ {
int i; 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.x = m_path[i].pos.x - pev->origin.x;
toPoint.y = m_path[i].pos.y - pev->origin.y; 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; *point = m_path[i].pos;
startIndex = i; startIndex = i;
@ -1019,9 +1019,9 @@ void CCSBot::SetPathIndex(int newIndex)
if (m_pathIndex < m_pathLength && m_pathIndex >= 2) 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); m_spotEncounter = m_path[ m_pathIndex - 1 ].area->GetSpotEncounter(m_path[ m_pathIndex - 2 ].area, m_path[ m_pathIndex ].area);
else 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) if (m_pathIndex == 0 || m_pathIndex >= m_pathLength)
return false; 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) if (m_path[ i ].area->GetAttributes() & NAV_JUMP)
{ {
float dz = m_path[ i + 1 ].pos.z - m_path[ i ].pos.z; float dz = m_path[ i + 1 ].pos.z - m_path[ i ].pos.z;
if (dz > 0.0f) if (dz > 0.0f)
{
return true; return true;
}
} }
} }
@ -1081,11 +1082,11 @@ bool CCSBot::IsFriendInTheWay(const Vector *goalPos) const
m_isFriendInTheWay = false; m_isFriendInTheWay = false;
// check if any friends are overlapping this linear path // 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); CBasePlayer *player = UTIL_PlayerByIndex(i);
if (player == NULL) if (!player)
continue; continue;
if (FNullEnt(player->pev)) if (FNullEnt(player->pev))
@ -1140,7 +1141,7 @@ bool CCSBot::IsFriendInTheWay(const Vector *goalPos) const
void CCSBot::FeelerReflexAdjustment(Vector *goalPosition) void CCSBot::FeelerReflexAdjustment(Vector *goalPosition)
{ {
// if we are in a "precise" area, do not do feeler adjustments // 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; return;
Vector dir(BotCOS(m_forwardAngle), BotSIN(m_forwardAngle), 0.0f); 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 // if there are no crouch areas coming up, stand
const float crouchRange = 50.0f; const float crouchRange = 50.0f;
bool didCrouch = false; 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; const CNavArea *to = m_path[i].area;
@ -1381,7 +1382,7 @@ CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
{ {
float along = toGoal.Length2D(); float along = toGoal.Length2D();
int i; 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; Vector delta = m_path[i].pos - m_path[i - 1].pos;
float segmentLength = delta.Length2D(); float segmentLength = delta.Length2D();
@ -1414,7 +1415,9 @@ CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
} }
if (i == m_pathLength) if (i == m_pathLength)
{
toGoal = GetPathEndpoint() - pev->origin; toGoal = GetPathEndpoint() - pev->origin;
}
} }
} }
else else
@ -1554,18 +1557,18 @@ void CCSBot::BuildTrivialPath(const Vector *goal)
m_path[0].area = m_lastKnownArea; m_path[0].area = m_lastKnownArea;
m_path[0].pos = pev->origin; m_path[0].pos = pev->origin;
m_path[0].pos.z = m_lastKnownArea->GetZ(&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[0].how = NUM_TRAVERSE_TYPES;
m_path[1].area = m_lastKnownArea; m_path[1].area = m_lastKnownArea;
m_path[1].pos = *goal; m_path[1].pos = *goal;
m_path[1].pos.z = m_lastKnownArea->GetZ(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_path[1].how = NUM_TRAVERSE_TYPES;
m_areaEnteredTimestamp = gpGlobals->time; m_areaEnteredTimestamp = gpGlobals->time;
m_spotEncounter = NULL; m_spotEncounter = nullptr;
m_pathLadder = NULL; m_pathLadder = nullptr;
m_goalPosition = *goal; m_goalPosition = *goal;
} }
@ -1590,16 +1593,16 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
// note final specific position // note final specific position
Vector pathEndPosition; Vector pathEndPosition;
if (goal == NULL && goalArea == NULL) if (!goal && !goalArea)
return false; return false;
if (goal == NULL) if (!goal)
pathEndPosition = *goalArea->GetCenter(); pathEndPosition = *goalArea->GetCenter();
else else
pathEndPosition = *goal; pathEndPosition = *goal;
// make sure path end position is on the ground // make sure path end position is on the ground
if (goalArea != NULL) if (goalArea)
pathEndPosition.z = goalArea->GetZ(&pathEndPosition); pathEndPosition.z = goalArea->GetZ(&pathEndPosition);
else else
GetGroundHeight(&pathEndPosition, &pathEndPosition.z); GetGroundHeight(&pathEndPosition, &pathEndPosition.z);
@ -1612,7 +1615,7 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
} }
// Compute shortest path to goal // Compute shortest path to goal
CNavArea *closestArea = NULL; CNavArea *closestArea = nullptr;
PathCost pathCost(this, route); PathCost pathCost(this, route);
bool pathToGoalExists = NavAreaBuildPath(startArea, goalArea, goal, pathCost, &closestArea); bool pathToGoalExists = NavAreaBuildPath(startArea, goalArea, goal, pathCost, &closestArea);
@ -1624,7 +1627,7 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
CNavArea *area; CNavArea *area;
for (area = effectiveGoalArea; area; area = area->GetParent()) for (area = effectiveGoalArea; area; area = area->GetParent())
{ {
++count; count++;
} }
// save room for endpoint // save room for endpoint
@ -1644,7 +1647,7 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
m_pathLength = count; m_pathLength = count;
for (area = effectiveGoalArea; count && area; area = area->GetParent()) for (area = effectiveGoalArea; count && area; area = area->GetParent())
{ {
--count; count--;
m_path[ count ].area = area; m_path[ count ].area = area;
m_path[ count ].how = area->GetParentHow(); m_path[ count ].how = area->GetParentHow();
} }
@ -1657,7 +1660,7 @@ bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route
return false; return false;
} }
if (goal == NULL) if (!goal)
{ {
switch (m_path[m_pathLength - 1].how) 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 // append path end position
m_path[ m_pathLength ].area = effectiveGoalArea; m_path[ m_pathLength ].area = effectiveGoalArea;
m_path[ m_pathLength ].pos = pathEndPosition; 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_path[ m_pathLength ].how = NUM_TRAVERSE_TYPES;
++m_pathLength; m_pathLength++;
// do movement setup // do movement setup
m_pathIndex = 1; m_pathIndex = 1;
m_areaEnteredTimestamp = gpGlobals->time; m_areaEnteredTimestamp = gpGlobals->time;
m_spotEncounter = NULL; m_spotEncounter = nullptr;
m_goalPosition = m_path[1].pos; m_goalPosition = m_path[1].pos;
if (m_path[1].ladder != NULL) if (m_path[1].ladder)
SetupLadderMovement(); SetupLadderMovement();
else else
m_pathLadder = NULL; m_pathLadder = nullptr;
return true; return true;
} }
@ -1709,7 +1712,7 @@ float CCSBot::GetPathDistanceRemaining() const
float dist = 0.0f; float dist = 0.0f;
const Vector *prevCenter = m_path[m_pathIndex].area->GetCenter(); 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(); dist += (*m_path[i].area->GetCenter() - *prevCenter).Length();
prevCenter = m_path[i].area->GetCenter(); prevCenter = m_path[i].area->GetCenter();
@ -1724,7 +1727,7 @@ void CCSBot::DrawPath()
if (!HasPath()) if (!HasPath())
return; 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); 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() void CCSBot::RespondToRadioCommands()
{ {
// bots use the chatter system to respond to each other // 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 (m_radioSubject->IsBot())
if (player->IsBot())
{ {
m_lastRadioCommand = EVENT_INVALID; m_lastRadioCommand = EVENT_INVALID;
return; return;
@ -71,8 +70,7 @@ void CCSBot::RespondToRadioCommands()
return; return;
} }
CBasePlayer *player = m_radioSubject; if (!m_radioSubject)
if (player == NULL)
return; return;
// respond to command // respond to command
@ -92,8 +90,8 @@ void CCSBot::RespondToRadioCommands()
{ {
if (!IsFollowing()) if (!IsFollowing())
{ {
Follow(player); Follow(m_radioSubject);
player->AllowAutoFollow(); m_radioSubject->AllowAutoFollow();
canDo = true; canDo = true;
} }
break; break;
@ -104,9 +102,9 @@ void CCSBot::RespondToRadioCommands()
{ {
if (!IsFollowing()) if (!IsFollowing())
{ {
Follow(player); Follow(m_radioSubject);
GetChatter()->Say("OnMyWay"); GetChatter()->Say("OnMyWay");
player->AllowAutoFollow(); m_radioSubject->AllowAutoFollow();
canDo = false; canDo = false;
} }
break; break;
@ -122,7 +120,7 @@ void CCSBot::RespondToRadioCommands()
// find the leader's area // find the leader's area
SetTask(HOLD_POSITION); SetTask(HOLD_POSITION);
StopFollowing(); StopFollowing();
player->InhibitAutoFollow(inhibitAutoFollowDuration); m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
Hide(TheNavAreaGrid.GetNearestNavArea(&m_radioPosition)); Hide(TheNavAreaGrid.GetNearestNavArea(&m_radioPosition));
canDo = true; canDo = true;
break; break;
@ -133,7 +131,7 @@ void CCSBot::RespondToRadioCommands()
StopFollowing(); StopFollowing();
Hunt(); Hunt();
canDo = true; canDo = true;
player->InhibitAutoFollow(inhibitAutoFollowDuration); m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
break; break;
} }
case EVENT_RADIO_GET_OUT_OF_THERE: case EVENT_RADIO_GET_OUT_OF_THERE:
@ -141,7 +139,7 @@ void CCSBot::RespondToRadioCommands()
if (TheCSBots()->IsBombPlanted()) if (TheCSBots()->IsBombPlanted())
{ {
EscapeFromBomb(); EscapeFromBomb();
player->InhibitAutoFollow(inhibitAutoFollowDuration); m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
canDo = true; canDo = true;
} }
break; break;
@ -154,9 +152,8 @@ void CCSBot::RespondToRadioCommands()
{ {
if (m_iTeam == CT && TheCSBots()->IsBombPlanted()) if (m_iTeam == CT && TheCSBots()->IsBombPlanted())
{ {
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(player); const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(m_radioSubject);
if (zone)
if (zone != NULL)
{ {
GetGameState()->ClearBombsite(zone->m_index); GetGameState()->ClearBombsite(zone->m_index);
@ -197,11 +194,11 @@ void CCSBot::StartVoiceFeedback(float duration)
m_voiceFeedbackStartTimestamp = gpGlobals->time; m_voiceFeedbackStartTimestamp = gpGlobals->time;
m_voiceFeedbackEndTimestamp = duration + gpGlobals->time; m_voiceFeedbackEndTimestamp = duration + gpGlobals->time;
CBasePlayer *pPlayer = NULL; CBasePlayer *pPlayer = nullptr;
while ((pPlayer = GetNextRadioRecipient(pPlayer)) != NULL) while ((pPlayer = GetNextRadioRecipient(pPlayer)))
{ {
MESSAGE_BEGIN(MSG_ONE, gmsgBotVoice, NULL, pPlayer->pev); MESSAGE_BEGIN(MSG_ONE, gmsgBotVoice, nullptr, pPlayer->pev);
WRITE_BYTE(1); // active is talking WRITE_BYTE(1); // active is talking
WRITE_BYTE(entindex()); // client index speaking WRITE_BYTE(entindex()); // client index speaking
MESSAGE_END(); MESSAGE_END();
} }
@ -264,7 +261,7 @@ bool CCSBot::RespondToHelpRequest(CBasePlayer *them, Place place, float maxRange
// go to where help is needed // go to where help is needed
const Vector *pos = GetRandomSpotAtPlace(place); const Vector *pos = GetRandomSpotAtPlace(place);
if (pos != NULL) if (pos)
{ {
MoveTo(pos, FASTEST_ROUTE); MoveTo(pos, FASTEST_ROUTE);
} }

View File

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

View File

@ -15,7 +15,7 @@ void CCSBot::Upkeep()
UpdateAimOffset(); UpdateAimOffset();
// aim at enemy, if he's still alive // aim at enemy, if he's still alive
if (m_enemy != NULL) if (m_enemy.IsValid())
{ {
float feetOffset = pev->origin.z - GetFeetZ(); float feetOffset = pev->origin.z - GetFeetZ();
@ -70,11 +70,15 @@ void CCSBot::Upkeep()
m_aimSpot.z -= feetOffset * 0.5f; m_aimSpot.z -= feetOffset * 0.5f;
} }
else // FEET else // FEET
{
m_aimSpot.z -= (feetOffset + feetOffset); m_aimSpot.z -= (feetOffset + feetOffset);
}
} }
} }
else else
{
m_aimSpot = m_lastEnemyPosition; m_aimSpot = m_lastEnemyPosition;
}
// add in aim error // add in aim error
m_aimSpot.x += m_aimOffset.x; m_aimSpot.x += m_aimOffset.x;
@ -157,10 +161,10 @@ void CCSBot::Update()
switch (m_processMode) switch (m_processMode)
{ {
case PROCESS_LEARN: UpdateLearnProcess(); return; case PROCESS_LEARN: UpdateLearnProcess(); return;
case PROCESS_ANALYZE_ALPHA: UpdateAnalyzeAlphaProcess(); return; case PROCESS_ANALYZE_ALPHA: UpdateAnalyzeAlphaProcess(); return;
case PROCESS_ANALYZE_BETA: UpdateAnalyzeBetaProcess(); return; case PROCESS_ANALYZE_BETA: UpdateAnalyzeBetaProcess(); return;
case PROCESS_SAVE: UpdateSaveProcess(); return; case PROCESS_SAVE: UpdateSaveProcess(); return;
} }
// update our radio chatter // update our radio chatter
@ -210,23 +214,15 @@ void CCSBot::Update()
// show encounter spot data // show encounter spot data
if ((cv_bot_traceview.value == 4.0f && IsLocalPlayerWatchingMe()) || cv_bot_traceview.value == 5.0f) 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); UTIL_DrawBeamPoints(m_spotEncounter->path.from, m_spotEncounter->path.to, 3, 0, 0, 255);
Vector dir = m_spotEncounter->path.to - m_spotEncounter->path.from; Vector dir = m_spotEncounter->path.to - m_spotEncounter->path.from;
float length = dir.NormalizeInPlace(); float length = dir.NormalizeInPlace();
const SpotOrder *order; for (auto &order : m_spotEncounter->spotList) {
Vector along; UTIL_DrawBeamPoints(m_spotEncounter->path.from + order.t * length * dir, *order.spot->GetPosition(), 3, 0, 255, 255);
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);
} }
} }
} }
@ -261,7 +257,7 @@ void CCSBot::Update()
} }
// track the last known area we were in // 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; m_lastKnownArea = m_currentArea;
// assume that we "clear" an area of enemies when we enter it // assume that we "clear" an area of enemies when we enter it
@ -276,7 +272,7 @@ void CCSBot::Update()
m_approachPointViewPosition = pev->origin; 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(); m_lastKnownArea->DrawConnectedAreas();
} }
@ -310,7 +306,7 @@ void CCSBot::Update()
// "threat" may be the same as our current enemy // "threat" may be the same as our current enemy
CBasePlayer *threat = GetRecognizedEnemy(); CBasePlayer *threat = GetRecognizedEnemy();
if (threat != NULL) if (threat)
{ {
// adjust our personal "safe" time // adjust our personal "safe" time
AdjustSafeTime(); AdjustSafeTime();
@ -355,7 +351,7 @@ void CCSBot::Update()
if (doAttack) if (doAttack)
{ {
if (GetEnemy() == NULL || threat != GetEnemy() || !IsAttacking()) if (!GetEnemy() || threat != GetEnemy() || !IsAttacking())
{ {
if (IsUsingKnife() && IsHiding()) if (IsUsingKnife() && IsHiding())
{ {
@ -397,12 +393,12 @@ void CCSBot::Update()
} }
// Validate existing enemy, if any // Validate existing enemy, if any
if (m_enemy != NULL) if (m_enemy.IsValid())
{ {
if (IsAwareOfEnemyDeath()) if (IsAwareOfEnemyDeath())
{ {
// we have noticed that our enemy has died // we have noticed that our enemy has died
m_enemy = NULL; m_enemy = nullptr;
m_isEnemyVisible = false; m_isEnemyVisible = false;
} }
else else
@ -442,7 +438,7 @@ void CCSBot::Update()
// if we have seen an enemy recently, keep an eye on him if we can // if we have seen an enemy recently, keep an eye on him if we can
const float seenRecentTime = 3.0f; const float seenRecentTime = 3.0f;
if (m_enemy != NULL && GetTimeSinceLastSawEnemy() < seenRecentTime) if (m_enemy.IsValid() && GetTimeSinceLastSawEnemy() < seenRecentTime)
{ {
AimAtEnemy(); AimAtEnemy();
} }
@ -523,13 +519,13 @@ void CCSBot::Update()
// make way // make way
const float avoidTime = 0.33f; 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); StrafeAwayFromPosition(&m_avoid->pev->origin);
} }
else else
{ {
m_avoid = NULL; m_avoid = nullptr;
} }
if (m_isJumpCrouching) if (m_isJumpCrouching)
@ -559,11 +555,15 @@ void CCSBot::Update()
UpdatePeripheralVision(); UpdatePeripheralVision();
// Update gamestate // Update gamestate
if (m_bomber != NULL) if (m_bomber)
{
GetChatter()->SpottedBomber(GetBomber()); GetChatter()->SpottedBomber(GetBomber());
}
if (CanSeeLooseBomb()) if (CanSeeLooseBomb())
{
GetChatter()->SpottedLooseBomb(TheCSBots()->GetLooseBomb()); GetChatter()->SpottedLooseBomb(TheCSBots()->GetLooseBomb());
}
// Scenario interrupts // Scenario interrupts
switch (TheCSBots()->GetScenario()) switch (TheCSBots()->GetScenario())
@ -632,7 +632,7 @@ void CCSBot::Update()
if (GetProfile()->GetTeamwork() > RANDOM_FLOAT(0.0f, 1.0f)) if (GetProfile()->GetTeamwork() > RANDOM_FLOAT(0.0f, 1.0f))
{ {
CBasePlayer *leader = GetClosestVisibleHumanFriend(); CBasePlayer *leader = GetClosestVisibleHumanFriend();
if (leader != NULL && leader->IsAutoFollowAllowed()) if (leader && leader->IsAutoFollowAllowed())
{ {
// count how many bots are already following this player // count how many bots are already following this player
const float maxFollowCount = 2; const float maxFollowCount = 2;
@ -642,7 +642,7 @@ void CCSBot::Update()
if ((leader->pev->origin - pev->origin).IsLengthLessThan(autoFollowRange)) if ((leader->pev->origin - pev->origin).IsLengthLessThan(autoFollowRange))
{ {
CNavArea *leaderArea = TheNavAreaGrid.GetNavArea(&leader->pev->origin); CNavArea *leaderArea = TheNavAreaGrid.GetNavArea(&leader->pev->origin);
if (leaderArea != NULL) if (leaderArea)
{ {
PathCost cost(this, FASTEST_ROUTE); PathCost cost(this, FASTEST_ROUTE);
float travelRange = NavAreaTravelDistance(GetLastKnownArea(), leaderArea, cost); float travelRange = NavAreaTravelDistance(GetLastKnownArea(), leaderArea, cost);
@ -676,8 +676,8 @@ void CCSBot::Update()
if (IsFollowing()) if (IsFollowing())
{ {
// if we are following someone, make sure they are still alive // if we are following someone, make sure they are still alive
CBaseEntity *leader = m_leader; CBaseEntity *pLeader = m_leader;
if (leader == NULL || !leader->IsAlive()) if (!pLeader || !pLeader->IsAlive())
{ {
StopFollowing(); 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 bool CCSBot::IsVisible(CBasePlayer *player, bool testFOV, unsigned char *visParts) const
{ {
Vector spot = player->pev->origin; Vector spot = player->pev->origin;
VisiblePartType testVisParts = NONE; unsigned char testVisParts = NONE;
// finish chest check // finish chest check
if (IsVisible(&spot, testFOV)) if (IsVisible(&spot, testFOV))
@ -266,7 +266,7 @@ bool CCSBot::IsVisible(CBasePlayer *player, bool testFOV, unsigned char *visPart
if (IsVisible(&spot, testFOV)) if (IsVisible(&spot, testFOV))
testVisParts |= RIGHT_SIDE; testVisParts |= RIGHT_SIDE;
if (visParts != NULL) if (visParts)
*visParts = testVisParts; *visParts = testVisParts;
if (testVisParts != NONE) if (testVisParts != NONE)
@ -295,7 +295,7 @@ void CCSBot::UpdateLookAt()
// Look at the given point in space for the given duration (-1 means forever) // 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) void CCSBot::SetLookAt(const char *desc, const Vector *pos, PriorityType pri, float duration, bool clearIfClose, float angleTolerance)
{ {
if (pos == NULL) if (!pos)
return; return;
// if currently looking at a point in space with higher priority, ignore this request // if currently looking at a point in space with higher priority, ignore this request
@ -344,14 +344,10 @@ void CCSBot::UpdatePeripheralVision()
if (m_spotEncounter) if (m_spotEncounter)
{ {
// check LOS to all spots in case we see them with our "peripheral vision" // check LOS to all spots in case we see them with our "peripheral vision"
const SpotOrder *spotOrder = NULL;
Vector pos; Vector pos;
for (auto &spotOrder : m_spotEncounter->spotList)
for (SpotOrderList::const_iterator iter = m_spotEncounter->spotList.begin(); iter != m_spotEncounter->spotList.end(); ++iter)
{ {
spotOrder = &(*iter); const Vector *spotPos = spotOrder.spot->GetPosition();
const Vector *spotPos = spotOrder->spot->GetPosition();
pos.x = spotPos->x; pos.x = spotPos->x;
pos.y = spotPos->y; pos.y = spotPos->y;
@ -361,7 +357,7 @@ void CCSBot::UpdatePeripheralVision()
continue; continue;
// can see hiding spot, remember when we saw it last // 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; return;
if (gpGlobals->time < m_lookAroundStateTimestamp) if (gpGlobals->time < m_lookAroundStateTimestamp)
@ -453,14 +449,12 @@ void CCSBot::UpdateLookAround(bool updateNow)
} }
int which = RANDOM_LONG(0, m_approachPointCount - 1); 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 // 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 // TODO: If this approach point is very near, this will cause us to aim up in the air if were crouching
spot.z += HalfHumanHeight; spot.z += HalfHumanHeight;
SetLookAt("Approach Point (Hiding)", &spot, PRIORITY_LOW); SetLookAt("Approach Point (Hiding)", &spot, PRIORITY_LOW);
return; return;
} }
@ -511,24 +505,22 @@ void CCSBot::UpdateLookAround(bool updateNow)
int dangerIndex = 0; int dangerIndex = 0;
const float checkTime = 10.0f; 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 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; continue;
if (spotOrder->t > t) if (spotOrder.t > t)
break; break;
dangerSpot[ dangerIndex++ ] = spotOrder->spot; dangerSpot[dangerIndex++] = spotOrder.spot;
if (dangerIndex >= MAX_DANGER_SPOTS) if (dangerIndex >= MAX_DANGER_SPOTS)
dangerIndex = 0; dangerIndex = 0;
if (dangerSpotCount < MAX_DANGER_SPOTS) if (dangerSpotCount < MAX_DANGER_SPOTS)
++dangerSpotCount; dangerSpotCount++;
} }
if (dangerSpotCount) if (dangerSpotCount)
@ -536,7 +528,7 @@ void CCSBot::UpdateLookAround(bool updateNow)
// pick one of the spots at random // pick one of the spots at random
int which = RANDOM_LONG(0, dangerSpotCount - 1); int which = RANDOM_LONG(0, dangerSpotCount - 1);
const Vector *checkSpot = dangerSpot[ which ]->GetPosition(); const Vector *checkSpot = dangerSpot[which]->GetPosition();
Vector pos = *checkSpot; Vector pos = *checkSpot;
pos.z += HalfHumanHeight; 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) for (float angle = angleInc; angle <= 135.0f; angle += angleInc)
{ {
// check both sides at this angle offset // 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 dx = BotCOS(actualAngle);
float dy = BotSIN(actualAngle); float dy = BotSIN(actualAngle);
@ -635,31 +627,44 @@ bool CCSBot::BendLineOfSight(const Vector *eye, const Vector *point, Vector *ben
CBasePlayer *CCSBot::FindMostDangerousThreat() CBasePlayer *CCSBot::FindMostDangerousThreat()
{ {
// maximum number of simulataneously attendable threats // 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 struct CloseInfo
{ {
CBasePlayer *enemy; CBasePlayer *enemy;
float range; float range;
} };
threat[ MAX_THREATS ];
CloseInfo threat[MAX_THREATS];
int threatCount = 0; 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; float closeFriendRange = 99999999999.9f;
m_closestVisibleHumanFriend = NULL;
float closeHumanFriendRange = 99999999999.9f; float closeHumanFriendRange = 99999999999.9f;
int i; int i;
{ {
for (i = 1; i <= gpGlobals->maxClients; ++i) for (i = 1; i <= gpGlobals->maxClients; i++)
{ {
CBasePlayer *player = UTIL_PlayerByIndex(i); CBasePlayer *player = UTIL_PlayerByIndex(i);
if (player == NULL) if (!player)
continue; continue;
if (FNullEnt(player->pev)) if (FNullEnt(player->pev))
@ -710,9 +715,21 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
} }
// check if this enemy is fully // check if this enemy is fully
if (!IsVisible(player, CHECK_FOV)) unsigned char visParts;
if (!IsVisible(player, CHECK_FOV, &visParts))
continue; 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 // update watch timestamp
int idx = player->entindex() - 1; int idx = player->entindex() - 1;
m_watchInfo[idx].timestamp = gpGlobals->time; m_watchInfo[idx].timestamp = gpGlobals->time;
@ -739,13 +756,12 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
{ {
// find insertion point // find insertion point
int j; int j;
for (j = 0; j < threatCount; ++j) for (j = 0; j < threatCount; j++)
{ {
if (distSq < threat[j].range) if (distSq < threat[j].range)
break; break;
} }
// shift lower half down a notch // shift lower half down a notch
for (int k = threatCount - 1; k >= j; --k) for (int k = threatCount - 1; k >= j; --k)
threat[k + 1] = threat[k]; threat[k + 1] = threat[k];
@ -755,7 +771,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
threat[j].range = distSq; threat[j].range = distSq;
if (threatCount < MAX_THREATS) if (threatCount < MAX_THREATS)
++threatCount; threatCount++;
} }
} }
} }
@ -766,7 +782,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
m_nearbyEnemyCount = 0; m_nearbyEnemyCount = 0;
m_nearbyFriendCount = 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) if (m_watchInfo[i].timestamp <= 0.0f)
continue; continue;
@ -775,9 +791,9 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
if (gpGlobals->time - m_watchInfo[i].timestamp < recentTime) if (gpGlobals->time - m_watchInfo[i].timestamp < recentTime)
{ {
if (m_watchInfo[i].isEnemy) if (m_watchInfo[i].isEnemy)
++m_nearbyEnemyCount; m_nearbyEnemyCount++;
else else
++m_nearbyFriendCount; m_nearbyFriendCount++;
} }
} }
@ -799,14 +815,14 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
unsigned int place; unsigned int place;
int count; int count;
}; };
static PlaceRank placeRank[ MAX_PLACES_PER_MAP ]; static PlaceRank placeRank[MAX_PLACES_PER_MAP];
int locCount = 0; int locCount = 0;
PlaceRank common; PlaceRank common;
common.place = 0; common.place = 0;
common.count = 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 // find the area the player/bot is standing on
CNavArea *area; CNavArea *area;
@ -821,7 +837,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
area = TheNavAreaGrid.GetNearestNavArea(&threat[i].enemy->pev->origin); area = TheNavAreaGrid.GetNearestNavArea(&threat[i].enemy->pev->origin);
} }
if (area == NULL) if (!area)
continue; continue;
unsigned int threatLoc = area->GetPlace(); unsigned int threatLoc = area->GetPlace();
@ -830,7 +846,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
// if place is already in set, increment count // if place is already in set, increment count
int j; int j;
for (j = 0; j < locCount; ++j) for (j = 0; j < locCount; j++)
{ {
if (placeRank[j].place == threatLoc) if (placeRank[j].place == threatLoc)
break; break;
@ -841,19 +857,19 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
// new place // new place
if (locCount < MAX_PLACES_PER_MAP) if (locCount < MAX_PLACES_PER_MAP)
{ {
placeRank[ locCount ].place = threatLoc; placeRank[locCount].place = threatLoc;
placeRank[ locCount ].count = 1; placeRank[locCount].count = 1;
if (common.count == 0) if (common.count == 0)
common = placeRank[locCount]; common = placeRank[locCount];
++locCount; locCount++;
} }
} }
else else
{ {
// others are in that place, increment // others are in that place, increment
++placeRank[j].count; placeRank[j].count++;
// keep track of the most common place // keep track of the most common place
if (placeRank[j].count > common.count) if (placeRank[j].count > common.count)
@ -867,11 +883,33 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
{ {
if (threatCount == 0) 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 // 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()) if (!threat[t].enemy->IsProtectedByShield())
{ {
@ -896,18 +934,23 @@ void CCSBot::UpdateReactionQueue()
int now = m_enemyQueueIndex; 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 // 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].player = threat;
m_enemyQueue[ now ].isReloading = threat->IsReloading(); m_enemyQueue[now].isReloading = threat->IsReloading();
m_enemyQueue[ now ].isProtectedByShield = threat->IsProtectedByShield(); m_enemyQueue[now].isProtectedByShield = threat->IsProtectedByShield();
} }
else else
{ {
m_enemyQueue[ now ].player = NULL; m_enemyQueue[now].player = nullptr;
m_enemyQueue[ now ].isReloading = false; m_enemyQueue[now].isReloading = false;
m_enemyQueue[ now ].isProtectedByShield = false; m_enemyQueue[now].isProtectedByShield = false;
} }
// queue is round-robin // queue is round-robin
@ -915,7 +958,7 @@ void CCSBot::UpdateReactionQueue()
m_enemyQueueIndex = 0; m_enemyQueueIndex = 0;
if (m_enemyQueueCount < MAX_ENEMY_QUEUE) if (m_enemyQueueCount < MAX_ENEMY_QUEUE)
++m_enemyQueueCount; m_enemyQueueCount++;
// clamp reaction time to enemy queue size // clamp reaction time to enemy queue size
float reactionTime = GetProfile()->GetReactionTime(); float reactionTime = GetProfile()->GetReactionTime();
@ -937,9 +980,9 @@ void CCSBot::UpdateReactionQueue()
CBasePlayer *CCSBot::GetRecognizedEnemy() CBasePlayer *CCSBot::GetRecognizedEnemy()
{ {
if (m_enemyQueueAttendIndex >= m_enemyQueueCount) 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 // Return true if the enemy we are "conscious" of is reloading
@ -948,7 +991,7 @@ bool CCSBot::IsRecognizedEnemyReloading()
if (m_enemyQueueAttendIndex >= m_enemyQueueCount) if (m_enemyQueueAttendIndex >= m_enemyQueueCount)
return false; 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 // 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) if (m_enemyQueueAttendIndex >= m_enemyQueueCount)
return false; return false;
return m_enemyQueue[ m_enemyQueueAttendIndex ].isProtectedByShield; return m_enemyQueue[m_enemyQueueAttendIndex].isProtectedByShield;
} }
// Return distance to closest enemy we are "conscious" of // Return distance to closest enemy we are "conscious" of
float CCSBot::GetRangeToNearestRecognizedEnemy() 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; return 99999999.9f;
@ -995,3 +1038,139 @@ void CCSBot::Blind(float duration, float holdTime, float fadeTime, int alpha)
// no longer safe // no longer safe
AdjustSafeTime(); 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() // NOTE: Aiming our weapon is handled in RunBotUpkeep()
void CCSBot::FireWeaponAtEnemy() void CCSBot::FireWeaponAtEnemy()
{ {
CBasePlayer *enemy = GetEnemy(); CBasePlayer *pEnemy = GetEnemy();
if (enemy == NULL) if (!pEnemy)
{ {
StopRapidFire(); StopRapidFire();
return; return;
@ -24,7 +24,7 @@ void CCSBot::FireWeaponAtEnemy()
{ {
ClearSurpriseDelay(); ClearSurpriseDelay();
if (!(IsRecognizedEnemyProtectedByShield() && IsPlayerFacingMe(enemy)) // dont shoot at enemies behind shields if (!(IsRecognizedEnemyProtectedByShield() && IsPlayerFacingMe(pEnemy)) // dont shoot at enemies behind shields
&& !IsActiveWeaponReloading() && !IsActiveWeaponReloading()
&& !IsActiveWeaponClipEmpty() && !IsActiveWeaponClipEmpty()
&& IsEnemyVisible()) && IsEnemyVisible())
@ -76,7 +76,7 @@ void CCSBot::FireWeaponAtEnemy()
ForceRun(5.0f); ForceRun(5.0f);
// if our prey is facing away, backstab him! // if our prey is facing away, backstab him!
if (!IsPlayerFacingMe(enemy)) if (!IsPlayerFacingMe(pEnemy))
{ {
SecondaryAttack(); SecondaryAttack();
} }
@ -278,9 +278,8 @@ bool isSniperRifle(CBasePlayerItem *item)
bool CCSBot::IsUsingAWP() const bool CCSBot::IsUsingAWP() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == WEAPON_AWP)
if (weapon != NULL && weapon->m_iId == WEAPON_AWP)
return true; return true;
return false; return false;
@ -289,12 +288,11 @@ bool CCSBot::IsUsingAWP() const
// Returns true if we are using a weapon with a removable silencer // Returns true if we are using a weapon with a removable silencer
bool CCSBot::DoesActiveWeaponHaveSilencer() const bool CCSBot::DoesActiveWeaponHaveSilencer() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (!pCurrentWeapon)
if (weapon == NULL)
return false; 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 true;
return false; return false;
@ -303,9 +301,8 @@ bool CCSBot::DoesActiveWeaponHaveSilencer() const
// Return true if we are using a sniper rifle // Return true if we are using a sniper rifle
bool CCSBot::IsUsingSniperRifle() const bool CCSBot::IsUsingSniperRifle() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && isSniperRifle(pCurrentWeapon))
if (weapon != NULL && isSniperRifle(weapon))
return true; return true;
return false; return false;
@ -314,20 +311,11 @@ bool CCSBot::IsUsingSniperRifle() const
// Return true if we have a sniper rifle in our inventory // Return true if we have a sniper rifle in our inventory
bool CCSBot::IsSniper() const bool CCSBot::IsSniper() const
{ {
for (int i = 0; i < MAX_ITEM_TYPES; ++i) auto sniperItem = this->ForEachItem([](CBasePlayerItem *pItem) {
{ return isSniperRifle(pItem);
CBasePlayerItem *item = m_rgpPlayerItems[i]; });
while (item != NULL) return sniperItem ? true : false;
{
if (isSniperRifle(item))
return true;
item = item->m_pNext;
}
}
return false;
} }
// Return true if we are actively sniping (moving to sniper spot or settled in) // 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 // Return true if we are using a shotgun
bool CCSBot::IsUsingShotgun() const bool CCSBot::IsUsingShotgun() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (!pCurrentWeapon)
if (weapon == NULL)
return false; 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 true;
return false; return false;
@ -356,9 +343,8 @@ bool CCSBot::IsUsingShotgun() const
// Returns true if using the big 'ol machinegun // Returns true if using the big 'ol machinegun
bool CCSBot::IsUsingMachinegun() const bool CCSBot::IsUsingMachinegun() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == WEAPON_M249)
if (weapon != NULL && weapon->m_iId == WEAPON_M249)
return true; return true;
return false; return false;
@ -367,13 +353,12 @@ bool CCSBot::IsUsingMachinegun() const
// Return true if primary weapon doesn't exist or is totally out of ammo // Return true if primary weapon doesn't exist or is totally out of ammo
bool CCSBot::IsPrimaryWeaponEmpty() const bool CCSBot::IsPrimaryWeaponEmpty() const
{ {
CBasePlayerWeapon *weapon = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PRIMARY_WEAPON_SLOT ]); CBasePlayerWeapon *pCurrentWeapon = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]);
if (!pCurrentWeapon)
if (weapon == NULL)
return true; return true;
// check if gun has any ammo left // check if gun has any ammo left
if (HasAnyAmmo(weapon)) if (HasAnyAmmo(pCurrentWeapon))
return false; return false;
return true; return true;
@ -382,13 +367,12 @@ bool CCSBot::IsPrimaryWeaponEmpty() const
// Return true if pistol doesn't exist or is totally out of ammo // Return true if pistol doesn't exist or is totally out of ammo
bool CCSBot::IsPistolEmpty() const bool CCSBot::IsPistolEmpty() const
{ {
CBasePlayerWeapon *weapon = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PISTOL_SLOT ]); CBasePlayerWeapon *pCurrentWeapon = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PISTOL_SLOT ]);
if (!pCurrentWeapon)
if (weapon == NULL)
return true; return true;
// check if gun has any ammo left // check if gun has any ammo left
if (HasAnyAmmo(weapon)) if (HasAnyAmmo(pCurrentWeapon))
{ {
return false; return false;
} }
@ -397,17 +381,17 @@ bool CCSBot::IsPistolEmpty() const
} }
// Equip the given item // Equip the given item
bool CCSBot::DoEquip(CBasePlayerWeapon *gun) bool CCSBot::DoEquip(CBasePlayerWeapon *pWeapon)
{ {
if (gun == NULL) if (!pWeapon)
return false; return false;
// check if weapon has any ammo left // check if weapon has any ammo left
if (!HasAnyAmmo(gun)) if (!HasAnyAmmo(pWeapon))
return false; return false;
// equip it // equip it
SelectItem(STRING(gun->pev->classname)); SelectItem(STRING(pWeapon->pev->classname));
m_equipTimer.Start(); m_equipTimer.Start();
return true; return true;
@ -423,11 +407,10 @@ void CCSBot::EquipBestWeapon(bool mustEquip)
if (!mustEquip && m_equipTimer.GetElapsedTime() < minEquipInterval) if (!mustEquip && m_equipTimer.GetElapsedTime() < minEquipInterval)
return; return;
CBasePlayerWeapon *primary = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PRIMARY_WEAPON_SLOT ]); CBasePlayerWeapon *pPrimary = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ PRIMARY_WEAPON_SLOT ]);
if (pPrimary)
if (primary != NULL)
{ {
WeaponClassType weaponClass = WeaponIDToWeaponClass(primary->m_iId); WeaponClassType weaponClass = WeaponIDToWeaponClass(pPrimary->m_iId);
if ((TheCSBots()->AllowShotguns() && weaponClass == WEAPONCLASS_SHOTGUN) if ((TheCSBots()->AllowShotguns() && weaponClass == WEAPONCLASS_SHOTGUN)
|| (TheCSBots()->AllowMachineGuns() && weaponClass == WEAPONCLASS_MACHINEGUN) || (TheCSBots()->AllowMachineGuns() && weaponClass == WEAPONCLASS_MACHINEGUN)
@ -438,9 +421,9 @@ void CCSBot::EquipBestWeapon(bool mustEquip)
#endif #endif
|| (TheCSBots()->AllowSnipers() && weaponClass == WEAPONCLASS_SNIPERRIFLE) || (TheCSBots()->AllowSnipers() && weaponClass == WEAPONCLASS_SNIPERRIFLE)
|| (TheCSBots()->AllowSubMachineGuns() && weaponClass == WEAPONCLASS_SUBMACHINEGUN) || (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; return;
} }
} }
@ -474,10 +457,10 @@ void CCSBot::EquipKnife()
{ {
if (!IsUsingKnife()) if (!IsUsingKnife())
{ {
CBasePlayerWeapon *knife = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ KNIFE_SLOT ]); CBasePlayerWeapon *pKnife = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ KNIFE_SLOT ]);
if (knife != NULL) 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 // Return true if we have a grenade in our inventory
bool CCSBot::HasGrenade() const bool CCSBot::HasGrenade() const
{ {
CBasePlayerWeapon *grenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ GRENADE_SLOT ]); CBasePlayerWeapon *pGrenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ GRENADE_SLOT ]);
return grenade != NULL; return pGrenade != nullptr;
} }
// Equip a grenade, return false if we cant // Equip a grenade, return false if we cant
@ -501,14 +484,13 @@ bool CCSBot::EquipGrenade(bool noSmoke)
if (HasGrenade()) if (HasGrenade())
{ {
CBasePlayerWeapon *grenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ GRENADE_SLOT ]); CBasePlayerWeapon *pGrenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[ GRENADE_SLOT ]);
if (pGrenade)
if (grenade != NULL)
{ {
if (noSmoke && grenade->m_iId == WEAPON_SMOKEGRENADE) if (noSmoke && pGrenade->m_iId == WEAPON_SMOKEGRENADE)
return false; return false;
SelectItem(STRING(grenade->pev->classname)); SelectItem(STRING(pGrenade->pev->classname));
return true; return true;
} }
} }
@ -519,9 +501,8 @@ bool CCSBot::EquipGrenade(bool noSmoke)
// Returns true if we have knife equipped // Returns true if we have knife equipped
bool CCSBot::IsUsingKnife() const bool CCSBot::IsUsingKnife() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == WEAPON_KNIFE)
if (weapon != NULL && weapon->m_iId == WEAPON_KNIFE)
return true; return true;
return false; return false;
@ -530,9 +511,8 @@ bool CCSBot::IsUsingKnife() const
// Returns true if we have pistol equipped // Returns true if we have pistol equipped
bool CCSBot::IsUsingPistol() const bool CCSBot::IsUsingPistol() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->IsPistol())
if (weapon != NULL && weapon->IsPistol())
return true; return true;
return false; return false;
@ -541,14 +521,14 @@ bool CCSBot::IsUsingPistol() const
// Returns true if we have a grenade equipped // Returns true if we have a grenade equipped
bool CCSBot::IsUsingGrenade() const bool CCSBot::IsUsingGrenade() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (weapon == NULL) if (!pCurrentWeapon)
return false; return false;
if (weapon->m_iId == WEAPON_SMOKEGRENADE if (pCurrentWeapon->m_iId == WEAPON_SMOKEGRENADE
|| weapon->m_iId == WEAPON_FLASHBANG || pCurrentWeapon->m_iId == WEAPON_FLASHBANG
|| weapon->m_iId == WEAPON_HEGRENADE) || pCurrentWeapon->m_iId == WEAPON_HEGRENADE)
return true; return true;
return false; return false;
@ -556,9 +536,8 @@ bool CCSBot::IsUsingGrenade() const
bool CCSBot::IsUsingHEGrenade() const bool CCSBot::IsUsingHEGrenade() const
{ {
CBasePlayerWeapon *weapon = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (pCurrentWeapon && pCurrentWeapon->m_iId == WEAPON_HEGRENADE)
if (weapon != NULL && weapon->m_iId == WEAPON_HEGRENADE)
return true; return true;
return false; return false;
@ -586,7 +565,7 @@ bool CCSBot::FindGrenadeTossPathTarget(Vector *pos)
// find farthest point we can see on the path // find farthest point we can see on the path
int i; 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))) if (!FVisible(m_path[i].pos + Vector(0, 0, HalfHumanHeight)))
break; break;
@ -733,7 +712,7 @@ void CCSBot::ReloadCheck()
{ {
PrintIfWatched("Retreating to a safe spot to reload!\n"); PrintIfWatched("Retreating to a safe spot to reload!\n");
const Vector *spot = FindNearbyRetreatSpot(this, 1000.0f); const Vector *spot = FindNearbyRetreatSpot(this, 1000.0f);
if (spot != NULL) if (spot)
{ {
// ignore enemies for a second to give us time to hide // ignore enemies for a second to give us time to hide
// reaching our hiding spot clears our disposition // reaching our hiding spot clears our disposition
@ -769,17 +748,17 @@ void CCSBot::SilencerCheck()
// don't touch the silencer if there are enemies nearby // don't touch the silencer if there are enemies nearby
if (GetNearbyEnemyCount() == 0) if (GetNearbyEnemyCount() == 0)
{ {
CBasePlayerWeapon *myGun = GetActiveWeapon(); CBasePlayerWeapon *pCurrentWeapon = GetActiveWeapon();
if (myGun == NULL) if (!pCurrentWeapon)
return; 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 #ifndef REGAMEDLL_FIXES
if (isSilencerOn != GetProfile()->PrefersSilencer() && !HasShield()) if (isSilencerOn != GetProfile()->PrefersSilencer() && !HasShield())
#else #else
if (myGun->m_flNextSecondaryAttack >= gpGlobals->time) if (pCurrentWeapon->m_flNextSecondaryAttack >= gpGlobals->time)
return; return;
// equip silencer if we want to and we don't have a shield. // equip silencer if we want to and we don't have a shield.
@ -787,7 +766,7 @@ void CCSBot::SilencerCheck()
#endif #endif
{ {
PrintIfWatched("%s silencer!\n", (isSilencerOn) ? "Unequipping" : "Equipping"); PrintIfWatched("%s silencer!\n", (isSilencerOn) ? "Unequipping" : "Equipping");
myGun->SecondaryAttack(); pCurrentWeapon->SecondaryAttack();
} }
} }
} }
@ -813,7 +792,7 @@ void CCSBot::OnTouchingWeapon(CWeaponBox *box)
if (GetTimeSinceLastSawEnemy() >= safeTime) if (GetTimeSinceLastSawEnemy() >= safeTime)
{ {
// we have a primary weapon - drop it if the one on the ground is better // 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); int prefID = GetProfile()->GetWeaponPreference(i);
if (!IsPrimaryWeapon(prefID)) if (!IsPrimaryWeapon(prefID))
@ -853,15 +832,12 @@ bool CCSBot::IsFriendInLineOfFire()
TraceResult result; TraceResult result;
UTIL_TraceLine(GetGunPosition(), target + 10000.0f * aimDir, dont_ignore_monsters, ignore_glass, ENT(pev), &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); CBasePlayer *pVictim = CBasePlayer::Instance(result.pHit);
if (pVictim && pVictim->IsPlayer() && pVictim->IsAlive())
if (victim != NULL && victim->IsPlayer() && victim->IsAlive())
{ {
CBasePlayer *player = static_cast<CBasePlayer *>(victim); if (BotRelationship(pVictim) == BOT_TEAMMATE)
if (BotRelationship(player) == BOT_TEAMMATE)
return true; return true;
} }
} }

View File

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

View File

@ -26,11 +26,7 @@
* *
*/ */
#ifndef CS_GAMESTATE_H
#define CS_GAMESTATE_H
#ifdef _WIN32
#pragma once #pragma once
#endif
class CCSBot; class CCSBot;
@ -94,7 +90,7 @@ public:
CHostage *GetNearestVisibleFreeHostage() const; CHostage *GetNearestVisibleFreeHostage() const;
// hostage rescue scenario // hostage rescue scenario
enum ValidateStatusType:uint8 enum ValidateStatusType : uint8
{ {
NO_CHANGE = 0x00, NO_CHANGE = 0x00,
HOSTAGE_DIED = 0x01, HOSTAGE_DIED = 0x01,
@ -147,5 +143,3 @@ private:
bool m_allHostagesRescued; // if true, so every hostages been is rescued 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) 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 // Begin attacking
void AttackState::OnEnter(CCSBot *me) void AttackState::OnEnter(CCSBot *me)
{ {
CBasePlayer *enemy = me->GetEnemy(); CBasePlayer *pEnemy = me->GetEnemy();
// store our posture when the attack began // store our posture when the attack began
me->PushPostureContext(); me->PushPostureContext();
me->DestroyPath(); me->DestroyPath();
// if we are using a knife, try to sneak up on the enemy // 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(); me->Walk();
else else
me->Run(); 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()) // decide whether to crouch where we are, or run and gun (if we havent already - see CCSBot::Attack())
if (!m_crouchAndHold) if (!m_crouchAndHold)
{ {
if (enemy != NULL) if (pEnemy)
{ {
const float crouchFarRange = 750.0f; const float crouchFarRange = 750.0f;
float crouchChance; 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 // more likely to crouch if using sniper rifle or if enemy is far away
if (me->IsUsingSniperRifle()) if (me->IsUsingSniperRifle())
crouchChance = 50.0f; 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; crouchChance = 50.0f;
else else
crouchChance = 20.0f * (1.0f - me->GetProfile()->GetAggression()); crouchChance = 20.0f * (1.0f - me->GetProfile()->GetAggression());
@ -69,7 +69,7 @@ void AttackState::OnEnter(CCSBot *me)
origin.z -= 20.0f; 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) if (result.flFraction == 1.0f)
{ {
@ -131,20 +131,20 @@ void AttackState::OnUpdate(CCSBot *me)
me->ResetStuckMonitor(); me->ResetStuckMonitor();
me->StopRapidFire(); me->StopRapidFire();
CBasePlayerWeapon *weapon = me->GetActiveWeapon(); CBasePlayerWeapon *pWeapon = me->GetActiveWeapon();
if (weapon != NULL) if (pWeapon)
{ {
if (weapon->m_iId == WEAPON_C4 || if (pWeapon->m_iId == WEAPON_C4 ||
weapon->m_iId == WEAPON_HEGRENADE || pWeapon->m_iId == WEAPON_HEGRENADE ||
weapon->m_iId == WEAPON_FLASHBANG || pWeapon->m_iId == WEAPON_FLASHBANG ||
weapon->m_iId == WEAPON_SMOKEGRENADE) pWeapon->m_iId == WEAPON_SMOKEGRENADE)
{ {
me->EquipBestWeapon(); me->EquipBestWeapon();
} }
} }
CBasePlayer *enemy = me->GetEnemy(); CBasePlayer *pEnemy = me->GetEnemy();
if (enemy == NULL) if (!pEnemy)
{ {
StopAttacking(me); StopAttacking(me);
return; return;
@ -200,7 +200,7 @@ void AttackState::OnUpdate(CCSBot *me)
me->StandUp(); me->StandUp();
// if we are using a knife and our prey is looking towards us, run at him // 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->ForceRun(5.0f);
me->Hurry(10.0f); me->Hurry(10.0f);
@ -218,7 +218,7 @@ void AttackState::OnUpdate(CCSBot *me)
if (me->HasPath()) if (me->HasPath())
{ {
const float repathRange = 100.0f; const float repathRange = 100.0f;
if ((me->GetPathEndpoint() - enemy->pev->origin).IsLengthGreaterThan(repathRange)) if ((me->GetPathEndpoint() - pEnemy->pev->origin).IsLengthGreaterThan(repathRange))
{ {
repath = true; repath = true;
} }
@ -230,7 +230,7 @@ void AttackState::OnUpdate(CCSBot *me)
if (repath && m_repathTimer.IsElapsed()) 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; const float repathInterval = 0.5f;
m_repathTimer.Start(repathInterval); m_repathTimer.Start(repathInterval);
@ -250,7 +250,7 @@ void AttackState::OnUpdate(CCSBot *me)
{ {
if (me->IsEnemyVisible() && !m_shieldForceOpen) 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 // close up - enemy is pointing his gun at us
if (!me->IsProtectedByShield()) 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 // 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() // NOTE: Must be larger than NO_ZOOM range in AdjustZoom()
const float sniperMinRange = 310.0f; 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(); me->EquipPistol();
} }
else if (me->IsUsingShotgun()) else if (me->IsUsingShotgun())
{ {
// if we have a shotgun equipped and enemy is too far away, switch to pistol // if we have a shotgun equipped and enemy is too far away, switch to pistol
const float shotgunMaxRange = 1000.0f; 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(); me->EquipPistol();
} }
@ -325,9 +325,9 @@ void AttackState::OnUpdate(CCSBot *me)
if (me->IsAwareOfEnemyDeath()) if (me->IsAwareOfEnemyDeath())
{ {
// let team know if we killed the last enemy // 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); StopAttacking(me);
@ -372,7 +372,7 @@ void AttackState::OnUpdate(CCSBot *me)
// hide in ambush nearby // hide in ambush nearby
// TODO: look towards where we know enemy is // TODO: look towards where we know enemy is
const Vector *spot = FindNearbyRetreatSpot(me, 200.0f); const Vector *spot = FindNearbyRetreatSpot(me, 200.0f);
if (spot != NULL) if (spot)
{ {
me->IgnoreEnemies(1.0f); me->IgnoreEnemies(1.0f);
me->Run(); me->Run();
@ -430,7 +430,7 @@ void AttackState::OnUpdate(CCSBot *me)
else else
{ {
// move to last known position of enemy // 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()); me->MoveTo(&me->GetLastKnownEnemyPosition());
return; return;
} }
@ -441,7 +441,7 @@ void AttackState::OnUpdate(CCSBot *me)
const float hurtRecentlyTime = 3.0f; const float hurtRecentlyTime = 3.0f;
if (!me->IsEnemyVisible() && if (!me->IsEnemyVisible() &&
me->GetTimeSinceAttacked() < hurtRecentlyTime && me->GetTimeSinceAttacked() < hurtRecentlyTime &&
me->GetAttacker() != NULL && me->GetAttacker() &&
me->GetAttacker() != me->GetEnemy()) me->GetAttacker() != me->GetEnemy())
{ {
// if we can see them, attack, otherwise panic // if we can see them, attack, otherwise panic
@ -460,7 +460,7 @@ void AttackState::OnUpdate(CCSBot *me)
// If sniping or crouching, stand still. // If sniping or crouching, stand still.
if (m_dodge && !me->IsUsingSniperRifle() && !m_crouchAndHold) 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(); float range = toEnemy.Length2D();
const float hysterisRange = 125.0f; // (+/-) m_combatRange const float hysterisRange = 125.0f; // (+/-) m_combatRange
@ -479,7 +479,7 @@ void AttackState::OnUpdate(CCSBot *me)
// don't dodge if enemy is facing away // don't dodge if enemy is facing away
const float dodgeRange = 2000.0f; const float dodgeRange = 2000.0f;
if (range > dodgeRange || !me->IsPlayerFacingMe(enemy)) if (range > dodgeRange || !me->IsPlayerFacingMe(pEnemy))
{ {
m_dodgeState = STEADY_ON; m_dodgeState = STEADY_ON;
m_nextDodgeStateTimestamp = 0.0f; m_nextDodgeStateTimestamp = 0.0f;

View File

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

View File

@ -14,7 +14,7 @@ void EscapeFromBombState::OnUpdate(CCSBot *me)
const Vector *bombPos = me->GetGameState()->GetBombPosition(); const Vector *bombPos = me->GetGameState()->GetBombPosition();
// if we don't know where the bomb is, we shouldn't be in this state // if we don't know where the bomb is, we shouldn't be in this state
if (bombPos == NULL) if (!bombPos)
{ {
me->Idle(); me->Idle();
return; return;
@ -33,7 +33,7 @@ void EscapeFromBombState::OnUpdate(CCSBot *me)
CNavArea *goalArea = FindMinimumCostArea(me->GetLastKnownArea(), func); CNavArea *goalArea = FindMinimumCostArea(me->GetLastKnownArea(), func);
// if this fails, we'll try again next time // 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; return;
} }
CBaseEntity *bomb = TheCSBots()->GetLooseBomb(); CBaseEntity *pBomb = TheCSBots()->GetLooseBomb();
if (bomb != NULL) if (pBomb)
{ {
if (!me->HasPath()) if (!me->HasPath())
{ {
// build a path to the bomb // 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"); me->PrintIfWatched("Fetch bomb pathfind failed\n");

View File

@ -75,7 +75,7 @@ void FollowState::ComputeLeaderMotionState(float leaderSpeed)
void FollowState::OnUpdate(CCSBot *me) void FollowState::OnUpdate(CCSBot *me)
{ {
// if we lost our leader, give up // if we lost our leader, give up
if (m_leader == NULL || !m_leader->IsAlive()) if (!m_leader || !m_leader->IsAlive())
{ {
me->Idle(); me->Idle();
return; return;
@ -159,7 +159,7 @@ void FollowState::OnUpdate(CCSBot *me)
if ((m_leader->pev->origin - me->pev->origin).IsLengthLessThan(nearLeaderRange)) if ((m_leader->pev->origin - me->pev->origin).IsLengthLessThan(nearLeaderRange))
{ {
const float hideRange = 250.0f; 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(); me->ResetStuckMonitor();
return; return;
@ -203,14 +203,14 @@ void FollowState::OnUpdate(CCSBot *me)
if (cv_bot_debug.value > 0.0f) 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); collector.m_targetArea[i]->Draw(255, 0, 0, 2);
} }
// move to one of the collected areas // move to one of the collected areas
if (collector.m_targetAreaCount) if (collector.m_targetAreaCount)
{ {
CNavArea *target = NULL; CNavArea *target = nullptr;
Vector targetPos; Vector targetPos;
// if we are idle, pick a random area // if we are idle, pick a random area
@ -229,7 +229,7 @@ void FollowState::OnUpdate(CCSBot *me)
float closeRangeSq = 9999999999.9f; float closeRangeSq = 9999999999.9f;
Vector close; 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 = collector.m_targetArea[a];
area->GetClosestPointOnArea(&me->pev->origin, &close); 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"); me->PrintIfWatched("Pathfind to leader failed.\n");
}
// throttle how often we repath // throttle how often we repath
m_repathInterval.Start(0.5f); 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 // if we're guarding a bombsite, continue to guard it but pick a new spot
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(&me->pev->origin); const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(&me->pev->origin);
if (zone != NULL) if (zone)
{ {
CNavArea *area = TheCSBots()->GetRandomAreaInZone(zone); CNavArea *area = TheCSBots()->GetRandomAreaInZone(zone);
if (area != NULL) if (area)
{ {
me->Hide(area); me->Hide(area);
return; 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 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(); me->Idle();
return; return;
} }
// if we are guarding the loose bomb and it is picked up, stop hiding // 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->GetChatter()->TheyPickedUpTheBomb();
me->Idle(); me->Idle();
@ -197,12 +197,12 @@ void HideState::OnUpdate(CCSBot *me)
else if (me->GetTask() == CCSBot::GUARD_HOSTAGE_RESCUE_ZONE) else if (me->GetTask() == CCSBot::GUARD_HOSTAGE_RESCUE_ZONE)
{ {
// if we stumble across a hostage, guard it // if we stumble across a hostage, guard it
CHostage *hostage = me->GetGameState()->GetNearestVisibleFreeHostage(); CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (hostage != NULL) if (pHostage)
{ {
// we see a free hostage, guard it // we see a free hostage, guard it
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin); CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area != NULL) if (area)
{ {
me->SetTask(CCSBot::GUARD_HOSTAGES); me->SetTask(CCSBot::GUARD_HOSTAGES);
me->Hide(area); me->Hide(area);
@ -300,8 +300,8 @@ void HideState::OnUpdate(CCSBot *me)
{ {
if (me->GetNearbyEnemyCount() == 0) if (me->GetNearbyEnemyCount() == 0)
{ {
CHostage *hostage = me->GetGameState()->GetNearestVisibleFreeHostage(); CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (hostage != NULL) if (pHostage)
{ {
me->GetChatter()->Encourage("WaitingForHumanToRescueHostages", RANDOM_FLOAT(10.0f, 15.0f)); 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 // if a Player is using this hiding spot, give up
float range; float range;
CBasePlayer *camper = UTIL_GetClosestPlayer(&m_hidingSpot, &range); CBasePlayer *pCamper = UTIL_GetClosestPlayer(&m_hidingSpot, &range);
const float closeRange = 75.0f; 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 // player is in our hiding spot
me->PrintIfWatched("Someone's in my hiding spot - picking another...\n"); 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 // search from hiding spot, since we know it was valid
const Vector *pos = FindNearbyHidingSpot(me, &m_hidingSpot, m_searchFromArea, m_range, me->IsSniper()); const Vector *pos = FindNearbyHidingSpot(me, &m_hidingSpot, m_searchFromArea, m_range, me->IsSniper());
if (pos == NULL) if (!pos)
{ {
// no available hiding spots // no available hiding spots
me->PrintIfWatched("No available hiding spots - hiding where I'm at.\n"); 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 // 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(); 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->SetTask(CCSBot::GUARD_TICKING_BOMB);
me->Hide(TheNavAreaGrid.GetNavArea(bombPos)); 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 safe time is up, and we stumble across a hostage, guard it
if (!me->IsRogue() && !me->IsSafe()) if (!me->IsRogue() && !me->IsSafe())
{ {
CHostage *hostage = me->GetGameState()->GetNearestVisibleFreeHostage(); CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (hostage != NULL) if (pHostage)
{ {
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin); CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area != NULL) if (area)
{ {
// we see a free hostage, guard it // we see a free hostage, guard it
me->SetTask(CCSBot::GUARD_HOSTAGES); me->SetTask(CCSBot::GUARD_HOSTAGES);
@ -137,19 +137,14 @@ void HuntState::OnUpdate(CCSBot *me)
// if our path fails, pick a new one // if our path fails, pick a new one
if (me->GetLastKnownArea() == m_huntArea || me->UpdatePathMovement() != CCSBot::PROGRESSING) if (me->GetLastKnownArea() == m_huntArea || me->UpdatePathMovement() != CCSBot::PROGRESSING)
{ {
m_huntArea = NULL; m_huntArea = nullptr;
float oldest = 0.0f; float oldest = 0.0f;
int areaCount = 0; int areaCount = 0;
const float minSize = 150.0f; const float minSize = 150.0f;
for (auto area : TheNavAreaList)
NavAreaList::iterator iter;
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
{ {
CNavArea *area = (*iter); areaCount++;
++areaCount;
// skip the small areas // skip the small areas
const Extent *extent = area->GetExtent(); const Extent *extent = area->GetExtent();
@ -169,20 +164,20 @@ void HuntState::OnUpdate(CCSBot *me)
int which = RANDOM_LONG(0, areaCount - 1); int which = RANDOM_LONG(0, areaCount - 1);
areaCount = 0; areaCount = 0;
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) for (auto area : TheNavAreaList)
{ {
m_huntArea = (*iter); m_huntArea = area;
if (which == areaCount) if (which == areaCount)
break; break;
--which; which--;
} }
if (m_huntArea != NULL) if (m_huntArea)
{ {
// create a new path to a far away area of the map // 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) void IdleState::OnEnter(CCSBot *me)
{ {
me->DestroyPath(); me->DestroyPath();
me->SetEnemy(NULL); me->SetEnemy(nullptr);
// lurking death // lurking death
if (me->IsUsingKnife() && me->IsWellPastSafe() && !me->IsHurrying()) 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 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(); const Vector *bombPos = me->GetGameState()->GetBombPosition();
@ -271,7 +271,7 @@ void IdleState::OnUpdate(CCSBot *me)
const CCSBotManager::Zone *zone = nullptr; const CCSBotManager::Zone *zone = nullptr;
float travelDistance = 9999999.9f; 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) if (TheCSBots()->GetZone(z)->m_areaCount == 0)
continue; continue;
@ -333,7 +333,7 @@ void IdleState::OnUpdate(CCSBot *me)
{ {
if (RANDOM_FLOAT(0, 100) <= defenseSniperCampChance) if (RANDOM_FLOAT(0, 100) <= defenseSniperCampChance)
{ {
CNavArea *snipingArea = NULL; CNavArea *snipingArea = nullptr;
// if the bomb is loose, snipe near it // if the bomb is loose, snipe near it
if (me->GetGameState()->IsLooseBombLocationKnown()) 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 // if early in round, pick a random zone, otherwise pick closest zone
const float earlyTime = 20.0f; const float earlyTime = 20.0f;
const CCSBotManager::Zone *zone = NULL; const CCSBotManager::Zone *zone = nullptr;
if (TheCSBots()->GetElapsedRoundTime() < earlyTime) 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 safe time is up, and we stumble across a hostage, guard it
if (!me->IsSafe() && !me->IsRogue()) if (!me->IsSafe() && !me->IsRogue())
{ {
CBaseEntity *hostage = me->GetGameState()->GetNearestVisibleFreeHostage(); CBaseEntity *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (hostage) if (pHostage)
{ {
// we see a free hostage, guard it // we see a free hostage, guard it
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin); CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area) if (area)
{ {
me->SetTask(CCSBot::GUARD_HOSTAGES); 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 // 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 we are not allowed to do the scenario, guard the hostages to clear the area for the human(s)
if (!me->IsDoingScenario()) if (!me->IsDoingScenario())
{ {
if (hostage) if (pHostage)
{ {
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&hostage->pev->origin); CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area) if (area)
{ {
me->SetTask(CCSBot::GUARD_HOSTAGES); me->SetTask(CCSBot::GUARD_HOSTAGES);
@ -678,8 +678,8 @@ void IdleState::OnUpdate(CCSBot *me)
bool fetchHostages = false; bool fetchHostages = false;
bool rescueHostages = false; bool rescueHostages = false;
const CCSBotManager::Zone *zone = NULL; const CCSBotManager::Zone *zone = nullptr;
me->SetGoalEntity(NULL); me->SetGoalEntity(nullptr);
// if we are escorting hostages, determine where to take them // if we are escorting hostages, determine where to take them
if (me->GetHostageEscortCount()) if (me->GetHostageEscortCount())
@ -687,13 +687,13 @@ void IdleState::OnUpdate(CCSBot *me)
// if we are escorting hostages and there are more hostages to rescue, // 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 // determine whether it's faster to rescue the ones we have, or go get the remaining ones
if (hostage) if (pHostage)
{ {
if (zone) if (zone)
{ {
PathCost pathCost(me, FASTEST_ROUTE); PathCost pathCost(me, FASTEST_ROUTE);
float toZone = NavAreaTravelDistance(me->GetLastKnownArea(), zone->m_area[0], pathCost); 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) if (toHostage < 0.0f)
{ {
@ -722,12 +722,12 @@ void IdleState::OnUpdate(CCSBot *me)
// go get hostages // go get hostages
me->SetTask(CCSBot::COLLECT_HOSTAGES); me->SetTask(CCSBot::COLLECT_HOSTAGES);
me->Run(); me->Run();
me->SetGoalEntity(hostage); me->SetGoalEntity(pHostage);
me->ResetWaitForHostagePatience(); me->ResetWaitForHostagePatience();
// if we already have some hostages, move to the others by the quickest route // if we already have some hostages, move to the others by the quickest route
RouteType route = (me->GetHostageEscortCount()) ? FASTEST_ROUTE : SAFEST_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"); me->PrintIfWatched("I'm collecting hostages\n");
return; return;
} }

View File

@ -41,8 +41,8 @@ void MoveToState::OnUpdate(CCSBot *me)
if (me->GetTask() == CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION) 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 // TODO: Account for reaction time so we take some time to realized the enemy is dead
CBasePlayer *victim = static_cast<CBasePlayer *>(me->GetTaskEntity()); CBaseEntity *pVictim = me->GetTaskEntity();
if (victim == NULL || !victim->IsAlive()) if (!pVictim || !pVictim->IsAlive())
{ {
me->PrintIfWatched("The enemy I was chasing was killed - giving up.\n"); me->PrintIfWatched("The enemy I was chasing was killed - giving up.\n");
me->Idle(); me->Idle();
@ -77,7 +77,7 @@ void MoveToState::OnUpdate(CCSBot *me)
} }
// check off bombsites that we explore or happen to stumble into // 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 // don't re-check zones
if (me->GetGameState()->IsBombsiteClear(z)) 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 // 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 // check if someone else collected our hostage, or the hostage died or was rescued
CHostage *hostage = static_cast<CHostage *>(me->GetGoalEntity()); CHostage *pHostage = me->GetGoalEntity<CHostage>();
if (!hostage || !hostage->IsAlive() || hostage->IsFollowingSomeone()) if (!pHostage || !pHostage->IsAlive() || pHostage->IsFollowingSomeone())
{ {
me->Idle(); me->Idle();
return; return;
@ -180,17 +180,17 @@ void MoveToState::OnUpdate(CCSBot *me)
// if our hostage has moved, repath // if our hostage has moved, repath
const float repathToleranceSq = 75.0f * 75.0f; 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) if (error > repathToleranceSq)
{ {
m_goalPosition = hostage->pev->origin; m_goalPosition = pHostage->pev->origin;
me->ComputePath(TheNavAreaGrid.GetNavArea(&m_goalPosition), &m_goalPosition, SAFEST_ROUTE); me->ComputePath(TheNavAreaGrid.GetNavArea(&m_goalPosition), &m_goalPosition, SAFEST_ROUTE);
} }
// TODO: Generalize ladder priorities over other tasks // TODO: Generalize ladder priorities over other tasks
if (!me->IsUsingLadder()) 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; Vector to = pos - me->pev->origin;
// look at the hostage as we approach // 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 // 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)) if (to.IsLengthLessThan(useRange))
{ {
me->UseEntity(me->GetGoalEntity()); 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) // 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(); const Vector *bombPos = me->GetGameState()->GetBombPosition();
if (bombPos != NULL) if (bombPos)
{ {
const float defuseRange = 100.0f; const float defuseRange = 100.0f;
Vector toBomb = *bombPos - me->pev->origin; Vector toBomb = *bombPos - me->pev->origin;
@ -271,8 +271,8 @@ void MoveToState::OnUpdate(CCSBot *me)
} }
case CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION: case CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION:
{ {
CBasePlayer *victim = static_cast<CBasePlayer *>(me->GetTaskEntity()); CBaseEntity *pVictim = me->GetTaskEntity();
if (victim != NULL && victim->IsAlive()) if (pVictim && pVictim->IsAlive())
{ {
// if we got here and haven't re-acquired the enemy, we lost him // if we got here and haven't re-acquired the enemy, we lost him
me->GetChatter()->Say("LostEnemy"); me->GetChatter()->Say("LostEnemy");

View File

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

View File

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

View File

@ -26,33 +26,9 @@
* *
*/ */
#ifndef BUTTON_H
#define BUTTON_H
#ifdef _WIN32
#pragma once #pragma once
#endif
#define SF_BUTTON_DONTMOVE 1 #define SF_GLOBAL_SET BIT(0) // Set global state to initial state on spawn
#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
class CEnvGlobal: public CPointEntity class CEnvGlobal: public CPointEntity
{ {
@ -71,6 +47,9 @@ public:
int m_initialstate; int m_initialstate;
}; };
#define SF_ROTBUTTON_NOTSOLID BIT(0)
#define SF_ROTBUTTON_BACKWARDS BIT(1)
class CRotButton: public CBaseButton class CRotButton: public CBaseButton
{ {
public: 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 class CMomentaryRotButton: public CBaseToggle
{ {
public: public:
@ -128,6 +113,9 @@ public:
int m_sounds; int m_sounds;
}; };
#define SF_SPARK_TOOGLE BIT(5)
#define SF_SPARK_IF_OFF BIT(6)
class CEnvSpark: public CBaseEntity class CEnvSpark: public CBaseEntity
{ {
public: public:
@ -147,6 +135,9 @@ public:
float m_flDelay; float m_flDelay;
}; };
#define SF_BTARGET_USE BIT(0)
#define SF_BTARGET_ON BIT(1)
class CButtonTarget: public CBaseEntity class CButtonTarget: public CBaseEntity
{ {
public: public:
@ -158,5 +149,3 @@ public:
char *ButtonSound(int sound); char *ButtonSound(int sound);
void DoSpark(entvars_t *pev, const Vector &location); void DoSpark(entvars_t *pev, const Vector &location);
#endif // BUTTON_H

View File

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

View File

@ -62,10 +62,10 @@ DLL_FUNCTIONS gFunctionTable =
NEW_DLL_FUNCTIONS gNewDLLFunctions = NEW_DLL_FUNCTIONS gNewDLLFunctions =
{ {
&OnFreeEntPrivateData, &OnFreeEntPrivateData,
NULL, nullptr,
NULL, nullptr,
NULL, nullptr,
NULL nullptr
}; };
// Global Savedata for Delay // Global Savedata for Delay
@ -112,10 +112,10 @@ void EmptyEntityHashTable()
item = &stringsHashTable[i]; item = &stringsHashTable[i];
temp = item->next; temp = item->next;
item->pev = NULL; item->pev = nullptr;
item->pevIndex = 0; item->pevIndex = 0;
item->lastHash = 0; item->lastHash = 0;
item->next = NULL; item->next = nullptr;
while (temp) 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; int count;
hash_item_t *item, *next, *temp, *newp; 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; pevtemp = item->pev;
item->pev = pev; item->pev = pev;
item->lastHash = NULL; item->lastHash = nullptr;
item->pevIndex = pevIndex; item->pevIndex = pevIndex;
pevIndex = ENTINDEX(ENT(pevtemp)); pevIndex = ENTINDEX(ENT(pevtemp));
@ -182,24 +182,24 @@ void EXT_FUNC AddEntityHashValue(entvars_t *pev, const char *value, hash_types_e
item->next = newp; item->next = newp;
newp->pev = pevtemp; newp->pev = pevtemp;
newp->lastHash = NULL; newp->lastHash = nullptr;
newp->pevIndex = pevIndex; newp->pevIndex = pevIndex;
if (next) if (next)
newp->next = temp; newp->next = temp;
else else
newp->next = NULL; newp->next = nullptr;
} }
} }
else else
{ {
item->pev = pev; item->pev = pev;
item->lastHash = NULL; item->lastHash = nullptr;
item->pevIndex = ENTINDEX(ENT(pev)); 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; int hash;
hash_item_t *item; 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->pev = item->next->pev;
item->pevIndex = item->next->pevIndex; item->pevIndex = item->next->pevIndex;
item->lastHash = NULL; item->lastHash = nullptr;
item->next = item->next->next; item->next = item->next->next;
} }
else else
{ {
item->pev = NULL; item->pev = nullptr;
item->lastHash = NULL; item->lastHash = nullptr;
item->pevIndex = 0; item->pevIndex = 0;
} }
} }
else else
{ {
if (stringsHashTable[hash].lastHash == item) if (stringsHashTable[hash].lastHash == item)
stringsHashTable[hash].lastHash = NULL; stringsHashTable[hash].lastHash = nullptr;
last->next = item->next; last->next = item->next;
hashItemMemPool.Free(item); hashItemMemPool.Free(item);
@ -266,25 +266,7 @@ void EXT_FUNC RemoveEntityHashValue(entvars_t *pev, const char *value, hash_type
} }
} }
void printEntities() NOINLINE edict_t *CREATE_NAMED_ENTITY(string_t iClass)
{
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)
{ {
edict_t *named = g_engfuncs.pfnCreateNamedEntity(iClass); edict_t *named = g_engfuncs.pfnCreateNamedEntity(iClass);
if (named) 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) C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion)
{ {
if (!pFunctionTable || interfaceVersion != INTERFACE_VERSION) if (!pFunctionTable || interfaceVersion != INTERFACE_VERSION)
@ -364,7 +294,7 @@ C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion
stringsHashTable.AddMultipleToTail(2048); stringsHashTable.AddMultipleToTail(2048);
for (int i = 0; i < stringsHashTable.Count(); ++i) for (int i = 0; i < stringsHashTable.Count(); ++i)
{ {
stringsHashTable[i].next = NULL; stringsHashTable[i].next = nullptr;
} }
EmptyEntityHashTable(); EmptyEntityHashTable();
@ -395,10 +325,9 @@ C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pFunctionTable, int *inter
return 1; 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) if (pEntity)
{ {
// Initialize these or entities who don't link to the world won't have anything in here // 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; return 0;
} }
void EXT_FUNC DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd) void DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
{ {
if (!pkvd || !pentKeyvalue) if (!pkvd || !pentKeyvalue)
return; 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) // HACKHACK -- this is a hack to keep the node graph entity from "touching" things (like triggers)
// while it builds the graph // 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 *pEntity = (CBaseEntity *)GET_PRIVATE(pentTouched);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther); CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther);
@ -486,7 +415,7 @@ void EXT_FUNC DispatchTouch(edict_t *pentTouched, edict_t *pentOther)
pEntity->Touch(pOther); 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 *pEntity = (CBaseEntity *)GET_PRIVATE(pentUsed);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther); 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); 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); 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 *pEntity = (CBaseEntity *)GET_PRIVATE(pentBlocked);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther); 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); 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 // different classes with the same global name
CBaseEntity *FindGlobalEntity(string_t classname, string_t globalname) 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); CBaseEntity *pReturn = CBaseEntity::Instance(pent);
if (pReturn) if (pReturn)
@ -571,14 +500,14 @@ CBaseEntity *FindGlobalEntity(string_t classname, string_t globalname)
if (!FClassnameIs(pReturn->pev, STRING(classname))) if (!FClassnameIs(pReturn->pev, STRING(classname)))
{ {
ALERT(at_console, "Global entity found %s, wrong class %s\n", STRING(globalname), STRING(pReturn->pev->classname)); ALERT(at_console, "Global entity found %s, wrong class %s\n", STRING(globalname), STRING(pReturn->pev->classname));
pReturn = NULL; pReturn = nullptr;
} }
} }
return pReturn; 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); CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
@ -692,7 +621,7 @@ int EXT_FUNC DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int glob
return 0; return 0;
} }
void EXT_FUNC DispatchObjectCollsionBox(edict_t *pent) void DispatchObjectCollsionBox(edict_t *pent)
{ {
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if (pEntity) 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); CSave saveHelper(pSaveData);
saveHelper.WriteFields(pname, pBaseData, pFields, fieldCount); 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); CRestore restoreHelper(pSaveData);
restoreHelper.ReadFields(pname, pBaseData, pFields, fieldCount); 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) BOOL CBaseEntity::TakeHealth(float flHealth, int bitsDamageType)
{ {
if (pev->takedamage == DAMAGE_NO) if (pev->takedamage == DAMAGE_NO)
@ -844,12 +724,12 @@ void CBaseEntity::Killed(entvars_t *pevAttacker, int iGib)
CBaseEntity *CBaseEntity::GetNextTarget() CBaseEntity *CBaseEntity::GetNextTarget()
{ {
if (FStringNull(pev->target)) 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)) if (FNullEnt(pTarget))
{ {
return NULL; return nullptr;
} }
return Instance(pTarget); return Instance(pTarget);
@ -941,16 +821,24 @@ void CBaseEntity::SetObjectCollisionBox()
::SetObjectCollisionBox(pev); ::SetObjectCollisionBox(pev);
} }
int CBaseEntity::Intersects(CBaseEntity *pOther) bool CBaseEntity::Intersects(CBaseEntity *pOther)
{ {
if (pOther->pev->absmin.x > pev->absmax.x return Intersects(pOther->pev->absmin, pOther->pev->absmax);
|| pOther->pev->absmin.y > pev->absmax.y }
|| pOther->pev->absmin.z > pev->absmax.z
|| pOther->pev->absmax.x < pev->absmin.x bool CBaseEntity::Intersects(const Vector &mins, const Vector &maxs)
|| pOther->pev->absmax.y < pev->absmin.y {
|| pOther->pev->absmax.z < pev->absmin.z) if (mins.x > pev->absmax.x
return 0; || mins.y > pev->absmax.y
return 1; || 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() void CBaseEntity::MakeDormant()
@ -1025,7 +913,7 @@ CBaseEntity *CBaseEntity::Create(char *szName, const Vector &vecOrigin, const Ve
if (FNullEnt(pent)) if (FNullEnt(pent))
{ {
ALERT(at_console, "NULL Ent in Create!\n"); ALERT(at_console, "NULL Ent in Create!\n");
return NULL; return nullptr;
} }
CBaseEntity *pEntity = Instance(pent); CBaseEntity *pEntity = Instance(pent);
@ -1039,13 +927,534 @@ CBaseEntity *CBaseEntity::Create(char *szName, const Vector &vecOrigin, const Ve
return pEntity; 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) if (!pEntity)
return; return;
pEntity->UpdateOnRemove(); #ifdef REGAMEDLL_API
pEntity->OnDestroy();
#endif
RemoveEntityHashValue(pEntity->pev, STRING(pEntity->pev->classname), CLASSNAME); RemoveEntityHashValue(pEntity->pev, STRING(pEntity->pev->classname), CLASSNAME);
#ifdef REGAMEDLL_API #ifdef REGAMEDLL_API
@ -1061,3 +1470,14 @@ void EXT_FUNC OnFreeEntPrivateData(edict_t *pEnt)
} }
#endif #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 #pragma once
#endif
#include "saverestore.h" #include "util.h"
#include "schedule.h" #include "schedule.h"
#include "saverestore.h"
#include "scriptevent.h"
#include "monsterevent.h" #include "monsterevent.h"
#undef CREATE_NAMED_ENTITY class CSave;
#undef REMOVE_ENTITY class CRestore;
class CBasePlayer;
// 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 CBaseEntity; class CBaseEntity;
class CBaseMonster; class CBaseMonster;
class CBasePlayerItem; class CBasePlayerItem;
class CBasePlayerWeapon;
class CSquadMonster; class CSquadMonster;
class CCSEntity; class CCSEntity;
class CCineMonster; #undef CREATE_NAMED_ENTITY
class CSound; #undef REMOVE_ENTITY
// 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;
};
// Base Entity. All entity types derive from this // Base Entity. All entity types derive from this
class CBaseEntity { class CBaseEntity {
@ -234,8 +57,14 @@ public:
virtual int Restore(CRestore &restore); virtual int Restore(CRestore &restore);
virtual int ObjectCaps() { return FCAP_ACROSS_TRANSITION; } virtual int ObjectCaps() { return FCAP_ACROSS_TRANSITION; }
virtual void Activate() {} virtual void Activate() {}
// Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box)
virtual void SetObjectCollisionBox(); 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 int Classify() { return CLASS_NONE; }
virtual void DeathNotice(entvars_t *pevChild) {} virtual void DeathNotice(entvars_t *pevChild) {}
virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); 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); 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 int BloodColor() { return DONT_BLEED; }
virtual void TraceBleed(float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); virtual void TraceBleed(float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
virtual BOOL IsTriggered(CBaseEntity *pActivator) { return TRUE; } virtual BOOL IsTriggered(CBaseEntity *pActivator) { return TRUE; }
virtual CBaseMonster *MyMonsterPointer() { return NULL; } virtual CBaseMonster *MyMonsterPointer() { return nullptr; }
virtual CSquadMonster *MySquadMonsterPointer() { return NULL; } virtual CSquadMonster *MySquadMonsterPointer() { return nullptr; }
virtual int GetToggleState() { return TS_AT_TOP; } virtual int GetToggleState() { return TS_AT_TOP; }
virtual void AddPoints(int score, BOOL bAllowNegativeScore) {} virtual void AddPoints(int score, BOOL bAllowNegativeScore) {}
virtual void AddPointsToTeam(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 int IsMoving() { return (pev->velocity != g_vecZero); }
virtual void OverrideReset() {} virtual void OverrideReset() {}
virtual int DamageDecal(int bitsDamageType); 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() {} virtual void StopSneaking() {}
#else #else
virtual void UpdateOnRemove(); virtual void OnCreate();
virtual void OnDestroy();
#endif #endif
virtual BOOL OnControls(entvars_t *onpev) { return FALSE; } 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 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 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 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 // used by monsters that are created by the MonsterMaker
virtual void UpdateOwner() {} virtual void UpdateOwner() {}
virtual BOOL FBecomeProne() { return FALSE; } 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 Center() { return (pev->absmax + pev->absmin) * 0.5f; } // center point of entity
virtual Vector EarPosition() { return (pev->origin + pev->view_ofs); } virtual Vector EyePosition() { return (pev->origin + pev->view_ofs); } // position of eyes
virtual Vector BodyTarget(const Vector &posSrc) { return Center(); } 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 int Illumination() { return GETENTITYILLUM(ENT(pev)); }
virtual BOOL FVisible(CBaseEntity *pEntity); virtual BOOL FVisible(CBaseEntity *pEntity);
@ -303,9 +137,7 @@ public:
void operator delete(void *pMem, entvars_t *pevnew) { pevnew->flags |= FL_KILLME; } void operator delete(void *pMem, entvars_t *pevnew) { pevnew->flags |= FL_KILLME; }
#endif #endif
#ifndef REGAMEDLL_FIXES
void UpdateOnRemove(); void UpdateOnRemove();
#endif
void EXPORT SUB_Remove(); void EXPORT SUB_Remove();
void EXPORT SUB_DoNothing(); void EXPORT SUB_DoNothing();
@ -313,10 +145,11 @@ public:
void EXPORT SUB_FadeOut(); void EXPORT SUB_FadeOut();
void EXPORT SUB_CallUseToggle() { Use(this, this, USE_TOGGLE, 0); } void EXPORT SUB_CallUseToggle() { Use(this, this, USE_TOGGLE, 0); }
int ShouldToggle(USE_TYPE useType, BOOL currentState); 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); 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); 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(); void MakeDormant();
int IsDormant(); int IsDormant();
BOOL IsLockedByMaster() { return FALSE; } BOOL IsLockedByMaster() { return FALSE; }
@ -337,26 +170,30 @@ public:
CBaseMonster *GetMonsterPointer(entvars_t *pevMonster) CBaseMonster *GetMonsterPointer(entvars_t *pevMonster)
{ {
CBaseEntity *pEntity = Instance(pevMonster); CBaseEntity *pEntity = Instance(pevMonster);
if (pEntity != NULL) if (pEntity) {
return pEntity->MyMonsterPointer(); return pEntity->MyMonsterPointer();
}
return NULL; return nullptr;
} }
CBaseMonster *GetMonsterPointer(edict_t *pentMonster) CBaseMonster *GetMonsterPointer(edict_t *pentMonster)
{ {
CBaseEntity *pEntity = Instance(pentMonster); CBaseEntity *pEntity = Instance(pentMonster);
if (pEntity != NULL) if (pEntity) {
return pEntity->MyMonsterPointer(); 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); } edict_t *edict() { return ENT(pev); }
EOFFSET eoffset() { return OFFSET(pev); } EOFFSET eoffset() { return OFFSET(pev); }
int entindex() { return ENTINDEX(edict()); } int entindex() { return ENTINDEX(edict()); }
public: 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 // path corners
CBaseEntity *m_pGoalEnt; // path corner we are heading towards CBaseEntity *m_pGoalEnt; // path corner we are heading towards
@ -364,11 +201,32 @@ public:
static TYPEDESCRIPTION IMPL(m_SaveData)[5]; static TYPEDESCRIPTION IMPL(m_SaveData)[5];
// fundamental callbacks
void (CBaseEntity::*m_pfnThink)(); void (CBaseEntity::*m_pfnThink)();
void (CBaseEntity::*m_pfnTouch)(CBaseEntity *pOther); void (CBaseEntity::*m_pfnTouch)(CBaseEntity *pOther);
void (CBaseEntity::*m_pfnUse)(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); void (CBaseEntity::*m_pfnUse)(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void (CBaseEntity::*m_pfnBlocked)(CBaseEntity *pOther); 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 #ifdef REGAMEDLL_API
CCSEntity *m_pEntity; CCSEntity *m_pEntity;
#else #else
@ -408,8 +266,52 @@ public:
bool has_disconnected; bool has_disconnected;
}; };
inline int FNullEnt(CBaseEntity *ent) { return (ent == NULL || FNullEnt(ent->edict())); } // Inlines
inline int FNullEnt(EHANDLE hent) { return (hent == NULL || FNullEnt(OFFSET(hent.Get()))); } 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 { class CPointEntity: public CBaseEntity {
public: public:
@ -417,33 +319,6 @@ public:
virtual int ObjectCaps() { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } 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. // generic Delay entity.
class CBaseDelay: public CBaseEntity { class CBaseDelay: public CBaseEntity {
public: public:
@ -458,7 +333,7 @@ public:
static TYPEDESCRIPTION IMPL(m_SaveData)[2]; static TYPEDESCRIPTION IMPL(m_SaveData)[2];
float m_flDelay; float m_flDelay;
int m_iszKillTarget; string_t m_iszKillTarget;
}; };
class CBaseAnimating: public CBaseDelay { class CBaseAnimating: public CBaseDelay {
@ -469,7 +344,7 @@ public:
public: public:
// Basic Monster Animation functions // 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 GetSequenceFlags();
int LookupActivity(int activity); int LookupActivity(int activity);
int LookupActivityHeaviest(int activity); int LookupActivityHeaviest(int activity);
@ -498,11 +373,11 @@ public:
static TYPEDESCRIPTION IMPL(m_SaveData)[5]; static TYPEDESCRIPTION IMPL(m_SaveData)[5];
// animation needs // animation needs
float m_flFrameRate; // computed FPS for current sequence float m_flFrameRate; // computed FPS for current sequence
float m_flGroundSpeed; // computed linear movement rate for current sequence float m_flGroundSpeed; // computed linear movement rate for current sequence
float m_flLastEventCheck; // last time the event list was checked float m_flLastEventCheck; // last time the event list was checked
BOOL m_fSequenceFinished; // flag set when StudioAdvanceFrame moves across a frame boundry BOOL m_fSequenceFinished; // flag set when StudioAdvanceFrame moves across a frame boundry
BOOL m_fSequenceLoops; // true if the sequence loops BOOL m_fSequenceLoops; // true if the sequence loops
}; };
// generic Toggle entity. // generic Toggle entity.
@ -534,8 +409,8 @@ public:
float m_flMoveDistance; // how far a door should slide or rotate float m_flMoveDistance; // how far a door should slide or rotate
float m_flWait; float m_flWait;
float m_flLip; float m_flLip;
float m_flTWidth; // for plats float m_flTWidth; // for plats
float m_flTLength; // for plats float m_flTLength; // for plats
Vector m_vecPosition1; Vector m_vecPosition1;
Vector m_vecPosition2; Vector m_vecPosition2;
@ -544,8 +419,14 @@ public:
int m_cTriggersLeft; // trigger_counter only, # of activations remaining int m_cTriggersLeft; // trigger_counter only, # of activations remaining
float m_flHeight; float m_flHeight;
EHANDLE m_hActivator; EHandle m_hActivator;
void (CBaseToggle::*m_pfnCallWhenMoveDone)(); 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_vecFinalDest;
Vector m_vecFinalAngle; Vector m_vecFinalAngle;
@ -558,7 +439,25 @@ public:
// deactivated. // 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 "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 // Generic Button
class CBaseButton: public CBaseToggle { class CBaseButton: public CBaseToggle {
@ -569,6 +468,8 @@ public:
virtual BOOL TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType); virtual BOOL TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType);
virtual int Save(CSave &save); virtual int Save(CSave &save);
virtual int Restore(CRestore &restore); virtual int Restore(CRestore &restore);
// Buttons that don't take damage can be IMPULSE used
virtual int ObjectCaps() virtual int ObjectCaps()
{ {
if (pev->takedamage == DAMAGE_NO) if (pev->takedamage == DAMAGE_NO)
@ -602,27 +503,50 @@ public:
public: public:
static TYPEDESCRIPTION IMPL(m_SaveData)[8]; static TYPEDESCRIPTION IMPL(m_SaveData)[8];
BOOL m_fStayPushed; BOOL m_fStayPushed; // button stays pushed in until touched again?
BOOL m_fRotating; BOOL m_fRotating; // a rotating button? default is a sliding button.
string_t m_strChangeTarget;
locksound_t m_ls; string_t m_strChangeTarget; // if this field is not null, this is an index into the engine string array.
byte m_bLockedSound; // 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_bLockedSentence;
byte m_bUnlockedSound; byte m_bUnlockedSound;
byte m_bUnlockedSentence; byte m_bUnlockedSentence;
int m_sounds; int m_sounds;
}; };
#define SF_WORLD_DARK 0x0001 // Fade from black at startup // MultiSouce
#define SF_WORLD_TITLE 0x0002 // Display game title at startup #define MAX_MS_TARGETS 32 // maximum number of targets a single multisource entity may be assigned.
#define SF_WORLD_FORCETEAM 0x0004 // Force teams #define SF_MULTI_INIT BIT(0)
// This spawns first when each level begins. class CMultiSource: public CPointEntity {
class CWorld: public CBaseEntity {
public: public:
virtual void Spawn(); virtual void Spawn();
virtual void Precache();
virtual void KeyValue(KeyValueData *pkvd); 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 // Converts a entvars_t * to a class pointer
@ -646,6 +570,7 @@ T *GetClassPtr(T *a)
a->pev = pev; a->pev = pev;
#ifdef REGAMEDLL_API #ifdef REGAMEDLL_API
a->OnCreate();
a->m_pEntity = new W(); a->m_pEntity = new W();
a->m_pEntity->m_pContainingEntity = a; a->m_pEntity->m_pContainingEntity = a;
#endif #endif
@ -663,27 +588,27 @@ extern CUtlVector<hash_item_t> stringsHashTable;
C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion); C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion);
C_DLLEXPORT int GetNewDLLFunctions(NEW_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); int CaseInsensitiveHash(const char *string, int iBounds);
void EmptyEntityHashTable(); 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 #pragma once
#endif
#define MAX_WEAPON_SLOTS 5 // hud item selection slots const int MAX_WEAPON_SLOTS = 5; // hud item selection slots
#define MAX_ITEM_TYPES 6 // 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 STATUSICON_HIDE 0
#define HIDEHUD_FLASHLIGHT (1<<1) #define STATUSICON_SHOW 1
#define HIDEHUD_ALL (1<<2) #define STATUSICON_FLASH 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 HUD_PRINTNOTIFY 1
#define STATUSICON_SHOW 1 #define HUD_PRINTCONSOLE 2
#define STATUSICON_FLASH 2 #define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define HUD_PRINTRADIO 5
#define HUD_PRINTNOTIFY 1 #define STATUS_NIGHTVISION_ON 1
#define HUD_PRINTCONSOLE 2 #define STATUS_NIGHTVISION_OFF 0
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define HUD_PRINTRADIO 5
#define STATUS_NIGHTVISION_ON 1 #define ITEM_STATUS_NIGHTVISION BIT(0)
#define STATUS_NIGHTVISION_OFF 0 #define ITEM_STATUS_DEFUSER BIT(1)
#define ITEM_STATUS_NIGHTVISION (1<<0) #define SCORE_STATUS_DEAD BIT(0)
#define ITEM_STATUS_DEFUSER (1<<1) #define SCORE_STATUS_BOMB BIT(1)
#define SCORE_STATUS_VIP BIT(2)
#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)
// player data iuser3 // player data iuser3
#define PLAYER_CAN_SHOOT (1<<0) #define PLAYER_CAN_SHOOT BIT(0)
#define PLAYER_FREEZE_TIME_OVER (1<<1) #define PLAYER_FREEZE_TIME_OVER BIT(1)
#define PLAYER_IN_BOMB_ZONE (1<<2) #define PLAYER_IN_BOMB_ZONE BIT(2)
#define PLAYER_HOLDING_SHIELD (1<<3) #define PLAYER_HOLDING_SHIELD BIT(3)
#define MENU_KEY_1 (1<<0) #define MENU_KEY_1 BIT(0)
#define MENU_KEY_2 (1<<1) #define MENU_KEY_2 BIT(1)
#define MENU_KEY_3 (1<<2) #define MENU_KEY_3 BIT(2)
#define MENU_KEY_4 (1<<3) #define MENU_KEY_4 BIT(3)
#define MENU_KEY_5 (1<<4) #define MENU_KEY_5 BIT(4)
#define MENU_KEY_6 (1<<5) #define MENU_KEY_6 BIT(5)
#define MENU_KEY_7 (1<<6) #define MENU_KEY_7 BIT(6)
#define MENU_KEY_8 (1<<7) #define MENU_KEY_8 BIT(7)
#define MENU_KEY_9 (1<<8) #define MENU_KEY_9 BIT(8)
#define MENU_KEY_0 (1<<9) #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 WEAPON_SUIT 31
#define HUD_PRINTCONSOLE 2 #define WEAPON_ALLWEAPONS (~(1<<WEAPON_SUIT))
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define WEAPON_SUIT 31
#define WEAPON_ALLWEAPONS (~(1 << WEAPON_SUIT))
// custom enum // custom enum
enum VGUIMenu enum VGUIMenu
@ -130,5 +118,3 @@ enum VGUIMenuSlot
VGUI_MenuSlot_Buy_SecAmmo, VGUI_MenuSlot_Buy_SecAmmo,
VGUI_MenuSlot_Buy_Item, VGUI_MenuSlot_Buy_Item,
}; };
#endif // CDLL_DLL_H

View File

@ -5,6 +5,88 @@
*/ */
#ifndef HOOK_GAMEDLL #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; bool g_bClientPrintEnable = true;
char *sPlayerModelFiles[] = char *sPlayerModelFiles[] =
@ -19,40 +101,40 @@ char *sPlayerModelFiles[] =
"models/player/sas/sas.mdl", "models/player/sas/sas.mdl",
"models/player/terror/terror.mdl", "models/player/terror/terror.mdl",
"models/player/urban/urban.mdl", "models/player/urban/urban.mdl",
"models/player/spetsnaz/spetsnaz.mdl", // CZ "models/player/spetsnaz/spetsnaz.mdl", // CZ
"models/player/militia/militia.mdl" // CZ "models/player/militia/militia.mdl" // CZ
}; };
bool g_skipCareerInitialSpawn = false; bool g_skipCareerInitialSpawn = false;
static entity_field_alias_t entity_field_alias[] = static entity_field_alias_t entity_field_alias[] =
{ {
{ "origin[0]", 0 }, { "origin[0]", 0 },
{ "origin[1]", 0 }, { "origin[1]", 0 },
{ "origin[2]", 0 }, { "origin[2]", 0 },
{ "angles[0]", 0 }, { "angles[0]", 0 },
{ "angles[1]", 0 }, { "angles[1]", 0 },
{ "angles[2]", 0 }, { "angles[2]", 0 },
}; };
static entity_field_alias_t player_field_alias[] = static entity_field_alias_t player_field_alias[] =
{ {
{ "origin[0]", 0 }, { "origin[0]", 0 },
{ "origin[1]", 0 }, { "origin[1]", 0 },
{ "origin[2]", 0 }, { "origin[2]", 0 },
}; };
static entity_field_alias_t custom_entity_field_alias[] = static entity_field_alias_t custom_entity_field_alias[] =
{ {
{ "origin[0]", 0 }, { "origin[0]", 0 },
{ "origin[1]", 0 }, { "origin[1]", 0 },
{ "origin[2]", 0 }, { "origin[2]", 0 },
{ "angles[0]", 0 }, { "angles[0]", 0 },
{ "angles[1]", 0 }, { "angles[1]", 0 },
{ "angles[2]", 0 }, { "angles[2]", 0 },
{ "skin", 0 }, { "skin", 0 },
{ "sequence", 0 }, { "sequence", 0 },
{ "animtime", 0 }, { "animtime", 0 },
}; };
#endif // HOOK_GAMEDLL #endif // HOOK_GAMEDLL
@ -62,15 +144,130 @@ PLAYERPVSSTATUS g_PVSStatus[MAX_CLIENTS];
unsigned short m_usResetDecals; unsigned short m_usResetDecals;
unsigned short g_iShadowSprite; 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_() int CMD_ARGC_()
{ {
if (!UseBotArgs) if (!UseBotArgs)
return CMD_ARGC(); return CMD_ARGC();
int i = 0; int i = 0;
while (BotArgs[i]) while (BotArgs[i])
++i; i++;
return i; return i;
} }
@ -83,7 +280,7 @@ const char *CMD_ARGV_(int i)
if (i < 4) if (i < 4)
return BotArgs[i]; return BotArgs[i];
return NULL; return nullptr;
} }
NOXREF void set_suicide_frame(entvars_t *pev) 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) 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); WRITE_BYTE(numBlinks);
MESSAGE_END(); MESSAGE_END();
} }
@ -127,7 +324,9 @@ void EXT_FUNC ClientDisconnect(edict_t *pEntity)
pEntity->v.flags = FL_DORMANT; pEntity->v.flags = FL_DORMANT;
if (pPlayer) if (pPlayer)
{
pPlayer->Disconnect(); pPlayer->Disconnect();
}
UTIL_SetOrigin(&pEntity->v, pEntity->v.origin); UTIL_SetOrigin(&pEntity->v, pEntity->v.origin);
g_pGameRules->ClientDisconnected(pEntity); 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) 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_SHORT(bitsValidSlots);
WRITE_CHAR(nDisplayTime); WRITE_CHAR(nDisplayTime);
WRITE_BYTE(fNeedMore); 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) 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_BYTE(MenuType);
WRITE_SHORT(BitMask); WRITE_SHORT(BitMask);
WRITE_CHAR(-1); WRITE_CHAR(-1);
@ -242,28 +441,28 @@ void EXT_FUNC __API_HOOK(ShowVGUIMenu)(CBasePlayer *pPlayer, int MenuType, int B
NOXREF int CountTeams() NOXREF int CountTeams()
{ {
int iNumCT = 0, iNumTerrorist = 0; 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; 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; continue;
if (player->pev->flags & FL_DORMANT) if (pPlayer->pev->flags & FL_DORMANT)
continue; continue;
if (player->m_iTeam == SPECTATOR) if (pPlayer->m_iTeam == SPECTATOR)
continue; continue;
if (player->m_iTeam == CT) if (pPlayer->m_iTeam == CT)
iNumCT++; iNumCT++;
else if (player->m_iTeam == TERRORIST) else if (pPlayer->m_iTeam == TERRORIST)
iNumTerrorist++; iNumTerrorist++;
} }
@ -274,23 +473,23 @@ void ListPlayers(CBasePlayer *current)
{ {
char message[120] = "", cNumber[12]; char message[120] = "", cNumber[12];
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; break;
if (pPlayer->pev->flags & FL_DORMANT) if (pEntity->pev->flags & FL_DORMANT)
continue; continue;
CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pPlayer->pev); CBasePlayer *pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
int iUserID = GETPLAYERUSERID(ENT(player->pev)); int iUserID = GETPLAYERUSERID(ENT(pPlayer->pev));
Q_sprintf(cNumber, "%d", iUserID); Q_sprintf(cNumber, "%d", iUserID);
Q_strcpy(message, "\n"); Q_strcpy(message, "\n");
Q_strcat(message, cNumber); Q_strcat(message, cNumber);
Q_strcat(message, " : "); Q_strcat(message, " : ");
Q_strcat(message, STRING(player->pev->netname)); Q_strcat(message, STRING(pPlayer->pev->netname));
ClientPrint(current->pev, HUD_PRINTCONSOLE, message); ClientPrint(current->pev, HUD_PRINTCONSOLE, message);
} }
@ -300,22 +499,23 @@ void ListPlayers(CBasePlayer *current)
int CountTeamPlayers(int iTeam) int CountTeamPlayers(int iTeam)
{ {
CBaseEntity *pPlayer = NULL; int nCount = 0;
int i = 0; CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")))
{ {
if (FNullEnt(pPlayer->edict())) if (FNullEnt(pEntity->edict()))
break; break;
if (pPlayer->pev->flags & FL_DORMANT) if (pEntity->pev->flags & FL_DORMANT)
continue; continue;
if (GetClassPtr<CCSPlayer>((CBasePlayer *)pPlayer->pev)->m_iTeam == iTeam) if (GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev)->m_iTeam == iTeam)
++i; {
nCount++;
}
} }
return i; return nCount;
} }
void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer) void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer)
@ -336,7 +536,7 @@ void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer)
return; return;
iValidVotes = 0; iValidVotes = 0;
pTempEntity = NULL; pTempEntity = nullptr;
iVoteID = pVotingPlayer->m_iCurrentKickVote; iVoteID = pVotingPlayer->m_iCurrentKickVote;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player"))) 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)); UTIL_ClientPrintAll(HUD_PRINTCENTER, "#Game_kicked", STRING(pKickPlayer->pev->netname));
SERVER_COMMAND(UTIL_VarArgs("kick # %d\n", iVoteID)); SERVER_COMMAND(UTIL_VarArgs("kick # %d\n", iVoteID));
pTempEntity = NULL; pTempEntity = nullptr;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player"))) while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")))
{ {
@ -457,25 +657,25 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
pPlayer->has_disconnected = false; pPlayer->has_disconnected = false;
pPlayer->m_iMenu = Menu_OFF; pPlayer->m_iMenu = Menu_OFF;
pPlayer->ClearAutoBuyData(); pPlayer->ClearAutoBuyData();
pPlayer->m_rebuyString = NULL; pPlayer->m_rebuyString = nullptr;
SET_CLIENT_MAXSPEED(ENT(pPlayer->pev), 1); SET_CLIENT_MAXSPEED(ENT(pPlayer->pev), 1);
SET_MODEL(ENT(pPlayer->pev), "models/player.mdl"); SET_MODEL(ENT(pPlayer->pev), "models/player.mdl");
pPlayer->SetThink(NULL); pPlayer->SetThink(NULL);
CBaseEntity *pTarget = NULL; CBaseEntity *pTarget = nullptr;
pPlayer->m_pIntroCamera = UTIL_FindEntityByClassname(NULL, "trigger_camera"); pPlayer->m_pIntroCamera = UTIL_FindEntityByClassname(nullptr, "trigger_camera");
if (g_pGameRules && g_pGameRules->IsMultiplayer()) if (g_pGameRules && g_pGameRules->IsMultiplayer())
{ {
CSGameRules()->m_bMapHasCameras = (pPlayer->m_pIntroCamera != NULL); CSGameRules()->m_bMapHasCameras = (pPlayer->m_pIntroCamera != nullptr);
} }
if (pPlayer->m_pIntroCamera) if (pPlayer->m_pIntroCamera)
{ {
// find the target (by default info_target) for the camera view direction. // 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) if (pPlayer->m_pIntroCamera && pTarget)
@ -599,15 +799,15 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
if (Q_strlen(p) <= 0) if (Q_strlen(p) <= 0)
return; return;
const char *placeName = NULL; const char *placeName = nullptr;
char *pszFormat = NULL; char *pszFormat = nullptr;
char *pszConsoleFormat = NULL; char *pszConsoleFormat = nullptr;
bool consoleUsesPlaceName = false; bool consoleUsesPlaceName = false;
// team only // team only
if (teamonly) 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 // search the place name where is located the player
Place playerPlace = TheNavAreaGrid.GetPlace(&player->pev->origin); 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 // 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 // so check it, or it will infinite loop
client = NULL; client = nullptr;
while ((client = (CBasePlayer *)UTIL_FindEntityByClassname(client, "player"))) while ((client = (CBasePlayer *)UTIL_FindEntityByClassname(client, "player")))
{ {
if (FNullEnt(client->edict())) 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) if ((client->m_iIgnoreGlobalChat == IGNOREMSG_ENEMY && client->m_iTeam == player->m_iTeam)
|| client->m_iIgnoreGlobalChat == IGNOREMSG_NONE) || 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_BYTE(ENTINDEX(pEntity));
WRITE_STRING(pszFormat); WRITE_STRING(pszFormat);
WRITE_STRING(""); WRITE_STRING("");
@ -772,7 +972,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
char *fullText = p; char *fullText = p;
// print to the sending client // 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_BYTE(ENTINDEX(pEntity));
WRITE_STRING(pszFormat); WRITE_STRING(pszFormat);
WRITE_STRING(""); WRITE_STRING("");
@ -968,7 +1168,7 @@ void BuyMachineGun(CBasePlayer *pPlayer, int iSlot)
void BuyItem(CBasePlayer *pPlayer, int iSlot) void BuyItem(CBasePlayer *pPlayer, int iSlot)
{ {
int iItemPrice = 0; int iItemPrice = 0;
const char *pszItem = NULL; const char *pszItem = nullptr;
if (!pPlayer->CanPlayerBuy(true)) if (!pPlayer->CanPlayerBuy(true))
return; return;
@ -1208,7 +1408,7 @@ void BuyItem(CBasePlayer *pPlayer, int iSlot)
bEnoughMoney = true; bEnoughMoney = true;
pPlayer->m_bHasDefuser = 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_BYTE(STATUSICON_SHOW);
WRITE_STRING("defuser"); WRITE_STRING("defuser");
WRITE_BYTE(0); 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) 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 struct
{ {
@ -1369,7 +1569,7 @@ void EXT_FUNC __API_HOOK(HandleMenu_ChooseAppearance)(CBasePlayer *player, int s
appearance.model_name = "guerilla"; appearance.model_name = "guerilla";
break; break;
case 5: case 5:
if (g_bIsCzeroGame) if (AreRunningCZero())
{ {
appearance.model_id = MODEL_MILITIA; appearance.model_id = MODEL_MILITIA;
appearance.model_name = "militia"; appearance.model_name = "militia";
@ -1418,7 +1618,7 @@ void EXT_FUNC __API_HOOK(HandleMenu_ChooseAppearance)(CBasePlayer *player, int s
appearance.model_name = "gign"; appearance.model_name = "gign";
break; break;
case 5: case 5:
if (g_bIsCzeroGame) if (AreRunningCZero())
{ {
appearance.model_id = MODEL_SPETSNAZ; appearance.model_id = MODEL_SPETSNAZ;
appearance.model_name = "spetsnaz"; appearance.model_name = "spetsnaz";
@ -1613,7 +1813,7 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *player, int slot)
#else #else
player->m_iAccount = 0; 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_LONG(player->m_iAccount);
WRITE_BYTE(0); WRITE_BYTE(0);
MESSAGE_END(); MESSAGE_END();
@ -1631,7 +1831,7 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *player, int slot)
WRITE_SHORT(0); WRITE_SHORT(0);
MESSAGE_END(); MESSAGE_END();
player->m_pIntroCamera = NULL; player->m_pIntroCamera = nullptr;
player->m_bTeamChanged = true; player->m_bTeamChanged = true;
if (TheBots) if (TheBots)
@ -1792,14 +1992,14 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *player, int slot)
switch (team) switch (team)
{ {
case CT: 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"); 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 else
ShowVGUIMenu(player, VGUI_Menu_Class_CT, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5), "#CT_Select"); ShowVGUIMenu(player, VGUI_Menu_Class_CT, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5), "#CT_Select");
break; break;
case TERRORIST: 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"); 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 else
ShowVGUIMenu(player, VGUI_Menu_Class_T, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5), "#Terrorist_Select"); 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 *EntityFromUserID(int userID)
{ {
CBaseEntity *pTempEntity = NULL; CBaseEntity *pTempEntity = nullptr;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player"))) while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")))
{ {
@ -2071,13 +2271,13 @@ CBaseEntity *EntityFromUserID(int userID)
} }
} }
return NULL; return nullptr;
} }
NOXREF int CountPlayersInServer() NOXREF int CountPlayersInServer()
{ {
int count = 0; int count = 0;
CBaseEntity *pTempEntity = NULL; CBaseEntity *pTempEntity = nullptr;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player"))) 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. // Let them buy it if it's got a weapon data string.
BOOL bRetVal = FALSE; BOOL bRetVal = FALSE;
const char *pszFailItem = NULL; const char *pszFailItem = nullptr;
WeaponIdType weaponID = WEAPON_NONE; WeaponIdType weaponID = WEAPON_NONE;
const char *weaponFailName = BuyAliasToWeaponID(pszCommand, weaponID); 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) 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; entvars_t *pev = &pEntity->v;
CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pev); CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pev);
@ -2530,7 +2730,7 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
} }
else else
{ {
MESSAGE_BEGIN(MSG_ONE, gmsgBuyClose, NULL, player->pev); MESSAGE_BEGIN(MSG_ONE, gmsgBuyClose, nullptr, player->pev);
MESSAGE_END(); MESSAGE_END();
} }
} }
@ -2892,7 +3092,7 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
if (mode == OBS_CHASE_FREE) if (mode == OBS_CHASE_FREE)
{ {
MESSAGE_BEGIN(MSG_ONE, gmsgADStop, NULL, player->pev); MESSAGE_BEGIN(MSG_ONE, gmsgADStop, nullptr, player->pev);
MESSAGE_END(); 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); 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 WRITE_BYTE(0); // disable nightvision
MESSAGE_END(); 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); 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 WRITE_BYTE(0); // disable nightvision
MESSAGE_END(); 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); 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 WRITE_BYTE(1); // enable nightvision
MESSAGE_END(); 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); 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 WRITE_BYTE(1); // enable nightvision
MESSAGE_END(); MESSAGE_END();
@ -3370,7 +3570,6 @@ void EXT_FUNC ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
#ifdef REGAMEDLL_ADD #ifdef REGAMEDLL_ADD
CSGameRules()->ServerActivate(); CSGameRules()->ServerActivate();
#endif #endif
} }
void EXT_FUNC PlayerPreThink(edict_t *pEntity) void EXT_FUNC PlayerPreThink(edict_t *pEntity)
@ -3422,7 +3621,7 @@ void EXT_FUNC StartFrame()
CLocalNav::Think(); CLocalNav::Think();
static cvar_t *skill = NULL; static cvar_t *skill = nullptr;
if (!skill) if (!skill)
{ {
skill = CVAR_GET_POINTER("skill"); skill = CVAR_GET_POINTER("skill");
@ -3443,11 +3642,6 @@ void EXT_FUNC StartFrame()
if (TheTutor) { if (TheTutor) {
TheTutor->StartFrame(gpGlobals->time); TheTutor->StartFrame(gpGlobals->time);
} }
#ifndef REGAMEDLL_FIXES
// it is noxref
++g_ulFrameCount;
#endif
} }
void ClientPrecache() void ClientPrecache()
@ -3557,8 +3751,8 @@ void ClientPrecache()
PRECACHE_SOUND("debris/glass1.wav"); PRECACHE_SOUND("debris/glass1.wav");
PRECACHE_SOUND("debris/glass2.wav"); PRECACHE_SOUND("debris/glass2.wav");
PRECACHE_SOUND("debris/glass3.wav"); PRECACHE_SOUND("debris/glass3.wav");
PRECACHE_SOUND("items/flashlight1.wav"); PRECACHE_SOUND(SOUND_FLASHLIGHT_ON);
PRECACHE_SOUND("items/flashlight1.wav"); PRECACHE_SOUND(SOUND_FLASHLIGHT_OFF);
PRECACHE_SOUND("common/bodysplat.wav"); PRECACHE_SOUND("common/bodysplat.wav");
PRECACHE_SOUND("player/pl_pain2.wav"); PRECACHE_SOUND("player/pl_pain2.wav");
PRECACHE_SOUND("player/pl_pain4.wav"); PRECACHE_SOUND("player/pl_pain4.wav");
@ -3567,7 +3761,7 @@ void ClientPrecache()
PRECACHE_SOUND("player/pl_pain7.wav"); PRECACHE_SOUND("player/pl_pain7.wav");
int numPlayerModels; int numPlayerModels;
if (g_bIsCzeroGame) if (AreRunningCZero())
numPlayerModels = ARRAYSIZE(sPlayerModelFiles); numPlayerModels = ARRAYSIZE(sPlayerModelFiles);
else else
numPlayerModels = ARRAYSIZE(sPlayerModelFiles) - 2; numPlayerModels = ARRAYSIZE(sPlayerModelFiles) - 2;
@ -3575,7 +3769,7 @@ void ClientPrecache()
for (i = 0; i < numPlayerModels; ++i) for (i = 0; i < numPlayerModels; ++i)
PRECACHE_MODEL(sPlayerModelFiles[i]); PRECACHE_MODEL(sPlayerModelFiles[i]);
if (g_bIsCzeroGame) if (AreRunningCZero())
{ {
for (i = FirstCustomSkin; i <= LastCustomSkin; ++i) for (i = FirstCustomSkin; i <= LastCustomSkin; ++i)
{ {
@ -3640,7 +3834,7 @@ void ClientPrecache()
for (i = 0; i < numPlayerModels; ++i) for (i = 0; i < numPlayerModels; ++i)
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, sPlayerModelFiles[i]); ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, sPlayerModelFiles[i]);
if (g_bIsCzeroGame) if (AreRunningCZero())
{ {
for (i = FirstCustomSkin; i <= LastCustomSkin; ++i) 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_ne.tga");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_sw.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); vMin = Vector(-13, -6, -22);
vMax = 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_fiveseven.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_glock18.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); vMin = Vector(-26, -19, -21);
vMax = Vector(26, 23, 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_xm1014.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_m3.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); vMin = Vector(-23, -9, -20);
vMax = Vector(23, 17, 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_tmp.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_p90.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); vMin = Vector(-38, -33, -22);
vMax = Vector(38, 15, 35); 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_famas.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_galil.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); vMin = Vector(-30, -10, -20);
vMax = Vector(30, 11, 20); vMax = Vector(30, 11, 20);
@ -3756,7 +3950,7 @@ void ClientPrecache()
vMin = Vector(-4, -8, -3); vMin = Vector(-4, -8, -3);
vMax = Vector(3, 7, 3); vMax = Vector(3, 7, 3);
if (g_bIsCzeroGame) if (AreRunningCZero())
{ {
vMin = Vector(-17, -8, -3); vMin = Vector(-17, -8, -3);
vMax = Vector(17, 7, 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"); ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/w_c4.mdl");
if (g_bIsCzeroGame) if (AreRunningCZero())
{ {
vMin = Vector(-7, -3, -18); vMin = Vector(-7, -3, -18);
vMax = Vector(7, 2, 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_hegrenade.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_smokegrenade.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); vMin = Vector(-5, -5, -7);
else else
vMin = Vector(-5, -5, -5); 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"); ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_knife.mdl");
if (g_bIsCzeroGame) if (AreRunningCZero())
{ {
vMin = Vector(-21, -25, -54); vMin = Vector(-21, -25, -54);
vMax = Vector(21, 23, 24); vMax = Vector(21, 23, 24);
@ -3867,7 +4061,7 @@ const char *EXT_FUNC GetGameDescription()
return CSGameRules()->GetGameDescription(); return CSGameRules()->GetGameDescription();
} }
#else #else
if (g_bIsCzeroGame) { if (AreRunningCZero()) {
return "Condition Zero"; return "Condition Zero";
} }
#endif #endif
@ -4045,7 +4239,6 @@ int EXT_FUNC AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, ed
int i; int i;
int hostnum = ENTINDEX(host) - 1; int hostnum = ENTINDEX(host) - 1;
if (CheckPlayerPVSLeafChanged(host, hostnum)) if (CheckPlayerPVSLeafChanged(host, hostnum))
ResetPlayerPVS(host, hostnum); ResetPlayerPVS(host, hostnum);
@ -4400,10 +4593,10 @@ int EXT_FUNC GetWeaponData(edict_t *player, struct weapon_data_s *info)
return 1; return 1;
// go through all of the weapons and make a list of the ones to pack // 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]; auto pPlayerItem = pPlayer->m_rgpPlayerItems[i];
while (pPlayerItem != nullptr) while (pPlayerItem)
{ {
// there's a weapon here. Should I pack it? // there's a weapon here. Should I pack it?
auto weapon = (CBasePlayerWeapon *)pPlayerItem->GetWeaponPtr(); auto weapon = (CBasePlayerWeapon *)pPlayerItem->GetWeaponPtr();

View File

@ -26,11 +26,7 @@
* *
*/ */
#ifndef CLIENT_H
#define CLIENT_H
#ifdef _WIN32
#pragma once #pragma once
#endif
// custom enum // custom enum
enum ChooseTeamMenuSlot enum ChooseTeamMenuSlot
@ -58,8 +54,8 @@ enum BuyItemMenuSlot
MENU_SLOT_ITEM_SHIELD, MENU_SLOT_ITEM_SHIELD,
}; };
#define CS_NUM_SKIN 4 #define CS_NUM_SKIN 4
#define CZ_NUM_SKIN 5 #define CZ_NUM_SKIN 5
#define FIELD_ORIGIN0 0 #define FIELD_ORIGIN0 0
#define FIELD_ORIGIN1 1 #define FIELD_ORIGIN1 1
@ -78,8 +74,8 @@ enum BuyItemMenuSlot
#define CUSTOMFIELD_ANGLES2 5 #define CUSTOMFIELD_ANGLES2 5
#define CUSTOMFIELD_SKIN 6 #define CUSTOMFIELD_SKIN 6
#define CUSTOMFIELD_SEQUENCE 7 #define CUSTOMFIELD_SEQUENCE 7
#define CUSTOMFIELD_ANIMTIME 8 #define CUSTOMFIELD_ANIMTIME 8
typedef struct typedef struct
{ {
@ -87,12 +83,13 @@ typedef struct
} ENTITYPVSSTATUS; } ENTITYPVSSTATUS;
const int MAX_ENTITIES = 1380;
struct PLAYERPVSSTATUS struct PLAYERPVSSTATUS
{ {
ENTITYPVSSTATUS m_Status[1380]; ENTITYPVSSTATUS m_Status[MAX_ENTITIES];
int headnode; int headnode;
int num_leafs; int num_leafs;
short int leafnums[ MAX_ENT_LEAFS ]; short int leafnums[MAX_ENT_LEAFS];
}; };
struct entity_field_alias_t 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); void ShowVGUIMenu_OrigFunc(CBasePlayer *pPlayer, int MenuType, int BitMask, char *szOldMenu);
#endif #endif
void LinkUserMessages();
void WriteSigonMessages();
int CMD_ARGC_(); int CMD_ARGC_();
const char *CMD_ARGV_(int i); const char *CMD_ARGV_(int i);
void set_suicide_frame(entvars_t *pev); void set_suicide_frame(entvars_t *pev);
@ -199,11 +199,91 @@ inline const char *GetTeamName(int team)
{ {
switch (team) switch (team)
{ {
case CT: return "CT"; case CT: return "CT";
case TERRORIST: return "TERRORIST"; case TERRORIST: return "TERRORIST";
case SPECTATOR: return "SPECTATOR"; case SPECTATOR: return "SPECTATOR";
default: return "UNASSIGNED"; 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 #pragma once
class CNullEntity: public CBaseEntity { void InstallCommands();
public:
virtual void Spawn() = 0;
};
class CBaseDMStart: public CPointEntity { EXT_FUNC void SV_Continue_f();
public: EXT_FUNC void SV_CareerMatchLimit_f();
virtual void KeyValue(KeyValueData *pkvd) = 0; EXT_FUNC void SV_CareerAddTask_f();
virtual BOOL IsTriggered(CBaseEntity *pEntity) = 0; 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

@ -26,17 +26,11 @@
* *
*/ */
#ifndef H_AI_H
#define H_AI_H
#ifdef _WIN32
#pragma once #pragma once
#endif
#define NUM_LATERAL_CHECKS 13 // how many checks are made on each side of a monster looking for lateral cover EXT_FUNC void PlayerBlind(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, float fadeTime, float fadeHold, int alpha, Vector &color);
#define NUM_LATERAL_LOS_CHECKS 6 // how many checks are made on each side of a monster looking for lateral cover EXT_FUNC void RadiusFlash_TraceLine_hook(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, Vector &vecSrc, Vector &vecSpot, TraceResult *tr);
BOOL FBoxVisible(entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize); void RadiusFlash(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore = 0, int bitsDamageType = 0);
Vector VecCheckToss(entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj); void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);
Vector VecCheckThrow(entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj); void RadiusDamage2(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);
#endif // H_AI_H

View File

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

View File

@ -26,26 +26,18 @@
* *
*/ */
#ifndef DEBUG_H
#define DEBUG_H
#ifdef _WIN32
#pragma once #pragma once
#endif
const int NUM_LEVELS = 6; enum DebugOutputType
const int DebugBufferSize = 1024;
typedef enum
{ {
DEBUG_NONE = 0, DEBUG_NONE = 0,
DEBUG_BOT = (1 << 0), DEBUG_BOT = BIT(0),
DEBUG_CAREER = (1 << 1), DEBUG_CAREER = BIT(1),
DEBUG_TUTOR = (1 << 2), DEBUG_TUTOR = BIT(2),
DEBUG_STATS = (1 << 3), DEBUG_STATS = BIT(3),
DEBUG_HOSTAGE = (1 << 4), DEBUG_HOSTAGE = BIT(4),
DEBUG_ALL = 0xFFFFFFFF, DEBUG_ALL = 0xFFFFFFFF,
};
} DebugOutputType;
struct DebugOutputLevel struct DebugOutputLevel
{ {
@ -53,6 +45,8 @@ struct DebugOutputLevel
DebugOutputType value; DebugOutputType value;
}; };
const int MAX_DEBUG_BUFF_SIZE = 1024;
bool IsDeveloper(); bool IsDeveloper();
void UTIL_DPrintf(DebugOutputType outputType, char *pszMsg, ...); void UTIL_DPrintf(DebugOutputType outputType, char *pszMsg, ...);
void UTIL_DPrintf(char *pszMsg, ...); void UTIL_DPrintf(char *pszMsg, ...);
@ -67,5 +61,3 @@ void UTIL_CareerDPrintf(char *pszMsg, ...);
void UTIL_TutorDPrintf(char *pszMsg, ...); void UTIL_TutorDPrintf(char *pszMsg, ...);
void UTIL_StatsDPrintf(char *pszMsg, ...); void UTIL_StatsDPrintf(char *pszMsg, ...);
void UTIL_HostageDPrintf(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 #pragma once
#endif
#define DEFINE_DECAL(name)\
{ name, 0 }
enum decal_e enum decal_e
{ {
@ -69,13 +68,14 @@ enum decal_e
DECAL_BIGSHOT5, DECAL_BIGSHOT5,
DECAL_SPIT1, DECAL_SPIT1,
DECAL_SPIT2, DECAL_SPIT2,
DECAL_BPROOF1, // Bulletproof glass decal DECAL_BPROOF1, // Bulletproof glass decal
DECAL_GARGSTOMP1, // Gargantua stomp crack DECAL_GARGSTOMP1, // Gargantua stomp crack
DECAL_SMALLSCORCH1, // Small scorch mark DECAL_SMALLSCORCH1, // Small scorch mark
DECAL_SMALLSCORCH2, // Small scorch mark DECAL_SMALLSCORCH2, // Small scorch mark
DECAL_SMALLSCORCH3, // Small scorch mark DECAL_SMALLSCORCH3, // Small scorch mark
DECAL_MOMMABIRTH, // Big momma birth splatter DECAL_MOMMABIRTH, // Big momma birth splatter
DECAL_MOMMASPLAT, DECAL_MOMMASPLAT,
DECAL_END
}; };
typedef struct typedef struct
@ -85,6 +85,4 @@ typedef struct
} DLL_DECALLIST; } DLL_DECALLIST;
extern DLL_DECALLIST gDecals[42]; extern DLL_DECALLIST gDecals[DECAL_END];
#endif // DECALS_H

View File

@ -162,7 +162,9 @@ void CBaseDoor::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CBaseToggle::KeyValue(pkvd); CBaseToggle::KeyValue(pkvd);
}
} }
// QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK TOGGLE // QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK TOGGLE
@ -210,7 +212,7 @@ void CBaseDoor::Spawn()
pev->solid = SOLID_NOT; pev->solid = SOLID_NOT;
// water is silent for now // water is silent for now
pev->spawnflags |= SF_DOOR_SILENT; pev->spawnflags |= SF_DOOR_ACTUALLY_WATER;
} }
pev->movetype = MOVETYPE_PUSH; pev->movetype = MOVETYPE_PUSH;
@ -482,7 +484,7 @@ int CBaseDoor::DoorActivate()
else // door should open else // door should open
{ {
// give health if player opened the door (medikit) // 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; // VARS(m_eoActivator)->health += m_bHealthValue;
m_hActivator->TakeHealth(m_bHealthValue, DMG_GENERIC); 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! // filter them out and leave a client stuck with looping door sounds!
if (!isReversing) 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) 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); 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); TheBots->OnEvent(EVENT_DOOR, m_hActivator);
} }
@ -533,12 +536,12 @@ void CBaseDoor::DoorGoUp()
{ {
float sign = 1.0; float sign = 1.0;
if (m_hActivator != NULL) if (m_hActivator)
{ {
pevActivator = m_hActivator->pev; pevActivator = m_hActivator->pev;
// Y axis rotation, move away from the player // 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(); 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. // The door has reached the "up" position. Either go back down, or wait for another activation.
void CBaseDoor::DoorHitTop() 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)); STOP_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving));
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), VOL_NORM, ATTN_NORM); EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), VOL_NORM, ATTN_NORM);
@ -660,14 +664,15 @@ void CBaseDoor::DoorGoDown()
if (!isReversing) 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) 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); 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); TheBots->OnEvent(EVENT_DOOR, m_hActivator);
} }
@ -694,7 +699,8 @@ void CBaseDoor::DoorGoDown()
// The door has reached the "down" position. Back to quiescence. // The door has reached the "down" position. Back to quiescence.
void CBaseDoor::DoorHitBottom() 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)); STOP_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving));
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), VOL_NORM, ATTN_NORM); 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) void CBaseDoor::Blocked(CBaseEntity *pOther)
{ {
edict_t *pentTarget = NULL; edict_t *pentTarget = nullptr;
CBaseDoor *pDoor = NULL; CBaseDoor *pDoor = nullptr;
const float checkBlockedInterval = 0.25f; const float checkBlockedInterval = 0.25f;
// Hurt the blocker a little. // 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)); 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 #pragma once
#endif
#define DOOR_SENTENCEWAIT 6 const float DOOR_SENTENCEWAIT = 6.0f;
#define DOOR_SOUNDWAIT 3 const float DOOR_SOUNDWAIT = 3.0f;
#define BUTTON_SOUNDWAIT 0.5 const float BUTTON_SOUNDWAIT = 0.5f;
#define SF_DOOR_ROTATE_Y 0 #define SF_DOOR_START_OPEN BIT(0)
#define SF_DOOR_START_OPEN 1 #define SF_DOOR_PASSABLE BIT(3)
#define SF_DOOR_ROTATE_BACKWARDS 2 #define SF_DOOR_NO_AUTO_RETURN BIT(5)
#define SF_DOOR_PASSABLE 8 #define SF_DOOR_USE_ONLY BIT(8) // Door must be opened by player's use button.
#define SF_DOOR_ONEWAY 16 #define SF_DOOR_TOUCH_ONLY_CLIENTS BIT(10) // Only clients can touch
#define SF_DOOR_NO_AUTO_RETURN 32 #define SF_DOOR_ACTUALLY_WATER BIT(31) // This bit marks that func_door are actually func_water
#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
class CBaseDoor: public CBaseToggle class CBaseDoor: public CBaseToggle
{ {
@ -60,7 +50,7 @@ public:
virtual int Restore(CRestore &restore); virtual int Restore(CRestore &restore);
virtual int ObjectCaps() 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; return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE;
else else
return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION);
@ -82,7 +72,6 @@ public:
public: public:
byte m_bHealthValue; // some doors are medi-kit doors, they give players health byte m_bHealthValue; // some doors are medi-kit doors, they give players health
byte m_bMoveSnd; // sound a door makes while moving byte m_bMoveSnd; // sound a door makes while moving
byte m_bStopSnd; // sound a door makes when it stops byte m_bStopSnd; // sound a door makes when it stops
@ -96,6 +85,11 @@ public:
float m_lastBlockedTimestamp; 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 class CRotDoor: public CBaseDoor
{ {
public: public:
@ -122,5 +116,3 @@ public:
}; };
void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton); 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; pkvd->fHandled = TRUE;
} }
else else
{
CBaseEntity::KeyValue(pkvd); CBaseEntity::KeyValue(pkvd);
}
} }
void CBubbling::FizzThink() void CBubbling::FizzThink()
@ -207,7 +209,7 @@ const Vector &CBeam::GetEndPos()
} }
edict_t *pent = INDEXENT(GetEndEntity()); edict_t *pent = INDEXENT(GetEndEntity());
if (pent != NULL) if (pent)
{ {
return pent->v.origin; return pent->v.origin;
} }
@ -218,7 +220,7 @@ const Vector &CBeam::GetEndPos()
CBeam *CBeam::BeamCreate(const char *pSpriteName, int width) CBeam *CBeam::BeamCreate(const char *pSpriteName, int width)
{ {
// Create a new entity with CBeam private data // 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); MAKE_STRING_CLASS("beam", pBeam->pev);
pBeam->BeamInit(pSpriteName, width); pBeam->BeamInit(pSpriteName, width);
@ -321,10 +323,10 @@ CBaseEntity *CBeam::RandomTargetname(const char *szName)
{ {
int total = 0; int total = 0;
CBaseEntity *pEntity = NULL; CBaseEntity *pEntity = nullptr;
CBaseEntity *pNewEntity = NULL; CBaseEntity *pNewEntity = nullptr;
while ((pNewEntity = UTIL_FindEntityByTargetname(pNewEntity, szName)) != NULL) while ((pNewEntity = UTIL_FindEntityByTargetname(pNewEntity, szName)))
{ {
total++; total++;
@ -475,7 +477,9 @@ void CLightning::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CBeam::KeyValue(pkvd); CBeam::KeyValue(pkvd);
}
} }
void CLightning::ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) void CLightning::ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
@ -557,7 +561,7 @@ void CLightning::StrikeThink()
else else
{ {
CBaseEntity *pStart = RandomTargetname(STRING(m_iszStartEntity)); CBaseEntity *pStart = RandomTargetname(STRING(m_iszStartEntity));
if (pStart != NULL) if (pStart)
RandomPoint(pStart->pev->origin); RandomPoint(pStart->pev->origin);
else else
ALERT(at_console, "env_beam: unknown entity \"%s\"\n", STRING(m_iszStartEntity)); 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 *pStart = RandomTargetname(STRING(m_iszStartEntity));
CBaseEntity *pEnd = RandomTargetname(STRING(m_iszEndEntity)); CBaseEntity *pEnd = RandomTargetname(STRING(m_iszEndEntity));
if (pStart != NULL && pEnd != NULL) if (pStart && pEnd)
{ {
if (IsPointEntity(pStart) || IsPointEntity(pEnd)) if (IsPointEntity(pStart) || IsPointEntity(pEnd))
{ {
@ -642,7 +646,7 @@ void CLightning::StrikeThink()
if (pev->dmg > 0) if (pev->dmg > 0)
{ {
TraceResult tr; 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); BeamDamageInstant(&tr, pev->dmg);
} }
} }
@ -652,11 +656,11 @@ void CBeam::BeamDamage(TraceResult *ptr)
{ {
RelinkBeam(); RelinkBeam();
if (ptr->flFraction != 1.0f && ptr->pHit != NULL) if (ptr->flFraction != 1.0f && ptr->pHit)
{ {
CBaseEntity *pHit = CBaseEntity::Instance(ptr->pHit); CBaseEntity *pHit = CBaseEntity::Instance(ptr->pHit);
if (pHit != NULL) if (pHit)
{ {
ClearMultiDamage(); ClearMultiDamage();
pHit->TraceAttack(pev, pev->dmg * (gpGlobals->time - pev->dmgtime), (ptr->vecEndPos - pev->origin).Normalize(), ptr, DMG_ENERGYBEAM); 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; pev->nextthink = gpGlobals->time + 0.1f;
TraceResult tr; TraceResult tr;
UTIL_TraceLine(GetStartPos(), GetEndPos(), dont_ignore_monsters, NULL, &tr); UTIL_TraceLine(GetStartPos(), GetEndPos(), dont_ignore_monsters, nullptr, &tr);
BeamDamage(&tr); BeamDamage(&tr);
} }
@ -778,8 +782,8 @@ void CLightning::BeamUpdateVars()
int beamType; int beamType;
int pointStart, pointEnd; int pointStart, pointEnd;
edict_t *pStart = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszStartEntity)); edict_t *pStart = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(m_iszStartEntity));
edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszEndEntity)); edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(m_iszEndEntity));
pointStart = IsPointEntity(CBaseEntity::Instance(pStart)); pointStart = IsPointEntity(CBaseEntity::Instance(pStart));
pointEnd = IsPointEntity(CBaseEntity::Instance(pEnd)); pointEnd = IsPointEntity(CBaseEntity::Instance(pEnd));
@ -869,7 +873,7 @@ void CLaser::Spawn()
if (!m_pSprite && m_iszSpriteName) if (!m_pSprite && m_iszSpriteName)
m_pSprite = CSprite::SpriteCreate(STRING(m_iszSpriteName), pev->origin, TRUE); m_pSprite = CSprite::SpriteCreate(STRING(m_iszSpriteName), pev->origin, TRUE);
else else
m_pSprite = NULL; m_pSprite = nullptr;
if (m_pSprite) if (m_pSprite)
m_pSprite->SetTransparency(kRenderGlow, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, pev->renderamt, pev->renderfx); 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; pkvd->fHandled = TRUE;
} }
else else
{
CBeam::KeyValue(pkvd); CBeam::KeyValue(pkvd);
}
} }
int CLaser::IsOn() int CLaser::IsOn()
@ -1000,7 +1006,7 @@ void CLaser::StrikeThink()
m_firePosition = pEnd->pev->origin; m_firePosition = pEnd->pev->origin;
TraceResult tr; 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); FireAtPoint(tr);
pev->nextthink = gpGlobals->time + 0.1f; 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 *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); pSprite->SpriteInit(pSpriteName, origin);
MAKE_STRING_CLASS("env_sprite", pSprite->pev); MAKE_STRING_CLASS("env_sprite", pSprite->pev);
@ -1310,7 +1316,9 @@ void CGibShooter::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CBaseDelay::KeyValue(pkvd); CBaseDelay::KeyValue(pkvd);
}
} }
void CGibShooter::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) void CGibShooter::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
@ -1343,9 +1351,9 @@ void CGibShooter::Spawn()
CGib *CGibShooter::CreateGib() CGib *CGibShooter::CreateGib()
{ {
if (CVAR_GET_FLOAT("violence_hgibs") == 0) 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->Spawn("models/hgibs.mdl");
pGib->m_bloodColor = BLOOD_COLOR_RED; pGib->m_bloodColor = BLOOD_COLOR_RED;
@ -1463,7 +1471,9 @@ void CEnvShooter::KeyValue(KeyValueData *pkvd)
} }
} }
else else
{
CGibShooter::KeyValue(pkvd); CGibShooter::KeyValue(pkvd);
}
} }
void CEnvShooter::Precache() void CEnvShooter::Precache()
@ -1474,7 +1484,7 @@ void CEnvShooter::Precache()
CGib *CEnvShooter::CreateGib() CGib *CEnvShooter::CreateGib()
{ {
CGib *pGib = GetClassPtr<CCSGib>((CGib *)NULL); CGib *pGib = GetClassPtr<CCSGib>((CGib *)nullptr);
pGib->Spawn(STRING(pev->model)); pGib->Spawn(STRING(pev->model));
@ -1606,7 +1616,9 @@ void CBlood::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CPointEntity::KeyValue(pkvd); CPointEntity::KeyValue(pkvd);
}
} }
Vector CBlood::Direction() Vector CBlood::Direction()
@ -1628,7 +1640,7 @@ Vector CBlood::BloodPosition(CBaseEntity *pActivator)
else else
pPlayer = INDEXENT(1); 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)); 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); Vector start = BloodPosition(pActivator);
TraceResult tr; 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) if (tr.flFraction != 1.0f)
{ {
@ -1695,7 +1707,9 @@ void CShake::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CPointEntity::KeyValue(pkvd); CPointEntity::KeyValue(pkvd);
}
} }
void CShake::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) void CShake::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
@ -1726,7 +1740,9 @@ void CFade::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CPointEntity::KeyValue(pkvd); CPointEntity::KeyValue(pkvd);
}
} }
void CFade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) void CFade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
@ -1813,12 +1829,14 @@ void CMessage::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CPointEntity::KeyValue(pkvd); CPointEntity::KeyValue(pkvd);
}
} }
void CMessage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) void CMessage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{ {
CBaseEntity *pPlayer = NULL; CBaseEntity *pPlayer = nullptr;
if (pev->spawnflags & SF_MESSAGE_ALL) if (pev->spawnflags & SF_MESSAGE_ALL)
UTIL_ShowMessageAll(STRING(pev->message)); UTIL_ShowMessageAll(STRING(pev->message));
@ -1831,7 +1849,7 @@ void CMessage::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
pPlayer = CBaseEntity::Instance(INDEXENT(1)); pPlayer = CBaseEntity::Instance(INDEXENT(1));
} }
if (pPlayer != NULL) if (pPlayer)
UTIL_ShowMessage(STRING(pev->message), pPlayer); UTIL_ShowMessage(STRING(pev->message), pPlayer);
} }

View File

@ -26,47 +26,11 @@
* *
*/ */
#ifndef EFFECTS_H
#define EFFECTS_H
#ifdef _WIN32
#pragma once #pragma once
#endif
#define SF_BEAM_STARTON 0x0001 #define SF_SPRITE_STARTON BIT(0)
#define SF_BEAM_TOGGLE 0x0002 #define SF_SPRITE_ONCE BIT(1)
#define SF_BEAM_RANDOM 0x0004 #define SF_SPRITE_TEMPORARY BIT(15)
#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
class CSprite: public CPointEntity class CSprite: public CPointEntity
{ {
@ -96,7 +60,7 @@ public:
void SetAttachment(edict_t *pEntity, int attachment) void SetAttachment(edict_t *pEntity, int attachment)
{ {
if (pEntity != NULL) if (pEntity)
{ {
pev->skin = ENTINDEX(pEntity); pev->skin = ENTINDEX(pEntity);
pev->body = attachment; pev->body = attachment;
@ -142,6 +106,17 @@ private:
float m_maxFrame; 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 class CBeam: public CBaseEntity
{ {
public: public:
@ -243,6 +218,8 @@ public:
Vector m_firePosition; Vector m_firePosition;
}; };
#define SF_BUBBLES_STARTOFF BIT(0)
class CBubbling: public CBaseEntity class CBubbling: public CBaseEntity
{ {
public: public:
@ -341,6 +318,8 @@ public:
bool m_bSetModel; bool m_bSetModel;
}; };
#define SF_GIBSHOOTER_REPEATABLE BIT(0) // Allows a gibshooter to be refired
class CGibShooter: public CBaseDelay class CGibShooter: public CBaseDelay
{ {
public: public:
@ -376,7 +355,7 @@ public:
virtual CGib *CreateGib(); virtual CGib *CreateGib();
}; };
#define MAX_BEAM 24 const int MAX_BEAM = 24;
class CTestEffect: public CBaseDelay class CTestEffect: public CBaseDelay
{ {
@ -392,12 +371,17 @@ public:
int m_iLoop; int m_iLoop;
int m_iBeam; 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; 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 class CBlood: public CPointEntity
{ {
public: public:
@ -417,6 +401,10 @@ public:
Vector BloodPosition(CBaseEntity *pActivator); 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 class CShake: public CPointEntity
{ {
public: public:
@ -436,6 +424,10 @@ public:
void SetRadius(float radius) { pev->dmg = radius; } 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 class CFade: public CPointEntity
{ {
public: public:
@ -451,6 +443,9 @@ public:
void SetHoldTime(float hold) { pev->dmg_save = hold; } 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 class CMessage: public CPointEntity
{ {
public: public:
@ -460,6 +455,8 @@ public:
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); 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 class CEnvFunnel: public CBaseDelay
{ {
public: public:
@ -491,5 +488,3 @@ public:
}; };
int IsPointEntity(CBaseEntity *pEnt); 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 #pragma once
#endif
#include "event_flags.h" #include "event_flags.h"
// Must be provided by user of this code
extern enginefuncs_t g_engfuncs; extern enginefuncs_t g_engfuncs;
#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId) // The actual engine callbacks
#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel) #define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId)
#define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound) #define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel)
#define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric) #define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound)
#define SET_MODEL (*g_engfuncs.pfnSetModel) #define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric)
#define MODEL_INDEX (*g_engfuncs.pfnModelIndex) #define SET_MODEL (*g_engfuncs.pfnSetModel)
#define MODEL_FRAMES (*g_engfuncs.pfnModelFrames) #define MODEL_INDEX (*g_engfuncs.pfnModelIndex)
#define SET_SIZE (*g_engfuncs.pfnSetSize) #define MODEL_FRAMES (*g_engfuncs.pfnModelFrames)
#define CHANGE_LEVEL (*g_engfuncs.pfnChangeLevel) #define SET_SIZE (*g_engfuncs.pfnSetSize)
#define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms) #define CHANGE_LEVEL (*g_engfuncs.pfnChangeLevel)
#define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms) #define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms)
#define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw) #define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms)
#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles) #define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw)
#define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin) #define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles)
#define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw) #define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin)
#define CHANGE_PITCH (*g_engfuncs.pfnChangePitch) #define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw)
#define MAKE_VECTORS (*g_engfuncs.pfnMakeVectors) #define CHANGE_PITCH (*g_engfuncs.pfnChangePitch)
#define CREATE_ENTITY (*g_engfuncs.pfnCreateEntity) #define MAKE_VECTORS (*g_engfuncs.pfnMakeVectors)
#define REMOVE_ENTITY (*g_engfuncs.pfnRemoveEntity) #define CREATE_ENTITY (*g_engfuncs.pfnCreateEntity)
#define CREATE_NAMED_ENTITY (*g_engfuncs.pfnCreateNamedEntity) #define REMOVE_ENTITY (*g_engfuncs.pfnRemoveEntity)
#define MAKE_STATIC (*g_engfuncs.pfnMakeStatic) #define CREATE_NAMED_ENTITY (*g_engfuncs.pfnCreateNamedEntity)
#define ENT_IS_ON_FLOOR (*g_engfuncs.pfnEntIsOnFloor) #define MAKE_STATIC (*g_engfuncs.pfnMakeStatic)
#define DROP_TO_FLOOR (*g_engfuncs.pfnDropToFloor) #define ENT_IS_ON_FLOOR (*g_engfuncs.pfnEntIsOnFloor)
#define WALK_MOVE (*g_engfuncs.pfnWalkMove) #define DROP_TO_FLOOR (*g_engfuncs.pfnDropToFloor)
#define SET_ORIGIN (*g_engfuncs.pfnSetOrigin) #define WALK_MOVE (*g_engfuncs.pfnWalkMove)
#define EMIT_SOUND_DYN2 (*g_engfuncs.pfnEmitSound) #define SET_ORIGIN (*g_engfuncs.pfnSetOrigin)
#define BUILD_SOUND_MSG (*g_engfuncs.pfnBuildSoundMsg) #define EMIT_SOUND_DYN2 (*g_engfuncs.pfnEmitSound)
#define TRACE_LINE (*g_engfuncs.pfnTraceLine) #define BUILD_SOUND_MSG (*g_engfuncs.pfnBuildSoundMsg)
#define TRACE_TOSS (*g_engfuncs.pfnTraceToss) #define TRACE_LINE (*g_engfuncs.pfnTraceLine)
#define TRACE_MONSTER_HULL (*g_engfuncs.pfnTraceMonsterHull) #define TRACE_TOSS (*g_engfuncs.pfnTraceToss)
#define TRACE_HULL (*g_engfuncs.pfnTraceHull) #define TRACE_MONSTER_HULL (*g_engfuncs.pfnTraceMonsterHull)
#define TRACE_MODEL (*g_engfuncs.pfnTraceModel) #define TRACE_HULL (*g_engfuncs.pfnTraceHull)
#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector) #define TRACE_MODEL (*g_engfuncs.pfnTraceModel)
#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand) #define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector)
#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute) #define SERVER_COMMAND (*g_engfuncs.pfnServerCommand)
#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand) #define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute)
#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect) #define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand)
#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle) #define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect)
#define DECAL_INDEX (*g_engfuncs.pfnDecalIndex) #define LIGHT_STYLE (*g_engfuncs.pfnLightStyle)
#define POINT_CONTENTS (*g_engfuncs.pfnPointContents) #define DECAL_INDEX (*g_engfuncs.pfnDecalIndex)
#define CRC32_INIT (*g_engfuncs.pfnCRC32_Init) #define POINT_CONTENTS (*g_engfuncs.pfnPointContents)
#define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC32_ProcessBuffer) #define CRC32_INIT (*g_engfuncs.pfnCRC32_Init)
#define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC32_ProcessByte) #define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC32_ProcessBuffer)
#define CRC32_FINAL (*g_engfuncs.pfnCRC32_Final) #define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC32_ProcessByte)
#define RANDOM_LONG (*g_engfuncs.pfnRandomLong) #define CRC32_FINAL (*g_engfuncs.pfnCRC32_Final)
#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) #define RANDOM_LONG (*g_engfuncs.pfnRandomLong)
#define ADD_SERVER_COMMAND (*g_engfuncs.pfnAddServerCommand) #define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat)
#define SET_CLIENT_LISTENING (*g_engfuncs.pfnVoice_SetClientListening) #define ADD_SERVER_COMMAND (*g_engfuncs.pfnAddServerCommand)
#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) #define SET_CLIENT_LISTENING (*g_engfuncs.pfnVoice_SetClientListening)
#define GET_FILE_SIZE (*g_engfuncs.pfnGetFileSize) #define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId)
#define GET_APPROX_WAVE_PLAY_LEN (*g_engfuncs.pfnGetApproxWavePlayLen) #define GET_FILE_SIZE (*g_engfuncs.pfnGetFileSize)
#define IS_CAREER_MATCH (*g_engfuncs.pfnIsCareerMatch) #define GET_APPROX_WAVE_PLAY_LEN (*g_engfuncs.pfnGetApproxWavePlayLen)
#define GET_LOCALIZED_STRING_LENGTH (*g_engfuncs.pfnGetLocalizedStringLength) #define IS_CAREER_MATCH (*g_engfuncs.pfnIsCareerMatch)
#define GET_LOCALIZED_STRING_LENGTH (*g_engfuncs.pfnGetLocalizedStringLength)
#define REGISTER_TUTOR_MESSAGE_SHOWN (*g_engfuncs.pfnRegisterTutorMessageShown) #define REGISTER_TUTOR_MESSAGE_SHOWN (*g_engfuncs.pfnRegisterTutorMessageShown)
#define GET_TIMES_TUTOR_MESSAGE_SHOWN (*g_engfuncs.pfnGetTimesTutorMessageShown) #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) if (pEdict)
return pent->pvPrivateData; {
return NULL; return static_cast<T *>(pEdict->pvPrivateData);
}
return nullptr;
} }
#define MESSAGE_END (*g_engfuncs.pfnMessageEnd) #define MESSAGE_END (*g_engfuncs.pfnMessageEnd)
#define WRITE_BYTE (*g_engfuncs.pfnWriteByte) #define WRITE_BYTE (*g_engfuncs.pfnWriteByte)
#define WRITE_CHAR (*g_engfuncs.pfnWriteChar) #define WRITE_CHAR (*g_engfuncs.pfnWriteChar)
#define WRITE_SHORT (*g_engfuncs.pfnWriteShort) #define WRITE_SHORT (*g_engfuncs.pfnWriteShort)
#define WRITE_LONG (*g_engfuncs.pfnWriteLong) #define WRITE_LONG (*g_engfuncs.pfnWriteLong)
#define WRITE_ANGLE (*g_engfuncs.pfnWriteAngle) #define WRITE_ANGLE (*g_engfuncs.pfnWriteAngle)
#define WRITE_COORD (*g_engfuncs.pfnWriteCoord) #define WRITE_COORD (*g_engfuncs.pfnWriteCoord)
#define WRITE_STRING (*g_engfuncs.pfnWriteString) #define WRITE_STRING (*g_engfuncs.pfnWriteString)
#define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity) #define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity)
#define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister) #define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister)
#define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat) #define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat)
#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString) #define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString)
#define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat) #define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat)
#define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString) #define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString)
#define CVAR_GET_POINTER (*g_engfuncs.pfnCVarGetPointer) #define CVAR_GET_POINTER (*g_engfuncs.pfnCVarGetPointer)
#define ALERT (*g_engfuncs.pfnAlertMessage) #define ALERT (*g_engfuncs.pfnAlertMessage)
#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf) #define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf)
#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData) #define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData)
#define FREE_PRIVATE (*g_engfuncs.pfnFreeEntPrivateData) #define FREE_PRIVATE (*g_engfuncs.pfnFreeEntPrivateData)
//#define STRING (*g_engfuncs.pfnSzFromIndex) //#define STRING (*g_engfuncs.pfnSzFromIndex)
#define ALLOC_STRING (*g_engfuncs.pfnAllocString) #define ALLOC_STRING (*g_engfuncs.pfnAllocString)
#define FIND_ENTITY_BY_STRING (*g_engfuncs.pfnFindEntityByString) #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_ENTITY_IN_SPHERE (*g_engfuncs.pfnFindEntityInSphere)
#define FIND_CLIENT_IN_PVS (*g_engfuncs.pfnFindClientInPVS) #define FIND_CLIENT_IN_PVS (*g_engfuncs.pfnFindClientInPVS)
#define FIND_ENTITY_IN_PVS (*g_engfuncs.pfnEntitiesInPVS) #define FIND_ENTITY_IN_PVS (*g_engfuncs.pfnEntitiesInPVS)
#define EMIT_AMBIENT_SOUND (*g_engfuncs.pfnEmitAmbientSound) #define EMIT_AMBIENT_SOUND (*g_engfuncs.pfnEmitAmbientSound)
#define GET_MODEL_PTR (*g_engfuncs.pfnGetModelPtr) #define GET_MODEL_PTR (*g_engfuncs.pfnGetModelPtr)
#define REG_USER_MSG (*g_engfuncs.pfnRegUserMsg) #define REG_USER_MSG (*g_engfuncs.pfnRegUserMsg)
#define GET_BONE_POSITION (*g_engfuncs.pfnGetBonePosition) #define GET_BONE_POSITION (*g_engfuncs.pfnGetBonePosition)
#define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName) #define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName)
#define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction) #define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction)
#define TRACE_TEXTURE (*g_engfuncs.pfnTraceTexture) #define TRACE_TEXTURE (*g_engfuncs.pfnTraceTexture)
#define CLIENT_PRINTF (*g_engfuncs.pfnClientPrintf) #define CLIENT_PRINTF (*g_engfuncs.pfnClientPrintf)
#define SERVER_PRINT (*g_engfuncs.pfnServerPrint) #define SERVER_PRINT (*g_engfuncs.pfnServerPrint)
#define CMD_ARGS (*g_engfuncs.pfnCmd_Args) #define CMD_ARGS (*g_engfuncs.pfnCmd_Args)
#define CMD_ARGC (*g_engfuncs.pfnCmd_Argc) #define CMD_ARGC (*g_engfuncs.pfnCmd_Argc)
#define CMD_ARGV (*g_engfuncs.pfnCmd_Argv) #define CMD_ARGV (*g_engfuncs.pfnCmd_Argv)
#define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment) #define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment)
#define SET_VIEW (*g_engfuncs.pfnSetView) #define SET_VIEW (*g_engfuncs.pfnSetView)
#define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle) #define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle)
#define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFileForMe) #define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFileForMe)
#define FREE_FILE (*g_engfuncs.pfnFreeFile) #define FREE_FILE (*g_engfuncs.pfnFreeFile)
#define END_SECTION (*g_engfuncs.pfnEndSection) #define END_SECTION (*g_engfuncs.pfnEndSection)
#define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime) #define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime)
#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir) #define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir)
#define SET_CLIENT_MAXSPEED (*g_engfuncs.pfnSetClientMaxspeed) #define SET_CLIENT_MAXSPEED (*g_engfuncs.pfnSetClientMaxspeed)
#define CREATE_FAKE_CLIENT (*g_engfuncs.pfnCreateFakeClient) #define CREATE_FAKE_CLIENT (*g_engfuncs.pfnCreateFakeClient)
#define PLAYER_RUN_MOVE (*g_engfuncs.pfnRunPlayerMove) #define PLAYER_RUN_MOVE (*g_engfuncs.pfnRunPlayerMove)
#define NUMBER_OF_ENTITIES (*g_engfuncs.pfnNumberOfEntities) #define NUMBER_OF_ENTITIES (*g_engfuncs.pfnNumberOfEntities)
#define GET_INFO_BUFFER (*g_engfuncs.pfnGetInfoKeyBuffer) #define GET_INFO_BUFFER (*g_engfuncs.pfnGetInfoKeyBuffer)
#define GET_KEY_VALUE (*g_engfuncs.pfnInfoKeyValue) #define GET_KEY_VALUE (*g_engfuncs.pfnInfoKeyValue)
#define SET_KEY_VALUE (*g_engfuncs.pfnSetKeyValue) #define SET_KEY_VALUE (*g_engfuncs.pfnSetKeyValue)
#define SET_CLIENT_KEY_VALUE (*g_engfuncs.pfnSetClientKeyValue) #define SET_CLIENT_KEY_VALUE (*g_engfuncs.pfnSetClientKeyValue)
#define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid) #define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid)
#define STATIC_DECAL (*g_engfuncs.pfnStaticDecal) #define STATIC_DECAL (*g_engfuncs.pfnStaticDecal)
#define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer) #define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer)
#define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent) #define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent)
#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent) #define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent)
#define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS) #define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS)
#define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS) #define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS)
#define ENGINE_CHECK_VISIBILITY (*g_engfuncs.pfnCheckVisibility) #define ENGINE_CHECK_VISIBILITY (*g_engfuncs.pfnCheckVisibility)
#define DELTA_SET (*g_engfuncs.pfnDeltaSetField) #define DELTA_SET (*g_engfuncs.pfnDeltaSetField)
#define DELTA_UNSET (*g_engfuncs.pfnDeltaUnsetField) #define DELTA_UNSET (*g_engfuncs.pfnDeltaUnsetField)
#define DELTA_ADDENCODER (*g_engfuncs.pfnDeltaAddEncoder) #define DELTA_ADDENCODER (*g_engfuncs.pfnDeltaAddEncoder)
#define ENGINE_CURRENT_PLAYER (*g_engfuncs.pfnGetCurrentPlayer) #define ENGINE_CURRENT_PLAYER (*g_engfuncs.pfnGetCurrentPlayer)
#define ENGINE_CANSKIP (*g_engfuncs.pfnCanSkipPlayer) #define ENGINE_CANSKIP (*g_engfuncs.pfnCanSkipPlayer)
#define DELTA_FINDFIELD (*g_engfuncs.pfnDeltaFindField) #define DELTA_FINDFIELD (*g_engfuncs.pfnDeltaFindField)
#define DELTA_SETBYINDEX (*g_engfuncs.pfnDeltaSetFieldByIndex) #define DELTA_SETBYINDEX (*g_engfuncs.pfnDeltaSetFieldByIndex)
#define DELTA_UNSETBYINDEX (*g_engfuncs.pfnDeltaUnsetFieldByIndex) #define DELTA_UNSETBYINDEX (*g_engfuncs.pfnDeltaUnsetFieldByIndex)
#define REMOVE_KEY_VALUE (*g_engfuncs.pfnInfo_RemoveKey) #define REMOVE_KEY_VALUE (*g_engfuncs.pfnInfo_RemoveKey)
#define SET_PHYSICS_KEY_VALUE (*g_engfuncs.pfnSetPhysicsKeyValue) #define SET_PHYSICS_KEY_VALUE (*g_engfuncs.pfnSetPhysicsKeyValue)
#define ENGINE_GETPHYSINFO (*g_engfuncs.pfnGetPhysicsInfoString) #define ENGINE_GETPHYSINFO (*g_engfuncs.pfnGetPhysicsInfoString)
#define ENGINE_SETGROUPMASK (*g_engfuncs.pfnSetGroupMask) #define ENGINE_SETGROUPMASK (*g_engfuncs.pfnSetGroupMask)
#define ENGINE_INSTANCE_BASELINE (*g_engfuncs.pfnCreateInstancedBaseline) #define ENGINE_INSTANCE_BASELINE (*g_engfuncs.pfnCreateInstancedBaseline)
#define ENGINE_FORCE_UNMODIFIED (*g_engfuncs.pfnForceUnmodified) #define ENGINE_FORCE_UNMODIFIED (*g_engfuncs.pfnForceUnmodified)
#define PLAYER_CNX_STATS (*g_engfuncs.pfnGetPlayerStats) #define PLAYER_CNX_STATS (*g_engfuncs.pfnGetPlayerStats)
#endif // ENGINECALLBACK_H

View File

@ -78,7 +78,9 @@ void CEnvExplosion::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CBaseEntity::KeyValue(pkvd); CBaseEntity::KeyValue(pkvd);
}
} }
void CEnvExplosion::Spawn() void CEnvExplosion::Spawn()
@ -173,7 +175,7 @@ void CEnvExplosion::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
for (int i = 0; i < sparkCount; ++i) 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->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 #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 class CShower: public CBaseEntity
{ {
@ -48,6 +37,13 @@ public:
virtual void Touch(CBaseEntity *pOther); 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 class CEnvExplosion: public CBaseMonster
{ {
public: public:
@ -68,5 +64,3 @@ public:
}; };
void ExplosionCreate(const Vector &center, Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage); void ExplosionCreate(const Vector &center, Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage);
#endif // EXPLODE_H

View File

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

View File

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

View File

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

View File

@ -26,32 +26,15 @@
* *
*/ */
#ifndef FUNC_BREAK_H
#define FUNC_BREAK_H
#ifdef _WIN32
#pragma once #pragma once
#endif
// this many shards spawned when breakable objects break; enum Explosions
#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
{ {
expRandom = 0, expRandom = 0,
expDirected, expDirected,
};
} Explosions; enum Materials
typedef enum
{ {
matGlass = 0, matGlass = 0,
matWood, matWood,
@ -64,8 +47,16 @@ typedef enum
matRocks, matRocks,
matNone, matNone,
matLastMaterial, 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 class CBreakable: public CBaseDelay
{ {
@ -125,6 +116,8 @@ public:
float m_flHealth; 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 class CPushable: public CBreakable
{ {
public: public:
@ -163,5 +156,3 @@ public:
float m_maxSpeed; float m_maxSpeed;
float m_soundTime; float m_soundTime;
}; };
#endif // FUNC_BREAK_H

View File

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

View File

@ -26,28 +26,25 @@
* *
*/ */
#ifndef FUNC_TANK_H
#define FUNC_TANK_H
#ifdef _WIN32
#pragma once #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 enum TANKBULLET
{ {
TANK_BULLET_NONE = 0, // Custom damage TANK_BULLET_NONE = 0, // Custom damage
TANK_BULLET_9MM, // env_laser (duration is 0.5 rate of fire) TANK_BULLET_9MM, // env_laser (duration is 0.5 rate of fire)
TANK_BULLET_MP5, // rockets TANK_BULLET_MP5, // rockets
TANK_BULLET_12MM, // explosion? 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 class CFuncTank: public CBaseEntity
{ {
public: public:
@ -114,30 +111,30 @@ protected:
float m_yawCenter; // "Center" yaw float m_yawCenter; // "Center" yaw
float m_yawRate; // Max turn rate to track targets float m_yawRate; // Max turn rate to track targets
float m_yawRange; // Range of turning motion (one-sided: 30 is +/- 30 degress from center) 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_pitchRate; // Max turn rate on pitch
float m_pitchRange; // Range of pitch motion as above 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_fireLast; // Last time I fired
float m_fireRate; // How many rounds/second 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_persist; // Persistence of firing (how long do I shoot when I can't see)
float m_minRange; // Minimum range to aim/track float m_minRange; // Minimum range to aim/track
float m_maxRange; // Max range to aim/track float m_maxRange; // Max range to aim/track
Vector m_barrelPos; // Length of the freakin barrel 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_iszSpriteSmoke;
int m_iszSpriteFlash; int m_iszSpriteFlash;
TANKBULLET m_bulletType; // Bullet type TANKBULLET m_bulletType;// Bullet type
int m_iBulletDamage; // 0 means use Bullet type's default damage 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_spread; // firing spread
int m_iszMaster; // Master entity (game_team_master or multisource) int m_iszMaster; // Master entity (game_team_master or multisource)
}; };
@ -196,5 +193,3 @@ public:
static TYPEDESCRIPTION IMPL(m_SaveData)[1]; static TYPEDESCRIPTION IMPL(m_SaveData)[1];
CFuncTank *m_pTank; 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 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 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 cvar_t showtriggers = { "showtriggers", "0", 0, 0.0f, nullptr }; // debug cvar shows triggers
// TODO: Maybe it's better to register in the engine? // TODO: Maybe it's better to register in the engine?
cvar_t hostagehurtable = { "mp_hostage_hurtable", "1", FCVAR_SERVER, 0.0f, nullptr }; cvar_t hostagehurtable = { "mp_hostage_hurtable", "1", FCVAR_SERVER, 0.0f, nullptr };
cvar_t roundover = { "mp_roundover", "0", 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 #pragma once
#endif
#define LOG_ENEMYATTACK 1 #define LOG_ENEMYATTACK 1
#define LOG_TEAMMATEATTACK 2 #define LOG_TEAMMATEATTACK 2
// playerid // playerid
#define PLAYERID_MODE_EVERYONE 0 #define PLAYERID_MODE_EVERYONE 0
#define PLAYERID_MODE_TEAMONLY 1 #define PLAYERID_MODE_TEAMONLY 1
#define PLAYERID_MODE_OFF 2 #define PLAYERID_MODE_OFF 2
#define PLAYERID_EVERYONE 0 #define PLAYERID_EVERYONE 0
#define PLAYERID_TEAMONLY 1 #define PLAYERID_TEAMONLY 1
#define PLAYERID_OFF 2 #define PLAYERID_OFF 2
extern cvar_t *g_psv_gravity; extern cvar_t *g_psv_gravity;
extern cvar_t *g_psv_aim; extern cvar_t *g_psv_aim;
@ -155,5 +151,3 @@ extern cvar_t show_radioicon;
#endif #endif
void GameDLLInit(); void GameDLLInit();
#endif // GAME_H

View File

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

View File

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

View File

@ -41,7 +41,7 @@ void CGrenade::Explode(TraceResult *pTrace, int bitsDamageType)
float flRndSound; // sound randomizer float flRndSound; // sound randomizer
pev->model = iStringNull; // invisible pev->model = iStringNull; // invisible
pev->solid = SOLID_NOT; // intangible pev->solid = SOLID_NOT; // intangible
pev->takedamage = DAMAGE_NO; pev->takedamage = DAMAGE_NO;
// Pull out of the wall a bit // 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 // can't traceline attack owner if this is set
pev->owner = NULL; pev->owner = nullptr;
RadiusFlash(pev->origin, pev, pevOwner, 4, CLASS_NONE, bitsDamageType); RadiusFlash(pev->origin, pev, pevOwner, 4, CLASS_NONE, bitsDamageType);
@ -89,9 +89,10 @@ void CGrenade::Explode(TraceResult *pTrace, int bitsDamageType)
if (iContents != CONTENTS_WATER) if (iContents != CONTENTS_WATER)
{ {
int sparkCount = RANDOM_LONG(0, 3); int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; i++)
for (int i = 0; i < sparkCount; ++i) {
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL); Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, nullptr);
}
} }
} }
@ -100,7 +101,7 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
float flRndSound; // sound randomizer float flRndSound; // sound randomizer
pev->model = iStringNull; // invisible pev->model = iStringNull; // invisible
pev->solid = SOLID_NOT; // intangible pev->solid = SOLID_NOT; // intangible
pev->takedamage = DAMAGE_NO; pev->takedamage = DAMAGE_NO;
UTIL_ScreenShake(pTrace->vecEndPos, 25, 150, 1, 3000); UTIL_ScreenShake(pTrace->vecEndPos, 25, 150, 1, 3000);
@ -174,7 +175,7 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
#endif #endif
entvars_t *pevOwner = VARS(pev->owner); entvars_t *pevOwner = VARS(pev->owner);
pev->owner = NULL; pev->owner = nullptr;
RadiusDamage(pev, pevOwner, CSGameRules()->m_flBombRadius, CLASS_NONE, bitsDamageType); RadiusDamage(pev, pevOwner, CSGameRules()->m_flBombRadius, CLASS_NONE, bitsDamageType);
if (CSGameRules()->IsCareer()) if (CSGameRules()->IsCareer())
@ -219,19 +220,19 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
if (iContents != CONTENTS_WATER) if (iContents != CONTENTS_WATER)
{ {
int sparkCount = RANDOM_LONG(0, 3); int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; i++)
for (int i = 0; i < sparkCount; ++i) {
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL); Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, nullptr);
}
} }
} }
void CGrenade::Explode3(TraceResult *pTrace, int bitsDamageType) void CGrenade::Explode3(TraceResult *pTrace, int bitsDamageType)
{ {
float flRndSound; // sound randomizer float flRndSound; // sound randomizer
//float damage;
pev->model = iStringNull; // invisible pev->model = iStringNull; // invisible
pev->solid = SOLID_NOT; // intangible pev->solid = SOLID_NOT; // intangible
pev->takedamage = DAMAGE_NO; pev->takedamage = DAMAGE_NO;
if (pTrace->flFraction != 1.0f) 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)); TheBots->OnEvent(EVENT_HE_GRENADE_EXPLODED, CBaseEntity::Instance(pev->owner));
} }
pev->owner = NULL; pev->owner = nullptr;
RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType); RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType);
if (RANDOM_FLOAT(0, 1) < 0.5f) if (RANDOM_FLOAT(0, 1) < 0.5f)
@ -293,19 +294,20 @@ void CGrenade::Explode3(TraceResult *pTrace, int bitsDamageType)
SetThink(&CGrenade::Smoke3_C); SetThink(&CGrenade::Smoke3_C);
pev->velocity = g_vecZero; pev->velocity = g_vecZero;
pev->nextthink = gpGlobals->time + 0.55f; pev->nextthink = gpGlobals->time + 0.55f;
int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; ++i) int sparkCount = RANDOM_LONG(0, 3);
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL); for (int i = 0; i < sparkCount; i++)
{
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, nullptr);
}
} }
NOXREF void CGrenade::SG_Explode(TraceResult *pTrace, int bitsDamageType) NOXREF void CGrenade::SG_Explode(TraceResult *pTrace, int bitsDamageType)
{ {
float flRndSound; // sound randomizer float flRndSound; // sound randomizer
//entvars_t *pevOwner;
pev->model = iStringNull; // invisible pev->model = iStringNull; // invisible
pev->solid = SOLID_NOT; // intangible pev->solid = SOLID_NOT; // intangible
pev->takedamage = DAMAGE_NO; pev->takedamage = DAMAGE_NO;
@ -321,7 +323,7 @@ NOXREF void CGrenade::SG_Explode(TraceResult *pTrace, int bitsDamageType)
#endif #endif
// can't traceline attack owner if this is set // can't traceline attack owner if this is set
pev->owner = NULL; pev->owner = nullptr;
if (RANDOM_FLOAT(0, 1) < 0.5f) if (RANDOM_FLOAT(0, 1) < 0.5f)
UTIL_DecalTrace(pTrace, DECAL_SCORCH1); UTIL_DecalTrace(pTrace, DECAL_SCORCH1);
@ -346,8 +348,10 @@ NOXREF void CGrenade::SG_Explode(TraceResult *pTrace, int bitsDamageType)
{ {
int sparkCount = RANDOM_LONG(0, 3); int sparkCount = RANDOM_LONG(0, 3);
for (int i = 0; i < sparkCount; ++i) for (int i = 0; i < sparkCount; i++)
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL); {
Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, nullptr);
}
} }
} }
@ -453,7 +457,7 @@ void CGrenade::Smoke()
WRITE_COORD(pev->origin.z); WRITE_COORD(pev->origin.z);
WRITE_SHORT(g_sModelIndexSmoke); WRITE_SHORT(g_sModelIndexSmoke);
WRITE_BYTE(25); // scale * 10 WRITE_BYTE(25); // scale * 10
WRITE_BYTE(6); // framerate WRITE_BYTE(6); // framerate
MESSAGE_END(); MESSAGE_END();
} }
@ -490,14 +494,14 @@ void CGrenade::SG_Smoke()
m_angle = (m_angle + 30) % 360; 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) if (m_SGSmoke <= 20)
{ {
pev->nextthink = gpGlobals->time + 1.0f; pev->nextthink = gpGlobals->time + 1.0f;
SetThink(&CGrenade::SG_Smoke); SetThink(&CGrenade::SG_Smoke);
++m_SGSmoke; m_SGSmoke++;
} }
else else
{ {
@ -547,7 +551,7 @@ void CGrenade::SG_Detonate()
{ {
TraceResult tr; TraceResult tr;
Vector vecSpot; Vector vecSpot;
edict_t *pentFind = NULL; edict_t *pentFind = nullptr;
vecSpot = pev->origin + Vector(0, 0, 8); vecSpot = pev->origin + Vector(0, 0, 8);
@ -570,7 +574,6 @@ void CGrenade::SG_Detonate()
if (pEnt) if (pEnt)
{ {
float fDistance = (pEnt->pev->origin - pev->origin).Length(); float fDistance = (pEnt->pev->origin - pev->origin).Length();
if (fDistance != 0.0f && fDistance <= 250.0f) if (fDistance != 0.0f && fDistance <= 250.0f)
{ {
if (gpGlobals->time > pEnt->pev->dmgtime) if (gpGlobals->time > pEnt->pev->dmgtime)
@ -582,7 +585,7 @@ void CGrenade::SG_Detonate()
} }
m_bDetonated = true; 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; m_vSmokeDetonate = pev->origin;
pev->velocity.x = RANDOM_FLOAT(-175, 175); pev->velocity.x = RANDOM_FLOAT(-175, 175);
@ -681,7 +684,7 @@ void CGrenade::BounceTouch(CBaseEntity *pOther)
{ {
// add a bit of static friction // add a bit of static friction
pev->velocity = pev->velocity * 0.8f; pev->velocity = pev->velocity * 0.8f;
pev->sequence = RANDOM_LONG(1, 1); // TODO: what? pev->sequence = RANDOM_LONG(1, 1); // TODO: what?
} }
else else
{ {
@ -698,7 +701,7 @@ void CGrenade::BounceTouch(CBaseEntity *pOther)
pev->velocity = g_vecZero; pev->velocity = g_vecZero;
} }
++m_iBounceCount; m_iBounceCount++;
} }
pev->framerate = pev->velocity.Length() / 200.0f; pev->framerate = pev->velocity.Length() / 200.0f;
@ -771,7 +774,9 @@ void CGrenade::TumbleThink()
SetThink(&CGrenade::Detonate); SetThink(&CGrenade::Detonate);
} }
else else
{
SetThink(&CGrenade::Detonate3); SetThink(&CGrenade::Detonate3);
}
} }
if (pev->waterlevel != 0) if (pev->waterlevel != 0)
@ -838,11 +843,11 @@ void CGrenade::Spawn()
NOXREF CGrenade *CGrenade::ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity) 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(); pGrenade->Spawn();
// contact grenades arc lower // 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); UTIL_SetOrigin(pGrenade->pev, vecStart);
pGrenade->pev->velocity = vecVelocity; 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 *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(); pGrenade->Spawn();
UTIL_SetOrigin(pGrenade->pev, vecStart); 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 *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(); pGrenade->Spawn();
UTIL_SetOrigin(pGrenade->pev, vecStart); UTIL_SetOrigin(pGrenade->pev, vecStart);
@ -944,6 +949,7 @@ void CGrenade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
if (!m_bIsC4) if (!m_bIsC4)
return; return;
// TODO: We must be sure that the activator is a player.
CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pActivator->pev); CBasePlayer *player = GetClassPtr<CCSPlayer>((CBasePlayer *)pActivator->pev);
// For CTs to defuse the c4 // For CTs to defuse the c4
@ -988,7 +994,7 @@ void CGrenade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
#endif #endif
player->m_bIsDefusing = true; player->m_bIsDefusing = true;
m_pBombDefuser = pActivator; m_pBombDefuser = static_cast<CBasePlayer *>(pActivator);
m_bStartDefuse = true; m_bStartDefuse = true;
m_flDefuseCountDown = gpGlobals->time + 5.0f; m_flDefuseCountDown = gpGlobals->time + 5.0f;
m_fNextDefuse = gpGlobals->time + 0.5f; m_fNextDefuse = gpGlobals->time + 0.5f;
@ -1010,7 +1016,7 @@ void CGrenade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
#endif #endif
player->m_bIsDefusing = true; player->m_bIsDefusing = true;
m_pBombDefuser = pActivator; m_pBombDefuser = static_cast<CBasePlayer *>(pActivator);
m_bStartDefuse = true; m_bStartDefuse = true;
m_flDefuseCountDown = gpGlobals->time + 10.0f; m_flDefuseCountDown = gpGlobals->time + 10.0f;
m_fNextDefuse = gpGlobals->time + 0.5f; 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 *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; pGrenade->pev->movetype = MOVETYPE_TOSS;
MAKE_STRING_CLASS("grenade", pGrenade->pev); 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_iCurWave = 0;
pGrenade->m_fAttenu = 0; pGrenade->m_fAttenu = 0;
pGrenade->m_sBeepName = NULL; pGrenade->m_sBeepName = nullptr;
pGrenade->m_flNextBeep = gpGlobals->time + 0.5f; pGrenade->m_flNextBeep = gpGlobals->time + 0.5f;
pGrenade->m_bIsC4 = true; pGrenade->m_bIsC4 = true;
pGrenade->m_fNextDefuse = 0; pGrenade->m_fNextDefuse = 0;
@ -1072,14 +1078,16 @@ CGrenade *CGrenade::ShootSatchelCharge(entvars_t *pevOwner, Vector vecStart, Vec
pGrenade->m_pentCurBombTarget = pOwner->m_pentCurBombTarget; pGrenade->m_pentCurBombTarget = pOwner->m_pentCurBombTarget;
} }
else else
pGrenade->m_pentCurBombTarget = NULL; {
pGrenade->m_pentCurBombTarget = nullptr;
}
return pGrenade; return pGrenade;
} }
CGrenade *CGrenade::ShootSmokeGrenade(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time, unsigned short usEvent) 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(); pGrenade->Spawn();
UTIL_SetOrigin(pGrenade->pev, vecStart); UTIL_SetOrigin(pGrenade->pev, vecStart);
@ -1115,7 +1123,7 @@ CGrenade *CGrenade::ShootSmokeGrenade(entvars_t *pevOwner, Vector vecStart, Vect
void AnnounceFlashInterval(float interval, float offset) void AnnounceFlashInterval(float interval, float offset)
{ {
if (!g_bIsCzeroGame) if (!AreRunningCZero())
return; return;
MESSAGE_BEGIN(MSG_ALL, gmsgScenarioIcon); MESSAGE_BEGIN(MSG_ALL, gmsgScenarioIcon);
@ -1176,7 +1184,7 @@ void CGrenade::C4Think()
break; break;
} }
++m_iCurWave; m_iCurWave++;
} }
if (gpGlobals->time >= m_flNextBeep) if (gpGlobals->time >= m_flNextBeep)
@ -1258,7 +1266,7 @@ void CGrenade::C4Think()
// if the defusing process has started // if the defusing process has started
if (m_bStartDefuse && m_pBombDefuser) if (m_bStartDefuse && m_pBombDefuser)
{ {
CBasePlayer *pPlayer = (CBasePlayer *)m_pBombDefuser; CBasePlayer *pPlayer = m_pBombDefuser;
// if the defusing process has not ended yet // if the defusing process has not ended yet
if (gpGlobals->time < m_flDefuseCountDown) if (gpGlobals->time < m_flDefuseCountDown)
@ -1279,7 +1287,7 @@ void CGrenade::C4Think()
// cancel the progress bar // cancel the progress bar
pPlayer->SetProgressBarTime(0); pPlayer->SetProgressBarTime(0);
m_pBombDefuser = NULL; m_pBombDefuser = nullptr;
m_bStartDefuse = false; m_bStartDefuse = false;
m_flDefuseCountDown = 0; m_flDefuseCountDown = 0;
@ -1345,7 +1353,7 @@ void CGrenade::C4Think()
MESSAGE_END(); MESSAGE_END();
g_pGameRules->m_bBombDropped = FALSE; g_pGameRules->m_bBombDropped = FALSE;
m_pBombDefuser = NULL; m_pBombDefuser = nullptr;
m_bStartDefuse = false; m_bStartDefuse = false;
} }
else else
@ -1356,7 +1364,7 @@ void CGrenade::C4Think()
pPlayer->m_bIsDefusing = false; pPlayer->m_bIsDefusing = false;
m_bStartDefuse = false; m_bStartDefuse = false;
m_pBombDefuser = NULL; m_pBombDefuser = nullptr;
// tell the bots someone has aborted defusing // tell the bots someone has aborted defusing
if (TheBots) if (TheBots)
@ -1377,7 +1385,7 @@ NOXREF void CGrenade::UseSatchelCharges(entvars_t *pevOwner, SATCHELCODE code)
if (!pevOwner) if (!pevOwner)
return; return;
edict_t *pentFind = NULL; edict_t *pentFind = nullptr;
CBaseEntity *pOwner = CBaseEntity::Instance(pevOwner); CBaseEntity *pOwner = CBaseEntity::Instance(pevOwner);
while ((pentFind = FIND_ENTITY_BY_CLASSNAME(pentFind, "grenade"))) while ((pentFind = FIND_ENTITY_BY_CLASSNAME(pentFind, "grenade")))
@ -1395,7 +1403,7 @@ NOXREF void CGrenade::UseSatchelCharges(entvars_t *pevOwner, SATCHELCODE code)
else else
{ {
// SATCHEL_RELEASE // 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. * version.
* *
*/ */
#pragma once #pragma once
class CFuncMortarField: public CBaseToggle { class CGib: public CBaseEntity
{
public: public:
virtual void Spawn() = 0; virtual int ObjectCaps() { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; }
virtual void Precache() = 0;
virtual void KeyValue(KeyValueData *pkvd) = 0;
virtual int Save(CSave &save) = 0;
virtual int Restore(CRestore &restore) = 0;
// Bmodels don't go across transitions
virtual int ObjectCaps() = 0;
public: public:
int m_iszXController; void Spawn(const char *szGibModel);
int m_iszYController; void EXPORT BounceGibTouch(CBaseEntity *pOther);
float m_flSpread; void EXPORT StickyGibTouch(CBaseEntity *pOther);
float m_flDelay; void EXPORT WaitTillLand();
int m_iCount; void LimitVelocity();
int m_fControl;
};
class CMortar: public CGrenade {
public: public:
virtual void Spawn() = 0; static void SpawnHeadGib(entvars_t *pevVictim);
virtual void Precache() = 0; static void SpawnRandomGibs(entvars_t *pevVictim, int cGibs, int human);
static void SpawnStickyGibs(entvars_t *pevVictim, Vector vecOrigin, int cGibs);
public: 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 #ifndef HOOK_GAMEDLL
const Vector g_vecZero(0, 0, 0); const Vector g_vecZero(0, 0, 0);
NOXREF u_long g_ulFrameCount = 0;
#endif #endif
int g_Language; int g_Language;
NOXREF u_long g_ulModelIndexEyes;
Vector g_vecAttackDir;
int g_iSkillLevel; int g_iSkillLevel;
int gDisplayTitle;
Vector g_vecAttackDir;
BOOL gDisplayTitle;
bool g_bIsCzeroGame = false; bool g_bIsCzeroGame = false;
bool g_bAllowedCSBot = false; bool g_bAllowedCSBot = false;
bool g_bHostageImprov = false; bool g_bHostageImprov = false;

View File

@ -26,23 +26,15 @@
* *
*/ */
#ifndef GLOBALS_H
#define GLOBALS_H
#ifdef _WIN32
#pragma once #pragma once
#endif
extern const Vector g_vecZero; extern const Vector g_vecZero;
extern int g_Language; extern int g_Language;
extern int g_iSkillLevel;
extern u_long g_ulFrameCount;
extern u_long g_ulModelIndexEyes;
extern Vector g_vecAttackDir; extern Vector g_vecAttackDir;
extern int g_iSkillLevel;
extern int gDisplayTitle; extern BOOL gDisplayTitle;
extern bool g_bIsCzeroGame; extern bool g_bIsCzeroGame;
extern bool g_bAllowedCSBot; extern bool g_bAllowedCSBot;
extern bool g_bHostageImprov; 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; pkvd->fHandled = TRUE;
} }
else else
{
CBaseToggle::KeyValue(pkvd); CBaseToggle::KeyValue(pkvd);
}
} }
void CRecharge::Spawn() void CRecharge::Spawn()
@ -50,7 +52,14 @@ void CRecharge::Spawn()
UTIL_SetSize(pev, pev->mins, pev->maxs); UTIL_SetSize(pev, pev->mins, pev->maxs);
SET_MODEL(ENT(pev), STRING(pev->model)); 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; pev->frame = 0;
} }
@ -120,6 +129,12 @@ void CRecharge::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT
// charge the player // charge the player
if (m_hActivator->pev->armorvalue < 100) 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_iJuice--;
m_hActivator->pev->armorvalue += 1.0f; m_hActivator->pev->armorvalue += 1.0f;
@ -133,7 +148,15 @@ void CRecharge::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT
void CRecharge::Recharge() 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; pev->frame = 0;
SetThink(&CRecharge::SUB_DoNothing); SetThink(&CRecharge::SUB_DoNothing);
} }
@ -152,5 +175,7 @@ void CRecharge::Off()
SetThink(&CRecharge::Recharge); SetThink(&CRecharge::Recharge);
} }
else else
{
SetThink(&CRecharge::SUB_DoNothing); SetThink(&CRecharge::SUB_DoNothing);
}
} }

View File

@ -26,11 +26,7 @@
* *
*/ */
#ifndef H_BATTERY_H
#define H_BATTERY_H
#ifdef _WIN32
#pragma once #pragma once
#endif
class CRecharge: public CBaseToggle class CRecharge: public CBaseToggle
{ {
@ -56,5 +52,3 @@ public:
int m_iOn; int m_iOn;
float m_flSoundTime; 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); MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, vecSrc);
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);
WRITE_BYTE(TE_SMOKE); WRITE_BYTE(TE_SMOKE);
WRITE_COORD(VecSrc.x); WRITE_COORD(vecSrc.x);
WRITE_COORD(VecSrc.y); WRITE_COORD(vecSrc.y);
WRITE_COORD(VecSrc.z); WRITE_COORD(vecSrc.z);
WRITE_SHORT(g_sModelIndexSmoke); WRITE_SHORT(g_sModelIndexSmoke);
WRITE_BYTE(RANDOM_LONG(0, 49) + 50); // scale * 10 WRITE_BYTE(RANDOM_LONG(0, 49) + 50); // scale * 10
WRITE_BYTE(RANDOM_LONG(0, 3) + 8); // framerate 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 #pragma once
#endif
class CCycler: public CBaseMonster class CCycler: public CBaseMonster
{ {
@ -55,7 +51,7 @@ public:
int m_animate; 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 class CGenericCycler: public CCycler
{ {
public: public:
@ -128,5 +124,3 @@ public:
int m_flStartTime; int m_flStartTime;
}; };
#endif // H_CYCLER_H

View File

@ -39,9 +39,17 @@ BOOL CHealthKit::MyTouch(CBasePlayer *pPlayer)
return FALSE; return FALSE;
#endif #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)); WRITE_STRING(STRING(pev->classname));
MESSAGE_END(); MESSAGE_END();
@ -73,7 +81,9 @@ void CWallHealth::KeyValue(KeyValueData *pkvd)
pkvd->fHandled = TRUE; pkvd->fHandled = TRUE;
} }
else else
{
CBaseToggle::KeyValue(pkvd); CBaseToggle::KeyValue(pkvd);
}
} }
void CWallHealth::Spawn() void CWallHealth::Spawn()
@ -89,7 +99,14 @@ void CWallHealth::Spawn()
SET_MODEL(ENT(pev), STRING(pev->model)); 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; pev->frame = 0.0f;
} }
@ -160,7 +177,16 @@ void CWallHealth::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us
void CWallHealth::Recharge() void CWallHealth::Recharge()
{ {
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", VOL_NORM, ATTN_NORM); 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; pev->frame = 0.0f;
SetThink(&CWallHealth::SUB_DoNothing); SetThink(&CWallHealth::SUB_DoNothing);
} }
@ -173,11 +199,13 @@ void CWallHealth::Off()
m_iOn = 0; 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; pev->nextthink = pev->ltime + m_iReactivate;
SetThink(&CWallHealth::Recharge); SetThink(&CWallHealth::Recharge);
} }
else else
{
SetThink(&CWallHealth::SUB_DoNothing); SetThink(&CWallHealth::SUB_DoNothing);
}
} }

View File

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

View File

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

View File

@ -26,35 +26,33 @@
* *
*/ */
#ifndef HINTMESSAGE_H
#define HINTMESSAGE_H
#ifdef _WIN32
#pragma once #pragma once
#endif
#define DHF_ROUND_STARTED (1<<1) #include "utlvector.h"
#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)
#define DHM_ROUND_CLEAR (DHF_ROUND_STARTED | DHF_HOSTAGE_KILLED | DHF_FRIEND_KILLED | DHF_BOMB_RETRIEVED) #define DHF_ROUND_STARTED BIT(1)
#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_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 class CHintMessage
{ {
@ -85,5 +83,3 @@ private:
float m_tmMessageEnd; float m_tmMessageEnd;
CUtlVector<CHintMessage *> m_messages; CUtlVector<CHintMessage *> m_messages;
}; };
#endif // HINTMESSAGE_H

View File

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

View File

@ -26,11 +26,7 @@
* *
*/ */
#ifndef HOSTAGE_H
#define HOSTAGE_H
#ifdef _WIN32
#pragma once #pragma once
#endif
#define MAX_NODES 100 #define MAX_NODES 100
#define MAX_HOSTAGES 12 #define MAX_HOSTAGES 12
@ -298,5 +294,3 @@ inline bool AreImprovAllowed()
void Hostage_RegisterCVars(); void Hostage_RegisterCVars();
void InstallHostageManager(); 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 // TODO: Look ahead *along path* instead of straight line
ClearPath(); ClearPath();
if ((m_lastKnownArea == NULL || !(m_lastKnownArea->GetAttributes() & NAV_NO_JUMP)) if ((!m_lastKnownArea || !(m_lastKnownArea->GetAttributes() & NAV_NO_JUMP))
&& !IsUsingLadder() && !IsJumping() && IsOnGround() && !IsCrouching()) && !IsUsingLadder() && !IsJumping() && IsOnGround() && !IsCrouching())
{ {
float ground; 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 *CHostageImprov::GetClosestPlayerByTravelDistance(int team, float *range) const
{ {
CBasePlayer *close = NULL; CBasePlayer *close = nullptr;
float closeRange = 9.9999998e10f; float closeRange = 9.9999998e10f;
if (GetLastKnownArea() == NULL) if (!GetLastKnownArea())
return NULL; return nullptr;
for (int i = 1; i <= gpGlobals->maxClients; ++i) for (int i = 1; i <= gpGlobals->maxClients; ++i)
{ {
@ -591,7 +591,7 @@ void CHostageImprov::OnReset()
m_actualVel = Vector(0, 0, 0); m_actualVel = Vector(0, 0, 0);
m_checkNearbyTerroristTimer.Invalidate(); m_checkNearbyTerroristTimer.Invalidate();
m_lastKnownArea = NULL; m_lastKnownArea = nullptr;
m_hasKnownGoodPos = false; m_hasKnownGoodPos = false;
m_hasPriorKnownGoodPos = false; m_hasPriorKnownGoodPos = false;
m_isTerroristNearby = false; m_isTerroristNearby = false;
@ -1038,29 +1038,31 @@ void CHostageImprov::UpdateGrenadeReactions()
if (m_grenadeTimer.IsElapsed()) if (m_grenadeTimer.IsElapsed())
{ {
CBaseEntity *entity = NULL; CBaseEntity *pEntity = nullptr;
const float watchGrenadeRadius = 500.0f; const float watchGrenadeRadius = 500.0f;
m_grenadeTimer.Start(RANDOM_FLOAT(0.4f, 0.6f)); 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; continue;
if (IsVisible(grenade->Center())) if (IsVisible(pGrenade->Center()))
{ {
Chatter(HOSTAGE_CHATTER_SAW_HE_GRENADE); Chatter(HOSTAGE_CHATTER_SAW_HE_GRENADE);
if (grenade->pev->dmg > 50.0f) if (pGrenade->pev->dmg > 50.0f)
{ {
m_idleState.OnInjury(); m_idleState.OnInjury();
Frighten(TERRIFIED); Frighten(TERRIFIED);
} }
else else
{
Frighten(SCARED); Frighten(SCARED);
}
m_grenadeTimer.Start(10); m_grenadeTimer.Start(10);
break; break;
@ -1480,22 +1482,22 @@ bool CHostageImprov::CanSeeRescueZone() const
CBasePlayer *CHostageImprov::GetClosestVisiblePlayer(int team) CBasePlayer *CHostageImprov::GetClosestVisiblePlayer(int team)
{ {
CBasePlayer *close = NULL; CBasePlayer *close = nullptr;
float closeRangeSq = 1e8f; float closeRangeSq = 1e8f;
for (int i = 0; i < m_visiblePlayerCount; ++i) 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; continue;
float_precision rangeSq = (GetCentroid() - player->pev->origin).LengthSquared(); float_precision rangeSq = (GetCentroid() - pPlayer->pev->origin).LengthSquared();
if (rangeSq < closeRangeSq) if (rangeSq < closeRangeSq)
{ {
closeRangeSq = rangeSq; closeRangeSq = rangeSq;
close = player; close = pPlayer;
} }
} }

View File

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

View File

@ -20,7 +20,7 @@ int CLocalNav::tot_hostages;
CLocalNav::CLocalNav(CHostage *pOwner) CLocalNav::CLocalNav(CHostage *pOwner)
{ {
m_pOwner = pOwner; m_pOwner = pOwner;
m_pTargetEnt = NULL; m_pTargetEnt = nullptr;
m_nodeArr = new localnode_t[MAX_NODES]; m_nodeArr = new localnode_t[MAX_NODES];
if (tot_hostages >= MAX_HOSTAGES_NAV) if (tot_hostages >= MAX_HOSTAGES_NAV)
@ -33,8 +33,11 @@ CLocalNav::CLocalNav(CHostage *pOwner)
CLocalNav::~CLocalNav() CLocalNav::~CLocalNav()
{ {
delete[] m_nodeArr; if (m_nodeArr)
m_nodeArr = NULL; {
delete[] m_nodeArr;
m_nodeArr = nullptr;
}
} }
node_index_t CLocalNav::AddNode(node_index_t nindexParent, Vector &vecLoc, int offsetX, int offsetY, byte bDepth) 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 vecStepStart;
Vector vecStepDest; Vector vecStepDest;
//BOOL fFwdTrace = FALSE; // unused?
float flFwdFraction; float flFwdFraction;
float flJumpHeight = s_flStepSize + 1.0f; float flJumpHeight = s_flStepSize + 1.0f;
//BOOL fJumpClear = FALSE; // unused?
//edict_t *hit = NULL; // unused?
vecStepStart = vecSource; vecStepStart = vecSource;
vecStepStart.z += flJumpHeight; vecStepStart.z += flJumpHeight;
@ -747,11 +747,11 @@ BOOL CLocalNav::LadderHit(Vector &vecSource, Vector &vecDest, TraceResult &tr)
void CLocalNav::Think() void CLocalNav::Think()
{ {
EHANDLE hCallback; EHANDLE hCallback;
static cvar_t *sv_stepsize = NULL; static cvar_t *sv_stepsize = nullptr;
if (gpGlobals->time >= flNextCvarCheck) if (gpGlobals->time >= flNextCvarCheck)
{ {
if (sv_stepsize != NULL) if (sv_stepsize)
s_flStepSize = sv_stepsize->value; s_flStepSize = sv_stepsize->value;
else else
{ {
@ -788,7 +788,7 @@ void CLocalNav::Think()
tot_inqueue--; tot_inqueue--;
if (!tot_inqueue) if (!tot_inqueue)
{ {
hCallback = NULL; hCallback = nullptr;
break; break;
} }
@ -857,7 +857,7 @@ void CLocalNav::HostagePrethink()
{ {
for (int iCount = 0; iCount < tot_hostages; ++iCount) for (int iCount = 0; iCount < tot_hostages; ++iCount)
{ {
if (hostages[ iCount ] != NULL) if (hostages[ iCount ])
{ {
GetClassPtr<CCSHostage>((CHostage *)hostages[ iCount ]->pev)->PreThink(); 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 #pragma once
#endif
#define NODE_INVALID_EMPTY -1 #define NODE_INVALID_EMPTY -1
#define PATH_TRAVERSABLE_EMPTY 0 #define PATH_TRAVERSABLE_EMPTY 0
#define PATH_TRAVERSABLE_SLOPE 1 #define PATH_TRAVERSABLE_SLOPE 1
#define PATH_TRAVERSABLE_STEP 2 #define PATH_TRAVERSABLE_STEP 2
#define PATH_TRAVERSABLE_STEPJUMPABLE 3 #define PATH_TRAVERSABLE_STEPJUMPABLE 3
typedef int node_index_t; typedef int node_index_t;
@ -64,10 +60,10 @@ public:
void SetTargetEnt(CBaseEntity *pTarget) void SetTargetEnt(CBaseEntity *pTarget)
{ {
if (pTarget != NULL) if (pTarget)
m_pTargetEnt = pTarget->edict(); m_pTargetEnt = pTarget->edict();
else else
m_pTargetEnt = NULL; m_pTargetEnt = nullptr;
} }
node_index_t FindPath(Vector &vecStart, Vector &vecDest, float flTargetRadius, int fNoMonsters); node_index_t FindPath(Vector &vecStart, Vector &vecDest, float flTargetRadius, int fNoMonsters);
@ -116,5 +112,3 @@ private:
node_index_t m_nindexAvailableNode; node_index_t m_nindexAvailableNode;
Vector m_vecStartingLoc; 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 #pragma once
#endif
class CHostageImprov; class CHostageImprov;
@ -185,11 +181,11 @@ public:
virtual void UpdateStationaryAnimation(CHostageImprov *improv); virtual void UpdateStationaryAnimation(CHostageImprov *improv);
public: public:
void SetLeader(CBaseEntity *leader) { m_leader = leader; } void SetLeader(CBasePlayer *leader) { m_leader = leader; }
CBaseEntity *GetLeader() const { return m_leader; } CBasePlayer *GetLeader() const { return m_leader; }
private: private:
mutable EHANDLE m_leader; mutable EntityHandle<CBasePlayer> m_leader;
Vector m_lastLeaderPos; Vector m_lastLeaderPos;
bool m_isWaiting; bool m_isWaiting;
float m_stopRange; float m_stopRange;
@ -259,5 +255,3 @@ private:
bool m_isHolding; bool m_isHolding;
CountdownTimer m_holdTimer; 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) if (m_sequenceCount >= MAX_SEQUENCES)
return; return;
if (seqName != NULL) if (seqName)
seqIndex = hostage->LookupSequence(seqName); seqIndex = hostage->LookupSequence(seqName);
else else
seqIndex = -1; seqIndex = -1;
m_sequence[m_sequenceCount].seqID = seqIndex; m_sequence[m_sequenceCount].seqID = seqIndex;
m_sequence[m_sequenceCount].holdTime = holdTime; m_sequence[m_sequenceCount].holdTime = holdTime;
m_sequence[m_sequenceCount++].rate = rate; m_sequence[m_sequenceCount].rate = rate;
m_sequenceCount++;
m_currentSequence = 0; m_currentSequence = 0;
StartSequence(improv, m_sequence); 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) void HostageAnimateState::AddSequence(CHostageImprov *improv, int activity, float holdTime, float rate)
{ {
CHostage *hostage = improv->GetEntity(); 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].seqID = LookupActivity(model, hostage->pev, activity);
m_sequence[m_sequenceCount].holdTime = holdTime; m_sequence[m_sequenceCount].holdTime = holdTime;
m_sequence[m_sequenceCount++].rate = rate; m_sequence[m_sequenceCount].rate = rate;
m_sequenceCount++;
m_currentSequence = 0; m_currentSequence = 0;
} }

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