Improved show hitboxes commands and networked m_fFlags from animoverlays

This commit is contained in:
Kamay Xutax 2024-09-01 23:55:01 +02:00
parent 867f106584
commit be7d8cc228
16 changed files with 465 additions and 285 deletions

View file

@ -19,16 +19,16 @@
#include "proto_version.h" #include "proto_version.h"
// Flow control bytes per second limits // Flow control bytes per second limits
#define MAX_RATE (16777216) #define MAX_RATE (67108864)
#define MIN_RATE 1000 #define MIN_RATE 1000
#define DEFAULT_RATE 80000 #define DEFAULT_RATE 67108864
#define SIGNON_TIME_OUT 300.0f // signon disconnect timeout #define SIGNON_TIME_OUT 300.0f // signon disconnect timeout
#define FRAGMENT_BITS 8 #define FRAGMENT_BITS 8
#define FRAGMENT_SIZE (1<<FRAGMENT_BITS) #define FRAGMENT_SIZE (1<<FRAGMENT_BITS)
#define MAX_FILE_SIZE_BITS 26 #define MAX_FILE_SIZE_BITS 30
#define MAX_FILE_SIZE ((1<<MAX_FILE_SIZE_BITS)-1) // maximum transferable size is 64MB #define MAX_FILE_SIZE ((1<<MAX_FILE_SIZE_BITS)-1) // maximum transferable size is 1GB
// 0 == regular, 1 == file stream // 0 == regular, 1 == file stream
#define MAX_STREAMS 2 #define MAX_STREAMS 2

View file

@ -56,8 +56,8 @@ ConVar engine_no_focus_sleep( "engine_no_focus_sleep", "50", FCVAR_ARCHIVE );
// sleep time when not focus // sleep time when not focus
#define NOT_FOCUS_SLEEP 50 #define NOT_FOCUS_SLEEP 50
#define DEFAULT_FPS_MAX 300 #define DEFAULT_FPS_MAX 0
#define DEFAULT_FPS_MAX_S "300" #define DEFAULT_FPS_MAX_S "0"
static int s_nDesiredFPSMax = DEFAULT_FPS_MAX; static int s_nDesiredFPSMax = DEFAULT_FPS_MAX;
static bool s_bFPSMaxDrivenByPowerSavings = false; static bool s_bFPSMaxDrivenByPowerSavings = false;

View file

