diff --git a/mp/src/game/client/c_baseplayer.h b/mp/src/game/client/c_baseplayer.h index d8f35827f..aa51dacf5 100644 --- a/mp/src/game/client/c_baseplayer.h +++ b/mp/src/game/client/c_baseplayer.h @@ -639,6 +639,8 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener bool ShouldGoSouth( Vector vNPCForward, Vector vNPCRight ); //Such a bad name. void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld; } + + virtual bool ShouldBreakStuffOnCollision() { return false; } }; EXTERN_RECV_TABLE(DT_BasePlayer); diff --git a/mp/src/game/client/c_func_break.cpp b/mp/src/game/client/c_func_break.cpp new file mode 100644 index 000000000..17e6733a4 --- /dev/null +++ b/mp/src/game/client/c_func_break.cpp @@ -0,0 +1,9 @@ +#include "cbase.h" +#include "c_func_break.h" + + +LINK_ENTITY_TO_CLASS(func_breakable, C_Breakable); + +IMPLEMENT_CLIENTCLASS_DT(C_Breakable, DT_Breakable, CBreakable) +RecvPropInt(RECVINFO(m_iHealth)), +END_RECV_TABLE() diff --git a/mp/src/game/client/c_func_break.h b/mp/src/game/client/c_func_break.h new file mode 100644 index 000000000..4122dc9c4 --- /dev/null +++ b/mp/src/game/client/c_func_break.h @@ -0,0 +1,15 @@ +#ifndef C_FUNC_BREAK_H +#define C_FUNC_BREAK_H +#pragma once + +#include "c_baseentity.h" + +class C_Breakable : public C_BaseEntity +{ +public: + DECLARE_CLASS(C_Breakable, C_BaseEntity); + DECLARE_CLIENTCLASS(); + +}; + +#endif diff --git a/mp/src/game/client/sdk/c_sdk_player.h b/mp/src/game/client/sdk/c_sdk_player.h index 3508639ef..9281d762c 100644 --- a/mp/src/game/client/sdk/c_sdk_player.h +++ b/mp/src/game/client/sdk/c_sdk_player.h @@ -296,6 +296,8 @@ class C_SDKPlayer : public C_BasePlayer void UpdateRichPresence(); + virtual bool ShouldBreakStuffOnCollision(); + public: // Public Variables CSDKPlayerAnimState *m_PlayerAnimState; #if defined ( SDK_USE_PRONE ) diff --git a/mp/src/game/server/func_break.cpp b/mp/src/game/server/func_break.cpp index 5fe774052..3febb7e6e 100644 --- a/mp/src/game/server/func_break.cpp +++ b/mp/src/game/server/func_break.cpp @@ -134,6 +134,11 @@ const char *pFGDPropData[] = }; LINK_ENTITY_TO_CLASS( func_breakable, CBreakable ); + +IMPLEMENT_SERVERCLASS_ST(CBreakable, DT_Breakable) + SendPropInt(SENDINFO(m_iHealth), -1, SPROP_VARINT | SPROP_CHANGES_OFTEN), +END_SEND_TABLE() + BEGIN_DATADESC( CBreakable ) DEFINE_FIELD( m_Material, FIELD_INTEGER ), diff --git a/mp/src/game/server/func_break.h b/mp/src/game/server/func_break.h index d423c9533..27b5f66f6 100644 --- a/mp/src/game/server/func_break.h +++ b/mp/src/game/server/func_break.h @@ -38,6 +38,15 @@ class CBreakable : public CBaseEntity, public IBreakableWithPropData, public CDe { public: DECLARE_CLASS( CBreakable, CBaseEntity ); + DECLARE_SERVERCLASS(); + + /* + int UpdateTransmitState() + { + // always send to all clients + return SetTransmitState(FL_EDICT_ALWAYS); + } + */ // basic functions virtual void Spawn( void ); diff --git a/mp/src/game/server/player.h b/mp/src/game/server/player.h index e11070541..3fc65b1de 100644 --- a/mp/src/game/server/player.h +++ b/mp/src/game/server/player.h @@ -1216,6 +1216,8 @@ class CBasePlayer : public CBaseCombatCharacter public: virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const; // returns the solid mask for the given player, so bots can have a more-restrictive set + virtual bool ShouldBreakStuffOnCollision() { return false; } + }; typedef CHandle CBasePlayerHandle; diff --git a/mp/src/game/server/sdk/sdk_player.cpp b/mp/src/game/server/sdk/sdk_player.cpp index 46b63ebff..c6bebb89f 100644 --- a/mp/src/game/server/sdk/sdk_player.cpp +++ b/mp/src/game/server/sdk/sdk_player.cpp @@ -777,7 +777,9 @@ void CSDKPlayer::PreThink(void) m_Shared.StartSuperfallDiving(); } - if (IsAlive() && ( m_Shared.IsDiving() || m_Shared.IsRolling() || m_Shared.IsSliding() || (!GetGroundEntity() && (GetAbsVelocity().z < -220.0f || GetAbsVelocity().Length2D() > 200)) )) + if (ConVarRef("da_test_break").GetFloat()); else + + if (ShouldBreakStuffOnCollision()) { Vector vecNormalizedVelocity = GetAbsVelocity(); vecNormalizedVelocity.NormalizeInPlace(); diff --git a/mp/src/game/server/sdk/sdk_player.h b/mp/src/game/server/sdk/sdk_player.h index ad580a008..f6be6cc6b 100644 --- a/mp/src/game/server/sdk/sdk_player.h +++ b/mp/src/game/server/sdk/sdk_player.h @@ -439,6 +439,8 @@ class CSDKPlayer : public CBaseMultiplayerPlayer virtual void CommitSuicide( bool bExplode = false, bool bForce = false ); virtual bool SuicideAllowed( void ) { return GetCurrentTime() > m_flNextSuicideTime; } + virtual bool ShouldBreakStuffOnCollision(); + private: // Last usercmd we shot a bullet on. int m_iLastWeaponFireUsercmd; diff --git a/mp/src/game/shared/gamemovement.cpp b/mp/src/game/shared/gamemovement.cpp index 8de6fc322..b4bf7a7d0 100644 --- a/mp/src/game/shared/gamemovement.cpp +++ b/mp/src/game/shared/gamemovement.cpp @@ -31,6 +31,7 @@ extern IFileSystem *filesystem; #ifndef CLIENT_DLL + #include "func_break.h" #include "env_player_surface_trigger.h" static ConVar dispcoll_drawplane( "dispcoll_drawplane", "0" ); #endif @@ -1312,7 +1313,9 @@ void CGameMovement::CheckWaterJump( void ) VectorMA( vecStart, 24.0f, flatforward, vecEnd ); trace_t tr; + blah = 101; TracePlayerBBox( vecStart, vecEnd, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr ); + blah = 0; if ( tr.fraction < 1.0 ) // solid at waist { IPhysicsObject *pPhysObj = tr.m_pEnt->VPhysicsGetObject(); @@ -1326,13 +1329,17 @@ void CGameMovement::CheckWaterJump( void ) VectorMA( vecStart, 24.0f, flatforward, vecEnd ); VectorMA( vec3_origin, -50.0f, tr.plane.normal, player->m_vecWaterJumpVel ); + blah = 102; TracePlayerBBox( vecStart, vecEnd, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr ); + blah = 0; if ( tr.fraction == 1.0 ) // open at eye level { // Now trace down to see if we would actually land on a standable surface. VectorCopy( vecEnd, vecStart ); vecEnd.z -= 1024.0f; + blah = 103; TracePlayerBBox( vecStart, vecEnd, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr ); + blah = 0; if ( ( tr.fraction < 1.0f ) && ( tr.plane.normal.z >= 0.7 ) ) { mv->m_vecVelocity[2] = 256.0f; // Push up @@ -1470,7 +1477,9 @@ void CGameMovement::WaterMove( void ) // assume it is a stair or a slope, so press down from stepheight above VectorMA (mv->GetAbsOrigin(), gpGlobals->frametime, mv->m_vecVelocity, dest); + blah = 104; TracePlayerBBox( mv->GetAbsOrigin(), dest, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm ); + blah = 0; if ( pm.fraction == 1.0f ) { VectorCopy( dest, start ); @@ -1479,8 +1488,10 @@ void CGameMovement::WaterMove( void ) start[2] += player->m_Local.m_flStepSize + 1; } + blah = 105; TracePlayerBBox( start, dest, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm ); - + blah = 0; + if (!pm.startsolid && !pm.allsolid) { float stepDist = pm.endpos.z - mv->GetAbsOrigin().z; @@ -1544,7 +1555,9 @@ void CGameMovement::StepMove( Vector &vecDestination, trace_t &trace ) vecEndPos.z += player->m_Local.m_flStepSize + DIST_EPSILON; } + blah = 106; TracePlayerBBox( mv->GetAbsOrigin(), vecEndPos, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; if ( !trace.startsolid && !trace.allsolid ) { mv->SetAbsOrigin( trace.endpos ); @@ -1560,8 +1573,10 @@ void CGameMovement::StepMove( Vector &vecDestination, trace_t &trace ) vecEndPos.z -= player->m_Local.m_flStepSize + DIST_EPSILON; } + blah = 107; TracePlayerBBox( mv->GetAbsOrigin(), vecEndPos, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); - + blah = 0; + // If we are not on the ground any more then use the original movement attempt. if ( trace.plane.normal[2] < 0.7 ) { @@ -1866,14 +1881,18 @@ void CGameMovement::StayOnGround( void ) // See how far up we can go without getting stuck + blah = 108; TracePlayerBBox( mv->GetAbsOrigin(), start, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; start = trace.endpos; // using trace.startsolid is unreliable here, it doesn't get set when // tracing bounding box vs. terrain // Now trace down from a known safe position + blah = 109; TracePlayerBBox( start, end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; if ( trace.fraction > 0.0f && // must go somewhere trace.fraction < 1.0f && // must hit something !trace.startsolid && // can't be embedded in a solid @@ -1980,7 +1999,9 @@ void CGameMovement::WalkMove( void ) dest[2] = mv->GetAbsOrigin()[2]; // first try moving directly to the next spot + blah = 110; TracePlayerBBox( mv->GetAbsOrigin(), dest, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm ); + blah = 0; // If we made it all the way, then copy trace end as new player position. mv->m_outWishVel += wishdir * wishspeed; @@ -2552,6 +2573,8 @@ void CGameMovement::FullLadderMove() TryPlayerMove(); VectorSubtract (mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity); } +int blah = 0; +ConVar da_test_break("da_test_break", "1", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY); //----------------------------------------------------------------------------- // Purpose: @@ -2610,12 +2633,16 @@ int CGameMovement::TryPlayerMove( Vector *pFirstDest, trace_t *pFirstTrace ) Msg( "bah\n" ); } #endif + blah = 111; TracePlayerBBox( mv->GetAbsOrigin(), end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm ); + blah = 0; } } else { + blah = 112; TracePlayerBBox( mv->GetAbsOrigin(), end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm ); + blah = 0; } allFraction += pm.fraction; @@ -2642,7 +2669,9 @@ int CGameMovement::TryPlayerMove( Vector *pFirstDest, trace_t *pFirstTrace ) // case until the bug is fixed. // If we detect getting stuck, don't allow the movement trace_t stuck; + blah = 113; TracePlayerBBox( pm.endpos, pm.endpos, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, stuck ); + blah = 0; if ( stuck.startsolid || stuck.fraction != 1.0f ) { //Msg( "Player will become stuck!!!\n" ); @@ -2672,6 +2701,48 @@ int CGameMovement::TryPlayerMove( Vector *pFirstDest, trace_t *pFirstTrace ) break; // moved the entire distance } + if (da_test_break.GetFloat() && player->ShouldBreakStuffOnCollision()) { + bool bIsBreakable = false; +#ifdef GAME_DLL + bIsBreakable = bIsBreakable || FClassnameIs(pm.m_pEnt, "func_breakable"); + bIsBreakable = bIsBreakable || FClassnameIs(pm.m_pEnt, "func_breakable_surf"); +#else + bIsBreakable = bIsBreakable || !strcmp(pm.m_pEnt->GetClientClass()->GetName(), "CBreakable"); + bIsBreakable = bIsBreakable || !strcmp(pm.m_pEnt->GetClientClass()->GetName(), "CBreakableSurface"); +#endif + /*bIsBreakable = true; + bIsBreakable = bIsBreakable && pm.DidHitNonWorldEntity(); + bIsBreakable = bIsBreakable && pm.m_pEnt->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS; + bIsBreakable = bIsBreakable && pm.m_pEnt->GetHealth() > 0;*/ +#ifdef GAME_DLL + //Msg("server: %s/%s\n", pm.m_pEnt->GetClassname(), pm.m_pEnt->GetServerClass()->GetName()); + if (bIsBreakable && da_test_break.GetFloat() == 1) { + CDisablePredictionFiltering c; + pm.m_pEnt->TakeDamage(CTakeDamageInfo(player, player, 0, DMG_CRUSH)); + static_cast(pm.m_pEnt)->Break(player); + pm.m_pEnt->Remove(); + + continue; + } +#else + //Msg("client: %s/%s\n", pm.m_pEnt->GetClassname(), pm.m_pEnt->GetClientClass()->GetName()); + if (bIsBreakable) { + //pm.m_pEnt->Remove(); + //pm.m_pEnt->TakeDamage(CTakeDamageInfo(player, player, 50, DMG_CRUSH)); + //pm.m_pEnt->SetCollisionGroup(COLLISION_GROUP_NONE); + //pm.m_pEnt->SetCollisionGroup(COLLISION_GROUP_DEBRIS); + //pm.m_pEnt->SetSolid(SOLID_NONE); + //pm.m_pEnt->SetSolidFlags(FSOLID_NOT_SOLID); + //pm.m_pEnt->AddSolidFlags(FSOLID_NOT_SOLID); + + //pm.m_pEnt->SetRenderColor(255, 0, 0); + //pm.m_pEnt->SetRenderMode() + + //continue; + } +#endif + } + // Save entity that blocked us (since fraction was < 1.0) // for contact // Add it if it's not already in the list!!! @@ -2768,6 +2839,9 @@ int CGameMovement::TryPlayerMove( Vector *pFirstDest, trace_t *pFirstTrace ) if (numplanes != 2) { VectorCopy (vec3_origin, mv->m_vecVelocity); + //SetGroundEntity(&pm); + //continue; + break; } CrossProduct (planes[0], planes[1], dir); @@ -2889,7 +2963,9 @@ bool CGameMovement::LadderMove( void ) // wishdir points toward the ladder if any exists VectorMA( mv->GetAbsOrigin(), LadderDistance(), wishdir, end ); + blah = 114; TracePlayerBBox( mv->GetAbsOrigin(), end, LadderMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm ); + blah = 0; // no ladder in that direction, return if ( pm.fraction == 1.0f || !OnLadder( pm ) ) @@ -3122,7 +3198,9 @@ void CGameMovement::PushEntity( Vector& push, trace_t *pTrace ) Vector end; VectorAdd (mv->GetAbsOrigin(), push, end); + blah = 115; TracePlayerBBox( mv->GetAbsOrigin(), end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, *pTrace ); + blah = 0; mv->SetAbsOrigin( pTrace->endpos ); // So we can run impact function afterwards. @@ -4067,7 +4145,9 @@ bool CGameMovement::CanUnduck() bool saveducked = player->m_Local.m_bDucked; player->m_Local.m_bDucked = false; + blah = 116; TracePlayerBBox( mv->GetAbsOrigin(), newOrigin, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; player->m_Local.m_bDucked = saveducked; if ( trace.startsolid || ( trace.fraction != 1.0f ) ) return false; @@ -4309,7 +4389,9 @@ bool CGameMovement::CanUnDuckJump( trace_t &trace ) // Trace down to the stand position and see if we can stand. Vector vecEnd( mv->GetAbsOrigin() ); vecEnd.z -= 36.0f; // This will have to change if bounding hull change! + blah = 117; TracePlayerBBox( mv->GetAbsOrigin(), vecEnd, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; if ( trace.fraction < 1.0f ) { // Find the endpoint. @@ -4319,7 +4401,9 @@ bool CGameMovement::CanUnDuckJump( trace_t &trace ) trace_t traceUp; bool bWasDucked = player->m_Local.m_bDucked; player->m_Local.m_bDucked = false; + blah = 118; TracePlayerBBox( vecEnd, vecEnd, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, traceUp ); + blah = 0; player->m_Local.m_bDucked = bWasDucked; if ( !traceUp.startsolid ) return true; diff --git a/mp/src/game/shared/gamemovement.h b/mp/src/game/shared/gamemovement.h index 02464c859..8b390e0e3 100644 --- a/mp/src/game/shared/gamemovement.h +++ b/mp/src/game/shared/gamemovement.h @@ -286,6 +286,6 @@ class CGameMovement : public IGameMovement #endif }; - +extern int blah; #endif // GAMEMOVEMENT_H diff --git a/mp/src/game/shared/sdk/sdk_gamemovement.cpp b/mp/src/game/shared/sdk/sdk_gamemovement.cpp index 16113278b..09a8d1490 100644 --- a/mp/src/game/shared/sdk/sdk_gamemovement.cpp +++ b/mp/src/game/shared/sdk/sdk_gamemovement.cpp @@ -26,6 +26,13 @@ #include "bots/sdk_bot.h" #endif +#if defined( CLIENT_DLL ) + #define CBreakable C_Breakable + #include "c_func_break.h" +#else + #include "func_break.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -126,6 +133,7 @@ class CSDKGameMovement : public CGameMovement protected: bool ResolveStanding( void ); + void TracePlayerBBox(const Vector& start, const Vector& end, unsigned int fMask, int collisionGroup, trace_t& pm); void TracePlayerBBoxWithStep( const Vector &vStart, const Vector &vEnd, unsigned int fMask, int collisionGroup, trace_t &trace ); public: // A reference to the player whose movement is currently being considered. @@ -571,7 +579,9 @@ void CSDKGameMovement::WalkMove( void ) // Try moving to the destination. trace_t trace; + blah = 201; TracePlayerBBox( mv->GetAbsOrigin(), vecDestination, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = false; if ( trace.fraction == 1.0f ) { // Made it to the destination (remove the base velocity). @@ -869,7 +879,9 @@ void CSDKGameMovement::CategorizePosition( void ) } trace_t trace; + blah = 202; TracePlayerBBox( vecStartPos, vecEndPos, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; // Steep plane, not on ground. if (trace.plane.normal.LengthSqr() > 0 && trace.plane.normal.z < 0.7f) @@ -924,7 +936,89 @@ void CSDKGameMovement::CategorizePosition( void ) player->m_surfaceFriction *= da_acro_roll_friction.GetFloat (); } -inline void CSDKGameMovement::TracePlayerBBoxWithStep( const Vector &vStart, const Vector &vEnd, +//#ifdef CLIENT_DLL +static bool ShouldHitFuncIgnoreFuncBreakables(IHandleEntity *pHandleEntity, int contentsMask) { + CBaseEntity *pEntity = EntityFromEntityHandle(pHandleEntity); + if (!pEntity) + return true; + + bool bIsBreakable = false; +#ifdef GAME_DLL + bIsBreakable = bIsBreakable || FClassnameIs(pEntity, "func_breakable"); + bIsBreakable = bIsBreakable || FClassnameIs(pEntity, "func_breakable_surf"); +#else + bIsBreakable = bIsBreakable || !strcmp(pEntity->GetClientClass()->GetName(), "CBreakable"); + bIsBreakable = bIsBreakable || !strcmp(pEntity->GetClientClass()->GetName(), "CBreakableSurface"); +#endif + if (bIsBreakable) { +#ifdef GAME_DLL + if (ConVarRef("da_test_break").GetFloat() == 2) { + CBasePlayer *player = g_GameMovement.player; + CBreakable * pBreakable = static_cast(pEntity); + CDisablePredictionFiltering c; + if (pBreakable->GetHealth() < 50) + { + pBreakable->TakeDamage(CTakeDamageInfo(player, player, 0, DMG_CRUSH)); + pBreakable->Break(player); + return false; + } + else + { + pBreakable->TakeDamage(CTakeDamageInfo(player, player, 50, DMG_CRUSH)); + //pBreakable->SetHealth(pBreakable->GetHealth() - 50); + } + } +#else + pEntity->SetRenderColor(255, 0, 0); + //trace_t tr; + //UTIL_TraceModel(player->GetAbsOrigin(), player->GetAbsOrigin(), player->GetPlayerMins(), player->GetPlayerMaxs(), pEntity, COLLISION_GROUP_PLAYER_MOVEMENT, &tr); + if (pEntity->GetHealth() < 50) + { + return false; + } + else + { + TODO: Den Fall da_test_break == 1 adden, nicht die neuen dateien vergessen! + I might be able to move that to TracePlayerBBox as well, but the naive approach of damaging it in the ShouldHit function resulted in more stuff breaking than I really touched. + Might work better if I evaluate the trace before returning it and then redo it until I no longer hit a(sufficiently damaged) func_breakable. + //pEntity->SetHealth(pBreakable->GetHealth() - 50); + //return false; + } +#endif + } + + return true; +} +//#endif + +void CSDKGameMovement::TracePlayerBBox(const Vector& start, const Vector& end, unsigned int fMask, int collisionGroup, trace_t& pm) +{ + VPROF("CSDKGameMovement::TracePlayerBBox"); + + Ray_t ray; + ray.Init(start, end, GetPlayerMins(), GetPlayerMaxs()); + if (!blah) { + Msg("not blah!\n"); + } + if (ConVarRef("da_test_break").GetFloat() == 0) { + UTIL_TraceRay(ray, fMask, mv->m_nPlayerHandle.Get(), collisionGroup, &pm); + return; + } + + if (!player->ShouldBreakStuffOnCollision()) { + // Not stunting/jumping => do normal trace + UTIL_TraceRay(ray, fMask, mv->m_nPlayerHandle.Get(), collisionGroup, &pm); + if (!pm.startsolid) { + // We're not stuck => return the normal trace + return; + } + } + + // At this point, we're either stunting/jumping or stuck in something => phase through sufficiently damaged func_breakables + UTIL_TraceRay(ray, fMask, mv->m_nPlayerHandle.Get(), collisionGroup, &pm, &ShouldHitFuncIgnoreFuncBreakables); +} + +inline void CSDKGameMovement::TracePlayerBBoxWithStep( const Vector &vStart, const Vector &vEnd, unsigned int fMask, int collisionGroup, trace_t &trace ) { VPROF( "CSDKGameMovement::TracePlayerBBoxWithStep" ); @@ -935,7 +1029,17 @@ inline void CSDKGameMovement::TracePlayerBBoxWithStep( const Vector &vStart, con Ray_t ray; ray.Init( vStart, vEnd, vHullMin, vHullMax ); - UTIL_TraceRay( ray, fMask, mv->m_nPlayerHandle.Get(), collisionGroup, &trace ); + if (!blah) { + Msg("not blah!\n"); + } + if (ConVarRef("da_test_break").GetFloat() && player->ShouldBreakStuffOnCollision()) { + UTIL_TraceRay(ray, fMask, mv->m_nPlayerHandle.Get(), collisionGroup, &trace, &ShouldHitFuncIgnoreFuncBreakables); + } + else + { + UTIL_TraceRay(ray, fMask, mv->m_nPlayerHandle.Get(), collisionGroup, &trace); + } + blah = 0; } // Taken from TF2 to prevent bouncing down slopes @@ -955,7 +1059,9 @@ bool CSDKGameMovement::ResolveStanding( void ) Vector vecStandPos( mv->GetAbsOrigin().x, mv->GetAbsOrigin().y, mv->GetAbsOrigin().z - ( flMaxStepDrop ) ); trace_t trace; + blah = 203; TracePlayerBBoxWithStep( mv->GetAbsOrigin(), vecStandPos, MASK_PLAYERSOLID, COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; // Anything between 0.5 and 1.0 is a valid stand value if ( fabs( trace.fraction - 0.5 ) < 0.0004f ) @@ -974,8 +1080,10 @@ bool CSDKGameMovement::ResolveStanding( void ) // Less than 0.5 mean we need to attempt to push up the difference. vecStandPos.z = ( mv->GetAbsOrigin().z + ( ( 0.5f - trace.fraction ) * ( player->m_Local.m_flStepSize * 2.0f ) ) ); + blah = 204; TracePlayerBBoxWithStep( mv->GetAbsOrigin(), vecStandPos, MASK_PLAYERSOLID, COLLISION_GROUP_PLAYER_MOVEMENT, trace ); - + blah = 0; + // A fraction of 1.0 means we stood up fine - done. if ( trace.fraction == 1.0f ) { @@ -1233,7 +1341,9 @@ bool CSDKGameMovement::CanUnduck() //temporarily set player bounds to represent a standing position m_pSDKPlayer->m_Shared.m_bIsTryingUnduck = true; + blah = 205; TracePlayerBBox( mv->GetAbsOrigin(), newOrigin, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; m_pSDKPlayer->m_Shared.m_bIsTryingUnduck = false; if ( trace.startsolid || ( trace.fraction != 1.0f ) ) return false; @@ -1292,7 +1402,9 @@ bool CSDKGameMovement::CanUnprone() //temporarily set player bounds to represent a crouching position m_pSDKPlayer->m_Shared.m_bIsTryingUnprone = true; + blah = 206; TracePlayerBBox( mv->GetAbsOrigin(), newOrigin, MASK_PLAYERSOLID, COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; // revert to reality m_pSDKPlayer->m_Shared.m_bIsTryingUnprone = false; @@ -1528,7 +1640,9 @@ bool CSDKGameMovement::LadderMove() // wishdir points toward the ladder if any exists VectorMA( mv->GetAbsOrigin(), LadderDistance(), wishdir, end ); + blah = 207; TracePlayerBBox( mv->GetAbsOrigin(), end, LadderMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm ); + blah = 0; // no ladder in that direction, return if ( pm.fraction == 1.0f || !OnLadder( pm ) ) @@ -2931,7 +3045,9 @@ void CSDKGameMovement::FullWalkMove () float flHeightToMoveUp = flCurrentHeight - flLastTimeHeight; Vector vecNewPosition = mv->GetAbsOrigin() + Vector(0, 0, flHeightToMoveUp); + blah = 208; TracePlayerBBoxWithStep (mv->GetAbsOrigin(), vecNewPosition, MASK_PLAYERSOLID, COLLISION_GROUP_PLAYER_MOVEMENT, trace); + blah = 0; mv->SetAbsOrigin (trace.endpos); m_pSDKPlayer->m_Shared.IncreaseDiveLerped(flCurrentLerp - m_pSDKPlayer->m_Shared.GetDiveLerped()); @@ -3053,7 +3169,9 @@ void CSDKGameMovement::StepMove( Vector &vecDestination, trace_t &trace ) vecEndPos.z += player->m_Local.m_flStepSize + DIST_EPSILON; } + blah = 209; TracePlayerBBox( mv->GetAbsOrigin(), vecEndPos, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace ); + blah = 0; if ( !trace.startsolid && !trace.allsolid ) { mv->SetAbsOrigin( trace.endpos ); @@ -3069,7 +3187,9 @@ void CSDKGameMovement::StepMove( Vector &vecDestination, trace_t &trace ) vecEndPos.z -= player->m_Local.m_flStepSize + DIST_EPSILON; } + blah = 210; TracePlayerBBox (mv->GetAbsOrigin (), vecEndPos, PlayerSolidMask (), COLLISION_GROUP_PLAYER_MOVEMENT, trace); + blah = 0; if (trace.plane.normal[2] < 0.7) { mv->SetAbsOrigin( vecDownPos ); diff --git a/mp/src/game/shared/sdk/sdk_player_shared.cpp b/mp/src/game/shared/sdk/sdk_player_shared.cpp index 070306a9c..8b3a05cea 100644 --- a/mp/src/game/shared/sdk/sdk_player_shared.cpp +++ b/mp/src/game/shared/sdk/sdk_player_shared.cpp @@ -2112,3 +2112,19 @@ bool CSDKPlayer::HasBriefcase() const { return !!m_hBriefcase; } + +bool CSDKPlayer::ShouldBreakStuffOnCollision() { + if (!IsAlive()) return false; + + // stunting + if (m_Shared.IsDiving()) return true; + if (m_Shared.IsRolling()) return true; + if (m_Shared.IsSliding()) return true; + + // jumping + if (GetGroundEntity()) return false; + if (GetAbsVelocity().z < -220.0f) return true; + if (GetAbsVelocity().Length2D() > 200) return true; + + return false; +} diff --git a/mp/src/game/shared/util_shared.h b/mp/src/game/shared/util_shared.h index 18f066c35..a05bf6b91 100644 --- a/mp/src/game/shared/util_shared.h +++ b/mp/src/game/shared/util_shared.h @@ -304,16 +304,27 @@ inline void UTIL_TraceHull( const Vector &vecAbsStart, const Vector &vecAbsEnd, } } -inline void UTIL_TraceRay( const Ray_t &ray, unsigned int mask, - const IHandleEntity *ignore, int collisionGroup, trace_t *ptr, ShouldHitFunc_t pExtraShouldHitCheckFn = NULL ) +inline void UTIL_TraceRay(const Ray_t &ray, unsigned int mask, + const IHandleEntity *ignore, int collisionGroup, trace_t *ptr, ShouldHitFunc_t pExtraShouldHitCheckFn = NULL) { - CTraceFilterSimple traceFilter( ignore, collisionGroup, pExtraShouldHitCheckFn ); + CTraceFilterSimple traceFilter(ignore, collisionGroup, pExtraShouldHitCheckFn); - enginetrace->TraceRay( ray, mask, &traceFilter, ptr ); - - if( r_visualizetraces.GetBool() ) + enginetrace->TraceRay(ray, mask, &traceFilter, ptr); + + if (r_visualizetraces.GetBool()) { - DebugDrawLine( ptr->startpos, ptr->endpos, 255, 0, 0, true, -1.0f ); + DebugDrawLine(ptr->startpos, ptr->endpos, 255, 0, 0, true, -1.0f); + } +} + +inline void UTIL_TraceRay(const Ray_t &ray, unsigned int mask, + ITraceFilter *pTraceFilter, trace_t *ptr) +{ + enginetrace->TraceRay(ray, mask, pTraceFilter, ptr); + + if (r_visualizetraces.GetBool()) + { + DebugDrawLine(ptr->startpos, ptr->endpos, 255, 0, 0, true, -1.0f); } }