diff --git a/game/client/client_portal.vpc b/game/client/client_portal.vpc index 78dc9649..1ca92e1d 100644 --- a/game/client/client_portal.vpc +++ b/game/client/client_portal.vpc @@ -73,6 +73,7 @@ $Project "Client (Portal)" $File "episodic\c_vort_charge_token.cpp" $File "hl2\c_weapon_crossbow.cpp" $File "episodic\c_weapon_hopwire.cpp" + $File "hl2\c_weapon_gravitygun.cpp" $File "episodic\c_vehicle_jeep_episodic.cpp" $File "hl2\hud_radar.cpp" $File "hl2\c_weapon_stunstick.cpp" diff --git a/game/client/hl2/c_weapon_gravitygun.cpp b/game/client/hl2/c_weapon_gravitygun.cpp index a3285842..d59e4bb8 100644 --- a/game/client/hl2/c_weapon_gravitygun.cpp +++ b/game/client/hl2/c_weapon_gravitygun.cpp @@ -6,6 +6,7 @@ //===========================================================================// #include "cbase.h" +#include "client_render_handle.h" #include "hud.h" #include "in_buttons.h" #include "beamdraw.h" @@ -13,7 +14,10 @@ #include "clienteffectprecachesystem.h" // memdbgon must be the last include file in a .cpp file!!! +#include "materialsystem/imaterialsystem.h" +#include "mathlib/mathlib.h" #include "tier0/memdbgon.h" +#include "tier2/tier2.h" CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectGravityGun ) CLIENTEFFECT_MATERIAL( "sprites/physbeam" ) @@ -47,6 +51,9 @@ public: int m_active; int m_glueTouching; int m_viewModelIndex; + + matrix3x4_t z; + const matrix3x4_t& RenderableToWorldTransform() { return z; } }; @@ -105,6 +112,7 @@ END_RECV_TABLE() C_BeamQuadratic::C_BeamQuadratic() { m_pOwner = NULL; + m_hRenderHandle = INVALID_CLIENT_RENDER_HANDLE; } void C_BeamQuadratic::Update( C_BaseEntity *pOwner ) @@ -124,6 +132,7 @@ void C_BeamQuadratic::Update( C_BaseEntity *pOwner ) else if ( !m_active && m_hRenderHandle != INVALID_CLIENT_RENDER_HANDLE ) { ClientLeafSystem()->RemoveRenderable( m_hRenderHandle ); + m_hRenderHandle = INVALID_CLIENT_RENDER_HANDLE; } } @@ -159,7 +168,8 @@ int C_BeamQuadratic::DrawModel( int ) } float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime; - materials->Bind( pMat ); + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->Bind( pMat ); DrawBeamQuadratic( points[0], points[1], points[2], 13, color, scrollOffset ); return 1; } diff --git a/game/client/portal/c_portal_player.cpp b/game/client/portal/c_portal_player.cpp index 59ce85bf..d19c0b0b 100644 --- a/game/client/portal/c_portal_player.cpp +++ b/game/client/portal/c_portal_player.cpp @@ -33,8 +33,8 @@ #endif -#define REORIENTATION_RATE 120.0f -#define REORIENTATION_ACCELERATION_RATE 400.0f +ConVar cl_reorient_rate( "cl_reorient_rate", "1000", FCVAR_ARCHIVE, "Rate at which the player reorients to the camera" ); +ConVar cl_reorient_acceleration_rate( "cl_reorient_acceleration_rate", "5000", FCVAR_ARCHIVE, "Acceleration rate at which the player reorients to the camera" ); #define ENABLE_PORTAL_EYE_INTERPOLATION_CODE @@ -668,7 +668,7 @@ void C_Portal_Player::FixTeleportationRoll( void ) if ( bForcePitchReorient ) { - m_fReorientationRate = REORIENTATION_RATE * ( ( bOnGround ) ? ( 2.0f ) : ( 1.0f ) ); + m_fReorientationRate = cl_reorient_rate.GetFloat() * ( ( bOnGround ) ? ( 2.0f ) : ( 1.0f ) ); } else { @@ -682,26 +682,26 @@ void C_Portal_Player::FixTeleportationRoll( void ) if ( vCurrentUp.z < 0.75f ) { - m_fReorientationRate += gpGlobals->frametime * REORIENTATION_ACCELERATION_RATE; + m_fReorientationRate += gpGlobals->frametime * cl_reorient_acceleration_rate.GetFloat(); // Upright faster if on the ground - float fMaxReorientationRate = REORIENTATION_RATE * ( ( bOnGround ) ? ( 2.0f ) : ( 1.0f ) ); + float fMaxReorientationRate = cl_reorient_rate.GetFloat() * ( ( bOnGround ) ? ( 2.0f ) : ( 1.0f ) ); if ( m_fReorientationRate > fMaxReorientationRate ) m_fReorientationRate = fMaxReorientationRate; } else { - if ( m_fReorientationRate > REORIENTATION_RATE * 0.5f ) + if ( m_fReorientationRate > cl_reorient_rate.GetFloat() * 0.5f ) { - m_fReorientationRate -= gpGlobals->frametime * REORIENTATION_ACCELERATION_RATE; - if ( m_fReorientationRate < REORIENTATION_RATE * 0.5f ) - m_fReorientationRate = REORIENTATION_RATE * 0.5f; + m_fReorientationRate -= gpGlobals->frametime * cl_reorient_acceleration_rate.GetFloat(); + if ( m_fReorientationRate < cl_reorient_rate.GetFloat() * 0.5f ) + m_fReorientationRate = cl_reorient_rate.GetFloat() * 0.5f; } - else if ( m_fReorientationRate < REORIENTATION_RATE * 0.5f ) + else if ( m_fReorientationRate < cl_reorient_rate.GetFloat() * 0.5f ) { - m_fReorientationRate += gpGlobals->frametime * REORIENTATION_ACCELERATION_RATE; - if ( m_fReorientationRate > REORIENTATION_RATE * 0.5f ) - m_fReorientationRate = REORIENTATION_RATE * 0.5f; + m_fReorientationRate += gpGlobals->frametime * cl_reorient_acceleration_rate.GetFloat(); + if ( m_fReorientationRate > cl_reorient_rate.GetFloat() * 0.5f ) + m_fReorientationRate = cl_reorient_rate.GetFloat() * 0.5f; } } diff --git a/game/server/physgun.cpp b/game/server/physgun.cpp index 21324bae..16663766 100644 --- a/game/server/physgun.cpp +++ b/game/server/physgun.cpp @@ -369,7 +369,7 @@ IMotionEvent::simresult_e CGravControllerPoint::Simulate( IPhysicsMotionControll float angleDiff = angleDest - angleSrc; angleDiff = RAD2DEG(angleDiff); axis += m_targetAlignNormal * angleDiff; - //world = m_targetPosition;// + rotDest * (1-ratio); + world = m_targetPosition;// + rotDest * (1-ratio); // NDebugOverlay::Line( worldRotCenter, worldRotCenter-m_targetAlignNormal*50, 255, 0, 0, false, 0.1 ); // NDebugOverlay::Line( worldRotCenter, worldRotCenter+tangent*50, 0, 255, 0, false, 0.1 ); // NDebugOverlay::Line( worldRotCenter, worldRotCenter+binormal*50, 0, 0, 255, false, 0.1 ); @@ -841,6 +841,8 @@ void CWeaponGravityGun::EffectUpdate( void ) { m_gravCallback.ClearAutoAlign(); } + + NetworkStateChanged(); } void CWeaponGravityGun::SoundCreate( void ) @@ -1213,7 +1215,6 @@ void CWeaponGravityGun::DetachObject( void ) void CWeaponGravityGun::AttachObject( CBaseEntity *pObject, const Vector& start, const Vector &end, float distance ) { m_hObject = pObject; - m_useDown = false; IPhysicsObject *pPhysics = pObject ? (pObject->VPhysicsGetObject()) : NULL; if ( pPhysics && pObject->GetMoveType() == MOVETYPE_VPHYSICS ) { @@ -1421,103 +1422,3 @@ bool CWeaponGravityGun::Reload( void ) return false; } - -#define NUM_COLLISION_TESTS 2500 -void CC_CollisionTest( const CCommand &args ) -{ - if ( !physenv ) - return; - - Msg( "Testing collision system\n" ); - int i; - CBaseEntity *pSpot = gEntList.FindEntityByClassname( NULL, "info_player_start"); - Vector start = pSpot->GetAbsOrigin(); - static Vector *targets = NULL; - static bool first = true; - static float test[2] = {1,1}; - if ( first ) - { - targets = new Vector[NUM_COLLISION_TESTS]; - float radius = 0; - float theta = 0; - float phi = 0; - for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) - { - radius += NUM_COLLISION_TESTS * 123.123; - radius = fabs(fmod(radius, 128)); - theta += NUM_COLLISION_TESTS * 76.76; - theta = fabs(fmod(theta, DEG2RAD(360))); - phi += NUM_COLLISION_TESTS * 1997.99; - phi = fabs(fmod(phi, DEG2RAD(180))); - - float st, ct, sp, cp; - SinCos( theta, &st, &ct ); - SinCos( phi, &sp, &cp ); - - targets[i].x = radius * ct * sp; - targets[i].y = radius * st * sp; - targets[i].z = radius * cp; - - // make the trace 1024 units long - Vector dir = targets[i] - start; - VectorNormalize(dir); - targets[i] = start + dir * 1024; - } - first = false; - } - - //Vector results[NUM_COLLISION_TESTS]; - - int testType = 0; - if ( args.ArgC() >= 2 ) - { - testType = atoi( args[1] ); - } - float duration = 0; - Vector size[2]; - size[0].Init(0,0,0); - size[1].Init(16,16,16); - unsigned int dots = 0; - - for ( int j = 0; j < 2; j++ ) - { - float startTime = engine->Time(); - if ( testType == 1 ) - { - const CPhysCollide *pCollide = g_PhysWorldObject->GetCollide(); - trace_t tr; - - for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) - { - physcollision->TraceBox( start, targets[i], -size[j], size[j], pCollide, vec3_origin, vec3_angle, &tr ); - dots += physcollision->ReadStat(0); - //results[i] = tr.endpos; - } - } - else - { - testType = 0; - CBaseEntity *pWorld = GetContainingEntity( INDEXENT(0) ); - trace_t tr; - - for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) - { - UTIL_TraceModel( start, targets[i], -size[j], size[j], pWorld, COLLISION_GROUP_NONE, &tr ); - //results[i] = tr.endpos; - } - } - - duration += engine->Time() - startTime; - } - test[testType] = duration; - Msg("%d collisions in %.2f ms (%u dots)\n", NUM_COLLISION_TESTS, duration*1000, dots ); - Msg("Current speed ratio: %.2fX BSP:JGJK\n", test[1] / test[0] ); -#if 0 - int red = 255, green = 0, blue = 0; - for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) - { - NDebugOverlay::Line( start, results[i], red, green, blue, false, 2 ); - } -#endif -} -static ConCommand collision_test("collision_test", CC_CollisionTest, "Tests collision system", FCVAR_CHEAT ); diff --git a/game/server/portal/portal_client.cpp b/game/server/portal/portal_client.cpp index e7ebaef2..03a2ed82 100644 --- a/game/server/portal/portal_client.cpp +++ b/game/server/portal/portal_client.cpp @@ -31,6 +31,8 @@ void Host_Say( edict_t *pEdict, bool teamonly ); +ConVar sv_use_portal_gamerules("sv_use_portal_gamerules", "0", FCVAR_REPLICATED | FCVAR_ARCHIVE | FCVAR_NOT_CONNECTED); + extern CBaseEntity* FindPickerEntityClass( CBasePlayer *pPlayer, char *classname ); extern bool g_fGameOver; @@ -154,23 +156,12 @@ void GameStartFrame( void ) //========================================================= void InstallGameRules() { - if ( !gpGlobals->deathmatch ) + if (sv_use_portal_gamerules.GetBool()) { - CreateGameRulesObject( "CPortalGameRules" ); - return; + CreateGameRulesObject("CPortalGameRules"); } else { - if ( teamplay.GetInt() > 0 ) - { - // teamplay - CreateGameRulesObject( "CTeamplayRules" ); - } - else - { - // vanilla deathmatch - CreateGameRulesObject( "CMultiplayRules" ); - } + CreateGameRulesObject("CHalfLife2"); } } - diff --git a/game/server/portal/portal_player.cpp b/game/server/portal/portal_player.cpp index 15dd2504..af0304d1 100644 --- a/game/server/portal/portal_player.cpp +++ b/game/server/portal/portal_player.cpp @@ -212,6 +212,7 @@ BEGIN_DATADESC( CPortal_Player ) END_DATADESC() ConVar sv_regeneration_wait_time ("sv_regeneration_wait_time", "1.0", FCVAR_REPLICATED ); +ConVar sv_regeneration_enable("sv_regeneration_enable", "0", FCVAR_REPLICATED | FCVAR_ARCHIVE); const char *g_pszChellModel = "models/player/chell.mdl"; const char *g_pszPlayerModel = g_pszChellModel; @@ -625,7 +626,7 @@ void CPortal_Player::PostThink( void ) SetLocalAngles( angles ); // Regenerate heath after 3 seconds - if ( IsAlive() && GetHealth() < GetMaxHealth() ) + if ( IsAlive() && GetHealth() < GetMaxHealth() && sv_regeneration_enable.GetBool() ) { // Color to overlay on the screen while the player is taking damage color32 hurtScreenOverlay = {64,0,0,64}; diff --git a/game/server/portal/prop_portal.cpp b/game/server/portal/prop_portal.cpp index aaa57809..ffa196d8 100644 --- a/game/server/portal/prop_portal.cpp +++ b/game/server/portal/prop_portal.cpp @@ -1827,7 +1827,7 @@ void CProp_Portal::UpdatePortalTeleportMatrix( void ) } } -void CProp_Portal::UpdatePortalLinkage( void ) +bool CProp_Portal::UpdatePortalLinkage( void ) { if( m_bActivated ) { @@ -1965,7 +1965,10 @@ void CProp_Portal::UpdatePortalLinkage( void ) Vector ptCenter = GetAbsOrigin(); QAngle qAngles = GetAbsAngles(); - m_PortalSimulator.MoveTo( ptCenter, qAngles ); + if (!m_PortalSimulator.MoveTo(ptCenter, qAngles)) + { + return false; + } if( pLink ) m_PortalSimulator.AttachTo( &pLink->m_PortalSimulator ); @@ -1984,6 +1987,8 @@ void CProp_Portal::UpdatePortalLinkage( void ) if( pRemote ) pRemote->UpdatePortalLinkage(); } + + return true; } void CProp_Portal::PlacePortal( const Vector &vOrigin, const QAngle &qAngles, float fPlacementSuccess, bool bDelay /*= false*/ ) @@ -2059,7 +2064,7 @@ void CProp_Portal::PlacePortal( const Vector &vOrigin, const QAngle &qAngles, fl } } -void CProp_Portal::NewLocation( const Vector &vOrigin, const QAngle &qAngles ) +void CProp_Portal::NewLocation( const Vector &vOrigin, const QAngle &qAngles, const bool isFailReplace ) { // Tell our physics environment to stop simulating it's entities. // Fast moving objects can pass through the hole this frame while it's in the old location. @@ -2071,6 +2076,9 @@ void CProp_Portal::NewLocation( const Vector &vOrigin, const QAngle &qAngles ) WakeNearbyEntities(); + Vector prevPos = GetAbsOrigin(); + QAngle prevRot = GetAbsAngles(); + Teleport( &vOrigin, &qAngles, 0 ); if ( m_hMicrophone ) @@ -2097,17 +2105,42 @@ void CProp_Portal::NewLocation( const Vector &vOrigin, const QAngle &qAngles ) controller.SoundChangeVolume( m_pAmbientSound, 0.4, 0.1 ); } - DispatchParticleEffect( ( ( m_bIsPortal2 ) ? ( "portal_2_particles" ) : ( "portal_1_particles" ) ), PATTACH_POINT_FOLLOW, this, "particles_2", true ); - DispatchParticleEffect( ( ( m_bIsPortal2 ) ? ( "portal_2_edge" ) : ( "portal_1_edge" ) ), PATTACH_POINT_FOLLOW, this, "particlespin" ); + if (!isFailReplace) + { + DispatchParticleEffect(((m_bIsPortal2) ? ("portal_2_particles") : ("portal_1_particles")), PATTACH_POINT_FOLLOW, this, "particles_2", true); + DispatchParticleEffect(((m_bIsPortal2) ? ("portal_2_edge") : ("portal_1_edge")), PATTACH_POINT_FOLLOW, this, "particlespin"); + } //if the other portal should be static, let's not punch stuff resting on it bool bOtherShouldBeStatic = false; if( !m_hLinkedPortal ) bOtherShouldBeStatic = true; + bool prevActivated = m_bActivated; + m_bActivated = true; - UpdatePortalLinkage(); + if (!UpdatePortalLinkage()) + { + Assert(!isFailReplace); + DoFizzleEffect(PORTAL_FIZZLE_CANT_FIT, false); + if (isFailReplace) // is is already failed, it should be ok to place on the prev position. But failed again, so only can Fizzle it. + { + Fizzle(); + } + else + { + if (prevActivated) + { + NewLocation(prevPos, prevRot, true); + } + else + { + Fizzle(); + } + } + return; + } UpdatePortalTeleportMatrix(); // Update the four corners of this portal for faster reference @@ -2124,13 +2157,16 @@ void CProp_Portal::NewLocation( const Vector &vOrigin, const QAngle &qAngles ) } } - if ( m_bIsPortal2 ) + if (!isFailReplace) { - EmitSound( "Portal.open_red" ); - } - else - { - EmitSound( "Portal.open_blue" ); + if (m_bIsPortal2) + { + EmitSound("Portal.open_red"); + } + else + { + EmitSound("Portal.open_blue"); + } } } diff --git a/game/server/portal/prop_portal.h b/game/server/portal/prop_portal.h index a866e9b2..ce181193 100644 --- a/game/server/portal/prop_portal.h +++ b/game/server/portal/prop_portal.h @@ -90,7 +90,7 @@ public: void ForceEntityToFitInPortalWall( CBaseEntity *pEntity ); //projects an object's center into the middle of the portal wall hall, and traces back to where it wants to be void PlacePortal( const Vector &vOrigin, const QAngle &qAngles, float fPlacementSuccess, bool bDelay = false ); - void NewLocation( const Vector &vOrigin, const QAngle &qAngles ); + void NewLocation( const Vector &vOrigin, const QAngle &qAngles, const bool isFailReplace = false ); void ResetModel( void ); //sets the model and bounding box void DoFizzleEffect( int iEffect, bool bDelayedPos = true ); //display cool visual effect @@ -107,7 +107,7 @@ public: void InputFizzle( inputdata_t &inputdata ); void InputNewLocation( inputdata_t &inputdata ); - void UpdatePortalLinkage( void ); + bool UpdatePortalLinkage( void ); void UpdatePortalTeleportMatrix( void ); //computes the transformation from this portal to the linked portal, and will update the remote matrix as well //void SendInteractionMessage( CBaseEntity *pEntity, bool bEntering ); //informs clients that the entity is interacting with a portal (mostly used for clip planes) diff --git a/game/server/portal/weapon_portalgun.cpp b/game/server/portal/weapon_portalgun.cpp index 1fe9e82a..2293b17f 100644 --- a/game/server/portal/weapon_portalgun.cpp +++ b/game/server/portal/weapon_portalgun.cpp @@ -734,3 +734,30 @@ static void change_portalgun_linkage_id_f( const CCommand &args ) } ConCommand change_portalgun_linkage_id( "change_portalgun_linkage_id", change_portalgun_linkage_id_f, "Changes the portal linkage ID for the portal gun held by the commanding player.", FCVAR_CHEAT ); + +//==================================================================================== +// WEAPON BEHAVIOUR +//==================================================================================== +void CWeaponPortalgun::ItemPostFrame(void) +{ + BaseClass::ItemPostFrame(); + + if (m_bInReload) + return; + + CBasePlayer *pOwner = ToBasePlayer(GetOwner()); + + if (pOwner == NULL) + return; + + //Allow a refire as fast as the player can click + if (((pOwner->m_nButtons & IN_ATTACK) == false) && (m_flSoonestPrimaryAttack < gpGlobals->curtime)) + { + m_flNextPrimaryAttack = gpGlobals->curtime - 0.1f; + } + + if (((pOwner->m_nButtons & IN_ATTACK2) == false) && (m_flSoonestPrimaryAttack < gpGlobals->curtime)) // we use the same delay as primary attack that's why m_flSoonestPrimaryAttack is used + { + m_flNextSecondaryAttack = gpGlobals->curtime - 0.1f; + } +} diff --git a/game/server/portal/weapon_portalgun.h b/game/server/portal/weapon_portalgun.h index b887e922..7f0fa458 100644 --- a/game/server/portal/weapon_portalgun.h +++ b/game/server/portal/weapon_portalgun.h @@ -110,6 +110,8 @@ public: PortalWeaponID GetWeaponID( void ) const { return WEAPON_PORTALGUN; } + void ItemPostFrame(void); + protected: void StartEffects( void ); // Initialize all sprites and beams @@ -135,6 +137,7 @@ public: private: CWeaponPortalgun( const CWeaponPortalgun & ); + float m_flSoonestPrimaryAttack; }; diff --git a/game/server/server_portal.vpc b/game/server/server_portal.vpc index 9d0edf9b..2ce08ef2 100644 --- a/game/server/server_portal.vpc +++ b/game/server/server_portal.vpc @@ -227,6 +227,7 @@ $Project "Server (Portal)" $File "hl2\vehicle_jeep.cpp" $File "hl2\vehicle_prisoner_pod.cpp" $File "hl2\vehicle_viewcontroller.cpp" + $File "physgun.cpp" $File "hl2\weapon_357.cpp" $File "hl2\weapon_alyxgun.cpp" $File "hl2\weapon_alyxgun.h" diff --git a/game/shared/basecombatweapon_shared.cpp b/game/shared/basecombatweapon_shared.cpp index 0b35d147..1d7b3594 100644 --- a/game/shared/basecombatweapon_shared.cpp +++ b/game/shared/basecombatweapon_shared.cpp @@ -1010,7 +1010,8 @@ void CBaseCombatWeapon::SetActivity( Activity act, float duration ) { //Adrian: Oh man... #if !defined( CLIENT_DLL ) && (defined( HL2MP ) || defined( PORTAL )) - SetModel( GetWorldModel() ); + if (GetOwner()->IsPlayer()) + SetModel(GetWorldModel()); #endif int sequence = SelectWeightedSequence( act ); @@ -1021,7 +1022,8 @@ void CBaseCombatWeapon::SetActivity( Activity act, float duration ) //Adrian: Oh man again... #if !defined( CLIENT_DLL ) && (defined( HL2MP ) || defined( PORTAL )) - SetModel( GetViewModel() ); + if (GetOwner()->IsPlayer()) + SetModel(GetViewModel()); #endif if ( sequence != ACTIVITY_NOT_AVAILABLE ) diff --git a/game/shared/portal/PortalSimulation.cpp b/game/shared/portal/PortalSimulation.cpp index 233c98f9..346591ac 100644 --- a/game/shared/portal/PortalSimulation.cpp +++ b/game/shared/portal/PortalSimulation.cpp @@ -197,10 +197,10 @@ CPortalSimulator::~CPortalSimulator( void ) -void CPortalSimulator::MoveTo( const Vector &ptCenter, const QAngle &angles ) +bool CPortalSimulator::MoveTo( const Vector &ptCenter, const QAngle &angles ) { if( (m_InternalData.Placement.ptCenter == ptCenter) && (m_InternalData.Placement.qAngles == angles) ) //not actually moving at all - return; + return true; CREATEDEBUGTIMER( functionTimer ); @@ -318,7 +318,11 @@ void CPortalSimulator::MoveTo( const Vector &ptCenter, const QAngle &angles ) #endif CreatePolyhedrons(); - CreateAllCollision(); + if (!CreateAllCollision()) + { + ClearLocalCollision(); + return false; + } #ifndef CLIENT_DLL CreateAllPhysics(); #endif @@ -345,6 +349,8 @@ void CPortalSimulator::MoveTo( const Vector &ptCenter, const QAngle &angles ) STOPDEBUGTIMER( functionTimer ); DECREMENTTABSPACING(); DEBUGTIMERONLY( DevMsg( 2, "[PSDT:%d] %sCPortalSimulator::MoveTo() FINISH: %fms\n", GetPortalSimulatorGUID(), TABSPACING, functionTimer.GetDuration().GetMillisecondsF() ); ); + + return true; } @@ -1603,7 +1609,7 @@ void CPortalSimulator::ClearLinkedEntities( void ) #endif //#ifndef CLIENT_DLL -void CPortalSimulator::CreateAllCollision( void ) +bool CPortalSimulator::CreateAllCollision( void ) { CREATEDEBUGTIMER( functionTimer ); @@ -1611,25 +1617,30 @@ void CPortalSimulator::CreateAllCollision( void ) DEBUGTIMERONLY( DevMsg( 2, "[PSDT:%d] %sCPortalSimulator::CreateAllCollision() START\n", GetPortalSimulatorGUID(), TABSPACING ); ); INCREMENTTABSPACING(); - CreateLocalCollision(); + if (!CreateLocalCollision()) + { + return false; + } CreateLinkedCollision(); STOPDEBUGTIMER( functionTimer ); DECREMENTTABSPACING(); DEBUGTIMERONLY( DevMsg( 2, "[PSDT:%d] %sCPortalSimulator::CreateAllCollision() FINISH: %fms\n", GetPortalSimulatorGUID(), TABSPACING, functionTimer.GetDuration().GetMillisecondsF() ); ); + + return true; } -void CPortalSimulator::CreateLocalCollision( void ) +bool CPortalSimulator::CreateLocalCollision( void ) { AssertMsg( m_bLocalDataIsReady, "Portal simulator attempting to create local collision before being placed." ); if( m_CreationChecklist.bLocalCollisionGenerated ) - return; + return true; if( IsCollisionGenerationEnabled() == false ) - return; + return true; DEBUGTIMERONLY( s_iPortalSimulatorGUID = GetPortalSimulatorGUID() ); @@ -1666,7 +1677,10 @@ void CPortalSimulator::CreateLocalCollision( void ) Assert( Representation.pCollide == NULL ); Representation.pCollide = ConvertPolyhedronsToCollideable( &pPolyhedronsBase[Representation.PolyhedronGroup.iStartIndex], Representation.PolyhedronGroup.iNumPolyhedrons ); - Assert( Representation.pCollide != NULL ); + if (Representation.pCollide == NULL) { + m_InternalData.Simulation.Static.World.Brushes.pCollideable = NULL; + return false; + } } } m_InternalData.Simulation.Static.World.StaticProps.bCollisionExists = true; @@ -1731,6 +1745,7 @@ void CPortalSimulator::CreateLocalCollision( void ) DEBUGTIMERONLY( DevMsg( 2, "[PSDT:%d] %sCPortalSimulator::CreateLocalCollision() FINISH: %fms\n", GetPortalSimulatorGUID(), TABSPACING, functionTimer.GetDuration().GetMillisecondsF() ); ); m_CreationChecklist.bLocalCollisionGenerated = true; + return true; } @@ -1943,7 +1958,11 @@ void CPortalSimulator::CreatePolyhedrons( void ) ICollideable *pProp = StaticProps[i]; CPolyhedron *PolyhedronArray[1024]; - int iPolyhedronCount = g_StaticCollisionPolyhedronCache.GetStaticPropPolyhedrons( pProp, PolyhedronArray, 1024 ); + int iPolyhedronCount = 0; + if (pProp->GetSolid() != SOLID_NONE) + { + iPolyhedronCount = g_StaticCollisionPolyhedronCache.GetStaticPropPolyhedrons(pProp, PolyhedronArray, 1024); + } StaticPropPolyhedronGroups_t indices; indices.iStartIndex = m_InternalData.Simulation.Static.World.StaticProps.Polyhedrons.Count(); @@ -2629,7 +2648,7 @@ static CPhysCollide *ConvertPolyhedronsToCollideable( CPolyhedron **pPolyhedrons { pConvexes[iConvexCount] = physcollision->ConvexFromConvexPolyhedron( *pPolyhedrons[i] ); - Assert( pConvexes[iConvexCount] != NULL ); + // Assert( pConvexes[iConvexCount] != NULL ); if( pConvexes[iConvexCount] ) ++iConvexCount; diff --git a/game/shared/portal/PortalSimulation.h b/game/shared/portal/PortalSimulation.h index 91c66511..9af361e6 100644 --- a/game/shared/portal/PortalSimulation.h +++ b/game/shared/portal/PortalSimulation.h @@ -280,7 +280,7 @@ public: CPortalSimulator( void ); ~CPortalSimulator( void ); - void MoveTo( const Vector &ptCenter, const QAngle &angles ); + bool MoveTo( const Vector &ptCenter, const QAngle &angles ); void ClearEverything( void ); void AttachTo( CPortalSimulator *pLinkedPortalSimulator ); @@ -374,8 +374,8 @@ protected: void ClearLinkedEntities( void ); //gets rid of transformed shadow clones #endif - void CreateAllCollision( void ); - void CreateLocalCollision( void ); + bool CreateAllCollision( void ); + bool CreateLocalCollision( void ); void CreateLinkedCollision( void ); void ClearAllCollision( void ); diff --git a/game/shared/portal/weapon_portalgun_shared.cpp b/game/shared/portal/weapon_portalgun_shared.cpp index 9cbb4f41..fcbbfb0c 100644 --- a/game/shared/portal/weapon_portalgun_shared.cpp +++ b/game/shared/portal/weapon_portalgun_shared.cpp @@ -53,6 +53,11 @@ CWeaponPortalgun::CWeaponPortalgun( void ) m_fMaxRange2 = MAX_TRACE_LENGTH; m_EffectState = (int)EFFECT_NONE; + +#ifdef GAME_DLL + m_flSoonestPrimaryAttack = gpGlobals->curtime; +#endif // GAME_DLL + } void CWeaponPortalgun::Precache() @@ -135,6 +140,10 @@ void CWeaponPortalgun::DryFire( void ) { WeaponSound(EMPTY); SendWeaponAnim( ACT_VM_DRYFIRE ); + +#ifdef GAME_DLL + m_flSoonestPrimaryAttack = gpGlobals->curtime + PORTALGUN_FASTEST_DRY_REFIRE_TIME; +#endif m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); } @@ -218,6 +227,7 @@ void CWeaponPortalgun::PrimaryAttack( void ) } #ifndef CLIENT_DLL + m_flSoonestPrimaryAttack = gpGlobals->curtime + PORTALGUN_FASTEST_REFIRE_TIME; inputdata_t inputdata; inputdata.pActivator = this; inputdata.pCaller = this; diff --git a/game/shared/portal/weapon_portalgun_shared.h b/game/shared/portal/weapon_portalgun_shared.h index 88ee0af0..6341474e 100644 --- a/game/shared/portal/weapon_portalgun_shared.h +++ b/game/shared/portal/weapon_portalgun_shared.h @@ -30,6 +30,9 @@ #define PORTALGUN_PORTAL_MUZZLE_GLOW_SPRITE "sprites/portalgun_effects" #define PORTALGUN_PORTAL_TUBE_BEAM_SPRITE "sprites/portalgun_effects" +#define PORTALGUN_FASTEST_REFIRE_TIME 0.1f +#define PORTALGUN_FASTEST_DRY_REFIRE_TIME 0.2f + enum { EFFECT_NONE,