@ -15,6 +15,13 @@
#include "lerp_functions.h" #include "lerp_functions.h"
#include "networkvar.h" #include "networkvar.h"
#define ANIM_LAYER_ACTIVE 0x0001
#define ANIM_LAYER_AUTOKILL 0x0002
#define ANIM_LAYER_KILLME 0x0004
#define ANIM_LAYER_DONTRESTORE 0x0008
#define ANIM_LAYER_CHECKACCESS 0x0010
#define ANIM_LAYER_DYING 0x0020
class C_AnimationLayer class C_AnimationLayer
{ {
public: public:
@ -29,12 +36,20 @@ public:
public: public:
bool IsActive( void ); bool IsActive( void ) { return ((m_fFlags & ANIM_LAYER_ACTIVE) != 0); }
bool IsAutokill( void ) { return ((m_fFlags & ANIM_LAYER_AUTOKILL) != 0); }
bool IsKillMe( void ) { return ((m_fFlags & ANIM_LAYER_KILLME) != 0); }
bool IsAutoramp( void ) { return (m_flBlendIn != 0.0 || m_flBlendOut != 0.0); }
void KillMe( void ) { m_fFlags |= ANIM_LAYER_KILLME; }
void Dying( void ) { m_fFlags |= ANIM_LAYER_DYING; }
bool IsDying( void ) { return ((m_fFlags & ANIM_LAYER_DYING) != 0); }
void Dead( void ) { m_fFlags &= ~ANIM_LAYER_DYING; }
CRangeCheckedVar<int, -1, 65535, 0> m_nSequence; CRangeCheckedVar< int, -1, 65535, 0 > m_nSequence;
CRangeCheckedVar<float, -2, 2, 0> m_flPrevCycle; CRangeCheckedVar< float, -2, 2, 0 > m_flPrevCycle;
CRangeCheckedVar<float, -5, 5, 0> m_flWeight; CRangeCheckedVar< float, -5, 5, 0 > m_flWeight;
int m_nOrder; int m_nOrder;
int m_fFlags;
// used for automatic crossfades between sequence changes // used for automatic crossfades between sequence changes
CRangeCheckedVar<float, -50, 50, 1> m_flPlaybackRate; CRangeCheckedVar<float, -50, 50, 1> m_flPlaybackRate;
@ -75,7 +90,6 @@ inline void C_AnimationLayer::Reset()
m_bClientBlend = false; m_bClientBlend = false;
} }
inline void C_AnimationLayer::SetOrder( int order ) inline void C_AnimationLayer::SetOrder( int order )
{ {
m_nOrder = order; m_nOrder = order;
@ -85,15 +99,15 @@ inline float C_AnimationLayer::GetFadeout( float flCurTime )
{ {
float s; float s;
if (m_flLayerFadeOuttime <= 0.0f) if ( m_flLayerFadeOuttime <= 0.0f )
{ {
s = 0; s = 0;
} }
else else
{ {
// blend in over 0.2 seconds // blend in over 0.2 seconds
s = 1.0 - (flCurTime - m_flLayerAnimtime) / m_flLayerFadeOuttime; s = 1.0 - ( flCurTime - m_flLayerAnimtime ) / m_flLayerFadeOuttime;
if (s > 0 && s <= 1.0) if ( s > 0 && s <= 1.0 )
{ {
// do a nice spline curve // do a nice spline curve
s = 3 * s * s - 2 * s * s * s; s = 3 * s * s - 2 * s * s * s;
@ -107,7 +121,6 @@ inline float C_AnimationLayer::GetFadeout( float flCurTime )
return s; return s;
} }
inline C_AnimationLayer LoopingLerp( float flPercent, C_AnimationLayer& from, C_AnimationLayer& to ) inline C_AnimationLayer LoopingLerp( float flPercent, C_AnimationLayer& from, C_AnimationLayer& to )
{ {
C_AnimationLayer output; C_AnimationLayer output;

View file

@ -96,11 +96,6 @@ void VCollideWireframe_ChangeCallback( IConVar *pConVar, char const *pOldString,
ConVar vcollide_wireframe( "vcollide_wireframe", "0", FCVAR_CHEAT, "Render physics collision models in wireframe", VCollideWireframe_ChangeCallback ); ConVar vcollide_wireframe( "vcollide_wireframe", "0", FCVAR_CHEAT, "Render physics collision models in wireframe", VCollideWireframe_ChangeCallback );
bool C_AnimationLayer::IsActive( void )
{
return (m_nOrder != C_BaseAnimatingOverlay::MAX_OVERLAYS);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Relative lighting entity // Relative lighting entity
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -3433,7 +3428,7 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
if ( nSeqNum >= nStudioNumSeq ) if ( nSeqNum >= nStudioNumSeq )
{ {
// This can happen e.g. while reloading Heavy's shotgun, switch to the minigun. // This can happen e.g. while reloading Heavy's shotgun, switch to the minigun.
Warning( "%s[%d]: Playing sequence %d but there's only %d in total?\n", GetDebugName(), entindex(), nSeqNum, nStudioNumSeq ); DevMsg( "%s[%d]: Playing sequence %d but there's only %d in total?\n", GetDebugName(), entindex(), nSeqNum, nStudioNumSeq );
return; return;
} }
@ -5552,20 +5547,47 @@ void C_BaseAnimating::DrawClientHitboxes( float duration /*= 0.0f*/, bool monoco
int g = 255; int g = 255;
int b = 0; int b = 0;
if ( !monocolor )
{
g = 0;
r = 255;
}
// printf( "got sequence: %i, cycle: %f\n", GetSequence(), GetCycle() );
// for ( int i = 0; i < pStudioHdr->GetNumPoseParameters(); i++ )
// {
// printf( "pose_param_%i: %f\n", i, GetPoseParameter( i ) );
// }
// float bc[MAXSTUDIOBONECTRLS];
// GetBoneControllers(bc);
// for ( int i = 0; i < pStudioHdr->GetNumBoneControllers(); i++ )
// {
// printf( "bone_controller_%i: %f\n", i, bc[i] );
// }
// C_BasePlayer* player = ( C_BasePlayer* )this;
// if ( player->IsPlayer() )
// {
// for ( int i = 0; i < player->GetNumAnimOverlays(); i++ )
// {
// auto animOverlay = player->GetAnimOverlay( i );
// printf( "anim_overlay_cycle_%i: %f\n", i, animOverlay->m_flCycle.GetRaw() );
// printf( "anim_overlay_sequence_%i: %i\n", i, animOverlay->m_nSequence.GetRaw() );
// printf( "anim_overlay_weight_%i: %f\n", i, animOverlay->m_flWeight.GetRaw() );
// printf( "anim_overlay_order_%i: %i\n", i, animOverlay->m_nOrder );
// }
// }
for ( int i = 0; i < set->numhitboxes; i++ ) for ( int i = 0; i < set->numhitboxes; i++ )
{ {
mstudiobbox_t *pbox = set->pHitbox( i ); mstudiobbox_t *pbox = set->pHitbox( i );
GetBonePosition( pbox->bone, position, angles ); GetBonePosition( pbox->bone, position, angles );
if ( !monocolor )
{
int j = (pbox->group % 8);
r = ( int ) ( 255.0f * hullcolor[j][0] );
g = ( int ) ( 255.0f * hullcolor[j][1] );
b = ( int ) ( 255.0f * hullcolor[j][2] );
}
debugoverlay->AddBoxOverlay( position, pbox->bbmin, pbox->bbmax, angles, r, g, b, 127 ,duration ); debugoverlay->AddBoxOverlay( position, pbox->bbmin, pbox->bbmax, angles, r, g, b, 127 ,duration );
} }
} }

View file

@ -44,7 +44,8 @@ BEGIN_RECV_TABLE_NOBASE(CAnimationLayer, DT_Animationlayer)
RecvPropFloat( RECVINFO_NAME(m_flCycle, m_flCycle)), RecvPropFloat( RECVINFO_NAME(m_flCycle, m_flCycle)),
RecvPropFloat( RECVINFO_NAME(m_flPrevCycle, m_flPrevCycle)), RecvPropFloat( RECVINFO_NAME(m_flPrevCycle, m_flPrevCycle)),
RecvPropFloat( RECVINFO_NAME(m_flWeight, m_flWeight)), RecvPropFloat( RECVINFO_NAME(m_flWeight, m_flWeight)),
RecvPropInt( RECVINFO_NAME(m_nOrder, m_nOrder)) RecvPropInt( RECVINFO_NAME(m_nOrder, m_nOrder)),
RecvPropInt( RECVINFO_NAME(m_fFlags, m_fFlags)),
END_RECV_TABLE() END_RECV_TABLE()
const char *s_m_iv_AnimOverlayNames[C_BaseAnimatingOverlay::MAX_OVERLAYS] = const char *s_m_iv_AnimOverlayNames[C_BaseAnimatingOverlay::MAX_OVERLAYS] =

View file

@ -2113,93 +2113,218 @@ void C_CSPlayer::FireEvent( const Vector& origin, const QAngle& angles, int even
BaseClass::FireEvent( origin, angles, event, options ); BaseClass::FireEvent( origin, angles, event, options );
} }
void C_CSPlayer::FireGameEvent(IGameEvent* event) ConVar cl_debug_duration( "cl_debug_duration", "60" );
void C_CSPlayer::FireGameEvent( IGameEvent* event )
{ {
static ConVarRef cl_showfirebullethitboxes("cl_showfirebullethitboxes"); static ConVarRef cl_showfirebullethitboxes( "cl_showfirebullethitboxes" );
static ConVarRef cl_showimpacts("cl_showimpacts"); static ConVarRef cl_showimpacts( "cl_showimpacts" );
static ConVarRef debug_screenshot_bullet_position("debug_screenshot_bullet_position"); static ConVarRef debug_screenshot_bullet_position( "debug_screenshot_bullet_position" );
BaseClass::FireGameEvent(event); BaseClass::FireGameEvent( event );
bool shouldShowImpacts = cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 3;
bool shouldShowFireBulletHitboxes = cl_showfirebullethitboxes.GetInt() == 1 || cl_showfirebullethitboxes.GetInt() == 3;
const auto showEventHitboxes = [&](float flDuration)
{
const int index = event->GetInt("userid");
if (index == GetUserID() && IsLocalPlayer())
{
const auto playerIndex = event->GetInt("player_index");
const auto player = UTIL_PlayerByIndex(playerIndex);
if (player && !player->IsLocalPlayer()) bool shouldShowImpacts = cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 3;
{ bool shouldShowFireBulletHitboxes = cl_showfirebullethitboxes.GetInt() == 1
const auto numhitboxes = event->GetInt("num_hitboxes"); || cl_showfirebullethitboxes.GetInt() == 3;
QAngle angles[MAXSTUDIOBONES];
Vector positions[MAXSTUDIOBONES];
for (int i = 0; i < numhitboxes; i++) const auto ShowEventHitboxes = [&]( float flDuration )
{ {
char buffer[256];
V_sprintf_safe(buffer, "hitbox_index_%i", i);
const auto hitboxIndex = event->GetInt(buffer);
V_sprintf_safe(buffer, "hitbox_position_x_%i", i);
positions[hitboxIndex].x = event->GetFloat(buffer);
V_sprintf_safe(buffer, "hitbox_position_y_%i", i);
positions[hitboxIndex].y = event->GetFloat(buffer);
V_sprintf_safe(buffer, "hitbox_position_z_%i", i);
positions[hitboxIndex].z = event->GetFloat(buffer);
V_sprintf_safe(buffer, "hitbox_angle_x_%i", i);
angles[hitboxIndex].x = event->GetFloat(buffer);
V_sprintf_safe(buffer, "hitbox_angle_y_%i", i);
angles[hitboxIndex].y = event->GetFloat(buffer);
V_sprintf_safe(buffer, "hitbox_angle_z_%i", i);
angles[hitboxIndex].z = event->GetFloat(buffer);
}
player->DrawServerHitboxes(positions, angles, flDuration, true);
}
}
};
if ( FStrEq( event->GetName(), "bullet_impact" ) && shouldShowImpacts )
{
const int index = event->GetInt( "userid" ); const int index = event->GetInt( "userid" );
if ( index == GetUserID() && IsLocalPlayer() ) if ( index == GetUserID() && IsLocalPlayer() )
{ {
Vector src(event->GetFloat("src_x"), event->GetFloat("src_y"), event->GetFloat("src_z")); const auto playerIndex = event->GetInt( "player_index" );
Vector dst(event->GetFloat("dst_x"), event->GetFloat("dst_y"), event->GetFloat("dst_z")); const auto player = UTIL_PlayerByIndex( playerIndex );
float flBulletRadius = event->GetFloat("radius");
Vector mins(-flBulletRadius); if ( player && !player->IsLocalPlayer() )
Vector maxs(flBulletRadius); {
const auto numhitboxes = event->GetInt( "num_hitboxes" );
QAngle angles[MAXSTUDIOBONES];
Vector positions[MAXSTUDIOBONES];
DrawBullet(src, dst, mins, maxs, 0, 0, 255, 127, m_flDebugDuration); for ( int i = 0; i < numhitboxes; i++ )
{
char buffer[256];
V_sprintf_safe( buffer, "hitbox_index_%i", i );
const auto hitboxIndex = event->GetInt( buffer );
// If both happens to be on the same frame, let it be. V_sprintf_safe( buffer, "hitbox_position_x_%i", i );
if (debug_screenshot_bullet_position.GetBool()) positions[hitboxIndex].x = event->GetFloat( buffer );
{ V_sprintf_safe( buffer, "hitbox_position_y_%i", i );
gpGlobals->client_taking_screenshot = true; positions[hitboxIndex].y = event->GetFloat( buffer );
} V_sprintf_safe( buffer, "hitbox_position_z_%i", i );
} positions[hitboxIndex].z = event->GetFloat( buffer );
}
else if (FStrEq(event->GetName(), "bullet_hit_player") && shouldShowImpacts)
{
showEventHitboxes(m_flDebugDuration);
// If both happens to be on the same frame, let it be. V_sprintf_safe( buffer, "hitbox_angle_x_%i", i );
if (debug_screenshot_bullet_position.GetBool()) angles[hitboxIndex].x = event->GetFloat( buffer );
{ V_sprintf_safe( buffer, "hitbox_angle_y_%i", i );
gpGlobals->client_taking_screenshot = true; angles[hitboxIndex].y = event->GetFloat( buffer );
} V_sprintf_safe( buffer, "hitbox_angle_z_%i", i );
} angles[hitboxIndex].z = event->GetFloat( buffer );
else if (FStrEq(event->GetName(), "bullet_player_hitboxes") && shouldShowFireBulletHitboxes) }
{
showEventHitboxes(m_flDebugDuration); player->DrawServerHitboxes( positions, angles, flDuration, true );
}
// Let's see what the client thinks to check if there's any problems with hitboxes
float flBackupPoseParams[MAXSTUDIOPOSEPARAM];
float flBackupBoneControllers[MAXSTUDIOBONECTRLS];
C_AnimationLayer backupAnimLayers[C_BaseAnimatingOverlay::MAX_OVERLAYS];
Vector vecBackupPosition = player->GetAbsOrigin();
QAngle angBackupAngles = player->GetAbsAngles();
auto flOldCycle = GetCycle();
auto iOldSequence = GetSequence();
auto pStudioHdr = GetModelPtr();
player->GetPoseParameters( pStudioHdr, flBackupPoseParams );
player->GetBoneControllers( flBackupBoneControllers );
for ( int i = 0; i < GetNumAnimOverlays(); i++ )
{
backupAnimLayers[i] = m_AnimOverlay[i];
}
player->SetSequence( event->GetInt( "sequence" ) );
player->SetCycle( event->GetFloat( "cycle" ) );
// printf("was sequence: %i, cycle: %f\n", player->GetSequence(), player->GetCycle() );
// Set setup bones modifiers
player->SetAbsOrigin( Vector( event->GetFloat( "position_x" ),
event->GetFloat( "position_y" ),
event->GetFloat( "position_z" ) ) );
player->SetAbsAngles( QAngle( event->GetFloat( "angle_x" ),
event->GetFloat( "angle_y" ),
event->GetFloat( "angle_z" ) ) );
const auto numposeparams = event->GetInt( "num_poseparams" );
Assert( numposeparams == pStudioHdr->GetNumPoseParameters() );
for ( int i = 0; i < numposeparams; i++ )
{
char buffer[256];
V_sprintf_safe( buffer, "pose_param_%i", i );
player->SetPoseParameter( i, event->GetFloat( buffer ) );
// printf("pose_param_%i: %f\n", i, player->GetPoseParameter(i) );
}
const auto numbonecontrollers = event->GetInt( "num_bonecontrollers" );
Assert( numbonecontrollers == pStudioHdr->GetNumBoneControllers() );
for ( int i = 0; i < numbonecontrollers; i++ )
{
char buffer[256];
V_sprintf_safe( buffer, "bone_controller_%i", i );
player->SetBoneController( i, event->GetFloat( buffer ) );
float tmp[MAXSTUDIOBONECTRLS];
player->GetBoneControllers( tmp );
// printf( "bone_controller_%i: %f\n", i, tmp[i] );
}
auto numanimoverlays = event->GetInt( "num_anim_overlays" );
Assert( num_anim_overlays == player->GetNumAnimOverlays() );
for ( int i = 0; i < numanimoverlays; i++ )
{
auto animOverlay = player->GetAnimOverlay( i );
char buffer[256];
V_sprintf_safe( buffer, "anim_overlay_cycle_%i", i );
animOverlay->m_flCycle = event->GetFloat( buffer );
// printf( "anim_overlay_cycle_%i: %f\n", i, animOverlay->m_flCycle.GetRaw() );
V_sprintf_safe( buffer, "anim_overlay_sequence_%i", i );
animOverlay->m_nSequence = event->GetInt( buffer );
// printf( "anim_overlay_sequence_%i: %i\n", i, animOverlay->m_nSequence.GetRaw() );
V_sprintf_safe( buffer, "anim_overlay_weight_%i", i );
animOverlay->m_flWeight = event->GetFloat( buffer );
// printf( "anim_overlay_weight_%i: %f\n", i,animOverlay->m_flWeight.GetRaw() );
V_sprintf_safe( buffer, "anim_overlay_order_%i", i );
animOverlay->m_nOrder = event->GetInt( buffer );
// printf( "anim_overlay_order_%i: %i\n", i, animOverlay->m_nOrder );
}
PushAllowBoneAccess( true, false, "Lag compensation context" );
// Be sure we setup the bones again.
player->InvalidateBoneCache();
player->SetupBones( NULL,
MAXSTUDIOBONES,
BONE_USED_BY_HITBOX | BONE_USED_BY_ATTACHMENT | BONE_USED_BY_BONE_MERGE,
gpGlobals->curtime );
player->DrawClientHitboxes( cl_debug_duration.GetFloat(), false );
// Re-invalidate bone cache for the next frame
player->InvalidateBoneCache();
PopBoneAccess( "Lag compensation context" );
// Set back original stuff.
player->SetSequence( iOldSequence );
player->SetCycle( flOldCycle );
player->SetAbsOrigin( vecBackupPosition );
player->SetAbsAngles( angBackupAngles );
for ( int i = 0; i < numposeparams; i++ )
{
player->SetPoseParameter( i, flBackupPoseParams[i] );
}
for ( int i = 0; i < numbonecontrollers; i++ )
{
player->SetBoneController( i, flBackupBoneControllers[i] );
}
for ( int i = 0; i < numanimoverlays; i++ )
{
auto animOverlay = player->GetAnimOverlay( i );
animOverlay->m_flCycle = backupAnimLayers[i].m_flCycle;
animOverlay->m_nSequence = backupAnimLayers[i].m_nSequence;
animOverlay->m_flWeight = backupAnimLayers[i].m_flWeight;
animOverlay->m_nOrder = backupAnimLayers[i].m_nOrder;
}
}
}
};
if ( FStrEq( event->GetName(), "bullet_impact" ) && shouldShowImpacts )
{
const int index = event->GetInt( "userid" );
if ( index == GetUserID() && IsLocalPlayer() )
{
Vector src( event->GetFloat( "src_x" ), event->GetFloat( "src_y" ), event->GetFloat( "src_z" ) );
Vector dst( event->GetFloat( "dst_x" ), event->GetFloat( "dst_y" ), event->GetFloat( "dst_z" ) );
float flBulletRadius = event->GetFloat( "radius" );
Vector mins( -flBulletRadius );
Vector maxs( flBulletRadius );
DrawBullet( src, dst, mins, maxs, 0, 0, 255, 127, cl_debug_duration.GetFloat() );
// If both happens to be on the same frame, let it be.
if ( debug_screenshot_bullet_position.GetBool() )
{
gpGlobals->client_taking_screenshot = true;
}
}
}
else if ( FStrEq( event->GetName(), "bullet_hit_player" ) && shouldShowImpacts )
{
ShowEventHitboxes( cl_debug_duration.GetFloat() );
// If both happens to be on the same frame, let it be.
if ( debug_screenshot_bullet_position.GetBool() )
{
gpGlobals->client_taking_screenshot = true;
}
}
else if ( FStrEq( event->GetName(), "bullet_player_hitboxes" ) && shouldShowFireBulletHitboxes )
{
ShowEventHitboxes( cl_debug_duration.GetFloat() );
}
} }
@ -2574,9 +2699,17 @@ float C_CSPlayer::GetDeathCamInterpolationTime()
} }
bool C_CSPlayer::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime ) bool C_CSPlayer::SetupBones( matrix3x4_t* pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime )
{ {
return BaseClass::SetupBones( pBoneToWorldOut, nMaxBones, boneMask, currentTime ); // Just in case.
float oldCurtime = gpGlobals->curtime;
gpGlobals->curtime = currentTime;
auto ret = BaseClass::SetupBones( pBoneToWorldOut, nMaxBones, boneMask, currentTime );
gpGlobals->curtime = oldCurtime;
return ret;
} }
//============================================================================= //=============================================================================

View file

@ -381,7 +381,6 @@ private:
// HPE_END // HPE_END
//============================================================================= //=============================================================================
static constexpr auto m_flDebugDuration = 60.f;
void DrawBullet(const Vector& src, void DrawBullet(const Vector& src,
const Vector& endpos, const Vector& endpos,
const Vector& mins, const Vector& mins,

View file

@ -1320,7 +1320,7 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
} }
cmd->simulationdata[pEntity->index].lerp_time = pEntity->m_flInterpolatedSimulationTime; cmd->simulationdata[pEntity->index].lerp_time = pEntity->m_flInterpolatedSimulationTime;
cmd->simulationdata[pEntity->index].animated_sim_time = pEntity->m_flSimulationTime; cmd->simulationdata[pEntity->index].animated_sim_time = pEntity->m_flAnimTime;
cmd->simulationdata[pEntity->index].entityexists = true; cmd->simulationdata[pEntity->index].entityexists = true;
} }

View file

@ -67,6 +67,7 @@ BEGIN_SEND_TABLE_NOBASE(CAnimationLayer, DT_Animationlayer)
SendPropFloat (SENDINFO(m_flPrevCycle)), SendPropFloat (SENDINFO(m_flPrevCycle)),
SendPropFloat (SENDINFO(m_flWeight)), SendPropFloat (SENDINFO(m_flWeight)),
SendPropInt (SENDINFO(m_nOrder)), SendPropInt (SENDINFO(m_nOrder)),
SendPropInt (SENDINFO(m_fFlags)),
END_SEND_TABLE() END_SEND_TABLE()

View file

@ -44,7 +44,7 @@ public:
#define ANIM_LAYER_CHECKACCESS 0x0010 #define ANIM_LAYER_CHECKACCESS 0x0010
#define ANIM_LAYER_DYING 0x0020 #define ANIM_LAYER_DYING 0x0020
int m_fFlags; CNetworkVar( int, m_fFlags );
bool m_bSequenceFinished; bool m_bSequenceFinished;
bool m_bLooping; bool m_bLooping;

View file

@ -2805,23 +2805,14 @@ CBoneCache *CBaseAnimating::GetBoneCache( void )
CStudioHdr *pStudioHdr = GetModelPtr( ); CStudioHdr *pStudioHdr = GetModelPtr( );
Assert(pStudioHdr); Assert(pStudioHdr);
// Use this for lag compensation
float oldcurtime = gpGlobals->curtime;
gpGlobals->curtime = m_flSimulationTime;
CBoneCache *pcache = Studio_GetBoneCache( m_boneCacheHandle ); CBoneCache *pcache = Studio_GetBoneCache( m_boneCacheHandle );
int boneMask = BONE_USED_BY_ANYTHING; int boneMask = BONE_USED_BY_BONE_MERGE | BONE_USED_BY_HITBOX | BONE_USED_BY_ATTACHMENT;
// TF queries these bones to position weapons when players are killed
#if defined( TF_DLL )
boneMask |= BONE_USED_BY_BONE_MERGE;
#endif
if ( pcache ) if ( pcache )
{ {
// Only validate for current time. // Only validate for current time.
if ( (pcache->m_boneMask & boneMask) == boneMask && pcache->m_timeValid == gpGlobals->curtime) if ( (pcache->m_boneMask & boneMask) == boneMask && pcache->m_timeValid == gpGlobals->curtime)
{ {
gpGlobals->curtime = oldcurtime;
// Msg("%s:%s:%s (%x:%x:%8.4f) cache\n", GetClassname(), GetDebugName(), STRING(GetModelName()), boneMask, pcache->m_boneMask, pcache->m_timeValid ); // Msg("%s:%s:%s (%x:%x:%8.4f) cache\n", GetClassname(), GetDebugName(), STRING(GetModelName()), boneMask, pcache->m_boneMask, pcache->m_timeValid );
// in memory and still valid, use it! // in memory and still valid, use it!
return pcache; return pcache;
@ -2856,7 +2847,6 @@ CBoneCache *CBaseAnimating::GetBoneCache( void )
} }
Assert(pcache); Assert(pcache);
gpGlobals->curtime = oldcurtime;
return pcache; return pcache;
} }

View file

@ -1,6 +1,6 @@
//========= Copyright Valve Corporation, All rights reserved. ============// //========= Copyright Valve Corporation, All rights reserved. ============//
// //
// Purpose: // Purpose:
// //
// $NoKeywords: $ // $NoKeywords: $
//=============================================================================// //=============================================================================//
@ -41,6 +41,24 @@ ConVar sv_lagflushbonecache( "sv_lagflushbonecache", "0", 0, "Flushes entity bon
// Purpose: // Purpose:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct LayerRecord
{
int m_sequence;
float m_cycle;
float m_weight;
int m_order;
int m_flags;
LayerRecord()
{
m_sequence = 0;
m_cycle = 0;
m_weight = 0;
m_order = 0;
m_flags = 0;
}
};
struct LagRecord struct LagRecord
{ {
public: public:
@ -86,7 +104,7 @@ struct LagRecord
{ {
m_layerRecords[layerIndex] = src.m_layerRecords[layerIndex]; m_layerRecords[layerIndex] = src.m_layerRecords[layerIndex];
} }
m_masterSequence = src.m_masterSequence; m_masterSequence = src.m_masterSequence;
m_masterCycle = src.m_masterCycle; m_masterCycle = src.m_masterCycle;
@ -280,6 +298,7 @@ void CLagCompensationManager::TrackPlayerData( CBasePlayer* pPlayer )
record.m_layerRecords[layerIndex].m_order = currentLayer->m_nOrder; record.m_layerRecords[layerIndex].m_order = currentLayer->m_nOrder;
record.m_layerRecords[layerIndex].m_sequence = currentLayer->m_nSequence; record.m_layerRecords[layerIndex].m_sequence = currentLayer->m_nSequence;
record.m_layerRecords[layerIndex].m_weight = currentLayer->m_flWeight; record.m_layerRecords[layerIndex].m_weight = currentLayer->m_flWeight;
record.m_layerRecords[layerIndex].m_flags = currentLayer->m_fFlags;
} }
} }
@ -412,7 +431,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer* pPlayer, CUserCmd* c
break; break;
} }
if ( recordAnim->m_flSimulationTime == flTargetAnimatedSimulationTime ) if ( recordAnim->m_flAnimTime == flTargetAnimatedSimulationTime )
{ {
break; break;
} }
@ -528,11 +547,13 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer* pPlayer, CUserCmd* c
restore->m_layerRecords[layerIndex].m_order = currentLayer->m_nOrder; restore->m_layerRecords[layerIndex].m_order = currentLayer->m_nOrder;
restore->m_layerRecords[layerIndex].m_sequence = currentLayer->m_nSequence; restore->m_layerRecords[layerIndex].m_sequence = currentLayer->m_nSequence;
restore->m_layerRecords[layerIndex].m_weight = currentLayer->m_flWeight; restore->m_layerRecords[layerIndex].m_weight = currentLayer->m_flWeight;
restore->m_layerRecords[layerIndex].m_flags = currentLayer->m_fFlags;
currentLayer->m_flCycle = recordAnim->m_layerRecords[layerIndex].m_cycle; currentLayer->m_flCycle = recordAnim->m_layerRecords[layerIndex].m_cycle;
currentLayer->m_nOrder = recordAnim->m_layerRecords[layerIndex].m_order; currentLayer->m_nOrder = recordAnim->m_layerRecords[layerIndex].m_order;
currentLayer->m_nSequence = recordAnim->m_layerRecords[layerIndex].m_sequence; currentLayer->m_nSequence = recordAnim->m_layerRecords[layerIndex].m_sequence;
currentLayer->m_flWeight = recordAnim->m_layerRecords[layerIndex].m_weight; currentLayer->m_flWeight = recordAnim->m_layerRecords[layerIndex].m_weight;
currentLayer->m_fFlags = recordAnim->m_layerRecords[layerIndex].m_flags;
} }
} }
@ -558,7 +579,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer* pPlayer, CUserCmd* c
for ( int encIndex = 0; encIndex < hdr->GetNumBoneControllers(); encIndex++ ) for ( int encIndex = 0; encIndex < hdr->GetNumBoneControllers(); encIndex++ )
{ {
restore->m_encodedControllers[encIndex] = pPlayer->GetBoneControllerArray()[encIndex]; restore->m_encodedControllers[encIndex] = pPlayer->GetBoneControllerArray()[encIndex];
float encodedController = recordAnim->m_encodedControllers[encIndex]; float encodedController = recordAnim->m_encodedControllers[encIndex];
pPlayer->SetBoneControllerRaw( encIndex, encodedController ); pPlayer->SetBoneControllerRaw( encIndex, encodedController );
} }
@ -662,6 +683,7 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer* player )
currentLayer->m_nOrder = restore->m_layerRecords[layerIndex].m_order; currentLayer->m_nOrder = restore->m_layerRecords[layerIndex].m_order;
currentLayer->m_nSequence = restore->m_layerRecords[layerIndex].m_sequence; currentLayer->m_nSequence = restore->m_layerRecords[layerIndex].m_sequence;
currentLayer->m_flWeight = restore->m_layerRecords[layerIndex].m_weight; currentLayer->m_flWeight = restore->m_layerRecords[layerIndex].m_weight;
currentLayer->m_fFlags = restore->m_layerRecords[layerIndex].m_flags;
} }
} }
} }

