diff --git a/lib/include/vgui/VGUI_Dar.h b/lib/include/vgui/VGUI_Dar.h index 2d5c64968..6f8eb513b 100644 --- a/lib/include/vgui/VGUI_Dar.h +++ b/lib/include/vgui/VGUI_Dar.h @@ -66,7 +66,7 @@ template class VGUIAPI Dar } _count=count; } - unsigned int getCount() + int getCount() { return _count; } diff --git a/lib/include/vgui/VGUI_String.h b/lib/include/vgui/VGUI_String.h index 289e1af71..9cdebadf2 100644 --- a/lib/include/vgui/VGUI_String.h +++ b/lib/include/vgui/VGUI_String.h @@ -37,7 +37,7 @@ class VGUIAPI String public: - unsigned int getCount(); + int getCount(); String operator+(String text); String operator+(const char* text); bool operator==(String text); diff --git a/src/common/beamdef.h b/src/common/beamdef.h index cc4d30472..1a41dccc8 100644 --- a/src/common/beamdef.h +++ b/src/common/beamdef.h @@ -37,9 +37,9 @@ struct beam_s BEAM *next; int type; int flags; - vec3_t source; - vec3_t target; - vec3_t delta; + Vector source; + Vector target; + Vector delta; float t; // 0 .. 1 over lifetime of beam float freq; float die; diff --git a/src/common/cl_entity.h b/src/common/cl_entity.h index dbf3981de..8adfb2236 100644 --- a/src/common/cl_entity.h +++ b/src/common/cl_entity.h @@ -39,8 +39,8 @@ typedef struct float prevanimtime; float sequencetime; byte prevseqblending[2]; - vec3_t prevorigin; - vec3_t prevangles; + Vector prevorigin; + Vector prevangles; int prevsequence; float prevframe; @@ -54,8 +54,8 @@ typedef struct // Time stamp for this movement float animtime; - vec3_t origin; - vec3_t angles; + Vector origin; + Vector angles; } position_history_t; typedef struct cl_entity_s cl_entity_t; @@ -93,11 +93,11 @@ struct cl_entity_s float lastmove; // Actual render position and angles - vec3_t origin; - vec3_t angles; + Vector origin; + Vector angles; // Attachment points - vec3_t attachment[4]; + Vector attachment[4]; // Other entity local information int trivial_accept; diff --git a/src/common/com_model.h b/src/common/com_model.h index 1694a5c9a..588fc4a98 100644 --- a/src/common/com_model.h +++ b/src/common/com_model.h @@ -87,7 +87,7 @@ typedef struct // 'model.h' and 'gl_model.h' typedef struct mplane_s { - vec3_t normal; // surface normal + Vector normal; // surface normal float dist; // closest appoach to origin byte type; // for texture axis selection and fast side tests byte signbits; // signx + signy<<1 + signz<<1 @@ -96,7 +96,7 @@ typedef struct mplane_s typedef struct { - vec3_t position; + Vector position; } mvertex_t; // 06/23/2002 MAH @@ -387,8 +387,8 @@ typedef struct hull_s mplane_t *planes; int firstclipnode; int lastclipnode; - vec3_t clip_mins; - vec3_t clip_maxs; + Vector clip_mins; + Vector clip_maxs; } hull_t; #if !defined(CACHE_USER) && !defined(QUAKEDEF_H) @@ -413,7 +413,7 @@ typedef struct model_s // // volume occupied by the model // - vec3_t mins, maxs; // +0x054, +060 + Vector mins, maxs; // +0x054, +060 float radius; // +0x06C // @@ -478,7 +478,7 @@ typedef struct alight_s { int ambientlight; // clip at 128 int shadelight; // clip at 192 - ambientlight - vec3_t color; + Vector color; float *plightvec; } alight_t; @@ -523,7 +523,7 @@ typedef struct player_info_s int gaitsequence; float gaitframe; float gaityaw; - vec3_t prevgaitorigin; + Vector prevgaitorigin; customization_t customdata; } player_info_t; diff --git a/src/common/const.h b/src/common/const.h index c37c7ab2b..39c7bb0dd 100644 --- a/src/common/const.h +++ b/src/common/const.h @@ -20,6 +20,7 @@ // Most came from server.h #include "Platform.h" +#include "vector.h" // edict->flags #define FL_FLY (1 << 0) // Changes the SV_Movestep() behavior to not need to be on ground @@ -760,7 +761,7 @@ typedef struct edict_s edict_t; typedef struct { - vec3_t normal; + Vector normal; float dist; } plane_t; @@ -770,7 +771,7 @@ typedef struct qboolean startsolid; // if true, the initial point was in a solid area qboolean inopen, inwater; float fraction; // time completed, 1.0 = didn't hit anything - vec3_t endpos; // final position + Vector endpos; // final position plane_t plane; // surface normal at impact edict_t *ent; // entity the surface is on int hitgroup; // 0 == generic, non zero is specific body part diff --git a/src/common/dlight.h b/src/common/dlight.h index 024ffadf5..fc68eef7a 100644 --- a/src/common/dlight.h +++ b/src/common/dlight.h @@ -20,7 +20,7 @@ typedef struct dlight_s { - vec3_t origin; + Vector origin; float radius; color24 color; float die; // stop lighting after this time diff --git a/src/common/entity_state.h b/src/common/entity_state.h index e26c99a43..01e571edd 100644 --- a/src/common/entity_state.h +++ b/src/common/entity_state.h @@ -38,8 +38,8 @@ struct entity_state_s int messagenum; // Fields which can be transmitted and reconstructed over the network stream - vec3_t origin; - vec3_t angles; + Vector origin; + Vector angles; int modelindex; int sequence; @@ -64,11 +64,11 @@ struct entity_state_s int body; byte controller[4]; byte blending[4]; - vec3_t velocity; + Vector velocity; // Send bbox down to client for use during prediction. - vec3_t mins; - vec3_t maxs; + Vector mins; + Vector maxs; int aiment; // If owned by a player, the index of that player ( for projectiles ). @@ -87,7 +87,7 @@ struct entity_state_s int weaponmodel; int gaitsequence; // If standing on conveyor, e.g. - vec3_t basevelocity; + Vector basevelocity; // Use the crouched hull, or the regular player hull. int usehull; // Latched buttons last time state updated. @@ -102,8 +102,8 @@ struct entity_state_s int weaponanim; // Parametric movement overrides - vec3_t startpos; - vec3_t endpos; + Vector startpos; + Vector endpos; float impacttime; //MS - Used for model scale float starttime; @@ -116,25 +116,25 @@ struct entity_state_s float fuser2; float fuser3; float fuser4; - vec3_t vuser1; - vec3_t vuser2; - vec3_t vuser3; - vec3_t vuser4; //MS - vuser4.x used to store idx of extra info (including all current bone positions) + Vector vuser1; + Vector vuser2; + Vector vuser3; + Vector vuser4; //MS - vuser4.x used to store idx of extra info (including all current bone positions) }; #include "pm_info.h" typedef struct clientdata_s { - vec3_t origin; - vec3_t velocity; + Vector origin; + Vector velocity; int viewmodel; - vec3_t punchangle; + Vector punchangle; int flags; int waterlevel; int watertype; - vec3_t view_ofs; + Vector view_ofs; float health; int bInDuck; @@ -175,10 +175,10 @@ typedef struct clientdata_s float fuser2; float fuser3; float fuser4; - vec3_t vuser1; - vec3_t vuser2; - vec3_t vuser3; - vec3_t vuser4; + Vector vuser1; + Vector vuser2; + Vector vuser3; + Vector vuser4; } clientdata_t; #include "weaponinfo.h" diff --git a/src/common/mathlib.h b/src/common/mathlib.h index 583acdf10..f79787b98 100644 --- a/src/common/mathlib.h +++ b/src/common/mathlib.h @@ -17,7 +17,7 @@ #pragma once #include -#include "hl/vector.h" +#include "vector.h" typedef float vec_t; typedef vec_t vec4_t[4]; // x,y,z,w diff --git a/src/common/particledef.h b/src/common/particledef.h index aadb22b18..314cccfa9 100644 --- a/src/common/particledef.h +++ b/src/common/particledef.h @@ -37,12 +37,12 @@ typedef enum typedef struct particle_s { // driver-usable fields - vec3_t org; + Vector org; short color; short packedColor; // drivers never touch the following fields struct particle_s *next; - vec3_t vel; + Vector vel; float ramp; float die; ptype_t type; diff --git a/src/common/pmtrace.h b/src/common/pmtrace.h index 868eb1103..7013a3f4a 100644 --- a/src/common/pmtrace.h +++ b/src/common/pmtrace.h @@ -20,7 +20,7 @@ typedef struct { - vec3_t normal; + Vector normal; float dist; } pmplane_t; @@ -32,10 +32,10 @@ struct pmtrace_s qboolean startsolid; // if true, the initial point was in a solid area qboolean inopen, inwater; // End point is in empty space or in water float fraction; // time completed, 1.0 = didn't hit anything - vec3_t endpos; // final position + Vector endpos; // final position pmplane_t plane; // surface normal at impact int ent; // entity at impact - vec3_t deltavelocity; // Change in player's velocity caused by impact. + Vector deltavelocity; // Change in player's velocity caused by impact. // Only run on server. int hitgroup; }; diff --git a/src/common/r_efx.h b/src/common/r_efx.h index d42c4ee9d..043bd17b2 100644 --- a/src/common/r_efx.h +++ b/src/common/r_efx.h @@ -106,7 +106,7 @@ typedef struct tempent_s // if COLLIDEALL, this is the index of the client to ignore // TENTS with FTENT_PLYRATTACHMENT MUST set the clientindex! - vec3_t tentOffset; // if attached, client origin + tentOffset = tent origin. + Vector tentOffset; // if attached, client origin + tentOffset = tent origin. cl_entity_t entity; // baseline.origin - velocity diff --git a/src/common/r_studioint.h b/src/common/r_studioint.h index 3e9caa52a..46f4c2e4f 100644 --- a/src/common/r_studioint.h +++ b/src/common/r_studioint.h @@ -135,8 +135,8 @@ typedef struct sv_blending_interface_s void (*SV_StudioSetupBones)(struct model_s *pModel, float frame, int sequence, - const vec3_t angles, - const vec3_t origin, + const Vector angles, + const Vector origin, const byte *pcontroller, const byte *pblending, int iBone, diff --git a/src/common/triangleapi.h b/src/common/triangleapi.h index 5e85cb035..ad15c4524 100644 --- a/src/common/triangleapi.h +++ b/src/common/triangleapi.h @@ -45,7 +45,7 @@ typedef struct triangleapi_s void (*Color4f)(float r, float g, float b, float a); void (*Color4ub)(unsigned char r, unsigned char g, unsigned char b, unsigned char a); void (*TexCoord2f)(float u, float v); - void (*Vertex3fv)(float *worldPnt); + void (*Vertex3fv)(const float *worldPnt); void (*Vertex3f)(float x, float y, float z); void (*Brightness)(float brightness); void (*CullFace)(TRICULLSTYLE style); diff --git a/src/common/usercmd.h b/src/common/usercmd.h index 8de5525c9..97db6a49f 100644 --- a/src/common/usercmd.h +++ b/src/common/usercmd.h @@ -22,7 +22,7 @@ typedef struct usercmd_s { short lerp_msec; // Interpolation time on client byte msec; // Duration in ms of command - vec3_t viewangles; // Command view angles. + Vector viewangles; // Command view angles. // intended velocities float forwardmove; // Forward velocity. @@ -35,7 +35,7 @@ typedef struct usercmd_s // Experimental player impact stuff. int impact_index; - vec3_t impact_position; + Vector impact_position; } usercmd_t; #endif // USERCMD_H diff --git a/src/common/vector.h b/src/common/vector.h new file mode 100644 index 000000000..5d4fa3227 --- /dev/null +++ b/src/common/vector.h @@ -0,0 +1,209 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#pragma once +#if !defined(VECTOR_H) +#define VECTOR_H + +#include + +#if __cplusplus >= 201703L +#define NODISCARD [[nodiscard]] +#else +#define NODISCARD +#endif + +//========================================================= +// 2DVector - used for many pathfinding and many other +// operations that are treated as planar rather than 3d. +//========================================================= +class Vector2D +{ +public: + constexpr Vector2D(void): x( 0.0f ), y( 0.0f ) {} + constexpr Vector2D(float X, float Y): x( X ), y( Y ) {} + NODISCARD constexpr Vector2D operator-() const { return Vector2D( -x, -y); } + NODISCARD constexpr bool operator==( const Vector2D& v ) const { return x==v.x && y==v.y; } + NODISCARD constexpr bool operator!=( const Vector2D& v ) const { return !( *this==v ); } + NODISCARD constexpr Vector2D operator+(const Vector2D& v) const { return Vector2D( x + v.x, y + v.y ); } + NODISCARD constexpr Vector2D operator-(const Vector2D& v) const { return Vector2D( x - v.x, y - v.y ); } + NODISCARD constexpr Vector2D operator*(float fl) const { return Vector2D( x * fl, y * fl ); } + NODISCARD constexpr Vector2D operator/(float fl) const { return Vector2D( x / fl, y / fl ); } + + inline Vector2D& operator+=(const Vector2D& v) { x += v.x; y += v.y; return *this; } + inline Vector2D& operator-=(const Vector2D& v) { x -= v.x; y -= v.y; return *this; } + inline Vector2D& operator*=(float fl) { x *= fl; y *= fl;; return *this; } + inline Vector2D& operator/=(float fl) { x /= fl; y /= fl;; return *this; } + + NODISCARD inline float Length() const { return sqrt(x * x + y * y ); } + NODISCARD inline constexpr float LengthSqr() const { return x * x + y * y; } + + NODISCARD inline constexpr bool IsLengthGreaterThan(float val) const { + return LengthSqr() > val*val; + } + NODISCARD inline constexpr bool IsLengthGreaterThanOrEqual(float val) const { + return LengthSqr() >= val*val; + } + NODISCARD inline constexpr bool IsLengthLessThan(float val) const { + return LengthSqr() < val*val; + } + NODISCARD inline constexpr bool IsLengthLessThanOrEqual(float val) const { + return LengthSqr() <= val*val; + } + + NODISCARD inline Vector2D Normalize() const + { + //Vector2D vec2; + + float flLen = Length(); + if( flLen == 0 ) + { + return Vector2D( 0, 0 ); + } + else + { + flLen = 1 / flLen; + return Vector2D( x * flLen, y * flLen ); + } + } + float NormalizeInPlace() + { + const float flLen = Length(); + if( flLen == 0 ) + { + x = y = 0; + } + else + { + float den = 1 / flLen; + x *= den; + y *= den; + } + return flLen; + } + + float x, y; +}; + +NODISCARD inline float DotProduct( const Vector2D& a, const Vector2D& b ) { return( a.x * b.x + a.y * b.y ); } +NODISCARD inline Vector2D operator*( float fl, const Vector2D& v ) { return v * fl; } + +//========================================================= +// 3D Vector +//========================================================= +class Vector // same data-layout as engine's vec3_t, +{ // which is a vec_t[3] +public: + // Construction/destruction + constexpr Vector( void ): x( 0.0f ), y( 0.0f ), z( 0.0f ) {} + constexpr Vector( float X, float Y, float Z ): x( X ), y( Y), z( Z ) {} + //inline Vector( double X, double Y, double Z ) { x = (float)X; y = (float)Y; z = (float)Z; } + //inline Vector( int X, int Y, int Z ) { x = (float)X; y = (float)Y; z = (float)Z; } + constexpr Vector( const Vector& v ) = default; + constexpr Vector( const float rgfl[3] ): x( rgfl[0] ), y( rgfl[1] ), z( rgfl[2] ) {} + + // Operators + NODISCARD constexpr Vector operator-( void ) const { return Vector( -x, -y, -z ); } + NODISCARD constexpr bool operator==( const Vector& v ) const { return x==v.x && y==v.y && z==v.z; } + NODISCARD constexpr bool operator!=( const Vector& v ) const { return !( *this==v ); } + NODISCARD constexpr Vector operator+( const Vector& v ) const { return Vector( x + v.x, y + v.y, z + v.z ); } + NODISCARD constexpr Vector operator-( const Vector& v ) const { return Vector( x - v.x, y - v.y, z - v.z ); } + NODISCARD constexpr Vector operator*( float fl) const { return Vector( x * fl, y * fl, z * fl ); } + NODISCARD constexpr Vector operator/( float fl) const { return Vector( x / fl, y / fl, z / fl ); } + + inline Vector& operator+=(const Vector& v) { x += v.x; y += v.y; z += v.z; return *this; } + inline Vector& operator-=(const Vector& v) { x -= v.x; y -= v.y; z -= v.z; return *this; } + inline Vector& operator*=(float fl) { x *= fl; y *= fl; z *= fl; return *this; } + inline Vector& operator/=(float fl) { x /= fl; y /= fl; z /= fl; return *this; } + + // Methods + void CopyToArray( float* rgfl ) const { rgfl[0] = x, rgfl[1] = y, rgfl[2] = z; } + NODISCARD inline float Length() const { return sqrt( x * x + y * y + z * z ); } + NODISCARD inline constexpr float LengthSqr() const { return x * x + y * y + z * z; } + operator float *() { return &x; } // Vectors will now automatically convert to float * when needed + constexpr operator const float *() const { return &x; } // Vectors will now automatically convert to float * when needed + NODISCARD inline Vector Normalize( void ) const + { + float flLen = Length(); + if( flLen == 0 ) return Vector( 0, 0, 1 ); // ???? + flLen = 1 / flLen; + return Vector( x * flLen, y * flLen, z * flLen ); + } + float NormalizeInPlace() + { + const float flLen = Length(); + if (flLen == 0) + { + x = 0; + y = 0; + z = 1; + } + else + { + float den = 1 / flLen; + x *= den; + y *= den; + z *= den; + } + return flLen; + } + + NODISCARD constexpr Vector2D Make2D( void ) const + { + return {x, y}; + } + NODISCARD inline float Length2D() const { return sqrt( x * x + y * y ); } + NODISCARD inline constexpr float Length2DSqr() const { return x * x + y * y; } + + NODISCARD inline constexpr bool IsLengthGreaterThan(float val) const { + return LengthSqr() > val*val; + } + NODISCARD inline constexpr bool IsLengthGreaterThanOrEqual(float val) const { + return LengthSqr() >= val*val; + } + NODISCARD inline constexpr bool IsLengthLessThan(float val) const { + return LengthSqr() < val*val; + } + NODISCARD inline constexpr bool IsLengthLessThanOrEqual(float val) const { + return LengthSqr() <= val*val; + } + + NODISCARD inline constexpr bool IsLength2DGreaterThan(float val) const { + return Length2DSqr() > val*val; + } + NODISCARD inline constexpr bool IsLength2DGreaterThanOrEqual(float val) const { + return Length2DSqr() >= val*val; + } + NODISCARD inline constexpr bool IsLength2DLessThan(float val) const { + return Length2DSqr() < val*val; + } + NODISCARD inline constexpr bool IsLength2DLessThanOrEqual(float val) const { + return Length2DSqr() <= val*val; + } + void ClampToLengthInPlace(float length) + { + if (IsLengthGreaterThan(length)) + { + NormalizeInPlace(); + operator*=(length); + } + } + + // Members + float x = 0, y = 0, z = 0; +}; +NODISCARD constexpr Vector operator*( float fl, const Vector& v ) { return v * fl; } +NODISCARD constexpr float DotProduct( const Vector& a, const Vector& b ) { return( a.x * b.x + a.y * b.y + a.z * b.z); } +NODISCARD constexpr Vector CrossProduct( const Vector& a, const Vector& b ) { return Vector( a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x ); } +#endif diff --git a/src/game/client/CMakeLists.txt b/src/game/client/CMakeLists.txt index f0a5b25fa..9616f89e3 100644 --- a/src/game/client/CMakeLists.txt +++ b/src/game/client/CMakeLists.txt @@ -80,6 +80,7 @@ target_include_directories(client PRIVATE target_compile_definitions(client PRIVATE ISCLIENT + AS_DISABLED CLIENT_WEAPONS DISCORD_DYNAMIC_LIB VERSION_SAFE_STEAM_API_INTERFACES @@ -171,6 +172,8 @@ set(HL1 "util.cpp" "view.cpp" "cl_util.h" + "tri.cpp" + "tri.h" "../shared/movement/pm_math.cpp" "../shared/voice_banmgr.cpp" "../shared/voice_status.cpp" @@ -207,7 +210,6 @@ source_group("MS" FILES ${MS}) set(MS_Headers "inc_huditem.h" - "ms/clenv.h" "ms/clglobal.h" "ms/health.h" "ms/hudid.h" @@ -246,15 +248,24 @@ set(Render "render/clrender.cpp" "render/clrender.h" "render/clrenderent.cpp" - "render/clrendermirror.cpp" "render/gamestudiomodelrenderer.cpp" "render/gamestudiomodelrenderer.h" - "render/opengl/clopengl.cpp" - "render/opengl/clopengl.h" "render/studio_util.cpp" "render/studio_util.h" "render/studiomodelrenderer.cpp" "render/studiomodelrenderer.h" + "render/clenv.cpp" + "render/clenv.h" + "particleman/CMiniMem.cpp" + "particleman/CMiniMem.h" + "particleman/CBaseParticle.cpp" + "particleman/CBaseParticle.h" + "particleman/CFrustum.cpp" + "particleman/CFrustum.h" + "particleman/IParticleMan_Active.cpp" + "particleman/IParticleMan_Active.h" + "particleman/particleman_internal.h" + "particleman/particleman.h" "../../../thirdparty/tartan/textureloader.cpp" "../../../thirdparty/tartan/tgaloader.cpp" "../../../thirdparty/gl/glext.h" @@ -275,11 +286,9 @@ set(Shared "../shared/ms/groupfile.cpp" "../shared/ms/mslogger.cpp" "../shared/ms/mslogger.h" - "../shared/ms/mscharacter.cpp" "../shared/ms/msdebug.h" "../shared/ms/msfileio.cpp" "../shared/ms/msmonstershared.cpp" - "../shared/ms/netcodeshared.cpp" "../shared/ms/script.cpp" "../shared/ms/script.h" "../shared/ms/scriptcmds.cpp" @@ -481,6 +490,7 @@ set(VGUI_MS "ui/ms/vgui_vote.h" "ui/ms/vgui_moveitempanel.cpp" "ui/ms/vgui_moveitempanel.h" + "ui/ms/vgui_image3d.cpp" ) source_group("VGUI\\ms" FILES ${VGUI_MS}) diff --git a/src/game/client/ammo.h b/src/game/client/ammo.h index acdb5791c..3ca1b1cd1 100644 --- a/src/game/client/ammo.h +++ b/src/game/client/ammo.h @@ -16,9 +16,11 @@ #ifndef __AMMO_H__ #define __AMMO_H__ -constexpr int MAX_WEAPON_NAME = 128; -constexpr int WEAPON_FLAGS_SELECTONEMPTY = 1; -constexpr int WEAPON_IS_ONTARGET = 0x40; +#define MAX_WEAPON_NAME 128 + +#define WEAPON_FLAGS_SELECTONEMPTY 1 + +#define WEAPON_IS_ONTARGET 0x40 struct WEAPON { diff --git a/src/game/client/ammo_secondary.cpp b/src/game/client/ammo_secondary.cpp index 81e80dff0..7b3749125 100644 --- a/src/game/client/ammo_secondary.cpp +++ b/src/game/client/ammo_secondary.cpp @@ -35,7 +35,7 @@ int CHudAmmoSecondary ::Init(void) gHUD.AddHudElem(this); m_HUD_ammoicon = 0; - for (unsigned int i = 0; i < MAX_SEC_AMMO_VALUES; i++) + for (int i = 0; i < MAX_SEC_AMMO_VALUES; i++) m_iAmmoAmounts[i] = -1; // -1 means don't draw this value Reset(); @@ -68,8 +68,8 @@ int CHudAmmoSecondary ::Draw(float flTime) AmmoWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left; - y = ScreenHeight() - (gHUD.m_iFontHeight * 4); // this is one font height higher than the weapon ammo values - x = ScreenWidth() - AmmoWidth; + y = ScreenHeight - (gHUD.m_iFontHeight * 4); // this is one font height higher than the weapon ammo values + x = ScreenWidth - AmmoWidth; if (m_HUD_ammoicon) { @@ -139,7 +139,7 @@ int CHudAmmoSecondary ::MsgFunc_SecAmmoVal(const char *pszName, int iSize, void // check to see if there is anything left to draw int count = 0; - for (unsigned int i = 0; i < MAX_SEC_AMMO_VALUES; i++) + for (int i = 0; i < MAX_SEC_AMMO_VALUES; i++) { count += V_max(0, m_iAmmoAmounts[i]); } diff --git a/src/game/client/ammohistory.cpp b/src/game/client/ammohistory.cpp index d3daf5013..40aa30c73 100644 --- a/src/game/client/ammohistory.cpp +++ b/src/game/client/ammohistory.cpp @@ -29,7 +29,7 @@ HistoryResource gHR; #define AMMO_PICKUP_GAP (gHR.iHistoryGap + 5) #define AMMO_PICKUP_PICK_HEIGHT (32 + (gHR.iHistoryGap * 2)) -#define AMMO_PICKUP_HEIGHT_MAX (ScreenHeight() - 100) +#define AMMO_PICKUP_HEIGHT_MAX (ScreenHeight - 100) #define MAX_ITEM_NAME 32 int HISTORY_DRAW_TIME = 5; @@ -91,7 +91,7 @@ void HistoryResource ::AddToHistory(int iType, const char *szName, int iCount) void HistoryResource ::CheckClearHistory(void) { - for (unsigned int i = 0; i < MAX_HISTORY; i++) + for (int i = 0; i < MAX_HISTORY; i++) { if (rgAmmoHistory[i].type) return; @@ -127,8 +127,8 @@ int HistoryResource ::DrawAmmoHistory(float flTime) ScaleColors(r, g, b, min(scale, 255) ); // Draw the pic - int ypos = ScreenHeight() - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth() - 24; + int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); + int xpos = ScreenWidth - 24; if ( spr && *spr ) // weapon isn't loaded yet so just don't draw the pic { // the dll has to make sure it has sent info the weapons you need SPR_Set( *spr, r, g, b ); @@ -154,8 +154,8 @@ int HistoryResource ::DrawAmmoHistory(float flTime) float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; ScaleColors(r, g, b, min(scale, 255) ); - int ypos = ScreenHeight() - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth() - (weap->rcInactive.right - weap->rcInactive.left); + int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); + int xpos = ScreenWidth - (weap->rcInactive.right - weap->rcInactive.left); SPR_Set( weap->hInactive, r, g, b ); SPR_DrawAdditive( 0, xpos, ypos, &weap->rcInactive ); } @@ -172,8 +172,8 @@ int HistoryResource ::DrawAmmoHistory(float flTime) float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; ScaleColors(r, g, b, min(scale, 255) ); - int ypos = ScreenHeight() - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth() - (rect.right - rect.left) - 10; + int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); + int xpos = ScreenWidth - (rect.right - rect.left) - 10; SPR_Set( gHUD.GetSprite( rgAmmoHistory[i].iId ), r, g, b ); SPR_DrawAdditive( 0, xpos, ypos, &rect ); diff --git a/src/game/client/ammohistory.h b/src/game/client/ammohistory.h index 71969039d..9d4d68702 100644 --- a/src/game/client/ammohistory.h +++ b/src/game/client/ammohistory.h @@ -17,6 +17,7 @@ // // this is the max number of items in each bucket +#define MAX_WEAPON_POSITIONS MAX_WEAPON_SLOTS class WeaponsResource { @@ -64,7 +65,7 @@ class WeaponsResource void DropAllWeapons(void) { - for (unsigned int i = 0; i < MAX_WEAPONS; i++) + for (int i = 0; i < MAX_WEAPONS; i++) { if (rgWeapons[i].iId) DropWeapon(&rgWeapons[i]); @@ -93,7 +94,7 @@ class WeaponsResource extern WeaponsResource gWR; -constexpr int MAX_HISTORY = 12; +#define MAX_HISTORY 12 enum { HISTSLOT_EMPTY, diff --git a/src/game/client/angelscript/ASVGUIBindings.cpp b/src/game/client/angelscript/ASVGUIBindings.cpp index 309f78a09..a4a1bfbab 100644 --- a/src/game/client/angelscript/ASVGUIBindings.cpp +++ b/src/game/client/angelscript/ASVGUIBindings.cpp @@ -69,13 +69,17 @@ namespace ASVGUIBindings { MS_ANGEL_INFO("[ASVGUIBindings] Cleaning up %d registered panels", g_PanelRegistry.size()); + // Move the registry out first: ~VGUIPanel calls UnregisterPanel, which would + // erase from the map we're iterating and invalidate the iterator + std::map panels; + panels.swap(g_PanelRegistry); + // Delete all registered panels - for (auto it = g_PanelRegistry.begin(); it != g_PanelRegistry.end(); ++it) + for (auto& entry : panels) { - VGUIPanel* panel = it->first; - if (panel) + if (entry.first) { - delete panel; + delete entry.first; } } diff --git a/src/game/client/camera.h b/src/game/client/camera.h index 35442bfff..36647c7bf 100644 --- a/src/game/client/camera.h +++ b/src/game/client/camera.h @@ -2,10 +2,10 @@ // NOTE: must include quakedef.h first #ifndef _CAMERA_H_ -#define _CAMERA_H_ +#define _CAMEA_H_ // pitch, yaw, dist -extern Vector cam_ofs; +extern Vector cam_ofs; // Using third person camera //extern int cam_thirdperson; //Master Sword - Moved to MSCLGlobals diff --git a/src/game/client/cdll_int.cpp b/src/game/client/cdll_int.cpp index 208d3a436..e88bb5ca1 100644 --- a/src/game/client/cdll_int.cpp +++ b/src/game/client/cdll_int.cpp @@ -28,6 +28,8 @@ #ifdef _WIN32 #include #endif +#include +#include #include #include "vgui_int.h" @@ -49,6 +51,13 @@ TeamFortressViewport *gViewPort = nullptr; extern CHud gHUD; extern float g_fMenuLastClosed; +#include "particleman/IParticleMan_Active.h" +#include "particleman/CBaseParticle.h" +IParticleMan* g_pParticleMan = nullptr; +extern cvar_t *ms_particle_tempents; +void CL_LoadParticleMan(); +void CL_UnloadParticleMan(); + void InitInput(void); void EV_HookEvents(void); void IN_Commands(void); @@ -57,7 +66,6 @@ static cvar_s *g_pVarBorderless = nullptr; static int g_iBorderlessMode = 0; // AngelScript cvars (client-side) -static cvar_s *cl_as_enabled = nullptr; static cvar_s *cl_as_debug_mode = nullptr; enum BORDERLESS_WINDOW_TYPES @@ -240,45 +248,41 @@ int DLLEXPORT Initialize(cl_enginefunc_t *pEnginefuncs, int iVersion) memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t)); EV_HookEvents(); + CL_LoadParticleMan(); g_pVarBorderless = CVAR_CREATE("ms_borderless", "0", FCVAR_ARCHIVE); // Register AngelScript cvars for client - cl_as_enabled = CVAR_CREATE("cl_as_enabled", "0", FCVAR_ARCHIVE); cl_as_debug_mode = CVAR_CREATE("cl_as_debug_mode", "0", FCVAR_ARCHIVE); if(!gClient.Initialize()) return 0; // Initialize AngelScript on client if enabled - if (cl_as_enabled && cl_as_enabled->value > 0) +#ifndef AS_DISABLED + MS_INFO("Initializing client-side AngelScript..."); + if (!CAngelScriptManager::Instance()->Initialize()) { - MS_INFO("Initializing client-side AngelScript..."); - if (!CAngelScriptManager::Instance()->Initialize()) - { - MS_ERROR("Client-side AngelScript initialization FAILED!"); - // Don't fail the entire client initialization, just disable AngelScript - if (cl_as_enabled) - cl_as_enabled->value = 0; - } - else + MS_ERROR("Client-side AngelScript initialization FAILED!"); + } + else + { + MS_INFO("Client-side AngelScript initialized successfully"); + + // Load client-side AngelScript modules + if (CAngelScriptManager::Instance()->IsInitialized()) { - MS_INFO("Client-side AngelScript initialized successfully"); + MS_INFO("Loading client-side AngelScript modules..."); - // Load client-side AngelScript modules - if (CAngelScriptManager::Instance()->IsInitialized()) + // Initialize the module system for client + ASModuleSystem* pModuleSystem = ASModuleSystem::Instance(); + if (pModuleSystem) { - MS_INFO("Loading client-side AngelScript modules..."); - - // Initialize the module system for client - ASModuleSystem* pModuleSystem = ASModuleSystem::Instance(); - if (pModuleSystem) - { - // Client modules will be loaded from scripts.pak with #pragma context client - MS_INFO("Client-side AngelScript module system ready"); - } + // Client modules will be loaded from scripts.pak with #pragma context client + MS_INFO("Client-side AngelScript module system ready"); } } } +#endif MS_INFO("[DLLEXPORT Initialize: Complete]"); @@ -301,6 +305,10 @@ int DLLEXPORT HUD_VidInit(void) VGui_Startup(); + //we place this here because this gets called every map change. + if (g_pParticleMan) + g_pParticleMan->ResetParticles(); + MS_INFO("[HUD_VidInit: Complete]"); return 1; @@ -329,7 +337,8 @@ void DLLEXPORT HUD_Init(void) Scheme_Init(); // Load client-side AngelScript modules when connecting to server - if (cl_as_enabled && cl_as_enabled->value > 0 && CAngelScriptManager::Instance()->IsInitialized()) +#ifndef AS_DISABLED + if (CAngelScriptManager::Instance()->IsInitialized()) { MS_INFO("=== CLIENT-SIDE ANGELSCRIPT MODULE LOADING ==="); MS_INFO("Build Context: CLIENT"); @@ -385,6 +394,7 @@ void DLLEXPORT HUD_Init(void) MS_INFO("=== CLIENT-SIDE ANGELSCRIPT MODULE LOADING COMPLETE ==="); } +#endif MS_INFO("[HUD_Init: Complete]"); } @@ -403,10 +413,12 @@ int DLLEXPORT HUD_Redraw(float time, int intermission) gHUD.Redraw(time, 0 != intermission); // Update AngelScript on client if enabled - if (cl_as_enabled && cl_as_enabled->value > 0 && CAngelScriptManager::Instance()->IsInitialized()) +#ifndef AS_DISABLED + if (CAngelScriptManager::Instance()->IsInitialized()) { CAngelScriptManager::Instance()->Think(); } +#endif return 1; } @@ -499,7 +511,7 @@ void DLLEXPORT HUD_ChatInputPosition(int* x, int* y) { if (g_iUser1 != 0 || gEngfuncs.IsSpectateOnly()) { - if ((int)gHUD.m_Spectator.m_pip->value == INSET_OFF) + if (gHUD.m_Spectator.m_pip->value == INSET_OFF) { *y = YRES(64); } @@ -510,20 +522,74 @@ void DLLEXPORT HUD_ChatInputPosition(int* x, int* y) } } -// void CL_UnloadParticleMan() -// { -// g_pParticleMan = nullptr; -// } +//Taken from https://github.com/FreeSlave/halflife-featureful +//so i can test that the particleman system is working. +void TestParticlesCmd() +{ + static model_t* texture = 0; + + if ( g_pParticleMan ) + { + const float clTime = gEngfuncs.GetClientTime(); + + if (texture == 0) + { + texture = (model_t*)gEngfuncs.GetSpritePointer(SPR_Load("sprites/steam1.spr")); + } + + if (!texture) + return; + + cl_entity_t* player = gEngfuncs.GetLocalPlayer(); + Vector origin = player->origin; + Vector forward; + AngleVectors(player->angles, &forward, NULL, NULL); + + for (int i = 0; i < 10; ++i) + { + Vector shift = forward * 64.0f + forward * 8.0f * i + Vector( 0.0f, 0.0f, i * 8.0f ); + + CBaseParticle *particle = g_pParticleMan->CreateParticle(origin + shift, Vector(0.0f, 0.0f, 0.0f), texture, 32.0f, 255.0f, "particle"); + + particle->SetLightFlag(LIGHT_NONE); + particle->SetCullFlag(CULL_PVS); + particle->SetRenderFlag(RENDER_FACEPLAYER); + particle->SetCollisionFlags(TRI_COLLIDEWORLD); + particle->m_iRendermode = kRenderTransAlpha; + particle->m_vColor = Vector(255, 255, 255); + particle->m_iFramerate = 10; + particle->m_iNumFrames = texture->numframes; + particle->m_flGravity = 0.01f; + particle->m_vVelocity = shift.Normalize() * 2; + + particle->m_flDieTime = clTime + 5 + i; + } + } +} + +void CL_UnloadParticleMan() +{ + if (g_pParticleMan) + { + delete g_pParticleMan; + g_pParticleMan = nullptr; + } +} -// void CL_LoadParticleMan() -// { -// //Now implemented in the client library. -// auto particleManFactory = Sys_GetFactoryThis(); +void CL_LoadParticleMan() +{ + //Now implemented in the client library. + g_pParticleMan = new IParticleMan_Active(); -// g_pParticleMan = (IParticleMan*)particleManFactory(PARTICLEMAN_INTERFACE, nullptr); + if (g_pParticleMan) + { + g_pParticleMan->SetUp(&gEngfuncs); + + //1 - Draw tempent sprites with ParticleMan + //0 - Draw with engine + //only effects the particles created by the scripts. + ms_particle_tempents = CVAR_CREATE("ms_particle_tempents", "1", 0); -// if (g_pParticleMan) -// { -// g_pParticleMan->SetUp(&gEngfuncs); -// } -// } + //gEngfuncs.pfnAddCommand("test_particles", &TestParticlesCmd); + } +} diff --git a/src/game/client/cl_dll.h b/src/game/client/cl_dll.h index c673b3411..696279043 100644 --- a/src/game/client/cl_dll.h +++ b/src/game/client/cl_dll.h @@ -28,7 +28,7 @@ typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf); #include "Platform.h" -#include "../shared/hl/vector.h" +#include "vector.h" #ifdef EXPORT #undef EXPORT diff --git a/src/game/client/cl_util.h b/src/game/client/cl_util.h index 18d22fa8c..fd73d6774 100644 --- a/src/game/client/cl_util.h +++ b/src/game/client/cl_util.h @@ -15,29 +15,16 @@ // // cl_util.h // - #include "sharedutil.h" #include "msdebug.h" #include "cvardef.h" +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif -// ScreenHeight() returns the height of the screen, in pixels - -inline int ScreenHeight(void) { - return gHUD.m_scrinfo.iHeight; -} - -inline int ScreenWidth(void){ - return gHUD.m_scrinfo.iWidth; -} - - -//#define ScreenHeight() (gHUD.m_scrinfo.iHeight) -// ScreenWidth() returns the width of the screen, in pixels -//#define ScreenWidth() (gHUD.m_scrinfo.iWidth) - -//these must stay macros, or we need to make a msg function for every command. // Macros to hook function calls into the HUD object #define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x); @@ -70,7 +57,7 @@ inline int ScreenWidth(void){ gHUD.y->UserCmd_##x(); \ } //------------------------------------------ -//end required macros + //Master Sword #undef CVAR_GET_FLOAT #undef CVAR_GET_STRING @@ -79,115 +66,44 @@ inline float CVAR_GET_FLOAT(const char *x) { return gEngfuncs.pfnGetCvarFloat(x) inline const char *CVAR_GET_STRING(const char *x) { return gEngfuncs.pfnGetCvarString(x); } inline struct cvar_s *CVAR_CREATE(const char *cv, const char *val, const int flags) { return gEngfuncs.pfnRegisterVariable(cv, val, flags); } -//#define SPR_Load (gEngfuncs.pfnSPR_Load( -//#define SPR_Set (*gEngfuncs.pfnSPR_Set) -//#define SPR_Frames (*gEngfuncs.pfnSPR_Frames) -//#define SPR_GetList (*gEngfuncs.pfnSPR_GetList) +#define SPR_Load (*gEngfuncs.pfnSPR_Load) +#define SPR_Set (*gEngfuncs.pfnSPR_Set) +#define SPR_Frames (*gEngfuncs.pfnSPR_Frames) +#define SPR_GetList (*gEngfuncs.pfnSPR_GetList) // SPR_Draw draws a the current sprite as solid -//#define SPR_Draw (*gEngfuncs.pfnSPR_Draw) - -//#define SPR_DrawHoles (*gEngfuncs.pfnSPR_DrawHoles) +#define SPR_Draw (*gEngfuncs.pfnSPR_Draw) +// SPR_DrawHoles draws the current sprites, with color index255 not drawn (transparent) +#define SPR_DrawHoles (*gEngfuncs.pfnSPR_DrawHoles) // SPR_DrawAdditive adds the sprites RGB values to the background (additive transulency) -//#define SPR_DrawAdditive (*gEngfuncs.pfnSPR_DrawAdditive) +#define SPR_DrawAdditive (*gEngfuncs.pfnSPR_DrawAdditive) // SPR_EnableScissor sets a clipping rect for HUD sprites. (0,0) is the top-left hand corner of the screen. -//#define SPR_EnableScissor (*gEngfuncs.pfnSPR_EnableScissor) - +#define SPR_EnableScissor (*gEngfuncs.pfnSPR_EnableScissor) // SPR_DisableScissor disables the clipping rect -//#define SPR_DisableScissor (*gEngfuncs.pfnSPR_DisableScissor) -//#define FillRGBA (*gEngfuncs.pfnFillRGBA) +#define SPR_DisableScissor (*gEngfuncs.pfnSPR_DisableScissor) +// +#define FillRGBA (*gEngfuncs.pfnFillRGBA) + +// ScreenHeight returns the height of the screen, in pixels +#define ScreenHeight (gHUD.m_scrinfo.iHeight) +// ScreenWidth returns the width of the screen, in pixels +#define ScreenWidth (gHUD.m_scrinfo.iWidth) // Use this to set any co-ords in 640x480 space -//#define XRES(x) ((int)(float(x) * ((float)ScreenWidth() / 640.0f) + 0.5f)) -//#define YRES(y) ((int)(float(y) * ((float)ScreenHeight() / 480.0f) + 0.5f)) +#define XRES(x) ((int)(float(x) * ((float)ScreenWidth / 640.0f) + 0.5f)) +#define YRES(y) ((int)(float(y) * ((float)ScreenHeight / 480.0f) + 0.5f)) // use this to project world coordinates to screen coordinates -//#define XPROJECT(x) ((1.0f + (x)) * ScreenWidth() * 0.5f) -//#define YPROJECT(y) ((1.0f - (y)) * ScreenHeight() * 0.5f) +#define XPROJECT(x) ((1.0f + (x)) * ScreenWidth * 0.5f) +#define YPROJECT(y) ((1.0f - (y)) * ScreenHeight * 0.5f) -//#define GetScreenInfo (*gEngfuncs.pfnGetScreenInfo) -//#define ServerCmd (*gEngfuncs.pfnServerCmd) -//#define ClientCmd (*gEngfuncs.pfnClientCmd) -//#define SetCrosshair (*gEngfuncs.pfnSetCrosshair) +#define GetScreenInfo (*gEngfuncs.pfnGetScreenInfo) +#define ServerCmd (*gEngfuncs.pfnServerCmd) +#define ClientCmd (*gEngfuncs.pfnClientCmd) +#define SetCrosshair (*gEngfuncs.pfnSetCrosshair) //#define AngleVectors (*gEngfuncs.pfnAngleVectors) - -inline HLSPRITE SPR_Load(const char* sprName) { - return gEngfuncs.pfnSPR_Load(sprName); -}; - -inline void SPR_Set(HLSPRITE hpic, const int r, const int g, const int b) { - gEngfuncs.pfnSPR_Set(hpic, r, g, b); -}; - -inline int SPR_Frames(HLSPRITE hpic) { - return gEngfuncs.pfnSPR_Frames(hpic); -}; - -inline client_sprite_s* SPR_GetList(const char* psz, int* piCount) { - return gEngfuncs.pfnSPR_GetList(psz, piCount); -}; - -//SPR_Draw draws the current sprite as solid -inline void SPR_Draw(const int frame, const int x, const int y, const Rect* pRect) { - gEngfuncs.pfnSPR_Draw(frame, x, y, pRect); -}; - -// SPR_DrawHoles draws the current sprites, with color index255 not drawn (transparent) -inline void SPR_DrawHoles(const int frame, const int x, const int y, const Rect* pRect) { - gEngfuncs.pfnSPR_DrawHoles(frame, x, y, pRect); -} - -inline void SPR_DrawAdditive(const int frame, const int x, const int y, const Rect* pRect) { - gEngfuncs.pfnSPR_DrawAdditive(frame, x, y, pRect); -} - -inline void SPR_EnableScissor(const int x, const int y, const int width, const int height) { - gEngfuncs.pfnSPR_EnableScissor(x, y, width, height); -} - -inline void SPR_DisableScissor() { - gEngfuncs.pfnSPR_DisableScissor(); -} - -inline void FillRGBA(const int x, const int y, const int width, const int height, const int r, const int b, const int g, const int a) { - gEngfuncs.pfnFillRGBA(x, y, width, height, r, g, b, a); -} - - -inline int XRES(const int x) { - return (int)(float(x) * ((float)ScreenWidth() / 640.0f) + 0.5f); -} - -inline int YRES(const int y) { - return (int)(float(y) * ((float)ScreenHeight() / 480.0f) + 0.5f); -} - -inline float XPROJECT(const float x) { - return (float)(1.0f + x) * ScreenWidth() * 0.5f; -} - -inline float YPROJECT(const float y) { - return (float)(1.0f - y) * ScreenHeight() * 0.5f; -} - -inline int GetScreenInfo(SCREENINFO_s * psScreenInfo) { - return gEngfuncs.pfnGetScreenInfo(psScreenInfo); -} - -inline int ServerCmd(const char* pszCmdString) { - return gEngfuncs.pfnServerCmd(pszCmdString); -} - -inline int ClientCmd(const char* pszCmdString) { - return gEngfuncs.pfnClientCmd(pszCmdString); -} - -inline void SetCrosshair(const HLSPRITE hSprite, const Rect rt, const int r, const int g, const int b) { - gEngfuncs.pfnSetCrosshair(hSprite, rt, r, g, b); -} - // Gets the height & width of a sprite, at the specified frame inline int SPR_Height(HLSPRITE x, int f) { return gEngfuncs.pfnSPR_Height(x, f); } inline int SPR_Width(HLSPRITE x, int f) { return gEngfuncs.pfnSPR_Width(x, f); } @@ -226,24 +142,17 @@ inline void CenterPrint(const char *string) gEngfuncs.pfnCenterPrint(string); } -inline void GetPlayerInfo(const int enum_num, hud_player_info_s* pInfo ) { - gEngfuncs.pfnGetPlayerInfo(enum_num, pInfo); -} - -// returnsthe players name of entity no. -//#define GetPlayerInfo (*gEngfuncs.pfnGetPlayerInfo) +// returns the players name of entity no. +#define GetPlayerInfo (*gEngfuncs.pfnGetPlayerInfo) // sound functions inline void PlaySound(const char *szSound, float vol) { gEngfuncs.pfnPlaySoundByName(szSound, vol); } inline void PlaySound(int iSound, float vol) { gEngfuncs.pfnPlaySoundByIndex(iSound, vol); } inline void PlayHUDSound(const char *Sound, float vol) { PlaySound((char *)Sound, vol); } -void ScaleColors(int &r, int &g, int &b, int a); +#define fabs(x) ((x) > 0 ? (x) : 0 - (x)) -template -float DotProduct(Type* x, Type* y) { - return (x[0] * y[0]) + (x[1] * y[1]) + (x[2] + y[2]); -}; +void ScaleColors(int &r, int &g, int &b, int a); //#define DotProduct(x, y) ((x)[0] * (y)[0] + (x)[1] * (y)[1] + (x)[2] * (y)[2]) @@ -252,9 +161,9 @@ float DotProduct(Type* x, Type* y) { // extern Vector vec3_origin; // disable 'possible loss of data converting float to int' warning message -//#pragma warning(disable : 4244) +#pragma warning(disable : 4244) // disable 'truncation from 'const double' to 'float' warning message -//#pragma warning(disable : 4305) +#pragma warning(disable : 4305) inline void UnpackRGB(int &r, int &g, int &b, unsigned long ulRGB) { diff --git a/src/game/client/clientlibrary.cpp b/src/game/client/clientlibrary.cpp index e0743519a..28676d8fe 100644 --- a/src/game/client/clientlibrary.cpp +++ b/src/game/client/clientlibrary.cpp @@ -9,6 +9,8 @@ #include "fmod/soundengine.h" #include "mslogger.h" #include "ms/angelscript/CAngelScriptManager.h" +#include "ms/angelscript/ASModuleSystem.h" +#include "ms/angelscript/ASEngineEventManager.h" CSoundEngine gSoundEngine; CRichPresence gRichPresence; @@ -48,8 +50,6 @@ void CClientLibrary::HUDInit() CVAR_CREATE("ms_developer", "0", FCVAR_CLIENTDLL); // Thothie MAR2007b - Hides client side developer messages when set to 0 CVAR_CREATE("ms_help", "1", FCVAR_ARCHIVE); // Whether help tips are shown - CVAR_CREATE("ms_reflect", "1", FCVAR_ARCHIVE); // Allow reflective surfaces - CVAR_CREATE("ms_reflect_dbg", "0", FCVAR_ARCHIVE); // Debug reflective surfaces //CVAR_CREATE("ms_reconnect_delay", "5", FCVAR_ARCHIVE); // Thothie AUG2017 - Make reconnect delay adjustable client side CVAR_CREATE("ms_quickslot_timeout", "2.5", FCVAR_ARCHIVE); // Timeout for the quickslots CVAR_CREATE("ms_autocharge", "1", FCVAR_ARCHIVE); // MiB MAR2012_05 - Let's you auto-charge your attack @@ -100,18 +100,18 @@ void CClientLibrary::Shutdown() { MS_INFO("[INIT: Shutdown]"); - // Shutdown AngelScript on client - if (CAngelScriptManager::Instance()->IsInitialized()) - { - MS_INFO("Shutting down client-side AngelScript..."); - CAngelScriptManager::Instance()->Destroy(); - CAngelScriptManager::Shutdown(); - MS_INFO("Client-side AngelScript shutdown complete"); - } - + // Shutdown AngelScript on client. The module system unloads modules through the + // engine, so it goes first. Deleting the manager runs Destroy() if it was initialized. + MS_INFO("Shutting down client-side AngelScript..."); + ASModuleSystem::Shutdown(); + CAngelScriptManager::Shutdown(); + ASEngineEventManager::Shutdown(); + MS_INFO("Client-side AngelScript shutdown complete"); + + // Reverse of initialization order gHUD.Shutdown(); - FileSystem_Shutdown(); gSoundEngine.ExitFMOD(); + FileSystem_Shutdown(); gRichPresence.Shutdown(); } diff --git a/src/game/client/com_weapons.h b/src/game/client/com_weapons.h index 5fdfa2470..6bafe01ec 100644 --- a/src/game/client/com_weapons.h +++ b/src/game/client/com_weapons.h @@ -33,7 +33,7 @@ void stub_SetModel(struct edict_s *e, const char *m); extern cvar_t *cl_lw; extern int g_runfuncs; -extern Vector v_angles; +extern Vector v_angles; extern float g_lastFOV; extern struct local_state_s *g_finalstate; diff --git a/src/game/client/death.cpp b/src/game/client/death.cpp index 9e8b64430..18dd983a0 100644 --- a/src/game/client/death.cpp +++ b/src/game/client/death.cpp @@ -39,16 +39,17 @@ struct DeathNoticeItem float *VictimColor; }; -constexpr int MAX_DEATHNOTICES = 4; +#define MAX_DEATHNOTICES 4 static int DEATHNOTICE_DISPLAY_TIME = 6; -constexpr int DEATHNOTICE_TOP = 20; + +#define DEATHNOTICE_TOP 20 DeathNoticeItem rgDeathNoticeList[MAX_DEATHNOTICES + 1]; -constexpr float g_ColorBlue[3] = {0.6, 0.8, 1.0}; -constexpr float g_ColorRed[3] = {1.0, 0.25, 0.25}; -constexpr float g_ColorGreen[3] = {0.6, 1.0, 0.6}; -constexpr float g_ColorYellow[3] = {1.0, 0.7, 0.0}; +float g_ColorBlue[3] = {0.6, 0.8, 1.0}; +float g_ColorRed[3] = {1.0, 0.25, 0.25}; +float g_ColorGreen[3] = {0.6, 1.0, 0.6}; +float g_ColorYellow[3] = {1.0, 0.7, 0.0}; float *GetClientColor(int clientIndex) { @@ -90,7 +91,7 @@ int CHudDeathNotice ::Draw(float flTime) { int x, y, r, g, b; - for (unsigned int i = 0; i < MAX_DEATHNOTICES; i++) + for (int i = 0; i < MAX_DEATHNOTICES; i++) { if (rgDeathNoticeList[i].iId == 0) break; // we've gone through them all @@ -112,7 +113,7 @@ int CHudDeathNotice ::Draw(float flTime) y = DEATHNOTICE_TOP + (20 * i); //!!! int id = (rgDeathNoticeList[i].iId == -1) ? m_HUD_d_skull : rgDeathNoticeList[i].iId; - x = ScreenWidth() - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left); + x = ScreenWidth - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left); if (!rgDeathNoticeList[i].iSuicide) { @@ -141,7 +142,7 @@ int CHudDeathNotice ::Draw(float flTime) x += (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left); // Draw victims name (if it was a player that was killed) - if (rgDeathNoticeList[i].iNonPlayerKill == false) + if (rgDeathNoticeList[i].iNonPlayerKill == FALSE) { if (rgDeathNoticeList[i].VictimColor) gEngfuncs.pfnDrawSetTextColor(rgDeathNoticeList[i].VictimColor[0], rgDeathNoticeList[i].VictimColor[1], rgDeathNoticeList[i].VictimColor[2]); @@ -221,7 +222,7 @@ int CHudDeathNotice ::MsgFunc_DeathMsg(const char *pszName, int iSize, void *pbu // Is it a non-player object kill? if (((char)victim) == -1) { - rgDeathNoticeList[i].iNonPlayerKill = true; + rgDeathNoticeList[i].iNonPlayerKill = TRUE; // Store the object's name in the Victim slot (skip the d_ bit) strncpy(rgDeathNoticeList[i].szVictim, killedwith + 2, MAX_PLAYER_NAME_LENGTH); @@ -229,10 +230,10 @@ int CHudDeathNotice ::MsgFunc_DeathMsg(const char *pszName, int iSize, void *pbu else { if (killer == victim || killer == 0) - rgDeathNoticeList[i].iSuicide = true; + rgDeathNoticeList[i].iSuicide = TRUE; if (!strcmp(killedwith, "d_teammate")) - rgDeathNoticeList[i].iTeamKill = true; + rgDeathNoticeList[i].iTeamKill = TRUE; } // Find the sprite in the list diff --git a/src/game/client/entity.cpp b/src/game/client/entity.cpp index 31fc8b2fe..afee7fe44 100644 --- a/src/game/client/entity.cpp +++ b/src/game/client/entity.cpp @@ -8,6 +8,8 @@ // Client side entity management functions #include +#include +#include #include "hud.h" #include "cl_util.h" @@ -26,12 +28,16 @@ #include "inc_weapondefs.h" #include "ms/hudscript.h" #include "ms/clglobal.h" +#include "render/clenv.h" #include "script.h" #include +#include "particleman/particleman.h" +extern IParticleMan* g_pParticleMan; + #undef DLLEXPORT //Master Sword #define DLLEXPORT EXPORT -constexpr int MAX_TEMPENT_EXTRA = 4096; +#define MAX_TEMPENT_EXTRA 4096 void Game_AddObjects(void); void SetClEntityProp(cl_entity_t &Ent, msstring &Cmd, mslist &ValueParams); @@ -76,6 +82,69 @@ struct tempentextra_t static tempentextra_t g_TempEntExtra[MAX_TEMPENT_EXTRA]; //Extra info about tempents extern bool g_TempEntNewLevel; +class CScriptParticle : public CBaseParticle +{ +public: + TEMPENTITY m_Temp; + + void Think(float time) override {} //Simulated in HUD_TempEntUpdate instead + void Die() override; + void SyncFromTemp(); +}; + +static std::vector g_ScriptParticles; +cvar_t *ms_particle_tempents = NULL; + +//ParticleMan calls this right before it deletes the particle +void CScriptParticle::Die() +{ + auto it = std::find(g_ScriptParticles.begin(), g_ScriptParticles.end(), this); + if (it != g_ScriptParticles.end()) + g_ScriptParticles.erase(it); + + if (m_Temp.entity.curstate.weaponanim) + g_TempEntExtra[m_Temp.entity.curstate.weaponanim].Active = false; +} + +//Copy what the simulation and the scripts did to m_Temp over to what ParticleMan draws +void CScriptParticle::SyncFromTemp() +{ + cl_entity_t &Ent = m_Temp.entity; + + m_vOrigin = Ent.origin; + + //The engine draws a sprite with a body at that attachment of the entity in skin ("follow" sets this up) + if (Ent.curstate.body >= 1 && Ent.curstate.body <= 4 && Ent.curstate.skin) + { + cl_entity_t *pParent = gEngfuncs.GetEntityByIndex(Ent.curstate.skin); + if (pParent) + m_vOrigin = pParent->attachment[Ent.curstate.body - 1]; + } + + if (Ent.model && Ent.model->type == mod_sprite) + { + float Width = Ent.model->maxs.x - Ent.model->mins.x; + float Height = Ent.model->maxs.z - Ent.model->mins.z; + float Scale = Ent.curstate.scale ? Ent.curstate.scale : 1.0f; //The engine draws scale 0 as 1 + + m_pTexture = Ent.model; + m_iNumFrames = Ent.model->numframes; + m_flSize = Width * Scale; + m_flStretchY = Width > 0 ? Height / Width : 1.0f; + } + + m_iFrame = (int)Ent.curstate.frame; + m_iRendermode = Ent.curstate.rendermode; + m_flBrightness = Ent.curstate.rendermode == kRenderNormal ? 255 : Ent.curstate.renderamt; + + //The engine draws a sprite with no rendercolor as white + color24 &Color = Ent.curstate.rendercolor; + if (!Color.r && !Color.g && !Color.b) + m_vColor = Vector(255, 255, 255); + else + m_vColor = Vector(Color.r, Color.g, Color.b); +} + /* ======================== HUD_AddEntity @@ -108,11 +177,15 @@ int DLLEXPORT HUD_AddEntity(int type, struct cl_entity_s *ent, const char *model { gHUD.m_Spectator.AddOverviewEntity(type, ent, modelname); - if ((g_iUser1 == OBS_IN_EYE || (int)gHUD.m_Spectator.m_pip->value == INSET_IN_EYE) && + if ((g_iUser1 == OBS_IN_EYE || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE) && ent->index == g_iUser2) return 0; // don't draw the player we are following in eye } + //fade out what the fog doesn't work on. + if (type == ET_NORMAL && !CEnvMgr::ApplyFogFade(ent)) + return 0; + return 1; } @@ -544,14 +617,10 @@ void DLLEXPORT HUD_CreateEntities(void) //Put here because all the cool headers are already defined here TEMPENTITY *g_CurrentTempEnt = NULL; cl_entity_t *g_CurrentEnt = NULL; - -enum { - - MSTEMPENT_ID = (1 << 0), - MSTEMPENT_CALLBACK = (1 << 1), - MSTEMPENT_GRAVITY = (1 << 2), - MSTEMPENT_FOLLOWENT = (1 << 3) -}; +#define MSTEMPENT_ID (1 << 0) +#define MSTEMPENT_CALLBACK (1 << 1) +#define MSTEMPENT_GRAVITY (1 << 2) +#define MSTEMPENT_FOLLOWENT (1 << 3) void TempEntCallback(struct tempent_s *ent, float frametime, float currenttime) { @@ -559,7 +628,7 @@ void TempEntCallback(struct tempent_s *ent, float frametime, float currenttime) return; g_CurrentTempEnt = ent; - gHUD.m_HUDScript->Effects_UpdateTempEnt(STRING(ent->entity.curstate.iuser3)); + HUDScript->Effects_UpdateTempEnt(STRING(ent->entity.curstate.iuser3)); g_CurrentTempEnt = nullptr; } @@ -583,7 +652,7 @@ void TempEntHitCallback(struct tempent_s *ent, struct pmtrace_s *ptr) { Params.add("world"); } - gHUD.m_HUDScript->Effects_UpdateTempEnt(TempEntExtra.CBCollide_CallbackEvent, &Params); + HUDScript->Effects_UpdateTempEnt(TempEntExtra.CBCollide_CallbackEvent, &Params); } g_CurrentTempEnt = NULL; } @@ -592,7 +661,7 @@ void CHudScript::Effects_UpdateTempEnt(const char* EventName, msstringlist *Para { //Update tempents TEMPENTITY *pTempEnt = g_CurrentTempEnt; //Save a copy, because this could get set to NULL during RunScriptEventByName - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) { CScript *Script = m_Scripts[i]; if (pTempEnt->entity.curstate.iuser2 != (int)Script) @@ -610,14 +679,14 @@ void CHudScript::Effects_UpdateTempEnt(const char* EventName, msstringlist *Para const char* CScript::CLGetCurrentTempEntProp(msstring &Prop) { if (!g_CurrentTempEnt) - return RETURN_NOTHING(); + RETURN_NOTHING; TEMPENTITY *p = g_CurrentTempEnt; static msstring Return; if (Prop == "deathtime") - return RETURN_FLOAT( p->die); + RETURN_FLOAT(p->die) else if (Prop == "bouncefactor") - return RETURN_FLOAT( p->bounceFactor); + RETURN_FLOAT(p->bounceFactor) else { static msstringlist Params; @@ -627,42 +696,9 @@ const char* CScript::CLGetCurrentTempEntProp(msstring &Prop) return CLGetEntProp(&p->entity, Params); } - return RETURN_NOTHING(); + RETURN_NOTHING; } -const char* RETURN_COLOR(const char* Prop, const char* name, const color24& color) { - - if (Prop == name) - { - Vector vTemp = Vector(color.r, color.g, color.b); - return VecToString(vTemp); - } - - std::string NameExt; - NameExt = name; - NameExt += ".r"; - - - if (Prop == NameExt) - return RETURN_INT(color.r); - - NameExt = name; - NameExt += ".g"; - - - if (Prop == NameExt) - return RETURN_INT(color.g); - - NameExt = name; - NameExt += ".b"; - - if (Prop == NameExt) - return RETURN_INT(color.b); - - return RETURN_NOTHING(); - -} -/* #define RETURN_COLOR(name, color) \ { \ if (Prop == name) \ @@ -671,14 +707,13 @@ const char* RETURN_COLOR(const char* Prop, const char* name, const color24& colo return (Return = VecToString(vTemp)); \ } \ else if (Prop == name ".r") \ - return RETURN_INT(color.r); \ + RETURN_INT(color.r) \ else if (Prop == name ".g") \ - return RETURN_INT(color.g); \ + RETURN_INT(color.g) \ else if (Prop == name ".b") \ - return RETURN_INT(color.b); \ + RETURN_INT(color.b) \ } -*/ //[begin] DEC2014_09 Thothie - beam_update //$getcl_beam(,) const char* CScript::CLGetBeamProp(int beamid, msstringlist &Params) @@ -687,7 +722,7 @@ const char* CScript::CLGetBeamProp(int beamid, msstringlist &Params) BEAM *pBeam = found_beam ? m_Beams[beamid] : NULL; /* bool found_beam = false; - for (unsigned int i = 0; i < m_Beams.size(); i++) + for (int i = 0; i < m_Beams.size(); i++) { Print("DEBUG: $get_clbeam checking %i for %i\n",i,beamid); if ( m_Beams[i]->id == beamid ) @@ -711,33 +746,35 @@ const char* CScript::CLGetBeamProp(int beamid, msstringlist &Params) else if (Prop == "delta") beamret = VecToString(pBeam->delta); else if (Prop == "width") - beamret = UTIL_VarArgs("%.2f", pBeam->width); + beamret = FloatToString(pBeam->width); else if (Prop == "amplitude") - beamret = UTIL_VarArgs("%.2f", pBeam->amplitude); + beamret = FloatToString(pBeam->amplitude); else if (Prop == "color") + { beamret = UTIL_VarArgs("(%f,%f,%f)", pBeam->r, pBeam->g, pBeam->b); + } else if (Prop == "brightness") - beamret = UTIL_VarArgs("%.2f", pBeam->brightness); + beamret = FloatToString(pBeam->brightness); else if (Prop == "speed") - beamret = UTIL_VarArgs("%.2f", pBeam->speed); + beamret = FloatToString(pBeam->speed); else if (Prop == "life") - beamret = UTIL_VarArgs("%.2f", pBeam->die); + beamret = FloatToString(pBeam->die); else if (Prop == "segments") - beamret = UTIL_VarArgs("%i", pBeam->segments); + beamret = IntToString(pBeam->segments); else if (Prop == "framerate") - beamret = UTIL_VarArgs("%.2f", pBeam->frameRate); + beamret = FloatToString(pBeam->frameRate); else if (Prop == "framecount") - beamret = UTIL_VarArgs("%i", pBeam->frameCount); + beamret = IntToString(pBeam->frameCount); else if (Prop == "sprite") - beamret = UTIL_VarArgs("%i", pBeam->modelIndex); + beamret = IntToString(pBeam->modelIndex); else if (Prop == "startent") - beamret = UTIL_VarArgs("%i", pBeam->startEntity); + beamret = IntToString(pBeam->startEntity); else if (Prop == "endent") - beamret = UTIL_VarArgs("%i", pBeam->endEntity); + beamret = IntToString(pBeam->endEntity); else if (Prop == "flags") - beamret = UTIL_VarArgs("%i", pBeam->flags); + beamret = IntToString(pBeam->flags); else if (Prop == "t") - beamret = UTIL_VarArgs("%.2f", pBeam->t); + beamret = FloatToString(pBeam->t); return beamret; } else @@ -750,21 +787,21 @@ const char* CScript::CLGetBeamProp(int beamid, msstringlist &Params) const char* CScript::CLGetEntProp(cl_entity_t *pclEntity, msstringlist &Params) { if (!pclEntity) - return RETURN_NOTHING(); + RETURN_NOTHING; cl_entity_t &ent = *pclEntity; static msstring Return; msstring &Prop = Params[1]; if (Prop.starts_with("origin")) - return RETURN_POSITION( Prop, "origin", ent.origin); + RETURN_POSITION("origin", ent.origin) else if (Prop.starts_with("center")) { Vector vecCenter = ent.curstate.origin + ((ent.curstate.mins + ent.curstate.maxs) * 0.5); - return RETURN_POSITION( Prop, "center", vecCenter); + RETURN_POSITION("center", vecCenter) } else if (Prop.starts_with("angles")) - return RETURN_ANGLE( Prop, "angles", ent.angles); + RETURN_ANGLE("angles", ent.angles) else if (Prop.starts_with("velocity")) - return RETURN_POSITION( Prop, "velocity", ent.baseline.vuser1); //can't use baseline.origin - it's used by networked ents + RETURN_POSITION("velocity", ent.baseline.vuser1) //can't use baseline.origin - it's used by networked ents else if (Prop.starts_with("inwater")) return EngineFunc::Shared_PointContents(Vector(ent.origin.x, ent.origin.y, ent.origin.z + ent.curstate.mins.z)) == CONTENTS_WATER ? "1" : "0"; else if (Prop.starts_with("underwater")) @@ -776,7 +813,7 @@ const char* CScript::CLGetEntProp(cl_entity_t *pclEntity, msstringlist &Params) { Origin.x = ent.origin.x; Origin.y = ent.origin.y; - return RETURN_POSITION( Prop, "waterorigin", Origin); + RETURN_POSITION("waterorigin", Origin) } } else if (Prop == "model") @@ -796,106 +833,106 @@ const char* CScript::CLGetEntProp(cl_entity_t *pclEntity, msstringlist &Params) //however you can store the time the tempent began on fuserX in the creation event //then guess how far along the anim has gotten in that time based on the frame rate /* - else if( Prop == "animtime" ) return RETURN_FLOAT( ent.curstate.animtime ); //FEB2009_19 - experimenting - else if( Prop == "starttime" ) return RETURN_FLOAT( ent.curstate.starttime ); //FEB2009_19 - experimenting + else if( Prop == "animtime" ) RETURN_FLOAT( ent.curstate.animtime ) //FEB2009_19 - experimenting + else if( Prop == "starttime" ) RETURN_FLOAT( ent.curstate.starttime ) //FEB2009_19 - experimenting */ else if (Prop == "ducking") return FBitSet(player.pev->flags, FL_DUCKING) ? "1" : "0"; //Thothie JUN2010_25 else if (Prop == "modelidx") - return RETURN_INT( ent.curstate.modelindex); + RETURN_INT(ent.curstate.modelindex) else if (Prop == "anim") - return RETURN_INT( ent.curstate.sequence); + RETURN_INT(ent.curstate.sequence) else if (Prop == "height") - return RETURN_FLOAT( (ent.curstate.maxs.z) - (ent.curstate.mins.z)); //Thothie SEP2018_15 - return height/width for $getcl + RETURN_FLOAT((ent.curstate.maxs.z) - (ent.curstate.mins.z)) //Thothie SEP2018_15 - return height/width for $getcl else if (Prop == "width") - return RETURN_FLOAT( (ent.curstate.maxs.x) - (ent.curstate.mins.x)); //Thothie SEP2018_15 - return height/width for $getcl + RETURN_FLOAT((ent.curstate.maxs.x) - (ent.curstate.mins.x)) //Thothie SEP2018_15 - return height/width for $getcl else if (Prop == "mins") - return RETURN_VECTOR( ent.curstate.mins); + RETURN_VECTOR(ent.curstate.mins) else if (Prop == "maxs") - return RETURN_VECTOR( ent.curstate.maxs); + RETURN_VECTOR(ent.curstate.maxs) else if (Prop == "frame") - return RETURN_FLOAT( ent.curstate.frame); + RETURN_FLOAT(ent.curstate.frame) else if (Prop == "framerate") - return RETURN_FLOAT( ent.curstate.framerate); + RETURN_FLOAT(ent.curstate.framerate) else if (Prop == "exists") return pclEntity->Exists() ? "1" : "0"; else if (Prop == "gravity") - return RETURN_FLOAT( ent.curstate.gravity); + RETURN_FLOAT(ent.curstate.gravity) else if (Prop == "scale") - return RETURN_FLOAT( ent.curstate.scale); + RETURN_FLOAT(ent.curstate.scale) //NOV2014_16 dealing with the fact that MSC scripts can't hanle percision more than 2f else if (Prop == "scaleHD") - return RETURN_FLOAT( ent.curstate.scale * 1000); + RETURN_FLOAT(ent.curstate.scale * 1000) else if (Prop == "fuser1HD") - return RETURN_FLOAT( ent.curstate.fuser1 * 1000); + RETURN_FLOAT(ent.curstate.fuser1 * 1000) else if (Prop == "renderfx") - return RETURN_INT( ent.curstate.renderfx); + RETURN_INT(ent.curstate.renderfx) else if (Prop == "rendermode") - return RETURN_INT( ent.curstate.rendermode); + RETURN_INT(ent.curstate.rendermode) else if (Prop == "renderamt") - return RETURN_INT( ent.curstate.renderamt); + RETURN_INT(ent.curstate.renderamt) else if (Prop.starts_with("rendercolor")) - return RETURN_COLOR( Prop,"rendercolor", ent.curstate.rendercolor); + RETURN_COLOR("rendercolor", ent.curstate.rendercolor) else if (Prop == "visible") return FBitSet(ent.curstate.effects, EF_NODRAW) ? "0" : "1"; else if (Prop == "isplayer") return ent.player ? "1" : "0"; else if (Prop.starts_with("attachment0")) - return RETURN_POSITION( Prop, "attachment0", ent.attachment[0]); + RETURN_POSITION("attachment0", ent.attachment[0]) else if (Prop.starts_with("attachment1")) - return RETURN_POSITION( Prop, "attachment1", ent.attachment[1]); + RETURN_POSITION("attachment1", ent.attachment[1]) else if (Prop.starts_with("attachment2")) - return RETURN_POSITION( Prop, "attachment2", ent.attachment[2]); + RETURN_POSITION("attachment2", ent.attachment[2]) else if (Prop.starts_with("attachment3")) - return RETURN_POSITION( Prop, "attachment3", ent.attachment[3]); + RETURN_POSITION("attachment3", ent.attachment[3]) else if (Prop == "iuser1") - return RETURN_INT(ent.curstate.iuser1); + RETURN_INT(ent.curstate.iuser1) else if (Prop == "iuser2") - return RETURN_INT(ent.curstate.iuser2); + RETURN_INT(ent.curstate.iuser2) else if (Prop == "iuser3") - return RETURN_INT(ent.curstate.iuser3); + RETURN_INT(ent.curstate.iuser3) else if (Prop == "iuser4") - return RETURN_INT(ent.curstate.iuser4); + RETURN_INT(ent.curstate.iuser4) else if (Prop == "fuser1") - return RETURN_FLOAT(ent.curstate.fuser1); + RETURN_FLOAT(ent.curstate.fuser1) else if (Prop == "fuser2") - return RETURN_FLOAT(ent.curstate.fuser2); + RETURN_FLOAT(ent.curstate.fuser2) else if (Prop == "fuser3") - return RETURN_FLOAT(ent.curstate.fuser3); + RETURN_FLOAT(ent.curstate.fuser3) else if (Prop == "fuser4") - return RETURN_FLOAT(ent.curstate.fuser4); + RETURN_FLOAT(ent.curstate.fuser4) else if (Prop == "prevstate.iuser1") - return RETURN_INT(ent.prevstate.iuser1); + RETURN_INT(ent.prevstate.iuser1) else if (Prop == "prevstate.iuser2") - return RETURN_INT( ent.prevstate.iuser2); + RETURN_INT(ent.prevstate.iuser2) else if (Prop == "prevstate.iuser3") - return RETURN_INT(ent.prevstate.iuser3); + RETURN_INT(ent.prevstate.iuser3) else if (Prop == "prevstate.iuser4") - return RETURN_INT( ent.prevstate.iuser4); + RETURN_INT(ent.prevstate.iuser4) else if (Prop == "prevstate.fuser1") - return RETURN_FLOAT( ent.prevstate.fuser1); + RETURN_FLOAT(ent.prevstate.fuser1) else if (Prop == "prevstate.fuser2") - return RETURN_FLOAT(ent.prevstate.fuser2); + RETURN_FLOAT(ent.prevstate.fuser2) else if (Prop == "prevstate.fuser3") - return RETURN_FLOAT( ent.prevstate.fuser3); + RETURN_FLOAT(ent.prevstate.fuser3) else if (Prop == "prevstate.fuser4") - return RETURN_FLOAT( ent.prevstate.fuser4); + RETURN_FLOAT(ent.prevstate.fuser4) else if (Prop == "baseline.iuser1") - return RETURN_INT(ent.baseline.iuser1); //Baseline props are not overriden by; + RETURN_INT(ent.baseline.iuser1) //Baseline props are not overriden by else if (Prop == "baseline.iuser2") - return RETURN_INT(ent.baseline.iuser2); //incoming server packets; + RETURN_INT(ent.baseline.iuser2) //incoming server packets else if (Prop == "baseline.iuser3") - return RETURN_INT(ent.baseline.iuser3); //Stuff stored here is persistent; + RETURN_INT(ent.baseline.iuser3) //Stuff stored here is persistent else if (Prop == "baseline.iuser4") - return RETURN_INT(ent.baseline.iuser4); + RETURN_INT(ent.baseline.iuser4) else if (Prop == "baseline.fuser1") - return RETURN_FLOAT( ent.baseline.fuser1); + RETURN_FLOAT(ent.baseline.fuser1) else if (Prop == "baseline.fuser2") - return RETURN_FLOAT( ent.baseline.fuser2); + RETURN_FLOAT(ent.baseline.fuser2) else if (Prop == "baseline.fuser3") - return RETURN_FLOAT( ent.baseline.fuser3); + RETURN_FLOAT(ent.baseline.fuser3) else if (Prop == "baseline.fuser4") - return RETURN_FLOAT( ent.baseline.fuser4); + RETURN_FLOAT(ent.baseline.fuser4) else if (Prop == "bonepos") { //Thothie (Comment Only) - We may want to move this up, as it is sometimes used every frame @@ -903,33 +940,33 @@ const char* CScript::CLGetEntProp(cl_entity_t *pclEntity, msstringlist &Params) //Vector Pos; /* if( !pclEntity->GetBonePos( atoi(Params[2]), Pos ) ) - return RETURN_ZERO(); + RETURN_ZERO; */ //AUG2013_25 Thothie - attempting to fix client side bonepos function Vector Pos; ent.GetBonePosVec(atoi(Params[2]), Pos); //GetBonePos is boolean, wtf? //pclEntity->GetBonePosVec( atoi(Params[2]), Pos ); - return RETURN_VECTOR( Pos); + RETURN_VECTOR(Pos); } else if (Prop.starts_with("bonecount")) { //AUG2013_25 - enabling getting bone count (be good to have this serverside too) - return RETURN_INT(ent.GetBoneCount()); + RETURN_INT(ent.GetBoneCount()) } else if (Prop.starts_with("viewangles")) { //MIB AUG2010_05 Vector viewangles; gEngfuncs.GetViewAngles((float *)viewangles); - RETURN_ANGLE( Prop, "viewangles", viewangles); + RETURN_ANGLE("viewangles", viewangles) } /* else if ( Prop.starts_with("eyepos") ) { //Thoth APR2012_05 - attempting to return eye position (fail) Vector eyepos = player.pev->view_ofs; - return RETURN_ANGLE(Prop, "eyepos", eyepos ); + RETURN_ANGLE( "eyepos", eyepos ) } */ @@ -943,7 +980,7 @@ const char* CScript::CLGetEntProp(cl_entity_t *pclEntity, msstringlist &Params) else if ( Prop == "race" ) return pPlayer->m_Race; } */ - return RETURN_ZERO(); + RETURN_ZERO; } int CL_LoadModel(const char* RelativePathname, model_s **ppModel = NULL) @@ -956,6 +993,38 @@ int CL_LoadModel(const char* RelativePathname, model_s **ppModel = NULL) return modelindex; } +static CScriptParticle *ScriptParticle_Create(const Vector &Origin, model_s *Model) +{ + if (!g_pParticleMan || !ms_particle_tempents || !ms_particle_tempents->value) + return NULL; + if (!Model || Model->type != mod_sprite) + return NULL; + + CScriptParticle *pParticle = new CScriptParticle(); + pParticle->InitializeSprite(Origin, Vector(0, 0, 0), Model, 1, 255); + pParticle->SetLightFlag(LIGHT_NONE); + pParticle->SetCullFlag(CULL_PVS); + pParticle->SetRenderFlag(RENDER_FACEPLAYER); + + TEMPENTITY &Temp = pParticle->m_Temp; + clrmem(Temp); + Temp.flags = FTENT_CLIENTCUSTOM | FTENT_NOMODEL; //NOMODEL keeps the simulation from adding it as an engine entity + Temp.callback = TempEntCallback; + Temp.die = gEngfuncs.GetClientTime(); + Temp.frameMax = Model->numframes > 1 ? Model->numframes - 1 : 0; + Temp.fadeSpeed = 0.5; + Temp.bounceFactor = 1; + Temp.entity.model = Model; + Temp.entity.origin = Origin; + Temp.entity.curstate.rendercolor.r = 255; + Temp.entity.curstate.rendercolor.g = 255; + Temp.entity.curstate.rendercolor.b = 255; + Temp.entity.curstate.renderamt = 255; + + g_ScriptParticles.push_back(pParticle); + return pParticle; +} + void CScript::CLScriptedEffect(msstringlist &Params) { if (!Params.size()) @@ -977,7 +1046,9 @@ void CScript::CLScriptedEffect(msstringlist &Params) model_s *Model = gEngfuncs.CL_LoadModel(FullName, &index); Vector Origin = StringToVec(Params[3]); - TEMPENTITY *p = gEngfuncs.pEfxAPI->CL_TentEntAllocCustom(Origin, Model, 0, TempEntCallback); + //Sprites are drawn by ParticleMan, everything else is an engine tempent + CScriptParticle *pParticle = IsSprite ? ScriptParticle_Create(Origin, Model) : NULL; + TEMPENTITY *p = pParticle ? &pParticle->m_Temp : gEngfuncs.pEfxAPI->CL_TentEntAllocCustom(Origin, Model, 0, TempEntCallback); if (!p) return; @@ -999,7 +1070,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) p->die += 1.0; int Spot = 0; - for (unsigned int i = 0; i < MAX_TEMPENT_EXTRA; i++) + for (int i = 0; i < MAX_TEMPENT_EXTRA; i++) if (!g_TempEntExtra[i].Active) { Spot = i; @@ -1034,6 +1105,9 @@ void CScript::CLScriptedEffect(msstringlist &Params) g_CurrentTempEnt = NULL; } } + + if (pParticle) + pParticle->SyncFromTemp(); } else if (Params[1] == "set_current_prop") @@ -1151,7 +1225,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) static mslist ValueParams; ValueParams.clearitems(); - for (unsigned int i = 0; i < Params.size() - 3; i++) + for (int i = 0; i < Params.size() - 3; i++) ValueParams.add(&(Params[i + 3])); SetClEntityProp(p->entity, Cmd, ValueParams); @@ -1217,7 +1291,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) static mslist ValueParams; ValueParams.clearitems(); - for (unsigned int i = 0; i < Params.size() - 3; i++) + for (int i = 0; i < Params.size() - 3; i++) ValueParams.add(&Params[i + 3]); SetClEntityProp(*g_CurrentEnt, Cmd, ValueParams); @@ -1243,7 +1317,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) static mslist ValueParams; ValueParams.clearitems(); - for (unsigned int i = 0; i < Params.size() - 3; i++) + for (int i = 0; i < Params.size() - 3; i++) ValueParams.add(&Params[i + 3]); SetClEntityProp(*pEnt, Cmd, ValueParams); @@ -1258,7 +1332,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) dlight_t NewLight; clrmem(NewLight); bool EntityLight = false; - unsigned int NextParm = 2; + int NextParm = 2; NewLight.origin = StringToVec(Params[NextParm++]); NewLight.radius = atof(Params[NextParm++]); @@ -1267,18 +1341,18 @@ void CScript::CLScriptedEffect(msstringlist &Params) NewLight.color.g = Color.y; NewLight.color.b = Color.z; NewLight.die = gEngfuncs.GetClientTime() + atof(Params[NextParm++]); - if( NextParm >= Params.size()) + + if (NextParm < Params.size()) // optional flags param present { - msstring &Flags = Params[NextParm++]; + msstring& Flags = Params[NextParm++]; if (Flags.contains("entity")) EntityLight = true; if (Flags.contains("dark")) NewLight.dark = true; } - dlight_t *pLight = Params[1] == "new" ? (EntityLight ? gEngfuncs.pEfxAPI->CL_AllocElight(0) : gEngfuncs.pEfxAPI->CL_AllocDlight(0)) : (dlight_t *)atoi(Params[1]); + dlight_t* pLight = Params[1] == "new" ? (EntityLight ? gEngfuncs.pEfxAPI->CL_AllocElight(0) : gEngfuncs.pEfxAPI->CL_AllocDlight(0)) : (dlight_t*)atoi(Params[1]); - //AUG2013_19 - Thothie - extended conditional to encase m_gLastLightID line for saftey if (pLight) { memcpy(pLight, &NewLight, sizeof(dlight_t)); @@ -1421,7 +1495,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) if ( m_Beams.size() > 0 ) { float gcltime = gEngfuncs.GetClientTime(); - for (unsigned int i = 0; i < m_Beams.size(); i++) + for (int i = 0; i < m_Beams.size(); i++) if ( m_Beams[i]->die > 0 && m_Beams[i]->die < gcltime ) m_Beams.erase(i); } @@ -1454,7 +1528,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) if (Params.size() >= 2 && Params[1] == "removeall") { size_t size = m_Beams.size(); - for (unsigned int i = 0; i < size; i++) + for (int i = 0; i < size; i++) { BEAM* pBeam = m_Beams[i]; if ( pBeam ) pBeam->die = 0; @@ -1469,7 +1543,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) /* bool found_beam =false; - for (unsigned int i = 0; i < m_Beams.size(); i++) + for (int i = 0; i < m_Beams.size(); i++) { Print("DEBUG: beam_update checking %i for %i\n",i,beamid); if ( m_Beams[i]->id == beamid ) @@ -1566,7 +1640,7 @@ void CScript::CLScriptedEffect(msstringlist &Params) /*if(Params[2].contains("clmsg")) { msstring sTemp = "ce"; - for (unsigned int i = 0; i < Params.size(); i++) //Thothie SEP2019_03 - fix need for "x" param (was Params.size()-1 ) + for (int i = 0; i < Params.size(); i++) //Thothie SEP2019_03 - fix need for "x" param (was Params.size()-1 ) { if (i > 0) { @@ -1761,7 +1835,7 @@ void SetClEntityProp(cl_entity_t &Ent, msstring &Cmd, mslist &Params else if (Cmd == "frame") Ent.curstate.frame = atof(Value); else if (Cmd == "update") - atoi(Value) ? SetBits(Ent.curstate.iuser4, MSTEMPENT_CALLBACK) : ClearBits(Ent.curstate.iuser4, MSTEMPENT_CALLBACK); + Ent.curstate.iuser4 = atoi(Value) ? SetBits(Ent.curstate.iuser4, MSTEMPENT_CALLBACK) : ClearBits(Ent.curstate.iuser4, MSTEMPENT_CALLBACK); else if (Cmd == "rendermode") { if (Value.find("normal") != msstring_error) @@ -1913,457 +1987,509 @@ Simulation and cleanup of temporary entities ================= */ int g_TempEntCount = 0; -void DLLEXPORT HUD_TempEntUpdate( - double frametime, // Simulation time - double client_time, // Absolute time on client - double cl_gravity, // True gravity on client - TEMPENTITY **ppTempEntFree, // List of freed temporary ents - TEMPENTITY **ppTempEntActive, // List + +//Simulates one tempent for this frame. Returns false once it's finished and should be removed +//Used for the engine's tempents and for the script sprites that ParticleMan draws +static bool TempEnt_Simulate( + TEMPENTITY *pTemp, + double frametime, // Simulation time + double client_time, // Absolute time on client + double cl_gravity, // True gravity on client + int gTempEntFrame, int (*Callback_AddVisibleEntity)(cl_entity_t *pEntity), void (*Callback_TempEntPlaySound)(TEMPENTITY *pTemp, float damp)) { - - static int gTempEntFrame = 0; int i; - TEMPENTITY *pTemp, *pnext, *pprev; - float freq, CommonGravity, gravitySlow, life, fastFreq; + int active = 1; + float fastFreq = client_time * 5.5; + float gravity = -frametime * cl_gravity; + float gravitySlow = gravity * 0.5; + if (FBitSet(pTemp->entity.curstate.iuser4, MSTEMPENT_GRAVITY)) // Script altered this tempent's gravity + gravity *= pTemp->entity.curstate.gravity; - // Nothing to simulate - if (!*ppTempEntActive) + float life = pTemp->die - client_time; + + try { - if (g_TempEntNewLevel) + if (life < 0) { - for (unsigned int i = 0; i < MAX_TEMPENT_EXTRA; i++) //On level change, this is called. Clear all tempent extra data from last level - clrmem(g_TempEntExtra[i]); - - g_TempEntNewLevel = false; + if (pTemp->flags & FTENT_FADEOUT) + { + if (pTemp->entity.curstate.rendermode == kRenderNormal) + pTemp->entity.curstate.rendermode = kRenderTransTexture; + pTemp->entity.curstate.renderamt = pTemp->entity.baseline.renderamt * (1 + life * pTemp->fadeSpeed); + if (pTemp->entity.curstate.renderamt <= 0) + active = 0; + } + else + active = 0; } - return; - } - - // in order to have tents collide with players, we have to run the player prediction code so - // that the client has the player list. We run this code once when we detect any COLLIDEALL - // tent, then set this BOOL to true so the code doesn't get run again if there's more than - // one COLLIDEALL ent for this update. (often are). - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction(false, true); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers(-1); - // !!!BUGBUG -- This needs to be time based - gTempEntFrame = (gTempEntFrame + 1) & 31; - - pTemp = *ppTempEntActive; - - // !!! Don't simulate while paused.... This is sort of a hack, revisit. - if (frametime <= 0) - { - while (pTemp) + if (pTemp->entity.curstate.weaponanim) { - if (!(pTemp->flags & FTENT_NOMODEL)) + tempentextra_t &TempEntExtra = g_TempEntExtra[pTemp->entity.curstate.weaponanim]; + if (TempEntExtra.DieWithEntActive) { - Callback_AddVisibleEntity(&pTemp->entity); + pTemp->die = gEngfuncs.GetClientTime() + 10; + cl_entity_t *pOtherEnt = gEngfuncs.GetEntityByIndex(TempEntExtra.DieWithEnt); + if (!pOtherEnt || !pOtherEnt->Exists()) + { + active = 0; + TempEntExtra.DieWithEntActive = false; + } } - pTemp = pTemp->next; } - goto finish; - } - pprev = NULL; - freq = client_time * 0.01; - fastFreq = client_time * 5.5; - CommonGravity = -frametime * cl_gravity; - gravitySlow = CommonGravity * 0.5; + if (active) + { + //Save old origin + VectorCopy(pTemp->entity.origin, pTemp->entity.prevstate.origin); - g_TempEntCount = 0; - while (pTemp) - { - g_TempEntCount++; - int active; - float gravity = CommonGravity; - if (FBitSet(pTemp->entity.curstate.iuser4, MSTEMPENT_GRAVITY)) // Script altered this tempent's gravity - gravity *= pTemp->entity.curstate.gravity; + //if Following, origin always equals attachment point + if (FBitSet(pTemp->entity.curstate.iuser4, MSTEMPENT_FOLLOWENT)) + { + cl_entity_t *pOtherEnt = gEngfuncs.GetEntityByIndex(pTemp->entity.curstate.aiment); + if (pOtherEnt) + pTemp->entity.origin = pOtherEnt->origin; + } - active = 1; - life = pTemp->die - client_time; + //Handle timer callback + //===================== + if (pTemp->entity.curstate.weaponanim) + { + tempentextra_t &TempExtra = g_TempEntExtra[pTemp->entity.curstate.weaponanim]; + if (TempExtra.CBTimer_Enabled) + if (client_time >= TempExtra.CBTimer_TimeCallback) + { + TempExtra.CBTimer_Enabled = false; - pnext = pTemp->next; + g_CurrentTempEnt = pTemp; + HUDScript->Effects_UpdateTempEnt(TempExtra.CBTimer_CallbackEvent); + g_CurrentTempEnt = NULL; + } - try - { - if (life < 0) - { - if (pTemp->flags & FTENT_FADEOUT) + //Handle Fade + //=========== + if (TempExtra.Fadeout) { + float Elapsed = client_time - TempExtra.FadeStart; + float Ratio = Elapsed / (TempExtra.FadeDuration ? TempExtra.FadeDuration : 1); if (pTemp->entity.curstate.rendermode == kRenderNormal) pTemp->entity.curstate.rendermode = kRenderTransTexture; - pTemp->entity.curstate.renderamt = pTemp->entity.baseline.renderamt * (1 + life * pTemp->fadeSpeed); - if (pTemp->entity.curstate.renderamt <= 0) - active = 0; + pTemp->entity.curstate.renderamt = 255 * (1 - Ratio); } - else - active = 0; - } - if (pTemp->entity.curstate.weaponanim) - { - tempentextra_t &TempEntExtra = g_TempEntExtra[pTemp->entity.curstate.weaponanim]; - if (TempEntExtra.DieWithEntActive) - { - pTemp->die = gEngfuncs.GetClientTime() + 10; - cl_entity_t *pOtherEnt = gEngfuncs.GetEntityByIndex(TempEntExtra.DieWithEnt); - if (!pOtherEnt || !pOtherEnt->Exists()) + //Check water touch + if (TempExtra.CBWater_Enabled) + if (EngineFunc::Shared_PointContents(Vector(pTemp->entity.origin.x, pTemp->entity.origin.y, pTemp->entity.origin.z + pTemp->entity.curstate.mins.z)) == CONTENTS_WATER) { - active = 0; - TempEntExtra.DieWithEntActive = false; + TempExtra.CBWater_Enabled = false; + g_CurrentTempEnt = pTemp; + HUDScript->Effects_UpdateTempEnt(TempExtra.CBWater_CallbackEvent); + g_CurrentTempEnt = NULL; } - } } - if (!active) // Kill it + if (pTemp->flags & FTENT_SPARKSHOWER) { - pTemp->next = *ppTempEntFree; - *ppTempEntFree = pTemp; - if (!pprev) // Deleting at head of list - *ppTempEntActive = pnext; - else - pprev->next = pnext; - - if (pTemp->entity.curstate.weaponanim) + // Adjust speed if it's time + // Scale is next think time + if (client_time > pTemp->entity.baseline.scale) { - tempentextra_t &TempEntExtra = g_TempEntExtra[pTemp->entity.curstate.weaponanim]; - TempEntExtra.Active = false; - } - } - else - { - pprev = pTemp; + // Show Sparks + gEngfuncs.pEfxAPI->R_SparkEffect(pTemp->entity.origin, 8, -200, 200); - //Save old origin - VectorCopy(pTemp->entity.origin, pTemp->entity.prevstate.origin); + // Reduce life + pTemp->entity.baseline.framerate -= 0.1; - //if Following, origin always equals attachment point - if (FBitSet(pTemp->entity.curstate.iuser4, MSTEMPENT_FOLLOWENT)) - { - cl_entity_t *pOtherEnt = gEngfuncs.GetEntityByIndex(pTemp->entity.curstate.aiment); - if (pOtherEnt) - pTemp->entity.origin = pOtherEnt->origin; - } - - //Handle timer callback - //===================== - if (pTemp->entity.curstate.weaponanim) - { - tempentextra_t &TempExtra = g_TempEntExtra[pTemp->entity.curstate.weaponanim]; - if (TempExtra.CBTimer_Enabled) - if (client_time >= TempExtra.CBTimer_TimeCallback) - { - TempExtra.CBTimer_Enabled = false; - - g_CurrentTempEnt = pTemp; - gHUD.m_HUDScript->Effects_UpdateTempEnt(TempExtra.CBTimer_CallbackEvent); - g_CurrentTempEnt = NULL; - } - - //Handle Fade - //=========== - if (TempExtra.Fadeout) + if (pTemp->entity.baseline.framerate <= 0.0) { - float Elapsed = client_time - TempExtra.FadeStart; - float Ratio = Elapsed / (TempExtra.FadeDuration ? TempExtra.FadeDuration : 1); - if (pTemp->entity.curstate.rendermode == kRenderNormal) - pTemp->entity.curstate.rendermode = kRenderTransTexture; - pTemp->entity.curstate.renderamt = 255 * (1 - Ratio); + pTemp->die = client_time; } - - //Check water touch - if (TempExtra.CBWater_Enabled) - if (EngineFunc::Shared_PointContents(Vector(pTemp->entity.origin.x, pTemp->entity.origin.y, pTemp->entity.origin.z + pTemp->entity.curstate.mins.z)) == CONTENTS_WATER) - { - TempExtra.CBWater_Enabled = false; - g_CurrentTempEnt = pTemp; - gHUD.m_HUDScript->Effects_UpdateTempEnt(TempExtra.CBWater_CallbackEvent); - g_CurrentTempEnt = NULL; - } - } - - if (pTemp->flags & FTENT_SPARKSHOWER) - { - // Adjust speed if it's time - // Scale is next think time - if (client_time > pTemp->entity.baseline.scale) + else { - // Show Sparks - gEngfuncs.pEfxAPI->R_SparkEffect(pTemp->entity.origin, 8, -200, 200); - - // Reduce life - pTemp->entity.baseline.framerate -= 0.1; + // So it will die no matter what + pTemp->die = client_time + 0.5; - if (pTemp->entity.baseline.framerate <= 0.0) - { - pTemp->die = client_time; - } - else - { - // So it will die no matter what - pTemp->die = client_time + 0.5; - - // Next think - pTemp->entity.baseline.scale = client_time + 0.1; - } + // Next think + pTemp->entity.baseline.scale = client_time + 0.1; } } - else if (pTemp->flags & FTENT_PLYRATTACHMENT) - { - cl_entity_t *pClient; + } + else if (pTemp->flags & FTENT_PLYRATTACHMENT) + { + cl_entity_t *pClient; - pClient = gEngfuncs.GetEntityByIndex(pTemp->clientIndex); + pClient = gEngfuncs.GetEntityByIndex(pTemp->clientIndex); - VectorAdd(pClient->origin, pTemp->tentOffset, pTemp->entity.origin); - } - else if (pTemp->flags & FTENT_SINEWAVE) - { - pTemp->x += pTemp->entity.baseline.origin[0] * frametime; - pTemp->y += pTemp->entity.baseline.origin[1] * frametime; + VectorAdd(pClient->origin, pTemp->tentOffset, pTemp->entity.origin); + } + else if (pTemp->flags & FTENT_SINEWAVE) + { + pTemp->x += pTemp->entity.baseline.origin[0] * frametime; + pTemp->y += pTemp->entity.baseline.origin[1] * frametime; - pTemp->entity.origin[0] = pTemp->x + sin(pTemp->entity.baseline.origin[2] + client_time * pTemp->entity.prevstate.frame) * (10 * pTemp->entity.curstate.framerate); - pTemp->entity.origin[1] = pTemp->y + sin(pTemp->entity.baseline.origin[2] + fastFreq + 0.7) * (8 * pTemp->entity.curstate.framerate); - pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; - } - else if (pTemp->flags & FTENT_SPIRAL) - { - float s, c; - s = sin(pTemp->entity.baseline.origin[2] + fastFreq); - c = cos(pTemp->entity.baseline.origin[2] + fastFreq); + pTemp->entity.origin[0] = pTemp->x + sin(pTemp->entity.baseline.origin[2] + client_time * pTemp->entity.prevstate.frame) * (10 * pTemp->entity.curstate.framerate); + pTemp->entity.origin[1] = pTemp->y + sin(pTemp->entity.baseline.origin[2] + fastFreq + 0.7) * (8 * pTemp->entity.curstate.framerate); + pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; + } + else if (pTemp->flags & FTENT_SPIRAL) + { + float s, c; + s = sin(pTemp->entity.baseline.origin[2] + fastFreq); + c = cos(pTemp->entity.baseline.origin[2] + fastFreq); - pTemp->entity.origin[0] += pTemp->entity.baseline.origin[0] * frametime + 8 * sin(client_time * 20 + (int)pTemp); - pTemp->entity.origin[1] += pTemp->entity.baseline.origin[1] * frametime + 4 * sin(client_time * 30 + (int)pTemp); - pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; - } + pTemp->entity.origin[0] += pTemp->entity.baseline.origin[0] * frametime + 8 * sin(client_time * 20 + (int)pTemp); + pTemp->entity.origin[1] += pTemp->entity.baseline.origin[1] * frametime + 4 * sin(client_time * 30 + (int)pTemp); + pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; + } - else - { - for (i = 0; i < 3; i++) - pTemp->entity.origin[i] += pTemp->entity.baseline.origin[i] * frametime; - } + else + { + for (i = 0; i < 3; i++) + pTemp->entity.origin[i] += pTemp->entity.baseline.origin[i] * frametime; + } - if (pTemp->flags & FTENT_SPRANIMATE) + if (pTemp->flags & FTENT_SPRANIMATE) + { + pTemp->entity.curstate.frame += frametime * pTemp->entity.curstate.framerate; + if (pTemp->entity.curstate.frame >= pTemp->frameMax) { - pTemp->entity.curstate.frame += frametime * pTemp->entity.curstate.framerate; - if (pTemp->entity.curstate.frame >= pTemp->frameMax) - { - pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame); + pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame); - if (!(pTemp->flags & FTENT_SPRANIMATELOOP)) - { - // this animating sprite isn't set to loop, so destroy it. - pTemp->die = client_time; - pTemp = pnext; - continue; - } + if (!(pTemp->flags & FTENT_SPRANIMATELOOP)) + { + // this animating sprite isn't set to loop, so destroy it. + pTemp->die = client_time; + return true; } } - else if (pTemp->flags & FTENT_SPRCYCLE) + } + else if (pTemp->flags & FTENT_SPRCYCLE) + { + pTemp->entity.curstate.frame += frametime * 10; + if (pTemp->entity.curstate.frame >= pTemp->frameMax) { - pTemp->entity.curstate.frame += frametime * 10; - if (pTemp->entity.curstate.frame >= pTemp->frameMax) - { - pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame); - } + pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame); } + } // Experiment #if 0 - if ( pTemp->flags & FTENT_SCALE ) - pTemp->entity.curstate.framerate += 20.0 * (frametime / pTemp->entity.curstate.framerate); + if ( pTemp->flags & FTENT_SCALE ) + pTemp->entity.curstate.framerate += 20.0 * (frametime / pTemp->entity.curstate.framerate); #endif - if (pTemp->flags & FTENT_ROTATE) - { - pTemp->entity.angles[0] += pTemp->entity.baseline.angles[0] * frametime; - pTemp->entity.angles[1] += pTemp->entity.baseline.angles[1] * frametime; - pTemp->entity.angles[2] += pTemp->entity.baseline.angles[2] * frametime; + if (pTemp->flags & FTENT_ROTATE) + { + pTemp->entity.angles[0] += pTemp->entity.baseline.angles[0] * frametime; + pTemp->entity.angles[1] += pTemp->entity.baseline.angles[1] * frametime; + pTemp->entity.angles[2] += pTemp->entity.baseline.angles[2] * frametime; - VectorCopy(pTemp->entity.angles, pTemp->entity.latched.prevangles); - } + VectorCopy(pTemp->entity.angles, pTemp->entity.latched.prevangles); + } - if (pTemp->flags & (FTENT_COLLIDEALL | FTENT_COLLIDEWORLD)) - { - Vector traceNormal; - float traceFraction = 1; + if (pTemp->flags & (FTENT_COLLIDEALL | FTENT_COLLIDEWORLD)) + { + Vector traceNormal; + float traceFraction = 1; - if (pTemp->flags & FTENT_COLLIDEALL) - { - pmtrace_t pmtrace; - physent_t *pe; + if (pTemp->flags & FTENT_COLLIDEALL) + { + pmtrace_t pmtrace; + physent_t *pe; - gEngfuncs.pEventAPI->EV_SetTraceHull(2); + gEngfuncs.pEventAPI->EV_SetTraceHull(2); - gEngfuncs.pEventAPI->EV_PlayerTrace(pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX, -1, &pmtrace); + gEngfuncs.pEventAPI->EV_PlayerTrace(pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX, -1, &pmtrace); - if (pmtrace.fraction != 1) + if (pmtrace.fraction != 1) + { + pe = gEngfuncs.pEventAPI->EV_GetPhysent(pmtrace.ent); + //AUG2013_25 - seeing if we can make cl projectile skip its owner + bool skip_ent = false; + if (pTemp->flags & (FTENT_SKIPENT)) { - pe = gEngfuncs.pEventAPI->EV_GetPhysent(pmtrace.ent); - //AUG2013_25 - seeing if we can make cl projectile skip its owner - bool skip_ent = false; - if (pTemp->flags & (FTENT_SKIPENT)) - { - int iSkipent = pTemp->entity.curstate.iuser1; - if (iSkipent && pe->info == iSkipent) - skip_ent = true; - } - if (!skip_ent) + int iSkipent = pTemp->entity.curstate.iuser1; + if (iSkipent && pe->info == iSkipent) + skip_ent = true; + } + if (!skip_ent) + { + if (!pmtrace.ent || (pe->info != pTemp->clientIndex)) { - if (!pmtrace.ent || (pe->info != pTemp->clientIndex)) + traceFraction = pmtrace.fraction; + VectorCopy(pmtrace.plane.normal, traceNormal); + + if (pTemp->hitcallback) { - traceFraction = pmtrace.fraction; - VectorCopy(pmtrace.plane.normal, traceNormal); - - if (pTemp->hitcallback) - { - pmtrace.ent = pe->info; //AUG2013_24 Thothie - make collide callback return model (bit of a hack to store the info here, but works.) - (*pTemp->hitcallback)(pTemp, &pmtrace); - } + pmtrace.ent = pe->info; //AUG2013_24 Thothie - make collide callback return model (bit of a hack to store the info here, but works.) + (*pTemp->hitcallback)(pTemp, &pmtrace); } } } } - else if (pTemp->flags & FTENT_COLLIDEWORLD) - { - pmtrace_t pmtrace; + } + else if (pTemp->flags & FTENT_COLLIDEWORLD) + { + pmtrace_t pmtrace; - gEngfuncs.pEventAPI->EV_SetTraceHull(2); + gEngfuncs.pEventAPI->EV_SetTraceHull(2); - gEngfuncs.pEventAPI->EV_PlayerTrace(pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX | PM_WORLD_ONLY, -1, &pmtrace); + gEngfuncs.pEventAPI->EV_PlayerTrace(pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX | PM_WORLD_ONLY, -1, &pmtrace); - if (pmtrace.fraction != 1) + if (pmtrace.fraction != 1) + { + traceFraction = pmtrace.fraction; + VectorCopy(pmtrace.plane.normal, traceNormal); + + if (pTemp->flags & FTENT_SPARKSHOWER) { - traceFraction = pmtrace.fraction; - VectorCopy(pmtrace.plane.normal, traceNormal); + // Chop spark speeds a bit more + // + VectorScale(pTemp->entity.baseline.origin, 0.6, pTemp->entity.baseline.origin); - if (pTemp->flags & FTENT_SPARKSHOWER) + if (Length(pTemp->entity.baseline.origin) < 10) { - // Chop spark speeds a bit more - // - VectorScale(pTemp->entity.baseline.origin, 0.6, pTemp->entity.baseline.origin); - - if (Length(pTemp->entity.baseline.origin) < 10) - { - pTemp->entity.baseline.framerate = 0.0; - } + pTemp->entity.baseline.framerate = 0.0; } + } - if (pTemp->hitcallback) - { - (*pTemp->hitcallback)(pTemp, &pmtrace); - } + if (pTemp->hitcallback) + { + (*pTemp->hitcallback)(pTemp, &pmtrace); } } + } - if (traceFraction != 1) // Decent collision now, and damping works - { - float proj, damp; + if (traceFraction != 1) // Decent collision now, and damping works + { + float proj, damp; - // Place at contact point - VectorMA(pTemp->entity.prevstate.origin, traceFraction * frametime, pTemp->entity.baseline.origin, pTemp->entity.origin); - // Damp velocity - damp = pTemp->bounceFactor; - if (pTemp->flags & (FTENT_GRAVITY | FTENT_SLOWGRAVITY)) + // Place at contact point + VectorMA(pTemp->entity.prevstate.origin, traceFraction * frametime, pTemp->entity.baseline.origin, pTemp->entity.origin); + // Damp velocity + damp = pTemp->bounceFactor; + if (pTemp->flags & (FTENT_GRAVITY | FTENT_SLOWGRAVITY)) + { + damp *= 0.5; + if (traceNormal[2] > 0.9) // Hit floor? { - damp *= 0.5; - if (traceNormal[2] > 0.9) // Hit floor? + if (pTemp->entity.baseline.origin[2] <= 0 && pTemp->entity.baseline.origin[2] >= gravity * 3) { - if (pTemp->entity.baseline.origin[2] <= 0 && pTemp->entity.baseline.origin[2] >= gravity * 3) - { - damp = 0; // Stop - pTemp->flags &= ~(FTENT_ROTATE | FTENT_GRAVITY | FTENT_SLOWGRAVITY | FTENT_COLLIDEWORLD | FTENT_SMOKETRAIL); - pTemp->entity.angles[0] = 0; - pTemp->entity.angles[2] = 0; - } + damp = 0; // Stop + pTemp->flags &= ~(FTENT_ROTATE | FTENT_GRAVITY | FTENT_SLOWGRAVITY | FTENT_COLLIDEWORLD | FTENT_SMOKETRAIL); + pTemp->entity.angles[0] = 0; + pTemp->entity.angles[2] = 0; } } + } - if (pTemp->hitSound) - { - Callback_TempEntPlaySound(pTemp, damp); - } + if (pTemp->hitSound) + { + Callback_TempEntPlaySound(pTemp, damp); + } - if (pTemp->flags & FTENT_COLLIDEKILL) - { - // die on impact - pTemp->flags &= ~FTENT_FADEOUT; - pTemp->die = client_time; - } - else + if (pTemp->flags & FTENT_COLLIDEKILL) + { + // die on impact + pTemp->flags &= ~FTENT_FADEOUT; + pTemp->die = client_time; + } + else + { + // Reflect velocity + if (damp != 0) { - // Reflect velocity - if (damp != 0) - { - proj = DotProduct(pTemp->entity.baseline.origin, traceNormal); - VectorMA(pTemp->entity.baseline.origin, -proj * 2, traceNormal, pTemp->entity.baseline.origin); - // Reflect rotation (fake) + proj = DotProduct(pTemp->entity.baseline.origin, traceNormal); + VectorMA(pTemp->entity.baseline.origin, -proj * 2, traceNormal, pTemp->entity.baseline.origin); + // Reflect rotation (fake) - pTemp->entity.angles[1] = -pTemp->entity.angles[1]; - } + pTemp->entity.angles[1] = -pTemp->entity.angles[1]; + } - if (damp != 1) - { + if (damp != 1) + { - VectorScale(pTemp->entity.baseline.origin, damp, pTemp->entity.baseline.origin); - VectorScale(pTemp->entity.angles, 0.9, pTemp->entity.angles); - } + VectorScale(pTemp->entity.baseline.origin, damp, pTemp->entity.baseline.origin); + VectorScale(pTemp->entity.angles, 0.9, pTemp->entity.angles); } } } + } - if ((pTemp->flags & FTENT_FLICKER) && gTempEntFrame == pTemp->entity.curstate.effects) - { - dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight(0); - VectorCopy(pTemp->entity.origin, dl->origin); - dl->radius = 60; - dl->color.r = 255; - dl->color.g = 120; - dl->color.b = 0; - dl->die = client_time + 0.01; - } + if ((pTemp->flags & FTENT_FLICKER) && gTempEntFrame == pTemp->entity.curstate.effects) + { + dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight(0); + VectorCopy(pTemp->entity.origin, dl->origin); + dl->radius = 60; + dl->color.r = 255; + dl->color.g = 120; + dl->color.b = 0; + dl->die = client_time + 0.01; + } - if (pTemp->flags & FTENT_SMOKETRAIL) - { - gEngfuncs.pEfxAPI->R_RocketTrail(pTemp->entity.prevstate.origin, pTemp->entity.origin, 1); - } + if (pTemp->flags & FTENT_SMOKETRAIL) + { + gEngfuncs.pEfxAPI->R_RocketTrail(pTemp->entity.prevstate.origin, pTemp->entity.origin, 1); + } - if (pTemp->flags & FTENT_GRAVITY) - pTemp->entity.baseline.origin[2] += gravity; - else if (pTemp->flags & FTENT_SLOWGRAVITY) - pTemp->entity.baseline.origin[2] += gravitySlow; + if (pTemp->flags & FTENT_GRAVITY) + pTemp->entity.baseline.origin[2] += gravity; + else if (pTemp->flags & FTENT_SLOWGRAVITY) + pTemp->entity.baseline.origin[2] += gravitySlow; - if (pTemp->flags & FTENT_CLIENTCUSTOM) + if (pTemp->flags & FTENT_CLIENTCUSTOM) + { + if (pTemp->callback) { - if (pTemp->callback) - { - (*pTemp->callback)(pTemp, frametime, client_time); - } + (*pTemp->callback)(pTemp, frametime, client_time); } + } - // Cull to PVS (not frustum cull, just PVS) - if (!(pTemp->flags & FTENT_NOMODEL)) + // Cull to PVS (not frustum cull, just PVS) + if (!(pTemp->flags & FTENT_NOMODEL)) + { + if (!Callback_AddVisibleEntity(&pTemp->entity)) { - if (!Callback_AddVisibleEntity(&pTemp->entity)) + if (!(pTemp->flags & FTENT_PERSIST)) { - if (!(pTemp->flags & FTENT_PERSIST)) - { - pTemp->die = client_time; // If we can't draw it this frame, just dump it. - pTemp->flags &= ~FTENT_FADEOUT; // Don't fade out, just die - } + pTemp->die = client_time; // If we can't draw it this frame, just dump it. + pTemp->flags &= ~FTENT_FADEOUT; // Don't fade out, just die } } } - pTemp->entity.baseline.vuser1 = pTemp->entity.baseline.origin; } - catch (...) + pTemp->entity.baseline.vuser1 = pTemp->entity.baseline.origin; + } + catch (...) + { + } + + return active != 0; +} + +//Script sprites that ParticleMan draws. They're simulated here, alongside the engine's tempents, so +//their script callbacks and collision traces run at the same point in the frame as they always have +static void ScriptParticles_Simulate( + double frametime, + double client_time, + double cl_gravity, + int gTempEntFrame, + int (*Callback_AddVisibleEntity)(cl_entity_t *pEntity), + void (*Callback_TempEntPlaySound)(TEMPENTITY *pTemp, float damp)) +{ + //Any that get created by a callback in here start simulating next frame + const size_t Count = g_ScriptParticles.size(); + for (size_t i = 0; i < Count; i++) + { + CScriptParticle &Particle = *g_ScriptParticles[i]; + if (Particle.m_flDieTime) + continue; //Already dead, waiting on ParticleMan to delete it + + bool Active = TempEnt_Simulate(&Particle.m_Temp, frametime, client_time, cl_gravity, gTempEntFrame, Callback_AddVisibleEntity, Callback_TempEntPlaySound); + + //The engine dumps a tempent that it can't draw this frame. Do the same + if (!Particle.GetParticlePVS() && !FBitSet(Particle.m_Temp.flags, FTENT_PERSIST)) + Active = false; + + if (Active) + Particle.SyncFromTemp(); + else + Particle.m_flDieTime = gEngfuncs.GetClientTime(); + } +} + +void DLLEXPORT HUD_TempEntUpdate( + double frametime, // Simulation time + double client_time, // Absolute time on client + double cl_gravity, // True gravity on client + TEMPENTITY **ppTempEntFree, // List of freed temporary ents + TEMPENTITY **ppTempEntActive, // List + int (*Callback_AddVisibleEntity)(cl_entity_t *pEntity), + void (*Callback_TempEntPlaySound)(TEMPENTITY *pTemp, float damp)) +{ + + static int gTempEntFrame = 0; + TEMPENTITY *pTemp, *pnext, *pprev; + + Vector vAngles; + gEngfuncs.GetViewAngles((float*)vAngles); + + if ( g_pParticleMan ) + g_pParticleMan->SetVariables(cl_gravity, vAngles); + + // Nothing to simulate + if (!*ppTempEntActive && g_ScriptParticles.empty()) + { + if (g_TempEntNewLevel) + { + for (int i = 0; i < MAX_TEMPENT_EXTRA; i++) //On level change, this is called. Clear all tempent extra data from last level + clrmem(g_TempEntExtra[i]); + + g_TempEntNewLevel = false; + } + return; + } + + // in order to have tents collide with players, we have to run the player prediction code so + // that the client has the player list. We run this code once when we detect any COLLIDEALL + // tent, then set this BOOL to true so the code doesn't get run again if there's more than + // one COLLIDEALL ent for this update. (often are). + gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction(false, true); + + // Store off the old count + gEngfuncs.pEventAPI->EV_PushPMStates(); + + // Now add in all of the players. + gEngfuncs.pEventAPI->EV_SetSolidPlayers(-1); + + // !!!BUGBUG -- This needs to be time based + gTempEntFrame = (gTempEntFrame + 1) & 31; + + //Done before reading the active list, because the script callbacks in here can add tempents to it + if (frametime > 0) + ScriptParticles_Simulate(frametime, client_time, cl_gravity, gTempEntFrame, Callback_AddVisibleEntity, Callback_TempEntPlaySound); + + pTemp = *ppTempEntActive; + + // !!! Don't simulate while paused.... This is sort of a hack, revisit. + if (frametime <= 0) + { + while (pTemp) + { + if (!(pTemp->flags & FTENT_NOMODEL)) + { + Callback_AddVisibleEntity(&pTemp->entity); + } + pTemp = pTemp->next; + } + goto finish; + } + + pprev = NULL; + + g_TempEntCount = 0; + while (pTemp) + { + g_TempEntCount++; + pnext = pTemp->next; + + if (TempEnt_Simulate(pTemp, frametime, client_time, cl_gravity, gTempEntFrame, Callback_AddVisibleEntity, Callback_TempEntPlaySound)) + pprev = pTemp; + else // Kill it { + pTemp->next = *ppTempEntFree; + *ppTempEntFree = pTemp; + if (!pprev) // Deleting at head of list + *ppTempEntActive = pnext; + else + pprev->next = pnext; + + if (pTemp->entity.curstate.weaponanim) + { + tempentextra_t &TempEntExtra = g_TempEntExtra[pTemp->entity.curstate.weaponanim]; + TempEntExtra.Active = false; + } } pTemp = pnext; diff --git a/src/game/client/ev_hldm.cpp b/src/game/client/ev_hldm.cpp index 162de8e4c..6d709cc38 100644 --- a/src/game/client/ev_hldm.cpp +++ b/src/game/client/ev_hldm.cpp @@ -52,20 +52,18 @@ extern "C" void EV_TrainPitchAdjust(struct event_args_s *args); } - - -constexpr Vector VECTOR_CONE_1DEGREES = Vector(0.00873, 0.00873, 0.00873); -constexpr Vector VECTOR_CONE_2DEGREES = Vector(0.01745, 0.01745, 0.01745); -constexpr Vector VECTOR_CONE_3DEGREES = Vector(0.02618, 0.02618, 0.02618); -constexpr Vector VECTOR_CONE_4DEGREES = Vector(0.03490, 0.03490, 0.03490); -constexpr Vector VECTOR_CONE_5DEGREES = Vector(0.04362, 0.04362, 0.04362); -constexpr Vector VECTOR_CONE_6DEGREES = Vector(0.05234, 0.05234, 0.05234); -constexpr Vector VECTOR_CONE_7DEGREES = Vector(0.06105, 0.06105, 0.06105); -constexpr Vector VECTOR_CONE_8DEGREES = Vector(0.06976, 0.06976, 0.06976); -constexpr Vector VECTOR_CONE_9DEGREES = Vector(0.07846, 0.07846, 0.07846); -constexpr Vector VECTOR_CONE_10DEGREES = Vector(0.08716, 0.08716, 0.08716); -constexpr Vector VECTOR_CONE_15DEGREES = Vector(0.13053, 0.13053, 0.13053); -constexpr Vector VECTOR_CONE_20DEGREES = Vector(0.17365, 0.17365, 0.17365); +#define VECTOR_CONE_1DEGREES Vector(0.00873, 0.00873, 0.00873) +#define VECTOR_CONE_2DEGREES Vector(0.01745, 0.01745, 0.01745) +#define VECTOR_CONE_3DEGREES Vector(0.02618, 0.02618, 0.02618) +#define VECTOR_CONE_4DEGREES Vector(0.03490, 0.03490, 0.03490) +#define VECTOR_CONE_5DEGREES Vector(0.04362, 0.04362, 0.04362) +#define VECTOR_CONE_6DEGREES Vector(0.05234, 0.05234, 0.05234) +#define VECTOR_CONE_7DEGREES Vector(0.06105, 0.06105, 0.06105) +#define VECTOR_CONE_8DEGREES Vector(0.06976, 0.06976, 0.06976) +#define VECTOR_CONE_9DEGREES Vector(0.07846, 0.07846, 0.07846) +#define VECTOR_CONE_10DEGREES Vector(0.08716, 0.08716, 0.08716) +#define VECTOR_CONE_15DEGREES Vector(0.13053, 0.13053, 0.13053) +#define VECTOR_CONE_20DEGREES Vector(0.17365, 0.17365, 0.17365) // play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the // original traceline endpoints used by the attacker, iBulletType is the type of bullet that hit the texture. @@ -117,7 +115,7 @@ float EV_HLDM_PlayTextureSound(int idx, pmtrace_t *ptr, float *vecSrc, float *ve // '}}' strncpy(szbuffer, pTextureName, sizeof(szbuffer)); - szbuffer[MAX_CBTEXTURENAME - 1] = 0; + szbuffer[CBTEXTURENAMEMAX - 1] = 0; // get texture type chTextureType = PM_FindTextureType(szbuffer); @@ -369,7 +367,7 @@ FireBullets Go to the trouble of combining multiple pellets into a single damage call. ================ */ -void EV_HLDM_FireBullets(int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount) +void EV_HLDM_FireBullets(int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float *vecSpread, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount) { int i; pmtrace_t tr; @@ -804,9 +802,7 @@ void EV_FirePython(event_args_t *args) } } -enum { - SND_CHANGE_PITCH = (1 << 7) // duplicated in protocol.h change sound pitch -}; +#define SND_CHANGE_PITCH (1 << 7) // duplicated in protocol.h change sound pitch void EV_SpinGauss(event_args_t *args) { diff --git a/src/game/client/ev_hldm.h b/src/game/client/ev_hldm.h index 885f5ddcf..fb3279ce6 100644 --- a/src/game/client/ev_hldm.h +++ b/src/game/client/ev_hldm.h @@ -68,12 +68,9 @@ enum python_e PYTHON_IDLE3 }; -enum { +#define GAUSS_PRIMARY_CHARGE_VOLUME 256 // how loud gauss is while charging +#define GAUSS_PRIMARY_FIRE_VOLUME 450 // how loud gauss is when discharged - GAUSS_PRIMARY_CHARGE_VOLUME = 256, // how loud gauss is while charging - GAUSS_PRIMARY_FIRE_VOLUME = 450 // how loud gauss is when discharged - -}; enum gauss_e { GAUSS_IDLE = 0, diff --git a/src/game/client/eventscripts.h b/src/game/client/eventscripts.h index 0fd02e45e..169819d1e 100644 --- a/src/game/client/eventscripts.h +++ b/src/game/client/eventscripts.h @@ -3,50 +3,53 @@ #define EVENTSCRIPTSH // defaults for clientinfo messages -inline constexpr int DEFAULT_VIEWHEIGHT = 28; -inline constexpr int VEC_DUCK_VIEW = 12; -//inline constexpr int FTENT_FADEOUT = 0x00000080; already defines as enum in a different file. - - -enum { - DMG_GENERIC = 0, // generic damage was done - DMG_CRUSH = (1 << 0), // crushed by falling or moving object - DMG_BULLET = (1 << 1), // shot - DMG_SLASH = (1 << 2), // cut, clawed, stabbed - DMG_BURN = (1 << 3), // heat burned - DMG_FREEZE = (1 << 4), // frozen - DMG_FALL = (1 << 5), // fell too far - DMG_BLAST = (1 << 6), // explosive blast damage - DMG_CLUB = (1 << 7), // crowbar, punch, headbutt - DMG_SHOCK = (1 << 8), // electric shock - DMG_SONIC = (1 << 9), // sound pulse shockwave - DMG_ENERGYBEAM = (1 << 10), // laser or other high energy beam - DMG_NEVERGIB = (1 << 12), // with this bit OR'd in, no damage type will be able to gib victims upon death - DMG_ALWAYSGIB = (1 << 13), // with this bit OR'd in, any damage type can be made to gib victims upon death. - - // time-based damage - //mask off TF-specific stuff too - DMG_TIMEBASED = (~(0xff003fff)), // mask for time-based damage - DMG_DROWN = (1 << 14), // Drowning - DMG_FIRSTTIMEBASED = DMG_DROWN, - DMG_PARALYZE = (1 << 15), // slows affected creature down - DMG_NERVEGAS = (1 << 16), // nerve toxins, very bad - DMG_POISON = (1 << 17), // blood poisioning - DMG_RADIATION = (1 << 18), // radiation exposure - DMG_DROWNRECOVER = (1 << 19), // drowning recovery - DMG_ACID = (1 << 20), // toxic chemicals or acid burns - DMG_SLOWBURN = (1 << 21), // in an oven - DMG_SLOWFREEZE = (1 << 22), // in a subzero freezer - DMG_MORTAR = (1 << 23), // Hit by air raid (done to distinguish grenade from mortar) - DMG_IGNITE = (1 << 24), // Players hit by this begin to burn - DMG_RADIUS_MAX = (1 << 25), // Radius damage with this flag doesn't decrease over distance - DMG_RADIUS_QUAKE = (1 << 26), // Radius damage is done like Quake. 1/2 damage at 1/2 radius. - DMG_IGNOREARMOR = (1 << 27), // Damage ignores target's armor - DMG_AIMED = (1 << 28), // Does Hit location damage - DMG_WALLPIERCING = (1 << 29), // Blast Damages ents through walls - DMG_CALTROP = (1 << 30), - DMG_HALLUC = (1 << 31) -}; +#define DEFAULT_VIEWHEIGHT 28 +#define VEC_DUCK_VIEW 12 + +#define FTENT_FADEOUT 0x00000080 + +#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. + +// time-based damage +//mask off TF-specific stuff too +#define DMG_TIMEBASED (~(0xff003fff)) // mask for time-based damage + +#define DMG_DROWN (1 << 14) // Drowning +#define DMG_FIRSTTIMEBASED DMG_DROWN + +#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) + +//TF ADDITIONS +#define DMG_IGNITE (1 << 24) // Players hit by this begin to burn +#define DMG_RADIUS_MAX (1 << 25) // Radius damage with this flag doesn't decrease over distance +#define DMG_RADIUS_QUAKE (1 << 26) // Radius damage is done like Quake. 1/2 damage at 1/2 radius. +#define DMG_IGNOREARMOR (1 << 27) // Damage ignores target's armor +#define DMG_AIMED (1 << 28) // Does Hit location damage +#define DMG_WALLPIERCING (1 << 29) // Blast Damages ents through walls + +#define DMG_CALTROP (1 << 30) +#define DMG_HALLUC (1 << 31) // Some of these are HL/TFC specific? void EV_EjectBrass(float *origin, float *velocity, float rotation, int model, int soundtype); diff --git a/src/game/client/fmod/musicsystem.cpp b/src/game/client/fmod/musicsystem.cpp index a0afae43d..6831aede5 100644 --- a/src/game/client/fmod/musicsystem.cpp +++ b/src/game/client/fmod/musicsystem.cpp @@ -20,9 +20,16 @@ void CMusicSystem::Init() void CMusicSystem::Shutdown() { if (m_pChannel) + { m_pChannel->stop(); + m_pChannel = nullptr; + } - m_pSound->release(); + if (m_pSound) + { + m_pSound->release(); + m_pSound = nullptr; + } } // Returns the name of the current ambient sound being played @@ -122,6 +129,19 @@ bool CMusicSystem::PlayMusic(std::string pszSong, bool fadeIn) m_CurSound = pszSong; char songPath[256]; _snprintf(songPath, 256, "%s/music/%s", gEngfuncs.pfnGetGameDirectory(), pszSong.c_str()); + + // Free the previous stream so each track change doesn't leak a file handle and decoder + if (m_pChannel) + { + m_pChannel->stop(); + m_pChannel = nullptr; + } + if (m_pSound) + { + m_pSound->release(); + m_pSound = nullptr; + } + FMOD_RESULT result = m_pSystem->createStream(songPath, FMOD_DEFAULT, 0, &m_pSound); if (result != FMOD_OK) diff --git a/src/game/client/fmod/musicsystem.h b/src/game/client/fmod/musicsystem.h index 0b53ae828..9193b40ce 100644 --- a/src/game/client/fmod/musicsystem.h +++ b/src/game/client/fmod/musicsystem.h @@ -40,8 +40,8 @@ class CMusicSystem float m_fFadeDelay = 0.0; float m_fVolume = 0.0; - FMOD::System* m_pSystem; - FMOD::Sound* m_pSound; - FMOD::Channel* m_pChannel = 0; - FMOD::ChannelGroup* m_pChannelGroup; + FMOD::System* m_pSystem = nullptr; + FMOD::Sound* m_pSound = nullptr; + FMOD::Channel* m_pChannel = nullptr; + FMOD::ChannelGroup* m_pChannelGroup = nullptr; }; \ No newline at end of file diff --git a/src/game/client/fmod/soundengine.cpp b/src/game/client/fmod/soundengine.cpp index a1a470151..2e50f98e3 100644 --- a/src/game/client/fmod/soundengine.cpp +++ b/src/game/client/fmod/soundengine.cpp @@ -21,6 +21,8 @@ bool CSoundEngine::InitFMOD(void) if (result != FMOD_OK) { gEngfuncs.Con_Printf("FMOD ERROR: Failed to initialize properly!\n"); + m_pSystem->release(); + m_pSystem = nullptr; return false; } else @@ -32,7 +34,11 @@ bool CSoundEngine::InitFMOD(void) // Stops FMOD bool CSoundEngine::ExitFMOD(void) { + if (!m_pSystem) + return true; + FMOD_RESULT result = m_pSystem->release(); + m_pSystem = nullptr; if (result != FMOD_OK) { diff --git a/src/game/client/fmod/soundengine.h b/src/game/client/fmod/soundengine.h index 587b9e829..7a2a16a93 100644 --- a/src/game/client/fmod/soundengine.h +++ b/src/game/client/fmod/soundengine.h @@ -17,7 +17,7 @@ class CSoundEngine //FMOD::ChannelGroup *GetChannelGroup(eChannelGroupType channelgroupType) { return m_pChannelGroups[channelgroupType]; } private: - FMOD::System *m_pSystem; + FMOD::System *m_pSystem = nullptr; const int m_NumChannels = 100; //No longer needed just pass NULL channel since we are not doing any submixing //FMOD::ChannelGroup* m_pChannelGroups[NUM_CHANNELGROUPS]; diff --git a/src/game/client/hl/hl_baseentity.cpp b/src/game/client/hl/hl_baseentity.cpp index f073ee538..db98d1f90 100644 --- a/src/game/client/hl/hl_baseentity.cpp +++ b/src/game/client/hl/hl_baseentity.cpp @@ -38,7 +38,6 @@ const Vector g_vecZero = Vector(0, 0, 0); int gmsgWeapPickup = 0; enginefuncs_t g_engfuncs; globalvars_t *gpGlobals; -constexpr int NEG_REF = -1; //----------- @@ -53,23 +52,23 @@ void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volu } // CBaseEntity Stubs -int CBaseEntity ::TakeHealth(float flHealth, int bitsDamageType) { return NULL; } -int CBaseEntity ::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return NULL; } +int CBaseEntity ::TakeHealth(float flHealth, int bitsDamageType) { return 1; } +int CBaseEntity ::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return 1; } CBaseEntity *CBaseEntity::GetNextTarget(void) { return NULL; } -int CBaseEntity::Save(CSave &save) { return NULL; } -int CBaseEntity::Restore(CRestore &restore) { return NULL; } +int CBaseEntity::Save(CSave &save) { return 1; } +int CBaseEntity::Restore(CRestore &restore) { return 1; } void CBaseEntity::SetObjectCollisionBox(void) {} -int CBaseEntity ::Intersects(CBaseEntity *pOther) { return NULL; } +int CBaseEntity ::Intersects(CBaseEntity *pOther) { return 0; } void CBaseEntity ::MakeDormant(void) {} -int CBaseEntity ::IsDormant(void) { return NULL; } -BOOL CBaseEntity ::IsInWorld(void) { return true; } -int CBaseEntity::ShouldToggle(USE_TYPE useType, BOOL currentState) { return NULL; } -int CBaseEntity ::DamageDecal(int bitsDamageType) { return NEG_REF; } +int CBaseEntity ::IsDormant(void) { return 0; } +BOOL CBaseEntity ::IsInWorld(void) { return TRUE; } +int CBaseEntity::ShouldToggle(USE_TYPE useType, BOOL currentState) { return 0; } +int CBaseEntity ::DamageDecal(int bitsDamageType) { return -1; } CBaseEntity *CBaseEntity::Create(const char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner) { return NULL; } void CBaseEntity::SUB_Remove(void) { Deactivate(); - MS_DEBUG("DELETE ITEM: %s (%i)", DisplayName(), IsMSItem() ? ((CBasePlayerItem*)this)->m_iId : NULL); + MS_DEBUG("DELETE ITEM: %s (%i)", DisplayName(), IsMSItem() ? ((CBasePlayerItem*)this)->m_iId : 0); MSCLGlobals::RemoveEnt(this, true); } //void CBaseEntity::StruckSound( CBaseEntity *pInflicter, CBaseEntity *pAttacker, float flDamage, TraceResult *ptr, int bitsDamageType ) { } @@ -77,13 +76,13 @@ void CBaseEntity::CounterEffect(CBaseEntity *pInflictor, int iEffect, void *pExt // CBaseDelay Stubs void CBaseDelay ::KeyValue(struct KeyValueData_s *) {} -int CBaseDelay::Restore(class CRestore &) { return true; } -int CBaseDelay::Save(class CSave &) { return true; } +int CBaseDelay::Restore(class CRestore &) { return 1; } +int CBaseDelay::Save(class CSave &) { return 1; } CBaseEntity *CBaseDelay::GetSelf() { return this; } // CBaseAnimating Stubs -int CBaseAnimating::Restore(class CRestore &) { return true; } -int CBaseAnimating::Save(class CSave &) { return true; } +int CBaseAnimating::Restore(class CRestore &) { return 1; } +int CBaseAnimating::Save(class CSave &) { return 1; } // DEBUG Stubs edict_t *DBG_EntOfVars(const entvars_t *pev) { return NULL; } @@ -95,9 +94,9 @@ void UTIL_BloodDrips(const Vector &origin, const Vector &direction, int color, i void UTIL_DecalTrace(TraceResult *pTrace, int decalNumber) {} void UTIL_GunshotDecalTrace(TraceResult *pTrace, int decalNumber) {} void UTIL_MakeVectors(const Vector &vecAngles) {} -BOOL UTIL_IsValidEntity(edict_t *pent) { return true; } +BOOL UTIL_IsValidEntity(edict_t *pent) { return TRUE; } void UTIL_SetOrigin(entvars_t *, const Vector &org) {} -BOOL UTIL_GetNextBestWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon) { return true; } +BOOL UTIL_GetNextBestWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon) { return TRUE; } void UTIL_LogPrintf(const char *, ...) {} void UTIL_ClientPrintAll(int, char const *, char const *, char const *, char const *, char const *) {} void PrintNotifyMsg(char *pszmsg); @@ -108,8 +107,8 @@ void ClientPrint(entvars_t *client, int msg_dest, const char *msg_name, const ch } // CBaseToggle Stubs -int CBaseToggle::Restore(class CRestore &) { return true; } -int CBaseToggle::Save(class CSave &) { return true; } +int CBaseToggle::Restore(class CRestore &) { return 1; } +int CBaseToggle::Save(class CSave &) { return 1; } void CBaseToggle ::KeyValue(struct KeyValueData_s *) {} // CGrenade Stubs @@ -121,118 +120,118 @@ void CGrenade::Spawn(void) {} CBaseEntity *CBaseMonster ::CheckTraceHullAttack(float flDist, int iDamage, int iDmgType) { return NULL; } void CBaseMonster ::Eat(float flFullDuration) {} -BOOL CBaseMonster ::FShouldEat(void) { return true; } +BOOL CBaseMonster ::FShouldEat(void) { return TRUE; } void CBaseMonster ::BarnacleVictimBitten(entvars_t *pevBarnacle) {} void CBaseMonster ::BarnacleVictimReleased(void) {} void CBaseMonster ::Listen(void) {} -float CBaseMonster::FLSoundVolume(CSound* pSound) { return NULL; } -BOOL CBaseMonster ::FValidateHintType(short sHint) { return false; } +float CBaseMonster ::FLSoundVolume(CSound *pSound) { return 0.0; } +BOOL CBaseMonster ::FValidateHintType(short sHint) { return FALSE; } void CBaseMonster ::Look(int iDistance) {} -int CBaseMonster ::ISoundMask(void) { return NULL; } +int CBaseMonster ::ISoundMask(void) { return 0; } CSound *CBaseMonster ::PBestSound(void) { return NULL; } CSound *CBaseMonster ::PBestScent(void) { return NULL; } -float CBaseAnimating ::StudioFrameAdvance(float flInterval) { return NULL; } +float CBaseAnimating ::StudioFrameAdvance(float flInterval) { return 0.0; } void CBaseMonster ::MonsterThink(void) {} void CBaseMonster ::MonsterUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) {} -int CBaseMonster ::IgnoreConditions(void) { return NULL; } +int CBaseMonster ::IgnoreConditions(void) { return 0; } void CBaseMonster ::RouteClear(void) {} void CBaseMonster ::RouteNew(void) {} -BOOL CBaseMonster ::FRouteClear(void) { return false; } -BOOL CBaseMonster ::FRefreshRoute(void) { return false; } -BOOL CBaseMonster::MoveToEnemy(Activity movementAct, float waitTime) { return false; } -BOOL CBaseMonster::MoveToLocation(Activity movementAct, float waitTime, const Vector &goal) { return false; } -BOOL CBaseMonster::MoveToTarget(Activity movementAct, float waitTime) { return false; } -BOOL CBaseMonster::MoveToNode(Activity movementAct, float waitTime, const Vector &goal) { return false; } -int ShouldSimplify(int routeType) { return true; } +BOOL CBaseMonster ::FRouteClear(void) { return FALSE; } +BOOL CBaseMonster ::FRefreshRoute(void) { return 0; } +BOOL CBaseMonster::MoveToEnemy(Activity movementAct, float waitTime) { return FALSE; } +BOOL CBaseMonster::MoveToLocation(Activity movementAct, float waitTime, const Vector &goal) { return FALSE; } +BOOL CBaseMonster::MoveToTarget(Activity movementAct, float waitTime) { return FALSE; } +BOOL CBaseMonster::MoveToNode(Activity movementAct, float waitTime, const Vector &goal) { return FALSE; } +int ShouldSimplify(int routeType) { return TRUE; } void CBaseMonster ::RouteSimplify(CBaseEntity *pTargetEnt) {} -BOOL CBaseMonster ::FBecomeProne(void) { return true; } -BOOL CBaseMonster ::CheckRangeAttack1(float flDot, float flDist) { return false; } -BOOL CBaseMonster ::CheckRangeAttack2(float flDot, float flDist) { return false; } -BOOL CBaseMonster ::CheckMeleeAttack1(float flDot, float flDist) { return false; } -BOOL CBaseMonster ::CheckMeleeAttack2(float flDot, float flDist) { return false; } +BOOL CBaseMonster ::FBecomeProne(void) { return TRUE; } +BOOL CBaseMonster ::CheckRangeAttack1(float flDot, float flDist) { return FALSE; } +BOOL CBaseMonster ::CheckRangeAttack2(float flDot, float flDist) { return FALSE; } +BOOL CBaseMonster ::CheckMeleeAttack1(float flDot, float flDist) { return FALSE; } +BOOL CBaseMonster ::CheckMeleeAttack2(float flDot, float flDist) { return FALSE; } void CBaseMonster ::CheckAttacks(CBaseEntity *pTarget, float flDist) {} -BOOL CBaseMonster ::FCanCheckAttacks(void) { return false; } -int CBaseMonster ::CheckEnemy(CBaseEntity *pEnemy) { return false; } +BOOL CBaseMonster ::FCanCheckAttacks(void) { return FALSE; } +int CBaseMonster ::CheckEnemy(CBaseEntity *pEnemy) { return 0; } void CBaseMonster ::PushEnemy(CBaseEntity *pEnemy, Vector &vecLastKnownPos) {} -BOOL CBaseMonster ::PopEnemy() { return false; } +BOOL CBaseMonster ::PopEnemy() { return FALSE; } void CBaseMonster ::SetActivity(Activity NewActivity) {} void CBaseMonster ::SetSequenceByName(char *szSequence) {} -int CBaseMonster ::CheckLocalMove(const Vector &vecStart, const Vector &vecEnd, CBaseEntity *pTarget, float *pflDist) { return NULL; } -float CBaseMonster::OpenDoorAndWait(entvars_t* pevDoor) { return NULL; } +int CBaseMonster ::CheckLocalMove(const Vector &vecStart, const Vector &vecEnd, CBaseEntity *pTarget, float *pflDist) { return 0; } +float CBaseMonster ::OpenDoorAndWait(entvars_t *pevDoor) { return 0.0; } void CBaseMonster ::AdvanceRoute(float distance) {} -int CBaseMonster::RouteClassify(int iMoveFlag) { return NULL; } -BOOL CBaseMonster ::BuildRoute(const Vector &vecGoal, int iMoveFlag, CBaseEntity *pTarget) { return false; } +int CBaseMonster ::RouteClassify(int iMoveFlag) { return 0; } +BOOL CBaseMonster ::BuildRoute(const Vector &vecGoal, int iMoveFlag, CBaseEntity *pTarget) { return FALSE; } void CBaseMonster ::InsertWaypoint(Vector vecLocation, int afMoveFlags) {} -BOOL CBaseMonster ::FTriangulate(const Vector &vecStart, const Vector &vecEnd, float flDist, CBaseEntity *pTargetEnt, Vector *pApex) { return false; } +BOOL CBaseMonster ::FTriangulate(const Vector &vecStart, const Vector &vecEnd, float flDist, CBaseEntity *pTargetEnt, Vector *pApex) { return FALSE; } void CBaseMonster ::Move(float flInterval) {} -BOOL CBaseMonster::ShouldAdvanceRoute(float flWaypointDist) { return false; } +BOOL CBaseMonster::ShouldAdvanceRoute(float flWaypointDist) { return FALSE; } void CBaseMonster::MoveExecute(CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval) {} void CBaseMonster ::MonsterInit(void) {} void CBaseMonster ::MonsterInitThink(void) {} void CBaseMonster ::StartMonster(void) {} void CBaseMonster ::MovementComplete(void) {} -int CBaseMonster::TaskIsRunning(void) { return false; } -int CBaseMonster::IRelationship(CBaseEntity *pTarget) { return NULL; } -BOOL CBaseMonster ::FindCover(Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist) { return false; } -BOOL CBaseMonster ::BuildNearestRoute(Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist) { return false; } +int CBaseMonster::TaskIsRunning(void) { return 0; } +int CBaseMonster::IRelationship(CBaseEntity *pTarget) { return 0; } +BOOL CBaseMonster ::FindCover(Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist) { return FALSE; } +BOOL CBaseMonster ::BuildNearestRoute(Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist) { return FALSE; } CBaseEntity *CBaseMonster ::BestVisibleEnemy(void) { return NULL; } -bool CBaseMonster ::FInViewCone(CBaseEntity *pEntity) { return false; } -bool CBaseMonster ::FInViewCone(Vector &Origin) { return false; } -BOOL CBaseEntity ::FVisible(CBaseEntity *pEntity) { return false; } -BOOL CBaseEntity ::FVisible(const Vector &vecOrigin) { return false; } -BOOL CBaseEntity ::FMVisible(CBaseEntity *pEntity) { return false; } -BOOL CBaseEntity ::FMVisible(const Vector &vecOrigin) { return false; } +bool CBaseMonster ::FInViewCone(CBaseEntity *pEntity) { return FALSE; } +bool CBaseMonster ::FInViewCone(Vector &Origin) { return FALSE; } +BOOL CBaseEntity ::FVisible(CBaseEntity *pEntity) { return FALSE; } +BOOL CBaseEntity ::FVisible(const Vector &vecOrigin) { return FALSE; } +BOOL CBaseEntity ::FMVisible(CBaseEntity *pEntity) { return FALSE; } +BOOL CBaseEntity ::FMVisible(const Vector &vecOrigin) { return FALSE; } void CBaseMonster ::MakeIdealYaw(Vector vecTarget) {} -float CBaseMonster::FlYawDiff(void) { return NULL; } -float CBaseMonster::ChangeYaw(int yawSpeed) { return NULL; } -float CBaseMonster::VecToYaw(Vector vecDir) { return NULL; } -int CBaseAnimating ::LookupActivity(int activity) { return NULL; } -int CBaseAnimating ::LookupActivityHeaviest(int activity) { return NULL; } +float CBaseMonster::FlYawDiff(void) { return 0.0; } +float CBaseMonster::ChangeYaw(int yawSpeed) { return 0; } +float CBaseMonster::VecToYaw(Vector vecDir) { return 0.0; } +int CBaseAnimating ::LookupActivity(int activity) { return 0; } +int CBaseAnimating ::LookupActivityHeaviest(int activity) { return 0; } void CBaseMonster ::SetEyePosition(void) {} -int CBaseAnimating ::LookupSequence(const char *label) { return NULL; } +int CBaseAnimating ::LookupSequence(const char *label) { return 0; } void CBaseAnimating ::ResetSequenceInfo() {} -BOOL CBaseAnimating ::GetSequenceFlags() { return false; } +BOOL CBaseAnimating ::GetSequenceFlags() { return FALSE; } void CBaseAnimating ::DispatchAnimEvents(float flInterval) {} void CBaseMonster ::HandleAnimEvent(MonsterEvent_t *pEvent) {} -float CBaseAnimating::SetBoneController(int iController, float flValue) { return NULL; } +float CBaseAnimating ::SetBoneController(int iController, float flValue) { return 0.0; } void CBaseAnimating ::InitBoneControllers(void) {} -float CBaseAnimating ::SetBlending(int iBlender, float flValue) { return NULL; } +float CBaseAnimating ::SetBlending(int iBlender, float flValue) { return 0; } void CBaseAnimating ::GetBonePosition(int iBone, Vector &origin, Vector &angles) {} void CBaseAnimating ::GetAttachment(int iAttachment, Vector &origin, Vector &angles) {} -int CBaseAnimating ::FindTransition(int iEndingSequence, int iGoalSequence, int *piDir) { return NEG_REF; } +int CBaseAnimating ::FindTransition(int iEndingSequence, int iGoalSequence, int *piDir) { return -1; } void CBaseAnimating ::GetAutomovement(Vector &origin, Vector &angles, float flInterval) {} void CBaseAnimating ::SetBodygroup(int iGroup, int iValue) {} -int CBaseAnimating ::GetBodygroup(int iGroup) { return NULL; } +int CBaseAnimating ::GetBodygroup(int iGroup) { return 0; } Vector CBaseMonster ::GetGunPosition(void) { return g_vecZero; } void CBaseEntity::FireBullets(unsigned long cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) {} void CBaseEntity ::TraceBleed(float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) {} void CBaseMonster ::MakeDamageBloodDecal(int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir) {} -BOOL CBaseMonster ::FGetNodeRoute(Vector vecDest) { return true; } +BOOL CBaseMonster ::FGetNodeRoute(Vector vecDest) { return TRUE; } int CBaseMonster ::FindHintNode(void) { return NO_NODE; } void CBaseMonster::ReportAIState(void) {} void CBaseMonster ::KeyValue(KeyValueData *pkvd) {} -BOOL CBaseMonster ::FCheckAITrigger(void) { return false; } -int CBaseMonster ::CanPlaySequence(BOOL fDisregardMonsterState, int interruptLevel) { return false; } -BOOL CBaseMonster ::FindLateralCover(const Vector &vecThreat, const Vector &vecViewOffset) { return false; } +BOOL CBaseMonster ::FCheckAITrigger(void) { return FALSE; } +int CBaseMonster ::CanPlaySequence(BOOL fDisregardMonsterState, int interruptLevel) { return FALSE; } +BOOL CBaseMonster ::FindLateralCover(const Vector &vecThreat, const Vector &vecViewOffset) { return FALSE; } Vector CBaseMonster ::ShootAtEnemy(const Vector &shootOrigin) { return g_vecZero; } -BOOL CBaseMonster ::FacingIdeal(void) { return false; } -BOOL CBaseMonster ::FCanActiveIdle(void) { return false; } +BOOL CBaseMonster ::FacingIdeal(void) { return FALSE; } +BOOL CBaseMonster ::FCanActiveIdle(void) { return FALSE; } void CBaseMonster::PlaySentence(const char *pszSentence, float duration, float volume, float attenuation) {} void CBaseMonster::PlayScriptedSentence(const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener) {} void CBaseMonster::SentenceStop(void) {} void CBaseMonster::CorpseFallThink(void) {} void CBaseMonster ::MonsterInitDead(void) {} -BOOL CBaseMonster ::BBoxFlat(void) { return true; } -BOOL CBaseMonster ::GetEnemy(void) { return false; } +BOOL CBaseMonster ::BBoxFlat(void) { return TRUE; } +BOOL CBaseMonster ::GetEnemy(void) { return FALSE; } void CBaseMonster ::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) {} CBaseEntity *CBaseMonster ::DropItem(char *pszItemName, const Vector &vecPos, const Vector &vecAng) { return NULL; } -BOOL CBaseMonster ::ShouldFadeOnDeath(void) { return false; } +BOOL CBaseMonster ::ShouldFadeOnDeath(void) { return FALSE; } void CBaseMonster ::RadiusDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType) {} void CBaseMonster ::RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType) {} void CBaseMonster::FadeMonster(void) {} void CBaseMonster ::GibMonster(void) {} -BOOL CBaseMonster ::HasHumanGibs(void) { return false; } -BOOL CBaseMonster ::HasAlienGibs(void) { return false; } +BOOL CBaseMonster ::HasHumanGibs(void) { return FALSE; } +BOOL CBaseMonster ::HasAlienGibs(void) { return FALSE; } Activity CBaseMonster ::GetDeathActivity(void) { return ACT_DIE_HEADSHOT; } MONSTERSTATE CBaseMonster ::GetIdealState(void) { return MONSTERSTATE_ALERT; } Schedule_t *CBaseMonster ::GetScheduleOfType(int Type) { return NULL; } @@ -243,35 +242,35 @@ Schedule_t *CBaseMonster::ScheduleFromName(const char *pName) { return NULL; } void CBaseMonster::BecomeDead(void) {} void CBaseMonster ::RunAI(void) {} void CBaseMonster ::Killed(entvars_t *pevAttacker, int iGib) {} -int CBaseMonster ::TakeHealth(float flHealth, int bitsDamageType) { return NULL; } -int CBaseMonster::TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType) {return NULL;} -int CBaseMonster::Restore(class CRestore &) { return true; } -int CBaseMonster::Save(class CSave &) { return true; } +int CBaseMonster ::TakeHealth(float flHealth, int bitsDamageType) { return 0; } +int CBaseMonster ::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return 0; } +int CBaseMonster::Restore(class CRestore &) { return 1; } +int CBaseMonster::Save(class CSave &) { return 1; } -int TrainSpeed(int iSpeed, int iMax) { return NULL; } +int TrainSpeed(int iSpeed, int iMax) { return 0; } //Master Sword void CBasePlayer::PainSound() {} void CBasePlayer::TakeDamageEffect(CBaseEntity *pInflictor, CBaseEntity *pAttacker, float flDamage, int bitsDamageType) {} -int CBasePlayer::IRelationship(CBaseEntity *pTarget) { return NULL; } +int CBasePlayer::IRelationship(CBaseEntity *pTarget) { return 0; } -int CBasePlayerWeapon::Restore(class CRestore &) { return true; } -int CBasePlayerWeapon::Save(class CSave &) { return true; } +int CBasePlayerWeapon::Restore(class CRestore &) { return 1; } +int CBasePlayerWeapon::Save(class CSave &) { return 1; } void CBasePlayer::StruckSound(CBaseEntity *pInflicter, CBaseEntity *pAttacker, float flDamage, TraceResult *ptr, int bitsDamageType) {} void CBasePlayer::DeathSound(void) {} -int CBasePlayer::TakeHealth(float flHealth, int bitsDamageType) { return NULL; } -int CBasePlayer::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return NULL; } +int CBasePlayer::TakeHealth(float flHealth, int bitsDamageType) { return 0; } +int CBasePlayer::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return 0; } void CBasePlayer::PackDeadPlayerItems(void) {} void CBasePlayer::WaterMove() {} -BOOL CBasePlayer::IsOnLadder(void) { return false; } +BOOL CBasePlayer::IsOnLadder(void) { return FALSE; } void CBasePlayer::PlayerDeathThink(void) {} void CBasePlayer::StartDeathCam(void) {} void CBasePlayer::StartObserver(Vector vecPosition, Vector vecViewAngle) {} void CBasePlayer::PlayerUse(void) {} void CBasePlayer::Jump() {} void CBasePlayer::Duck() {} -int CBasePlayer::Classify(void) { return NULL; } +int CBasePlayer::Classify(void) { return 0; } //void CBasePlayer :: PlayStepSound(int step, float fvol) { } //void CBasePlayer :: UpdateStepSound( void ) { } void CBasePlayer::PreThink(void) {} @@ -280,14 +279,14 @@ void CBasePlayer ::UpdateGeigerCounter(void) {} void CBasePlayer ::UpdatePlayerSound(void) {} void CBasePlayer::PostThink() {} void CBasePlayer ::Precache(void) {} -int CBasePlayer::Save(CSave &save) { return NULL; } +int CBasePlayer::Save(CSave &save) { return 0; } void CBasePlayer::RenewItems(void) {} -int CBasePlayer::Restore(CRestore &restore) { return NULL; } +int CBasePlayer::Restore(CRestore &restore) { return 0; } void CBasePlayer::SelectNextItem(int iItem) {} -BOOL CBasePlayer::HasWeapons(void) { return false; } +BOOL CBasePlayer::HasWeapons(void) { return FALSE; } void CBasePlayer::SelectPrevItem(int iItem) {} CBaseEntity *FindEntityForward(CBaseEntity *pMe) { return NULL; } -//BOOL CBasePlayer :: FlashlightIsOn( void ) { return false; } +//BOOL CBasePlayer :: FlashlightIsOn( void ) { return FALSE; } //void CBasePlayer :: FlashlightTurnOn( void ) { } //void CBasePlayer :: FlashlightTurnOff( void ) { } //void CBasePlayer :: ForceClientDllUpdate( void ) { } @@ -295,25 +294,25 @@ void CBasePlayer::ImpulseCommands() {} void CBasePlayer::CheatImpulseCommands(int iImpulse) {} void CBasePlayer::ItemPreFrame() {} void CBasePlayer::ItemPostFrame() {} -int CBasePlayer::AmmoInventory(int iAmmoIndex) { return NEG_REF; } +int CBasePlayer::AmmoInventory(int iAmmoIndex) { return -1; } //Master Sword void CBasePlayer ::UpdateClientData(void) {} -BOOL CBasePlayer ::FBecomeProne(void) { return true; } +BOOL CBasePlayer ::FBecomeProne(void) { return TRUE; } void CBasePlayer ::BarnacleVictimBitten(entvars_t *pevBarnacle) {} void CBasePlayer ::BarnacleVictimReleased(void) {} -int CBasePlayer ::Illumination(void) { return NULL; } +int CBasePlayer ::Illumination(void) { return 0; } void CBasePlayer ::EnableControl(BOOL fControl) {} Vector CBasePlayer ::GetAutoaimVector(float flDelta) { return g_vecZero; } //Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ) { return g_vecZero; } void CBasePlayer ::ResetAutoaim() {} void CBasePlayer ::SetCustomDecalFrames(int nFrames) {} -int CBasePlayer ::GetCustomDecalFrames(void) { return NEG_REF; } +int CBasePlayer ::GetCustomDecalFrames(void) { return -1; } Vector CBasePlayer ::GetGunPosition(void) { return g_vecZero; } //Master Sword void CBasePlayer::Trade() {} bool CBasePlayer::AcceptOffer() { return false; } tradeinfo_t *CBasePlayer::TradeItem(tradeinfo_t *ptiTradeInfo) { return NULL; } -BOOL CBasePlayer::SkinMonster(CMSMonster *pDeadMonster) { return false; } +BOOL CBasePlayer::SkinMonster(CMSMonster *pDeadMonster) { return FALSE; } void CBasePlayer::AddNoise(float flNoiseAmt) {} void CBasePlayer::Attacked(CBaseEntity *pAttacker, float flDamage, int bitsDamageType) {} void CBasePlayer::Seen(CMSMonster *pMonster) {} diff --git a/src/game/client/hud.cpp b/src/game/client/hud.cpp index c084f356a..f30437fca 100644 --- a/src/game/client/hud.cpp +++ b/src/game/client/hud.cpp @@ -48,16 +48,15 @@ #include "fmod/soundengine.h" #include "mslogger.h" -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - - //----------------- extern client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount); extern cvar_t *sensitivity; cvar_t *cl_lw = NULL; +// FULLBRIGHT START +extern bool m_bCacheFullbrightModels; +// FULLBRIGHT END + void ShutdownInput(void); int __MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf) @@ -241,7 +240,10 @@ int __MsgFunc_ViewModel(const char *pszName, int iSize, void *pbuf) return 1; } - +#define SetMSHUD(ptr, type) \ + ptr = new (type); \ + strncpy(ptr->Name, #type, 32 ) + // This is called every time the DLL is loaded void CHud::Init(void) { @@ -249,15 +251,15 @@ void CHud::Init(void) //ClientCmd( "r_shadows 1" ); ClientCmd("cl_himodels 0"); - m_Menu = new(CHudMenu); - m_Fatigue = new(CHudFatigue); - m_Magic = new(CHudMagic); - m_Music = new(CHudMusic); - m_Action = new(CHudAction); - m_Health = new(CHudHealth); - m_HUDScript = new(CHudScript); - m_Misc = new(CHudMisc); - m_HUDId = new(CHudID); + SetMSHUD(m_Menu, CHudMenu); + SetMSHUD(m_Fatigue, CHudFatigue); + SetMSHUD(m_Magic, CHudMagic); + SetMSHUD(m_Music, CHudMusic); + SetMSHUD(m_Action, CHudAction); + SetMSHUD(m_Health, CHudHealth); + SetMSHUD(m_HUDScript, CHudScript); + SetMSHUD(m_Misc, CHudMisc); + SetMSHUD(m_HUDId, CHudID); //MS commands and messages //HOOK_COMMAND( "use", PlayerUseItem ); @@ -365,17 +367,27 @@ void CHud::Init(void) void CHud::Shutdown() { - m_Music->Shutdown(); - + if (m_Music) + m_Music->Shutdown(); + delete m_Menu; + m_Menu = nullptr; delete m_Fatigue; + m_Fatigue = nullptr; delete m_Magic; + m_Magic = nullptr; delete m_Music; + m_Music = nullptr; delete m_Action; + m_Action = nullptr; delete m_Health; + m_Health = nullptr; delete m_HUDScript; + m_HUDScript = nullptr; delete m_Misc; + m_Misc = nullptr; delete m_HUDId; + m_HUDId = nullptr; } // GetSpriteIndex() @@ -385,7 +397,7 @@ void CHud::Shutdown() int CHud::GetSpriteIndex(const char *SpriteName) { // look through the loaded sprite name list for SpriteName - for (unsigned int i = 0; i < m_Sprites.size() - 1; ++i) + for (int i = 0; i < m_Sprites.size() - 1; ++i) { if (m_Sprites[i].Name == SpriteName) return static_cast(i); @@ -394,117 +406,6 @@ int CHud::GetSpriteIndex(const char *SpriteName) return -1; // invalid sprite } -// Redraw -// step through the local data, placing the appropriate graphics & text as appropriate -// returns 1 if they've changed, 0 otherwise -int CHud::Redraw(float flTime, int intermission) -{ - //Print( "Time: %f\n", flTime ); - m_fOldTime = m_flTime; // save time of previous redraw - m_flTime = flTime; - m_flTimeDelta = (double)m_flTime - m_fOldTime; - static float m_flShotTime = 0; - - // Clock was reset, reset delta - if (m_flTimeDelta < 0) - { - m_flTimeDelta = 0; - } - - // Bring up the scoreboard during intermission - if (gViewPort) - { - if (m_iIntermission && !intermission) - { - // Have to do this here so the scoreboard goes away - m_iIntermission = intermission; - gViewPort->HideCommandMenu(); - gViewPort->HideScoreBoard(); - } - else if (!m_iIntermission && intermission) - { - gViewPort->HideCommandMenu(); - gViewPort->ShowScoreBoard(); - - // Take a screenshot if the client's got the cvar set - //if ( CVAR_GET_FLOAT( "hud_takesshots" ) != 0 ) - // m_flShotTime = flTime + 1.0; // Take a screenshot in a second - } - } - - if (m_flShotTime && m_flShotTime < flTime) - { - gEngfuncs.pfnClientCmd("snapshot\n"); - m_flShotTime = 0; - } - - m_iIntermission = intermission; - - // if no redrawing is necessary - // return 0; - - for (auto hudElement : m_HudList) - { - if (!intermission) - { - if ((hudElement->m_iFlags & HUD_ACTIVE) != 0 && (m_iHideHUDDisplay & HIDEHUD_ALL) == 0) - hudElement->Draw(flTime); - } - else - { // it's an intermission, so only draw hud elements that are set to draw during intermissions - if ((hudElement->m_iFlags & HUD_INTERMISSION) != 0) - hudElement->Draw(flTime); - } - } - - // are we in demo mode? do we need to draw the logo in the top corner? - // if (m_iLogo) - // { - // int x, y, i; - - // if (m_hsprLogo == 0) - // m_hsprLogo = LoadSprite("sprites/%d_logo.spr"); - - // SPR_Set(m_hsprLogo, 250, 250, 250); - - // x = SPR_Width(m_hsprLogo, 0); - // x = ScreenWidth() - x; - // y = SPR_Height(m_hsprLogo, 0) / 2; - - // // Draw the logo at 20 fps - // int iFrame = (int)(flTime * 20) % MAX_LOGO_FRAMES; - // i = grgLogoFrame[iFrame] - 1; - - // SPR_DrawAdditive(i, x, y, NULL); - // } - - /* - if ( g_iVisibleMouse ) - { - void IN_GetMousePos( int *mx, int *my ); - int mx, my; - - IN_GetMousePos( &mx, &my ); - - if (m_hsprCursor == 0) - { - char sz[256]; - strncpy(sz, "sprites/cursor.spr", sizeof(sz) ); - m_hsprCursor = SPR_Load( sz ); - } - - SPR_Set(m_hsprCursor, 250, 250, 250 ); - - // Draw the logo at 20 fps - SPR_DrawAdditive( 0, mx, my, NULL ); - } - */ - - //m_Music->Redraw(flTime, intermission); - - return 1; -} - extern int g_iVisibleMouse; float HUD_GetFOV(void); extern cvar_t *sensitivity; @@ -568,7 +469,7 @@ void CHud::VidInit(void) m_hsprLogo = 0; m_hsprCursor = 0; - if (ScreenWidth() < 640) + if (ScreenWidth < 640) m_iRes = 320; else m_iRes = 640; @@ -637,6 +538,10 @@ void CHud::VidInit(void) //Reload the Master Sword global sprite/TGA list //(only sprites are reloaded, not TGAs) MSBitmap::ReloadSprites(); + + // FULLBRIGHT START + m_bCacheFullbrightModels = true; + // FULLBRIGHT END } //this should get called whenever the client changes levels or servers. diff --git a/src/game/client/hud.h b/src/game/client/hud.h index 82f6b3569..225ef6c45 100644 --- a/src/game/client/hud.h +++ b/src/game/client/hud.h @@ -39,27 +39,20 @@ class CHudMisc; ///////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\// -enum { - RGB_YELLOWISH = 0x00FFA000, //255,160,0 - RGB_REDISH = 0x00FF1010, //255,160,0 - RGB_GREENISH = 0x0000A000 //0,160,0 -}; +#define RGB_YELLOWISH 0x00FFA000 //255,160,0 +#define RGB_REDISH 0x00FF1010 //255,160,0 +#define RGB_GREENISH 0x0000A000 //0,160,0 #include "wrect.h" #include "cl_dll.h" #include "ammo.h" -enum { - DHN_DRAWZERO = 1, - DHN_2DIGITS = 2, - DHN_3DIGITS = 4 -}; - -constexpr int MIN_ALPHA = 100; +#define DHN_DRAWZERO 1 +#define DHN_2DIGITS 2 +#define DHN_3DIGITS 4 +#define MIN_ALPHA 100 -enum { - HUDELEM_ACTIVE = 1 -}; +#define HUDELEM_ACTIVE 1 enum { @@ -80,13 +73,12 @@ typedef struct typedef struct cvar_s cvar_t; -enum { - HUD_ACTIVE = 1, - HUD_INTERMISSION = 2 -}; +#define HUD_ACTIVE 1 +#define HUD_INTERMISSION 2 + +#define MAX_PLAYER_NAME_LENGTH 32 -constexpr int MAX_PLAYER_NAME_LENGTH = 32; -constexpr int MAX_MOTD_LENGTH = 1024; +#define MAX_MOTD_LENGTH 1024 // Master Sword //----------------------------------------------------- @@ -107,7 +99,7 @@ typedef int BOOL; #endif //Moved here from CHudStatusIcons -constexpr int MAX_SPRITE_NAME_LENGTH = 24; +#define MAX_SPRITE_NAME_LENGTH 24 typedef struct { @@ -158,7 +150,7 @@ class CHudAmmoSecondary : public CHudBase float m_fFade; }; -constexpr int FADE_TIME = 100; +#define FADE_TIME 100 // //----------------------------------------------------- @@ -218,7 +210,7 @@ class CHudStatusBar : public CHudBase char m_szStatusBar[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; // the constructed bar that is drawn int m_iStatusValues[MAX_STATUSBAR_VALUES]; // an array of values for use in the status bar - int m_bReparseString; // set to true whenever the m_szStatusBar needs to be recalculated + int m_bReparseString; // set to TRUE whenever the m_szStatusBar needs to be recalculated }; extern int g_IsSpectator[MAX_PLAYERS + 1]; @@ -263,7 +255,7 @@ class CHudSayText : public CHudBase // //----------------------------------------------------- // -constexpr int maxHUDMessages = 16; +const int maxHUDMessages = 16; struct message_parms_t { client_textmessage_t *pMessage; @@ -455,7 +447,7 @@ class CHud void ReloadClient(); int UpdateClientData(client_data_t *cdata, float time); - CHud() = default; + CHud() = default; ~CHud() = default; // destructor, frees allocated memory // user messages diff --git a/src/game/client/hud_msg.cpp b/src/game/client/hud_msg.cpp index 00f6c5c77..2c1e6155e 100644 --- a/src/game/client/hud_msg.cpp +++ b/src/game/client/hud_msg.cpp @@ -23,7 +23,7 @@ #include "string.h" #include "mscharacter.h" #include "clglobal.h" -#include "clenv.h" +#include "render/clenv.h" #include "vgui_choosecharacter.h" #include "monsters/msmonster.h" #include "mslogger.h" @@ -49,7 +49,7 @@ int CHud ::MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf) return 1; } -constexpr unsigned int CLPERMENT_TOTALK = 3; +#define CLPERMENT_TOTALK 3 void CHud ::MsgFunc_InitHUD(const char *pszName, int iSize, void *pbuf) { @@ -65,7 +65,7 @@ void CHud ::MsgFunc_InitHUD(const char *pszName, int iSize, void *pbuf) //g_NetCode.m.HostIP = READ_STRING(); MS_INFO("[MsgFunc_InitHUD: CLEnt Readin]"); - for (unsigned int i = 0; i < CLPERMENT_TOTALK; i++) + for (int i = 0; i < CLPERMENT_TOTALK; i++) MSGlobals::ClEntities[i] = READ_SHORT(); int flags = READ_BYTE(); @@ -74,7 +74,6 @@ void CHud ::MsgFunc_InitHUD(const char *pszName, int iSize, void *pbuf) MSGlobals::IsLanGame = (flags & (1 << 1)) ? true : false; MSGlobals::CanCreateCharOnMap = (flags & (1 << 2)) ? true : false; MSGlobals::GameType = (flags & (1 << 3)) ? GAMETYPE_ADVENTURE : GAMETYPE_CHALLENGE; - MSGlobals::ServerSideChar = (flags & (1 << 4)) ? true : false; MSCLGlobals::OtherPlayers = (flags & (1 << 5)) ? true : false; MSCLGlobals::AuthID = READ_STRING(); @@ -86,7 +85,7 @@ void CHud ::MsgFunc_InitHUD(const char *pszName, int iSize, void *pbuf) MS_INFO("[MsgFunc_InitHUD: Clearvotes]"); vote_t::VotesTypesAllowed.clearitems(); - for (unsigned int i = 0; i < vote_t::VotesTypes.size(); i++) + for (int i = 0; i < vote_t::VotesTypes.size(); i++) if (FBitSet(VotesAllowed, (1 << i))) vote_t::VotesTypesAllowed.add(vote_t::VotesTypes[i]); diff --git a/src/game/client/hud_redraw.cpp b/src/game/client/hud_redraw.cpp index 1dba4ff79..c813a8139 100644 --- a/src/game/client/hud_redraw.cpp +++ b/src/game/client/hud_redraw.cpp @@ -26,7 +26,7 @@ #include "clglobal.h" #include "sharedutil.h" -constexpr unsigned int MAX_LOGO_FRAMES = 56; +#define MAX_LOGO_FRAMES 56 int grgLogoFrame[MAX_LOGO_FRAMES] = { @@ -41,8 +41,6 @@ float HUD_GetFOV(void); extern cvar_t *sensitivity; // Think - - void ScaleColors(int &r, int &g, int &b, int a) { float x = (float)a / 255; @@ -51,6 +49,130 @@ void ScaleColors(int &r, int &g, int &b, int a) b = (int)(b * x); } +// FULLBRIGHT START +void CacheFullbrightModels(); +bool m_bCacheFullbrightModels = true; +// FULLBRIGHT END + +// Redraw +// step through the local data, placing the appropriate graphics & text as appropriate +// returns 1 if they've changed, 0 otherwise +int CHud::Redraw(float flTime, int intermission) +{ + // FULLBRIGHT START + if (m_bCacheFullbrightModels) + { + CacheFullbrightModels(); + m_bCacheFullbrightModels = false; + } + // FULLBRIGHT END + + //Print( "Time: %f\n", flTime ); + m_fOldTime = m_flTime; // save time of previous redraw + m_flTime = flTime; + m_flTimeDelta = (double)m_flTime - m_fOldTime; + static float m_flShotTime = 0; + + // Clock was reset, reset delta + if (m_flTimeDelta < 0) + { + m_flTimeDelta = 0; + } + + // Bring up the scoreboard during intermission + if (gViewPort) + { + if (m_iIntermission && !intermission) + { + // Have to do this here so the scoreboard goes away + m_iIntermission = intermission; + gViewPort->HideCommandMenu(); + gViewPort->HideScoreBoard(); + } + else if (!m_iIntermission && intermission) + { + gViewPort->HideCommandMenu(); + gViewPort->ShowScoreBoard(); + + // Take a screenshot if the client's got the cvar set + //if ( CVAR_GET_FLOAT( "hud_takesshots" ) != 0 ) + // m_flShotTime = flTime + 1.0; // Take a screenshot in a second + } + } + + if (m_flShotTime && m_flShotTime < flTime) + { + gEngfuncs.pfnClientCmd("snapshot\n"); + m_flShotTime = 0; + } + + m_iIntermission = intermission; + + // if no redrawing is necessary + // return 0; + + for (auto hudElement : m_HudList) + { + if (!intermission) + { + if ((hudElement->m_iFlags & HUD_ACTIVE) != 0 && (m_iHideHUDDisplay & HIDEHUD_ALL) == 0) + hudElement->Draw(flTime); + } + else + { // it's an intermission, so only draw hud elements that are set to draw during intermissions + if ((hudElement->m_iFlags & HUD_INTERMISSION) != 0) + hudElement->Draw(flTime); + } + } + + // are we in demo mode? do we need to draw the logo in the top corner? + // if (m_iLogo) + // { + // int x, y, i; + + // if (m_hsprLogo == 0) + // m_hsprLogo = LoadSprite("sprites/%d_logo.spr"); + + // SPR_Set(m_hsprLogo, 250, 250, 250); + + // x = SPR_Width(m_hsprLogo, 0); + // x = ScreenWidth - x; + // y = SPR_Height(m_hsprLogo, 0) / 2; + + // // Draw the logo at 20 fps + // int iFrame = (int)(flTime * 20) % MAX_LOGO_FRAMES; + // i = grgLogoFrame[iFrame] - 1; + + // SPR_DrawAdditive(i, x, y, NULL); + // } + + /* + if ( g_iVisibleMouse ) + { + void IN_GetMousePos( int *mx, int *my ); + int mx, my; + + IN_GetMousePos( &mx, &my ); + + if (m_hsprCursor == 0) + { + char sz[256]; + strncpy(sz, "sprites/cursor.spr", sizeof(sz) ); + m_hsprCursor = SPR_Load( sz ); + } + + SPR_Set(m_hsprCursor, 250, 250, 250 ); + + // Draw the logo at 20 fps + SPR_DrawAdditive( 0, mx, my, NULL ); + } + */ + + //m_Music->Redraw(flTime, intermission); + + return 1; +} + int CHud::DrawHudString(int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b) { // draw the string until we hit the null character or a newline character diff --git a/src/game/client/hud_spectator.cpp b/src/game/client/hud_spectator.cpp index 295405c3c..3a11e0a8a 100644 --- a/src/game/client/hud_spectator.cpp +++ b/src/game/client/hud_spectator.cpp @@ -71,7 +71,7 @@ void SpectatorSpray(void) if (!gEngfuncs.IsSpectateOnly()) return; - AngleVectors(v_angles, &forward, nullptr, nullptr); + AngleVectors(v_angles, &forward, NULL, NULL); VectorScale(forward, 128, forward); VectorAdd(forward, v_origin, forward); pmtrace_t *trace = gEngfuncs.PM_TraceLine(v_origin, forward, PM_TRACELINE_PHYSENTSONLY, 2, -1); @@ -174,18 +174,16 @@ int CHudSpectator::Init() void UTIL_StringToVector(float *pVector, const char *pString) { - - const unsigned int bufferLength = 128; - char* pstr, * pfront, tempString[bufferLength] = { 0 }; + char *pstr, *pfront, tempString[128]; int j; - strcpy(tempString, pString); - pstr = tempString; - pfront = tempString; + strncpy(tempString, pString, sizeof(tempString) ); + pstr = pfront = tempString; for (j = 0; j < 3; j++) { pVector[j] = atof(pfront); + while (*pstr && *pstr != ' ') pstr++; if (!*pstr) @@ -252,7 +250,6 @@ int UTIL_FindEntityInMap(const char *name, float *origin, float *angle) }; strncpy(keyname, token, sizeof(keyname) ); - keyname[255] = '\0'; // another hack to fix keynames with trailing spaces n = strlen(keyname); @@ -389,7 +386,7 @@ int CHudSpectator::Draw(float flTime) int lx; char string[256]; - float *color = nullptr; + float *color; // draw only in spectator mode if (!g_iUser1) @@ -415,7 +412,7 @@ int CHudSpectator::Draw(float flTime) VectorNormalize(right); VectorScale(right, m_moveDelta, right); - VectorAdd(m_mapOrigin, right, m_mapOrigin); + VectorAdd(m_mapOrigin, right, m_mapOrigin) } // Only draw the icon names only if map mode is in Main Mode @@ -429,14 +426,14 @@ int CHudSpectator::Draw(float flTime) gViewPort->GetAllPlayersInfo(); // loop through all the players and draw additional infos to their sprites on the map - for (unsigned int i = 0; i < MAX_PLAYERS; i++) + for (int i = 0; i < MAX_PLAYERS; i++) { if (m_vPlayerPos[i][2] < 0) // marked as invisible ? continue; // check if name would be in inset window - if ((int)m_pip->value != INSET_OFF) + if (m_pip->value != INSET_OFF) { if (m_vPlayerPos[i][0] > XRES(m_OverviewData.insetWindowX) && m_vPlayerPos[i][1] > YRES(m_OverviewData.insetWindowY) && @@ -1057,7 +1054,7 @@ void CHudSpectator::DrawOverviewLayer() float screenaspect, xs, ys, xStep, yStep, x, y, z; int ix, iy, i, xTiles, yTiles, frame; - qboolean hasMapImage = m_MapSprite ? true : false; + qboolean hasMapImage = m_MapSprite ? TRUE : FALSE; model_t *dummySprite = (struct model_s *)gEngfuncs.GetSpritePointer(m_hsprUnkownMap); if (hasMapImage) @@ -1310,11 +1307,11 @@ void CHudSpectator::DrawOverviewEntities() // get current camera position and angle - if ((int)m_pip->value == INSET_IN_EYE || g_iUser1 == OBS_IN_EYE) + if (m_pip->value == INSET_IN_EYE || g_iUser1 == OBS_IN_EYE) { V_GetInEyePos(g_iUser2, origin, angles); } - else if ((int)m_pip->value == INSET_CHASE_FREE || g_iUser1 == OBS_CHASE_FREE) + else if (m_pip->value == INSET_CHASE_FREE || g_iUser1 == OBS_CHASE_FREE) { V_GetChasePos(g_iUser2, v_cl_angles, origin, angles); } @@ -1324,7 +1321,7 @@ void CHudSpectator::DrawOverviewEntities() VectorCopy(v_cl_angles, angles); } else - V_GetChasePos(g_iUser2, nullptr, origin, angles); + V_GetChasePos(g_iUser2, NULL, origin, angles); // draw camera sprite @@ -1340,7 +1337,7 @@ void CHudSpectator::DrawOverviewEntities() gEngfuncs.pTriAPI->Color4f(r, g, b, 1.0); - AngleVectors(angles, &forward, nullptr, nullptr); + AngleVectors(angles, &forward, NULL, NULL); VectorScale(forward, 512.0f, forward); offset[0] = 0.0f; @@ -1373,10 +1370,10 @@ void CHudSpectator::DrawOverview() return; // Only draw the overview if Map Mode is selected for this view - if (!m_iDrawCycle && ((g_iUser1 != OBS_MAP_FREE) && (g_iUser1 != OBS_MAP_CHASE))) + if (m_iDrawCycle == 0 && ((g_iUser1 != OBS_MAP_FREE) && (g_iUser1 != OBS_MAP_CHASE))) return; - if (m_iDrawCycle && (int)m_pip->value < INSET_MAP_FREE) + if (m_iDrawCycle == 1 && m_pip->value < INSET_MAP_FREE) return; DrawOverviewLayer(); @@ -1388,7 +1385,7 @@ void CHudSpectator::CheckOverviewEntities() double time = gEngfuncs.GetClientTime(); // removes old entities from list - for (unsigned int i = 0; i < MAX_OVERVIEW_ENTITIES; i++) + for (int i = 0; i < MAX_OVERVIEW_ENTITIES; i++) { // remove entity from list if it is too old if (m_OverviewEntities[i].killTime < time) @@ -1448,7 +1445,7 @@ void CHudSpectator::DeathMessage(int victim) bool CHudSpectator::AddOverviewEntityToList(HLSPRITE sprite, cl_entity_t *ent, double killTime) { - for (unsigned int i = 0; i < MAX_OVERVIEW_ENTITIES; i++) + for (int i = 0; i < MAX_OVERVIEW_ENTITIES; i++) { // find empty entity slot if (m_OverviewEntities[i].entity == NULL) @@ -1468,13 +1465,13 @@ void CHudSpectator::CheckSettings() m_pip->value = (int)m_pip->value; - if ((g_iUser1 < OBS_MAP_FREE) && ((int)m_pip->value == INSET_CHASE_FREE || (int)m_pip->value == INSET_IN_EYE)) + if ((g_iUser1 < OBS_MAP_FREE) && (m_pip->value == INSET_CHASE_FREE || m_pip->value == INSET_IN_EYE)) { // otherwise both would show in World picures m_pip->value = INSET_MAP_FREE; } - if ((g_iUser1 >= OBS_MAP_FREE) && ((int)m_pip->value >= INSET_MAP_FREE)) + if ((g_iUser1 >= OBS_MAP_FREE) && (m_pip->value >= INSET_MAP_FREE)) { // both would show map views m_pip->value = INSET_CHASE_FREE; @@ -1523,7 +1520,7 @@ void CHudSpectator::CheckSettings() m_pip->value = INSET_OFF; // draw small border around inset view, adjust upper black bar - gViewPort->m_pSpectatorPanel->EnableInsetView((int)m_pip->value != INSET_OFF); + gViewPort->m_pSpectatorPanel->EnableInsetView(m_pip->value != INSET_OFF); } int CHudSpectator::ToggleInset(bool allowOff) diff --git a/src/game/client/hud_spectator.h b/src/game/client/hud_spectator.h index 6ca7a3af9..cfc9fceb0 100644 --- a/src/game/client/hud_spectator.h +++ b/src/game/client/hud_spectator.h @@ -11,18 +11,16 @@ #include "cl_entity.h" -enum { - INSET_OFF = 0, - INSET_CHASE_FREE = 1, - INSET_IN_EYE = 2, - INSET_MAP_FREE = 3, - INSET_MAP_CHASE = 4 -}; +#define INSET_OFF 0 +#define INSET_CHASE_FREE 1 +#define INSET_IN_EYE 2 +#define INSET_MAP_FREE 3 +#define INSET_MAP_CHASE 4 +#define MAX_SPEC_HUD_MESSAGES 8 -constexpr int MAX_SPEC_HUD_MESSAGES = 8; -constexpr int OVERVIEW_TILE_SIZE = 128;// don't change this -constexpr int OVERVIEW_MAX_LAYERS = 1; +#define OVERVIEW_TILE_SIZE 128 // don't change this +#define OVERVIEW_MAX_LAYERS 1 //----------------------------------------------------------------------------- // Purpose: Handles the drawing of the spectator stuff (camera & top-down map and all the things on it ) @@ -52,7 +50,7 @@ typedef struct overviewEntity_s double killTime; } overviewEntity_t; -constexpr int MAX_OVERVIEW_ENTITIES = 128; +#define MAX_OVERVIEW_ENTITIES 128 class CHudSpectator : public CHudBase { diff --git a/src/game/client/hud_update.cpp b/src/game/client/hud_update.cpp index 290b52ad5..5a89b176d 100644 --- a/src/game/client/hud_update.cpp +++ b/src/game/client/hud_update.cpp @@ -31,8 +31,8 @@ extern void HUD_SetCmdBits(int bits); int CHud::UpdateClientData(client_data_t *cdata, float time) { - memcpy(m_vecOrigin, cdata->origin, sizeof(Vector )); - memcpy(m_vecAngles, cdata->viewangles, sizeof(Vector )); + memcpy(m_vecOrigin, cdata->origin, sizeof(Vector)); + memcpy(m_vecAngles, cdata->viewangles, sizeof(Vector)); m_iKeyBits = CL_ButtonBits(0); m_iWeaponBits = cdata->iWeaponBits; diff --git a/src/game/client/in_camera.cpp b/src/game/client/in_camera.cpp index dfd67acca..737f1bb22 100644 --- a/src/game/client/in_camera.cpp +++ b/src/game/client/in_camera.cpp @@ -33,16 +33,16 @@ extern cl_enginefunc_t gEngfuncs; //-------------------------------------------------- Constants -constexpr float CAM_DIST_DELTA = 1.0; -constexpr float CAM_ANGLE_DELTA = 2.5; -constexpr float CAM_ANGLE_SPEED = 2.5; -constexpr float CAM_MIN_DIST = 30.0; -constexpr float CAM_ANGLE_MOVE = .5; -constexpr float MAX_ANGLE_DIFF = 10.0; -constexpr float PITCH_MAX = 90.0; -constexpr float PITCH_MIN = 0; -constexpr float YAW_MAX = 135.0; -constexpr float YAW_MIN = -135.0; +#define CAM_DIST_DELTA 1.0 +#define CAM_ANGLE_DELTA 2.5 +#define CAM_ANGLE_SPEED 2.5 +#define CAM_MIN_DIST 30.0 +#define CAM_ANGLE_MOVE .5 +#define MAX_ANGLE_DIFF 10.0 +#define PITCH_MAX 90.0 +#define PITCH_MIN 0 +#define YAW_MAX 135.0 +#define YAW_MIN -135.0 enum ECAM_Command { @@ -148,9 +148,9 @@ float MoveToward(float cur, float goal, float maxspeed) /*typedef struct { - Vector boxmins, boxmaxs;// enclose the test object along entire move + Vector boxmins, boxmaxs;// enclose the test object along entire move float *mins, *maxs; // size of the moving object - Vector mins2, maxs2; // size when clipping against mosnters + Vector mins2, maxs2; // size when clipping against mosnters float *start, *end; trace_t trace; int type; @@ -667,8 +667,6 @@ int DLLEXPORT CL_IsThirdPerson(void) // - Later, in StudioDrawPlayer() I check to make sure the proper thirdperson model is being drawn // - Update: The above is UNDONE //return 1; - //if( CMirrorMgr::m_CurrentMirror.Enabled ) - // return 1; return MSCLGlobals::CamThirdPerson ? 1 : 0; } diff --git a/src/game/client/in_defs.h b/src/game/client/in_defs.h index 00f996a51..102f8a3a8 100644 --- a/src/game/client/in_defs.h +++ b/src/game/client/in_defs.h @@ -2,14 +2,12 @@ #define IN_DEFSH #pragma once -enum { - // up / down - PITCH = 0, +// up / down +#define PITCH 0 // left / right - YAW = 1, +#define YAW 1 // fall over - ROLL = 2 -}; +#define ROLL 2 #define DLLEXPORT EXPORT diff --git a/src/game/client/input.cpp b/src/game/client/input.cpp index 5e93e02b3..32b5c878f 100644 --- a/src/game/client/input.cpp +++ b/src/game/client/input.cpp @@ -37,6 +37,7 @@ extern "C" #include "clientlibrary.h" #include "scriptmgr.h" #include "ms/clglobal.h" +#include "ms/mslogger.h" #include extern "C" @@ -140,7 +141,7 @@ typedef struct kblist_s char name[32]; } kblist_t; -kblist_t *g_kbkeys = nullptr; +kblist_t *g_kbkeys = NULL; /* ============ @@ -163,7 +164,7 @@ int KB_ConvertString(char *in, char **ppout) if (!ppout) return 0; - *ppout = nullptr; + *ppout = NULL; p = in; pOut = sz; while (*p) @@ -178,7 +179,7 @@ int KB_ConvertString(char *in, char **ppout) *pEnd = '\0'; - pBinding = nullptr; + pBinding = NULL; if (strlen(binding + 1) > 0) { // See if there is a binding for binding? @@ -240,7 +241,7 @@ struct kbutton_s DLLEXPORT *KB_Find(const char *name) p = p->next; } - return nullptr; + return NULL; } /* @@ -279,7 +280,7 @@ Add kbutton_t definitions that the engine can query if needed */ void KB_Init(void) { - g_kbkeys = nullptr; + g_kbkeys = NULL; KB_Add("in_graph", &in_graph); KB_Add("in_mlook", &in_mlook); @@ -303,7 +304,7 @@ void KB_Shutdown(void) free(p); p = n; } - g_kbkeys = nullptr; + g_kbkeys = NULL; } /* @@ -442,11 +443,7 @@ void IN_ForwardUp(void) gHUD.m_Spectator.HandleButtonsUp(IN_FORWARD); } -//#define GAME_LEAP(dir) ServerCmd(UTIL_VarArgs("game_leap %s %f", dir, player.Stamina)) - -inline void GAME_LEAP(const char * dir, float& stamina){ - ServerCmd(UTIL_VarArgs("game_leap %s %f", dir, stamina)); -} +#define GAME_LEAP(dir) ServerCmd(UTIL_VarArgs("game_leap %s %f", dir, player.Stamina)) void IN_BackDown(void) { @@ -456,7 +453,7 @@ void IN_BackDown(void) float cvar_flDtapDelay = CVAR_GET_FLOAT("ms_doubletap_delay"); if ((!strcmp(CVAR_GET_STRING("ms_doubletapdodge"), "1") && lastMoveBackUp + cvar_flDtapDelay > gpGlobals->time)) - GAME_LEAP("back", player.Stamina); + GAME_LEAP("back"); } void IN_BackUp(void) @@ -479,7 +476,7 @@ void IN_MoveleftDown(void) float cvar_flDtapDelay = CVAR_GET_FLOAT("ms_doubletap_delay"); if ((!strcmp(CVAR_GET_STRING("ms_doubletapdodge"), "1") && lastMoveLeftUp + cvar_flDtapDelay > gpGlobals->time)) - GAME_LEAP("left", player.Stamina); + GAME_LEAP("left"); } void IN_MoveleftUp(void) @@ -497,7 +494,7 @@ void IN_MoverightDown(void) float cvar_flDtapDelay = CVAR_GET_FLOAT("ms_doubletap_delay"); if ((!strcmp(CVAR_GET_STRING("ms_doubletapdodge"), "1") && lastMoveRightUp + cvar_flDtapDelay > gpGlobals->time)) - GAME_LEAP("right", player.Stamina); + GAME_LEAP("right"); } void IN_MoverightUp(void) @@ -1137,10 +1134,14 @@ void ShutdownInput(void) KB_Shutdown(); } +void CL_UnloadParticleMan(); + void DLLEXPORT HUD_Shutdown(void) { + MS_INFO("[HUD_Shutdown: Enter]"); ScriptMgr::GameShutdown(); gClient.Shutdown(); + CL_UnloadParticleMan(); ShutdownInput(); #ifndef _WIN32 diff --git a/src/game/client/inputw32.cpp b/src/game/client/inputw32.cpp index c80d25ddc..92ad2dfdf 100644 --- a/src/game/client/inputw32.cpp +++ b/src/game/client/inputw32.cpp @@ -27,7 +27,7 @@ #include #include -constexpr int MOUSE_BUTTON_COUNT = 5; +#define MOUSE_BUTTON_COUNT 5 // Set this to 1 to show mouse cursor. Experimental int g_iVisibleMouse = 0; @@ -95,18 +95,15 @@ static bool g_ReceivedFirstMouseActivate = false; // joystick defines and variables // where should defines be moved? - -enum { - JOY_ABSOLUTE_AXIS = 0x00000000, // control like a joystick - JOY_RELATIVE_AXIS = 0x00000010, // control like a mouse, spinner, trackball - JOY_MAX_AXES = 6, // X, Y, Z, R, U, V - JOY_AXIS_X = 0, - JOY_AXIS_Y = 1, - JOY_AXIS_Z = 2, - JOY_AXIS_R = 3, - JOY_AXIS_U = 4, - JOY_AXIS_V = 5 -}; +#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick +#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball +#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V +#define JOY_AXIS_X 0 +#define JOY_AXIS_Y 1 +#define JOY_AXIS_Z 2 +#define JOY_AXIS_R 3 +#define JOY_AXIS_U 4 +#define JOY_AXIS_V 5 enum _ControlList { @@ -190,7 +187,7 @@ long ThreadInterlockedExchange(long *pDest, long value) DWORD WINAPI MousePos_ThreadFunction(LPVOID p) { - s_hMouseDoneQuitEvent = CreateEvent(NULL, false, false, NULL); + s_hMouseDoneQuitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); while (1) { @@ -320,7 +317,6 @@ void IN_Shutdown(void) if (s_hMouseThread) { - TerminateThread(s_hMouseThread, 0); CloseHandle(s_hMouseThread); s_hMouseThread = (HANDLE)0; @@ -659,11 +655,10 @@ void IN_StartupJoystick(void) // assume no joystick joy_avail = 0; - unsigned int nJoysticks = SDL_NumJoysticks(); - + int nJoysticks = SDL_NumJoysticks(); if (nJoysticks > 0) { - for (unsigned int i = 0; i < nJoysticks; i++) + for (int i = 0; i < nJoysticks; i++) { if (SDL_IsGameController(i)) { @@ -1096,7 +1091,7 @@ void IN_Init(void) { s_mouseDeltaX = s_mouseDeltaY = 0; - s_hMouseQuitEvent = CreateEvent(NULL, false, false, NULL); + s_hMouseQuitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (s_hMouseQuitEvent) { s_hMouseThread = CreateThread(NULL, 0, MousePos_ThreadFunction, NULL, 0, &s_hMouseThreadId); diff --git a/src/game/client/message.cpp b/src/game/client/message.cpp index 7add57e7e..105eefdcf 100644 --- a/src/game/client/message.cpp +++ b/src/game/client/message.cpp @@ -88,18 +88,18 @@ int CHudMessage::XPosition(float x, int width, int totalWidth) if (x == -1) { - xPos = (ScreenWidth() - width) / 2; + xPos = (ScreenWidth - width) / 2; } else { if (x < 0) - xPos = (1.0 + x) * ScreenWidth() - totalWidth; // Alight right + xPos = (1.0 + x) * ScreenWidth - totalWidth; // Alight right else - xPos = x * ScreenWidth(); + xPos = x * ScreenWidth; } - if (xPos + width > ScreenWidth()) - xPos = ScreenWidth() - width; + if (xPos + width > ScreenWidth) + xPos = ScreenWidth - width; else if (xPos < 0) xPos = 0; @@ -111,18 +111,18 @@ int CHudMessage::YPosition(float y, int height) int yPos; if (y == -1) // Centered? - yPos = (ScreenHeight() - height) * 0.5; + yPos = (ScreenHeight - height) * 0.5; else { // Alight bottom? if (y < 0) - yPos = (1.0 + y) * ScreenHeight() - height; // Alight bottom + yPos = (1.0 + y) * ScreenHeight - height; // Alight bottom else // align top - yPos = y * ScreenHeight(); + yPos = y * ScreenHeight; } - if (yPos + height > ScreenHeight()) - yPos = ScreenHeight() - height; + if (yPos + height > ScreenHeight) + yPos = ScreenHeight - height; else if (yPos < 0) yPos = 0; @@ -187,7 +187,7 @@ void CHudMessage::MessageScanNextChar(void) if (m_parms.pMessage->effect == 1 && m_parms.charTime != 0) { - if (m_parms.x >= 0 && m_parms.y >= 0 && (m_parms.x + gHUD.m_scrinfo.charWidths[m_parms.text]) <= ScreenWidth()) + if (m_parms.x >= 0 && m_parms.y >= 0 && (m_parms.x + gHUD.m_scrinfo.charWidths[m_parms.text]) <= ScreenWidth) TextMessageDrawChar(m_parms.x, m_parms.y, m_parms.text, m_parms.pMessage->r2, m_parms.pMessage->g2, m_parms.pMessage->b2); } } @@ -292,7 +292,7 @@ void CHudMessage::MessageDrawScan(client_textmessage_t *pMessage, float time) int next = m_parms.x + gHUD.m_scrinfo.charWidths[m_parms.text]; MessageScanNextChar(); - if (m_parms.x >= 0 && m_parms.y >= 0 && next <= ScreenWidth()) + if (m_parms.x >= 0 && m_parms.y >= 0 && next <= ScreenWidth) TextMessageDrawChar(m_parms.x, m_parms.y, m_parms.text, m_parms.r, m_parms.g, m_parms.b); m_parms.x = next; } @@ -456,7 +456,7 @@ int CHudMessage::MsgFunc_HudText(const char *pszName, int iSize, void *pbuf) int CHudMessage::MsgFunc_GameTitle(const char *pszName, int iSize, void *pbuf) { m_pGameTitle = TextMessageGet("GAMETITLE"); - if (m_pGameTitle != nullptr) + if (m_pGameTitle != NULL) { m_gameTitleTime = gHUD.m_flTime; diff --git a/src/game/client/ms/action.cpp b/src/game/client/ms/action.cpp index c5b1c8ec0..04de03458 100644 --- a/src/game/client/ms/action.cpp +++ b/src/game/client/ms/action.cpp @@ -49,7 +49,7 @@ int CHudAction::MsgFunc_Action(const char *pszName, int iSize, void *pbuf) NewAction.Name = READ_STRING(); NewAction.ID = ID; - for (unsigned int i = 0; i < PlayerActions.size(); i++) + for (int i = 0; i < PlayerActions.size(); i++) if (PlayerActions[i].ID == NewAction.ID) { PlayerActions[i] = NewAction; @@ -60,7 +60,7 @@ int CHudAction::MsgFunc_Action(const char *pszName, int iSize, void *pbuf) } else //Remove { - for (unsigned int i = 0; i < PlayerActions.size(); i++) + for (int i = 0; i < PlayerActions.size(); i++) if (PlayerActions[i].ID == ID) { PlayerActions.erase(i); @@ -90,7 +90,7 @@ void CHudAction::UserCmd_Action(void) int iBitsValid = 0; msstring MenuText(msstring(Localized("#ACTION_QUERY")) + "\n\n"); - for (unsigned int i = 0; i < PlayerActions.size(); i++) + for (int i = 0; i < PlayerActions.size(); i++) { //Print("DEBUG: UserCmd_Action: loop: %i %s %s\n",i,PlayerActions[i].Name.c_str(),PlayerActions[i].ID.c_str()); MenuText += (i + 1); diff --git a/src/game/client/ms/action.h b/src/game/client/ms/action.h index 0b1a47d15..149c88704 100644 --- a/src/game/client/ms/action.h +++ b/src/game/client/ms/action.h @@ -16,7 +16,7 @@ class CHudAction : public CHudBase int MsgFunc_Action(const char *pszName, int iSize, void *pbuf); void UserCmd_Action(void); void SelectMenuItem(int menu_item); - char Name[32] = "CHudAction"; + mslist PlayerActions; }; #endif //HUD_ACTION_H diff --git a/src/game/client/ms/clenv.h b/src/game/client/ms/clenv.h deleted file mode 100644 index d02c1fcf8..000000000 --- a/src/game/client/ms/clenv.h +++ /dev/null @@ -1,61 +0,0 @@ -//The client-side enviroment -// - -//Used by various source files - -class CEnvMgr -{ -public: - static void Init(); - static void InitNewLevel(); - static void Think_DrawTransparentTriangles(); - static void RenderSky(); - static void Cleanup(); - - static void ChangeSkyTexture(const char* NewTexture); - static void ChangeTint(const Color4F &Color); - static void SetLightGamma(float Value); - - static float m_LightGamma; - static float m_MaxViewDistance; - - //Fog - struct fog_t - { - bool Enabled; - Vector Color; - float Density, Start, End; - int Type; - }; - static fog_t m_Fog; -}; - -//Mastersword Special rendering -class CRender -{ -public: - static void PushHLStates(); - static void PopHLStates(); - - static void Cleanup(); - - //Render to texture interface - static void RT_ClearBuffer(bool ClearColor, bool ClearDepth, bool ClearStencil); - static void SetRenderTarget(bool ToTexture, bool ClearDepth = true); - static void SyncOffScreenSurface(); - - static bool CheckOpenGL(); //MS only works in openGL - static void CleanupWGL(); - static void RT_GetNewFrameBufferTexture(uint &TextureID); - static void RT_BindTexture(); - static void RT_ReleaseTexture(); - - static int m_OldHLTexture[10]; - static bool m_OldMultiTextureEnabled; - - static float m_RT_SizeRatio; - static uint m_RT_Width; //Properties of offscreen buffer - static uint m_RT_Height; - static float m_RT_TexU; - static float m_RT_TexV; -}; diff --git a/src/game/client/ms/clglobal.cpp b/src/game/client/ms/clglobal.cpp index eecf08042..bb7e01cab 100644 --- a/src/game/client/ms/clglobal.cpp +++ b/src/game/client/ms/clglobal.cpp @@ -3,7 +3,7 @@ #include "com_weapons.h" #include "msdllheaders.h" #include "clglobal.h" -#include "clenv.h" +#include "render/clenv.h" #include "mscharacter.h" #include "vgui_menudefsshared.h" #include "player/player.h" @@ -27,7 +27,6 @@ std::vector MSCLGlobals::m_Strings; //All client-side globally mslist MSCLGlobals::m_ClEntites; //All client-side entities mslist MSCLGlobals::m_ClModels; //Extra models to be updated/animated client-side cl_entity_t MSCLGlobals::CLViewEntities[MAX_PLAYER_HANDITEMS]; //All View entity models -mslist MSCLGlobals::Textures; //Custom textures, to be rendered in a unique way (reflective, blended, etc) hudcharanims_t MSCLGlobals::DefaultHUDCharAnims; //Anims for the char select VGUI hudsounds_t MSCLGlobals::DefaultHUDSounds; //HUD sounds hudcoords_t MSCLGlobals::DefaultHUDCoords; //HUD placement coordinates @@ -44,9 +43,10 @@ void MSCLGlobals::AddEnt(CBaseEntity *pEntity) m_ClEntites.add(pEntity); } + void MSCLGlobals::RemoveEnt(CBaseEntity *pEntity, bool fDelete) { - for (unsigned int e = 0; e < m_ClEntites.size(); e++) + for (int e = 0; e < m_ClEntites.size(); e++) if (m_ClEntites[e] == pEntity) { m_ClEntites.erase(e); @@ -69,7 +69,72 @@ void MSCLGlobals::Initialize() // Set up pointer // Fill in current time gpGlobals->time = gEngfuncs.GetClientTime(); + + // //Client CVARs + // CVAR_CREATE("ms_status_icons", "1", FCVAR_CLIENTDLL); // Drigien MAY2008 - Shows/Hides The HUD Status Icons + // //JAN2010_11 - not optional - used to blind player sometimes + // //CVAR_CREATE( "ms_showhudimgs", "1", FCVAR_CLIENTDLL ); // Drigien MAY2008 - Shows/Hides The HUD Images + // CVAR_CREATE("hud_classautokill", "1", FCVAR_ARCHIVE); // controls whether or not to suicide immediately on TF class switch + // CVAR_CREATE("hud_takesshots", "0", FCVAR_ARCHIVE); // controls whether or not to automatically take screenshots at the end of a round + // CVAR_CREATE("ms_hidehud", "0", FCVAR_ARCHIVE); // Hides the HUD and viewmodel completely + // CVAR_CREATE("ms_lildude", "1", FCVAR_ARCHIVE); // Thothie MAR2007a - Hides the 3d Guy if set 0 + // CVAR_CREATE("ms_clgender", "0", FCVAR_CLIENTDLL); // Thothie FEB2011_22 - Adding a cvar to store client gender + // CVAR_CREATE("ms_xpdisplay", "0", FCVAR_ARCHIVE); // Thothie AUG2007a - XP Display Options + // CVAR_CREATE("ms_developer", "0", FCVAR_CLIENTDLL); // Thothie MAR2007b - Hides client side developer messages when set to 0 + // CVAR_CREATE("ms_evthud_decaytime", "5", FCVAR_ARCHIVE); // Time each line in the Event Console lasts before it shrinks + // CVAR_CREATE("ms_evthud_history", "10", FCVAR_ARCHIVE); // Max number of text lines to keep in the Event Console history + // CVAR_CREATE("ms_evthud_size", "5", FCVAR_ARCHIVE); // Max number of text lines shown at once + // CVAR_CREATE("ms_evthud_bgtrans", "0", FCVAR_CLIENTDLL); // Transparency of the background + // CVAR_CREATE("ms_txthud_decaytime", "9", FCVAR_ARCHIVE); // Time each line in the Event Console lasts before it shrinks + // CVAR_CREATE("ms_txthud_history", "50", FCVAR_ARCHIVE); // Max number of text lines to keep in the Event Console history + // CVAR_CREATE("ms_txthud_size", "8", FCVAR_ARCHIVE); // Max number of text lines shown at once + // CVAR_CREATE("ms_txthud_bgtrans", "0", FCVAR_ARCHIVE); // Transparency of the background + // CVAR_CREATE("ms_txthud_width", "640", FCVAR_ARCHIVE); // Width of console + // CVAR_CREATE(CVAR_HELPTIPS, "1", FCVAR_ARCHIVE /*|FCVAR_USERINFO*/); // Whether help tips are shown + // CVAR_CREATE("ms_bloom_darken", "-1", FCVAR_ARCHIVE); // MiB DEC2010 - Darken bloom + // CVAR_CREATE("ms_bloom_level", "0", FCVAR_ARCHIVE); // Thothie DEC2010_30 - Fix ms_bloom_level stickiness + // //CVAR_CREATE("ms_reconnect_delay", "5", FCVAR_ARCHIVE); // Thothie AUG2017 - Make reconnect delay adjustable client side + // CVAR_CREATE(MSCVAR_QUICKSLOT_TIMEOUT, "2.5", FCVAR_ARCHIVE); // Timeout for the quickslots + // CVAR_CREATE("ms_autocharge", "1", FCVAR_ARCHIVE); // MiB MAR2012_05 - Let's you auto-charge your attack + // CVAR_CREATE("ms_doubletapdodge", "0", FCVAR_ARCHIVE); // MiB MAR2012_05 -Enable/Disable double tapping to dodge + // CVAR_CREATE("ms_invtype", "1", FCVAR_ARCHIVE); // MiB FEB2012_12 - Inventory types (added post-doc by Thothie) + // CVAR_CREATE("ms_showotherglow", "1", FCVAR_ARCHIVE); + // CVAR_CREATE("ms_chargebar_sound", "magic/chargebar_alt1.wav", FCVAR_ARCHIVE); + // CVAR_CREATE("ms_chargebar_volume", "15", FCVAR_ARCHIVE); + // CVAR_CREATE("ms_doubletap_delay", "0.45", FCVAR_ARCHIVE); // The higher the amount, the longer the player has to hit left/right/back for a second time + // CVAR_CREATE("ms_sprint_verbose", "2", FCVAR_ARCHIVE); // 0 for no messages , 1 for only warnings , 2 for everything + // CVAR_CREATE("ms_sprint_toggle", "1", FCVAR_ARCHIVE); + // CVAR_CREATE("ms_sprint_doubletap", "1", FCVAR_ARCHIVE); + + //CVAR_CREATE("ms_alpha_inventory", "0", FCVAR_ARCHIVE); // MiB FEB2019_24 [ALPHABETICAL_INVENTORY] + //CVAR_CREATE("ms_hands_display", "2", FCVAR_ARCHIVE); + //CVAR_CREATE("ms_hands_display_y", "20", FCVAR_ARCHIVE); + //CVAR_CREATE("ms_scrollamount", "30", FCVAR_ARCHIVE); + //CVAR_CREATE("ms_doubleclicktime", "1", FCVAR_ARCHIVE); + + /*msstring DefaultLANID = "this_must_be_unique"; + gEngfuncs.pfnRegisterVariable( "ms_id", DefaultID, FCVAR_USERINFO|FCVAR_ARCHIVE ); + + if( DefaultLANID == (const char *)gEngfuncs.pfnGetCvarString("ms_id") ) + { + //If I'm still using the default ID, generate a random one + char ID[8]; + for (int i = 0; i < 6; i++) + { + int CharType = RANDOM_LONG(0,2); + int Low, High; + switch( CharType ) { + case 0: Low = '0'; High = '9'; break; + case 1: Low = 'a'; High = 'z'; break; + case 2: Low = 'A'; High = 'Z'; break; + } + ID[i] = RANDOM_LONG( Low, High ); ID[i+1] = 0; + } + gEngfuncs.pfnClientCmd( msstring("ms_id ") + ID + "\n" ); + }*/ + InitializePlayer(); + MSGlobalItemInit(); } @@ -82,17 +147,17 @@ void MSCLGlobals::InitializePlayer() player.CreateStats(); player.m_CharacterState = CHARSTATE_UNLOADED; player.m_DisplayName = "Adventurer"; - player.PlayerHands = nullptr; + player.PlayerHands = NULL; player.ClearConditions(MONSTER_OPENCONTAINER); player.Gear.clear(); player.m_HP = player.m_MP = 0; - player.m_fGameHUDInitialized = true; + player.m_fGameHUDInitialized = TRUE; //player.pbs.fMaxForwardPressTime = 0; player.m_SprintDelay = gpGlobals->time; player.m_Initialized = false; - for (unsigned int i = 0; i < MAX_PLAYER_HANDITEMS; i++) + for (int i = 0; i < MAX_PLAYER_HANDITEMS; i++) { MSCLGlobals::CLViewEntities[i].index = MSGlobals::ClEntities[(i != 2) ? CLPERMENT_LEFTVIEW + i : CLPERMENT_LEFTVIEW]; MSCLGlobals::CLViewEntities[i].curstate.number = MSGlobals::ClEntities[(i != 2) ? CLPERMENT_LEFTVIEW + i : CLPERMENT_LEFTVIEW]; @@ -115,7 +180,7 @@ void MSCLGlobals::Think() RemoveEnt(m_ClEntites[e], m_ClEntites[e] != &player); //Call entity Think() functions - for (unsigned int e = 0; e < m_ClEntites.size(); e++) + for (int e = 0; e < m_ClEntites.size(); e++) if (flLastThinkTime <= m_ClEntites[e]->pev->nextthink && m_ClEntites[e]->pev->nextthink < gpGlobals->time) m_ClEntites[e]->Think(); @@ -130,7 +195,7 @@ void MSCLGlobals::PrintAllEntites() Print("Global Items...\n"); int items = 0; - for (unsigned int e = 0; e < m_ClEntites.size(); e++) + for (int e = 0; e < m_ClEntites.size(); e++) Print("Item %i: %s", items++, m_ClEntites[e]->DisplayName()); } @@ -139,7 +204,7 @@ void MSCLGlobals::RemoveAllEntities() //Delete all entites if (player.m_CharacterState == CHARSTATE_LOADED) { - player.Killed(nullptr, 0); + player.Killed(NULL, 0); player.RemoveAllItems(false, true); } @@ -148,7 +213,7 @@ void MSCLGlobals::RemoveAllEntities() //deleted beforehand //(presumably within RemoveAllItems() somewhere) int killed = 0; - for (unsigned int e = 0; e < m_ClEntites.size(); e++) + for (int e = 0; e < m_ClEntites.size(); e++) { CBaseEntity *pEntity = m_ClEntites[e]; if (!pEntity) continue; @@ -158,7 +223,7 @@ void MSCLGlobals::RemoveAllEntities() //unset player hands (should happen in CBasePlayer::RemoveAllItems() first...) if (pEntity == (CBaseEntity *)player.PlayerHands) - player.PlayerHands = nullptr; + player.PlayerHands = NULL; Print("Cleanup Item %i: %s\n", killed++, pEntity->DisplayName()); @@ -235,7 +300,7 @@ string_t MSCLGlobals::AllocString(const char *pszString) return 0; size_t size = m_Strings.size(); - for (unsigned int s = 0; s < size; s++) + for (int s = 0; s < size; s++) { if (FStrEq(m_Strings[s].c_str(), pszString)) return m_Strings[s].c_str() - gpGlobals->pStringBase; @@ -275,6 +340,7 @@ void MSCLGlobals::SetupGlobalEngFuncRedirects(void) g_engfuncs.pfnRandomFloat = gEngfuncs.pfnRandomFloat; g_engfuncs.pfnRandomLong = gEngfuncs.pfnRandomLong; } + //I've recieved all script files, I can now spawn void CreateStoreMenus(); void ShowVGUIMenu(int iMenu); @@ -290,8 +356,6 @@ void MSCLGlobals::SpawnIntoServer() CreateStoreMenus(); - MSChar_Interface::CLInit(); - ShowVGUIMenu(MENU_NEWCHARACTER); MS_INFO("DONE"); @@ -310,7 +374,7 @@ void MSCLGlobals::Cleanup() RemoveAllEntities(); //Remove Environment Special Effects - CRender::Cleanup(); + CEnvMgr::Cleanup(); } void DLLAttach(HINSTANCE hinstDLL) @@ -333,6 +397,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) DLLAttach(hinstDLL); else if (fdwReason == DLL_PROCESS_DETACH) DLLDetach(); - return true; + return TRUE; } #endif diff --git a/src/game/client/ms/clglobal.h b/src/game/client/ms/clglobal.h index 1632d6a16..45f4554c2 100644 --- a/src/game/client/ms/clglobal.h +++ b/src/game/client/ms/clglobal.h @@ -9,23 +9,6 @@ inline CBaseEntity *PrivData(entvars_t *pev) { return (CBaseEntity *)pev->pConta //Client-side Globals //=================== -struct mstexture_t -{ - msstring Name; - bool IsReflective, //Reflect world - IsWater; //Do splashes, refractions - //Color4F Color; - //bool Blending; //Blend surface texture -- UNDONE - map does this - struct mirrorsettings_t - { - Color4F Color; - bool Blending; //Blend reflection with the original surface texture - float Range; //Only reflects when eye is within this range - bool NoWorld; //Don't reflect the world - bool NoEnts; //Don't reflect studio ents - } Mirror; -}; - struct hudcharanims_t { msstring Idle_NoWeapon, @@ -57,7 +40,6 @@ class MSCLGlobals static bool CreatingCharacter; //In the process of creating a character? static bool CamThirdPerson; //Camera is in thirdperson? static bool OtherPlayers; //Other players who can legally play this map are on the server - static mslist Textures; //Custom textures, to be rendered in a unique way (reflective, blended, etc) static hudcharanims_t DefaultHUDCharAnims; //Anims for the char select VGUI static hudsounds_t DefaultHUDSounds; //HUD sounds static hudcoords_t DefaultHUDCoords; //HUD placement coordinates diff --git a/src/game/client/ms/clplayer.cpp b/src/game/client/ms/clplayer.cpp index 99e1cbc7b..271087a09 100644 --- a/src/game/client/ms/clplayer.cpp +++ b/src/game/client/ms/clplayer.cpp @@ -509,7 +509,7 @@ physent_t* MSUTIL_EntityByIndex(int playerindex) } } gEngfuncs.pEventAPI->EV_PopPMStates(); - return nullptr; + return NULL; } /* ===================== @@ -595,8 +595,7 @@ void HUD_WeaponsPostThink(local_state_s* from, local_state_s* to, usercmd_t* cmd static int PreserveMask = PLAYER_MOVE_RUNNING | PLAYER_MOVE_ATTACKING; //These are client-side bits to be saved int PreserveBits = (player.m_StatusFlags & PreserveMask); //Save the client-side bits - ClearBits(from->client.iuser3, PreserveMask); //clear flags execpt client side ones - player.m_StatusFlags = from->client.iuser3; //Copy all the flags except the client-side ones + player.m_StatusFlags = ClearBits(from->client.iuser3, PreserveMask); //Copy all the flags except the client-side ones SetBits(player.m_StatusFlags, PreserveBits); //Copy the client-side bits back over to->playerstate.iuser3 = from->playerstate.iuser3; @@ -666,7 +665,7 @@ void HUD_WeaponsPostThink(local_state_s* from, local_state_s* to, usercmd_t* cmd player.m_afButtonLast = KeyHistory[0].Buttons; //player.pev->button; // Wipe it so we can't use it after this frame - g_finalstate = nullptr; + g_finalstate = NULL; } /* ===================== @@ -731,7 +730,7 @@ void ShowWeaponDesc(CGenericItem* pItem) msg.fadein = 2.0; msg.holdtime = 5.0; msg.fadeout = 3.0; - msg.pName = nullptr; + msg.pName = NULL; msg.pMessage = cDescString; gHUD.m_Message.MessageAdd(msg); } @@ -893,11 +892,15 @@ int __MsgFunc_Item(const char* pszName, int iSize, void* pbuf) CGenericItem* pItem = MSUtil_GetItemByID(lID); int attackNum = READ_BYTE(); - attackdata_t* AttData = &pItem->m_Attacks[attackNum]; msstring PropName = READ_STRING(); msstring PropValue = READ_STRING(); + if (!pItem || attackNum >= (int)pItem->m_Attacks.size()) + break; + + attackdata_t* AttData = &pItem->m_Attacks[attackNum]; + int Int = atoi(PropValue); float Float = atof(PropValue); Vector Vec = StringToVec(PropValue); @@ -975,7 +978,7 @@ int __MsgFunc_Item(const char* pszName, int iSize, void* pbuf) //setviewmodelprop edits APR2008a MIB { msstring Mode = READ_STRING(); - int iHand = READ_SHORT(); + ulong lID = READ_LONG(); int iParam1; float fParam1; msstring sParam1; @@ -990,10 +993,10 @@ int __MsgFunc_Item(const char* pszName, int iSize, void* pbuf) iParam1 = READ_BYTE(); } - CGenericItem* pItem = player.Hand(iHand); + CGenericItem* pItem = MSUtil_GetItemByID(lID); if (pItem) { - if (Mode == "submodel") + if (Mode == "submodel" || Mode == "submodelbody") { pItem->m_ViewModelPart = iParam1; pItem->m_ViewModelSubmodel = READ_BYTE(); @@ -1029,11 +1032,11 @@ int __MsgFunc_Item(const char* pszName, int iSize, void* pbuf) CGenericItem* pItem = MSUtil_GetItemByID(lID); msstring Event = READ_STRING(); - unsigned int numParams = READ_BYTE(); + int numParams = READ_BYTE(); msstringlist Params; Params.clear(); - for (unsigned int i = 0; i < numParams; i++) + for (int i = 0; i < numParams; i++) Params.add(READ_STRING()); if (pItem) @@ -1094,7 +1097,7 @@ int __MsgFunc_SetProp(const char* pszName, int iSize, void* pbuf) //Memory dellocation errors when using '.erase()', so I'm now using this loop int idx = READ_BYTE(); msstringlist newSpells; - for (unsigned int i = 0; i < player.m_SpellList.size(); i++) + for (int i = 0; i < player.m_SpellList.size(); i++) if (i != idx) newSpells.add(player.m_SpellList[i]); //Add all spells to the new list except the one to erase player.m_SpellList = newSpells; //Overwrite the player spells with the new list @@ -1127,8 +1130,8 @@ void Player_ToggleInventory() return; } - CGenericItem* pWearable = nullptr; //Fallback, in case a pack isn't found - for (unsigned int i = 0; i < player.Gear.size(); i++) + CGenericItem* pWearable = NULL; //Fallback, in case a pack isn't found + for (int i = 0; i < player.Gear.size(); i++) { CGenericItem* pPack = player.Gear[i]; if (FBitSet(pPack->MSProperties(), ITEM_CONTAINER) && pPack->m_Location > ITEMPOS_HANDS) @@ -1232,7 +1235,7 @@ void __CmdFunc_DynamicNPC(void) } int iBitsValid = 0; - for (unsigned int i = 0; i < NPCList.size(); i++) + for (int i = 0; i < NPCList.size(); i++) { const char* arg = UTIL_VarArgs("%i. %s\n", i + 1, NPCList[i].c_str()); strncat(MenuText, arg, strlen(arg)); @@ -1300,7 +1303,7 @@ int __MsgFunc_CLDllFunc(const char* pszName, int iSize, void* pbuf) case 1: //Killed if (player.m_CharacterState == CHARSTATE_UNLOADED) break; - player.Killed(nullptr, NULL); + player.Killed(NULL, NULL); break; case 2: //[OPEN] @@ -1381,7 +1384,7 @@ int __MsgFunc_CLDllFunc(const char* pszName, int iSize, void* pbuf) //Set up a variable to switch back if (g_SwitchToHand == -1) g_SwitchToHand = player.m_CurrentHand; - if (player.SwitchHands(iHand, false)) + if (player.SwitchHands(iHand, FALSE)) player.BlockButton(IN_ATTACK); else g_SwitchToHand = -1; @@ -1394,12 +1397,6 @@ int __MsgFunc_CLDllFunc(const char* pszName, int iSize, void* pbuf) } break; - case 11: //Recieve char data - { - MSChar_Interface::HL_CLReadCharData(); - } - break; - case 12: //Item gain/lose quality { CGenericItem* pItem = MSUtil_GetItemByID(READ_LONG()); @@ -1444,14 +1441,6 @@ int __MsgFunc_CLDllFunc(const char* pszName, int iSize, void* pbuf) } break; - case 18: //Start receiving char from server - { - int CharIdx = READ_BYTE(); - uint Size = READ_LONG(); - MSChar_Interface::HL_CLNewIncomingChar(CharIdx, Size); - } - break; - case 20: //New quickslot was assigned { int Flags = READ_BYTE(); @@ -1477,7 +1466,7 @@ int __MsgFunc_CLDllFunc(const char* pszName, int iSize, void* pbuf) msg.fadein = 0.01; msg.holdtime = 3.0; msg.fadeout = 1.0; - msg.pName = nullptr; + msg.pName = NULL; msg.fxtime = 4.0; static char msgtext[256]; @@ -1500,7 +1489,7 @@ int __MsgFunc_CLDllFunc(const char* pszName, int iSize, void* pbuf) case 21: //Retrieve all quickslots (Sent at spawn) { - for (unsigned int i = 0; i < MAX_QUICKSLOTS; i++) + for (int i = 0; i < MAX_QUICKSLOTS; i++) { quickslot_t& QuickSlot = player.m_QuickSlots[i]; QuickSlot.Active = READ_BYTE() ? true : false; diff --git a/src/game/client/ms/fatigue.cpp b/src/game/client/ms/fatigue.cpp index 89bee72ca..710b642bf 100644 --- a/src/game/client/ms/fatigue.cpp +++ b/src/game/client/ms/fatigue.cpp @@ -31,7 +31,7 @@ MS_DECLARE_MESSAGE(m_Fatigue, Fatigue); int CHudFatigue::Init(void) { - m_DrawFatigue = false; + m_DrawFatigue = FALSE; HOOK_MESSAGE(Fatigue); //HOOK_COMMAND("fatigue", ToggleFatigue); @@ -47,8 +47,8 @@ int CHudFatigue::Draw(float flTime) { if (m_DrawFatigue) { - gHUD.DrawHudNumberSML(ScreenWidth() - 40, ScreenHeight() - 40, NULL, player.Stamina, 255, 255, 255); - gHUD.DrawHudNumberSML(ScreenWidth() - 20, ScreenHeight() - 40, NULL, player.MaxStamina(), 255, 255, 255); + gHUD.DrawHudNumberSML(ScreenWidth - 40, ScreenHeight - 40, NULL, player.Stamina, 255, 255, 255); + gHUD.DrawHudNumberSML(ScreenWidth - 20, ScreenHeight - 40, NULL, player.MaxStamina(), 255, 255, 255); } return 1; } diff --git a/src/game/client/ms/fatigue.h b/src/game/client/ms/fatigue.h index 8fa86c673..153d604bd 100644 --- a/src/game/client/ms/fatigue.h +++ b/src/game/client/ms/fatigue.h @@ -13,7 +13,6 @@ class CHudFatigue : public CHudBase void InitHUDData(void); int MsgFunc_Fatigue(const char *pszName, int iSize, void *pbuf); void UserCmd_ToggleFatigue(void); - char Name[32] = "CHudFatigue"; private: float fBreatheTime; diff --git a/src/game/client/ms/health.cpp b/src/game/client/ms/health.cpp index eea96b4a6..dc7a73f06 100644 --- a/src/game/client/ms/health.cpp +++ b/src/game/client/ms/health.cpp @@ -39,27 +39,26 @@ MS_DECLARE_MESSAGE(m_Health, HP) MS_DECLARE_MESSAGE(m_Health, MP) MS_DECLARE_MESSAGE(m_Health, Damage) -constexpr int MOVE_INC = 3; -constexpr const char* PAIN_NAME = "sprites/%d_pain.spr"; -constexpr const char* DAMAGE_NAME = "sprites/%d_dmg.spr"; +#define MOVE_INC 3 +#define PAIN_NAME "sprites/%d_pain.spr" +#define DAMAGE_NAME "sprites/%d_dmg.spr" int giDmgHeight, giDmgWidth; int giDmgFlags[NUM_DMG_TYPES] = -{ - DMG_POISON, - DMG_ACID, - DMG_FREEZE | DMG_SLOWFREEZE, - DMG_DROWN, - DMG_BURN | DMG_SLOWBURN, - DMG_NERVEGAS, - DMG_RADIATION, - DMG_SHOCK, - DMG_CALTROP, - DMG_TRANQ, - DMG_CONCUSS, - DMG_HALLUC -}; + { + DMG_POISON, + DMG_ACID, + DMG_FREEZE | DMG_SLOWFREEZE, + DMG_DROWN, + DMG_BURN | DMG_SLOWBURN, + DMG_NERVEGAS, + DMG_RADIATION, + DMG_SHOCK, + DMG_CALTROP, + DMG_TRANQ, + DMG_CONCUSS, + DMG_HALLUC}; int CHudHealth::Init(void) { @@ -77,6 +76,14 @@ int CHudHealth::Init(void) m_iTempHP = m_iTempMP = 0; memset(m_dmg, 0, sizeof(DAMAGE_IMAGE) * NUM_DMG_TYPES); + + /* if( !CVAR_GET_FLOAT("gl_polyoffset") ) { + char a[64]; + _snprintf(a, sizeof(a), "Software mode detected! Disabling Health/Mana Flasks!.\n", CVAR_GET_FLOAT("gl_polyoffset") ); + ConsolePrint( a ); + m_iFlags = 0; + }*/ + gHUD.AddHudElem(this); return 1; } @@ -88,7 +95,7 @@ void CHudHealth::Reset(void) // force all the flashing damage icons to expire m_bitsDamage = 0; - for (unsigned int i = 0; i < NUM_DMG_TYPES; i++) + for (int i = 0; i < NUM_DMG_TYPES; i++) { m_dmg[i].fExpire = 0; } @@ -155,7 +162,7 @@ int CHudHealth::MsgFunc_Damage(const char *pszName, int iSize, void *pbuf) Vector vecFrom; - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) vecFrom[i] = READ_COORD(); UpdateTiles(gHUD.m_flTime, bitsDamage); @@ -177,7 +184,7 @@ void CHudHealth::GetPainColor(int &r, int &g, int &b) iHealth -= 25; else if (iHealth < 0) iHealth = 0; -#if 0 +#if 0 g = iHealth * 255 / 100; r = 255 - g; b = 0; @@ -201,6 +208,90 @@ void CHudHealth::GetPainColor(int &r, int &g, int &b) int CHudHealth::Draw(float flTime) { return 1; + /* int HPr, HPg, HPb; + int x, y; + int xFlask, yFlask; + int iHealth = player.m_HP, + iMaxHP = player.m_MaxHP, + iMana = player.m_MP, + iMaxMP = player.m_MaxMP; + + if( player.m_HP < 1.0f && player.m_HP > 0 ) iHealth = 1; //Cap integers at 1 + if( player.m_MP < 1.0f && player.m_MP > 0 ) iMana = 1; + + if ( gHUD.m_iHideHUDDisplay & (HIDEHUD_HEALTH|HIDEHUD_ALL) || !(m_iFlags&HUD_ACTIVE) ) + return 1; + + if ( !m_hSprite ) + m_hSprite = LoadSprite(PAIN_NAME); + + + // If health is getting low, make it bright red + //if (m_iHealth <= 15) ScaleColors(r, g, b, a ); + + if( (gHUD.m_flTime-flChangeTime) >= .007) { + float inc = (100/MOVE_INC); + if( m_iTempHP > iHealth ) { m_iTempHP -= (iHealth/inc)+1; if(m_iTempHPiHealth) m_iTempHP = iHealth; } + if( m_iTempMP > iMana ) { m_iTempMP -= (iMana/inc)+1; if(m_iTempMPiMana) m_iTempMP = iMana; } + flChangeTime = gHUD.m_flTime; + } + +// if( m_iTempHP < iHealth ) m_iTempHP = iHealth; +// if( m_iTempMP < iMana ) m_iTempMP = iMana; + +// ScaleColors(r, g, b, a ); + + int iHealthFlask = gHUD.GetSpriteIndex("healthflask"), + iManaFlask = gHUD.GetSpriteIndex("manaflask"), + iframe; + int SMLNumWidth = gHUD.GetSpriteRect(gHUD.m_HUD_numberSML_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_numberSML_0).left, + SMLSlashWidth = gHUD.GetSpriteRect(gHUD.m_HUD_char_slashSML).right - gHUD.GetSpriteRect(gHUD.m_HUD_char_slashSML).left, + HFlaskWidth = gHUD.GetSpriteRect(iHealthFlask).right - gHUD.GetSpriteRect(iHealthFlask).left, + MFlaskWidth = gHUD.GetSpriteRect(iManaFlask).right - gHUD.GetSpriteRect(iManaFlask).left; + int xStart, yStart; + + //y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2; + yFlask = ScreenHeight - 110; xFlask = XRES(15); + + xStart = (xFlask+(HFlaskWidth/2))-(((numofdigits(m_iTempHP)*SMLNumWidth)+(numofdigits(iMaxHP)*SMLNumWidth)+SMLSlashWidth)/2); yStart = ScreenHeight - 40; + + y = yStart; x = xStart; + + + float fltemp; int maxframes; + maxframes = (SPR_Frames(gHUD.GetSprite(iHealthFlask))-1); + fltemp = (float)((float)m_iTempHP/(float)iMaxHP) * maxframes; + iframe = min(fltemp,maxframes); //round up if not at integer + SPR_Set(gHUD.GetSprite(iHealthFlask), 128, 128, 128 ); + SPR_DrawHoles( iframe, xFlask, yFlask, &gHUD.GetSpriteRect(iHealthFlask)); + + GetPainColor( HPr, HPg, HPb ); + x = gHUD.DrawHudNumberSML(x, y, NULL, m_iTempHP, HPr, HPg, HPb); + + x = gHUD.DrawHudStringSML( x, y, "/", 255, 255, 255 ); + + x = gHUD.DrawHudNumberSML(x, y, NULL, iMaxHP, 255, 255, 255); + + xFlask += (gHUD.GetSpriteRect(iHealthFlask).right - gHUD.GetSpriteRect(iHealthFlask).left) + XRES(10); + + maxframes = (SPR_Frames(gHUD.GetSprite(iManaFlask))-1); + fltemp = (float)((float)m_iTempMP/(float)iMaxMP) * maxframes; + iframe = min(fltemp,maxframes); //round up if not at integer + SPR_Set(gHUD.GetSprite(iManaFlask), 128, 128, 128 ); + SPR_DrawHoles( iframe, xFlask, yFlask, &gHUD.GetSpriteRect(iManaFlask)); + + x = (xFlask+(MFlaskWidth/2))-(((numofdigits(m_iTempMP)*SMLNumWidth)+(numofdigits(iMaxMP)*SMLNumWidth)+SMLSlashWidth)/2); yStart = ScreenHeight - 40; + + x = gHUD.DrawHudNumberSML(x, y, NULL, m_iTempMP, 255, 255, 255); + + x = gHUD.DrawHudStringSML( x, y, "/", 255, 255, 255 ); + + x = gHUD.DrawHudNumberSML(x, y, NULL, iMaxMP, 255, 255, 255); + + DrawDamage(flTime); + return DrawPain(flTime);*/ } void CHudHealth::CalcDamageDirection(Vector vecFrom) @@ -215,8 +306,8 @@ void CHudHealth::CalcDamageDirection(Vector vecFrom) return; } - memcpy(vecOrigin, gHUD.m_vecOrigin, sizeof(Vector )); - memcpy(vecAngles, gHUD.m_vecAngles, sizeof(Vector )); + memcpy(vecOrigin, gHUD.m_vecOrigin, sizeof(Vector)); + memcpy(vecAngles, gHUD.m_vecAngles, sizeof(Vector)); VectorSubtract(vecFrom, vecOrigin, vecFrom); @@ -281,8 +372,8 @@ int CHudHealth::DrawPain(float flTime) ScaleColors(r, g, b, shade); SPR_Set(m_hSprite, r, g, b); - x = ScreenWidth() / 2 - SPR_Width(m_hSprite, 0) / 2; - y = ScreenHeight() / 2 - SPR_Height(m_hSprite, 0) * 3; + x = ScreenWidth / 2 - SPR_Width(m_hSprite, 0) / 2; + y = ScreenHeight / 2 - SPR_Height(m_hSprite, 0) * 3; SPR_DrawAdditive(0, x, y, NULL); m_fAttackFront = V_max(0, m_fAttackFront - fFade); } @@ -296,8 +387,8 @@ int CHudHealth::DrawPain(float flTime) ScaleColors(r, g, b, shade); SPR_Set(m_hSprite, r, g, b); - x = ScreenWidth() / 2 + SPR_Width(m_hSprite, 1) * 2; - y = ScreenHeight() / 2 - SPR_Height(m_hSprite, 1) / 2; + x = ScreenWidth / 2 + SPR_Width(m_hSprite, 1) * 2; + y = ScreenHeight / 2 - SPR_Height(m_hSprite, 1) / 2; SPR_DrawAdditive(1, x, y, NULL); m_fAttackRight = V_max(0, m_fAttackRight - fFade); } @@ -311,8 +402,8 @@ int CHudHealth::DrawPain(float flTime) ScaleColors(r, g, b, shade); SPR_Set(m_hSprite, r, g, b); - x = ScreenWidth() / 2 - SPR_Width(m_hSprite, 2) / 2; - y = ScreenHeight() / 2 + SPR_Height(m_hSprite, 2) * 2; + x = ScreenWidth / 2 - SPR_Width(m_hSprite, 2) / 2; + y = ScreenHeight / 2 + SPR_Height(m_hSprite, 2) * 2; SPR_DrawAdditive(2, x, y, NULL); m_fAttackRear = V_max(0, m_fAttackRear - fFade); } @@ -326,8 +417,8 @@ int CHudHealth::DrawPain(float flTime) ScaleColors(r, g, b, shade); SPR_Set(m_hSprite, r, g, b); - x = ScreenWidth() / 2 - SPR_Width(m_hSprite, 3) * 3; - y = ScreenHeight() / 2 - SPR_Height(m_hSprite, 3) / 2; + x = ScreenWidth / 2 - SPR_Width(m_hSprite, 3) * 3; + y = ScreenHeight / 2 - SPR_Height(m_hSprite, 3) / 2; SPR_DrawAdditive(3, x, y, NULL); m_fAttackLeft = V_max(0, m_fAttackLeft - fFade); @@ -338,6 +429,66 @@ int CHudHealth::DrawPain(float flTime) return 1; } +/*int CHudHealth::DrawDamage(float flTime) +{ + int r, g, b, a; + DAMAGE_IMAGE *pdmg; + + if (!m_bitsDamage) + return 1; + + UnpackRGB(r,g,b, RGB_YELLOWISH); + + a = (int)( fabs(sin(flTime*2)) * 256.0); + + ScaleColors(r, g, b, a); + + // Draw all the items + for (int i = 0; i < NUM_DMG_TYPES; i++) + { + if (m_bitsDamage & giDmgFlags[i]) + { + pdmg = &m_dmg[i]; + SPR_Set(gHUD.GetSprite(m_HUD_dmg_bio + i), r, g, b ); + SPR_DrawAdditive(0, pdmg->x, pdmg->y, &gHUD.GetSpriteRect(m_HUD_dmg_bio + i)); + } + } + + + // check for bits that should be expired + for ( i = 0; i < NUM_DMG_TYPES; i++ ) + { + DAMAGE_IMAGE *pdmg = &m_dmg[i]; + + if ( m_bitsDamage & giDmgFlags[i] ) + { + pdmg->fExpire = min( flTime + DMG_IMAGE_LIFE, pdmg->fExpire ); + + if ( pdmg->fExpire <= flTime // when the time has expired + && a < 40 ) // and the flash is at the low point of the cycle + { + pdmg->fExpire = 0; + + int y = pdmg->y; + pdmg->x = pdmg->y = 0; + + // move everyone above down + for (int j = 0; j < NUM_DMG_TYPES; j++) + { + pdmg = &m_dmg[j]; + if ((pdmg->y) && (pdmg->y < y)) + pdmg->y += giDmgHeight; + + } + + m_bitsDamage &= ~giDmgFlags[i]; // clear the bits + } + } + } + + return 1; +}*/ + void CHudHealth::UpdateTiles(float flTime, long bitsDamage) { DAMAGE_IMAGE *pdmg; @@ -345,14 +496,14 @@ void CHudHealth::UpdateTiles(float flTime, long bitsDamage) // Which types are new? long bitsOn = ~m_bitsDamage & bitsDamage; - for (unsigned int i = 0; i < NUM_DMG_TYPES; i++) + for (int i = 0; i < NUM_DMG_TYPES; i++) { pdmg = &m_dmg[i]; // Is this one already on? if (m_bitsDamage & giDmgFlags[i]) { - pdmg->fExpire = flTime + static_cast(DMG_IMAGE_LIFE); // extend the duration + pdmg->fExpire = flTime + DMG_IMAGE_LIFE; // extend the duration if (!pdmg->fBaseline) pdmg->fBaseline = flTime; } @@ -362,8 +513,8 @@ void CHudHealth::UpdateTiles(float flTime, long bitsDamage) { // put this one at the bottom pdmg->x = giDmgWidth / 8; - pdmg->y = ScreenHeight() - giDmgHeight * 2; - pdmg->fExpire = flTime + static_cast(DMG_IMAGE_LIFE); + pdmg->y = ScreenHeight - giDmgHeight * 2; + pdmg->fExpire = flTime + DMG_IMAGE_LIFE; // move everyone else up for (int j = 0; j < NUM_DMG_TYPES; j++) diff --git a/src/game/client/ms/health.h b/src/game/client/ms/health.h index 171efbb87..d2b8799a7 100644 --- a/src/game/client/ms/health.h +++ b/src/game/client/ms/health.h @@ -13,27 +13,76 @@ * ****/ -enum { +#define DMG_IMAGE_LIFE 2 // seconds that image is up - DMG_IMAGE_POISON = 0, - DMG_IMAGE_ACID = 1, - DMG_IMAGE_COLD = 2, - DMG_IMAGE_LIFE = 2,// seconds that image is up - DMG_IMAGE_DROWN = 3, - DMG_IMAGE_BURN = 4, - DMG_IMAGE_NERVE = 5, - DMG_IMAGE_RAD = 6, - DMG_IMAGE_SHOCK = 7, - //tf defines - DMG_IMAGE_CALTROP = 8, - DMG_IMAGE_TRANQ = 9, - DMG_IMAGE_CONCUSS = 10, - DMG_IMAGE_HALLUC = 11 -}; - -constexpr int NUM_DMG_TYPES = 12; +#define DMG_IMAGE_POISON 0 +#define DMG_IMAGE_ACID 1 +#define DMG_IMAGE_COLD 2 +#define DMG_IMAGE_DROWN 3 +#define DMG_IMAGE_BURN 4 +#define DMG_IMAGE_NERVE 5 +#define DMG_IMAGE_RAD 6 +#define DMG_IMAGE_SHOCK 7 +//tf defines +#define DMG_IMAGE_CALTROP 8 +#define DMG_IMAGE_TRANQ 9 +#define DMG_IMAGE_CONCUSS 10 +#define DMG_IMAGE_HALLUC 11 +#define NUM_DMG_TYPES 12 // instant damage +#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. + +// time-based damage +//mask off TF-specific stuff too +//#define DMG_TIMEBASED (~(0xff003fff)) // mask for time-based damage + +#define DMG_DROWN (1 << 14) // Drowning +#define DMG_FIRSTTIMEBASED DMG_DROWN + +#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) + +//TF ADDITIONS +#define DMG_IGNITE (1 << 24) // Players hit by this begin to burn +#define DMG_RADIUS_MAX (1 << 25) // Radius damage with this flag doesn't decrease over distance +#define DMG_RADIUS_QUAKE (1 << 26) // Radius damage is done like Quake. 1/2 damage at 1/2 radius. +#define DMG_IGNOREARMOR (1 << 27) // Damage ignores target's armor +#define DMG_AIMED (1 << 28) // Does Hit location damage +#define DMG_WALLPIERCING (1 << 29) // Blast Damages ents through walls + +#define DMG_CALTROP (1 << 30) +#define DMG_HALLUC (1 << 31) + +// TF Healing Additions for TakeHealth +#define DMG_IGNORE_MAXHEALTH DMG_IGNITE +// TF Redefines since we never use the originals +#define DMG_NAIL DMG_SLASH +#define DMG_NOT_SELF DMG_FREEZE + +#define DMG_TRANQ DMG_MORTAR +#define DMG_CONCUSS DMG_SONIC + typedef struct { float fExpire; @@ -59,7 +108,6 @@ class CHudHealth : public CHudBase int m_HUD_dmg_bio; int m_HUD_cross; float flChangeTime; - char Name[32] = "CHudHealth"; private: HLSPRITE m_hSprite; diff --git a/src/game/client/ms/hudid.cpp b/src/game/client/ms/hudid.cpp index 73efc944b..47dc589af 100644 --- a/src/game/client/ms/hudid.cpp +++ b/src/game/client/ms/hudid.cpp @@ -50,7 +50,7 @@ void CHudID::Reset(void) m_iFlags |= HUD_ACTIVE; TimeDecAlpha = 0; Alpha = 0; - pActiveInfo = pDrawInfo = nullptr; + pActiveInfo = pDrawInfo = NULL; } void CHudID ::InitHUDData(void) { @@ -81,10 +81,10 @@ int CHudID::Draw(float flTime) GetConsoleStringSize( pDrawInfo->Name, &TextWidth, &TextHeight ); int Y_START; - if ( ScreenHeight() >= 480 ) - Y_START = ScreenHeight() - 128; + if ( ScreenHeight >= 480 ) + Y_START = ScreenHeight - 128; else - Y_START = ScreenHeight() - 64; + Y_START = ScreenHeight - 64; int x = 5; int y = Y_START - TextHeight; // draw along bottom of screen @@ -148,7 +148,7 @@ int CHudID::MsgFunc_EntInfo(const char *pszName, int iSize, void *pbuf) EntData.Type = (EntType)READ_BYTE(); //Search for a current entry with this info - for (unsigned int i = 0; i < player.m_EntInfo.size(); i++) + for (int i = 0; i < player.m_EntInfo.size(); i++) if (player.m_EntInfo[i].entindex == EntData.entindex) { player.m_EntInfo[i] = EntData; @@ -168,7 +168,7 @@ entinfo_t *CHudID::GetEntInFrontOfMe(float Range) Vector vViewAngle; gEngfuncs.GetViewAngles(vViewAngle); cl_entity_s *clplayer = gEngfuncs.GetLocalPlayer(); - AngleVectors(vViewAngle, &vForward, nullptr, nullptr); + AngleVectors(vViewAngle, &vForward, NULL, NULL); Vector vecSrc = clplayer->origin, vecEnd, viewOfs; gEngfuncs.pEventAPI->EV_LocalPlayerViewheight(viewOfs); @@ -179,7 +179,7 @@ entinfo_t *CHudID::GetEntInFrontOfMe(float Range) physent_t *pPhyplayer = gEngfuncs.pEventAPI->EV_GetPhysent(clplayer->index); if (!pPhyplayer) - return nullptr; + return NULL; // Now add in all of the players. gEngfuncs.pEventAPI->EV_SetSolidPlayers(clplayer->index - 1); @@ -190,10 +190,10 @@ entinfo_t *CHudID::GetEntInFrontOfMe(float Range) if (tr.fraction < 1.0 && tr.ent) { physent_t *pe = gEngfuncs.pEventAPI->EV_GetPhysent(tr.ent); - for (unsigned int i = 0; i < player.m_EntInfo.size(); i++) + for (int i = 0; i < player.m_EntInfo.size(); i++) if (player.m_EntInfo[i].entindex == pe->info) return &player.m_EntInfo[i]; } - return nullptr; + return NULL; } diff --git a/src/game/client/ms/hudid.h b/src/game/client/ms/hudid.h index 3c93fc1c6..cdc812b23 100644 --- a/src/game/client/ms/hudid.h +++ b/src/game/client/ms/hudid.h @@ -16,10 +16,10 @@ class CHudID : public CHudBase void SearchThink(void); entinfo_t *GetEntInFrontOfMe(float Range); + entinfo_t *pActiveInfo, *pDrawInfo; float Alpha; float TimeDecAlpha; - char Name[32] = "CHudID"; }; #endif //__HUDID diff --git a/src/game/client/ms/hudmagic.cpp b/src/game/client/ms/hudmagic.cpp index 6220f49ab..c39a77f9f 100644 --- a/src/game/client/ms/hudmagic.cpp +++ b/src/game/client/ms/hudmagic.cpp @@ -25,13 +25,15 @@ void CHudMagic_SelectMenuItem(int menu_item, TCallbackMenu *pcbMenu); MS_DECLARE_MESSAGE(m_Magic, Spells); - +//MS_DECLARE_COMMAND( m_Magic, ListSpells ); int CHudMagic::Init(void) { gHUD.AddHudElem(this); HOOK_MESSAGE(Spells); + //HOOK_COMMAND("listspells", ListSpells); + Reset(); return 1; @@ -62,12 +64,48 @@ void CHudMagic::Think() int CHudMagic::MsgFunc_Spells(const char *pszName, int iSize, void *pbuf) { BEGIN_READ(pbuf, iSize); - bool Verbose = (READ_BYTE() == 1); + + /*short Spells = READ_SHORT( ); //The number of spells have I memorized + short VerboseIdx = READ_SHORT( ); //If Verbose: Which spell was learned (incremented by 1 | 0 = Non-verbose) + + bool Verbose = VerboseIdx ? true : false; + if( Verbose ) VerboseIdx--; //The index is offset by 1, so that 0 == Non-verbose + + player.m_SpellList.clear(); + for (int s = 0; s < Spells; s++) + player.LearnSpell( READ_STRING(), (Verbose && (VerboseIdx == s)) ? true : false ); //Spell scriptname*/ + + bool Verbose = READ_BYTE() == 1; player.LearnSpell(READ_STRING(), Verbose); return 1; } +/*void CHudMagic::UserCmd_ListSpells(void) +{ + if( gHUD.m_Menu->HideMyMenu( MENU_LISTSPELLS ) ) return; + + //Disallow choosing spells by unsetting HUD_ACTIVE + if( !FBitSet(m_iFlags,HUD_ACTIVE) ) + return; + int iBitsValid = 0; + char MenuText[1024]; + //Activate + if( !SpellsMemorized() ) return; + strncpy(MenuText, "Cast spell:\n\n", sizeof(MenuText) ); + spellgroup_v &SpellList = player.m_SpellList; + for (int n = 0; n < SpellList.size(); n++) + { + CGenericItem *pItem = NewGenericItem( SpellList[n] ); + if( pItem ) + strcat( MenuText, UTIL_VarArgs("%i. %s\n", n+1, pItem->DisplayName() ) ); + else + strcat( MenuText, UTIL_VarArgs("%i. %s\n", n+1, SpellList[n].c_str() ) ); + iBitsValid += pow(2,n); + SpellMenuIndex[n] = n; + } + gHUD.m_Menu->ShowMenu( iBitsValid, MenuText, CHudMagic_SelectMenuItem, MENU_LISTSPELLS ); +}*/ void CHudMagic_SelectMenuItem(int idx, TCallbackMenu *pcbMenu) { if (!gHUD.m_Magic) diff --git a/src/game/client/ms/hudmagic.h b/src/game/client/ms/hudmagic.h index c70975b8a..2c02d36d9 100644 --- a/src/game/client/ms/hudmagic.h +++ b/src/game/client/ms/hudmagic.h @@ -18,6 +18,5 @@ class CHudMagic : public CHudBase void InitHUDData(void); int SpellMenuIndex[256]; - char Name[32] = "CHudMagic"; }; #endif //HUD_MAGIC_H diff --git a/src/game/client/ms/hudmisc.cpp b/src/game/client/ms/hudmisc.cpp index 11a03abb5..d03c74089 100644 --- a/src/game/client/ms/hudmisc.cpp +++ b/src/game/client/ms/hudmisc.cpp @@ -113,7 +113,7 @@ int CHudMisc::Draw(float flTime) } SPR_Set(gHUD.GetSprite(SpriteIndex), 255, 255, 255 ); - SPR_DrawAdditive( 0, ScreenWidth() - 70, ScreenHeight() - 70, &gHUD.GetSpriteRect(SpriteIndex));*/ + SPR_DrawAdditive( 0, ScreenWidth - 70, ScreenHeight - 70, &gHUD.GetSpriteRect(SpriteIndex));*/ return 1; } @@ -149,9 +149,6 @@ HLSPRITE CHudMisc::GetCrosshairSprite(int type) void CHudMisc::Think(void) { //SaveCharSend(); //Done every frame so I can retry the connect - - //Handle character upload to server - MSChar_Interface::Think_SendChar(&player); } void CHudMisc ::UserCmd_ChangeSayType(void) @@ -199,17 +196,17 @@ void CHudMisc ::UserCmd_RemovePack(void) int test = *(int *)&m_RemoveList; int test2 = m_RemoveList.size(); - strncpy(MenuText, "Remove item:\n\n", sizeof(MenuText) ); + strncpy(MenuText, "Remove item:\n\n", sizeof(MenuText) ); m_RemoveList.clear(); - for (unsigned int i = 0; i < player.Gear.size(); i++) + for (int i = 0; i < player.Gear.size(); i++) { CGenericItem *pGearItem = player.Gear[i]; if (!FBitSet(pGearItem->MSProperties(), ITEM_WEARABLE) || pGearItem->m_Location == ITEMPOS_HANDS) continue; msstring ItemName; - ItemName += SPEECH::ItemName(pGearItem); + ItemName += SPEECH_GetItemName(pGearItem); msstring SendString; int Size = m_RemoveList.size(); @@ -315,12 +312,12 @@ void CHudMisc ::UserCmd_Offer(void) } int r = 0; - for (unsigned int i = 0; i < MAX_PLAYER_HANDS; i++) + for (int i = 0; i < MAX_PLAYER_HANDS; i++) { if (!player.Hand(i)) continue; - const char *arg = UTIL_VarArgs("%i. %s hand: %s\n", r + 2, SPEECH::HandName(i, true), SPEECH::ItemName(player.Hand(i), true)); + const char *arg = UTIL_VarArgs("%i. %s hand: %s\n", r + 2, SPEECH_IntToHand(i, true), SPEECH::ItemName(player.Hand(i), true)); strncat(MenuText, arg, strlen(arg)); m_OfferInfo.OfferItem[r] = i; iBitsValid |= (1 << (++r)); //Starts at 1 diff --git a/src/game/client/ms/hudmisc.h b/src/game/client/ms/hudmisc.h index 74c47099c..e89720a33 100644 --- a/src/game/client/ms/hudmisc.h +++ b/src/game/client/ms/hudmisc.h @@ -3,8 +3,8 @@ #include "hudbase.h" //typedef struct cl_entity_s cl_entity_t; -inline constexpr int MAX_ARROWS = 5; -inline constexpr int MAX_GOLD_OFFER = 1000000; +#define MAX_ARROWS 5 + class CHudMisc : public CHudBase { public: @@ -19,7 +19,7 @@ class CHudMisc : public CHudBase void UserCmd_Accept(void); //void UserCmd_ListSkills( void ); void SelectMenuItem(int menu_item, TCallbackMenu *pcbMenu); - char Name[32] = "CHudMisc"; + entinfo_t m_OfferTarget; private: @@ -29,6 +29,8 @@ class CHudMisc : public CHudBase Rect m_rcCrosshair; HLSPRITE GetCrosshairSprite(int type); +#define MAX_GOLD_OFFER 1000000 + struct offerinfo_t { bool GoldScreen; //Whether I'm currently determining an amount of gold to offer diff --git a/src/game/client/ms/hudmusic.h b/src/game/client/ms/hudmusic.h index 0039c6566..edb1c3dc7 100644 --- a/src/game/client/ms/hudmusic.h +++ b/src/game/client/ms/hudmusic.h @@ -13,7 +13,6 @@ class CHudMusic : public CHudBase void Shutdown(void); void Reload(void); int MsgFunc_Music(const char* pszName, int iSize, void* pbuf); - char Name[32] = "CHudMusic"; private: CMusicSystem m_MP3; diff --git a/src/game/client/ms/hudscript.cpp b/src/game/client/ms/hudscript.cpp index bc58328df..c0c607d5f 100644 --- a/src/game/client/ms/hudscript.cpp +++ b/src/game/client/ms/hudscript.cpp @@ -31,81 +31,6 @@ extern physent_t *MSUTIL_EntityByIndex( int playerindex ); - -static void SCRIPT_CONTROLVEC_POS(CScript* Script, const char* name, Vector& vec) { - - const char* ofsX = "_ofs.x"; - const char* ofsY = "_ofs.y"; - const char* ofsZ = "_ofs.z"; - const char* setX = "_set.x"; - const char* setY = "_set.y"; - const char* setZ = "_set.z"; - - std::string ScriptVarNameX = name; ScriptVarNameX += ofsX; - std::string ScriptVarNameY = name; ScriptVarNameY += ofsY; - std::string ScriptVarNameZ = name; ScriptVarNameZ += ofsZ; - - std::string ScriptVarSetNameX = {name}; ScriptVarSetNameX += setX; - std::string ScriptVarSetNameY = {name}; ScriptVarSetNameY += setY; - std::string ScriptVarSetNameZ = {name}; ScriptVarSetNameZ += setZ; - - if (Script->VarExists(ScriptVarNameX.c_str())) vec.x += atof(Script->GetVar(ScriptVarNameX.c_str())); - if (Script->VarExists(ScriptVarNameY.c_str())) vec.y += atof(Script->GetVar(ScriptVarNameY.c_str())); - if (Script->VarExists(ScriptVarNameZ.c_str())) vec.z += atof(Script->GetVar(ScriptVarNameZ.c_str())); - if (Script->VarExists(ScriptVarSetNameX.c_str())) vec.x = atof(Script->GetVar(ScriptVarNameX.c_str())); - if (Script->VarExists(ScriptVarSetNameY.c_str())) vec.y = atof(Script->GetVar(ScriptVarNameY.c_str())); - if (Script->VarExists(ScriptVarSetNameZ.c_str())) vec.z = atof(Script->GetVar(ScriptVarNameZ.c_str())); - - -}; - -static void SCRIPT_CONTROLVEC_ANG(CScript* Script, const char* name, Vector& vec) { - - const char* ofsPitch = "_ofs.pitch"; - const char* ofsYaw = "_ofs.yaw"; - const char* ofsRoll = "_ofs.roll"; - const char* setPitch = "_set.pitch"; - const char* setYaw = "_set.yaw"; - const char* setRoll = "_set.roll"; - - std::string ScriptVarPitch = { name }; ScriptVarPitch += ofsPitch; - std::string ScriptVarYaw = {name}; ScriptVarYaw += ofsYaw; - std::string ScriptVarRoll = {name}; ScriptVarRoll += ofsRoll; - - std::string ScriptVarSetPitch = {name}; ScriptVarSetPitch += setPitch; - std::string ScriptVarSetYaw = {name}; ScriptVarSetYaw += setYaw; - std::string ScriptVarSetRoll = {name}; ScriptVarSetRoll += setRoll; - - if (Script->VarExists(ScriptVarPitch.c_str())) vec.x += atof(Script->GetVar(ScriptVarPitch.c_str())); - if (Script->VarExists(ScriptVarYaw.c_str())) vec.y += atof(Script->GetVar(ScriptVarYaw.c_str())); - if (Script->VarExists(ScriptVarRoll.c_str())) vec.z += atof(Script->GetVar(ScriptVarRoll.c_str())); - if (Script->VarExists(ScriptVarSetPitch.c_str())) vec.x = atof(Script->GetVar(ScriptVarSetPitch.c_str())); - if (Script->VarExists(ScriptVarSetYaw.c_str())) vec.y = atof(Script->GetVar(ScriptVarSetYaw.c_str())); - if (Script->VarExists(ScriptVarSetRoll.c_str())) vec.z = atof(Script->GetVar(ScriptVarSetRoll.c_str())); -}; - -static void SCRIPT_CONTROLVEC_POS_CUSTOM(CScript* Script, const char* name, Vector& vec, const char* xname, const char* yname, const char* zname) { - - const char* ofs = "_ofs."; - const char* set = "_set."; - - std::string ScriptVarCustomXOffset{ name }; ScriptVarCustomXOffset += ofs; ScriptVarCustomXOffset += xname; - std::string ScriptVarCustomYOffset{ name }; ScriptVarCustomYOffset += ofs; ScriptVarCustomYOffset += yname; - std::string ScriptVarCustomZOffset{ name }; ScriptVarCustomZOffset += ofs; ScriptVarCustomZOffset += zname; - - std::string ScriptVarCustomXSet{ name }; ScriptVarCustomXSet += set; ScriptVarCustomXSet += xname; - std::string ScriptVarCustomYSet{ name }; ScriptVarCustomYSet += set; ScriptVarCustomYSet += yname; - std::string ScriptVarCustomZSet{ name }; ScriptVarCustomZSet += set; ScriptVarCustomZSet += zname; - - if (Script->VarExists(ScriptVarCustomXOffset.c_str())) vec.x += atof(Script->GetVar(ScriptVarCustomXOffset.c_str())); - if (Script->VarExists(ScriptVarCustomYOffset.c_str())) vec.y += atof(Script->GetVar(ScriptVarCustomYOffset.c_str())); - if (Script->VarExists(ScriptVarCustomZOffset.c_str())) vec.z += atof(Script->GetVar(ScriptVarCustomZOffset.c_str())); - if (Script->VarExists(ScriptVarCustomXSet.c_str())) vec.x = atof(Script->GetVar(ScriptVarCustomXSet.c_str())); - if (Script->VarExists(ScriptVarCustomYSet.c_str())) vec.y = atof(Script->GetVar(ScriptVarCustomYSet.c_str())); - if (Script->VarExists(ScriptVarCustomZSet.c_str())) vec.z = atof(Script->GetVar(ScriptVarCustomZSet.c_str())); - -}; -/* #define SCRIPT_CONTROLVEC_POS( name, vec ) \ if( Script->VarExists( name "_ofs.x" ) ) vec.x += atof(Script->GetVar( name "_ofs.x" )); \ if( Script->VarExists( name "_ofs.y" ) ) vec.y += atof(Script->GetVar( name "_ofs.y" )); \ @@ -129,10 +54,10 @@ static void SCRIPT_CONTROLVEC_POS_CUSTOM(CScript* Script, const char* name, Vect if( Script->VarExists( name "_set." xname ) ) vec.x = atof(Script->GetVar( name "_set." xname )); \ if( Script->VarExists( name "_set." yname ) ) vec.y = atof(Script->GetVar( name "_set." yname )); \ if( Script->VarExists( name "_set." zname ) ) vec.z = atof(Script->GetVar( name "_set." zname )); -\ -*/ + //---------------- +#include "hudscript.h" int CHudScript::Init( void ) { @@ -155,7 +80,8 @@ void CHudScript::Reset( void ) } void CHudScript::InitHUDData( void ) { - for (unsigned int i = 0; i < m_Scripts.size(); i++) + int scriptnum = m_Scripts.size(); + for (int i = 0; i < scriptnum; i++) Script_Remove( 0 ); } @@ -175,31 +101,31 @@ int CHudScript::MsgFunc_ClientScript( const char *pszName, int iSize, void *pbuf if( !Action ) //Add Script { msstring ScriptName = READ_STRING( ); - unsigned int iParameters = READ_BYTE( ); - for (unsigned int i = 0; i < iParameters; i++) Parameters.add(READ_STRING()); + int iParameters = READ_BYTE( ); + for (int i = 0; i < iParameters; i++) Parameters.add(READ_STRING()); CScript *Script = CreateScript( ScriptName, Parameters, true, ID ); } else if( Action == 1 ) //Send Msg to Script { - unsigned int iParameters = READ_BYTE( ); + int iParameters = READ_BYTE( ); msstring EventName = READ_STRING( ); //First parameter is the eventname - for (unsigned int i = 0; i < (iParameters - 1); i++) Parameters.add(READ_STRING()); + for (int i = 0; i < (iParameters - 1); i++) Parameters.add(READ_STRING()); - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) { CScript *Script = m_Scripts[i]; if( Script->m.UniqueID != ID ) continue; - for (unsigned int p = 0; p < Parameters.size(); p++) - Script->SetVar( msstring("PARAM") + ((int)p+1), Parameters[p].c_str() ); - Script->RunScriptEventByName( EventName, Parameters.size() ? &Parameters : nullptr ); + for (int p = 0; p < Parameters.size(); p++) + Script->SetVar( msstring("PARAM") + (p+1), Parameters[p].c_str() ); + Script->RunScriptEventByName( EventName, Parameters.size() ? &Parameters : NULL ); break; } } else //Remove script { - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) { if( m_Scripts[i]->m.UniqueID != ID ) continue; @@ -217,8 +143,8 @@ CScript *CHudScript::CreateScript(const char* ScriptName, msstringlist &Paramete //If I don't allow dupes, try to find a prev copy of this script if( !AllowDupe ) { - unsigned int events = m_Scripts.size(); - for (unsigned int i = 0; i < events; i++) + int events = m_Scripts.size(); + for (int i = 0; i < events; i++) if( strstr( m_Scripts[i]->m.ScriptFile.c_str(), ScriptName ) ) { UniqueID = m_Scripts[i]->m.UniqueID; @@ -228,7 +154,7 @@ CScript *CHudScript::CreateScript(const char* ScriptName, msstringlist &Paramete //Create a new script if not latching onto a prev copy CScript *Script = Script_Add( ScriptName, &player ); - if( !Script ) return nullptr; + if( !Script ) return NULL; Script->m.pScriptedInterface = &player; @@ -249,13 +175,13 @@ void CHudScript::HandleAnimEvent(const char* Options, const cl_entity_s *clEntit const char* ScriptName = ParsedOptions[0]; const char* EventName = ParsedOptions[1]; - CScript *Script = nullptr; + CScript *Script = NULL; //Latch onto an existing script if( Type == HAE_EITHER || Type == HAE_ATTACH ) { - unsigned int events = m_Scripts.size( ); - for (unsigned int i = 0; i < events; i++) + int events = m_Scripts.size( ); + for (int i = 0; i < events; i++) if( strstr( m_Scripts[i]->m.ScriptFile.c_str(), ScriptName ) ) { Script = m_Scripts[i]; break; } } @@ -272,7 +198,7 @@ void CHudScript::HandleAnimEvent(const char* Options, const cl_entity_s *clEntit static msstringlist Params; Params.clearitems( ); - for (unsigned int i = 0; i < ParsedOptions.size()-2; i++) + for (int i = 0; i < ParsedOptions.size()-2; i++) Params.add( ParsedOptions[i+2] ); Script->RunScriptEventByName( EventName, &Params ); @@ -280,23 +206,23 @@ void CHudScript::HandleAnimEvent(const char* Options, const cl_entity_s *clEntit void CHudScript::Effects_GetView( ref_params_s *pparams, cl_entity_t *ViewModel ) { - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) { CScript *Script = m_Scripts[i]; Vector &ViewOfs = *(Vector *)&pparams->vieworg; Vector &ViewAng = *(Vector *)&pparams->viewangles; Vector &ViewMdlOfs = *(Vector *)&ViewModel->origin; Vector &ViewMdlAng = *(Vector *)&ViewModel->angles; - SCRIPT_CONTROLVEC_POS(Script, "game.cleffect.view", ViewOfs ); - SCRIPT_CONTROLVEC_ANG(Script, "game.cleffect.view", ViewAng ); - SCRIPT_CONTROLVEC_POS(Script, "game.cleffect.viewmodel", ViewMdlOfs ); - SCRIPT_CONTROLVEC_ANG(Script, "game.cleffect.viewmodel", ViewMdlAng ); + SCRIPT_CONTROLVEC_POS( "game.cleffect.view", ViewOfs ); + SCRIPT_CONTROLVEC_ANG( "game.cleffect.view", ViewAng ); + SCRIPT_CONTROLVEC_POS( "game.cleffect.viewmodel", ViewMdlOfs ); + SCRIPT_CONTROLVEC_ANG( "game.cleffect.viewmodel", ViewMdlAng ); } } Vector CHudScript::Effects_GetMoveScale( ) { Vector NewScale( 1.0f, 1.0f, 1.0f ); - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) { CScript *Script = m_Scripts[i]; if( Script->VarExists( "game.cleffect.move_scale.forward" ) ) NewScale.x *= atof(Script->GetVar( "game.cleffect.move_scale.forward" )); @@ -309,7 +235,7 @@ Vector CHudScript::Effects_GetMoveScale( ) Vector CHudScript::Effects_GetMove( Vector &OriginalMove ) { Vector NewMove = OriginalMove; - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) { CScript *Script = m_Scripts[i]; NewMove.x += atof(Script->GetVar( "game.cleffect.move_ofs.forward" )); @@ -324,7 +250,7 @@ void CHudScript::Effects_GetFade( screenfade_t &ScreenFade ) { float OldScreenAlpha = ScreenFade.fadealpha; ScreenFade.fadeFlags = 0; - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) { CScript *Script = m_Scripts[i]; if( !atoi(Script->GetVar( "game.cleffect.screenfade.newfade" )) ) @@ -355,27 +281,27 @@ void CHudScript::Effects_GetFade( screenfade_t &ScreenFade ) } void CHudScript::Effects_PreRender( ) { - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) if( m_Scripts[i]->m.m_HandleRender ) m_Scripts[i]->RunScriptEventByName( "game_prerender" ); } -void CHudScript::Effects_Render( cl_entity_t &Ent, bool InMirror ) +void CHudScript::Effects_Render( cl_entity_t &Ent ) { - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) if( m_Scripts[i]->m.m_HandleRender ) { static msstringlist Params; Params.clearitems( ); Params.add( UTIL_VarArgs("%i",Ent.index) ); //Index of entity being rendered - Params.add( InMirror ? "1" : "0" ); //Rendering in a mirror + Params.add( "0" ); //Was "rendering in a mirror" - kept so script param indices don't shift m_Scripts[i]->RunScriptEventByName( "game_render", &Params ); } } void CHudScript::Effects_DrawTransPararentTriangles( ) { - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) if( m_Scripts[i]->m.m_HandleRender ) m_Scripts[i]->RunScriptEventByName( "game_render_transparent" ); } diff --git a/src/game/client/ms/hudscript.h b/src/game/client/ms/hudscript.h index f0544dc9e..0ad17cc38 100644 --- a/src/game/client/ms/hudscript.h +++ b/src/game/client/ms/hudscript.h @@ -32,11 +32,9 @@ class CHudScript : public CHudBase, public IScripted void Effects_GetFade(screenfade_t &ScreenFade); void Effects_UpdateTempEnt(const char* EventName, msstringlist *Parameters = NULL); void Effects_PreRender(); - void Effects_Render(cl_entity_t &Ent, bool InMirror); + void Effects_Render(cl_entity_t &Ent); void Effects_DrawTransPararentTriangles(); - - char Name[32] = "CHudScript"; }; - +#define HUDScript gHUD.m_HUDScript #endif //HUDSCRIPT_H diff --git a/src/game/client/ms/menu.cpp b/src/game/client/ms/menu.cpp index 77f1a9ae4..e0bfccd06 100644 --- a/src/game/client/ms/menu.cpp +++ b/src/game/client/ms/menu.cpp @@ -35,6 +35,7 @@ #include "action.h" #include "menu.h" +#define MAX_MENU_STRING 512 //char m.cMenuText[MAX_MENU_STRING]; char g_szPrelocalisedMenuString[MAX_MENU_STRING]; @@ -65,7 +66,7 @@ void CHudMenu ::InitHUDData(void) void CHudMenu ::Reset(void) { g_szPrelocalisedMenuString[0] = 0; - m_fWaitingForMore = false; + m_fWaitingForMore = FALSE; } int CHudMenu ::VidInit(void) @@ -94,14 +95,14 @@ int CHudMenu ::Draw(float flTime) // count the number of newlines int nlc = 0; - for (unsigned int i = 0; i < MAX_MENU_STRING && m.cMenuText[i] != '\0'; i++) + for (int i = 0; i < MAX_MENU_STRING && m.cMenuText[i] != '\0'; i++) { if (m.cMenuText[i] == '\n') nlc++; } // center it - int y = (ScreenHeight() / 2) - ((nlc / 2) * 12) - 40; // make sure it is above the say text + int y = (ScreenHeight / 2) - ((nlc / 2) * 12) - 40; // make sure it is above the say text int x = 20; int i = 0; @@ -144,7 +145,7 @@ void Menu_ServerMenuCallback(int idx, struct TCallbackMenu *pcbMenu) // takes four values: // short: a bitfield of keys that are valid input // char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen. -// byte : a boolean, true if there is more string yet to be received before displaying the menu, false if it's the last string +// byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, FALSE if it's the last string // string: menu string to display // if this message is never received, then scores will simply be the combined totals of the players. int CHudMenu ::MsgFunc_ShowMenu(const char *pszName, int iSize, void *pbuf) @@ -203,7 +204,7 @@ int CHudMenu ::MsgFunc_ShowMenu(const char *pszName, int iSize, void *pbuf) } int CHudMenu ::ShowMenu(int bitsValidSlots, const char *pcMenuText, MenuCallback CallBack, MenuType mtMenuType, float ShutOffTime) { - // if( !pcMenuText ) return false; + // if( !pcMenuText ) return FALSE; m_fOfferedNextMenu = true; m_bitsValidSlots = bitsValidSlots; strncpy(m.cMenuText, pcMenuText, sizeof(m.cMenuText) ); @@ -212,7 +213,7 @@ int CHudMenu ::ShowMenu(int bitsValidSlots, const char *pcMenuText, MenuCallback m_flShutoffTime = ShutOffTime; m_fMenuDisplayed = 1; m_iFlags |= HUD_ACTIVE; - return true; + return TRUE; } //Hides a certain menu only if that menu is open diff --git a/src/game/client/ms/menu.h b/src/game/client/ms/menu.h index bc496b068..014a9ddbc 100644 --- a/src/game/client/ms/menu.h +++ b/src/game/client/ms/menu.h @@ -1,7 +1,5 @@ //Master Sword -#include "sharedmenu.h" - -constexpr int MAX_MENU_STRING = 512; +#define MAX_MENU_STRING 512 enum MenuType { //menutypes @@ -13,7 +11,7 @@ enum MenuType MENU_DYNAMICNPC, }; //------------ - +#include "sharedmenu.h" class CHudMenu : public CHudBase { public: @@ -31,12 +29,11 @@ class CHudMenu : public CHudBase float m_flShutoffTime; int m_fWaitingForMore; bool m_fOfferedNextMenu; - char Name[32] = "CHudMenu"; //Master Sword TCallbackMenu m; - int ShowMenu(int bitsValidSlots, const char *pszMenuString, MenuCallback CallBack, MenuType mtMenuType = MenuType::MENU_NORMAL, float ShutOffTime = 0); + int ShowMenu(int bitsValidSlots, const char *pszMenuString, MenuCallback CallBack, MenuType mtMenuType = MENU_NORMAL, float ShutOffTime = 0); bool HideMyMenu(int mtMenuType); //------------ }; diff --git a/src/game/client/overview.cpp b/src/game/client/overview.cpp index 09019876f..db3662238 100644 --- a/src/game/client/overview.cpp +++ b/src/game/client/overview.cpp @@ -110,7 +110,7 @@ int CHudOverview::Draw(float flTime) gEngfuncs.pTriAPI->Color4f(r, g, bc, 1.0f); // calculate rotational matrix - Vector a, b, angles; + Vector a, b, angles; float rmatrix[3][4]; // transformation matrix VectorCopy(pl->angles, angles); angles[0] = 0.0f; diff --git a/src/game/client/parsemsg.cpp b/src/game/client/parsemsg.cpp index 659f85239..ab8ce165a 100644 --- a/src/game/client/parsemsg.cpp +++ b/src/game/client/parsemsg.cpp @@ -16,7 +16,7 @@ // parsemsg.cpp // typedef unsigned char byte; - +#define true 1 static byte *gpBuf; static int giSize; @@ -68,12 +68,6 @@ int READ_BYTE( void ) return c; } - -bool READ_BOOL( void ) { - return (READ_BYTE() == 1); -} - - int READ_SHORT( void ) { int c; diff --git a/src/game/client/parsemsg.h b/src/game/client/parsemsg.h index e3cbe7348..72b3b3bf2 100644 --- a/src/game/client/parsemsg.h +++ b/src/game/client/parsemsg.h @@ -16,7 +16,8 @@ // parsemsg.h // -bool READ_BOOL(void);// MIB FEB2019_23 [LOCAL_PANEL_IMAGE] +#define READ_BOOL() ( READ_BYTE() == 1 ) // MIB FEB2019_23 [LOCAL_PANEL_IMAGE] + void BEGIN_READ(void *buf, int size); int READ_CHAR(void); int READ_BYTE(void); diff --git a/src/game/client/particleman/CBaseParticle.cpp b/src/game/client/particleman/CBaseParticle.cpp new file mode 100644 index 000000000..4262d84fb --- /dev/null +++ b/src/game/client/particleman/CBaseParticle.cpp @@ -0,0 +1,510 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#include "hud.h" +#include "cl_util.h" + +#include "event_api.h" +#include "triangleapi.h" + +#include "particleman.h" +#include "particleman_internal.h" +#include "CBaseParticle.h" + +#include "pm_defs.h" +#include "pmtrace.h" +#include + +extern const Vector g_vecZero; + +void CBaseParticle::InitializeSprite(Vector org, Vector normal, model_s* sprite, float size, float brightness) +{ + m_flSize = m_flOriginalSize = 10; + + m_flScaleSpeed = 0; + m_flContractSpeed = 0; + m_flStretchX = m_flStretchY = 1; + + m_pTexture = nullptr; + m_flOriginalBrightness = 255; + m_flBrightness = 255; + + strncpy(m_szClassname, "particle", sizeof(m_szClassname) - 1); + m_szClassname[sizeof(m_szClassname) - 1] = '\0'; + + m_flDieTime = 0; + m_flDampingTime = 0; + + m_flNextPVSCheck = gEngfuncs.GetClientTime(); + + m_flGravity = 0; + m_flNextCollisionTime = 0; + + m_bInPVS = true; + + m_flFadeSpeed = -1; + m_iFramerate = 0; + m_iNumFrames = 0; + m_iFrame = 0; + m_iCollisionFlags = 0; + + m_iRendermode = kRenderNormal; + m_iRenderFlags = 0; + + m_vVelocity.x = 0; + m_vVelocity.y = 0; + m_vVelocity.z = 0; + + m_flBounceFactor = 1; + + m_vOriginalAngles = g_vecZero; + m_vAngles = g_vecZero; + m_vAVelocity = g_vecZero; + + m_bInWater = false; + m_bAffectedByForce = false; + + m_vColor.x = 255; + m_vColor.y = 255; + m_vColor.z = 255; + + m_flTimeCreated = gEngfuncs.GetClientTime(); + + m_vPrevOrigin = m_vOrigin = org; + m_vOriginalAngles = m_vAngles = normal; + + m_pTexture = sprite; + m_flOriginalSize = m_flSize = size; + m_flOriginalBrightness = m_flBrightness = brightness; + + Vector forward, right, up; + gEngfuncs.pfnAngleVectors(normal, forward, right, up); + + const Vector scaledRight = right * size; + const Vector scaledUp = up * size; + + m_vLowLeft = org - scaledRight * 0.5 - scaledUp * 0.5; + + //TODO: not sure if these are correct. If low left is half of the scaled directions then the full direction * 2 results in double size particles. + m_vLowRight = m_vLowLeft + scaledRight + scaledRight; + m_vTopLeft = m_vLowLeft + scaledUp + scaledUp; +} + +bool CBaseParticle::CheckVisibility() +{ + const float radius = m_flSize / 5.0; + + if (gEngfuncs.GetClientTime() >= m_flNextPVSCheck) + { + const Vector radiusVector{radius, radius, radius}; + Vector mins = m_vOrigin - radiusVector; + Vector maxs = m_vOrigin + radiusVector; + + m_bInPVS = gEngfuncs.pTriAPI->BoxInPVS(mins, maxs) != 0; + + m_flNextPVSCheck = gEngfuncs.GetClientTime() + 0.1; + } + + if ((m_iRenderFlags & CULL_FRUSTUM_SPHERE) != 0) + { + if (!g_cFrustum.SphereInsideFrustum(m_vOrigin.x, m_vOrigin.y, m_vOrigin.z, radius)) + { + return false; + } + } + else if ((m_iRenderFlags & CULL_FRUSTUM_PLANE) != 0) + { + if (!g_cFrustum.PlaneInsideFrustum(m_vOrigin.x, m_vOrigin.y, m_vOrigin.z, radius)) + { + return false; + } + } + else if ((m_iRenderFlags & CULL_FRUSTUM_POINT) != 0) + { + if (!g_cFrustum.PointInsideFrustum(m_vOrigin.x, m_vOrigin.y, m_vOrigin.z)) + { + return false; + } + } + + if (!m_bInPVS) + { + return (m_iRenderFlags & CULL_PVS) == 0; + } + + return true; +} + +void CBaseParticle::Draw() +{ + if (m_flDieTime == gEngfuncs.GetClientTime()) + { + return; + } + + Vector vColor; + float intensity = 0.0; + + if ((m_iRenderFlags & LIGHT_NONE) == 0) + { + gEngfuncs.pTriAPI->LightAtPoint(m_vOrigin, vColor); + + intensity = (vColor.x + vColor.y + vColor.z) / 3.0; + //gEngfuncs.Con_Printf("Intensity: %g. Color: %g, %g, %g\n", intensity, vColor.x, vColor.y, vColor.z); + } + + if ((m_iRenderFlags & (RENDER_FACEPLAYER | RENDER_FACEPLAYER_ROTATEZ)) != 0) + { + m_vAngles.x = g_vViewAngles.x; + m_vAngles.y = g_vViewAngles.y; + + if ((m_iRenderFlags & RENDER_FACEPLAYER_ROTATEZ) == 0) + { + m_vAngles.z = g_vViewAngles.z; + } + } + + Vector resultColor; + + if ((m_iRenderFlags & LIGHT_NONE) != 0) + { + resultColor = m_vColor; + } + else if ((m_iRenderFlags & LIGHT_COLOR) != 0) + { + resultColor.x = (vColor.x * m_vColor.x / 255.0f); + resultColor.y = (vColor.y * m_vColor.y / 255.0f); + resultColor.z = (vColor.z * m_vColor.z / 255.0f); + } + else if ((m_iRenderFlags & LIGHT_INTENSITY) != 0) + { + resultColor.x = (intensity * m_vColor.x / 255.0f); + resultColor.y = (intensity * m_vColor.y / 255.0f); + resultColor.z = (intensity * m_vColor.z / 255.0f); + } + + resultColor.x = std::clamp(resultColor.x, 0.f, 255.f); + resultColor.y = std::clamp(resultColor.y, 0.f, 255.f); + resultColor.z = std::clamp(resultColor.z, 0.f, 255.f); + + Vector forward, right, up; + gEngfuncs.pfnAngleVectors(m_vAngles, forward, right, up); + + const float radius = m_flSize; + const Vector width = right * radius * m_flStretchX; + const Vector height = up * radius * m_flStretchY; + + const Vector lowLeft = m_vOrigin - (width * 0.5) - (height * 0.5); + + const Vector lowRight = lowLeft + width; + const Vector topLeft = lowLeft + height; + const Vector topRight = lowRight + height; + + gEngfuncs.pTriAPI->SpriteTexture(m_pTexture, m_iFrame); + gEngfuncs.pTriAPI->RenderMode(m_iRendermode); + gEngfuncs.pTriAPI->CullFace(TRI_NONE); + + gEngfuncs.pTriAPI->Begin(TRI_QUADS); + gEngfuncs.pTriAPI->Color4f(resultColor.x / 255, resultColor.y / 255, resultColor.z / 255, m_flBrightness / 255); + + gEngfuncs.pTriAPI->TexCoord2f(0, 0); + gEngfuncs.pTriAPI->Vertex3fv(topLeft); + + gEngfuncs.pTriAPI->TexCoord2f(0, 1); + gEngfuncs.pTriAPI->Vertex3fv(lowLeft); + + gEngfuncs.pTriAPI->TexCoord2f(1, 1); + gEngfuncs.pTriAPI->Vertex3fv(lowRight); + + gEngfuncs.pTriAPI->TexCoord2f(1, 0); + gEngfuncs.pTriAPI->Vertex3fv(topRight); + + gEngfuncs.pTriAPI->End(); + + gEngfuncs.pTriAPI->RenderMode(kRenderNormal); + gEngfuncs.pTriAPI->CullFace(TRI_FRONT); +} + +void CBaseParticle::Animate(float time) +{ + if (0 != m_iFramerate && 0 != m_iNumFrames) + { + m_iFrame = static_cast(m_iFramerate * (time - m_flTimeCreated)) % m_iNumFrames; + } +} + +void CBaseParticle::AnimateAndDie(float time) +{ + if (0 != m_iFramerate && 0 != m_iNumFrames) + { + const float frame = m_iFramerate * (time - m_flTimeCreated); + + if (frame > m_iNumFrames) + { + m_flDieTime = time; + } + else + { + m_iFrame = frame; + } + + if (m_iFrame > m_iNumFrames) + { + m_iFrame = m_iNumFrames - 1; + } + } +} + +void CBaseParticle::Expand(float time) +{ + if (m_flScaleSpeed != 0) + { + m_flSize = (m_flScaleSpeed * 30.0 * (time - m_flTimeCreated)) + m_flOriginalSize; + + if (m_flSize < 0.0001) + { + m_flDieTime = time; + } + } +} + +void CBaseParticle::Contract(float time) +{ + if (m_flContractSpeed != 0) + { + m_flSize = m_flOriginalSize - (m_flContractSpeed * 30.0 * (time - m_flTimeCreated)); + + if (m_flSize < 0.0001) + { + m_flDieTime = time; + } + } +} + +void CBaseParticle::Fade(float time) +{ + if (m_flFadeSpeed >= -0.5) + { + if (m_flFadeSpeed == 0) + { + m_flBrightness = (1.0 - (time - m_flTimeCreated) / (m_flDieTime - m_flTimeCreated)) * m_flOriginalBrightness; + } + else + { + m_flBrightness = m_flOriginalBrightness - m_flFadeSpeed * 30.0 * (time - m_flTimeCreated); + } + + if (m_flBrightness < 1) + { + m_flDieTime = time; + } + } +} + +void CBaseParticle::Spin(float time) +{ + if (m_vAVelocity == g_vecZero) + { + return; + } + + //Superfluous; overwritten below. + //m_vAngles = m_vAngles + m_vAVelocity; + + Vector point = m_vAVelocity; + + const float length = VectorNormalize(point) * 30.0 * (time - m_flTimeCreated); + + m_vAngles = m_vOriginalAngles + m_vAVelocity * length; +} + +void CBaseParticle::CalculateVelocity(float time) +{ + const float deltaTime = time - g_flOldTime; + const float gravity = -deltaTime * g_flGravity * m_flGravity; + + if (m_vVelocity == g_vecZero && gravity == 0) + { + return; + } + + if ((m_iCollisionFlags & TRI_SPIRAL) != 0) + { + m_vOrigin = m_vOrigin + m_vVelocity * deltaTime; + + m_vOrigin.x += sin(time * 5.0 + reinterpret_cast(this)) * 2; + m_vOrigin.y += sin(time * 7.5 + reinterpret_cast(this)); + } + else + { + m_vOrigin = m_vOrigin + m_vVelocity * deltaTime; + } + + m_vVelocity.z = m_vVelocity.z + gravity; +} + +void CBaseParticle::CheckCollision(float time) +{ + if (m_iCollisionFlags == 0) + { + return; + } + + m_flNextCollisionTime = time; + + if ((m_iCollisionFlags & (TRI_WATERTRACE | TRI_COLLIDEALL | TRI_COLLIDEWORLD)) == 0) + { + return; + } + + pmtrace_t trace; + + bool collided = false; + + if ((m_iCollisionFlags & TRI_COLLIDEALL) != 0) + { + gEngfuncs.pEventAPI->EV_SetTraceHull(2); + gEngfuncs.pEventAPI->EV_PlayerTrace(m_vPrevOrigin, m_vOrigin, PM_STUDIO_BOX, -1, &trace); + + if (trace.fraction != 1.0) + { + //Called but never used, probably unfinished code for colliding with other entities. + //auto entity = gEngfuncs.pEventAPI->EV_GetPhysent(trace.ent); + + //Collided with something other than world, ignore. + if (0 == trace.ent) + { + collided = true; + } + } + } + else if ((m_iCollisionFlags & TRI_COLLIDEWORLD) != 0) + { + gEngfuncs.pEventAPI->EV_SetTraceHull(2); + gEngfuncs.pEventAPI->EV_PlayerTrace(m_vPrevOrigin, m_vOrigin, PM_WORLD_ONLY | PM_STUDIO_BOX, -1, &trace); + + if (trace.fraction != 1.0) + { + m_vVelocity = m_vVelocity * 0.6; + + if (m_vVelocity.Length() < 10) + { + m_iCollisionFlags = 0; + m_vVelocity = g_vecZero; + m_vAVelocity = g_vecZero; + m_vOrigin = trace.endpos; + } + + collided = true; + } + } + + if (collided) + { + const float frametime = time - g_flOldTime; + + m_vOrigin = m_vPrevOrigin + m_vVelocity * (trace.fraction * frametime); + + float bounce; + + bool dead = false; + + if (trace.plane.normal.z <= 0.9 || m_vVelocity.z > 0 || (m_vVelocity.z < -frametime * g_flGravity * m_flGravity * 3.0)) + { + if ((m_iCollisionFlags & TRI_COLLIDEKILL) != 0) + { + m_flDieTime = gEngfuncs.GetClientTime(); + dead = true; + } + else + { + bounce = m_flBounceFactor * 0.5; + + if (bounce != 0) + { + const float dot = DotProduct(trace.plane.normal, m_vVelocity) * -2; + m_vVelocity = m_vVelocity + trace.plane.normal * dot; + m_vAngles.y = -m_vAngles.y; + } + } + } + else + { + //Particle fell on an (almost) flat surface and has no velocity to bounce back up; disable collisions from now on. + bounce = 0; + m_vVelocity = g_vecZero; + m_vAVelocity = g_vecZero; + m_iCollisionFlags = 0; + } + + if (!dead && bounce != 1) + { + m_vVelocity = m_vVelocity * bounce; + m_vAngles = m_vAngles * 0.9; + } + + Touch(trace.endpos, trace.plane.normal, trace.ent, false); + } + else if ((m_iCollisionFlags & TRI_WATERTRACE) != 0) + { + if (gEngfuncs.PM_PointContents(m_vOrigin, nullptr) == CONTENTS_WATER && !m_bInWater) + { + Touch(m_vOrigin, {0, 0, 1}, 0, true); + + m_bInWater = true; + + if ((m_iCollisionFlags & TRI_COLLIDEKILL) != 0) + { + m_flDieTime = gEngfuncs.GetClientTime(); + } + } + } + + m_vPrevOrigin = m_vOrigin; +} + +void CBaseParticle::Touch(Vector pos, Vector normal, int index, bool enteringWater) +{ + //Nothing. +} + +void CBaseParticle::Die() +{ + //Nothing. +} + +void CBaseParticle::Force() +{ + //Nothing. +} + +void CBaseParticle::Think(float time) +{ + if ((m_iCollisionFlags & TRI_ANIMATEDIE) != 0) + { + AnimateAndDie(time); + } + else + { + Animate(time); + } + + Contract(time); + Expand(time); + Fade(time); + Spin(time); + CalculateVelocity(time); + CheckCollision(time); +} diff --git a/src/game/client/particleman/CBaseParticle.h b/src/game/client/particleman/CBaseParticle.h new file mode 100644 index 000000000..811296c9e --- /dev/null +++ b/src/game/client/particleman/CBaseParticle.h @@ -0,0 +1,180 @@ +#pragma once + +#define TRI_COLLIDEWORLD 0x00000020 +#define TRI_COLLIDEALL 0x00001000 // will collide with world and slideboxes +#define TRI_COLLIDEKILL 0x00004000 // tent is removed upon collision with anything +#define TRI_SPIRAL 0x00008000 +#define TRI_ANIMATEDIE 0x00016000 //animate once and then die +#define TRI_WATERTRACE 0x00032000 + + +#define CULL_FRUSTUM_POINT (1 << 0) +#define CULL_FRUSTUM_SPHERE (1 << 1) +#define CULL_FRUSTUM_PLANE (1 << 2) +#define CULL_PVS (1 << 3) + +#define LIGHT_NONE (1 << 4) +#define LIGHT_COLOR (1 << 5) +#define LIGHT_INTENSITY (1 << 6) + +#define RENDER_FACEPLAYER (1 << 7) // m_vAngles == Player view angles +#define RENDER_FACEPLAYER_ROTATEZ (1 << 8) //Just like above but m_vAngles.z is untouched so the sprite can rotate. + + +#include "CMiniMem.h" + +//pure virtual baseclass +class CBaseParticle +{ +private: + int m_iRenderFlags; + float m_flNextPVSCheck; + bool m_bInPVS; + + int m_iCollisionFlags; + float m_flPlayerDistance; //Used for sorting the particles, DO NOT TOUCH. + +public: + virtual ~CBaseParticle() {} + void* operator new(size_t size) + { + return CMiniMem::Instance()->Allocate(size); + } + + void operator delete(void* memory) + { + CMiniMem::Instance()->Deallocate(memory); + } + + virtual void Think(float time); + virtual bool CheckVisibility(); + virtual void Draw(); + virtual void Animate(float time); + virtual void AnimateAndDie(float time); + virtual void Expand(float time); + virtual void Contract(float time); + virtual void Fade(float time); + virtual void Spin(float time); + virtual void CalculateVelocity(float time); + virtual void CheckCollision(float time); + virtual void Touch(Vector pos, Vector normal, int index, bool enteringWater); + virtual void Die(); + virtual void InitializeSprite(Vector org, Vector normal, model_s* sprite, float size, float brightness); + virtual void Force(); + + float m_flSize; //scale of object + float m_flScaleSpeed; //speed at which object expands + float m_flContractSpeed; //speed at which object expands + + float m_flStretchX; + float m_flStretchY; + + float m_flBrightness; //transparency of object + float m_flFadeSpeed; //speed at which object fades + + float m_flTimeCreated; //time object was instanced + float m_flDieTime; //time to remove an object + + float m_flGravity; //how effected by gravity is this object + float m_flAfterDampGrav; + float m_flDampingVelocity; + float m_flDampingTime; + + int m_iFramerate; + int m_iNumFrames; + int m_iFrame; + int m_iRendermode; + + Vector m_vOrigin; //object's position + Vector m_vAngles; //normal angles of object + + Vector m_vAVelocity; + + Vector m_vVelocity; + + Vector m_vLowLeft; + Vector m_vLowRight; + Vector m_vTopLeft; + + Vector m_vColor; + float m_flMass; + + model_s* m_pTexture; + + float m_flBounceFactor; + + char m_szClassname[32]; + + bool m_bInWater; + bool m_bAffectedByForce; + + int m_iAfterDampFlags; + + void SetLightFlag(int iFlag) + { + m_iRenderFlags &= ~(LIGHT_NONE | LIGHT_INTENSITY | LIGHT_COLOR); + m_iRenderFlags |= iFlag; + } + + void SetCullFlag(int iFlag) + { + m_iRenderFlags &= ~(CULL_PVS | CULL_FRUSTUM_POINT | CULL_FRUSTUM_PLANE | CULL_FRUSTUM_SPHERE); + m_iRenderFlags |= iFlag; + } + + int GetRenderFlags() + { + return m_iRenderFlags; + } + + bool GetParticlePVS() + { + return m_bInPVS; + } + + void SetParticlePVS(bool bPVSStat) + { + m_bInPVS = bPVSStat; + } + + float GetNextPVSCheck() + { + return m_flNextPVSCheck; + } + + void SetNextPVSCheck(float flTime) + { + m_flNextPVSCheck = flTime; + } + + void SetCollisionFlags(int iFlag) + { + m_iCollisionFlags |= iFlag; + } + + void ClearCollisionFlags(int iFlag) + { + m_iCollisionFlags &= ~iFlag; + } + + int GetCollisionFlags() + { + return m_iCollisionFlags; + } + + void SetRenderFlag(int iFlag) + { + m_iRenderFlags |= iFlag; + } + + float GetPlayerDistance() const { return m_flPlayerDistance; } + void SetPlayerDistance(float flDistance) { m_flPlayerDistance = flDistance; } + +protected: + float m_flOriginalSize; + Vector m_vOriginalAngles; + float m_flOriginalBrightness; + Vector m_vPrevOrigin; + + float m_flNextCollisionTime; +}; diff --git a/src/game/client/particleman/CFrustum.cpp b/src/game/client/particleman/CFrustum.cpp new file mode 100644 index 000000000..203214a10 --- /dev/null +++ b/src/game/client/particleman/CFrustum.cpp @@ -0,0 +1,164 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +//The triangle API uses OpenGL constants for certain functions. +#ifdef WIN32 +#include "PlatformWin.h" +#endif + +#include + +#include "hud.h" + +#include "cl_util.h" +#include "triangleapi.h" +#include "CFrustum.h" + +//TODO: this function always operates on the frustum matrix that's part of this object, so there is no need to pass the address. +void CFrustum::NormalizeFrustumPlane(float frustum[6][4], int side) +{ + auto& elements = frustum[side]; + + const float length = Vector{elements[0], elements[1], elements[2]}.Length(); + + elements[0] /= length; + elements[1] /= length; + elements[2] /= length; + elements[3] /= length; +} + +void CFrustum::CalculateFrustum() +{ + float proj[16]; + gEngfuncs.pTriAPI->GetMatrix(GL_PROJECTION_MATRIX, proj); + + float modl[16]; + gEngfuncs.pTriAPI->GetMatrix(GL_MODELVIEW_MATRIX, modl); + + float frustum[16]{}; + + //TODO: clean this up. It's a 4x4 matrix multiplication. + frustum[0] = proj[0] * modl[0] + proj[1] * modl[4] + proj[2] * modl[8] + proj[3] * modl[12]; + frustum[1] = proj[1] * modl[0] + proj[1] * modl[5] + proj[2] * modl[9] + proj[3] * modl[13]; + frustum[2] = proj[2] * modl[0] + proj[1] * modl[6] + proj[2] * modl[10] + proj[3] * modl[14]; + frustum[3] = modl[3] * proj[0] + modl[1] * proj[7] + modl[2] * proj[11] + modl[3] * proj[15]; + + frustum[4] = proj[0] * modl[4] + proj[4] * modl[5] + proj[6] * modl[8] + proj[7] * modl[12]; + frustum[5] = proj[1] * modl[4] + proj[5] * modl[5] + proj[6] * modl[9] + proj[7] * modl[13]; + frustum[6] = proj[2] * modl[4] + proj[5] * modl[6] + proj[6] * modl[10] + proj[7] * modl[14]; + frustum[7] = modl[3] * proj[4] + modl[5] * proj[7] + modl[6] * proj[11] + modl[7] * proj[15]; + + frustum[8] = proj[0] * modl[8] + proj[4] * modl[9] + proj[8] * modl[10] + proj[12] * modl[11]; + frustum[9] = proj[1] * modl[8] + proj[5] * modl[9] + proj[9] * modl[10] + proj[11] * modl[13]; + frustum[10] = proj[2] * modl[8] + proj[6] * modl[9] + proj[10] * modl[10] + proj[11] * modl[14]; + frustum[11] = modl[3] * proj[8] + modl[7] * proj[9] + modl[10] * proj[11] + modl[11] * proj[15]; + + frustum[12] = proj[0] * modl[12] + proj[4] * modl[13] + proj[8] * modl[14] + proj[12] * modl[15]; + frustum[13] = proj[1] * modl[12] + proj[5] * modl[13] + proj[9] * modl[14] + proj[13] * modl[15]; + frustum[14] = proj[2] * modl[12] + proj[6] * modl[13] + proj[10] * modl[14] + proj[14] * modl[15]; + frustum[15] = modl[3] * proj[12] + proj[7] * modl[13] + proj[11] * modl[14] + proj[15] * modl[15]; + + g_flFrustum[RIGHT][0] = frustum[3] - frustum[0]; + g_flFrustum[RIGHT][1] = frustum[7] - frustum[4]; + g_flFrustum[RIGHT][2] = frustum[11] - frustum[8]; + g_flFrustum[RIGHT][3] = frustum[15] - frustum[12]; + + NormalizeFrustumPlane(g_flFrustum, RIGHT); + + g_flFrustum[LEFT][0] = frustum[0] + frustum[3]; + g_flFrustum[LEFT][1] = frustum[4] + frustum[7]; + g_flFrustum[LEFT][2] = frustum[8] + frustum[11]; + g_flFrustum[LEFT][3] = frustum[12] + frustum[15]; + NormalizeFrustumPlane(g_flFrustum, LEFT); + + g_flFrustum[BOTTOM][0] = frustum[1] + frustum[3]; + g_flFrustum[BOTTOM][1] = frustum[5] + frustum[7]; + g_flFrustum[BOTTOM][2] = frustum[9] + frustum[11]; + g_flFrustum[BOTTOM][3] = frustum[15] + frustum[13]; + NormalizeFrustumPlane(g_flFrustum, BOTTOM); + + g_flFrustum[TOP][0] = frustum[3] - frustum[1]; + g_flFrustum[TOP][1] = frustum[7] - frustum[5]; + g_flFrustum[TOP][2] = frustum[11] - frustum[9]; + g_flFrustum[TOP][3] = frustum[15] - frustum[13]; + NormalizeFrustumPlane(g_flFrustum, TOP); + + g_flFrustum[BACK][0] = frustum[3] - frustum[2]; + g_flFrustum[BACK][1] = frustum[7] - frustum[6]; + g_flFrustum[BACK][2] = frustum[11] - frustum[10]; + g_flFrustum[BACK][3] = frustum[15] - frustum[14]; + NormalizeFrustumPlane(g_flFrustum, BACK); + + g_flFrustum[FRONT][0] = frustum[2] + frustum[3]; + g_flFrustum[FRONT][1] = frustum[6] + frustum[7]; + g_flFrustum[FRONT][2] = frustum[10] + frustum[11]; + g_flFrustum[FRONT][3] = frustum[14] + frustum[15]; + NormalizeFrustumPlane(g_flFrustum, FRONT); +} + +bool CFrustum::PointInsideFrustum(float x, float y, float z) +{ + for (int i = 0; i < 6; ++i) + { + if (((g_flFrustum[i][0] * x) + (g_flFrustum[i][1] * y) + (g_flFrustum[i][2] * z) + g_flFrustum[i][3]) <= 0) + { + return false; + } + } + + return true; +} + +bool CFrustum::SphereInsideFrustum(float x, float y, float z, float radius) +{ + for (int i = 0; i < 6; ++i) + { + if (((g_flFrustum[i][0] * x) + (g_flFrustum[i][1] * y) + (g_flFrustum[i][2] * z) + g_flFrustum[i][3]) <= -radius) + { + return false; + } + } + + return true; +} + +bool CFrustum::PlaneInsideFrustum(float x, float y, float z, float size) +{ + const float sizes[3][2] = + { + {x - size, x + size}, + {y - size, y + size}, + {z - size, z + size}}; + + for (int i = 0; i < 6; ++i) + { + //Test every permutation of plane sizes. + for (int zAxis = 0; zAxis < 2; ++zAxis) + { + for (int yAxis = 0; yAxis < 2; ++yAxis) + { + for (int xAxis = 0; xAxis < 2; ++xAxis) + { + if (((sizes[0][xAxis] * g_flFrustum[i][0]) + (sizes[1][yAxis] * g_flFrustum[i][1]) + (sizes[2][zAxis] * g_flFrustum[i][2]) + g_flFrustum[i][3]) <= 0) + { + return false; + } + } + } + } + } + + return true; +} diff --git a/src/game/client/particleman/CFrustum.h b/src/game/client/particleman/CFrustum.h new file mode 100644 index 000000000..070d03618 --- /dev/null +++ b/src/game/client/particleman/CFrustum.h @@ -0,0 +1,43 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#pragma once + +enum FrustumSide +{ + RIGHT = 0, + LEFT = 1, + BOTTOM = 2, + TOP = 3, + BACK = 4, + FRONT = 5, +}; + +struct CFrustum +{ + void CalculateFrustum(); + + bool PointInsideFrustum(float x, float y, float z); + + bool SphereInsideFrustum(float x, float y, float z, float radius); + + bool PlaneInsideFrustum(float x, float y, float z, float size); + +private: + void NormalizeFrustumPlane(float frustum[6][4], int side); + +public: + float g_flFrustum[6][4]; +}; diff --git a/src/game/client/particleman/CMiniMem.cpp b/src/game/client/particleman/CMiniMem.cpp new file mode 100644 index 000000000..a659574e4 --- /dev/null +++ b/src/game/client/particleman/CMiniMem.cpp @@ -0,0 +1,236 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#include + +#include "hud.h" +#include "cl_util.h" +#include "particleman.h" +#include "particleman_internal.h" +#include "CMiniMem.h" + +CMiniMem* CMiniMem::_instance = nullptr; + +void* CMiniMem::Allocate(std::size_t sizeInBytes) +{ + //auto particle = reinterpret_cast(_pool.allocate(sizeInBytes, alignment)); + auto particle = reinterpret_cast(malloc(sizeInBytes)); + + if (nullptr != particle) + { + _particles.push_back(particle); + } + + return particle; +} + +void CMiniMem::Deallocate(void* memory) +{ + if (!memory) + { + return; + } + + auto it = std::find(_particles.begin(), _particles.end(), memory); + if (it != _particles.end()) + _particles.erase(it); + else + gEngfuncs.Con_Printf("Couldn't find a particle in the particles array to erase!\n"); + + free(memory); + //_pool.deallocate(memory, sizeInBytes, alignment); +} + +void CMiniMem::Shutdown() +{ + delete _instance; + _instance = nullptr; +} + +CMiniMem* CMiniMem::Instance() +{ + if (!_instance) + { + _instance = new CMiniMem(); + } + + return _instance; +} + +void CMiniMem::ProcessAll() +{ + const float time = gEngfuncs.GetClientTime(); + + //Clear list of visible particles. + _visibleParticles = 0; + + //Divide the particle list in two: the list of visible particles and the list of invisible particles. + //Remove any particles that have died. + std::size_t invisibleCount = 0; + + for (std::size_t i = 0; i < (_particles.size() - invisibleCount);) + { + auto effect = _particles[i]; + + if (!IsGamePaused()) + { + effect->Think(time); + } + + if (0 != effect->m_flDieTime && time >= effect->m_flDieTime) + { + effect->Die(); + delete effect; + + //Don't do this! operator delete removes the effect from the list. + //_particles.erase(_particles.begin() + i); + continue; + } + + if (effect->CheckVisibility()) + { + auto player = gEngfuncs.GetLocalPlayer(); + effect->SetPlayerDistance((player->origin - effect->m_vOrigin).Length()*(player->origin - effect->m_vOrigin).Length()); + + ++_visibleParticles; + } + else + { + if (i + invisibleCount < _particles.size()) + { + //There is an effect we haven't checked yet. + //Put the invisible effect at the end of the list and check the other effect next. + std::swap(_particles[i], _particles[_particles.size() - 1 - invisibleCount]); + ++invisibleCount; + continue; + } + //No more unchecked effects in the list. + } + + ++i; + } + + std::sort(_particles.begin(), _particles.begin() + _visibleParticles, [](const CBaseParticle* lhs, const CBaseParticle* rhs) + { + //Particles are ordered farthest to nearest so they can be drawn in order. + const float lhsDistance = lhs->GetPlayerDistance(); + const float rhsDistance = rhs->GetPlayerDistance(); + + return lhsDistance > rhsDistance; + }); + + for (std::size_t i = 0; i < _visibleParticles; ++i) + { + auto effect = _particles[i]; + effect->Draw(); + } + + g_flOldTime = time; +} + +int CMiniMem::ApplyForce(Vector vOrigin, Vector vDirection, float flRadius, float flStrength) +{ + const float radiusSquared = flRadius * flRadius; + + for (auto effect : _particles) + { + if (!effect->m_bAffectedByForce) + { + continue; + } + + const float size = effect->m_flSize / 5; + + const Vector mins = effect->m_vOrigin - Vector{size, size, size}; + const Vector maxs = effect->m_vOrigin + Vector{size, size, size}; + + //If the force origin lies outside the effect's bounding box, calculate the distance from the box. + float totalDistanceSquared = 0; + + for (int i = 0; i < 3; ++i) + { + float boundingValue; + + if (vOrigin[i] < mins[i]) + { + boundingValue = mins[i]; + } + else if (vOrigin[i] > maxs[i]) + { + boundingValue = maxs[i]; + } + else + { + continue; + } + + totalDistanceSquared += (vOrigin[i] - boundingValue) * (vOrigin[i] - boundingValue); + } + + //Effect is further away from position than force radius, don't apply force. + if (totalDistanceSquared > radiusSquared) + { + continue; + } + + const float strength = std::max(0.f, flStrength - (vOrigin - effect->m_vOrigin).Length() * (flStrength / (0.5f * radiusSquared))); + + if (vDirection == Vector(0,0,0)) + { + const float acceleration = -(strength / effect->m_flMass); + + const Vector direction = (vOrigin - effect->m_vOrigin).Normalize(); + const Vector velocity = effect->m_vVelocity.Normalize(); + + effect->m_vVelocity = acceleration * (direction + velocity); + } + else + { + const float acceleration = strength / effect->m_flMass; + + const Vector direction = vDirection.Normalize(); + const Vector velocity = effect->m_vVelocity.Normalize(); + + effect->m_vVelocity = acceleration * (direction + velocity); + } + + effect->Force(); + } + + return 1; +} + +void CMiniMem::Reset() +{ + _visibleParticles = 0; + + auto particles = _particles; + + for (auto particle : particles) + { + particle->Die(); + delete particle; + } + + if (_particles.size() != 0) + { + gEngfuncs.Con_Printf("Didn't delete all particles?!"); + _particles.clear(); + } + + //Wipe away previously allocated memory so maps with loads of particles don't eat up memory forever. + //_pool.release(); + _particles.shrink_to_fit(); +} diff --git a/src/game/client/particleman/CMiniMem.h b/src/game/client/particleman/CMiniMem.h new file mode 100644 index 000000000..aa8d8abc7 --- /dev/null +++ b/src/game/client/particleman/CMiniMem.h @@ -0,0 +1,46 @@ +#pragma once +#ifndef MINIMEM_H +#define MINIMEM_H + +#include +#include + +class CBaseParticle; + +#define TRIANGLE_FPS 30 + +/** +* @brief Simple allocator that uses a chunk-based pool to serve requests. +*/ +class CMiniMem +{ +private: + static CMiniMem* _instance; + + std::vector _particles; + std::size_t _visibleParticles = 0; + +protected: + // private constructor and destructor. + CMiniMem() = default; + ~CMiniMem() = default; + +public: + void* Allocate(std::size_t sizeInBytes); + + void Deallocate(void* memory); + + void ProcessAll(); //Processes all + + void Reset(); //clears memory, setting all particles to not used. + + void Shutdown(); + + int ApplyForce(Vector vOrigin, Vector vDirection, float flRadius, float flStrength); + + static CMiniMem* Instance(); + + std::size_t GetTotalParticles() { return _particles.size(); } + std::size_t GetDrawnParticles() { return _visibleParticles; } +}; +#endif diff --git a/src/game/client/particleman/IParticleMan_Active.cpp b/src/game/client/particleman/IParticleMan_Active.cpp new file mode 100644 index 000000000..70af73478 --- /dev/null +++ b/src/game/client/particleman/IParticleMan_Active.cpp @@ -0,0 +1,147 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#include + +#include "hud.h" +#include "cl_util.h" +#include "triangleapi.h" +#include "particleman.h" +#include "particleman_internal.h" +#include "CMiniMem.h" +#include "IParticleMan_Active.h" +#include + +CFrustum g_cFrustum; +float g_flGravity; +float g_flOldTime; +Vector g_vViewAngles; +Vector g_viewPlaneNormal; + +static bool g_iRenderMode = true; + +static cvar_t* cl_pmanstats = nullptr; + +static std::vector g_pForceList; + +IParticleMan_Active::IParticleMan_Active() +{ + g_pForceList.reserve(MaxForceElements); +} + +void IParticleMan_Active::SetRender(int iRender) +{ + g_iRenderMode = iRender != 0; +} + +void IParticleMan_Active::ApplyForce(Vector vOrigin, Vector vDirection, float flRadius, float flStrength, float flDuration) +{ + if (g_pForceList.size() >= MaxForceElements) + { + return; + } + + ForceMember member; + + member.m_vOrigin = vOrigin; + member.m_vDirection = vDirection; + member.m_flRadius = flRadius; + member.m_flStrength = flStrength; + member.m_flDieTime = gEngfuncs.GetClientTime() + flDuration; + + g_pForceList.push_back(member); +} + +void IParticleMan_Active::SetUp(cl_enginefunc_t* pEnginefuncs) +{ + //Note: disabled because we're in the client dll. + //std::memcpy(&gEngfuncs, pEnginefuncs, sizeof(gEngfuncs)); + + cl_pmanstats = gEngfuncs.pfnRegisterVariable("cl_pmanstats", "0", 0); +} + +CBaseParticle* IParticleMan_Active::CreateParticle(Vector org, Vector normal, model_s* sprite, float size, float brightness, const char* classname) +{ + auto particle = new CBaseParticle(); + + particle->InitializeSprite(org, normal, sprite, size, brightness); + strncpy(particle->m_szClassname, classname, sizeof(particle->m_szClassname) - 1); + particle->m_szClassname[sizeof(particle->m_szClassname) - 1] = '\0'; + + return particle; +} + +void IParticleMan_Active::ResetParticles() +{ + CMiniMem::Instance()->Reset(); + g_pForceList.clear(); +} + +void IParticleMan_Active::SetVariables(float flGravity, Vector vViewAngles) +{ + g_flGravity = flGravity; + + if (gEngfuncs.GetClientTime() != g_flOldTime) + { + g_vViewAngles = vViewAngles; + + Vector right, up; + AngleVectors(g_vViewAngles, &g_viewPlaneNormal, &right, &up); + } +} + +void IParticleMan_Active::Update() +{ + g_pParticleMan = this; + + const float time = gEngfuncs.GetClientTime(); + + for (std::size_t i = 0; i < g_pForceList.size();) + { + auto& member = g_pForceList[i]; + if (member.m_flDieTime != 0 && member.m_flDieTime < time) + { + //Always swap to last before erasing to make it cheaper to do. + if (i + 1 < g_pForceList.size()) + { + std::swap(member, g_pForceList[g_pForceList.size() - 1]); + } + + g_pForceList.erase(g_pForceList.begin() + (g_pForceList.size() - 1)); + } + else + { + ++i; + } + } + + auto memory = CMiniMem::Instance(); + + for (const auto& member : g_pForceList) + { + memory->ApplyForce(member.m_vOrigin, member.m_vDirection, member.m_flRadius, member.m_flStrength); + } + + g_cFrustum.CalculateFrustum(); + + memory->ProcessAll(); + + if (nullptr != cl_pmanstats && cl_pmanstats->value == 1) + { + //TODO: engine doesn't support printing size_t, use local printf + gEngfuncs.Con_NPrintf(15, "Number of Particles: %d", static_cast(CMiniMem::Instance()->GetTotalParticles())); + gEngfuncs.Con_NPrintf(16, "Particles Drawn: %d", static_cast(CMiniMem::Instance()->GetDrawnParticles())); + } +} diff --git a/src/game/client/particleman/IParticleMan_Active.h b/src/game/client/particleman/IParticleMan_Active.h new file mode 100644 index 000000000..5edee3ea8 --- /dev/null +++ b/src/game/client/particleman/IParticleMan_Active.h @@ -0,0 +1,34 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#pragma once + +#include "particleman.h" + +class IParticleMan_Active : public IParticleMan +{ +public: + IParticleMan_Active(); + + void SetUp(cl_enginefunc_t* pEnginefuncs) override; + void Update() override; + void SetVariables(float flGravity, Vector vViewAngles) override; + void ResetParticles() override; + void ApplyForce(Vector vOrigin, Vector vDirection, float flRadius, float flStrength, float flDuration) override; + + CBaseParticle* CreateParticle(Vector org, Vector normal, model_s* sprite, float size, float brightness, const char* classname) override; + + void SetRender(int iRender) override; +}; diff --git a/src/game/client/particleman/particleman.h b/src/game/client/particleman/particleman.h new file mode 100644 index 000000000..309f94a7e --- /dev/null +++ b/src/game/client/particleman/particleman.h @@ -0,0 +1,26 @@ +#pragma once +#ifndef PARTICLEMAN_H +#define PARTICLEMAN_H + +#include "interface.h" +#include "CBaseParticle.h" + +class IParticleMan +{ +public: + virtual ~IParticleMan() {} + virtual void SetUp(cl_enginefunc_t* pEnginefuncs) = 0; + virtual void Update() = 0; + virtual void SetVariables(float flGravity, Vector vViewAngles) = 0; + virtual void ResetParticles() = 0; + virtual void ApplyForce(Vector vOrigin, Vector vDirection, float flRadius, float flStrength, float flDuration) = 0; + + //Use this if you want to create a new particle without any overloaded functions, Think, Touch, etc. + //Just call this function, set the particle's behavior and let it rip. + virtual CBaseParticle* CreateParticle(Vector org, Vector normal, model_s* sprite, float size, float brightness, const char* classname) = 0; + + virtual void SetRender(int iRender) = 0; +}; + +extern IParticleMan* g_pParticleMan; +#endif diff --git a/src/game/client/particleman/particleman_internal.h b/src/game/client/particleman/particleman_internal.h new file mode 100644 index 000000000..d13e11594 --- /dev/null +++ b/src/game/client/particleman/particleman_internal.h @@ -0,0 +1,51 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#pragma once +#ifndef PARTICLEMAN_INTERNAL_H +#define PARTICLEMAN_INTERNAL_H + +/** +* @file +* +* Internal header for particle manager +*/ + +#include +#include + +#include "CFrustum.h" + +constexpr std::size_t MaxForceElements = 128; + +extern CFrustum g_cFrustum; +extern float g_flGravity; +extern float g_flOldTime; +extern Vector g_vViewAngles; + +inline bool IsGamePaused() +{ + return gEngfuncs.GetClientTime() == g_flOldTime; +} + +struct ForceMember +{ + Vector m_vOrigin; + Vector m_vDirection; + float m_flRadius; + float m_flStrength; + float m_flDieTime; +}; +#endif diff --git a/src/game/client/render/clenv.cpp b/src/game/client/render/clenv.cpp new file mode 100644 index 000000000..fe3d1cbe0 --- /dev/null +++ b/src/game/client/render/clenv.cpp @@ -0,0 +1,485 @@ +#include "inc_weapondefs.h" +#include "render/clrender.h" +#include "clglobal.h" + +#include "hud.h" +#include "cl_util.h" +#include "const.h" +#include "entity_state.h" +#include "cl_entity.h" +#include "triangleapi.h" +#include "com_model.h" +#include "mslogger.h" +#include "particleman/particleman.h" +#include + +#define MS_GL_ATTRIBUTES GL_ALL_ATTRIB_BITS + +#ifdef _WIN32 +static PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL; +#else // _WIN32 +#define glActiveTextureARB glActiveTexture +#endif + +float CEnvMgr::m_LightGamma = 2.5; +float CEnvMgr::m_MaxViewDistance = 4096; +CEnvMgr::fog_t CEnvMgr::m_Fog = {false, Vector(0, 0, 0), 0.01, 0.01, 10000, GL_EXP}; + +int CEnvMgr::m_OldHLTexture[10] = {0}; +bool CEnvMgr::m_OldMultiTextureEnabled = false; + +extern float v_ViewDist; +void VGUIImages_NewLevel(); + +struct skyface_t +{ + CParticle Face; + + //Vector Offset; +}; + +#define SKYFILENAME_PREFIX "gfx/env/" +struct +{ + Vector Dir; + const char* FileNameSuffix; + bool Rotate; +} g_SkyBoxInfo[6] = + { + {Vector(0, 180, 0), "ft", false}, + {Vector(0, 90, 0), "lf", false}, + {Vector(0, 0, 0), "bk", false}, + {Vector(0, 270, 0), "rt", false}, + {Vector(-90, 0, 0), "dn", false}, + {Vector(90, 0, 0), "up", true}, +}; + +class CSkyBox +{ +public: + msstring m_SkyName; + mslist Faces; + int m_uiNextTexIdx; + + CSkyBox() + { + m_uiNextTexIdx = 1; + m_SkyName = "g_morning"; + + for (int i = 0; i < 6; i++) + { + Faces.add(skyface_t()); + + CParticle &Face = Faces[i].Face; + Face.m_Color = Color4F(1, 1, 1, 1); + Face.m_Brightness = 1.0f; + } + } + + //Called once each level load + void Setup() + { + for (int i = 0; i < Faces.size(); i++) + { + CParticle &Face = Faces[i].Face; + Face.SetAngles(g_SkyBoxInfo[i].Dir); + if (g_SkyBoxInfo[i].Rotate) + { + Vector2D Tmp = Face.m_TexCoords[0]; + Face.m_TexCoords[0] = Vector2D(0, 0); + Face.m_TexCoords[1] = Vector2D(1, 0); + Face.m_TexCoords[2] = Vector2D(1, 1); + Face.m_TexCoords[3] = Vector2D(0, 1); + } + } + + ChangeTexture(m_SkyName); + } + + //Dynamic. Can change textures anytime + void ChangeTexture(const char* NewTexture) + { + m_SkyName = NewTexture; + for (int i = 0; i < Faces.size(); i++) + { + msstring FileName = /*msstring(EngineFunc::GetGameDir()) + "/" +*/ msstring(SKYFILENAME_PREFIX) + NewTexture + g_SkyBoxInfo[i].FileNameSuffix + ".tga"; + Faces[i].Face.m_GLTex = 0; + CEnvMgr::LoadGLTexture(FileName, Faces[i].Face.m_GLTex); + } + } + + void Render() + { + //if( MSGlobals::GameScript ) + // MSGlobals::GameScript->CallScriptEvent( "game_render_sky" ); + + for (int i = 0; i < Faces.size(); i++) + { + CParticle &Face = Faces[i].Face; + Face.m_Width = v_ViewDist - 1; + + Face.m_Origin = ViewMgr.Origin - Face.m_DirForward * Face.m_Width / 2.0f; + Face.m_ContinuedParticle = false; + Face.Render(); + } + } +}; + +CSkyBox g_CustomSkyBox; +CParticle g_Tint; + +//The renderamt the server sent for an entity, and what ApplyFogFade replaced it with +#define FOGFADE_MAX_ENTS 4096 +struct fogfade_t +{ + int ModelIndex; + int Original, Written; +}; +static fogfade_t g_FogFade[FOGFADE_MAX_ENTS]; + +void CEnvMgr::Init() +{ + m_MaxViewDistance = EngineFunc::CVAR_GetFloat("sv_zmax"); + g_CustomSkyBox.Setup(); + g_Tint.m_Color = Color4F(0, 0, 0, 0); +} + +void CEnvMgr::InitNewLevel() +{ + InitGL(); + memset(g_FogFade, 0, sizeof(g_FogFade)); + VGUIImages_NewLevel(); + MS_INFO("[InitNewLevel Complete]"); +} + +void CEnvMgr::ChangeSkyTexture(const char* NewTexture) +{ + g_CustomSkyBox.ChangeTexture(NewTexture); + g_CustomSkyBox.Setup(); //Thothie DEC2014_02 - trying to make setenv sky.texture work. + g_CustomSkyBox.Render(); //Thothie DEC2014_02 - trying to make setenv sky.texture work. +} + +void CEnvMgr::RenderSky() +{ + g_CustomSkyBox.Render(); +} + +void Surface_ResetLighting(msurface_t *pSurface) +{ + pSurface->cached_dlight = 1; +} + +//Traverses all nodes and leafs, calling Func on each surface found +void TraverseAllNodes(mnode_t *pNode, void *Func) +{ + if (!pNode) + return; + + mnode_t &Node = *pNode; + + if (Node.contents == CONTENTS_SOLID) + return; + + if (Node.contents < 0) + { + //Call Function on Leaf + mleaf_t &Leaf = *(mleaf_t *)&Node; + for (int s = 0; s < Leaf.nummarksurfaces; s++) + (*(ParseAllSurfacesFunc *)Func)(Leaf.firstmarksurface[s]); + return; + } + + for (int i = 0; i < 2; i++) + TraverseAllNodes(Node.children[i], Func); +} + +void CEnvMgr::SetLightGamma(float Value) +{ + m_LightGamma = Value; + EngineFunc::CVAR_SetFloat("lightgamma", m_LightGamma); + + TraverseAllNodes(gEngfuncs.GetEntityByIndex(0)->model->nodes, Surface_ResetLighting); +} + +void CEnvMgr::ChangeTint(const Color4F &Color) +{ + g_Tint.m_ContinuedParticle = false; + g_Tint.m_DoubleSided = false; + g_Tint.m_Color = Color; + g_Tint.m_Brightness = 0.0f; + g_Tint.m_Width = 500; + g_Tint.m_RenderMode = kRenderTransAlpha; +} + +//Draw transparent stuff +void CEnvMgr::Think_DrawTransparentTriangles() +{ + bool HideTint = MSCLGlobals::CharPanelActive || //Hide while choosing character + !g_Tint.m_Color.a; //Hide if alpha is zero + + if (!HideTint) + { + g_Tint.m_Origin = ViewMgr.Params->vieworg + ViewMgr.Params->forward * 4.2; + g_Tint.BillBoard(); + g_Tint.Render(); + } +} + +void CEnvMgr::Cleanup() +{ + //Unload all OGL Textures (skybox) + DeleteGLTextures(); //Thothie JAN2011_03, restore texture cleanup +} + +void CEnvMgr::RenderFog( bool bRender ) +{ + if ( CEnvMgr::m_Fog.Enabled ) + { + glEnable( GL_FOG ); + if ( bRender ) + glFogfv( GL_FOG_COLOR, CEnvMgr::m_Fog.Color ); + else + glFogfv( GL_FOG_COLOR, Vector( 0, 0, 0 ) ); + glFogi( GL_FOG_MODE, CEnvMgr::m_Fog.Type ); //GL_EXP, GL_LINEAR + glFogf( GL_FOG_DENSITY, CEnvMgr::m_Fog.Density ); + glFogf( GL_FOG_START, CEnvMgr::m_Fog.Start ); + glFogf( GL_FOG_END, CEnvMgr::m_Fog.End ); + } + else + glDisable( GL_FOG ); + + // Required for transparent crap, else they refuse to apply fog. Thank you engine. + gEngfuncs.pTriAPI->Fog( bRender ? CEnvMgr::m_Fog.Color : Vector( 0, 0, 0 ), CEnvMgr::m_Fog.Start, CEnvMgr::m_Fog.End, CEnvMgr::m_Fog.Enabled ); +} + +//How much of something at Origin is left after fog. Same math OpenGL uses for each fog type +float CEnvMgr::GetFogFactor(const Vector &Origin) +{ + if (!m_Fog.Enabled) + return 1.0f; + + float Dist = (Origin - ViewMgr.Origin).Length(); + float Factor = 1.0f; + + if (m_Fog.Type == GL_EXP) + Factor = exp(-m_Fog.Density * Dist); + else if (m_Fog.Type == GL_EXP2) + Factor = exp(-(m_Fog.Density * Dist) * (m_Fog.Density * Dist)); + else if (m_Fog.End != m_Fog.Start) //GL_LINEAR + Factor = (m_Fog.End - Dist) / (m_Fog.End - m_Fog.Start); + + if (Factor < 0.0f) + return 0.0f; + if (Factor > 1.0f) + return 1.0f; + return Factor; +} + +//The engine never fogs sprites or additive/glow entities, so fade them out by distance instead +bool CEnvMgr::ApplyFogFade(cl_entity_s *pEnt) +{ + cl_entity_t &Ent = *pEnt; + + if (!Ent.model || Ent.curstate.rendermode == kRenderNormal) + return true; + + if (Ent.model->type != mod_sprite && + Ent.curstate.rendermode != kRenderTransAdd && + Ent.curstate.rendermode != kRenderGlow) + return true; + + if (Ent.index < 0 || Ent.index >= FOGFADE_MAX_ENTS) + return true; + + //curstate is only refreshed when a server update arrives, so scale from the saved value + //or the fade would compound every frame + fogfade_t &Fade = g_FogFade[Ent.index]; + if (Fade.ModelIndex != Ent.curstate.modelindex || Fade.Written != Ent.curstate.renderamt) + { + //The server changed it, or this is a different entity + Fade.ModelIndex = Ent.curstate.modelindex; + Fade.Original = Ent.curstate.renderamt; + } + + Fade.Written = (int)(Fade.Original * GetFogFactor(Ent.origin)); + Ent.curstate.renderamt = Fade.Written; + + return Fade.Written > 0 || Fade.Original <= 0; +} + +//MS OGL extention stuff +void CEnvMgr::InitGL() +{ + const char *VendorString = (const char *)glGetString(GL_VENDOR); + const char *CardString = (const char *)glGetString(GL_RENDERER); + const char *VersionString = (const char *)glGetString(GL_VERSION); + const char *ExtensionsString = (const char *)glGetString(GL_EXTENSIONS); + MS_RENDER_INFO("Video Card Vendor: %s", VendorString); + MS_RENDER_INFO("Video Card: %s", CardString); + MS_RENDER_INFO("OpenGL Version: %s", VersionString); + MS_RENDER_INFO("OpenGL Extensions: %s", ExtensionsString); + +#ifdef _WIN32 + glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)SDL_GL_GetProcAddress("glActiveTextureARB"); +#endif +} + +void CEnvMgr::PushHLStates() +{ + if (!glActiveTextureARB) + return; + + glPushAttrib(MS_GL_ATTRIBUTES); + + glActiveTextureARB(GL_TEXTURE0_ARB); + glGetIntegerv(0x8069, &m_OldHLTexture[0]); //GL_TEXTURE_2D_BINDING = 0x8069 + + //Workaround - + //Half-life sometimes uses Texture1 to draw normal textures and other times Texture2 + //It just depends on where you're standing. Here I check whether HL is using Texture2, + //disable it, use texture1, then set it back to Texture2 when done + glActiveTextureARB(GL_TEXTURE1_ARB); + glGetIntegerv(0x8069, &m_OldHLTexture[1]); //GL_TEXTURE_2D_BINDING = 0x8069 + + m_OldMultiTextureEnabled = glIsEnabled(GL_TEXTURE_2D) ? true : false; + glDisable(GL_TEXTURE_2D); + + glActiveTextureARB(GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_2D); + + /*glEnable( GL_COLOR_MATERIAL ); + glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); + glColorMaterial( GL_FRONT, GL_EMISSION ); + glColorMaterial( GL_FRONT, GL_SPECULAR );*/ + + //--------------- + + /*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);*/ +} + +void CEnvMgr::PopHLStates() +{ + if (!glActiveTextureARB) + return; + + //Part of the Texture1/Texture2 Workaround + //Set the active texture back to what HL was using before + //---------------------------------------- + glPopAttrib(); + + glActiveTextureARB(GL_TEXTURE1_ARB); + glBindTexture(GL_TEXTURE_2D, m_OldHLTexture[1]); + if (m_OldMultiTextureEnabled) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + glActiveTextureARB(GL_TEXTURE0_ARB); + glBindTexture(GL_TEXTURE_2D, m_OldHLTexture[0]); + + if (m_OldMultiTextureEnabled) + glActiveTextureARB(GL_TEXTURE1_ARB); + + //static float color[4] = { 0, 0, 0, 0 }; + //int Param = GL_MODULATE; + //glTexEnviv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &Param ); + //glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color ); + + //---------------------------------------- +} + +void CEnvMgr::RenderParticles() +{ + if (!g_pParticleMan) + return; + + glPushAttrib(MS_GL_ATTRIBUTES); + + g_pParticleMan->Update(); + + //The engine remembers the last texture it bound and won't bind it again, so that one has to stay bound + int LastTexture = 0; + glGetIntegerv(0x8069, &LastTexture); //GL_TEXTURE_2D_BINDING = 0x8069 + glPopAttrib(); + glBindTexture(GL_TEXTURE_2D, LastTexture); +} + +struct gltexture_t : loadtex_t +{ + msstring Name; +}; +static mslist g_TextureList; + +bool CEnvMgr::LoadGLTexture(const char *FileName, loadtex_t &LoadTex) +{ + bool Loaded = false; + + for (int i = 0; i < g_TextureList.size(); i++) + { + if (g_TextureList[i].Name == FileName) + { + LoadTex = (loadtex_t)g_TextureList[i]; + return true; + } + } + + Loaded = Tartan::LoadTextureFile(FileName, LoadTex); + + if (Loaded) + { + gltexture_t Newtexture; + loadtex_t < = Newtexture; + LT = LoadTex; + Newtexture.Name = FileName; + g_TextureList.add(Newtexture); + } + else + { + Print("Missing MS Texture: %s\n", FileName); + } + + return Loaded; +} + +bool CEnvMgr::LoadGLTexture(const char *FileName, uint &TextureID) +{ + loadtex_t LoadTex; + bool Success = LoadGLTexture(FileName, LoadTex); + if (Success) + TextureID = LoadTex.GLTexureID; + + return Success; +} + +void CEnvMgr::DeleteGLTextures() +{ + for (int i = 0; i < g_TextureList.size(); i++) + glDeleteTextures(1, &g_TextureList[i].GLTexureID); + g_TextureList.clear(); +} + +//Called by the Tartan texture loader +void GetCompatibleTextureSize(uint SizeW, uint SizeH, uint &outNewSizeW, uint &outNewSizeH, float &outTexCoordU, float &outTexCoordV) +{ + //Force the texture to have dimensions 2^X + float LargestDimension = SizeW > SizeH ? SizeW : SizeH; + float Power = logf(LargestDimension) / logf(2); + int IntPower = (int)Power; + if (Power > IntPower) + IntPower++; //Dimension is in-between standardized texure sizes. Use the next highest size + float TexSize = pow(2, (int)IntPower); + + //Cap texure size at GL_MAX_TEXTURE_SIZE + int TexSizeMax = 0; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &TexSizeMax); + if (TexSize > TexSizeMax) + TexSize = (float)TexSizeMax; + + outNewSizeW = outNewSizeH = TexSize; + outTexCoordU = SizeW / (float)outNewSizeW; + outTexCoordV = SizeH / (float)outNewSizeH; +} diff --git a/src/game/client/render/clenv.h b/src/game/client/render/clenv.h new file mode 100644 index 000000000..9813289ac --- /dev/null +++ b/src/game/client/render/clenv.h @@ -0,0 +1,48 @@ +#pragma once + +struct loadtex_t; +struct cl_entity_s; + +class CEnvMgr +{ +public: + static void Init(); + static void InitNewLevel(); + static void Think_DrawTransparentTriangles(); + static void RenderSky(); + static void RenderFog(bool bRender); + static void Cleanup(); + + static void ChangeSkyTexture(const char* NewTexture); + static void ChangeTint(const Color4F &Color); + static void SetLightGamma(float Value); + + static float m_LightGamma; + static float m_MaxViewDistance; + + //Fog + struct fog_t + { + bool Enabled; + Vector Color; + float Density, Start, End; + int Type; + }; + static fog_t m_Fog; + static float GetFogFactor(const Vector &Origin); //1 = clear, 0 = fully fogged + static bool ApplyFogFade(cl_entity_s *pEnt); + + //OpenGL + static void PushHLStates(); + static void PopHLStates(); + static void RenderParticles(); + static bool LoadGLTexture(const char *FileName, unsigned int &TextureID); + static bool LoadGLTexture(const char *FileName, loadtex_t &LoadTex); + static void DeleteGLTextures(); + +private: + static void InitGL(); + + static int m_OldHLTexture[10]; + static bool m_OldMultiTextureEnabled; +}; diff --git a/src/game/client/render/clrender.cpp b/src/game/client/render/clrender.cpp index 125a2902d..cb5054e88 100644 --- a/src/game/client/render/clrender.cpp +++ b/src/game/client/render/clrender.cpp @@ -14,51 +14,20 @@ #include "entity_state.h" #include "cl_entity.h" #include "triangleapi.h" - +#include "const.h" #include "com_model.h" #include "studio.h" +#include "entity_state.h" #include "studio_util.h" #include "r_studioint.h" #include "ref_params.h" #include "mslogger.h" -//OGL -void DeleteGLTextures(); -#ifdef _WIN32 -PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = nullptr; -PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = nullptr; -#endif - -//Environment Manager -float CEnvMgr::m_LightGamma = 2.5; -float CEnvMgr::m_MaxViewDistance = 4096; -CEnvMgr::fog_t CEnvMgr::m_Fog = {false, Vector(0, 0, 0), 0.01, 0.01, 10000, GL_EXP}; - -//Half-life callback -#define DLLEXPORT EXPORT -extern "C" -{ - void DLLEXPORT HUD_DrawNormalTriangles(void); - void DLLEXPORT HUD_DrawTransparentTriangles(void); -}; - -//TWHL Project - Thothie JUN2010_22 - -extern engine_studio_api_t IEngineStudio; - -//PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL; -//PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL; - -//extern Vector g_ViewForward, g_ViewRight, g_ViewUp; -extern float v_ViewDist; -void VectorAngles(const float *forward, float *angles); -void VGUIImages_NewLevel(); - CParticle::CParticle() { m_Width = 0; m_Origin = g_vecZero; - m_Texture = nullptr; + m_Texture = NULL; m_Color = Color4F(1.0f, 1.0f, 1.0f, 1.0f); m_Brightness = 1.0f; m_DirForward = g_vecZero; @@ -89,6 +58,7 @@ void CParticle::BillBoard() m_DirRight = ViewMgr.Params->right; m_DirUp = ViewMgr.Params->up; } + bool CParticle::LoadTexture(const char* Name) { HLSPRITE Sprite = MSBitmap::GetSprite(Name); @@ -101,6 +71,7 @@ bool CParticle::LoadTexture(const char* Name) return true; } + void CParticle::Render() { //return; @@ -176,563 +147,3 @@ void CParticle::Render() gEngfuncs.pTriAPI->RenderMode(kRenderNormal); } - -struct skyface_t -{ - CParticle Face; - - //Vector Offset; -}; - -constexpr const char* SKYFILENAME_PREFIX = "gfx/env/"; -struct -{ - Vector Dir; //Dir the wall is facing. It gets scooted back in the opp. direction - const char* FileNameSuffix; - bool Rotate; -} g_SkyBoxInfo[6] = - { - {Vector(0, 180, 0), "ft", false}, - {Vector(0, 90, 0), "lf", false}, - {Vector(0, 0, 0), "bk", false}, - {Vector(0, 270, 0), "rt", false}, - {Vector(-90, 0, 0), "dn", false}, - {Vector(90, 0, 0), "up", true}, -}; - -class CSkyBox -{ -public: - msstring m_SkyName; - mslist Faces; - int m_uiNextTexIdx; - - CSkyBox() - { - m_uiNextTexIdx = 1; - m_SkyName = "g_morning"; - - for (unsigned int i = 0; i < 6; i++) - { - Faces.add(skyface_t()); - - CParticle &Face = Faces[i].Face; - Face.m_Color = Color4F(1, 1, 1, 1); - Face.m_Brightness = 1.0f; - } - } - - //Called once each level load - void Setup() //Be sure to call after EngineFunc stuff is valid - { - for (unsigned int i = 0; i < Faces.size(); i++) - { - CParticle &Face = Faces[i].Face; - Face.SetAngles(g_SkyBoxInfo[i].Dir); - if (g_SkyBoxInfo[i].Rotate) - { - Vector2D Tmp = Face.m_TexCoords[0]; - Face.m_TexCoords[0] = Vector2D(0, 0); - Face.m_TexCoords[1] = Vector2D(1, 0); - Face.m_TexCoords[2] = Vector2D(1, 1); - Face.m_TexCoords[3] = Vector2D(0, 1); - } - } - - ChangeTexture(m_SkyName); - } - - //Dynamic. Can change textures anytime - void ChangeTexture(const char* NewTexture) - { - m_SkyName = NewTexture; - for (unsigned int i = 0; i < Faces.size(); i++) - { - msstring FileName = /*msstring(EngineFunc::GetGameDir()) + "/" +*/ msstring(SKYFILENAME_PREFIX) + NewTexture + g_SkyBoxInfo[i].FileNameSuffix + ".tga"; - Faces[i].Face.m_GLTex = 0; - LoadGLTexture(FileName, Faces[i].Face.m_GLTex); - } - } - - void Render() - { - //if( MSGlobals::GameScript ) - // MSGlobals::GameScript->CallScriptEvent( "game_render_sky" ); - - for (unsigned int i = 0; i < Faces.size(); i++) - { - CParticle &Face = Faces[i].Face; - Face.m_Width = v_ViewDist - 1; - - Face.m_Origin = ViewMgr.Origin - Face.m_DirForward * Face.m_Width / 2.0f; - Face.m_ContinuedParticle = false; - Face.Render(); - } - } -}; - -CSkyBox g_CustomSkyBox; -CParticle g_Tint; - -void CEnvMgr::Init() -{ - m_MaxViewDistance = EngineFunc::CVAR_GetFloat("sv_zmax"); - g_CustomSkyBox.Setup(); - g_Tint.m_Color = Color4F(0, 0, 0, 0); -} - -void CEnvMgr::InitNewLevel() -{ - CMirrorMgr::InitMirrors(); - VGUIImages_NewLevel(); - MS_INFO("[InitNewLevel Complete]"); -} - -void CEnvMgr::ChangeSkyTexture(const char* NewTexture) -{ - g_CustomSkyBox.ChangeTexture(NewTexture); - g_CustomSkyBox.Setup(); //Thothie DEC2014_02 - trying to make setenv sky.texture work. - g_CustomSkyBox.Render(); //Thothie DEC2014_02 - trying to make setenv sky.texture work. -} - -void CEnvMgr::RenderSky() -{ - g_CustomSkyBox.Render(); -} - -void Surface_ResetLighting(msurface_t *pSurface) -{ - pSurface->cached_dlight = 1; -} - -//Traverses all nodes and leafs, calling Func on each surface found -void TraverseAllNodes(mnode_t *pNode, void *Func) -{ - if (!pNode) - return; - - mnode_t &Node = *pNode; - - if (Node.contents == CONTENTS_SOLID) - return; - - if (Node.contents < 0) - { - //Call Function on Leaf - mleaf_t &Leaf = *(mleaf_t *)&Node; - for (unsigned int s = 0; s < Leaf.nummarksurfaces; s++) - (*(ParseAllSurfacesFunc *)Func)(Leaf.firstmarksurface[s]); - return; - } - - for (unsigned int i = 0; i < 2; i++) - TraverseAllNodes(Node.children[i], Func); -} - -void CEnvMgr::SetLightGamma(float Value) -{ - m_LightGamma = Value; - EngineFunc::CVAR_SetFloat("lightgamma", m_LightGamma); - - TraverseAllNodes(gEngfuncs.GetEntityByIndex(0)->model->nodes, Surface_ResetLighting); -} - -void CEnvMgr::ChangeTint(const Color4F &Color) -{ - g_Tint.m_ContinuedParticle = false; - g_Tint.m_DoubleSided = false; - g_Tint.m_Color = Color; - g_Tint.m_Brightness = 0.0f; - g_Tint.m_Width = 500; - g_Tint.m_RenderMode = kRenderTransAlpha; -} - -//Draw transparent stuff -void CEnvMgr::Think_DrawTransparentTriangles() -{ - bool HideTint = CMirrorMgr::m_CurrentMirror.Enabled //Hide while rendering in mirror - || MSCLGlobals::CharPanelActive || //Hide while choosing character - !g_Tint.m_Color.a; //Hide if alpha is zero - - if (!HideTint) - { - g_Tint.m_Origin = ViewMgr.Params->vieworg + ViewMgr.Params->forward * 4.2; - g_Tint.BillBoard(); - g_Tint.Render(); - } -} -void CEnvMgr::Cleanup() -{ - //Unload all OGL Textures (skybox) - DeleteGLTextures(); //Thothie JAN2011_03, restore texture cleanup -} - -/* -================= -HUD_DrawNormalTriangles - -Non-transparent triangles-- add them here -================= -*/ - -void ModifyLevel(); -void RenderFog( bool bRender ); -bool FindSkyHeight(Vector Origin, float &SkyHeight); -bool UnderSky(Vector Origin); //Thothie AUG2010_03 -int OldVisFrame = -1; -int OldContents = CONTENTS_EMPTY; -//void Mirror_MirrorVisibleSurfaces( ); -//void Mirror_UnMirrorVisibleSurfaces( ); - -int CRender::m_OldHLTexture[10] = {0}; -bool CRender::m_OldMultiTextureEnabled = false; -float CRender::m_RT_SizeRatio = 1.0f; -uint CRender::m_RT_Width = 256; -uint CRender::m_RT_Height = 256; -float CRender::m_RT_TexU = 1.0f; -float CRender::m_RT_TexV = 1.0f; - -enum { - MS_GL_ATTRIBUTES = GL_ALL_ATTRIB_BITS -}; -//#define MS_GL_ATTRIBUTES - -void CRender::PushHLStates() -{ - if (!glActiveTextureARB) - return; - - glPushAttrib(MS_GL_ATTRIBUTES); - - glActiveTextureARB(GL_TEXTURE0_ARB); - glGetIntegerv(0x8069, &m_OldHLTexture[0]); //GL_TEXTURE_2D_BINDING = 0x8069 - - //Workaround - - //Half-life sometimes uses Texture1 to draw normal textures and other times Texture2 - //It just depends on where you're standing. Here I check whether HL is using Texture2, - //disable it, use texture1, then set it back to Texture2 when done - glActiveTextureARB(GL_TEXTURE1_ARB); - glGetIntegerv(0x8069, &m_OldHLTexture[1]); //GL_TEXTURE_2D_BINDING = 0x8069 - - m_OldMultiTextureEnabled = glIsEnabled(GL_TEXTURE_2D) ? true : false; - glDisable(GL_TEXTURE_2D); - - glActiveTextureARB(GL_TEXTURE0_ARB); - glEnable(GL_TEXTURE_2D); - - /*glEnable( GL_COLOR_MATERIAL ); - glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); - glColorMaterial( GL_FRONT, GL_EMISSION ); - glColorMaterial( GL_FRONT, GL_SPECULAR );*/ - - //--------------- - - /*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);*/ -} -void CRender::PopHLStates() -{ - if (!glActiveTextureARB) - return; - - //Part of the Texture1/Texture2 Workaround - //Set the active texture back to what HL was using before - //---------------------------------------- - glPopAttrib(); - - glActiveTextureARB(GL_TEXTURE1_ARB); - glBindTexture(GL_TEXTURE_2D, m_OldHLTexture[1]); - if (m_OldMultiTextureEnabled) - glEnable(GL_TEXTURE_2D); - else - glDisable(GL_TEXTURE_2D); - - glActiveTextureARB(GL_TEXTURE0_ARB); - glBindTexture(GL_TEXTURE_2D, m_OldHLTexture[0]); - - if (m_OldMultiTextureEnabled) - glActiveTextureARB(GL_TEXTURE1_ARB); - - //static float color[4] = { 0, 0, 0, 0 }; - //int Param = GL_MODULATE; - //glTexEnviv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &Param ); - //glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color ); - - //---------------------------------------- -} - -void DLLEXPORT HUD_DrawNormalTriangles(void) -{ - RenderFog( true ); - /*if( CMirrorMgr::m_CurrentMirror.Enabled - && OldVisFrame > -1 ) - { - cl_entity_t *clWorldEnt = gEngfuncs.GetEntityByIndex( 0 ); - if( clWorldEnt->model->nodes[0].visframe != 0 ) - { - //The world was marked to be hidden for this mirror, but was drawn - //The player changed leafs, and thus the world visframe was updated and the world drawn - - //The mirror will attempt to render *again* this frame. - //This is done by adding a copy of the mirror to the end of the RdrMirrors list. After the copy - //is done rendering, it is deleted - CMirror MirrorCopy; - CMirrorMgr::m_RdrMirrors.add( MirrorCopy ); - CMirrorMgr::m_CurrentMirror.Mirror = &CMirrorMgr::m_RdrMirrors[CMirrorMgr::m_CurrentMirror.Index]; //The pointer changed, because I re-allocated - MirrorCopy = *CMirrorMgr::m_CurrentMirror.Mirror; - MirrorCopy.Frame_NoRender = false; - MirrorCopy.Frame_IsCopy = true; - - //Don't render the current mirror this frame, since the world was drawn on top of it - CMirrorMgr::m_CurrentMirror.Mirror->Frame_NoRender = true; - } - }*/ -} - -/* -================= -HUD_DrawTransparentTriangles - -Render any triangles with transparent rendermode needs here -================= -*/ - -//Draw Mirrors -void DLLEXPORT HUD_DrawTransparentTriangles(void) -{ - CRender::PushHLStates(); - - RenderFog( false ); - CMirrorMgr::HUD_DrawTransparentTriangles(); - CEnvMgr::Think_DrawTransparentTriangles(); - gHUD.m_HUDScript->Effects_DrawTransPararentTriangles(); - - CRender::PopHLStates(); - - /*if( OldVisFrame > -1 ) - { - cl_entity_t *clWorldEnt = gEngfuncs.GetEntityByIndex( 0 ); - if( clWorldEnt->model->nodes[0].visframe == 0 ) - clWorldEnt->model->nodes[0].visframe = OldVisFrame; - }*/ -} - -void CRender::Cleanup() -{ - CleanupWGL(); - CEnvMgr::Cleanup(); - CMirrorMgr::Cleanup(); -} - -void RenderFog( bool bRender ) -{ - if ( CEnvMgr::m_Fog.Enabled ) - { - glEnable( GL_FOG ); - if ( bRender ) - glFogfv( GL_FOG_COLOR, CEnvMgr::m_Fog.Color ); - else - glFogfv( GL_FOG_COLOR, Vector( 0, 0, 0 ) ); - glFogi( GL_FOG_MODE, CEnvMgr::m_Fog.Type ); //GL_EXP, GL_LINEAR - glFogf( GL_FOG_DENSITY, CEnvMgr::m_Fog.Density ); - glFogf( GL_FOG_START, CEnvMgr::m_Fog.Start ); - glFogf( GL_FOG_END, CEnvMgr::m_Fog.End ); - } - else - glDisable( GL_FOG ); - - // Required for transparent crap, else they refuse to apply fog. Thank you engine. - gEngfuncs.pTriAPI->Fog( bRender ? CEnvMgr::m_Fog.Color : Vector( 0, 0, 0 ), CEnvMgr::m_Fog.Start, CEnvMgr::m_Fog.End, CEnvMgr::m_Fog.Enabled ); -} - -//VGUI_Image3D - 3D HUD Sprite -//============ -#include "vgui_teamfortressviewport.h" -#include "ms/vgui_mscontrols.h" - -mslist g_VGUIImages; -void VGUIImages_NewLevel() -{ - //Reload the TGA textures for the 3D VGUI Images - for (unsigned int i = 0; i < g_VGUIImages.size(); i++) - { - if (g_VGUIImages[i]->m_TGAorSprite) - { - g_VGUIImages[i]->m_ImageLoaded = false; - g_VGUIImages[i]->LoadImg(); - } - } - MS_INFO("[VGUIImages_NewLevel Complete]"); -} - -VGUI_Image3D::VGUI_Image3D(const char *pszImageName, bool TGAorSprite, bool Delayed, int x, int y, int wide, int tall) - : CImageDelayed(pszImageName, TGAorSprite, Delayed, x, y, wide, tall) -{ - init(); -} -void VGUI_Image3D::init() -{ - m_Particle = new CParticle(); - m_Particle->m_ContinuedParticle = false; - m_Particle->m_DoubleSided = true; - m_Particle->m_Color = Color4F(1, 1, 1, 1); - m_Particle->m_Brightness = 1.0f; - m_Particle->m_Square = false; - m_Particle->m_RenderMode = kRenderTransAlpha; - g_VGUIImages.add(this); -} - -void VGUI_Image3D::LoadImg() -{ - if (m_ImageLoaded) - return; - - if (!m_Particle) - return; - - if (m_TGAorSprite) - { - msstring FileName = msstring("gfx/vgui/") + m_ImageName + ".tga"; - - loadtex_t LoadTex; - m_ImageLoaded = LoadGLTexture(FileName, LoadTex); - if (m_ImageLoaded) - { - m_Particle->m_GLTex = LoadTex.GLTexureID; - m_Particle->m_TexCoords[0] = Vector2D(LoadTex.CoordU, 0); - m_Particle->m_TexCoords[1] = Vector2D(LoadTex.CoordU, LoadTex.CoordV); - m_Particle->m_TexCoords[2] = Vector2D(0, LoadTex.CoordV); - m_Particle->m_TexCoords[3] = Vector2D(0, 0); - } - } - else - { - CImageDelayed::LoadImg(); - m_Particle->m_Texture = (model_s *)gEngfuncs.GetSpritePointer(m_SpriteHandle); - m_ImageLoaded = m_Particle->m_Texture ? true : false; - } -} -void VGUI_Image3D::paintBackground() -{ - if (!m_ImageLoaded) - return; - - if (!m_Particle) - return; - - CRender::PushHLStates(); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - //m_Particle->BillBoard(); - m_Particle->m_Width = getWide(); - m_Particle->m_Height = getTall(); - m_Particle->m_SpriteFrame = m_Frame; - m_Particle->m_DirForward = Vector(0, 0, 1); - float VerticalMultiplier = m_TGAorSprite ? -1 : 1; - m_Particle->m_DirRight = Vector(-1, 0, 0); - m_Particle->m_DirUp = Vector(0, 1 * VerticalMultiplier, 0); //m_DirUp is actually pointing down here - m_Particle->m_Origin = (-m_Particle->m_DirRight * m_Particle->m_Width / 2.0f) + (m_Particle->m_DirUp * VerticalMultiplier * m_Particle->m_Height / 2.0f); - m_Particle->Render(); - - CRender::PopHLStates(); -} - -VGUI_Image3D::~VGUI_Image3D() -{ - for (unsigned int i = 0; i < g_VGUIImages.size(); i++) - if (g_VGUIImages[i] == this) - { - g_VGUIImages.erase(i); - break; - } -} - -//MS OGL extention stuff - -struct gltexture_t : loadtex_t -{ - msstring Name; -}; -mslist g_TextureList; - -bool LoadGLTexture(const char *FileName, loadtex_t &LoadTex) -{ - bool Loaded = false; - - for (unsigned int i = 0; i < g_TextureList.size(); i++) - { - if (g_TextureList[i].Name == FileName) - { - LoadTex = (loadtex_t)g_TextureList[i]; - return true; - } - } - - Loaded = Tartan::LoadTextureFile(FileName, LoadTex); - - if (Loaded) - { - gltexture_t Newtexture; - loadtex_t < = Newtexture; - LT = LoadTex; - Newtexture.Name = FileName; - g_TextureList.add(Newtexture); - } - else - { - Print("Missing MS Texture: %s\n", FileName); - } - - return Loaded; -} - -bool LoadGLTexture(const char *FileName, uint &TextureID) -{ - loadtex_t LoadTex; - bool Success = LoadGLTexture(FileName, LoadTex); - if (Success) - TextureID = LoadTex.GLTexureID; - - return Success; -} - -void DeleteGLTextures() -{ - for (unsigned int i = 0; i < g_TextureList.size(); i++) - glDeleteTextures(1, &g_TextureList[i].GLTexureID); - g_TextureList.clear(); -} - -/*void DeleteGLTexure( int &TextureID ) -{ - glDeleteTextures( 1, &TextureID ); -}*/ - -void GetCompatibleTextureSize(uint SizeW, uint SizeH, uint &outNewSizeW, uint &outNewSizeH, float &outTexCoordU, float &outTexCoordV) -{ - //Force the texture to have dimensions 2^X - float LargestDimension = SizeW > SizeH ? SizeW : SizeH; - float Power = logf(LargestDimension) / logf(2); - int IntPower = (int)Power; - if (Power > IntPower) - IntPower++; //Dimension is in-between standardized texure sizes. Use the next highest size - float TexSize = pow(2, (int)IntPower); - - //Cap texure size at GL_MAX_TEXTURE_SIZE - int TexSizeMax = 0; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &TexSizeMax); - if (TexSize > TexSizeMax) - TexSize = (float)TexSizeMax; - - outNewSizeW = outNewSizeH = TexSize; - outTexCoordU = SizeW / (float)outNewSizeW; - outTexCoordV = SizeH / (float)outNewSizeH; -} diff --git a/src/game/client/render/clrender.h b/src/game/client/render/clrender.h index f566a2b0f..86459570c 100644 --- a/src/game/client/render/clrender.h +++ b/src/game/client/render/clrender.h @@ -1,41 +1,37 @@ //curstate.oldbuttons - - -enum { - MSRDR_VIEWMODEL = (1 << 0), //Model is a view model (parent view model... never rendered fully) - MSRDR_FLIPPED = (1 << 1), //Model is flipped across the verical axis, changing it from the right to left hand - MSRDR_SKIP = (1 << 2), //Do all setup (for attachments later), but don't render - MSRDR_NOREFLECT = (1 << 3), //Don't render to mirrors - MSRDR_FULLROT = (1 << 4), //Use full rotation this frame (automatically unset in ) - - //Separate flags from the above -- stored in curstate.colormap - MSRDR_GLOW_GRN = (1 << 0), //Green glow - MSRDR_GLOW_RED = (1 << 1), //Highlight slected weapons - Red Glow - MSRDR_DARK = (1 << 2), //Dim lights on the inset player model - MSRDR_LIGHT_DIM = (1 << 3), - MSRDR_LIGHT_NORMAL = (1 << 4), //Give a moderate amount of artificial light - MSRDR_LIGHT_BRIGHT = (1 << 5), //Make it fullbright - MSRDR_ANIM_ONCE = (1 << 6), //Only play the client-side anim once (no loop) - MSRDR_ASPLAYER = (1 << 7), //Render as player - MSRDR_COPYPLAYER = (1 << 8), //Copy the local player's anims - MSRDR_HANDMODEL = (1 << 9), //This is one of the two hand models (coming off the viewmodel) - - //mouth.sndavg - MSRDR_HASEXTRA = (1 << 0) //The extra info is initialied -}; +#define MSRDR_VIEWMODEL (1 << 0) //Model is a view model (parent view model... never rendered fully) +#define MSRDR_FLIPPED (1 << 1) //Model is flipped across the verical axis, changing it from the right to left hand +#define MSRDR_SKIP (1 << 2) //Do all setup (for attachments later), but don't render +#define MSRDR_FULLROT (1 << 4) //Use full rotation this frame (automatically unset in ) + +//Separate flags from the above -- stored in curstate.colormap +#define MSRDR_GLOW_GRN (1 << 0) //Green glow +#define MSRDR_GLOW_RED (1 << 1) //Highlight slected weapons - Red Glow +#define MSRDR_DARK (1 << 2) //Dim lights on the inset player model +#define MSRDR_LIGHT_DIM (1 << 3) +#define MSRDR_LIGHT_NORMAL (1 << 4) //Give a moderate amount of artificial light +#define MSRDR_LIGHT_BRIGHT (1 << 5) //Make it fullbright +#define MSRDR_ANIM_ONCE (1 << 6) //Only play the client-side anim once (no loop) +#define MSRDR_ASPLAYER (1 << 7) //Render as player +#define MSRDR_COPYPLAYER (1 << 8) //Copy the local player's anims +#define MSRDR_HANDMODEL (1 << 9) //This is one of the two hand models (coming off the viewmodel) +#define MSRDR_DRAWLATE (1 << 10) //Hand model was queued as transparent so it gets drawn late. It's really kRenderNormal + +//mouth.sndavg +#define MSRDR_HASEXTRA (1 << 0) //The extra info is initialied //Specifics -constexpr float INSET_SCALE = 0.026f; //0.02f -enum { - ANIM_RUN = 11, - ANIM_CROUCH = 0, - ANIM_CRAWL = 1, - ANIM_SIT = 19, - ANIM_ATTENTION = 4, - ANIM_DEEPIDLE = 5, - ANIM_JUMP = 6 -}; +#define INSET_SCALE 0.026f //0.02f +#define ANIM_RUN 11 +#define ANIM_CROUCH 0 +#define ANIM_CRAWL 1 +#define ANIM_SIT 19 +#define ANIM_ATTENTION 4 +#define ANIM_DEEPIDLE 5 +#define ANIM_JUMP 6 +#define ANIM_SIT 19 + typedef struct msurface_s msurface_t; typedef struct decal_s decal_t; @@ -105,16 +101,6 @@ class CRenderPlayerInset : public CRenderPlayer cl_entity_t &GearItemEntity(CGenericItem &Item) { return Item.m_ClEntity[CGenericItem::ITEMENT_3DINSET]; } }; -//Mirrors - -struct surfaceinfo_t -{ - //Vector Bounds[2]; - Vector Origin; - float Radius; - //struct mnode_s *ParentNode; //Parent node or leaf -}; - class Plane { public: @@ -140,7 +126,7 @@ class Plane bool BBoxIsInFront(Vector Bounds[2]) { Vector Point; - for (unsigned int i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { switch (i) { @@ -181,168 +167,14 @@ class Plane } }; -class CSurface -{ -public: - CSurface() { m_Surface = nullptr; } - CSurface(msurface_t *Surface) { m_Surface = Surface; } - void Draw(); - void DrawProjective(); - void DrawNormal(); - - enum - { - TEXCOORD_2D, - TEXCOORD_3D - } m_ModeTexCoord; - msurface_t *m_Surface; - - Vector m_Origin; - float m_Radius; - Vector Bounds[2]; - Vector m_SurfaceNormal; -}; - -enum { - RDR_TEXTURE = (1 << 0), - RDR_PROJECTIVE = (1 << 1), - RDR_ALPHATEST = (1 << 2), - RDR_STENCIL = (1 << 3), - RDR_CLRSTENCIL = (1 << 4), - RDR_CHKSTENCIL = (1 << 5), - RDR_CLEARZ = (1 << 6), - RDR_CLRALPHA = (1 << 7) -}; - -class CMirror -{ -public: - Vector Normal; - float Dist; - - Vector2D TexSize; //Size of the buffer'd texture. Must be 2^x to work on all cards - struct mstexture_t *m_Texture; //Custom Texture defined by script - - cl_entity_t *Entity; - //mslist Surfaces; //Mirror surfaces. Draw reflected texture here - mslist m_Surfaces; //Mirror surfaces. Draw reflected texture here - mslist SurfaceInfo; //Mirror surfaces extra info - mslist m_ChildMirrors; //Child mirrors seen while rendering mirrored world - CMirror *m_Parent; //For when reflecting Mirror within mirror - //mslist WorldSurfaces; //Pre-mirrored world Surfaces. Render these for an reflected world - - //bool RenderThisFrame; //Marked for rendering. Not occluded - uint GLBufferTexture; //Texture that the mirrored world is stored onto - uint GLIgnoreTexture; //Ignore the original 'glass' texture. Replace with our own - bool IsWater, - m_OnWorld; //Mirror is a part of the world. don't look for it each frame. Keep it cached - int WaterRippleAmt; - float ChangeSpeed; - float TimeChangeSpeed; - float MirrorMatrix[4][4]; //Current mirror matrix - float Frame_ReflectMatrix[4][4]; //Reflect matrix temporarily used whenever this is a child mirror - Plane Frame_Plane; //Mirror plane for whenever this is a child mirror - bool Frame_NoRender; - bool Frame_IsCopy; - int Frame_ChildLevel; - Plane Frame_ClipPlane; - bool UseRenderOrigin; - Vector m_CustomRenderOrigin; - bool Vis_Eye(); //Check if the camera is facing the mirror and not behind it - bool Vis_Surface(); //Check if the camera is close enough to the mirror - //Vector Bounds; - - void RenderMirroredWorld(int RecurseCall = 0); - void EnableClippingPlane(bool); - void CreateMatrix(); - void ApplyTransformation(); - void BindTexture(); //Bind texture - void ReleaseTexture(); //Release offscreen texture - void SetCustomTextureSettings(bool Enable); //Change render settings, like blend, color, etc - void Draw(int Flags); - void SetStencil(); - void SetupLighting(); -}; - -struct mirrorprops_t -{ - int Index; //Mirror index - bool Enabled; //Enabled - CMirror *Mirror; //Mirror info -}; - -struct rendersurface_t -{ - CMirror *Mirror; - msurface_t *Surface; -}; - -class CMirrorMgr -{ -public: - static mslist m_MirrorTextures; //List of mirror textures in level - static mslist m_Mirrors; //List of mirrors in the level - static mslist m_RdrMirrors; //List of mirrors to render - static mslist m_WorldMirrors; //Static list of mirrors attached to the world. Cached at startup. - static mirrorprops_t m_CurrentMirror; //Current mirror being rendered. Enabled == false if none - static mslist m_BrushEnts; //List of brush entites found to be mirrored - static mslist m_FrameEnts; //List of entites found to be mirrored - static bool UseMirrors; //The system can support mirrors - static bool m_Initialized; //Mirrors have been found and marked - static struct mleaf_s *m_pStartLeaf; //The viewer's current leaf - static mslist m_RenderSurfaces; //List of special surfaces - static mslist m_WorldSurfaces; //List of special surfaces attached to world (cached for speed) - - static Vector m_OldOrg, m_OldAng; //Keep copy of view parameters - - static bool InitMirrors(); - static bool Enabled(); - static void MarkCustomTextures(); //Check all visible surfaces for custom textures - //static void MarkCustomTextures( cl_entity_t *pEntity, struct mnode_s *CurrNode ); //Traverse the main world entity for custom textures - //static void CheckSurface( cl_entity_t *pEntity, struct mnode_s *ParentNode, struct msurface_s *pSurface ); - - static void HUD_DrawTransparentTriangles(); - static void Render_SetupViewReflection(); - static bool Render_StudioModel(cl_entity_t *pEnt); - - static void SetupMirrorView(int MirrorNum); - static void SetupNormalView(); - static void SetupNextView(); - - static void Cleanup(); -}; -void RenderModel(cl_entity_t *pEntity); - - -enum { - - SURF_PLANEBACK = 2, - SURF_DRAWSKY = 4, - SURF_DRAWSPRITE = 8, - SURF_DRAWTURB = 0x10, - SURF_DRAWTILED = 0x20, - SURF_DRAWBACKGROUND = 0x40, - SURF_UNDERWATER = 0x80 - -}; - #include // Header File For The OpenGL32 Library #include -#ifdef _WIN32 -extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB; -extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; -#else // _WIN32 -#define glMultiTexCoord2fARB glMultiTexCoord2f -#define glActiveTextureARB glActiveTexture -#endif - #include "ref_params.h" struct viewmgr_t { Vector Origin, Angles, LastOrigin, LastAngles; - int Passes; ref_params_s *Params; }; extern viewmgr_t ViewMgr; @@ -368,28 +200,4 @@ class CParticle int m_SpriteFrame; }; -bool CheckBBox(Vector Bounds[2]); - -struct TraverseInfo_t -{ - cl_entity_t *pEntity; - struct mnode_s *pNode; - bool CheckFrustum; - bool CheckClipplane; - Plane ClipPlane; - void *Func; - - Vector Origin; - int VisFrame; - int RecurseCall; - class CMirror *Mirror; - struct model_s *pModel; - int TraverseAmt; - float MoveMatrix[4][4]; - float OrigProjectionMatrix[4][4]; - float OrigModelViewMatrix[4][4]; -}; -typedef bool ParseSurfaceFunc(TraverseInfo_t &Info, struct msurface_s *pSurface); typedef void ParseAllSurfacesFunc(struct msurface_s *pSurface); - -bool ParseVisibleSurfaces(TraverseInfo_t &Info, struct mleaf_s *pStartLeaf); diff --git a/src/game/client/render/clrenderent.cpp b/src/game/client/render/clrenderent.cpp index dd029cc8e..80b3e94a5 100644 --- a/src/game/client/render/clrenderent.cpp +++ b/src/game/client/render/clrenderent.cpp @@ -35,7 +35,7 @@ void Game_AddObjects(void) { g_FirstRender = true; - for (unsigned int i = 0; i < MSCLGlobals::m_ClModels.size(); i++) + for (int i = 0; i < MSCLGlobals::m_ClModels.size(); i++) { cl_entity_t &Entity = MSCLGlobals::m_ClModels[i]; CLFrameShowModel(Entity); @@ -206,7 +206,7 @@ void CBasePlayer::BeginRender() void CBasePlayer::Render() { - for (unsigned int i = 0; i < g_RenderEnts.size(); i++) + for (int i = 0; i < g_RenderEnts.size(); i++) g_RenderEnts[i]->Render(); } void CBasePlayer::RenderCleanup() @@ -214,8 +214,8 @@ void CBasePlayer::RenderCleanup() mslist RenderEntListCopy; RenderEntListCopy = g_RenderEnts; - unsigned int size = RenderEntListCopy.size(); - for (unsigned int i = 0; i < size; i++) + int size = RenderEntListCopy.size(); + for (int i = 0; i < size; i++) { CRenderEntity *pRdrEnt = RenderEntListCopy[i]; if (pRdrEnt->IsPermanent()) @@ -236,7 +236,7 @@ void CRenderEntity::Render() } void CRenderEntity::UnRegister() { - for (unsigned int i = 0; i < g_RenderEnts.size(); i++) + for (int i = 0; i < g_RenderEnts.size(); i++) if (g_RenderEnts[i] == this) { g_RenderEnts.erase(i--); @@ -261,7 +261,7 @@ void CRenderPlayer::Render() //m_Ent.origin and m_Ent.angles are calulated in V_CalcRefdef for precise accuracy. cl_entity_t &Ent = GetEntity(); - /* for (unsigned int i = 0; i < HUMAN_BODYPARTS; i++) + /* for (int i = 0; i < HUMAN_BODYPARTS; i++) { cl_entity_t &BPEnt = m_BodyParts[i]; BPEnt.SetModel( ModelList[i][m_Gender] ); @@ -282,10 +282,10 @@ void CRenderPlayer::Render() CRenderEntity::Render(); CItemList &Gear = GetGear(); - for (unsigned int i = 0; i < Gear.size(); i++) + for (int i = 0; i < Gear.size(); i++) RenderGearItem(*Gear[i]); - /* for (unsigned int i = 0; i < HUMAN_BODYPARTS; i++) + /* for (int i = 0; i < HUMAN_BODYPARTS; i++) { cl_entity_t &BPEnt = m_BodyParts[i]; if( BPEnt.curstate.number != 0 ) CLFrameShowModel( BPEnt ); @@ -312,7 +312,7 @@ void CRenderPlayer::RenderGearItem(CGenericItem &Item) // foreach( i, Item.m_WearModelPositions.size( ) ) // Ent.SetBody( Item.m_WearModelPositions[i], 1 ); - /* for (unsigned int i = 0; i < HUMAN_BODYPARTS; i++) + /* for (int i = 0; i < HUMAN_BODYPARTS; i++) { cl_entity_t &BPEnt = m_BodyParts[i]; int PlayerBody = Item.Armor_GetBody( i ); @@ -375,11 +375,11 @@ void CRenderPlayerInset::Render() //m_Ent.index = clplayer->index; //m_Ent.curstate.number = clplayer->index; - /* for (unsigned int i = 0; i < 4; i++) + /* for (int i = 0; i < 4; i++) m_Ent.latched.prevcontroller[i] = m_Ent.curstate.controller[i] = 127; m_Ent.curstate.gaitsequence = 0; m_Ent.curstate.framerate = 1; - for (unsigned int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) m_Ent.attachment[i] = clplayer->attachment[i]; ClearBits( m_Ent.curstate.colormap, MSRDR_ANIM_ONCE ); @@ -410,7 +410,6 @@ void CRenderPlayerInset::Render() else m_Ent.curstate.sequence = 2; //Default Idle*/ SetBits(m_Ent.curstate.colormap, MSRDR_ASPLAYER | MSRDR_COPYPLAYER | MSRDR_GLOW_RED); - SetBits(m_Ent.curstate.oldbuttons, MSRDR_NOREFLECT); CRenderPlayer::Render(); //Thothie JAN2010_12 - commenting this out to play nice with new ref model @@ -432,7 +431,6 @@ void CRenderPlayerInset::RenderGearItem(CGenericItem &Item) ItemEnt.curstate.scale = INSET_SCALE; - SetBits(ItemEnt.curstate.oldbuttons, MSRDR_NOREFLECT); SetBits(ItemEnt.curstate.colormap, MSRDR_GLOW_RED); if (Item.m_Location == ITEMPOS_HANDS && player.m_CurrentHand == Item.m_Hand) { diff --git a/src/game/client/render/clrendermirror.cpp b/src/game/client/render/clrendermirror.cpp deleted file mode 100644 index 615d9ee76..000000000 --- a/src/game/client/render/clrendermirror.cpp +++ /dev/null @@ -1,1650 +0,0 @@ - -//Render mirrors -#include "inc_weapondefs.h" -#include "../hud.h" -#include "../cl_util.h" -#include "com_model.h" -#include "studio.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "dlight.h" -#include "triangleapi.h" -#include "studio_util.h" -#include "../r_studioint.h" -#include "studiomodelrenderer.h" -#include "gamestudiomodelrenderer.h" -#include "pm_movevars.h" -#include "opengl/clopengl.h" // OpenGL stuff - -void VectorAngles(const float *forward, float *angles); -void GenerateInverseMatrix4f(const float inMatrix[4][4], float outInverse[4][4]); - -//#include "r_efx.h" -#include "entity_types.h" -#include "clglobal.h" -#include "clrender.h" - -#include "hudmisc.h" -extern CGameStudioModelRenderer g_StudioRenderer; -extern float ClFOV; - -mleaf_t *FindLeaf(Vector &Origin, mnode_t *pNode); -bool CheckSurface(TraverseInfo_t &Info, msurface_t *pSurface); -bool IsLeafVisible(cl_entity_t *pEntity, mleaf_t *pStartLeaf, mleaf_t *pSearchLeaf); -bool IsLeafVisible(cl_entity_t *pEntity, mnode_t *pNode, mleaf_t *pSearchLeaf); -bool IsBoundsVisible(cl_entity_t *pEntity, mleaf_t *pStartLeaf, Vector Bounds[2]); -bool Mirror_DrawSurface(TraverseInfo_t &Info, msurface_t *pSurface); -void MirrorPoint(Vector &OrigPoint, Plane &Plane, Vector &MirroredPoint) -{ - float Dist = Plane.GetDist(OrigPoint); - MirroredPoint = OrigPoint + ((-Plane.m_Normal) * (Dist * 2)); -} - -mslist CMirrorMgr::m_MirrorTextures; //List of mirror textures in level -mslist CMirrorMgr::m_Mirrors; //List of mirrors in the level -mslist CMirrorMgr::m_RdrMirrors; //List of mirrors to render this frame -mslist CMirrorMgr::m_WorldMirrors; //List of mirrors attached to the world -mslist CMirrorMgr::m_RenderSurfaces; //List of special surfaces -mslist CMirrorMgr::m_WorldSurfaces; //List of special surfaces attached to world (cached for speed) -mirrorprops_t CMirrorMgr::m_CurrentMirror; -mslist CMirrorMgr::m_BrushEnts; //List of brush entites found to be mirrored -mslist CMirrorMgr::m_FrameEnts; //List of entites found to be mirrored -bool CMirrorMgr::UseMirrors = false; -bool CMirrorMgr::m_Initialized = false; -struct mleaf_s *CMirrorMgr::m_pStartLeaf; //The viewer's current leaf -extern int OldVisFrame, OldContents; - -//#define DEBUG_MIRRORS //Enable viewing mirrors at world origin -//#define MIRROR_STENCIL_MASK 0x3 -constexpr unsigned int MIRROR_STENCIL_MASK = 0xFFFFFFFF; - -class CFrustum -{ -public: - Vector m_Forward, m_Right, m_Up; - Plane Planes[6]; - - void Update() - { - float FOV = gHUD.m_iFOV ? ((float)gHUD.m_iFOV / 2.0f) : 45; - float RightPlaneYaw = FOV; - float UpPlanePitch = FOV; - for (unsigned int i = 0; i < 6; i++) - { - Plane &plane = Planes[i]; - switch (i) - { - case 0: //Near plane - plane.m_Normal = ViewMgr.Params->forward; - plane.m_Dist = DotProduct(ViewMgr.Origin, plane.m_Normal); - break; - case 1: //Far plane - { - plane.m_Normal = -ViewMgr.Params->forward; - Vector Spot = ViewMgr.Origin + ViewMgr.Params->forward * ViewMgr.Params->movevars->zmax; - plane.m_Dist = DotProduct(Spot, plane.m_Normal); - break; - } - case 2: //Right plane - { - Vector Forward; - Vector NewAng = ViewMgr.Angles + Vector(0, RightPlaneYaw, 0); - EngineFunc::MakeVectors(NewAng, &Forward); - plane.m_Normal = Forward; - plane.m_Dist = DotProduct(ViewMgr.Origin, plane.m_Normal); - break; - } - case 3: //Left plane - { - Vector Forward; - Vector NewAng = ViewMgr.Angles + Vector(0, -RightPlaneYaw, 0); - EngineFunc::MakeVectors(NewAng, &Forward); - plane.m_Normal = Forward; - plane.m_Dist = DotProduct(ViewMgr.Origin, plane.m_Normal); - break; - } - case 4: //Top plane - { - Vector Forward; - Vector NewAng = ViewMgr.Angles + Vector(-UpPlanePitch, 0, 0); - EngineFunc::MakeVectors(NewAng, &Forward); - plane.m_Normal = Forward; - plane.m_Dist = DotProduct(ViewMgr.Origin, plane.m_Normal); - break; - } - case 5: //Bottom plane - { - Vector Forward; - Vector NewAng = ViewMgr.Angles + Vector(UpPlanePitch, 0, 0); - EngineFunc::MakeVectors(NewAng, &Forward); - plane.m_Normal = Forward; - plane.m_Dist = DotProduct(ViewMgr.Origin, plane.m_Normal); - break; - } - } - } - } - - bool IsBBoxVisible(Vector Bounds[2]) - { - for (unsigned int i = 0; i < 6; i++) - { - Plane &plane = Planes[i]; - if (!plane.BBoxIsInFront(Bounds)) - return false; - } - - return true; - } -} Frustum; - -bool CheckBBox(Vector Bounds[2]) -{ - return Frustum.IsBBoxVisible(Bounds); -} - -void CMirrorMgr::Cleanup() -{ - //Clear out old mirror data - for (unsigned int m = 0; m < CMirrorMgr::m_MirrorTextures.size(); m++) - { - //CMirror &Mirror = CMirrorMgr::m_LevelMirrors[m]; - glDeleteTextures(1, &m_MirrorTextures[m]); - } - - CMirrorMgr::m_MirrorTextures.clearitems(); - CMirrorMgr::m_Mirrors.clearitems(); - CMirrorMgr::m_RdrMirrors.clearitems(); - CMirrorMgr::m_CurrentMirror.Enabled = false; - - MSCLGlobals::Textures.clear(); -} - -bool CheckSurface(TraverseInfo_t &Info, msurface_t *pSurface) -{ - //if( !FBitSet(pSurface->flags,(1<<8)) ) - // return; - - cl_entity_t *pEntity = Info.pEntity; - - //Frontside Visiblity check - msurface_t &Surface = *pSurface; - float PlaneMutliplier = (FBitSet(Surface.flags, SURF_PLANEBACK) ? -1 : 1); - - Vector SurfaceNormal = Surface.plane->normal * PlaneMutliplier; - float SurfaceDist = Surface.plane->dist * PlaneMutliplier; - - //!!! TEST TEST TEST !!!! - /*if( SurfaceNormal.z != 1 ) - return false; - if( Surface.plane->dist != -64 ) - return false;*/ - - mstexture_t *pCustomTexture = nullptr; - for (unsigned int t = 0; t < MSCLGlobals::Textures.size(); t++) - { - mstexture_t &MSTexture = MSCLGlobals::Textures[t]; - - // if( Surface.texinfo->texture->name[0] == '!' ) - - if (!_stricmp(MSTexture.Name, Surface.texinfo->texture->name)) //Case in-sensitive compare for the texture name - { - pCustomTexture = &MSCLGlobals::Textures[t]; - break; - } - } - - if (!pCustomTexture) - return false; //This surface is not a custom texture - - mstexture_t &CustomTexture = *pCustomTexture; - - if (CustomTexture.IsReflective) - { - CMirror *pUseMirror = NULL; - - for (unsigned int m = 0; m < CMirrorMgr::m_Mirrors.size(); m++) - { - CMirror &Mirror = CMirrorMgr::m_Mirrors[m]; - if (Mirror.Normal == SurfaceNormal && - Mirror.Dist == SurfaceDist) - { - pUseMirror = &CMirrorMgr::m_Mirrors[m]; - break; - } - } - - surfaceinfo_t SurfInfo; - Vector Bounds[2]; - Bounds[0] = Vector(9999999.9f, 9999999.9f, 9999999.9f); - Bounds[1] = Vector(-9999999.9f, -9999999.9f, -9999999.9f); - float *Vertex = Surface.polys->verts[0]; - for (int t = 0; t < Surface.polys->numverts; t++, Vertex += VERTEXSIZE) - { - Vector Vert = Vector(Vertex); - for (unsigned int i = 0; i < 3; i++) - { - if (Vert[i] < Bounds[0][i]) - Bounds[0][i] = Vert[i]; - if (Vert[i] > Bounds[1][i]) - Bounds[1][i] = Vert[i]; - } - } - - SurfInfo.Origin = (Bounds[0] + Bounds[1]) * 0.5f; - SurfInfo.Radius = (Bounds[1] - Bounds[0]).Length(); - //float Dist = (SurfInfo.Origin - ViewMgr.Origin).Length( ); - //if( Dist > (SurfInfo.Radius + pCustomTexture->Mirror.Range) ) - // return false; - - if (!pUseMirror) - { - //Create new mirror - //A mirror can extend across multiple faces - even faces across the level, - //as long as they have the same plane and dist - CMirror TmpMirror; - pUseMirror = &CMirrorMgr::m_Mirrors.add(TmpMirror); - memset(pUseMirror, 0, sizeof(CMirror)); - - int MirrorNum = CMirrorMgr::m_Mirrors.size() - 1; - if (MirrorNum < (signed)CMirrorMgr::m_MirrorTextures.size()) - pUseMirror->GLBufferTexture = CMirrorMgr::m_MirrorTextures[MirrorNum]; //Re-use old Buffer texture - else - { - glGenTextures(1, (GLuint *)&pUseMirror->GLBufferTexture); // Create a new Buffer Texture - glBindTexture(GL_TEXTURE_2D, pUseMirror->GLBufferTexture); - // glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, CRender::m_RT_Width, CRender::m_RT_Height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0 ); - // glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, CRender::m_RT_Width, CRender::m_RT_Height, 0, GL_RGBA, GL_FLOAT, 0 ); - //glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, CRender::m_RT_Width, CRender::m_RT_Height, 0, GL_RGB, GL_FLOAT, 0 ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - CMirrorMgr::m_MirrorTextures.add(pUseMirror->GLBufferTexture); - } - - pUseMirror->m_Texture = pCustomTexture; - pUseMirror->IsWater = false; - pUseMirror->Normal = SurfaceNormal; - pUseMirror->Dist = SurfaceDist; - pUseMirror->GLIgnoreTexture = Surface.texinfo->texture->gl_texturenum; - pUseMirror->m_OnWorld = !Info.pEntity->index ? true : false; - //Surface.texinfo->texture->gl_texturenum = 0; - //The texture must have dimensions 2^X - float Power = logf(ScreenWidth()) / logf(2); //Use ScreenHeight() because it's smaller than width - int IntPower = (int)Power; - if (Power > IntPower) - IntPower++; //Screen Width is in-between standardized texure sizes. Use the next highest size - float TexSize = pow(2, (int)IntPower); - - //Cap texure size at GL_MAX_TEXTURE_SIZE - int TexSizeMax = 0; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &TexSizeMax); - if (TexSizeMax < TexSize) - TexSize = (float)TexSizeMax; - - pUseMirror->TexSize.x = pUseMirror->TexSize.y = TexSize; - - //logfile << "Mirror #" << CMirrorMgr::m_LevelMirrors.size() << " - Screen: " << ScreenWidth() << "x" << ScreenHeight() << " Power: " << Power << " (" << IntPower << ")" << endl; - //logfile << "Mirror #" << CMirrorMgr::m_LevelMirrors.size() << " - Size: " << pUseMirror->TexSize.x << "x" << pUseMirror->TexSize.y << " Max: " << TexSizeMax << "x" << TexSizeMax << endl; - - pUseMirror->CreateMatrix(); - } - - //Add this surface to the mirror - CMirror &Mirror = *pUseMirror; - - Mirror.Entity = pEntity; - SetBits(Surface.flags, (1 << 8)); - - CSurface NewSurface(pSurface); - NewSurface.Bounds[0] = Bounds[0]; - NewSurface.Bounds[1] = Bounds[1]; - NewSurface.m_Origin = SurfInfo.Origin; - //NewSurface.ParentNode = Info.pNode->parent; - NewSurface.m_Radius = SurfInfo.Radius; - - Mirror.m_Surfaces.add(NewSurface); - - //surfaceinfo_t &SurfInfo = Mirror.SurfaceInfo.add( surfaceinfo_t() ); - } - - return true; -} - -bool CMirrorMgr::Enabled() -{ - return UseMirrors && EngineFunc::CVAR_GetFloat("ms_reflect"); -} - -void CMirrorMgr::MarkCustomTextures() -{ - m_RdrMirrors.clearitems(); //Reset visble mirrors - m_FrameEnts.clearitems(); //Reset entites marked for rendering last frame - - static float TimeLastUpdate = 0; - if (gpGlobals->time > TimeLastUpdate && (gpGlobals->time - TimeLastUpdate) < 0.5f) //OPTIMIZATION: Only check for new brushes and mirros every now and then - return; - - TimeLastUpdate = gpGlobals->time; - - //Find and mark any mirrors in the level for later rendering - m_RenderSurfaces.clearitems(); //Reset surfaces - m_Mirrors.clearitems(); //Reset mirrors - m_BrushEnts.clearitems(); //Reset mirrored brush entities - //m_FrameEnts.clearitems( ); //Reset mirrored entities - - bool SearchWorld = !m_Initialized; - - if (!gEngfuncs.GetEntityByIndex(0)) - return; //No world yet... keep trying until there is one - - if (!UseMirrors) - return; - - //Search through all visible faces looking for custom textures - cl_entity_t &WorldEntity = *gEngfuncs.GetEntityByIndex(0); - m_pStartLeaf = FindLeaf(ViewMgr.Origin, WorldEntity.model->nodes); - TraverseInfo_t Info; - //Info.CheckFrustum = true; - Info.CheckFrustum = false; - Info.CheckClipplane = false; - Info.Func = CheckSurface; - - if (!m_pStartLeaf || m_pStartLeaf->contents == CONTENTS_SOLID) - return; - - for (unsigned int e = 0; e < ViewMgr.Params->max_entities; e++) //MAX_MAP_MODELS - { - cl_entity_t *pEntity = gEngfuncs.GetEntityByIndex(e); - if (!pEntity || !pEntity->model) - continue; - - model_t &Model = *pEntity->model; - if (Model.type != mod_brush) - continue; - - cl_entity_t &Ent = *pEntity; - Info.pEntity = pEntity; - - if (!Model.firstmodelsurface) - { - if (SearchWorld) - { - //This is the main world model. Traverse the BSP tree to mark textures - ParseVisibleSurfaces(Info, m_pStartLeaf); - } - else if (!e) - { - //This is being called on a frame basis. Don't search the world, just check cached level mirrors - - //Find any cached mirrors with at least one surface close enough to the camera - for (unsigned int wm = 0; wm < m_WorldMirrors.size(); wm++) - { - CMirror &Mirror = m_WorldMirrors[wm]; - - if (!Mirror.Vis_Surface()) - continue; - - m_Mirrors.add(m_WorldMirrors[wm]); - } - - //m_Mirrors = m_WorldMirrors; - } - - m_BrushEnts.add(pEntity); - } - else if (!SearchWorld) - { - //if( (pEntity->curstate.rendermode == kRenderTransAlpha - // ||pEntity->curstate.rendermode == kRenderTransTexture ) - // && !pEntity->curstate.renderamt ) - // continue; - - if (FBitSet(pEntity->curstate.effects, EF_NODRAW)) - continue; - - //Brush only has to be potientially visible to be drawn in the mirrored world - m_BrushEnts.add(pEntity); - - //Now check the view frustum to see if any mirrors on this brush should be drawn - Vector Bounds[2] = {pEntity->origin + pEntity->model->mins, pEntity->origin + pEntity->model->maxs}; - if (!CheckBBox(Bounds)) - continue; - - //Success = false; - for (unsigned int s = 0; s < Model.nummodelsurfaces; s++) - CheckSurface(Info, &Model.surfaces[Model.firstmodelsurface + s]); - } - } - - //Store a lookup table. - //Surface --> mirror, So I can find child mirrors by the surface - for (unsigned int i = 0; i < m_Mirrors.size(); i++) - { - CMirror &Mirror = m_Mirrors[i]; - for (unsigned int s = 0; s < Mirror.m_Surfaces.size(); s++) - { - rendersurface_t RendSurface; - RendSurface.Mirror = &m_Mirrors[i]; - RendSurface.Surface = Mirror.m_Surfaces[i].m_Surface; - m_RenderSurfaces.add(RendSurface); - } - } - - if (SearchWorld) - { - m_WorldMirrors = m_Mirrors; //This is the first call since a level change. Save the mirrors - m_WorldSurfaces = m_RenderSurfaces; //and surfaces found in the level geometry. Just cache them for runtime - } - - m_Initialized = true; -} - -void CMirrorMgr::Render_SetupViewReflection() -{ - //UNDONE - NICEST is too slow for a simple mirror reflection. Use it for drawing the main world - //glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Really Nice Perspective Calculations - - if (!ViewMgr.Passes) //It's the first view... rendering the normal world - { - - //Find visible mirrors - //The first time this is called in a level, it finds world mirrors only and caches them - //After that (m_Initialized), it starts with the cached list and adds on dynamic mirrors (found in visible brush ents) - if (Enabled()) - { - Frustum.Update(); - } - - MarkCustomTextures(); - - //Reset mirrors to be drawn this frame - - //Do vis checks on mirrors - if (Enabled() && m_Mirrors.size()) - { - // cl_entity_t &WorldEntity = *gEngfuncs.GetEntityByIndex( 0 ); - - for (unsigned int i = 0; i < m_Mirrors.size(); i++) - { - CMirror &Mirror = m_Mirrors[i]; - - Mirror.Frame_Plane = Plane(Mirror.Normal, Mirror.Dist); - - if (!Mirror.Vis_Eye()) - continue; - - /*if( Mirror.Entity ) - { - Vector Bounds[2] = { Mirror.Entity->model->mins, Mirror.Entity->model->maxs }; - bool Success = IsBoundsVisible( &WorldEntity, m_pStartLeaf, Bounds ); - if( !Success ) - continue; - }*/ - - m_RdrMirrors.add(&m_Mirrors[i]); - } - } - - static bool dbg_on = false; - if (CVAR_GET_FLOAT("ms_reflect_dbg")) - { - dbg_on = true; - dbgtxt(msstring("Mirrors Rendered: ") + (int)m_RdrMirrors.size()); - } - else if (dbg_on) - { - dbg_on = false; - dbgtxt(""); - } - - m_CurrentMirror.Index = 0; - SetupNormalView(); //Done rendering mirrors, next, render the normal view - } - else if (ViewMgr.Passes == 1) - { - //Finished normal view. Start rendering mirrors - SetupMirrorView(0); - } - else - { - //Finished rendering mirror. Save screen into a texture for rendering later - - // CMirror &Mirror = m_RdrMirrors[CMirrorMgr::m_CurrentMirror.Index]; - - /*if( !Mirror.Frame_NoRender ) - { - CRender::PushHLStates( ); - - Mirror.BindTexture( ); //Sets the texture with the copy of the mirrored screen - - ///NOTE!!!! - glCopyTexImage2D must use texture sizes 2^x. And older cards will clamp negative start coords - - glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, Mirror.TexSize.x, Mirror.TexSize.y, 0 ); - //glClear( GL_DEPTH_BUFFER_BIT ); - - //glClear( GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT|GL_ACCUM_BUFFER_BIT ); - - //Render next mirror - CRender::PopHLStates( ); - }*/ - - /*Mirror.Frame_NoRender = false; - - if( Mirror.Frame_IsCopy ) - { - //This mirror was overriden by the world (a client changed leafs during this frame) - //It is being drawn a second time to make up for that. Now get rid of the second copy - m_RdrMirrors.erase( CMirrorMgr::m_CurrentMirror.Index-- ); - }*/ - - m_CurrentMirror.Index++; - - if (m_CurrentMirror.Index >= (signed)CMirrorMgr::m_RdrMirrors.size()) - //[Note: Should never happen, because a check is made the previous pass if there is another mirror or not] - SetupNormalView(); //Done rendering mirrors, next, render the normal view - else - SetupMirrorView(m_CurrentMirror.Index); //Continue rendering mirrors - } - - SetupNextView(); -} - -void CMirrorMgr::SetupNormalView() -{ - //Params.vieworg = OldView; - //Params.viewangles = OldAng; - - ref_params_t &Params = *ViewMgr.Params; - - /*#ifdef DEBUG_MIRRORS - //Only use a portion of the screen, so I can see what the mirror sees in the top left - Params.viewport[0] = MIRRORTEX_W; - Params.viewport[1] = MIRRORTEX_H; - Params.viewport[2] = ScreenWidth() - MIRRORTEX_W; - Params.viewport[3] = ScreenHeight() - MIRRORTEX_H; - #else*/ - Params.viewport[0] = 0; - Params.viewport[1] = 0; - Params.viewport[2] = ScreenWidth(); - Params.viewport[3] = ScreenHeight(); - //#endif - m_CurrentMirror.Enabled = false; -} -void CMirrorMgr::SetupMirrorView(int MirrorNum) -{ - //CMirror &Mirror = *CMirrorMgr::m_RdrMirrors[MirrorNum]; - - m_CurrentMirror.Enabled = true; - m_CurrentMirror.Index = MirrorNum; - m_CurrentMirror.Mirror = CMirrorMgr::m_RdrMirrors[MirrorNum]; - - /*if( !Mirror.Texture->Mirror.NoWorld ) - { - cl_entity_t *clWorldEnt = gEngfuncs.GetEntityByIndex( 0 ); - model_t *pModel = clWorldEnt->model; - OldVisFrame = clWorldEnt->model->nodes[0].visframe; - clWorldEnt->model->nodes[0].visframe = 0; - }*/ - - //if( Mirror.Texture->Mirror.NoWorld ) - // glClear( GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT/*|GL_ACCUM_BUFFER_BIT*/ ); -} -void CMirrorMgr::SetupNextView() -{ - ref_params_t &Params = *ViewMgr.Params; - - Params.nextView = 0; - - /*if( !m_CurrentMirror.Enabled ) - { - if( m_RdrMirrors.size() ) - Params.nextView = 1; //Render the first mirror next frame - else - { - Params.nextView = 0; //No mirrors visible - } - } - else - { - if( m_CurrentMirror.Index+1 < (signed)CMirrorMgr::m_RdrMirrors.size() ) - Params.nextView = 1; //Render the next mirror next frame - else - { - Params.nextView = 0; //All done rendering mirrors - } - }*/ -} - -//extern Vector v_origin, v_angles, v_cl_angles, v_sim_org, v_lastAngles; -bool Mirror_TraverseVis(TraverseInfo_t &Info); -void DrawVisLeafs(model_t *pModel, mleaf_t *pStartLeaf, TraverseInfo_t &Info); -void rdrsky(); - -void CMirrorMgr::HUD_DrawTransparentTriangles() -{ - if (!UseMirrors) - return; - - CRender::PushHLStates(); - - if (CMirrorMgr::m_RdrMirrors.size()) - { - CRender::SyncOffScreenSurface(); - - for (unsigned int i = 0; i < CMirrorMgr::m_RdrMirrors.size(); i++) - { - CMirrorMgr::SetupMirrorView(i); - CMirrorMgr::m_RdrMirrors[i]->RenderMirroredWorld(0); - -// -//This allows me to test the texture that the mirrored world is rendered onto -// -#ifdef DEBUG_MIRRORS - if (!i) - { - CParticle Particle; - //Particle.BillBoard( ); - CMirror &Mirror = *CMirrorMgr::m_RdrMirrors[i]; - int basex = 100 + i * 280; - int basey = 380; - int basez = 200; - Particle.SetAngles(Vector(0, -90, 0)); - Particle.m_Origin = Vector(basex, basey, basez); - Mirror.BindTexture(); - Particle.m_GLTex = Mirror.GLBufferTexture; - Particle.m_Width = 256; //Mirror.TexSize.x; - Particle.m_ContinuedParticle = false; - Particle.Render(); - Mirror.ReleaseTexture(); - } -#endif - } - CMirrorMgr::SetupNormalView(); - } - - CRender::PopHLStates(); -} -void CMirror::SetupLighting() -{ - /*glEnable( GL_COLOR_MATERIAL ); - glColor4f( 1, 1, 1, 1 ); - //glDisable( GL_COLOR_MATERIAL ); - glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); - glColorMaterial( GL_FRONT_AND_BACK, GL_EMISSION ); - glColorMaterial( GL_FRONT_AND_BACK, GL_SPECULAR ); - glLightModelfv( GL_LIGHT_MODEL_AMBIENT, Color4F(1,1,1,1) ); - - glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, Color4F(1,1,1,1) ); - glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, Color4F(1,1,1,1) ); - glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, Color4F(1,1,1,1) ); - glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); - - - //glDisable( GL_COLOR_MATERIAL ); - glDisable(GL_ALPHA_TEST ); - //glDisable( GL_BLEND ); - glDisable( GL_LOGIC_OP ); - glDisable( GL_DITHER ); - //glBlendFunc( GL_ONE, GL_ONE ); - //glColorMask( 1, 1, 1, 1 ); - glIndexMask( 0xFFFFFFFF );*/ - //glDrawBuffer( GL_FRONT ); -} -bool CMirror::Vis_Eye() //Check if the camera is facing the mirror and not behind it -{ - float Dist = DotProduct(ViewMgr.Origin, Frame_Plane.m_Normal) - Frame_Plane.m_Dist; - if (Dist < 0) - return false; //Player is behind this surface - - Dist = DotProduct(Frame_Plane.m_Normal, ViewMgr.Params->forward); - if (Dist >= ClFOV) - return false; //The player is looking the same direction as my normal - - return true; -} -bool CMirror::Vis_Surface() //Check if the camera is close enough to the mirror -{ - for (unsigned int s = 0; s < m_Surfaces.size(); s++) - { - CSurface &Surface = m_Surfaces[s]; - - float Dist = (Surface.m_Origin - ViewMgr.Origin).Length(); - if (Dist > (Surface.m_Radius + m_Texture->Mirror.Range)) - continue; - - return true; - } - - return false; -} - -void CMirror::RenderMirroredWorld(int RecurseCall) -{ - CMirror &Mirror = *this; - if (RecurseCall >= 2) - return; - - if (m_Parent) - { - //Change the mirror's orientation - Vector Point1 = Vector(Normal.x * Dist, Normal.y * Dist, Normal.z * Dist); - Vector Point2 = Point1 + Normal; - - float flDist = DotProduct(m_Parent->Normal, Point1) - m_Parent->Dist; - Vector ReflectedPt1 = Point1 + -m_Parent->Normal * (flDist * 2); - flDist = DotProduct(m_Parent->Normal, Point2) - m_Parent->Dist; - Vector ReflectedPt2 = Point2 + -m_Parent->Normal * (flDist * 2); - - Frame_Plane.m_Normal = (ReflectedPt2 - ReflectedPt1).Normalize(); - Frame_Plane.m_Dist = DotProduct(Frame_Plane.m_Normal, ReflectedPt1); - - if (!Vis_Eye()) - return; //New orientation is not visible - - CreateMatrix(); //If this is a child, re-create the reflection matrix, based on my new orientation - } - - //Mirror all visible surfaces - - mirrorprops_t OldCurrentMirror; - - //If child mirror, take over the spot as current mirror - if (m_Parent) - { - OldCurrentMirror = CMirrorMgr::m_CurrentMirror; - CMirrorMgr::m_CurrentMirror.Mirror = this; - } - Frame_ChildLevel = RecurseCall; - - CRender::SetRenderTarget(true, false); //Start rendering to offscreen buffer - - SetupLighting(); - - if (!m_Texture->Mirror.NoWorld) //Drawing world. Clear the Z and the Stencil for the mirror's offscreen surface area - { - if (!m_Parent) - Draw(RDR_CLEARZ | RDR_CLRSTENCIL); //Parent mirror. Clear the Z buffer for the mirror's full area. - else - Draw(RDR_CLEARZ | RDR_CHKSTENCIL); //It's a child mirror. Clear the Z buffer only within my stencil section. - - SetStencil(); //Limit rendering to the cleared area. For parent, that's the full mirror. For child, just a section - } - else - { - Draw(RDR_CLEARZ | RDR_CLRALPHA); //If not rendering world, clear the color alpha instead of stencil - //CRender::RT_ClearBuffer( true, false ); //The entites are drawn with alpha = 1, - //so the area in-between the entites is masked out - } - - TraverseInfo_t Info; - Info.Func = Mirror_DrawSurface; - Info.Mirror = this; - Info.RecurseCall = RecurseCall; - Info.CheckClipplane = true; - //Info.CheckFrustum = true; - //Info.CheckClipplane = false; - Info.CheckFrustum = false; - EnableClippingPlane(true); - - //Render world - if (m_Parent) - SetCustomTextureSettings(true); - - if (!m_Texture->Mirror.NoWorld) - { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - ApplyTransformation(); - CEnvMgr::RenderSky(); - - gEngfuncs.pTriAPI->CullFace(TRI_NONE); - - for (unsigned int i = 0; i < CMirrorMgr::m_BrushEnts.size(); i++) - { - cl_entity_t *pEntity = CMirrorMgr::m_BrushEnts[i]; - if (!pEntity || !pEntity->model) - continue; - - model_t &Model = *pEntity->model; - if (Model.type == mod_brush) - { - Info.pEntity = pEntity; - Info.Origin = ViewMgr.Origin; - Info.pModel = pEntity->model; - Info.pNode = Info.pModel->nodes; - Info.TraverseAmt = 0; - - glPushMatrix(); - - Info.ClipPlane = Plane(Normal, Dist); //Always use the original normal for this. Skips objects behind the mirror - - //Move/Rotate moving brushes - - cl_entity_t &Ent = *pEntity; - - AngleMatrix(Vector(-Ent.angles[0], Ent.angles[1], -Ent.angles[2]), Info.MoveMatrix); - Info.MoveMatrix[3][0] = Ent.origin[0]; - Info.MoveMatrix[3][1] = Ent.origin[1]; - Info.MoveMatrix[3][2] = Ent.origin[2]; - Info.MoveMatrix[3][3] = 1; - glMultMatrixf((float *)Info.MoveMatrix); - - if (!Model.firstmodelsurface) - { - //This is the main world model. Traverse the BSP tree to draw it - ParseVisibleSurfaces(Info, CMirrorMgr::m_pStartLeaf); - } - else - { - if (Ent.curstate.rendermode = kRenderTransTexture) - { - glEnable(GL_BLEND); //This is just so that transparent brushes get drawn transparent. Nothing to do with mirror in mirrot - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - for (unsigned int s = 0; s < Model.nummodelsurfaces; s++) - Mirror_DrawSurface(Info, &Model.surfaces[Model.firstmodelsurface + s]); - } - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } - } - - glPopMatrix(); - } - - if (!Mirror.m_Texture->Mirror.NoEnts) - { - //Alpha - If rendering world always use 1. It's belended later. If not, set alpha now - float Alpha = !m_Texture->Mirror.NoWorld ? 1 : Mirror.m_Texture->Mirror.Color.a; - gEngfuncs.pTriAPI->Color4f(Mirror.m_Texture->Mirror.Color.r, Mirror.m_Texture->Mirror.Color.g, Mirror.m_Texture->Mirror.Color.b, Alpha); - } - - //gEngfuncs.pTriAPI->Brightness( 1 ); - - //Render entities - //Warning: Drawing entites causes half-life to kill the culling order, so restore it afterwards - - if (!Mirror.m_Texture->Mirror.NoEnts) - for (unsigned int i = 0; i < CMirrorMgr::m_FrameEnts.size(); i++) - RenderModel(CMirrorMgr::m_FrameEnts[i]); - - gEngfuncs.pTriAPI->CullFace(TRI_NONE); //Warning: This must be reset after calling RenderModel. HL changes the mode - - //Reset states - - if (m_Parent) - SetCustomTextureSettings(false); - - EnableClippingPlane(false); - - //glDisable( GL_ALPHA_TEST ); - glDisable(GL_STENCIL_TEST); - - //Set render target back to HL framebuffer - CRender::SetRenderTarget(false); - - - int ChildMirrors = 0; - if (!m_Parent && !m_Texture->Mirror.NoWorld) - for (unsigned int m = 0; m < m_ChildMirrors.size(); m++) - { - CMirror &ChildMirror = *m_ChildMirrors[m]; - if (m_ChildMirrors[m] == this) - continue; - - ChildMirror.m_Parent = this; - ChildMirror.RenderMirroredWorld(RecurseCall + 1); - ChildMirror.m_Parent = NULL; - ChildMirrors++; - } - m_ChildMirrors.clearitems(); - - //Draw the mirror onscreen - if (!m_Parent) - { - SetupLighting(); - if (!Mirror.m_Texture->Mirror.NoWorld) - Draw(RDR_TEXTURE | RDR_PROJECTIVE); - else - Draw(RDR_TEXTURE | RDR_PROJECTIVE /*|RDR_ALPHATEST*/); - } - - //If child, Reset current mirror to parent - if (m_Parent) - CMirrorMgr::m_CurrentMirror = OldCurrentMirror; -} - -mleaf_t *FindLeaf(Vector &Origin, mnode_t *pNode) -{ - if (!pNode) - return nullptr; - - mnode_t &Node = *pNode; - - if (Node.contents == CONTENTS_SOLID) - return nullptr; - - if (Node.contents < 0) - { - //Found the resident Leaf - return (mleaf_t *)pNode; - } - - mplane_t &Plane = *Node.plane; - - float Dist = 0; - - switch (Plane.type) - { - case PLANE_X: - Dist = Origin[0] - Plane.dist; - break; - case PLANE_Y: - Dist = Origin[1] - Plane.dist; - break; - case PLANE_Z: - Dist = Origin[2] - Plane.dist; - break; - default: - Dist = DotProduct(Origin, Plane.normal) - Plane.dist; - break; - } - - int Side = (Dist >= 0) ? 0 : 1; - - for (unsigned int i = 0; i < 2; i++) - { - mleaf_t *pLeaf = FindLeaf(Origin, Node.children[(i == 0) ? Side : !Side]); - if (pLeaf) - return pLeaf; - } - - return nullptr; -} - -inline bool ParseLeaf(TraverseInfo_t &Info, mleaf_t &Leaf) -{ - bool Success = false; - Vector Bounds[2] = {&Leaf.minmaxs[0], &Leaf.minmaxs[3]}; - bool CallFunc = Info.CheckFrustum ? CheckBBox(Bounds) : true; - - if (Info.CheckClipplane) - CallFunc = Info.ClipPlane.BBoxIsInFront(Bounds); - - if (CallFunc) - for (unsigned int s = 0; s < Leaf.nummarksurfaces; s++) - if ((*(ParseSurfaceFunc *)Info.Func)(Info, Leaf.firstmarksurface[s])) - Success = true; - - return Success; -} - -bool ParseVisibleSurfaces(TraverseInfo_t &Info, mleaf_t *pStartLeaf) -{ - bool FoundOne = false; - model_t &Model = *Info.pEntity->model; - - mleaf_t &StartLeaf = *pStartLeaf; - int num_leaves = Model.numleafs; - int visofs = 0; //Leaf.visofs; - if (!StartLeaf.compressed_vis) - { - FoundOne = true; - for (int c = 1; c <= num_leaves; c++) - { - mleaf_t &DrawLeaf = Model.leafs[c]; //c+1 - ParseLeaf(Info, DrawLeaf); - } - return true; - } - - for (int c = 1; c <= num_leaves; visofs++) - if (StartLeaf.compressed_vis[visofs] == 0) - c += 8 * StartLeaf.compressed_vis[++visofs]; - else - for (byte bit = 1; bit != 0; bit = (bit * 2) & (0xFF), c++) - if (StartLeaf.compressed_vis[visofs] & bit) - { - int leafnum = c /*+1*/; - mleaf_t &DrawLeaf = Model.leafs[leafnum]; - FoundOne = ParseLeaf(Info, DrawLeaf); - } - - return FoundOne; -} - -//Starts at a headnode, checks all leaves found in child nodes to see if any -//of those leaves can see the desired leaf -bool IsLeafVisible(cl_entity_t *pEntity, mnode_t *pNode, mleaf_t *pSearchLeaf) -{ - if (!pNode) - return false; - - mnode_t &Node = *pNode; - - if (Node.contents == CONTENTS_SOLID) - return false; - - if (Node.contents < 0) - { - //Search Leaf - return IsLeafVisible(pEntity, (mleaf_t *)pNode, pSearchLeaf); - } - - //Search child nodes - for (unsigned int i = 0; i < 2; i++) - { - bool Found = IsLeafVisible(pEntity, Node.children[i], pSearchLeaf); - if (Found) - return Found; - } - - return false; -} - -bool Intersects(Vector Bounds[2], Vector OtherBounds[2]) -{ - if (OtherBounds[0][0] > Bounds[1][0] || - OtherBounds[0][1] > Bounds[1][1] || - OtherBounds[0][2] > Bounds[1][2] || - OtherBounds[1][0] < Bounds[0][0] || - OtherBounds[1][1] < Bounds[0][1] || - OtherBounds[1][2] < Bounds[0][2]) - return false; - return true; -} - -bool IsLeafVisible(cl_entity_t *pEntity, mleaf_t *pStartLeaf, mleaf_t *pSearchLeaf) -{ - /*model_t &Model = *pEntity->model; - mleaf_t &StartLeaf = *pStartLeaf; - int num_leaves = Model.numleafs; - int visofs = 0;//Leaf.visofs; - if( !StartLeaf.compressed_vis ) - return true; - - Vector CheckBounds[2] = { &pSearchLeaf->minmaxs[0], &pSearchLeaf->minmaxs[3] }; - - for (int c = 1; c <= num_leaves; visofs++) - if(StartLeaf.compressed_vis[visofs] == 0) - c += 8 * StartLeaf.compressed_vis[++visofs]; - else - for (byte bit = 1; bit != 0; bit = (bit * 2) & (0xFF), c++) - if( StartLeaf.compressed_vis[visofs] & bit ) - { - int leafnum = c+1; - mleaf_t *pVisLeaf = &Model.leafs[leafnum]; - Vector VisBounds[2] = { &pVisLeaf->minmaxs[0], &pVisLeaf->minmaxs[3] }; - if( Intersects( VisBounds, CheckBounds) ) - return true; - }*/ - - return false; -} - -bool IsBoundsVisible(cl_entity_t *pWorldEntity, mleaf_t *pStartLeaf, Vector Bounds[2]) -{ - model_t &Model = *pWorldEntity->model; - mleaf_t &StartLeaf = *pStartLeaf; - int num_leaves = Model.numleafs; - int visofs = 0; //Leaf.visofs; - if (!StartLeaf.compressed_vis) - return true; - - for (int c = 1; c <= num_leaves; visofs++) - if (StartLeaf.compressed_vis[visofs] == 0) - c += 8 * StartLeaf.compressed_vis[++visofs]; - else - for (byte bit = 1; bit != 0; bit = (bit * 2) & (0xFF), c++) - if (StartLeaf.compressed_vis[visofs] & bit) - { - int leafnum = c; //c+1; - mleaf_t *pVisLeaf = &Model.leafs[leafnum]; - Vector VisBounds[2] = {&pVisLeaf->minmaxs[0], &pVisLeaf->minmaxs[3]}; - if (Intersects(VisBounds, Bounds)) - return true; - } - - return false; -} - -bool Mirror_DrawSurface(TraverseInfo_t &Info, msurface_t *pSurface) -{ - //If it's the original glass texture, don't draw - msurface_t &Surface = *pSurface; - //if( Surface.texinfo->texture->gl_texturenum == Info.Mirror->GLIgnoreTexture ) - // return false; - - //Don't draw polys on the same normal - float PlaneMutliplier = (FBitSet(Surface.flags, SURF_PLANEBACK) ? -1 : 1); - Vector SurfaceNormal = Surface.plane->normal * PlaneMutliplier; - float SurfaceDist = Surface.plane->dist * PlaneMutliplier; - - if (SurfaceNormal == Info.Mirror->Normal && SurfaceDist == Info.Mirror->Dist) - return false; - - if (FBitSet(Surface.flags, SURF_DRAWSKY | SURF_DRAWTURB | SURF_UNDERWATER)) - return false; - - CMirror &Mirror = *Info.Mirror; - - //Check if the polygon is part of a mirror. If so, mark it as a child mirror for later - - glColor4f(1, 1, 1, 1); - bool IsMirrorSurface = false; - - if (FBitSet(Surface.flags, (1 << 8)) && !Mirror.m_Parent) - { - //glPushAttrib( GL_STENCIL_BUFFER_BIT ); - glStencilFunc(GL_GEQUAL, Mirror.Frame_ChildLevel + 1, MIRROR_STENCIL_MASK); - glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE); - IsMirrorSurface = true; - - for (unsigned int r = 0; r < CMirrorMgr::m_RenderSurfaces.size(); r++) - { - rendersurface_t &Rend = CMirrorMgr::m_RenderSurfaces[r]; - if (Rend.Surface != pSurface || Rend.Mirror == Info.Mirror) - continue; - - bool MirrorAlreadyFound = false; - for (unsigned int m = 0; m < Mirror.m_ChildMirrors.size(); m++) - if (Mirror.m_ChildMirrors[m] == Rend.Mirror) - { - MirrorAlreadyFound = true; - break; - } - - if (MirrorAlreadyFound) - break; - - Mirror.m_ChildMirrors.add(Rend.Mirror); - break; - } - } - - //Draw surface - glBindTexture(GL_TEXTURE_2D, Surface.texinfo->texture->gl_texturenum); - - CSurface DrawSurface(&Surface); - DrawSurface.DrawNormal(); - - if (IsMirrorSurface) - { - Mirror.SetStencil(); - //glPopAttrib( ); - } - - /*glBindTexture( GL_TEXTURE_2D, surf->lightmaptexturenum ); - glEnable( GL_BLEND ); - glBegin( GL_POLYGON ); - Vertex = Poly.verts[0]; - for( int t = 0; t < Poly.numverts; t++, Vertex += VERTEXSIZE ) - { - glTexCoord2f( Vertex[5], Vertex[6] ); - glVertex3fv( Vertex ); - } - glEnd ();*/ - - return true; -} - -bool CMirrorMgr::Render_StudioModel(cl_entity_t *pEnt) -{ - if (m_CurrentMirror.Enabled) - { - CMirror &Mirror = *m_CurrentMirror.Mirror; - if (Mirror.m_Texture->Mirror.NoEnts) - return false; //Don't reflect any entities - - //if( FBitSet( pEnt->curstate.oldbuttons, MSRDR_NOREFLECT ) ) - // return false; //Don't reflect this entity - - if (Mirror.Frame_NoRender) - return false; //Render got canceled for this frame - } - else - { - if (FBitSet(pEnt->curstate.oldbuttons, MSRDR_NOREFLECT)) - return true; //Don't reflect this entity, but still draw it (return true) - - m_FrameEnts.add(pEnt); //List of ents to reflect - } - - return true; -} - -void CMirror::EnableClippingPlane(bool Enable) -{ - if (Enable) - { - Vector &vNormal = !m_Parent ? Normal : Frame_Plane.m_Normal; - Frame_ClipPlane.m_Normal = Vector(-vNormal.x, -vNormal.y, -vNormal.z); - Frame_ClipPlane.m_Dist = !m_Parent ? Dist : Frame_Plane.m_Dist; - - //Clip - double glplane[4] = {Frame_ClipPlane.m_Normal.x, Frame_ClipPlane.m_Normal.y, Frame_ClipPlane.m_Normal.z, Frame_ClipPlane.m_Dist}; - glClipPlane(GL_CLIP_PLANE0, glplane); - glEnable(GL_CLIP_PLANE0); - } - else - { - glDisable(GL_CLIP_PLANE0); - } -} - -void CMirror::CreateMatrix() -{ - //Creates a matrix that reflects through an arbitrary plane - - //Find the angles for that plane - //Find the delta required to align the angles to the Y axis (0,90,0) - //Rotate the world by the delta, so that what's directly in front of the mirror is now straight down the Y axis - //Flip the world across the Y axis - //Rotate the world back, inverse of the delta - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - float mm[4][4], mi[4][4]; - - //New mirror calculation - - Vector ang; - VectorAngles(!m_Parent ? Normal : Frame_Plane.m_Normal, ang); - if (Entity) - ang += Entity->angles; - - //This matrix translates the world so that the mirror would be facing down the Y axis. - AngleMatrix(Vector(/*-ang.z*/ 0, -(90 - ang.y), ang.x), mm); - mm[3][0] = 0; - mm[3][1] = 0; - mm[3][2] = 0; - mm[3][3] = 1; - - GenerateInverseMatrix4f(mm, mi); - - //Reflect along z axis - static float my[4][4] = - { - 1, - 0, - 0, - 0, - 0, - -1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - /*Dynamic Dist Value*/ 0, - 0, - 1, - }; - - my[3][1] = (!m_Parent ? Dist : Frame_Plane.m_Dist) * 2; - - glLoadIdentity(); - glMultMatrixf((float *)mi); //Rotate back to normal - glMultMatrixf((float *)my); //Flip across Y axis - glMultMatrixf((float *)mm); //Align World to Y axis - - glGetFloatv(GL_MODELVIEW_MATRIX, !m_Parent ? (float *)MirrorMatrix : (float *)Frame_ReflectMatrix); - - glPopMatrix(); -} - -void CMirror::SetStencil() -{ - //All world surfaces and entities to update the stencil buffer - //Any child mirrors conform to the parent's stencil areas - //Remember: Passes if ( ref & mask) OPERATOR ( stencil & mask) - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_LEQUAL, Frame_ChildLevel, MIRROR_STENCIL_MASK); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); -} - -void CMirror::ApplyTransformation() -{ - if (!m_Parent) - glMultMatrixf((float *)MirrorMatrix); - else - { - glMultMatrixf((float *)Frame_ReflectMatrix); - glMultMatrixf((float *)m_Parent->MirrorMatrix); - } -} - -void CMirror::BindTexture() -{ - glBindTexture(GL_TEXTURE_2D, GLBufferTexture); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - CRender::RT_BindTexture(); -} -void CMirror::ReleaseTexture() -{ - CRender::RT_ReleaseTexture(); -} - -void CMirror::SetCustomTextureSettings(bool Enable) -{ - if (Enable) - { - mstexture_t &Tex = *m_Texture; - glColor4fv(Tex.Mirror.Color); - - if (Tex.Mirror.Blending) - { - //glEnable( GL_ALPHA_TEST ); - //glAlphaFunc( GL_EQUAL, 1 ); - glDisable(GL_DEPTH); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - } - else - { - glDisable(GL_BLEND); - } -} - -void CMirror::Draw(int Flags) -{ - float OldProjMatrix[16]; - int oldDepthFunc = GL_LEQUAL; - - if (FBitSet(Flags, RDR_PROJECTIVE)) - { - float mp[16], mm[16]; - glGetFloatv(GL_PROJECTION_MATRIX, mp); - glGetFloatv(GL_MODELVIEW_MATRIX, mm); - - // Select and save the texture matrix - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - - // Generate the perspective projection and range remapping matrix - glLoadIdentity(); - - //~~Important~~ - //The basic calculation for Projective Texture Mapping is Scale 0.5 then add 0.5 as shown: - //glTranslatef( 0.5f, 0.5f, 0.5f ); //Bulids a matrix which will scale by 0.5, then add - //glScalef( 0.5f, 0.5f , 0.5f ); //0.5. Yes, the translatef comes first - otherwise the translation gets scaled too - - //I had to modify this equation to take into acount that my texures are generally going to - //have extra space (For compatibility, I force them to be 2^x, but I dont use all the space). - //So below is the modified equation - - float RatioW = (float)ScreenWidth() / TexSize.x; - float RatioH = (float)ScreenHeight() / TexSize.y; - //glTranslatef( 0.5f * RatioW, 0.5f * (1-(1-RatioH)), 0.0f ); - glTranslatef(0.5f * RatioW, 0.5f * RatioH, 0.0f); - glScalef(0.5f * RatioW, 0.5f * RatioH, 1); - - glMultMatrixf(mp); - glMultMatrixf(mm); - - SetBits(Flags, RDR_TEXTURE); - } - - if (FBitSet(Flags, RDR_TEXTURE)) - { - SetCustomTextureSettings(true); - BindTexture(); //Texture containing the mirrored screen - } - else - { - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - } - - if (FBitSet(Flags, RDR_ALPHATEST)) - { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_EQUAL, 1); - } - - if (FBitSet(Flags, RDR_CLEARZ)) //Clear the Z buffer only within the surface area - { - glGetFloatv(GL_PROJECTION_MATRIX, OldProjMatrix); - - static float ClearZMatrix[4][4] = - { - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - }; - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf((GLfloat *)ClearZMatrix); - glMultMatrixf((GLfloat *)OldProjMatrix); - - glGetIntegerv(GL_DEPTH_FUNC, &oldDepthFunc); - glDepthFunc(GL_ALWAYS); - } - - if (FBitSet(Flags, RDR_CLRALPHA)) //Clear the alpha buffer within the surface area - { - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - glColor4f(0, 0, 1, 0); - } - - if (FBitSet(Flags, RDR_STENCIL)) - { - //-- unused - /*glEnable( GL_STENCIL_TEST ); - //glStencilFunc( GL_NEVER, 2, 2 ); - glStencilFunc( GL_ALWAYS, 1, 1 ); - glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );*/ - } - - if (FBitSet(Flags, RDR_CLRSTENCIL)) //Clear the stencil buffer within the surface area - { - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 0, MIRROR_STENCIL_MASK); - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); - } - - if (FBitSet(Flags, RDR_CHKSTENCIL)) //Only clear the Z if within a certain stencil'd area - { - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_LEQUAL, Frame_ChildLevel, MIRROR_STENCIL_MASK); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - } - - if (m_Parent) - { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glMultMatrixf((float *)m_Parent->MirrorMatrix); - } - - for (unsigned int s = 0; s < m_Surfaces.size(); s++) - { - //if( !Mirror.Surfaces[s]->visframe )//!= Mirror.Entity->model->nodes[0].visframe ) - // continue; - /*surfaceinfo_t &SurfInfo = Mirror.SurfaceInfo[s]; - if( !CheckBBox( SurfInfo.Origin, SurfInfo.Bounds ) ) - continue;*/ - - //gEngfuncs.pTriAPI->CullFace( TRI_NONE ); - //glDisable( GL_DEPTH_TEST ); - CSurface &Surface = m_Surfaces[s]; - Surface.m_SurfaceNormal = Normal; - if (FBitSet(Flags, RDR_PROJECTIVE)) - Surface.DrawProjective(); - else - Surface.DrawNormal(); - - //glEnable( GL_DEPTH_TEST ); - } - - //Restore - //======= - - if (m_Parent) - { - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } - - if (FBitSet(Flags, RDR_TEXTURE)) - { - SetCustomTextureSettings(false); - ReleaseTexture(); - } - else - { - glEnable(GL_LIGHTING); - glEnable(GL_TEXTURE_2D); - - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } - - if (FBitSet(Flags, RDR_PROJECTIVE)) - { - glMatrixMode(GL_TEXTURE); //restore - glPopMatrix(); - } - - if (FBitSet(Flags, RDR_ALPHATEST)) - { - glDisable(GL_ALPHA_TEST); - } - - if (FBitSet(Flags, RDR_CLEARZ)) - { - glMatrixMode(GL_PROJECTION); //restore - glPopMatrix(); - glDepthFunc(oldDepthFunc); - } - - if (FBitSet(Flags, RDR_CLRALPHA)) - { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } - - if (FBitSet(Flags, RDR_STENCIL) || FBitSet(Flags, RDR_CLRSTENCIL) || FBitSet(Flags, RDR_CHKSTENCIL)) - { - glDisable(GL_STENCIL_TEST); - } -} - -// -// CSurface - Adds funtionality the bsp struct -// -void CSurface::Draw() -{ - glpoly_t &Poly = *m_Surface->polys; - glBegin(GL_POLYGON); - - //this loops backwards, for backfaces - //float *Vertex = Poly.verts[0] + (Poly.numverts-1) * VERTEXSIZE; - //for( int t = Poly.numverts-1; t >= 0 ; t--, Vertex -= VERTEXSIZE ) - - float *Vertex = Poly.verts[0]; - for (int t = 0; t < Poly.numverts; t++, Vertex += VERTEXSIZE) - { - //Vector Vec = Vector(Vertex) + m_SurfaceNormal * 5; - //Set Texture coordinates - if (m_ModeTexCoord == TEXCOORD_3D) - glTexCoord3fv(Vertex); //3D coords - Projective texturing - else - glTexCoord2f(Vertex[3], Vertex[4]); //2D coords - Normal mapped texureing - - //Set Vertex - glVertex3fv(Vertex); - } - glEnd(); -} -void CSurface::DrawProjective() -{ - m_ModeTexCoord = TEXCOORD_3D; - Draw(); -} -void CSurface::DrawNormal() -{ - m_ModeTexCoord = TEXCOORD_2D; - Draw(); -} - -float Determinant4f(const float m[16]) -{ - return m[12] * m[9] * m[6] * m[3] - - m[8] * m[13] * m[6] * m[3] - - m[12] * m[5] * m[10] * m[3] + - m[4] * m[13] * m[10] * m[3] + - m[8] * m[5] * m[14] * m[3] - - m[4] * m[9] * m[14] * m[3] - - m[12] * m[9] * m[2] * m[7] + - m[8] * m[13] * m[2] * m[7] + - m[12] * m[1] * m[10] * m[7] - - m[0] * m[13] * m[10] * m[7] - - m[8] * m[1] * m[14] * m[7] + - m[0] * m[9] * m[14] * m[7] + - m[12] * m[5] * m[2] * m[11] - - m[4] * m[13] * m[2] * m[11] - - m[12] * m[1] * m[6] * m[11] + - m[0] * m[13] * m[6] * m[11] + - m[4] * m[1] * m[14] * m[11] - - m[0] * m[5] * m[14] * m[11] - - m[8] * m[5] * m[2] * m[15] + - m[4] * m[9] * m[2] * m[15] + - m[8] * m[1] * m[6] * m[15] - - m[0] * m[9] * m[6] * m[15] - - m[4] * m[1] * m[10] * m[15] + - m[0] * m[5] * m[10] * m[15]; -} - -void GenerateInverseMatrix4f(const float inMatrix[4][4], float outInverse[4][4]) -{ - float x = Determinant4f(&inMatrix[0][0]); - const float *m = &inMatrix[0][0]; - float *i = &outInverse[0][0]; - - i[0] = (-m[13] * m[10] * m[7] + m[9] * m[14] * m[7] + m[13] * m[6] * m[11] - m[5] * m[14] * m[11] - m[9] * m[6] * m[15] + m[5] * m[10] * m[15]) / x; - i[4] = (m[12] * m[10] * m[7] - m[8] * m[14] * m[7] - m[12] * m[6] * m[11] + m[4] * m[14] * m[11] + m[8] * m[6] * m[15] - m[4] * m[10] * m[15]) / x; - i[8] = (-m[12] * m[9] * m[7] + m[8] * m[13] * m[7] + m[12] * m[5] * m[11] - m[4] * m[13] * m[11] - m[8] * m[5] * m[15] + m[4] * m[9] * m[15]) / x; - i[12] = (m[12] * m[9] * m[6] - m[8] * m[13] * m[6] - m[12] * m[5] * m[10] + m[4] * m[13] * m[10] + m[8] * m[5] * m[14] - m[4] * m[9] * m[14]) / x; - i[1] = (m[13] * m[10] * m[3] - m[9] * m[14] * m[3] - m[13] * m[2] * m[11] + m[1] * m[14] * m[11] + m[9] * m[2] * m[15] - m[1] * m[10] * m[15]) / x; - i[5] = (-m[12] * m[10] * m[3] + m[8] * m[14] * m[3] + m[12] * m[2] * m[11] - m[0] * m[14] * m[11] - m[8] * m[2] * m[15] + m[0] * m[10] * m[15]) / x; - i[9] = (m[12] * m[9] * m[3] - m[8] * m[13] * m[3] - m[12] * m[1] * m[11] + m[0] * m[13] * m[11] + m[8] * m[1] * m[15] - m[0] * m[9] * m[15]) / x; - i[13] = (-m[12] * m[9] * m[2] + m[8] * m[13] * m[2] + m[12] * m[1] * m[10] - m[0] * m[13] * m[10] - m[8] * m[1] * m[14] + m[0] * m[9] * m[14]) / x; - i[2] = (-m[13] * m[6] * m[3] + m[5] * m[14] * m[3] + m[13] * m[2] * m[7] - m[1] * m[14] * m[7] - m[5] * m[2] * m[15] + m[1] * m[6] * m[15]) / x; - i[6] = (m[12] * m[6] * m[3] - m[4] * m[14] * m[3] - m[12] * m[2] * m[7] + m[0] * m[14] * m[7] + m[4] * m[2] * m[15] - m[0] * m[6] * m[15]) / x; - i[10] = (-m[12] * m[5] * m[3] + m[4] * m[13] * m[3] + m[12] * m[1] * m[7] - m[0] * m[13] * m[7] - m[4] * m[1] * m[15] + m[0] * m[5] * m[15]) / x; - i[14] = (m[12] * m[5] * m[2] - m[4] * m[13] * m[2] - m[12] * m[1] * m[6] + m[0] * m[13] * m[6] + m[4] * m[1] * m[14] - m[0] * m[5] * m[14]) / x; - i[3] = (m[9] * m[6] * m[3] - m[5] * m[10] * m[3] - m[9] * m[2] * m[7] + m[1] * m[10] * m[7] + m[5] * m[2] * m[11] - m[1] * m[6] * m[11]) / x; - i[7] = (-m[8] * m[6] * m[3] + m[4] * m[10] * m[3] + m[8] * m[2] * m[7] - m[0] * m[10] * m[7] - m[4] * m[2] * m[11] + m[0] * m[6] * m[11]) / x; - i[11] = (m[8] * m[5] * m[3] - m[4] * m[9] * m[3] - m[8] * m[1] * m[7] + m[0] * m[9] * m[7] + m[4] * m[1] * m[11] - m[0] * m[5] * m[11]) / x; - i[15] = (-m[8] * m[5] * m[2] + m[4] * m[9] * m[2] + m[8] * m[1] * m[6] - m[0] * m[9] * m[6] - m[4] * m[1] * m[10] + m[0] * m[5] * m[10]) / x; -} diff --git a/src/game/client/render/gamestudiomodelrenderer.cpp b/src/game/client/render/gamestudiomodelrenderer.cpp index 373b8614b..326e3237e 100644 --- a/src/game/client/render/gamestudiomodelrenderer.cpp +++ b/src/game/client/render/gamestudiomodelrenderer.cpp @@ -60,10 +60,7 @@ R_StudioDrawPlayer */ int R_StudioDrawPlayer(int flags, entity_state_t *pplayer) { - - //return g_StudioRenderer.StudioDrawPlayer( flags, pplayer ); - - return CModelMgr::MSStudioDrawModel(flags, pplayer); + return g_StudioRenderer.StudioDrawPlayer(flags, pplayer); } /* @@ -74,38 +71,7 @@ R_StudioDrawModel */ int R_StudioDrawModel(int flags) { - //return g_StudioRenderer.StudioDrawModel( flags ); - return CModelMgr::MSStudioDrawModel(flags, nullptr); -} - -extern cl_entity_t *DrawEnt; - -int CModelMgr::MSStudioDrawModel(int flags, entity_state_t *pplayer) -{ - cl_entity_t OldEntity; - bool Replaced = false; - - //Override curent entity if specified by DrawEnt - cl_entity_t *CurrentEnt = IEngineStudio.GetCurrentEntity(); - if (DrawEnt) - { - OldEntity = *CurrentEnt; - *CurrentEnt = *DrawEnt; - DrawEnt = nullptr; - Replaced = true; - } - - //Draw a player or regular model, as appropriate - int Return = CurrentEnt->player ? g_StudioRenderer.StudioDrawPlayer(flags, pplayer) - : g_StudioRenderer.StudioDrawModel(flags); - - //Set current entity back to normal - if (Replaced) - { - *CurrentEnt = OldEntity; - } - - return Return; + return g_StudioRenderer.StudioDrawModel(flags); } /* @@ -152,3 +118,10 @@ extern "C" int DLLEXPORT HUD_GetStudioModelInterface(int version, struct r_studi // Success return 1; } + +// FULLBRIGHT START +void CacheFullbrightModels() +{ + g_StudioRenderer.StudioCacheFullbrightNames(); +} +// FULLBRIGHT END \ No newline at end of file diff --git a/src/game/client/render/gamestudiomodelrenderer.h b/src/game/client/render/gamestudiomodelrenderer.h index c8081a9fd..3042fce22 100644 --- a/src/game/client/render/gamestudiomodelrenderer.h +++ b/src/game/client/render/gamestudiomodelrenderer.h @@ -5,11 +5,7 @@ // $NoKeywords: $ //============================================================================= -#if !defined(GAMESTUDIOMODELRENDERER_H) -#define GAMESTUDIOMODELRENDERER_H -#if defined(_WIN32) #pragma once -#endif /* ==================== @@ -21,6 +17,4 @@ class CGameStudioModelRenderer : public CStudioModelRenderer { public: CGameStudioModelRenderer(void); -}; - -#endif // GAMESTUDIOMODELRENDERER_H \ No newline at end of file +}; \ No newline at end of file diff --git a/src/game/client/render/opengl/clopengl.cpp b/src/game/client/render/opengl/clopengl.cpp deleted file mode 100644 index 8a79a67ee..000000000 --- a/src/game/client/render/opengl/clopengl.cpp +++ /dev/null @@ -1,481 +0,0 @@ -//Render mirrors - -// Include Windows and OpenGL headers first for proper WGL function declarations -#ifdef _WIN32 -#include -#include -#include -#endif -#include - -#include "inc_weapondefs.h" -#include "../hud.h" -#include "../cl_util.h" -#include "com_model.h" -#include "studio.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "triangleapi.h" -#include "com_model.h" -#include "../studio_util.h" -#include "../r_studioint.h" -#include "../studiomodelrenderer.h" -#include "../gamestudiomodelrenderer.h" -#include "pm_movevars.h" -#include "clopengl.h" // OpenGL stuff -#include "mslogger.h" - -#ifdef _WIN32 -// WGL_ARB_extensions_string -PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL; - -// WGL_ARB_pbuffer -PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = NULL; -PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = NULL; -PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = NULL; -PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = NULL; -PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = NULL; - -// WGL_ARB_pixel_format -PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL; - -// WGL_ARB_render_texture -PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = NULL; -PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = NULL; -PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB = NULL; -#endif // _WIN32 - -void VectorAngles(const float *forward, float *angles); -void GenerateInverseMatrix4f(const float inMatrix[4][4], float outInverse[4][4]); - -uint id = 0; - -struct Vertex -{ - float tu, tv; - float x, y, z; -}; - -Vertex g_cubeVertices[] = - { - {0.0f, 0.0f, -1.0f, -1.0f, 1.0f}, - {1.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - {1.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - {0.0f, 1.0f, -1.0f, 1.0f, 1.0f}, - - {1.0f, 0.0f, -1.0f, -1.0f, -1.0f}, - {1.0f, 1.0f, -1.0f, 1.0f, -1.0f}, - {0.0f, 1.0f, 1.0f, 1.0f, -1.0f}, - {0.0f, 0.0f, 1.0f, -1.0f, -1.0f}, - - {0.0f, 1.0f, -1.0f, 1.0f, -1.0f}, - {0.0f, 0.0f, -1.0f, 1.0f, 1.0f}, - {1.0f, 0.0f, 1.0f, 1.0f, 1.0f}, - {1.0f, 1.0f, 1.0f, 1.0f, -1.0f}, - - {1.0f, 1.0f, -1.0f, -1.0f, -1.0f}, - {0.0f, 1.0f, 1.0f, -1.0f, -1.0f}, - {0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - {1.0f, 0.0f, -1.0f, -1.0f, 1.0f}, - - {1.0f, 0.0f, 1.0f, -1.0f, -1.0f}, - {1.0f, 1.0f, 1.0f, 1.0f, -1.0f}, - {0.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - - {0.0f, 0.0f, -1.0f, -1.0f, -1.0f}, - {1.0f, 0.0f, -1.0f, -1.0f, 1.0f}, - {1.0f, 1.0f, -1.0f, 1.0f, 1.0f}, - {0.0f, 1.0f, -1.0f, 1.0f, -1.0f}}; - -//#include "r_efx.h" -#include "entity_types.h" -#include "clglobal.h" -#include "../clrender.h" - -#ifdef _WIN32 -typedef struct -{ - HPBUFFERARB hPBuffer; - HDC hDC; - HGLRC hRC; -} PBUFFER; - -HDC OldhDC; -HGLRC OldhRC; - -PBUFFER g_pbuffer; -#endif - -void CRender::RT_GetNewFrameBufferTexture(uint &Tex) -{ - // - // This is our dynamic texture, which will be loaded with new pixel data - // after we're finshed rendering to the p-buffer. - // - - SetRenderTarget(true); - glGenTextures(1, &Tex); - glBindTexture(GL_TEXTURE_2D, Tex); - //glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR ); - //glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR ); - SetRenderTarget(false); -} - -void CRender::RT_BindTexture() -{ -#ifdef _WIN32 - if (!wglBindTexImageARB(g_pbuffer.hPBuffer, WGL_FRONT_LEFT_ARB)) - { - //MessageBox(NULL, "Could not bind p-buffer to render texture!", "ERROR", MB_OK | MB_ICONEXCLAMATION); - MS_ERROR("Error: Could not bind p-buffer to render texture!"); - Print("Could not bind p-buffer to render texture!"); - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Renderer Error", "Could not bind p-buffer to render texture!", NULL); - //exit(-1); - } -#endif -} - -void CRender::RT_ReleaseTexture() -{ - //we need to make sure that the p-buffer has been - // released from the dynamic "render-to" texture. - // - -#ifdef _WIN32 - if (!wglReleaseTexImageARB(g_pbuffer.hPBuffer, WGL_FRONT_LEFT_ARB)) - { - //MessageBox(NULL, "Could not release p-buffer from render texture!", "ERROR", MB_OK | MB_ICONEXCLAMATION); - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Renderer Error", "Could not release p-buffer from render texture!", NULL); - //exit(-1); - } -#endif -} -struct gllightinfo_t -{ - int Enabled; - float Pos[4]; //In GL, it's 4 floats. The last one specifies a sort of attenuation - float AmbientColor[4], DiffuseColor[4], SpecularColor[4]; - float ConstAttn; -}; - -// Used to setup the offscreen surface before rendering to it -// Copies the GL values used from HL's framebuffer -void CRender::SyncOffScreenSurface() -{ -#ifdef _WIN32 - static bool copied = false; - - //if( !copied ) - { - //wglCopyContext( OldhRC, g_pbuffer.hRC, /*GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT |*/ GL_TEXTURE_BIT ); - //wglCopyContext( OldhRC, g_pbuffer.hRC, GL_LIGHTING_BIT ); - } - - float mp[16], mmv[16] /*, mt[16]*/; - glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *)mp); - glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)mmv); - //glGetFloatv( GL_TEXTURE_MATRIX, (GLfloat *)mt ); - - SetRenderTarget(true, false); - - if (!copied) - { - /*glEnable( GL_COLOR_MATERIAL ); - glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); - glColorMaterial( GL_FRONT, GL_EMISSION ); - glColorMaterial( GL_FRONT, GL_SPECULAR );*/ - } - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(mp); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(mmv); - - //glMatrixMode( GL_TEXTURE ); - //glLoadMatrixf( mt ); - - //glClear( GL_DEPTH_BUFFER_BIT ); - copied = true; -#endif // _WIN32 - - SetRenderTarget(false); -} -void CRender::RT_ClearBuffer(bool ClearColor, bool ClearDepth, bool ClearStencil) -{ - //glClearColor( 0.0f, 0.0f, 1.0f, 0.0f ); - - if (ClearColor) - glClear(GL_COLOR_BUFFER_BIT); - if (ClearDepth) - glClear(GL_DEPTH_BUFFER_BIT); - if (ClearStencil) - glClear(GL_STENCIL_BUFFER_BIT); -} -void CRender::SetRenderTarget(bool ToTexture, bool ClearDepth) -{ -#ifdef _WIN32 - if (ToTexture) - { - if (!wglMakeCurrent(g_pbuffer.hDC, g_pbuffer.hRC)) - { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Renderer Error", "Could not make the p-buffer's context current!", NULL); - //MessageBox(NULL, "Could not make the p-buffer's context current!", "ERROR", MB_OK | MB_ICONEXCLAMATION); - //exit(-1); - } - if (ClearDepth) - glClear(GL_DEPTH_BUFFER_BIT); - } - else - { - //glMatrixMode( GL_PROJECTION ); - //glPopMatrix( ); - - if (!wglMakeCurrent(OldhDC, OldhRC)) - { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Renderer Error", "Could not make the normal half-life context current!", NULL); - //MessageBox(NULL, "Could not make the normal half-life context current!", "ERROR", MB_OK | MB_ICONEXCLAMATION); - //exit(-1); - } - } -#endif -} - -bool CMirrorMgr::InitMirrors() -{ - //CRender::m_RT_SizeRatio = 0.2f; - UseMirrors = false; - if (!IEngineStudio.IsHardware()) //Not using openGL - return false; - - const char *VendorString = (const char *)glGetString(GL_VENDOR); - const char *CardString = (const char *)glGetString(GL_RENDERER); - const char *VersionString = (const char *)glGetString(GL_VERSION); - const char *ExtensionsString = (const char *)glGetString(GL_EXTENSIONS); - MS_RENDER_INFO("Video Card Vendor: %s", VendorString); - MS_RENDER_INFO("Video Card: %s", CardString); - MS_RENDER_INFO("OpenGL Version: %s", VersionString); - MS_RENDER_INFO("OpenGL Extensions: %s", ExtensionsString); - - if (atof(VersionString) < 1.1) //Not high enough OpenGL version - { - MS_RENDER_WARN("OpenGL Version Not High Enough For Mirrors (Needs 1.1)"); - return false; - } - -#ifdef _WIN32 - glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB"); - glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB"); -#endif - - MS_RENDER_INFO("OpenGL ActiveTexture Extention: %s", (glActiveTextureARB ? "FOUND" : "NOT FOUND")); - -#ifdef _WIN32 - if (!glActiveTextureARB) //Doesn't support Multitexturing - return false; - - //Get the WGL extensions string - wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); - const char *wglExtensions = wglGetExtensionsStringARB(wglGetCurrentDC()); - - //Set up wgl extensions - if (!strstr(wglExtensions, "WGL_ARB_pbuffer") || !strstr(wglExtensions, "WGL_ARB_pixel_format") || !strstr(wglExtensions, "WGL_ARB_render_texture")) - { - MS_RENDER_WARN("OpenGL Version Not High Enough For Mirrors (wglExtensions not Present)!"); - return false; - } - - OldhDC = wglGetCurrentDC(); - OldhRC = wglGetCurrentContext(); - - //Init the pbuffer - wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB"); - wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB"); - wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB"); - wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB"); - wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress("wglQueryPbufferARB"); - wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); - wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB"); - wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)wglGetProcAddress("wglReleaseTexImageARB"); - wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress("wglSetPbufferAttribARB"); - - // - // Define the minimum pixel format requirements we will need for our - // p-buffer. A p-buffer is just like a frame buffer, it can have a depth - // buffer associated with it and it can be double buffered. - // - - int pf_attr[] = - { - WGL_SUPPORT_OPENGL_ARB, true, // P-buffer will be used with OpenGL - WGL_DRAW_TO_PBUFFER_ARB, true, // Enable render to p-buffer - WGL_BIND_TO_TEXTURE_RGBA_ARB, true, // P-buffer will be used as a texture - WGL_RED_BITS_ARB, 8, // At least 8 bits for RED channel - WGL_GREEN_BITS_ARB, 8, // At least 8 bits for GREEN channel - WGL_BLUE_BITS_ARB, 8, // At least 8 bits for BLUE channel - WGL_ALPHA_BITS_ARB, 8, // At least 8 bits for ALPHA channel - WGL_DEPTH_BITS_ARB, 16, // At least 16 bits for depth buffer - WGL_DOUBLE_BUFFER_ARB, false, // We don't require double buffering - 0 // Zero terminates the list - }; - - unsigned int count = 0; - int pixelFormat = 0; - wglChoosePixelFormatARB(OldhDC, (const int *)pf_attr, NULL, 1, &pixelFormat, &count); - - if (count == 0) - { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Renderer Error", "Could not find an acceptable pixel format!", NULL); - //MessageBox(NULL, "Could not find an acceptable pixel format!", "ERROR", MB_OK | MB_ICONEXCLAMATION); - //exit(-1); - } - - // - // Set some p-buffer attributes so that we can use this p-buffer as a - // 2D RGBA texture target. - // - - int pb_attr[] = - { - WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, // Our p-buffer will have a texture format of RGBA - WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, // Of texture target will be GL_TEXTURE_2D - 0 // Zero terminates the list - }; - - // - // Create the p-buffer... - // - - GetCompatibleTextureSize(ScreenWidth() * CRender::m_RT_SizeRatio, ScreenHeight() * CRender::m_RT_SizeRatio, CRender::m_RT_Width, CRender::m_RT_Height, CRender::m_RT_TexU, CRender::m_RT_TexV); - - g_pbuffer.hPBuffer = wglCreatePbufferARB(OldhDC, pixelFormat, CRender::m_RT_Width, CRender::m_RT_Height, pb_attr); - g_pbuffer.hDC = wglGetPbufferDCARB(g_pbuffer.hPBuffer); - g_pbuffer.hRC = wglCreateContext(g_pbuffer.hDC); - - wglShareLists(OldhRC, g_pbuffer.hRC); - - if (!g_pbuffer.hPBuffer) - { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Renderer Error", "Could not create Offscreen buffer", NULL); - //MessageBox(NULL, "Could not create Offscreen buffer", "ERROR", MB_OK | MB_ICONEXCLAMATION); - //exit(-1); - } - - int h; - int w; - wglQueryPbufferARB(g_pbuffer.hPBuffer, WGL_PBUFFER_WIDTH_ARB, &h); - wglQueryPbufferARB(g_pbuffer.hPBuffer, WGL_PBUFFER_WIDTH_ARB, &w); - - /*if( h != g_pbuffer.nHeight || w != g_pbuffer.nWidth ) - { - MessageBox(NULL,"The width and height of the created p-buffer don't match the requirements!", - "ERROR",MB_OK|MB_ICONEXCLAMATION); - exit(-1); - }*/ - - // - // We were successful in creating a p-buffer. We can now make its context - // current and set it up just like we would a regular context - // attached to a window. - // - - //glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); - //glEnable(GL_TEXTURE_2D); - //glEnable(GL_DEPTH_TEST); - - //glMatrixMode( GL_PROJECTION ); - //glLoadIdentity(); - //gluPerspective( 45.0f, CRender::m_RT_Width / CRender::m_RT_Height, 0.1f, 10.0f ); - - //uint Tex = 0; - //CRender::RT_GetNewFrameBufferTexture( Tex ); - - //CRender::SetRenderTarget( true ); - - if (!wglMakeCurrent(g_pbuffer.hDC, g_pbuffer.hRC)) - { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Renderer Error", "Could not make the p-buffer's context current!", NULL); - //MessageBox(NULL, "Could not make the p-buffer's context current!", "ERROR", MB_OK | MB_ICONEXCLAMATION); - //exit(-1); - } - - //glDrawBuffer( GL_FRONT ); - //glReadBuffer( GL_FRONT ); - - glViewport(0.0, 0.0, CRender::m_RT_Width * CRender::m_RT_TexU, CRender::m_RT_Height * CRender::m_RT_TexV); - glClearColor(0.0f, 0.0f, 1.0f, 0.0f); - // glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Color4F(1, 1, 1, 1)); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_LIGHTING); - glShadeModel(GL_FLAT); - - glClearDepth(1.0f); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - - glColor4f(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //hints - //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - CRender::SetRenderTarget(false); - //wglCopyContext( OldhRC, g_pbuffer.hRC, GL_LIGHTING_BIT | GL_TEXTURE_BIT ); - - UseMirrors = true; - m_Initialized = false; - - m_WorldMirrors.clearitems(); //Reset world mirrors - m_WorldSurfaces.clearitems(); //Reset world special surfaces - - return true; -#else - MS_RENDER_WARN("OpenGL mirrors are not implemented on this platform"); - return false; -#endif -} - -void CRender::CleanupWGL() -{ - //glDeleteTextures( 1, &g_testTextureID ); - //glDeleteTextures( 1, &g_dynamicTextureID ); - - // - // Don't forget to clean up after our p-buffer... - // -#ifdef _WIN32 - if (g_pbuffer.hRC != NULL) - { - //wglMakeCurrent( g_pbuffer.hDC, g_pbuffer.hRC ); - wglDeleteContext(g_pbuffer.hRC); - wglReleasePbufferDCARB(g_pbuffer.hPBuffer, g_pbuffer.hDC); - wglDestroyPbufferARB(g_pbuffer.hPBuffer); - g_pbuffer.hRC = NULL; - } - - if (g_pbuffer.hDC != NULL) - { - //ReleaseDC( g_hWnd, g_pbuffer.hDC ); - ReleaseDC(NULL, g_pbuffer.hDC); - g_pbuffer.hDC = NULL; - } -#endif -} - -bool CRender::CheckOpenGL() -{ - //Thothie attempting to enable D3D (failed) - if (!IEngineStudio.IsHardware()) - { - //MessageBox(NULL, "Master Sword uses features only available in OpenGL mode! Attempting other modes may result in instability.", "Invalid Video Mode", MB_OK); - //SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Invalid Video Mode", "We make use of features only in OpenGL!", NULL); - MS_RENDER_ERROR("CRender::CheckOpenGL - User chose non-opengl video mode (semi-fatal)"); - //exit( 0 ); - return false; - } - - return true; -} diff --git a/src/game/client/render/opengl/clopengl.h b/src/game/client/render/opengl/clopengl.h deleted file mode 100644 index 38fc774d5..000000000 --- a/src/game/client/render/opengl/clopengl.h +++ /dev/null @@ -1,9 +0,0 @@ -#include -#ifdef _WIN32 -#include -#include -#endif -#include -#ifdef _WIN32 -#include "gl/wglext.h" -#endif diff --git a/src/game/client/render/studio_util.cpp b/src/game/client/render/studio_util.cpp index bfc476d10..78bfded6c 100644 --- a/src/game/client/render/studio_util.cpp +++ b/src/game/client/render/studio_util.cpp @@ -11,10 +11,6 @@ #include "const.h" #include "com_model.h" #include "studio_util.h" -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - // angles index are not the same as ROLL, PITCH, YAW diff --git a/src/game/client/render/studio_util.h b/src/game/client/render/studio_util.h index 9248f80dc..7a2aa47bd 100644 --- a/src/game/client/render/studio_util.h +++ b/src/game/client/render/studio_util.h @@ -7,31 +7,21 @@ #pragma once -//#ifndef PITCH +#ifndef M_PI +#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h +#endif + +#ifndef PITCH // MOVEMENT INFO // up / down -enum { - PITCH = 0, - // left / right - YAW = 1, - // fall over - ROLL = 2 -}; -//#endif - -#undef PLANE_ANYZ - -enum planes_e { - PLANE_X = 0, - PLANE_Y = 1, - PLANE_Z = 2, - PLANE_ANYZ = 5 -}; +#define PITCH 0 +// left / right +#define YAW 1 +// fall over +#define ROLL 2 +#endif -template -inline Type FDotProduct(const Type a, const Type b) { - return fabs(a[0] * b[0]) + fabs(a[1] * b[1]) + fabs(a[2] * b[2]); -} +#define FDotProduct(a, b) (fabs((a[0]) * (b[0])) + fabs((a[1]) * (b[1])) + fabs((a[2]) * (b[2]))) void AngleMatrix(const float *angles, float (*matrix)[4]); bool VectorCompare (const float *v1, const float *v2); diff --git a/src/game/client/render/studiomodelrenderer.cpp b/src/game/client/render/studiomodelrenderer.cpp index ccd406769..c038241c5 100644 --- a/src/game/client/render/studiomodelrenderer.cpp +++ b/src/game/client/render/studiomodelrenderer.cpp @@ -37,6 +37,13 @@ #include // Header File For The OpenGL32 Library #include +// FULLBRIGHT START +#define GL_CLAMP_TO_EDGE 0x812F + +static GLuint g_iBlankTex = 0; + +// FULLBRIGHT END + // Global engine <-> studio model rendering code interface engine_studio_api_t IEngineStudio; @@ -49,11 +56,49 @@ void ViewModel_InactiveModelVisible(bool fVisible, const cl_entity_s* ActiveEnti { ViewModel_ExclusiveViewHand = fVisible ? ActiveEntity->curstate.iuser2 : -1; } + +//The engine draws additive textures without writing depth, and only when the entity is kRenderNormal. +//A normal entity is drawn before the transparent ones, so those (alpha tested brushes mostly) paint over +//the additive parts of a view model. To get around it the hand model is queued as transparent, which +//makes the engine draw it last, and is set back to normal right before it's rendered +static int ViewModel_SavedRenderAmt[MAX_PLAYER_HANDITEMS]; + +static bool StudioHasAdditiveTexture(studiohdr_t* pStudioHeader) +{ + if (!pStudioHeader || !pStudioHeader->textureindex) + return false; + + mstudiotexture_t* pTexture = (mstudiotexture_t*)((byte*)pStudioHeader + pStudioHeader->textureindex); + for (int i = 0; i < pStudioHeader->numtextures; i++) + if (FBitSet(pTexture[i].flags, STUDIO_NF_ADDITIVE)) + return true; + + return false; +} + +static void ViewModel_QueueDrawLate(cl_entity_t& Ent) +{ + ViewModel_SavedRenderAmt[Ent.curstate.iuser2] = Ent.curstate.renderamt; + Ent.curstate.rendermode = kRenderTransTexture; + Ent.curstate.renderamt = 255; //The engine skips transparent models that have no renderamt + SetBits(Ent.curstate.colormap, MSRDR_DRAWLATE); +} + +//Returns true if the model was queued +static bool ViewModel_UndoDrawLate(cl_entity_t& Ent) +{ + if (!FBitSet(Ent.curstate.colormap, MSRDR_DRAWLATE)) + return false; + + ClearBits(Ent.curstate.colormap, MSRDR_DRAWLATE); + Ent.curstate.rendermode = kRenderNormal; + Ent.curstate.renderamt = ViewModel_SavedRenderAmt[Ent.curstate.iuser2]; + return true; +} + extern Vector v_origin, v_angles, v_cl_angles, v_sim_org, v_lastAngles; //CStudioModelRenderer *g_StudioRender = NULL; -cl_entity_t* DrawEnt = nullptr; - ///////////////////// // Implementation of CStudioModelRenderer.h @@ -65,6 +110,10 @@ Init */ void CStudioModelRenderer::Init(void) { + // FULLBRIGHT START + StudioCacheFullbrightNames(); + // FULLBRIGHT END + // Set up some variables shared with engine m_pCvarHiModels = IEngineStudio.GetCvar("cl_himodels"); m_pCvarDeveloper = IEngineStudio.GetCvar("developer"); @@ -89,25 +138,24 @@ CStudioModelRenderer */ CStudioModelRenderer::CStudioModelRenderer(void) { - m_fDoInterp = 1; - m_fGaitEstimation = 1; - m_pCurrentEntity = nullptr; - m_pCvarHiModels = nullptr; - m_pCvarDeveloper = nullptr; - m_pCvarDrawEntities = nullptr; - m_pChromeSprite = nullptr; - m_pStudioModelCount = nullptr; - m_pModelsDrawn = nullptr; - m_protationmatrix = nullptr; - m_paliastransform = nullptr; - m_pbonetransform = nullptr; - m_plighttransform = nullptr; - m_pStudioHeader = nullptr; - m_pBodyPart = nullptr; - m_pSubModel = nullptr; - m_pPlayerInfo = nullptr; - m_pRenderModel = nullptr; - //m_MirrorRender = false; + m_fDoInterp = 1; + m_fGaitEstimation = 1; + m_pCurrentEntity = NULL; + m_pCvarHiModels = NULL; + m_pCvarDeveloper = NULL; + m_pCvarDrawEntities = NULL; + m_pChromeSprite = NULL; + m_pStudioModelCount = NULL; + m_pModelsDrawn = NULL; + m_protationmatrix = NULL; + m_paliastransform = NULL; + m_pbonetransform = NULL; + m_plighttransform = NULL; + m_pStudioHeader = NULL; + m_pBodyPart = NULL; + m_pSubModel = NULL; + m_pPlayerInfo = NULL; + m_pRenderModel = NULL; /*AngleMatrix( g_vecZero, m_FlipMatrix ); float scalemat[ 3 ][ 4 ] = { @@ -280,13 +328,13 @@ void CStudioModelRenderer::StudioCalcBoneQuaterion(int frame, float s, mstudiobo if( pbone->parent == -1 ) { animrot += orig1; - animrot -= PI/2; + animrot -= M_PI/2; } animrot *= -1; if( pbone->parent == -1 ) { - animrot += PI/2; + animrot += M_PI/2; animrot -= (-orig1); } @@ -317,8 +365,8 @@ void CStudioModelRenderer::StudioCalcBoneQuaterion(int frame, float s, mstudiobo /*if( FBitSet(m_pCurrentEntity->curstate.oldbuttons,MSRDR_FLIPPED) ) if( pbone->parent != -1 ) { - if( angle[0] > PI ) angle[0] -= PI*2; - if( angle[0] < -PI ) angle[0] += PI*2; + if( angle[0] > M_PI ) angle[0] -= M_PI*2; + if( angle[0] < -M_PI ) angle[0] += M_PI*2; for (int j = 0; j < 2; j++) if( panim->offset[j+1+3] == 0 ) { @@ -928,7 +976,7 @@ void CStudioModelRenderer::StudioSetupBones(void) static vec4_t q4[MAXSTUDIOBONES]; cl_entity_t& Ent = *m_pCurrentEntity; - if (Ent.curstate.sequence >= static_cast(m_pStudioHeader->numseq)) + if (Ent.curstate.sequence >= m_pStudioHeader->numseq) { Ent.curstate.sequence = 0; } @@ -977,14 +1025,14 @@ void CStudioModelRenderer::StudioSetupBones(void) if (m_fDoInterp && Ent.latched.sequencetime && (Ent.latched.sequencetime + 0.2 > m_clTime) && - (Ent.latched.prevsequence < (float)m_pStudioHeader->numseq)) + (Ent.latched.prevsequence < m_pStudioHeader->numseq)) { // blend from last sequence static float pos1b[MAXSTUDIOBONES][3]; static vec4_t q1b[MAXSTUDIOBONES]; float s; - if (Ent.latched.prevsequence >= static_cast(m_pStudioHeader->numseq)) + if (Ent.latched.prevsequence >= m_pStudioHeader->numseq) Ent.latched.prevsequence = 0; pseqdesc = (mstudioseqdesc_t*)((byte*)m_pStudioHeader + m_pStudioHeader->seqindex) + Ent.latched.prevsequence; @@ -1028,7 +1076,7 @@ void CStudioModelRenderer::StudioSetupBones(void) pbones = (mstudiobone_t*)((byte*)m_pStudioHeader + m_pStudioHeader->boneindex); // bounds checking - if (m_pPlayerInfo && (m_pPlayerInfo->gaitsequence >= static_cast(m_pStudioHeader->numseq))) + if (m_pPlayerInfo && (m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq)) m_pPlayerInfo->gaitsequence = 0; // calc gait animation @@ -1137,7 +1185,7 @@ void CStudioModelRenderer::StudioMergeBones(model_t* m_pSubModel) float bonematrix[3][4]; static vec4_t q[MAXSTUDIOBONES]; - if (Ent.curstate.sequence >= static_cast(m_pStudioHeader->numseq)) + if (Ent.curstate.sequence >= m_pStudioHeader->numseq) { Ent.curstate.sequence = 0; } @@ -1255,20 +1303,10 @@ StudioDrawModel */ //#define rdrdbg(a) dbg(msstring(a) + " Entity #" + m_pCurrentEntity->curstate.number) -#define rdrdbg( a ) extern bool g_FirstRender; extern CGameStudioModelRenderer g_StudioRenderer; -void RenderModel(cl_entity_t* pEntity) -{ - DrawEnt = pEntity; - if (DrawEnt->player) - CModelMgr::MSStudioDrawModel(STUDIO_RENDER, (IEngineStudio.GetPlayerState(pEntity->index - 1))); - else - CModelMgr::MSStudioDrawModel(STUDIO_RENDER, NULL); -} - //MIB APR2008a - massive changes int CStudioModelRenderer::StudioDrawModel(int flags) { @@ -1280,20 +1318,10 @@ int CStudioModelRenderer::StudioDrawModel(int flags) g_FirstRender = false; } - if (DrawEnt) - { - m_pCurrentEntity = DrawEnt; - DrawEnt = NULL; - } - else - m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); + m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); cl_entity_t& Ent = *m_pCurrentEntity; - if (FBitSet(flags, STUDIO_RENDER)) - if (!CMirrorMgr::Render_StudioModel(m_pCurrentEntity)) - return 0; //Rendering inside of a mirror was canceled - //Default is to only render the one 'current' entity. The view model overrides this and renders two cl_entity_t* RenderEnts[MAX_PLAYER_HANDITEMS] = { m_pCurrentEntity, NULL, NULL }; int TotalModels = 1; @@ -1309,9 +1337,6 @@ int CStudioModelRenderer::StudioDrawModel(int flags) if (ViewModel_ExclusiveViewHand >= 0 && ViewModel_ExclusiveViewHand != hand) continue; - if (CMirrorMgr::m_CurrentMirror.Enabled) - return 0; - //Check if an item is hend in this hand CGenericItem* pItem = player.Hand(hand); if (!pItem) @@ -1329,6 +1354,7 @@ int CStudioModelRenderer::StudioDrawModel(int flags) //Try to create an entity for this viewmodel (only lasts this frame) cl_entity_t& RenderEnt = MSCLGlobals::CLViewEntities[hand]; + ViewModel_UndoDrawLate(RenderEnt); //In case it was queued last frame but never got drawn int Ent = gEngfuncs.CL_CreateVisibleEntity(ET_NORMAL, &RenderEnt); if (!Ent) continue; @@ -1340,15 +1366,15 @@ int CStudioModelRenderer::StudioDrawModel(int flags) studiohdr_t* pStudioHeader = (studiohdr_t*)IEngineStudio.Mod_Extradata(RenderEnt.model); cl_entity_s* view = gEngfuncs.GetViewModel(); - view->model = nullptr; //MiB JUN2010_21 - Disable the HL viewmodel. We use our own. + view->model = NULL; //MiB JUN2010_21 - Disable the HL viewmodel. We use our own. + RenderEnt.curstate.body = 0; //view model is reused, doesn't carry the last model's sub over - Dravus RenderEnt.SetBody(pItem->m_ViewModelPart, pItem->m_ViewModelSubmodel); //Set the specified submodel on the item //MiB Apr 2008a NOTE: //These ifs may need to be removed. Skins and other things CAN be 0. //Untested right now. - if (pItem->m_Skin > 0) - RenderEnt.curstate.skin = pItem->m_Skin; + RenderEnt.curstate.skin = pItem->m_Skin; //skin 0 is valid, but > 0 left the last items sub model on. Ex: Fire Tomahawk would look like the last toma used sub model. - Dravus if (pItem->m_RenderMode > 0) RenderEnt.curstate.rendermode = pItem->m_RenderMode; if (pItem->m_RenderFx > 0) @@ -1358,8 +1384,11 @@ int CStudioModelRenderer::StudioDrawModel(int flags) //[/Shuriken] SetBits(RenderEnt.curstate.colormap, MSRDR_HANDMODEL); - SetBits(RenderEnt.curstate.oldbuttons, MSRDR_NOREFLECT); RenderEnt.curstate.iuser2 = hand; + + if (RenderEnt.curstate.rendermode == kRenderNormal && StudioHasAdditiveTexture(pStudioHeader)) + ViewModel_QueueDrawLate(RenderEnt); + RenderEnt.curstate.modelindex = 0; //RenderEnt.current_position = m_pCurrentEntity->current_position; RenderEnt.origin = m_pCurrentEntity->origin; @@ -1522,7 +1551,7 @@ int CStudioModelRenderer::StudioDrawModel(int flags) m_pPlayerInfo = IEngineStudio.PlayerInfo(ZeroBasedPlayerIdx); m_pPlayerInfo->prevgaitorigin = PrevOrigin; - m_pPlayerInfo = nullptr; + m_pPlayerInfo = NULL; m_pCurrentEntity->curstate.number = oldnum; m_pCurrentEntity->index = oldidx; @@ -1545,9 +1574,6 @@ int CStudioModelRenderer::StudioDrawModel(int flags) if (FBitSet(Ent.curstate.playerclass, ENT_EFFECT_FOLLOW_ROTATE) && Ent.curstate.owner == gEngfuncs.GetLocalPlayer()->index) SkipVisCheck = true; - if (CMirrorMgr::m_CurrentMirror.Enabled) - SkipVisCheck = true; //Skip vis on entites for mirror rendering - if (flags & STUDIO_RENDER) { // see if the bounding box lets us trivially reject, also sets @@ -1565,15 +1591,7 @@ int CStudioModelRenderer::StudioDrawModel(int flags) } if (!SkipVisCheck) - { - /*if( CMirrorMgr::m_CurrentMirror.Enabled ) - { - Vector Bounds[2] = { m_pCurrentEntity->origin + m_pCurrentEntity->curstate.mins, m_pCurrentEntity->origin + m_pCurrentEntity->curstate.maxs }; - Visible = CheckBBox( Bounds ); //Special vis check on mirrored entities - } - else*/ Visible = IEngineStudio.StudioCheckBBox() ? true : false; - } if (RestoreOrigin) m_pCurrentEntity->origin = m_pCurrentEntity->curstate.origin = OldOrigin; if (!Visible) @@ -1607,24 +1625,40 @@ int CStudioModelRenderer::StudioDrawModel(int flags) cl_entity_t* ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); if (ent) - memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(Vector ) * 4); + memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(Vector) * 4); } } if (flags & STUDIO_RENDER) { //MiB JUN2010_21 - Makes the viewmodels not stick into walls - if (FBitSet(m_pCurrentEntity->curstate.colormap, MSRDR_HANDMODEL)) + bool IsHandModel = FBitSet(m_pCurrentEntity->curstate.colormap, MSRDR_HANDMODEL); + float tmp[2]; + if (IsHandModel) { - float tmp[2]; glGetFloatv(GL_DEPTH_RANGE, tmp); glDepthRange(tmp[0], tmp[0] + 0.3 * (tmp[1] - tmp[0])); + } - StudioRenderModel(); - glDepthRange(tmp[0], tmp[1]); + //Start from what the engine has set when it draws normal entities, whatever the last transparent one left + if (ViewModel_UndoDrawLate(*m_pCurrentEntity)) + { + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + } + + // FULLBRIGHT START + if (StudioGetFullbright(m_pRenderModel)) + { + StudioRenderEntity(false); + StudioRenderEntity(true); } else StudioRenderModel(); + // FULLBRIGHT END + + if (IsHandModel) + glDepthRange(tmp[0], tmp[1]); } } @@ -1732,13 +1766,13 @@ StudioProcessGait */ void CStudioModelRenderer::StudioProcessGait(entity_state_t* pplayer) { - mstudioseqdesc_t* pseqdesc = nullptr; + mstudioseqdesc_t* pseqdesc = NULL; //float frametime; int iBlend = 0; float flYaw = 0; // view direction relative to movement float frametime = 0; - if (m_pCurrentEntity->curstate.sequence >= static_cast(m_pStudioHeader->numseq)) + if (m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq) m_pCurrentEntity->curstate.sequence = 0; pseqdesc = (mstudioseqdesc_t*)((byte*)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; @@ -1817,7 +1851,7 @@ void CStudioModelRenderer::StudioProcessGait(entity_state_t* pplayer) m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; } - if (pplayer->gaitsequence >= static_cast(m_pStudioHeader->numseq)) + if (pplayer->gaitsequence >= m_pStudioHeader->numseq) pplayer->gaitsequence = 0; pseqdesc = (mstudioseqdesc_t*)((byte*)m_pStudioHeader + m_pStudioHeader->seqindex) + pplayer->gaitsequence; @@ -1870,25 +1904,6 @@ int CStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t* pplayer) m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); cl_entity_t& Ent = *m_pCurrentEntity; - /*if( m_pCurrentEntity->player && - m_pCurrentEntity->player == gEngfuncs.GetLocalPlayer()->index && - !MSCLGlobals::CamThirdPerson && - !CMirrorMgr::m_CurrentMirror.Enabled ) - { - //Manually draw the Viewmodel. The engine doesn't draw it because MS always reports thirdperson for mirrors - m_pPlayerInfo = NULL; - DrawEnt = IEngineStudio.GetViewEntity(); - StudioDrawModel( flags ); - - m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); - SetBits( m_pCurrentEntity->curstate.oldbuttons, MSRDR_SKIP ); - //return 0; - }*/ - - if (FBitSet(flags, STUDIO_RENDER)) - if (!CMirrorMgr::Render_StudioModel(m_pCurrentEntity)) - return 0; //Rendering inside of a mirror was cancelled - IEngineStudio.GetTimes(&m_nFrameCount, &m_clTime, &m_clOldTime); IEngineStudio.GetViewInfo(m_vRenderOrigin, m_vUp, m_vRight, m_vNormal); IEngineStudio.GetAliasScale(&m_fSoftwareXScale, &m_fSoftwareYScale); @@ -1913,7 +1928,7 @@ int CStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t* pplayer) return 0; m_pRenderModel = IEngineStudio.SetupPlayerModel(m_nPlayerIndex); - if (m_pRenderModel == nullptr) + if (m_pRenderModel == NULL) return 0; m_pStudioHeader = (studiohdr_t*)IEngineStudio.Mod_Extradata(m_pRenderModel); @@ -1944,7 +1959,7 @@ int CStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t* pplayer) } else { - modelinfo_t* pModelInfo = nullptr; + modelinfo_t* pModelInfo = NULL; if (Ent.HasExtra()) pModelInfo = &CModelMgr::m_ModelInfo[Ent.index]; @@ -2035,7 +2050,7 @@ int CStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t* pplayer) { cl_entity_t* ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); - memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(Vector ) * 4); + memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(Vector) * 4); } } @@ -2108,7 +2123,7 @@ int CStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t* pplayer) //Instead, the bodypart attachmets are rendered -- UNDONE StudioRenderModel(); - m_pPlayerInfo = nullptr; + m_pPlayerInfo = NULL; /* Master Sword - don't render the weaponmodel @@ -2184,7 +2199,9 @@ void CStudioModelRenderer::StudioRenderModel(void) alight_t lighting; Vector lightdir; - gHUD.m_HUDScript->Effects_Render(*m_pCurrentEntity, CMirrorMgr::m_CurrentMirror.Enabled); + // FULLBRIGHT - only run script effects once per frame, not again for the fullbright pass + if (!m_bFullbrightPass) + HUDScript->Effects_Render(*m_pCurrentEntity); lighting.plightvec = lightdir; IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting); @@ -2216,6 +2233,16 @@ void CStudioModelRenderer::StudioRenderModel(void) lighting.shadelight = 100; } + // FULLBRIGHT START + if (m_bFullbrightPass) + { + lighting.ambientlight = 128; + lighting.shadelight = 192; + lighting.color = Vector(255, 255, 255); + lightdir = Vector(0, 0, -1); + } + // FULLBRIGHT END + // model and frame independant IEngineStudio.StudioSetupLighting(&lighting); @@ -2349,15 +2376,6 @@ void CStudioModelRenderer::StudioRenderFinal_Hardware(void) IEngineStudio.GL_SetRenderMode(rendermode); - /*if( CMirrorMgr::m_CurrentMirror.Enabled ) - { - glColorMask( 1, 1, 1, 1 ); - CMirror &Mirror = *CMirrorMgr::m_CurrentMirror.Mirror; - float Alpha = !Mirror.m_Texture->Mirror.NoWorld ? 1 : Mirror.m_Texture->Mirror.Color.a; - gEngfuncs.pTriAPI->Color4f( Mirror.m_Texture->Mirror.Color.r, Mirror.m_Texture->Mirror.Color.g, Mirror.m_Texture->Mirror.Color.b, Alpha ); - //glEnable( GL_BLEND ); - }*/ - IEngineStudio.StudioDrawPoints(); IEngineStudio.GL_StudioDrawShadow(); } @@ -2386,25 +2404,6 @@ void CStudioModelRenderer::StudioSetupRender(bool Setup) { m_DrawStyle = DRAW_DEFAULT; - if (CMirrorMgr::m_CurrentMirror.Enabled) - { - CMirror& Mirror = *CMirrorMgr::m_CurrentMirror.Mirror; - - if (Setup) - { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - Mirror.ApplyTransformation(); - m_DrawStyle = DRAW_BACKFACES; - } - else - { - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } - } - //Master Sword - Flip the model (left-right) the when neccesary if (FBitSet(m_pCurrentEntity->curstate.oldbuttons, MSRDR_FLIPPED)) { @@ -2445,6 +2444,160 @@ void CStudioModelRenderer::StudioRenderFinal(void) StudioSetupRender(false); } + +// FULLBRIGHT START +/* +==================== +StudioGetFullbright + +returns true if model has a fullbright texture +also caches the name if it isnt cached yet +==================== +*/ +bool CStudioModelRenderer::StudioGetFullbright(model_s* pmodel) +{ + if (!pmodel || pmodel->type != mod_studio) + return false; + + // check if this model is already been checked + for (size_t list = 0; list < m_szFullBrightModels.size(); list++) + { + if (!_stricmp(pmodel->name, m_szFullBrightModels[list].c_str())) + { + return true; + } + } + + // check if this model is already on our list + for (size_t list = 0; list < m_szCheckedModels.size(); list++) + { + if (!strcmp(pmodel->name, m_szCheckedModels[list].c_str())) + { + return false; + } + } + + studiohdr_t* pHdr = (studiohdr_t*)IEngineStudio.Mod_Extradata(pmodel); + mstudiotexture_t* pTexture = (mstudiotexture_t*)((byte*)pmodel->cache.data + pHdr->textureindex); + + if (strncmp((const char*)pHdr, "IDST", 4) && strncmp((const char*)pHdr, "IDSQ", 4)) + { + m_szCheckedModels.push_back(pmodel->name); + return false; + } + + bool foundfullbright = false; + if (pHdr->textureindex) + { + for (int i = 0; i < pHdr->numtextures; i++) + { + if (pTexture[i].flags & STUDIO_NF_FULLBRIGHT) + { + foundfullbright = true; + break; + } + } + if (foundfullbright) + { + m_szFullBrightModels.push_back(pmodel->name); + } + } + + m_szCheckedModels.push_back(pmodel->name); + + return foundfullbright; +} + + +/* +==================== +StudioRenderEntity + +if fullbright boolean is true, it renders only the fullbright texture +if false, it renders all non-fullbright textures +==================== +*/ +void CStudioModelRenderer::StudioRenderEntity(bool fullbright) +{ + studiohdr_t* pHdr = (studiohdr_t*)m_pStudioHeader; + mstudiotexture_t* pTexture = (mstudiotexture_t*)((byte*)m_pRenderModel->cache.data + pHdr->textureindex); + + std::vector savedtexture; + + if (pHdr->textureindex > 0) + { + for (int i = 0; i < pHdr->numtextures; i++) + { + savedtexture.push_back(pTexture[i]); + if ((pTexture[i].flags & STUDIO_NF_FULLBRIGHT) != 0) + { + if (!fullbright) + { + pTexture[i].index = g_iBlankTex; + pTexture[i].flags |= STUDIO_NF_ADDITIVE | STUDIO_NF_MASKED; + } + } + else if (fullbright) + { + pTexture[i].index = g_iBlankTex; + pTexture[i].flags |= STUDIO_NF_ADDITIVE | STUDIO_NF_MASKED; + } + } + } + + // StudioRenderModel sets up its own lighting, so tell it which pass this is + m_bFullbrightPass = fullbright; + StudioRenderModel(); + m_bFullbrightPass = false; + + if (pHdr->textureindex > 0) + { + for (int i = 0; i < pHdr->numtextures; i++) + { + memcpy(&pTexture[i], &savedtexture[i], sizeof(mstudiotexture_t)); + } + } +} + +void GenBlackTex() +{ + GLubyte pixels[4] = {0,0,0,0}; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &g_iBlankTex); + glBindTexture(GL_TEXTURE_2D, g_iBlankTex); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +/* +==================== +StudioCacheFullbrightNames + +==================== +*/ +void CStudioModelRenderer::StudioCacheFullbrightNames() +{ + const char* gamedir = gEngfuncs.pfnGetGameDirectory(); + + if (g_iBlankTex == 0) + GenBlackTex(); + + // clear the cache + m_szFullBrightModels.clear(); + m_szCheckedModels.clear(); + + for (int i = 0; i < 512; i++) + { + StudioGetFullbright(IEngineStudio.GetModelByIndex(i)); + } +} + +// FULLBRIGHT END + /* ================== Dogg - FlipModel diff --git a/src/game/client/render/studiomodelrenderer.h b/src/game/client/render/studiomodelrenderer.h index 423ddc559..009306297 100644 --- a/src/game/client/render/studiomodelrenderer.h +++ b/src/game/client/render/studiomodelrenderer.h @@ -110,6 +110,13 @@ class CStudioModelRenderer //Setup the renderer just before rendering the model void StudioSetupRender(bool Setup); + // FULLBRIGHT START + bool StudioGetFullbright(model_s* pmodel); + + void StudioRenderEntity(bool fullbright = false); + void StudioCacheFullbrightNames(); + // FULLBRIGHT END + enum { DRAW_DEFAULT, @@ -179,6 +186,12 @@ class CStudioModelRenderer float m_rgCachedBoneTransform[MAXSTUDIOBONES][3][4]; float m_rgCachedLightTransform[MAXSTUDIOBONES][3][4]; + // FULLBRIGHT START + std::vector m_szCheckedModels; + std::vector m_szFullBrightModels; + bool m_bFullbrightPass = false; // StudioRenderModel uses fullbright lighting while set + // FULLBRIGHT END + // Software renderer scale factors float m_fSoftwareXScale, m_fSoftwareYScale; @@ -221,7 +234,6 @@ class CModelMgr { public: static modelinfo_t m_ModelInfo[4096]; - static int MSStudioDrawModel(int flags, entity_state_t *pplayer); }; #endif // STUDIOMODELRENDERER_H \ No newline at end of file diff --git a/src/game/client/richpresence.cpp b/src/game/client/richpresence.cpp index 677b71e68..623b52d68 100644 --- a/src/game/client/richpresence.cpp +++ b/src/game/client/richpresence.cpp @@ -15,7 +15,7 @@ #include "discord/discord_rpc.h" #include -constexpr float DISCORD_RPC_UPDATE_TIME = 35.0; // sec +#define DISCORD_RPC_UPDATE_TIME 35.0 // sec void CRichPresence::Init(void) { @@ -57,7 +57,7 @@ void CRichPresence::Update(void) { for (int i = 1; i < MAX_PLAYERS; i++) { - if (g_PlayerInfoList[i].name == nullptr) + if (g_PlayerInfoList[i].name == NULL) continue; if (g_PlayerInfoList[i].thisplayer) diff --git a/src/game/client/saytext.cpp b/src/game/client/saytext.cpp index 111305a4e..d4ec5aca4 100644 --- a/src/game/client/saytext.cpp +++ b/src/game/client/saytext.cpp @@ -29,12 +29,12 @@ extern float *GetClientColor( int clientIndex ); -constexpr int MAX_LINES = 5; -constexpr int MAX_CHARS_PER_LINE = 256; /* it can be less than this, depending on char size */ +#define MAX_LINES 5 +#define MAX_CHARS_PER_LINE 256 /* it can be less than this, depending on char size */ // allow 20 pixels on either side of the text -const int MAX_LINE_WIDTH = (ScreenWidth() - 40); -constexpr int LINE_START = 10; +#define MAX_LINE_WIDTH ( ScreenWidth - 40 ) +#define LINE_START 10 static float SCROLL_SPEED = 5; static char g_szLineBuffer[ MAX_LINES + 1 ][ MAX_CHARS_PER_LINE ]; @@ -42,7 +42,7 @@ static float *g_pflNameColors[ MAX_LINES + 1 ]; static int g_iNameLengths[ MAX_LINES + 1 ]; static float flScrollTime = 0; // the time at which the lines next scroll up -const int SAYTEXT_START_Y = (ScreenHeight() - YRES(160)); +#define SAYTEXT_START_Y ( ScreenHeight - YRES(160) ) static int Y_START = 0; //varies static int line_height = 0; @@ -99,7 +99,7 @@ int CHudSayText :: Draw( float flTime ) { int y = Y_START; - if ( ( gViewPort && gViewPort->AllowedToPrintText() == false) || !m_HUD_saytext->value ) + if ( ( gViewPort && gViewPort->AllowedToPrintText() == FALSE) || !m_HUD_saytext->value ) return 1; // make sure the scrolltime is within reasonable bounds, to guard against the clock being reset @@ -184,7 +184,7 @@ int CHudSayText :: MsgFunc_SayText( const char *pszName, int iSize, void *pbuf ) void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex ) { ConsolePrint( pszBuf ); - if ( gViewPort && gViewPort->AllowedToPrintText() == false ) + if ( gViewPort && gViewPort->AllowedToPrintText() == FALSE ) { // Print it straight to the console return; @@ -225,7 +225,7 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn } }*/ - strncpy( g_szLineBuffer[i], pszBuf, V_max(iBufSize -1, MAX_CHARS_PER_LINE - 1) ); + strncpy( g_szLineBuffer[i], pszBuf, V_max(iBufSize -1, MAX_CHARS_PER_LINE-1) ); // make sure the text fits in one line EnsureTextFitsInOneLineAndWrapIfHaveTo( i ); @@ -239,10 +239,10 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn m_iFlags |= HUD_ACTIVE; PlaySound( "misc/talk.wav", 1 ); - //if ( ScreenHeight() >= 480 ) + //if ( ScreenHeight >= 480 ) Y_START = SAYTEXT_START_Y; //else - // Y_START = ScreenHeight() - 45; + // Y_START = ScreenHeight - 45; Y_START -= (line_height * (MAX_LINES+1)); } diff --git a/src/game/client/status_icons.cpp b/src/game/client/status_icons.cpp index 6255b5daa..28141280e 100644 --- a/src/game/client/status_icons.cpp +++ b/src/game/client/status_icons.cpp @@ -54,10 +54,10 @@ int CHudStatusIcons::Draw(float flTime) { // find starting position to draw from, along right-hand side of screen int x = 5; - int y = ScreenHeight() / 2; + int y = ScreenHeight / 2; // loop through icon list, and draw any valid icons drawing up from the middle of screen - for (unsigned int i = 0; i < MAX_ICONSPRITES; i++) + for (int i = 0; i < MAX_ICONSPRITES; i++) { if (m_IconList[i].spr) { @@ -73,7 +73,7 @@ int CHudStatusIcons::Draw(float flTime) // Message handler for StatusIcon message // accepts five values: -// byte : true = ENABLE icon, false = DISABLE icon +// byte : TRUE = ENABLE icon, FALSE = DISABLE icon // string : the sprite name to display // byte : red // byte : green @@ -149,7 +149,7 @@ void CHudStatusIcons::EnableIcon(const char *pszIconName, unsigned char red, uns void CHudStatusIcons::DisableIcon(const char *pszIconName) { // find the sprite is in the current list - for (unsigned int i = 0; i < MAX_ICONSPRITES; i++) + for (int i = 0; i < MAX_ICONSPRITES; i++) { if (!_stricmp(m_IconList[i].szSpriteName, pszIconName)) { diff --git a/src/game/client/statusbar.cpp b/src/game/client/statusbar.cpp index 0fa06298b..e766c5299 100644 --- a/src/game/client/statusbar.cpp +++ b/src/game/client/statusbar.cpp @@ -56,7 +56,7 @@ int CHudStatusBar ::VidInit(void) void CHudStatusBar ::Reset(void) { m_iFlags &= ~HUD_ACTIVE; // start out inactive - for (unsigned int i = 0; i < MAX_STATUSBAR_LINES; i++) + for (int i = 0; i < MAX_STATUSBAR_LINES; i++) m_szStatusText[i][0] = 0; memset(m_iStatusValues, 0, sizeof m_iStatusValues); @@ -166,22 +166,22 @@ int CHudStatusBar ::Draw(float fTime) { if (m_bReparseString) { - for (unsigned int i = 0; i < MAX_STATUSBAR_LINES; i++) + for (int i = 0; i < MAX_STATUSBAR_LINES; i++) ParseStatusString(i); - m_bReparseString = false; + m_bReparseString = FALSE; } // Draw the status bar lines - for (unsigned int i = 0; i < MAX_STATUSBAR_LINES; i++) + for (int i = 0; i < MAX_STATUSBAR_LINES; i++) { int TextHeight, TextWidth; GetConsoleStringSize(m_szStatusBar[i], &TextWidth, &TextHeight); int Y_START; - if (ScreenHeight() >= 480) - Y_START = ScreenHeight() - 55; + if (ScreenHeight >= 480) + Y_START = ScreenHeight - 55; else - Y_START = ScreenHeight() - 45; + Y_START = ScreenHeight - 45; int x = 5; int y = Y_START - (TextHeight * i); // draw along bottom of screen @@ -189,8 +189,8 @@ int CHudStatusBar ::Draw(float fTime) // let user set status ID bar centering if ((i == STATUSBAR_ID_LINE) && CVAR_GET_FLOAT("hud_centerid")) { - x = V_max(0, V_max(2, (ScreenWidth() - TextWidth)) / 2); - y = (ScreenHeight() / 2) + (TextHeight * CVAR_GET_FLOAT("hud_centerid")); + x = V_max(0, V_max(2, (ScreenWidth - TextWidth)) / 2); + y = (ScreenHeight / 2) + (TextHeight * CVAR_GET_FLOAT("hud_centerid")); } DrawConsoleString(x, y, m_szStatusBar[i]); @@ -228,7 +228,7 @@ int CHudStatusBar ::MsgFunc_StatusText(const char *pszName, int iSize, void *pbu else m_iFlags |= HUD_ACTIVE; // we have status text, so turn on the status bar - m_bReparseString = true; + m_bReparseString = TRUE; return 1; } @@ -247,7 +247,7 @@ int CHudStatusBar ::MsgFunc_StatusValue(const char *pszName, int iSize, void *pb m_iStatusValues[index] = READ_SHORT(); - m_bReparseString = true; + m_bReparseString = TRUE; return 1; } \ No newline at end of file diff --git a/src/game/client/text_message.cpp b/src/game/client/text_message.cpp index 8296b8624..5de0cf347 100644 --- a/src/game/client/text_message.cpp +++ b/src/game/client/text_message.cpp @@ -166,7 +166,7 @@ char *ConvertCRtoNL(char *str) // the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#') int CHudTextMessage::MsgFunc_TextMsg(const char *pszName, int iSize, void *pbuf) { - constexpr unsigned int MSG_BUF_SIZE = 128; + #define MSG_BUF_SIZE 128 BEGIN_READ(pbuf, iSize); int msg_dest = READ_BYTE(); @@ -190,7 +190,7 @@ int CHudTextMessage::MsgFunc_TextMsg(const char *pszName, int iSize, void *pbuf) StripEndNewlineFromString(sstr4); char* psz = szBuf[5]; - if (gViewPort && gViewPort->AllowedToPrintText() == false) + if (gViewPort && gViewPort->AllowedToPrintText() == FALSE) return 1; switch (msg_dest) diff --git a/src/game/client/train.cpp b/src/game/client/train.cpp index b0b81e784..0bf0e8a77 100644 --- a/src/game/client/train.cpp +++ b/src/game/client/train.cpp @@ -58,8 +58,8 @@ int CHudTrain::Draw(float fTime) SPR_Set(m_hSprite, r, g, b ); // This should show up to the right and part way up the armor number - y = ScreenHeight() - SPR_Height(m_hSprite,0) - gHUD.m_iFontHeight; - x = ScreenWidth()/3 + SPR_Width(m_hSprite,0)/4; + y = ScreenHeight - SPR_Height(m_hSprite,0) - gHUD.m_iFontHeight; + x = ScreenWidth/3 + SPR_Width(m_hSprite,0)/4; SPR_DrawAdditive( m_iPos - 1, x, y, NULL); diff --git a/src/game/client/tri.cpp b/src/game/client/tri.cpp new file mode 100644 index 000000000..72c742c0c --- /dev/null +++ b/src/game/client/tri.cpp @@ -0,0 +1,72 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// Triangle rendering, if any + +#include "tri.h" +#include "inc_weapondefs.h" +#include "hud.h" +#include "cl_util.h" +#include "render/clenv.h" +#include "hudscript.h" + +// Triangle rendering apis are in gEngfuncs.pTriAPI + +#include "const.h" +#include "entity_state.h" +#include "cl_entity.h" +#include "triangleapi.h" + +//Half-life callback +#define DLLEXPORT EXPORT +extern "C" +{ + void DLLEXPORT HUD_DrawNormalTriangles(void); + void DLLEXPORT HUD_DrawTransparentTriangles(void); +}; + +/* +================= +HUD_DrawNormalTriangles + +Non-transparent triangles-- add them here +================= +*/ +void DLLEXPORT HUD_DrawNormalTriangles() +{ + // RecClDrawNormalTriangles(); + + CEnvMgr::RenderFog(true); + + //gHUD.m_Spectator.DrawOverview(); +} + + +/* +================= +HUD_DrawTransparentTriangles + +Render any triangles with transparent rendermode needs here +================= +*/ +void DLLEXPORT HUD_DrawTransparentTriangles() +{ + // RecClDrawTransparentTriangles(); + + //Before the push, so the black fog is still set after PopHLStates, for the particles and for + //what the engine draws after this (beams). Additive quads show up in the fog color otherwise + CEnvMgr::RenderFog(false); + + CEnvMgr::PushHLStates(); + + CEnvMgr::Think_DrawTransparentTriangles(); + gHUD.m_HUDScript->Effects_DrawTransPararentTriangles(); + + CEnvMgr::PopHLStates(); + + CEnvMgr::RenderParticles(); +} diff --git a/src/game/client/tri.h b/src/game/client/tri.h new file mode 100644 index 000000000..7b9637ef9 --- /dev/null +++ b/src/game/client/tri.h @@ -0,0 +1 @@ +#pragma once \ No newline at end of file diff --git a/src/game/client/ui/ms/vgui_choosecharacter.cpp b/src/game/client/ui/ms/vgui_choosecharacter.cpp index 472294b4c..82edcab71 100644 --- a/src/game/client/ui/ms/vgui_choosecharacter.cpp +++ b/src/game/client/ui/ms/vgui_choosecharacter.cpp @@ -73,7 +73,7 @@ #include "mslogger.h" extern engine_studio_api_t IEngineStudio; -unsigned int ChooseChar_Interface::ServerCharNum = 0; +int ChooseChar_Interface::ServerCharNum = 0; bool ChooseChar_Interface::CentralServer; const char *GenderPanel_MainBtnText[] = @@ -96,7 +96,7 @@ class CAction_SelectOption : public ActionSignal { //protected: CNewCharacterPanel *m_pPanel; - unsigned int m_Option, m_Value; + int m_Option, m_Value; static createchar_t m_NewChar; public: CAction_SelectOption( CNewCharacterPanel *pPanel, int iOption, int iValue ) @@ -116,34 +116,16 @@ class CAction_SelectOption : public ActionSignal { case STG_CHOOSECHAR: { - //Load and send my save character + //Load my save character - if( MSGlobals::ServerSideChar - && m_Option >= ChooseChar_Interface::ServerCharNum ) - return; + if( m_Option >= ChooseChar_Interface::ServerCharNum ) + return; charinfo_t &Char = player.m_CharInfo[m_Value]; - if( Char.Status != CDS_NOTFOUND ) + if( Char.Status != CDS_NOTFOUND ) { - if( Char.Location == LOC_CLIENT && - Char.m_SendStatus != CSS_SENT ) - { - //Local file - - if( Char.m_SendStatus == CSS_DORMANT ) - { - Char.m_SendStatus = CSS_SENDING; - - player.SendChar( Char ); - } - - //RestoreAll( m_Value ); - } - else - { - msstring CharCmd = msstring("char ") + (int)m_Value + "\n"; - ServerCmd( CharCmd ); - } + msstring CharCmd = msstring("char ") + m_Value + "\n"; + ServerCmd( CharCmd ); return; } else @@ -165,7 +147,6 @@ class CAction_SelectOption : public ActionSignal m_NewChar.Name = m_pPanel->Gender_Name; break; case STG_CHOOSEWEAPON: - //if( MSGlobals::ServerSideChar ) { //Create a new character, using the options the user specified. msstring NewCharCmd = "char "; //Command "char" @@ -218,16 +199,7 @@ class CChoose_DeleteChar : public ActionSignal virtual void actionPerformed( Panel* panel ) { if( m_ConfirmState ) - { - if( MSGlobals::ServerSideChar ) - ServerCmd( msstring("char -1 ") + m_pPanel->m_DeleteChar ); - else - { - DeleteChar( m_pPanel->m_DeleteChar ); - player.m_CharInfo[m_pPanel->m_DeleteChar].Status = CDS_NOTFOUND; - m_pPanel->Update( ); - } - } + ServerCmd( msstring("char -1 ") + m_pPanel->m_DeleteChar ); m_pPanel->m_ConfirmPanel->setVisible( false ); } }; @@ -400,9 +372,9 @@ int GetCenteredItemX( int WorkSpaceSizeX, int ItemSizeX, int Items, int SpaceBew // Creation CMenuPanel *CreateNewCharacterPanel( ) { - return new CNewCharacterPanel( 1, true, 0, 0, ScreenWidth(), ScreenHeight()); + return new CNewCharacterPanel( 1, true, 0, 0, ScreenWidth, ScreenHeight); } -CNewCharacterPanel::CNewCharacterPanel( int iTrans, int iRemoveMe, int x, int y, int wide,int tall ) : CMenuPanel( 0, true, x, y, wide, tall ) +CNewCharacterPanel::CNewCharacterPanel( int iTrans, int iRemoveMe, int x, int y, int wide,int tall ) : CMenuPanel( 0, TRUE, x, y, wide, tall ) { SetBits( m_Flags, MENUFLAG_TRAPNUMINPUT ); @@ -480,8 +452,6 @@ CNewCharacterPanel::CNewCharacterPanel( int iTrans, int iRemoveMe, int x, int y, Choose_DeleteChar[i]->setText( Localized("#CHOOSECHAR_DELETE") ); //For Font } - Choose_UploadStatus = new MSLabel( m_ChoosePanel, "", XRES(0), m_ChoosePanel->getTall() - CHOOSE_MAINLBLSIZEY, CHOOSE_SIZEX, CHOOSE_MAINLBLSIZEY, MSLabel::a_center ); - Choose_UploadStatus->SetFGColorRGB( Color_Text_White ); //Confirm character deletion Panel #define CONFIRM_SIZEX XRES(120) @@ -558,7 +528,7 @@ CNewCharacterPanel::CNewCharacterPanel( int iTrans, int iRemoveMe, int x, int y, Gender_GenderLabel->addInputSignal( new GenderInput_ChangeName( this, 1 ) ); StartX = GetCenteredItemX( m_ChoosePanel->getWide(), CHOOSE_BTNWIDTH, 2, XRES(32) ); - for (unsigned int i = 0; i < GENDERPANEL_MAINBTNS; i++) + for (int i = 0; i < GENDERPANEL_MAINBTNS; i++) { int ix = StartX + i * CHOOSE_BTNWIDTH + i * CHOOSE_BTNSPACERX, iy = CHOOSE_BTNY + CHOOSE_CHARHANDLING_H; //int ix = StartX + i * CHOOSE_BTNWIDTH + i * CHOOSE_BTNSPACERX, iy = GENDER_BTNY; @@ -585,7 +555,7 @@ CNewCharacterPanel::CNewCharacterPanel( int iTrans, int iRemoveMe, int x, int y, StartX = GetCenteredItemX( m_ChoosePanel->getWide(), WEAPON_BTN_SIZEX, 3, CHOOSE_BTNSPACERX ); int WeaponPanelSizeY = m_WeaponPanel->getTall( ); - for (unsigned int i = 0; i < WEAPONPANEL_MAINBTNS; i++) + for (int i = 0; i < WEAPONPANEL_MAINBTNS; i++) { if( i >= WEAPONPANEL_MAINBTNMAX ) break; //Max of 9 starting weapon choices @@ -672,20 +642,12 @@ void CNewCharacterPanel::Update() _snprintf(cTemp, sizeof(cTemp), Localized("#CHOOSECHAR_ENTERING"), cTemp2); //Entering: Choose_MainLabel->setText( cTemp ); - if( MSGlobals::ServerSideChar ) - { - cTemp2[0] = 0; - if ((MSGlobals::IsLanGame) && (MSGlobals::ServerSideChar == false)) - _snprintf(cTemp2, sizeof(cTemp2), "\n%s", Localized("#CHOOSECHAR_LAN")); + cTemp2[0] = 0; + if(ChooseChar_Interface::CentralServer) + _snprintf(cTemp2, sizeof(cTemp2), "\n%s", Localized("#CHOOSECHAR_CENTRALNETWORK")); - if(ChooseChar_Interface::CentralServer) - _snprintf(cTemp2, sizeof(cTemp2), "\n%s", Localized("#CHOOSECHAR_CENTRALNETWORK")); - - _snprintf(cTemp, sizeof(cTemp), "%s%s", Localized("#CHOOSECHAR_SERVER"), cTemp2); - Choose_CharHandlingLabel->setText( cTemp ); //Character are stored on the server - } - else - Choose_CharHandlingLabel->setText(Localized("#CHOOSECHAR_LOCAL")); //Character are stored on the client + _snprintf(cTemp, sizeof(cTemp), "%s%s", Localized("#CHOOSECHAR_SERVER"), cTemp2); + Choose_CharHandlingLabel->setText( cTemp ); //Character are stored on the server switch( m_Stage ) { @@ -693,7 +655,7 @@ void CNewCharacterPanel::Update() m_ChoosePanel->setVisible( true ); iButtons = CHOOSEPANEL_MAINBTNS; - for (unsigned int i = 0; i < iButtons; i++) + for (int i = 0; i < iButtons; i++) { //Only certain fields can be assumed valid in this savedata //If client-side characters - all savedata_t info is valid; @@ -705,9 +667,7 @@ void CNewCharacterPanel::Update() if( CharSlot.Status == CDS_NOTFOUND && //No char at this slot and MSGlobals::CanCreateCharOnMap && //Map allows creating characters and - player.m_CharSend.Status == CSS_DORMANT && //Not currently uploading a character and - (!MSGlobals::ServerSideChar || //Characters are client side or - i < ChooseChar_Interface::ServerCharNum) ) //Server allows clients to create at least this many characters + i < ChooseChar_Interface::ServerCharNum ) //Server allows clients to create at least this many characters { //Choose_MainBtn[i]->SetBGColorRGB( NewCharColor ); //Choose_MainBtn[i]->SetFGColorRGB( NewCharColor ); @@ -759,9 +719,6 @@ void CNewCharacterPanel::Update() //Grey out the char if it can't join the map bool GreyedOut = CharSlot.JoinType == JN_NOTALLOWED; - - //Grey out all chars while uploading a char - if( player.m_CharSend.Status != CSS_DORMANT ) GreyedOut = true; msstring model = MODEL_HUMAN_REF; @@ -812,7 +769,7 @@ void CNewCharacterPanel::Update() iButtons = GENDERPANEL_MAINBTNS; break; case STG_CHOOSEWEAPON: - for (unsigned int i = 0; i < WEAPONPANEL_MAINBTNS; i++) + for (int i = 0; i < WEAPONPANEL_MAINBTNS; i++) Weapon_MainBtnImg[i]->LoadImg( ); m_WeaponPanel->setVisible( true ); m_BackBtn->setVisible( true ); @@ -849,7 +806,7 @@ void CNewCharacterPanel::Gender_SelectItem( int Btn ) Gender_CharEnts[0].m_Gender = GENDER_MALE; //Thothie FEB2011_02 gender bender fixes Gender_CharEnts[1].m_Gender = GENDER_FEMALE; //Thothie FEB2011_02 gender bender fixes - for (unsigned int i = 0; i < GENDERPANEL_MAINBTNS; i++) + for (int i = 0; i < GENDERPANEL_MAINBTNS; i++) { Gender_CharEnts[i].SetActive( Btn == 1 ? true : false ); Gender_MainBtn[i]->setEnabled( Btn == 1 ? true : false ); @@ -905,13 +862,13 @@ void CNewCharacterPanel::Close( void ) return; }*/ - for (unsigned int i = 0; i < CHOOSEPANEL_MAINBTNS; i++) + for (int i = 0; i < CHOOSEPANEL_MAINBTNS; i++) { CRenderChar &CharEnt = m_CharEnts[i]; CharEnt.UnRegister( ); } - for (unsigned int i = 0; i < GENDERPANEL_MAINBTNS; i++) + for (int i = 0; i < GENDERPANEL_MAINBTNS; i++) { CRenderChar &CharEnt = Gender_CharEnts[i]; CharEnt.UnRegister( ); @@ -958,7 +915,7 @@ void CNewCharacterPanel::Close( void ) //gViewPort->HideTopMenu( ); //Remove from menu list - for (unsigned int i = 0; i < gViewPort->m_Menus.size(); i++) + for (int i = 0; i < gViewPort->m_Menus.size(); i++) if( gViewPort->m_Menus[i] == this ) { gViewPort->m_Menus.erase( i ); break; } @@ -966,7 +923,7 @@ void CNewCharacterPanel::Close( void ) } //====================================== // Key inputs for the Class Menu -bool CNewCharacterPanel::SlotInput( unsigned int iSlot ) +bool CNewCharacterPanel::SlotInput( int iSlot ) { //Convert iSlot to be zero-based iSlot--; @@ -1013,7 +970,7 @@ void CNewCharacterPanel::Open( void ) CMenuPanel::Open(); - for (unsigned int i = 0; i < CHOOSEPANEL_MAINBTNS; i++) + for (int i = 0; i < CHOOSEPANEL_MAINBTNS; i++) { CRenderChar &CharEnt = m_CharEnts[i]; CharEnt.m_Stage = STG_CHOOSECHAR; @@ -1021,7 +978,7 @@ void CNewCharacterPanel::Open( void ) CharEnt.Init( i ); } - for (unsigned int i = 0; i < GENDERPANEL_MAINBTNS; i++) + for (int i = 0; i < GENDERPANEL_MAINBTNS; i++) { CRenderChar &CharEnt = Gender_CharEnts[i]; CharEnt.m_Stage = STG_CHOOSEGENDER; @@ -1044,22 +1001,6 @@ void CNewCharacterPanel::Initialize( void ) m_pScrollPanel->setScrollValue( 0, 0 ); } -void CNewCharacterPanel::UpdateUpload( ) -{ - if( player.m_CharSend.Status == CSS_SENDING ) - { - Choose_UploadStatus->setVisible( true ); - int Percent = ((float)player.m_CharSend.DataSent / player.m_CharSend.DataLen) * 100; - msstring Text = msstring("Uploading (") + Percent + "%)"; - Choose_UploadStatus->setText( Text.c_str() ); - } - else - { - Choose_UploadStatus->setVisible( false ); - } - -} - void ShowVGUIMenu( int iMenu ); void __CmdFunc_PlayerChooseChar( ) { @@ -1074,9 +1015,7 @@ int __MsgFunc_CharInfo(const char* pszName, int iSize, void* pbuf) BEGIN_READ(pbuf, iSize); //Put my character header info into a global structure, so the choose character panel knows what's what. - //This info comes from the server, if characters are server-side - //If chars are client-side, then this message only comes with Status == CDS_LOADED after I've uploaded a char - //Read data for one character at a time + //This info comes from the server. Read data for one character at a time byte CharMsgType = READ_BYTE(); byte CharIndex = READ_BYTE(); //Which char the info describes @@ -1088,8 +1027,8 @@ int __MsgFunc_CharInfo(const char* pszName, int iSize, void* pbuf) if (CharMsgType == CHAR_TYPE_ITEMS) { - unsigned int GearItems = READ_BYTE(); - for (unsigned int i = 0; i < GearItems; i++) + int GearItems = READ_BYTE(); + for (int i = 0; i < GearItems; i++) { gearinfo_t GearInfo; GearInfo.Flags = READ_BYTE(); @@ -1115,23 +1054,17 @@ int __MsgFunc_CharInfo(const char* pszName, int iSize, void* pbuf) CharSlot.OldTrans = READ_STRING(); CharSlot.NextMap = READ_STRING(); CharSlot.NewTrans = READ_STRING(); - CharSlot.body = READ_SHORT(); //MiB JAN2010_27 - Char Selection Fix + CharSlot.Body = READ_SHORT(); //MiB JAN2010_27 - Char Selection Fix //CharSlot.Race = READ_STRING( ); // MIB FEB2015_21 [RACE_MENU] - Read the character's race byte CharFlags = READ_BYTE(); CharSlot.IsElite = FBitSet(CharFlags, (1 << 0)); CharSlot.Gender = FBitSet(CharFlags, (1 << 1)) ? GENDER_FEMALE : GENDER_MALE; CharSlot.JoinType = FBitSet(CharFlags, (1 << 2)) ? JN_TRAVEL : JN_NOTALLOWED; //Thothie FEB2011_02 - invisible new character fix (default based on gender) - if (CharSlot.body == 0) + if (CharSlot.Body == 0) { - CharSlot.body = 40; - if (CharSlot.Gender == GENDER_FEMALE) CharSlot.body = 80; - } - - if (CharSlot.Location == LOC_CLIENT) - { - CharSlot.m_SendStatus = CSS_SENT; //I just finished sending this char to the server - player.m_CharSend.Status = CSS_DORMANT; + CharSlot.Body = 40; + if (CharSlot.Gender == GENDER_FEMALE) CharSlot.Body = 80; } } } @@ -1149,12 +1082,6 @@ void ChooseChar_Interface::UpdateCharScreen() if (gViewPort && gViewPort->m_pCurrentMenu) ((CNewCharacterPanel*)gViewPort->m_pCurrentMenu)->Update(); } -void ChooseChar_Interface::UpdateCharScreenUpload() -{ - if (MSCLGlobals::CharPanelActive) - if (gViewPort && gViewPort->m_pCurrentMenu) - ((CNewCharacterPanel*)gViewPort->m_pCurrentMenu)->UpdateUpload(); -} //CRenderChar @@ -1178,12 +1105,11 @@ void CRenderChar::Init( int Idx, msstring model ) m_Ent.curstate.scale = CHAR_SCALE; m_Ent.curstate.framerate = 1.0f; SetBits( m_Ent.curstate.effects, EF_NOINTERP ); - SetBits( m_Ent.curstate.oldbuttons, MSRDR_NOREFLECT ); SetBits( m_Ent.curstate.colormap, MSRDR_ASPLAYER ); m_Gender = GENDER_MALE; - for (unsigned int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) m_Ent.latched.prevcontroller[i] = m_Ent.curstate.controller[i] = 127; m_Ent.curstate.gaitsequence = 0; @@ -1225,7 +1151,7 @@ void CRenderChar::Render( ) m_Gear.clear(); uint BodyParts[HUMAN_BODYPARTS] = { 0 }; - for (unsigned int i = 0; i < player.m_CharInfo[m_Idx].GearInfo.size(); i++) + for (int i = 0; i < player.m_CharInfo[m_Idx].GearInfo.size(); i++) { gearinfo_t &GearInfo = player.m_CharInfo[m_Idx].GearInfo[i]; CGenericItem pItem = CGenericItem(); @@ -1240,8 +1166,13 @@ void CRenderChar::Render( ) ItemEnt.curstate.body = GearInfo.Body; ItemEnt.curstate.skin = GearInfo.Skin; ItemEnt.PlayAnim( GearInfo.Anim ); + + // set the body to 0 if it goes into negatives. + if (GearInfo.Body < 0) { + ItemEnt.curstate.body = 0; + } - for (unsigned int i = 0; i < HUMAN_BODYPARTS; i++) + for (int i = 0; i < HUMAN_BODYPARTS; i++) { if( FBitSet( GearInfo.Flags, (1<Click( this, code ) ) { - mouseDoublePressed( code, panel ); + m_Callback->GearItemDoubleClicked( m_Idx ); } else { @@ -74,7 +74,7 @@ class CHandler_GearButton : public InputSignal void mouseReleased(MouseCode code, Panel *panel) {}; void mouseDoublePressed(MouseCode code, Panel *panel) { - m_Callback->GearItemDoubleClicked(m_Idx); + mousePressed(code, panel); }; void cursorExited(Panel *panel) { mpHighlightCallback->mbMouseOver = false; }; void mouseWheeled(int delta, Panel *panel) {}; @@ -91,7 +91,7 @@ VGUI_Inv_GearItem::VGUI_Inv_GearItem(Panel *pContainerParent, VGUI_ItemCallbackP m_ContainerParent = pContainerParent; m_Name = new MSLabel(this, "", 0, 0, getWide(), getTall(), MSLabel::a_center); - m_Name->addInputSignal(m_pSignal = new CHandler_GearButton(pGearCallback, pGearCallback, this, m_Idx)); + m_Name->addInputSignal(m_pSignal = new CHandler_GearButton(pGearCallback, pGearCallback, this, 0)); // Index is set in Update() m_ItemContainer = new VGUI_Container(ITEM_CONTAINER_X, ITEM_CONTAINER_Y, ITEM_CONTAINER_SIZE_X, ITEM_CONTAINER_SIZE_Y, pItemCallbackPanel, pContainerParent); mbMouseOver = false; } @@ -207,17 +207,20 @@ VGUI_Inv_GearItem *VGUI_InventoryPanel::AddGearItem(gearitem_t &GearItem) void VGUI_InventoryPanel::Reset() { //Delete the old - for (unsigned int i = 0; i < GearItemButtonTotal; i++) + for (int i = 0; i < GearItemButtonTotal; i++) GearItemButtons[i]->Reset(); GearItemButtonTotal = 0; + + // Rows are about to be repopulated, possibly with different items + ResetDoubleClick(); } -void VGUI_InventoryPanel::Select(unsigned int Idx) +void VGUI_InventoryPanel::Select(int Idx) { if (Idx < 0 || Idx >= GearItemButtonTotal) return; - for (unsigned int i = 0; i < GearItemButtonTotal; i++) + for (int i = 0; i < GearItemButtonTotal; i++) GearItemButtons[i]->DeSelect(); m_Selected = Idx; @@ -246,7 +249,7 @@ CTFScrollPanel* VGUI_InventoryPanel::GetScrollForStepInput() { if ( mbScrollHighlighted ) return m_Scroll; - for (unsigned int i = 0; i < GearItemButtons.size(); i++) + for (int i = 0; i < GearItemButtons.size(); i++) { if (GearItemButtons[i]->IsMouseOver()) { @@ -343,7 +346,7 @@ void VGUI_ItemInfoPanel::Update(containeritem_t &Item) } // Creation -VGUI_ContainerPanel::VGUI_ContainerPanel() : CMenuPanel(100, false, 0, 0, ScreenWidth(), ScreenHeight()), VGUI_ItemCallbackPanel() +VGUI_ContainerPanel::VGUI_ContainerPanel() : CMenuPanel(100, FALSE, 0, 0, ScreenWidth, ScreenHeight), VGUI_ItemCallbackPanel() { COLOR Color_TitleText = COLOR(255, 100, 100, 0), Color_SubtitleText = COLOR(160, 160, 160, 0), @@ -412,7 +415,7 @@ void VGUI_ContainerPanel::Update() void VGUI_ContainerPanel::AddInventoryItems() { gearitem_t GearItem; - const unsigned int gearSize = player.Gear.size(); + const int gearSize = player.Gear.size(); std::vector sortedItems; std::vector sortedOther; sortedItems.reserve(gearSize); @@ -422,7 +425,7 @@ void VGUI_ContainerPanel::AddInventoryItems() GearItem.ID = 0; GearItem.IsContainer = true; VGUI_Inv_GearItem *pGearItemButton = m_GearPanel->AddGearItem(GearItem); - for (unsigned int i = 0; i < MAX_PLAYER_HANDS; i++) + for (int i = 0; i < MAX_PLAYER_HANDS; i++) { if (player.Hand(i)) { @@ -431,7 +434,7 @@ void VGUI_ContainerPanel::AddInventoryItems() } } - for (unsigned int i = 0; i < gearSize; i++) + for (int i = 0; i < gearSize; i++) { CGenericItem *pGearItem = player.Gear[i]; const auto props = pGearItem->MSProperties(); // cache property lookup @@ -530,7 +533,7 @@ VGUI_InvTypePanel::VGUI_InvTypePanel(Panel *pParent, VGUI_Container *pCallback) pAlphaCheckBox->SetHandler(new AlphabetizeCheckBoxHandler(pCallback)); addChild(pAlphaCheckBox); - for (unsigned int i = 0; i < INVTYPE_BUTTONS_TOTAL; i++) + for (int i = 0; i < INVTYPE_BUTTONS_TOTAL; i++) { int x = 0, y; @@ -554,6 +557,10 @@ VGUI_InvTypePanel::VGUI_InvTypePanel(Panel *pParent, VGUI_Container *pCallback) void VGUI_ContainerPanel::Open(void) { + // Don't let a click from before the menu was opened count towards a double-click + ResetDoubleClick(); + m_GearPanel->ResetDoubleClick(); + // Update before opening m_AllowUpdate = true; Update(); @@ -565,11 +572,13 @@ void VGUI_ContainerPanel::Close(void) player.BlockButton(IN_ATTACK); m_pCancelButton->setArmed(false); //If the user presses cancel, the cancel button doesn't automaticaly get unarmed... so manually do it m_ActButton->setArmed(false); + ResetDoubleClick(); + m_GearPanel->ResetDoubleClick(); CMenuPanel::Close(); m_AllowUpdate = false; } -bool VGUI_ContainerPanel::SlotInput(unsigned int iSlot) +bool VGUI_ContainerPanel::SlotInput(int iSlot) { iSlot--; @@ -601,10 +610,10 @@ void VGUI_ContainerPanel::ItemHighlighted(void *pData) bool VGUI_ContainerPanel::HasSelectedItems() { - for(unsigned int i = 0; i < m_GearPanel->GearItemButtonTotal; i++) + for(int i = 0; i < m_GearPanel->GearItemButtonTotal; i++) { VGUI_Inv_GearItem &GearItem = *m_GearPanel->GearItemButtons[i]; - for(unsigned int g = 0; g < GearItem.m_ItemContainer->m_ItemButtonTotal; g++) + for(int g = 0; g < GearItem.m_ItemContainer->m_ItemButtonTotal; g++) { VGUI_ItemButton &ItemButton = *GearItem.m_ItemContainer->m_ItemButtons[g]; if(ItemButton.m_Selected) @@ -619,10 +628,10 @@ void VGUI_ContainerPanel::GetSelectedItems(mslist &SelectedIt { SelectedItems.clear(); - for (unsigned int g = 0; g < m_GearPanel->GearItemButtonTotal; g++) + for (int g = 0; g < m_GearPanel->GearItemButtonTotal; g++) { VGUI_Inv_GearItem &GearItem = *m_GearPanel->GearItemButtons[g]; - for (unsigned int i = 0; i < GearItem.m_ItemContainer->m_ItemButtonTotal; i++) + for (int i = 0; i < GearItem.m_ItemContainer->m_ItemButtonTotal; i++) { VGUI_ItemButton &ItemButton = *GearItem.m_ItemContainer->m_ItemButtons[i]; if (!ItemButton.m_Selected) @@ -636,6 +645,6 @@ void VGUI_ContainerPanel::UnSelectAllItems() { mslist SelectedItems; GetSelectedItems(SelectedItems); - for (unsigned int i = 0; i < SelectedItems.size(); i++) + for (int i = 0; i < SelectedItems.size(); i++) SelectedItems[i]->Select(false); } \ No newline at end of file diff --git a/src/game/client/ui/ms/vgui_container.h b/src/game/client/ui/ms/vgui_container.h index c97627e8a..a98c378a1 100644 --- a/src/game/client/ui/ms/vgui_container.h +++ b/src/game/client/ui/ms/vgui_container.h @@ -16,7 +16,7 @@ #define ITEM_CONTAINER_X (GEARPNL_X + GEARPNL_SIZE_X) + CONTAINERMENU_SPACER_X #define ITEM_CONTAINER_Y GEARPNL_Y -#define ITEM_CONTAINER_SIZE_X (ScreenWidth() - (ITEM_CONTAINER_X + CONTAINERMENU_SPACER_X)) +#define ITEM_CONTAINER_SIZE_X (ScreenWidth - (ITEM_CONTAINER_X + CONTAINERMENU_SPACER_X)) #define ITEM_CONTAINER_SIZE_Y YRES(340) #define ACTBTN_SIZE_X XRES(130) @@ -61,9 +61,9 @@ class VGUI_InventoryPanel : public CTransparentPanel, public VGUI_ItemCallbackPa { public: mslist GearItemButtons; - unsigned int GearItemButtonTotal; + int GearItemButtonTotal; int m_Selected; - unsigned int m_InitializedItemButtons; + int m_InitializedItemButtons; VGUI_ItemCallbackPanel *m_pCallbackPanel; CTFScrollPanel *m_Scroll; bool mbScrollHighlighted; @@ -71,7 +71,7 @@ class VGUI_InventoryPanel : public CTransparentPanel, public VGUI_ItemCallbackPa VGUI_InventoryPanel(VGUI_ItemCallbackPanel *pCallbackPanel, Panel *pParent); virtual VGUI_Inv_GearItem *AddGearItem(gearitem_t &GearItem); - virtual void Select(unsigned int Idx); + virtual void Select(int Idx); virtual void Reset(); //Callbacks @@ -118,7 +118,7 @@ class VGUI_ContainerPanel : public CMenuPanel, public VGUI_ItemCallbackPanel virtual void Close(void); virtual void Update(void); virtual void Initialize(void); - virtual bool SlotInput(unsigned int iSlot); + virtual bool SlotInput(int iSlot); //Callbacks virtual void ItemHighlighted(void* pData); diff --git a/src/game/client/ui/ms/vgui_containerlist.cpp b/src/game/client/ui/ms/vgui_containerlist.cpp index 1892b5e1a..929217ad9 100644 --- a/src/game/client/ui/ms/vgui_containerlist.cpp +++ b/src/game/client/ui/ms/vgui_containerlist.cpp @@ -169,7 +169,7 @@ void CContainerPanel::DropAllSelected() { mslist vSelectedItems; GetSelectedItems( vSelectedItems ); - for(unsigned int i = 0; i < vSelectedItems.size(); i++) + for(int i = 0; i < vSelectedItems.size(); i++) { ServerCmd( msstring("drop ") + (int)vSelectedItems[i]->m_Data.ID + "\n" ); } @@ -293,13 +293,13 @@ bool CContainerPanel::GearItemClicked(ulong ID) //Extract the IDs of the selected items. I can't keep the list of selected items because the itembuttons get //modified when I start moving items around /*mslist SelectedIDs; - for (unsigned int i = 0; i < SelectedItems.size(); i++) + for (int i = 0; i < SelectedItems.size(); i++) { SelectedIDs.push_back( SelectedItems[i]->m_Data.ID ); SelectedItems[i]->Select( false ); }*/ - for (unsigned int i = 0; i < SelectedItems.size(); i++) + for (int i = 0; i < SelectedItems.size(); i++) { CGenericItem *pItem = MSUtil_GetItemByID(SelectedItems[i]->m_Data.ID, &player); if (!pItem) @@ -358,7 +358,7 @@ void CContainerPanel::Open(void) VGUI_ContainerPanel::Open(); //Select the open pack - for (unsigned int i = 0; i < m_GearPanel->GearItemButtonTotal; i++) + for (int i = 0; i < m_GearPanel->GearItemButtonTotal; i++) { if (player.HasConditions(MONSTER_OPENCONTAINER)) { diff --git a/src/game/client/ui/ms/vgui_eventconsole.h b/src/game/client/ui/ms/vgui_eventconsole.h index 2ce308ef5..b8214231c 100644 --- a/src/game/client/ui/ms/vgui_eventconsole.h +++ b/src/game/client/ui/ms/vgui_eventconsole.h @@ -89,7 +89,7 @@ class VGUI_EventConsole : public Panel m_ScrollBarWidth = m_ScrollPanel->getVerticalScrollBar()->getWide(); int ScrollClientWidth = m_ScrollPanel->getWide() - m_ScrollBarWidth; - for (unsigned int i = 0; i < EVENTCON_PREF_MAXLINES; i++) + for (int i = 0; i < EVENTCON_PREF_MAXLINES; i++) { m_Line[i] = new EventConsoleText( 0, 0, ScrollClientWidth, EVENTCON_LINE_SIZE_Y, NULL ); if( TextFont ) @@ -109,7 +109,7 @@ class VGUI_EventConsole : public Panel if (!Text || !Text[0]) return; - unsigned int MaxLines = V_min(EVENTCON_PREF_MAXLINES, EVENTCON_MAXLINES); + int MaxLines = V_min(EVENTCON_PREF_MAXLINES, EVENTCON_MAXLINES); if( m_TotalLines >= MaxLines ) { @@ -121,7 +121,7 @@ class VGUI_EventConsole : public Panel } // The newest line is always at logical index (m_TotalLines - 1) - unsigned int iNewLine = m_TotalLines - 1; + int iNewLine = m_TotalLines - 1; // If the active line was tracking the bottom, keep it there if( m_ActiveLine >= (iNewLine - 1) ) @@ -129,7 +129,7 @@ class VGUI_EventConsole : public Panel // Reposition all active lines in the scroll panel // (VGUI needs the panels laid out top-to-bottom by logical order) - for (unsigned int i = 0; i < m_TotalLines; i++) + for( int i = 0; i < m_TotalLines; i++ ) { EventConsoleText *line = GetLine(i); line->setParent( m_ScrollPanel->getClient() ); @@ -150,11 +150,11 @@ class VGUI_EventConsole : public Panel char ctemp[512] = ""; int w, h; - unsigned int MaxWidth = NewLine.getWide(); - unsigned int MaxHeight = EVENTCON_LINE_SIZE_Y; + int MaxWidth = NewLine.getWide(); + int MaxHeight = EVENTCON_LINE_SIZE_Y; NewLine.getTextImage()->getFont()->getTextSize( ThisLineText, w, h ); - if( (unsigned int)w > MaxWidth || (unsigned int)h > MaxHeight ) + if( w > MaxWidth || h > MaxHeight ) { int TextLen = (int)strlen(Text); int WrapPos = -1; @@ -170,7 +170,7 @@ class VGUI_EventConsole : public Panel ctemp[mid + 1] = 0; int testw, testh; NewLine.getTextImage()->getFont()->getTextSize( ctemp, testw, testh ); - if( (unsigned int)testw > MaxWidth || (unsigned int)testh > MaxHeight ) + if( testw > MaxWidth || testh > MaxHeight ) hi = mid; else lo = mid + 1; @@ -258,7 +258,7 @@ class VGUI_EventConsole : public Panel if( m_DynamicWidth ) { w = 0; - for (unsigned int i = 0; i < m_VisibleLines; i++) + for (int i = 0; i < m_VisibleLines; i++) { int logIdx = m_ActiveLine - i; EventConsoleText *line = GetLine(logIdx); @@ -303,7 +303,7 @@ class VGUI_EventConsole : public Panel m_VisibleLines--; Resize( ); - int TopLine = V_max( m_ActiveLine - (m_VisibleLines - 1), (unsigned int)0 ); + int TopLine = V_max( m_ActiveLine - (m_VisibleLines - 1), 0 ); EventConsoleText *topLine = GetLine(TopLine); if (topLine != nullptr && !topLine->m_SpansFromPrevLine) @@ -337,7 +337,7 @@ class VGUI_EventConsole : public Panel CTFScrollPanel *m_ScrollPanel; EventConsoleText *m_Line[EVENTCON_MAXLINES]; int m_Head; // index of the oldest (logical 0) line - unsigned int m_VisibleLines, + int m_VisibleLines, m_TotalLines, m_ActiveLine, m_StartY, diff --git a/src/game/client/ui/ms/vgui_health.h b/src/game/client/ui/ms/vgui_health.h index eb23611de..48afdd255 100644 --- a/src/game/client/ui/ms/vgui_health.h +++ b/src/game/client/ui/ms/vgui_health.h @@ -6,7 +6,7 @@ #include "vgui_ihud.h" //Scales flasks down to only 40% wide of the screen if sprites are too big -#define BAR_SCALE (1.0f - ((730 - (ScreenWidth() * 0.40f)) / ScreenHeight())) +#define BAR_SCALE (1.0f - ((730 - (ScreenWidth * 0.40f)) / ScreenHeight)) #define BAR_W (320 * BAR_SCALE) #define BAR_H (40 * BAR_SCALE) @@ -144,7 +144,7 @@ namespace PrimaryHUD public: //Main HUD Image - VGUI_Health(Panel* pParent) : Panel(0, 0, ScreenWidth(), ScreenHeight()) + VGUI_Health(Panel* pParent) : Panel(0, 0, ScreenWidth, ScreenHeight) { CHARGE_W = XRES(30); CHARGE_H = YRES(6); @@ -157,7 +157,7 @@ namespace PrimaryHUD float coords[2]; coords[0] = 10; //x - coords[1] = (ScreenHeight() - (2 * BAR_H) - YRES(10)); //y, from the bottom of the screen, as high as the sprites are + coords[1] = (ScreenHeight - (2 * BAR_H) - YRES(10)); //y, from the bottom of the screen, as high as the sprites are // Status Bars @@ -179,7 +179,7 @@ namespace PrimaryHUD m_HUDImage.setPos(coords[0] + BAR_W, coords[1] - (7 * BAR_SCALE)); //Charge system - for (unsigned int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { int Multiplier = (i == 0) ? -1 : 1; float OffsetW = CHARGE_SPACER_W + (i == 0) ? CHARGE_W : 0; @@ -196,14 +196,14 @@ namespace PrimaryHUD void Update() { //Update flasks - for (unsigned int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) m_Bar[i]->Update(); bool bShowHealth = ShowHealth(); m_HUDImage.setVisible(bShowHealth); - for (unsigned int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { m_Charge[i]->setVisible(false); m_ChargeLbl[i]->setVisible(false); @@ -213,7 +213,7 @@ namespace PrimaryHUD std::vector *vHandsItems = new std::vector; //get all hands items - for (unsigned int i = 0; i < player.Gear.size(); i++) + for (int i = 0; i < player.Gear.size(); i++) { CGenericItem* Item = player.Gear[i]; if (Item->m_Location != ITEMPOS_HANDS) @@ -222,7 +222,7 @@ namespace PrimaryHUD vHandsItems->push_back(Item); } - for (unsigned int i = 0; i < vHandsItems->size(); i++) + for (int i = 0; i < vHandsItems->size(); i++) { CGenericItem* Item = vHandsItems->at(i); diff --git a/src/game/client/ui/ms/vgui_healthretro.h b/src/game/client/ui/ms/vgui_healthretro.h index 7d5bb1e98..d6f62b7c4 100644 --- a/src/game/client/ui/ms/vgui_healthretro.h +++ b/src/game/client/ui/ms/vgui_healthretro.h @@ -6,6 +6,7 @@ #define FLASK_W YRES(64 * 0.625) //I want 64x104 in 1024x768 res, and smaller in lower res #define FLASK_H YRES(104 * 0.625) +#define STONE_PX(x) YRES((x) * 0.625) //A pixel of the 192x192 hud_stone sprite, at the same scale as the flasks namespace RetroHUD { @@ -97,7 +98,9 @@ namespace RetroHUD class VGUI_Health : public Panel, public IHUD { private: - int FLASK_SPACER = 0; + int HUD_X = 0; + int HUD_Y = 0; + int HUD_SIZE = 0; int FLASK_START_X = 0; int FLASK_START_Y = 0; @@ -109,9 +112,11 @@ namespace RetroHUD int STAMINA_SIZE_Y = 0; int STAMINA_LBL_SIZE_Y = 0; + int WEIGHT_Y = 0; int WEIGHT_SIZE_Y = 0; int WEIGHT_LBL_SIZE_Y = 0; + int CHARGE_Y = 0; int CHARGE_W = 0; int CHARGE_H = 0; int CHARGE_SPACER_W = 0; @@ -136,23 +141,30 @@ namespace RetroHUD VGUI_Image3D m_HUDImage; public: - VGUI_Health(Panel *pParent) : Panel(0, 0, ScreenWidth(), ScreenHeight()) + VGUI_Health(Panel *pParent) : Panel(0, 0, ScreenWidth, ScreenHeight) { - FLASK_SPACER = XRES(10); + //Everything is positioned in hud_stone sprite pixels, so it lines up with the background at any resolution + HUD_SIZE = STONE_PX(192); + HUD_X = XRES(30) - STONE_PX(24); + HUD_Y = ScreenHeight - HUD_SIZE; - FLASK_START_X = XRES(30); - FLASK_START_Y = YRES(480) - YRES(30) - FLASK_H; - MANA_FLASK_X = FLASK_START_X + FLASK_W + FLASK_SPACER; + //Flasks stand on the ledge, above the bar slot + FLASK_START_X = HUD_X + STONE_PX(24); + FLASK_START_Y = HUD_Y + STONE_PX(41); + MANA_FLASK_X = HUD_X + STONE_PX(104); + //The bar slot is 144x35 at (24, 152) in the sprite. Stamina takes the top 19 rows, weight the bottom 16 STAMINA_X = FLASK_START_X; - STAMINA_Y = YRES(453); - STAMINA_SIZE_X = FLASK_W + FLASK_SPACER + FLASK_W; - STAMINA_SIZE_Y = YRES(12); + STAMINA_Y = HUD_Y + STONE_PX(152); + WEIGHT_Y = HUD_Y + STONE_PX(171); + STAMINA_SIZE_X = (HUD_X + STONE_PX(168)) - STAMINA_X; + STAMINA_SIZE_Y = WEIGHT_Y - STAMINA_Y; STAMINA_LBL_SIZE_Y = YRES(10); - WEIGHT_SIZE_Y = YRES(10); + WEIGHT_SIZE_Y = (HUD_Y + STONE_PX(187)) - WEIGHT_Y; WEIGHT_LBL_SIZE_Y = WEIGHT_SIZE_Y; + CHARGE_Y = YRES(453); CHARGE_W = XRES(30); CHARGE_H = YRES(6); CHARGE_SPACER_W = XRES(2); @@ -161,11 +173,9 @@ namespace RetroHUD SetBGColorRGB(Color_Transparent); m_HUDImage.setParent(this); - // TODO: make the new hud image scale with the resolution. - // m_HUDImage.LoadImg("hud_main3", true, false); - // m_HUDImage.setFgColor(255, 255, 255, 255); - // m_HUDImage.setSize(256, 256); - // m_HUDImage.setPos(0, ScreenHeight() - 256); + m_HUDImage.LoadImg("hud/hud_stone", false, false); + m_HUDImage.setSize(HUD_SIZE, HUD_SIZE); + m_HUDImage.setPos(HUD_X, HUD_Y); //Health and mana flasks m_Flask[0] = new VGUI_Flask(this, 0, FLASK_START_X, FLASK_START_Y); @@ -182,7 +192,7 @@ namespace RetroHUD COLOR WeightColor(250, 150, 0, 100); - m_pWeight = new CStatusBar(this, STAMINA_X, STAMINA_Y + STAMINA_SIZE_Y, STAMINA_SIZE_X, WEIGHT_SIZE_Y); + m_pWeight = new CStatusBar(this, STAMINA_X, WEIGHT_Y, STAMINA_SIZE_X, WEIGHT_SIZE_Y); m_pWeight->m_fBorder = false; m_pWeight->SetFGColorRGB(WeightColor); @@ -191,15 +201,15 @@ namespace RetroHUD pLabel->SetFGColorRGB(Color_Text_White); //Charge system - for (unsigned int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { int Multiplier = (i == 0) ? -1 : 1; float OffsetW = CHARGE_SPACER_W + (i == 0) ? CHARGE_W : 0; - m_Charge[i] = new CStatusBar(this, XRES(320) + OffsetW * Multiplier, STAMINA_Y, CHARGE_W, CHARGE_H); + m_Charge[i] = new CStatusBar(this, XRES(320) + OffsetW * Multiplier, CHARGE_Y, CHARGE_W, CHARGE_H); m_Charge[i]->SetBGColorRGB(COLOR(128, 128, 128, 100)); //m_Charge[i]->m_fBorder = false; m_Charge[i]->setVisible(false); - m_ChargeLbl[i] = new MSLabel(this, "0/0", XRES(320) + OffsetW * Multiplier, STAMINA_Y, CHARGE_W, CHARGE_H, MSLabel::a_center); + m_ChargeLbl[i] = new MSLabel(this, "0/0", XRES(320) + OffsetW * Multiplier, CHARGE_Y, CHARGE_W, CHARGE_H, MSLabel::a_center); m_ChargeLbl[i]->setVisible(false); } } @@ -208,7 +218,7 @@ namespace RetroHUD void Update() { //Update Health & Mana flasks - for (unsigned int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) m_Flask[i]->Update(); bool bShowHealth = ShowHealth(); @@ -229,7 +239,7 @@ namespace RetroHUD m_pWeight->Set(player.Weight(), player.Volume()); - for (unsigned int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { m_Charge[i]->setVisible(false); m_ChargeLbl[i]->setVisible(false); @@ -239,7 +249,7 @@ namespace RetroHUD std::vector *vHandsItems = new std::vector; //get all hands items - for (unsigned int i = 0; i < player.Gear.size(); i++) + for (int i = 0; i < player.Gear.size(); i++) { CGenericItem* Item = player.Gear[i]; if (Item->m_Location != ITEMPOS_HANDS) @@ -248,7 +258,7 @@ namespace RetroHUD vHandsItems->push_back(Item); } - for (unsigned int i = 0; i < vHandsItems->size(); i++) + for (int i = 0; i < vHandsItems->size(); i++) { CGenericItem* Item = vHandsItems->at(i); diff --git a/src/game/client/ui/ms/vgui_hud.cpp b/src/game/client/ui/ms/vgui_hud.cpp index 9d4df689d..4dd859abb 100644 --- a/src/game/client/ui/ms/vgui_hud.cpp +++ b/src/game/client/ui/ms/vgui_hud.cpp @@ -118,6 +118,7 @@ class CHUDPanel : public VGUI_MainPanel void AddInfoWin(const char* Title, const char* Text); void AddHelpWin(const char* Title, const char* Text); + void AddTutorialWin(const char* Title, const char* Text); void Cleanup(); void UpdateInfoWindows(std::vector& Windows); void RemoveInfoWindow(std::vector& Windows, int idx); @@ -151,7 +152,7 @@ class CHUDPanel : public VGUI_MainPanel VGUI_MainPanel* CreateHUDPanel(Panel* pParent) { return new CHUDPanel(pParent); } -CHUDPanel::CHUDPanel(Panel* pParent) : VGUI_MainPanel(0, 0, 0, ScreenWidth(), ScreenHeight()) +CHUDPanel::CHUDPanel(Panel* pParent) : VGUI_MainPanel(0, 0, 0, ScreenWidth, ScreenHeight) { setParent(pParent); @@ -211,12 +212,12 @@ CHUDPanel::~CHUDPanel() delete m_StartSayText; delete m_DebugText; - for(unsigned int i = 0; i < m_HUDElements.size(); i++) + for(int i = 0; i < m_HUDElements.size(); i++) { delete m_HUDElements[i]; } - for(unsigned int i = 0; i < m_Consoles.size(); i++) + for(int i = 0; i < m_Consoles.size(); i++) { delete m_Consoles[i]; } @@ -241,12 +242,12 @@ void CHUDPanel::Cleanup() delete m_StartSayText; delete m_DebugText; - for(unsigned int i = 0; i < m_HUDElements.size(); i++) + for(int i = 0; i < m_HUDElements.size(); i++) { delete m_HUDElements[i]; } - for(unsigned int i = 0; i < m_Consoles.size(); i++) + for(int i = 0; i < m_Consoles.size(); i++) { delete m_Consoles[i]; } @@ -276,15 +277,37 @@ void CHUDPanel::AddInfoWin(const char* Title, const char* Text) } // Create new Help window - void CHUDPanel::AddHelpWin(const char* Title, const char* Text) +{ + //Replaces '|' with '\n' + int size = strlen(Text); + for (int i = 0; i < size; i++) + { + if (Text[i] == '|') + ((char*)Text)[i] = '\n'; + } + + //CInfoWindow &NewInfoWin = *new CInfoWindow( Title, Text, INFOWIN_HELP_DISPLAY_X, INFOWIN_HELP_DISPLAY_Y, this ); + CInfoWindow& NewInfoWin = *new CInfoWindow(Title, Text, INFOWIN_HELP_DISPLAY_X, YRES(10), this); //MAR2008a - moving helptip window not to overlap eventhud + + NewInfoWin.Resize(); + //NewInfoWin.setPos( XRES(640) - NewInfoWin.getWide()- XRES(60), INFOWIN_HELP_DISPLAY_Y ); + NewInfoWin.setPos(XRES(640) - NewInfoWin.getWide() - XRES(60), YRES(10)); //MAR2008a - moving helptip window not to overlap eventhud + NewInfoWin.Title->setFgColor(0, 150, 200, 0); + NewInfoWin.m_TimeDisplayed = gpGlobals->time; + NewInfoWin.m_Duration = INFOWIN_DURATION + (strlen(Text) / 60.0f); + NewInfoWin.setVisible(false); + m_HelpWindows.push_back(&NewInfoWin); +} + +void CHUDPanel::AddTutorialWin(const char* Title, const char* Text) { if (!EngineFunc::CVAR_GetFloat("ms_help")) return; //Replaces '|' with '\n' - unsigned int size = strlen(Text); - for (unsigned int i = 0; i < size; i++) + int size = strlen(Text); + for (int i = 0; i < size; i++) { if (Text[i] == '|') ((char*)Text)[i] = '\n'; @@ -325,7 +348,7 @@ void CHUDPanel::Think() m_ID->Update(); //Update HUD Elements - for (unsigned int i = 0; i < m_HUDElements.size(); i++) + for (int i = 0; i < m_HUDElements.size(); i++) { msstring d = "HUD Elements loop: "; d += i; @@ -347,7 +370,7 @@ void CHUDPanel::Think() UpdateInfoWindows(m_HelpWindows); //Update Help windows //Update Text Consoles - for (unsigned int i = 0; i < m_Consoles.size(); i++) + for (int i = 0; i < m_Consoles.size(); i++) { msstring d = "Text Consoles: "; d += i; @@ -433,59 +456,88 @@ int __MsgFunc_HUDInfoMsg(const char* pszName, int iSize, void* pbuf) msstring sText; byte Type = READ_BYTE(); - if (!Type) - { - //Display info window - msstring sTitle = READ_STRING(); - sText = Localized(READ_STRING()); - - HUD_ShowInfoWin(sTitle, sText); - } - else if (Type == 1) - { - //Print to Event console - ulong lColor = READ_LONG(); - Color color(((uchar*)&lColor)[0], ((uchar*)&lColor)[1], ((uchar*)&lColor)[2], ((uchar*)&lColor)[3]); - sText = READ_STRING(); - - HUD_PrintEvent(color, sText); - } - else if (Type == 2) - { - //Help window part - int idx = READ_BYTE(); - if (!idx) - HelpParts.clear(); - HelpParts.add(READ_STRING()); - } - else if (Type == 3) - { - //Print to help window - msstring sTitle = READ_STRING(); - - std::string buffer = ""; - for (unsigned int i = 0; i < HelpParts.size(); i++) - buffer += static_cast(HelpParts[i]); - - HUD_ShowHelpWin(sTitle, buffer.c_str()); - } - else if (Type == 4) - { - //Print to saytext console - saytext_e TextType = (saytext_e)READ_BYTE(); - sText = READ_STRING(); - Color color(255, 255, 255, 0); - if (TextType == SAYTEXT_GLOBAL) - color = Color(255, 255, 255, 0); - else if (TextType == SAYTEXT_LOCAL) - color = Color(255, 178, 0, 0); - else if (TextType == SAYTEXT_PARTY) - color = Color(60, 200, 20, 0); - else if (TextType == SAYTEXT_NPC) - color = Color(255, 178, 0, 0); - - HUD_SayTextEvent(color, sText); + switch(Type) { + case 0: + { + //Display info window + msstring sTitle = READ_STRING(); + sText = Localized(READ_STRING()); + + HUD_ShowInfoWin(sTitle, sText); + break; + } + case 1: + { + //Print to Event console + ulong lColor = READ_LONG(); + Color color(((uchar*)&lColor)[0], ((uchar*)&lColor)[1], ((uchar*)&lColor)[2], ((uchar*)&lColor)[3]); + sText = READ_STRING(); + + HUD_PrintEvent(color, sText); + break; + } + case 2: + { + //Help window part + int idx = READ_BYTE(); + if (!idx) + HelpParts.clear(); + HelpParts.add(READ_STRING()); + break; + } + case 3: + { + //Print to help window + msstring sTitle = READ_STRING(); + + std::string buffer = ""; + for (int i = 0; i < HelpParts.size(); i++) + buffer += static_cast(HelpParts[i]); + + HUD_ShowHelpWin(sTitle, buffer.c_str()); + break; + } + case 4: + { + //Print to saytext console + saytext_e TextType = (saytext_e)READ_BYTE(); + sText = READ_STRING(); + Color color(255, 255, 255, 0); + if (TextType == SAYTEXT_GLOBAL) + color = Color(255, 255, 255, 0); + else if (TextType == SAYTEXT_LOCAL) + color = Color(255, 178, 0, 0); + else if (TextType == SAYTEXT_PARTY) + color = Color(60, 200, 20, 0); + else if (TextType == SAYTEXT_NPC) + color = Color(255, 178, 0, 0); + + HUD_SayTextEvent(color, sText); + break; + } + case 5: + { + //Help window part + int idx = READ_BYTE(); + if (!idx) + HelpParts.clear(); + HelpParts.add(READ_STRING()); + break; + } + case 6: + { + //Print to help window + msstring sTitle = READ_STRING(); + + std::string buffer = ""; + for (int i = 0; i < HelpParts.size(); i++) + buffer += static_cast(HelpParts[i]); + + HUD_ShowTutorialWin(sTitle, buffer.c_str()); + break; + } } + return 0; } @@ -565,6 +617,14 @@ void HUD_ShowHelpWin(const char* Title, const char* Text) ((CHUDPanel*)gViewPort->m_pHUDPanel)->AddHelpWin(Title, Text); } +void HUD_ShowTutorialWin(const char* Title, const char* Text) +{ + if (!gViewPort || !gViewPort->m_pHUDPanel || !ShowHUD()) + return; + + ((CHUDPanel*)gViewPort->m_pHUDPanel)->AddTutorialWin(Title, Text); +} + void HUD_StepInput(hudscroll_e ScrollCmd) { if (!gViewPort || !gViewPort->m_pHUDPanel) diff --git a/src/game/client/ui/ms/vgui_hud.h b/src/game/client/ui/ms/vgui_hud.h index d016364ad..39186a537 100644 --- a/src/game/client/ui/ms/vgui_hud.h +++ b/src/game/client/ui/ms/vgui_hud.h @@ -11,6 +11,7 @@ void VGUI_ShowMenuInteract(); void HUD_ShowInfoWin(const char* Title, const char* Text); void HUD_ShowHelpWin(const char* Title, const char* Text); +void HUD_ShowTutorialWin(const char* Title, const char* Text); void HUD_PrintEvent(vgui::Color color, const char* Text); void HUD_SayTextEvent(vgui::Color color, const char* Text); #ifdef TEAMFORTRESSVIEWPORT_H diff --git a/src/game/client/ui/ms/vgui_id.h b/src/game/client/ui/ms/vgui_id.h index 00f869275..b1b32eaf7 100644 --- a/src/game/client/ui/ms/vgui_id.h +++ b/src/game/client/ui/ms/vgui_id.h @@ -26,7 +26,7 @@ class VGUI_ID : public Panel setParent(pParent); setBgColor(0, 0, 0, 255); - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_Label[i] = new VGUI_FadeText(this, 0.2, "", 0, i * g_FontID->getTall(), MSLabel::a_center); m_Label[i]->setFont(g_FontID); @@ -155,7 +155,7 @@ class VGUI_ID : public Panel } else { - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { float PrevDelta = gpGlobals->time - m_Label[i]->m_StartTime; PrevDelta = V_min(PrevDelta, m_Label[i]->m_FadeDuration); @@ -167,12 +167,12 @@ class VGUI_ID : public Panel m_LastID = pEntInfo; m_pClientEnt = (pEntInfo ? gEngfuncs.GetEntityByIndex(pEntInfo->entindex) : NULL); SetStatus(); - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) m_Label[i]->Update(); } void Update() { - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) m_Label[i]->Update(); //get our wanted position @@ -248,7 +248,7 @@ class VGUI_ID : public Panel void NewLevel() { m_LastID = NULL; - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_Label[i]->m_StartTime = -1000; //Ensure ID doesn't show up after a level change m_Label[i]->setText(""); diff --git a/src/game/client/ui/ms/vgui_image3d.cpp b/src/game/client/ui/ms/vgui_image3d.cpp new file mode 100644 index 000000000..e18456cd6 --- /dev/null +++ b/src/game/client/ui/ms/vgui_image3d.cpp @@ -0,0 +1,113 @@ +#include "inc_weapondefs.h" +#include "render/clrender.h" +#include "hud.h" +#include "cl_util.h" +#include "vgui_teamfortressviewport.h" +#include "vgui_mscontrols.h" +#include "mslogger.h" + +mslist g_VGUIImages; + +VGUI_Image3D::VGUI_Image3D(const char *pszImageName, bool TGAorSprite, bool Delayed, int x, int y, int wide, int tall) +: CImageDelayed(pszImageName, TGAorSprite, Delayed, x, y, wide, tall) +{ + init(); +} +void VGUI_Image3D::init() +{ + m_Particle = new CParticle(); + m_Particle->m_ContinuedParticle = false; + m_Particle->m_DoubleSided = true; + m_Particle->m_Color = Color4F(1, 1, 1, 1); + m_Particle->m_Brightness = 1.0f; + m_Particle->m_Square = false; + m_Particle->m_RenderMode = kRenderTransAlpha; + g_VGUIImages.add(this); +} + +void VGUI_Image3D::LoadImg() +{ + if (m_ImageLoaded) + return; + + if (!m_Particle) + return; + + if (m_TGAorSprite) + { + msstring FileName = msstring("gfx/vgui/") + m_ImageName + ".tga"; + + loadtex_t LoadTex; + m_ImageLoaded = CEnvMgr::LoadGLTexture(FileName, LoadTex); + if (m_ImageLoaded) + { + m_Particle->m_GLTex = LoadTex.GLTexureID; + m_Particle->m_TexCoords[0] = Vector2D(LoadTex.CoordU, 0); + m_Particle->m_TexCoords[1] = Vector2D(LoadTex.CoordU, LoadTex.CoordV); + m_Particle->m_TexCoords[2] = Vector2D(0, LoadTex.CoordV); + m_Particle->m_TexCoords[3] = Vector2D(0, 0); + } + } + else + { + CImageDelayed::LoadImg(); + m_Particle->m_Texture = (model_s *)gEngfuncs.GetSpritePointer(m_SpriteHandle); + m_ImageLoaded = m_Particle->m_Texture ? true : false; + } +} + +void VGUI_Image3D::paintBackground() +{ + if (!m_ImageLoaded) + return; + + if (!m_Particle) + return; + + CEnvMgr::PushHLStates(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + //m_Particle->BillBoard(); + m_Particle->m_Width = getWide(); + m_Particle->m_Height = getTall(); + m_Particle->m_SpriteFrame = m_Frame; + m_Particle->m_DirForward = Vector(0, 0, 1); + float VerticalMultiplier = m_TGAorSprite ? -1 : 1; + m_Particle->m_DirRight = Vector(-1, 0, 0); + m_Particle->m_DirUp = Vector(0, 1 * VerticalMultiplier, 0); //m_DirUp is actually pointing down here + m_Particle->m_Origin = (-m_Particle->m_DirRight * m_Particle->m_Width / 2.0f) + (m_Particle->m_DirUp * VerticalMultiplier * m_Particle->m_Height / 2.0f); + m_Particle->Render(); + + CEnvMgr::PopHLStates(); +} + +VGUI_Image3D::~VGUI_Image3D() +{ + for (int i = 0; i < g_VGUIImages.size(); i++) + { + if (g_VGUIImages[i] == this) + { + g_VGUIImages.erase(i); + break; + } + } +} + +void VGUIImages_NewLevel() +{ + //Reload the TGA textures for the 3D VGUI Images + for (int i = 0; i < g_VGUIImages.size(); i++) + { + if (g_VGUIImages[i]->m_TGAorSprite) + { + g_VGUIImages[i]->m_ImageLoaded = false; + g_VGUIImages[i]->LoadImg(); + } + } + MS_INFO("[VGUIImages_NewLevel Complete]"); +} diff --git a/src/game/client/ui/ms/vgui_infowin.h b/src/game/client/ui/ms/vgui_infowin.h index 9c6628ef3..06df48286 100644 --- a/src/game/client/ui/ms/vgui_infowin.h +++ b/src/game/client/ui/ms/vgui_infowin.h @@ -85,7 +85,7 @@ class CInfoWindow : public CTransparentPanel setSize(x, y); } - void Update(std::vector &Windows, unsigned int idx) + void Update(std::vector &Windows, int idx) { float elapsedtime = gpGlobals->time - m_TimeDisplayed; @@ -108,7 +108,7 @@ class CInfoWindow : public CTransparentPanel m_iTransparency = 255 - ((255 - INFOWIN_BKTRANS) * fadeamt); int yPos = m_StartY; - for (unsigned int i = 0; i < idx; i++) + for (int i = 0; i < idx; i++) yPos += Windows[i]->getTall() + INFOWIN_DISPLAY_SPACER_Y; if (idx > 0) diff --git a/src/game/client/ui/ms/vgui_localizedpanel.cpp b/src/game/client/ui/ms/vgui_localizedpanel.cpp index 807802eae..9e9325ede 100644 --- a/src/game/client/ui/ms/vgui_localizedpanel.cpp +++ b/src/game/client/ui/ms/vgui_localizedpanel.cpp @@ -16,8 +16,8 @@ #define LOCAL_TRANSPARENCY 60 #define LOCAL_MAINPANEL_RATIO (.875) -#define LOCAL_MAINPANEL_WIDTH (LOCAL_MAINPANEL_RATIO * ScreenWidth()) -#define LOCAL_MAINPANEL_HEIGHT (LOCAL_MAINPANEL_RATIO * ScreenHeight()) +#define LOCAL_MAINPANEL_WIDTH (LOCAL_MAINPANEL_RATIO * ScreenWidth) +#define LOCAL_MAINPANEL_HEIGHT (LOCAL_MAINPANEL_RATIO * ScreenHeight) #define LOCAL_SCROLLPANEL_X_SPACE_L XRES(10) #define LOCAL_SCROLLPANEL_X_SPACE_R LOCAL_SCROLLPANEL_X_SPACE_L @@ -49,7 +49,7 @@ bool LocalExists(msstring title) } CLocalizedPanel::CLocalizedPanel(Panel *pParent) - : CMenuPanel(LOCAL_TRANSPARENCY, false, 0, 0, ScreenWidth(), ScreenHeight()) + : CMenuPanel(LOCAL_TRANSPARENCY, false, 0, 0, ScreenWidth, ScreenHeight) { setParent(pParent); m_Name = LOCAL_MENU_NAME; @@ -59,8 +59,8 @@ CLocalizedPanel::CLocalizedPanel(Panel *pParent) m_iButtonTotal = 0; m_iSubPanelTotal = 0; - int xMainPanel = GetCenteredItem(ScreenWidth(), LOCAL_MAINPANEL_WIDTH, 1, 0); - int yMainPanel = GetCenteredItem(ScreenHeight(), LOCAL_MAINPANEL_HEIGHT, 1, 0); + int xMainPanel = GetCenteredItem(ScreenWidth, LOCAL_MAINPANEL_WIDTH, 1, 0); + int yMainPanel = GetCenteredItem(ScreenHeight, LOCAL_MAINPANEL_HEIGHT, 1, 0); m_pMainPanel = new CTransparentPanel(LOCAL_TRANSPARENCY, xMainPanel, yMainPanel, LOCAL_MAINPANEL_WIDTH, LOCAL_MAINPANEL_HEIGHT); m_pMainPanel->setParent(this); m_pMainPanel->setVisible(true); @@ -120,7 +120,7 @@ void CLocalizedPanel::Hide(void) void CLocalizedPanel::Close(void) { - for (unsigned int i = 0; i < m_iButtonTotal; i++) + for (int i = 0; i < m_iButtonTotal; i++) m_ButtonList[i]->setArmed(false); m_pCloseButton->setArmed(false); setVisible(false); @@ -196,7 +196,7 @@ void CLocalizedPanel::AddButton(msstring sText, bool bEnabled, bool bCloseOnClic void CLocalizedPanel::PositionButtons(void) { int x = GetCenteredItem(m_pMainPanel->getWide(), LOCAL_BUTTON_WIDTH, m_iButtonTotal, LOCAL_BUTTON_SPACE); - for (unsigned int i = 0; i < m_iButtonTotal; i++) + for (int i = 0; i < m_iButtonTotal; i++) { m_ButtonList[i]->setPos(x + i * (LOCAL_BUTTON_WIDTH + LOCAL_BUTTON_SPACE), LOCAL_BUTTON_Y); } @@ -204,7 +204,7 @@ void CLocalizedPanel::PositionButtons(void) void CLocalizedPanel::ClearButtons(void) { - for (unsigned int i = 0; i < m_iButtonTotal; i++) + for (int i = 0; i < m_iButtonTotal; i++) { m_ButtonList[i]->setVisible(false); m_pMainPanel->removeChild(m_ButtonList[i]); @@ -284,7 +284,7 @@ void CLocalizedPanel::AddSubPanel( Panel *pPanel ) void CLocalizedPanel::ClearSubPanels( void ) { - for(unsigned int i = 0; i < m_iSubPanelTotal; i++) + for(int i = 0; i < m_iSubPanelTotal; i++) { m_pTextPanel->removeChild( m_SubPanelList[i] ); delete m_SubPanelList[i]; diff --git a/src/game/client/ui/ms/vgui_localizedpanel.h b/src/game/client/ui/ms/vgui_localizedpanel.h index 50180df71..be1774ed4 100644 --- a/src/game/client/ui/ms/vgui_localizedpanel.h +++ b/src/game/client/ui/ms/vgui_localizedpanel.h @@ -14,10 +14,10 @@ class CLocalizedPanel : public CMenuPanel TextPanel *m_pTitle; // Title label mslist m_ButtonList; // List of all dynamic buttons - unsigned int m_iButtonTotal; // Total number of buttons allocated + int m_iButtonTotal; // Total number of buttons allocated mslist m_SubPanelList; // List of all dynamic sub-panels - unsigned int m_iSubPanelTotal; // Total number of sub-panels + int m_iSubPanelTotal; // Total number of sub-panels CTFScrollPanel *m_pScroll; // Scrolling window Panel *m_pTextPanel; // Panel inside scrolling window diff --git a/src/game/client/ui/ms/vgui_menu_interact.h b/src/game/client/ui/ms/vgui_menu_interact.h index 6087c3dff..81378a989 100644 --- a/src/game/client/ui/ms/vgui_menu_interact.h +++ b/src/game/client/ui/ms/vgui_menu_interact.h @@ -42,12 +42,12 @@ class VGUI_MenuInteract : public VGUI_MenuBase int w, h; m_pMainPanel->getPos(w, h); - m_pMainPanel->setPos(ScreenWidth() - m_pMainPanel->getWide() - XRES(80), h); //Thothie JAN2008a was XRES(20) + m_pMainPanel->setPos(ScreenWidth - m_pMainPanel->getWide() - XRES(80), h); //Thothie JAN2008a was XRES(20) m_ButtonY = BTN_START_Y; - for (unsigned int i = 0; i < INTERACT_MAX_BUTTONS; i++) //Create all the buttons now. Fill them in later - AddButton("", 0, (int)i); + for (int i = 0; i < INTERACT_MAX_BUTTONS; i++) //Create all the buttons now. Fill them in later + AddButton("", 0, i); // MiB NOV2014_25, center the title and separator NpcInteractMenus.rft m_AllowKeys = true; // MiB 25NOV_2014 - Disable key-input @@ -63,7 +63,7 @@ class VGUI_MenuInteract : public VGUI_MenuBase m_EntIdx = -1; m_Options.clearitems(); - for (unsigned int i = 0; i < m_Buttons.size(); i++) //Reset all buttons except cance + for (int i = 0; i < m_Buttons.size(); i++) //Reset all buttons except cance { m_Buttons[i]->setVisible(false); m_Buttons[i]->setEnabled(true); diff --git a/src/game/client/ui/ms/vgui_menu_main.h b/src/game/client/ui/ms/vgui_menu_main.h index 2a7aaa04e..c36bf9a00 100644 --- a/src/game/client/ui/ms/vgui_menu_main.h +++ b/src/game/client/ui/ms/vgui_menu_main.h @@ -41,7 +41,7 @@ class VGUI_MenuMain : public VGUI_MenuBase "#CANCEL", XRES(33), 0}; m_ButtonY = BTN_START_Y; - for (unsigned int i = 0; i < std::size(g_ButtonNames); i++) + for (int i = 0; i < std::size(g_ButtonNames); i++) MSButton *pButton = AddButton(Localized(g_ButtonNames[i].Name), g_ButtonNames[i].Width, msvariant(g_ButtonNames[i].OptionScreen)); m_OptionsPanel = new CPanel_Options(this); @@ -53,7 +53,7 @@ class VGUI_MenuMain : public VGUI_MenuBase { m_Buttons[OPT_VOTEKICK]->setEnabled(false); m_Buttons[OPT_VOTETIME]->setEnabled(false); - for (unsigned int i = 0; i < vote_t::VotesTypesAllowed.size(); i++) + for (int i = 0; i < vote_t::VotesTypesAllowed.size(); i++) { if (vote_t::VotesTypesAllowed[i] == "kick") m_Buttons[OPT_VOTEKICK]->setEnabled(true); diff --git a/src/game/client/ui/ms/vgui_menubase.cpp b/src/game/client/ui/ms/vgui_menubase.cpp index 2c2f23fc5..3dc2a08d4 100644 --- a/src/game/client/ui/ms/vgui_menubase.cpp +++ b/src/game/client/ui/ms/vgui_menubase.cpp @@ -90,7 +90,7 @@ void CAction_SelectMainOption::actionPerformed(Panel *panel) int GetCenteredItemX(int WorkSpaceSizeX, int ItemSizeX, int Items, int SpaceBewteenItems); // Creation -VGUI_MenuBase::VGUI_MenuBase(Panel *myParent) : CMenuPanel(255, 0, 0, 0, ScreenWidth(), ScreenHeight()) +VGUI_MenuBase::VGUI_MenuBase(Panel *myParent) : CMenuPanel(255, 0, 0, 0, ScreenWidth, ScreenHeight) { m_AllowKeys = true; // MiB NOV2014_25, block number shortcuts: NpcInteractMenus.rft setParent(myParent); @@ -176,7 +176,7 @@ bool VGUI_MenuBase::SlotInput(int iSlot) // Update the menu before opening it void VGUI_MenuBase::Open(void) { - for (unsigned int i = 0; i < m_Buttons.size(); i++) + for (int i = 0; i < m_Buttons.size(); i++) m_Buttons[i]->setArmed(false); Reset(); @@ -208,7 +208,7 @@ void VGUI_MenuBase::UpdateFade(void) //m_pMainPanel->setBorder( NULL ); //m_pMainPanel->setBorder( m_Border ); - for (unsigned int i = 0; i < m_Buttons.size(); i++) + for (int i = 0; i < m_Buttons.size(); i++) { m_Buttons[i]->m_ArmedColor.a = InveserdFade; m_Buttons[i]->m_UnArmedColor.a = InveserdFade; diff --git a/src/game/client/ui/ms/vgui_moveitempanel.cpp b/src/game/client/ui/ms/vgui_moveitempanel.cpp index 8155a03d8..ee417289f 100644 --- a/src/game/client/ui/ms/vgui_moveitempanel.cpp +++ b/src/game/client/ui/ms/vgui_moveitempanel.cpp @@ -12,7 +12,7 @@ VGUI_MoveItemPanel::VGUI_MoveItemPanel(CContainerPanel *pParent) : CTransparentP int y = 0; int w = 0; - for(unsigned int i = 0; i < gNumMoveNumbers + 1; i++) + for(int i = 0; i < gNumMoveNumbers + 1; i++) { int vNumMove; msstring vsText; @@ -57,7 +57,7 @@ void VGUI_MoveItemPanel::ShowForButton(VGUI_ItemButton *pButton) pButton->getAbsExtents(x, y, w, h); setPos(x,y); - for(unsigned int i = 0; i < gNumMoveNumbers; i++) + for(int i = 0; i < gNumMoveNumbers; i++) { mButtons[i]->setEnabled(pButton->m_Data.Quantity >= gMoveNumbers[i]); } @@ -76,7 +76,7 @@ void VGUI_MoveItemPanel::Move(int vNumMove) void VGUI_MoveItemPanel::setVisible(bool bVisible) { CTransparentPanel::setVisible(bVisible); - for(unsigned int i = 0; i < gNumMoveNumbers + 1; i++) + for(int i = 0; i < gNumMoveNumbers + 1; i++) { mButtons[i]->setArmed(false); } diff --git a/src/game/client/ui/ms/vgui_mscontrols.cpp b/src/game/client/ui/ms/vgui_mscontrols.cpp index 3e91f2267..39dba64c5 100644 --- a/src/game/client/ui/ms/vgui_mscontrols.cpp +++ b/src/game/client/ui/ms/vgui_mscontrols.cpp @@ -30,7 +30,7 @@ BitmapTGA *MSBitmap::GetTGA(const char *pszImageName) if( !pszImageName ) return NULL; - for (unsigned int i = 0; i < g_Bitmaps.size(); i++) + for (int i = 0; i < g_Bitmaps.size(); i++) { if( g_Bitmaps[i].m_TGAorSprite && !strcmp(g_Bitmaps[i].sImageName, pszImageName) ) return g_Bitmaps[i].m_TGA; //Return existing TGA @@ -55,7 +55,7 @@ HLSPRITE MSBitmap::GetSprite(const char *pszImageName) if( !pszImageName ) return NULL; - for (unsigned int i = 0; i < g_Bitmaps.size(); i++) + for (int i = 0; i < g_Bitmaps.size(); i++) if( !g_Bitmaps[i].m_TGAorSprite && !strcmp(g_Bitmaps[i].sImageName, pszImageName) ) return g_Bitmaps[i].m_Sprite; //Return existing Sprite @@ -82,7 +82,7 @@ HLSPRITE MSBitmap::LoadSprite(const char *pszImageName) void MSBitmap::ReloadSprites() { //Reload sprites after a video or level change - for (unsigned int i = 0; i < g_Bitmaps.size(); i++) + for (int i = 0; i < g_Bitmaps.size(); i++) if( !g_Bitmaps[i].m_TGAorSprite ) g_Bitmaps[i].m_Sprite = LoadSprite( g_Bitmaps[i].sImageName ); } @@ -315,7 +315,7 @@ class CHandler_ItemButton : public InputSignal { if ( mpDoubleClickDetector->Click(this, code) && m_pItemButton->m_Selected) { - mouseDoublePressed(code, panel); + m_pItemButton->Doubleclicked( ); } else { @@ -329,7 +329,7 @@ class CHandler_ItemButton : public InputSignal }; void cursorMoved(int x,int y,Panel* panel) {}; void mouseReleased(MouseCode code,Panel* panel) {}; - void mouseDoublePressed( MouseCode code, Panel* panel ) { m_pItemButton->Doubleclicked( ); }; + void mouseDoublePressed( MouseCode code, Panel* panel ) { mousePressed( code, panel ); }; void mouseWheeled(int delta,Panel* panel) {}; void keyPressed(KeyCode code,Panel* panel) {}; void keyTyped(KeyCode code,Panel* panel) {}; @@ -363,7 +363,7 @@ VGUI_ItemButton::VGUI_ItemButton( int x, int y, VGUI_ItemCallbackPanel *pCallbac m_Image.setParent( this ); //Set the label - for (unsigned int i = 0; i < ITEMBTN_LABELS_MAX; i++) + for (int i = 0; i < ITEMBTN_LABELS_MAX; i++) m_Labels[i] = new MSLabel( this, "Item", 0, 0, 1, 1, MSLabel::a_center ); m_Description = new TextPanel( "", 0, 0, 1, 1 ); @@ -385,7 +385,7 @@ VGUI_ItemButton::VGUI_ItemButton( int x, int y, VGUI_ItemCallbackPanel *pCallbac m_Button->removeInputSignal( m_Signal ); removeChild( m_Button ); - for (unsigned int i = 0; i < ITEMBTN_LABELS; i++) + for (int i = 0; i < ITEMBTN_LABELS; i++) { removeChild( Labels[i] ); delete Labels[i]; @@ -435,7 +435,7 @@ void VGUI_ItemButton::Update( ) int lblx, lbly; int w, h; - for (unsigned int i = 0; i < ITEMBTN_LABELS_MAX; i++) + for (int i = 0; i < ITEMBTN_LABELS_MAX; i++) { switch( i ) { @@ -567,7 +567,7 @@ void VGUI_ItemButton::paint( ) } m_Image.SetFGColorRGB( ImageColor ); - for (unsigned int i = 0; i < ITEMBTN_LABELS_MAX; i++) + for (int i = 0; i < ITEMBTN_LABELS_MAX; i++) m_Labels[i]->SetFGColorRGB( LabelColor ); m_Description->SetFGColorRGB( LabelColor ); } @@ -654,7 +654,7 @@ VGUI_ItemButton *VGUI_Container::AddItem(containeritem_t &Item) VGUI_ItemButton &NewItemButton = *m_ItemButtons[m_ItemButtonTotal]; NewItemButton.SetItem(Item); - unsigned int iAlphaLoc = m_ItemButtonTotal; + int iAlphaLoc = m_ItemButtonTotal; if (m_ItemButtonTotal > 0) { @@ -672,7 +672,7 @@ VGUI_ItemButton *VGUI_Container::AddItem(containeritem_t &Item) } iAlphaLoc = lo; - for (unsigned int i = m_ItemButtonTotal; i > iAlphaLoc; --i) + for (int i = m_ItemButtonTotal; i > iAlphaLoc; --i) m_AlphabetizedItemButtons[i] = m_AlphabetizedItemButtons[i - 1]; } @@ -684,7 +684,7 @@ VGUI_ItemButton *VGUI_Container::AddItem(containeritem_t &Item) const int invType = atoi(gEngfuncs.pfnGetCvarString("ms_invtype")); if (IsAlphabetical()) { - for (unsigned int i = iAlphaLoc; i < m_ItemButtonTotal; ++i) + for (int i = iAlphaLoc; i < m_ItemButtonTotal; ++i) UpdatePosition(i, invType); } else @@ -700,7 +700,7 @@ void VGUI_Container::Update( ) { bool bIsAlpha = IsAlphabetical(); const int invType = atoi(gEngfuncs.pfnGetCvarString("ms_invtype")); - for (unsigned int i = 0; i < m_ItemButtonTotal; i++) + for (int i = 0; i < m_ItemButtonTotal; i++) { // MiB FEB2019_24 [ALPHABETICAL_INVENTORY] if ( bIsAlpha ) @@ -749,7 +749,7 @@ void VGUI_Container::UpdatePosition(int idx, int invType) void VGUI_Container::PurgeButtons( ) { //Reset the old buttons - for (unsigned int i = 0; i < m_ItemButtonTotal; i++) + for (int i = 0; i < m_ItemButtonTotal; i++) m_ItemButtons[i]->Reset( ); m_ItemButtonTotal = 0; diff --git a/src/game/client/ui/ms/vgui_mscontrols.h b/src/game/client/ui/ms/vgui_mscontrols.h index c6726a8b8..e59a7ff1b 100644 --- a/src/game/client/ui/ms/vgui_mscontrols.h +++ b/src/game/client/ui/ms/vgui_mscontrols.h @@ -377,6 +377,12 @@ class VGUI_DoubleClickDetector public: VGUI_DoubleClickDetector() + { + ResetDoubleClick(); + } + + // Forget the last click so the next one can't be treated as the second half of a double-click + void ResetDoubleClick() { mLastClick = 0.0; mpLastClicked = nullptr; @@ -389,12 +395,11 @@ class VGUI_DoubleClickDetector float vCurTime = gEngfuncs.GetClientTime(); if (pClicked == mpLastClicked && mLastMouseCode == vMouseCode) { - float vThreshhold = gEngfuncs.pfnGetCvarFloat("ms_doubleclicktime") + mLastClick; - if (vCurTime < vThreshhold) + // Client time resets on map change / reconnect, so a negative elapsed time is a fresh click + float vElapsed = vCurTime - mLastClick; + if (vElapsed >= 0.0f && vElapsed < gEngfuncs.pfnGetCvarFloat("ms_doubleclicktime")) { - mLastClick = 0.0; - mpLastClicked = nullptr; - mLastMouseCode = MOUSE_LAST; + ResetDoubleClick(); return true; } } @@ -460,8 +465,8 @@ class VGUI_Container : public CTransparentPanel public: std::vector m_ItemButtons; std::vector m_AlphabetizedItemButtons; // MiB FEB2019_24 [ALPHABETICAL_INVENTORY] - unsigned int m_ItemButtonTotal; - unsigned int m_InitializedItemButtons; + int m_ItemButtonTotal; + int m_InitializedItemButtons; CTFScrollPanel *m_pScrollPanel; VGUI_ItemCallbackPanel *m_CallbackPanel; MSLabel *m_NoItems; @@ -619,7 +624,7 @@ class VGUI_TextPanel : public CTransparentPanel int w, h; m_MessageLabel->getTextSize( w, h ); x += w + 1; - for (unsigned int i = 0; i < m_FadeLabels.size(); i++) { m_FadeLabels[i]->getTextSize(w, h); x += w; } + for (int i = 0; i < m_FadeLabels.size(); i++) { m_FadeLabels[i]->getTextSize(w, h); x += w; } m_FadeLabels.add( new VGUI_FadeText( this, 0, Letter, x, y, XRES(16), m_MessageLabel->getTall() ) ); m_Message += Letter; @@ -636,8 +641,8 @@ class VGUI_TextPanel : public CTransparentPanel { m_VisibleMsg = m_Message; m_MessageLabel->setText( m_Message ); - unsigned int sz = m_FadeLabels.size(); - for (unsigned int i = 0; i < sz; i++) + int sz = m_FadeLabels.size(); + for (int i = 0; i < sz; i++) { m_FadeLabels[0]->setParent( NULL ); delete m_FadeLabels[0]; @@ -654,7 +659,7 @@ class VGUI_TextPanel : public CTransparentPanel void Update( ) { - for (unsigned int i = 0; i < m_FadeLabels.size(); i++) + for (int i = 0; i < m_FadeLabels.size(); i++) { VGUI_FadeText *pFadeText = m_FadeLabels[i]; pFadeText->Update( ); @@ -702,6 +707,7 @@ class CMouseInputHandler CMouseInputHandler(VGUI_DoubleClickDetector *pDoubleClickDetector = nullptr, void *pDoubleClickTarget = nullptr) { mpDoubleClickDetector = pDoubleClickDetector; + mpDoubleClickTarget = pDoubleClickTarget; } virtual void mouseWheeled(int vDelta, Panel *pPanel) diff --git a/src/game/client/ui/ms/vgui_options.cpp b/src/game/client/ui/ms/vgui_options.cpp index d424c7993..f33a63d15 100644 --- a/src/game/client/ui/ms/vgui_options.cpp +++ b/src/game/client/ui/ms/vgui_options.cpp @@ -202,7 +202,7 @@ class VGUI_Options : public CTransparentPanel //m_pScrollPanel->setBorder( new LineBorder( Color(255,255,255,0) ) ); int yPos = PLAYERBTN_START_Y; - for (unsigned int i = 0; i < MAX_VOTE_PLAYERS; i++) + for (int i = 0; i < MAX_VOTE_PLAYERS; i++) { ListButton *pButton = m_pListButton[i] = new ListButton(this, i, PLAYERBTN_X, yPos, PLAYERBTN_SIZE_X, PLAYERBTN_SIZE_Y); pButton->setFont(pSchemes->getFont(hClassWindowText)); @@ -225,7 +225,7 @@ class VGUI_Options : public CTransparentPanel { m_Target = -1; setVisible(true); - for (unsigned int i = 0; i < MAX_VOTE_PLAYERS; i++) + for (int i = 0; i < MAX_VOTE_PLAYERS; i++) { m_pListButton[i]->setArmed(false); m_pListButton[i]->SetBGColorRGB(Color_Transparent); @@ -251,7 +251,7 @@ class VGUI_Options : public CTransparentPanel virtual void ButtonClicked(int idx) { m_Target = idx; - for (unsigned int i = 0; i < MAX_VOTE_PLAYERS; i++) + for (int i = 0; i < MAX_VOTE_PLAYERS; i++) m_pListButton[i]->SetBgColor(Color_Transparent); m_pListButton[m_Target]->SetBgColor(Color_BG_NameHightlight); m_pBegin->setEnabled(true); @@ -290,7 +290,7 @@ class CInitVotePanel : public VGUI_Options if (m_VoteType == "kick") { - for (unsigned int i = 0; i < MAX_VOTE_PLAYERS; i++) + for (int i = 0; i < MAX_VOTE_PLAYERS; i++) if (g_PlayerInfoList[i].name && i != MSCLGlobals::GetLocalPlayerIndex()) { @@ -303,10 +303,10 @@ class CInitVotePanel : public VGUI_Options } else if (m_VoteType == "advtime") { - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_pListButton[i]->setParent(m_pScrollPanel->getClient()); - m_pListButton[i]->setText(Localized(msstring("#VOTE_ADVTIME_OPT") + (int)i)); + m_pListButton[i]->setText(Localized(msstring("#VOTE_ADVTIME_OPT") + i)); UsedBtns++; } } @@ -329,7 +329,7 @@ class CInitVotePanel : public VGUI_Options virtual void ButtonClicked(int idx) { m_Target = idx; - for (unsigned int i = 0; i < MAX_VOTE_PLAYERS; i++) + for (int i = 0; i < MAX_VOTE_PLAYERS; i++) m_pListButton[i]->SetBgColor(Color_Transparent); m_pListButton[m_Target]->SetBgColor(Color_BG_NameHightlight); m_pBegin->setEnabled(true); @@ -435,7 +435,7 @@ class CPartyPanel : public VGUI_Options void Update() { int r = 0; - for (unsigned int i = 0; i < MAX_VOTE_PLAYERS; i++) + for (int i = 0; i < MAX_VOTE_PLAYERS; i++) if (g_PlayerExtraInfo[i].teamname[0] /*&& i != GetLocalPlayerIndex()*/ ) diff --git a/src/game/client/ui/ms/vgui_quickslot.h b/src/game/client/ui/ms/vgui_quickslot.h index b1ab31a40..3c4aa0914 100644 --- a/src/game/client/ui/ms/vgui_quickslot.h +++ b/src/game/client/ui/ms/vgui_quickslot.h @@ -46,7 +46,7 @@ class VGUI_QuickSlot : public Panel, public IHUD #define QUICKSLOT_H YRES(14) - VGUI_QuickSlot(Panel *pParent) : Panel(XRES(170), ScreenHeight() - QUICKSLOT_H, ScreenWidth(), QUICKSLOT_H) + VGUI_QuickSlot(Panel *pParent) : Panel(XRES(170), ScreenHeight - QUICKSLOT_H, ScreenWidth, QUICKSLOT_H) { setParent(pParent); SetBGColorRGB(Color_Transparent); @@ -356,10 +356,42 @@ class VGUI_QuickSlot : public Panel, public IHUD if (!QuickSlot.Active) return; + if (QuickSlot.Type == QS_ITEM) + { + CGenericItem *pItem = player.FindItem(QuickSlot.ID); + CGenericItem *pSpare = (pItem && pItem->m_Location == ITEMPOS_HANDS) ? FindSpare(pItem) : NULL; + if (pSpare) + { + quickslot_t SpareSlot = QuickSlot; + SpareSlot.ID = pSpare->m_iId; + ConfirmItem(SpareSlot); + return; + } + } + ConfirmItem(QuickSlot); } } + CGenericItem *FindSpare(CGenericItem *pItem) + { + for (unsigned int i = 0; i < player.Gear.size(); i++) + { + CGenericItem *pPack = player.Gear[i]; + if (pPack->m_Location == ITEMPOS_HANDS) + continue; + + for (unsigned int n = 0; n < pPack->Container_ItemCount(); n++) + { + CGenericItem *pCopy = pPack->Container_GetItem(n); + if (pCopy && pCopy != pItem && !strcmp(pCopy->m_Name, pItem->m_Name)) + return pCopy; + } + } + + return NULL; + } + void AssignSlot(int Slot) { if (Slot < 0 || Slot >= MAX_QUICKSLOTS) diff --git a/src/game/client/ui/ms/vgui_spawn.cpp b/src/game/client/ui/ms/vgui_spawn.cpp index a9fe4ffa9..9d583f2cd 100644 --- a/src/game/client/ui/ms/vgui_spawn.cpp +++ b/src/game/client/ui/ms/vgui_spawn.cpp @@ -76,7 +76,7 @@ #define MSG_H YRES(60) // Creation -CSpawnPanel::CSpawnPanel(Panel *pParent) : CMenuPanel(1, false, 0, 0, ScreenWidth(), ScreenHeight()) +CSpawnPanel::CSpawnPanel(Panel *pParent) : CMenuPanel(1, false, 0, 0, ScreenWidth, ScreenHeight) { // Get the scheme used for the Titles CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); diff --git a/src/game/client/ui/ms/vgui_stats.cpp b/src/game/client/ui/ms/vgui_stats.cpp index 15a386e77..293044999 100644 --- a/src/game/client/ui/ms/vgui_stats.cpp +++ b/src/game/client/ui/ms/vgui_stats.cpp @@ -64,7 +64,7 @@ static COLOR Color_TitleText = COLOR(255, 255, 255, 0), Color_TransparentText = COLOR(0, 0, 0, 255); // Creation -CStatPanel::CStatPanel(Panel *pParent) : CMenuPanel(0, false, 0, 0, ScreenWidth(), ScreenHeight()) +CStatPanel::CStatPanel(Panel *pParent) : CMenuPanel(0, false, 0, 0, ScreenWidth, ScreenHeight) { setParent(pParent); setVisible(false); @@ -145,7 +145,7 @@ CStatPanel::CStatPanel(Panel *pParent) : CMenuPanel(0, false, 0, 0, ScreenWidth( pLabel->getPos(ix, iy); offset = iy + pLabel->getTall(); - for (unsigned int i = 0; i < SKILL_MAX_STATS + 1; i++) + for (int i = 0; i < SKILL_MAX_STATS + 1; i++) { TextPanel *pTextbox = Skill_StatLabel[i] = new TextPanel("", TITLE_SKILLS_X, offset + i * MAINBUTTON_SIZE_Y, MAINBUTTON_SIZE_X, MAINBUTTON_SIZE_Y); @@ -267,7 +267,7 @@ void CStatPanel::Update() } bool FOUND_PARRY = false; - for (unsigned int i = 0; i < SKILL_MAX_STATS; i++) + for (int i = 0; i < SKILL_MAX_STATS; i++) { FOUND_PARRY = FOUND_PARRY || msstring(SkillStatList[i].Name) == "Parry"; bool blank = i == SKILL_MAX_STATS - 1; @@ -306,9 +306,9 @@ void CStatPanel::Update() { int Height = SKILLINFOPANEL_TITLE_Y + SKILLINFOPANEL_TITLE_H + SKILLINFOPANEL_BTM_BORDERSPACER_H; int UnusedSlots = 0; - for (unsigned int i = 0; i < STAT_MAGIC_TOTAL; i++) + for (int i = 0; i < STAT_MAGIC_TOTAL; i++) { - unsigned int iSubStats = pStat->m_SubStats.size(); + int iSubStats = pStat->m_SubStats.size(); if (i >= iSubStats) { m_StatTypeLabel[i]->setVisible(false); @@ -330,7 +330,7 @@ void CStatPanel::Update() Percent = 0.0; const char* Name = ""; - if (iSubStats <= STAT_PROP_TOTAL) + if (iSubStats <= STATPROP_TOTAL) Name = SkillTypeList[i]; else Name = SpellTypeList[i]; @@ -467,7 +467,7 @@ int __MsgFunc_SetStat(const char *pszName, int iSize, void *pbuf) if (iStat < (signed)player.m_Stats.size()) { CStat &Stat = player.m_Stats[iStat]; - for (unsigned int i = 0; i < Stat.m_SubStats.size(); i++) + for (int i = 0; i < Stat.m_SubStats.size(); i++) { Stat.m_SubStats[i].Value = READ_BYTE(); if (Stat.m_Type == CStat::STAT_SKILL) diff --git a/src/game/client/ui/ms/vgui_storage.cpp b/src/game/client/ui/ms/vgui_storage.cpp index ebb13c9d6..f2d1b594f 100644 --- a/src/game/client/ui/ms/vgui_storage.cpp +++ b/src/game/client/ui/ms/vgui_storage.cpp @@ -76,7 +76,7 @@ void CStoragePanel::AddInventoryItems() { //Find the storage on the player storage_t *pStorage = NULL; - for (unsigned int s = 0; s < player.m_Storages.size(); s++) + for (int s = 0; s < player.m_Storages.size(); s++) if (player.m_Storages[s].Name == player.m_CurrentStorage.StorageName) { pStorage = &player.m_Storages[s]; @@ -100,7 +100,7 @@ void CStoragePanel::AddInventoryItems() //Add the storage items storage_t &Storage = *pStorage; - for (unsigned int i = 0; i < Storage.Items.size(); i++) + for (int i = 0; i < Storage.Items.size(); i++) { containeritem_t vNewItem = containeritem_t(Storage.Items[i]); pGearItemButton->m_ItemContainer->AddItem(vNewItem); @@ -166,7 +166,7 @@ bool CStoragePanel::GearItemClicked(ulong ID) bool leftAnItemOff = false; - for (unsigned int i = 0; i < m_SelectedItems.size(); i++) + for (int i = 0; i < m_SelectedItems.size(); i++) { if (checkValid(m_SelectedItems[i])) //Check it against the bank mask (MiB Feb2008a) { @@ -246,10 +246,10 @@ void CStoragePanel::ItemSelectChanged(ulong ID, bool fSelected) int Valuetotal = 0; - for (unsigned int g = 0; g < m_GearPanel->GearItemButtonTotal; g++) + for (int g = 0; g < m_GearPanel->GearItemButtonTotal; g++) { VGUI_Inv_GearItem &GearItem = *m_GearPanel->GearItemButtons[g]; - for (unsigned int i = 0; i < GearItem.m_ItemContainer->m_ItemButtonTotal; i++) + for (int i = 0; i < GearItem.m_ItemContainer->m_ItemButtonTotal; i++) { VGUI_ItemButton &ItemButton = *GearItem.m_ItemContainer->m_ItemButtons[i]; if (!ItemButton.m_Selected) @@ -282,7 +282,7 @@ void CStoragePanel::ItemSelectChanged(ulong ID, bool fSelected) if( m_SelectedItems.size() > 0 ) { CommandString = "trade sell"; - for (unsigned int i = 0; i < m_SelectedItems.size(); i++) + for (int i = 0; i < m_SelectedItems.size(); i++) { CommandString += " "; CommandString += (int)m_SelectedItems[i].ID; @@ -320,7 +320,7 @@ void Storage_ItemMsg() msstring StorageName = READ_STRING(); storage_t *pStorage = NULL; - for (unsigned int s = 0; s < player.m_Storages.size(); s++) + for (int s = 0; s < player.m_Storages.size(); s++) if (player.m_Storages[s].Name == StorageName) { pStorage = &player.m_Storages[s]; diff --git a/src/game/client/ui/ms/vgui_store.cpp b/src/game/client/ui/ms/vgui_store.cpp index cb79334b2..9004d1660 100644 --- a/src/game/client/ui/ms/vgui_store.cpp +++ b/src/game/client/ui/ms/vgui_store.cpp @@ -145,7 +145,7 @@ CStoreMenuPanel::CStoreMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide m_pScrollPanel->validate(); // Create the Store buttons - for (unsigned int i = 0; i < STORE_BUTTONS; i++) + for (int i = 0; i < STORE_BUTTONS; i++) { int iYPos = STORE_SIDEBUTTON_TOPLEFT_Y + ( (STORE_SIDEBUTTON_SIZE_Y + STORE_SIDEBUTTON_SPACER_Y) * i ); @@ -154,7 +154,7 @@ CStoreMenuPanel::CStoreMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide m_pButtons[i]->setContentAlignment( vgui::Label::a_west ); if( i != 2 ) m_pButtons[i]->addActionSignal( new CStoreBtn(iMenuToShow[i]) ); - else m_pButtons[i]->addActionSignal( new CMenuHandler_StringCommand( "trade sell 0", true ) ); + else m_pButtons[i]->addActionSignal( new CMenuHandler_StringCommand( "trade sell 0", TRUE ) ); m_pButtons[i]->addInputSignal( new CHandler_MenuButtonOver(this, i) ); m_pButtons[i]->setParent( this ); @@ -205,7 +205,7 @@ void CStoreMenuPanel::Update() char sz[256]; int width, height; pTitleLabel->setText( "%s's Shop", CStorePanel::StoreVendorName.c_str() ); - for (unsigned int i = 0; i < STORE_BUTTONS; i++) + for (int i = 0; i < STORE_BUTTONS; i++) { //Don't show buttons if not activated m_pButtons[i]->setVisible( false ); @@ -256,7 +256,7 @@ void CStoreMenuPanel::Initialize( void ) void CStoreMenuPanel::SetActiveInfo( int iInput ) { // Remove all the Info panels and bring up the specified one - for (unsigned int i = 0; i < STORE_BUTTONS; i++) + for (int i = 0; i < STORE_BUTTONS; i++) { m_pButtons[i]->setArmed( false ); m_pClassInfoPanel[i]->setVisible( false ); diff --git a/src/game/client/ui/ms/vgui_storebuy.cpp b/src/game/client/ui/ms/vgui_storebuy.cpp index f3c849766..53835f01b 100644 --- a/src/game/client/ui/ms/vgui_storebuy.cpp +++ b/src/game/client/ui/ms/vgui_storebuy.cpp @@ -41,7 +41,7 @@ void CStoreBuyPanel::AddInventoryItems() pGearItemButton->setVisible(false); //Add store items with at least 1 in inventory to the container - for (unsigned int i = 0; i < StoreItems.size(); i++) + for (int i = 0; i < StoreItems.size(); i++) if (StoreItems[i].Quantity > 0) pGearItemButton->m_ItemContainer->AddItem(StoreItems[i]); @@ -91,7 +91,7 @@ void CStoreBuyPanel::ItemHighlighted(void *pData) m_InfoPanel->m_SaleText->setText("Price"); containeritem_t &Item = ItemButton.m_Data; - for (unsigned int s = 0; s < CStorePanel::StoreItems.size(); s++) + for (int s = 0; s < CStorePanel::StoreItems.size(); s++) { storeitem_t &StoreItem = CStorePanel::StoreItems[s]; if (Item.Name != StoreItem.Name) diff --git a/src/game/client/ui/ms/vgui_storemainwin.cpp b/src/game/client/ui/ms/vgui_storemainwin.cpp index 9cdbd369d..86c7cecbf 100644 --- a/src/game/client/ui/ms/vgui_storemainwin.cpp +++ b/src/game/client/ui/ms/vgui_storemainwin.cpp @@ -56,7 +56,7 @@ CStorePanel::CStorePanel() : VGUI_ContainerPanel() m_SaleLabel->setText("Selling 0 Items (0 Gold)"); //Set up the cancel button - m_pCancelButton->addActionSignal(new CMenuHandler_StringCommand("trade stop", true)); + m_pCancelButton->addActionSignal(new CMenuHandler_StringCommand("trade stop", TRUE)); m_pCancelButton->setText(Localized("#CLOSE")); Text_StoreGold = "GOLD"; diff --git a/src/game/client/ui/ms/vgui_storesell.cpp b/src/game/client/ui/ms/vgui_storesell.cpp index bb1305bf7..c31154abd 100644 --- a/src/game/client/ui/ms/vgui_storesell.cpp +++ b/src/game/client/ui/ms/vgui_storesell.cpp @@ -79,7 +79,7 @@ CStoreSellPanel::CStoreSellPanel(Panel *pParent) : CStorePanel() bool CStoreSellPanel::InterestedInItem(const char* pszItemName) { - for (unsigned int i = 0; i < CStorePanel::StoreItems.size(); i++) + for (int i = 0; i < CStorePanel::StoreItems.size(); i++) if (CStorePanel::StoreItems[i].Name == pszItemName) return true; @@ -104,7 +104,7 @@ void CStoreSellPanel::ItemHighlighted(void *pData) m_InfoPanel->m_SaleText->setText("Worthless"); containeritem_t &Item = ItemButton.m_Data; - for (unsigned int s = 0; s < CStorePanel::StoreItems.size(); s++) + for (int s = 0; s < CStorePanel::StoreItems.size(); s++) { storeitem_t &StoreItem = CStorePanel::StoreItems[s]; if (Item.Name != StoreItem.Name) @@ -126,17 +126,17 @@ void CStoreSellPanel::ItemSelectChanged(ulong ID, bool fSelected) int Valuetotal = 0; - for (unsigned int g = 0; g < m_GearPanel->GearItemButtonTotal; g++) + for (int g = 0; g < m_GearPanel->GearItemButtonTotal; g++) { VGUI_Inv_GearItem &GearItem = *m_GearPanel->GearItemButtons[g]; - for (unsigned int i = 0; i < GearItem.m_ItemContainer->m_ItemButtonTotal; i++) + for (int i = 0; i < GearItem.m_ItemContainer->m_ItemButtonTotal; i++) { VGUI_ItemButton &ItemButton = *GearItem.m_ItemContainer->m_ItemButtons[i]; if (!ItemButton.m_Selected) continue; containeritem_t &Item = ItemButton.m_Data; - for (unsigned int s = 0; s < CStorePanel::StoreItems.size(); s++) + for (int s = 0; s < CStorePanel::StoreItems.size(); s++) { storeitem_t &StoreItem = CStorePanel::StoreItems[s]; if (Item.Name != StoreItem.Name) @@ -159,7 +159,7 @@ void CStoreSellPanel::SellAll() if (m_SelectedItems.size() > 0) { CommandString = "trade sell"; - for (unsigned int i = 0; i < m_SelectedItems.size(); i++) + for (int i = 0; i < m_SelectedItems.size(); i++) { CommandString += " "; CommandString += (int)m_SelectedItems[i].ID; diff --git a/src/game/client/ui/ms/vgui_vote.h b/src/game/client/ui/ms/vgui_vote.h index b224b5a9a..267ec1e83 100644 --- a/src/game/client/ui/ms/vgui_vote.h +++ b/src/game/client/ui/ms/vgui_vote.h @@ -14,7 +14,7 @@ class VGUI_VoteInfo : public Panel, public IHUD *m_pVoteDesc; TextPanel *m_YesVotes; - VGUI_VoteInfo(Panel *pParent) : Panel(0, 0, ScreenWidth(), ScreenHeight()) + VGUI_VoteInfo(Panel *pParent) : Panel(0, 0, ScreenWidth, ScreenHeight) { setParent(pParent); setBgColor(0, 0, 0, 255); diff --git a/src/game/client/ui/vgui_customobjects.cpp b/src/game/client/ui/vgui_customobjects.cpp index af23b5b47..739a1f258 100644 --- a/src/game/client/ui/vgui_customobjects.cpp +++ b/src/game/client/ui/vgui_customobjects.cpp @@ -54,7 +54,7 @@ char *GetTGANameForRes(const char *pszName) static char gd[256]; int i = 640; - if (ScreenWidth() < 640) + if (ScreenWidth < 640) i = 320; snprintf(sz, sizeof(sz), pszName, i); diff --git a/src/game/client/ui/vgui_global.cpp b/src/game/client/ui/vgui_global.cpp index d8875863d..a011837eb 100644 --- a/src/game/client/ui/vgui_global.cpp +++ b/src/game/client/ui/vgui_global.cpp @@ -75,7 +75,7 @@ bool VGUI::HideMenu(VGUI_MainPanel *pPanel) VGUI_MainPanel *VGUI::FindPanel(const char* Name) { - for (unsigned int i = 0; i < gViewPort->m_Menus.size(); i++) + for (int i = 0; i < gViewPort->m_Menus.size(); i++) { VGUI_MainPanel *pPanel = gViewPort->m_Menus[i]; if (pPanel->m_Name == Name) diff --git a/src/game/client/ui/vgui_int.cpp b/src/game/client/ui/vgui_int.cpp index 00cac9f9d..d4ec3e0ee 100644 --- a/src/game/client/ui/vgui_int.cpp +++ b/src/game/client/ui/vgui_int.cpp @@ -18,7 +18,7 @@ #include "in_defs.h" #include "vgui_teamfortressviewport.h" #include "vgui_controlconfigpanel.h" -#include "clenv.h" +#include "render/clenv.h" #include "mslogger.h" namespace @@ -82,9 +82,6 @@ void *VGui_GetPanel() void VGui_Startup() { - if (!CRender::CheckOpenGL()) //This exits if not in OpenGL mode - return; - Panel *root = (Panel *)VGui_GetPanel(); root->setBgColor(128, 128, 0, 0); //root->setNonPainted(false); diff --git a/src/game/client/ui/vgui_loadtga.cpp b/src/game/client/ui/vgui_loadtga.cpp index 771bcbad3..250161801 100644 --- a/src/game/client/ui/vgui_loadtga.cpp +++ b/src/game/client/ui/vgui_loadtga.cpp @@ -64,7 +64,7 @@ class MemoryInputStream : public vgui::InputStream void readUChar(uchar* buf, int count, bool& success) override { - for (unsigned int i = 0; i < (unsigned int)count; i++) + for (int i = 0; i < count; i++) buf[i] = readUChar(success); } diff --git a/src/game/client/ui/vgui_schememanager.cpp b/src/game/client/ui/vgui_schememanager.cpp index faae8fffc..ebc127cc9 100644 --- a/src/game/client/ui/vgui_schememanager.cpp +++ b/src/game/client/ui/vgui_schememanager.cpp @@ -379,12 +379,12 @@ CSchemeManager::CSchemeManager(int xRes, int yRes) memcpy(m_pSchemeList, tmpSchemes, sizeof(CScheme) * m_iNumSchemes); // create the fonts - for (unsigned int i = 0; i < m_iNumSchemes; i++) + for (int i = 0; i < m_iNumSchemes; i++) { m_pSchemeList[i].font = NULL; // see if the current font values exist in a previously loaded font - for (unsigned int j = 0; j < i; j++) + for (int j = 0; j < i; j++) { // check if the font name, size, and weight are the same if ( @@ -483,7 +483,7 @@ CSchemeManager::~CSchemeManager() SchemeHandle_t CSchemeManager::getSchemeHandle(const char *schemeName) { // iterate through the list - for (unsigned int i = 0; i < m_iNumSchemes; i++) + for (int i = 0; i < m_iNumSchemes; i++) { if (!_stricmp(schemeName, m_pSchemeList[i].schemeName)) return i; diff --git a/src/game/client/ui/vgui_schememanager.h b/src/game/client/ui/vgui_schememanager.h index 38913d8b6..f0befbbfc 100644 --- a/src/game/client/ui/vgui_schememanager.h +++ b/src/game/client/ui/vgui_schememanager.h @@ -1,7 +1,7 @@ #include // handle to an individual scheme -typedef unsigned int SchemeHandle_t; +typedef int SchemeHandle_t; // Register console variables, etc.. void Scheme_Init(); @@ -33,7 +33,7 @@ class CSchemeManager private: class CScheme; CScheme *m_pSchemeList; - unsigned int m_iNumSchemes; + int m_iNumSchemes; // Resolution we were initted at. int m_xRes; diff --git a/src/game/client/ui/vgui_scorepanel.cpp b/src/game/client/ui/vgui_scorepanel.cpp index 46b075af5..41b2f082e 100644 --- a/src/game/client/ui/vgui_scorepanel.cpp +++ b/src/game/client/ui/vgui_scorepanel.cpp @@ -87,7 +87,7 @@ SBColumnInfo g_ColumnInfo[NUM_COLUMNS] = void ScorePanel::HitTestPanel::internalMousePressed(MouseCode code) { - for (unsigned int i = 0; i < _inputSignalDar.getCount(); i++) + for (int i = 0; i < _inputSignalDar.getCount(); i++) { _inputSignalDar[i]->mousePressed(code, this); } @@ -120,7 +120,7 @@ ScorePanel::ScorePanel(int x, int y, int wide, int tall) : Panel(x, y, wide, tal setPaintBorderEnabled(true); int xpos = g_ColumnInfo[0].m_Width + 3; - if (ScreenWidth() >= 640) + if (ScreenWidth >= 640) { // only expand column size for res greater than 640 xpos = XRES(xpos); @@ -133,7 +133,7 @@ ScorePanel::ScorePanel(int x, int y, int wide, int tall) : Panel(x, y, wide, tal m_HeaderGrid.SetDimensions(NUM_COLUMNS, 1); m_HeaderGrid.SetSpacing(0, 0); - for (unsigned int i = 0; i < NUM_COLUMNS; i++) + for (int i = 0; i < NUM_COLUMNS; i++) { if (g_ColumnInfo[i].m_pTitle && g_ColumnInfo[i].m_pTitle[0] == '#') m_HeaderLabels[i].setText(CHudTextMessage::BufferedLocaliseTextString(g_ColumnInfo[i].m_pTitle)); @@ -141,11 +141,11 @@ ScorePanel::ScorePanel(int x, int y, int wide, int tall) : Panel(x, y, wide, tal m_HeaderLabels[i].setText(g_ColumnInfo[i].m_pTitle); int xwide = g_ColumnInfo[i].m_Width; - if (ScreenWidth() >= 640) + if (ScreenWidth >= 640) { xwide = XRES(xwide); } - else if (ScreenWidth() == 400) + else if (ScreenWidth == 400) { // hack to make 400x300 resolution scoreboard fit if (i == 1) @@ -168,7 +168,7 @@ ScorePanel::ScorePanel(int x, int y, int wide, int tall) : Panel(x, y, wide, tal m_HeaderLabels[i].setContentAlignment(g_ColumnInfo[i].m_Alignment); int yres = 12; - if (ScreenHeight() >= 480) + if (ScreenHeight >= 480) { yres = YRES(yres); } @@ -341,9 +341,9 @@ void ScorePanel::SortTeams() g_TeamInfo[j].packetloss += g_PlayerInfoList[i].packetloss; if (g_PlayerInfoList[i].thisplayer) - g_TeamInfo[j].ownteam = true; + g_TeamInfo[j].ownteam = TRUE; else - g_TeamInfo[j].ownteam = false; + g_TeamInfo[j].ownteam = FALSE; // Set the team's number (used for team colors) g_TeamInfo[j].teamnumber = g_PlayerExtraInfo[i].teamnumber; @@ -352,7 +352,7 @@ void ScorePanel::SortTeams() // find team ping/packetloss averages for (i = 1; i <= m_iNumTeams; i++) { - g_TeamInfo[i].already_drawn = false; + g_TeamInfo[i].already_drawn = FALSE; if (g_TeamInfo[i].players > 0) { @@ -391,7 +391,7 @@ void ScorePanel::SortTeams() // Put this team in the sorted list m_iSortedRows[m_iRows] = best_team; m_iIsATeam[m_iRows] = TEAM_YES; - g_TeamInfo[best_team].already_drawn = true; // set the already_drawn to be true, so this team won't get sorted again + g_TeamInfo[best_team].already_drawn = TRUE; // set the already_drawn to be TRUE, so this team won't get sorted again m_iRows++; // Now sort all the players on this team @@ -573,7 +573,7 @@ void ScorePanel::FillGrid() pLabel->setTextOffset(0, 0); int rowheight = 13; - if (ScreenHeight() > 480) + if (ScreenHeight > 480) { rowheight = YRES(rowheight); } @@ -608,7 +608,7 @@ void ScorePanel::FillGrid() // different height for team header rows rowheight = 20; - if (ScreenHeight() >= 480) + if (ScreenHeight >= 480) { rowheight = YRES(rowheight); } @@ -630,7 +630,7 @@ void ScorePanel::FillGrid() // different height for team header rows rowheight = 20; - if (ScreenHeight() >= 480) + if (ScreenHeight >= 480) { rowheight = YRES(rowheight); } @@ -900,7 +900,7 @@ void ScorePanel::cursorMoved(int x, int y, Panel *panel) if (GetClientVoiceMgr()->IsInSquelchMode()) { // look for which cell the mouse is currently over - for (unsigned int i = 0; i < NUM_ROWS; i++) + for (int i = 0; i < NUM_ROWS; i++) { int row, col; if (m_PlayerGrids[i].getCellAtPoint(x, y, row, col)) diff --git a/src/game/client/ui/vgui_scrollbar2.cpp b/src/game/client/ui/vgui_scrollbar2.cpp index c19b42ccc..e07bf7089 100644 --- a/src/game/client/ui/vgui_scrollbar2.cpp +++ b/src/game/client/ui/vgui_scrollbar2.cpp @@ -189,7 +189,7 @@ void ScrollBar2::setRange(int min, int max) void ScrollBar2::fireIntChangeSignal() { - for (unsigned int i = 0; i < _intChangeSignalDar.getCount(); i++) + for (int i = 0; i < _intChangeSignalDar.getCount(); i++) { _intChangeSignalDar[i]->intChanged(_slider->getValue(), this); } @@ -280,7 +280,7 @@ void ScrollBar2::validate() { int buttonOffset = 0; - for (unsigned int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { if (_button[i] != null) { diff --git a/src/game/client/ui/vgui_slider2.cpp b/src/game/client/ui/vgui_slider2.cpp index 4d3031a2a..a06345bae 100644 --- a/src/game/client/ui/vgui_slider2.cpp +++ b/src/game/client/ui/vgui_slider2.cpp @@ -254,7 +254,7 @@ void Slider2::addIntChangeSignal(IntChangeSignal* s) void Slider2::fireIntChangeSignal() { - for(unsigned int i=0;i<_intChangeSignalDar.getCount();i++) + for(int i=0;i<_intChangeSignalDar.getCount();i++) { _intChangeSignalDar[i]->intChanged(getValue(),this); } diff --git a/src/game/client/ui/vgui_spectatorpanel.cpp b/src/game/client/ui/vgui_spectatorpanel.cpp index 55a179cb2..98e139d6e 100644 --- a/src/game/client/ui/vgui_spectatorpanel.cpp +++ b/src/game/client/ui/vgui_spectatorpanel.cpp @@ -87,10 +87,10 @@ void SpectatorPanel::Initialize() SchemeHandle_t hSmallScheme = pSchemes->getSchemeHandle("Team Info Text"); - m_TopBorder = new CTransparentPanel(64, 0, 0, ScreenWidth(), YRES(PANEL_HEIGHT)); + m_TopBorder = new CTransparentPanel(64, 0, 0, ScreenWidth, YRES(PANEL_HEIGHT)); m_TopBorder->setParent(this); - m_BottomBorder = new CTransparentPanel(64, 0, ScreenHeight() - YRES(32), ScreenWidth(), YRES(PANEL_HEIGHT)); + m_BottomBorder = new CTransparentPanel(64, 0, ScreenHeight - YRES(32), ScreenWidth, YRES(PANEL_HEIGHT)); m_BottomBorder->setParent(this); setPaintBackgroundEnabled(false); @@ -143,7 +143,7 @@ void SpectatorPanel::Initialize() m_OptionButton->setUnArmedColor(143, 143, 54, 0); m_OptionButton->setArmedColor(194, 202, 54, 0); - m_CamButton = new ColorButton(CHudTextMessage::BufferedLocaliseTextString("#CAM_OPTIONS"), ScreenWidth() - (XRES(CAMOPTIONS_BUTTON_X) + 15), YRES(6), XRES(CAMOPTIONS_BUTTON_X), YRES(20), false, false); + m_CamButton = new ColorButton(CHudTextMessage::BufferedLocaliseTextString("#CAM_OPTIONS"), ScreenWidth - (XRES(CAMOPTIONS_BUTTON_X) + 15), YRES(6), XRES(CAMOPTIONS_BUTTON_X), YRES(20), false, false); m_CamButton->setParent(m_BottomBorder); m_CamButton->setContentAlignment(vgui::Label::a_center); m_CamButton->setBoundKey((char)255); // special no bound to avoid leading spaces in name @@ -163,7 +163,7 @@ void SpectatorPanel::Initialize() m_PrevPlayerButton->setUnArmedColor(143, 143, 54, 0); m_PrevPlayerButton->setArmedColor(194, 202, 54, 0); - m_NextPlayerButton = new ColorButton(">", (ScreenWidth() - (XRES(CAMOPTIONS_BUTTON_X) + 15)) - XRES(24 + 15), YRES(6), XRES(24), YRES(20), false, false); + m_NextPlayerButton = new ColorButton(">", (ScreenWidth - (XRES(CAMOPTIONS_BUTTON_X) + 15)) - XRES(24 + 15), YRES(6), XRES(24), YRES(20), false, false); m_NextPlayerButton->setParent(m_BottomBorder); m_NextPlayerButton->setContentAlignment(vgui::Label::a_center); m_NextPlayerButton->setBoundKey((char)255); // special no bound to avoid leading spaces in name @@ -175,7 +175,7 @@ void SpectatorPanel::Initialize() // Initialize the bottom title. - float flLabelSize = ((ScreenWidth() - (XRES(CAMOPTIONS_BUTTON_X) + 15)) - XRES(24 + 15)) - XRES((15 + OPTIONS_BUTTON_X + 15) + 38); + float flLabelSize = ((ScreenWidth - (XRES(CAMOPTIONS_BUTTON_X) + 15)) - XRES(24 + 15)) - XRES((15 + OPTIONS_BUTTON_X + 15) + 38); m_BottomMainLabel = new Label("Spectator Bottom", XRES((15 + OPTIONS_BUTTON_X + 15) + 31), YRES(6), flLabelSize, YRES(20)); m_BottomMainLabel->setParent(m_BottomBorder); @@ -222,7 +222,7 @@ void SpectatorPanel::ShowMenu(bool isVisible) { int iLabelSizeX, iLabelSizeY; m_BottomMainLabel->getSize(iLabelSizeX, iLabelSizeY); - m_BottomMainLabel->setPos((ScreenWidth() / 2) - (iLabelSizeX / 2), YRES(6)); + m_BottomMainLabel->setPos((ScreenWidth / 2) - (iLabelSizeX / 2), YRES(6)); } else m_BottomMainLabel->setPos(XRES((15 + OPTIONS_BUTTON_X + 15) + 31), YRES(6)); @@ -315,7 +315,7 @@ void SpectatorPanel::EnableInsetView(bool isEnabled) else m_TopBanner->setVisible(false); - m_TopBorder->setBounds(0, 0, ScreenWidth(), YRES(PANEL_HEIGHT)); + m_TopBorder->setBounds(0, 0, ScreenWidth, YRES(PANEL_HEIGHT)); m_InsetViewButton->setVisible(false); } @@ -360,7 +360,7 @@ void SpectatorPanel::Update() if (iTimeWidth > iTextWidth) iTextWidth = iTimeWidth; - int xPos = ScreenWidth() - (iTextWidth + XRES(4 + offset)); + int xPos = ScreenWidth - (iTextWidth + XRES(4 + offset)); m_ExtraInfo->setBounds(xPos, YRES(1), iTextWidth, iTextHeight); @@ -368,7 +368,7 @@ void SpectatorPanel::Update() m_CurrentTime->setBounds(xPos + XRES(14 + 1), YRES(2) + iTextHeight, iTimeWidth, iTimeHeight); - m_Separator->setPos(ScreenWidth() - (iTextWidth + XRES(4 + 2 + 4 + offset)), YRES(1)); + m_Separator->setPos(ScreenWidth - (iTextWidth + XRES(4 + 2 + 4 + offset)), YRES(1)); m_Separator->setSize(XRES(4), YRES(PANEL_HEIGHT - 2)); for (j = 0; j < TEAM_NUMBER; j++) @@ -376,6 +376,6 @@ void SpectatorPanel::Update() int iwidth, iheight; m_TeamScores[j]->getTextSize(iwidth, iheight); - m_TeamScores[j]->setBounds(ScreenWidth() - (iTextWidth + XRES(4 + 2 + 4 + 2 + offset) + iwidth), YRES(1) + (iheight * j), iwidth, iheight); + m_TeamScores[j]->setBounds(ScreenWidth - (iTextWidth + XRES(4 + 2 + 4 + 2 + offset) + iwidth), YRES(1) + (iheight * j), iwidth, iheight); } } diff --git a/src/game/client/ui/vgui_status.h b/src/game/client/ui/vgui_status.h index ee4f618e5..15737c07d 100644 --- a/src/game/client/ui/vgui_status.h +++ b/src/game/client/ui/vgui_status.h @@ -133,8 +133,8 @@ class VGUI_ImgIcon : public Panel //thothie messes JAN2010_29 - sloppy but works //moved to side that calls this /* - float fimgsize_w = ScreenWidth() * (w*0.01); - float fimgsize_h = ScreenHeight() * (h*0.01); + float fimgsize_w = ScreenWidth * (w*0.01); + float fimgsize_h = ScreenHeight * (h*0.01); int imgsize_w = (int)fimgsize_w; int imgsize_h = (int)fimgsize_h; */ @@ -186,7 +186,7 @@ class VGUI_Status : public Panel, public IHUD CImageDelayed m_FN; bool m_bFN; - VGUI_Status(Panel *pParent) : Panel(0, 0, ScreenWidth(), ScreenHeight()) + VGUI_Status(Panel *pParent) : Panel(0, 0, ScreenWidth, ScreenHeight) { StatusIcons = this; @@ -259,7 +259,7 @@ static void SetFN(bool Up) static void AddStatus(const char* Icon, const char* Name, float Dur, bool bSprite = false) { // MiB FEB2019_22 - When sent a duplicate name, reset the duration - for (unsigned int i = 0; i < StatusIcons->m_Status.size(); i++) + for (int i = 0; i < StatusIcons->m_Status.size(); i++) { VGUI_StatusIcon* pIcon = StatusIcons->m_Status[i]; if (pIcon == NULL) continue; @@ -276,7 +276,7 @@ static void AddImg(const char *Img, const char *Name, int x, int y, int w, int h, float Dur = -1.0) { bool found = false; - for (unsigned int i = 0; i < StatusIcons->m_Img.size(); i++) + for (int i = 0; i < StatusIcons->m_Img.size(); i++) //Check for ID conflictions if (!strcmp(Name, StatusIcons->m_Img[i]->m_Name)) { @@ -287,13 +287,13 @@ static void AddImg(const char *Img, const char *Name, if (!found) { //Thothie JAN2010_29 - convert x/y/h/w coords to % of screen - float fimg_x = ScreenWidth() * (x * 0.01); - float fimg_y = ScreenHeight() * (y * 0.01); + float fimg_x = ScreenWidth * (x * 0.01); + float fimg_y = ScreenHeight * (y * 0.01); int img_x = (int)fimg_x; int img_y = (int)fimg_y; - float fimg_w = ScreenWidth() * (w * 0.01); - float fimg_h = ScreenHeight() * (h * 0.01); + float fimg_w = ScreenWidth * (w * 0.01); + float fimg_h = ScreenHeight * (h * 0.01); int img_w = (int)fimg_w; int img_h = (int)fimg_h; @@ -304,7 +304,7 @@ static void AddImg(const char *Img, const char *Name, void KillStatus(const char *Name) { - for (unsigned int i = 0; i < StatusIcons->m_Status.size(); i++) + for (int i = 0; i < StatusIcons->m_Status.size(); i++) { if (!strcmp(StatusIcons->m_Status[i]->m_Name, Name)) { @@ -316,7 +316,7 @@ void KillStatus(const char *Name) } void KillImg(const char *Name) { - for (unsigned int i = 0; i < StatusIcons->m_Img.size(); i++) + for (int i = 0; i < StatusIcons->m_Img.size(); i++) { if (!strcmp(StatusIcons->m_Img[i]->m_Name, Name)) { diff --git a/src/game/client/ui/vgui_teamfortressviewport.cpp b/src/game/client/ui/vgui_teamfortressviewport.cpp index 3507464ad..40a0a250b 100644 --- a/src/game/client/ui/vgui_teamfortressviewport.cpp +++ b/src/game/client/ui/vgui_teamfortressviewport.cpp @@ -98,7 +98,7 @@ void VGUI_Think() if (!gViewPort) return; - for (unsigned int i = 0; i < gViewPort->m_Menus.size(); i++) + for (int i = 0; i < gViewPort->m_Menus.size(); i++) { gViewPort->m_Menus[i]->Think(); } @@ -224,7 +224,7 @@ void CCommandMenu::AddButton(CommandButton *pButton) bool CCommandMenu::KeyInput(int keyNum) { // loop through all our buttons looking for one bound to keyNum - for (unsigned int i = 0; i < m_iButtons; i++) + for (int i = 0; i < m_iButtons; i++) { if (!m_aButtons[i]->IsNotValid()) { @@ -256,7 +256,7 @@ bool CCommandMenu::KeyInput(int keyNum) //----------------------------------------------------------------------------- void CCommandMenu::ClearButtonsOfArmedState(void) { - for (unsigned int i = 0; i < GetNumButtons(); i++) + for (int i = 0; i < GetNumButtons(); i++) { m_aButtons[i]->setArmed(false); @@ -274,7 +274,7 @@ void CCommandMenu::ClearButtonsOfArmedState(void) //----------------------------------------------------------------------------- CommandButton *CCommandMenu::FindButtonWithSubmenu(CCommandMenu *pSubMenu) { - for (unsigned int i = 0; i < GetNumButtons(); i++) + for (int i = 0; i < GetNumButtons(); i++) { if (m_aButtons[i]->GetSubMenu() == pSubMenu) return m_aButtons[i]; @@ -294,7 +294,7 @@ bool CCommandMenu::RecalculateVisibles(int iNewYPos, bool bHideAll) setPos(_pos[0], iNewYPos); // Cycle through all the buttons in this menu, and see which will be visible - for (unsigned int i = 0; i < m_iButtons; i++) + for (int i = 0; i < m_iButtons; i++) { int iClass = m_aButtons[i]->GetPlayerClass(); if ((iClass && iClass != g_iPlayerClass) || (m_aButtons[i]->IsNotValid()) || bHideAll) @@ -343,10 +343,10 @@ void CCommandMenu::RecalculatePositions(int iYOffset) // Calculate if this is going to fit onscreen, and shuffle it up if it won't int iBottom = iNewYPos + _size[1]; - if (iBottom > ScreenHeight()) + if (iBottom > ScreenHeight) { // Move in increments of button sizes - while (iAdjust < (iBottom - ScreenHeight())) + while (iAdjust < (iBottom - ScreenHeight)) { iAdjust += BUTTON_SIZE_Y - 1; } @@ -362,7 +362,7 @@ void CCommandMenu::RecalculatePositions(int iYOffset) // We need to force all menus below this one to update their positions now, because they // might have submenus riding off buttons in this menu that have just shifted. - for (unsigned int i = 0; i < m_iButtons; i++) + for (int i = 0; i < m_iButtons; i++) m_aButtons[i]->UpdateSubMenus(iAdjust); setPos(_pos[0], iNewYPos); @@ -373,7 +373,7 @@ void CCommandMenu::MakeVisible(CCommandMenu *pChildMenu) { /* // Push down the button leading to the child menu - for (unsigned int i = 0; i < m_iButtons; i++) + for (int i = 0; i < m_iButtons; i++) { if ( (pChildMenu != NULL) && (m_aButtons[i]->GetSubMenu() == pChildMenu) ) { @@ -568,7 +568,7 @@ TeamFortressViewport::TeamFortressViewport(int x, int y, int wide, int tall) : P //CreateCommandMenu(); // Create the spectator Panel - m_pSpectatorPanel = new SpectatorPanel(0, 0, ScreenWidth(), ScreenHeight()); + m_pSpectatorPanel = new SpectatorPanel(0, 0, ScreenWidth, ScreenHeight); m_pSpectatorPanel->setParent(this); m_pSpectatorPanel->setVisible(false); @@ -643,7 +643,7 @@ void TeamFortressViewport::Initialize(void) strncpy(m_sMapName, "", sizeof(m_sMapName) ); strncpy(m_szServerName, "", sizeof(m_szServerName) ); - for (unsigned int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) { m_iValidClasses[i] = 0; strncpy(m_sTeamNames[i], "", MAX_TEAMNAME_SIZE); @@ -1003,7 +1003,7 @@ void TeamFortressViewport::HideScoreBoard(void) // Set the submenu of the Command Menu void TeamFortressViewport::SetCurrentCommandMenu(CCommandMenu *pNewMenu) { - for (unsigned int i = 0; i < m_iNumMenus; i++) + for (int i = 0; i < m_iNumMenus; i++) m_pCommandMenus[i]->setVisible(false); m_pCurrentCommandMenu = pNewMenu; @@ -1180,18 +1180,18 @@ void TeamFortressViewport::UpdateSpectatorPanel() void TeamFortressViewport::CreateScoreBoard(void) { int xdent = SBOARD_INDENT_X, ydent = SBOARD_INDENT_Y; - if (ScreenWidth() == 512) + if (ScreenWidth == 512) { xdent = SBOARD_INDENT_X_512; ydent = SBOARD_INDENT_Y_512; } - else if (ScreenWidth() == 400) + else if (ScreenWidth == 400) { xdent = SBOARD_INDENT_X_400; ydent = SBOARD_INDENT_Y_400; } - m_pScoreBoard = new ScorePanel(xdent, ydent, ScreenWidth() - (xdent * 2), ScreenHeight() - (ydent * 2)); + m_pScoreBoard = new ScorePanel(xdent, ydent, ScreenWidth - (xdent * 2), ScreenHeight - (ydent * 2)); m_pScoreBoard->setParent(this); m_pScoreBoard->setVisible(false); @@ -1322,7 +1322,7 @@ CMenuPanel *TeamFortressViewport::CreateTextWindow(int iTextToShow) }*/ // if we're in the game (ie. have selected a class), flag the menu to be only grayed in the dialog box, instead of full screen - CMenuPanel *pMOTDPanel = CMessageWindowPanel_Create(cText, cTitle, g_iPlayerClass == PC_UNDEFINED, false, 0, 0, ScreenWidth(), ScreenHeight()); + CMenuPanel *pMOTDPanel = CMessageWindowPanel_Create(cText, cTitle, g_iPlayerClass == PC_UNDEFINED, false, 0, 0, ScreenWidth, ScreenHeight); pMOTDPanel->setParent(this); if (pfile) @@ -1478,7 +1478,7 @@ void TeamFortressViewport::HideTopMenu() UpdateCursorState(); } -// Return true if the HUD's allowed to print text messages +// Return TRUE if the HUD's allowed to print text messages bool TeamFortressViewport::AllowedToPrintText(void) { // Prevent text messages when fullscreen menus are up @@ -1488,10 +1488,10 @@ bool TeamFortressViewport::AllowedToPrintText(void) { int iId = m_pCurrentMenu->GetMenuID(); if ( iId == MENU_SPAWN || iId == MENU_NEWCHARACTER ) - return false; + return FALSE; }*/ - return true; + return TRUE; } //====================================================================================== @@ -1510,7 +1510,7 @@ bool TeamFortressViewport::AllowedToPrintText(void) void TeamFortressViewport::CreateTeamMenu() { // Create the panel - m_pTeamMenu = new CTeamMenuPanel(100, false, 0, 0, ScreenWidth(), ScreenHeight()); + m_pTeamMenu = new CTeamMenuPanel(100, false, 0, 0, ScreenWidth, ScreenHeight); m_pTeamMenu->setParent( this ); m_pTeamMenu->setVisible( false ); }*/ @@ -1558,12 +1558,12 @@ void TeamFortressViewport::CreateStoreMenu() if (m_pStoreMenu) return; // Create the panel - m_pStoreMenu = new CStoreMenuPanel(100, false, 0, 0, ScreenWidth(), ScreenHeight()); + m_pStoreMenu = new CStoreMenuPanel(100, false, 0, 0, ScreenWidth, ScreenHeight); m_pStoreMenu->setParent(this); m_pStoreMenu->setVisible(false); // Create the buy panel - m_pStoreBuyMenu = new CStoreBuyPanel(100, false, 0, 0, ScreenWidth(), ScreenHeight()); + m_pStoreBuyMenu = new CStoreBuyPanel(100, false, 0, 0, ScreenWidth, ScreenHeight); m_pStoreBuyMenu->setParent(this); // Create the sell panel @@ -1573,7 +1573,7 @@ void TeamFortressViewport::CreateStoreMenu() m_pStoreStorageMenu = new CStoragePanel(this); // Create the container panel - m_pContainerMenu = new CContainerPanel(100, false, 0, 0, ScreenWidth(), ScreenHeight()); + m_pContainerMenu = new CContainerPanel(100, false, 0, 0, ScreenWidth, ScreenHeight); m_pContainerMenu->setParent(this); m_pContainerMenu->setVisible(false); } @@ -1586,7 +1586,7 @@ void TeamFortressViewport::CreateVGUIMenus() m_Menus.add(CreateHUD_MenuInteract(this)); //Create Interact menu m_Menus.add(m_pLocalizedMenu = new CLocalizedPanel(this)); // MiB MAR2015_01 [LOCAL_PANEL] - Add local panel to list and set pointer - for (unsigned int i = 0; i < m_Menus.size(); i++) + for (int i = 0; i < m_Menus.size(); i++) m_Menus[i]->setVisible(false); m_pHUDPanel->setVisible(true); @@ -1601,7 +1601,7 @@ void TeamFortressViewport::CreateVGUIMenus() /*void TeamFortressViewport::CreateSpectatorMenu() { // Create the Panel - m_pSpectatorMenu = new CTransparentPanel(100, 0, ScreenHeight() - YRES(60), ScreenWidth(), YRES(60)); + m_pSpectatorMenu = new CTransparentPanel(100, 0, ScreenHeight - YRES(60), ScreenWidth, YRES(60)); m_pSpectatorMenu->setParent(this); m_pSpectatorMenu->setVisible(false); @@ -1616,7 +1616,7 @@ void TeamFortressViewport::CreateVGUIMenus() int r, g, b, a; // Create the title - m_pSpectatorLabel = new Label( "Spectator", 0, 0, ScreenWidth(), YRES(25) ); + m_pSpectatorLabel = new Label( "Spectator", 0, 0, ScreenWidth, YRES(25) ); m_pSpectatorLabel->setParent( m_pSpectatorMenu ); m_pSpectatorLabel->setFont( pSchemes->getFont(hTitleScheme) ); pSchemes->getFgColor( hTitleScheme, r, g, b, a ); @@ -1626,7 +1626,7 @@ void TeamFortressViewport::CreateVGUIMenus() m_pSpectatorLabel->setContentAlignment( vgui::Label::a_north ); // Create the Help - Label *pLabel = new Label( CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help" ), 0, YRES(25), ScreenWidth(), YRES(15) ); + Label *pLabel = new Label( CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help" ), 0, YRES(25), ScreenWidth, YRES(15) ); pLabel->setParent( m_pSpectatorMenu ); pLabel->setFont( pSchemes->getFont(hHelpText) ); pSchemes->getFgColor( hHelpText, r, g, b, a ); @@ -1635,7 +1635,7 @@ void TeamFortressViewport::CreateVGUIMenus() pLabel->setBgColor( r, g, b, 255 ); pLabel->setContentAlignment( vgui::Label::a_north ); - pLabel = new Label( CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help2" ), 0, YRES(40), ScreenWidth(), YRES(20) ); + pLabel = new Label( CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help2" ), 0, YRES(40), ScreenWidth, YRES(20) ); pLabel->setParent( m_pSpectatorMenu ); pLabel->setFont( pSchemes->getFont(hHelpText) ); pSchemes->getFgColor( hHelpText, r, g, b, a ); @@ -1803,7 +1803,7 @@ bool TeamFortressViewport::SlotInput(int iSlot) if (m_pCurrentMenu) return m_pCurrentMenu->SlotInput(iSlot); - return false; + return FALSE; } // Direct Key Input @@ -1912,7 +1912,7 @@ int TeamFortressViewport::MsgFunc_ValClass(const char *pszName, int iSize, void { BEGIN_READ(pbuf, iSize); - for (unsigned int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) m_iValidClasses[i] = READ_SHORT(); // Force the menu to update @@ -1927,7 +1927,7 @@ int TeamFortressViewport::MsgFunc_TeamNames(const char *pszName, int iSize, void m_iNumberOfTeams = READ_BYTE(); - for (unsigned int i = 0; i < m_iNumberOfTeams; i++) + for (int i = 0; i < m_iNumberOfTeams; i++) { int teamNum = i + 1; @@ -2075,7 +2075,7 @@ int TeamFortressViewport::MsgFunc_TeamScore(const char *pszName, int iSize, void return 1; // use this new score data instead of combined player scoresw - g_TeamInfo[i].scores_overriden = true; + g_TeamInfo[i].scores_overriden = TRUE; g_TeamInfo[i].frags = READ_SHORT(); g_TeamInfo[i].deaths = READ_SHORT(); diff --git a/src/game/client/ui/vgui_teamfortressviewport.h b/src/game/client/ui/vgui_teamfortressviewport.h index d736559e4..c6d74ad73 100644 --- a/src/game/client/ui/vgui_teamfortressviewport.h +++ b/src/game/client/ui/vgui_teamfortressviewport.h @@ -97,20 +97,20 @@ extern int iTeamColors[5][3]; #define MAPBRIEF_INDENT 30 // Team Menu -#define TMENU_INDENT_X (30 * ((float)ScreenHeight() / 640)) +#define TMENU_INDENT_X (30 * ((float)ScreenHeight / 640)) #define TMENU_HEADER 100 -#define TMENU_SIZE_X (ScreenWidth() - (TMENU_INDENT_X * 2)) +#define TMENU_SIZE_X (ScreenWidth - (TMENU_INDENT_X * 2)) #define TMENU_SIZE_Y (TMENU_HEADER + BUTTON_SIZE_Y * 7) #define TMENU_PLAYER_INDENT (((float)TMENU_SIZE_X / 3) * 2) -#define TMENU_INDENT_Y (((float)ScreenHeight() - TMENU_SIZE_Y) / 2) +#define TMENU_INDENT_Y (((float)ScreenHeight - TMENU_SIZE_Y) / 2) // Class Menu -#define CLMENU_INDENT_X (30 * ((float)ScreenHeight() / 640)) +#define CLMENU_INDENT_X (30 * ((float)ScreenHeight / 640)) #define CLMENU_HEADER 100 -#define CLMENU_SIZE_X (ScreenWidth() - (CLMENU_INDENT_X * 2)) +#define CLMENU_SIZE_X (ScreenWidth - (CLMENU_INDENT_X * 2)) #define CLMENU_SIZE_Y (CLMENU_HEADER + BUTTON_SIZE_Y * 11) #define CLMENU_PLAYER_INDENT (((float)CLMENU_SIZE_X / 3) * 2) -#define CLMENU_INDENT_Y (((float)ScreenHeight() - CLMENU_SIZE_Y) / 2) +#define CLMENU_INDENT_Y (((float)ScreenHeight - CLMENU_SIZE_Y) / 2) // Arrows enum @@ -243,7 +243,7 @@ class CCommandMenu : public Panel // Buttons in this menu CommandButton *m_aButtons[MAX_BUTTONS]; - unsigned int m_iButtons; + int m_iButtons; public: CCommandMenu(CCommandMenu *pParentMenu, int x, int y, int wide, int tall) : Panel(x, y, wide, tall) @@ -264,7 +264,7 @@ class CCommandMenu : public Panel CCommandMenu *GetParentMenu() { return m_pParentMenu; }; int GetXOffset() { return m_iXOffset; }; int GetYOffset() { return m_iYOffset; }; - unsigned int GetNumButtons() { return m_iButtons; }; + int GetNumButtons() { return m_iButtons; }; CommandButton *FindButtonWithSubmenu(CCommandMenu *pSubMenu); void ClearButtonsOfArmedState(void); @@ -290,7 +290,7 @@ class TeamFortressViewport : public Panel float m_flMenuOpenTime; float m_flScoreBoardLastUpdated; float m_flSpectatorPanelLastUpdated; - unsigned int m_iNumMenus; + int m_iNumMenus; int m_iCurrentTeamNumber; int m_iCurrentPlayerClass; int m_iUser1; @@ -333,7 +333,7 @@ class TeamFortressViewport : public Panel int m_iValidClasses[5]; int m_iIsFeigning; int m_iIsSettingDetpack; - unsigned int m_iNumberOfTeams; + int m_iNumberOfTeams; int m_iBuildState; int m_iRandomPC; char m_sTeamNames[5][MAX_TEAMNAME_SIZE]; diff --git a/src/game/client/ui/vgui_voice_tweakdlg.cpp b/src/game/client/ui/vgui_voice_tweakdlg.cpp index b4636fb4d..d59d9ecb8 100644 --- a/src/game/client/ui/vgui_voice_tweakdlg.cpp +++ b/src/game/client/ui/vgui_voice_tweakdlg.cpp @@ -175,8 +175,8 @@ void CVoiceVGUITweakDlg::Open() g_bTweakDlgOpen = true; - m_DlgWidth = ScreenWidth(); - m_DlgHeight = ScreenHeight(); + m_DlgWidth = ScreenWidth; + m_DlgHeight = ScreenHeight; m_pVoiceTweak = gEngfuncs.pVoiceTweak; @@ -184,7 +184,7 @@ void CVoiceVGUITweakDlg::Open() m_pVoiceTweak->StartVoiceTweakMode(); // Set our size. - setPos((ScreenWidth() - m_DlgWidth) / 2, (ScreenHeight() - m_DlgHeight) / 2); + setPos((ScreenWidth - m_DlgWidth) / 2, (ScreenHeight - m_DlgHeight) / 2); setSize(m_DlgWidth, m_DlgHeight); int curY = ITEM_BORDER; diff --git a/src/game/client/util.cpp b/src/game/client/util.cpp index 81062d5f7..71af8638f 100644 --- a/src/game/client/util.cpp +++ b/src/game/client/util.cpp @@ -30,7 +30,7 @@ HLSPRITE LoadSprite(const char *pszName) int i; char sz[256]; - if (ScreenWidth() < 640) + if (ScreenWidth < 640) i = 320; else i = 640; diff --git a/src/game/client/view.cpp b/src/game/client/view.cpp index 1469277a6..9e19c615a 100644 --- a/src/game/client/view.cpp +++ b/src/game/client/view.cpp @@ -97,10 +97,8 @@ extern cvar_t *chase_active; extern cvar_t *scr_ofsx, *scr_ofsy, *scr_ofsz; extern cvar_t *cl_vsmoothing; -enum { - CAM_MODE_RELAX = 1, - CAM_MODE_FOCUS = 2 -}; +#define CAM_MODE_RELAX 1 +#define CAM_MODE_FOCUS 2 Vector v_origin, v_angles, v_cl_angles, v_sim_org, v_lastAngles; Vector g_ViewForward, g_ViewRight, g_ViewUp; @@ -399,7 +397,7 @@ void V_CalcGunAngle(struct ref_params_s *pparams) VectorCopy(viewent->angles, viewent->latched.prevangles); //Master Sword - Setup the viewmodel for rendering - SetBits(viewent->curstate.oldbuttons, MSRDR_VIEWMODEL | MSRDR_NOREFLECT); + SetBits(viewent->curstate.oldbuttons, MSRDR_VIEWMODEL); //Flip the view model based on the hand it's in //if( player.ActiveItemHand() == LEFT_HAND ) SetBits( viewent->curstate.oldbuttons, MSRDR_FLIPPED ); @@ -491,8 +489,8 @@ void V_CalcIntermissionRefdef(struct ref_params_s *pparams) v_angles = pparams->viewangles; } -constexpr unsigned int ORIGIN_BACKUP = 64; -constexpr unsigned int ORIGIN_MASK = (ORIGIN_BACKUP - 1); +#define ORIGIN_BACKUP 64 +#define ORIGIN_MASK (ORIGIN_BACKUP - 1) typedef struct { @@ -515,7 +513,7 @@ V_CalcRefdef void V_CalcNormalRefdef(struct ref_params_s *pparams) { cl_entity_t *ent; - unsigned int i; + int i; Vector angles; float bob, waterOffset; static viewinterp_t ViewInterp; @@ -574,7 +572,7 @@ void V_CalcNormalRefdef(struct ref_params_s *pparams) if (pparams->hardware) { waterEntity = gEngfuncs.PM_WaterEntity(pparams->simorg); - if (waterEntity >= 0 && (unsigned int)waterEntity < pparams->max_entities) + if (waterEntity >= 0 && waterEntity < pparams->max_entities) { pwater = gEngfuncs.GetEntityByIndex(waterEntity); if (pwater && (pwater->model != NULL)) @@ -892,7 +890,7 @@ void V_SmoothInterpolateAngles(float *startAngle, float *endAngle, float *finalA NormalizeAngles(startAngle); NormalizeAngles(endAngle); - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { d = endAngle[i] - startAngle[i]; @@ -1121,7 +1119,7 @@ float MaxAngleBetweenAngles(float *a1, float *a2) NormalizeAngles(a1); NormalizeAngles(a2); - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { d = a2[i] - a1[i]; if (d > 180) @@ -1500,7 +1498,7 @@ void V_CalcSpectatorRefdef(struct ref_params_s *pparams) VectorCopy(pparams->viewangles, v_angles); VectorCopy(pparams->vieworg, v_origin); - if ((g_iUser1 == OBS_IN_EYE || (int)gHUD.m_Spectator.m_pip->value == INSET_IN_EYE) && ent) + if ((g_iUser1 == OBS_IN_EYE || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE) && ent) { // calculate player velocity float timeDiff = ent->curstate.msg_time - ent->prevstate.msg_time; @@ -1654,48 +1652,21 @@ void V_CalcSpectatorRefdef(struct ref_params_s *pparams) VectorCopy(v_origin, pparams->vieworg); } extern float newfov; -void V_CalcMirrorRefdef(struct ref_params_s *pparams) -{ - //float old; - - // ent is the player model ( visible when out of body ) - //ent = gEngfuncs.GetLocalPlayer(); - - //VectorCopy ( pparams->simorg, pparams->vieworg ); - //VectorCopy ( pparams->cl_viewangles, pparams->viewangles ); - - // allways idle in intermission - //old = v_idlescale; - //v_idlescale = 1; - - //V_AddIdle ( pparams ); - - /*if ( gEngfuncs.IsSpectateOnly() ) - { - // in HLTV we must go to 'intermission' position by ourself - VectorCopy( gHUD.m_Spectator.m_cameraOrigin, pparams->vieworg ); - VectorCopy( gHUD.m_Spectator.m_cameraAngles, pparams->viewangles ); - }*/ - - //v_idlescale = old; - - //v_cl_angles = pparams->cl_viewangles; - //v_origin = pparams->vieworg; - //v_angles = pparams->viewangles; -} extern CRenderPlayerInset g_Inset; -void RenderFog( bool bRender ); -void ModifyLevel(ref_params_s &Params); void DLLEXPORT V_CalcRefdef(struct ref_params_s *pparams) { ViewMgr.Origin = pparams->vieworg; ViewMgr.Angles = pparams->viewangles; ViewMgr.Params = pparams; - ViewMgr.Passes = pparams->nextView ? ViewMgr.Passes + 1 : 0; - CMirrorMgr::Render_SetupViewReflection(); + //Single full-screen view pass + pparams->viewport[0] = 0; + pparams->viewport[1] = 0; + pparams->viewport[2] = ScreenWidth; + pparams->viewport[3] = ScreenHeight; + pparams->nextView = 0; // intermission / finale rendering if (pparams->intermission) @@ -1706,12 +1677,10 @@ void DLLEXPORT V_CalcRefdef(struct ref_params_s *pparams) { V_CalcSpectatorRefdef(pparams); } - else if (!ViewMgr.Passes) + else { V_CalcNormalRefdef(pparams); } - else - V_CalcMirrorRefdef(pparams); //Must recalculate this, for the extra stuff that gets rendered later. //This new calculation takes view lowers/view rotations from falling into account @@ -1747,7 +1716,7 @@ void DLLEXPORT V_CalcRefdef(struct ref_params_s *pparams) pparams->movevars->skyvec_y = 0; pparams->movevars->skyvec_z = -1;*/ - RenderFog( true ); + CEnvMgr::RenderFog( true ); v_ViewDist = pparams->movevars->zmax; ViewMgr.LastAngles = ViewMgr.Angles; @@ -1822,11 +1791,11 @@ float CalcFov(float fov_x, float width, float height) if (fov_x < 1 || fov_x > 179) fov_x = 90; // error, set to 90 - x = width / tan(fov_x / 360 * PI); + x = width / tan(fov_x / 360 * M_PI); a = atan(height / x); - a = a * 360 / PI; + a = a * 360 / M_PI; return a; } @@ -1846,10 +1815,10 @@ void V_Move(int mx, int my) Vector farpoint; pmtrace_t tr; - fov = CalcFov(in_fov, (float)ScreenWidth(), (float)ScreenHeight()); + fov = CalcFov(in_fov, (float)ScreenWidth, (float)ScreenHeight); - c_x = (float)ScreenWidth() / 2.0; - c_y = (float)ScreenHeight() / 2.0; + c_x = (float)ScreenWidth / 2.0; + c_y = (float)ScreenHeight / 2.0; dx = (float)mx - c_x; dy = (float)my - c_y; diff --git a/src/game/server/CMakeLists.txt b/src/game/server/CMakeLists.txt index fe38f62b1..d55b71680 100644 --- a/src/game/server/CMakeLists.txt +++ b/src/game/server/CMakeLists.txt @@ -44,6 +44,7 @@ target_include_directories(server PRIVATE ${BASEDIR}/thirdparty ${BASEDIR}/thirdparty/angelscript/include ${BASEDIR}/thirdparty/spdlog/include + ${BASEDIR}/thirdparty/msgpack/include ${BASEDIR}/lib/include ${CMAKE_CURRENT_SOURCE_DIR} effects @@ -58,6 +59,7 @@ target_compile_definitions(server PRIVATE VERSION_SAFE_STEAM_API_INTERFACES VALVE_DLL CURL_STATICLIB + AS_DISABLED HTTP_ONLY) # Check if spdlog is available @@ -65,6 +67,12 @@ if(EXISTS "${BASEDIR}/thirdparty/spdlog/include/spdlog/spdlog.h") target_compile_definitions(server PRIVATE HAS_SPDLOG) endif() +# Check if msgpack is available +if(EXISTS "${BASEDIR}/thirdparty/msgpack/include/msgpack.hpp") + target_compile_definitions(server PRIVATE MSGPACK_DISABLE_BOOST) + target_compile_definitions(server PRIVATE MSGPACK_NO_BOOST) +endif() + if (UNIX) target_compile_definitions(server PRIVATE SWDS) @@ -181,13 +189,14 @@ set(MS "player/playerstats.cpp" "shield.cpp" "store.cpp" - "sv_character.cpp" "svglobals.cpp" + "character/mscharacter.cpp" + "character/sv_character.cpp" + "character/mscharacterheader.h" #"SteamServerHelper.cpp" "../shared/movement/pm_shared.cpp" "../shared/movement/pm_shared.h" "../shared/ms/msmonstershared.cpp" - "../shared/ms/netcodeshared.cpp" "../shared/stats/races.cpp" "../shared/syntax/syntax.cpp" ) @@ -213,7 +222,6 @@ set(MS_Headers #"SteamServerHelper.h" "../shared/ms/groupfile.h" "../shared/ms/mscharacter.h" - "../shared/ms/mscharacterheader.h" "../shared/ms/titles.h" "../shared/ms/votedefs.h" "../shared/stats/races.h" @@ -261,7 +269,6 @@ set(Shared "../shared/ms/mslogger.cpp" "../shared/ms/mslogger.h" "../shared/ms/magic.h" - "../shared/ms/mscharacter.cpp" "../shared/ms/msdebug.h" "../shared/ms/msfileio.cpp" "../shared/ms/msfileio.h" diff --git a/src/game/server/basemonster.h b/src/game/server/basemonster.h index 1aa3ec6ab..eeb652f00 100644 --- a/src/game/server/basemonster.h +++ b/src/game/server/basemonster.h @@ -235,7 +235,7 @@ class CBaseMonster : public CBaseToggle BOOL FindLateralCover(const Vector &vecThreat, const Vector &vecViewOffset); virtual BOOL FindCover(Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist); - virtual BOOL FValidateCover(const Vector &vecCoverLocation) { return true; }; + virtual BOOL FValidateCover(const Vector &vecCoverLocation) { return TRUE; }; virtual float CoverRadius(void) { return 784; } // Default cover radius virtual BOOL FCanCheckAttacks(void); @@ -247,14 +247,14 @@ class CBaseMonster : public CBaseToggle inline BOOL HasConditions(int iConditions) { if (m_afConditions & iConditions) - return true; - return false; + return TRUE; + return FALSE; } inline BOOL HasAllConditions(int iConditions) { if ((m_afConditions & iConditions) == iConditions) - return true; - return false; + return TRUE; + return FALSE; } virtual BOOL FValidateHintType(short sHint); @@ -340,14 +340,14 @@ class CBaseMonster : public CBaseToggle inline BOOL HasMemory(int iMemory) { if (m_afMemory & iMemory) - return true; - return false; + return TRUE; + return FALSE; } inline BOOL HasAllMemories(int iMemory) { if ((m_afMemory & iMemory) == iMemory) - return true; - return false; + return TRUE; + return FALSE; } BOOL ExitScriptedSequence(); diff --git a/src/game/server/bmodels.cpp b/src/game/server/bmodels.cpp index 7d292f97c..a118f362b 100644 --- a/src/game/server/bmodels.cpp +++ b/src/game/server/bmodels.cpp @@ -25,16 +25,16 @@ extern DLL_GLOBAL Vector g_vecAttackDir; - +#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. // covering cheesy noise1, noise2, & noise3 fields so they make more sense (for rotating fans) - -//overloaded generic variable names #define noiseStart noise1 #define noiseStop noise2 #define noiseRunning noise3 - +#define SF_PENDULUM_SWING 2 // spawnflag that makes a pendulum a rope swing. // // BModelOrigin - calculates origin of a bmodel from absmin/size because all bmodel origins are 0 0 0 // @@ -79,6 +79,7 @@ void CFuncWall ::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use CScriptedEnt::Use(pActivator, pCaller, useType, value); } +#define SF_WALL_START_OFF 0x0001 class CFuncWallToggle : public CFuncWall { @@ -116,8 +117,8 @@ void CFuncWallToggle ::TurnOn(void) BOOL CFuncWallToggle ::IsOn(void) { if (pev->solid == SOLID_NOT) - return false; - return true; + return FALSE; + return TRUE; } void CFuncWallToggle ::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) @@ -134,6 +135,9 @@ void CFuncWallToggle ::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY CScriptedEnt::Use(pActivator, pCaller, useType, value); } +#define SF_CONVEYOR_VISUAL 0x0001 +#define SF_CONVEYOR_NOTSOLID 0x0002 +#define SF_CONVEYOR_TOGGLE 0x0004 //Thothie AUG2011_30 toggle conveyors class CFuncConveyor : public CFuncWall { @@ -237,7 +241,7 @@ void CFuncIllusionary ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "skin")) //skin is used for content type { pev->skin = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseToggle::KeyValue(pkvd); @@ -270,7 +274,7 @@ void CFuncIllusionary ::Spawn(void) // // ------------------------------------------------------------------------------- - +#define SF_MONSTERCLIP_START_OFF 0x0001 class CFuncMonsterClip : public CFuncWallToggle { @@ -334,9 +338,9 @@ void CFuncMonsterClip::TurnOn(void) BOOL CFuncMonsterClip::IsOn(void) { if (pev->flags & FL_MONSTERCLIP) - return true; + return TRUE; else - return false; + return FALSE; } // ------------------------------------------------------------------------------- @@ -348,7 +352,7 @@ BOOL CFuncMonsterClip::IsOn(void) // // ------------------------------------------------------------------------------- - +#define SF_PLAYERCLIP_START_OFF 0x0001 class CMSFuncPlayerClip : public CFuncWallToggle { @@ -422,9 +426,9 @@ void CMSFuncPlayerClip::TurnOn(void) BOOL CMSFuncPlayerClip::IsOn(void) { if (pev->solid & SOLID_TRIGGER) - return true; + return TRUE; else - return false; + return FALSE; } // ------------------------------------------------------------------------------- @@ -496,7 +500,7 @@ void CFuncRotating ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "fanfriction")) { m_flFanFriction = atof(pkvd->szValue) / 100; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "volume")) { @@ -506,7 +510,7 @@ void CFuncRotating ::KeyValue(KeyValueData *pkvd) m_flVolume = 1.0; if (m_flVolume < 0.0) m_flVolume = 0.0; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spawnorigin")) { @@ -518,7 +522,7 @@ void CFuncRotating ::KeyValue(KeyValueData *pkvd) else if (FStrEq(pkvd->szKeyName, "sounds")) { m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else BaseClass::KeyValue(pkvd); @@ -713,8 +717,8 @@ void CFuncRotating ::HurtTouch(CBaseEntity *pOther) // RampPitchVol - ramp pitch and volume up to final values, based on difference // between how fast we're going vs how fast we plan to go // -constexpr float FANPITCHMIN = 30; -constexpr float FANPITCHMAX = 100; +#define FANPITCHMIN 30 +#define FANPITCHMAX 100 void CFuncRotating ::RampPitchVol(int fUp) { @@ -783,7 +787,7 @@ void CFuncRotating ::SpinUp(void) } else { - RampPitchVol(true); + RampPitchVol(TRUE); } } @@ -824,7 +828,7 @@ void CFuncRotating ::SpinDown(void) } else { - RampPitchVol(false); + RampPitchVol(FALSE); } } @@ -944,12 +948,12 @@ void CPendulum ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "distance")) { m_distance = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "damp")) { m_damp = atof(pkvd->szValue) * 0.001; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CScriptedEnt::KeyValue(pkvd); diff --git a/src/game/server/cdll_dll.h b/src/game/server/cdll_dll.h index 665a0dfc2..00519ceec 100644 --- a/src/game/server/cdll_dll.h +++ b/src/game/server/cdll_dll.h @@ -20,30 +20,26 @@ #ifndef CDLL_DLL_H #define CDLL_DLL_H -constexpr int MAX_WEAPONS = 32; // ??? -constexpr int MAX_NORMAL_BATTERY = 100; -constexpr int WEAPON_NOCLIP = -1; -constexpr int MAX_WEAPON_SLOTS = 5; // hud item selection slots -constexpr int MAX_ITEM_TYPES = 6; // hud item selection slots -constexpr int MAX_ITEMS = 5; // hard coded item types -constexpr int MAX_WEAPON_POSITIONS = MAX_WEAPON_SLOTS; - -enum { - HIDEHUD_WEAPONS = (1 << 0), - HIDEHUD_FLASHLIGHT = (1 << 1), - HIDEHUD_ALL = (1 << 2), - HIDEHUD_HEALTH = (1 << 3) -}; - -constexpr int MAX_AMMO_TYPES = 32;// ??? -constexpr int MAX_AMMO_SLOTS = 32;// not really slots - -enum { - HUD_PRINTNOTIFY = 1, - HUD_PRINTCONSOLE = 2, - HUD_PRINTTALK = 3, - HUD_PRINTCENTER = 4 -}; +#define MAX_WEAPONS 32 // ??? +#define MAX_WEAPON_SLOTS 5 // hud item selection slots +#define MAX_ITEM_TYPES 6 // hud item selection slots + +#define MAX_ITEMS 5 // hard coded item types + +#define HIDEHUD_WEAPONS (1 << 0) +#define HIDEHUD_FLASHLIGHT (1 << 1) +#define HIDEHUD_ALL (1 << 2) +#define HIDEHUD_HEALTH (1 << 3) + +#define MAX_AMMO_TYPES 32 // ??? +#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 WEAPON_SUIT 31 #endif \ No newline at end of file diff --git a/src/game/server/character/mscharacter.cpp b/src/game/server/character/mscharacter.cpp new file mode 100644 index 000000000..0b46bd8b7 --- /dev/null +++ b/src/game/server/character/mscharacter.cpp @@ -0,0 +1,103 @@ +/* + MSCharacter.cpp - Shared character definitions +*/ + +#include "inc_weapondefs.h" +#include "stats/stats.h" +#include "global.h" +#include "fn/FNSharedDefs.h" +#include "mscharacter.h" +#include "magic.h" +#include "script.h" + +//Vector MSChar_Interface::LastGoodPos, +// MSChar_Interface::LastGoodAng; + +void ReplaceChar(char *pString, char org, char dest); + +const char *GetSaveFileName(int iCharacter, CBasePlayer *pPlayer) +{ + static char cFileName[MAX_PATH]; + + msstring FileID = GETPLAYERAUTHID(pPlayer->edict()); + msstring Prefix = FNShared::IsEnabled() ? "central_" : ""; + + //Thothie MAR2010_08 emergency work around + //iCharacter = pPlayer->m_CharacterNum; + //Print("CHAR_SAVE_DEBUG [MSCharacter]: %i vs %i\n",iCharacter+1,pPlayer->m_CharacterNum); + + _snprintf(cFileName, MAX_PATH, "%s/save/%s%s_%i.char", EngineFunc::GetGameDir(), Prefix.c_str(), FileID.c_str(), iCharacter + 1); + ReplaceChar(cFileName, ':', '-'); + + return cFileName; +} + +const char *GetSaveFileName(int iCharacter, const char *AuthID) +{ + static char cFileName[MAX_PATH]; + + //Server + Print("CHAR_SAVE_DEBUG [GetSaveFileName]: %s %#i\n", cFileName, iCharacter + 1); + _snprintf(cFileName, MAX_PATH, "%s/save/%s_%i.char", EngineFunc::GetGameDir(), AuthID, iCharacter + 1); + ReplaceChar(cFileName, ':', '-'); + + return cFileName; +} + +jointype_e MSChar_Interface::CanJoinThisMap(savedata_t &Data, const std::vector &VisitedMaps) +{ + //phase this function out. Use the one below + jointype_e JoinType = JN_NOTALLOWED; + if (MSGlobals::CanCreateCharOnMap) + JoinType = JN_STARTMAP; //Can create a character on this map + + if (!_stricmp(Data.MapName, MSGlobals::MapName) || //Already in this map Or trying to + !_stricmp(Data.NextMap, MSGlobals::MapName)) //transition to this map + JoinType = JN_TRAVEL; + else if (HasVisited(MSGlobals::MapName, VisitedMaps) && + GetOtherPlayerTransition(NULL)) + JoinType = JN_STARTMAP; // Already visited this map before and at least + //1 other player is currently playing it + else if (Data.IsElite) + JoinType = JN_ELITE; //GM. You can always join any may + + if (strcmp(Data.Name, "LOAD_ERROR-RECONNECT") == 0) + { + JoinType = JN_NOTALLOWED; + } + if (strcmp(Data.Name, "LOAD_FAILED-RECONNECT") == 0) + { + JoinType = JN_NOTALLOWED; + } + //If this character is one that shouldn't be loaded + //then don't allow it to be loaded. ---MiB--- + + return JoinType; +} + +jointype_e MSChar_Interface::CanJoinThisMap(charinfo_t &CharData, const std::vector &VisitedMaps) +{ + jointype_e JoinType = JN_NOTALLOWED; + if (MSGlobals::CanCreateCharOnMap) + JoinType = JN_STARTMAP; //Can create a character on this map + + if (!_stricmp(CharData.MapName, MSGlobals::MapName) || //Already in this map Or trying to + !_stricmp(CharData.NextMap, MSGlobals::MapName)) //transition to this map + JoinType = JN_TRAVEL; + else if (HasVisited(MSGlobals::MapName, VisitedMaps) && + GetOtherPlayerTransition(NULL)) + JoinType = JN_STARTMAP; // Already visited this map before and at least + //1 other player is currently playing it + else if (CharData.IsElite) + JoinType = JN_ELITE; //GM. You can always join any may + + return JoinType; +} + +bool MSChar_Interface::HasVisited(const char* MapName, const std::vector &VisitedMaps) +{ + for (const std::string &Map : VisitedMaps) + if (Map == MapName) + return true; + return false; +} \ No newline at end of file diff --git a/src/game/server/character/mscharacterheader.h b/src/game/server/character/mscharacterheader.h new file mode 100644 index 000000000..edc93c07c --- /dev/null +++ b/src/game/server/character/mscharacterheader.h @@ -0,0 +1,125 @@ +#ifndef MSCHARACTERHEADER_H +#define MSCHARACTERHEADER_H + +#ifdef _WIN32 +#include +#endif + +//Legacy on-disk character header. Old (pre-msgpack) save files store this struct raw, +//so its layout is FROZEN - never add, remove or reorder anything in here. +//Add new header fields to savedata_t below instead. +struct savedata_legacy_t +{ + //Player info + int Version; + char Name[32], + Race[16], + MapName[16], + NextMap[32], + OldTrans[32], + NewTrans[32], + SteamID[32], + Party[12]; + byte IsElite; + int Gold; + short MaxHP, MaxMP, HP, MP; + Vector Origin, Angles; + byte Gender; + ulong PartyID; //Unique ID for party. If I join a server that has a party with the same name, I won't + //automatically join their party + + short PlayerKills; + float TimeWaitedToForgetKill; //Counts up... when reachs a certain number, decrement PlayerKills + float TimeWaitedToForgetSteal; //Counts up... when reachs a certain number, player is not considered a thief +}; + +#ifdef _WIN32 +#include +#endif + +//In-memory character header. New header fields go here (and get a charfield_e key). +struct savedata_t : savedata_legacy_t +{ + short Body = 0; +}; + +// +// Character save format (msgpack) +// =============================== +// A save is "MSRC" followed by a msgpack map of { charfield_e -> value }. +// Sub-records (items, storages, companions) are maps keyed by their own enums below. +// +// Rules for changing the format: +// - Add a field: append a NEW key to the right enum, write it in SaveChar and read it in the reader. +// Older builds ignore keys they don't know. Saves without the key leave the field zeroed. +// - Remove a field: stop writing/reading it and mark the key "// RETIRED". Never reuse or renumber a key. +// - Only bump CHARFMT_VERSION when an existing key changes meaning. Readers refuse saves +// with a newer format, and can branch on CF_FORMAT to convert older ones. +// +// Reading and writing live in sv_character.cpp (server only). +// + +#define CHARFMT_VERSION 1 + +//Top-level keys +enum charfield_e +{ + CF_FORMAT = 0, //int - CHARFMT_VERSION the save was written with + CF_NAME = 1, //str + CF_MAPNAME = 2, //str + CF_NEXTMAP = 3, //str + CF_OLDTRANS = 4, //str + CF_NEWTRANS = 5, //str + CF_STEAMID = 6, //str + CF_PARTY = 7, //str + CF_PARTYID = 8, //uint + CF_ISELITE = 9, //int + CF_GOLD = 10, //int + CF_MAXHP = 11, //int + CF_MAXMP = 12, //int + CF_HP = 13, //int + CF_MP = 14, //int + CF_GENDER = 15, //int + CF_PLAYERKILLS = 16, //int + CF_TIMEFORGETKILL = 17, //float + CF_BODY = 18, //int + + CF_VISITEDMAPS = 32, //[str, ...] + CF_SKILLS = 33, //[ stat: [ substat: [value, exp], ... ], ... ] + CF_SPELLS = 34, //[str, ...] + CF_ITEMS = 35, //[item, ...] + CF_STORAGES = 36, //[storage, ...] + CF_COMPANIONS = 37, //[companion, ...] + CF_QUESTS = 38, //[ [name, data], ... ] + CF_QUICKSLOTS = 39, //[ nil | [type, id], ... ] +}; + +//Item keys +enum charitemfield_e +{ + CI_NAME = 0, //str + CI_PROPERTIES = 1, //uint + CI_LOCATION = 2, //int + CI_HAND = 3, //int + CI_ID = 4, //uint - item ID at last save (used by quickslots) + CI_QUALITY = 5, //int - perishable/drinkable only + CI_MAXQUALITY = 6, //int - perishable/drinkable only + CI_QUANTITY = 7, //int - groupable only + CI_CONTENTS = 8, //[item, ...] - containers only +}; + +//Storage keys +enum charstoragefield_e +{ + CS_NAME = 0, //str + CS_ITEMS = 1, //[item, ...] +}; + +//Companion keys +enum charcompanionfield_e +{ + CC_SCRIPT = 0, //str + CC_VARS = 1, //[ [name, value], ... ] +}; + +#endif //MSCHARACTERHEADER_H diff --git a/src/game/server/character/sv_character.cpp b/src/game/server/character/sv_character.cpp new file mode 100644 index 000000000..7ce4c5238 --- /dev/null +++ b/src/game/server/character/sv_character.cpp @@ -0,0 +1,1297 @@ +// +// Character functions for the Server +// + +#include "inc_weapondefs.h" +#include "stats/stats.h" +#include "global.h" +#include "mscharacter.h" +#include "magic.h" +#include "script.h" +#include "fn/FNSharedDefs.h" +#include "mslogger.h" + +#include + +#ifndef _WIN32 +#include "sys/io.h" +#endif + +//NOTENOTE: remove this when char corruption bug is fixed - Solokiller 5/10/2017 +#include "game.h" +//END NOTE + +void CBasePlayer::CreateChar(createchar_t &CharData) +{ + //Create a new character, using the options the user specified. + //A custom savedata_t struct can be created for the new + //character and passed to SaveAll, but any items the character + //starts with need to be added to Gear + + savedata_t Data; + memset(&Data, 0, sizeof(savedata_t)); + + strncpy(Data.Name, CharData.Name, sizeof(Data.Name)); + strncpy(Data.Race, "Human", sizeof(Data.Race)); // LEGACY + strncpy(Data.MapName, MSGlobals::MapName, sizeof(Data.MapName)); + Data.Gender = CharData.Gender; + Data.Gold = MSGlobals::DefaultGold; + +#ifndef VALVE_DLL + MSCLGlobals::RemoveAllEntities(); +#else + RemoveAllItems(false, true); +#endif + //Give 1 skill to each stat + for (int i = 0; i < m_Stats.size(); i++) + { + CStat &Stat = m_Stats[i]; + if (Stat.m_SubStats.size() == 1) //Parry - Only give 1 to proficiency + Stat.m_SubStats[0].Value = 1; + else if (Stat.m_SubStats.size() <= STATPROP_TOTAL) //Weapon Skills - Give 1 to power + Stat.m_SubStats[STATPROP_POWER].Value = 1; + else if (Stat.m_SubStats.size() > STATPROP_TOTAL) //Spellcasting - Give 1 to each spell category + for (int r = 0; r < Stat.m_SubStats.size(); r++) + Stat.m_SubStats[r].Value = 1; + } + + //Give free items. Wear any packs + for (int i = 0; i < MSGlobals::DefaultFreeItems.size(); i++) + { + CGenericItem *pStartingItem = NewGenericItem(MSGlobals::DefaultFreeItems[i]); + if (!pStartingItem) + continue; + + if (FBitSet(pStartingItem->MSProperties(), ITEM_WEARABLE)) + { + //Wear packs + //m_fClientInitiated = true; //Dont send a client update + if (!AddItem(pStartingItem, false, true) || !pStartingItem->WearItem()) + pStartingItem->SUB_Remove(); + //m_fClientInitiated = false; + } + else if (FBitSet(pStartingItem->MSProperties(), ITEM_SPELL)) + { + LearnSpell(pStartingItem->ItemName, true); + pStartingItem->SUB_Remove(); + } + else + { + //Normal item + if (!AddItem(pStartingItem, true, true)) + pStartingItem->SUB_Remove(); + } + } + + //Put the chosen weapon in the player's right hand + CGenericItem *pStartingItem = NewGenericItem(CharData.Weapon); + + if (FBitSet(pStartingItem->MSProperties(), ITEM_SPELL)) + //It's a spell + { + LearnSpell(pStartingItem->ItemName, false); + pStartingItem->SUB_Remove(); + } + else + { + if (!AddItem(pStartingItem, true, true)) + pStartingItem->SUB_Remove(); + } + + m_CharacterNum = CharData.iChar; + m_CharacterState = CHARSTATE_LOADED; //Temporary, so the save will succeed + MSChar_Interface::SaveChar(this, &Data); //Save the new character + + m_CharacterState = CHARSTATE_UNLOADED; //Created a new character... this one is no longer valid + + //Clean up + RemoveAllItems(false, true); + +#ifdef VALVE_DLL + //Update player's character list, so the new char is sent down to client + if (!FNShared::IsEnabled()) + PreLoadChars(); +#endif +} + +bool DeleteChar(CBasePlayer *pPlayer, int iCharacter) +{ +#ifdef VALVE_DLL + if (FNShared::IsEnabled()) + { + FNShared::DeleteCharacter(pPlayer, iCharacter); + return true; + } +#endif + + const char *pszCharFileName = GetSaveFileName(iCharacter, pPlayer); + int ret = remove(pszCharFileName); //Delete savefile + remove(BACKUP_NAME(pszCharFileName)); //Delete backup + + //Update player's char list + if (iCharacter < MAX_CHARSLOTS) + pPlayer->m_CharInfo[iCharacter].Status = CDS_NOTFOUND; + + return (!ret) ? true : false; +} + +void MSChar_Interface::AutoSave(CBasePlayer* pPlayer) +{ + if (gpGlobals->time <= pPlayer->m_TimeNextSave) return; + + SaveChar(pPlayer, NULL); // Don't auto save too often when using FN. + pPlayer->m_TimeNextSave = gpGlobals->time + RANDOM_FLOAT(5.0f, 10.0f); +} + +// +// msgpack character format. Field keys and versioning rules are in mscharacterheader.h +// A save is CHARPACK_MAGIC followed by one msgpack map. +// + +#define CHARPACK_MAGIC "MSRC" //Legacy saves always start with 0 (CHARDATA_HEADER1), so this can't collide +#define CHARPACK_MAGIC_LEN 4 + +//Non-throwing readers. A value of the wrong type reads as the default, so a malformed +//or changed field can never take down the whole load. + +static long long PackReadInt(const msgpack::object &Obj, long long Default = 0) +{ + switch (Obj.type) + { + case msgpack::type::POSITIVE_INTEGER: return (long long)Obj.via.u64; + case msgpack::type::NEGATIVE_INTEGER: return Obj.via.i64; + case msgpack::type::FLOAT32: + case msgpack::type::FLOAT64: return (long long)Obj.via.f64; + case msgpack::type::BOOLEAN: return Obj.via.boolean ? 1 : 0; + default: return Default; + } +} + +static float PackReadFloat(const msgpack::object &Obj, float Default = 0.0f) +{ + switch (Obj.type) + { + case msgpack::type::FLOAT32: + case msgpack::type::FLOAT64: return (float)Obj.via.f64; + case msgpack::type::POSITIVE_INTEGER: return (float)Obj.via.u64; + case msgpack::type::NEGATIVE_INTEGER: return (float)Obj.via.i64; + default: return Default; + } +} + +//Copies a string into a fixed buffer, truncating if needed. Always null-terminates. +static void PackReadStr(const msgpack::object &Obj, char *pOut, size_t OutSize) +{ + if (!OutSize) + return; + + size_t Len = 0; + if (Obj.type == msgpack::type::STR) + { + Len = Obj.via.str.size; + if (Len > OutSize - 1) + Len = OutSize - 1; + memcpy(pOut, Obj.via.str.ptr, Len); + } + pOut[Len] = 0; +} + +static msstring PackReadMsStr(const msgpack::object &Obj) +{ + char cTemp[MSSTRING_SIZE]; + PackReadStr(Obj, cTemp, sizeof(cTemp)); + return msstring(cTemp); +} + +//Returns the array/map, or an empty one if the object is some other type +static msgpack::object_array PackArray(const msgpack::object &Obj) +{ + if (Obj.type == msgpack::type::ARRAY) + return Obj.via.array; + + msgpack::object_array Empty; + Empty.size = 0; + Empty.ptr = NULL; + return Empty; +} + +static msgpack::object_map PackMap(const msgpack::object &Obj) +{ + if (Obj.type == msgpack::type::MAP) + return Obj.via.map; + + msgpack::object_map Empty; + Empty.size = 0; + Empty.ptr = NULL; + return Empty; +} + +// +// Helpers shared by the msgpack and legacy readers +// + +// MiB JUL2010_02 - Hacky, but if we add more stats and we load a character that doesn't have said stat in the file +// we set it to the default new stat value (level 0 in Prof and Balance, 1 in Power) +static void InitUnsavedStats(statlist &Stats, int SavedStats) +{ + for (int i = SavedStats; i < Stats.size(); i++) + { + CStat &Stat = Stats[i]; + Stat.m_SubStats[Stat.m_SubStats.size() - 1].Value = 1; + } +} + +static void ApplyItemAlias(msstring &ItemName) +{ + msstringstringhash::iterator iAlias = CGenericItemMgr::mItemAlias.find(ItemName); + if (iAlias != CGenericItemMgr::mItemAlias.end()) + ItemName = iAlias->second; +} + +// +// Read msgpack sections +// + +static void ReadItemListPack(const msgpack::object &Obj, mslist &outItems); + +static bool ReadItemPack(const msgpack::object &Obj, genericitem_full_t &outItem) +{ + clrmem(outItem); + + msgpack::object_map Fields = PackMap(Obj); + for (uint32_t f = 0; f < Fields.size; f++) + { + const msgpack::object &Value = Fields.ptr[f].val; + switch (PackReadInt(Fields.ptr[f].key, -1)) + { + case CI_NAME: outItem.Name = PackReadMsStr(Value); break; + case CI_PROPERTIES: outItem.Properties = (ulong)PackReadInt(Value); break; + case CI_LOCATION: outItem.Location = (unsigned short)PackReadInt(Value); break; + case CI_HAND: outItem.Hand = (byte)PackReadInt(Value); break; + case CI_ID: outItem.ID = (ulong)PackReadInt(Value); break; + case CI_QUALITY: outItem.Quality = (unsigned short)PackReadInt(Value); break; + case CI_MAXQUALITY: outItem.MaxQuality = (unsigned short)PackReadInt(Value); break; + case CI_QUANTITY: outItem.Quantity = (unsigned short)PackReadInt(Value); break; + case CI_CONTENTS: ReadItemListPack(Value, outItem.ContainerItems); break; + } + } + + if (!outItem.Name.len()) + return false; + + ApplyItemAlias(outItem.Name); + return true; +} + +static void ReadItemListPack(const msgpack::object &Obj, mslist &outItems) +{ + msgpack::object_array Items = PackArray(Obj); + for (uint32_t i = 0; i < Items.size; i++) + { + genericitem_full_t Item; + if (!ReadItemPack(Items.ptr[i], Item)) + { + MS_ERROR("ReadCharData: Bad item, skipping..."); + continue; + } + outItems.add(Item); + } +} + +static void ReadStringListPack(const msgpack::object &Obj, std::vector &outList) +{ + msgpack::object_array Strings = PackArray(Obj); + outList.clear(); + outList.reserve(Strings.size); + char cTemp[MSSTRING_SIZE]; + for (uint32_t i = 0; i < Strings.size; i++) + { + PackReadStr(Strings.ptr[i], cTemp, sizeof(cTemp)); + outList.emplace_back(cTemp); + } +} + +bool MSChar_Interface::ReadCharData(void *pData, ulong Size, chardata_t *CharData) +{ + return CharData->ReadData(pData, Size); +} + +//Reads both msgpack and legacy saves +bool chardata_t::ReadData(void *pData, ulong Size) +{ + if (Size >= CHARPACK_MAGIC_LEN && !memcmp(pData, CHARPACK_MAGIC, CHARPACK_MAGIC_LEN)) + return ReadDataPack((const char *)pData + CHARPACK_MAGIC_LEN, Size - CHARPACK_MAGIC_LEN); + + return ReadDataLegacy(pData, Size); +} + +bool chardata_t::ReadDataPack(const char *pData, size_t Size) +{ + memset(static_cast(this), 0, sizeof(savedata_t)); + Version = SAVECHAR_VERSION; + strncpy(Race, "Human", sizeof(Race)); // LEGACY + + try + { + //Every element takes at least a byte, so no count can legitimately exceed Size. Stops a corrupt + //save from requesting a huge allocation or nesting deep enough to blow the stack. + const msgpack::unpack_limit Limit(Size, Size, Size, Size, Size, 64); + msgpack::object_handle Handle = msgpack::unpack(pData, Size, MSGPACK_NULLPTR, MSGPACK_NULLPTR, Limit); + msgpack::object_map Root = PackMap(Handle.get()); + + //Check the format before reading anything + int Format = -1; + for (uint32_t i = 0; i < Root.size; i++) + if (PackReadInt(Root.ptr[i].key, -1) == CF_FORMAT) + Format = (int)PackReadInt(Root.ptr[i].val, -1); + + if (Format < 1 || Format > CHARFMT_VERSION) + { + MS_ERROR("ReadCharData: unsupported character format %i (this build supports up to %i)", Format, CHARFMT_VERSION); + return false; + } + + //Keys not handled here were written by a newer build, or are retired, and are skipped + for (uint32_t i = 0; i < Root.size; i++) + { + const msgpack::object &Value = Root.ptr[i].val; + + switch (PackReadInt(Root.ptr[i].key, -1)) + { + //Header + case CF_NAME: PackReadStr(Value, Name, sizeof(Name)); break; + case CF_MAPNAME: PackReadStr(Value, MapName, sizeof(MapName)); break; + case CF_NEXTMAP: PackReadStr(Value, NextMap, sizeof(NextMap)); break; + case CF_OLDTRANS: PackReadStr(Value, OldTrans, sizeof(OldTrans)); break; + case CF_NEWTRANS: PackReadStr(Value, NewTrans, sizeof(NewTrans)); break; + case CF_STEAMID: PackReadStr(Value, SteamID, sizeof(SteamID)); break; + case CF_PARTY: PackReadStr(Value, Party, sizeof(Party)); break; + case CF_PARTYID: PartyID = (ulong)PackReadInt(Value); break; + case CF_ISELITE: IsElite = (byte)PackReadInt(Value); break; + case CF_GOLD: Gold = (int)PackReadInt(Value); break; + case CF_MAXHP: MaxHP = (short)PackReadInt(Value); break; + case CF_MAXMP: MaxMP = (short)PackReadInt(Value); break; + case CF_HP: HP = (short)PackReadInt(Value); break; + case CF_MP: MP = (short)PackReadInt(Value); break; + case CF_GENDER: Gender = (byte)PackReadInt(Value); break; + case CF_PLAYERKILLS: PlayerKills = (short)PackReadInt(Value); break; + case CF_TIMEFORGETKILL: TimeWaitedToForgetKill = PackReadFloat(Value); break; + case CF_BODY: Body = (short)PackReadInt(Value); break; + + //Sections + case CF_VISITEDMAPS: ReadStringListPack(Value, m_VisitedMaps); break; + case CF_SPELLS: ReadStringListPack(Value, m_Spells); break; + case CF_ITEMS: ReadItemListPack(Value, m_Items); break; + + case CF_SKILLS: + { + CStat::InitStatList(m_Stats); + + msgpack::object_array Stats = PackArray(Value); + for (uint32_t s = 0; s < Stats.size; s++) + { + CStat *pStat = GetStat(s); + if (!pStat) + continue; + + msgpack::object_array SubStats = PackArray(Stats.ptr[s]); + for (uint32_t r = 0; r < SubStats.size; r++) + { + CSubStat *pSubStat = pStat->GetSubStat(r); + if (!pSubStat) + continue; + + msgpack::object_array SubStat = PackArray(SubStats.ptr[r]); //[value, exp] + if (SubStat.size > 0) + pSubStat->Value = (int)PackReadInt(SubStat.ptr[0]); + if (SubStat.size > 1) + pSubStat->Exp = (ulong)PackReadInt(SubStat.ptr[1]); + } + } + + InitUnsavedStats(m_Stats, Stats.size); + break; + } + + case CF_STORAGES: + { + msgpack::object_array Storages = PackArray(Value); + for (uint32_t s = 0; s < Storages.size; s++) + { + storage_t Storage; + msgpack::object_map Fields = PackMap(Storages.ptr[s]); + for (uint32_t f = 0; f < Fields.size; f++) + { + const msgpack::object &FieldValue = Fields.ptr[f].val; + switch (PackReadInt(Fields.ptr[f].key, -1)) + { + case CS_NAME: Storage.Name = PackReadMsStr(FieldValue); break; + case CS_ITEMS: ReadItemListPack(FieldValue, Storage.Items); break; + } + } + m_Storages.add(Storage); + } + break; + } + + case CF_COMPANIONS: + { + msgpack::object_array Companions = PackArray(Value); + for (uint32_t c = 0; c < Companions.size; c++) + { + companion_t &Companion = m_Companions.add(companion_t()); + Companion.Active = false; + + msgpack::object_map Fields = PackMap(Companions.ptr[c]); + for (uint32_t f = 0; f < Fields.size; f++) + { + const msgpack::object &FieldValue = Fields.ptr[f].val; + switch (PackReadInt(Fields.ptr[f].key, -1)) + { + case CC_SCRIPT: Companion.ScriptName = PackReadMsStr(FieldValue); break; + case CC_VARS: + { + msgpack::object_array Vars = PackArray(FieldValue); + for (uint32_t v = 0; v < Vars.size; v++) + { + msgpack::object_array Var = PackArray(Vars.ptr[v]); //[name, value] + if (Var.size < 2) + continue; + Companion.SaveVarName.add(PackReadMsStr(Var.ptr[0])); + Companion.SaveVarValue.add(PackReadMsStr(Var.ptr[1])); + } + break; + } + } + } + } + break; + } + + case CF_QUESTS: + { + msgpack::object_array Quests = PackArray(Value); + m_Quests.clear(); + for (uint32_t q = 0; q < Quests.size; q++) + { + msgpack::object_array QuestData = PackArray(Quests.ptr[q]); //[name, data] + if (QuestData.size < 2) + continue; + + quest_t Quest; + Quest.Name = PackReadMsStr(QuestData.ptr[0]); + Quest.Data = PackReadMsStr(QuestData.ptr[1]); + m_Quests.add(Quest); + } + break; + } + + case CF_QUICKSLOTS: + { + msgpack::object_array QuickSlots = PackArray(Value); + m_QuickSlots.clear(); + for (uint32_t q = 0; q < QuickSlots.size; q++) + { + quickslot_t QuickSlot; + msgpack::object_array SlotData = PackArray(QuickSlots.ptr[q]); //nil or [type, id] + if (SlotData.size >= 2) + { + QuickSlot.Active = true; + QuickSlot.Type = (quickslottype_e)PackReadInt(SlotData.ptr[0]); + QuickSlot.ID = (uint)PackReadInt(SlotData.ptr[1]); + } + else + QuickSlot.Active = false; + + m_QuickSlots.push_back(QuickSlot); //Drops anything past MAX_QUICKSLOTS + } + break; + } + } + } + } + catch (const std::exception &e) + { + MS_ERROR("ReadCharData: corrupt character data (%s)", e.what()); + return false; + } + + return true; +} + +// +// LEGACY: Read pre-msgpack saves +// + +static bool IsValidCharVersion(int Version) +{ + return (Version == SAVECHAR_VERSION_MSC) || (Version == SAVECHAR_VERSION_MSR); +} + +bool chardata_t::ReadDataLegacy(void *pData, ulong Size) +{ + bool ValidVersion = false; + memset(static_cast(this), 0, sizeof(savedata_t)); //Header fields added after the legacy format start at 0 + + CPlayer_DataBuffer m_File(Size); + m_File.Write(pData, Size); + byte DataID = CHARDATA_UNKNOWN; + + do + { + m_File.ReadByte(DataID); + if (DataID >= CHARDATA_UNKNOWN) + { + ValidVersion = false; + break; + } + + if (ReadHeader1(DataID, m_File)) + ValidVersion = true; + + ReadMaps1(DataID, m_File); + ReadSkills1(DataID, m_File); + ReadSpells1(DataID, m_File); + ReadItems1(DataID, m_File); + ReadStorageItems1(DataID, m_File); + ReadCompanions1(DataID, m_File); + SkipHelpTips1(DataID, m_File); + ReadQuests1(DataID, m_File); + ReadQuickSlots1(DataID, m_File); + } while (!m_File.Eof()); + + m_File.Close(); + + return ValidVersion; +} + +bool chardata_t::ReadHeader1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_HEADER1) + { + m_File.Read(static_cast(this), sizeof(savedata_legacy_t)); //[HEADER} + + if (!IsValidCharVersion(Version)) + return false; + + return true; + } + return false; +} + +// +// LEGACY: Read chunks from raw char data +// + +static char cTemp[MSSTRING_SIZE]; + +void chardata_t::ReadMaps1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_MAPSVISITED1) + { + //Read Maps Visited + //Must come DIRECTLY after reading the savedata_t Data + int Maps = 0; + m_File.ReadInt(Maps); //[INT] + m_VisitedMaps.clear(); + if (Maps > 0) + m_VisitedMaps.reserve(Maps); + for (int m = 0; m < Maps; m++) + { + m_File.ReadString(cTemp, MSSTRING_SIZE); //[STRING] + m_VisitedMaps.emplace_back(cTemp); + } + } +} + +void chardata_t::ReadSkills1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_SKILLS1) + { + // Read skills + CStat::InitStatList(m_Stats); + + CStat* pStat = NULL; + CSubStat* pSubStat = NULL; + + byte Stats = 0; + m_File.ReadByte(Stats); + + for (int i = 0; i < Stats; i++) + { + pStat = GetStat(i); + byte SubStats = 0; + m_File.ReadByte(SubStats); + + for (int r = 0; r < SubStats; r++) + { + short Value = 0; + int Exp = 0; + m_File.ReadShort(Value); //[SHORT] + m_File.ReadInt(Exp); //[INT] + + pSubStat = (pStat ? pStat->GetSubStat(r) : NULL); + + // Handle legacy loading, hacky & messy: + if ((Version == SAVECHAR_VERSION_MSC) && (i == SKILL_SPELLCASTING)) + { + switch (r) + { + case 5: // Used to be DIVINATION + pSubStat = (pStat ? pStat->GetSubStat(STAT_MAGIC_DIVINATION) : NULL); + break; + + case 6: // Used to be AFFLICTION + pSubStat = (pStat ? pStat->GetSubStat(STAT_MAGIC_AFFLICTION) : NULL); + break; + } + } + + if (pStat && pSubStat) + { + pSubStat->Value = Value; + pSubStat->Exp = Exp; + } + } + } + + InitUnsavedStats(m_Stats, Stats); + } +} + +void chardata_t::ReadSpells1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_SPELLS1) + { + //Read Magic spells + byte Spells = 0; + m_File.ReadByte(Spells); //[BYTE] + m_Spells.reserve(Spells); + for (int s = 0; s < Spells; s++) + { + m_File.ReadString(cTemp, MSSTRING_SIZE); //[STRING] + m_Spells.emplace_back(cTemp); + } + } +} + +void chardata_t::ReadItems1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_ITEMS1 || DataID == CHARDATA_ITEMS2) + { + //Read Items + byte GearItems = 0; + m_File.ReadByte(GearItems); //[SHORT] + for (int i = 0; i < GearItems; i++) + { + genericitem_full_t Item; + if (!ReadItem1(DataID, m_File, Item)) //[X ITEMS] + continue; + + m_Items.add(Item); + } + } +} + +void chardata_t::ReadStorageItems1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_STORAGE1) + { + //Read storage items + + short Storages = 0; + m_File.ReadShort(Storages); //[SHORT] + for (int i = 0; i < Storages; i++) + { + storage_t Storage; + m_File.ReadString(Storage.Name, MSSTRING_SIZE); //[X STRINGS] + + short Items = 0; + m_File.ReadShort(Items); //[X SHORTS] + for (int i = 0; i < Items; i++) + { + genericitem_full_t Item; + if (!ReadItem1(DataID, m_File, Item)) //[Y ITEMS] + continue; + + Storage.Items.add(Item); + } + + m_Storages.add(Storage); + } + } +} + +void chardata_t::ReadCompanions1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_COMPANIONS1) + { + //Read Companions + short Companions = 0; + m_File.ReadShort(Companions); //[SHORT] + for (int c = 0; c < Companions; c++) + { + companion_t &Companion = m_Companions.add(companion_t()); + m_File.ReadString(cTemp, MSSTRING_SIZE); //[STRING] + Companion.ScriptName = cTemp; + Companion.Active = false; + + //Read the saved variables + short Vars = 0; + m_File.ReadShort(Vars); //[SHORT] + for (int var = 0; var < Vars; var++) + { + m_File.ReadString(cTemp, MSSTRING_SIZE); //[STRING] + Companion.SaveVarName.add(cTemp); + m_File.ReadString(cTemp, MSSTRING_SIZE); //[STRING] + Companion.SaveVarValue.add(cTemp); + } + } + } +} + +void chardata_t::SkipHelpTips1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_HELPTIPS1) + { + //Help tips are no longer saved, but the chunk still has to be read past + short HelpTips = 0; + m_File.ReadShort(HelpTips); //[SHORT] + for (int t = 0; t < HelpTips; t++) + m_File.ReadString(cTemp, MSSTRING_SIZE); //[STRING] + } +} + +void chardata_t::ReadQuests1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_QUESTS1) + { + //Read Quests + int Quests = 0; + m_File.ReadInt(Quests); //[INT] + m_Quests.clear(); + for (int q = 0; q < Quests; q++) + { + quest_t Quest; + m_File.ReadString(cTemp, MSSTRING_SIZE); //[STRING] + Quest.Name = cTemp; + m_File.ReadString(cTemp, MSSTRING_SIZE); //[STRING] + Quest.Data = cTemp; + m_Quests.add(Quest); + } + } +} + +void chardata_t::ReadQuickSlots1(byte DataID, CPlayer_DataBuffer &m_File) +{ + if (DataID == CHARDATA_QUICKSLOTS1) + { + //Read Quickslots + byte QuickSlots = 0; + m_File.ReadByte(QuickSlots); //[BYTE] + m_QuickSlots.clear(); + for (int q = 0; q < QuickSlots; q++) + { + quickslot_t QuickSlot; + byte Type = 0; + m_File.ReadByte(Type); //[BYTE] + + if (Type) //Something in this slot + { + int OldID = -1; + m_File.ReadInt(OldID); //[INT] + + QuickSlot.Active = true; + QuickSlot.Type = (quickslottype_e)(Type - 1); //Slot type is offset by 1 + QuickSlot.ID = OldID; + } + else //Nothing in this slot + { + QuickSlot.Active = false; + } + + m_QuickSlots.push_back(QuickSlot); //Drops anything past MAX_QUICKSLOTS, but still reads it so the next chunk lines up + } + } +} + +bool chardata_t::ReadItem1(byte DataID, CPlayer_DataBuffer &Data, genericitem_full_t &outItem) +{ + clrmem(outItem); + + char cTemp[128]; + Data.ReadString(cTemp, sizeof(cTemp)); //[STRING] + if (!cTemp || !cTemp[0]) + return false; + + outItem.Name = cTemp; + ApplyItemAlias(outItem.Name); + + //It is now possible to read an item from file correctly, but not be able to spawn that item. + //Be sure that, even if the item can't be created, all of the item's data is read from file properly + + short Properties = 0; + Data.ReadShort(Properties); //[SHORT] + + outItem.Properties = Properties; + + short Location = 0; + Data.ReadShort(Location); //[SHORT] + outItem.Location = Location; + + byte Hand = 0; + Data.ReadByte(Hand); //[BYTE] + outItem.Hand = Hand; + + if (DataID == CHARDATA_ITEMS2) + { + int LastID = 0; + Data.ReadInt(LastID); //[INT] + outItem.ID = LastID; + } + + if (FBitSet(Properties, ITEM_PERISHABLE) || + FBitSet(Properties, ITEM_DRINKABLE)) + { + short Quality = 0, MaxQuality = 0; + Data.ReadShort(Quality); //[SHORT] + Data.ReadShort(MaxQuality); //[SHORT] + + outItem.Quality = Quality; + outItem.MaxQuality = MaxQuality; + } + + if (FBitSet(Properties, ITEM_GROUPABLE)) + { + short GroupAmt = 0; + Data.ReadShort(GroupAmt); //[SHORT] + + outItem.Quantity = GroupAmt; + } + + if (FBitSet(Properties, ITEM_CONTAINER)) + { + short iItemCount = 0; + Data.ReadShort(iItemCount); //[SHORT] + + genericitem_full_t PackItem; + for (int i = 0; i < iItemCount; i++) + { + bool Success = ReadItem1(DataID, Data, PackItem); + if (!Success) + { + MS_ERROR("ReadItem() Bad item in container, skipping..."); + continue; + } + outItem.ContainerItems.add(PackItem); + + /*if( pItem ) + pPackItem->PutInPack( pItem ); + else + //If I couldn't spawn this pack, drop the item that's supposed to be inside it + pPackItem->Drop( 3, (Vector &)g_vecZero, (Vector &)g_vecZero, (Vector &)g_vecZero );*/ + } + } + + return true; +} + +// +// Save Character +// ============== + +struct charpack_t +{ + msgpack::sbuffer Buf; + msgpack::packer Pk; + + charpack_t() : Pk(Buf) {} +}; + +static void PackStr(charpack_t &Out, const char *pszValue, size_t MaxLen = MSSTRING_SIZE) +{ + uint32_t Len = pszValue ? (uint32_t)strnlen(pszValue, MaxLen) : 0; + Out.Pk.pack_str(Len); + if (Len) + Out.Pk.pack_str_body(pszValue, Len); +} + +static void PackStr(charpack_t &Out, msstring &Value) +{ + PackStr(Out, Value.c_str(), Value.len()); +} + +//A map or array whose size isn't known up front. Reserves a 16-bit count and patches in the +//real one when the scope ends, so fields can be added or written conditionally without +//keeping a separate count in sync. Nested scopes must end before their parent (just use C++ scoping). +class CPackScope +{ +public: + CPackScope(charpack_t &Out, bool IsMap) : m_Out(Out), m_Offset(Out.Buf.size()), m_Count(0) + { + const char Header[3] = {(char)(IsMap ? 0xde : 0xdc), 0, 0}; //map16 / array16 + m_Out.Buf.write(Header, sizeof(Header)); + } + + ~CPackScope() + { + if (m_Count > 0xFFFF) + MS_ERROR("SaveChar: too many entries (%u) in one map/array, save is corrupt!", m_Count); + + //Buffer may have been reallocated since the header was written, so go through the offset + char *pHeader = m_Out.Buf.data() + m_Offset; + pHeader[1] = (char)((m_Count >> 8) & 0xFF); + pHeader[2] = (char)(m_Count & 0xFF); + } + + //Map: write a key and value + template + void Field(int FieldKey, const T &Value) + { + m_Out.Pk.pack(FieldKey); + m_Out.Pk.pack(Value); + m_Count++; + } + + void FieldStr(int FieldKey, const char *pszValue, size_t MaxLen) + { + m_Out.Pk.pack(FieldKey); + PackStr(m_Out, pszValue, MaxLen); + m_Count++; + } + + void FieldStr(int FieldKey, msstring &Value) + { + m_Out.Pk.pack(FieldKey); + PackStr(m_Out, Value); + m_Count++; + } + + //Map: write a key, the caller packs exactly one value (or nested scope) after it + void Key(int FieldKey) + { + m_Out.Pk.pack(FieldKey); + m_Count++; + } + + //Array: the caller packed one element + void Added() { m_Count++; } + +private: + charpack_t &m_Out; + size_t m_Offset; + uint32_t m_Count; +}; + +//Returns false if the item isn't saved (spells) +static bool PackItem(charpack_t &Out, genericitem_full_t &Item) +{ + if (FBitSet(Item.Properties, ITEM_SPELL)) + return false; + + CPackScope Fields(Out, true); + Fields.FieldStr(CI_NAME, Item.Name); + Fields.Field(CI_PROPERTIES, Item.Properties); + Fields.Field(CI_LOCATION, Item.Location); + Fields.Field(CI_HAND, Item.Hand); + Fields.Field(CI_ID, Item.ID); //Item ID at last save (used by quickslots to identify this item) + + if (FBitSet(Item.Properties, ITEM_PERISHABLE) || + FBitSet(Item.Properties, ITEM_DRINKABLE)) + { + Fields.Field(CI_QUALITY, Item.Quality); + Fields.Field(CI_MAXQUALITY, Item.MaxQuality); + } + + if (FBitSet(Item.Properties, ITEM_GROUPABLE)) + Fields.Field(CI_QUANTITY, Item.Quantity); + + if (FBitSet(Item.Properties, ITEM_CONTAINER)) + { + Fields.Key(CI_CONTENTS); + CPackScope Contents(Out, false); + for (int i = 0; i < Item.ContainerItems.size(); i++) + if (PackItem(Out, Item.ContainerItems[i])) + Contents.Added(); + } + + return true; +} + +static CScript *GetCompanionScript(companion_t &Companion) +{ + CBaseEntity *pEntity = Companion.Entity.Entity(); + if (!pEntity) + return NULL; + IScripted *pScripted = pEntity->GetScripted(); + if (!pScripted || !pScripted->m_Scripts.size()) + return NULL; + return pScripted->m_Scripts[0]; +} + +//Packs the whole character into Out.Buf. Keys and versioning rules: mscharacterheader.h +static void PackChar(charpack_t &Out, CBasePlayer *pPlayer, savedata_t &Data) +{ + Out.Buf.clear(); //Keeps its allocation + Out.Buf.write(CHARPACK_MAGIC, CHARPACK_MAGIC_LEN); + + CPackScope Root(Out, true); + + //Header + Root.Field(CF_FORMAT, CHARFMT_VERSION); + Root.FieldStr(CF_NAME, Data.Name, sizeof(Data.Name)); + Root.FieldStr(CF_MAPNAME, Data.MapName, sizeof(Data.MapName)); + Root.FieldStr(CF_NEXTMAP, Data.NextMap, sizeof(Data.NextMap)); + Root.FieldStr(CF_OLDTRANS, Data.OldTrans, sizeof(Data.OldTrans)); + Root.FieldStr(CF_NEWTRANS, Data.NewTrans, sizeof(Data.NewTrans)); + Root.FieldStr(CF_STEAMID, Data.SteamID, sizeof(Data.SteamID)); + Root.FieldStr(CF_PARTY, Data.Party, sizeof(Data.Party)); + Root.Field(CF_PARTYID, Data.PartyID); + Root.Field(CF_ISELITE, Data.IsElite); + Root.Field(CF_GOLD, Data.Gold); + Root.Field(CF_MAXHP, Data.MaxHP); + Root.Field(CF_MAXMP, Data.MaxMP); + Root.Field(CF_HP, Data.HP); + Root.Field(CF_MP, Data.MP); + Root.Field(CF_GENDER, Data.Gender); + Root.Field(CF_PLAYERKILLS, Data.PlayerKills); + Root.Field(CF_TIMEFORGETKILL, Data.TimeWaitedToForgetKill); + Root.Field(CF_BODY, Data.Body); + + //Maps visited + Root.Key(CF_VISITEDMAPS); + Out.Pk.pack_array(pPlayer->m_Maps.size()); + for (const std::string &Map : pPlayer->m_Maps) + PackStr(Out, Map.c_str(), MSSTRING_MAXLEN); + + //Skills + Root.Key(CF_SKILLS); + statlist &StatList = pPlayer->m_Stats; + Out.Pk.pack_array(StatList.size()); + for (int i = 0; i < StatList.size(); i++) + { + CStat &Stat = StatList[i]; + Out.Pk.pack_array(Stat.m_SubStats.size()); + for (int r = 0; r < Stat.m_SubStats.size(); r++) + { + CSubStat &SubStat = Stat.m_SubStats[r]; + Out.Pk.pack_array(2); + Out.Pk.pack(SubStat.Value); + Out.Pk.pack(SubStat.Exp); + } + } + + //Magic spells + Root.Key(CF_SPELLS); + spellgroup_v &SpellList = pPlayer->m_SpellList; + Out.Pk.pack_array(SpellList.size()); + for (int s = 0; s < SpellList.size(); s++) + PackStr(Out, SpellList[s]); + + //Items + Root.Key(CF_ITEMS); + { + CPackScope Items(Out, false); + for (int i = 0; i < pPlayer->Gear.size(); i++) + { + if (pPlayer->Gear[i] == pPlayer->PlayerHands) //Skip player hands + continue; + + genericitem_full_t Item = genericitem_full_t(pPlayer->Gear[i]); + if (PackItem(Out, Item)) + Items.Added(); + } + } + + //Storage items + Root.Key(CF_STORAGES); + Out.Pk.pack_array(pPlayer->m_Storages.size()); + for (int s = 0; s < pPlayer->m_Storages.size(); s++) + { + storage_t &Storage = pPlayer->m_Storages[s]; + + CPackScope StorageFields(Out, true); + StorageFields.FieldStr(CS_NAME, Storage.Name); + StorageFields.Key(CS_ITEMS); + CPackScope Items(Out, false); + for (int i = 0; i < Storage.Items.size(); i++) + if (PackItem(Out, Storage.Items[i])) + Items.Added(); + } + + //Companions - save any variables that start with "companion.save." + Root.Key(CF_COMPANIONS); + Out.Pk.pack_array(pPlayer->m_Companions.size()); + for (int c = 0; c < pPlayer->m_Companions.size(); c++) + { + companion_t &Companion = pPlayer->m_Companions[c]; + + CPackScope CompanionFields(Out, true); + CompanionFields.FieldStr(CC_SCRIPT, Companion.ScriptName); + CompanionFields.Key(CC_VARS); + CPackScope Vars(Out, false); + + CScript *Script = GetCompanionScript(Companion); + if (!Script) + continue; + + for (int v = 0; v < Script->m_Variables.size(); v++) + { + scriptvar_t &Var = Script->m_Variables[v]; + if (!Var.Name.starts_with("companion.save.")) + continue; + + Out.Pk.pack_array(2); + PackStr(Out, Var.Name); + PackStr(Out, Var.Value); + Vars.Added(); + } + } + + //Quests + Root.Key(CF_QUESTS); + Out.Pk.pack_array(pPlayer->m_Quests.size()); + for (int q = 0; q < pPlayer->m_Quests.size(); q++) + { + Out.Pk.pack_array(2); + PackStr(Out, pPlayer->m_Quests[q].Name); + PackStr(Out, pPlayer->m_Quests[q].Data); + } + + //Quickslots + Root.Key(CF_QUICKSLOTS); + Out.Pk.pack_array(MAX_QUICKSLOTS); + for (int q = 0; q < MAX_QUICKSLOTS; q++) + { + quickslot_t &QuickSlot = pPlayer->m_QuickSlots[q]; + if (QuickSlot.Active) + { + Out.Pk.pack_array(2); + Out.Pk.pack((int)QuickSlot.Type); + Out.Pk.pack(QuickSlot.ID); + } + else + Out.Pk.pack_nil(); + } +} + +//If pData != NULL, then this is a new char +void MSChar_Interface::SaveChar(CBasePlayer *pPlayer, savedata_t *pData) +{ + //Can I save right now? + if (pPlayer->m_CharacterState == CHARSTATE_UNLOADED /*|| //Can't save if no character is created + MSGlobals::GameType != GAMETYPE_ADVENTURE*/ + ) //If the gametype isn't adventure, we can't save no matter what. + { + return; + } + + //MiB JUL2010_13 - Don't save in dev mode + if (MSGlobals::DevModeEnabled) + return; + + //FEB2015_25 Thothie - don't save if <15 hp (char delete bug workaround) + if (pPlayer->MaxHP() < 15) + return; + + //Add this map to the list of maps visited + if (!HasVisited(MSGlobals::MapName, pPlayer->m_Maps)) + pPlayer->m_Maps.emplace_back(MSGlobals::MapName.c_str()); + + const char *pszFileName; + //#ifdef VALVE_DLL + pszFileName = GetSaveFileName(pPlayer->m_CharacterNum, pPlayer); + //#else + // pszFileName = GetSaveFileName( pPlayer->m_CharacterNum ); + //#endif + + //if( fVerbose ) Print( "Saving to file: %s\n", pszFileName ); + + //Initialize + savedata_t Data; + memset(&Data, 0, sizeof(savedata_t)); + if (pData) + memcpy(&Data, pData, sizeof(savedata_t)); + + //Copy the data + Data.Version = SAVECHAR_VERSION; + //strcpy( Data.MapName, (pPlayer->iHP > 0) ? g_MapName : "" ); + + if (!pData) + { + strncpy(Data.Name, pPlayer->m_DisplayName, sizeof(Data.Name)); // Store actual character name (DisplayName() is servername, and will have a (#) at the end if there are duplicates on the server) + strncpy(Data.Race, "Human", sizeof(Data.Race)); // LEGACY + strncpy(Data.Party, pPlayer->GetPartyName(), sizeof(Data.Party) - 1); + Data.PartyID = pPlayer->GetPartyID(); + + strncpy(Data.MapName, MSGlobals::MapName, sizeof(Data.MapName)); + + strncpy(Data.OldTrans, pPlayer->m_OldTransition, 32); + strncpy(Data.NextMap, pPlayer->m_NextMap, 32); + strncpy(Data.NewTrans, pPlayer->m_NextTransition, 32); + + //MS_INFO("SaveChar: Saving transitions - MapName='%s', OldTrans='%s', NextMap='%s', NewTrans='%s'", + // Data.MapName, Data.OldTrans, Data.NextMap, Data.NewTrans); + + Data.IsElite = pPlayer->m_fIsElite; + Data.Gold = pPlayer->m_Gold; + Data.MaxHP = pPlayer->m_MaxHP; + Data.MaxMP = pPlayer->m_MaxMP; + if (pPlayer->pev->deadflag == DEAD_NO) + { + Data.HP = pPlayer->m_HP; + Data.MP = pPlayer->m_MP; + } + else + { + //Tried to save while dead. + //Set Health/Mana to 0 to indicate this + Data.HP = Data.MP = 0.0; + //fDead = true; + //pPlayer->iHP = 1.0; + } + + //Data.Origin = LastGoodPos; + //Data.Angles = LastGoodAng; + //Print( "Save: Data.Origin: %f %f %f\n", Data.Origin.x, Data.Origin.y, Data.Origin.z ); + //Data.SayType = pPlayer->m_SayType; + Data.Gender = pPlayer->m_Gender; + Data.PlayerKills = pPlayer->m_PlayersKilled; + Data.TimeWaitedToForgetKill = pPlayer->m_TimeWaitedToForgetKill; + Data.Body = pPlayer->m_CharInfo[pPlayer->m_CharacterNum].Body; + //#ifdef VALVE_DLL + strncpy(Data.SteamID, GETPLAYERAUTHID(pPlayer->edict()), 32); + //#else + // strncpy( Data.SteamID, MSCLGlobals::AuthID, 32 ); + //#endif + } + + //Let companions update their saved vars. Done before packing so no script runs mid-pack. + for (int c = 0; c < pPlayer->m_Companions.size(); c++) + { + CBaseEntity *pEntity = pPlayer->m_Companions[c].Entity.Entity(); + IScripted *pScripted = pEntity ? pEntity->GetScripted() : NULL; + if (pScripted && pScripted->m_Scripts.size()) + pScripted->CallScriptEvent("game_companion_save"); + } + + //The pack buffer is reused between saves, so steady-state saves don't allocate. + //Everything below copies the data before returning. + static charpack_t s_CharPack; + PackChar(s_CharPack, pPlayer, Data); + + const char *pPackData = s_CharPack.Buf.data(); + const size_t PackSize = s_CharPack.Buf.size(); + + if (FNShared::IsEnabled()) + { + // If Central Server is enabled, save to the Central Server instead of locally + FNShared::CreateOrUpdateCharacter(pPlayer, pPlayer->m_CharacterNum, pPackData, PackSize, (pData == NULL)); + return; + } + + CPlayer_DataBuffer gFile; + gFile.SetBuffer((byte *)pPackData, PackSize); + gFile.WriteToFile(pszFileName, "wb", true); + gFile.Close(); +} diff --git a/src/game/server/client.cpp b/src/game/server/client.cpp index f14b66238..ef1a6f904 100644 --- a/src/game/server/client.cpp +++ b/src/game/server/client.cpp @@ -50,7 +50,7 @@ extern void PlayerPrecache(); // Temp -constexpr int MAX_MONSTERS = 5; +#define MAX_MONSTERS 5 int g_SummonedMonsters = 0; extern DLL_GLOBAL unsigned long g_ulModelIndexPlayer; @@ -186,7 +186,6 @@ void ClientDisconnect(edict_t *pEntity) // Try to get Steam ID from client info int iPlayerIndex = ENTINDEX(pEntity) - 1; - if (iPlayerIndex >= 0 && iPlayerIndex < gpGlobals->maxClients) { clientaddr_t &ClientInfo = g_NewClients[iPlayerIndex]; @@ -351,16 +350,16 @@ void Host_Say(edict_t *pEntity, int teamonly) } // make sure the text has content - char *pc = nullptr; - for (pc = p; pc != nullptr && *pc != 0; pc++) + char *pc = NULL; + for (pc = p; pc != NULL && *pc != 0; pc++) { if (isprint(*pc) && !isspace(*pc)) { - pc = nullptr; // we've found an alphanumeric character, so text is valid + pc = NULL; // we've found an alphanumeric character, so text is valid break; } } - if (pc != nullptr) + if (pc != NULL) return; // no character found, so say nothing // turn on color set 2 (color on, no sound) @@ -383,8 +382,8 @@ void Host_Say(edict_t *pEntity, int teamonly) // This may return the world in single player if the client types something between levels or during spawn // so check it, or it will infinite loop - client = nullptr; - while (((client = (CBasePlayer *)UTIL_FindEntityByClassname(client, "player")) != nullptr) && (!FNullEnt(client->edict()))) + client = NULL; + while (((client = (CBasePlayer *)UTIL_FindEntityByClassname(client, "player")) != NULL) && (!FNullEnt(client->edict()))) { if (!client->pev) continue; @@ -402,14 +401,14 @@ void Host_Say(edict_t *pEntity, int teamonly) if (teamonly && g_pGameRules->PlayerRelationship(client, CBaseEntity::Instance(pEntity)) != GR_TEAMMATE) continue; - MESSAGE_BEGIN(MSG_ONE, gmsgSayText, nullptr, client->pev); + MESSAGE_BEGIN(MSG_ONE, gmsgSayText, NULL, client->pev); WRITE_BYTE(ENTINDEX(pEntity)); WRITE_STRING(text); MESSAGE_END(); } // print to the sending client - MESSAGE_BEGIN(MSG_ONE, gmsgSayText, nullptr, &pEntity->v); + MESSAGE_BEGIN(MSG_ONE, gmsgSayText, NULL, &pEntity->v); WRITE_BYTE(ENTINDEX(pEntity)); WRITE_STRING(text); MESSAGE_END(); @@ -515,8 +514,8 @@ void ClientCommand2(edict_t *pEntity) msstring Text = msstring(Args).find_str(" "); //skip the first parameter Text = Text.substr(1); - CBaseEntity* pGameMasterEnt = UTIL_FindEntityByString(nullptr, "netname", msstring("-") + "game_master"); - IScripted* pGMScript = (pGameMasterEnt ? pGameMasterEnt->GetScripted() : nullptr); + CBaseEntity* pGameMasterEnt = UTIL_FindEntityByString(NULL, "netname", msstring("-") + "game_master"); + IScripted* pGMScript = (pGameMasterEnt ? pGameMasterEnt->GetScripted() : NULL); if (pGMScript) { msstringlist Parameters; @@ -526,6 +525,7 @@ void ClientCommand2(edict_t *pEntity) pGMScript->CallScriptEvent("game_playerspeak", &Parameters); } +#ifndef AS_DISABLED // Fire the PlayerSayText event to AngelScript ASEngineEventManager* pEventManager = ASEngineEventManager::Instance(); if( pEventManager && pPlayer ) @@ -534,6 +534,7 @@ void ClientCommand2(edict_t *pEntity) const char* pszSteamID = GETPLAYERAUTHID( pPlayer->edict() ); pEventManager->FirePlayerSayTextEvent(pszPlayerName, pszSteamID, Text.c_str()); } +#endif pPlayer->Speak(Text, static_cast(SayType)); } @@ -654,7 +655,7 @@ void ClientCommand2(edict_t *pEntity) if (CMD_ARGC() >= 3) { CBaseEntity *pEntity = StringToEnt(CMD_ARGV(1)); - IScripted *pScript = nullptr; + IScripted *pScript = NULL; if (pEntity && (pScript = pEntity->GetScripted())) { static msstringlist Params; @@ -758,7 +759,7 @@ void ClientCommand2(edict_t *pEntity) //Validate default weapon spawn bool validItem = false; - for (unsigned int i = 0; i < MSGlobals::DefaultWeapons.size(); i++) + for (int i = 0; i < MSGlobals::DefaultWeapons.size(); i++) { if (MSGlobals::DefaultWeapons[i] == NewChar.Weapon) { @@ -776,28 +777,6 @@ void ClientCommand2(edict_t *pEntity) else ClientPrint(pPlayer->pev, at_console, "*** Can't Access Character Menu - Character Loaded or Loading ***\n"); } - else if (FStrEq(pcmd, "ul") && CMD_ARGC() >= 2) - { - if (!MSGlobals::ServerSideChar) - return; - - if (MSGlobals::CentralEnabled) - return; - - char Buffer[256]; - strncpy(Buffer, CMD_ARGV(1), 3); - Buffer[3] = 0; - - if (!strcmp(Buffer, "new") && strlen(CMD_ARGV(1)) == 3 && CMD_ARGC() == 5) - { - MSChar_Interface::HL_SVNewIncomingChar(pPlayer, atoi(CMD_ARGV(2)), atoi(CMD_ARGV(3)), atoi(CMD_ARGV(4))); - } - else if (CMD_ARGC() == 2) - { - MSChar_Interface::HL_SVReadCharData(pPlayer, CMD_ARGV(1)); - } - } - else if (FStrEq(pcmd, "+special")) pPlayer->pbs.MoreBTNSDown |= BTN_SPECIAL; else if (FStrEq(pcmd, "-special")) @@ -814,11 +793,11 @@ void ClientCommand2(edict_t *pEntity) //Stealing disabled //else if (FStrEq(pcmd, "steal")) - // pPlayer->StealAnyItems( nullptr ); + // pPlayer->StealAnyItems( NULL ); else if (FStrEq(pcmd, "getmenuoptions")) { - CMSMonster *pMonster = nullptr; + CMSMonster *pMonster = NULL; if (CMD_ARGC() >= 2) { @@ -972,7 +951,7 @@ void ClientCommand2(edict_t *pEntity) for (unsigned int ID = 0; ID < SHRT_MAX; ID++) { bool Duplicate = false; - for (unsigned int i = 0; i < pStorage->Items.size(); i++) + for (int i = 0; i < pStorage->Items.size(); i++) if (pStorage->Items[i].ID == ID) { Duplicate = true; @@ -997,7 +976,7 @@ void ClientCommand2(edict_t *pEntity) return; int ItemID = atoi(CMD_ARGV(2)); - genericitem_t *pStorageItem = nullptr; + genericitem_t *pStorageItem = NULL; int StorageItemIdx = 0; for (unsigned int i = 0; i < pStorage->Items.size(); i++) if (pStorage->Items[i].ID == ItemID) @@ -1048,11 +1027,6 @@ void ClientCommand2(edict_t *pEntity) } } } - else if (FStrEq(pcmd, "reset_tips")) - { - pPlayer->m_ViewedHelpTips.clear(); - pPlayer->SendInfoMsg("Tips reset."); - } else if (FStrEq(pcmd, "reset_quests")) { //Thothie JAN2010_09 spolitable @@ -1115,7 +1089,7 @@ void ClientCommand2(edict_t *pEntity) //syntax: "drop " if (bCanUseInventory) { - CGenericItem *pItem = nullptr; + CGenericItem *pItem = NULL; if (CMD_ARGC() > 1) pItem = MSUtil_GetItemByID(atol(CMD_ARGV(1)), pPlayer); else @@ -1151,7 +1125,6 @@ void ClientCommand2(edict_t *pEntity) //Thothie JUL2007a - anti item dup //Player is reconnecting, alert scripts //syntax: "drop " - pPlayer->m_TimeCharLastSent = 0; //Thothie SEP2011_07 - force save (attempt) msstringlist Parameters; Parameters.add(EntToString(pPlayer)); MSGlobals::GameScript->CallScriptEvent("game_playerleave", &Parameters); @@ -1192,7 +1165,7 @@ void ClientCommand2(edict_t *pEntity) if( pItem->GiveTo( pPlayer, true, false ) ) { - MESSAGE_BEGIN( MSG_ONE, g_netmsg[NETMSG_PACK], nullptr, pPlayer->pev ); + MESSAGE_BEGIN( MSG_ONE, g_netmsg[NETMSG_PACK], NULL, pPlayer->pev ); WRITE_BYTE( 1 ); WRITE_LONG( pItem->m_iId ); WRITE_BYTE( iHand + 1 ); @@ -1389,7 +1362,7 @@ void ClientCommand2(edict_t *pEntity) else if (FStrEq(CMD_ARGV(1), "open")) { //Thothie MAR2011_18 - moved item stacker here to prevent overflow - for (unsigned int i = 0; i < pPlayer->Gear.size(); i++) + for (int i = 0; i < pPlayer->Gear.size(); i++) { CGenericItem *pItem = pPlayer->Gear[i]; if (pItem) @@ -1455,7 +1428,7 @@ void ClientCommand2(edict_t *pEntity) pAddToHand->iQuantity = vNewStackAmount; pItem->iQuantity -= vNewStackAmount; - MESSAGE_BEGIN(MSG_ONE, g_netmsg[NETMSG_ITEM], nullptr, pPlayer->pev); + MESSAGE_BEGIN(MSG_ONE, g_netmsg[NETMSG_ITEM], NULL, pPlayer->pev); WRITE_BYTE(1); SendGenericItem(pPlayer, pItem, false); MESSAGE_END(); @@ -1514,7 +1487,7 @@ void ClientCommand2(edict_t *pEntity) //#else /*if( IsGM(GETPLAYERWONID(pPlayer->edict())) ) pPlayer->m_fIsElite = !pPlayer->m_fIsElite; - else return false;*/ + else return FALSE;*/ // pPlayer->m_fIsElite = true; //#endif @@ -1524,7 +1497,7 @@ void ClientCommand2(edict_t *pEntity) pPlayer->SendInfoMsg("You are now Elite\n"); else pPlayer->SendInfoMsg("You are now Normal\n"); - MESSAGE_BEGIN(MSG_ONE, g_netmsg[NETMSG_CLDLLFUNC], nullptr, pPlayer->pev); + MESSAGE_BEGIN(MSG_ONE, g_netmsg[NETMSG_CLDLLFUNC], NULL, pPlayer->pev); WRITE_BYTE(7); WRITE_BYTE(pPlayer->m_fIsElite); MESSAGE_END(); @@ -1610,7 +1583,7 @@ void ClientCommand2(edict_t *pEntity) if (iProp > -1) { int value = atoi(CMD_ARGV(2)); - pStat->m_SubStats[iProp].Value = min(value, STAT_PROP_MAX_VALUE); + pStat->m_SubStats[iProp].Value = min(value, STATPROP_MAX_VALUE); } } } @@ -1622,7 +1595,7 @@ void ClientCommand2(edict_t *pEntity) int iSubStat = atoi(CMD_ARGV(2)); int value = atoi(CMD_ARGV(3)); if (iSubStat < (signed)pStat->m_SubStats.size()) - pStat->m_SubStats[iSubStat].Value = min(value, STAT_PROP_MAX_VALUE); + pStat->m_SubStats[iSubStat].Value = min(value, STATPROP_MAX_VALUE); } } } @@ -1729,14 +1702,14 @@ void ClientCommand2(edict_t *pEntity) ClearBits(pPlayer->m_afPhysicsFlags, PFLAG_OBSERVER); ClearBits(pPlayer->pev->flags, FL_NOTARGET); //pPlayer->SetSpeed( 0 ); - MESSAGE_BEGIN(MSG_ONE, gmsgHideWeapon, nullptr, pPlayer->pev); + MESSAGE_BEGIN(MSG_ONE, gmsgHideWeapon, NULL, pPlayer->pev); WRITE_BYTE(0); MESSAGE_END(); } break; case 1: - //pPlayer->RemoveAllItems( false, true ); - MESSAGE_BEGIN(MSG_ONE, gmsgHideWeapon, nullptr, pPlayer->pev); + //pPlayer->RemoveAllItems( FALSE, TRUE ); + MESSAGE_BEGIN(MSG_ONE, gmsgHideWeapon, NULL, pPlayer->pev); WRITE_BYTE(HIDEHUD_ALL); MESSAGE_END(); //--- NO BREAK --- @@ -1792,7 +1765,7 @@ void ClientUserInfoChanged(edict_t *pEntity, char *infobuffer) { char text[256]; _snprintf(text, sizeof(text), "* %s prefers the name %s\n", STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); - MESSAGE_BEGIN( MSG_ALL, gmsgSayText, nullptr ); + MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); WRITE_BYTE( ENTINDEX(pEntity) ); WRITE_STRING( text ); MESSAGE_END(); @@ -1850,9 +1823,7 @@ void ServerDeactivate(void) g_pGameMasterEntity = nullptr; MS_INFO("Game_master entity handle cleared (will be recreated in ServerActivate)"); - if (g_pGameRules) - g_pGameRules->EndMultiplayerGame(); - + //MSGameEnd calls EndMultiplayerGame after saving characters, so the save still sees each player's party MSGameEnd(); MS_INFO("=== ServerDeactivate: Cleanup complete ==="); @@ -1925,7 +1896,7 @@ void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) // If not found via global, search by netname if (!pGameMasterEnt) { - pGameMasterEnt = UTIL_FindEntityByString(nullptr, "netname", msstring("-") + "game_master"); + pGameMasterEnt = UTIL_FindEntityByString(NULL, "netname", msstring("-") + "game_master"); if (pGameMasterEnt) { MS_INFO("Game master found via search at index %d", pGameMasterEnt->entindex()); @@ -1937,45 +1908,43 @@ void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) } CBaseEntity* pInitGameMaster = nullptr; - if (as_enabled.value > 0) +#ifndef AS_DISABLED + if (!pGameMasterEnt) { - if (!pGameMasterEnt) + MS_INFO("Game master not found, firing AngelScript ServerActivate event to create it..."); + + // Fire AngelScript ServerActivate event to allow scripts to initialize and spawn game_master + CAngelScriptManager* pASManager = CAngelScriptManager::Instance(); + if (pASManager && pASManager->IsInitialized()) { - MS_INFO("Game master not found, firing AngelScript ServerActivate event to create it..."); + pASManager->CallGlobalFunctionWithParams("ServerActivate"); + MS_INFO("ServerActivate event fired successfully"); - // Fire AngelScript ServerActivate event to allow scripts to initialize and spawn game_master - CAngelScriptManager* pASManager = CAngelScriptManager::Instance(); - if (pASManager && pASManager->IsInitialized()) + // After ServerActivate, try to find the game_master again + pGameMasterEnt = UTIL_FindEntityByString(NULL, "netname", msstring("-") + "game_master"); + if (pGameMasterEnt) { - pASManager->CallGlobalFunctionWithParams("ServerActivate"); - MS_INFO("ServerActivate event fired successfully"); - - // After ServerActivate, try to find the game_master again - pGameMasterEnt = UTIL_FindEntityByString(nullptr, "netname", msstring("-") + "game_master"); - if (pGameMasterEnt) - { - MS_INFO("Game master created by AngelScript at index %d", pGameMasterEnt->entindex()); - } - else - { - MS_ERROR("AngelScript ServerActivate did not create game_master entity!"); - } + MS_INFO("Game master created by AngelScript at index %d", pGameMasterEnt->entindex()); } else { - MS_ERROR("AngelScript manager not available for ServerActivate event - game_master not created!"); + MS_ERROR("AngelScript ServerActivate did not create game_master entity!"); } } else { - MS_INFO("Game master entity already exists at index %d with netname '%s'", - pGameMasterEnt->entindex(), - pGameMasterEnt->pev->netname ? STRING(pGameMasterEnt->pev->netname) : "(null)"); + MS_ERROR("AngelScript manager not available for ServerActivate event - game_master not created!"); } } else { - CBaseEntity* pGameMasterEnt = UTIL_FindEntityByString(nullptr, "netname", msstring("-") + "game_master"); + MS_INFO("Game master entity already exists at index %d with netname '%s'", + pGameMasterEnt->entindex(), + pGameMasterEnt->pev->netname ? STRING(pGameMasterEnt->pev->netname) : "(null)"); + } +#else + { + CBaseEntity* pGameMasterEnt = UTIL_FindEntityByString(NULL, "netname", msstring("-") + "game_master"); if (!pGameMasterEnt) { MS_INFO("Creating legacy game master"); @@ -1993,6 +1962,7 @@ void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) } } } +#endif // Store the game_master entity in global handle for easy access if (pGameMasterEnt) @@ -2201,7 +2171,7 @@ const char *GetGameDescription() #else char build[8] = {__DATE__[0], __DATE__[1], __DATE__[2], __DATE__[7], __DATE__[8], __DATE__[9], __DATE__[10]}; static char gameDesc[64]; - sprintf(gameDesc, "MS:R - %sa", _strupr(build)); + sprintf(gameDesc, "MS:R - %sa", strupr(build)); #endif return gameDesc; @@ -2328,8 +2298,8 @@ void SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs if (pClient->v.flags & FL_PROXY) { - *pvs = nullptr; // the spectator proxy sees - *pas = nullptr; // and hears everything + *pvs = NULL; // the spectator proxy sees + *pas = NULL; // and hears everything return; } @@ -2595,7 +2565,7 @@ int AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *ho } // defaults for clientinfo messages -constexpr int DEFAULT_VIEWHEIGHT = 28; +#define DEFAULT_VIEWHEIGHT 28 /* =================== @@ -2852,17 +2822,15 @@ void Player_Encode(struct delta_s *pFields, const unsigned char *from, const uns } } -enum { - CUSTOMFIELD_ORIGIN0 = 0, - CUSTOMFIELD_ORIGIN1 = 1, - CUSTOMFIELD_ORIGIN2 = 2, - CUSTOMFIELD_ANGLES0 = 3, - CUSTOMFIELD_ANGLES1 = 4, - CUSTOMFIELD_ANGLES2 = 5, - CUSTOMFIELD_SKIN = 6, - CUSTOMFIELD_SEQUENCE = 7, - CUSTOMFIELD_ANIMTIME = 8 -}; +#define CUSTOMFIELD_ORIGIN0 0 +#define CUSTOMFIELD_ORIGIN1 1 +#define CUSTOMFIELD_ORIGIN2 2 +#define CUSTOMFIELD_ANGLES0 3 +#define CUSTOMFIELD_ANGLES1 4 +#define CUSTOMFIELD_ANGLES2 5 +#define CUSTOMFIELD_SKIN 6 +#define CUSTOMFIELD_SEQUENCE 7 +#define CUSTOMFIELD_ANIMTIME 8 entity_field_alias_t custom_entity_field_alias[] = { diff --git a/src/game/server/effects.cpp b/src/game/server/effects.cpp index ab671feb9..f4b8a2c88 100644 --- a/src/game/server/effects.cpp +++ b/src/game/server/effects.cpp @@ -21,6 +21,9 @@ #include "func_break.h" #include "shake.h" +#define SF_GIBSHOOTER_REPEATABLE 1 // allows a gibshooter to be refired + +#define SF_FUNNEL_REVERSE 1 // funnel effect repels particles instead of attracting them. // Lightning target, just alias landmark LINK_ENTITY_TO_CLASS(info_target, CPointEntity); @@ -59,6 +62,7 @@ TYPEDESCRIPTION CBubbling::m_SaveData[] = IMPLEMENT_SAVERESTORE(CBubbling, CBaseEntity); +#define SF_BUBBLES_STARTOFF 0x0001 void CBubbling::Spawn(void) { @@ -112,17 +116,17 @@ void CBubbling::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "density")) { m_density = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "frequency")) { m_frequency = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "current")) { pev->speed = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); @@ -361,8 +365,8 @@ class CLightning : public CBeam inline BOOL ServerSide(void) { if (m_life == 0 && !(pev->spawnflags & SF_BEAM_RING)) - return true; - return false; + return TRUE; + return FALSE; } virtual int Save(CSave &save); @@ -492,57 +496,57 @@ void CLightning::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "LightningStart")) { m_iszStartEntity = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "LightningEnd")) { m_iszEndEntity = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "life")) { m_life = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "BoltWidth")) { m_boltWidth = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "NoiseAmplitude")) { m_noiseAmplitude = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "TextureScroll")) { m_speed = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "StrikeTime")) { m_restrike = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "texture")) { m_iszSpriteName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "framestart")) { m_frameStart = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "Radius")) { m_radius = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "damage")) { pev->dmg = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBeam::KeyValue(pkvd); @@ -843,8 +847,8 @@ void CLightning::BeamUpdateVars(void) int beamType; int pointStart, pointEnd; - edict_t *pStart = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(m_iszStartEntity)); - edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(m_iszEndEntity)); + edict_t *pStart = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszStartEntity)); + edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszEndEntity)); pointStart = IsPointEntity(CBaseEntity::Instance(pStart)); pointEnd = IsPointEntity(CBaseEntity::Instance(pEnd)); @@ -929,7 +933,7 @@ void CLaser::Spawn(void) PointsInit(pev->origin, pev->origin); 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 m_pSprite = NULL; @@ -954,42 +958,42 @@ void CLaser::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "LaserTarget")) { pev->message = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "width")) { SetWidth(atof(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "NoiseAmplitude")) { SetNoise(atoi(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "TextureScroll")) { SetScrollRate(atoi(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "texture")) { pev->model = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "EndSprite")) { m_iszSpriteName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "framestart")) { pev->frame = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "damage")) { pev->dmg = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBeam::KeyValue(pkvd); @@ -1348,22 +1352,22 @@ void CGibShooter::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "m_iGibs")) { m_iGibs = m_iGibCapacity = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_flVelocity")) { m_flGibVelocity = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_flVariance")) { m_flVariance = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_flGibLife")) { m_flGibLife = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else { @@ -1484,12 +1488,12 @@ void CEnvShooter ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "shootmodel")) { pev->model = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "shootsounds")) { int iNoise = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; switch (iNoise) { case 0: @@ -1674,6 +1678,11 @@ class CBlood : public CPointEntity LINK_ENTITY_TO_CLASS(env_blood, CBlood); +#define SF_BLOOD_RANDOM 0x0001 +#define SF_BLOOD_STREAM 0x0002 +#define SF_BLOOD_PLAYER 0x0004 +#define SF_BLOOD_DECAL 0x0008 + void CBlood::Spawn(void) { pev->solid = SOLID_NOT; @@ -1698,12 +1707,12 @@ void CBlood::KeyValue(KeyValueData *pkvd) break; } - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "amount")) { SetBloodAmount(atof(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CPointEntity::KeyValue(pkvd); @@ -1785,7 +1794,10 @@ LINK_ENTITY_TO_CLASS(env_shake, CShake); // radius of 0 means all players // NOTE: UTIL_ScreenShake() will only shake players who are on the ground - +#define SF_SHAKE_EVERYONE 0x0001 // Don't check radius +// UNDONE: These don't work yet +#define SF_SHAKE_DISRUPT 0x0002 // Disrupt controls +#define SF_SHAKE_INAIR 0x0004 // Shake players in air void CShake::Spawn(void) { @@ -1803,22 +1815,22 @@ void CShake::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "amplitude")) { SetAmplitude(atof(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "frequency")) { SetFrequency(atof(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "duration")) { SetDuration(atof(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "radius")) { SetRadius(atof(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CPointEntity::KeyValue(pkvd); @@ -1849,6 +1861,9 @@ LINK_ENTITY_TO_CLASS(env_fade, CFade); // pev->dmg_take is duration // pev->dmg_save is hold duration +#define SF_FADE_IN 0x0001 // Fade in, not out +#define SF_FADE_MODULATE 0x0002 // Modulate, don't blend +#define SF_FADE_ONLYONE 0x0004 void CFade::Spawn(void) { @@ -1863,12 +1878,12 @@ void CFade::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "duration")) { SetDuration(atof(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "holdtime")) { SetHoldTime(atof(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CPointEntity::KeyValue(pkvd); @@ -1955,17 +1970,17 @@ void CMessage::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "messagesound")) { pev->noise = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "messagevolume")) { pev->scale = atof(pkvd->szValue) * 0.1; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "messageattenuation")) { pev->impulse = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CPointEntity::KeyValue(pkvd); diff --git a/src/game/server/effects/mseffects.cpp b/src/game/server/effects/mseffects.cpp index 43c38a10a..0da40ad11 100644 --- a/src/game/server/effects/mseffects.cpp +++ b/src/game/server/effects/mseffects.cpp @@ -5,9 +5,6 @@ #include "ms/angelscript/CAngelScriptManager.h" // For AngelScript map transitions //#include "monsters/bodyparts/bodyparts.h" -#include "player.h" - - void UTIL_ScreenFadeBuild(ScreenFade &fade, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags); void UTIL_ScreenFadeWrite(const ScreenFade &fade, CBaseEntity *pEntity); @@ -117,7 +114,7 @@ void CTorchLight ::Create(float flDuration, edict_t *peOwner) } void CTorchLight ::Spawn() { - for (unsigned int i = 0; i < TORCH_LIGHTS; i++) + for (int i = 0; i < TORCH_LIGHTS; i++) { pLight[i] = GetClassPtr((CBaseEntity *)NULL); SET_MODEL(pLight[i]->edict(), "models/null.mdl"); @@ -147,13 +144,13 @@ void CTorchLight ::Think() if (FBitSet(pTorchTouse->pev->effects, EF_NODRAW) || pTorchTouse->pev->waterlevel > 2) - for (unsigned int i = 0; i < TORCH_LIGHTS; i++) + for (int i = 0; i < TORCH_LIGHTS; i++) SetBits(pLight[i]->pev->effects, EF_NODRAW); else - for (unsigned int i = 0; i < TORCH_LIGHTS; i++) + for (int i = 0; i < TORCH_LIGHTS; i++) ClearBits(pLight[i]->pev->effects, EF_NODRAW); - for (unsigned int i = 0; i < TORCH_LIGHTS; i++) + for (int i = 0; i < TORCH_LIGHTS; i++) { if (pLight[i]) { @@ -169,12 +166,13 @@ void CTorchLight ::Think() } void CTorchLight ::SUB_Remove() { - for (unsigned int i = 0; i < TORCH_LIGHTS; i++) + for (int i = 0; i < TORCH_LIGHTS; i++) pLight[i]->SUB_Remove(); CBaseEntity ::SUB_Remove(); } LINK_ENTITY_TO_CLASS(ms_torchlight, CTorchLight); +#include "player.h" class CChangePlayerSpeed : public CBaseDelay { @@ -232,8 +230,7 @@ void CChangePlayerSpeed ::Spawn(void) void CChangePlayerSpeed ::Think(void) { - - for (unsigned int i = 0; i < 256; i++) + for (int i = 0; i < 256; i++) { playerinfo_t *pInfo = &m_PlayerInfo[i]; if (!pInfo->pePlayer) @@ -269,7 +266,7 @@ void CChangePlayerSpeed ::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE return; playerinfo_t *pInfo = NULL; - for (unsigned int i = 0; i < 256; i++) + for (int i = 0; i < 256; i++) { if (!m_PlayerInfo[i].pePlayer) { @@ -295,7 +292,7 @@ void CChangePlayerSpeed ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "duration")) { m_Duration = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); @@ -308,7 +305,7 @@ CEntGlow *CEntGlow::Create(CBaseEntity *pTarget, Vector Color, float Amount, flo pGlowEnt->m_Target = pTarget; pGlowEnt->m_Color = Color; pGlowEnt->m_Amount = Amount; - pGlowEnt->m_CurrentAmount = pGlowEnt->m_Amount; + pGlowEnt->m_CurentAmount = pGlowEnt->m_Amount; pGlowEnt->m_Duration = Duration; pGlowEnt->m_FadeDuration = FadeDuration; pGlowEnt->m_StartTime = gpGlobals->time; @@ -342,7 +339,7 @@ void CEntGlow::SetGlow(bool On) { pEntity->pev->renderfx = kRenderFxGlowShell; pEntity->pev->rendercolor = m_Color; - pEntity->pev->renderamt = m_CurrentAmount; + pEntity->pev->renderamt = m_CurentAmount; } } else @@ -383,7 +380,7 @@ void CEntGlow::Think() if (FadeAmt > 1) FadeAmt = 1; - m_CurrentAmount = m_Amount * (1 - FadeAmt); + m_CurentAmount = m_Amount * (1 - FadeAmt); SetGlow(true); pev->nextthink = gpGlobals->time; //MiB } @@ -424,7 +421,7 @@ class CMSChangeLevel : public CBaseEntity //MAR2008a - Thothie - Let game master handle mstrig_changelevel level changes //- original: CHANGE_LEVEL( (char *)STRING(sDestMap), NULL ); // Updated to use AngelScript instead of MSScript for map transitions - #ifdef VALVE_DLL +#ifndef AS_DISABLED CAngelScriptManager* pASManager = CAngelScriptManager::Instance(); if (pASManager && pASManager->IsInitialized()) { @@ -440,19 +437,31 @@ class CMSChangeLevel : public CBaseEntity { ALERT(at_console, "Unable to execute changelevel - AngelScript not initialized!\n"); } - #endif +#else + CBaseEntity *pGameMasterEnt = UTIL_FindEntityByString(NULL, "netname", msstring("-") + "game_master"); + IScripted *pGMScript = (pGameMasterEnt ? pGameMasterEnt->GetScripted() : NULL); + if (pGMScript) + { + msstringlist Parameters; + Parameters.add(STRING(sDestMap)); + Parameters.add(STRING(sDestTrans)); + pGMScript->CallScriptEvent("gm_manual_map_change", &Parameters); + } + else + ALERT(at_console, "Unable to find game_master for level change!\n"); +#endif } void KeyValue(KeyValueData *pkvd) { if (FStrEq(pkvd->szKeyName, "destmap")) { sDestMap = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "desttrans")) { sDestTrans = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); @@ -460,24 +469,12 @@ class CMSChangeLevel : public CBaseEntity }; LINK_ENTITY_TO_CLASS(mstrig_changelevel, CMSChangeLevel); - -bool REQPARAMS(msstring& ScriptFileName, msstringlist& Params, unsigned int count) { - - if (Params.size() < count) { - ALERT(at_console, "Script: %s, effect '%s' missing parameters!\n", ScriptFileName.c_str(), Params[0].c_str()); - return false; +#define REQPARAMS(a) \ + if (Params.size() < a) \ + { \ + ALERT(at_console, "Script: %s, effect '%s' missing parameters!\n", m.ScriptFile.c_str(), Params[0].c_str()); \ + return; \ } - else return true; -} - -//#define REQPARAMS(a) -// if (Params.size() < a) -// { -// ALERT(at_console, "Script: %s, effect '%s' missing parameters!\n", m.ScriptFile.c_str(), Params[0].c_str()); -// return; -// } -// - void CScript::ScriptedEffect(msstringlist &Params) { @@ -514,11 +511,7 @@ void CScript::ScriptedEffect(msstringlist &Params) if (Params[0] == "beam") { - - if (!REQPARAMS(m.ScriptFile, Params, 4)) { - return; - } - + REQPARAMS(4); int Type = 0; if (Params[1] == "end") Type = 0; @@ -738,23 +731,17 @@ void CScript::ScriptedEffect(msstringlist &Params) if (Params[1] == "gibs") { Type = 0; - if (!REQPARAMS(m.ScriptFile, Params, 9)) { - return; - } + REQPARAMS(9); } else if (Params[1] == "spray") { Type = 1; - if (!REQPARAMS(m.ScriptFile, Params, 8)) { - return; - } + REQPARAMS(8); } else if (Params[1] == "trail") { Type = 2; - if (!REQPARAMS(m.ScriptFile, Params, 10)) { - return; - } + REQPARAMS(10); } const char* ModelName = GetFullResourceName(Params[2]); @@ -874,9 +861,7 @@ void CScript::ScriptedEffect(msstringlist &Params) } else if (Params[0] == "screenshake") { - if (!REQPARAMS(m.ScriptFile, Params, 6)) { - return; - } + REQPARAMS(6); Vector Origin = StringToVec(Params[1]); float Amplitude = atof(Params[2]); @@ -890,9 +875,7 @@ void CScript::ScriptedEffect(msstringlist &Params) { //Thothie APR2016_08 - allow screen shake vs. single client //effect screenshake_one - if (!REQPARAMS(m.ScriptFile, Params, 5)) { - return; - } + REQPARAMS(5); CBaseEntity* pEntity = (m.pScriptedEnt ? m.pScriptedEnt->RetrieveEntity(Params[1]) : NULL); if (pEntity && pEntity->IsPlayer()) { @@ -937,9 +920,7 @@ void CScript::ScriptedEffect(msstringlist &Params) } else if (Params[0] == "glow") { - if (!REQPARAMS(m.ScriptFile, Params, 6)) { - return; - } + REQPARAMS(6); CBaseEntity *pTarget = m.pScriptedEnt->RetrieveEntity(Params[1]); if (!pTarget) diff --git a/src/game/server/effects/mseffects.h b/src/game/server/effects/mseffects.h index 8d4029094..b86096985 100644 --- a/src/game/server/effects/mseffects.h +++ b/src/game/server/effects/mseffects.h @@ -1,68 +1,55 @@ - - - - -#ifndef EFFECTS_H +class CPortal : public CBaseEntity +{ +public: + //virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } + void Spawn(void){}; + void Precache(void){}; + void Spawn2(void); + void CloseSpawnPortal(void); +}; + +#define SPRITE_TORCH 1 + #include "effects.h" -#endif // !EFFECTS_H - - - -constexpr int SPRITE_TORCH = 1; -constexpr int TORCH_LIGHTS = 2; - -class CPortal : public CBaseEntity -{ -public: - //virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } - void Spawn(void){}; - void Precache(void){}; - void Spawn2(void); - void CloseSpawnPortal(void); -}; - - -class CMSSprite : public CSprite -{ -public: - int SpriteType; - - //Torch sprite - void TorchInit(char *pszName, float flFramerate, float flScale, edict_t *peOwner); - void Think(); -}; - - - -class CTorchLight : public CBaseEntity -{ -public: - CBaseEntity *pLight[2]; - ulong m_OwnerID; - - //Torch sprite - static void Create(float flDuration, edict_t *peOwner); - void Spawn(); - void Think(); - void SUB_Remove(); -}; - -//Makes entities glow for a time -class CEntGlow : public CBaseEntity -{ -public: - static CEntGlow *Create(CBaseEntity *pTarget, Vector Color, float Amount, float Duration, float FadeDuration); - - void Think(); - void SetGlow(bool On); - - entityinfo_t m_Target; - float m_Amount, m_CurrentAmount; - float m_StartTime; - float m_Duration; - float m_FadeDuration; - Vector m_Color; -}; - - -bool REQPARAMS(msstring& ScriptFileName, msstringlist& Params, unsigned int count); \ No newline at end of file + +class CMSSprite : public CSprite +{ +public: + int SpriteType; + + //Torch sprite + void TorchInit(char *pszName, float flFramerate, float flScale, edict_t *peOwner); + void Think(); +}; + +#define TORCH_LIGHTS 2 + +class CTorchLight : public CBaseEntity +{ +public: + CBaseEntity *pLight[2]; + ulong m_OwnerID; + + //Torch sprite + static void Create(float flDuration, edict_t *peOwner); + void Spawn(); + void Think(); + void SUB_Remove(); +}; + +//Makes entities glow for a time +class CEntGlow : public CBaseEntity +{ +public: + static CEntGlow *Create(CBaseEntity *pTarget, Vector Color, float Amount, float Duration, float FadeDuration); + + void Think(); + void SetGlow(bool On); + + entityinfo_t m_Target; + float m_Amount, m_CurentAmount; + float m_StartTime; + float m_Duration; + float m_FadeDuration; + Vector m_Color; +}; diff --git a/src/game/server/enginecallback.h b/src/game/server/enginecallback.h index 4829bebc9..24aaf5a7f 100644 --- a/src/game/server/enginecallback.h +++ b/src/game/server/enginecallback.h @@ -22,7 +22,7 @@ extern enginefuncs_t g_engfuncs; extern unsigned int g_iNumBytesWritten; extern int g_iUserMessageType; -inline constexpr int MAX_USERMESSAGE_SIZE = 192; +#define MAX_USERMESSAGE_SIZE 192 // The actual engine callbacks #define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId) @@ -41,12 +41,7 @@ void SET_MODEL( edict_t *e, const char *szModel ); #define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms) #define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms) #define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw) -//#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles) - -inline void VEC_TO_ANGLES(const float* rgflVectorIn, float* rgflVectorOut ) { - g_engfuncs.pfnVecToAngles(rgflVectorIn, rgflVectorOut); -} - +#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles) #define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin) #define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw) #define CHANGE_PITCH (*g_engfuncs.pfnChangePitch) @@ -77,41 +72,9 @@ inline void VEC_TO_ANGLES(const float* rgflVectorIn, float* rgflVectorOut ) { #define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC32_ProcessBuffer) #define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC32_ProcessByte) #define CRC32_FINAL (*g_engfuncs.pfnCRC32_Final) -//#define RANDOM_LONG (*g_engfuncs.pfnRandomLong) -//#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) -//#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) - -template -int32 RANDOM_LONG(const Type1 &lLow, const Type2 &lHigh) { - - if (lLow > lHigh) { - return g_engfuncs.pfnRandomLong(static_cast(lHigh), static_cast(lLow)); - } - - return g_engfuncs.pfnRandomLong(static_cast(lLow), static_cast(lHigh)); - - -} - - -template -float RANDOM_FLOAT(const Type1 &flLow, const Type2 &flHigh) { - - if (flLow > flHigh) { - return g_engfuncs.pfnRandomFloat( static_cast(flHigh), static_cast(flLow) ); - } - - return g_engfuncs.pfnRandomFloat(static_cast(flLow), static_cast(flHigh)); - -} - - -inline const char* GETPLAYERAUTHID(edict_t* e) { - return g_engfuncs.pfnGetPlayerAuthId(e); -} - - -//undoing this would just invite more macros, will keep this and any others that user variadic args / fmt +#define RANDOM_LONG (*g_engfuncs.pfnRandomLong) +#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) +#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) #define ALERT (*g_engfuncs.pfnAlertMessage) //MIB JUN2010_17 - enable total disable of debug alert messages @@ -197,10 +160,10 @@ inline void WRITE_STRING(const char* sz) } #ifdef VALVE_DLL -constexpr unsigned int WRITE_STRING_MAX = 180; // Upper limit for a usermessage is around 192 bytes, keep this in mind! +#define WRITE_STRING_MAX 180 // Upper limit for a usermessage is around 192 bytes, keep this in mind! extern char g_pTempStringLimit[WRITE_STRING_MAX]; // Use this to ensure that we only write this many bytes, ensure null terminated string, prevent overflows. -#define WRITE_STRING_LIMIT(src, len) memset(g_pTempStringLimit, 0, WRITE_STRING_MAX); strncpy(g_pTempStringLimit, src, WRITE_STRING_MAX); g_pTempStringLimit[V_min((unsigned int)WRITE_STRING_MAX-1, (unsigned int)len)] = 0; WRITE_STRING(g_pTempStringLimit) +#define WRITE_STRING_LIMIT(src, len) memset(g_pTempStringLimit, 0, WRITE_STRING_MAX); strncpy(g_pTempStringLimit, src, WRITE_STRING_MAX); g_pTempStringLimit[V_min(WRITE_STRING_MAX-1, len)] = 0; WRITE_STRING(g_pTempStringLimit) #endif #define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister) @@ -225,12 +188,7 @@ inline void *GET_PRIVATE(edict_t *pent) int ALLOC_STRING(const char *szValue); //Master Sword - Keep track of all string allocations on server void ClearStringPool(); #else - -inline unsigned int ALLOC_STRING(const char* szValue) { - return g_engfuncs.pfnAllocString(szValue); -} - -//#define ALLOC_STRING (*g_engfuncs.pfnAllocString) +#define ALLOC_STRING (*g_engfuncs.pfnAllocString) #endif #define FIND_ENTITY_BY_STRING (*g_engfuncs.pfnFindEntityByString) diff --git a/src/game/server/entity.cpp b/src/game/server/entity.cpp index 324f20438..866db8a5e 100644 --- a/src/game/server/entity.cpp +++ b/src/game/server/entity.cpp @@ -57,7 +57,7 @@ void CBaseEntity::SetFollow(CBaseEntity *pTarget, int Flags) bool CBaseEntity::CanDamage(CBaseEntity *pOther) { - return (static_cast(pOther->pev->takedamage) > DAMAGE_NO) && //The entity can take damage + return (pOther->pev->takedamage > DAMAGE_NO) && //The entity can take damage (!FBitSet(pOther->pev->flags, FL_GODMODE)); //The entity is not invulnerable; } diff --git a/src/game/server/fn/FNSharedDefs.cpp b/src/game/server/fn/FNSharedDefs.cpp index f49e700da..a9f5e2dea 100644 --- a/src/game/server/fn/FNSharedDefs.cpp +++ b/src/game/server/fn/FNSharedDefs.cpp @@ -20,7 +20,7 @@ #include "LoadCharacterReq.h" #include "DeleteCharacterReq.h" -constexpr unsigned int STRING_BUFFER = 1024; +#define STRING_BUFFER 1024 // AsyncSendRequest does not make use the connection pooling. // Frequent requests should make use the RequestManager to take advantage of @@ -45,7 +45,7 @@ bool FNShared::IsSlotValid(int slot) bool FNShared::IsEnabled(void) { - return (MSGlobals::CentralEnabled && !MSGlobals::IsLanGame && MSGlobals::ServerSideChar); + return (MSGlobals::CentralEnabled && !MSGlobals::IsLanGame); } static bool SendBlockingRequest(HTTPRequest* req) @@ -168,7 +168,7 @@ void FNShared::LoadCharacter(CBasePlayer* pPlayer) if ((pPlayer == NULL) || (pPlayer->steamID64 == 0ULL)) return; - for (unsigned int i = 0; i < MAX_CHARSLOTS; i++) + for (int i = 0; i < MAX_CHARSLOTS; i++) { charinfo_t& CharInfo = pPlayer->m_CharInfo[i]; diff --git a/src/game/server/func_break.cpp b/src/game/server/func_break.cpp index c6285423a..7acac0ee4 100644 --- a/src/game/server/func_break.cpp +++ b/src/game/server/func_break.cpp @@ -64,12 +64,12 @@ void CBreakable::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "scriptevent")) { m_scriptevent = pkvd->szValue; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "killtarget")) { m_iszKillTarget = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // UNDONE_WC: explicitly ignoring these fields, but they shouldn't be in the map file! @@ -82,7 +82,7 @@ void CBreakable::KeyValue(KeyValueData *pkvd) else m_Explosion = expRandom; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "material")) { @@ -95,21 +95,21 @@ void CBreakable::KeyValue(KeyValueData *pkvd) else m_Material = (Materials)i; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "deadmodel")) { - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "shards")) { // m_iShards = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "gibmodel")) { m_iszGibModel = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spawnobject")) { @@ -117,16 +117,16 @@ void CBreakable::KeyValue(KeyValueData *pkvd) //if ( object > 0 && object < ARRAYSIZE(pSpawnObjects) ) // m_iszSpawnObject = MAKE_STRING( pSpawnObjects[object] ); - //pkvd->fHandled = true; + //pkvd->fHandled = TRUE; CBaseDelay::KeyValue(pkvd); } else if (FStrEq(pkvd->szKeyName, "explodemagnitude")) { ExplosionSetMagnitude(atoi(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "lip")) - pkvd->fHandled = true; + pkvd->fHandled = TRUE; else CBaseDelay::KeyValue(pkvd); } @@ -597,7 +597,7 @@ int CBreakable ::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, flo if (Tokens.size() > 1) { - for (unsigned int i = 0; i < Tokens.size(); i++) + for (int i = 0; i < Tokens.size(); i++) { if (i > 0) Params.add(Tokens[i].c_str()); @@ -623,7 +623,7 @@ int CBreakable ::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, flo Params.clearitems(); if (Tokens.size() > 1) { - for (unsigned int i = 0; i < Tokens.size(); i++) + for (int i = 0; i < Tokens.size(); i++) { if (i > 0) Params.add(Tokens[i].c_str()); @@ -651,7 +651,7 @@ void CBreakable::Die(void) { Vector vecSpot; // shard origin Vector vecVelocity; // shard velocity - CBaseEntity *pEntity = nullptr; + CBaseEntity *pEntity = NULL; char cFlag = 0; int pitch; float fvol; @@ -802,10 +802,10 @@ void CBreakable::Die(void) // BUGBUG -- can only find 256 entities on a breakable -- should be enough CBaseEntity *pList[256]; - unsigned int count = UTIL_EntitiesInBox(pList, 256, mins, maxs, FL_ONGROUND); + int count = UTIL_EntitiesInBox(pList, 256, mins, maxs, FL_ONGROUND); if (count) { - for (unsigned int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { ClearBits(pList[i]->pev->flags, FL_ONGROUND); pList[i]->pev->groundentity = NULL; @@ -826,7 +826,7 @@ void CBreakable::Die(void) if (Explodable()) { - ExplosionCreate(Center(), pev->angles, edict(), ExplosionMagnitude(), true); + ExplosionCreate(Center(), pev->angles, edict(), ExplosionMagnitude(), TRUE); } } @@ -915,7 +915,7 @@ void CPushable ::Spawn(void) void CPushable ::Precache(void) { - for (unsigned int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) PRECACHE_SOUND(m_soundNames[i]); if (pev->spawnflags & SF_PUSH_BREAKABLE) @@ -927,7 +927,7 @@ void CPushable ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "size")) { int bbox = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; switch (bbox) { @@ -952,7 +952,7 @@ void CPushable ::KeyValue(KeyValueData *pkvd) else if (FStrEq(pkvd->szKeyName, "buoyancy")) { pev->skin = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBreakable::KeyValue(pkvd); diff --git a/src/game/server/gamerules/gamerules.cpp b/src/game/server/gamerules/gamerules.cpp index 91101ddf4..c10a19c58 100644 --- a/src/game/server/gamerules/gamerules.cpp +++ b/src/game/server/gamerules/gamerules.cpp @@ -35,7 +35,7 @@ extern int gmsgMOTD; //========================================================= BOOL CGameRules::CanHaveAmmo(CBasePlayer *pPlayer, const char *pszAmmoName, int iMaxCarry) { - return false; + return FALSE; } //========================================================= @@ -51,7 +51,7 @@ edict_t *CGameRules ::GetPlayerSpawnSpot(CBasePlayer *pPlayer) { // only living players can have items if ( pPlayer->pev->deadflag != DEAD_NO ) - return false; + return FALSE; if ( pWeapon->pszAmmo1() ) { @@ -61,7 +61,7 @@ edict_t *CGameRules ::GetPlayerSpawnSpot(CBasePlayer *pPlayer) // have the gun if we aren't already carrying one of this type if ( pPlayer->HasPlayerItem( pWeapon ) ) { - return false; + return FALSE; } } } @@ -70,12 +70,12 @@ edict_t *CGameRules ::GetPlayerSpawnSpot(CBasePlayer *pPlayer) // weapon doesn't use ammo, don't take another if you already have it. if ( pPlayer->HasPlayerItem( pWeapon ) ) { - return false; + return FALSE; } } // note: will fall through to here if GetItemInfo doesn't fill the struct! - return true; + return TRUE; }*/ //========================================================= diff --git a/src/game/server/gamerules/gamerules.h b/src/game/server/gamerules/gamerules.h index 3ce7856e2..40eb1cce0 100644 --- a/src/game/server/gamerules/gamerules.h +++ b/src/game/server/gamerules/gamerules.h @@ -70,7 +70,7 @@ class CGameRules // Functions to verify the single/multiplayer status of a game virtual BOOL IsMultiplayer(void) = 0; // is this a multiplayer game? (either coop or deathmatch) virtual BOOL IsDeathmatch(void) = 0; //is this a deathmatch game? - virtual BOOL IsTeamplay(void) { return false; }; // is this deathmatch game being played with team rules? + virtual BOOL IsTeamplay(void) { return FALSE; }; // is this deathmatch game being played with team rules? virtual BOOL IsCoOp(void) = 0; // is this a coop game? virtual const char *GetGameDescription(void) { return "Half-Life"; } // this is the game name that gets seen in the server browser @@ -82,8 +82,8 @@ class CGameRules // Client damage rules virtual float FlPlayerFallDamage(CBasePlayer *pPlayer) = 0; // this client just hit the ground after a fall. How much damage? - virtual BOOL FPlayerCanTakeDamage(CBasePlayer *pPlayer, CBaseEntity *pAttacker) { return true; }; // can this player take damage from this attacker? - virtual BOOL ShouldAutoAim(CBasePlayer *pPlayer, edict_t *target) { return true; } + virtual BOOL FPlayerCanTakeDamage(CBasePlayer *pPlayer, CBaseEntity *pAttacker) { return TRUE; }; // can this player take damage from this attacker? + virtual BOOL ShouldAutoAim(CBasePlayer *pPlayer, edict_t *target) { return TRUE; } // Client spawn/respawn control virtual void PlayerSpawn(CBasePlayer *pPlayer) = 0; // called by CBasePlayer::Spawn just before releasing player into the game @@ -92,8 +92,8 @@ class CGameRules virtual float FlPlayerSpawnTime(CBasePlayer *pPlayer) = 0; // When in the future will this player be able to spawn? virtual edict_t *GetPlayerSpawnSpot(CBasePlayer *pPlayer); // Place this player on their spawnspot and face them the proper direction. - virtual BOOL AllowAutoTargetCrosshair(void) { return true; }; - virtual BOOL ClientCommand(CBasePlayer *pPlayer, const char *pcmd) { return false; }; // handles the user commands; returns true if command handled properly + virtual BOOL AllowAutoTargetCrosshair(void) { return TRUE; }; + virtual BOOL ClientCommand(CBasePlayer *pPlayer, const char *pcmd) { return FALSE; }; // handles the user commands; returns TRUE if command handled properly virtual void ClientUserInfoChanged(CBasePlayer *pPlayer, char *infobuffer) {} // the player has changed userinfo; can change it now // Client kills/scoring @@ -144,13 +144,13 @@ class CGameRules virtual int PlayerRelationship(CBaseEntity *pPlayer, CBaseEntity *pTarget) = 0; // What is the player's relationship with this entity? virtual int GetTeamIndex(const char *pTeamName) { return -1; } virtual const char *GetIndexedTeamName(int teamIndex) { return ""; } - virtual BOOL IsValidTeam(const char *pTeamName) { return true; } + virtual BOOL IsValidTeam(const char *pTeamName) { return TRUE; } virtual void ChangePlayerTeam(CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib) {} virtual const char *SetDefaultPlayerTeam(CBasePlayer *pPlayer) { return ""; } // Sounds - virtual BOOL PlayTextureSounds(void) { return true; } - virtual BOOL PlayFootstepSounds(CBasePlayer *pl, float fvol) { return true; } + virtual BOOL PlayTextureSounds(void) { return TRUE; } + virtual BOOL PlayFootstepSounds(CBasePlayer *pl, float fvol) { return TRUE; } // Monsters virtual BOOL FAllowMonsters(void) = 0; //are monsters allowed @@ -173,7 +173,7 @@ class CHalfLifeRules : public CGameRules // GR_Think virtual void Think(void); virtual BOOL IsAllowedToSpawn(CBaseEntity *pEntity); - virtual BOOL FAllowFlashlight(void) { return true; }; + virtual BOOL FAllowFlashlight(void) { return TRUE; }; virtual BOOL FShouldSwitchWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon); virtual BOOL GetNextBestWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon); diff --git a/src/game/server/gamerules/multiplay_gamerules.cpp b/src/game/server/gamerules/multiplay_gamerules.cpp index 0bed2c090..31cafb45f 100644 --- a/src/game/server/gamerules/multiplay_gamerules.cpp +++ b/src/game/server/gamerules/multiplay_gamerules.cpp @@ -34,9 +34,6 @@ #include "trains.h" // for CFuncVehicle #include -#ifndef DOORS_H -#include "doors.h" -#endif #include #include #include @@ -51,12 +48,12 @@ extern int gmsgMOTD; bool CheckBanned(const char* SteamID ); //float g_TimeTryValidate = 0.0f; -constexpr int VALIDATE_DELAY = (60 * 30);// 30 mins +#define VALIDATE_DELAY (60 * 30)// 30 mins float g_ServerResetTimer = 0.0f; -constexpr int ITEM_RESPAWN_TIME = 30; -constexpr int WEAPON_RESPAWN_TIME = 20; -constexpr int AMMO_RESPAWN_TIME = 20; +#define ITEM_RESPAWN_TIME 30 +#define WEAPON_RESPAWN_TIME 20 +#define AMMO_RESPAWN_TIME 20 CVoiceGameMgr g_VoiceGameMgr; @@ -139,7 +136,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() SERVER_EXECUTE( ); m_CurrentVote.fActive = false; - for (unsigned int i = 0; i < CLPERMENT_TOTAL; i++) + for (int i = 0; i < CLPERMENT_TOTAL; i++) { CBaseEntity *pInvEntity = GetClassPtr( (CBaseEntity *)NULL ); SetBits( pInvEntity->pev->flags, FL_DORMANT ); @@ -156,7 +153,8 @@ void CHalfLifeMultiplay::RefreshSkillData( void ) } // longest the intermission can last, in seconds -constexpr int MAX_INTERMISSION_TIME = 120; +#define MAX_INTERMISSION_TIME 120 + //Master Sword //bool CheckData( ); //------------ @@ -263,14 +261,14 @@ bool CHalfLifeMultiplay::IsAnyPlayerAllowedInMap() //========================================================= BOOL CHalfLifeMultiplay::IsMultiplayer( void ) { - return true; + return TRUE; } //========================================================= //========================================================= BOOL CHalfLifeMultiplay::IsDeathmatch( void ) { - return true; + return TRUE; } //========================================================= @@ -287,33 +285,33 @@ BOOL CHalfLifeMultiplay::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerI if ( !pWeapon->CanDeploy() ) { // that weapon can't deploy anyway. - return false; + return FALSE; } if ( !pPlayer->m_pActiveItem ) { // player doesn't have an active item! - return true; + return TRUE; } if ( !pPlayer->m_pActiveItem->CanHolster() ) { // can't put away the active item. - return false; + return FALSE; } if ( pWeapon->iWeight() > pPlayer->m_pActiveItem->iWeight() ) { - return true; + return TRUE; } - return false; + return FALSE; } BOOL CHalfLifeMultiplay::GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) { //Function unused - return false; + return FALSE; } //========================================================= @@ -328,12 +326,12 @@ BOOL CHalfLifeMultiplay::ClientConnected(edict_t *pEntity, const char *pszName, if( CheckBanned( AuthID ) ) { strncpy(szRejectReason, "You are BANNED\n", 128); - return false; + return FALSE; } g_ServerResetTimer = NULL; - return true; + return TRUE; } extern int gmsgSayText; @@ -366,7 +364,7 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pPlayer ) //Notify all the entities with scripts CBaseEntity *pEntity = NULL; edict_t *pEdict = NULL; - for(int i = 1; i < gpGlobals->maxEntities; i++ ) + for( int i = 1; i < gpGlobals->maxEntities; i++ ) { pEdict = g_engfuncs.pfnPEntityOfEntIndex( i ); @@ -396,7 +394,7 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pPlayer ) //SendMOTDToClient( pl->edict() ); // loop through all active players and send their score info to the new client - for (int i = 1; i <= gpGlobals->maxClients; i++ ) + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer *pOtherPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); if( !pOtherPlayer ) continue; @@ -476,7 +474,7 @@ float CHalfLifeMultiplay::FlPlayerFallDamage( CBasePlayer *pPlayer ) { case 1://progressive pPlayer->m_flFallVelocity -= PLAYER_MAX_SAFE_FALL_SPEED; - return pPlayer->m_flFallVelocity * PLAYER_DAMAGE_FOR_FALL_SPEED; + return pPlayer->m_flFallVelocity * DAMAGE_FOR_FALL_SPEED; break; default: case 0:// fixed @@ -489,7 +487,7 @@ float CHalfLifeMultiplay::FlPlayerFallDamage( CBasePlayer *pPlayer ) //========================================================= BOOL CHalfLifeMultiplay::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) { - return true; + return TRUE; } //========================================================= @@ -500,7 +498,7 @@ void CHalfLifeMultiplay::PlayerThink( CBasePlayer *pPlayer ) { // check for button presses if ( pPlayer->m_afButtonPressed & ( IN_DUCK | IN_ATTACK | IN_ATTACK2 | IN_USE | IN_JUMP ) ) - m_iEndIntermissionButtonHit = true; + m_iEndIntermissionButtonHit = TRUE; // clear attack/use commands from player pPlayer->m_afButtonPressed = 0; @@ -520,7 +518,7 @@ void CHalfLifeMultiplay::PlayerSpawn( CBasePlayer *pPlayer ) //========================================================= BOOL CHalfLifeMultiplay::FPlayerCanRespawn( CBasePlayer *pPlayer ) { - return true; + return TRUE; } //========================================================= @@ -532,7 +530,7 @@ float CHalfLifeMultiplay::FlPlayerSpawnTime( CBasePlayer *pPlayer ) BOOL CHalfLifeMultiplay::AllowAutoTargetCrosshair( void ) { - return false; + return FALSE; } //========================================================= @@ -774,7 +772,7 @@ float CHalfLifeMultiplay::FlWeaponRespawnTime( CBasePlayerItem *pWeapon ) // when we are within this close to running out of entities, items // marked with the ITEM_FLAG_LIMITINWORLD will delay their respawn -constexpr int ENTITY_INTOLERANCE = 100; +#define ENTITY_INTOLERANCE 100 //========================================================= // FlWeaponRespawnTime - Returns 0 if the weapon can respawn @@ -785,7 +783,7 @@ float CHalfLifeMultiplay::FlWeaponTryRespawn( CBasePlayerItem *pWeapon ) { if ( pWeapon && pWeapon->m_iId && (pWeapon->iFlags() & ITEM_FLAG_LIMITINWORLD) ) { - if (NUMBER_OF_ENTITIES() < (gpGlobals->maxEntities - ENTITY_INTOLERANCE) ) + if ( NUMBER_OF_ENTITIES() < (gpGlobals->maxEntities - ENTITY_INTOLERANCE) ) return 0; // we're past the entity tolerance level, so delay the respawn @@ -819,7 +817,7 @@ int CHalfLifeMultiplay::WeaponShouldRespawn( CBasePlayerItem *pWeapon ) } //========================================================= -// CanHaveWeapon - returns false if the player is not allowed +// CanHaveWeapon - returns FALSE if the player is not allowed // to pick up this weapon //========================================================= /*BOOL CHalfLifeMultiplay::CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pItem ) @@ -838,7 +836,7 @@ int CHalfLifeMultiplay::WeaponShouldRespawn( CBasePlayerItem *pWeapon ) { if ( it->m_iId == pItem->m_iId ) { - return false; + return FALSE; } it = it->m_pNext; @@ -853,7 +851,7 @@ int CHalfLifeMultiplay::WeaponShouldRespawn( CBasePlayerItem *pWeapon ) //========================================================= BOOL CHalfLifeMultiplay::CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ) { - return true; + return TRUE; } //========================================================= @@ -902,7 +900,7 @@ void CHalfLifeMultiplay::PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int //========================================================= BOOL CHalfLifeMultiplay::IsAllowedToSpawn( CBaseEntity *pEntity ) { - return true; + return TRUE; } //========================================================= @@ -975,30 +973,30 @@ int CHalfLifeMultiplay::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *p BOOL CHalfLifeMultiplay::PlayFootstepSounds( CBasePlayer *pl, float fvol ) { if ( g_footsteps && g_footsteps->value == 0 ) - return false; + return FALSE; if ( pl->IsOnLadder() || pl->pev->velocity.Length2D() > 220 ) - return true; // only make step sounds in multiplayer if the player is moving fast enough + return TRUE; // only make step sounds in multiplayer if the player is moving fast enough - return false; + return FALSE; } BOOL CHalfLifeMultiplay::FAllowFlashlight( void ) { - return false; + return FALSE; } //========================================================= //========================================================= BOOL CHalfLifeMultiplay::FAllowMonsters( void ) { - return true; + return TRUE; //return ( CVAR_GET_FLOAT( "mp_allowmonsters" ) != 0 ); } //========================================================= //======== CHalfLifeMultiplay private functions =========== -constexpr int INTERMISSION_TIME = 6; +#define INTERMISSION_TIME 6 void CHalfLifeMultiplay::GoToIntermission( void ) { @@ -1009,17 +1007,18 @@ void CHalfLifeMultiplay::GoToIntermission( void ) MESSAGE_END(); m_flIntermissionEndTime = gpGlobals->time + INTERMISSION_TIME; - g_fGameOver = true; - m_iEndIntermissionButtonHit = false; + g_fGameOver = TRUE; + m_iEndIntermissionButtonHit = FALSE; } -constexpr int MAX_RULE_BUFFER = 1024; + +#define MAX_RULE_BUFFER 1024 typedef struct mapcycle_item_s { struct mapcycle_item_s *next; char mapname[ 32 ]; - int minplayers, maxplayers; + int minplayers, maxplayers; char rulebuffer[ MAX_RULE_BUFFER ]; } mapcycle_item_t; @@ -1215,7 +1214,6 @@ int ReloadMapCycleFile( char *filename, mapcycle_t *cycle ) item->minplayers = 0; item->maxplayers = 0; - int Minimum = 0; memset( item->rulebuffer, 0, MAX_RULE_BUFFER ); @@ -1225,14 +1223,14 @@ int ReloadMapCycleFile( char *filename, mapcycle_t *cycle ) if ( s && s[0] ) { item->minplayers = atoi( s ); - item->minplayers = V_max( item->minplayers, Minimum); + item->minplayers = V_max( item->minplayers, 0 ); item->minplayers = V_min( item->minplayers, gpGlobals->maxClients ); } s = g_engfuncs.pfnInfoKeyValue( szBuffer, "maxplayers" ); if ( s && s[0] ) { item->maxplayers = atoi( s ); - item->maxplayers = V_max( item->maxplayers, Minimum); + item->maxplayers = V_max( item->maxplayers, 0 ); item->maxplayers = V_min( item->maxplayers, gpGlobals->maxClients ); } @@ -1338,7 +1336,7 @@ bool CheckBanned(const char* SteamID ) { if( g_BanList.size() <= 0 ) return false; - for (unsigned int b = 0; b < g_BanList.size(); b++) + for (int b = 0; b < g_BanList.size(); b++) if( g_BanList[b] == (const char *)SteamID ) return true; @@ -1419,8 +1417,8 @@ void CHalfLifeMultiplay :: ChangeLevel( void ) int minplayers = 0, maxplayers = 0; strncpy(szFirstMapInList, "edana", sizeof(szFirstMapInList)); // the absolute default level is edana - int curplayers; - BOOL do_cycle = true; + int curplayers; + BOOL do_cycle = TRUE; // find the map to change to char *mapcfile = (char*)CVAR_GET_STRING( "mapcyclefile" ); @@ -1441,14 +1439,14 @@ void CHalfLifeMultiplay :: ChangeLevel( void ) if ( !ReloadMapCycleFile( mapcfile, &mapcycle ) || ( !mapcycle.items ) ) { ALERT( at_console, "Unable to load map cycle file %s\n", mapcfile ); - do_cycle = false; + do_cycle = FALSE; } } if ( do_cycle && mapcycle.items ) { - BOOL keeplooking = false; - BOOL found = false; + BOOL keeplooking = FALSE; + BOOL found = FALSE; mapcycle_item_s *item; // Assume current map @@ -1458,7 +1456,7 @@ void CHalfLifeMultiplay :: ChangeLevel( void ) // Traverse list for ( item = mapcycle.next_item; item->next != mapcycle.next_item; item = item->next ) { - keeplooking = false; + keeplooking = FALSE; ASSERT( item != NULL ); @@ -1466,12 +1464,12 @@ void CHalfLifeMultiplay :: ChangeLevel( void ) { if ( curplayers >= item->minplayers ) { - found = true; + found = TRUE; minplayers = item->minplayers; } else { - keeplooking = true; + keeplooking = TRUE; } } @@ -1479,19 +1477,19 @@ void CHalfLifeMultiplay :: ChangeLevel( void ) { if ( curplayers <= item->maxplayers ) { - found = true; + found = TRUE; maxplayers = item->maxplayers; } else { - keeplooking = true; + keeplooking = TRUE; } } if ( keeplooking ) continue; - found = true; + found = TRUE; break; } @@ -1515,7 +1513,7 @@ void CHalfLifeMultiplay :: ChangeLevel( void ) strncpy(szNextMap, szFirstMapInList, sizeof(szNextMap) ); } - g_fGameOver = true; + g_fGameOver = TRUE; ALERT( at_console, "CHANGE LEVEL: %s\n", szNextMap ); if ( minplayers || maxplayers ) @@ -1534,8 +1532,8 @@ void CHalfLifeMultiplay :: ChangeLevel( void ) } } -constexpr int MAX_MOTD_CHUNK = 60; -constexpr int MAX_MOTD_LENGTH = (MAX_MOTD_CHUNK * 4); +#define MAX_MOTD_CHUNK 60 +#define MAX_MOTD_LENGTH (MAX_MOTD_CHUNK * 4) void CHalfLifeMultiplay :: SendMOTDToClient( edict_t *client ) { @@ -1573,7 +1571,7 @@ void CHalfLifeMultiplay :: SendMOTDToClient( edict_t *client ) *pFileList = 0; MESSAGE_BEGIN( MSG_ONE, gmsgMOTD, NULL, client ); - WRITE_BYTE( *pFileList ? false : true ); // false means there is still more message to come + WRITE_BYTE( *pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come WRITE_STRING_LIMIT(chunk, sizeof(chunk)); MESSAGE_END(); } @@ -1589,13 +1587,13 @@ void CHalfLifeMultiplay :: SendMOTDToClient( edict_t *client ) BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) { if(g_VoiceGameMgr.ClientCommand(pPlayer, pcmd)) - return true; + return TRUE; int OldMenu; if( FStrEq( pcmd, "menuselect" ) ) { if ( CMD_ARGC() < 2 ) - return false; + return FALSE; int slot = atoi( CMD_ARGV(1) );//Starts at 1 @@ -1604,7 +1602,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd //Check if you've set a different menu first if( pPlayer->CurrentMenu == OldMenu && !pPlayer->CurrentCallbackMenu ) pPlayer->CurrentMenu = NULL; - return true; + return TRUE; } else if( FStrEq( pcmd, "forgive" ) ) { @@ -1630,7 +1628,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd else { pPlayer->SendInfoMsg( "Forgive: Use this command to remove your accidental death from the killer's record\n" ); } - return true; + return TRUE; } else if( FStrEq( pcmd, "joinparty" ) ) { @@ -1639,7 +1637,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd if( pPlayer->m_pTeam ) { pPlayer->SendInfoMsg( "You are already in a party! Type 'leaveparty' to leave it\n" ); - return true; + return TRUE; } //Get the party name char Name[MAX_TEAMNAME_LEN+1]; @@ -1680,7 +1678,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd } } else { - pTeam = CTeam::CreateTeam( Name, RANDOM_LONG(0, LONG_MAX) ); + pTeam = CTeam::CreateTeam( Name, 0 ); //0 = assign a new unique ID //pPlayer->SendInfoMsg( "You are now the leader of %s\n", Name ); msstring CreateMsg = msstring("You are now the leader of ") + pTeam->m_TeamName; pPlayer->SendHUDMsg( "Party", CreateMsg ); @@ -1688,7 +1686,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd pPlayer->SetTeam( pTeam ); } } - return true; + return TRUE; } else if( FStrEq( pcmd, "leaveparty" ) ) { @@ -1699,7 +1697,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd pPlayer->SendInfoMsg( "You leave the %s party\n", pTeam->TeamName() ); int iTeamPlayers = pTeam->MemberList.size(); if( iTeamPlayers ) - for (unsigned int i = 0; i < pTeam->MemberList.size(); i++) + for (int i = 0; i < pTeam->MemberList.size(); i++) { CBasePlayer *pOtherPlayer = pTeam->GetPlayer( i ); //Send to all other players, but not myself @@ -1715,7 +1713,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd else { pPlayer->SendInfoMsg( "You aren't in a party!\n" ); } - return true; + return TRUE; } else if (FStrEq(pcmd, "startvote") && CMD_ARGC() >= 3 ) { @@ -1733,13 +1731,13 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd else pPlayer->SendInfoMsg( "This server doesn't allow time voting\n" ); } - else return false; - return true; + else return FALSE; + return TRUE; } else if (FStrEq(pcmd, "vote") && CMD_ARGV(1)) { TallyVote( pPlayer, atoi(CMD_ARGV(1)) ? true : false ); - return true; + return TRUE; } else if( FStrEq( pcmd, "accept" ) ) { @@ -1756,7 +1754,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd if( pPlayer->m_pTeam && pPlayer->m_pTeam->GetPlayer( 0 ) == pPlayer ) { CBasePlayer *pCheckPlayer = NULL; - for(int n = 1; n <= gpGlobals->maxClients; n++ ) + for( int n = 1; n <= gpGlobals->maxClients; n++ ) { pCheckPlayer = (CBasePlayer *)UTIL_PlayerByIndex( n ); if( pCheckPlayer && pCheckPlayer->m_pJoinTeam == pPlayer->m_pTeam ) @@ -1773,7 +1771,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd msstring JoinMsg = msstring(pCheckPlayer->DisplayName()) + " joins your party"; pTeam->ValidateUnits( ); - for (unsigned int i = 0; i < pTeam->MemberList.size(); i++) + for (int i = 0; i < pTeam->MemberList.size(); i++) { CBasePlayer *pOtherPlayer = pTeam->GetPlayer( i ); //if( pOtherPlayer ) pOtherPlayer->SendInfoMsg( "%s joins your party\n", STRING(pCheckPlayer->DisplayName) ); @@ -1802,7 +1800,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd AcceptType = 3; } } - return true; + return TRUE; } else if( FStrEq( pcmd, "as_reload_scripts" ) ) { @@ -1815,7 +1813,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd { pPlayer->SendInfoMsg("Error: This command requires developer permissions."); ALERT(at_console, "as_reload_scripts: Permission denied for %s (Steam ID: %s)\n", pPlayer->DisplayName(), pszSteamID ? pszSteamID : "Unknown"); - return true; + return TRUE; } } @@ -1824,7 +1822,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd { pPlayer->SendInfoMsg("Error: Development mode must be enabled (ms_dev_mode 1)."); ALERT(at_console, "as_reload_scripts: Development mode not enabled\n"); - return true; + return TRUE; } pPlayer->SendInfoMsg("Initiating script hot-reload..."); @@ -1842,7 +1840,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ALERT(at_console, "as_reload_scripts: Script hot-reload completed successfully\n"); // Send notification to all players - for(int i = 1; i <= gpGlobals->maxClients; i++ ) + for( int i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer* pOtherPlayer = (CBasePlayer*)UTIL_PlayerByIndex( i ); if( pOtherPlayer && pOtherPlayer != pPlayer ) @@ -1863,13 +1861,13 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ALERT(at_console, "as_reload_scripts: Module system not available\n"); } - return true; + return TRUE; } else if( FStrEq( pcmd, "as_pak_status" ) ) { // Console command to check PAK file status if( !pPlayer ) - return true; + return TRUE; // Check developer permissions msstring steamid = pPlayer->AuthID(); @@ -1878,7 +1876,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd if( !( szSteamID && ( FStrEq( szSteamID, "STEAM_0:1:630973602" ) || pPlayer->IsElite() ) ) ) { pPlayer->SendInfoMsg("Access denied. Developer permissions required."); - return true; + return TRUE; } // Display PAK file diagnostic information @@ -1930,13 +1928,13 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ALERT(at_console, "Module System: NOT AVAILABLE\n"); } - return true; + return TRUE; } else if( FStrEq( pcmd, "as_pak_test" ) ) { // Console command to test PAK file access if( !pPlayer ) - return true; + return TRUE; // Check developer permissions msstring steamid = pPlayer->AuthID(); @@ -1945,7 +1943,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd if( !( szSteamID && ( FStrEq( szSteamID, "STEAM_0:1:630973602" ) || pPlayer->IsElite() ) ) ) { pPlayer->SendInfoMsg("Access denied. Developer permissions required."); - return true; + return TRUE; } pPlayer->SendInfoMsg("Testing PAK file refresh..."); @@ -1973,7 +1971,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ALERT(at_console, "as_pak_test: Module system not available\n"); } - return true; + return TRUE; } else if( FStrEq( pcmd, "say" ) ) { @@ -1984,7 +1982,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd if( !pszText ) { ALERT( at_console, "Say command: CMD_ARGS() returned NULL pointer\n" ); - return false; // Let default handling continue + return FALSE; // Let default handling continue } // Additional memory validation - check if pointer is in valid memory range @@ -1992,14 +1990,14 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd /*if( IsBadReadPtr( pszText, 1 ) ) { ALERT( at_console, "Say command: CMD_ARGS() returned invalid memory pointer\n" ); - return false; + return FALSE; }*/ // Check for empty string if( !*pszText ) { // Empty text - let default handling continue - return false; + return FALSE; } // Safe length calculation with additional bounds checking @@ -2016,21 +2014,21 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd if( textLen == 0 ) { - return false; // Empty text + return FALSE; // Empty text } if( textLen >= MAX_SAFE_LENGTH ) { ALERT( at_console, "Say command: Text length exceeds safety limit (%zu >= %zu)\n", textLen, MAX_SAFE_LENGTH ); ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "Message too long" ); - return true; // Block this command + return TRUE; // Block this command } if( textLen > 256 ) { // Reject excessively long messages ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "Message too long" ); - return true; // Block this command + return TRUE; // Block this command } // Create a safe copy of the text for further processing @@ -2047,7 +2045,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd else { ALERT( at_console, "Say command: Text length invalid for safe copy (%zu)\n", textLen ); - return false; + return FALSE; } // Use the safe copy for all further operations @@ -2055,6 +2053,7 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd // Fire PlayerSayText event for ALL chat messages to AngelScript // This allows AngelScript to process regular chat, commands, and vote requests +#ifndef AS_DISABLED ASEngineEventManager* pEventManager = ASEngineEventManager::Instance(); if( pEventManager && pPlayer ) { @@ -2113,13 +2112,14 @@ BOOL CHalfLifeMultiplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd if( isVoteCommand ) { // Block the normal chat message since this is a command - return true; + return TRUE; } +#endif // Let normal chat messages continue through default handling - return false; + return FALSE; } - return false; + return FALSE; } //========================================================= @@ -2166,8 +2166,8 @@ void CHalfLifeMultiplay::ClientUserInfoChanged( CBasePlayer *pPlayer, const char void CHalfLifeMultiplay::EndMultiplayerGame( void ) { //Delete all the teams - for (unsigned int i = 0; i < CTeam::Teams.size(); i++) - delete CTeam::Teams[0]; + for (int i = 0; i < CTeam::Teams.size(); i++) + delete CTeam::Teams[i]; CTeam::Teams.clear(); m_CurrentVote.fActive = false; @@ -2274,7 +2274,7 @@ void CHalfLifeMultiplay :: UpdateVote( ) //Count SPAWNED players (Connecting players don't count) int iTotalPlayers = 0; - for (int i = 1; i <= gpGlobals->maxClients; i++ ) + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); if( pPlayer && pPlayer->m_fGameHUDInitialized ) diff --git a/src/game/server/gamerules/team.cpp b/src/game/server/gamerules/team.cpp index bb7578eb5..1e38df26c 100644 --- a/src/game/server/gamerules/team.cpp +++ b/src/game/server/gamerules/team.cpp @@ -7,33 +7,51 @@ extern int gmsgTeamInfo; mslist CTeam::Teams; +//Never returns 0, so an ID of 0 always means "no party" +static ulong NewTeamID() +{ + ulong ID; + do + ID = (ulong)RANDOM_LONG(1, LONG_MAX); + while (CTeam::GetTeam(ID)); + + return ID; +} + +//Pass ID 0 to create a brand new party. Pass a saved ID to restore a party: all members with +//that ID end up in the same team, no matter who loads first. CTeam *CTeam::CreateTeam(const char *pszName, ulong ID) { if (!pszName || !pszName[0]) return NULL; - CTeam *pNewTeam = GetTeam(ID); + //Team exists (another member already restored it), use it + if (ID) + { + CTeam *pTeam = GetTeam(ID); + if (pTeam) + return pTeam; + } - //Team exists, use it - if (pNewTeam) - return pNewTeam; + //A different party already uses this name. Don't merge into a stranger's party + if (GetTeam(pszName)) + return NULL; //Create new team - CTeam* NewTeam = msnew CTeam; - - strncpy((char*)NewTeam->m_TeamName, pszName, MAX_TEAMNAME_LEN); - NewTeam->m_ID = RANDOM_LONG(0, LONG_MAX); //Assign Unique ID + CTeam *pNewTeam = msnew CTeam; + strncpy((char *)pNewTeam->m_TeamName, pszName, MAX_TEAMNAME_LEN); + pNewTeam->m_ID = (int)(ID ? ID : NewTeamID()); - Teams.add(NewTeam); + Teams.add(pNewTeam); - return NewTeam; + return pNewTeam; } CTeam *CTeam::GetTeam(const char *pszName) { if (!pszName || !pszName[0]) return NULL; - for (unsigned int i = 0; i < Teams.size(); i++) + for (int i = 0; i < Teams.size(); i++) if (FStrEq(Teams[i]->TeamName(), pszName)) return Teams[i]; @@ -41,7 +59,7 @@ CTeam *CTeam::GetTeam(const char *pszName) } CTeam *CTeam::GetTeam(ulong ID) { - for (unsigned int i = 0; i < Teams.size(); i++) + for (int i = 0; i < Teams.size(); i++) if (Teams[i]->m_ID == ID) return Teams[i]; @@ -50,7 +68,7 @@ CTeam *CTeam::GetTeam(ulong ID) void CTeam ::ValidateUnits() { - for (unsigned int i = 0; i < MemberList.size(); i++) + for (int i = 0; i < MemberList.size(); i++) { teamunit_t &Unit = MemberList[i]; if ((ulong)UTIL_PlayerByIndex(Unit.idx) != Unit.ID) @@ -98,7 +116,7 @@ void CTeam ::RemoveFromTeam(CBasePlayer *pPlayer) if (!pPlayer || !ExistsInList(pPlayer)) return; - for (unsigned int i = 0; i < MemberList.size(); i++) + for (int i = 0; i < MemberList.size(); i++) if (GetPlayer(i) == pPlayer) { MemberList.erase(i); @@ -121,17 +139,18 @@ void CTeam ::RemoveFromTeam(CBasePlayer *pPlayer) BOOL CTeam ::ExistsInList(CBasePlayer *pPlayer) { if (!pPlayer) - return false; + return FALSE; ValidateUnits(); - for (unsigned int i = 0; i < MemberList.size(); i++) + for (int i = 0; i < MemberList.size(); i++) if (MemberList[i].idx == pPlayer->entindex() && MemberList[i].ID == (ulong)pPlayer) - return true; - return false; + return TRUE; + return FALSE; } CTeam::~CTeam() { ValidateUnits(); - for (unsigned int i = 0; i < MemberList.size(); i++) + //Backwards, because SetTeam(NULL) erases the member from MemberList + for (int i = (int)MemberList.size() - 1; i >= 0; i--) { CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(MemberList[i].idx); if (!pPlayer || (ulong)pPlayer != MemberList[i].ID) @@ -160,15 +179,15 @@ void CTeam ::SetSolidMembers(BOOL fSolid) BOOL SameTeam(CBaseEntity *pObject1, CBaseEntity *pObject2) { //Original: - /*if( !pObject1->TeamID()[0] || !pObject2->TeamID()[0] ) return false; - if( pObject1->TeamID() == pObject2->TeamID() ) return true; - return false;*/ + /*if( !pObject1->TeamID()[0] || !pObject2->TeamID()[0] ) return FALSE; + if( pObject1->TeamID() == pObject2->TeamID() ) return TRUE; + return FALSE;*/ if (!pObject1->TeamID()[0] || !pObject2->TeamID()[0]) - return false; + return FALSE; if (strcmp(pObject1->TeamID(), pObject2->TeamID()) == 0) - return true; //MiB AUG2007a: Comparing with == is bad. Bad, Dogg. Bad. - return false; + return TRUE; //MiB AUG2007a: Comparing with == is bad. Bad, Dogg. Bad. + return FALSE; } /*int CBaseEntity::TeamID( void ) { return m_pTeam ? m_pTeam->TeamID() : -1; } void CBaseEntity::SetTeam( CTeam *pTeam ) { diff --git a/src/game/server/gamerules/teams.h b/src/game/server/gamerules/teams.h index 9d3906f19..4950a4825 100644 --- a/src/game/server/gamerules/teams.h +++ b/src/game/server/gamerules/teams.h @@ -1,7 +1,7 @@ #ifndef TEAM_H #define TEAM_H -constexpr int MAX_TEAMNAME_LEN = 12; +#define MAX_TEAMNAME_LEN 12 #ifdef VALVE_DLL #ifdef CBASE_H diff --git a/src/game/server/ggrenade.cpp b/src/game/server/ggrenade.cpp index 4d73aa3dd..25f0e7cf8 100644 --- a/src/game/server/ggrenade.cpp +++ b/src/game/server/ggrenade.cpp @@ -25,15 +25,12 @@ #include "soundent.h" #include "decals.h" -#ifndef EFFECTS_H -#include "effects.h" -#endif - //===================grenade LINK_ENTITY_TO_CLASS(grenade, CGrenade); // Grenades flagged with this will be triggered when the owner calls detonateSatchelCharges +#define SF_DETONATE 0x0001 // // Grenade Explode @@ -124,8 +121,8 @@ void CGrenade::Explode(TraceResult *pTrace, int bitsDamageType) if (iContents != CONTENTS_WATER) { - unsigned int sparkCount = RANDOM_LONG(0, 3); - for (unsigned int i = 0; i < sparkCount; i++) + int sparkCount = RANDOM_LONG(0, 3); + for (int i = 0; i < sparkCount; i++) Create("spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL); } } @@ -253,7 +250,7 @@ void CGrenade::BounceTouch(CBaseEntity *pOther) // register a radius louder than the explosion, so we make sure everyone gets out of the way CSoundEnt::InsertSound(bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3); - m_fRegisteredSound = true; + m_fRegisteredSound = TRUE; } if (pev->flags & FL_ONGROUND) @@ -354,7 +351,7 @@ void CGrenade::Spawn(void) UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0)); pev->dmg = 100; - m_fRegisteredSound = false; + m_fRegisteredSound = FALSE; } CGrenade *CGrenade::ShootContact(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity) diff --git a/src/game/server/h_export.cpp b/src/game/server/h_export.cpp index 2dea9b628..78ecb7a63 100644 --- a/src/game/server/h_export.cpp +++ b/src/game/server/h_export.cpp @@ -57,7 +57,7 @@ BOOL WINAPI DllMain( else if (fdwReason == DLL_PROCESS_DETACH) MSGlobals::DLLDetach(); - return true; + return TRUE; } #endif diff --git a/src/game/server/hl/animating.cpp b/src/game/server/hl/animating.cpp index 5c829afc7..856ab391c 100644 --- a/src/game/server/hl/animating.cpp +++ b/src/game/server/hl/animating.cpp @@ -21,9 +21,6 @@ */ #define VALVE_DLL 1 -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif #include "msdllheaders.h" #include "animation.h" @@ -67,7 +64,7 @@ float CBaseAnimating ::StudioFrameAdvance(float flInterval) pev->frame -= (int)(pev->frame / 256.0) * 256.0; else pev->frame = (pev->frame < 0.0) ? 0 : 255; - m_fSequenceFinished = true; // just in case it wasn't caught in GetEvents + m_fSequenceFinished = TRUE; // just in case it wasn't caught in GetEvents } return flInterval; @@ -116,7 +113,7 @@ void CBaseAnimating ::ResetSequenceInfo() m_fSequenceLoops = ((GetSequenceFlags() & STUDIO_LOOPING) != 0); pev->animtime = gpGlobals->time; pev->framerate = 1.0; - m_fSequenceFinished = false; + m_fSequenceFinished = FALSE; m_flLastEventCheck = gpGlobals->time; } @@ -157,9 +154,9 @@ void CBaseAnimating ::DispatchAnimEvents(float flInterval) float flEnd = pev->frame + flInterval * m_flFrameRate * pev->framerate; m_flLastEventCheck = pev->animtime + flInterval; - m_fSequenceFinished = false; + m_fSequenceFinished = FALSE; if (flEnd >= 256 || flEnd <= 0.0) - m_fSequenceFinished = true; + m_fSequenceFinished = TRUE; int index = 0; @@ -282,7 +279,7 @@ void CBaseAnimating ::SetSequenceBox(void) Vector rmax(-9999, -9999, -9999); Vector base, transformed; - for (unsigned int i = 0; i <= 1; i++) + for (int i = 0; i <= 1; i++) { base.x = bounds[i].x; for (int j = 0; j <= 1; j++) diff --git a/src/game/server/hl/animation.cpp b/src/game/server/hl/animation.cpp index 74666866b..ab8ce426e 100644 --- a/src/game/server/hl/animation.cpp +++ b/src/game/server/hl/animation.cpp @@ -22,14 +22,15 @@ typedef bool BOOL; // hack into header files that we can ship typedef int qboolean; typedef unsigned char byte; -//#include "../utils/common/mathlib.h" -#include "hl/vector.h" +#include "../utils/common/mathlib.h" #include "const.h" -#include "mathlib.h" + #include "progdefs.h" #include "edict.h" #include "eiface.h" + #include "studio.h" + #include "../engine/studio.h" #ifndef ACTIVITY_H @@ -290,7 +291,6 @@ int GetAnimationEvent(void* pmodel, entvars_t* pev, MonsterEvent_t* pMonsterEven { studiohdr_t* pstudiohdr; - pstudiohdr = (studiohdr_t*)pmodel; if (!pstudiohdr || pev->sequence < 0 || pev->sequence >= pstudiohdr->numseq || !pMonsterEvent) return 0; @@ -303,7 +303,7 @@ int GetAnimationEvent(void* pmodel, entvars_t* pev, MonsterEvent_t* pMonsterEven pseqdesc = (mstudioseqdesc_t*)((byte*)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; pevent = (mstudioevent_t*)((byte*)pstudiohdr + pseqdesc->eventindex); - if (pseqdesc->numevents == 0 || static_cast(index) > pseqdesc->numevents) + if (pseqdesc->numevents == 0 || index > pseqdesc->numevents) return 0; if (pseqdesc->numframes > 1) @@ -317,7 +317,7 @@ int GetAnimationEvent(void* pmodel, entvars_t* pev, MonsterEvent_t* pMonsterEven flEnd = 1.0; } - for (index; index < pseqdesc->numevents; index++) + for (; index < pseqdesc->numevents; index++) { // Don't send client-side events to the server AI if (pevent[index].event >= EVENT_CLIENT) diff --git a/src/game/server/hl/animation.h b/src/game/server/hl/animation.h index 658f706ee..21a64bc9a 100644 --- a/src/game/server/hl/animation.h +++ b/src/game/server/hl/animation.h @@ -12,17 +12,10 @@ * without written permission from Valve LLC. * ****/ - -#ifndef STUDIO_H -#include "studio.h" -#endif - #ifndef ANIMATION_H #define ANIMATION_H -enum { - ACTIVITY_NOT_AVAILABLE = -1 -}; +#define ACTIVITY_NOT_AVAILABLE -1 #ifndef MONSTEREVENT_H #include "monsterevent.h" @@ -48,4 +41,7 @@ int GetBodygroup(void *pmodel, entvars_t *pev, int iGroup); int GetAnimationEvent(void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index); int ExtractBbox(void *pmodel, int sequence, float *mins, float *maxs); +// From /engine/studio.h +#define STUDIO_LOOPING 0x0001 + #endif //ANIMATION_H diff --git a/src/game/server/hl/buttons.cpp b/src/game/server/hl/buttons.cpp index 3f5ce2b9e..2ee68c709 100644 --- a/src/game/server/hl/buttons.cpp +++ b/src/game/server/hl/buttons.cpp @@ -24,6 +24,13 @@ #include "saverestore.h" #include "doors.h" +#define SF_BUTTON_DONTMOVE 1 +#define SF_ROTBUTTON_NOTSOLID 1 +#define SF_BUTTON_TOGGLE 32 // button stays pushed until reactivated +#define SF_BUTTON_SPARK_IF_OFF 64 // button sparks in OFF state +#define SF_BUTTON_TOUCH_ONLY 256 // button only fires as a result of USE key. + +#define SF_GLOBAL_SET 1 // Set global state to initial state on spawn class CEnvGlobal : public CPointEntity { @@ -55,7 +62,7 @@ LINK_ENTITY_TO_CLASS(env_global, CEnvGlobal); void CEnvGlobal::KeyValue(KeyValueData *pkvd) { - pkvd->fHandled = true; + pkvd->fHandled = TRUE; if (FStrEq(pkvd->szKeyName, "globalstate")) // State name m_globalstate = ALLOC_STRING(pkvd->szValue); @@ -140,16 +147,18 @@ void CMultiSource::KeyValue(KeyValueData *pkvd) FStrEq(pkvd->szKeyName, "value1") || FStrEq(pkvd->szKeyName, "value2") || FStrEq(pkvd->szKeyName, "value3")) - pkvd->fHandled = true; + pkvd->fHandled = TRUE; else if (FStrEq(pkvd->szKeyName, "globalstate")) { m_globalstate = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CPointEntity::KeyValue(pkvd); } +#define SF_MULTI_INIT 1 + void CMultiSource::Spawn() { // set up think for later registration @@ -393,32 +402,32 @@ void CBaseButton::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "changetarget")) { m_strChangeTarget = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "locked_sound")) { m_bLockedSound = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "locked_sentence")) { m_bLockedSentence = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "unlocked_sound")) { m_bUnlockedSound = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "unlocked_sentence")) { m_bUnlockedSentence = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "sounds")) { m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseToggle::KeyValue(pkvd); @@ -522,8 +531,8 @@ void CBaseButton::Spawn() if (((m_vecPosition2 - m_vecPosition1).Length() < 1) || (pev->spawnflags & SF_BUTTON_DONTMOVE)) m_vecPosition2 = m_vecPosition1; - m_fStayPushed = (m_flWait == -1 ? true : false); - m_fRotating = false; + m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); + m_fRotating = FALSE; // if the button is flagged for USE button activation only, take away it's touch function and add a use function @@ -727,7 +736,7 @@ void CBaseButton::ButtonTouch(CBaseEntity *pOther) if (!UTIL_IsMasterTriggered(m_sMaster, pOther)) { // play button locked sound - PlayLockSounds(pev, &m_ls, true, true); + PlayLockSounds(pev, &m_ls, TRUE, TRUE); return; } @@ -754,20 +763,18 @@ void CBaseButton::ButtonActivate() if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) { // button is locked, play locked sound - PlayLockSounds(pev, &m_ls, true, true); + PlayLockSounds(pev, &m_ls, TRUE, TRUE); return; } else { // button is unlocked, play unlocked sound - PlayLockSounds(pev, &m_ls, false, true); + PlayLockSounds(pev, &m_ls, FALSE, TRUE); } ASSERT(m_toggle_state == TS_AT_BOTTOM); m_toggle_state = TS_GOING_UP; - - SetMoveDone(&CBaseButton::TriggerAndWait); if (!m_fRotating) LinearMove(m_vecPosition2, pev->speed); @@ -932,8 +939,8 @@ void CRotButton::Spawn(void) m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance; ASSERTSZ(m_vecAngle1 != m_vecAngle2, "rotating button start/end positions are equal"); - m_fStayPushed = (m_flWait == -1 ? true : false); - m_fRotating = true; + m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); + m_fRotating = TRUE; // if the button is flagged for USE button activation only, take away it's touch function and add a use function if (!FBitSet(pev->spawnflags, SF_BUTTON_TOUCH_ONLY)) @@ -951,7 +958,7 @@ void CRotButton::Spawn(void) // 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 class CMomentaryRotButton : public CBaseToggle { @@ -1043,12 +1050,12 @@ void CMomentaryRotButton::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "returnspeed")) { m_returnSpeed = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "sounds")) { m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseToggle::KeyValue(pkvd); @@ -1097,11 +1104,11 @@ void CMomentaryRotButton::UpdateAllButtons(float value, int start) void CMomentaryRotButton::UpdateSelf(float value) { - BOOL fplaysound = false; + BOOL fplaysound = FALSE; if (!m_lastUsed) { - fplaysound = true; + fplaysound = TRUE; m_direction = -m_direction; } m_lastUsed = 1; @@ -1264,7 +1271,7 @@ void CEnvSpark::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "MaxDelay")) { m_flDelay = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "style") || FStrEq(pkvd->szKeyName, "height") || @@ -1272,7 +1279,7 @@ void CEnvSpark::KeyValue(KeyValueData *pkvd) FStrEq(pkvd->szKeyName, "value1") || FStrEq(pkvd->szKeyName, "value2") || FStrEq(pkvd->szKeyName, "value3")) - pkvd->fHandled = true; + pkvd->fHandled = TRUE; else CBaseEntity::KeyValue(pkvd); } @@ -1296,6 +1303,9 @@ void EXPORT CEnvSpark::SparkStop(CBaseEntity *pActivator, CBaseEntity *pCaller, SetThink(NULL); } +#define SF_BTARGET_USE 0x0001 +#define SF_BTARGET_ON 0x0002 + class CButtonTarget : public CBaseEntity { public: diff --git a/src/game/server/hl/cbase.cpp b/src/game/server/hl/cbase.cpp index 48dead1e5..c9e889966 100644 --- a/src/game/server/hl/cbase.cpp +++ b/src/game/server/hl/cbase.cpp @@ -109,11 +109,11 @@ extern "C" { { if (!pFunctionTable || interfaceVersion != INTERFACE_VERSION) { - return false; + return FALSE; } memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS)); - return true; + return TRUE; } int GetEntityAPI2(DLL_FUNCTIONS* pFunctionTable, int* interfaceVersion) @@ -122,11 +122,11 @@ extern "C" { { // Tell engine what version we had, so it can figure out who is out of date. *interfaceVersion = INTERFACE_VERSION; - return false; + return FALSE; } memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS)); - return true; + return TRUE; } int GetNewDLLFunctions(NEW_DLL_FUNCTIONS* pFunctionTable, int* interfaceVersion) @@ -134,11 +134,11 @@ extern "C" { if (!pFunctionTable || *interfaceVersion != NEW_DLL_FUNCTIONS_VERSION) { *interfaceVersion = NEW_DLL_FUNCTIONS_VERSION; - return false; + return FALSE; } memcpy(pFunctionTable, &gNewDLLFunctions, sizeof(gNewDLLFunctions)); - return true; + return TRUE; } } @@ -228,7 +228,7 @@ void DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd) // HACKHACK -- this is a hack to keep the node graph entity from "touching" things (like triggers) // while it builds the graph -BOOL gTouchDisabled = false; +BOOL gTouchDisabled = FALSE; void DispatchTouch(edict_t *pentTouched, edict_t *pentOther) { @@ -761,32 +761,32 @@ BOOL CBaseEntity ::IsInWorld(void) { // position if (pev->origin.x >= 4096) - return false; + return FALSE; if (pev->origin.y >= 4096) - return false; + return FALSE; if (pev->origin.z >= 4096) - return false; + return FALSE; if (pev->origin.x <= -4096) - return false; + return FALSE; if (pev->origin.y <= -4096) - return false; + return FALSE; if (pev->origin.z <= -4096) - return false; + return FALSE; // speed if (pev->velocity.x >= 2000) - return false; + return FALSE; if (pev->velocity.y >= 2000) - return false; + return FALSE; if (pev->velocity.z >= 2000) - return false; + return FALSE; if (pev->velocity.x <= -2000) - return false; + return FALSE; if (pev->velocity.y <= -2000) - return false; + return FALSE; if (pev->velocity.z <= -2000) - return false; + return FALSE; - return true; + return TRUE; } int CBaseEntity::ShouldToggle(USE_TYPE useType, BOOL currentState) diff --git a/src/game/server/hl/cbase.h b/src/game/server/hl/cbase.h index 552e89b14..ec3361e2c 100644 --- a/src/game/server/hl/cbase.h +++ b/src/game/server/hl/cbase.h @@ -27,30 +27,28 @@ CBaseEntity #ifndef CBASE_H #define CBASE_H -constexpr int MAX_PATH_SIZE = 10; // max number of nodes available for a path. +#define MAX_PATH_SIZE 10 // max number of nodes available for a path. // These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions) -enum fcap_bits_e { - FCAP_CUSTOMSAVE = 0x00000001, - FCAP_ACROSS_TRANSITION = 0x00000002,// should transfer between transitions - FCAP_MUST_SPAWN = 0x00000004, // Spawn after restore - FCAP_DONT_SAVE = 0x80000000, // Don't save this - FCAP_IMPULSE_USE = 0x00000008, // can be used by the player - FCAP_CONTINUOUS_USE = 0x00000010, // can be used by the player - FCAP_ONOFF_USE = 0x00000020, // can be used by the player - FCAP_DIRECTIONAL_USE = 0x00000040, // Player sends +/- 1 when using (currently only tracktrains) - FCAP_MASTER = 0x00000080, // Can be used to "master" other entities (like multisource) - - // UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!! - FCAP_FORCE_TRANSITION = 0x00000080 // ALWAYS goes across 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) + +// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!! +#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions #include "iscript.h" #include "archtypes.h" // DAL //Master Sword - no save/restore in client dll -constexpr unsigned int MAXPLAYERS = 32; +#define MAXPLAYERS 32 #ifdef VALVE_DLL #include "saverestore.h" #else @@ -119,40 +117,39 @@ typedef void (CBaseEntity::*USEPTR)(CBaseEntity *pActivator, CBaseEntity *pCalle // Master Sword - New CLASS defs: -enum class_entity_e { - CLASS_NONE = 0, - CLASS_MACHINE = 1, - CLASS_PLAYER = 2, - CLASS_NPC = 3, - CLASS_MONSTER = 4, //CLASS_HUMAN_MILITARY - - // OLD DEFS! - // For CLASSIFY - //#define CLASS_NONE 0 - //#define CLASS_MACHINE 1 - //#define CLASS_PLAYER 2 - CLASS_HUMAN_PASSIVE = 5, - CLASS_HUMAN_MILITARY = 6, - CLASS_ALIEN_MILITARY = 7, - CLASS_ALIEN_PASSIVE = 8, - CLASS_ALIEN_MONSTER = 9, - CLASS_ALIEN_PREY = 10, - CLASS_ALIEN_PREDATOR = 11, - CLASS_INSECT = 12, - CLASS_PLAYER_ALLY = 13, - CLASS_PLAYER_BIOWEAPON = 14, // hornets and snarks.launched by players - CLASS_ALIEN_BIOWEAPON = 15, // hornets and snarks.launched by the alien menace - CLASS_BARNACLE = 99, // special because no one pays attention to it, and it eats a wide cross-section of creatures. - CLASS_VEHICLE = 16, // we use 16 because of MS class defines. -}; - -constexpr unsigned int CHAR_LEVEL_CAP = 45; // MiB JAN2010_15 Global Level Cap +#define CLASS_NONE 0 +#define CLASS_MACHINE 1 +#define CLASS_PLAYER 2 +#define CLASS_NPC 3 +#define CLASS_MONSTER 4 //CLASS_HUMAN_MILITARY + +// OLD DEFS! +// For CLASSIFY +//#define CLASS_NONE 0 +//#define CLASS_MACHINE 1 +//#define CLASS_PLAYER 2 +#define CLASS_HUMAN_PASSIVE 5 +#define CLASS_HUMAN_MILITARY 6 +#define CLASS_ALIEN_MILITARY 7 +#define CLASS_ALIEN_PASSIVE 8 +#define CLASS_ALIEN_MONSTER 9 +#define CLASS_ALIEN_PREY 10 +#define CLASS_ALIEN_PREDATOR 11 +#define CLASS_INSECT 12 +#define CLASS_PLAYER_ALLY 13 +#define CLASS_PLAYER_BIOWEAPON 14 // hornets and snarks.launched by players +#define CLASS_ALIEN_BIOWEAPON 15 // hornets and snarks.launched by the alien menace +#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures. +#define CHAR_LEVEL_CAP 45 // MiB JAN2010_15 Global Level Cap +#define CLASS_VEHICLE 16 // we use 16 because of MS class defines. class CBaseEntity; class CBaseMonster; class CBasePlayerItem; class CSquadMonster; +#define SF_NORESPAWN (1 << 30) // !!!set this bit on guns and stuff that should never respawn. + // // EHANDLE. Safe way to point to CBaseEntities who may die between frames // @@ -400,7 +397,7 @@ class CBaseEntity // initialization functions virtual void Spawn(void) {} virtual void Precache(void) { return; } - virtual void KeyValue(KeyValueData *pkvd) { pkvd->fHandled = false; } + virtual void KeyValue(KeyValueData *pkvd) { pkvd->fHandled = FALSE; } virtual int Save(CSave &save); virtual int Restore(CRestore &restore); @@ -424,7 +421,7 @@ class CBaseEntity virtual void Killed(entvars_t *pevAttacker, int iGib); virtual int BloodColor(void) { return DONT_BLEED; } 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(void) { return NULL; } virtual CSquadMonster *MySquadMonsterPointer(void) { return NULL; } virtual bool IsMSMonster(void) { return false; } @@ -440,15 +437,15 @@ class CBaseEntity virtual void SetToggleState(int state) {} virtual void StartSneaking(void) {} virtual void StopSneaking(void) {} - virtual BOOL OnControls(entvars_t *pev) { return false; } - virtual BOOL IsSneaking(void) { return false; } + virtual BOOL OnControls(entvars_t *pev) { return FALSE; } + virtual BOOL IsSneaking(void) { return FALSE; } virtual BOOL IsAlive(void) { return (pev->deadflag == DEAD_NO) && pev->health > 0; } virtual BOOL IsBSPModel(void) { return pev->solid == SOLID_BSP || pev->movetype == MOVETYPE_PUSHSTEP; } virtual BOOL ReflectGauss(void) { return (IsBSPModel() && !pev->takedamage); } virtual BOOL HasTarget(string_t targetname) { return FStrEq(STRING(targetname), STRING(pev->targetname)); } virtual BOOL IsInWorld(void); - virtual BOOL IsPlayer(void) { return false; } - virtual BOOL IsNetClient(void) { return false; } + virtual BOOL IsPlayer(void) { return FALSE; } + virtual BOOL IsNetClient(void) { return FALSE; } virtual const char *TeamID(void) { return ""; } // virtual void SetActivator( CBaseEntity *pActivator ) {} @@ -519,7 +516,7 @@ class CBaseEntity int Intersects(CBaseEntity *pOther); void MakeDormant(void); int IsDormant(void); - BOOL IsLockedByMaster(void) { return false; } + BOOL IsLockedByMaster(void) { return FALSE; } static CBaseEntity *Instance(edict_t *pent) { @@ -595,7 +592,7 @@ class CBaseEntity // static CBaseEntity *Create(const char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = NULL); - virtual BOOL FBecomeProne(void) { return false; }; + virtual BOOL FBecomeProne(void) { return FALSE; }; edict_t *edict() { //Master Sword... Client has no edict_t ! #ifdef VALVE_DLL @@ -693,8 +690,8 @@ void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton); // MultiSouce // -constexpr int MAX_MULTI_TARGETS = 16; // maximum number of targets a single multi_manager entity may be assigned. -constexpr int MS_MAX_TARGETS = 32; +#define MAX_MULTI_TARGETS 16 // maximum number of targets a single multi_manager entity may be assigned. +#define MS_MAX_TARGETS 32 class CMultiSource : public CPointEntity { @@ -782,7 +779,7 @@ class CBaseAnimating : public CBaseDelay // // generic Toggle entity. // - +#define SF_ITEM_USE_ONLY 256 // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!! class CBaseToggle : public CBaseAnimating { @@ -836,128 +833,121 @@ class CBaseToggle : public CBaseAnimating // the button will be allowed to operate. Otherwise, it will be // deactivated. }; +#define SetMoveDone(a) m_pfnCallWhenMoveDone = static_cast(a) +// people gib if their health is <= this at the time of death +#define GIB_HEALTH_VALUE -30 -#define SetMoveDone(a) m_pfnCallWhenMoveDone = static_cast(a) +#define ROUTE_SIZE 8 // how many waypoints a monster can store at one time +#define MAX_OLD_ENEMIES 4 // how many old enemies to remember +#define bits_CAP_DUCK (1 << 0) // crouch +#define bits_CAP_JUMP (1 << 1) // jump/leap +#define bits_CAP_STRAFE (1 << 2) // strafe ( walk/run sideways) +#define bits_CAP_SQUAD (1 << 3) // can form squads +#define bits_CAP_SWIM (1 << 4) // proficiently navigate in water +#define bits_CAP_CLIMB (1 << 5) // climb ladders/ropes +#define bits_CAP_USE (1 << 6) // open doors/push buttons/pull levers +#define bits_CAP_HEAR (1 << 7) // can hear forced sounds +#define bits_CAP_AUTO_DOORS (1 << 8) // can trigger auto doors +#define bits_CAP_OPEN_DOORS (1 << 9) // can open manual doors +#define bits_CAP_TURN_HEAD (1 << 10) // can turn head, always bone controller 0 +#define bits_CAP_RANGE_ATTACK1 (1 << 11) // can do a range attack 1 +#define bits_CAP_RANGE_ATTACK2 (1 << 12) // can do a range attack 2 +#define bits_CAP_MELEE_ATTACK1 (1 << 13) // can do a melee attack 1 +#define bits_CAP_MELEE_ATTACK2 (1 << 14) // can do a melee attack 2 + +#define bits_CAP_FLY (1 << 15) // can fly, move all around + +#define bits_CAP_DOORS_GROUP (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS) -// people gib if their health is <= this at the time of death -constexpr int GIB_HEALTH_VALUE = -30; -constexpr int ROUTE_SIZE = 8; // how many waypoints a monster can store at one time -constexpr int MAX_OLD_ENEMIES = 4; // how many old enemies to remember - -enum bits_cap_e { - bits_CAP_DUCK = (1 << 0), // crouch - bits_CAP_JUMP = (1 << 1), // jump/leap - bits_CAP_STRAFE = (1 << 2), // strafe ( walk/run sideways) - bits_CAP_SQUAD = (1 << 3), // can form squads - bits_CAP_SWIM = (1 << 4), // proficiently navigate in water - bits_CAP_CLIMB = (1 << 5), // climb ladders/ropes - bits_CAP_USE = (1 << 6), // open doors/push buttons/pull levers - bits_CAP_HEAR = (1 << 7), // can hear forced sounds - bits_CAP_AUTO_DOORS = (1 << 8), // can trigger auto doors - bits_CAP_OPEN_DOORS = (1 << 9), // can open manual doors - bits_CAP_TURN_HEAD = (1 << 10), // can turn head, always bone controller 0 - bits_CAP_RANGE_ATTACK1 = (1 << 11), // can do a range attack 1 - bits_CAP_RANGE_ATTACK2 = (1 << 12), // can do a range attack 2 - bits_CAP_MELEE_ATTACK1 = (1 << 13), // can do a melee attack 1 - bits_CAP_MELEE_ATTACK2 = (1 << 14), // can do a melee attack 2 - bits_CAP_FLY = (1 << 15), // can fly, move all around - bits_CAP_DOORS_GROUP = (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS) -}; // used by suit voice to indicate damage sustained and repaired type to player // instant damage - -enum dmg_type_e { - DMG_GENERIC = (0 << 0), // generic damage was done - DMG_CRUSH = (1 << 0), // crushed by falling or moving object - DMG_BULLET = (1 << 1), // shot - DMG_SLASH = (1 << 2), // cut, clawed, stabbed - DMG_BURN = (1 << 3), // heat burned - DMG_FREEZE = (1 << 4), // frozen - DMG_FALL = (1 << 5), // fell too far - DMG_BLAST = (1 << 6), // explosive blast damage - DMG_CLUB = (1 << 7), // crowbar, punch, headbutt - DMG_SHOCK = (1 << 8), // electric shock - DMG_SONIC = (1 << 9), // sound pulse shockwave - DMG_ENERGYBEAM = (1 << 10), // laser or other high energy beam - DMG_NEVERGIB = (1 << 12), // with this bit OR'd in, no damage type will be able to gib victims upon death - DMG_ALWAYSGIB = (1 << 13), // with this bit OR'd in, any damage type can be made to gib victims upon death. - DMG_DROWN = (1 << 14), // Drowning - DMG_TIMEBASED = (~(0x3fff)), // mask for time-based damage - DMG_PARALYZE = (1 << 15), // slows affected creature down - DMG_NERVEGAS = (1 << 16), // nerve toxins, very bad - DMG_POISON = (1 << 17), // blood poisioning - DMG_RADIATION = (1 << 18), // radiation exposure - DMG_DROWNRECOVER = (1 << 19), // drowning recovery - DMG_ACID = (1 << 20), // toxic chemicals or acid burns - DMG_SLOWBURN = (1 << 21), // in an oven - DMG_SLOWFREEZE = (1 << 22), // in a subzero freezer - DMG_MORTAR = (1 << 23), // Hit by air raid (done to distinguish grenade from mortar) - DMG_CALTROP = (1 << 30), - DMG_HALLUC = (1 << 31), - DMG_TRANQ = DMG_MORTAR, - DMG_CONCUSS = DMG_SONIC, - //Master Sword -- - DMG_NOKILL = (1 << 24), // (Dogg) This damage cannot kill you (fists reflective damage...) - DMG_SIMPLEBBOX = (1 << 25), // (Dogg) Use a simple BBox for tracelines - DMG_DIRECT = (1 << 26), // (Dogg) Ignore the traceline and just do damage to the target - DMG_REFLECTIVE = (1 << 27), // (Dogg) This damage can hurt you - DMG_AOE = (1 << 28), // (Dogg) Area of Effect Damage - DMG_NONE = (1 << 29), // (Dogg) Find a target, but don't damage it - DMG_NOSKIN = (1 << 30), // (Dogg) This damage won't skin creatures (arrows, fireball, etc.) - DMG_MARTIALARTS = (1 << 31), // (Dogg) Martial arts attack (punch, kick, jumpkick...) - //--------------- - // these are the damage types that are allowed to gib corpses - DMG_GIB_CORPSE = (DMG_CRUSH | DMG_FALL | DMG_BLAST | DMG_SONIC | DMG_CLUB), - // these are the damage types that have client hud art - DMG_SHOWNHUD = (DMG_POISON | DMG_ACID | DMG_FREEZE | DMG_SLOWFREEZE | DMG_DROWN | DMG_BURN | DMG_SLOWBURN | DMG_NERVEGAS | DMG_RADIATION | DMG_SHOCK) -}; + +#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) +//Master Sword -- +#define DMG_NOKILL (1 << 24) // (Dogg) This damage cannot kill you (fists reflective damage...) +#define DMG_SIMPLEBBOX (1 << 25) // (Dogg) Use a simple BBox for tracelines +#define DMG_DIRECT (1 << 26) // (Dogg) Ignore the traceline and just do damage to the target +#define DMG_REFLECTIVE (1 << 27) // (Dogg) This damage can hurt you +#define DMG_AOE (1 << 28) // (Dogg) Area of Effect Damage +#define DMG_NONE (1 << 29) // (Dogg) Find a target, but don't damage it +#define DMG_NOSKIN (1 << 30) // (Dogg) This damage won't skin creatures (arrows, fireball, etc.) +#define DMG_MARTIALARTS (1 << 31) // (Dogg) Martial arts attack (punch, kick, jumpkick...) +//--------------- +// 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) + // NOTE: tweak these values based on gameplay feedback: -constexpr int PARALYZE_DURATION = 2; // number of 2 second intervals to take damage -constexpr float PARALYZE_DAMAGE = 1.0;// damage to take each 2 second interval +#define PARALYZE_DURATION 2 // number of 2 second intervals to take damage +#define PARALYZE_DAMAGE 1.0 // damage to take each 2 second interval -constexpr int NERVEGAS_DURATION = 2; -constexpr float NERVEGAS_DAMAGE = 5.0; +#define NERVEGAS_DURATION 2 +#define NERVEGAS_DAMAGE 5.0 -constexpr int POISON_DURATION = 5; -constexpr float POISON_DAMAGE = 2.0; +#define POISON_DURATION 5 +#define POISON_DAMAGE 2.0 -constexpr int RADIATION_DURATION = 2; -constexpr float RADIATION_DAMAGE = 1.0; +#define RADIATION_DURATION 2 +#define RADIATION_DAMAGE 1.0 -constexpr int ACID_DURATION = 2; -constexpr float ACID_DAMAGE = 5.0; +#define ACID_DURATION 2 +#define ACID_DAMAGE 5.0 -constexpr int SLOWBURN_DURATION = 2; -constexpr float SLOWBURN_DAMAGE = 1.0; +#define SLOWBURN_DURATION 2 +#define SLOWBURN_DAMAGE 1.0 -constexpr int SLOWFREEZE_DURATION = 2; -constexpr float SLOWFREEZE_DAMAGE = 1.0; +#define SLOWFREEZE_DURATION 2 +#define SLOWFREEZE_DAMAGE 1.0 -enum dot_type_e { - itbd_Paralyze = 0, - itbd_NerveGas = 1, - itbd_Poison = 2, - itbd_Radiation = 3, - itbd_DrownRecover = 4, - itbd_Acid = 5, - itbd_SlowBurn = 6, - itbd_SlowFreeze = 7, - CDMG_TIMEBASED = 8 -}; +#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 ) -enum gib_setting_e { - GIB_NORMAL = 0, // gib if entity was overkilled - GIB_NEVER = 1, // never gib, no matter how much death damage is done ( freezing, etc ) - GIB_ALWAYS = 2 // always gib ( Houndeye Shock, Barnacle Bite ) -}; class CBaseMonster; class CCineMonster; class CSound; @@ -1028,7 +1018,7 @@ class CBaseButton : public CBaseToggle // Weapons // -constexpr unsigned int BAD_WEAPON = 0x00007FFF; +#define BAD_WEAPON 0x00007FFF // // Converts a entvars_t * to a class pointer @@ -1078,7 +1068,7 @@ env_sound_data push_trigger_data */ -constexpr int TRACER_FREQ = 4; // Tracers fire every 4 bullets +#define TRACER_FREQ 4 // Tracers fire every 4 bullets typedef struct _SelAmmo { diff --git a/src/game/server/hl/client.h b/src/game/server/hl/client.h index 11a72bec2..f1b9df353 100644 --- a/src/game/server/hl/client.h +++ b/src/game/server/hl/client.h @@ -44,7 +44,7 @@ extern void Sys_Error(const char *error_string); extern void SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas); extern void UpdateClientData(const struct edict_s *ent, int sendweapons, struct clientdata_s *cd); extern int AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet); -extern void CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, Vector player_mins, Vector player_maxs); +extern void CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, Vector player_mins, Vector player_maxs); extern void RegisterEncoders(void); extern int GetWeaponData(struct edict_s *player, struct weapon_data_s *info); diff --git a/src/game/server/hl/doors.cpp b/src/game/server/hl/doors.cpp index 1120a86ac..5c7110a03 100644 --- a/src/game/server/hl/doors.cpp +++ b/src/game/server/hl/doors.cpp @@ -25,7 +25,6 @@ extern void SetMovedir(entvars_t *ev); -//overloaded varables with generic names #define noiseMoving noise1 #define noiseArrived noise2 @@ -90,6 +89,10 @@ TYPEDESCRIPTION CBaseDoor::m_SaveData[] = IMPLEMENT_SAVERESTORE(CBaseDoor, CBaseToggle); +#define DOOR_SENTENCEWAIT 6 +#define DOOR_SOUNDWAIT 3 +#define BUTTON_SOUNDWAIT 0.5 + // play door or button locked or unlocked sounds. // pass in pointer to valid locksound struct. // if flocked is true, play 'door is locked' sound, @@ -135,7 +138,7 @@ void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton) int iprev = pls->iLockedSentence; pls->iLockedSentence = SENTENCEG_PlaySequentialSz(ENT(pev), STRING(pls->sLockedSentence), - 0.85, ATTN_NORM, 0, 100, pls->iLockedSentence, false); + 0.85, ATTN_NORM, 0, 100, pls->iLockedSentence, FALSE); pls->iUnlockedSentence = 0; // make sure we don't keep calling last sentence in list @@ -171,7 +174,7 @@ void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton) int iprev = pls->iUnlockedSentence; pls->iUnlockedSentence = SENTENCEG_PlaySequentialSz(ENT(pev), STRING(pls->sUnlockedSentence), - 0.85, ATTN_NORM, 0, 100, pls->iUnlockedSentence, false); + 0.85, ATTN_NORM, 0, 100, pls->iUnlockedSentence, FALSE); pls->iLockedSentence = 0; // make sure we don't keep calling last sentence in list @@ -191,47 +194,47 @@ void CBaseDoor::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "skin")) //skin is used for content type { pev->skin = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "movesnd")) { m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "stopsnd")) { m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "healthvalue")) { m_bHealthValue = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "locked_sound")) { m_bLockedSound = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "locked_sentence")) { m_bLockedSentence = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "unlocked_sound")) { m_bUnlockedSound = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "unlocked_sentence")) { m_bUnlockedSentence = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "WaveHeight")) { pev->scale = atof(pkvd->szValue) * (1.0 / 8.0); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseToggle::KeyValue(pkvd); @@ -522,7 +525,7 @@ void CBaseDoor::DoorTouch(CBaseEntity *pOther) // play 'locked' sound if (m_sMaster && !UTIL_IsMasterTriggered(m_sMaster, pOther)) - PlayLockSounds(pev, &m_ls, true, false); + PlayLockSounds(pev, &m_ls, TRUE, FALSE); // If door is somebody's target, then touching does nothing. // You have to activate the owner (e.g. button). @@ -530,7 +533,7 @@ void CBaseDoor::DoorTouch(CBaseEntity *pOther) if (!FStringNull(pev->targetname)) { // play locked sound - PlayLockSounds(pev, &m_ls, true, false); + PlayLockSounds(pev, &m_ls, TRUE, FALSE); return; } @@ -574,7 +577,7 @@ int CBaseDoor::DoorActivate() } // play door unlock sounds - PlayLockSounds(pev, &m_ls, false, false); + PlayLockSounds(pev, &m_ls, FALSE, FALSE); DoorGoUp(); } @@ -1019,17 +1022,17 @@ void CMomentaryDoor::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "movesnd")) { m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "stopsnd")) { // m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "healthvalue")) { // m_bHealthValue = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseToggle::KeyValue(pkvd); diff --git a/src/game/server/hl/doors.h b/src/game/server/hl/doors.h index e9463d594..3fefa6351 100644 --- a/src/game/server/hl/doors.h +++ b/src/game/server/hl/doors.h @@ -14,63 +14,19 @@ ****/ #ifndef DOORS_H #define DOORS_H -#endif // doors - -constexpr int DOOR_SENTENCEWAIT = 6; -constexpr int DOOR_SOUNDWAIT = 3; -constexpr float BUTTON_SOUNDWAIT = 0.5; - - -enum { - SF_GLOBAL_SET = 1, - SF_MULTI_INIT = 1, - SF_MOMENTARY_DOOR = 0x0001 -}; - -enum { - SF_DOOR_ROTATE_Y = 0, - SF_DOOR_START_OPEN = 1, - SF_DOOR_ROTATE_BACKWARDS = 2, - SF_DOOR_PASSABLE = 8, - SF_DOOR_ONEWAY = 16, - SF_DOOR_NO_AUTO_RETURN = 32, - SF_DOOR_ROTATE_Z = 64, - SF_DOOR_ROTATE_X = 128, - SF_DOOR_USE_ONLY = 256, // door must be opened by player's use button. - SF_DOOR_NOMONSTERS = 512, // Monster can't open - SF_DOOR_UNBLOCKABLE = 1024, //Thothie AUG2011_29 - make door unstoppable - SF_DOOR_SILENT = 0x80000000, - -}; - -enum { - SF_CONVEYOR_VISUAL = 0x0001, - SF_CONVEYOR_NOTSOLID = 0x0002, - SF_CONVEYOR_TOGGLE = 0x0004, //Thothie AUG2011_30 toggle conveyors -}; - -enum { - - SF_ITEM_USE_ONLY = 256, // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!! - SF_BUTTON_USE_ONLY = 256, - SF_PLAYERCLIP_START_OFF = 0x0001, - SF_WALL_START_OFF = 0x0001, - SF_MONSTERCLIP_START_OFF = 0x0001, - SF_PENDULUM_SWING = 2, // spawnflag that makes a pendulum a rope swing. - SF_BRUSH_ACCDCC = 16, // brush should accelerate and decelerate when toggled - SF_BRUSH_HURT = 32, // rotating brush that inflicts pain based on rotation speed - SF_ROTATING_NOT_SOLID = 64, // some special rotating objects are not solid. - SF_NORESPAWN = (1 << 30), // !!!set this bit on guns and stuff that should never respawn. -}; - -enum { - SF_BUTTON_DONTMOVE = 1, - SF_ROTBUTTON_NOTSOLID = 1, - SF_BUTTON_TOGGLE = 32, // button stays pushed until reactivated - SF_BUTTON_SPARK_IF_OFF = 64, // button sparks in OFF state - SF_BUTTON_TOUCH_ONLY = 256, // button only fires as a result of USE key. - SF_BTARGET_USE = 0x0001, - SF_BTARGET_ON = 0x0002 -}; +#define SF_DOOR_ROTATE_Y 0 +#define SF_DOOR_START_OPEN 1 +#define SF_DOOR_ROTATE_BACKWARDS 2 +#define SF_DOOR_PASSABLE 8 +#define SF_DOOR_ONEWAY 16 +#define SF_DOOR_NO_AUTO_RETURN 32 +#define SF_DOOR_ROTATE_Z 64 +#define SF_DOOR_ROTATE_X 128 +#define SF_DOOR_USE_ONLY 256 // door must be opened by player's use button. +#define SF_DOOR_NOMONSTERS 512 // Monster can't open +#define SF_DOOR_UNBLOCKABLE 1024 //Thothie AUG2011_29 - make door unstoppable +#define SF_DOOR_SILENT 0x80000000 + +#endif //DOORS_H diff --git a/src/game/server/hl/effects.h b/src/game/server/hl/effects.h index b70f3a66b..24efca7d2 100644 --- a/src/game/server/hl/effects.h +++ b/src/game/server/hl/effects.h @@ -15,69 +15,20 @@ #ifndef EFFECTS_H #define EFFECTS_H -enum { - SF_BEAM_STARTON = 0x0001, - SF_BEAM_TOGGLE = 0x0002, - SF_BEAM_RANDOM = 0x0004, - SF_BEAM_RING = 0x0008, - SF_BEAM_SPARKSTART = 0x0010, - SF_BEAM_SPARKEND = 0x0020, - SF_BEAM_DECALS = 0x0040, - SF_BEAM_SHADEIN = 0x0080, - SF_BEAM_SHADEOUT = 0x0100, - SF_BEAM_TEMPORARY = 0x8000, - SF_SPRITE_STARTON = 0x0001, - SF_SPRITE_ONCE = 0x0002, - SF_SPRITE_TEMPORARY = 0x8000, - SF_GIBSHOOTER_REPEATABLE = 1, // allows a gibshooter to be refired - SF_FUNNEL_REVERSE = 1, // funnel effect repels particles instead of attracting them. - SF_BUBBLES_STARTOFF = 0x0001, - SF_BLOOD_RANDOM = 0x0001, - SF_BLOOD_STREAM = 0x0002, - SF_BLOOD_PLAYER = 0x0004, - SF_BLOOD_DECAL = 0x0008, - SF_SHAKE_EVERYONE = 0x0001, // Don't check radius - // UNDONE: These don't work yet - SF_SHAKE_DISRUPT = 0x0002, // Disrupt controls - SF_SHAKE_INAIR = 0x0004, // Shake players in air - SF_FADE_IN = 0x0001, // Fade in, not out - SF_FADE_MODULATE = 0x0002, // Modulate, don't blend - SF_FADE_ONLYONE = 0x0004, - SF_MESSAGE_ONCE = 0x0001, // Fade in, not out - SF_MESSAGE_ALL = 0x0002, // Send to all clients - SF_DETONATE = 0x0001, - SF_LOOP = 1, - SF_REMOVE_ON_FIRE = 2, - SF_DECAL_NOTINDEATHMATCH = 2048, - SF_WORLD_DARK = 0x0001, // Fade from black at startup - SF_WORLD_TITLE = 0x0002, // Display game title at startup - SF_WORLD_FORCETEAM = 0x0004 // Force teams - -}; - - -enum { - SF_AUTO_FIREONCE = 0x0001, - SF_TRIGGER_PUSH_START_OFF = 2, //spawnflag that makes trigger_push spawn turned OFF - SF_TRIGGER_HURT_TARGETONCE = 1, // Only fire hurt target once - SF_TRIGGER_HURT_START_OFF = 2, //spawnflag that makes trigger_push spawn turned OFF - SF_TRIGGER_HURT_NO_CLIENTS = 8, //spawnflag that makes trigger_push spawn turned OFF - SF_TRIGGER_HURT_CLIENTONLYFIRE = 16, // trigger hurt will only fire its target if it is hurting a client - SF_TRIGGER_HURT_CLIENTONLYTOUCH = 32, // only clients may touch this trigger. - SF_RELAY_FIREONCE = 0x0001, - SF_MULTIMAN_CLONE = 0x80000000, - SF_MULTIMAN_THREAD = 0x00000001, - SF_RENDER_MASKFX = (1 << 0), - SF_RENDER_MASKAMT = (1 << 1), - SF_RENDER_MASKMODE = (1 << 2), - SF_RENDER_MASKCOLOR = (1 << 3), - SF_CHANGELEVEL_USEONLY = 0x0002, - SF_ENDSECTION_USEONLY = 0x0001, - SF_CAMERA_PLAYER_POSITION = 1, - SF_CAMERA_PLAYER_TARGET = 2, - SF_CAMERA_PLAYER_TAKECONTROL = 4, - SF_CAMERA_PLAYER_ALL = 8 -}; +#define SF_BEAM_STARTON 0x0001 +#define SF_BEAM_TOGGLE 0x0002 +#define SF_BEAM_RANDOM 0x0004 +#define SF_BEAM_RING 0x0008 +#define SF_BEAM_SPARKSTART 0x0010 +#define SF_BEAM_SPARKEND 0x0020 +#define SF_BEAM_DECALS 0x0040 +#define SF_BEAM_SHADEIN 0x0080 +#define SF_BEAM_SHADEOUT 0x0100 +#define SF_BEAM_TEMPORARY 0x8000 + +#define SF_SPRITE_STARTON 0x0001 +#define SF_SPRITE_ONCE 0x0002 +#define SF_SPRITE_TEMPORARY 0x8000 class CSprite : public CPointEntity { @@ -238,7 +189,8 @@ class CBeam : public CBaseEntity } }; - +#define SF_MESSAGE_ONCE 0x0001 // Fade in, not out +#define SF_MESSAGE_ALL 0x0002 // Send to all clients class CLaser : public CBeam { diff --git a/src/game/server/hl/explode.cpp b/src/game/server/hl/explode.cpp index ff5504dbd..667285e9a 100644 --- a/src/game/server/hl/explode.cpp +++ b/src/game/server/hl/explode.cpp @@ -115,7 +115,7 @@ void CEnvExplosion::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "iMagnitude")) { m_iMagnitude = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); @@ -232,9 +232,9 @@ void CEnvExplosion::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE // draw sparks if (!(pev->spawnflags & SF_ENVEXPLOSION_NOSPARKS)) { - unsigned int sparkCount = RANDOM_LONG(0, 3); + int sparkCount = RANDOM_LONG(0, 3); - for (unsigned int i = 0; i < sparkCount; i++) + for (int i = 0; i < sparkCount; i++) { Create("spark_shower", pev->origin, tr.vecPlaneNormal, NULL); } diff --git a/src/game/server/hl/explode.h b/src/game/server/hl/explode.h index 77fabe9cd..95f183f43 100644 --- a/src/game/server/hl/explode.h +++ b/src/game/server/hl/explode.h @@ -15,14 +15,13 @@ #ifndef EXPLODE_H #define EXPLODE_H -enum sf_envexplosion_e { - SF_ENVEXPLOSION_NODAMAGE = (1 << 0), // when set, ENV_EXPLOSION will not actually inflict damage - SF_ENVEXPLOSION_REPEATABLE = (1 << 1), // can this entity be refired? - SF_ENVEXPLOSION_NOFIREBALL = (1 << 2), // don't draw the fireball - SF_ENVEXPLOSION_NOSMOKE = (1 << 3), // don't draw the smoke - SF_ENVEXPLOSION_NODECAL = (1 << 4), // don't make a scorch mark - SF_ENVEXPLOSION_NOSPARKS = (1 << 5) // don't make a scorch mark -}; +#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 + //extern DLL_GLOBAL short g_sModelIndexFireball; //extern DLL_GLOBAL short g_sModelIndexSmoke; diff --git a/src/game/server/hl/extdll.h b/src/game/server/hl/extdll.h index 7b7373639..aca45894e 100644 --- a/src/game/server/hl/extdll.h +++ b/src/game/server/hl/extdll.h @@ -25,6 +25,8 @@ #ifdef _WIN32 #include "PlatformWin.h" #else // _WIN32 +#define FALSE 0 +#define TRUE 1 typedef unsigned int uint; typedef int BOOL; @@ -45,7 +47,7 @@ typedef int BOOL; #include "math.h" // Vector class -#include "hl/vector.h" +#include "vector.h" // Shared engine/DLL constants #include "const.h" diff --git a/src/game/server/hl/func_break.h b/src/game/server/hl/func_break.h index 795efa311..81b17ffda 100644 --- a/src/game/server/hl/func_break.h +++ b/src/game/server/hl/func_break.h @@ -35,7 +35,7 @@ typedef enum matLastMaterial } Materials; -constexpr int NUM_SHARDS = 6; // this many shards spawned when breakable objects break; +#define NUM_SHARDS 6 // this many shards spawned when breakable objects break; class CBreakable : public CBaseDelay { diff --git a/src/game/server/hl/func_tank.cpp b/src/game/server/hl/func_tank.cpp index fb058abc7..5e018c24c 100644 --- a/src/game/server/hl/func_tank.cpp +++ b/src/game/server/hl/func_tank.cpp @@ -20,20 +20,14 @@ #include "explode.h" #include "player.h" -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - - -enum sf_tank_e { - SF_TANK_ACTIVE = 0x0001, - SF_TANK_PLAYER = 0x0002, - SF_TANK_HUMANS = 0x0004, - SF_TANK_ALIENS = 0x0008, - SF_TANK_LINEOFSIGHT = 0x0010, - SF_TANK_CANCONTROL = 0x0020, - SF_TANK_SOUNDON = 0x8000, -}; + +#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 { @@ -70,7 +64,7 @@ class CFuncTank : public CBaseEntity // Bmodels don't go across transitions virtual int ObjectCaps(void) { return CBaseEntity ::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - inline BOOL IsActive(void) { return (pev->spawnflags & SF_TANK_ACTIVE) ? true : false; } + inline BOOL IsActive(void) { return (pev->spawnflags & SF_TANK_ACTIVE) ? TRUE : FALSE; } inline void TankActivate(void) { pev->spawnflags |= SF_TANK_ACTIVE; @@ -184,8 +178,7 @@ static Vector gTankSpread[] = Vector(0.1, 0.1, 0.1), // large cone Vector(0.25, 0.25, 0.25), // extra-large cone }; - -constexpr size_t MAX_FIRING_SPREADS = std::size(gTankSpread); +#define MAX_FIRING_SPREADS std::size(gTankSpread) void CFuncTank ::Spawn(void) { @@ -227,107 +220,107 @@ void CFuncTank ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "yawrate")) { m_yawRate = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "yawrange")) { m_yawRange = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "yawtolerance")) { m_yawTolerance = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "pitchrange")) { m_pitchRange = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "pitchrate")) { m_pitchRate = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "pitchtolerance")) { m_pitchTolerance = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "firerate")) { m_fireRate = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "barrel")) { m_barrelPos.x = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "barrely")) { m_barrelPos.y = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "barrelz")) { m_barrelPos.z = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spritescale")) { m_spriteScale = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spritesmoke")) { m_iszSpriteSmoke = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spriteflash")) { m_iszSpriteFlash = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "rotatesound")) { pev->noise = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "persistence")) { m_persist = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "bullet")) { m_bulletType = (TANKBULLET)atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "bullet_damage")) { m_iBulletDamage = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "firespread")) { m_spread = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "minRange")) { m_minRange = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "maxRange")) { m_maxRange = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "master")) { m_iszMaster = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); @@ -340,26 +333,26 @@ void CFuncTank ::KeyValue(KeyValueData *pkvd) BOOL CFuncTank ::OnControls(entvars_t *pevTest) { if (!(pev->spawnflags & SF_TANK_CANCONTROL)) - return false; + return FALSE; Vector offset = pevTest->origin - pev->origin; if ((m_vecControllerUsePos - pevTest->origin).Length() < 30) - return true; + return TRUE; - return false; + return FALSE; } BOOL CFuncTank ::StartControl(CBasePlayer *pController) { if (m_pController != NULL) - return false; + return FALSE; // Team only or disabled? if (m_iszMaster) { if (!UTIL_IsMasterTriggered(m_iszMaster, pController)) - return false; + return FALSE; } ALERT(at_console, "using TANK!\n"); @@ -377,7 +370,7 @@ BOOL CFuncTank ::StartControl(CBasePlayer *pController) pev->nextthink = pev->ltime + 0.1; - return true; + return TRUE; } void CFuncTank ::StopControl() @@ -468,11 +461,11 @@ edict_t *CFuncTank ::FindTarget(edict_t *pPlayer) BOOL CFuncTank ::InRange(float range) { if (range < m_minRange) - return false; + return FALSE; if (m_maxRange > 0 && range > m_maxRange) - return false; + return FALSE; - return true; + return TRUE; } void CFuncTank ::Think(void) @@ -490,7 +483,7 @@ void CFuncTank::TrackTarget(void) { TraceResult tr; edict_t *pPlayer = FIND_CLIENT_IN_PVS(edict()); - BOOL updateTime = false, lineOfSight; + BOOL updateTime = FALSE, lineOfSight; Vector angles, direction, targetPosition, barrelEnd; edict_t *pTarget = NULL; @@ -529,16 +522,16 @@ void CFuncTank::TrackTarget(void) UTIL_TraceLine(barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr); - lineOfSight = false; + lineOfSight = FALSE; // No line of sight, don't track if (tr.flFraction == 1.0 || tr.pHit == pTarget) { - lineOfSight = true; + lineOfSight = TRUE; CBaseEntity *pInstance = CBaseEntity::Instance(pTarget); if (InRange(range) && pInstance && pInstance->IsAlive()) { - updateTime = true; + updateTime = TRUE; m_sightOrigin = UpdateTargetPosition(pInstance); } } @@ -564,12 +557,12 @@ void CFuncTank::TrackTarget(void) if (angles.y > m_yawCenter + m_yawRange) { angles.y = m_yawCenter + m_yawRange; - updateTime = false; // Don't update if you saw the player, but out of range + updateTime = FALSE; // Don't update if you saw the player, but out of range } else if (angles.y < (m_yawCenter - m_yawRange)) { angles.y = (m_yawCenter - m_yawRange); - updateTime = false; // Don't update if you saw the player, but out of range + updateTime = FALSE; // Don't update if you saw the player, but out of range } if (updateTime) @@ -603,7 +596,7 @@ void CFuncTank::TrackTarget(void) if (CanFire() && ((fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (pev->spawnflags & SF_TANK_LINEOFSIGHT))) { - BOOL fire = false; + BOOL fire = FALSE; Vector forward; UTIL_MakeVectorsPrivate(pev->angles, forward, NULL, NULL); @@ -612,10 +605,10 @@ void CFuncTank::TrackTarget(void) float length = direction.Length(); UTIL_TraceLine(barrelEnd, barrelEnd + forward * length, dont_ignore_monsters, edict(), &tr); if (tr.pHit == pTarget) - fire = true; + fire = TRUE; } else - fire = true; + fire = TRUE; if (fire) { @@ -657,7 +650,7 @@ void CFuncTank::Fire(const Vector &barrelEnd, const Vector &forward, entvars_t * { if (m_iszSpriteSmoke) { - CSprite *pSprite = CSprite::SpriteCreate(STRING(m_iszSpriteSmoke), barrelEnd, true); + CSprite *pSprite = CSprite::SpriteCreate(STRING(m_iszSpriteSmoke), barrelEnd, TRUE); pSprite->AnimateAndDie(RANDOM_FLOAT(15.0, 20.0)); pSprite->SetTransparency(kRenderTransAlpha, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, 255, kRenderFxNone); pSprite->pev->velocity.z = RANDOM_FLOAT(40, 80); @@ -665,7 +658,7 @@ void CFuncTank::Fire(const Vector &barrelEnd, const Vector &forward, entvars_t * } if (m_iszSpriteFlash) { - CSprite *pSprite = CSprite::SpriteCreate(STRING(m_iszSpriteFlash), barrelEnd, true); + CSprite *pSprite = CSprite::SpriteCreate(STRING(m_iszSpriteFlash), barrelEnd, TRUE); pSprite->AnimateAndDie(60); pSprite->SetTransparency(kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation); pSprite->SetScale(m_spriteScale); @@ -804,7 +797,7 @@ void CFuncTankLaser::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "laserentity")) { pev->message = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CFuncTank::KeyValue(pkvd); @@ -921,7 +914,7 @@ void CFuncTankMortar::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "iMagnitude")) { pev->impulse = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CFuncTank::KeyValue(pkvd); @@ -942,7 +935,7 @@ void CFuncTankMortar::Fire(const Vector &barrelEnd, const Vector &forward, entva TankTrace(barrelEnd, forward, gTankSpread[m_spread], tr); - ExplosionCreate(tr.vecEndPos, pev->angles, edict(), pev->impulse, true); + ExplosionCreate(tr.vecEndPos, pev->angles, edict(), pev->impulse, TRUE); CFuncTank::Fire(barrelEnd, forward, pev); } diff --git a/src/game/server/hl/items.h b/src/game/server/hl/items.h index 82cc25589..2a2f7f729 100644 --- a/src/game/server/hl/items.h +++ b/src/game/server/hl/items.h @@ -22,7 +22,7 @@ class CItem : public CBaseEntity CBaseEntity *Respawn(void); void EXPORT ItemTouch(CBaseEntity *pOther); void EXPORT Materialize(void); - virtual BOOL MyTouch(CBasePlayer *pPlayer) { return false; }; + virtual BOOL MyTouch(CBasePlayer *pPlayer) { return FALSE; }; }; #endif // ITEMS_H diff --git a/src/game/server/hl/lights.cpp b/src/game/server/hl/lights.cpp index 050f14e1c..1edf4c46f 100644 --- a/src/game/server/hl/lights.cpp +++ b/src/game/server/hl/lights.cpp @@ -58,17 +58,17 @@ void CLight ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "style")) { m_iStyle = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "pitch")) { pev->angles.x = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "pattern")) { m_iszPattern = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else { @@ -163,7 +163,7 @@ void CEnvLight::KeyValue(KeyValueData *pkvd) g = pow(g / 114.0, 0.6) * 264; b = pow(b / 114.0, 0.6) * 264; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; _snprintf(szColor, sizeof(szColor), "%d", r ); CVAR_SET_STRING("sv_skycolor_r", szColor); _snprintf(szColor, sizeof(szColor), "%d", g ); diff --git a/src/game/server/hl/monsterevent.h b/src/game/server/hl/monsterevent.h index b9b637ddb..78d396fcb 100644 --- a/src/game/server/hl/monsterevent.h +++ b/src/game/server/hl/monsterevent.h @@ -21,17 +21,14 @@ typedef struct char *options; } MonsterEvent_t; -enum { - EVENT_SPECIFIC = 0, - EVENT_SCRIPTED = 1000, - EVENT_SHARED = 2000, - EVENT_CLIENT = 5000 -}; +#define EVENT_SPECIFIC 0 +#define EVENT_SCRIPTED 1000 +#define EVENT_SHARED 2000 +#define EVENT_CLIENT 5000 -enum { - MONSTER_EVENT_BODYDROP_LIGHT = 2001, - MONSTER_EVENT_BODYDROP_HEAVY = 2002, - MONSTER_EVENT_SWISHSOUND = 2010 -}; +#define MONSTER_EVENT_BODYDROP_LIGHT 2001 +#define MONSTER_EVENT_BODYDROP_HEAVY 2002 + +#define MONSTER_EVENT_SWISHSOUND 2010 #endif // MONSTEREVENT_H diff --git a/src/game/server/hl/monsters.cpp b/src/game/server/hl/monsters.cpp index da5a35c6f..c470bdb03 100644 --- a/src/game/server/hl/monsters.cpp +++ b/src/game/server/hl/monsters.cpp @@ -34,7 +34,7 @@ #include "soundent.h" #include "gamerules.h" -constexpr float MONSTER_CUT_CORNER_DIST = 8; // 8 means the monster's bounding box is contained without the box of the node in WC +#define MONSTER_CUT_CORNER_DIST 8 // 8 means the monster's bounding box is contained without the box of the node in WC Vector VecBModelOrigin(entvars_t *pevBModel); @@ -153,10 +153,10 @@ BOOL CBaseMonster ::FShouldEat(void) { if (m_flHungryTime > gpGlobals->time) { - return false; + return FALSE; } - return true; + return TRUE; } //========================================================= @@ -286,7 +286,7 @@ float CBaseMonster ::FLSoundVolume(CSound *pSound) //========================================================= BOOL CBaseMonster ::FValidateHintType(short sHint) { - return false; + return FALSE; } //========================================================= @@ -321,8 +321,8 @@ void CBaseMonster ::Look(int iDistance) // Find only monsters/clients in box, NOT limited to PVS //dbg("Entities in box"); - unsigned int count = UTIL_EntitiesInBox(pList, 100, pev->origin - delta, pev->origin + delta, FL_CLIENT | FL_MONSTER); - for (unsigned int i = 0; i < count; i++) + int count = UTIL_EntitiesInBox(pList, 100, pev->origin - delta, pev->origin + delta, FL_CLIENT | FL_MONSTER); + for (int i = 0; i < count; i++) { //dbg("Assign ent Pre"); if (!pList[i]) @@ -626,15 +626,15 @@ void CBaseMonster ::RouteNew(void) } //========================================================= -// FRouteClear - returns true is the Route is cleared out +// FRouteClear - returns TRUE is the Route is cleared out // ( invalid ) //========================================================= BOOL CBaseMonster ::FRouteClear(void) { if (m_Route[m_iRouteIndex].iType == 0 || m_movementGoal == MOVEGOAL_NONE) - return true; + return TRUE; - return false; + return FALSE; } //========================================================= @@ -650,7 +650,7 @@ BOOL CBaseMonster ::FRefreshRoute(void) RouteNew(); - returnCode = false; + returnCode = FALSE; switch (m_movementGoal) { @@ -674,7 +674,7 @@ BOOL CBaseMonster ::FRefreshRoute(void) i++; } } - returnCode = true; + returnCode = TRUE; break; case MOVEGOAL_ENEMY: @@ -812,8 +812,8 @@ int ShouldSimplify(int routeType) routeType &= ~bits_MF_IS_GOAL; if ((routeType == bits_MF_TO_PATHCORNER) || (routeType & bits_MF_DONT_SIMPLIFY)) - return false; - return true; + return FALSE; + return TRUE; } //========================================================= @@ -937,7 +937,7 @@ BOOL CBaseMonster ::FBecomeProne(void) } m_IdealMonsterState = MONSTERSTATE_PRONE; - return true; + return TRUE; } //========================================================= @@ -947,9 +947,9 @@ BOOL CBaseMonster ::CheckRangeAttack1(float flDot, float flDist) { if (flDist > 64 && flDist <= 784 && flDot >= 0.5) { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= @@ -959,9 +959,9 @@ BOOL CBaseMonster ::CheckRangeAttack2(float flDot, float flDist) { if (flDist > 64 && flDist <= 512 && flDot >= 0.5) { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= @@ -972,9 +972,9 @@ BOOL CBaseMonster ::CheckMeleeAttack1(float flDot, float flDist) // Decent fix to keep folks from kicking/punching hornets and snarks is to check the onground flag(sjb) if (flDist <= 64 && flDot >= 0.7 && m_hEnemy != NULL && FBitSet(m_hEnemy->pev->flags, FL_ONGROUND)) { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= @@ -984,9 +984,9 @@ BOOL CBaseMonster ::CheckMeleeAttack2(float flDot, float flDist) { if (flDist <= 64 && flDot >= 0.7) { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= @@ -1042,23 +1042,23 @@ BOOL CBaseMonster ::FCanCheckAttacks(void) { if (HasConditions(bits_COND_SEE_ENEMY) && !HasConditions(bits_COND_ENEMY_TOOFAR)) { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= // CheckEnemy - part of the Condition collection process, // gets and stores data and conditions pertaining to a monster's -// enemy. Returns true if Enemy LKP was updated. +// enemy. Returns TRUE if Enemy LKP was updated. //========================================================= int CBaseMonster ::CheckEnemy(CBaseEntity *pEnemy) { float flDistToEnemy; - int iUpdatedLKP; // set this to true if you update the EnemyLKP in this function. + int iUpdatedLKP; // set this to TRUE if you update the EnemyLKP in this function. - iUpdatedLKP = false; + iUpdatedLKP = FALSE; ClearConditions(bits_COND_ENEMY_FACING_ME); if (!FVisible(pEnemy)) @@ -1073,7 +1073,7 @@ int CBaseMonster ::CheckEnemy(CBaseEntity *pEnemy) { SetConditions(bits_COND_ENEMY_DEAD); ClearConditions(bits_COND_SEE_ENEMY | bits_COND_ENEMY_OCCLUDED); - return false; + return FALSE; } Vector vecEnemyPos = pEnemy->pev->origin; @@ -1097,7 +1097,7 @@ int CBaseMonster ::CheckEnemy(CBaseEntity *pEnemy) { CBaseMonster *pEnemyMonster; - iUpdatedLKP = true; + iUpdatedLKP = TRUE; m_vecEnemyLKP = pEnemy->pev->origin; pEnemyMonster = pEnemy->MyMonsterPointer(); @@ -1127,7 +1127,7 @@ int CBaseMonster ::CheckEnemy(CBaseEntity *pEnemy) // if the enemy is not occluded, and unseen, that means it is behind or beside the monster. // if the enemy is near enough the monster, we go ahead and let the monster know where the // enemy is. - iUpdatedLKP = true; + iUpdatedLKP = TRUE; m_vecEnemyLKP = pEnemy->pev->origin; } @@ -1204,7 +1204,7 @@ BOOL CBaseMonster ::PopEnemy() m_hEnemy = m_hOldEnemy[i]; m_vecEnemyLKP = m_vecOldEnemy[i]; // ALERT( at_console, "remembering\n"); - return true; + return TRUE; } else { @@ -1212,7 +1212,7 @@ BOOL CBaseMonster ::PopEnemy() } } } - return false; + return FALSE; } //========================================================= @@ -1281,7 +1281,7 @@ void CBaseMonster ::SetSequenceByName(char *szSequence) } //========================================================= -// CheckLocalMove - returns true if the caller can walk a +// CheckLocalMove - returns TRUE if the caller can walk a // straight line from its current origin to the given // location. If so, don't use the node graph! // @@ -1293,7 +1293,7 @@ void CBaseMonster ::SetSequenceByName(char *szSequence) // !!!PERFORMANCE - should we try to load balance this? // DON"T USE SETORIGIN! //========================================================= -constexpr float LOCAL_STEP_SIZE = 16; +#define LOCAL_STEP_SIZE 16 int CBaseMonster ::CheckLocalMove(const Vector &vecStart, const Vector &vecEnd, CBaseEntity *pTarget, float *pflDist) { Vector vecStartPos; // record monster's position before trying the move @@ -1329,7 +1329,7 @@ int CBaseMonster ::CheckLocalMove(const Vector &vecStart, const Vector &vecEnd, // since we've actually moved the monster during the check, undo the move. pev->origin = vecStartPos; - return false; + return FALSE; } */ // this loop takes single steps to the goal. @@ -1359,7 +1359,7 @@ int CBaseMonster ::CheckLocalMove(const Vector &vecStart, const Vector &vecEnd, { // If we're going toward an entity, and we're almost getting there, it's OK. // if ( pTarget && fabs( flDist - iStep ) < LOCAL_STEP_SIZE ) - // fReturn = true; + // fReturn = TRUE; // else iReturn = LOCALMOVE_INVALID; break; @@ -1552,7 +1552,7 @@ BOOL CBaseMonster ::BuildRoute(const Vector &vecGoal, int iMoveFlag, CBaseEntity if (iLocalMove == LOCALMOVE_VALID) { // monster can walk straight there! - return true; + return TRUE; } // try to triangulate around any obstacles. else if (iLocalMove != LOCALMOVE_INVALID_DONT_TRIANGULATE && FTriangulate(pev->origin, vecGoal, flDist, pTarget, &vecApex)) @@ -1576,7 +1576,7 @@ BOOL CBaseMonster ::BuildRoute(const Vector &vecGoal, int iMoveFlag, CBaseEntity */ RouteSimplify(pTarget); - return true; + return TRUE; } // last ditch, try nodes @@ -1585,11 +1585,11 @@ BOOL CBaseMonster ::BuildRoute(const Vector &vecGoal, int iMoveFlag, CBaseEntity // ALERT ( at_console, "Can get there on nodes\n" ); m_vecMoveGoal = vecGoal; RouteSimplify(pTarget); - return true; + return TRUE; } // b0rk - return false; + return FALSE; } //========================================================= @@ -1729,7 +1729,7 @@ BOOL CBaseMonster ::FTriangulate(const Vector &vecStart, const Vector &vecEnd, f *pApex = vecRight; } - return true; + return TRUE; } } if (CheckLocalMove(pev->origin, vecLeft, pTargetEnt, NULL) == LOCALMOVE_VALID) @@ -1741,7 +1741,7 @@ BOOL CBaseMonster ::FTriangulate(const Vector &vecStart, const Vector &vecEnd, f *pApex = vecLeft; } - return true; + return TRUE; } } @@ -1757,7 +1757,7 @@ BOOL CBaseMonster ::FTriangulate(const Vector &vecStart, const Vector &vecEnd, f //ALERT(at_aiconsole, "triangulate over\n"); } - return true; + return TRUE; } } #if 1 @@ -1771,7 +1771,7 @@ BOOL CBaseMonster ::FTriangulate(const Vector &vecStart, const Vector &vecEnd, f //ALERT(at_aiconsole, "triangulate under\n"); } - return true; + return TRUE; } } #endif @@ -1786,13 +1786,13 @@ BOOL CBaseMonster ::FTriangulate(const Vector &vecStart, const Vector &vecEnd, f } } - return false; + return FALSE; } //========================================================= // Move - take a single step towards the next ROUTE location //========================================================= -constexpr float DIST_TO_CHECK = 200; +#define DIST_TO_CHECK 200 void CBaseMonster ::Move(float flInterval) { @@ -1968,10 +1968,10 @@ BOOL CBaseMonster::ShouldAdvanceRoute(float flWaypointDist) if (flWaypointDist <= MONSTER_CUT_CORNER_DIST) { // ALERT( at_console, "cut %f\n", flWaypointDist ); - return true; + return TRUE; } - return false; + return FALSE; } void CBaseMonster::MoveExecute(CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval) @@ -2230,7 +2230,7 @@ int CBaseMonster::IRelationship(CBaseEntity *pTarget) BOOL CBaseMonster ::FindCover(Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist) { - unsigned int i; + int i; int iMyHullIndex; int iMyNode; int iThreatNode; @@ -2255,7 +2255,7 @@ BOOL CBaseMonster ::FindCover(Vector vecThreat, Vector vecViewOffset, float flMi if (!WorldGraph.m_fGraphPresent || !WorldGraph.m_fGraphPointersSet) { ALERT(at_aiconsole, "Graph not ready for findcover!\n"); - return false; + return FALSE; } iMyNode = WorldGraph.FindNearestNode(pev->origin, this); @@ -2265,13 +2265,13 @@ BOOL CBaseMonster ::FindCover(Vector vecThreat, Vector vecViewOffset, float flMi if (iMyNode == NO_NODE) { ALERT(at_aiconsole, "FindCover() - %s has no nearest node!\n", STRING(pev->classname)); - return false; + return FALSE; } if (iThreatNode == NO_NODE) { // ALERT ( at_aiconsole, "FindCover() - Threat has no nearest node!\n" ); iThreatNode = iMyNode; - // return false; + // return FALSE; } vecLookersOffset = vecThreat + vecViewOffset; // calculate location of enemy's eyes @@ -2315,13 +2315,13 @@ BOOL CBaseMonster ::FindCover(Vector vecThreat, Vector vecViewOffset, float flMi MESSAGE_END(); */ - return true; + return TRUE; } } } } } - return false; + return FALSE; } //========================================================= @@ -2335,7 +2335,7 @@ BOOL CBaseMonster ::FindCover(Vector vecThreat, Vector vecViewOffset, float flMi //========================================================= BOOL CBaseMonster ::BuildNearestRoute(Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist) { - unsigned int i; + int i; int iMyHullIndex; int iMyNode; float flDist; @@ -2359,7 +2359,7 @@ BOOL CBaseMonster ::BuildNearestRoute(Vector vecThreat, Vector vecViewOffset, fl if (!WorldGraph.m_fGraphPresent || !WorldGraph.m_fGraphPointersSet) { ALERT(at_aiconsole, "Graph not ready for BuildNearestRoute!\n"); - return false; + return FALSE; } iMyNode = WorldGraph.FindNearestNode(pev->origin, this); @@ -2368,7 +2368,7 @@ BOOL CBaseMonster ::BuildNearestRoute(Vector vecThreat, Vector vecViewOffset, fl if (iMyNode == NO_NODE) { ALERT(at_aiconsole, "BuildNearestRoute() - %s has no nearest node!\n", STRING(pev->classname)); - return false; + return FALSE; } vecLookersOffset = vecThreat + vecViewOffset; // calculate location of enemy's eyes @@ -2399,14 +2399,14 @@ BOOL CBaseMonster ::BuildNearestRoute(Vector vecThreat, Vector vecViewOffset, fl { flMaxDist = flDist; m_vecMoveGoal = node.m_vecOrigin; - return true; // UNDONE: keep looking for something closer! + return TRUE; // UNDONE: keep looking for something closer! } } } } } - return false; + return FALSE; } //========================================================= @@ -2656,12 +2656,12 @@ void CBaseMonster ::HandleAnimEvent(MonsterEvent_t *pEvent) case SCRIPT_EVENT_NOINTERRUPT: // Can't be interrupted from now on if (m_pCine) - m_pCine->AllowInterrupt(false); + m_pCine->AllowInterrupt(FALSE); break; case SCRIPT_EVENT_CANINTERRUPT: // OK to interrupt now if (m_pCine) - m_pCine->AllowInterrupt(true); + m_pCine->AllowInterrupt(TRUE); break; #if 0 @@ -2733,8 +2733,8 @@ Vector CBaseMonster ::GetGunPosition() // FGetNodeRoute - tries to build an entire node path from // the callers origin to the passed vector. If this is // possible, ROUTE_SIZE waypoints will be copied into the -// callers m_Route. true is returned if the operation -// succeeds (path is valid) or false if failed (no path +// callers m_Route. TRUE is returned if the operation +// succeeds (path is valid) or FALSE if failed (no path // exists ) //========================================================= BOOL CBaseMonster ::FGetNodeRoute(Vector vecDest) @@ -2752,13 +2752,13 @@ BOOL CBaseMonster ::FGetNodeRoute(Vector vecDest) { // no node nearest self // ALERT ( at_aiconsole, "FGetNodeRoute: No valid node near self!\n" ); - return false; + return FALSE; } else if (iDestNode == -1) { // no node nearest target // ALERT ( at_aiconsole, "FGetNodeRoute: No valid node near target!\n" ); - return false; + return FALSE; } // valid src and dest nodes were found, so it's safe to proceed with @@ -2770,16 +2770,16 @@ BOOL CBaseMonster ::FGetNodeRoute(Vector vecDest) { #if 1 ALERT(at_aiconsole, "No Path from %d to %d!\n", iSrcNode, iDestNode); - return false; + return FALSE; #else BOOL bRoutingSave = WorldGraph.m_fRoutingComplete; - WorldGraph.m_fRoutingComplete = false; + WorldGraph.m_fRoutingComplete = FALSE; iResult = WorldGraph.FindShortestPath(iPath, iSrcNode, iDestNode, iNodeHull, m_afCapability); WorldGraph.m_fRoutingComplete = bRoutingSave; if (!iResult) { ALERT(at_aiconsole, "No Path from %d to %d!\n", iSrcNode, iDestNode); - return false; + return FALSE; } else { @@ -2814,7 +2814,7 @@ BOOL CBaseMonster ::FGetNodeRoute(Vector vecDest) m_Route[iNumToCopy].iType |= bits_MF_IS_GOAL; } - return true; + return TRUE; } //========================================================= @@ -2822,7 +2822,7 @@ BOOL CBaseMonster ::FGetNodeRoute(Vector vecDest) //========================================================= int CBaseMonster ::FindHintNode(void) { - unsigned int i; + int i; TraceResult tr; if (!WorldGraph.m_fGraphPresent) @@ -2953,12 +2953,12 @@ void CBaseMonster ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "TriggerTarget")) { m_iszTriggerTarget = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "TriggerCondition")) { m_iTriggerCondition = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else { @@ -2971,7 +2971,7 @@ void CBaseMonster ::KeyValue(KeyValueData *pkvd) // if there is a condition, then checks to see if condition is // met. If yes, the monster's TriggerTarget is fired. // -// Returns true if the target is fired. +// Returns TRUE if the target is fired. //========================================================= BOOL CBaseMonster ::FCheckAITrigger(void) { @@ -2980,23 +2980,23 @@ BOOL CBaseMonster ::FCheckAITrigger(void) if (m_iTriggerCondition == AITRIGGER_NONE) { // no conditions, so this trigger is never fired. - return false; + return FALSE; } - fFireTarget = false; + fFireTarget = FALSE; switch (m_iTriggerCondition) { case AITRIGGER_SEEPLAYER_ANGRY_AT_PLAYER: if (m_hEnemy != NULL && m_hEnemy->IsPlayer() && HasConditions(bits_COND_SEE_ENEMY)) { - fFireTarget = true; + fFireTarget = TRUE; } break; case AITRIGGER_SEEPLAYER_UNCONDITIONAL: if (HasConditions(bits_COND_SEE_CLIENT)) { - fFireTarget = true; + fFireTarget = TRUE; } break; case AITRIGGER_SEEPLAYER_NOT_IN_COMBAT: @@ -3005,25 +3005,25 @@ BOOL CBaseMonster ::FCheckAITrigger(void) m_MonsterState != MONSTERSTATE_PRONE && m_MonsterState != MONSTERSTATE_SCRIPT) { - fFireTarget = true; + fFireTarget = TRUE; } break; case AITRIGGER_TAKEDAMAGE: if (m_afConditions & (bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE)) { - fFireTarget = true; + fFireTarget = TRUE; } break; case AITRIGGER_DEATH: if (pev->deadflag != DEAD_NO) { - fFireTarget = true; + fFireTarget = TRUE; } break; case AITRIGGER_HALFHEALTH: if (IsAlive() && pev->health <= (pev->max_health / 2)) { - fFireTarget = true; + fFireTarget = TRUE; } break; /* @@ -3038,19 +3038,19 @@ BOOL CBaseMonster ::FCheckAITrigger(void) case AITRIGGER_HEARWORLD: if (m_afConditions & bits_COND_HEAR_SOUND && m_afSoundTypes & bits_SOUND_WORLD) { - fFireTarget = true; + fFireTarget = TRUE; } break; case AITRIGGER_HEARPLAYER: if (m_afConditions & bits_COND_HEAR_SOUND && m_afSoundTypes & bits_SOUND_PLAYER) { - fFireTarget = true; + fFireTarget = TRUE; } break; case AITRIGGER_HEARCOMBAT: if (m_afConditions & bits_COND_HEAR_SOUND && m_afSoundTypes & bits_SOUND_COMBAT) { - fFireTarget = true; + fFireTarget = TRUE; } break; } @@ -3061,10 +3061,10 @@ BOOL CBaseMonster ::FCheckAITrigger(void) ALERT(at_aiconsole, "AI Trigger Fire Target\n"); FireTargets(STRING(m_iszTriggerTarget), this, this, USE_TOGGLE, 0); m_iTriggerCondition = AITRIGGER_NONE; - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= @@ -3079,26 +3079,26 @@ int CBaseMonster ::CanPlaySequence(BOOL fDisregardMonsterState, int interruptLev if (m_pCine || !IsAlive() || m_MonsterState == MONSTERSTATE_PRONE) { // monster is already running a scripted sequence or dead! - return false; + return FALSE; } if (fDisregardMonsterState) { // ok to go, no matter what the monster state. (scripted AI) - return true; + return TRUE; } if (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE) { // ok to go, but only in these states - return true; + return TRUE; } if (m_MonsterState == MONSTERSTATE_ALERT && interruptLevel >= SS_INTERRUPT_BY_NAME) - return true; + return TRUE; // unknown situation - return false; + return FALSE; } //========================================================= @@ -3106,10 +3106,8 @@ int CBaseMonster ::CanPlaySequence(BOOL fDisregardMonsterState, int interruptLev // directly to the left or right of the caller that will // conceal them from view of pSightEnt //========================================================= - - -constexpr unsigned int COVER_CHECKS = 5; // how many checks are made -constexpr unsigned int COVER_DELTA = 48; // distance between checks +#define COVER_CHECKS 5 // how many checks are made +#define COVER_DELTA 48 // distance between checks BOOL CBaseMonster ::FindLateralCover(const Vector &vecThreat, const Vector &vecViewOffset) { @@ -3141,7 +3139,7 @@ BOOL CBaseMonster ::FindLateralCover(const Vector &vecThreat, const Vector &vecV { if (MoveToLocation(ACT_RUN, 0, vecLeftTest)) { - return true; + return TRUE; } } } @@ -3155,13 +3153,13 @@ BOOL CBaseMonster ::FindLateralCover(const Vector &vecThreat, const Vector &vecV { if (MoveToLocation(ACT_RUN, 0, vecRightTest)) { - return true; + return TRUE; } } } } - return false; + return FALSE; } Vector CBaseMonster ::ShootAtEnemy(const Vector &shootOrigin) @@ -3187,10 +3185,10 @@ BOOL CBaseMonster ::FacingIdeal(void) { if (fabs(FlYawDiff()) <= 0.006) //!!!BUGBUG - no magic numbers!!! { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= @@ -3201,10 +3199,10 @@ BOOL CBaseMonster ::FCanActiveIdle(void) /* if ( m_MonsterState == MONSTERSTATE_IDLE && m_IdealMonsterState == MONSTERSTATE_IDLE && !IsMoving() ) { - return true; + return TRUE; } */ - return false; + return FALSE; } void CBaseMonster::PlaySentence(const char *pszSentence, float duration, float volume, float attenuation) @@ -3296,7 +3294,7 @@ BOOL CBaseMonster ::BBoxFlat(void) flLength2 = (vecPoint - tr.vecEndPos).Length(); if (flLength2 > flLength) { - return false; + return FALSE; } flLength = flLength2; @@ -3306,7 +3304,7 @@ BOOL CBaseMonster ::BBoxFlat(void) flLength2 = (vecPoint - tr.vecEndPos).Length(); if (flLength2 > flLength) { - return false; + return FALSE; } flLength = flLength2; @@ -3316,11 +3314,11 @@ BOOL CBaseMonster ::BBoxFlat(void) flLength2 = (vecPoint - tr.vecEndPos).Length(); if (flLength2 > flLength) { - return false; + return FALSE; } flLength = flLength2; - return true; + return TRUE; } //========================================================= @@ -3375,10 +3373,10 @@ BOOL CBaseMonster ::GetEnemy(void) if (m_hEnemy != NULL) { // monster has an enemy. - return true; + return TRUE; } - return false; // monster has no enemy + return FALSE; // monster has no enemy } //========================================================= @@ -3404,7 +3402,7 @@ CBaseEntity *CBaseMonster ::DropItem(char *pszItemName, const Vector &vecPos, co else { ALERT(at_console, "DropItem() - Didn't create!\n"); - return nullptr; + return FALSE; } } @@ -3412,7 +3410,7 @@ BOOL CBaseMonster ::ShouldFadeOnDeath(void) { // if flagged to fade out or I have an owner (I came from a monster spawner) if ((pev->spawnflags & SF_MONSTER_FADECORPSE) || !FNullEnt(pev->owner)) - return true; + return TRUE; - return false; + return FALSE; } diff --git a/src/game/server/hl/monsters.h b/src/game/server/hl/monsters.h index 3ac159945..f2e64b1d0 100644 --- a/src/game/server/hl/monsters.h +++ b/src/game/server/hl/monsters.h @@ -25,54 +25,45 @@ */ // CHECKLOCALMOVE result types - -enum localmove_e { - LOCALMOVE_INVALID = 0, // move is not possible - LOCALMOVE_INVALID_DONT_TRIANGULATE = 1, // move is not possible, don't try to triangulate - LOCALMOVE_VALID = 2 // move is possible -}; - -enum hitgroup_e { - // Hit Group standards - - HITGROUP_GENERIC = 0, - HITGROUP_HEAD = 1, - HITGROUP_CHEST = 2, - HITGROUP_STOMACH = 3, - HITGROUP_LEFTARM = 4, - HITGROUP_RIGHTARM = 5, - HITGROUP_LEFTLEG = 6, - HITGROUP_RIGHTLEG = 7 -}; - -enum monster_sf_e { - // Monster Spawnflags - SF_MONSTER_WAIT_TILL_SEEN = 1, // spawnflag that makes monsters wait until player can see them before attacking. - SF_MONSTER_GAG = 2, // no idle noises from this monster - SF_MONSTER_HITMONSTERCLIP = 4, -// 8 - SF_MONSTER_PRISONER = 16, // monster won't attack anyone, no one will attacke him. +#define LOCALMOVE_INVALID 0 // move is not possible +#define LOCALMOVE_INVALID_DONT_TRIANGULATE 1 // move is not possible, don't try to triangulate +#define LOCALMOVE_VALID 2 // move is possible + +// Hit Group standards +#define HITGROUP_GENERIC 0 +#define HITGROUP_HEAD 1 +#define HITGROUP_CHEST 2 +#define HITGROUP_STOMACH 3 +#define HITGROUP_LEFTARM 4 +#define HITGROUP_RIGHTARM 5 +#define HITGROUP_LEFTLEG 6 +#define HITGROUP_RIGHTLEG 7 + +// Monster Spawnflags +#define SF_MONSTER_WAIT_TILL_SEEN 1 // spawnflag that makes monsters wait until player can see them before attacking. +#define SF_MONSTER_GAG 2 // no idle noises from this monster +#define SF_MONSTER_HITMONSTERCLIP 4 +// 8 +#define SF_MONSTER_PRISONER 16 // monster won't attack anyone, no one will attacke him. // 32 // 64 - SF_MONSTER_WAIT_FOR_SCRIPT = 128, //spawnflag that makes monsters wait to check for attacking until the script is done or they've been attacked - SF_MONSTER_PREDISASTER = 256, //this is a predisaster scientist or barney. Influences how they speak. - SF_MONSTER_FADECORPSE = 512, // Fade out corpse after death - SF_MONSTER_FALL_TO_GROUND = 0x80000000, +#define SF_MONSTER_WAIT_FOR_SCRIPT 128 //spawnflag that makes monsters wait to check for attacking until the script is done or they've been attacked +#define SF_MONSTER_PREDISASTER 256 //this is a predisaster scientist or barney. Influences how they speak. +#define SF_MONSTER_FADECORPSE 512 // Fade out corpse after death +#define SF_MONSTER_FALL_TO_GROUND 0x80000000 // specialty spawnflags +#define SF_MONSTER_TURRET_AUTOACTIVATE 32 +#define SF_MONSTER_TURRET_STARTINACTIVE 64 +#define SF_MONSTER_WAIT_UNTIL_PROVOKED 64 // don't attack the player unless provoked - SF_MONSTER_TURRET_AUTOACTIVATE = 32, - SF_MONSTER_TURRET_STARTINACTIVE = 64, - SF_MONSTER_WAIT_UNTIL_PROVOKED = 64 // don't attack the player unless provoked -}; +// MoveToOrigin stuff +#define MOVE_START_TURN_DIST 64 // when this far away from moveGoal, start turning to face next goal +#define MOVE_STUCK_DIST 32 // if a monster can't step this far, it is stuck. -enum move_origin_e { - // MoveToOrigin stuff - MOVE_NORMAL = 0 ,// normal move in the direction monster is facing - MOVE_STRAFE = 1 ,// moves in direction specified, no matter which way monster is facing - MOVE_STUCK_DIST = 32, // if a monster can't step this far, it is stuck. - MOVE_START_TURN_DIST = 64 // when this far away from moveGoal, start turning to face next goal -}; +// MoveToOrigin stuff +#define MOVE_NORMAL 0 // normal move in the direction monster is facing +#define MOVE_STRAFE 1 // moves in direction specified, no matter which way monster is facing // spawn flags 256 and above are already taken by the engine extern void UTIL_MoveToOrigin(edict_t *pent, const Vector &vecGoal, float flDist, int iMoveType); @@ -80,9 +71,9 @@ extern void UTIL_MoveToOrigin(edict_t *pent, const Vector &vecGoal, float flDist Vector VecCheckToss(entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj = 1.0); Vector VecCheckThrow(entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj = 1.0); extern DLL_GLOBAL Vector g_vecAttackDir; -extern DLL_GLOBAL float g_flMeleeRange; -extern DLL_GLOBAL float g_flMediumRange; -extern DLL_GLOBAL float g_flLongRange; +extern DLL_GLOBAL CONSTANT float g_flMeleeRange; +extern DLL_GLOBAL CONSTANT float g_flMediumRange; +extern DLL_GLOBAL CONSTANT float g_flLongRange; extern void EjectBrass(const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype); extern void ExplodeModel(const Vector &vecOrigin, float speed, int model, int count); @@ -90,38 +81,31 @@ BOOL FBoxVisible(entvars_t *pevLooker, entvars_t *pevTarget); BOOL FBoxVisible(entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize = 0.0); // monster to monster relationship types - -enum monster_relationship_e { - R_AL = -2, // (ALLY) pals. Good alternative to R_NO when applicable. - R_FR = -1, // (FEAR)will run - R_NO = 0, // (NO RELATIONSHIP) disregard - R_DL = 1, // (DISLIKE) will attack - R_HT = 2, // (HATE)will attack this character instead of any visible DISLIKEd characters - R_NM = 3 // (NEMESIS) A monster Will ALWAYS attack its nemsis, no matter what -}; +#define R_AL -2 // (ALLY) pals. Good alternative to R_NO when applicable. +#define R_FR -1 // (FEAR)will run +#define R_NO 0 // (NO RELATIONSHIP) disregard +#define R_DL 1 // (DISLIKE) will attack +#define R_HT 2 // (HATE)will attack this character instead of any visible DISLIKEd characters +#define R_NM 3 // (NEMESIS) A monster Will ALWAYS attack its nemsis, no matter what // these bits represent the monster's memory +#define MEMORY_CLEAR 0 +#define bits_MEMORY_PROVOKED (1 << 0) // right now only used for houndeyes. +#define bits_MEMORY_INCOVER (1 << 1) // monster knows it is in a covered position. +#define bits_MEMORY_SUSPICIOUS (1 << 2) // Ally is suspicious of the player, and will move to provoked more easily +#define bits_MEMORY_PATH_FINISHED (1 << 3) // Finished monster path (just used by big momma for now) +#define bits_MEMORY_ON_PATH (1 << 4) // Moving on a path +#define bits_MEMORY_MOVE_FAILED (1 << 5) // Movement has already failed +#define bits_MEMORY_FLINCHED (1 << 6) // Has already flinched +#define bits_MEMORY_KILLED (1 << 7) // HACKHACK -- remember that I've already called my Killed() +#define bits_MEMORY_CUSTOM4 (1 << 28) // Monster-specific memory +#define bits_MEMORY_CUSTOM3 (1 << 29) // Monster-specific memory +#define bits_MEMORY_CUSTOM2 (1 << 30) // Monster-specific memory +#define bits_MEMORY_CUSTOM1 (1 << 31) // Monster-specific memory -enum monster_bits_e { - - MEMORY_CLEAR = 0, - bits_MEMORY_PROVOKED = (1 << 0), // right now only used for houndeyes. - bits_MEMORY_INCOVER = (1 << 1), // monster knows it is in a covered position. - bits_MEMORY_SUSPICIOUS = (1 << 2), // Ally is suspicious of the player, and will move to provoked more easily - bits_MEMORY_PATH_FINISHED = (1 << 3), // Finished monster path (just used by big momma for now) - bits_MEMORY_ON_PATH = (1 << 4), // Moving on a path - bits_MEMORY_MOVE_FAILED = (1 << 5), // Movement has already failed - bits_MEMORY_FLINCHED = (1 << 6), // Has already flinched - bits_MEMORY_KILLED = (1 << 7), // HACKHACK -- remember that I've already called my Killed() - bits_MEMORY_CUSTOM4 = (1 << 28), // Monster-specific memory - bits_MEMORY_CUSTOM3 = (1 << 29), // Monster-specific memory - bits_MEMORY_CUSTOM2 = (1 << 30), // Monster-specific memory - bits_MEMORY_CUSTOM1 = (1 << 31), // Monster-specific memory - -}; // trigger conditions for scripted AI // these MUST match the CHOICES interface in halflife.fgd for the base monster -enum aitrigger_e +enum { AITRIGGER_NONE = 0, AITRIGGER_SEEPLAYER_ANGRY_AT_PLAYER, diff --git a/src/game/server/hl/nodes.cpp b/src/game/server/hl/nodes.cpp index 2ada603d2..8c4eb71f6 100644 --- a/src/game/server/hl/nodes.cpp +++ b/src/game/server/hl/nodes.cpp @@ -26,11 +26,13 @@ #include "doors.h" #include "filesystem_shared.h" - +#define HULL_STEP_SIZE 16 // how far the test hull moves on each step +#define NODE_HEIGHT 8 // how high to lift nodes off the ground after we drop them all (make stair/ramp mapping easier) // to help eliminate node clutter by level designers, this is used to cap how many other nodes // any given node is allowed to 'see' in the first stage of graph creation "LinkVisibleNodes()". - +#define MAX_NODE_INITIAL_LINKS 128 +#define MAX_NODES 1024 extern DLL_GLOBAL edict_t *g_pBodyQueueHead; @@ -51,9 +53,9 @@ void CGraph ::InitGraph(void) // Make the graph unavailable // - m_fGraphPresent = false; - m_fGraphPointersSet = false; - m_fRoutingComplete = false; + m_fGraphPresent = FALSE; + m_fGraphPointersSet = FALSE; + m_fRoutingComplete = FALSE; // Free the link pool // @@ -115,10 +117,10 @@ int CGraph ::AllocNodes(void) if (!WorldGraph.m_pNodes) { ALERT(at_aiconsole, "**ERROR**\nCouldn't malloc %d nodes!\n", WorldGraph.m_cNodes); - return false; + return FALSE; } - return true; + return TRUE; } //========================================================= @@ -211,13 +213,13 @@ int CGraph ::HandleLinkEnt(int iNode, entvars_t *pevLinkEnt, int afCapMask, NODE if (!m_fGraphPresent || !m_fGraphPointersSet) { // protect us in the case that the node graph isn't available ALERT(at_aiconsole, "Graph not ready!\n"); - return false; + return FALSE; } if (FNullEnt(pevLinkEnt)) { ALERT(at_aiconsole, "dead path ent!\n"); - return true; + return TRUE; } pentWorld = NULL; @@ -232,17 +234,17 @@ int CGraph ::HandleLinkEnt(int iNode, entvars_t *pevLinkEnt, int afCapMask, NODE if ((afCapMask & bits_CAP_OPEN_DOORS)) { // let monster right through if he can open doors - return true; + return TRUE; } else { // monster should try for it if the door is open and looks as if it will stay that way if (pDoor->GetToggleState() == TS_AT_TOP && (pevLinkEnt->spawnflags & SF_DOOR_NO_AUTO_RETURN)) { - return true; + return TRUE; } - return false; + return FALSE; } } else @@ -251,35 +253,35 @@ int CGraph ::HandleLinkEnt(int iNode, entvars_t *pevLinkEnt, int afCapMask, NODE // monster should try for it if the door is open and looks as if it will stay that way if (pDoor->GetToggleState() == TS_AT_TOP && (pevLinkEnt->spawnflags & SF_DOOR_NO_AUTO_RETURN)) { - return true; + return TRUE; } if ((afCapMask & bits_CAP_OPEN_DOORS)) { if (!(pevLinkEnt->spawnflags & SF_DOOR_NOMONSTERS) || queryType == NODEGRAPH_STATIC) - return true; + return TRUE; } - return false; + return FALSE; } } // func_breakable else if (FClassnameIs(pevLinkEnt, "func_breakable") && queryType == NODEGRAPH_STATIC) { - return true; + return TRUE; } else { ALERT(at_aiconsole, "Unhandled Ent in Path %s\n", STRING(pevLinkEnt->classname)); - return false; + return FALSE; } - return false; + return FALSE; } #if 0 //========================================================= // FindNearestLink - finds the connection (line) nearest -// the given point. Returns false if fails, or true if it +// the given point. Returns FALSE if fails, or TRUE if it // has stuffed the index into the nearest link pool connection // into the passed int pointer, and a BOOL telling whether or // not the point is along the line into the passed BOOL pointer. @@ -304,7 +306,7 @@ int CGraph :: FindNearestLink ( const Vector &vecTestPoint, int *piNearestLink, TraceResult tr; iNearestLink = -1;// prepare for failure - fSuccess = false; + fSuccess = FALSE; flMinDist = 9999;// anything will be closer than this @@ -368,17 +370,17 @@ int CGraph :: FindNearestLink ( const Vector &vecTestPoint, int *piNearestLink, if ( DotProduct ( vec2Line, ( vec2TestPoint - vec2Spot1 ) ) > 0 ) {// point outside of line flDistToLine = ( vec2TestPoint - vec2Spot1 ).Length(); - fCurrentAlongLine = false; + fCurrentAlongLine = FALSE; } else if ( DotProduct ( vec2Line, ( vec2TestPoint - vec2Spot2 ) ) < 0 ) {// point outside of line flDistToLine = ( vec2TestPoint - vec2Spot2 ).Length(); - fCurrentAlongLine = false; + fCurrentAlongLine = FALSE; } else {// point inside line flDistToLine = fabs( DotProduct ( vec2TestPoint - vec2Spot2, vec2Normal ) ); - fCurrentAlongLine = true; + fCurrentAlongLine = TRUE; } if ( flDistToLine < flMinDist ) @@ -397,7 +399,7 @@ int CGraph :: FindNearestLink ( const Vector &vecTestPoint, int *piNearestLink, } - fSuccess = true;// we know there will be something to return. + fSuccess = TRUE;// we know there will be something to return. flMinDist = flDistToLine; iNearestLink = m_pNodes [ i ].m_iFirstLink + j; *piNearestLink = m_pNodes[ i ].m_iFirstLink + j; @@ -505,15 +507,15 @@ float CGraph::PathLength(int iStart, int iDest, int iHull, int afCapMask) // Parse the routing table at iCurrentNode for the next node on the shortest path to iDest int CGraph::NextNodeInRoute(int iCurrentNode, int iDest, int iHull, int iCap) { - unsigned int iNext = iCurrentNode; - unsigned int nCount = iDest + 1; + int iNext = iCurrentNode; + int nCount = iDest + 1; char *pRoute = m_pRouteInfo + m_pNodes[iCurrentNode].m_pNextBestNode[iHull][iCap]; // Until we decode the next best node // while (nCount > 0) { - unsigned char ch = *pRoute++; + char ch = *pRoute++; //ALERT(at_aiconsole, "C(%d)", ch); if (ch < 0) { @@ -538,7 +540,7 @@ int CGraph::NextNodeInRoute(int iCurrentNode, int iDest, int iHull, int iCap) // Repeat phrase // - if (nCount <= (unsigned char)(ch + 1)) + if (nCount <= ch + 1) { iNext = iCurrentNode + *pRoute; if (iNext >= m_cNodes) @@ -577,13 +579,13 @@ int CGraph ::FindShortestPath(int *piPath, int iStart, int iDest, int iHull, int if (!m_fGraphPresent || !m_fGraphPointersSet) { // protect us in the case that the node graph isn't available or built ALERT(at_aiconsole, "Graph not ready!\n"); - return false; + return FALSE; } - if (iStart < 0 || (unsigned int)iStart > m_cNodes) + if (iStart < 0 || iStart > m_cNodes) { // The start node is bad? ALERT(at_aiconsole, "Can't build a path, iStart is %d!\n", iStart); - return false; + return FALSE; } if (iStart == iDest) @@ -649,7 +651,7 @@ int CGraph ::FindShortestPath(int *piPath, int iStart, int iDest, int iHull, int // Mark all the nodes as unvisited. // - unsigned int i; + int i; for (i = 0; i < m_cNodes; i++) { m_pNodes[i].m_flClosestSoFar = -1.0; @@ -890,7 +892,7 @@ int CGraph ::FindNearestNode(const Vector &vecOrigin, int afNodeTypes) m_CheckedCounter++; if (m_CheckedCounter == 0) { - for (unsigned int i = 0; i < m_cNodes; i++) + for (int i = 0; i < m_cNodes; i++) { m_di[i].m_CheckedEvent = 0; } @@ -932,7 +934,7 @@ int CGraph ::FindNearestNode(const Vector &vecOrigin, int afNodeTypes) int halfY = (m_minY + m_maxY) / 2; int halfZ = (m_minZ + m_maxZ) / 2; - unsigned int j; + int j; for (i = halfX; i >= m_minX; i--) { @@ -1132,7 +1134,7 @@ void CGraph ::ShowNodeConnections(int iNode) Vector vecSpot; CNode *pNode; CNode *pLinkNode; - unsigned int i; + int i; if (!m_fGraphPresent || !m_fGraphPointersSet) { // protect us in the case that the node graph isn't available or built @@ -1188,9 +1190,9 @@ void CGraph ::ShowNodeConnections(int iNode) //========================================================= int CGraph ::LinkVisibleNodes(CLink *pLinkPool, CFile &file, int *piBadNode) { - unsigned int i, j, z; + int i, j, z; edict_t *pTraceEnt; - unsigned int cTotalLinks, cLinksThisNode, cMaxInitialLinks; + int cTotalLinks, cLinksThisNode, cMaxInitialLinks; TraceResult tr; // !!!BUGBUG - this function returns 0 if there is a problem in the middle of connecting the graph @@ -1202,7 +1204,7 @@ int CGraph ::LinkVisibleNodes(CLink *pLinkPool, CFile &file, int *piBadNode) if (m_cNodes <= 0) { ALERT(at_aiconsole, "No Nodes!\n"); - return false; + return FALSE; } // if the file pointer is bad, don't blow up, just don't write the @@ -1338,13 +1340,13 @@ int CGraph ::LinkVisibleNodes(CLink *pLinkPool, CFile &file, int *piBadNode) ALERT(at_aiconsole, "**LinkVisibleNodes:\nNode %d has NodeLinks > MAX_NODE_INITIAL_LINKS", i); file.Printf("** NODE %d HAS NodeLinks > MAX_NODE_INITIAL_LINKS **\n", i); *piBadNode = i; - return false; + return FALSE; } else if (cTotalLinks > MAX_NODE_INITIAL_LINKS * m_cNodes) { // this is paranoia ALERT(at_aiconsole, "**LinkVisibleNodes:\nTotalLinks > MAX_NODE_INITIAL_LINKS * NUMNODES"); *piBadNode = i; - return false; + return FALSE; } if (cLinksThisNode == 0) @@ -1383,7 +1385,7 @@ int CGraph ::LinkVisibleNodes(CLink *pLinkPool, CFile &file, int *piBadNode) //========================================================= int CGraph ::RejectInlineLinks(CLink *pLinkPool, CFile &file) { - unsigned int i, j, k; + int i, j, k; int cRejectedLinks; @@ -1425,7 +1427,7 @@ int CGraph ::RejectInlineLinks(CLink *pLinkPool, CFile &file) pLinkPool[pSrcNode->m_iFirstLink + j].m_flWeight = flDistToCheckNode; - fRestartLoop = false; + fRestartLoop = FALSE; for (k = 0; k < pSrcNode->m_cNumLinks && !fRestartLoop; k++) { if (k == j) @@ -1456,7 +1458,7 @@ int CGraph ::RejectInlineLinks(CLink *pLinkPool, CFile &file) cRejectedLinks++; // keeping track of how many links are cut, so that we can return that value. - fRestartLoop = true; + fRestartLoop = TRUE; } } } @@ -1548,13 +1550,13 @@ void CNodeEnt ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "hinttype")) { m_sHintType = (short)atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } if (FStrEq(pkvd->szKeyName, "activity")) { m_sHintActivity = (short)atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); @@ -1586,7 +1588,7 @@ void CNodeEnt ::Spawn(void) } WorldGraph.m_pNodes[WorldGraph.m_cNodes].m_vecOriginPeek = - WorldGraph.m_pNodes[WorldGraph.m_cNodes].m_vecOrigin = pev->origin; + WorldGraph.m_pNodes[WorldGraph.m_cNodes].m_vecOrigin = pev->origin; WorldGraph.m_pNodes[WorldGraph.m_cNodes].m_flHintYaw = pev->angles.y; WorldGraph.m_pNodes[WorldGraph.m_cNodes].m_sHintType = m_sHintType; WorldGraph.m_pNodes[WorldGraph.m_cNodes].m_sHintActivity = m_sHintActivity; @@ -1627,9 +1629,9 @@ extern BOOL gTouchDisabled; void CTestHull::CallBuildNodeGraph(void) { // TOUCH HACK -- Don't allow this entity to call anyone's "touch" function - gTouchDisabled = true; + gTouchDisabled = TRUE; BuildNodeGraph(); - gTouchDisabled = false; + gTouchDisabled = FALSE; // Undo TOUCH HACK } @@ -1653,11 +1655,11 @@ void CTestHull ::BuildNodeGraph(void) BOOL fSkipRemainingHulls; //if smallest hull can't fit, don't check any others BOOL fPairsValid; // are all links in the graph evenly paired? - unsigned int i, j, hull; + int i, j, hull; int iBadNode; // this is the node that caused graph generation to fail - unsigned int iPoolIndex = 0; + int iPoolIndex = 0; int cPoolLinks; // number of links in the pool. Vector vecDirToCheckNode; @@ -1810,7 +1812,7 @@ void CTestHull ::BuildNodeGraph(void) // if we can't fit a tiny hull through a connection, no other hulls with fit either, so we // should just fall out of the loop. Do so by setting the SkipRemainingHulls flag. - fSkipRemainingHulls = false; + fSkipRemainingHulls = FALSE; for (hull = 0; hull < MAX_NODE_HULLS; hull++) { if (fSkipRemainingHulls && (hull == NODE_HUMAN_HULL || hull == NODE_LARGE_HULL)) // skip the remaining walk hulls @@ -1871,7 +1873,7 @@ void CTestHull ::BuildNodeGraph(void) flDist = (vecSpot - pev->origin).Length2D(); - int fWalkFailed = false; + int fWalkFailed = FALSE; // in this loop we take tiny steps from the current node to the nodes that it links to, one at a time. // pev->angles.y = flYaw; @@ -1885,7 +1887,7 @@ void CTestHull ::BuildNodeGraph(void) if (!WALK_MOVE(ENT(pev), flYaw, stepSize, MoveMode)) { // can't take the next step - fWalkFailed = true; + fWalkFailed = TRUE; break; } } @@ -1894,7 +1896,7 @@ void CTestHull ::BuildNodeGraph(void) { // ALERT( at_console, "bogus walk\n"); // we thought we - fWalkFailed = true; + fWalkFailed = TRUE; } if (fWalkFailed) @@ -1908,12 +1910,12 @@ void CTestHull ::BuildNodeGraph(void) case NODE_SMALL_HULL: // if this hull can't fit, nothing can, so drop the connection file.Printf("NODE_SMALL_HULL step %i\n", step); pTempPool[pSrcNode->m_iFirstLink + j].m_afLinkInfo &= ~(bits_LINK_SMALL_HULL | bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL); - fSkipRemainingHulls = true; // don't bother checking larger hulls + fSkipRemainingHulls = TRUE; // don't bother checking larger hulls break; case NODE_HUMAN_HULL: file.Printf("NODE_HUMAN_HULL step %i\n", step); pTempPool[pSrcNode->m_iFirstLink + j].m_afLinkInfo &= ~(bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL); - fSkipRemainingHulls = true; // don't bother checking larger hulls + fSkipRemainingHulls = TRUE; // don't bother checking larger hulls break; case NODE_LARGE_HULL: file.Printf("NODE_LARGE_HULL step %i\n", step); @@ -1990,7 +1992,7 @@ void CTestHull ::BuildNodeGraph(void) // WorldGraph.BuildLinkLookups(); - fPairsValid = true; // assume that the connection pairs are all valid to start + fPairsValid = TRUE; // assume that the connection pairs are all valid to start file.Printf("\n\n-------------------------------------------------------------------------------\n"); file.Printf("Link Pairings:\n"); @@ -2006,7 +2008,7 @@ void CTestHull ::BuildNodeGraph(void) WorldGraph.HashSearch(WorldGraph.INodeLink(i, j), i, iLink); if (iLink < 0) { - fPairsValid = false; // unmatched link pair. + fPairsValid = FALSE; // unmatched link pair. file.Printf("WARNING: Node %3d does not connect back to Node %3d\n", WorldGraph.INodeLink(i, j), i); } } @@ -2051,9 +2053,9 @@ void CTestHull ::BuildNodeGraph(void) // We now have some graphing capabilities. // - WorldGraph.m_fGraphPresent = true; //graph is in memory. - WorldGraph.m_fGraphPointersSet = true; // since the graph was generated, the pointers are ready - WorldGraph.m_fRoutingComplete = false; // Optimal routes aren't computed, yet. + WorldGraph.m_fGraphPresent = TRUE; //graph is in memory. + WorldGraph.m_fGraphPointersSet = TRUE; // since the graph was generated, the pointers are ready + WorldGraph.m_fRoutingComplete = FALSE; // Optimal routes aren't computed, yet. // Compute and compress the routing information. // @@ -2260,20 +2262,9 @@ int CQueuePriority ::Remove(float &fPriority) return iReturn; } -int HEAP_LEFT_CHILD(int parent) { - return ((2 * parent) + 1); -} -int HEAP_RIGHT_CHILD(int parent) { - return ((2 * parent) + 2); -} - -int HEAP_PARENT(int child) { - return ((child-1) / 2); -} - -//#define HEAP_LEFT_CHILD(x) (2 * (x) + 1) -//#define HEAP_RIGHT_CHILD(x) (2 * (x) + 2) -//#define HEAP_PARENT(x) (((x)-1) / 2) +#define HEAP_LEFT_CHILD(x) (2 * (x) + 1) +#define HEAP_RIGHT_CHILD(x) (2 * (x) + 2) +#define HEAP_PARENT(x) (((x)-1) / 2) void CQueuePriority::Heap_SiftDown(int iSubRoot) { @@ -2444,7 +2435,7 @@ int CGraph ::FLoadGraph(const char *szMapName) return false; } m_CheckedCounter = 0; - for (unsigned int i = 0; i < m_cNodes; i++) + for (int i = 0; i < m_cNodes; i++) { m_di[i].m_CheckedEvent = 0; } @@ -2554,7 +2545,7 @@ if (0 == m_fGraphPresent || 0 == m_fGraphPointersSet) //========================================================= int CGraph ::FSetGraphPointers(void) { - unsigned int i; + int i; edict_t *pentLinkEnt; for (i = 0; i < m_cLinks; i++) @@ -2592,8 +2583,8 @@ int CGraph ::FSetGraphPointers(void) } // the pointers are now set. - m_fGraphPointersSet = true; - return true; + m_fGraphPointersSet = TRUE; + return TRUE; } //========================================================= @@ -2602,7 +2593,7 @@ int CGraph ::FSetGraphPointers(void) // ssociated .NOD file. If the NOD file is not present, or // is older than the BSP file, we rebuild it. // -// returns false if the .NOD file doesn't qualify and needs +// returns FALSE if the .NOD file doesn't qualify and needs // to be rebuilt. // // !!!BUGBUG - the file times we get back are 20 hours ahead! @@ -2639,9 +2630,17 @@ int CGraph ::CheckNODFile(const char *szMapName) return retValue; } +#define ENTRY_STATE_EMPTY -1 + +struct tagNodePair +{ + short iSrc; + short iDest; +}; + void CGraph::HashInsert(int iSrcNode, int iDestNode, int iKey) { - struct tagNodePair np {}; + struct tagNodePair np; np.iSrc = iSrcNode; np.iDest = iDestNode; @@ -2651,7 +2650,7 @@ void CGraph::HashInsert(int iSrcNode, int iDestNode, int iKey) dwHash = CRC32_FINAL(dwHash); int di = m_HashPrimes[dwHash & 15]; - unsigned int i = (dwHash >> 4) % m_nHashLinks; + int i = (dwHash >> 4) % m_nHashLinks; while (m_pHashLinks[i] != ENTRY_STATE_EMPTY) { i += di; @@ -2673,7 +2672,7 @@ void CGraph::HashSearch(int iSrcNode, int iDestNode, int &iKey) dwHash = CRC32_FINAL(dwHash); int di = m_HashPrimes[dwHash & 15]; - unsigned int i = (dwHash >> 4) % m_nHashLinks; + int i = (dwHash >> 4) % m_nHashLinks; while (m_pHashLinks[i] != ENTRY_STATE_EMPTY) { CLink &link = Link(m_pHashLinks[i]); @@ -2691,9 +2690,24 @@ void CGraph::HashSearch(int iSrcNode, int iDestNode, int &iKey) iKey = m_pHashLinks[i]; } +#define NUMBER_OF_PRIMES 177 + +int Primes[NUMBER_OF_PRIMES] = + {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, + 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, + 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, + 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, + 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, + 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, + 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, + 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, + 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, + 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, + 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 0}; + void CGraph::HashChoosePrimes(int TableSize) { - unsigned int LargestPrime = TableSize / 2; + int LargestPrime = TableSize / 2; if (LargestPrime > Primes[NUMBER_OF_PRIMES - 2]) { LargestPrime = Primes[NUMBER_OF_PRIMES - 2]; @@ -2755,14 +2769,14 @@ void CGraph::HashChoosePrimes(int TableSize) // Renumber nodes so that nodes that link together are together. // - +#define UNNUMBERED_NODE -1 void CGraph::SortNodes(void) { // We are using m_iPreviousNode to be the new node number. // After assigning new node numbers to everything, we move // things and patchup the links. // - unsigned int i, iNodeCnt = 0; + int i, iNodeCnt = 0; m_pNodes[0].m_iPreviousNode = iNodeCnt++; for (i = 1; i < m_cNodes; i++) { @@ -2773,7 +2787,7 @@ void CGraph::SortNodes(void) { // Run through all of this node's neighbors // - for (unsigned int j = 0; j < m_pNodes[i].m_cNumLinks; j++) + for (int j = 0; j < m_pNodes[i].m_cNumLinks; j++) { int iDestNode = INodeLink(i, j); if (m_pNodes[iDestNode].m_iPreviousNode == UNNUMBERED_NODE) @@ -2820,7 +2834,7 @@ void CGraph::SortNodes(void) void CGraph::BuildLinkLookups(void) { - unsigned int i; + int i; m_nHashLinks = 3 * m_cLinks / 2 + 3; HashChoosePrimes(m_nHashLinks); @@ -2871,7 +2885,7 @@ void CGraph::BuildRegionTables(void) // Calculate regions for all the nodes. // // - unsigned int i; + int i; for (i = 0; i < 3; i++) { m_RegionMin[i] = 999999999.0; // just a big number out there; @@ -2902,7 +2916,7 @@ void CGraph::BuildRegionTables(void) for (i = 0; i < 3; i++) { - unsigned int j; + int j; for (j = 0; j < NUM_RANGES; j++) { m_RangeStart[i][j] = 255; @@ -2933,7 +2947,7 @@ void CGraph::BuildRegionTables(void) break; } - for (unsigned int k = j + 1; k < m_cNodes; k++) + for (int k = j + 1; k < m_cNodes; k++) { int kNode = m_di[k].m_SortedBy[i]; int kCodeX = m_pNodes[kNode].m_Region[0]; @@ -3004,18 +3018,10 @@ void CGraph::BuildRegionTables(void) memset(m_Cache, 0, sizeof(m_Cache)); } - -//#define FROM_TO(x, y) ((x)*m_cNodes + (y)) - -int FROM_TO(unsigned int iFrom, unsigned int iTo, int nodes) { - return (iFrom * nodes) + iTo; -} - - void CGraph ::ComputeStaticRoutingTables(void) { int nRoutes = m_cNodes * m_cNodes; - +#define FROM_TO(x, y) ((x)*m_cNodes + (y)) short *Routes = new short[nRoutes]; int *pMyPath = new int[m_cNodes]; @@ -3043,20 +3049,20 @@ void CGraph ::ComputeStaticRoutingTables(void) // Initialize Routing table to uncalculated. // - unsigned int iFrom, iTo; + int iFrom, iTo; for (iFrom = 0; iFrom < m_cNodes; iFrom++) { - for (unsigned int iTo = 0; iTo < m_cNodes; iTo++) + for (int iTo = 0; iTo < m_cNodes; iTo++) { - Routes[FROM_TO(iFrom, iTo, m_cNodes)] = -1; + Routes[FROM_TO(iFrom, iTo)] = -1; } } for (iFrom = 0; iFrom < m_cNodes; iFrom++) { - for (iTo = m_cNodes - 1; iTo > 0; iTo--) + for (iTo = m_cNodes - 1; iTo >= 0; iTo--) { - if (Routes[FROM_TO(iFrom, iTo, m_cNodes)] != -1) + if (Routes[FROM_TO(iFrom, iTo)] != -1) continue; int cPathSize = FindShortestPath(pMyPath, iFrom, iTo, iHull, iCapMask); @@ -3072,7 +3078,7 @@ void CGraph ::ComputeStaticRoutingTables(void) for (int iNode1 = iNode + 1; iNode1 < cPathSize; iNode1++) { int iEnd = pMyPath[iNode1]; - Routes[FROM_TO(iStart, iEnd, m_cNodes)] = iNext; + Routes[FROM_TO(iStart, iEnd)] = iNext; } } #if 0 @@ -3088,34 +3094,34 @@ void CGraph ::ComputeStaticRoutingTables(void) for (int iNode1 = iNode-1; iNode1 >= 0; iNode1--) { int iEnd = pMyPath[iNode1]; - Routes[FROM_TO(iStart, iEnd, m_cNodes)] = iNext; + Routes[FROM_TO(iStart, iEnd)] = iNext; } } #endif } else { - Routes[FROM_TO(iFrom, iTo, m_cNodes)] = iFrom; - Routes[FROM_TO(iTo, iFrom, m_cNodes)] = iTo; + Routes[FROM_TO(iFrom, iTo)] = iFrom; + Routes[FROM_TO(iTo, iFrom)] = iTo; } } } for (iFrom = 0; iFrom < m_cNodes; iFrom++) { - for (unsigned int iTo = 0; iTo < m_cNodes; iTo++) + for (int iTo = 0; iTo < m_cNodes; iTo++) { - BestNextNodes[iTo] = Routes[FROM_TO(iFrom, iTo, m_cNodes)]; + BestNextNodes[iTo] = Routes[FROM_TO(iFrom, iTo)]; } // Compress this node's routing table. // - unsigned int iLastNode = 9999999; // just really big. + int iLastNode = 9999999; // just really big. int cSequence = 0; int cRepeats = 0; int CompressedSize = 0; char *p = pRoute; - unsigned int i; + int i; for (i = 0; i < m_cNodes; i++) { BOOL CanRepeat = ((BestNextNodes[i] == iLastNode) && cRepeats < 127); @@ -3259,7 +3265,7 @@ void CGraph ::ComputeStaticRoutingTables(void) // Go find a place to store this thing and point to it. // - unsigned int nRoute = p - pRoute; + int nRoute = p - pRoute; if (m_pRouteInfo) { for (i = 0; i < m_nRouteInfo - nRoute; i++) @@ -3289,7 +3295,6 @@ void CGraph ::ComputeStaticRoutingTables(void) { m_nRouteInfo = nRoute; m_pRouteInfo = (char *)calloc(sizeof(char), nRoute); - memcpy(m_pRouteInfo, pRoute, nRoute); m_pNodes[iFrom].m_pNextBestNode[iHull][iCap] = 0; nTotalCompressedSize += CompressedSize; @@ -3315,7 +3320,7 @@ void CGraph ::ComputeStaticRoutingTables(void) #if 0 TestRoutingTables(); #endif - m_fRoutingComplete = true; + m_fRoutingComplete = TRUE; } // Test those routing tables. Doesn't really work, yet. @@ -3326,9 +3331,9 @@ void CGraph ::TestRoutingTables(void) int *pMyPath2 = new int[m_cNodes]; if (pMyPath && pMyPath2) { - for (unsigned int iHull = 0; iHull < MAX_NODE_HULLS; iHull++) + for (int iHull = 0; iHull < MAX_NODE_HULLS; iHull++) { - for (unsigned int iCap = 0; iCap < 2; iCap++) + for (int iCap = 0; iCap < 2; iCap++) { int iCapMask; switch (iCap) @@ -3342,14 +3347,14 @@ void CGraph ::TestRoutingTables(void) break; } - for (unsigned int iFrom = 0; iFrom < m_cNodes; iFrom++) + for (int iFrom = 0; iFrom < m_cNodes; iFrom++) { - for (unsigned int iTo = 0; iTo < m_cNodes; iTo++) + for (int iTo = 0; iTo < m_cNodes; iTo++) { - m_fRoutingComplete = false; - unsigned int cPathSize1 = FindShortestPath(pMyPath, iFrom, iTo, iHull, iCapMask); - m_fRoutingComplete = true; - unsigned int cPathSize2 = FindShortestPath(pMyPath2, iFrom, iTo, iHull, iCapMask); + m_fRoutingComplete = FALSE; + int cPathSize1 = FindShortestPath(pMyPath, iFrom, iTo, iHull, iCapMask); + m_fRoutingComplete = TRUE; + int cPathSize2 = FindShortestPath(pMyPath2, iFrom, iTo, iHull, iCapMask); // Unless we can look at the entire path, we can verify that it's correct. // @@ -3360,22 +3365,22 @@ void CGraph ::TestRoutingTables(void) // #if 1 float flDistance1 = 0.0; - unsigned int i; + int i; for (i = 0; i < cPathSize1 - 1; i++) { // Find the link from pMyPath[i] to pMyPath[i+1] // if (pMyPath[i] == pMyPath[i + 1]) continue; - unsigned int iVisitNode, iLink; - BOOL bFound = false; + int iVisitNode, iLink; + BOOL bFound = FALSE; for (iLink = 0; iLink < m_pNodes[pMyPath[i]].m_cNumLinks; iLink++) { iVisitNode = INodeLink(pMyPath[i], iLink); if (iVisitNode == pMyPath[i + 1]) { flDistance1 += m_pLinkPool[m_pNodes[pMyPath[i]].m_iFirstLink + iLink].m_flWeight; - bFound = true; + bFound = TRUE; break; } } @@ -3393,14 +3398,14 @@ void CGraph ::TestRoutingTables(void) if (pMyPath2[i] == pMyPath2[i + 1]) continue; int iVisitNode; - BOOL bFound = false; - for (unsigned int iLink = 0; iLink < m_pNodes[pMyPath2[i]].m_cNumLinks; iLink++) + BOOL bFound = FALSE; + for (int iLink = 0; iLink < m_pNodes[pMyPath2[i]].m_cNumLinks; iLink++) { iVisitNode = INodeLink(pMyPath2[i], iLink); if (iVisitNode == pMyPath2[i + 1]) { flDistance2 += m_pLinkPool[m_pNodes[pMyPath2[i]].m_iFirstLink + iLink].m_flWeight; - bFound = true; + bFound = TRUE; break; } } @@ -3427,9 +3432,9 @@ void CGraph ::TestRoutingTables(void) ALERT(at_aiconsole, "%d ", pMyPath2[i]); } ALERT(at_aiconsole, "\n"); - m_fRoutingComplete = false; + m_fRoutingComplete = FALSE; cPathSize1 = FindShortestPath(pMyPath, iFrom, iTo, iHull, iCapMask); - m_fRoutingComplete = true; + m_fRoutingComplete = TRUE; cPathSize2 = FindShortestPath(pMyPath2, iFrom, iTo, iHull, iCapMask); goto EnoughSaid; } @@ -3461,7 +3466,7 @@ class CNodeViewer : public CBaseEntity int m_iBaseNode; int m_iDraw; - unsigned int m_nVisited; + int m_nVisited; int m_aFrom[128]; int m_aTo[128]; int m_iHull; @@ -3519,7 +3524,7 @@ void CNodeViewer::Spawn() if (WorldGraph.m_cNodes < 128) { - for (unsigned int i = 0; i < WorldGraph.m_cNodes; i++) + for (int i = 0; i < WorldGraph.m_cNodes; i++) { AddNode(i, WorldGraph.NextNodeInRoute(i, m_iBaseNode, m_iHull, 0)); } @@ -3553,7 +3558,7 @@ void CNodeViewer::Spawn() void CNodeViewer ::FindNodeConnections(int iNode) { AddNode(iNode, WorldGraph.NextNodeInRoute(iNode, m_iBaseNode, m_iHull, 0)); - for (unsigned int i = 0; i < WorldGraph.m_pNodes[iNode].m_cNumLinks; i++) + for (int i = 0; i < WorldGraph.m_pNodes[iNode].m_cNumLinks; i++) { CLink *pToLink = &WorldGraph.NodeLink(iNode, i); AddNode(pToLink->m_iDestNode, WorldGraph.NextNodeInRoute(pToLink->m_iDestNode, m_iBaseNode, m_iHull, 0)); @@ -3571,7 +3576,7 @@ void CNodeViewer::AddNode(int iFrom, int iTo) if (iFrom == iTo) return; - for (unsigned int i = 0; i < m_nVisited; i++) + for (int i = 0; i < m_nVisited; i++) { if (m_aFrom[i] == iFrom && m_aTo[i] == iTo) return; @@ -3588,7 +3593,7 @@ void CNodeViewer ::DrawThink(void) { /*pev->nextthink = gpGlobals->time; - for (unsigned int i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) { if (m_iDraw == m_nVisited) { diff --git a/src/game/server/hl/nodes.h b/src/game/server/hl/nodes.h index 7e0623ab1..a6233e60f 100644 --- a/src/game/server/hl/nodes.h +++ b/src/game/server/hl/nodes.h @@ -24,47 +24,15 @@ class CFile; //========================================================= // DEFINE //========================================================= +#define MAX_STACK_NODES 100 +#define NO_NODE -1 +#define MAX_NODE_HULLS 4 -constexpr unsigned int MAX_STACK_NODES = 100; -constexpr unsigned int MAX_NODE_HULLS = 4; -constexpr unsigned int CACHE_SIZE = 128; -constexpr unsigned int NUM_RANGES = 256; -constexpr unsigned MAX_NODE_INITIAL_LINKS = 128; -constexpr unsigned MAX_NODES = 1024; -constexpr float HULL_STEP_SIZE = 16; // how far the test hull moves on each step -constexpr float NODE_HEIGHT = 8; // how high to lift nodes off the ground after we drop them all (make stair/ramp mapping easier) -constexpr unsigned int NUMBER_OF_PRIMES = 177; -constexpr int NO_NODE = -1; -constexpr int UNNUMBERED_NODE = -1; -constexpr int ENTRY_STATE_EMPTY = -1; - -constexpr unsigned int Primes[NUMBER_OF_PRIMES] = -{ 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, - 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, - 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, - 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, - 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, - 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, - 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, - 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, - 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, - 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, - 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 0 }; - -struct tagNodePair -{ - short iSrc; - short iDest; -}; - -enum bits_node_type_e { +#define bits_NODE_LAND (1 << 0) // Land node, so nudge if necessary. +#define bits_NODE_AIR (1 << 1) // Air node, don't nudge. +#define bits_NODE_WATER (1 << 2) // Water node, don't nudge. +#define bits_NODE_GROUP_REALM (bits_NODE_LAND | bits_NODE_AIR | bits_NODE_WATER) - bits_NODE_LAND = (1 << 0), // Land node, so nudge if necessary. - bits_NODE_AIR = (1 << 1), // Air node, don't nudge. - bits_NODE_WATER = (1 << 2), // Water node, don't nudge. - bits_NODE_GROUP_REALM = (bits_NODE_LAND | bits_NODE_AIR | bits_NODE_WATER) - -}; //========================================================= // Instance of a node. //========================================================= @@ -76,8 +44,8 @@ class CNode byte m_Region[3]; // Which of 256 regions do each of the coordinate belong? int m_afNodeInfo; // bits that tell us more about this location - unsigned int m_cNumLinks; // how many links this node has - unsigned int m_iFirstLink; // index of this node's first link in the link pool. + int m_cNumLinks; // how many links this node has + int m_iFirstLink; // index of this node's first link in the link pool. // Where to start looking in the compressed routing table (offset into m_pRouteInfo). // (4 hull sizes -- smallest to largest + fly/swim), and secondly, door capability. @@ -99,23 +67,17 @@ class CNode //========================================================= // CLink - A link between 2 nodes //========================================================= +#define bits_LINK_SMALL_HULL (1 << 0) // headcrab box can fit through this connection +#define bits_LINK_HUMAN_HULL (1 << 1) // player box can fit through this connection +#define bits_LINK_LARGE_HULL (1 << 2) // big box can fit through this connection +#define bits_LINK_FLY_HULL (1 << 3) // a flying big box can fit through this connection +#define bits_LINK_DISABLED (1 << 4) // link is not valid when the set -enum bits_clink_e { - bits_LINK_SMALL_HULL = (1 << 0), // headcrab box can fit through this connection - bits_LINK_HUMAN_HULL = (1 << 1), // player box can fit through this connection - bits_LINK_LARGE_HULL = (1 << 2), // big box can fit through this connection - bits_LINK_FLY_HULL = (1 << 3), // a flying big box can fit through this connection - bits_LINK_DISABLED = (1 << 4) // link is not valid when the set -}; - -enum node_hull_e { - - NODE_SMALL_HULL = 0, - NODE_HUMAN_HULL = 1, - NODE_LARGE_HULL = 2, - NODE_FLY_HULL = 3 +#define NODE_SMALL_HULL 0 +#define NODE_HUMAN_HULL 1 +#define NODE_LARGE_HULL 2 +#define NODE_FLY_HULL 3 -}; class CLink { public: @@ -159,9 +121,9 @@ class CGraph CLink *m_pLinkPool; // big list of all node connections char *m_pRouteInfo; // compressed routing information the nodes use. - unsigned int m_cNodes; // total number of nodes - unsigned int m_cLinks; // total number of links - unsigned int m_nRouteInfo; // size of m_pRouteInfo in bytes. + int m_cNodes; // total number of nodes + int m_cLinks; // total number of links + int m_nRouteInfo; // size of m_pRouteInfo in bytes. // Tables for making nearest node lookup faster. SortedBy provided nodes in a // order of a particular coordinate. Instead of doing a binary search, RangeStart @@ -172,10 +134,11 @@ class CGraph // search each range. After the search is exhausted, we know we have the closest // node. // - +#define CACHE_SIZE 128 +#define NUM_RANGES 256 DIST_INFO *m_di; // This is m_cNodes long, but the entries don't correspond to CNode entries. - unsigned int m_RangeStart[3][NUM_RANGES]; - unsigned int m_RangeEnd[3][NUM_RANGES]; + int m_RangeStart[3][NUM_RANGES]; + int m_RangeEnd[3][NUM_RANGES]; float m_flShortest; int m_iNearest; int m_minX, m_minY, m_minZ, m_maxX, m_maxY, m_maxZ; @@ -186,12 +149,12 @@ class CGraph int m_HashPrimes[16]; short *m_pHashLinks; - unsigned int m_nHashLinks; + int m_nHashLinks; // kinda sleazy. In order to allow variety in active idles for monster groups in a room with more than one node, // we keep track of the last node we searched from and store it here. Subsequent searches by other monsters will pick // up where the last search stopped. - unsigned int m_iLastActiveIdleSearch; + int m_iLastActiveIdleSearch; // another such system used to track the search for cover nodes, helps greatly with two monsters trying to get to the same node. int m_iLastCoverSearch; @@ -384,7 +347,7 @@ class CQueuePriority // hints - these MUST coincide with the HINTS listed under // info_node in the FGD file! //========================================================= -enum hint_node_e +enum { HINT_NONE = 0, HINT_WORLD_DOOR, diff --git a/src/game/server/hl/pathcorner.cpp b/src/game/server/hl/pathcorner.cpp index becd13323..cf9ea94af 100644 --- a/src/game/server/hl/pathcorner.cpp +++ b/src/game/server/hl/pathcorner.cpp @@ -56,7 +56,7 @@ void CPathCorner ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "wait")) { m_flWait = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CPointEntity::KeyValue(pkvd); @@ -135,7 +135,7 @@ void CPathTrack ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "altpath")) { m_altName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CPointEntity::KeyValue(pkvd); diff --git a/src/game/server/hl/plane.cpp b/src/game/server/hl/plane.cpp index dc8f28e75..601ceb08a 100644 --- a/src/game/server/hl/plane.cpp +++ b/src/game/server/hl/plane.cpp @@ -21,7 +21,7 @@ //========================================================= CPlane ::CPlane(void) { - m_fInitialized = false; + m_fInitialized = FALSE; } //========================================================= @@ -32,7 +32,7 @@ void CPlane ::InitializePlane(const Vector &vecNormal, const Vector &vecPoint) { m_vecNormal = vecNormal; m_flDist = DotProduct(m_vecNormal, vecPoint); - m_fInitialized = true; + m_fInitialized = TRUE; } //========================================================= @@ -45,15 +45,15 @@ BOOL CPlane ::PointInFront(const Vector &vecPoint) if (!m_fInitialized) { - return false; + return FALSE; } flFace = DotProduct(m_vecNormal, vecPoint) - m_flDist; if (flFace >= 0) { - return true; + return TRUE; } - return false; + return FALSE; } diff --git a/src/game/server/hl/plats.cpp b/src/game/server/hl/plats.cpp index 734e2c3d1..51b0a374a 100644 --- a/src/game/server/hl/plats.cpp +++ b/src/game/server/hl/plats.cpp @@ -28,10 +28,8 @@ static void PlatSpawnInsideTrigger(entvars_t *pevPlatform); -enum sf_plat_e { - SF_PLAT_TOGGLE = 0x0001, - SF_PLAT_ADJUST = 0x0002 //MAR2010_10 - Thothie - adjust platform for stuck bugs when reach top -}; +#define SF_PLAT_TOGGLE 0x0001 +#define SF_PLAT_ADJUST 0x0002 //MAR2010_10 - Thothie - adjust platform for stuck bugs when reach top class CBasePlatTrain : public CBaseToggle { @@ -41,9 +39,9 @@ class CBasePlatTrain : public CBaseToggle void Precache(void); // This is done to fix spawn flag collisions between this class and a derived class - virtual BOOL IsTogglePlat(void) { return (pev->spawnflags & SF_PLAT_TOGGLE) ? true : false; } + virtual BOOL IsTogglePlat(void) { return (pev->spawnflags & SF_PLAT_TOGGLE) ? TRUE : FALSE; } - virtual BOOL IsStuckAdjust(void) { return (pev->spawnflags & SF_PLAT_ADJUST) ? true : false; } //MAR2010_10 - Thothie - adjust platform for stuck bugs when reach top + virtual BOOL IsStuckAdjust(void) { return (pev->spawnflags & SF_PLAT_ADJUST) ? TRUE : FALSE; } //MAR2010_10 - Thothie - adjust platform for stuck bugs when reach top virtual int Save(CSave &save); virtual int Restore(CRestore &restore); @@ -68,37 +66,37 @@ void CBasePlatTrain ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "lip")) { m_flLip = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "wait")) { m_flWait = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "height")) { m_flHeight = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "rotation")) { m_vecFinalAngle.x = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "movesnd")) { m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "stopsnd")) { m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "volume")) { m_volume = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseToggle::KeyValue(pkvd); @@ -398,7 +396,7 @@ void CFuncPlat ::PlatUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE if (IsTogglePlat()) { // Top is off, bottom is on - BOOL on = (m_toggle_state == TS_AT_BOTTOM) ? true : false; + BOOL on = (m_toggle_state == TS_AT_BOTTOM) ? TRUE : FALSE; if (!ShouldToggle(useType, on)) return; @@ -651,7 +649,7 @@ void CFuncTrain ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "sounds")) { m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBasePlatTrain::KeyValue(pkvd); @@ -793,7 +791,7 @@ void CFuncTrain ::Activate(void) // Not yet active, so teleport to first target if (!m_activated) { - m_activated = true; + m_activated = TRUE; entvars_t *pevTarg = VARS(FIND_ENTITY_BY_TARGETNAME(NULL, STRING(pev->target))); pev->target = pevTarg->target; @@ -845,7 +843,7 @@ void CFuncTrain ::Spawn(void) UTIL_SetSize(pev, pev->mins, pev->maxs); UTIL_SetOrigin(pev, pev->origin); - m_activated = false; + m_activated = FALSE; if (m_volume == 0) m_volume = 0.85; @@ -934,33 +932,33 @@ void CFuncTrackTrain ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "wheels")) { m_length = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "height")) { m_height = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "startspeed")) { m_startSpeed = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "sounds")) { m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "volume")) { m_flVolume = (float)(atoi(pkvd->szValue)); m_flVolume *= 0.1; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "bank")) { m_flBank = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); @@ -1241,7 +1239,7 @@ void CFuncTrackTrain ::Next(void) } } SetThink(&CFuncTrackTrain::Next); - NextThink(pev->ltime + time, true); + NextThink(pev->ltime + time, TRUE); } else // end of path, stop { @@ -1262,7 +1260,7 @@ void CFuncTrackTrain ::Next(void) time = distance / m_oldSpeed; pev->velocity = pev->velocity * (m_oldSpeed / distance); SetThink(&CFuncTrackTrain::DeadEnd); - NextThink(pev->ltime + time, false); + NextThink(pev->ltime + time, FALSE); } else { @@ -1288,7 +1286,7 @@ void CFuncTrackTrain::DeadEnd(void) { do { - pNext = pTrack->ValidPath(pTrack->GetPrevious(), true); + pNext = pTrack->ValidPath(pTrack->GetPrevious(), TRUE); if (pNext) pTrack = pNext; } while (pNext); @@ -1297,7 +1295,7 @@ void CFuncTrackTrain::DeadEnd(void) { do { - pNext = pTrack->ValidPath(pTrack->GetNext(), true); + pNext = pTrack->ValidPath(pTrack->GetNext(), TRUE); if (pNext) pTrack = pNext; } while (pNext); @@ -1329,7 +1327,7 @@ BOOL CFuncTrackTrain ::OnControls(entvars_t *pevTest) Vector offset = pevTest->origin - pev->origin; if (pev->spawnflags & SF_TRACKTRAIN_NOCONTROL) - return false; + return FALSE; // Transform offset into local coordinates UTIL_MakeVectors(pev->angles); @@ -1340,9 +1338,9 @@ BOOL CFuncTrackTrain ::OnControls(entvars_t *pevTest) if (local.x >= m_controlMins.x && local.y >= m_controlMins.y && local.z >= m_controlMins.z && local.x <= m_controlMaxs.x && local.y <= m_controlMaxs.y && local.z <= m_controlMaxs.z) - return true; + return TRUE; - return false; + return FALSE; } void CFuncTrackTrain ::Find(void) @@ -1374,7 +1372,7 @@ void CFuncTrackTrain ::Find(void) if (pev->spawnflags & SF_TRACKTRAIN_NOPITCH) pev->angles.x = 0; UTIL_SetOrigin(pev, nextPos); - NextThink(pev->ltime + 0.1, false); + NextThink(pev->ltime + 0.1, FALSE); SetThink(&CFuncTrackTrain::Next); pev->speed = m_startSpeed; @@ -1423,14 +1421,14 @@ void CFuncTrackTrain ::NearestPath(void) if (pev->speed != 0) { - NextThink(pev->ltime + 0.1, false); + NextThink(pev->ltime + 0.1, FALSE); SetThink(&CFuncTrackTrain::Next); } } void CFuncTrackTrain::OverrideReset(void) { - NextThink(pev->ltime + 0.1, false); + NextThink(pev->ltime + 0.1, FALSE); SetThink(&CFuncTrackTrain::NearestPath); } @@ -1488,7 +1486,7 @@ void CFuncTrackTrain ::Spawn(void) m_controlMaxs.z += 72; // start trains on the next frame, to make sure their targets have had // a chance to spawn/activate - NextThink(pev->ltime + 0.1, false); + NextThink(pev->ltime + 0.1, FALSE); SetThink(&CFuncTrackTrain::Find); Precache(); } @@ -1623,7 +1621,7 @@ class CFuncTrackChange : public CFuncPlatRot virtual void HitTop(void); void Touch(CBaseEntity *pOther); virtual void UpdateAutoTargets(int toggleState); - virtual BOOL IsTogglePlat(void) { return true; } + virtual BOOL IsTogglePlat(void) { return TRUE; } void DisableUse(void) { m_use = 0; } void EnableUse(void) { m_use = 1; } @@ -1715,17 +1713,17 @@ void CFuncTrackChange ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "train")) { m_trainName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "toptrack")) { m_trackTopName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "bottomtrack")) { m_trackBottomName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else { @@ -1812,7 +1810,7 @@ void CFuncTrackChange ::UpdateTrain(Vector &dest) m_train->pev->velocity = pev->velocity; m_train->pev->avelocity = pev->avelocity; - m_train->NextThink(m_train->pev->ltime + time, false); + m_train->NextThink(m_train->pev->ltime + time, FALSE); // Attempt at getting the train to rotate properly around the origin of the trackchange if (time <= 0) @@ -2124,7 +2122,7 @@ void CGunTarget::Spawn(void) pev->takedamage = DAMAGE_NO; pev->flags |= FL_MONSTER; - m_on = false; + m_on = FALSE; pev->max_health = pev->health; if (pev->spawnflags & FGUNTARGET_START_ON) diff --git a/src/game/server/hl/saverestore.h b/src/game/server/hl/saverestore.h index f5593f966..644bb44b4 100644 --- a/src/game/server/hl/saverestore.h +++ b/src/game/server/hl/saverestore.h @@ -65,7 +65,7 @@ class CSave : public CSaveRestoreBuffer int WriteFields(const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount); private: - int DataEmpty(const char *pdata, unsigned int size); + int DataEmpty(const char *pdata, int size); void BufferField(const char *pname, int size, const char *pdata); void BufferString(char *pdata, int len); void BufferData(const char *pdata, int size); @@ -85,7 +85,7 @@ class CRestore : public CSaveRestoreBuffer CRestore(SAVERESTOREDATA *pdata) : CSaveRestoreBuffer(pdata) { m_global = 0; - m_precache = true; + m_precache = TRUE; } int ReadEntVars(const char *pname, entvars_t *pev); // entvars_t diff --git a/src/game/server/hl/schedule.cpp b/src/game/server/hl/schedule.cpp index 9434edb75..317dfe4f4 100644 --- a/src/game/server/hl/schedule.cpp +++ b/src/game/server/hl/schedule.cpp @@ -27,17 +27,17 @@ extern CGraph WorldGraph; //========================================================= -// FHaveSchedule - Returns true if monster's m_pSchedule +// FHaveSchedule - Returns TRUE if monster's m_pSchedule // is anything other than NULL. //========================================================= BOOL CBaseMonster ::FHaveSchedule(void) { if (m_pSchedule == NULL) { - return false; + return FALSE; } - return true; + return TRUE; } //========================================================= @@ -52,7 +52,7 @@ void CBaseMonster ::ClearSchedule(void) } //========================================================= -// FScheduleDone - Returns true if the caller is on the +// FScheduleDone - Returns TRUE if the caller is on the // last task in the schedule //========================================================= BOOL CBaseMonster ::FScheduleDone(void) @@ -61,10 +61,10 @@ BOOL CBaseMonster ::FScheduleDone(void) if (m_iScheduleIndex == m_pSchedule->cTasks) { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= @@ -164,7 +164,7 @@ int CBaseMonster ::IScheduleFlags(void) } //========================================================= -// FScheduleValid - returns true as long as the current +// FScheduleValid - returns TRUE as long as the current // schedule is still the proper schedule to be executing, // taking into account all conditions //========================================================= @@ -173,7 +173,7 @@ BOOL CBaseMonster ::FScheduleValid(void) if (m_pSchedule == NULL) { // schedule is empty, and therefore not valid. - return false; + return FALSE; } if (HasConditions(m_pSchedule->iInterruptMask | bits_COND_SCHEDULE_DONE | bits_COND_TASK_FAILED)) @@ -191,10 +191,10 @@ BOOL CBaseMonster ::FScheduleValid(void) #endif // DEBUG // some condition has interrupted the schedule, or the schedule is done - return false; + return FALSE; } - return true; + return TRUE; } //========================================================= @@ -524,7 +524,7 @@ void CBaseMonster ::RunTask(Task_t *pTask) if (m_pCine->m_iDelay <= 0 && gpGlobals->time >= m_pCine->m_startTime) { TaskComplete(); - m_pCine->StartSequence((CBaseMonster *)this, m_pCine->m_iszPlay, true); + m_pCine->StartSequence((CBaseMonster *)this, m_pCine->m_iszPlay, TRUE); if (m_fSequenceFinished) ClearSchedule(); pev->framerate = 1.0; @@ -1254,7 +1254,7 @@ void CBaseMonster ::StartTask(Task_t *pTask) { if (m_pCine->m_iszIdle) { - m_pCine->StartSequence((CBaseMonster *)this, m_pCine->m_iszIdle, false); + m_pCine->StartSequence((CBaseMonster *)this, m_pCine->m_iszIdle, FALSE); if (FStrEq(STRING(m_pCine->m_iszIdle), STRING(m_pCine->m_iszPlay))) { pev->framerate = 0; diff --git a/src/game/server/hl/schedule.h b/src/game/server/hl/schedule.h index 211b5050e..b1d6dd66c 100644 --- a/src/game/server/hl/schedule.h +++ b/src/game/server/hl/schedule.h @@ -1,294 +1,290 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -//========================================================= -// Scheduling -//========================================================= - -#ifndef SCHEDULE_H -#define SCHEDULE_H +/*** +* +* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* This source code contains proprietary and confidential information of +* Valve LLC and its suppliers. Access to this code is restricted to +* persons who have executed a written SDK license with Valve. Any access, +* use or distribution of this code by or to any unlicensed person is illegal. +* +****/ +//========================================================= +// Scheduling +//========================================================= - - -enum taskstatus_e { - TASKSTATUS_NEW = 0, // Just started - TASKSTATUS_RUNNING = 1, // Running task & movement - TASKSTATUS_RUNNING_MOVEMENT = 2, // Just running movement - TASKSTATUS_RUNNING_TASK = 3, // Just running task - TASKSTATUS_COMPLETE = 4 // Completed, get next task -}; - -//========================================================= -// These are the schedule types -//========================================================= -typedef enum -{ - SCHED_NONE = 0, - SCHED_IDLE_STAND, - SCHED_IDLE_WALK, - SCHED_WAKE_ANGRY, - SCHED_WAKE_CALLED, - SCHED_ALERT_FACE, - SCHED_ALERT_SMALL_FLINCH, - SCHED_ALERT_BIG_FLINCH, - SCHED_ALERT_STAND, - SCHED_INVESTIGATE_SOUND, - SCHED_COMBAT_FACE, - SCHED_COMBAT_STAND, - SCHED_CHASE_ENEMY, - SCHED_CHASE_ENEMY_FAILED, - SCHED_VICTORY_DANCE, - SCHED_TARGET_FACE, - SCHED_TARGET_CHASE, - SCHED_SMALL_FLINCH, - SCHED_TAKE_COVER_FROM_ENEMY, - SCHED_TAKE_COVER_FROM_BEST_SOUND, - SCHED_TAKE_COVER_FROM_ORIGIN, - SCHED_COWER, // usually a last resort! - SCHED_MELEE_ATTACK1, - SCHED_MELEE_ATTACK2, - SCHED_RANGE_ATTACK1, - SCHED_RANGE_ATTACK2, - SCHED_SPECIAL_ATTACK1, - SCHED_SPECIAL_ATTACK2, - SCHED_STANDOFF, - SCHED_ARM_WEAPON, - SCHED_RELOAD, - SCHED_GUARD, - SCHED_AMBUSH, - SCHED_DIE, - SCHED_WAIT_TRIGGER, - SCHED_FOLLOW, - SCHED_SLEEP, - SCHED_WAKE, - SCHED_BARNACLE_VICTIM_GRAB, - SCHED_BARNACLE_VICTIM_CHOMP, - SCHED_AISCRIPT, - SCHED_FAIL, - LAST_COMMON_SCHEDULE // Leave this at the bottom -} SCHEDULE_TYPE; - -//========================================================= -// These are the shared tasks -//========================================================= -typedef enum -{ - TASK_INVALID = 0, - TASK_WAIT, - TASK_WAIT_FACE_ENEMY, - TASK_WAIT_PVS, - TASK_SUGGEST_STATE, - TASK_WALK_TO_TARGET, - TASK_RUN_TO_TARGET, - TASK_MOVE_TO_TARGET_RANGE, - TASK_GET_PATH_TO_ENEMY, - TASK_GET_PATH_TO_ENEMY_LKP, - TASK_GET_PATH_TO_ENEMY_CORPSE, - TASK_GET_PATH_TO_LEADER, - TASK_GET_PATH_TO_SPOT, - TASK_GET_PATH_TO_TARGET, - TASK_GET_PATH_TO_HINTNODE, - TASK_GET_PATH_TO_LASTPOSITION, - TASK_GET_PATH_TO_BESTSOUND, - TASK_GET_PATH_TO_BESTSCENT, - TASK_RUN_PATH, - TASK_WALK_PATH, - TASK_STRAFE_PATH, - TASK_CLEAR_MOVE_WAIT, - TASK_STORE_LASTPOSITION, - TASK_CLEAR_LASTPOSITION, - TASK_PLAY_ACTIVE_IDLE, - TASK_FIND_HINTNODE, - TASK_CLEAR_HINTNODE, - TASK_SMALL_FLINCH, - TASK_FACE_IDEAL, - TASK_FACE_ROUTE, - TASK_FACE_ENEMY, - TASK_FACE_HINTNODE, - TASK_FACE_TARGET, - TASK_FACE_LASTPOSITION, - TASK_RANGE_ATTACK1, - TASK_RANGE_ATTACK2, - TASK_MELEE_ATTACK1, - TASK_MELEE_ATTACK2, - TASK_RELOAD, - TASK_RANGE_ATTACK1_NOTURN, - TASK_RANGE_ATTACK2_NOTURN, - TASK_MELEE_ATTACK1_NOTURN, - TASK_MELEE_ATTACK2_NOTURN, - TASK_RELOAD_NOTURN, - TASK_SPECIAL_ATTACK1, - TASK_SPECIAL_ATTACK2, - TASK_CROUCH, - TASK_STAND, - TASK_GUARD, - TASK_STEP_LEFT, - TASK_STEP_RIGHT, - TASK_STEP_FORWARD, - TASK_STEP_BACK, - TASK_DODGE_LEFT, - TASK_DODGE_RIGHT, - TASK_SOUND_ANGRY, - TASK_SOUND_DEATH, - TASK_SET_ACTIVITY, - TASK_SET_SCHEDULE, - TASK_SET_FAIL_SCHEDULE, - TASK_CLEAR_FAIL_SCHEDULE, - TASK_PLAY_SEQUENCE, - TASK_PLAY_SEQUENCE_FACE_ENEMY, - TASK_PLAY_SEQUENCE_FACE_TARGET, - TASK_SOUND_IDLE, - TASK_SOUND_WAKE, - TASK_SOUND_PAIN, - TASK_SOUND_DIE, - TASK_FIND_COVER_FROM_BEST_SOUND,// tries lateral cover first, then node cover - TASK_FIND_COVER_FROM_ENEMY,// tries lateral cover first, then node cover - TASK_FIND_LATERAL_COVER_FROM_ENEMY, - TASK_FIND_NODE_COVER_FROM_ENEMY, - TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY,// data for this one is the MAXIMUM acceptable distance to the cover. - TASK_FIND_FAR_NODE_COVER_FROM_ENEMY,// data for this one is there MINIMUM aceptable distance to the cover. - TASK_FIND_COVER_FROM_ORIGIN, - TASK_EAT, - TASK_DIE, - TASK_WAIT_FOR_SCRIPT, - TASK_PLAY_SCRIPT, - TASK_ENABLE_SCRIPT, - TASK_PLANT_ON_SCRIPT, - TASK_FACE_SCRIPT, - TASK_WAIT_RANDOM, - TASK_WAIT_INDEFINITE, - TASK_STOP_MOVING, - TASK_TURN_LEFT, - TASK_TURN_RIGHT, - TASK_REMEMBER, - TASK_FORGET, - TASK_WAIT_FOR_MOVEMENT, // wait until MovementIsComplete() - LAST_COMMON_TASK, // LEAVE THIS AT THE BOTTOM!! (sjb) -} SHARED_TASKS; - - -// These go in the flData member of the TASK_WALK_TO_TARGET, TASK_RUN_TO_TARGET -enum target_move_e -{ - TARGET_MOVE_NORMAL = 0, - TARGET_MOVE_SCRIPTED = 1, -}; - - -// A goal should be used for a task that requires several schedules to complete. -// The goal index should indicate which schedule (ordinally) the monster is running. -// That way, when tasks fail, the AI can make decisions based on the context of the -// current goal and sequence rather than just the current schedule. -enum goal_e -{ - GOAL_ATTACK_ENEMY, - GOAL_MOVE, - GOAL_TAKE_COVER, - GOAL_MOVE_TARGET, - GOAL_EAT, -}; - -// an array of tasks is a task list -// an array of schedules is a schedule list -struct Task_t -{ - - int iTask; - float flData; -}; - -struct Schedule_t -{ - - Task_t *pTasklist; - int cTasks; - int iInterruptMask;// a bit mask of conditions that can interrupt this schedule - - // a more specific mask that indicates which TYPES of sounds will interrupt the schedule in the - // event that the schedule is broken by COND_HEAR_SOUND - int iSoundMask; - const char *pName; -}; - -// an array of waypoints makes up the monster's route. -// !!!LATER- this declaration doesn't belong in this file. -struct WayPoint_t -{ - Vector vecLocation; - int iType; -}; - -// these MoveFlag values are assigned to a WayPoint's TYPE in order to demonstrate the -// type of movement the monster should use to get there. - -enum { - bits_MF_TO_TARGETENT = ( 1 << 0 ), // local move to targetent. - bits_MF_TO_ENEMY = ( 1 << 1 ), // local move to enemy - bits_MF_TO_COVER = ( 1 << 2 ), // local move to a hiding place - bits_MF_TO_DETOUR = ( 1 << 3 ), // local move to detour point. - bits_MF_TO_PATHCORNER = ( 1 << 4 ), // local move to a path corner - bits_MF_TO_NODE = ( 1 << 5 ), // local move to a node - bits_MF_TO_LOCATION = ( 1 << 6 ), // local move to an arbitrary point - bits_MF_IS_GOAL = ( 1 << 7 ), // this waypoint is the goal of the whole move. - bits_MF_DONT_SIMPLIFY = ( 1 << 8 ), // Don't let the route code simplify this waypoint - bits_MF_NOT_TO_MASK = (bits_MF_IS_GOAL | bits_MF_DONT_SIMPLIFY) -}; -// If you define any flags that aren't _TO_ flags, add them here so we can mask -// them off when doing compares. - -enum { - MOVEGOAL_NONE = 0, - MOVEGOAL_TARGETENT = bits_MF_TO_TARGETENT, - MOVEGOAL_ENEMY = bits_MF_TO_ENEMY, - MOVEGOAL_PATHCORNER = bits_MF_TO_PATHCORNER, - MOVEGOAL_LOCATION = bits_MF_TO_LOCATION, - MOVEGOAL_NODE = bits_MF_TO_NODE -}; -// these bits represent conditions that may befall the monster, of which some are allowed -// to interrupt certain schedules. - -enum { - bits_COND_NO_AMMO_LOADED = (1 << 0),// weapon needs to be reloaded! - bits_COND_SEE_HATE = (1 << 1),// see something that you hate - bits_COND_SEE_FEAR = (1 << 2),// see something that you are afraid of - bits_COND_SEE_DISLIKE = (1 << 3),// see something that you dislike - bits_COND_SEE_ENEMY = (1 << 4),// target entity is in full view. - bits_COND_ENEMY_OCCLUDED = (1 << 5),// target entity occluded by the world - bits_COND_SMELL_FOOD = (1 << 6), - bits_COND_ENEMY_TOOFAR = (1 << 7), - bits_COND_LIGHT_DAMAGE = (1 << 8),// hurt a little - bits_COND_HEAVY_DAMAGE = (1 << 9),// hurt a lot - bits_COND_CAN_RANGE_ATTACK1 = (1 << 10), - bits_COND_CAN_MELEE_ATTACK1 = (1 << 11), - bits_COND_CAN_RANGE_ATTACK2 = (1 << 12), - bits_COND_CAN_MELEE_ATTACK2 = (1 << 13), - //bits_COND_CAN_RANGE_ATTACK3 = ( 1 << 14), - bits_COND_PROVOKED = (1 << 15), - bits_COND_NEW_ENEMY = (1 << 16), - bits_COND_HEAR_SOUND = (1 << 17),// there is an interesting sound - bits_COND_SMELL = (1 << 18),// there is an interesting scent - bits_COND_ENEMY_FACING_ME = (1 << 19),// enemy is facing me - bits_COND_ENEMY_DEAD = (1 << 20),// enemy was killed. If you get this in combat, try to find another enemy. If you get it in alert, victory dance. - bits_COND_SEE_CLIENT = (1 << 21),// see a client - bits_COND_SEE_NEMESIS = (1 << 22),// see my nemesis - bits_COND_SPECIAL1 = (1 << 28),// Defined by individual monster - bits_COND_SPECIAL2 = (1 << 29),// Defined by individual monster - bits_COND_TASK_FAILED = (1 << 30), - bits_COND_SCHEDULE_DONE = (1 << 31), - bits_COND_ALL_SPECIAL = (bits_COND_SPECIAL1 | bits_COND_SPECIAL2), - bits_COND_CAN_ATTACK = (bits_COND_CAN_RANGE_ATTACK1 | bits_COND_CAN_MELEE_ATTACK1 | bits_COND_CAN_RANGE_ATTACK2 | bits_COND_CAN_MELEE_ATTACK2) - -}; - -#endif // SCHEDULE_H +#ifndef SCHEDULE_H +#define SCHEDULE_H + +#define TASKSTATUS_NEW 0 // Just started +#define TASKSTATUS_RUNNING 1 // Running task & movement +#define TASKSTATUS_RUNNING_MOVEMENT 2 // Just running movement +#define TASKSTATUS_RUNNING_TASK 3 // Just running task +#define TASKSTATUS_COMPLETE 4 // Completed, get next task + + +//========================================================= +// These are the schedule types +//========================================================= +typedef enum +{ + SCHED_NONE = 0, + SCHED_IDLE_STAND, + SCHED_IDLE_WALK, + SCHED_WAKE_ANGRY, + SCHED_WAKE_CALLED, + SCHED_ALERT_FACE, + SCHED_ALERT_SMALL_FLINCH, + SCHED_ALERT_BIG_FLINCH, + SCHED_ALERT_STAND, + SCHED_INVESTIGATE_SOUND, + SCHED_COMBAT_FACE, + SCHED_COMBAT_STAND, + SCHED_CHASE_ENEMY, + SCHED_CHASE_ENEMY_FAILED, + SCHED_VICTORY_DANCE, + SCHED_TARGET_FACE, + SCHED_TARGET_CHASE, + SCHED_SMALL_FLINCH, + SCHED_TAKE_COVER_FROM_ENEMY, + SCHED_TAKE_COVER_FROM_BEST_SOUND, + SCHED_TAKE_COVER_FROM_ORIGIN, + SCHED_COWER, // usually a last resort! + SCHED_MELEE_ATTACK1, + SCHED_MELEE_ATTACK2, + SCHED_RANGE_ATTACK1, + SCHED_RANGE_ATTACK2, + SCHED_SPECIAL_ATTACK1, + SCHED_SPECIAL_ATTACK2, + SCHED_STANDOFF, + SCHED_ARM_WEAPON, + SCHED_RELOAD, + SCHED_GUARD, + SCHED_AMBUSH, + SCHED_DIE, + SCHED_WAIT_TRIGGER, + SCHED_FOLLOW, + SCHED_SLEEP, + SCHED_WAKE, + SCHED_BARNACLE_VICTIM_GRAB, + SCHED_BARNACLE_VICTIM_CHOMP, + SCHED_AISCRIPT, + SCHED_FAIL, + + LAST_COMMON_SCHEDULE // Leave this at the bottom +} SCHEDULE_TYPE; + +//========================================================= +// These are the shared tasks +//========================================================= +typedef enum +{ + TASK_INVALID = 0, + TASK_WAIT, + TASK_WAIT_FACE_ENEMY, + TASK_WAIT_PVS, + TASK_SUGGEST_STATE, + TASK_WALK_TO_TARGET, + TASK_RUN_TO_TARGET, + TASK_MOVE_TO_TARGET_RANGE, + TASK_GET_PATH_TO_ENEMY, + TASK_GET_PATH_TO_ENEMY_LKP, + TASK_GET_PATH_TO_ENEMY_CORPSE, + TASK_GET_PATH_TO_LEADER, + TASK_GET_PATH_TO_SPOT, + TASK_GET_PATH_TO_TARGET, + TASK_GET_PATH_TO_HINTNODE, + TASK_GET_PATH_TO_LASTPOSITION, + TASK_GET_PATH_TO_BESTSOUND, + TASK_GET_PATH_TO_BESTSCENT, + TASK_RUN_PATH, + TASK_WALK_PATH, + TASK_STRAFE_PATH, + TASK_CLEAR_MOVE_WAIT, + TASK_STORE_LASTPOSITION, + TASK_CLEAR_LASTPOSITION, + TASK_PLAY_ACTIVE_IDLE, + TASK_FIND_HINTNODE, + TASK_CLEAR_HINTNODE, + TASK_SMALL_FLINCH, + TASK_FACE_IDEAL, + TASK_FACE_ROUTE, + TASK_FACE_ENEMY, + TASK_FACE_HINTNODE, + TASK_FACE_TARGET, + TASK_FACE_LASTPOSITION, + TASK_RANGE_ATTACK1, + TASK_RANGE_ATTACK2, + TASK_MELEE_ATTACK1, + TASK_MELEE_ATTACK2, + TASK_RELOAD, + TASK_RANGE_ATTACK1_NOTURN, + TASK_RANGE_ATTACK2_NOTURN, + TASK_MELEE_ATTACK1_NOTURN, + TASK_MELEE_ATTACK2_NOTURN, + TASK_RELOAD_NOTURN, + TASK_SPECIAL_ATTACK1, + TASK_SPECIAL_ATTACK2, + TASK_CROUCH, + TASK_STAND, + TASK_GUARD, + TASK_STEP_LEFT, + TASK_STEP_RIGHT, + TASK_STEP_FORWARD, + TASK_STEP_BACK, + TASK_DODGE_LEFT, + TASK_DODGE_RIGHT, + TASK_SOUND_ANGRY, + TASK_SOUND_DEATH, + TASK_SET_ACTIVITY, + TASK_SET_SCHEDULE, + TASK_SET_FAIL_SCHEDULE, + TASK_CLEAR_FAIL_SCHEDULE, + TASK_PLAY_SEQUENCE, + TASK_PLAY_SEQUENCE_FACE_ENEMY, + TASK_PLAY_SEQUENCE_FACE_TARGET, + TASK_SOUND_IDLE, + TASK_SOUND_WAKE, + TASK_SOUND_PAIN, + TASK_SOUND_DIE, + TASK_FIND_COVER_FROM_BEST_SOUND,// tries lateral cover first, then node cover + TASK_FIND_COVER_FROM_ENEMY,// tries lateral cover first, then node cover + TASK_FIND_LATERAL_COVER_FROM_ENEMY, + TASK_FIND_NODE_COVER_FROM_ENEMY, + TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY,// data for this one is the MAXIMUM acceptable distance to the cover. + TASK_FIND_FAR_NODE_COVER_FROM_ENEMY,// data for this one is there MINIMUM aceptable distance to the cover. + TASK_FIND_COVER_FROM_ORIGIN, + TASK_EAT, + TASK_DIE, + TASK_WAIT_FOR_SCRIPT, + TASK_PLAY_SCRIPT, + TASK_ENABLE_SCRIPT, + TASK_PLANT_ON_SCRIPT, + TASK_FACE_SCRIPT, + TASK_WAIT_RANDOM, + TASK_WAIT_INDEFINITE, + TASK_STOP_MOVING, + TASK_TURN_LEFT, + TASK_TURN_RIGHT, + TASK_REMEMBER, + TASK_FORGET, + TASK_WAIT_FOR_MOVEMENT, // wait until MovementIsComplete() + LAST_COMMON_TASK, // LEAVE THIS AT THE BOTTOM!! (sjb) +} SHARED_TASKS; + + +// These go in the flData member of the TASK_WALK_TO_TARGET, TASK_RUN_TO_TARGET +enum +{ + TARGET_MOVE_NORMAL = 0, + TARGET_MOVE_SCRIPTED = 1, +}; + + +// A goal should be used for a task that requires several schedules to complete. +// The goal index should indicate which schedule (ordinally) the monster is running. +// That way, when tasks fail, the AI can make decisions based on the context of the +// current goal and sequence rather than just the current schedule. +enum +{ + GOAL_ATTACK_ENEMY, + GOAL_MOVE, + GOAL_TAKE_COVER, + GOAL_MOVE_TARGET, + GOAL_EAT, +}; + +// an array of tasks is a task list +// an array of schedules is a schedule list +struct Task_t +{ + + int iTask; + float flData; +}; + +struct Schedule_t +{ + + Task_t *pTasklist; + int cTasks; + int iInterruptMask;// a bit mask of conditions that can interrupt this schedule + + // a more specific mask that indicates which TYPES of sounds will interrupt the schedule in the + // event that the schedule is broken by COND_HEAR_SOUND + int iSoundMask; + const char *pName; +}; + +// an array of waypoints makes up the monster's route. +// !!!LATER- this declaration doesn't belong in this file. +struct WayPoint_t +{ + Vector vecLocation; + int iType; +}; + +// these MoveFlag values are assigned to a WayPoint's TYPE in order to demonstrate the +// type of movement the monster should use to get there. +#define bits_MF_TO_TARGETENT ( 1 << 0 ) // local move to targetent. +#define bits_MF_TO_ENEMY ( 1 << 1 ) // local move to enemy +#define bits_MF_TO_COVER ( 1 << 2 ) // local move to a hiding place +#define bits_MF_TO_DETOUR ( 1 << 3 ) // local move to detour point. +#define bits_MF_TO_PATHCORNER ( 1 << 4 ) // local move to a path corner +#define bits_MF_TO_NODE ( 1 << 5 ) // local move to a node +#define bits_MF_TO_LOCATION ( 1 << 6 ) // local move to an arbitrary point +#define bits_MF_IS_GOAL ( 1 << 7 ) // this waypoint is the goal of the whole move. +#define bits_MF_DONT_SIMPLIFY ( 1 << 8 ) // Don't let the route code simplify this waypoint + +// If you define any flags that aren't _TO_ flags, add them here so we can mask +// them off when doing compares. +#define bits_MF_NOT_TO_MASK (bits_MF_IS_GOAL | bits_MF_DONT_SIMPLIFY) + +#define MOVEGOAL_NONE (0) +#define MOVEGOAL_TARGETENT (bits_MF_TO_TARGETENT) +#define MOVEGOAL_ENEMY (bits_MF_TO_ENEMY) +#define MOVEGOAL_PATHCORNER (bits_MF_TO_PATHCORNER) +#define MOVEGOAL_LOCATION (bits_MF_TO_LOCATION) +#define MOVEGOAL_NODE (bits_MF_TO_NODE) + +// these bits represent conditions that may befall the monster, of which some are allowed +// to interrupt certain schedules. +#define bits_COND_NO_AMMO_LOADED ( 1 << 0 ) // weapon needs to be reloaded! +#define bits_COND_SEE_HATE ( 1 << 1 ) // see something that you hate +#define bits_COND_SEE_FEAR ( 1 << 2 ) // see something that you are afraid of +#define bits_COND_SEE_DISLIKE ( 1 << 3 ) // see something that you dislike +#define bits_COND_SEE_ENEMY ( 1 << 4 ) // target entity is in full view. +#define bits_COND_ENEMY_OCCLUDED ( 1 << 5 ) // target entity occluded by the world +#define bits_COND_SMELL_FOOD ( 1 << 6 ) +#define bits_COND_ENEMY_TOOFAR ( 1 << 7 ) +#define bits_COND_LIGHT_DAMAGE ( 1 << 8 ) // hurt a little +#define bits_COND_HEAVY_DAMAGE ( 1 << 9 ) // hurt a lot +#define bits_COND_CAN_RANGE_ATTACK1 ( 1 << 10) +#define bits_COND_CAN_MELEE_ATTACK1 ( 1 << 11) +#define bits_COND_CAN_RANGE_ATTACK2 ( 1 << 12) +#define bits_COND_CAN_MELEE_ATTACK2 ( 1 << 13) +// #define bits_COND_CAN_RANGE_ATTACK3 ( 1 << 14) +#define bits_COND_PROVOKED ( 1 << 15) +#define bits_COND_NEW_ENEMY ( 1 << 16) +#define bits_COND_HEAR_SOUND ( 1 << 17) // there is an interesting sound +#define bits_COND_SMELL ( 1 << 18) // there is an interesting scent +#define bits_COND_ENEMY_FACING_ME ( 1 << 19) // enemy is facing me +#define bits_COND_ENEMY_DEAD ( 1 << 20) // enemy was killed. If you get this in combat, try to find another enemy. If you get it in alert, victory dance. +#define bits_COND_SEE_CLIENT ( 1 << 21) // see a client +#define bits_COND_SEE_NEMESIS ( 1 << 22) // see my nemesis + +#define bits_COND_SPECIAL1 ( 1 << 28) // Defined by individual monster +#define bits_COND_SPECIAL2 ( 1 << 29) // Defined by individual monster + +#define bits_COND_TASK_FAILED ( 1 << 30) +#define bits_COND_SCHEDULE_DONE ( 1 << 31) + + +#define bits_COND_ALL_SPECIAL (bits_COND_SPECIAL1 | bits_COND_SPECIAL2) + +#define bits_COND_CAN_ATTACK (bits_COND_CAN_RANGE_ATTACK1 | bits_COND_CAN_MELEE_ATTACK1 | bits_COND_CAN_RANGE_ATTACK2 | bits_COND_CAN_MELEE_ATTACK2) + +#endif // SCHEDULE_H diff --git a/src/game/server/hl/scripted.cpp b/src/game/server/hl/scripted.cpp index 52b525c71..b3e766913 100644 --- a/src/game/server/hl/scripted.cpp +++ b/src/game/server/hl/scripted.cpp @@ -57,37 +57,37 @@ void CCineMonster ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "m_iszIdle")) { m_iszIdle = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_iszPlay")) { m_iszPlay = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_iszEntity")) { m_iszEntity = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_fMoveTo")) { m_fMoveTo = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_flRepeat")) { m_flRepeat = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_flRadius")) { m_flRadius = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "m_iFinishSchedule")) { m_iFinishSchedule = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else { @@ -143,20 +143,20 @@ void CCineMonster ::Spawn(void) m_startTime = gpGlobals->time + 1E6; } if (pev->spawnflags & SF_SCRIPT_NOINTERRUPT) - m_interruptable = false; + m_interruptable = FALSE; else - m_interruptable = true; + m_interruptable = TRUE; } //========================================================= -// FCanOverrideState - returns false, scripted sequences +// FCanOverrideState - returns FALSE, scripted sequences // cannot possess entities regardless of state. //========================================================= BOOL CCineMonster ::FCanOverrideState(void) { if (pev->spawnflags & SF_SCRIPT_OVERRIDESTATE) - return true; - return false; + return TRUE; + return FALSE; } //========================================================= @@ -165,7 +165,7 @@ BOOL CCineMonster ::FCanOverrideState(void) //========================================================= BOOL CCineAI ::FCanOverrideState(void) { - return true; + return TRUE; } // @@ -273,7 +273,7 @@ int CCineMonster ::FindEntity(void) if (pTarget && pTarget->CanPlaySequence(FCanOverrideState(), SS_INTERRUPT_BY_NAME)) { m_hTargetEnt = pTarget; - return true; + return TRUE; } ALERT(at_console, "Found %s, but can't play!\n", STRING(m_iszEntity)); } @@ -294,7 +294,7 @@ int CCineMonster ::FindEntity(void) if (pTarget && pTarget->CanPlaySequence(FCanOverrideState(), SS_INTERRUPT_IDLE)) { m_hTargetEnt = pTarget; - return true; + return TRUE; } } } @@ -302,7 +302,7 @@ int CCineMonster ::FindEntity(void) } pTarget = NULL; m_hTargetEnt = NULL; - return false; + return FALSE; } // make the entity enter a scripted sequence @@ -368,7 +368,7 @@ void CCineMonster ::PossessEntity(void) pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT; if (m_iszIdle) { - StartSequence(pTarget, m_iszIdle, false); + StartSequence(pTarget, m_iszIdle, FALSE); if (FStrEq(STRING(m_iszIdle), STRING(m_iszPlay))) { pTarget->pev->framerate = 0; @@ -445,7 +445,7 @@ void CCineAI ::PossessEntity(void) /* if (m_iszIdle) { - StartSequence( pTarget, m_iszIdle, false ); + StartSequence( pTarget, m_iszIdle, FALSE ); if (FStrEq( STRING(m_iszIdle), STRING(m_iszPlay))) { pTarget->pev->framerate = 0; @@ -482,7 +482,7 @@ BOOL CCineMonster ::StartSequence(CBaseMonster *pTarget, int iszSeq, BOOL comple if (!iszSeq && completeOnEmpty) { SequenceDone(pTarget); - return false; + return FALSE; } pTarget->pev->sequence = pTarget->LookupSequence(STRING(iszSeq)); @@ -490,7 +490,7 @@ BOOL CCineMonster ::StartSequence(CBaseMonster *pTarget, int iszSeq, BOOL comple { ALERT(at_error, "%s: unknown scripted sequence \"%s\"\n", STRING(pTarget->pev->targetname), STRING(iszSeq)); pTarget->pev->sequence = 0; - // return false; + // return FALSE; } #if 0 @@ -505,7 +505,7 @@ BOOL CCineMonster ::StartSequence(CBaseMonster *pTarget, int iszSeq, BOOL comple pTarget->pev->frame = 0; pTarget->ResetSequenceInfo(); - return true; + return TRUE; } // lookup a sequence name and setup the target monster to play it @@ -521,7 +521,7 @@ BOOL CCineAI ::StartSequence(CBaseMonster *pTarget, int iszSeq, BOOL completeOnE SequenceDone(pTarget); - return true; + return TRUE; } pTarget->pev->sequence = pTarget->LookupSequence(STRING(iszSeq)); @@ -530,12 +530,12 @@ BOOL CCineAI ::StartSequence(CBaseMonster *pTarget, int iszSeq, BOOL completeOnE { ALERT(at_error, "%s: unknown aiscripted sequence \"%s\"\n", STRING(pTarget->pev->targetname), STRING(iszSeq)); pTarget->pev->sequence = 0; - // return false; + // return FALSE; } pTarget->pev->frame = 0; pTarget->ResetSequenceInfo(); - return true; + return TRUE; } //========================================================= @@ -618,7 +618,7 @@ BOOL CBaseMonster ::ExitScriptedSequence() // is this legal? // BUGBUG -- This doesn't call Killed() m_IdealMonsterState = MONSTERSTATE_DEAD; - return false; + return FALSE; } if (m_pCine) @@ -626,7 +626,7 @@ BOOL CBaseMonster ::ExitScriptedSequence() m_pCine->CancelScript(); } - return true; + return TRUE; } void CCineMonster::AllowInterrupt(BOOL fAllow) @@ -639,14 +639,14 @@ void CCineMonster::AllowInterrupt(BOOL fAllow) BOOL CCineMonster::CanInterrupt(void) { if (!m_interruptable) - return false; + return FALSE; CBaseEntity *pTarget = m_hTargetEnt; if (pTarget != NULL && pTarget->pev->deadflag == DEAD_NO) - return true; + return TRUE; - return false; + return FALSE; } int CCineMonster::IgnoreConditions(void) @@ -815,7 +815,7 @@ BOOL CBaseMonster ::CineCleanup() StopAnimation(); pev->movetype = MOVETYPE_NONE; pev->effects |= EF_NOINTERP; // Don't interpolate either, assume the corpse is positioned in its final resting place - return false; + return FALSE; } // If we actually played a sequence @@ -890,7 +890,7 @@ BOOL CBaseMonster ::CineCleanup() // SetAnimation( m_MonsterState ); ClearBits(pev->spawnflags, SF_MONSTER_WAIT_FOR_SCRIPT); - return true; + return TRUE; } class CScriptedSentence : public CBaseToggle @@ -924,7 +924,10 @@ class CScriptedSentence : public CBaseToggle int m_iszListener; // name of entity to look at while talking }; - +#define SF_SENTENCE_ONCE 0x0001 +#define SF_SENTENCE_FOLLOWERS 0x0002 // only say if following player +#define SF_SENTENCE_INTERRUPT 0x0004 // force talking except when dead +#define SF_SENTENCE_CONCURRENT 0x0008 // allow other people to keep talking TYPEDESCRIPTION CScriptedSentence::m_SaveData[] = { @@ -948,42 +951,42 @@ void CScriptedSentence ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "sentence")) { m_iszSentence = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "entity")) { m_iszEntity = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "duration")) { m_flDuration = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "radius")) { m_flRadius = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "refire")) { m_flRepeat = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "attenuation")) { pev->impulse = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "volume")) { m_flVolume = atof(pkvd->szValue) * 0.1; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "listener")) { m_iszListener = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseToggle::KeyValue(pkvd); @@ -1002,7 +1005,7 @@ void CScriptedSentence ::Spawn(void) { pev->solid = SOLID_NOT; - m_active = true; + m_active = TRUE; // if no targetname, start now if (!pev->targetname) { @@ -1046,7 +1049,7 @@ void CScriptedSentence ::FindThink(void) UTIL_Remove(this); SetThink(&CScriptedSentence::DelayThink); pev->nextthink = gpGlobals->time + m_flDuration + m_flRepeat; - m_active = false; + m_active = FALSE; // ALERT( at_console, "%s: found monster %s\n", STRING(m_iszSentence), STRING(m_iszEntity) ); } else @@ -1058,7 +1061,7 @@ void CScriptedSentence ::FindThink(void) void CScriptedSentence ::DelayThink(void) { - m_active = true; + m_active = TRUE; if (!pev->targetname) pev->nextthink = gpGlobals->time + 0.1; SetThink(&CScriptedSentence::FindThink); @@ -1071,17 +1074,17 @@ BOOL CScriptedSentence ::AcceptableSpeaker(CBaseMonster *pMonster) if (pev->spawnflags & SF_SENTENCE_FOLLOWERS) { if (pMonster->m_hTargetEnt == NULL || !FClassnameIs(pMonster->m_hTargetEnt->pev, "player")) - return false; + return FALSE; } BOOL override; if (pev->spawnflags & SF_SENTENCE_INTERRUPT) - override = true; + override = TRUE; else - override = false; + override = FALSE; if (pMonster->CanPlaySentence(override)) - return true; + return TRUE; } - return false; + return FALSE; } CBaseMonster *CScriptedSentence ::FindEntity(void) @@ -1129,9 +1132,9 @@ BOOL CScriptedSentence ::StartSentence(CBaseMonster *pTarget) return NULL; } - BOOL bConcurrent = false; + BOOL bConcurrent = FALSE; if (!(pev->spawnflags & SF_SENTENCE_CONCURRENT)) - bConcurrent = true; + bConcurrent = TRUE; CBaseEntity *pListener = NULL; if (!FStringNull(m_iszListener)) @@ -1147,7 +1150,7 @@ BOOL CScriptedSentence ::StartSentence(CBaseMonster *pTarget) pTarget->PlayScriptedSentence(STRING(m_iszSentence), m_flDuration, m_flVolume, m_flAttenuation, bConcurrent, pListener); ALERT(at_aiconsole, "Playing sentence %s (%.1f)\n", STRING(m_iszSentence), m_flDuration); SUB_UseTargets(NULL, USE_TOGGLE, 0); - return true; + return TRUE; } /* diff --git a/src/game/server/hl/scripted.h b/src/game/server/hl/scripted.h index 8698cb49e..064da13f1 100644 --- a/src/game/server/hl/scripted.h +++ b/src/game/server/hl/scripted.h @@ -19,24 +19,16 @@ #include "scriptevent.h" #endif -enum script_conditions_e { - SF_SCRIPT_WAITTILLSEEN = 1, - SF_SCRIPT_EXITAGITATED = 2, - SF_SCRIPT_REPEATABLE = 4, - SF_SCRIPT_LEAVECORPSE = 8, - //SF_SCRIPT_INTERPOLATE = 16, // don't use, old bug - SF_SCRIPT_NOINTERRUPT = 32, - SF_SCRIPT_OVERRIDESTATE = 64, - SF_SCRIPT_NOSCRIPTMOVEMENT = 128, - SCRIPT_BREAK_CONDITIONS = (bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE) -}; +#define SF_SCRIPT_WAITTILLSEEN 1 +#define SF_SCRIPT_EXITAGITATED 2 +#define SF_SCRIPT_REPEATABLE 4 +#define SF_SCRIPT_LEAVECORPSE 8 +//#define SF_SCRIPT_INTERPOLATE 16 // don't use, old bug +#define SF_SCRIPT_NOINTERRUPT 32 +#define SF_SCRIPT_OVERRIDESTATE 64 +#define SF_SCRIPT_NOSCRIPTMOVEMENT 128 -enum sf_sentence_e { - SF_SENTENCE_ONCE = 0x0001, - SF_SENTENCE_FOLLOWERS = 0x0002, // only say if following player - SF_SENTENCE_INTERRUPT = 0x0004, // force talking except when dead - SF_SENTENCE_CONCURRENT = 0x0008 // allow other people to keep talking -}; +#define SCRIPT_BREAK_CONDITIONS (bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE) enum SS_INTERRUPT { @@ -48,11 +40,8 @@ enum SS_INTERRUPT // when a monster finishes an AI scripted sequence, we can choose // a schedule to place them in. These defines are the aliases to // resolve worldcraft input to real schedules (sjb) - -enum script_finishedsched_e { - SCRIPT_FINISHSCHED_DEFAULT = 0, - SCRIPT_FINISHSCHED_AMBUSH = 1 -}; +#define SCRIPT_FINISHSCHED_DEFAULT 0 +#define SCRIPT_FINISHSCHED_AMBUSH 1 class CCineMonster : public CBaseMonster { diff --git a/src/game/server/hl/scriptevent.h b/src/game/server/hl/scriptevent.h index 0e11a23d0..e8b297033 100644 --- a/src/game/server/hl/scriptevent.h +++ b/src/game/server/hl/scriptevent.h @@ -15,18 +15,15 @@ #ifndef SCRIPTEVENT_H #define SCRIPTEVENT_H -enum script_event_e { - - SCRIPT_EVENT_DEAD = 1000, // character is now dead - SCRIPT_EVENT_NOINTERRUPT = 1001, // does not allow interrupt - SCRIPT_EVENT_CANINTERRUPT = 1002, // will allow interrupt - SCRIPT_EVENT_FIREEVENT = 1003, // event now fires - SCRIPT_EVENT_SOUND = 1004, // Play named wave file (on CHAN_BODY) - SCRIPT_EVENT_SENTENCE = 1005, // Play named sentence - SCRIPT_EVENT_INAIR = 1006, // Leave the character in air at the end of the sequence (don't find the floor) - SCRIPT_EVENT_ENDANIMATION = 1007, // Set the animation by name after the sequence completes - SCRIPT_EVENT_SOUND_VOICE = 1008, // Play named wave file (on CHAN_VOICE) - SCRIPT_EVENT_SENTENCE_RND1 = 1009, // Play sentence group 25% of the time - SCRIPT_EVENT_NOT_DEAD = 1010 // Bring back to life (for life/death sequences) -}; +#define SCRIPT_EVENT_DEAD 1000 // character is now dead +#define SCRIPT_EVENT_NOINTERRUPT 1001 // does not allow interrupt +#define SCRIPT_EVENT_CANINTERRUPT 1002 // will allow interrupt +#define SCRIPT_EVENT_FIREEVENT 1003 // event now fires +#define SCRIPT_EVENT_SOUND 1004 // Play named wave file (on CHAN_BODY) +#define SCRIPT_EVENT_SENTENCE 1005 // Play named sentence +#define SCRIPT_EVENT_INAIR 1006 // Leave the character in air at the end of the sequence (don't find the floor) +#define SCRIPT_EVENT_ENDANIMATION 1007 // Set the animation by name after the sequence completes +#define SCRIPT_EVENT_SOUND_VOICE 1008 // Play named wave file (on CHAN_VOICE) +#define SCRIPT_EVENT_SENTENCE_RND1 1009 // Play sentence group 25% of the time +#define SCRIPT_EVENT_NOT_DEAD 1010 // Bring back to life (for life/death sequences) #endif //SCRIPTEVENT_H diff --git a/src/game/server/hl/skill.h b/src/game/server/hl/skill.h index 73c9f1482..fd0729178 100644 --- a/src/game/server/hl/skill.h +++ b/src/game/server/hl/skill.h @@ -141,9 +141,6 @@ float GetSkillCvar(char *pName); extern DLL_GLOBAL int g_iSkillLevel; - -enum skill_level_e { - SKILL_EASY = 1, - SKILL_MEDIUM = 2, - SKILL_HARD = 3 -}; \ No newline at end of file +#define SKILL_EASY 1 +#define SKILL_MEDIUM 2 +#define SKILL_HARD 3 diff --git a/src/game/server/hl/sound.cpp b/src/game/server/hl/sound.cpp index 3a3183b35..5b7ac96ec 100644 --- a/src/game/server/hl/sound.cpp +++ b/src/game/server/hl/sound.cpp @@ -17,6 +17,8 @@ //========================================================= #define VALVE_DLL 1 +#define CHAR_TEX_SNOW 'N' + #include "msdllheaders.h" #include "weapons.h" #include "player.h" @@ -28,8 +30,6 @@ #include #endif -constexpr unsigned int MAX_CDPVPRESET = 27; - // ==================== GENERIC AMBIENT SOUND ====================================== // THOTHIE: I cut and pasted from the original HL1SDK's SOUND.CPP the entire Ambient Generic section in an effort to restore functionality // THOTHIE: Just the ambient_generic entity, I left the rest alone @@ -80,9 +80,11 @@ typedef struct dynpitchvol } dynpitchvol_t; +#define CDPVPRESETMAX 27 + // presets for runtime pitch and vol modulation of ambient sounds -dynpitchvol_t rgdpvpreset[MAX_CDPVPRESET] = +dynpitchvol_t rgdpvpreset[CDPVPRESETMAX] = { // pitch pstart spinup spindwn volrun volstrt fadein fadeout lfotype lforate modptch modvol cspnup {1, 255, 75, 95, 95, 10, 1, 50, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -131,8 +133,8 @@ class CAmbientGeneric : public CBaseEntity float m_flAttenuation; // attenuation value dynpitchvol_t m_dpv; - BOOL m_fActive; // only true when the entity is playing a looping sound - BOOL m_fLooping; // true when the sound played will loop + BOOL m_fActive; // only TRUE when the entity is playing a looping sound + BOOL m_fLooping; // TRUE when the sound played will loop }; LINK_ENTITY_TO_CLASS(ambient_generic, CAmbientGeneric); //Thothie - attempting to build new amb generic ms MSMapEnts - so this needs to be altered @@ -209,12 +211,12 @@ void CAmbientGeneric ::Spawn(void) SetUse(&CAmbientGeneric::ToggleUse); - m_fActive = false; + m_fActive = FALSE; if (FBitSet(pev->spawnflags, AMBIENT_SOUND_NOT_LOOPING)) - m_fLooping = false; + m_fLooping = FALSE; else - m_fLooping = true; + m_fLooping = TRUE; Precache(); } @@ -234,7 +236,7 @@ void CAmbientGeneric ::Precache(void) { // start the sound ASAP if (m_fLooping) - m_fActive = true; + m_fActive = TRUE; } if (m_fActive) { @@ -256,7 +258,7 @@ void CAmbientGeneric ::RampThink(void) int pitch = m_dpv.pitch; int vol = m_dpv.vol; int flags = 0; - int fChanged = 0; // false if pitch and vol remain unchanged this round + int fChanged = 0; // FALSE if pitch and vol remain unchanged this round int prev; if (!m_dpv.spinup && !m_dpv.spindown && !m_dpv.fadein && !m_dpv.fadeout && !m_dpv.lfotype) @@ -460,7 +462,7 @@ void CAmbientGeneric ::InitModulationParms(void) m_dpv.volrun = 0; // get presets - if (m_dpv.preset != 0 && m_dpv.preset <= MAX_CDPVPRESET) + if (m_dpv.preset != 0 && m_dpv.preset <= CDPVPRESETMAX) { // load preset values m_dpv = rgdpvpreset[m_dpv.preset - 1]; @@ -591,7 +593,7 @@ void CAmbientGeneric ::ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, // Toggle - // m_fActive is true only if a looping sound is playing. + // m_fActive is TRUE only if a looping sound is playing. if (m_fActive) { // turn sound off @@ -622,7 +624,7 @@ void CAmbientGeneric ::ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, } else { - m_fActive = false; + m_fActive = FALSE; // HACKHACK - this makes the code in Precache() work properly after a save/restore pev->spawnflags |= AMBIENT_SOUND_START_SILENT; @@ -651,7 +653,7 @@ void CAmbientGeneric ::ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, // and then restarted. if (m_fLooping) - m_fActive = true; + m_fActive = TRUE; else // shut sound off now - may be interrupting a long non-looping sound UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, @@ -679,14 +681,14 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "preset")) { m_dpv.preset = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // pitchrun else if (FStrEq(pkvd->szKeyName, "pitch")) { m_dpv.pitchrun = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; if (m_dpv.pitchrun > 255) m_dpv.pitchrun = 255; @@ -698,7 +700,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) else if (FStrEq(pkvd->szKeyName, "pitchstart")) { m_dpv.pitchstart = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; if (m_dpv.pitchstart > 255) m_dpv.pitchstart = 255; @@ -719,7 +721,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) if (m_dpv.spinup > 0) m_dpv.spinup = (101 - m_dpv.spinup) * 64; m_dpv.spinupsav = m_dpv.spinup; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // spindown @@ -735,7 +737,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) if (m_dpv.spindown > 0) m_dpv.spindown = (101 - m_dpv.spindown) * 64; m_dpv.spindownsav = m_dpv.spindown; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // volstart @@ -750,7 +752,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) m_dpv.volstart *= 10; // 0 - 100 - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // fadein @@ -766,7 +768,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) if (m_dpv.fadein > 0) m_dpv.fadein = (101 - m_dpv.fadein) * 64; m_dpv.fadeinsav = m_dpv.fadein; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // fadeout @@ -782,7 +784,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) if (m_dpv.fadeout > 0) m_dpv.fadeout = (101 - m_dpv.fadeout) * 64; m_dpv.fadeoutsav = m_dpv.fadeout; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // lfotype @@ -791,7 +793,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) m_dpv.lfotype = atoi(pkvd->szValue); if (m_dpv.lfotype > 4) m_dpv.lfotype = LFO_TRIANGLE; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // lforate @@ -806,7 +808,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) m_dpv.lforate *= 256; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // lfomodpitch else if (FStrEq(pkvd->szKeyName, "lfomodpitch")) @@ -817,7 +819,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) if (m_dpv.lfomodpitch < 0) m_dpv.lfomodpitch = 0; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // lfomodvol @@ -829,7 +831,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) if (m_dpv.lfomodvol < 0) m_dpv.lfomodvol = 0; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } // cspinup @@ -841,7 +843,7 @@ void CAmbientGeneric ::KeyValue(KeyValueData *pkvd) if (m_dpv.cspinup < 0) m_dpv.cspinup = 0; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); @@ -880,16 +882,16 @@ void CEnvSound ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "radius")) { m_flRadius = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } if (FStrEq(pkvd->szKeyName, "roomtype")) { m_flRoomtype = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } } -// returns true if the given sound entity (pev) is in range +// returns TRUE if the given sound entity (pev) is in range // and can see the given player entity (pevTarget) BOOL FEnvSoundInRange(entvars_t *pev, entvars_t *pevTarget, float *pflRange) @@ -906,7 +908,7 @@ BOOL FEnvSoundInRange(entvars_t *pev, entvars_t *pevTarget, float *pflRange) // check if line of sight crosses water boundary, or is blocked if ((tr.fInOpen && tr.fInWater) || tr.flFraction != 1) - return false; + return FALSE; // calc range from sound entity to player @@ -914,12 +916,12 @@ BOOL FEnvSoundInRange(entvars_t *pev, entvars_t *pevTarget, float *pflRange) flRange = vecRange.Length(); if (pSound->m_flRadius < flRange) - return false; + return FALSE; if (pflRange) *pflRange = flRange; - return true; + return TRUE; } // @@ -1043,25 +1045,25 @@ void CEnvSound ::Spawn() // ==================== SENTENCE GROUPS, UTILITY FUNCTIONS ====================================== -constexpr unsigned int CSENTENCE_LRU_MAX = 32; // max number of elements per sentence group +#define CSENTENCE_LRU_MAX 32 // max number of elements per sentence group // group of related sentences typedef struct sentenceg { - char szgroupname[MAX_CBSENTENCENAME]; + char szgroupname[CBSENTENCENAME_MAX]; int count; unsigned char rgblru[CSENTENCE_LRU_MAX]; } SENTENCEG; -constexpr unsigned int CSENTENCEG_MAX = 200; // max number of sentence groups +#define CSENTENCEG_MAX 200 // max number of sentence groups // globals SENTENCEG rgsentenceg[CSENTENCEG_MAX]; bool bSentencesInit = false; -char gszallsentencenames[MAX_CVOXFILESENTENCE][MAX_CBSENTENCENAME]; +char gszallsentencenames[CVOXFILESENTENCEMAX][CBSENTENCENAME_MAX]; int gcallsentences = 0; // randomize list of sentence name indices @@ -1119,7 +1121,7 @@ int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int fres ipick = count - 1; strncpy(szfound, "!", 64); - strncat(szfound, szgroupname, MAX_CBSENTENCENAME); + strncat(szfound, szgroupname, CBSENTENCENAME_MAX); _snprintf(sznum, sizeof(sznum), "%i", ipick); strncat(szfound, sznum, sizeof(sznum)); @@ -1151,7 +1153,7 @@ int USENTENCEG_Pick(int isentenceg, char *szfound) unsigned char count; char sznum[8]; unsigned char ipick; - int ffound = false; + int ffound = FALSE; if (!bSentencesInit) return -1; @@ -1170,7 +1172,7 @@ int USENTENCEG_Pick(int isentenceg, char *szfound) { ipick = plru[i]; plru[i] = 0xFF; - ffound = true; + ffound = TRUE; break; } @@ -1179,7 +1181,7 @@ int USENTENCEG_Pick(int isentenceg, char *szfound) else { strncpy(szfound, "!", 64); - strncat(szfound, szgroupname, MAX_CBSENTENCENAME); + strncat(szfound, szgroupname, CBSENTENCENAME_MAX); _snprintf(sznum, sizeof(sznum), "%i", ipick); strncat(szfound, sznum, sizeof(sznum)); return ipick; @@ -1302,7 +1304,7 @@ void SENTENCEG_Stop(edict_t *entity, int isentenceg, int ipick) return; strncpy(buffer, "!", sizeof(buffer)); - strncat(buffer, rgsentenceg[isentenceg].szgroupname, MAX_CBSENTENCENAME); + strncat(buffer, rgsentenceg[isentenceg].szgroupname, CBSENTENCENAME_MAX); _snprintf(sznum, sizeof(sznum), "%i", ipick); strncat(buffer, sznum, sizeof(sznum)); @@ -1323,7 +1325,7 @@ void SENTENCEG_Init() if (bSentencesInit) return; - memset(gszallsentencenames, 0, MAX_CVOXFILESENTENCE * MAX_CBSENTENCENAME); + memset(gszallsentencenames, 0, CVOXFILESENTENCEMAX * CBSENTENCENAME_MAX); gcallsentences = 0; memset(rgsentenceg, 0, CSENTENCEG_MAX * sizeof(SENTENCEG)); @@ -1357,7 +1359,7 @@ void SENTENCEG_Init() if (!buffer[j]) continue; - if (gcallsentences > MAX_CVOXFILESENTENCE) + if (gcallsentences > CVOXFILESENTENCEMAX) { ALERT(at_error, "Too many sentences in sentences.txt!\n"); break; @@ -1367,10 +1369,10 @@ void SENTENCEG_Init() buffer[j] = 0; const char *pString = buffer + i; - if (strlen(pString) >= MAX_CBSENTENCENAME) - ALERT(at_warning, "Sentence %s longer than %d letters\n", pString, MAX_CBSENTENCENAME - 1); + if (strlen(pString) >= CBSENTENCENAME_MAX) + ALERT(at_warning, "Sentence %s longer than %d letters\n", pString, CBSENTENCENAME_MAX - 1); - strncpy(gszallsentencenames[gcallsentences++], pString, MAX_CBSENTENCENAME); + strncpy(gszallsentencenames[gcallsentences++], pString, CBSENTENCENAME_MAX); j--; if (j <= i) @@ -1401,7 +1403,7 @@ void SENTENCEG_Init() break; } - strncpy(rgsentenceg[isentencegs].szgroupname, &(buffer[i]), MAX_CBSENTENCENAME); + strncpy(rgsentenceg[isentencegs].szgroupname, &(buffer[i]), CBSENTENCENAME_MAX); rgsentenceg[isentencegs].count = 1; strncpy(szgroup, &(buffer[i]), 64); @@ -1526,9 +1528,11 @@ void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname) // Used to detect the texture the player is standing on, map the // texture name to a material type. Play footstep sound based // on material type. -unsigned int gcTextures = 0; -char grgszTextureName[MAX_CTEXTURES][MAX_CBTEXTURENAME]; // texture names -char grgchTextureType[MAX_CTEXTURES]; // parallel array of texture types +#define CTEXTURESMAX 512 // max number of textures loaded + +int gcTextures = 0; +char grgszTextureName[CTEXTURESMAX][CBTEXTURENAMEMAX]; // texture names +char grgchTextureType[CTEXTURESMAX]; // parallel array of texture types // given texture name, find texture type // if not found, return type 'concrete' @@ -1540,9 +1544,9 @@ char TEXTURETYPE_Find(char *name) { // CONSIDER: pre-sort texture names and perform faster binary search here - for (unsigned int i = 0; i < gcTextures; i++) + for (int i = 0; i < gcTextures; i++) { - if (!_strnicmp(name, &(grgszTextureName[i][0]), MAX_CBTEXTURENAME - 1)) + if (!_strnicmp(name, &(grgszTextureName[i][0]), CBTEXTURENAMEMAX - 1)) return (grgchTextureType[i]); } @@ -1605,7 +1609,7 @@ float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int pTextureName++; // '}}' strncpy(szbuffer, pTextureName, sizeof(szbuffer) ); - szbuffer[MAX_CBTEXTURENAME - 1] = 0; + szbuffer[CBTEXTURENAMEMAX - 1] = 0; // ALERT ( at_console, "texture hit: %s\n", szbuffer); @@ -1807,9 +1811,8 @@ void CSpeaker ::Spawn(void) Precache(); } - -constexpr float ANNOUNCE_MINUTES_MIN = 0.25; -constexpr float ANNOUNCE_MINUTES_MAX = 2.25; +#define ANNOUNCE_MINUTES_MIN 0.25 +#define ANNOUNCE_MINUTES_MAX 2.25 static float g_talkWaitTime = 0.0f; // time delay until it's ok to speak: used so that two NPCs don't talk at once void CSpeaker ::Precache(void) @@ -1912,7 +1915,7 @@ void CSpeaker ::ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP { int fActive = (pev->nextthink > 0.0); - // fActive is true only if an announcement is pending + // fActive is TRUE only if an announcement is pending if (useType != USE_TOGGLE) { @@ -1960,7 +1963,7 @@ void CSpeaker ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "preset")) { m_preset = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); diff --git a/src/game/server/hl/soundent.cpp b/src/game/server/hl/soundent.cpp index 705924691..4ec6aa2b9 100644 --- a/src/game/server/hl/soundent.cpp +++ b/src/game/server/hl/soundent.cpp @@ -48,29 +48,29 @@ void CSound :: Reset ( void ) } //========================================================= -// FIsSound - returns true if the sound is an Audible sound +// FIsSound - returns TRUE if the sound is an Audible sound //========================================================= BOOL CSound :: FIsSound ( void ) { if ( m_iType & ( bits_SOUND_COMBAT | bits_SOUND_WORLD | bits_SOUND_PLAYER | bits_SOUND_DANGER ) ) { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= -// FIsScent - returns true if the sound is actually a scent +// FIsScent - returns TRUE if the sound is actually a scent //========================================================= BOOL CSound :: FIsScent ( void ) { if ( m_iType & ( bits_SOUND_CARCASS | bits_SOUND_MEAT | bits_SOUND_GARBAGE ) ) { - return true; + return TRUE; } - return false; + return FALSE; } //========================================================= @@ -102,7 +102,7 @@ void CSoundEnt :: Think ( void ) while ( iSound != SOUNDLIST_EMPTY ) { - if ( m_SoundPool[ iSound ].m_flExpireTime <= gpGlobals->time && (int)m_SoundPool[ iSound ].m_flExpireTime != SOUND_NEVER_EXPIRE ) + if ( m_SoundPool[ iSound ].m_flExpireTime <= gpGlobals->time && m_SoundPool[ iSound ].m_flExpireTime != SOUND_NEVER_EXPIRE ) { int iNext = m_SoundPool[ iSound ].m_iNext; @@ -272,11 +272,11 @@ void CSoundEnt :: Initialize ( void ) if ( CVAR_GET_FLOAT("displaysoundlist") == 1 ) { - m_fShowReport = true; + m_fShowReport = TRUE; } else { - m_fShowReport = false; + m_fShowReport = FALSE; } } @@ -286,8 +286,8 @@ void CSoundEnt :: Initialize ( void ) //========================================================= int CSoundEnt :: ISoundsInList ( int iListType ) { - unsigned int i; - int iThisSound{}; + int i; + int iThisSound; if ( iListType == SOUNDLISTTYPE_FREE ) { diff --git a/src/game/server/hl/soundent.h b/src/game/server/hl/soundent.h index 8ac6faa38..49e943a49 100644 --- a/src/game/server/hl/soundent.h +++ b/src/game/server/hl/soundent.h @@ -18,28 +18,27 @@ // lists. //========================================================= -constexpr int MAX_WORLD_SOUNDS = 64; // maximum number of sounds handled by the world at one time. - - -enum { - bits_SOUND_NONE = 0, - bits_SOUND_COMBAT = (1 << 0), // gunshots, explosions - bits_SOUND_WORLD = (1 << 1), // door opening/closing, glass breaking - bits_SOUND_PLAYER = (1 << 2), // all noises generated by player. walking, shooting, falling, splashing - bits_SOUND_CARCASS = (1 << 3), // dead body - bits_SOUND_MEAT = (1 << 4), // gib or pork chop - bits_SOUND_DANGER = (1 << 5), // pending danger. Grenade that is about to explode, explosive barrel that is damaged, falling crate - bits_SOUND_GARBAGE = (1 << 6), // trash cans, banana peels, old fast food bags. - bits_SOUND_WALKING = (1 << 7), // MasterSword: Just walking/moving - bits_ALL_SOUNDS = 0xFFFFFFFF -}; +#define MAX_WORLD_SOUNDS 64 // maximum number of sounds handled by the world at one time. + +#define bits_SOUND_NONE 0 +#define bits_SOUND_COMBAT (1 << 0) // gunshots, explosions +#define bits_SOUND_WORLD (1 << 1) // door opening/closing, glass breaking +#define bits_SOUND_PLAYER (1 << 2) // all noises generated by player. walking, shooting, falling, splashing +#define bits_SOUND_CARCASS (1 << 3) // dead body +#define bits_SOUND_MEAT (1 << 4) // gib or pork chop +#define bits_SOUND_DANGER (1 << 5) // pending danger. Grenade that is about to explode, explosive barrel that is damaged, falling crate +#define bits_SOUND_GARBAGE (1 << 6) // trash cans, banana peels, old fast food bags. +#define bits_SOUND_WALKING (1 << 7) // MasterSword: Just walking/moving + +#define bits_ALL_SOUNDS 0xFFFFFFFF + +#define SOUNDLIST_EMPTY -1 + +#define SOUNDLISTTYPE_FREE 1 // identifiers passed to functions that can operate on either list, to indicate which list to operate on. +#define SOUNDLISTTYPE_ACTIVE 2 + +#define SOUND_NEVER_EXPIRE -1 // with this set as a sound's ExpireTime, the sound will never expire. -enum { - SOUNDLIST_EMPTY = -1, - SOUNDLISTTYPE_FREE = 1, // identifiers passed to functions that can operate on either list, to indicate which list to operate on. - SOUNDLISTTYPE_ACTIVE = 2, - SOUND_NEVER_EXPIRE = -1 // with this set as a sound's ExpireTime, the sound will never expire. -}; //========================================================= // CSound - an instance of a sound in the world. //========================================================= diff --git a/src/game/server/hl/spectator.cpp b/src/game/server/hl/spectator.cpp index 4c8b62e29..c359bd911 100644 --- a/src/game/server/hl/spectator.cpp +++ b/src/game/server/hl/spectator.cpp @@ -74,7 +74,7 @@ void CBaseSpectator::SpectatorImpulseCommand(void) // Start at the current goal, skip the world, and stop if we looped // back around - bFound = false; + bFound = FALSE; while (1) { pCurrentGoal = FIND_ENTITY_BY_CLASSNAME(pCurrentGoal, "info_player_deathmatch"); @@ -87,7 +87,7 @@ void CBaseSpectator::SpectatorImpulseCommand(void) // Found a non-world entity, set success, otherwise, look for the next one. if (!FNullEnt(pCurrentGoal)) { - bFound = true; + bFound = TRUE; break; } } @@ -98,7 +98,7 @@ void CBaseSpectator::SpectatorImpulseCommand(void) pGoal = pCurrentGoal; UTIL_SetOrigin(pev, pGoal->v.origin); pev->angles = pGoal->v.angles; - pev->fixangle = false; + pev->fixangle = FALSE; break; default: ALERT(at_console, "Unknown spectator impulse\n"); diff --git a/src/game/server/hl/subs.cpp b/src/game/server/hl/subs.cpp index d5a840a84..2584b45ec 100644 --- a/src/game/server/hl/subs.cpp +++ b/src/game/server/hl/subs.cpp @@ -71,7 +71,7 @@ void CBaseDMStart::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "master")) { pev->netname = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CPointEntity::KeyValue(pkvd); @@ -80,6 +80,7 @@ void CBaseDMStart::KeyValue(KeyValueData *pkvd) BOOL CBaseDMStart::IsTriggered(CBaseEntity *pEntity) { BOOL master = UTIL_IsMasterTriggered(pev->netname, pEntity); + return master; } @@ -101,7 +102,7 @@ void CBaseEntity::UpdateOnRemove(void) { // this entity was a LinkEnt in the world node graph, so we must remove it from // the graph since we are removing it from the world. - for (unsigned int i = 0; i < WorldGraph.m_cLinks; i++) + for (int i = 0; i < WorldGraph.m_cLinks; i++) { if (WorldGraph.m_pLinkPool[i].m_pLinkEnt == pev) { @@ -160,12 +161,12 @@ void CBaseDelay ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "delay")) { m_flDelay = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "killtarget")) { m_iszKillTarget = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else { @@ -208,20 +209,31 @@ void FireTargets(const char* targetName, CBaseEntity* pActivator, CBaseEntity* p ALERT(at_aiconsole, "Firing: (%s)\n", targetName); - //NOV2015_05 let GM capture triggers + +#ifndef AS_DISABLED // Updated to use AngelScript instead of MSScript for game triggers - #ifdef VALVE_DLL CAngelScriptManager* pASManager = CAngelScriptManager::Instance(); if (pASManager && pASManager->IsInitialized()) { std::vector params; params.push_back(targetName); - + // Call AngelScript GameMaster function // This will be handled by MS::GameTriggered in GameMasterMapTransitions.as pASManager->CallGlobalFunctionWithParams("GameTriggered", params); } - #endif +#else + //NOV2015_05 let GM capture triggers + CBaseEntity* pGameMasterEnt = UTIL_FindEntityByString(NULL, "netname", msstring("-") + "game_master"); + IScripted* pGMScript = (pGameMasterEnt ? pGameMasterEnt->GetScripted() : NULL); + if (pGMScript) + { + static msstringlist Params; + Params.clearitems(); + Params.add(targetName); + pGMScript->CallScriptEvent("game_triggered", &Params); + } +#endif edict_t* pentTarget = NULL; for (;;) @@ -394,22 +406,22 @@ void CBaseToggle::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "lip")) { m_flLip = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "wait")) { m_flWait = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "master")) { m_sMaster = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "distance")) { m_flMoveDistance = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseDelay::KeyValue(pkvd); @@ -468,9 +480,9 @@ void CBaseToggle ::LinearMoveDone(void) BOOL CBaseToggle ::IsLockedByMaster(void) { if (m_sMaster && !UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - return true; + return TRUE; else - return false; + return FALSE; } /* @@ -559,7 +571,7 @@ float CBaseToggle ::AxisDelta(int flags, const Vector &angle1, const Vector &ang ============= FEntIsVisible -returns true if the passed entity is visible to caller, even if not infront () +returns TRUE if the passed entity is visible to caller, even if not infront () ============= */ BOOL FEntIsVisible( @@ -573,10 +585,10 @@ BOOL FEntIsVisible( UTIL_TraceLine(vecSpot1, vecSpot2, ignore_monsters, ENT(pev), &tr); if (tr.fInOpen && tr.fInWater) - return false; // sight line crossed contents + return FALSE; // sight line crossed contents if (tr.flFraction == 1) - return true; + return TRUE; - return false; + return FALSE; } diff --git a/src/game/server/hl/trains.h b/src/game/server/hl/trains.h index e054da237..69be4f146 100644 --- a/src/game/server/hl/trains.h +++ b/src/game/server/hl/trains.h @@ -15,45 +15,25 @@ #ifndef TRAINS_H #define TRAINS_H -enum train_state_e { - - TRAIN_ACTIVE = 0x80, - TRAIN_NEW = 0xc0, - TRAIN_OFF = 0x00, - TRAIN_NEUTRAL = 0x01, - TRAIN_SLOW = 0x02, - TRAIN_MEDIUM = 0x03, - TRAIN_FAST = 0x04, - TRAIN_BACK = 0x05 - -}; - // Tracktrain spawn flags -enum sf_tracktrain_e { - SF_TRACKTRAIN_NOPITCH = 0x0001, - SF_TRACKTRAIN_NOCONTROL = 0x0002, - SF_TRACKTRAIN_FORWARDONLY = 0x0004, - SF_TRACKTRAIN_PASSABLE = 0x0008, - SF_TRACKTRAIN_NOYAW = 0x0010, //APR2008a - No Yaw option for Tracktrain -}; +#define SF_TRACKTRAIN_NOPITCH 0x0001 +#define SF_TRACKTRAIN_NOCONTROL 0x0002 +#define SF_TRACKTRAIN_FORWARDONLY 0x0004 +#define SF_TRACKTRAIN_PASSABLE 0x0008 +#define SF_TRACKTRAIN_NOYAW 0x0010 //APR2008a - No Yaw option for Tracktrain // Spawnflag for CPathTrack - -enum sf_cpathtrack_e { - SF_PATH_DISABLED = 0x00000001, - SF_PATH_FIREONCE = 0x00000002, - SF_PATH_ALTREVERSE = 0x00000004, - SF_PATH_DISABLE_TRAIN = 0x00000008, - SF_PATH_ALTERNATE = 0x00008000 -}; +#define SF_PATH_DISABLED 0x00000001 +#define SF_PATH_FIREONCE 0x00000002 +#define SF_PATH_ALTREVERSE 0x00000004 +#define SF_PATH_DISABLE_TRAIN 0x00000008 +#define SF_PATH_ALTERNATE 0x00008000 // Spawnflags of CPathCorner +#define SF_CORNER_WAITFORTRIG 0x001 +#define SF_CORNER_TELEPORT 0x002 +#define SF_CORNER_FIREONCE 0x004 -enum sf_cpath_corner_e { - SF_CORNER_WAITFORTRIG = 0x001, - SF_CORNER_TELEPORT = 0x002, - SF_CORNER_FIREONCE = 0x004 -}; //#define PATH_SPARKLE_DEBUG 1 // This makes a particle effect around path_track entities for debugging class CPathTrack : public CPointEntity { diff --git a/src/game/server/hl/util.cpp b/src/game/server/hl/util.cpp index b2d908be5..0ffc2c035 100644 --- a/src/game/server/hl/util.cpp +++ b/src/game/server/hl/util.cpp @@ -316,7 +316,7 @@ TYPEDESCRIPTION gEntvarsDescription[] = DEFINE_ENTITY_FIELD(radsuit_finished, FIELD_TIME), }; -constexpr unsigned int ENTVARS_COUNT = (sizeof(gEntvarsDescription) / sizeof(gEntvarsDescription[0])); +#define ENTVARS_COUNT (sizeof(gEntvarsDescription) / sizeof(gEntvarsDescription[0])) #ifdef DEBUG edict_t *DBG_EntOfVars(const entvars_t *pev) @@ -683,7 +683,7 @@ void UTIL_DoTokenScriptEvent(const char *tokenevents, CBaseEntity *pTarget) TokenizeString(m_scriptevent.c_str(), Tokens); if (Tokens.size() > 1) { - for (unsigned int i = 0; i < Tokens.size(); i++) + for (int i = 0; i < Tokens.size(); i++) { if (i > 0) Params.add(Tokens[i].c_str()); @@ -711,7 +711,7 @@ void UTIL_DoTokenScriptEvent(const char *tokenevents, CBaseEntity *pTarget) Params.clearitems(); if (Tokens.size() > 1) { - for (unsigned int i = 0; i < Tokens.size(); i++) + for (int i = 0; i < Tokens.size(); i++) { if (i > 0) Params.add(Tokens[i].c_str()); @@ -992,13 +992,7 @@ void UTIL_MakeAimVectors(const Vector &vecAngles) MAKE_VECTORS(rgflVec); } -//#define SWAP(a, b, temp) ((temp) = (a), (a) = (b), (b) = (temp)) -template -inline void SWAP (Type &a, Type &b, Type &temp) { - temp = a; - a = b; - b = temp; -} +#define SWAP(a, b, temp) ((temp) = (a), (a) = (b), (b) = (temp)) void UTIL_MakeInvVectors(const Vector &vec, globalvars_t *pgv) { @@ -1064,7 +1058,7 @@ void UTIL_ScreenShake(const Vector ¢er, float amplitude, float frequency, fl { int i; float localAmplitude; - ScreenShake shake{}; + ScreenShake shake; shake.duration = FixedUnsigned16(duration, 1 << 12); // 4.12 fixed shake.frequency = FixedUnsigned16(frequency, 1 << 8); // 8.8 fixed @@ -1345,12 +1339,12 @@ void UTIL_TraceLine(const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTER void UTIL_TraceLine(const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr) { - TRACE_LINE(vecStart, vecEnd, (igmon == ignore_monsters ? true : false), pentIgnore, ptr); + TRACE_LINE(vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE), pentIgnore, ptr); } void UTIL_TraceHull(const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, int hullNumber, edict_t *pentIgnore, TraceResult *ptr) { - TRACE_HULL(vecStart, vecEnd, (igmon == ignore_monsters ? true : false), hullNumber, pentIgnore, ptr); + TRACE_HULL(vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE), hullNumber, pentIgnore, ptr); } void UTIL_TraceModel(const Vector &vecStart, const Vector &vecEnd, int hullNumber, edict_t *pentModel, TraceResult *ptr) @@ -1502,15 +1496,15 @@ BOOL UTIL_ShouldShowBlood(int color) if (color == BLOOD_COLOR_RED) { if (CVAR_GET_FLOAT("violence_hblood") != 0) - return true; + return TRUE; } else { if (CVAR_GET_FLOAT("violence_ablood") != 0) - return true; + return TRUE; } } - return false; + return FALSE; } int UTIL_PointContents(const Vector &vec) @@ -1737,16 +1731,16 @@ BOOL UTIL_TeamsMatch(const char *pTeamName1, const char *pTeamName2) { // Everyone matches unless it's teamplay if (!g_pGameRules->IsTeamplay()) - return true; + return TRUE; // Both on a team? if (*pTeamName1 != 0 && *pTeamName2 != 0) { if (!_stricmp(pTeamName1, pTeamName2)) // Same Team? - return true; + return TRUE; } - return false; + return FALSE; } void UTIL_StringToVector(float *pVector, const char *pString) @@ -1951,8 +1945,8 @@ void UTIL_Remove(CBaseEntity *pEntity) BOOL UTIL_IsValidEntity(edict_t *pent) { if (!pent || pent->free || (pent->v.flags & FL_KILLME)) - return false; - return true; + return FALSE; + return TRUE; } void UTIL_PrecacheOther(const char *szClassname) @@ -2185,10 +2179,10 @@ unsigned short CSaveRestoreBuffer ::TokenHash(const char *pszToken) for (int i = 0; i < m_pdata->tokenCount; i++) { #if _DEBUG - static qboolean beentheredonethat = false; + static qboolean beentheredonethat = FALSE; if (i > 50 && !beentheredonethat) { - beentheredonethat = true; + beentheredonethat = TRUE; ALERT(at_error, "CSaveRestoreBuffer :: TokenHash() is getting too full!"); } #endif @@ -2381,7 +2375,7 @@ void EntvarsKeyvalue(entvars_t *pev, KeyValueData *pkvd) ALERT(at_error, "Bad field in entity!!\n"); break; } - pkvd->fHandled = true; + pkvd->fHandled = TRUE; return; } } @@ -2509,9 +2503,9 @@ void CSave ::BufferString(char *pdata, int len) BufferData(&c, 1); // Write a null terminator } -int CSave ::DataEmpty(const char *pdata, unsigned int size) +int CSave ::DataEmpty(const char *pdata, int size) { - for (unsigned int i = 0; i < size; i++) + for (int i = 0; i < size; i++) { if (pdata[i]) return 0; diff --git a/src/game/server/hl/util.h b/src/game/server/hl/util.h index 0a6557663..4ce391b79 100644 --- a/src/game/server/hl/util.h +++ b/src/game/server/hl/util.h @@ -61,26 +61,9 @@ inline edict_t *FIND_ENTITY_BY_TARGET(edict_t *entStart, const char *pszName) ENGINE_FPRINTF(pf, "\"%s\" \"%f %f %f\"\n", szKeyName, flX, flY, flZ) // Keeps clutter down a bit, when using a float as a bit-vector - -template -void SetBits(Type& vector, const int bits) { - vector = (int)vector | bits; -} - -template -void ClearBits(Type& vector, const int bits) { - vector = (int)vector & ~bits; -} - -template -bool FBitSet(const Type& vector, const int bit) { - return (int)vector & bit; -} - - -//#define SetBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) | (bits)) -//#define ClearBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) & ~(bits)) -//#define FBitSet(flBitVector, bit) ((int)(flBitVector) & (bit)) +#define SetBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) | (bits)) +#define ClearBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) & ~(bits)) +#define FBitSet(flBitVector, bit) ((int)(flBitVector) & (bit)) // Makes these more explicit, and easier to find #define FILE_GLOBAL static @@ -88,7 +71,7 @@ bool FBitSet(const Type& vector, const int bit) { // Until we figure out why "const" gives the compiler problems, we'll just have to use // this bogus "empty" define to mark things as constant. -//#define CONSTANT +#define CONSTANT // More explicit than "int" typedef int EOFFSET; @@ -97,6 +80,10 @@ typedef int EOFFSET; typedef int BOOL; // In case this ever changes +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + // Keeps clutter down a bit, when declaring external entity/global method prototypes #define DECLARE_GLOBAL_METHOD(MethodName) extern void UTIL_DLLEXPORT MethodName( void ) #define GLOBAL_METHOD(funcname) void UTIL_DLLEXPORT funcname(void) @@ -162,7 +149,7 @@ inline entvars_t *VARS(entvars_t *pev) { return pev; } inline entvars_t *VARS(edict_t *pent) { if (!pent) - return nullptr; + return NULL; return &pent->v; } @@ -177,34 +164,34 @@ inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float* pOrigin, entv } // Testing the three types of "entity" for nullity -constexpr int eoNullEntity = 0; +#define eoNullEntity 0 inline BOOL FNullEnt(EOFFSET eoffset) { return eoffset == 0; } -inline BOOL FNullEnt(const edict_t *pent) { return pent == nullptr || FNullEnt(OFFSET(pent)); } -inline BOOL FNullEnt(entvars_t *pev) { return pev == nullptr || FNullEnt(OFFSET(pev)); } +inline BOOL FNullEnt(const edict_t *pent) { return pent == NULL || FNullEnt(OFFSET(pent)); } +inline BOOL FNullEnt(entvars_t *pev) { return pev == NULL || FNullEnt(OFFSET(pev)); } // Testing strings for nullity -constexpr int iStringNull = 0; +#define iStringNull 0 inline BOOL FStringNull(int iString) { return iString == iStringNull; } -constexpr int cchMapNameMost = 32; +#define cchMapNameMost 32 // Dot products for view cone checking -constexpr float VIEW_FIELD_FULL = -1.0f; // +-180 degrees -constexpr float VIEW_FIELD_WIDE = -0.7f; // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks -constexpr float VIEW_FIELD_NARROW = 0.7f; // +-45 degrees, more narrow check used to set up ranged attacks -constexpr float VIEW_FIELD_ULTRA_NARROW = 0.9f; // +-25 degrees, more narrow check used to set up ranged attacks +#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees +#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks +#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks +#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks // All monsters need this data -constexpr int DONT_BLEED = -1; -constexpr byte BLOOD_COLOR_RED = (byte)247; -constexpr byte BLOOD_COLOR_YELLOW = (byte)195; -constexpr byte BLOOD_COLOR_GREEN = BLOOD_COLOR_YELLOW; +#define DONT_BLEED -1 +#define BLOOD_COLOR_RED (byte)247 +#define BLOOD_COLOR_YELLOW (byte)195 +#define BLOOD_COLOR_GREEN BLOOD_COLOR_YELLOW typedef enum { @@ -264,12 +251,7 @@ extern CBaseEntity *UTIL_FindEntityGeneric(const char *szName, Vector &vecSrc, f // Index is 1 based extern CBaseEntity *UTIL_PlayerByIndex(int playerIndex); -//#define UTIL_EntitiesInPVS(edict_t * pent) (*g_engfuncs.pfnEntitiesInPVS)(pent) - -inline edict_t* UTIL_EntitiesInPVS(edict_t* pent) { - return g_engfuncs.pfnEntitiesInPVS(pent); -} - +#define UTIL_EntitiesInPVS(pent) (*g_engfuncs.pfnEntitiesInPVS)(pent) extern void UTIL_MakeVectors(const Vector &vecAngles); // Pass in an array of pointers and an array size, it fills the array and returns the number inserted @@ -314,24 +296,20 @@ typedef enum dont_ignore_monsters = 0, missile = 2 } IGNORE_MONSTERS; - typedef enum { ignore_glass = 1, dont_ignore_glass = 0 } IGNORE_GLASS; - extern void UTIL_TraceLine(const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr); extern void UTIL_TraceLine(const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr); - -enum hull_e +enum { point_hull = 0, human_hull = 1, large_hull = 2, head_hull = 3 }; - extern void UTIL_TraceHull(const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, int hullNumber, edict_t *pentIgnore, TraceResult *ptr); extern TraceResult UTIL_GetGlobalTrace(void); extern void UTIL_TraceModel(const Vector &vecStart, const Vector &vecEnd, int hullNumber, edict_t *pentModel, TraceResult *ptr); @@ -373,8 +351,8 @@ extern void UTIL_BubbleTrail(Vector from, Vector to, int count); extern void UTIL_PrecacheOther(const char *szClassname); // prints a message to each client -extern void UTIL_ClientPrintAll(int msg_dest, const char *msg_name, const char *param1 = nullptr, const char *param2 = nullptr, const char *param3 = nullptr, const char *param4 = nullptr); -inline void UTIL_CenterPrintAll(const char *msg_name, const char *param1 = nullptr, const char *param2 = nullptr, const char *param3 = nullptr, const char *param4 = nullptr) +extern void UTIL_ClientPrintAll(int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL); +inline void UTIL_CenterPrintAll(const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL) { UTIL_ClientPrintAll(HUD_PRINTCENTER, msg_name, param1, param2, param3, param4); } @@ -388,7 +366,7 @@ extern CBasePlayer* UTIL_PlayerBySteamID(ID64 steamID64); extern ID64 UTIL_ComputeSteamID64(const char* id, char sep = ':'); // prints messages through the HUD -extern void ClientPrint(entvars_t *client, int msg_dest, const char *msg_name, const char *param1 = nullptr, const char *param2 = nullptr, const char *param3 = nullptr, const char *param4 = nullptr); +extern void ClientPrint(entvars_t *client, int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL); // prints a message to the HUD say (chat) extern void UTIL_SayText(const char *pText, CBaseEntity *pEntity); @@ -450,121 +428,101 @@ extern DLL_GLOBAL const Vector g_vecZero; // // Un-comment only as needed // +#define LANGUAGE_ENGLISH 0 +#define LANGUAGE_GERMAN 1 +#define LANGUAGE_FRENCH 2 +#define LANGUAGE_BRITISH 3 -enum language_setting_e { - LANGUAGE_ENGLISH = 0, - LANGUAGE_GERMAN = 1, - LANGUAGE_FRENCH = 2, - LANGUAGE_BRITISH = 3 -}; extern DLL_GLOBAL int g_Language; -enum amient_sound_e { - AMBIENT_SOUND_STATIC = 0,// medium radius attenuation - AMBIENT_SOUND_EVERYWHERE = 1, - AMBIENT_SOUND_SMALLRADIUS = 2, - AMBIENT_SOUND_MEDIUMRADIUS = 4, - AMBIENT_SOUND_LARGERADIUS = 8, - AMBIENT_SOUND_START_SILENT = 16, - AMBIENT_SOUND_NOT_LOOPING = 32 -}; - -enum speaker_start_e { - SPEAKER_START_SILENT = 1 // wait for trigger 'on' to start announcements -}; +#define AMBIENT_SOUND_STATIC 0 // medium radius attenuation +#define AMBIENT_SOUND_EVERYWHERE 1 +#define AMBIENT_SOUND_SMALLRADIUS 2 +#define AMBIENT_SOUND_MEDIUMRADIUS 4 +#define AMBIENT_SOUND_LARGERADIUS 8 +#define AMBIENT_SOUND_START_SILENT 16 +#define AMBIENT_SOUND_NOT_LOOPING 32 + +#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements + +#define SND_SPAWNING (1 << 8) // duplicated in protocol.h we're spawing, used in some cases for ambients +#define SND_STOP (1 << 5) // duplicated in protocol.h stop sound +#define SND_CHANGE_VOL (1 << 6) // duplicated in protocol.h change sound vol +#define SND_CHANGE_PITCH (1 << 7) // duplicated in protocol.h change sound pitch + +#define LFO_SQUARE 1 +#define LFO_TRIANGLE 2 +#define LFO_RANDOM 3 + +// 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_PENDULUM_AUTO_RETURN 16 +#define SF_PENDULUM_PASSABLE 32 + +#define SF_BRUSH_ROTATE_SMALLRADIUS 128 +#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256 +#define SF_BRUSH_ROTATE_LARGERADIUS 512 + +#define PUSH_BLOCK_ONLY_X 1 +#define PUSH_BLOCK_ONLY_Y 2 + +#define VEC_HULL_MIN Vector(-16, -16, -36) +#define VEC_HULL_MAX Vector(16, 16, 36) +#define VEC_HUMAN_HULL_MIN Vector(-16, -16, 0) +#define VEC_HUMAN_HULL_MAX Vector(16, 16, 72) +#define VEC_HUMAN_HULL_DUCK Vector(16, 16, 36) + +#define VEC_VIEW Vector(0, 0, 28) + +#define VEC_DUCK_HULL_MIN Vector(-16, -16, -18) +#define VEC_DUCK_HULL_MAX Vector(16, 16, 18) +#define VEC_DUCK_VIEW Vector(0, 0, 12) + +#define SVC_TEMPENTITY 23 +#define SVC_INTERMISSION 30 +#define SVC_CDTRACK 32 +#define SVC_WEAPONANIM 35 +#define SVC_ROOMTYPE 37 +#define SVC_DIRECTOR 51 -enum sound_cmd_e { - SND_STOP = (1 << 5), // duplicated in protocol.h stop sound - SND_CHANGE_VOL = (1 << 6), // duplicated in protocol.h change sound vol - SND_CHANGE_PITCH = (1 << 7), // duplicated in protocol.h change sound pitch - SND_SPAWNING = (1 << 8) // duplicated in protocol.h we're spawing, used in some cases for ambients -}; +// triggers +#define SF_TRIGGER_ALLOWMONSTERS 1 // monsters allowed to fire this trigger +#define SF_TRIGGER_NOCLIENTS 2 // players not allowed to fire this trigger +#define SF_TRIGGER_PUSHABLES 4 // only pushables can fire this trigger -enum lfo_wave_e { - LFO_SQUARE = 1, - LFO_TRIANGLE = 2, - LFO_RANDOM = 3 -}; +// 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 -enum sf_brush_e { - SF_BRUSH_ROTATE_Y_AXIS = 0, - SF_BRUSH_ROTATE_INSTANT = 1, - SF_BRUSH_ROTATE_BACKWARDS = 2, - SF_BRUSH_ROTATE_Z_AXIS = 4, - SF_BRUSH_ROTATE_X_AXIS = 8, - SF_PENDULUM_AUTO_RETURN = 16, - SF_PENDULUM_PASSABLE = 32, - SF_BRUSH_ROTATE_SMALLRADIUS = 128, - SF_BRUSH_ROTATE_MEDIUMRADIUS = 256, - SF_BRUSH_ROTATE_LARGERADIUS = 512 -}; +// func_pushable (it's also func_breakable, so don't collide with those flags) +#define SF_PUSH_BREAKABLE 128 +#define SF_LIGHT_START_OFF 1 -enum push_block_e { - PUSH_BLOCK_ONLY_X = 1, - PUSH_BLOCK_ONLY_Y = 2 -}; +#define SPAWNFLAG_NOMESSAGE 1 +#define SPAWNFLAG_NOTOUCH 1 +#define SPAWNFLAG_DROIDONLY 4 -constexpr Vector VEC_HULL_MIN = Vector(-16,-16,-36); -constexpr Vector VEC_HULL_MAX = Vector(16, 16, 36); -constexpr Vector VEC_HUMAN_HULL_MIN = Vector(-16, -16, 0); -constexpr Vector VEC_HUMAN_HULL_MAX = Vector(16, 16, 72); -constexpr Vector VEC_HUMAN_HULL_DUCK = Vector(16, 16, 36); -constexpr Vector VEC_VIEW = Vector(0, 0, 28); -constexpr Vector VEC_DUCK_HULL_MIN = Vector(-16, -16, -18); -constexpr Vector VEC_DUCK_HULL_MAX = Vector(16, 16, 18); -constexpr Vector VEC_DUCK_VIEW = Vector(0, 0, 12); - -enum svc_type_e { - SVC_TEMPENTITY = 23, - SVC_INTERMISSION = 30, - SVC_CDTRACK = 32, - SVC_WEAPONANIM = 35, - SVC_ROOMTYPE = 37, - SVC_DIRECTOR = 51 -}; +#define SPAWNFLAG_USEONLY 1 // can't be touched, must be used (buttons) -// triggers +#define TELE_PLAYER_ONLY 1 +#define TELE_SILENT 2 -enum sf_trigger_e { - SF_TRIG_PUSH_ONCE = 1, - SF_TRIGGER_ALLOWMONSTERS = 1, // monsters allowed to fire this trigger - SF_TRIGGER_NOCLIENTS = 2, // players not allowed to fire this trigger - SF_TRIGGER_PUSHABLES = 4 // only pushables can fire this trigger -}; +#define SF_TRIG_PUSH_ONCE 1 -// func breakable -enum sf_func_breakable_e { - SF_BREAK_TRIGGER_ONLY = 1, // may only be broken by trigger - SF_BREAK_TOUCH = 2, // can be 'crashed through' by running player (plate glass) - SF_BREAK_PRESSURE = 4, // can be broken by a player standing on it - SF_PUSH_BREAKABLE = 128, // func_pushable (it's also func_breakable, so don't collide with those flags) - SF_BREAK_CROWBAR = 256 // instant break if hit with crowbar -}; - -enum sf_light_start_e { - SF_LIGHT_START_OFF = 1 -}; - -enum spawnflag_e { - SPAWNFLAG_NOMESSAGE = 1, - SPAWNFLAG_NOTOUCH = 1, - SPAWNFLAG_USEONLY = 1, - SPAWNFLAG_DROIDONLY = 4 -}; - -enum teleport_sound_e { - TELE_PLAYER_ONLY = 1, - TELE_SILENT = 2 -}; // Sound Utilities - // sentence groups -constexpr int MAX_CBSENTENCENAME = 16; -constexpr int MAX_CVOXFILESENTENCE = 1536;// max number of sentences in game. NOTE: this must match CVOXFILESENTENCEMAX in engine\sound.h!!! +#define CBSENTENCENAME_MAX 16 +#define CVOXFILESENTENCEMAX 1536 // max number of sentences in game. NOTE: this must match CVOXFILESENTENCEMAX in engine\sound.h!!! -extern char gszallsentencenames[MAX_CVOXFILESENTENCE][MAX_CBSENTENCENAME]; +extern char gszallsentencenames[CVOXFILESENTENCEMAX][CBSENTENCENAME_MAX]; extern int gcallsentences; int USENTENCEG_Pick(int isentenceg, char *szfound); @@ -582,7 +540,7 @@ int SENTENCEG_Lookup(const char *sample, char *sentencenum); char TEXTURETYPE_Find(char *name); float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int iBulletType); -/*#define MAX_CBTEXTURENAME 13 // only load first n chars of name +/*#define CBTEXTURENAMEMAX 13 // only load first n chars of name #define CHAR_TEX_CONCRETE 'C' // texture types #define CHAR_TEX_METAL 'M' @@ -638,12 +596,9 @@ void EMIT_SOUND_SUIT(edict_t *entity, const char *sample); void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg); void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); - -//these don't look used -/* #define PRECACHE_SOUND_ARRAY(a) \ { \ - for (unsigned int i = 0; i < std::size(a); i++) \ + for (int i = 0; i < std::size(a); i++) \ PRECACHE_SOUND((char *)a[i]); \ } @@ -654,12 +609,10 @@ void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); #define PLAYBACK_EVENT(flags, who, index) PLAYBACK_EVENT_FULL(flags, who, index, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0); #define PLAYBACK_EVENT_DELAY(flags, who, index, delay) PLAYBACK_EVENT_FULL(flags, who, index, delay, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0); -*/ -enum { - GROUP_OP_AND = 0, - GROUP_OP_NAND = 1 -}; +#define GROUP_OP_AND 0 +#define GROUP_OP_NAND 1 + extern int g_groupmask; extern int g_groupop; @@ -682,5 +635,5 @@ float UTIL_SharedRandomFloat(unsigned int seed, float low, float high); float UTIL_WeaponTimeBase(void); //Master Sword -//#include "sharedutil.h" +#include "sharedutil.h" #endif diff --git a/src/game/server/monsters/bodyparts/bodyparts.cpp b/src/game/server/monsters/bodyparts/bodyparts.cpp index 43c1201c0..251258c60 100644 --- a/src/game/server/monsters/bodyparts/bodyparts.cpp +++ b/src/game/server/monsters/bodyparts/bodyparts.cpp @@ -47,7 +47,7 @@ CBodypart *CBodypart::Duplicate(CBodypart *pExistingBodypart) CMSMonster *pOwner = (CMSMonster *)MSInstance( pev->owner ); if( !pOwner ) return flDamage; - for (unsigned int i = 0; i < pOwner->Gear.size(); i++) + for (int i = 0; i < pOwner->Gear.size(); i++) { CGenericItem *pItemWorn = pOwner->Gear[ i ]; @@ -66,7 +66,7 @@ CBodypart *CBodypart::Duplicate(CBodypart *pExistingBodypart) CMSMonster *pOwner = (CMSMonster *)MSInstance( pev->owner ); if( !pOwner ) return flDamage; - for (unsigned int i = 0; i < pOwner->Gear.size(); i++) + for (int i = 0; i < pOwner->Gear.size(); i++) { CGenericItem *Item = *pOwner->Gear[ i ]; if( FBitSet(Item.MSProperties(),ITEM_ARMOR) ) @@ -127,16 +127,16 @@ void CBodypart::Set(int iState, void *vData) } void CBaseBody::Set(int iState, void *vData) { - for (unsigned int i = 0; i < Bodyparts.size(); i++) + for (int i = 0; i < Bodyparts.size(); i++) Bodyparts[i]->Set(iState, vData); } void CBaseBody::Think(CMSMonster *pOwner) { - for (unsigned int b = 0; b < Bodyparts.size(); b++) + for (int b = 0; b < Bodyparts.size(); b++) { int Body = 0; bool Visible = true; - for (unsigned int i = 0; i < pOwner->Gear.size(); i++) + for (int i = 0; i < pOwner->Gear.size(); i++) { if (pOwner->Gear[i]->m_Location <= ITEMPOS_HANDS) continue; @@ -157,13 +157,13 @@ void CBaseBody::Think(CMSMonster *pOwner) CBaseBody *CBaseBody::Duplicate() { CBaseBody &NewBody = *msnew(CBaseBody); - for (unsigned int i = 0; i < Bodyparts.size(); i++) + for (int i = 0; i < Bodyparts.size(); i++) NewBody.Bodyparts[i] = Bodyparts[i]->Duplicate(); return &NewBody; } void CBaseBody::Delete() { - for (unsigned int i = 0; i < Bodyparts.size(); i++) + for (int i = 0; i < Bodyparts.size(); i++) { Bodyparts[i]->SUB_Remove(); Bodyparts.erase(i--); diff --git a/src/game/server/monsters/bodyparts/bodyparts_human.cpp b/src/game/server/monsters/bodyparts/bodyparts_human.cpp index 7d63a766e..1a723d871 100644 --- a/src/game/server/monsters/bodyparts/bodyparts_human.cpp +++ b/src/game/server/monsters/bodyparts/bodyparts_human.cpp @@ -12,7 +12,7 @@ CHumanBodypart *CHumanBodypart::Duplicate() void CHumanBody::Initialize(CBaseEntity *pOwner, void *pvData) { - for (unsigned int i = 0; i < HUMAN_BODYPARTS; i++) + for (int i = 0; i < HUMAN_BODYPARTS; i++) { CHumanBodypart& HumanBodypart = *(CHumanBodypart*)GetClassPtr((CHumanBodypart*)NULL); @@ -27,7 +27,7 @@ void CHumanBody::Initialize(CBaseEntity *pOwner, void *pvData) CBaseBody *CHumanBody::Duplicate() { CHumanBody *NewBody = new CHumanBody; - for (unsigned int i = 0; i < Bodyparts.size(); i++) + for (int i = 0; i < Bodyparts.size(); i++) NewBody->Bodyparts.add(Bodyparts[i]->Duplicate()); return NewBody; diff --git a/src/game/server/monsters/bodyparts/bodyparts_human.h b/src/game/server/monsters/bodyparts/bodyparts_human.h index a047cb215..95e4b550d 100644 --- a/src/game/server/monsters/bodyparts/bodyparts_human.h +++ b/src/game/server/monsters/bodyparts/bodyparts_human.h @@ -1,7 +1,5 @@ - -#ifndef BODYPARTS_HUMAN_H #include "bodyparts.h" -#define BODYPARTS_HUMAN_H + enum { //Human bodyparts @@ -25,5 +23,4 @@ class CHumanBody : public CBaseBody CBaseBody *Duplicate(); }; -int HitGroupToBodyPart(int HitGroup); -#endif \ No newline at end of file +int HitGroupToBodyPart(int HitGroup); \ No newline at end of file diff --git a/src/game/server/monsters/combat.cpp b/src/game/server/monsters/combat.cpp index 337300803..1294fbcda 100644 --- a/src/game/server/monsters/combat.cpp +++ b/src/game/server/monsters/combat.cpp @@ -34,11 +34,9 @@ extern DLL_GLOBAL int g_iSkillLevel; extern Vector VecBModelOrigin(entvars_t *pevBModel); extern entvars_t *g_pevLastInflictor; -enum gib_count_e { - GERMAN_GIB_COUNT = 4, - HUMAN_GIB_COUNT = 6, - ALIEN_GIB_COUNT = 4 -}; +#define GERMAN_GIB_COUNT 4 +#define HUMAN_GIB_COUNT 6 +#define ALIEN_GIB_COUNT 4 // HACKHACK -- The gib velocity equations don't work void CGib ::LimitVelocity(void) @@ -257,9 +255,9 @@ BOOL CBaseMonster ::HasHumanGibs(void) myClass == CLASS_HUMAN_PASSIVE || myClass == CLASS_PLAYER) - return true; + return TRUE; - return false; + return FALSE; } BOOL CBaseMonster ::HasAlienGibs(void) @@ -273,9 +271,9 @@ BOOL CBaseMonster ::HasAlienGibs(void) myClass == CLASS_ALIEN_PREDATOR || myClass == CLASS_ALIEN_PREY) - return true; + return TRUE; - return false; + return FALSE; } void CBaseMonster::FadeMonster(void) @@ -296,7 +294,7 @@ void CBaseMonster::FadeMonster(void) void CBaseMonster ::GibMonster(void) { TraceResult tr; - BOOL gibbed = false; + BOOL gibbed = FALSE; EMIT_SOUND(ENT(pev), CHAN_WEAPON, "common/bodysplat.wav", 1, ATTN_NORM); @@ -310,7 +308,7 @@ void CBaseMonster ::GibMonster(void) CGib::SpawnHeadGib(pev); CGib::SpawnRandomGibs(pev, 4, 1); // throw some human gibs. } - gibbed = true; + gibbed = TRUE; } else if (HasAlienGibs()) { @@ -318,7 +316,7 @@ void CBaseMonster ::GibMonster(void) { CGib::SpawnRandomGibs(pev, 4, 0); // Throw alien gibs } - gibbed = true; + gibbed = TRUE; } if (!IsPlayer()) @@ -359,7 +357,7 @@ Activity CBaseMonster ::GetDeathActivity(void) vecSrc = Center(); - fTriedDirection = false; + fTriedDirection = FALSE; deathActivity = ACT_DIESIMPLE; // in case we can't find any special deaths to do. UTIL_MakeVectors(pev->angles); @@ -378,7 +376,7 @@ Activity CBaseMonster ::GetDeathActivity(void) case HITGROUP_GENERIC: // try to pick a death based on attack direction - fTriedDirection = true; + fTriedDirection = TRUE; if (flDot > 0.3) { @@ -392,7 +390,7 @@ Activity CBaseMonster ::GetDeathActivity(void) default: // try to pick a death based on attack direction - fTriedDirection = true; + fTriedDirection = TRUE; if (flDot > 0.3) { @@ -469,7 +467,7 @@ Activity CBaseMonster ::GetSmallFlinchActivity(void) BOOL fTriedDirection; float flDot; - fTriedDirection = false; + fTriedDirection = FALSE; UTIL_MakeVectors(pev->angles); flDot = DotProduct(gpGlobals->v_forward, g_vecAttackDir * -1); @@ -529,24 +527,24 @@ void CBaseMonster::BecomeDead(void) BOOL CBaseMonster::ShouldGibMonster(int iGib) { if ((iGib == GIB_NORMAL && pev->health < GIB_HEALTH_VALUE) || (iGib == GIB_ALWAYS)) - return true; + return TRUE; - return false; + return FALSE; } void CBaseMonster::CallGibMonster(void) { - BOOL fade = false; + BOOL fade = FALSE; if (HasHumanGibs()) { if (CVAR_GET_FLOAT("violence_hgibs") == 0) - fade = true; + fade = TRUE; } else if (HasAlienGibs()) { if (CVAR_GET_FLOAT("violence_agibs") == 0) - fade = true; + fade = TRUE; } pev->takedamage = DAMAGE_NO; @@ -582,7 +580,7 @@ Killed */ void CBaseMonster ::Killed(entvars_t *pevAttacker, int iGib) { - BOOL fDone = false; + BOOL fDone = FALSE; if (HasMemory(bits_MEMORY_KILLED)) { @@ -1048,7 +1046,7 @@ void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker // iterate on all entities in the vicinity. while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecSrc, flRadius)) != NULL) { - if (static_cast(pEntity->pev->takedamage) != DAMAGE_NO) + if (pEntity->pev->takedamage != DAMAGE_NO) { // UNDONE: this should check a damage mask, not an ignore if (iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore) @@ -1167,11 +1165,11 @@ bool CBaseEntity ::FInViewCone(CBaseEntity *pEntity, float m_flFieldOfView) if (flDot > m_flFieldOfView) { - return true; + return TRUE; } else { - return false; + return FALSE; } } @@ -1222,14 +1220,14 @@ BOOL CBaseEntity ::FMVisible(CBaseEntity *pEntity) Vector vecTargetOrigin; if (FBitSet(pEntity->pev->flags, FL_NOTARGET)) - return false; + return FALSE; // don't look through water // Thothie APR2011_29 - WTF not? This is causing issues with players in water /* if ((pev->waterlevel != 3 && pEntity->pev->waterlevel == 3) || (pev->waterlevel == 3 && pEntity->pev->waterlevel == 0)) - return false; + return FALSE; */ vecLookerOrigin = pev->origin + pev->view_ofs; //look through the caller's 'eyes' @@ -1240,13 +1238,13 @@ BOOL CBaseEntity ::FMVisible(CBaseEntity *pEntity) if (tr.flFraction != 1.0) { if (tr.pHit == pEntity->edict()) - return true; //hit my target + return TRUE; //hit my target - return false; // Line of sight is not established + return FALSE; // Line of sight is not established } else { - return true; // line of sight is valid. + return TRUE; // line of sight is valid. } } @@ -1265,11 +1263,11 @@ BOOL CBaseEntity ::FMVisible(const Vector &vecOrigin) if (tr.flFraction != 1.0) { - return false; // Line of sight is not established + return FALSE; // Line of sight is not established } else { - return true; // line of sight is valid. + return TRUE; // line of sight is valid. } } //========================================================= @@ -1283,12 +1281,12 @@ BOOL CBaseEntity ::FVisible(CBaseEntity *pEntity) Vector vecTargetOrigin; if (FBitSet(pEntity->pev->flags, FL_NOTARGET)) - return false; + return FALSE; // don't look through water //if ((pev->waterlevel != 3 && pEntity->pev->waterlevel == 3) // || (pev->waterlevel == 3 && pEntity->pev->waterlevel == 0)) - // return false; + // return FALSE; vecLookerOrigin = pev->origin + pev->view_ofs; //look through the caller's 'eyes' vecTargetOrigin = pEntity->EyePosition(); @@ -1297,11 +1295,11 @@ BOOL CBaseEntity ::FVisible(CBaseEntity *pEntity) if (tr.flFraction != 1.0) { - return false; // Line of sight is not established + return FALSE; // Line of sight is not established } else { - return true; // line of sight is valid. + return TRUE; // line of sight is valid. } } @@ -1320,11 +1318,11 @@ BOOL CBaseEntity ::FVisible(const Vector &vecOrigin) if (tr.flFraction != 1.0) { - return false; // Line of sight is not established + return FALSE; // Line of sight is not established } else { - return true; // line of sight is valid. + return TRUE; // line of sight is valid. } } diff --git a/src/game/server/monsters/corpse.cpp b/src/game/server/monsters/corpse.cpp index ccb709ae0..f0fc5d539 100644 --- a/src/game/server/monsters/corpse.cpp +++ b/src/game/server/monsters/corpse.cpp @@ -28,7 +28,7 @@ void CCorpse::CreateCorpse(CMSMonster* pSource, float LoseGoldPercent) { // if (pSource->pev->effects & EF_NODRAW) return; - pPlayerSource = (pSource->IsPlayer() ? (CBasePlayer*)pSource : NULL); + m_hPlayerSource = (pSource->IsPlayer() ? pSource : NULL); Spawn(); int LoseGold = pSource->m_Gold * (LoseGoldPercent * 0.01); @@ -56,8 +56,8 @@ void CCorpse::CreateCorpse(CMSMonster* pSource, float LoseGoldPercent) float CheckRange = 1024; Vector delta = Vector(CheckRange, CheckRange, CheckRange); CBaseEntity* pEnt[100]; - unsigned int count = UTIL_EntitiesInBox(pEnt, 100, pev->origin - delta, pev->origin + delta, NULL); - for (unsigned int i = 0; i < count; i++) + int count = UTIL_EntitiesInBox(pEnt, 100, pev->origin - delta, pev->origin + delta, NULL); + for (int i = 0; i < count; i++) { //Cut every corpse's expire time in half pCorpse = pEnt[i]; @@ -123,7 +123,7 @@ bool CCorpse::AddItem(CGenericItem* pItem, bool ToHand, bool CheckWeight, int Fo if (!pItem->WearItem()) { pItem->SUB_Remove(); - fReturn = false; + fReturn = FALSE; } } else diff --git a/src/game/server/monsters/corpse.h b/src/game/server/monsters/corpse.h index b326e1ab1..ecb0b720a 100644 --- a/src/game/server/monsters/corpse.h +++ b/src/game/server/monsters/corpse.h @@ -1,20 +1,21 @@ -constexpr const char* SKELETON_MODEL = "models/monsters/skeleton.mdl"; +#define SKELETON_MODEL "models/monsters/skeleton.mdl" class CCorpse : public CMSMonster { public: void CreateCorpse(CMSMonster* pSource, float LoseGoldPercent = 100.0); - //Pass pointer to player down if a player made the corpse - CBasePlayer* pPlayerSource; + //Handle to the player if a player made the corpse + //EHANDLE resolves to NULL once the player's edict is freed (e.g. disconnect), unlike a raw pointer + EHANDLE m_hPlayerSource; //Overridden int ObjectCaps(void) { return FCAP_DONT_SAVE; } - int MSProperties() { return ITEM_MS_CORPSE; } + int MSProperties() { return MS_CORPSE; } void Spawn(); bool AddItem(CGenericItem* pItem, bool ToHand, bool CheckWeight, int ForceHand = -1); bool RemoveItem(CGenericItem* pItem); - BOOL HasHumanGibs() { return true; } - BOOL HasAlienGibs() { return false; } + BOOL HasHumanGibs() { return TRUE; } + BOOL HasAlienGibs() { return FALSE; } int BloodColor(void) { return BLOOD_COLOR_RED; } bool ShouldGibMonster(int iGib) { return true; } int Classify() { return CLASS_NONE; } diff --git a/src/game/server/monsters/monsteranimation.cpp b/src/game/server/monsters/monsteranimation.cpp index e96dd8aec..6ca458af6 100644 --- a/src/game/server/monsters/monsteranimation.cpp +++ b/src/game/server/monsters/monsteranimation.cpp @@ -2,13 +2,13 @@ #include "weapons/weapons.h" //Shorten things up a lot - -//#define LookupSequence m_pOwner->LookupSequence +#define m_Activity m_pOwner->m_Activity +#define m_fSequenceFinished m_pOwner->m_fSequenceFinished +#define LookupSequence m_pOwner->LookupSequence #undef Wielded - - -//#define CHWielded ((m_pPlayer->Hand[m_pPlayer->iCurrentHand]) ? m_pPlayer->Hand[m_pPlayer->iCurrentHand]->Wielded() : (m_pPlayer->PlayerHands ? m_pPlayer->PlayerHands->Wielded() : false)) +#undef CHWielded +#define CHWielded ((m_pPlayer->Hand[m_pPlayer->iCurrentHand]) ? m_pPlayer->Hand[m_pPlayer->iCurrentHand]->Wielded() : (m_pPlayer->PlayerHands ? m_pPlayer->PlayerHands->Wielded() : FALSE)) CAnimation *CAnimation::ChangeTo(MONSTER_ANIM NewAnim) { @@ -33,7 +33,7 @@ bool CAnimation ::SetAnim(const char* pszSequence) if (!pszSequence || !pszSequence[0]) return false; - int animDesired = m_pOwner->LookupSequence(pszSequence); + int animDesired = LookupSequence(pszSequence); if (animDesired <= -1) { @@ -52,7 +52,7 @@ bool CAnimation ::SetAnim(const char* pszSequence) } bool CAnimation ::SetGaitAnim(const char* pszSequence) { - int animDesired = m_pOwner->LookupSequence(pszSequence); + int animDesired = LookupSequence(pszSequence); if (animDesired <= -1) { m_pOwner->pev->gaitsequence = 0; @@ -86,41 +86,41 @@ void CAnimation ::GaitAnimate() if (speed == 0) { if (bCustomLegs) - NewGait = m_pOwner->LookupSequence(UTIL_VarArgs("crouchidle_", m_szAnimLegs)); + NewGait = LookupSequence(UTIL_VarArgs("crouchidle_", m_szAnimLegs)); if (NewGait < 0) - NewGait = m_pOwner->LookupSequence("crouchidle"); + NewGait = LookupSequence("crouchidle"); } else { if (bCustomLegs) - NewGait = m_pOwner->LookupSequence(UTIL_VarArgs("crouchmove_", m_szAnimLegs)); + NewGait = LookupSequence(UTIL_VarArgs("crouchmove_", m_szAnimLegs)); if (NewGait < 0) - NewGait = m_pOwner->LookupSequence("crouch"); + NewGait = LookupSequence("crouch"); } } - else if (speed > m_pOwner->WalkSpeed(false) + 1) + else if (speed > m_pOwner->WalkSpeed(FALSE) + 1) { if (bCustomLegs) - NewGait = m_pOwner->LookupSequence(UTIL_VarArgs("run_%s", m_szAnimLegs)); + NewGait = LookupSequence(UTIL_VarArgs("run_%s", m_szAnimLegs)); if (NewGait < 0) - NewGait = m_pOwner->LookupSequence("run"); + NewGait = LookupSequence("run"); } else if (speed > 0) { if (bCustomLegs) - NewGait = m_pOwner->LookupSequence(UTIL_VarArgs("walk_%s", m_szAnimLegs)); + NewGait = LookupSequence(UTIL_VarArgs("walk_%s", m_szAnimLegs)); if (NewGait < 0) - NewGait = m_pOwner->LookupSequence("walk"); + NewGait = LookupSequence("walk"); } else { if (bCustomLegs) - NewGait = m_pOwner->LookupSequence(UTIL_VarArgs("stand_%s", m_szAnimLegs)); + NewGait = LookupSequence(UTIL_VarArgs("stand_%s", m_szAnimLegs)); // if( bCustomLegs ) NewGait = 0; if (NewGait < 0) - NewGait = m_pOwner->LookupSequence("stand"); + NewGait = LookupSequence("stand"); //else NewGait = 0; } @@ -157,7 +157,7 @@ void CWalkAnim ::Animate() LegsAnimName = pPlayer->m_szAnimLegs; } - int animDesired = m_pOwner->LookupSequence(TorsoAnimName); + int animDesired = LookupSequence(TorsoAnimName); if (animDesired != m_pOwner->pev->sequence) //Continue playing the same uninterrupted animation until told otherwise SetAnim(TorsoAnimName); @@ -167,18 +167,18 @@ void CWalkAnim ::Animate() } CAnimHold gAnimHold; //Never submits to MONSTER_ANIM_WALK - //Submits to anything else if ReleaseAnim == true + //Submits to anything else if ReleaseAnim == TRUE //Only uses gait if specified with flags void CAnimHold ::Initialize(void *vData) { - ReleaseAnim = true; + ReleaseAnim = TRUE; UseGait = false; //defaults int Flags = (int)vData; if (Flags & (1 << 0)) - ReleaseAnim = false; //Release to any anim besides walk + ReleaseAnim = FALSE; //Release to any anim besides walk if (Flags & (1 << 1)) - UseGait = true; //Use gait - IsNewAnim = true; + UseGait = TRUE; //Use gait + IsNewAnim = TRUE; } bool CAnimHold ::CanChangeTo(MONSTER_ANIM NewAnim, void *vData) { @@ -218,7 +218,7 @@ void CAnimOnce ::Initialize(void *vData) } bool CAnimOnce ::CanChangeTo(MONSTER_ANIM NewAnim, void *vData) { - return m_pOwner->m_fSequenceFinished ? true : false; + return m_fSequenceFinished ? true : false; } void CAnimOnce ::Animate() { @@ -243,13 +243,13 @@ void CAnimOnce ::Animate() /* //stays in the last pose void CAnimAct :: Initialize( void *vData ) { - if( vData ) ReleaseAnim = false; - else ReleaseAnim = true; - IsNewAnim = true; + if( vData ) ReleaseAnim = FALSE; + else ReleaseAnim = TRUE; + IsNewAnim = TRUE; } bool CAnimAct :: CanChangeTo( MONSTER_ANIM NewAnim, void *vData ) { - if( m_fSequenceFinished && ReleaseAnim ) return true; - return false; + if( m_fSequenceFinished && ReleaseAnim ) return TRUE; + return FALSE; } void CAnimAct :: Animate( ) { if( !IsNewAnim ) return; diff --git a/src/game/server/monsters/msmonster.h b/src/game/server/monsters/msmonster.h index bb43b455f..fee4544ca 100644 --- a/src/game/server/monsters/msmonster.h +++ b/src/game/server/monsters/msmonster.h @@ -78,8 +78,7 @@ enum speech_type SPEECH_LOCAL, SPEECH_PARTY }; - -constexpr float SPEECH_LOCAL_RANGE = 300; +#define SPEECH_LOCAL_RANGE 300 enum gender_e { @@ -201,28 +200,22 @@ struct random_monster_t //NOV2014_20 - Thothie msmonster_random [end] //Frame conditions - -enum frame_condition_monster_e { - FC_STEP = (1 << 1), //Monster walked up a step this frame - FC_JUMP = (1 << 2), //Monster began a jump this frame - FC_AVOID = (1 << 3) //Monster is avoiding an object this frame -}; +#define FC_STEP (1 << 1) //Monster walked up a step this frame +#define FC_JUMP (1 << 2) //Monster began a jump this frame +#define FC_AVOID (1 << 3) //Monster is avoiding an object this frame //General Conditions (Added to those defined in schedule.h) - -enum monster_conditions_e { - MONSTER_ROAM = (1 << 23),// Monster should roam around - MONSTER_HASMOVEDEST = (1 << 24),// vMoveDest is valid - MONSTER_TRADING = (1 << 25),// NPC is trading with a player - MONSTER_REFLECTIVEDMG = (1 << 26),// Damage is reflected back to attacker - MONSTER_NOAI = (1 << 27),// Don't normal script events - MONSTER_OPENCONTAINER = (1 << 28),// Player is looking inside a pack - MONSTER_BLIND = (1 << 29),// MAR2008b - Monster is blind - MONSTER_INVISIBLE = (1 << 30),// MAR2008b - Monster is invisible -}; - -constexpr int MAX_ENEMYLIST = 12; -constexpr int MAX_NPC_HANDS = 3; +#define MONSTER_ROAM (1 << 23) // Monster should roam around +#define MONSTER_HASMOVEDEST (1 << 24) // vMoveDest is valid +#define MONSTER_TRADING (1 << 25) // NPC is trading with a player +#define MONSTER_REFLECTIVEDMG (1 << 26) // Damage is reflected back to attacker +#define MONSTER_NOAI (1 << 27) // Don't normal script events +#define MONSTER_OPENCONTAINER (1 << 28) // Player is looking inside a pack +#define MONSTER_BLIND (1 << 29) // MAR2008b - Monster is blind +#define MONSTER_INVISIBLE (1 << 30) // MAR2008b - Monster is invisible + +#define MAX_ENEMYLIST 12 +#define MAX_NPC_HANDS 3 class CMSMonster : public CBaseMonster { @@ -274,9 +267,9 @@ class CMSMonster : public CBaseMonster m_HPReq_min, //Thothie AUG2007a - adding optional req total hp on server to spawn monster m_HPReq_max, //Thothie FEB2011_22 - adding option for "min;max" hpreq m_ReqPlayers, //Thothie AUG2007a - adding optional REQ players to spawn monster + m_nRndMobs, //NOV2014_20 - Thothie msmonster_random m_HPReq_useavg; - unsigned int m_nRndMobs; //NOV2014_20 - Thothie msmonster_random float m_HPMulti, //Thothie SEP2007a - multiply HP by this amount m_DMGMulti; //Thothie SEP2007a - multiply DMG by this amount @@ -325,7 +318,7 @@ class CMSMonster : public CBaseMonster //a relationship better than R_NO) EHANDLE m_hEnemyList[MAX_ENEMYLIST], m_LastEnemy; - unsigned int m_EnemyListNum; + int m_EnemyListNum; CBaseBody *Body; //If this monster uses body parts CItemList Gear; //This monster's gear @@ -364,7 +357,7 @@ class CMSMonster : public CBaseMonster virtual float MaxMP() { return m_MaxMP; } virtual float GetDefaultMoveProximity() { return m_Width * 1.1; } - BOOL IsAlive() { return pev ? pev->deadflag == DEAD_NO : false; } + BOOL IsAlive() { return pev ? pev->deadflag == DEAD_NO : FALSE; } virtual void CancelAttack(); //virtual void Step( ); //virtual void Jump( ); @@ -436,8 +429,8 @@ class CMSMonster : public CBaseMonster int MSProperties(); float HearingSensitivity(void) { return m_HearingSensitivity; } int ObjectCaps(void) { return CBaseMonster ::ObjectCaps() | FCAP_IMPULSE_USE; } - BOOL HasHumanGibs() { return true; } - BOOL ShouldFadeOnDeath(void) { return false; } + BOOL HasHumanGibs() { return TRUE; } + BOOL ShouldFadeOnDeath(void) { return FALSE; } #ifdef VALVE_DLL virtual float GiveHP(float flAmount) @@ -463,7 +456,7 @@ class CMSMonster : public CBaseMonster virtual void Used(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); virtual void Trade(); // Handle trading with others virtual bool AcceptOffer(); // Accept an offer from a player or monster - virtual BOOL SkinMonster(CMSMonster *pDeadMonster) { return false; } //Skin other monsters + virtual BOOL SkinMonster(CMSMonster *pDeadMonster) { return FALSE; } //Skin other monsters virtual tradeinfo_t *TradeItem(tradeinfo_t *tiTradeInfo); // Trade an item virtual void Attacked(CBaseEntity *pAttacker, damage_t &Damage); virtual void Seen(CMSMonster *pMonster) {} diff --git a/src/game/server/monsters/msmonsterserver.cpp b/src/game/server/monsters/msmonsterserver.cpp index 8d07556d7..18f6f3769 100644 --- a/src/game/server/monsters/msmonsterserver.cpp +++ b/src/game/server/monsters/msmonsterserver.cpp @@ -24,8 +24,7 @@ #include "saytext.h" #include "mslogger.h" #include "ms/angelscript/ASEngineEventManager.h" -//this can be removed once AS is fully finished, it's for as_enabled check. -#include "svglobals.h" +//originally added for the as_enabled check, which is now the AS_DISABLED macro; this can be removed once AS is fully finished. #ifdef VALVE_DLL @@ -83,6 +82,7 @@ int CMSMonster::IRelationship(CBaseEntity* pTarget) return (int)CRaceManager::Relationship(m_Race, pMonster->m_Race); } + bool CMSMonster::CanDamage(CBaseEntity* pOther) //Can I damage this entity? { return (CBaseEntity::CanDamage(pOther)) && //The entity can take damage @@ -136,7 +136,7 @@ void CMSMonster::Spawn() m_OldGold = 0; // Initialize menu protection flags to false for all players - for (unsigned int i = 0; i < MAXPLAYERS; i++) + for (int i = 0; i < MAXPLAYERS; i++) { m_MenuOptionsProtected[i] = false; } @@ -150,7 +150,7 @@ void CMSMonster::Spawn() { //precache all random mob scripts msstring orig_scriptName = m_ScriptName; - for (unsigned int i = 0; i < m_nRndMobs; i++) + for (int i = 0; i < m_nRndMobs; i++) { MS_DEBUG("DEBUG: msmonster_random precache #%i / %i as %s", i, m_nRndMobs, random_monsterdata[i].m_ScriptName.c_str()); CScript TempScript; @@ -300,32 +300,32 @@ void CMSMonster::KeyValue(KeyValueData* pkvd) if (FStrEq(pkvd->szKeyName, "killtarget")) { m_iszKillTarget = pkvd->szValue; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "perishtarget")) { m_iszPerishTarget = pkvd->szValue; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spawnarea")) { m_iszMonsterSpawnArea = pkvd->szValue; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "delaylow")) { m_SpawnDelayLow = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "delayhigh")) { m_SpawnDelayHigh = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "lives")) { m_Lives = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spawnchance")) { @@ -339,18 +339,18 @@ void CMSMonster::KeyValue(KeyValueData* pkvd) if (!m_SpawnChance) m_SpawnChance = -1; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "spawnstart")) { m_fSpawnOnTrigger = (atoi(pkvd->szValue)) ? true : false; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "nplayers")) { //Thothie - AUG2007a - adding option to only spawn monster if # players present m_ReqPlayers = (atoi(pkvd->szValue)); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "reqhp")) { @@ -375,19 +375,19 @@ void CMSMonster::KeyValue(KeyValueData* pkvd) } if (reqhp_stringlist.size() >= 2 && reqhp_stringlist[1].contains("avg")) m_HPReq_useavg = true; //Thothie OCT2015_28 - allow use average when calculating HP req, if token 2-3 is "avg" - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "title")) { //Thothie - AUG2007b - adding option to change monster name m_title = pkvd->szValue; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "params")) { //Thothie - DEC2007b - adding option to send params to script m_addparams = pkvd->szValue; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "hpmulti")) { @@ -396,7 +396,7 @@ void CMSMonster::KeyValue(KeyValueData* pkvd) if (flHealthMulti > 1) { m_HPMulti = flHealthMulti; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } } else if (FStrEq(pkvd->szKeyName, "dmgmulti")) @@ -406,14 +406,14 @@ void CMSMonster::KeyValue(KeyValueData* pkvd) if (flDamageMulti > 1) { m_DMGMulti = flDamageMulti; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } } else if (FStrEq(pkvd->szKeyName, "scriptfile") || (FStrEq(pkvd->szKeyName, "defscriptfile") && !m_ScriptName)) { m_ScriptName = pkvd->szValue; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } //NOV2014_20 - Thothie msmonster_random [begin] else if (randomdata.starts_with("random_")) //optimize this - dis is stupid lazy @@ -430,7 +430,7 @@ void CMSMonster::KeyValue(KeyValueData* pkvd) if (random_monsterdata.size() == 0) { //random_monster_t tmp; - for (unsigned int i = 0; i < 32; i++) + for (int i = 0; i < 32; i++) { random_monsterdata.add_blank(); }; @@ -493,7 +493,7 @@ void CMSMonster::KeyValue(KeyValueData* pkvd) } //Gotta use the logfile here, dernitall MS_DEBUG("DEBUG: msmonster_random added rndproperty #%i / tot %i - %s %s", idx, m_nRndMobs, rndproperty.c_str(), pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } //NOV2014_20 - Thothie msmonster_random [end] else @@ -829,7 +829,7 @@ bool CMSMonster::MoveExecute(moveexec_t& MoveExec) return fSuccess; } -BOOL CMSMonster::CanSetVelocity() { return true; } +BOOL CMSMonster::CanSetVelocity() { return TRUE; } void CMSMonster::Float() { @@ -1262,7 +1262,7 @@ void CMSMonster::AvoidFrontObject(float MoveAmt) Vector vAng, vAvoidDir, SideAng[2]; float Dist[2]; - for (unsigned int i = 0; i < 2; i++) //Try each side + for (int i = 0; i < 2; i++) //Try each side { //Finds the forward vector of the avoidance direction vAng.y = UTIL_AngleMod(m_LastYaw + ang * -Side[i]); @@ -1402,19 +1402,19 @@ void CMSMonster::Act() if( m_fSequenceFinished ) { //m_Hand->CurrentAttack->tStart = -65534; - //m_Hand->CurrentAttack->fCanCancel = true; + //m_Hand->CurrentAttack->fCanCancel = TRUE; StopWalking( ); CurrentHand->CancelAttack( ); return; } - else CurrentHand->CurrentAttack->fCanCancel = false; + else CurrentHand->CurrentAttack->fCanCancel = FALSE; if( LastEvent.event == 600 ) //call attack this frame { CurrentHand->CurrentAttack->fAttackThisFrame = true; pev->iuser4 = -1; } - else CurrentHand->CurrentAttack->fAttackThisFrame = false; //basically never + else CurrentHand->CurrentAttack->fAttackThisFrame = FALSE; //basically never } //m_Hand->AttackButtonDown( ); @@ -1613,13 +1613,13 @@ void CMSMonster::Speak(char* pszSentence, speech_type SpeechType) CBaseEntity* pList[255], * pEnt = NULL; // Fill pList with a all the monsters and players on the level including players that have died. - unsigned int count = UTIL_EntitiesInBox(pList, 255, Vector(-6000, -6000, -6000), Vector(6000, 6000, 6000), FL_MONSTER | FL_CLIENT | FL_SPECTATOR); + int count = UTIL_EntitiesInBox(pList, 255, Vector(-6000, -6000, -6000), Vector(6000, 6000, 6000), FL_MONSTER | FL_CLIENT | FL_SPECTATOR); // Keep track of players that have already received a message; std::set pTrackAlreadySent = {}; // Now try to speak to each one - for (unsigned int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { pEnt = pList[i]; if (pEnt == NULL) @@ -1628,8 +1628,13 @@ void CMSMonster::Speak(char* pszSentence, speech_type SpeechType) // Corpses didn't have edicts so were never delivered messages // attempt to fix by passing the pointer to the player's edict pointer down through the corpse and into this. CCorpse* pCorpse = dynamic_cast(pEnt); - if (pCorpse && (pCorpse->pPlayerSource != NULL)) - pEnt = pCorpse->pPlayerSource; // this var only exists if the corpse comes from a player + if (pCorpse) + { + // only set if the corpse comes from a player, and NULL if that player has since disconnected + CBaseEntity* pSource = pCorpse->m_hPlayerSource; + if (pSource) + pEnt = pSource; + } //skip players that have already been sent messages. if (pEnt->IsPlayer() && !pTrackAlreadySent.insert(pEnt).second) @@ -1727,18 +1732,18 @@ void CMSMonster::HearPhrase(CMSMonster* pSpeaker, const char* phrase) listenphrase_t* BestPhrase = NULL; float BestMatchedRatio = 0; - for (unsigned int i = 0; i < m_Phrases.size(); i++) + for (int i = 0; i < m_Phrases.size(); i++) { listenphrase_t& Phrase = m_Phrases[i]; - for (unsigned int p = 0; p < Phrase.Phrases.size(); p++) + for (int p = 0; p < Phrase.Phrases.size(); p++) { const char* CheckPhrase = Phrase.Phrases[p]; const char* SubPhrase = NULL; if (SubPhrase = strstr(cTemp1, CheckPhrase)) { int Matched = 0; - unsigned int len = strlen(CheckPhrase); - for (unsigned int x = 0; x < len; x++) + int len = strlen(CheckPhrase); + for (int x = 0; x < len; x++) if (SubPhrase[x] == CheckPhrase[x]) Matched++; @@ -2129,7 +2134,7 @@ float CMSMonster::TraceAttack(damage_t& Damage) //- maybe internalize Parry for monsters? //- Thothie note of FEB2008a - int ParryValue = GetSkillStat("parry", STAT_PROP_SKILL); + int ParryValue = GetSkillStat("parry", STATPROP_SKILL); if (ParryValue > 60) ParryValue = 60; //Thothie JAN2010_22 - cap out parry (shhh) @@ -2198,14 +2203,14 @@ float CMSMonster::TraceAttack(damage_t& Damage) //Learn parry skill from a successful parry if( !pAttacker->IsPlayer() ) //Can't learn from being attacked by players if ( GetSkillStat( SKILL_PARRY, 0 ) < CHAR_LEVEL_CAP ) - LearnSkill ( SKILL_PARRY, STAT_PROP_SKILL, max( 0 , pMonster->m_SkillLevel * 2 ) ); + LearnSkill ( SKILL_PARRY, STATPROP_SKILL, max( 0 , pMonster->m_SkillLevel * 2 ) ); //MiB Jul2008a (JAN2010_15) - Parry was capped at 40. What say we stop exp gain? /*if (pMonster->m_SkillLevel * 2 > 0) - LearnSkill (SKILL_PARRY, STAT_PROP_SKILL, pMonster->m_SkillLevel * 2 ); + LearnSkill (SKILL_PARRY, STATPROP_SKILL, pMonster->m_SkillLevel * 2 ); else - LearnSkill (SKILL_PARRY, STAT_PROP_SKILL, 0 ); - //LearnSkill( SKILL_PARRY, STAT_PROP_SKILL, max(pAttacker->m_SkillLevel * 2,0) );*/ + LearnSkill (SKILL_PARRY, STATPROP_SKILL, 0 ); + //LearnSkill( SKILL_PARRY, STATPROP_SKILL, max(pAttacker->m_SkillLevel * 2,0) );*/ } } @@ -2213,7 +2218,7 @@ float CMSMonster::TraceAttack(damage_t& Damage) //Damage Modifiers ( takedmg xxx ) Damage.flDamage *= m.GenericTDM; if (Damage.sDamageType) - for (unsigned int i = 0; i < m.TakeDamageModifiers.size(); i++) + for (int i = 0; i < m.TakeDamageModifiers.size(); i++) { takedamagemodifier_t& TDM = m.TakeDamageModifiers[i]; //msstring thoth_my_dmgtype = TDM.DamageType; @@ -2260,7 +2265,7 @@ float CMSMonster::TraceAttack(damage_t& Damage) //Each script sets a ratio of damage you should take. Factor each one into the damage msstringlist DamageRatios; TokenizeString(m_ReturnData, DamageRatios); - for (unsigned int i = 0; i < DamageRatios.size(); i++) + for (int i = 0; i < DamageRatios.size(); i++) Damage.flDamage *= atof(DamageRatios[i]); //Script can reject the damage with "returndata" } @@ -2384,7 +2389,7 @@ void CMSMonster::CounterEffect(CBaseEntity* pInflictor, int iEffect, void* pExtr void CMSMonster::Killed(entvars_t* pevAttacker, int iGib) { - BOOL DeleteMe = true; + BOOL DeleteMe = TRUE; //NOV2014_21 Thothie - script side XP management option [begin] bool xp_dump = (strcmp(GetFirstScriptVar("NPC_DUMP_XP"), "1") == 0); //dump hits to array @@ -2408,7 +2413,7 @@ void CMSMonster::Killed(entvars_t* pevAttacker, int iGib) IScripted* pScripted = (pTarget ? pTarget->GetScripted() : NULL); if (pScripted) { - for (unsigned int i = 0; i < pScripted->m_Scripts.size(); i++) // Check each + for (int i = 0; i < pScripted->m_Scripts.size(); i++) // Check each { if (pScripted->m_Scripts[i]->VarExists("game.effect.id")) //This is an effect { @@ -2434,7 +2439,7 @@ void CMSMonster::Killed(entvars_t* pevAttacker, int iGib) float mult = V_min(1, m_MaxHP / m_PlayerDamage[i - 1].dmgInTotal); for (int n = SKILL_FIRSTSKILL; n < SKILL_MAX_ATTACK; n++) { - for (int r = 0; r < STAT_PROP_ALL_TOTAL; r++) + for (int r = 0; r < STATPROP_ALL_TOTAL; r++) { float dmg = m_PlayerDamage[i - 1].dmg[n][r]; if (dmg > 0) @@ -2528,7 +2533,7 @@ void CMSMonster::Killed(entvars_t* pevAttacker, int iGib) // ALERT( at_console, "m_flFrameRate: %f\n", m_flFrameRate ); //pev->nextthink = gpGlobals->time + ((256 / m_flFrameRate) * pev->framerate); pev->health = pev->max_health / 2; //Thothie - Dunno what this is about - DeleteMe = false; //live until the body's dead + DeleteMe = FALSE; //live until the body's dead if (FStrEq(STRING(pev->classname), "msmonster_summoned")) g_SummonedMonsters--; @@ -2579,7 +2584,7 @@ void CMSMonster::Killed(entvars_t* pevAttacker, int iGib) m_SkillLevel = 0; //Thothie APR2011_06 - attempt to make sure monster does not give additional skill post mortem } else - DeleteMe = true; // Gibbed, destroy this entity + DeleteMe = TRUE; // Gibbed, destroy this entity } if (DeleteMe) { @@ -2707,7 +2712,7 @@ std::tuple CMSMonster::LearnSkill(int iStat, int iStatType, int Enemy //Look through the other SubStats for one that's not at the cap, yet. //Not random, but good enough. - for (unsigned int i = 0; i < 1; i++) + for (int i = 0; i < 1; i++) { iStatType = (iStatType + 1) % 3; CSubStat& SubStat = pStat->m_SubStats[iStatType]; @@ -2760,8 +2765,8 @@ std::tuple CMSMonster::LearnSkill(int iStat, int iStatType, int Enemy return std::make_tuple(false, iExpRemaining); SubStat.Value += 1; - if (SubStat.Value > MAX_STAT_PROPVALUE) - SubStat.Value = MAX_STAT_PROPVALUE; + if (SubStat.Value > STATPROP_MAX_VALUE) + SubStat.Value = STATPROP_MAX_VALUE; SubStat.Exp = 0; //Thothie - why's this here twice? I dont see where oldval could change. @@ -2795,7 +2800,7 @@ void CMSMonster::SetSpeed() float SpeedPercent = 100.0f; m_Framerate_Modifier = 1.0; - for (unsigned int i = 0; i < m_Scripts.size(); i++) + for (int i = 0; i < m_Scripts.size(); i++) { if (!m_Scripts[i]->VarExists("game.effect.id")) continue; @@ -2819,7 +2824,7 @@ void CMSMonster::SetSpeed() //Can't move while a spell is preparing //Thothie/Orochi APR2011_04 - undone /* - for (unsigned int i = 0; i < MAX_NPC_HANDS; i++) + for (int i = 0; i < MAX_NPC_HANDS; i++) if( Hand(i) && !Hand(i)->Spell_CanAttack() ) SpeedPercent = 0; //Percentage of normal speed */ @@ -2869,7 +2874,7 @@ void CMSMonster::OpenMenu(CBasePlayer* pPlayer) m_MenuCurrentOptions = NULL; - for (unsigned int i = 0; i < Menuoptions.size(); i++) + for (int i = 0; i < Menuoptions.size(); i++) { menuoption_t& MenuOption = Menuoptions[i]; if (MenuOption.Access != MOA_ALL) @@ -2888,337 +2893,334 @@ void CMSMonster::OpenMenu(CBasePlayer* pPlayer) } void CMSMonster::UseMenuOption(CBasePlayer* pPlayer, int Option) { - // quick and dirty fix to enable menu callbacks again for no AS. - if (as_enabled.value > 0) - { - int playerIndex = pPlayer->entindex(); - MS_ANGEL_INFO("UseMenuOption called for player %s (idx:%d), option %d", - pPlayer ? pPlayer->DisplayName() : "NULL", playerIndex, Option); - MS_ANGEL_INFO(" Protection flag: %s, Entity: %d", - m_MenuOptionsProtected[playerIndex] ? "true" : "false", entindex()); - - pPlayer->InMenu = false; - mslist& Menuoptions = m_MenuOptions[playerIndex]; + // quick and dirty fix to enable menu callbacks again for no AS (AS_DISABLED). +#ifndef AS_DISABLED + int playerIndex = pPlayer->entindex(); + MS_ANGEL_INFO("UseMenuOption called for player %s (idx:%d), option %d", + pPlayer ? pPlayer->DisplayName() : "NULL", playerIndex, Option); + MS_ANGEL_INFO(" Protection flag: %s, Entity: %d", + m_MenuOptionsProtected[playerIndex] ? "TRUE" : "FALSE", entindex()); + + pPlayer->InMenu = false; + mslist& Menuoptions = m_MenuOptions[playerIndex]; + + MS_ANGEL_INFO(" Menu has %d options for this player", Menuoptions.size()); - MS_ANGEL_INFO(" Menu has %d options for this player", Menuoptions.size()); + //Thothie JAN2008a - need a way of dealing with canceled menus + if (Option == -1) + { + MS_ANGEL_INFO(" Option is -1 (cancel), calling game_menu_cancel"); + static msstringlist Params; + Params.clearitems(); + Params.add(EntToString(pPlayer)); + CallScriptEvent("game_menu_cancel", &Params); + + // Clear protection flag when menu is cancelled + m_MenuOptionsProtected[playerIndex] = false; + MS_ANGEL_INFO("*** VOTE MENU PROTECTION: CLEARED for player %d (menu cancelled) ***", playerIndex); + + return; + } - //Thothie JAN2008a - need a way of dealing with canceled menus - if (Option == -1) + if (Option < 0 || Option >= (signed)Menuoptions.size()) + { + MS_ANGEL_ERROR(" Option %d is out of range (0-%d)", Option, Menuoptions.size() - 1); + + // For vote menus (MOT_CALLBACK with game_vote_menu_callback), still call the callback + // This allows AngelScript to handle expired votes gracefully + if (Menuoptions.size() == 0) { - MS_ANGEL_INFO(" Option is -1 (cancel), calling game_menu_cancel"); + MS_ANGEL_INFO(" Menu has no options - checking if this might be an expired vote menu"); + + // Try to call the vote callback even with no options + // The AngelScript side will handle the expired vote appropriately static msstringlist Params; Params.clearitems(); - Params.add(EntToString(pPlayer)); - CallScriptEvent("game_menu_cancel", &Params); - - // Clear protection flag when menu is cancelled - m_MenuOptionsProtected[playerIndex] = false; - MS_ANGEL_INFO("*** VOTE MENU PROTECTION: CLEARED for player %d (menu cancelled) ***", playerIndex); - return; - } - - if (Option < 0 || Option >= (signed)Menuoptions.size()) - { - MS_ANGEL_ERROR(" Option %d is out of range (0-%d)", Option, Menuoptions.size() - 1); - - // For vote menus (MOT_CALLBACK with game_vote_menu_callback), still call the callback - // This allows AngelScript to handle expired votes gracefully - if (Menuoptions.size() == 0) - { - MS_ANGEL_INFO(" Menu has no options - checking if this might be an expired vote menu"); - - // Try to call the vote callback even with no options - // The AngelScript side will handle the expired vote appropriately - static msstringlist Params; - Params.clearitems(); - - // Format player entity as "ent:index" for AngelScript compatibility - char entFormat[32]; - _snprintf(entFormat, sizeof(entFormat) - 1, "ent:%d", playerIndex); - entFormat[sizeof(entFormat) - 1] = '\0'; - - Params.add(entFormat); - Params.add(""); // Empty option data since menu is gone - - MS_ANGEL_INFO(" Calling game_vote_menu_callback for expired menu"); - CallScriptEvent("game_vote_menu_callback", &Params); - } + // Format player entity as "ent:index" for AngelScript compatibility + char entFormat[32]; + _snprintf(entFormat, sizeof(entFormat) - 1, "ent:%d", playerIndex); + entFormat[sizeof(entFormat) - 1] = '\0'; - // Clear protection flag when option is out of range (vote may have expired) - m_MenuOptionsProtected[playerIndex] = false; - MS_ANGEL_INFO("*** VOTE MENU PROTECTION: CLEARED for player %d (option out of range) ***", playerIndex); + Params.add(entFormat); + Params.add(""); // Empty option data since menu is gone - return; + MS_ANGEL_INFO(" Calling game_vote_menu_callback for expired menu"); + CallScriptEvent("game_vote_menu_callback", &Params); } + + // Clear protection flag when option is out of range (vote may have expired) + m_MenuOptionsProtected[playerIndex] = false; + MS_ANGEL_INFO("*** VOTE MENU PROTECTION: CLEARED for player %d (option out of range) ***", playerIndex); + + return; + } - menuoption_t& MenuOption = Menuoptions[Option]; - MS_ANGEL_INFO(" Menu option: Type=%d, Data='%s', CB_Name='%s'", - MenuOption.Type, MenuOption.Data.c_str(), MenuOption.CB_Name.c_str()); + menuoption_t& MenuOption = Menuoptions[Option]; + MS_ANGEL_INFO(" Menu option: Type=%d, Data='%s', CB_Name='%s'", + MenuOption.Type, MenuOption.Data.c_str(), MenuOption.CB_Name.c_str()); - bool PlayerCanPay = true; + bool PlayerCanPay = true; - if (MenuOption.Type == MOT_SAY) - { - pPlayer->Speak(MenuOption.Data, SPEECH_LOCAL); - } - else if (MenuOption.Type == MOT_PAYMENT) - { - static msstringlist Payments; - Payments.clearitems(); + if (MenuOption.Type == MOT_SAY) + { + pPlayer->Speak(MenuOption.Data, SPEECH_LOCAL); + } + else if (MenuOption.Type == MOT_PAYMENT) + { + static msstringlist Payments; + Payments.clearitems(); - TokenizeString(MenuOption.Data, Payments); + TokenizeString(MenuOption.Data, Payments); - int TotalGold = 0; - static mslist TotalFoundItems; - TotalFoundItems.clearitems(); + int TotalGold = 0; + static mslist TotalFoundItems; + TotalFoundItems.clearitems(); - for (unsigned int i = 0; i < Payments.size(); i++) + for (int i = 0; i < Payments.size(); i++) + { + msstring& Payment = Payments[i]; + if (Payment.starts_with("gold")) + TotalGold += atoi(Payment.substr(5)); + else { - msstring& Payment = Payments[i]; - if (Payment.starts_with("gold")) - TotalGold += atoi(Payment.substr(5)); - else + //Find x number of specified item + int Amount = 1; + if (Payment.contains(":")) { - //Find x number of specified item - int Amount = 1; - if (Payment.contains(":")) - { - Amount = atoi(Payment.substr(Payment.findchar(":") + 1)); - if (!Amount) - Amount = 1; - } - - msstring ItemName = Payment.thru_char(":"); + Amount = atoi(Payment.substr(Payment.findchar(":") + 1)); + if (!Amount) + Amount = 1; + } - ulong LastItem = 0; - ulong FirstItem = 0; - CGenericItem* pItem = NULL; - static mslist FoundItems; - FoundItems.clearitems(); - while ((pItem = pPlayer->GetItemInInventory(LastItem, false, true, true)) && ((signed)FoundItems.size() < Amount)) - { - if (pItem->ItemName == ItemName) - FoundItems.add(pItem); + msstring ItemName = Payment.thru_char(":"); - LastItem = pItem->m_iId; + ulong LastItem = 0; + ulong FirstItem = 0; + CGenericItem* pItem = NULL; + static mslist FoundItems; + FoundItems.clearitems(); + while ((pItem = pPlayer->GetItemInInventory(LastItem, false, true, true)) && ((signed)FoundItems.size() < Amount)) + { + if (FirstItem == 0) + FirstItem = pItem->m_iId; + else if (pItem->m_iId == FirstItem) + break; - if (FirstItem == 0) - FirstItem = LastItem; - else if (LastItem == FirstItem) - break; - } + if (pItem->ItemName == ItemName) + FoundItems.add(pItem); - if ((signed)FoundItems.size() < Amount) - { - msstring ItemDispName = CGenericItemMgr::GetItemDisplayName(ItemName, false, true, Amount); + LastItem = pItem->m_iId; + } - if (!MenuOption.SilentPayment) - pPlayer->SendEventMsg(HUDEVENT_UNABLE, msstring("You can't afford the payment of ") + ItemDispName); - PlayerCanPay = false; - break; - } + if ((signed)FoundItems.size() < Amount) + { + msstring ItemDispName = CGenericItemMgr::GetItemDisplayName(ItemName, false, true, Amount); - for (unsigned int x = 0; x < FoundItems.size(); x++) - TotalFoundItems.add(FoundItems[x]); + if (!MenuOption.SilentPayment) + pPlayer->SendEventMsg(HUDEVENT_UNABLE, msstring("You can't afford the payment of ") + ItemDispName); + PlayerCanPay = false; + break; } - } - - int PlayerGold = pPlayer->m_Gold; - if (PlayerGold < TotalGold) - { - if (!MenuOption.SilentPayment) - pPlayer->SendEventMsg(HUDEVENT_UNABLE, msstring("You can't afford the payment of ") + TotalGold + " Gold"); - PlayerCanPay = false; - } - if (PlayerCanPay) - { - pPlayer->m_Gold -= TotalGold; - for (unsigned int i = 0; i < TotalFoundItems.size(); i++) - TotalFoundItems[i]->SUB_Remove(); //MIB JUN2010_14 (original line commented below) - //pPlayer->RemoveItem( TotalFoundItems[i] ); + for (int x = 0; x < FoundItems.size(); x++) + TotalFoundItems.add(FoundItems[x]); } } - //Handle callback - // IMPORTANT: Copy callback name FIRST before any operations that might modify MenuOption - msstring CallbackEvent = MenuOption.CB_Name; - msstring CallbackFailedEvent = MenuOption.CB_Failed_Name; - msstring OptionData = MenuOption.Data; - menuoptiontype_e OptionType = MenuOption.Type; - - MS_ANGEL_INFO(" Callback event: '%s', Type: %d", CallbackEvent.c_str(), OptionType); - - static msstringlist Params; - Params.clearitems(); - - // Format player entity as "ent:index" for AngelScript compatibility - char entFormat[32]; - _snprintf(entFormat, sizeof(entFormat) - 1, "ent:%d", playerIndex); - entFormat[sizeof(entFormat) - 1] = '\0'; - - msstring PlayerEntStr = entFormat; - MS_ANGEL_INFO(" Entity format: '%s' (index=%d)", PlayerEntStr.c_str(), playerIndex); - - Params.add(PlayerEntStr); - Params.add(OptionData); //Thothie - reg.mitem.data function wasn't returning as PARAM2 in type callback as described by docs, so I tried this, seems to work - - MS_ANGEL_INFO(" Preparing callback with params: player='%s', data='%s'", - Params[0].c_str(), OptionData.c_str()); - - if (OptionType == MOT_PAYMENT) + int PlayerGold = pPlayer->m_Gold; + if (PlayerGold < TotalGold) { - if (!PlayerCanPay) - { - MS_ANGEL_INFO(" Player can't pay, using failed callback"); - CallbackEvent = CallbackFailedEvent; - } + if (!MenuOption.SilentPayment) + pPlayer->SendEventMsg(HUDEVENT_UNABLE, msstring("You can't afford the payment of ") + TotalGold + " Gold"); + PlayerCanPay = false; } - if (CallbackEvent.len()) + if (PlayerCanPay) { - MS_ANGEL_INFO(" Calling script event: '%s' with %d parameters", - CallbackEvent.c_str(), (int)Params.size()); - CallScriptEvent(CallbackEvent, &Params); - MS_ANGEL_INFO(" Script event completed"); + pPlayer->m_Gold -= TotalGold; + for (int i = 0; i < TotalFoundItems.size(); i++) + TotalFoundItems[i]->SUB_Remove(); //MIB JUN2010_14 (original line commented below) + //pPlayer->RemoveItem( TotalFoundItems[i] ); } - else + } + + //Handle callback + // IMPORTANT: Copy callback name FIRST before any operations that might modify MenuOption + msstring CallbackEvent = MenuOption.CB_Name; + msstring CallbackFailedEvent = MenuOption.CB_Failed_Name; + msstring OptionData = MenuOption.Data; + menuoptiontype_e OptionType = MenuOption.Type; + + MS_ANGEL_INFO(" Callback event: '%s', Type: %d", CallbackEvent.c_str(), OptionType); + + static msstringlist Params; + Params.clearitems(); + + // Format player entity as "ent:index" for AngelScript compatibility + char entFormat[32]; + _snprintf(entFormat, sizeof(entFormat) - 1, "ent:%d", playerIndex); + entFormat[sizeof(entFormat) - 1] = '\0'; + + msstring PlayerEntStr = entFormat; + MS_ANGEL_INFO(" Entity format: '%s' (index=%d)", PlayerEntStr.c_str(), playerIndex); + + Params.add(PlayerEntStr); + Params.add(OptionData); //Thothie - reg.mitem.data function wasn't returning as PARAM2 in type callback as described by docs, so I tried this, seems to work + + MS_ANGEL_INFO(" Preparing callback with params: player='%s', data='%s'", + Params[0].c_str(), OptionData.c_str()); + + if (OptionType == MOT_PAYMENT) + { + if (!PlayerCanPay) { - MS_ANGEL_WARN(" No callback event name specified for this menu option"); + MS_ANGEL_INFO(" Player can't pay, using failed callback"); + CallbackEvent = CallbackFailedEvent; } - - MS_ANGEL_INFO(" Clearing menu options"); - Menuoptions.clearitems(); - - // Clear protection flag (used for vote menus) - m_MenuOptionsProtected[playerIndex] = false; - MS_ANGEL_INFO("*** VOTE MENU PROTECTION: CLEARED for player %d (normal menu completion) ***", playerIndex); + } + + if (CallbackEvent.len()) + { + MS_ANGEL_INFO(" Calling script event: '%s' with %d parameters", + CallbackEvent.c_str(), (int)Params.size()); + CallScriptEvent(CallbackEvent, &Params); + MS_ANGEL_INFO(" Script event completed"); } else { - pPlayer->InMenu = false; - mslist& Menuoptions = m_MenuOptions[pPlayer->entindex()]; + MS_ANGEL_WARN(" No callback event name specified for this menu option"); + } + + MS_ANGEL_INFO(" Clearing menu options"); + Menuoptions.clearitems(); + + // Clear protection flag (used for vote menus) + m_MenuOptionsProtected[playerIndex] = false; + MS_ANGEL_INFO("*** VOTE MENU PROTECTION: CLEARED for player %d (normal menu completion) ***", playerIndex); +#else + pPlayer->InMenu = false; + mslist& Menuoptions = m_MenuOptions[pPlayer->entindex()]; - //Thothie JAN2008a - need a way of dealing with canceled menus - if (Option == -1) - { - static msstringlist Params; - Params.clearitems(); - Params.add(EntToString(pPlayer)); - CallScriptEvent("game_menu_cancel", &Params); - } + //Thothie JAN2008a - need a way of dealing with canceled menus + if (Option == -1) + { + static msstringlist Params; + Params.clearitems(); + Params.add(EntToString(pPlayer)); + CallScriptEvent("game_menu_cancel", &Params); + } - if (Option < 0 || Option >= (signed)Menuoptions.size()) - return; + if (Option < 0 || Option >= (signed)Menuoptions.size()) + return; - menuoption_t& MenuOption = Menuoptions[Option]; + menuoption_t& MenuOption = Menuoptions[Option]; - bool PlayerCanPay = true; + bool PlayerCanPay = true; - if (MenuOption.Type == MOT_SAY) - { - pPlayer->Speak(MenuOption.Data, SPEECH_LOCAL); - } - else if (MenuOption.Type == MOT_PAYMENT) - { - static msstringlist Payments; - Payments.clearitems(); + if (MenuOption.Type == MOT_SAY) + { + pPlayer->Speak(MenuOption.Data, SPEECH_LOCAL); + } + else if (MenuOption.Type == MOT_PAYMENT) + { + static msstringlist Payments; + Payments.clearitems(); - TokenizeString(MenuOption.Data, Payments); + TokenizeString(MenuOption.Data, Payments); - int TotalGold = 0; - static mslist TotalFoundItems; - TotalFoundItems.clearitems(); + int TotalGold = 0; + static mslist TotalFoundItems; + TotalFoundItems.clearitems(); - for (unsigned int i = 0; i < Payments.size(); i++) + for (int i = 0; i < Payments.size(); i++) + { + msstring& Payment = Payments[i]; + if (Payment.starts_with("gold")) + TotalGold += atoi(Payment.substr(5)); + else { - msstring& Payment = Payments[i]; - if (Payment.starts_with("gold")) - TotalGold += atoi(Payment.substr(5)); - else + //Find x number of specified item + int Amount = 1; + if (Payment.contains(":")) { - //Find x number of specified item - int Amount = 1; - if (Payment.contains(":")) - { - Amount = atoi(Payment.substr(Payment.findchar(":") + 1)); - if (!Amount) - Amount = 1; - } - - msstring ItemName = Payment.thru_char(":"); + Amount = atoi(Payment.substr(Payment.findchar(":") + 1)); + if (!Amount) + Amount = 1; + } - ulong LastItem = 0; - ulong FirstItem = 0; - CGenericItem* pItem = NULL; - static mslist FoundItems; - FoundItems.clearitems(); - while ((pItem = pPlayer->GetItemInInventory(LastItem, false, true, true)) && ((signed)FoundItems.size() < Amount)) - { - if (pItem->ItemName == ItemName) - FoundItems.add(pItem); + msstring ItemName = Payment.thru_char(":"); - LastItem = pItem->m_iId; + ulong LastItem = 0; + ulong FirstItem = 0; + CGenericItem* pItem = NULL; + static mslist FoundItems; + FoundItems.clearitems(); + while ((pItem = pPlayer->GetItemInInventory(LastItem, false, true, true)) && ((signed)FoundItems.size() < Amount)) + { + if (FirstItem == 0) + FirstItem = pItem->m_iId; + else if (pItem->m_iId == FirstItem) + break; - if (FirstItem == 0) - FirstItem = LastItem; - else if (LastItem == FirstItem) - break; - } + if (pItem->ItemName == ItemName) + FoundItems.add(pItem); - if ((signed)FoundItems.size() < Amount) - { - msstring ItemDispName = CGenericItemMgr::GetItemDisplayName(ItemName, false, true, Amount); + LastItem = pItem->m_iId; + } - if (!MenuOption.SilentPayment) - pPlayer->SendEventMsg(HUDEVENT_UNABLE, msstring("You can't afford the payment of ") + ItemDispName); - PlayerCanPay = false; - break; - } + if ((signed)FoundItems.size() < Amount) + { + msstring ItemDispName = CGenericItemMgr::GetItemDisplayName(ItemName, false, true, Amount); - for (unsigned int x = 0; x < FoundItems.size(); x++) - TotalFoundItems.add(FoundItems[x]); + if (!MenuOption.SilentPayment) + pPlayer->SendEventMsg(HUDEVENT_UNABLE, msstring("You can't afford the payment of ") + ItemDispName); + PlayerCanPay = false; + break; } - } - int PlayerGold = pPlayer->m_Gold; - if (PlayerGold < TotalGold) - { - if (!MenuOption.SilentPayment) - pPlayer->SendEventMsg(HUDEVENT_UNABLE, msstring("You can't afford the payment of ") + TotalGold + " Gold"); - PlayerCanPay = false; - } - - if (PlayerCanPay) - { - pPlayer->m_Gold -= TotalGold; - for (unsigned int i = 0; i < TotalFoundItems.size(); i++) - TotalFoundItems[i]->SUB_Remove(); //MIB JUN2010_14 (original line commented below) - //pPlayer->RemoveItem( TotalFoundItems[i] ); + for (int x = 0; x < FoundItems.size(); x++) + TotalFoundItems.add(FoundItems[x]); } } - //Handle callback - static msstringlist Params; - Params.clearitems(); - Params.add(EntToString(pPlayer)); - Params.add(MenuOption.Data); //Thothie - reg.mitem.data function wasn't returning as PARAM2 in type callback as described by docs, so I tried this, seems to work - - msstring CallbackEvent = MenuOption.CB_Name; - - if (MenuOption.Type == MOT_PAYMENT) + int PlayerGold = pPlayer->m_Gold; + if (PlayerGold < TotalGold) { - if (!PlayerCanPay) - CallbackEvent = MenuOption.CB_Failed_Name; + if (!MenuOption.SilentPayment) + pPlayer->SendEventMsg(HUDEVENT_UNABLE, msstring("You can't afford the payment of ") + TotalGold + " Gold"); + PlayerCanPay = false; } - if (CallbackEvent.len()) + if (PlayerCanPay) { - CallScriptEvent(CallbackEvent, &Params); + pPlayer->m_Gold -= TotalGold; + for (int i = 0; i < TotalFoundItems.size(); i++) + TotalFoundItems[i]->SUB_Remove(); //MIB JUN2010_14 (original line commented below) + //pPlayer->RemoveItem( TotalFoundItems[i] ); } - Menuoptions.clearitems(); } + + //Handle callback + static msstringlist Params; + Params.clearitems(); + Params.add(EntToString(pPlayer)); + Params.add(MenuOption.Data); //Thothie - reg.mitem.data function wasn't returning as PARAM2 in type callback as described by docs, so I tried this, seems to work + + msstring CallbackEvent = MenuOption.CB_Name; + + if (MenuOption.Type == MOT_PAYMENT) + { + if (!PlayerCanPay) + CallbackEvent = MenuOption.CB_Failed_Name; + } + + if (CallbackEvent.len()) + { + CallScriptEvent(CallbackEvent, &Params); + } + Menuoptions.clearitems(); +#endif } void AlignToNormal(/*In*/ Vector& vNormal, /*In - yaw must be set | Out - Sets pitch and roll*/ Vector& vAngles) diff --git a/src/game/server/monsters/npcact.cpp b/src/game/server/monsters/npcact.cpp index 03c97f72d..43ec1a1d7 100644 --- a/src/game/server/monsters/npcact.cpp +++ b/src/game/server/monsters/npcact.cpp @@ -198,7 +198,7 @@ void NPCScript ::PlayAnim() pMonster->SetAnimation(MONSTER_ANIM_ONCE, (char *)STRING(m_sActionAnim)); } pMonster->pev->frame = 0; //In case the previous AND current anim is sequence 0 - pMonster->m_fSequenceFinished = false; //ditto... + pMonster->m_fSequenceFinished = FALSE; //ditto... SetThink(&NPCScript::AnimateThink); pev->nextthink = gpGlobals->time + 0.1; } @@ -327,42 +327,42 @@ void NPCScript ::KeyValue(KeyValueData *pkvd) if (FStrEq(pkvd->szKeyName, "type")) { m_iType = atoi(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "moveanim")) { m_sMoveAnim = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "actionanim")) { m_sActionAnim = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "eventname")) { m_sEventName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "firewhendone")) { m_sFireWhenDone = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "fireonbreak")) { m_sFireOnBreak = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "firedelay")) { m_flFireDelay = atof(pkvd->szValue); - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "stopai")) { m_fStopAI = atoi(pkvd->szValue) ? true : false; - pkvd->fHandled = true; + pkvd->fHandled = TRUE; } else CBaseEntity ::KeyValue(pkvd); diff --git a/src/game/server/monsters/npcglobal.cpp b/src/game/server/monsters/npcglobal.cpp index 36d613df6..74ef031a9 100644 --- a/src/game/server/monsters/npcglobal.cpp +++ b/src/game/server/monsters/npcglobal.cpp @@ -12,7 +12,7 @@ void CMSMonster::DynamicPrecache() TokenizeString(pszString, NPCs); - for (unsigned int i = 0; i < NPCs.size(); i++) + for (int i = 0; i < NPCs.size(); i++) { const char* ScriptFile = NPCs[i]; diff --git a/src/game/server/monsters/npcscript.cpp b/src/game/server/monsters/npcscript.cpp index b530ef8ae..4476a4128 100644 --- a/src/game/server/monsters/npcscript.cpp +++ b/src/game/server/monsters/npcscript.cpp @@ -7,11 +7,6 @@ #include "stats/stats.h" #include "stats/races.h" #include "msitemdefs.h" -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - - // TODO: get rid of the macro for logging when we get rid of MSScript. #include "mslogger.h" @@ -113,7 +108,7 @@ bool CMSMonster::Script_ExecuteCmd(CScript *Script, SCRIPT_EVENT &Event, scriptc { //say [mouth open length] if (Params.size() >= 1) { - for (unsigned int i = 0; i < Params.size(); i++) + for (int i = 0; i < Params.size(); i++) { float fDuration = 0.2; msstring &FullWord = Params[i]; @@ -154,7 +149,7 @@ bool CMSMonster::Script_ExecuteCmd(CScript *Script, SCRIPT_EVENT &Event, scriptc CBaseEntity *pTarget = RetrieveEntity(ENT_ME); IScripted *pScripted = pTarget->GetScripted(); // UScripted? IScripted. - for (unsigned int i = 0; i < pScripted->m_Scripts.size(); i++) // Check each + for (int i = 0; i < pScripted->m_Scripts.size(); i++) // Check each { if (pScripted->m_Scripts[i]->VarExists("game.effect.id")) //This is an effect { @@ -408,11 +403,11 @@ bool CMSMonster::Script_ExecuteCmd(CScript *Script, SCRIPT_EVENT &Event, scriptc } //[end] - for (unsigned int p = 0; p < m_PlayerDamage.size(); p++) + for (int p = 0; p < m_PlayerDamage.size(); p++) { // for (int r = 0; r < SKILL_MAX_ATTACK; r++) // { - // for (unsigned int s = 0; s < STAT_PROP_ALL_TOTAL; s++) + // for (int s = 0; s < STATPROP_ALL_TOTAL; s++) // m_PlayerDamage[p].dmg[r][s] = 0; // } // m_PlayerDamage[p].dmgInTotal = 0; @@ -440,11 +435,11 @@ bool CMSMonster::Script_ExecuteCmd(CScript *Script, SCRIPT_EVENT &Event, scriptc if (atof(GetFirstScriptVar("NPC_ORIG_EXP")) > 0) { //first, wipe player hits, otherwise, we'll have problems - for (unsigned int p = 0; p < m_PlayerDamage.size(); p++) + for (int p = 0; p < m_PlayerDamage.size(); p++) { // for (int r = 0; r < SKILL_MAX_ATTACK; r++) // { - // for (unsigned int s = 0; s < STAT_PROP_ALL_TOTAL; s++) + // for (int s = 0; s < STATPROP_ALL_TOTAL; s++) // m_PlayerDamage[p].dmg[r][s] = 0; // } // m_PlayerDamage[p].dmgInTotal = 0; @@ -647,7 +642,7 @@ bool CMSMonster::Script_ExecuteCmd(CScript *Script, SCRIPT_EVENT &Event, scriptc bool inventory_full = false; if (pPlayer) { - if (pPlayer->NumItems() >= MAX_NUM_ITEMS) + if (pPlayer->NumItems() >= NUM_MAX_ITEMS) inventory_full = true; } @@ -700,7 +695,7 @@ bool CMSMonster::Script_ExecuteCmd(CScript *Script, SCRIPT_EVENT &Event, scriptc { //Parameters: