diff --git a/sp/src/game/client/hl2/c_script_intro.cpp b/sp/src/game/client/hl2/c_script_intro.cpp index 66c59aa8..0101336f 100644 --- a/sp/src/game/client/hl2/c_script_intro.cpp +++ b/sp/src/game/client/hl2/c_script_intro.cpp @@ -183,7 +183,7 @@ void C_ScriptIntro::PostDataUpdate( DataUpdateType_t updateType ) // If it's a point_camera and it's ortho, send it to the intro data // Change this code if the purpose of m_hCameraEntity in intro data ever goes beyond ortho - if ( Q_strncmp(m_hCameraEntity->GetClassname(), "point_camera", 12) == 0 ) + if ( m_hCameraEntity && Q_strncmp(m_hCameraEntity->GetClassname(), "point_camera", 12) == 0 ) { C_PointCamera *pCamera = dynamic_cast(m_hCameraEntity.Get()); if (pCamera && pCamera->IsOrtho()) diff --git a/sp/src/game/server/ai_concommands.cpp b/sp/src/game/server/ai_concommands.cpp index ac4e65d7..e004dca1 100644 --- a/sp/src/game/server/ai_concommands.cpp +++ b/sp/src/game/server/ai_concommands.cpp @@ -450,9 +450,12 @@ public: angles.z = 0; } + // Pass through the player's vehicle + CTraceFilterSkipTwoEntities filter( pPlayer, pPlayer->GetVehicleEntity(), COLLISION_GROUP_NONE ); AI_TraceLine(pPlayer->EyePosition(), pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_NPCSOLID, - pPlayer, COLLISION_GROUP_NONE, &tr ); + &filter, &tr ); + if ( tr.fraction != 1.0) { if (baseNPC->CapabilitiesGet() & bits_CAP_MOVE_FLY) diff --git a/sp/src/game/server/ai_networkmanager.cpp b/sp/src/game/server/ai_networkmanager.cpp index 6ce635a5..d5bc187c 100644 --- a/sp/src/game/server/ai_networkmanager.cpp +++ b/sp/src/game/server/ai_networkmanager.cpp @@ -70,7 +70,7 @@ CON_COMMAND( ai_debug_node_connect, "Debug the attempted connection between two ConVar g_ai_norebuildgraph( "ai_norebuildgraph", "0" ); #ifdef MAPBASE -ConVar g_ai_nographrebuildmessage( "ai_nographrebuildmessage", "0", FCVAR_ARCHIVE, "Stops the \"Node graph out of date\" message from appearing when rebuilding node graph" ); +ConVar g_ai_norebuildgraphmessage( "ai_norebuildgraphmessage", "0", FCVAR_ARCHIVE, "Stops the \"Node graph out of date\" message from appearing when rebuilding node graph" ); #endif @@ -1114,7 +1114,7 @@ void CAI_NetworkManager::DelayedInit( void ) DevMsg( "Node Graph out of Date. Rebuilding... (%d, %d, %d)\n", (int)m_bDontSaveGraph, (int)!CAI_NetworkManager::NetworksLoaded(), (int) engine->IsInEditMode() ); #ifdef MAPBASE - if (!g_ai_nographrebuildmessage.GetBool()) + if (!g_ai_norebuildgraphmessage.GetBool()) UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding...\n" ); // Do it much sooner after map load diff --git a/sp/src/game/server/baseentity.cpp b/sp/src/game/server/baseentity.cpp index 1e5dc43e..2091fa7e 100644 --- a/sp/src/game/server/baseentity.cpp +++ b/sp/src/game/server/baseentity.cpp @@ -2053,6 +2053,8 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_INPUTFUNC( FIELD_VOID, "DisableDraw", InputUndrawEntity ), DEFINE_INPUTFUNC( FIELD_INTEGER, "AddEFlags", InputAddEFlags ), DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveEFlags", InputRemoveEFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "AddSolidFlags", InputAddSolidFlags ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveSolidFlags", InputRemoveSolidFlags ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMoveType", InputSetMoveType ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCollisionGroup", InputSetCollisionGroup ), @@ -7690,6 +7692,22 @@ void CBaseEntity::InputRemoveEFlags( inputdata_t& inputdata ) RemoveEFlags(inputdata.value.Int()); } +//----------------------------------------------------------------------------- +// Purpose: Adds solid flags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputAddSolidFlags( inputdata_t& inputdata ) +{ + AddSolidFlags(inputdata.value.Int()); +} + +//----------------------------------------------------------------------------- +// Purpose: Removes solid flags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputRemoveSolidFlags( inputdata_t& inputdata ) +{ + RemoveSolidFlags(inputdata.value.Int()); +} + //----------------------------------------------------------------------------- // Purpose: Sets the movetype. //----------------------------------------------------------------------------- @@ -8828,9 +8846,13 @@ public: trace_t tr; Vector forward; pPlayer->EyeVectors( &forward ); + + // Pass through the player's vehicle + CTraceFilterSkipTwoEntities filter( pPlayer, pPlayer->GetVehicleEntity(), COLLISION_GROUP_NONE ); UTIL_TraceLine(pPlayer->EyePosition(), pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_SOLID, - pPlayer, COLLISION_GROUP_NONE, &tr ); + &filter, &tr ); + if ( tr.fraction != 1.0 ) { // Raise the end position a little up off the floor, place the npc and drop him down diff --git a/sp/src/game/server/baseentity.h b/sp/src/game/server/baseentity.h index e609b079..da619c55 100644 --- a/sp/src/game/server/baseentity.h +++ b/sp/src/game/server/baseentity.h @@ -716,6 +716,8 @@ public: void InputUndrawEntity( inputdata_t &inputdata ); void InputAddEFlags( inputdata_t &inputdata ); void InputRemoveEFlags( inputdata_t &inputdata ); + void InputAddSolidFlags( inputdata_t &inputdata ); + void InputRemoveSolidFlags( inputdata_t &inputdata ); void InputSetMoveType( inputdata_t &inputdata ); void InputSetCollisionGroup( inputdata_t &inputdata ); diff --git a/sp/src/game/server/filters.cpp b/sp/src/game/server/filters.cpp index c4e8efeb..c8d0fd06 100644 --- a/sp/src/game/server/filters.cpp +++ b/sp/src/game/server/filters.cpp @@ -1917,8 +1917,15 @@ public: return false; } - info.ScaleDamage(m_flDamageMultiplier); - info.AddDamage(m_flDamageAddend); + if (m_flDamageMultiplier != 1.0f) + info.ScaleDamage(m_flDamageMultiplier); + if (m_flDamageAddend != 0.0f) + info.AddDamage(m_flDamageAddend); + + if (m_iDamageBitsAdded != 0) + info.AddDamageType(m_iDamageBitsAdded); + if (m_iDamageBitsRemoved != 0) + info.AddDamageType(~m_iDamageBitsRemoved); if (m_iszNewAttacker != NULL_STRING) { @@ -1948,6 +1955,8 @@ public: float m_flDamageMultiplier = 1.0f; float m_flDamageAddend; + int m_iDamageBitsAdded; + int m_iDamageBitsRemoved; string_t m_iszNewAttacker; EHANDLE m_hNewAttacker; string_t m_iszNewInflictor; EHANDLE m_hNewInflictor; @@ -1970,6 +1979,8 @@ BEGIN_DATADESC( CFilterDamageMod ) DEFINE_INPUT( m_flDamageMultiplier, FIELD_FLOAT, "SetDamageMultiplier" ), DEFINE_INPUT( m_flDamageAddend, FIELD_FLOAT, "SetDamageAddend" ), + DEFINE_INPUT( m_iDamageBitsAdded, FIELD_INTEGER, "SetDamageBitsAdded" ), + DEFINE_INPUT( m_iDamageBitsRemoved, FIELD_INTEGER, "SetDamageBitsRemoved" ), DEFINE_KEYFIELD( m_iSecondaryFilterMode, FIELD_INTEGER, "SecondaryFilterMode" ), diff --git a/sp/src/game/server/hl2/func_recharge.cpp b/sp/src/game/server/hl2/func_recharge.cpp index e68c1c96..c3bf74c1 100644 --- a/sp/src/game/server/hl2/func_recharge.cpp +++ b/sp/src/game/server/hl2/func_recharge.cpp @@ -522,7 +522,14 @@ bool CNewRecharge::KeyValue( const char *szKeyName, const char *szValue ) void CNewRecharge::Precache( void ) { +#ifdef MAPBASE + if ( GetModelName() == NULL_STRING ) + SetModelName( AllocPooledString(HEALTH_CHARGER_MODEL_NAME) ); + + PrecacheModel( STRING(GetModelName()) ); +#else PrecacheModel( HEALTH_CHARGER_MODEL_NAME ); +#endif PrecacheScriptSound( "SuitRecharge.Deny" ); PrecacheScriptSound( "SuitRecharge.Start" ); @@ -564,7 +571,11 @@ void CNewRecharge::Spawn() SetSolid( SOLID_VPHYSICS ); CreateVPhysics(); +#ifdef MAPBASE + SetModel( STRING(GetModelName()) ); +#else SetModel( HEALTH_CHARGER_MODEL_NAME ); +#endif AddEffects( EF_NOSHADOW ); ResetSequence( LookupSequence( "idle" ) ); @@ -576,7 +587,10 @@ void CNewRecharge::Spawn() if (m_iJuice == 0) UpdateJuice( MaxJuice() ); else if (m_iJuice == -1) + { UpdateJuice( 0 ); + ResetSequence( LookupSequence( "empty" ) ); + } else UpdateJuice( m_iJuice ); #else @@ -683,22 +697,22 @@ void CNewRecharge::InputRecharge( inputdata_t &inputdata ) void CNewRecharge::InputSetCharge( inputdata_t &inputdata ) { - ResetSequence( LookupSequence( "idle" ) ); - int iJuice = inputdata.value.Int(); m_flJuice = m_iMaxJuice = m_iJuice = iJuice; + + ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) ); StudioFrameAdvance(); } #ifdef MAPBASE void CNewRecharge::InputSetChargeNoMax( inputdata_t &inputdata ) { - ResetSequence( LookupSequence( "idle" ) ); - m_flJuice = inputdata.value.Float(); UpdateJuice(m_flJuice); + + ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) ); StudioFrameAdvance(); } #endif diff --git a/sp/src/game/server/hl2/item_healthkit.cpp b/sp/src/game/server/hl2/item_healthkit.cpp index e977c080..70e1a21a 100644 --- a/sp/src/game/server/hl2/item_healthkit.cpp +++ b/sp/src/game/server/hl2/item_healthkit.cpp @@ -438,7 +438,7 @@ public: void InputSetChargeNoMax( inputdata_t &inputdata ); void UpdateJuice( int newJuice ); float MaxJuice() const; - int SetInitialCharge( void ); + void SetInitialCharge( void ); int m_iMaxJuice; int m_iIncrementValue; #endif @@ -544,13 +544,15 @@ bool CNewWallHealth::KeyValue( const char *szKeyName, const char *szValue ) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -int CNewWallHealth::SetInitialCharge( void ) +void CNewWallHealth::SetInitialCharge( void ) { - if ( m_iMaxJuice == 0 ) + if ( m_iMaxJuice != 0 ) { - m_iMaxJuice = sk_healthcharger.GetFloat(); + // It must've been overridden by the mapper + return; } - return m_iMaxJuice; + + m_iMaxJuice = sk_healthcharger.GetFloat(); } //----------------------------------------------------------------------------- @@ -574,7 +576,11 @@ void CNewWallHealth::Spawn(void) SetSolid( SOLID_VPHYSICS ); CreateVPhysics(); +#ifdef MAPBASE + SetModel( STRING(GetModelName()) ); +#else SetModel( HEALTH_CHARGER_MODEL_NAME ); +#endif AddEffects( EF_NOSHADOW ); ResetSequence( LookupSequence( "idle" ) ); @@ -583,13 +589,16 @@ void CNewWallHealth::Spawn(void) if (m_iIncrementValue == 0) m_iIncrementValue = 1; - int iMaxJuice = SetInitialCharge(); + SetInitialCharge(); // In case the juice was overridden if (m_iJuice == 0) UpdateJuice( MaxJuice() ); else if (m_iJuice == -1) + { UpdateJuice( 0 ); + ResetSequence( LookupSequence( "empty" ) ); + } else UpdateJuice( m_iJuice ); #else @@ -605,7 +614,7 @@ void CNewWallHealth::Spawn(void) m_flJuice = m_iJuice; #ifdef MAPBASE - SetCycle( 1.0f - ( m_flJuice / iMaxJuice ) ); + SetCycle( 1.0f - ( m_flJuice / MaxJuice() ) ); #else SetCycle( 1.0f - ( m_flJuice / sk_healthcharger.GetFloat() ) ); #endif @@ -638,7 +647,14 @@ bool CNewWallHealth::CreateVPhysics(void) //----------------------------------------------------------------------------- void CNewWallHealth::Precache(void) { +#ifdef MAPBASE + if ( GetModelName() == NULL_STRING ) + SetModelName( AllocPooledString(HEALTH_CHARGER_MODEL_NAME) ); + + PrecacheModel( STRING(GetModelName()) ); +#else PrecacheModel( HEALTH_CHARGER_MODEL_NAME ); +#endif PrecacheScriptSound( "WallHealth.Deny" ); PrecacheScriptSound( "WallHealth.Start" ); @@ -651,7 +667,7 @@ void CNewWallHealth::StudioFrameAdvance( void ) m_flPlaybackRate = 0; #ifdef MAPBASE - float flMaxJuice = MaxJuice(); + float flMaxJuice = MaxJuice() + 0.1f; #else float flMaxJuice = sk_healthcharger.GetFloat(); #endif @@ -707,21 +723,21 @@ void CNewWallHealth::InputRecharge( inputdata_t &inputdata ) void CNewWallHealth::InputSetCharge( inputdata_t &inputdata ) { - ResetSequence( LookupSequence( "idle" ) ); - int iJuice = inputdata.value.Int(); m_flJuice = m_iMaxJuice = m_iJuice = iJuice; + + ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) ); StudioFrameAdvance(); } void CNewWallHealth::InputSetChargeNoMax( inputdata_t &inputdata ) { - ResetSequence( LookupSequence( "idle" ) ); - m_flJuice = inputdata.value.Float(); UpdateJuice(m_flJuice); + + ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) ); StudioFrameAdvance(); } #endif diff --git a/sp/src/game/server/hl2/proto_sniper.cpp b/sp/src/game/server/hl2/proto_sniper.cpp index 93fff599..5427850a 100644 --- a/sp/src/game/server/hl2/proto_sniper.cpp +++ b/sp/src/game/server/hl2/proto_sniper.cpp @@ -1072,7 +1072,11 @@ void CProtoSniper::Spawn( void ) // Point the cursor straight ahead so that the sniper's // first sweep of the laser doesn't look weird. Vector vecForward; +#ifdef MAPBASE + AngleVectors( GetAbsAngles(), &vecForward ); +#else AngleVectors( GetLocalAngles(), &vecForward ); +#endif m_vecPaintCursor = GetBulletOrigin() + vecForward * 1024; m_fWeaponLoaded = true; @@ -1287,7 +1291,11 @@ Vector CProtoSniper::GetBulletOrigin( void ) else { Vector vecForward; +#ifdef MAPBASE + AngleVectors( GetAbsAngles(), &vecForward ); +#else AngleVectors( GetLocalAngles(), &vecForward ); +#endif return WorldSpaceCenter() + vecForward * 20; } } @@ -1428,7 +1436,7 @@ void CProtoSniper::Event_Killed( const CTakeDamageInfo &info ) else { Vector vecForward; - AngleVectors( GetLocalAngles(), &vecForward ); + AngleVectors( GetAbsAngles(), &vecForward ); float flForce = random->RandomFloat( 500, 700 ) * 10; vecForce = (vecForward * flForce) + Vector(0, 0, 600); @@ -1451,7 +1459,7 @@ void CProtoSniper::Event_Killed( const CTakeDamageInfo &info ) CBaseEntity *pGib; #ifdef MAPBASE bool bShouldIgnite = IsOnFire() || HasSpawnFlags(SF_SNIPER_DIE_ON_FIRE); - pGib = CreateRagGib( STRING(GetModelName()), GetLocalOrigin(), GetLocalAngles(), vecForce, flFadeTime, bShouldIgnite ); + pGib = CreateRagGib( STRING(GetModelName()), GetAbsOrigin(), GetAbsAngles(), vecForce, flFadeTime, bShouldIgnite ); #else bool bShouldIgnite = IsOnFire() || hl2_episodic.GetBool(); pGib = CreateRagGib( "models/combine_soldier.mdl", GetLocalOrigin(), GetLocalAngles(), (vecForward * flForce) + Vector(0, 0, 600), flFadeTime, bShouldIgnite ); @@ -1929,7 +1937,11 @@ int CProtoSniper::RangeAttack1Conditions ( float flDot, float flDist ) float flDist; +#ifdef MAPBASE + flDist = ( GetAbsOrigin() - GetEnemy()->GetAbsOrigin() ).Length2D(); +#else flDist = ( GetLocalOrigin() - GetEnemy()->GetLocalOrigin() ).Length2D(); +#endif if( flDist <= m_flPatience ) { @@ -2027,7 +2039,11 @@ bool CProtoSniper::FireBullet( const Vector &vecTarget, bool bDirectShot ) vecBulletOrigin = GetBulletOrigin(); +#ifdef MAPBASE + pBullet = (CSniperBullet *)Create( "sniperbullet", GetBulletOrigin(), GetAbsAngles(), NULL ); +#else pBullet = (CSniperBullet *)Create( "sniperbullet", GetBulletOrigin(), GetLocalAngles(), NULL ); +#endif Assert( pBullet != NULL ); @@ -2128,10 +2144,18 @@ void CProtoSniper::StartTask( const Task_t *pTask ) // Otherwise, sweep from wherever the cursor was. if( m_hSweepTarget->HasSpawnFlags( SF_SNIPERTARGET_SNAPTO ) ) { +#ifdef MAPBASE + m_vecPaintCursor = m_hSweepTarget->GetAbsOrigin(); +#else m_vecPaintCursor = m_hSweepTarget->GetLocalOrigin(); +#endif } +#ifdef MAPBASE + LaserOn( m_hSweepTarget->GetAbsOrigin(), vec3_origin ); +#else LaserOn( m_hSweepTarget->GetLocalOrigin(), vec3_origin ); +#endif break; case TASK_SNIPER_PAINT_ENEMY: @@ -2200,7 +2224,11 @@ void CProtoSniper::StartTask( const Task_t *pTask ) else { // Try to start the laser where the player can't miss seeing it! +#ifdef MAPBASE + AngleVectors( GetEnemy()->GetAbsAngles(), &vecCursor ); +#else AngleVectors( GetEnemy()->GetLocalAngles(), &vecCursor ); +#endif vecCursor = vecCursor * 300; vecCursor += GetEnemy()->EyePosition(); LaserOn( vecCursor, Vector( 16, 16, 16 ) ); @@ -2334,7 +2362,11 @@ void CProtoSniper::RunTask( const Task_t *pTask ) if ( m_hSweepTarget->HasSpawnFlags( SF_SNIPERTARGET_SHOOTME ) ) { +#ifdef MAPBASE + FireBullet( m_hSweepTarget->GetAbsOrigin(), false ); +#else FireBullet( m_hSweepTarget->GetLocalOrigin(), false ); +#endif TaskComplete(); // Force a reload. } @@ -2343,7 +2375,11 @@ void CProtoSniper::RunTask( const Task_t *pTask ) // Bump the timer up, update the cursor, paint the new target! // This is done regardless of whether we just fired at the current target. +#ifdef MAPBASE + m_vecPaintCursor = m_hSweepTarget->GetAbsOrigin(); +#else m_vecPaintCursor = m_hSweepTarget->GetLocalOrigin(); +#endif if( IsSweepingRandomly() ) { // If sweeping randomly, just pick another target. @@ -2533,7 +2569,11 @@ Vector CProtoSniper::EyePosition( void ) { if( m_spawnflags & SF_SNIPER_HIDDEN ) { +#ifdef MAPBASE + return GetAbsOrigin(); +#else return GetLocalOrigin(); +#endif } else { @@ -2672,7 +2712,11 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget ) vecAngle.x = 0; vecAngle.z = 0; +#ifdef MAPBASE + vecAngle.y += pTarget->GetAbsAngles().y; +#else vecAngle.y += pTarget->GetLocalAngles().y; +#endif AngleVectors( vecAngle, &vecVelocity ); @@ -2707,7 +2751,11 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget ) { Vector vecBulletOrigin; vecBulletOrigin = GetBulletOrigin(); +#ifdef MAPBASE + CPVSFilter filter( GetAbsOrigin() ); +#else CPVSFilter filter( GetLocalOrigin() ); +#endif te->ShowLine( filter, 0.0, &vecBulletOrigin, &vecAdjustedShot ); } @@ -2906,7 +2954,11 @@ bool CProtoSniper::FVisible( CBaseEntity *pEntity, int traceMask, CBaseEntity ** vecVerticalOffset = SNIPER_TARGET_VERTICAL_OFFSET; } +#ifdef MAPBASE + AngleVectors( pEntity->GetAbsAngles(), NULL, &vecRight, NULL ); +#else AngleVectors( pEntity->GetLocalAngles(), NULL, &vecRight, NULL ); +#endif vecEye = vecRight * SNIPER_EYE_DIST - vecVerticalOffset; UTIL_TraceLine( EyePosition(), pEntity->EyePosition() + vecEye, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr ); diff --git a/sp/src/game/server/item_world.cpp b/sp/src/game/server/item_world.cpp index 1cad6c3b..6f124280 100644 --- a/sp/src/game/server/item_world.cpp +++ b/sp/src/game/server/item_world.cpp @@ -358,6 +358,11 @@ bool UTIL_ItemCanBeTouchedByPlayer( CBaseEntity *pItem, CBasePlayer *pPlayer ) // so we have to make sure we're not dealing with a weapon for this check after all. if (pItem->HasSpawnFlags(SF_ITEM_NO_PLAYER_PICKUP) && !pItem->IsBaseCombatWeapon()) return false; + + // Fortunately, unlike the above code, this flag is identical in between weapons and items + // and can safely be used without identifying the entity. + if (pItem->HasSpawnFlags(SF_ITEM_ALWAYS_TOUCHABLE)) + return true; #endif // For now, always allow a vehicle riding player to pick up things they're driving over diff --git a/sp/src/game/server/items.h b/sp/src/game/server/items.h index 39295cef..2089fa1f 100644 --- a/sp/src/game/server/items.h +++ b/sp/src/game/server/items.h @@ -42,6 +42,8 @@ #define SF_ITEM_NO_PLAYER_PICKUP (1<<1) #define SF_ITEM_NO_PHYSCANNON_PUNT (1<<2) #define SF_ITEM_NO_NPC_PICKUP (1<<3) + +#define SF_ITEM_ALWAYS_TOUCHABLE (1<<6) // This needs to stay synced with the weapon spawnflag #endif diff --git a/sp/src/game/server/physics.cpp b/sp/src/game/server/physics.cpp index 2aa424a9..3117a3e1 100644 --- a/sp/src/game/server/physics.cpp +++ b/sp/src/game/server/physics.cpp @@ -514,7 +514,12 @@ int CCollisionEvent::ShouldCollide_2( IPhysicsObject *pObj0, IPhysicsObject *pOb if ( pEntity0->edict() && pEntity1->edict() ) { // don't collide with your owner +#ifdef MAPBASE + if ( (pEntity0->GetOwnerEntity() == pEntity1 && !pEntity0->IsSolidFlagSet(FSOLID_COLLIDE_WITH_OWNER)) + || (pEntity1->GetOwnerEntity() == pEntity0 && !pEntity1->IsSolidFlagSet(FSOLID_COLLIDE_WITH_OWNER)) ) +#else if ( pEntity0->GetOwnerEntity() == pEntity1 || pEntity1->GetOwnerEntity() == pEntity0 ) +#endif return 0; } diff --git a/sp/src/game/server/player.cpp b/sp/src/game/server/player.cpp index 511ebd0b..fccb4816 100644 --- a/sp/src/game/server/player.cpp +++ b/sp/src/game/server/player.cpp @@ -6673,7 +6673,11 @@ bool CBasePlayer::BumpWeapon( CBaseCombatWeapon *pWeapon ) else { // Don't let the player fetch weapons through walls (use MASK_SOLID so that you can't pickup through windows) +#ifdef MAPBASE + if( (pWeapon->FVisible( this, MASK_SOLID ) == false && !(GetFlags() & FL_NOTARGET)) && !HasSpawnFlags(SF_WEAPON_ALWAYS_TOUCHABLE) ) +#else if( pWeapon->FVisible( this, MASK_SOLID ) == false && !(GetFlags() & FL_NOTARGET) ) +#endif return false; } diff --git a/sp/src/game/server/scripted.cpp b/sp/src/game/server/scripted.cpp index 3a282ca1..31d7cb57 100644 --- a/sp/src/game/server/scripted.cpp +++ b/sp/src/game/server/scripted.cpp @@ -120,6 +120,7 @@ BEGIN_DATADESC( CAI_ScriptedSequence ) DEFINE_OUTPUT(m_OnScriptEvent[7], "OnScriptEvent08"), #ifdef MAPBASE DEFINE_OUTPUT(m_OnPreIdleSequence, "OnPreIdleSequence"), + DEFINE_OUTPUT(m_OnFoundNPC, "OnFoundNPC"), #endif END_DATADESC() @@ -803,6 +804,10 @@ void CAI_ScriptedSequence::StartScript( void ) DevWarning( "scripted_sequence %d:%s - restarting dormant entity %d:%s : %.1f:%.1f\n", entindex(), GetDebugName(), pTarget->entindex(), pTarget->GetDebugName(), gpGlobals->curtime, pTarget->GetNextThink() ); pTarget->SetNextThink( gpGlobals->curtime ); } + +#ifdef MAPBASE + m_OnFoundNPC.FireOutput( pTarget, this ); +#endif } } diff --git a/sp/src/game/server/scripted.h b/sp/src/game/server/scripted.h index 20ac4c1d..1b7398a4 100644 --- a/sp/src/game/server/scripted.h +++ b/sp/src/game/server/scripted.h @@ -221,6 +221,7 @@ private: COutputEvent m_OnScriptEvent[MAX_SCRIPT_EVENTS]; #ifdef MAPBASE COutputEvent m_OnPreIdleSequence; + COutputEvent m_OnFoundNPC; #endif static void ScriptEntityCancel( CBaseEntity *pentCine, bool bPretendSuccess = false ); diff --git a/sp/src/game/shared/basecombatweapon_shared.h b/sp/src/game/shared/basecombatweapon_shared.h index a35847d6..af5f37fa 100644 --- a/sp/src/game/shared/basecombatweapon_shared.h +++ b/sp/src/game/shared/basecombatweapon_shared.h @@ -55,6 +55,7 @@ class CUserCmd; #define SF_WEAPON_NO_NPC_PICKUP (1<<3) // Prevents NPCs from picking up the weapon. #define SF_WEAPON_PRESERVE_AMMO (1<<4) // Prevents the weapon from filling up to max automatically when dropped or picked up by players. #define SF_WEAPON_PRESERVE_NAME (1<<5) // Prevents the weapon's name from being cleared upon being picked up by a player. +#define SF_WEAPON_ALWAYS_TOUCHABLE (1<<6) // Makes a weapon always touchable/pickupable, even through walls. // ---------------------------------------------- // These spawnflags are not supposed to be used by level designers. diff --git a/sp/src/game/shared/util_shared.cpp b/sp/src/game/shared/util_shared.cpp index 920f9ca9..c3d6419c 100644 --- a/sp/src/game/shared/util_shared.cpp +++ b/sp/src/game/shared/util_shared.cpp @@ -219,6 +219,15 @@ bool PassServerEntityFilter( const IHandleEntity *pTouch, const IHandleEntity *p if ( !pEntTouch || !pEntPass ) return true; +#ifdef MAPBASE + // don't clip against own missiles + if ( pEntTouch->GetOwnerEntity() == pEntPass && !pEntTouch->IsSolidFlagSet(FSOLID_COLLIDE_WITH_OWNER) ) + return false; + + // don't clip against owner + if ( pEntPass->GetOwnerEntity() == pEntTouch && !pEntPass->IsSolidFlagSet(FSOLID_COLLIDE_WITH_OWNER) ) + return false; +#else // don't clip against own missiles if ( pEntTouch->GetOwnerEntity() == pEntPass ) return false; @@ -226,6 +235,7 @@ bool PassServerEntityFilter( const IHandleEntity *pTouch, const IHandleEntity *p // don't clip against owner if ( pEntPass->GetOwnerEntity() == pEntTouch ) return false; +#endif return true; diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp index e363f70a..49cfe8ae 100644 --- a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp @@ -177,6 +177,9 @@ void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** pa if( !g_pConfig->UseSpecular() && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) { params[info.m_nEnvmap]->SetUndefined(); +#ifdef PARALLAX_CORRECTED_CUBEMAPS + params[info.m_nEnvmapParallax]->SetUndefined(); +#endif } if( !params[info.m_nBaseTextureNoEnvmap]->IsDefined() ) diff --git a/sp/src/public/const.h b/sp/src/public/const.h index 98293c08..8105f866 100644 --- a/sp/src/public/const.h +++ b/sp/src/public/const.h @@ -250,7 +250,14 @@ enum SolidFlags_t FSOLID_ROOT_PARENT_ALIGNED = 0x0100, // Collisions are defined in root parent's local coordinate space FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200, // This trigger will touch debris objects +#ifdef MAPBASE + // From https://developer.valvesoftware.com/wiki/Owner + FSOLID_COLLIDE_WITH_OWNER = 0X0400, + + FSOLID_MAX_BITS = 11 +#else FSOLID_MAX_BITS = 10 +#endif }; //-----------------------------------------------------------------------------