View file

@ -39,7 +39,6 @@
#include "engine/ivdebugoverlay.h" #include "engine/ivdebugoverlay.h"
#include "obstacle_pushaway.h" #include "obstacle_pushaway.h"
#include "props_shared.h" #include "props_shared.h"
// #include <iostream>
ConVar weapon_accuracy_nospread( "weapon_accuracy_nospread", "0", FCVAR_REPLICATED ); ConVar weapon_accuracy_nospread( "weapon_accuracy_nospread", "0", FCVAR_REPLICATED );
#define CS_MASK_SHOOT (MASK_SOLID|CONTENTS_DEBRIS) #define CS_MASK_SHOOT (MASK_SOLID|CONTENTS_DEBRIS)
@ -422,6 +421,7 @@ inline void UTIL_TraceLineIgnoreTwoEntities(const Vector& vecAbsStart, const Vec
} }
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
extern ConVar cl_debug_duration;
void CCSPlayer::DrawBullet(const Vector& src, void CCSPlayer::DrawBullet(const Vector& src,
const Vector& endpos, const Vector& endpos,
const Vector& mins, const Vector& mins,
@ -522,79 +522,127 @@ void CCSPlayer::FireBullet(
shouldDebugHitboxesOnHit = shouldDebugHitboxesOnHit && (cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 2); shouldDebugHitboxesOnHit = shouldDebugHitboxesOnHit && (cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 2);
shouldDebugHitboxesOnFire = shouldDebugHitboxesOnFire && (cl_showfirebullethitboxes.GetInt() == 1 || cl_showfirebullethitboxes.GetInt() == 2); shouldDebugHitboxesOnFire = shouldDebugHitboxesOnFire && (cl_showfirebullethitboxes.GetInt() == 1 || cl_showfirebullethitboxes.GetInt() == 2);
#endif #endif
if ( shouldDebugHitboxesOnFire )
{ #ifndef CLIENT_DLL
for (int i = 1; i <= gpGlobals->maxClients; i++) auto WritePlayerHitboxEvent = [&]( CBasePlayer* lagPlayer )
{ {
CBasePlayer* lagPlayer = UTIL_PlayerByIndex(i); if ( IsBot() )
if (lagPlayer && lagPlayer != this) {
return;
}
IGameEvent* event = gameeventmanager->CreateEvent( "bullet_player_hitboxes" );
if ( event )
{
event->SetInt( "userid", GetUserID() );
event->SetInt( "player_index", lagPlayer->entindex() );
Vector positions[MAXSTUDIOBONES];
QAngle angles[MAXSTUDIOBONES];
int indexes[MAXSTUDIOBONES];
auto angle = lagPlayer->GetAbsAngles();
auto position = lagPlayer->GetAbsOrigin();
event->SetFloat( "position_x", position.x );
event->SetFloat( "position_y", position.y );
event->SetFloat( "position_z", position.z );
event->SetFloat( "angle_x", angle.x );
event->SetFloat( "angle_y", angle.y );
event->SetFloat( "angle_z", angle.z );
event->SetFloat( "cycle", lagPlayer->GetCycle() );
event->SetInt( "sequence", lagPlayer->GetSequence() );
int numhitboxes = lagPlayer->GetServerHitboxes( positions, angles, indexes );
event->SetInt( "num_hitboxes", numhitboxes );
for ( int i = 0; i < numhitboxes; i++ )
{ {
// #ifdef CLIENT_DLL char buffer[256];
// if ( !m_pCurrentCommand->hasbeenpredicted ) V_sprintf_safe( buffer, "hitbox_index_%i", i );
// { event->SetInt( buffer, indexes[i] );
// std::string text = "client:\n"; V_sprintf_safe( buffer, "hitbox_position_x_%i", i );
event->SetFloat( buffer, positions[indexes[i]].x );
V_sprintf_safe( buffer, "hitbox_position_y_%i", i );
event->SetFloat( buffer, positions[indexes[i]].y );
V_sprintf_safe( buffer, "hitbox_position_z_%i", i );
event->SetFloat( buffer, positions[indexes[i]].z );
V_sprintf_safe( buffer, "hitbox_angle_x_%i", i );
event->SetFloat( buffer, angles[indexes[i]].x );
V_sprintf_safe( buffer, "hitbox_angle_y_%i", i );
event->SetFloat( buffer, angles[indexes[i]].y );
V_sprintf_safe( buffer, "hitbox_angle_z_%i", i );
event->SetFloat( buffer, angles[indexes[i]].z );
}
// auto angles = lagPlayer->GetRenderAngles(); auto model = lagPlayer->GetModelPtr();
// text += "x: " + std::to_string(angles.x) + ", y: " + std::to_string(angles.y) + ", z: " + std::to_string(angles.z) + '\n'; auto numposeparams = model->GetNumPoseParameters();
event->SetInt( "num_poseparams", numposeparams );
// NDebugOverlay::EntityBounds( lagPlayer, 255, 0, 0, 32, 60 ); for ( int i = 0; i < numposeparams; i++ )
// std::cout << text; {
// } char buffer[256];
// #else V_sprintf_safe( buffer, "pose_param_%i", i );
// std::string text = "server:\n"; event->SetFloat( buffer, lagPlayer->GetPoseParameterArray()[i] );
}
// auto angles = lagPlayer->GetAbsAngles(); auto numbonecontrollers = model->GetNumBoneControllers();
event->SetInt( "num_bonecontrollers", numbonecontrollers );
// text += "x: " + std::to_string(angles.x) + ", y: " + std::to_string(angles.y) + ", z: " + std::to_string(angles.z) + '\n'; for ( int i = 0; i < numbonecontrollers; i++ )
{
// NDebugOverlay::EntityBounds( lagPlayer, 0, 255, 0, 32, 60 ); char buffer[256];
// std::cout << text; V_sprintf_safe( buffer, "bone_controller_%i", i );
// #endif event->SetFloat( buffer, lagPlayer->GetBoneControllerArray()[i] );
#ifdef CLIENT_DLL }
if (!m_pCurrentCommand->hasbeenpredicted)
{
lagPlayer->DrawClientHitboxes(m_flDebugDuration, true);
}
#else
IGameEvent* event = gameeventmanager->CreateEvent("bullet_player_hitboxes");
if (event)
{
event->SetInt("userid", GetUserID());
event->SetInt("player_index", lagPlayer->entindex());
Vector positions[MAXSTUDIOBONES]; auto numanimoverlays = lagPlayer->GetNumAnimOverlays();
QAngle angles[MAXSTUDIOBONES]; event->SetInt( "num_anim_overlays", numanimoverlays );
int indexes[MAXSTUDIOBONES];
int numhitboxes = lagPlayer->GetServerHitboxes(positions, angles, indexes); for ( int i = 0; i < numanimoverlays; i++ )
event->SetInt("num_hitboxes", numhitboxes); {
auto animOverlay = lagPlayer->GetAnimOverlay( i );
for (int i = 0; i < numhitboxes; i++) char buffer[256];
{ V_sprintf_safe( buffer, "anim_overlay_cycle_%i", i );
char buffer[256]; event->SetFloat( buffer, animOverlay->m_flCycle.Get() );
V_sprintf_safe(buffer, "hitbox_index_%i", i);
event->SetInt(buffer, indexes[i]);
V_sprintf_safe(buffer, "hitbox_position_x_%i", i);
event->SetFloat(buffer, positions[indexes[i]].x);
V_sprintf_safe(buffer, "hitbox_position_y_%i", i);
event->SetFloat(buffer, positions[indexes[i]].y);
V_sprintf_safe(buffer, "hitbox_position_z_%i", i);
event->SetFloat(buffer, positions[indexes[i]].z);
V_sprintf_safe(buffer, "hitbox_angle_x_%i", i);
event->SetFloat(buffer, angles[indexes[i]].x);
V_sprintf_safe(buffer, "hitbox_angle_y_%i", i);
event->SetFloat(buffer, angles[indexes[i]].y);
V_sprintf_safe(buffer, "hitbox_angle_z_%i", i);
event->SetFloat(buffer, angles[indexes[i]].z);
}
gameeventmanager->FireEvent(event); V_sprintf_safe( buffer, "anim_overlay_sequence_%i", i );
} event->SetInt( buffer, animOverlay->m_nSequence.Get() );
V_sprintf_safe( buffer, "anim_overlay_weight_%i", i );
event->SetFloat( buffer, animOverlay->m_flWeight.Get() );
V_sprintf_safe( buffer, "anim_overlay_order_%i", i );
event->SetInt( buffer, animOverlay->m_nOrder.Get() );
}
gameeventmanager->FireEvent( event );
}
};
#endif #endif
}
} if ( shouldDebugHitboxesOnFire )
} {
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer* lagPlayer = UTIL_PlayerByIndex( i );
if ( lagPlayer && lagPlayer != this )
{
#ifdef CLIENT_DLL
if ( !m_pCurrentCommand->hasbeenpredicted )
{
lagPlayer->DrawClientHitboxes( cl_debug_duration.GetFloat(), true );
}
#else
WritePlayerHitboxEvent( lagPlayer );
#endif
}
}
}
while ( fCurrentDamage > 0 ) while ( fCurrentDamage > 0 )
{ {
@ -640,84 +688,51 @@ void CCSPlayer::FireBullet(
flDamageModifier = 0.99f; flDamageModifier = 0.99f;
} }
if (shouldDebugHitboxesOnHit) if ( shouldDebugHitboxesOnHit )
{ {
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
if (!m_pCurrentCommand->hasbeenpredicted) if ( !m_pCurrentCommand->hasbeenpredicted )
{ {
DrawBullet(vecSrc, DrawBullet( vecSrc,
tr.endpos, tr.endpos,
vecBulletRadiusMins, vecBulletRadiusMins,
vecBulletRadiusMaxs, vecBulletRadiusMaxs,
0, 0,
255, 255,
0, 0,
127, 127,
m_flDebugDuration); cl_debug_duration.GetFloat() );
} }
#else #else
IGameEvent* event = gameeventmanager->CreateEvent("bullet_impact"); IGameEvent* event = gameeventmanager->CreateEvent( "bullet_impact" );
if (event) if ( event )
{ {
event->SetInt("userid", GetUserID()); event->SetInt( "userid", GetUserID() );
event->SetFloat("src_x", vecSrc.x); event->SetFloat( "src_x", vecSrc.x );
event->SetFloat("src_y", vecSrc.y); event->SetFloat( "src_y", vecSrc.y );
event->SetFloat("src_z", vecSrc.z); event->SetFloat( "src_z", vecSrc.z );
event->SetFloat("dst_x", tr.endpos.x); event->SetFloat( "dst_x", tr.endpos.x );
event->SetFloat("dst_y", tr.endpos.y); event->SetFloat( "dst_y", tr.endpos.y );
event->SetFloat("dst_z", tr.endpos.z); event->SetFloat( "dst_z", tr.endpos.z );
event->SetFloat("radius", flBulletRadius); event->SetFloat( "radius", flBulletRadius );
gameeventmanager->FireEvent(event); gameeventmanager->FireEvent( event );
} }
#endif #endif
if (tr.m_pEnt && tr.m_pEnt->IsPlayer() && !shouldDebugHitboxesOnFire) if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() && !shouldDebugHitboxesOnFire )
{ {
const auto lagPlayer = UTIL_PlayerByIndex(tr.m_pEnt->entindex()); const auto lagPlayer = UTIL_PlayerByIndex( tr.m_pEnt->entindex() );
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
if (!m_pCurrentCommand->hasbeenpredicted) if ( !m_pCurrentCommand->hasbeenpredicted )
{ {
lagPlayer->DrawClientHitboxes(m_flDebugDuration, true); lagPlayer->DrawClientHitboxes( cl_debug_duration.GetFloat(), true );
} }
#else #else
IGameEvent* eventHit = gameeventmanager->CreateEvent("bullet_hit_player"); WritePlayerHitboxEvent( lagPlayer );
if (eventHit)
{
eventHit->SetInt("userid", GetUserID());
eventHit->SetInt("player_index", lagPlayer->entindex());
Vector positions[MAXSTUDIOBONES];
QAngle angles[MAXSTUDIOBONES];
int indexes[MAXSTUDIOBONES];
int numhitboxes = lagPlayer->GetServerHitboxes(positions, angles, indexes);
eventHit->SetInt("num_hitboxes", numhitboxes);
for (int i = 0; i < numhitboxes; i++)
{
char buffer[256];
V_sprintf_safe(buffer, "hitbox_index_%i", i);
eventHit->SetInt(buffer, indexes[i]);
V_sprintf_safe(buffer, "hitbox_position_x_%i", i);
eventHit->SetFloat(buffer, positions[indexes[i]].x);
V_sprintf_safe(buffer, "hitbox_position_y_%i", i);
eventHit->SetFloat(buffer, positions[indexes[i]].y);
V_sprintf_safe(buffer, "hitbox_position_z_%i", i);
eventHit->SetFloat(buffer, positions[indexes[i]].z);
V_sprintf_safe(buffer, "hitbox_angle_x_%i", i);
eventHit->SetFloat(buffer, angles[indexes[i]].x);
V_sprintf_safe(buffer, "hitbox_angle_y_%i", i);
eventHit->SetFloat(buffer, angles[indexes[i]].y);
V_sprintf_safe(buffer, "hitbox_angle_z_%i", i);
eventHit->SetFloat(buffer, angles[indexes[i]].z);
}
gameeventmanager->FireEvent(eventHit);
}
#endif #endif
} }
} }
//calculate the damage based on the distance the bullet travelled. //calculate the damage based on the distance the bullet travelled.
flCurrentDistance += tr.fraction * flDistance; flCurrentDistance += tr.fraction * flDistance;
fCurrentDamage *= pow (flRangeModifier, (flCurrentDistance / 500)); fCurrentDamage *= pow (flRangeModifier, (flCurrentDistance / 500));

View file

@ -144,8 +144,8 @@ void FX_FireBullets(
// #endif // #endif
CUserCmd* playerCmd = NULL; CUserCmd* playerCmd = NULL;
if (pPlayer) if ( pPlayer )
{ {
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
playerCmd = pPlayer->m_pCurrentCommand; playerCmd = pPlayer->m_pCurrentCommand;
#else #else
@ -153,9 +153,9 @@ void FX_FireBullets(
#endif #endif
} }
if (playerCmd) if ( playerCmd )
{ {
vHookedOrigin = VectorLerp(pPlayer->m_vecPreviousShootPosition, vOrigin, playerCmd->interpolated_amount); vHookedOrigin = VectorLerp( pPlayer->m_vecPreviousShootPosition, vOrigin, playerCmd->interpolated_amount );
} }
// #ifndef CLIENT_DLL // #ifndef CLIENT_DLL

View file

@ -36,22 +36,6 @@
class bf_read; class bf_read;
class bf_write; class bf_write;
struct LayerRecord
{
int m_sequence;
float m_cycle;
float m_weight;
int m_order;
LayerRecord()
{
m_sequence = 0;
m_cycle = 0;
m_weight = 0;
m_order = 0;
}
};
struct SimulationData struct SimulationData
{ {
// TODO_ENHANCED: // TODO_ENHANCED:

View file

@ -54,10 +54,10 @@ data field should not be broadcasted to clients, use the type "local".
*/ */
#define MAX_EVENT_NAME_LENGTH 32 // max game event name length #define MAX_EVENT_NAME_LENGTH 64 // max game event name length
#define MAX_EVENT_BITS 9 // max bits needed for an event index #define MAX_EVENT_BITS 14 // max bits needed for an event index
#define MAX_EVENT_NUMBER (1<<MAX_EVENT_BITS) // max number of events allowed #define MAX_EVENT_NUMBER (1<<MAX_EVENT_BITS) // max number of events allowed
#define MAX_EVENT_BYTES (1<<12) // max size in bytes for a serialized event #define MAX_EVENT_BYTES (1<<26) // max size in bytes for a serialized event
class KeyValues; class KeyValues;
class CGameEvent; class CGameEvent;