diff --git a/README b/README index fcdd4ebc..a03c310c 100644 --- a/README +++ b/README @@ -2,16 +2,17 @@ This repository contains the code and game files of the Source 2013 modification known as Mapbase. -The projected texture fixes within the "ASW_PROJECTED_TEXTURES" preprocessor are from Insolence 2013. (https://github.com/95Navigator/insolence-2013) -The projected texture fixes within the "C17EP1_PROJECTED_TEXTURES" preprocessor are from City 17: Episode One. (https://github.com/KyleGospo/City-17-Episode-One-Source) -The vortigaunt LOS fix is from Half-Life 2: Community Edition, more specifically dky.tehkingd.u. (https://gitlab.com/RaraCerberus/HL2CE) +The projected texture fixes within the "ASW_PROJECTED_TEXTURES" preprocessor and most of the shader changes involving projected textures are cumulative changes from Insolence's repository using fixes from Alien Swarm, G-String, and City 17: Episode One. (https://github.com/95Navigator/insolence-2013, https://github.com/Biohazard90/g-string_2013, https://github.com/KyleGospo/City-17-Episode-One-Source) +The original code for phong reflections on LightmappedGeneric-derived shaders are from City 17: Episode One. (https://github.com/KyleGospo/City-17-Episode-One-Source) +The Alien Swarm-based radial fog and rope code as well as the multiple skybox support are from Half-Life 2: Downfall. (https://github.com/DownFall-Team/DownFall) The dynamic RTT shadow angles code is from Saul Rennison on the VDC. (https://developer.valvesoftware.com/wiki/Dynamic_RTT_shadow_angles_in_Source_2007) +The vortigaunt LOS fix is from Half-Life 2: Community Edition (dky.tehkingd.u in particular). (https://gitlab.com/RaraCerberus/HL2CE) Various other code and contributions were based off of pull requests in the Source 2013 SDK (https://github.com/ValveSoftware/source-sdk-2013/pulls) and snippets on the Valve Developer Community (http://developer.valvesoftware.com/). All of the work mentioned above was open source when it was borrowed. -Miscellaneous credits can be found here: -https://trello.com/c/cnaEy4Jr +More credits can be found here: +https://github.com/mapbase-source/source-sdk-2013/wiki/Mapbase-Credits Please see the Source SDK 2013 license below: diff --git a/sp/src/game/client/c_baseanimating.cpp b/sp/src/game/client/c_baseanimating.cpp index c41ff46b..5bfd8e18 100644 --- a/sp/src/game/client/c_baseanimating.cpp +++ b/sp/src/game/client/c_baseanimating.cpp @@ -54,6 +54,9 @@ #include "replay/replay_ragdoll.h" #include "studio_stats.h" #include "tier1/callqueue.h" +#ifdef MAPBASE +#include "viewrender.h" +#endif #ifdef TF_CLIENT_DLL #include "c_tf_player.h" @@ -3061,6 +3064,17 @@ int C_BaseAnimating::DrawModel( int flags ) int drawn = 0; +#ifdef MAPBASE + if (m_iViewHideFlags > 0) + { + // Hide this entity if it's not supposed to be drawn in this view. + if (m_iViewHideFlags & (1 << CurrentViewID())) + { + return 0; + } + } +#endif + #ifdef TF_CLIENT_DLL ValidateModelIndex(); #endif @@ -4606,6 +4620,14 @@ C_BaseAnimating *C_BaseAnimating::CreateRagdollCopy() pRagdoll->m_nForceBone = m_nForceBone; pRagdoll->SetNextClientThink( CLIENT_THINK_ALWAYS ); +#ifdef MAPBASE + pRagdoll->m_iViewHideFlags = m_iViewHideFlags; + + pRagdoll->m_fadeMinDist = m_fadeMinDist; + pRagdoll->m_fadeMaxDist = m_fadeMaxDist; + pRagdoll->m_flFadeScale = m_flFadeScale; +#endif + pRagdoll->SetModelName( AllocPooledString(pModelName) ); pRagdoll->SetModelScale( GetModelScale() ); return pRagdoll; diff --git a/sp/src/game/client/c_baseentity.cpp b/sp/src/game/client/c_baseentity.cpp index 8f40d7ef..5d1cfd73 100644 --- a/sp/src/game/client/c_baseentity.cpp +++ b/sp/src/game/client/c_baseentity.cpp @@ -40,6 +40,9 @@ #include "cdll_bounded_cvars.h" #include "inetchannelinfo.h" #include "proto_version.h" +#ifdef MAPBASE +#include "viewrender.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -451,6 +454,9 @@ BEGIN_RECV_TABLE_NOBASE(C_BaseEntity, DT_BaseEntity) RecvPropInt(RECVINFO(m_nRenderMode)), RecvPropInt(RECVINFO(m_nRenderFX)), RecvPropInt(RECVINFO(m_clrRender)), +#ifdef MAPBASE + RecvPropInt(RECVINFO(m_iViewHideFlags)), +#endif RecvPropInt(RECVINFO(m_iTeamNum)), RecvPropInt(RECVINFO(m_CollisionGroup)), RecvPropFloat(RECVINFO(m_flElasticity)), @@ -1978,6 +1984,17 @@ int C_BaseEntity::DrawModel( int flags ) return drawn; } +#ifdef MAPBASE + if (m_iViewHideFlags > 0) + { + // Hide this entity if it's not supposed to be drawn in this view. + if (m_iViewHideFlags & (1 << CurrentViewID())) + { + return 0; + } + } +#endif + int modelType = modelinfo->GetModelType( model ); switch ( modelType ) { diff --git a/sp/src/game/client/c_baseentity.h b/sp/src/game/client/c_baseentity.h index c62b732f..4ca3fa49 100644 --- a/sp/src/game/client/c_baseentity.h +++ b/sp/src/game/client/c_baseentity.h @@ -1275,6 +1275,10 @@ public: CNetworkColor32( m_clrRender ); +#ifdef MAPBASE + int m_iViewHideFlags; +#endif + private: // Model for rendering diff --git a/sp/src/game/client/hl2/c_env_starfield.cpp b/sp/src/game/client/hl2/c_env_starfield.cpp index 632c6f35..123dc0c1 100644 --- a/sp/src/game/client/hl2/c_env_starfield.cpp +++ b/sp/src/game/client/hl2/c_env_starfield.cpp @@ -90,6 +90,11 @@ void C_EnvStarfield::ClientThink( void ) if ( !m_bOn || !m_flDensity ) return; +#ifdef MAPBASE + if ( engine->IsPaused() ) + return; +#endif + PMaterialHandle hParticleMaterial = m_pEmitter->GetPMaterial( "effects/spark_noz" ); // Find a start & end point for the particle diff --git a/sp/src/game/client/hl2/c_script_intro.cpp b/sp/src/game/client/hl2/c_script_intro.cpp index ecfdb37c..1c0da0e8 100644 --- a/sp/src/game/client/hl2/c_script_intro.cpp +++ b/sp/src/game/client/hl2/c_script_intro.cpp @@ -10,6 +10,9 @@ #include "iviewrender.h" #include "view_shared.h" #include "viewrender.h" +#ifdef MAPBASE +#include "c_point_camera.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -175,6 +178,14 @@ void C_ScriptIntro::PostDataUpdate( DataUpdateType_t updateType ) m_IntroData.m_bDrawPrimary = true; #ifdef MAPBASE m_IntroData.m_bDrawSky2 = m_bDrawSky2; + + // 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 + C_PointCamera *pCamera = dynamic_cast(m_hCameraEntity.Get()); + if (pCamera && pCamera->IsOrtho()) + { + m_IntroData.m_hCameraEntity = m_hCameraEntity; + } #endif } diff --git a/sp/src/game/client/hud_closecaption.cpp b/sp/src/game/client/hud_closecaption.cpp index f0594e7a..a06dd122 100644 --- a/sp/src/game/client/hud_closecaption.cpp +++ b/sp/src/game/client/hud_closecaption.cpp @@ -2562,8 +2562,10 @@ void CHudCloseCaption::Flush() void CHudCloseCaption::InitCaptionDictionary( const char *dbfile ) { +#ifndef MAPBASE // Nbc66 if ( m_CurrentLanguage.IsValid() && !Q_stricmp( m_CurrentLanguage.String(), dbfile ) ) return; +#endif m_CurrentLanguage = dbfile; @@ -2602,6 +2604,7 @@ void CHudCloseCaption::InitCaptionDictionary( const char *dbfile ) AsyncCaption_t& entry = m_AsyncCaptions[ m_AsyncCaptions.AddToTail() ]; +#ifndef MAPBASE // Nbc66 // Read the header filesystem->Read( &entry.m_Header, sizeof( entry.m_Header ), fh ); if ( entry.m_Header.magic != COMPILED_CAPTION_FILEID ) @@ -2612,6 +2615,7 @@ void CHudCloseCaption::InitCaptionDictionary( const char *dbfile ) Error( "Invalid directory size %d for %s\n", entry.m_Header.directorysize, fullpath ); //if ( entry.m_Header.blocksize != MAX_BLOCK_SIZE ) // Error( "Invalid block size %d, expecting %d for %s\n", entry.m_Header.blocksize, MAX_BLOCK_SIZE, fullpath ); +#endif int directoryBytes = entry.m_Header.directorysize * sizeof( CaptionLookup_t ); entry.m_CaptionDirectory.EnsureCapacity( entry.m_Header.directorysize ); @@ -2776,7 +2780,14 @@ void OnCaptionLanguageChanged( IConVar *pConVar, const char *pOldString, float f { if ( g_pFullFileSystem->FileExists( fn ) ) { +#ifdef MAPBASE // Nbc66 + char dbfile[512]; + Q_snprintf( dbfile, sizeof( dbfile ), "resource/closecaption_%s.txt", var.GetString() ); g_pVGuiLocalize->AddFile( fn, "GAME", true ); + hudCloseCaption->InitCaptionDictionary( dbfile ); +#else + g_pVGuiLocalize->AddFile( fn, "GAME", true ); +#endif } else { @@ -2804,6 +2815,12 @@ void OnCaptionLanguageChanged( IConVar *pConVar, const char *pOldString, float f hudCloseCaption->InitCaptionDictionary( dbfile ); } } +#ifdef MAPBASE // Nbc66 + if (!engine->IsInGame()) + { + engine->ClientCmd_Unrestricted( "hud_reloadscheme" ); + } +#endif DevMsg( "cc_lang = %s\n", var.GetString() ); } diff --git a/sp/src/game/client/viewrender.cpp b/sp/src/game/client/viewrender.cpp index ca52a711..d9b6fa07 100644 --- a/sp/src/game/client/viewrender.cpp +++ b/sp/src/game/client/viewrender.cpp @@ -2924,6 +2924,15 @@ void CViewRender::ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, CViewSetup playerView( view ); playerView.origin = introData.m_vecCameraView; playerView.angles = introData.m_vecCameraViewAngles; +#ifdef MAPBASE + // Ortho handling (change this code if we ever use m_hCameraEntity for other things) + if (introData.m_hCameraEntity /*&& introData.m_hCameraEntity->IsOrtho()*/) + { + playerView.m_bOrtho = true; + introData.m_hCameraEntity->GetOrthoDimensions( playerView.m_OrthoTop, playerView.m_OrthoBottom, + playerView.m_OrthoLeft, playerView.m_OrthoRight ); + } +#endif if ( introData.m_playerViewFOV ) { playerView.fov = ScaleFOVByWidthRatio( introData.m_playerViewFOV, engine->GetScreenAspectRatio() / ( 4.0f / 3.0f ) ); @@ -6450,6 +6459,12 @@ void CReflectiveGlassView::Draw() CMatRenderContextPtr pRenderContext( materials ); PIXEVENT( pRenderContext, "CReflectiveGlassView::Draw" ); +#ifdef MAPBASE + // Store off view origin and angles and set the new view + int nSaveViewID = CurrentViewID(); + SetupCurrentView( origin, angles, VIEW_REFLECTION ); +#endif + // Disable occlusion visualization in reflection bool bVisOcclusion = r_visocclusion.GetInt(); r_visocclusion.SetValue( 0 ); @@ -6458,6 +6473,11 @@ void CReflectiveGlassView::Draw() r_visocclusion.SetValue( bVisOcclusion ); +#ifdef MAPBASE + // finish off the view. restore the previous view. + SetupCurrentView( origin, angles, (view_id_t)nSaveViewID ); +#endif + pRenderContext->ClearColor4ub( 0, 0, 0, 255 ); pRenderContext->Flush(); } @@ -6519,8 +6539,19 @@ void CRefractiveGlassView::Draw() CMatRenderContextPtr pRenderContext( materials ); PIXEVENT( pRenderContext, "CRefractiveGlassView::Draw" ); +#ifdef MAPBASE + // Store off view origin and angles and set the new view + int nSaveViewID = CurrentViewID(); + SetupCurrentView( origin, angles, VIEW_REFRACTION ); +#endif + BaseClass::Draw(); +#ifdef MAPBASE + // finish off the view. restore the previous view. + SetupCurrentView( origin, angles, (view_id_t)nSaveViewID ); +#endif + pRenderContext->ClearColor4ub( 0, 0, 0, 255 ); pRenderContext->Flush(); } diff --git a/sp/src/game/client/viewrender.h b/sp/src/game/client/viewrender.h index ecd92340..c3e02a4b 100644 --- a/sp/src/game/client/viewrender.h +++ b/sp/src/game/client/viewrender.h @@ -51,6 +51,10 @@ struct IntroData_t bool m_bDrawPrimary; Vector m_vecCameraView; QAngle m_vecCameraViewAngles; +#ifdef MAPBASE + // Used for ortho views + CHandle m_hCameraEntity; +#endif float m_playerViewFOV; CUtlVector m_Passes; diff --git a/sp/src/game/server/ai_basenpc.cpp b/sp/src/game/server/ai_basenpc.cpp index 3ef2aa00..2149a19d 100644 --- a/sp/src/game/server/ai_basenpc.cpp +++ b/sp/src/game/server/ai_basenpc.cpp @@ -7815,14 +7815,41 @@ void CAI_BaseNPC::InputPickupWeapon( inputdata_t &inputdata ) if (iszWeaponName == NULL_STRING) return; - // Searching "generically" could potentially get a weapon already held by someone. - CBaseEntity *pEntity = gEntList.FindEntityByNameNearest(STRING(iszWeaponName), GetLocalOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller); + // Doing a custom search implementation to prevent us from trying to pick up other people's weapons + // Also works generically so you could do things like "PickupWeapon > weapon_smg1" to pick up the nearest SMG + float flCurDist = MAX_TRACE_LENGTH; CBaseCombatWeapon *pWeapon = NULL; - if (pEntity) - pWeapon = pEntity->MyCombatWeaponPointer(); - if (!pEntity || !pWeapon) + CBaseEntity *pSearch = NULL; + while ((pSearch = gEntList.FindEntityGeneric(pSearch, STRING(iszWeaponName), this, inputdata.pActivator, inputdata.pCaller)) != NULL) + { + if (!pSearch->edict()) + continue; + + // Don't pick up non-weapons or weapons we can't use + CBaseCombatWeapon *pSearchWeapon = pSearch->MyCombatWeaponPointer(); + if (!pSearchWeapon || pSearchWeapon->GetOwner() || pSearchWeapon->IsLocked(this)) + continue; + + // If the weapon is marked to deny NPC pickup, only reject it if we're not searching for this weapon specifically. + // It might only have that spawnflag to prevent other NPCs from picking it up automatically. + // If we're searching for any weapon in general though (classnames or wildcards), don't use it. + if (pSearchWeapon->HasSpawnFlags( SF_WEAPON_NO_NPC_PICKUP ) && iszWeaponName != pSearchWeapon->GetEntityName()) + continue; + + float flDist = (pSearch->GetAbsOrigin() - GetAbsOrigin()).LengthSqr(); + if (flDist < flCurDist) + { + pWeapon = pSearchWeapon; + flCurDist = flDist; + } + } + + if (!pWeapon) + { + Msg("%s couldn't find %s to pick up\n", GetDebugName(), STRING(iszWeaponName)); return; + } m_flNextWeaponSearchTime = gpGlobals->curtime + 10.0; // Now lock the weapon for several seconds while we go to pick it up. @@ -7840,8 +7867,8 @@ void CAI_BaseNPC::InputPickupItem( inputdata_t &inputdata ) if (iszItemName == NULL_STRING) return; - // Searching "generically" could potentially get a weapon already held by someone. - CBaseEntity *pEntity = gEntList.FindEntityByNameNearest(STRING(iszItemName), GetLocalOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller); + // Searching generically allows for things like "PickupItem > item_health*" to pick up the nearest healthkit + CBaseEntity *pEntity = gEntList.FindEntityGenericNearest(STRING(iszItemName), GetLocalOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller); if (!pEntity) return; diff --git a/sp/src/game/server/ai_networkmanager.cpp b/sp/src/game/server/ai_networkmanager.cpp index 21a6f9de..d4b2cc05 100644 --- a/sp/src/game/server/ai_networkmanager.cpp +++ b/sp/src/game/server/ai_networkmanager.cpp @@ -69,6 +69,9 @@ CON_COMMAND( ai_debug_node_connect, "Debug the attempted connection between two // line to properly override the node graph building. 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 rbeuilding node graph" ); +#endif //----------------------------------------------------------------------------- @@ -1110,9 +1113,18 @@ void CAI_NetworkManager::DelayedInit( void ) #endif 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()) + UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding...\n" ); + + // Do it much sooner after map load + g_pAINetworkManager->SetNextThink( gpGlobals->curtime + 0.5 ); + m_bNeedGraphRebuild = true; +#else UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding...\n" ); m_bNeedGraphRebuild = true; g_pAINetworkManager->SetNextThink( gpGlobals->curtime + 1 ); +#endif return; } diff --git a/sp/src/game/server/ai_speech.cpp b/sp/src/game/server/ai_speech.cpp index 2c729c33..f62918a4 100644 --- a/sp/src/game/server/ai_speech.cpp +++ b/sp/src/game/server/ai_speech.cpp @@ -522,7 +522,7 @@ AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t concept, AI_CriteriaS // Input : *response - //----------------------------------------------------------------------------- #ifdef MAPBASE -bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *result, IRecipientFilter *filter, const char *modifiers ) +bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *result, IRecipientFilter *filter, AI_CriteriaSet *modifiers ) #else bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *result, IRecipientFilter *filter /* = NULL */ ) #endif @@ -533,23 +533,43 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *res #ifdef MAPBASE if (response[0] == '$') { - response[0] = '\0'; - const char *replace = GetOuter()->GetContextValue(response); - if (!replace) - { - replace = modifiers; + const char *context = response + 1; + const char *replace = GetOuter()->GetContextValue(context); - char key[128] = { 0 }; - char value[128] = { 0 }; - replace = SplitContext(replace, key, sizeof(key), value, sizeof(value), NULL); - replace = value; + // If we can't find the context, check modifiers + if (!replace && modifiers) + { + for (int i = 0; i < modifiers->GetCount(); i++) + { + if (FStrEq(context, modifiers->GetName(i))) + { + replace = modifiers->GetValue(i); + break; + } + } } if (replace) { - DevMsg("Replacing %s with %s...\n", response, GetOuter()->GetContextValue(response)); + DevMsg("Replacing %s with %s...\n", response, replace); Q_strncpy(response, replace, sizeof(response)); - GetOuter()->PrecacheScriptSound( response ); + + // Precache it now because it may not have been precached before + switch ( result->GetType() ) + { + case RESPONSE_SPEAK: + { + GetOuter()->PrecacheScriptSound( response ); + } + break; + + case RESPONSE_SCENE: + { + // TODO: Gender handling? + PrecacheInstancedScene( response ); + } + break; + } } } #endif @@ -805,7 +825,7 @@ bool CAI_Expresser::Speak( AIConcept_t concept, AI_CriteriaSet& modifiers, char SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)\n", STRING(GetOuter()->GetEntityName()), GetOuter(), concept, gpGlobals->curtime ); - bool spoke = SpeakDispatchResponse( concept, result, filter ); + bool spoke = SpeakDispatchResponse( concept, result, filter, &modifiers ); if ( pszOutResponseChosen ) { result->GetResponse( pszOutResponseChosen, bufsize ); diff --git a/sp/src/game/server/ai_speech.h b/sp/src/game/server/ai_speech.h index 7c3c30cb..41e99980 100644 --- a/sp/src/game/server/ai_speech.h +++ b/sp/src/game/server/ai_speech.h @@ -166,7 +166,7 @@ public: // These two methods allow looking up a response and dispatching it to be two different steps AI_Response *SpeakFindResponse( AIConcept_t concept, const char *modifiers = NULL ); #ifdef MAPBASE - bool SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, IRecipientFilter *filter = NULL, const char *modifiers = NULL ); + bool SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, IRecipientFilter *filter = NULL, AI_CriteriaSet *modifiers = NULL ); #else bool SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, IRecipientFilter *filter = NULL ); #endif diff --git a/sp/src/game/server/baseanimating.cpp b/sp/src/game/server/baseanimating.cpp index 17957d95..0bca7c42 100644 --- a/sp/src/game/server/baseanimating.cpp +++ b/sp/src/game/server/baseanimating.cpp @@ -3303,6 +3303,18 @@ void CBaseAnimating::CopyAnimationDataFrom( CBaseAnimating *pSource ) this->m_flAnimTime = pSource->m_flAnimTime; this->m_nBody = pSource->m_nBody; this->m_nSkin = pSource->m_nSkin; +#ifdef MAPBASE + this->m_clrRender = pSource->m_clrRender; + this->m_nRenderMode = pSource->m_nRenderMode; + this->m_nRenderFX = pSource->m_nRenderFX; + this->m_iViewHideFlags = pSource->m_iViewHideFlags; + this->m_fadeMinDist = pSource->m_fadeMinDist; + this->m_fadeMaxDist = pSource->m_fadeMaxDist; + this->m_flFadeScale = pSource->m_flFadeScale; + + if (this->GetModelScale() != pSource->GetModelScale()) + this->SetModelScale( pSource->GetModelScale() ); +#endif this->LockStudioHdr(); } diff --git a/sp/src/game/server/baseentity.cpp b/sp/src/game/server/baseentity.cpp index 629e1130..fa8843fc 100644 --- a/sp/src/game/server/baseentity.cpp +++ b/sp/src/game/server/baseentity.cpp @@ -278,6 +278,10 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity ) SendPropInt (SENDINFO(m_nRenderMode), 8, SPROP_UNSIGNED ), SendPropInt (SENDINFO(m_fEffects), EF_MAX_BITS, SPROP_UNSIGNED), SendPropInt (SENDINFO(m_clrRender), 32, SPROP_UNSIGNED), +#ifdef MAPBASE + // Keep consistent with VIEW_ID_COUNT in viewrender.h + SendPropInt (SENDINFO(m_iViewHideFlags), 9, SPROP_UNSIGNED ), +#endif SendPropInt (SENDINFO(m_iTeamNum), TEAMNUM_NUM_BITS, 0), SendPropInt (SENDINFO(m_CollisionGroup), 5, SPROP_UNSIGNED), SendPropFloat (SENDINFO(m_flElasticity), 0, SPROP_COORD), @@ -1822,6 +1826,9 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_KEYFIELD( m_fEffects, FIELD_INTEGER, "effects" ), DEFINE_KEYFIELD( m_clrRender, FIELD_COLOR32, "rendercolor" ), DEFINE_GLOBAL_KEYFIELD( m_nModelIndex, FIELD_SHORT, "modelindex" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_iViewHideFlags, FIELD_INTEGER, "viewhideflags" ), +#endif #if !defined( NO_ENTITY_PREDICTION ) // DEFINE_FIELD( m_PredictableID, CPredictableId ), #endif @@ -2037,6 +2044,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveSpawnFlags", InputRemoveSpawnFlags ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetRenderMode", InputSetRenderMode ), DEFINE_INPUTFUNC( FIELD_INTEGER, "SetRenderFX", InputSetRenderFX ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetViewHideFlags", InputSetViewHideFlags ), DEFINE_INPUTFUNC( FIELD_INTEGER, "AddEffects", InputAddEffects ), DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveEffects", InputRemoveEffects ), DEFINE_INPUTFUNC( FIELD_VOID, "EnableDraw", InputDrawEntity ), @@ -5677,7 +5685,11 @@ public: { const char *target = "", *action = "Use"; variant_t value; +#ifdef MAPBASE + float delay = 0; +#else int delay = 0; +#endif target = STRING( AllocPooledString(command.Arg( 1 ) ) ); @@ -5715,7 +5727,11 @@ public: } if ( command.ArgC() >= 5 ) { +#ifdef MAPBASE + delay = atof( command.Arg( 4 ) ); +#else delay = atoi( command.Arg( 4 ) ); +#endif } g_EventQueue.AddEvent( target, action, value, delay, pPlayer, pPlayer ); @@ -7596,6 +7612,14 @@ void CBaseEntity::InputSetRenderFX( inputdata_t& inputdata ) m_nRenderFX = inputdata.value.Int(); } +//----------------------------------------------------------------------------- +// Purpose: Sets our view hide flags. +//----------------------------------------------------------------------------- +void CBaseEntity::InputSetViewHideFlags( inputdata_t& inputdata ) +{ + m_iViewHideFlags = inputdata.value.Int(); +} + //----------------------------------------------------------------------------- // Purpose: Adds effects. //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/baseentity.h b/sp/src/game/server/baseentity.h index d8b4d367..73c270df 100644 --- a/sp/src/game/server/baseentity.h +++ b/sp/src/game/server/baseentity.h @@ -707,6 +707,7 @@ public: void InputRemoveSpawnFlags( inputdata_t &inputdata ); void InputSetRenderMode( inputdata_t &inputdata ); void InputSetRenderFX( inputdata_t &inputdata ); + void InputSetViewHideFlags( inputdata_t &inputdata ); void InputAddEffects( inputdata_t &inputdata ); void InputRemoveEffects( inputdata_t &inputdata ); void InputDrawEntity( inputdata_t &inputdata ); @@ -855,6 +856,16 @@ public: CNetworkArray( int, m_nModelIndexOverrides, MAX_VISION_MODES ); // used to override the base model index on the client if necessary #endif +#ifdef MAPBASE + // Prevents this entity from drawing under certain view IDs. Each flag is (1 << the view ID to hide from). + // For example, hiding an entity from VIEW_MONITOR prevents it from showing up on RT camera monitors + // and hiding an entity from VIEW_MAIN just prevents it from showing up through the player's own "eyes". + // Doing this via flags allows for the entity to be hidden from multiple view IDs at the same time. + // + // This was partly inspired by Underhell's keyvalue that allows entities to only render in mirrors and cameras. + CNetworkVar( int, m_iViewHideFlags ); +#endif + // was pev->rendercolor CNetworkColor32( m_clrRender ); const color32 GetRenderColor() const; diff --git a/sp/src/game/server/bmodels.cpp b/sp/src/game/server/bmodels.cpp index 949e0940..bcfbb144 100644 --- a/sp/src/game/server/bmodels.cpp +++ b/sp/src/game/server/bmodels.cpp @@ -1392,6 +1392,9 @@ public: void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata ); +#ifdef MAPBASE + void InputSetFilter( inputdata_t &inputdata ); +#endif private: @@ -1414,6 +1417,9 @@ BEGIN_DATADESC( CFuncVPhysicsClip ) DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), +#ifdef MAPBASE + DEFINE_INPUTFUNC( FIELD_EHANDLE, "SetFilter", InputSetFilter ), +#endif END_DATADESC() @@ -1485,3 +1491,19 @@ void CFuncVPhysicsClip::InputDisable( inputdata_t &inputdata ) VPhysicsGetObject()->EnableCollisions(false); m_bDisabled = true; } + +#ifdef MAPBASE +void CFuncVPhysicsClip::InputSetFilter( inputdata_t &inputdata ) +{ + if (inputdata.value.Entity()) + { + m_iFilterName = inputdata.value.Entity()->GetEntityName(); + m_hFilter = dynamic_cast(inputdata.value.Entity().Get()); + } + else + { + m_iFilterName = NULL_STRING; + m_hFilter = NULL; + } +} +#endif diff --git a/sp/src/game/server/effects.cpp b/sp/src/game/server/effects.cpp index cb1b51b4..94e5dc30 100644 --- a/sp/src/game/server/effects.cpp +++ b/sp/src/game/server/effects.cpp @@ -2506,7 +2506,7 @@ public: int m_iCount; float m_flDelay; Vector m_vecGibSize; - Vector m_vecGibVelocity; + float m_flGibSpeed; int m_iRandomization; float m_flLifetime; int m_iGibFlags; @@ -2518,7 +2518,7 @@ BEGIN_DATADESC( CBreakableGibShooter ) DEFINE_INPUT( m_iCount, FIELD_INTEGER, "SetCount" ), DEFINE_INPUT( m_flDelay, FIELD_FLOAT, "SetDelay" ), DEFINE_INPUT( m_vecGibSize, FIELD_VECTOR, "SetGibSize" ), - DEFINE_INPUT( m_vecGibVelocity, FIELD_VECTOR, "SetGibVelocity" ), + DEFINE_INPUT( m_flGibSpeed, FIELD_FLOAT, "SetGibSpeed" ), DEFINE_INPUT( m_iRandomization, FIELD_INTEGER, "SetRandomization" ), DEFINE_INPUT( m_flLifetime, FIELD_FLOAT, "SetLifetime" ), DEFINE_INPUT( m_iGibFlags, FIELD_INTEGER, "SetGibFlags" ), @@ -2584,7 +2584,11 @@ void CBreakableGibShooter::Shoot( void ) slaveFlag = BREAK_SLAVE; } - te->BreakModel( filter, m_flDelay, GetAbsOrigin(), GetAbsAngles(), m_vecGibSize, m_vecGibVelocity, iModelIndex, m_iRandomization, 1, m_flLifetime, m_iGibFlags | slaveFlag ); + Vector vecShootDir; + AngleVectors( GetAbsAngles(), &vecShootDir ); + VectorNormalize( vecShootDir ); + + te->BreakModel( filter, m_flDelay, GetAbsOrigin(), GetAbsAngles(), m_vecGibSize, vecShootDir * m_flGibSpeed, iModelIndex, m_iRandomization, 1, m_flLifetime, m_iGibFlags | slaveFlag ); } } diff --git a/sp/src/game/server/env_projectedtexture.cpp b/sp/src/game/server/env_projectedtexture.cpp index 2f69064f..237e77d4 100644 --- a/sp/src/game/server/env_projectedtexture.cpp +++ b/sp/src/game/server/env_projectedtexture.cpp @@ -351,6 +351,14 @@ void CEnvProjectedTexture::Activate( void ) SetThink( &CEnvProjectedTexture::InitialThink ); SetNextThink( gpGlobals->curtime + 0.1f ); +#ifdef MAPBASE + if (m_bProjectedTextureVersion == 0 && GetMoveParent()) + { + // Pre-Mapbase projected textures should use the VDC parenting fix. + m_bAlwaysUpdate = true; + } +#endif + BaseClass::Activate(); } diff --git a/sp/src/game/server/func_break.cpp b/sp/src/game/server/func_break.cpp index dcb5c040..7c097e3f 100644 --- a/sp/src/game/server/func_break.cpp +++ b/sp/src/game/server/func_break.cpp @@ -220,6 +220,10 @@ bool CBreakable::KeyValue( const char *szKeyName, const char *szValue ) int object = atoi( szValue ); if ( object > 0 && object < ARRAYSIZE(pSpawnObjects) ) m_iszSpawnObject = MAKE_STRING( pSpawnObjects[object] ); +#ifdef MAPBASE + else + m_iszSpawnObject = AllocPooledString(szValue); +#endif } else if (FStrEq(szKeyName, "propdata") ) { @@ -432,24 +436,6 @@ void CBreakable::Precache( void ) pGibName = "ConcreteChunks"; break; -#ifdef MAPBASE - case matComputer: - pGibName = "ComputerGibs"; - break; - - case matCeilingTile: - pGibName = "CeilingTile"; - break; - - case matFlesh: - pGibName = "FleshGibs"; - break; - - case matWeb: - pGibName = "WebGibs"; - break; -#endif - #endif #if HL2_EPISODIC || MAPBASE diff --git a/sp/src/game/server/hl2/combine_mine.cpp b/sp/src/game/server/hl2/combine_mine.cpp index 82034a11..dbc73c6f 100644 --- a/sp/src/game/server/hl2/combine_mine.cpp +++ b/sp/src/game/server/hl2/combine_mine.cpp @@ -104,6 +104,16 @@ BEGIN_DATADESC( CBounceBomb ) DEFINE_FIELD( m_flTimeGrabbed, FIELD_TIME ), DEFINE_FIELD( m_iMineState, FIELD_INTEGER ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bFilterExclusive, FIELD_BOOLEAN, "FilterExclusive" ), + DEFINE_KEYFIELD( m_iszEnemyFilter, FIELD_STRING, "enemyfilter" ), + DEFINE_FIELD( m_hEnemyFilter, FIELD_EHANDLE ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetEnemyFilter", InputSetEnemyFilter ), + DEFINE_KEYFIELD( m_iszFriendFilter, FIELD_STRING, "friendfilter" ), + DEFINE_FIELD( m_hFriendFilter, FIELD_EHANDLE ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetFriendFilter", InputSetFriendFilter ), +#endif + // Physics Influence DEFINE_FIELD( m_hPhysicsAttacker, FIELD_EHANDLE ), DEFINE_FIELD( m_flLastPhysicsInfluenceTime, FIELD_TIME ), @@ -145,6 +155,13 @@ void CBounceBomb::Precache() gm_iszFloorTurretClassname = AllocPooledString( "npc_turret_floor" ); gm_iszGroundTurretClassname = AllocPooledString( "npc_turret_ground" ); + +#ifdef MAPBASE + if (m_iszEnemyFilter != NULL_STRING) + m_hEnemyFilter = dynamic_cast(gEntList.FindEntityByName(NULL, STRING(m_iszEnemyFilter), this)); + if (m_iszFriendFilter != NULL_STRING) + m_hFriendFilter = dynamic_cast(gEntList.FindEntityByName( NULL, STRING(m_iszFriendFilter), this )); +#endif } //--------------------------------------------------------- @@ -877,6 +894,27 @@ float CBounceBomb::FindNearestNPC() if( pNPC->EyePosition().z < GetAbsOrigin().z ) continue; +#ifdef MAPBASE + bool bPassesFilter = false; + if (m_hEnemyFilter || m_hFriendFilter) + { + // If we have an enemy or friend filter, always accept those who pass it + // If we're only supposed to be using filters, only find entities that pass one of them + + if (m_hEnemyFilter && m_hEnemyFilter->PassesFilter( this, pNPC )) + bPassesFilter = true; + + else if (m_hFriendFilter && m_hFriendFilter->PassesFilter( this, pNPC )) + bPassesFilter = true; + + if (m_bFilterExclusive && !bPassesFilter) + continue; + } + + if (!bPassesFilter) + { +#endif + // Disregard things that want to be disregarded if( pNPC->Classify() == CLASS_NONE ) continue; @@ -889,6 +927,10 @@ float CBounceBomb::FindNearestNPC() if( pNPC->m_iClassname == gm_iszFloorTurretClassname || pNPC->m_iClassname == gm_iszGroundTurretClassname ) continue; +#ifdef MAPBASE + } +#endif + float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr(); @@ -925,9 +967,28 @@ float CBounceBomb::FindNearestNPC() if( pPlayer && !(pPlayer->GetFlags() & FL_NOTARGET) ) { +#ifdef MAPBASE + bool bPassesFilter = true; + if ((m_hEnemyFilter || m_hFriendFilter) && m_bFilterExclusive) + { + // If we have an enemy or friend filter, and that's all we're supposed to be using, + // don't accept the player if they don't pass our filters + + if (m_hEnemyFilter && !m_hEnemyFilter->PassesFilter( this, pPlayer )) + bPassesFilter = false; + + else if (m_hFriendFilter && !m_hFriendFilter->PassesFilter( this, pPlayer )) + bPassesFilter = false; + } +#endif + float flDist = (pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); +#ifdef MAPBASE + if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) && bPassesFilter ) +#else if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) ) +#endif { flNearest = flDist; SetNearestNPC( pPlayer ); @@ -943,8 +1004,9 @@ float CBounceBomb::FindNearestNPC() if( m_bFoeNearest ) { // Changing state to where a friend is nearest. - +#ifndef MAPBASE if( IsFriend( m_hNearestNPC ) ) +#endif { // Friend UpdateLight( true, 0, 255, 0, 190 ); @@ -970,6 +1032,14 @@ float CBounceBomb::FindNearestNPC() //--------------------------------------------------------- bool CBounceBomb::IsFriend( CBaseEntity *pEntity ) { +#ifdef MAPBASE + if (m_hFriendFilter && m_hFriendFilter->PassesFilter(this, pEntity)) + return true; + + if (m_hEnemyFilter && m_hEnemyFilter->PassesFilter(this, pEntity)) + return false; +#endif + int classify = pEntity->Classify(); bool bIsCombine = false; @@ -1234,6 +1304,22 @@ void CBounceBomb::InputDisarm( inputdata_t &inputdata ) } #ifdef MAPBASE +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBounceBomb::InputSetEnemyFilter( inputdata_t &inputdata ) +{ + m_iszEnemyFilter = inputdata.value.StringID(); + m_hEnemyFilter = dynamic_cast(gEntList.FindEntityByName( NULL, STRING(m_iszEnemyFilter), this )); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBounceBomb::InputSetFriendFilter( inputdata_t &inputdata ) +{ + m_iszFriendFilter = inputdata.value.StringID(); + m_hFriendFilter = dynamic_cast(gEntList.FindEntityByName( NULL, STRING(m_iszFriendFilter), this )); +} + //--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::InputBounce( inputdata_t &inputdata ) diff --git a/sp/src/game/server/hl2/combine_mine.h b/sp/src/game/server/hl2/combine_mine.h index 12384ee9..56ab6cd2 100644 --- a/sp/src/game/server/hl2/combine_mine.h +++ b/sp/src/game/server/hl2/combine_mine.h @@ -24,6 +24,9 @@ class CSoundPatch; #define BOUNCEBOMB_EXPLODE_RADIUS 125.0 #define BOUNCEBOMB_EXPLODE_DAMAGE 150.0 #include "player_pickup.h" +#ifdef MAPBASE +#include "filters.h" +#endif class CBounceBomb : public CBaseAnimating, public CDefaultPlayerPickupVPhysics { @@ -126,6 +129,19 @@ private: IPhysicsConstraint *m_pConstraint; int m_iMineState; +#ifdef MAPBASE + // Makes the filters the exclusive factor in determining friend/foe + bool m_bFilterExclusive; + + string_t m_iszEnemyFilter; + CHandle m_hEnemyFilter; + void InputSetEnemyFilter( inputdata_t &inputdata ); + + string_t m_iszFriendFilter; + CHandle m_hFriendFilter; + void InputSetFriendFilter( inputdata_t &inputdata ); +#endif + COutputEvent m_OnPulledUp; void InputDisarm( inputdata_t &inputdata ); #ifdef MAPBASE diff --git a/sp/src/game/server/hl2/func_tank.cpp b/sp/src/game/server/hl2/func_tank.cpp index b2d99cdf..bec8b1fa 100644 --- a/sp/src/game/server/hl2/func_tank.cpp +++ b/sp/src/game/server/hl2/func_tank.cpp @@ -1875,6 +1875,15 @@ QAngle CFuncTank::AimBarrelAt( const Vector &parentTarget ) { return GetLocalAngles(); } +#ifdef MAPBASE + else if ( m_barrelPos.LengthSqr() == 0.0f ) + { + // Do a simpler calculation that doesn't take barrel into account + float targetToCenterYaw = atan2( target.y, target.x ); + float targetToCenterPitch = atan2( target.z, sqrt( quadTargetXY ) ); + return QAngle( -RAD2DEG( targetToCenterPitch ), RAD2DEG( targetToCenterYaw ), 0 ); + } +#endif else { // We're trying to aim the offset barrel at an arbitrary point. diff --git a/sp/src/game/server/hl2/grenade_frag.cpp b/sp/src/game/server/hl2/grenade_frag.cpp index 1788d191..b0ad60fb 100644 --- a/sp/src/game/server/hl2/grenade_frag.cpp +++ b/sp/src/game/server/hl2/grenade_frag.cpp @@ -11,6 +11,9 @@ #include "Sprite.h" #include "SpriteTrail.h" #include "soundent.h" +#ifdef MAPBASE +#include "mapbase/ai_grenade.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -126,8 +129,31 @@ void CGrenadeFrag::Spawn( void ) SetCollisionGroup( COLLISION_GROUP_WEAPON ); CreateVPhysics(); +#ifdef MAPBASE + if (GetThrower() && GetThrower()->IsNPC()) + { + // One of OnThrowGrenade's useful applications is replacing it with another entity using point_entity_replace. + // However, the grenade is always able to let out a blip before being replaced, which can be confusing/undesirable. + // This code checks to see if OnThrowGrenade is being used for anything, in which case the first blip will be very slightly delayed. + // This doesn't interfere with when the grenade actually detonates and shouldn't be noticable if the grenade is kept by OnThrowGrenade anyway. + CAI_GrenadeUserSink *pGrenadeUser = dynamic_cast(GetThrower()); + if (pGrenadeUser && pGrenadeUser->UsingOnThrowGrenade()) + { + // We delay the blip by 0.05, so replacement must occur within that period in order to skip the blip. + m_flNextBlipTime = gpGlobals->curtime + 0.05f; + } + } + + // Do the blip if m_flNextBlipTime wasn't changed + if (m_flNextBlipTime <= gpGlobals->curtime) + { + BlipSound(); + m_flNextBlipTime = gpGlobals->curtime + FRAG_GRENADE_BLIP_FREQUENCY; + } +#else BlipSound(); m_flNextBlipTime = gpGlobals->curtime + FRAG_GRENADE_BLIP_FREQUENCY; +#endif AddSolidFlags( FSOLID_NOT_STANDABLE ); diff --git a/sp/src/game/server/hl2/hl2_player.cpp b/sp/src/game/server/hl2/hl2_player.cpp index 3283c71a..a12b7ff7 100644 --- a/sp/src/game/server/hl2/hl2_player.cpp +++ b/sp/src/game/server/hl2/hl2_player.cpp @@ -2172,7 +2172,7 @@ void CHL2_Player::InputSquadForceGoTo( inputdata_t &inputdata ) } else { - goal.m_pGoalEntity = var.FieldType() == FIELD_EHANDLE ? var.Entity() : gEntList.FindEntityByNameNearest(var.String(), pPlayerSquadLeader->GetLocalOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller); + goal.m_pGoalEntity = var.FieldType() == FIELD_EHANDLE ? var.Entity() : gEntList.FindEntityByNameNearest(var.String(), pPlayerSquadLeader->GetAbsOrigin(), 0, this, inputdata.pActivator, inputdata.pCaller); goal.m_vecGoalLocation = vec3_invalid; } diff --git a/sp/src/game/server/hl2/item_ammo.cpp b/sp/src/game/server/hl2/item_ammo.cpp index 15f2362c..fa54ad1f 100644 --- a/sp/src/game/server/hl2/item_ammo.cpp +++ b/sp/src/game/server/hl2/item_ammo.cpp @@ -68,6 +68,8 @@ BEGIN_DATADESC( CItemAmmo ) END_DATADESC() +// Almost all instances of CItem below are for declaring the base class, which is now CItemAmmo. +// This is here so we don't have to #ifdef all of them. #define CItem CItemAmmo #else diff --git a/sp/src/game/server/hl2/npc_citizen17.cpp b/sp/src/game/server/hl2/npc_citizen17.cpp index 7efaa294..d3283642 100644 --- a/sp/src/game/server/hl2/npc_citizen17.cpp +++ b/sp/src/game/server/hl2/npc_citizen17.cpp @@ -114,7 +114,7 @@ ConVar player_squad_autosummon_debug( "player_squad_autosummon_debug", "0" ); #ifdef MAPBASE ConVar npc_citizen_resupplier_adjust_ammo("npc_citizen_resupplier_adjust_ammo", "1", FCVAR_NONE, "If what ammo we give to the player would go over their max, should we adjust what we give accordingly (1) or cancel it altogether? (0)" ); -ConVar npc_citizen_nocollide_player( "npc_citizen_nocollide_player", "1" ); +ConVar npc_citizen_nocollide_player( "npc_citizen_nocollide_player", "0" ); #endif #define ShouldAutosquad() (npc_citizen_auto_player_squad.GetBool()) diff --git a/sp/src/game/server/hl2/npc_combine.cpp b/sp/src/game/server/hl2/npc_combine.cpp index 0d728f02..64ae37dd 100644 --- a/sp/src/game/server/hl2/npc_combine.cpp +++ b/sp/src/game/server/hl2/npc_combine.cpp @@ -190,6 +190,7 @@ DEFINE_FIELD( m_flStopMoveShootTime, FIELD_TIME ), DEFINE_KEYFIELD( m_iNumGrenades, FIELD_INTEGER, "NumGrenades" ), #else DEFINE_INPUT( m_bUnderthrow, FIELD_BOOLEAN, "UnderthrowGrenades" ), +DEFINE_INPUT( m_bAlternateCapable, FIELD_BOOLEAN, "SetAlternateCapable" ), #endif #ifndef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM DEFINE_EMBEDDED( m_Sentences ), @@ -698,19 +699,23 @@ Class_T CNPC_Combine::Classify ( void ) //----------------------------------------------------------------------------- inline bool CNPC_Combine::IsElite( void ) { - //if (m_bUnderthrow) - // return false; - return m_fIsElite; } //----------------------------------------------------------------------------- // Purpose: Function for gauging whether we're capable of alt-firing. -// It just returns IsElite() right now, but you could change it here. //----------------------------------------------------------------------------- -inline bool CNPC_Combine::IsAltFireCapable( void ) +bool CNPC_Combine::IsAltFireCapable( void ) { - return IsElite(); + return IsElite() || m_bAlternateCapable; +} + +//----------------------------------------------------------------------------- +// Purpose: Function for gauging whether we're capable of throwing grenades. +//----------------------------------------------------------------------------- +bool CNPC_Combine::IsGrenadeCapable( void ) +{ + return !IsElite() || m_bAlternateCapable; } #endif @@ -1945,10 +1950,9 @@ int CNPC_Combine::SelectSchedule( void ) Vector vecTarget = m_hForcedGrenadeTarget->WorldSpaceCenter(); #ifdef MAPBASE - if ( IsAltFireCapable() ) -#else - if ( IsElite() ) + // I switched this to IsAltFireCapable() before, but m_bAlternateCapable makes it necessary to use IsElite() again. #endif + if ( IsElite() ) { if ( FVisible( m_hForcedGrenadeTarget ) ) { @@ -1976,6 +1980,12 @@ int CNPC_Combine::SelectSchedule( void ) } } +#ifdef MAPBASE + // Drop a grenade? + if ( HasCondition( COND_COMBINE_DROP_GRENADE ) ) + return SCHED_COMBINE_DROP_GRENADE; +#endif + if ( m_NPCState != NPC_STATE_SCRIPT) { // If we're hit by bugbait, thrash around @@ -2167,9 +2177,11 @@ bool CNPC_Combine::ShouldChargePlayer() int CNPC_Combine::SelectScheduleAttack() { +#ifndef MAPBASE // Moved to SelectSchedule() // Drop a grenade? if ( HasCondition( COND_COMBINE_DROP_GRENADE ) ) return SCHED_COMBINE_DROP_GRENADE; +#endif // Kick attack? if ( HasCondition( COND_CAN_MELEE_ATTACK1 ) ) @@ -2197,18 +2209,14 @@ int CNPC_Combine::SelectScheduleAttack() } } -#ifdef MAPBASE - if (IsUsingTacticalVariant(TACTICAL_VARIANT_GRENADE_HAPPY)) - { - // Don't do turret charging during grenade happiness. - // I guess just do nothing and let the rest of the AI handle it. - } - else -#endif - // If we're not in the viewcone of the turret, run up and hit it. Do this a bit later to // give other squadmembers a chance to throw a grenade before I run in. +#ifdef MAPBASE + // Don't do turret charging of we're just grenade happy. + if ( !IsUsingTacticalVariant(TACTICAL_VARIANT_GRENADE_HAPPY) && !GetEnemy()->MyNPCPointer()->FInViewCone( this ) && OccupyStrategySlot( SQUAD_SLOT_GRENADE1 ) ) +#else if ( !GetEnemy()->MyNPCPointer()->FInViewCone( this ) && OccupyStrategySlot( SQUAD_SLOT_GRENADE1 ) ) +#endif return SCHED_COMBINE_CHARGE_TURRET; } @@ -3421,7 +3429,7 @@ bool CNPC_Combine::CanAltFireEnemy( bool bUseFreeKnowledge ) bool CNPC_Combine::CanGrenadeEnemy( bool bUseFreeKnowledge ) { #ifdef MAPBASE - if ( IsAltFireCapable() ) + if ( !IsGrenadeCapable() ) #else if ( IsElite() ) #endif diff --git a/sp/src/game/server/hl2/npc_combine.h b/sp/src/game/server/hl2/npc_combine.h index f88bc95c..ad96125d 100644 --- a/sp/src/game/server/hl2/npc_combine.h +++ b/sp/src/game/server/hl2/npc_combine.h @@ -107,6 +107,7 @@ public: #ifdef MAPBASE bool IsElite(); bool IsAltFireCapable(); + bool IsGrenadeCapable(); const char* GetGrenadeAttachment() { return "lefthand"; } #else bool IsElite() { return m_fIsElite; } @@ -316,6 +317,7 @@ private: #else // Underthrow grenade at target bool m_bUnderthrow; + bool m_bAlternateCapable; #endif bool m_bShouldPatrol; bool m_bFirstEncounter;// only put on the handsign show in the squad's first encounter. diff --git a/sp/src/game/server/hl2/npc_playercompanion.cpp b/sp/src/game/server/hl2/npc_playercompanion.cpp index 0ec05069..981f5692 100644 --- a/sp/src/game/server/hl2/npc_playercompanion.cpp +++ b/sp/src/game/server/hl2/npc_playercompanion.cpp @@ -1017,7 +1017,7 @@ int CNPC_PlayerCompanion::SelectScheduleCombat() //Msg("Time: %f Dist: %f\n", flTime, flDist ); if ( flTime <= COMBINE_GRENADE_FLUSH_TIME && flDist <= COMBINE_GRENADE_FLUSH_DIST && CanGrenadeEnemy( false ) && OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) { - return SCHED_RANGE_ATTACK2; + return SCHED_PC_RANGE_ATTACK2; } } #endif @@ -1222,7 +1222,7 @@ int CNPC_PlayerCompanion::TranslateSchedule( int scheduleType ) { if ( OccupyStrategySlot( SQUAD_SLOT_SPECIAL_ATTACK ) ) { - return SCHED_RANGE_ATTACK2; + return SCHED_PC_RANGE_ATTACK2; } } diff --git a/sp/src/game/server/hl2/npc_turret_ground.cpp b/sp/src/game/server/hl2/npc_turret_ground.cpp index de35097b..8ffd37df 100644 --- a/sp/src/game/server/hl2/npc_turret_ground.cpp +++ b/sp/src/game/server/hl2/npc_turret_ground.cpp @@ -132,8 +132,8 @@ void CNPC_GroundTurret::Spawn( void ) DevMsg("ERROR! npc_ground_turret with no parent!\n"); #ifndef MAPBASE UTIL_Remove(this); -#endif return; +#endif } m_flTimeNextShoot = gpGlobals->curtime; diff --git a/sp/src/game/server/hl2/weapon_crossbow.cpp b/sp/src/game/server/hl2/weapon_crossbow.cpp index 50a51b74..b86b4c05 100644 --- a/sp/src/game/server/hl2/weapon_crossbow.cpp +++ b/sp/src/game/server/hl2/weapon_crossbow.cpp @@ -41,6 +41,10 @@ extern ConVar sk_plr_dmg_crossbow; extern ConVar sk_npc_dmg_crossbow; +#ifdef MAPBASE +ConVar weapon_crossbow_new_hit_locations( "weapon_crossbow_new_hit_locations", "1", FCVAR_NONE, "Toggles new crossbow knockback that properly pushes back the correct limbs." ); +#endif + void TE_StickyBolt( IRecipientFilter& filter, float delay, Vector vecDirection, const Vector *origin ); #define BOLT_SKIN_NORMAL 0 @@ -289,6 +293,38 @@ void CCrossbowBolt::BoltTouch( CBaseEntity *pOther ) } #endif//HL2_EPISODIC +#ifdef MAPBASE + if (weapon_crossbow_new_hit_locations.GetInt() > 0) + { + // A very experimental and weird way of getting a crossbow bolt to deal accurate knockback. + CBaseAnimating *pOtherAnimating = pOther->GetBaseAnimating(); + if (pOtherAnimating && pOtherAnimating->GetModelPtr() && pOtherAnimating->GetModelPtr()->numbones() > 1) + { + int iClosestBone = -1; + float flCurDistSqr = Square(128.0f); + matrix3x4_t bonetoworld; + Vector vecBonePos; + for (int i = 0; i < pOtherAnimating->GetModelPtr()->numbones(); i++) + { + pOtherAnimating->GetBoneTransform( i, bonetoworld ); + MatrixPosition( bonetoworld, vecBonePos ); + + float flDist = vecBonePos.DistToSqr(GetLocalOrigin()); + if (flDist < flCurDistSqr) + { + iClosestBone = i; + flCurDistSqr = flDist; + } + } + + if (iClosestBone != -1) + { + tr.physicsbone = pOtherAnimating->GetPhysicsBone(iClosestBone); + } + } + } +#endif + if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() ) { #ifdef MAPBASE diff --git a/sp/src/game/server/hl2/weapon_shotgun.cpp b/sp/src/game/server/hl2/weapon_shotgun.cpp index a832a3d6..fb9ec215 100644 --- a/sp/src/game/server/hl2/weapon_shotgun.cpp +++ b/sp/src/game/server/hl2/weapon_shotgun.cpp @@ -24,6 +24,10 @@ extern ConVar sk_auto_reload_time; extern ConVar sk_plr_num_shotgun_pellets; +#ifdef MAPBASE +extern ConVar sk_plr_num_shotgun_pellets_double; +extern ConVar sk_npc_num_shotgun_pellets; +#endif class CWeaponShotgun : public CBaseHLCombatWeapon { @@ -183,7 +187,11 @@ void CWeaponShotgun::FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, bool vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin ); } +#ifdef MAPBASE + pOperator->FireBullets( sk_npc_num_shotgun_pellets.GetInt(), vecShootOrigin, vecShootDir, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 ); +#else pOperator->FireBullets( 8, vecShootOrigin, vecShootDir, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 ); +#endif } //----------------------------------------------------------------------------- @@ -526,7 +534,11 @@ void CWeaponShotgun::SecondaryAttack( void ) Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT ); // Fire the bullets +#ifdef MAPBASE + pPlayer->FireBullets( sk_plr_num_shotgun_pellets_double.GetInt(), vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0, -1, -1, 0, NULL, false, false ); +#else pPlayer->FireBullets( 12, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0, -1, -1, 0, NULL, false, false ); +#endif pPlayer->ViewPunch( QAngle(random->RandomFloat( -5, 5 ),0,0) ); pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 1.0 ); diff --git a/sp/src/game/server/logic_measure_movement.cpp b/sp/src/game/server/logic_measure_movement.cpp index 17d19843..7d2df131 100644 --- a/sp/src/game/server/logic_measure_movement.cpp +++ b/sp/src/game/server/logic_measure_movement.cpp @@ -734,6 +734,91 @@ END_DATADESC() //----------------------------------------------------------------------------- void CLogicMirrorMovement::DoMeasure( Vector &vecOrigin, QAngle &angAngles ) { + + matrix3x4_t matRefToMeasure, matWorldToMeasure; + switch( m_nMeasureType ) + { + case MEASURE_POSITION: + MatrixInvert( m_hMeasureTarget->EntityToWorldTransform(), matWorldToMeasure ); + break; + + case MEASURE_EYE_POSITION: + AngleIMatrix( m_hMeasureTarget->EyeAngles(), m_hMeasureTarget->EyePosition(), matWorldToMeasure ); + break; + + case MEASURE_ATTACHMENT: + if (CBaseAnimating *pAnimating = m_hMeasureTarget->GetBaseAnimating()) + { + if (m_iAttachment <= 0) + m_iAttachment = m_hMeasureTarget->GetBaseAnimating()->LookupAttachment(STRING(m_strAttachment)); + + if (m_iAttachment == -1) + Warning("WARNING: %s requesting invalid attachment %s on %s!\n", GetDebugName(), STRING(m_strAttachment), m_hMeasureTarget->GetDebugName()); + else + pAnimating->GetAttachment(m_iAttachment, matWorldToMeasure); + } + else + { + Warning("WARNING: %s requesting attachment point on non-animating entity %s!\n", GetDebugName(), m_hMeasureTarget->GetDebugName()); + } + break; + } + + ConcatTransforms( matWorldToMeasure, m_hMeasureReference->EntityToWorldTransform(), matRefToMeasure ); + + // If we have spawn flags, we might be supposed to ignore something + if (GetSpawnFlags() > 0) + { + if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_USE_IGNORE_FLAGS_FOR_ORIGIN )) + { + // Get the position from the matrix's column directly and re-assign it + Vector vecPosition; + MatrixGetColumn( matRefToMeasure, 3, vecPosition ); + + HandleIgnoreFlags( vecPosition.Base() ); + + MatrixSetColumn( vecPosition, 3, matRefToMeasure ); + } + else + { + // Get the angles from the matrix and re-assign it + QAngle angMod; + MatrixAngles( matWorldToMeasure, angMod ); + + HandleIgnoreFlags( angMod.Base() ); + + AngleMatrix( angMod, matWorldToMeasure ); + } + } + + // Apply the scale factor + if ( ( m_flScale != 0.0f ) && ( m_flScale != 1.0f ) ) + { + Vector vecTranslation; + MatrixGetColumn( matRefToMeasure, 3, vecTranslation ); + vecTranslation /= m_flScale; + MatrixSetColumn( vecTranslation, 3, matRefToMeasure ); + } + + MatrixScaleBy( -1.0f, matRefToMeasure ); + + QAngle angRot; + Vector vecPos; + MatrixAngles( matRefToMeasure, angRot ); + MatrixPosition( matRefToMeasure, vecPos ); + angRot.z *= -1.0f; + vecPos.z *= -1.0f; + AngleMatrix( angRot, vecPos, matWorldToMeasure ); + + // Now apply the new matrix to the new reference point + matrix3x4_t matMeasureToRef, matNewTargetToWorld; + MatrixInvert( matRefToMeasure, matMeasureToRef ); + + ConcatTransforms( m_hTargetReference->EntityToWorldTransform(), matMeasureToRef, matNewTargetToWorld ); + + MatrixAngles( matNewTargetToWorld, angAngles, vecOrigin ); + + /* VMatrix matPortal1ToWorldInv, matPortal2ToWorld; MatrixInverseGeneral( m_hMeasureReference->EntityToWorldTransform(), matPortal1ToWorldInv ); switch( m_nMeasureType ) @@ -820,5 +905,6 @@ void CLogicMirrorMovement::DoMeasure( Vector &vecOrigin, QAngle &angAngles ) vecOrigin = ptNewPosition; angAngles = qNewAngles; + */ } #endif diff --git a/sp/src/game/server/logicentities.cpp b/sp/src/game/server/logicentities.cpp index 2b78a3eb..ae2a8cf2 100644 --- a/sp/src/game/server/logicentities.cpp +++ b/sp/src/game/server/logicentities.cpp @@ -3245,10 +3245,26 @@ class CLogicCollisionPair : public CLogicalEntity DECLARE_CLASS( CLogicCollisionPair, CLogicalEntity ); public: +#ifdef MAPBASE + // !activator, !caller, etc. support + void EnableCollisions( bool bEnable, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL ) + { + IPhysicsObject *pPhysics0 = NULL; + IPhysicsObject *pPhysics1 = NULL; + + CBaseEntity *pEntity0 = gEntList.FindEntityByName( NULL, m_nameAttach1, this, pActivator, pCaller ); + if (pEntity0) + pPhysics0 = pEntity0->VPhysicsGetObject(); + + CBaseEntity *pEntity1 = gEntList.FindEntityByName( NULL, m_nameAttach2, this, pActivator, pCaller ); + if (pEntity1) + pPhysics1 = pEntity1->VPhysicsGetObject(); +#else void EnableCollisions( bool bEnable ) { IPhysicsObject *pPhysics0 = FindPhysicsObjectByNameOrWorld( m_nameAttach1, this ); IPhysicsObject *pPhysics1 = FindPhysicsObjectByNameOrWorld( m_nameAttach2, this ); +#endif // need two different objects to do anything if ( pPhysics0 && pPhysics1 && pPhysics0 != pPhysics1 ) @@ -3283,14 +3299,22 @@ public: { if ( m_succeeded && m_disabled ) return; +#ifdef MAPBASE + EnableCollisions( false, inputdata.pActivator, inputdata.pCaller ); +#else EnableCollisions( false ); +#endif } void InputEnableCollisions( inputdata_t &inputdata ) { if ( m_succeeded && !m_disabled ) return; +#ifdef MAPBASE + EnableCollisions( true, inputdata.pActivator, inputdata.pCaller ); +#else EnableCollisions( true ); +#endif } // If Activate() becomes PostSpawn() //void OnRestore() { Activate(); } @@ -6390,7 +6414,15 @@ void CMathGenerate::GenerateLinearRamp() // CLinearRampProxy in mathproxy.cpp // Param1 = rate - m_Value.Set( m_flParam1 * gpGlobals->curtime + m_Value.Get(), NULL, this ); + float flVal = m_flParam1 * gpGlobals->curtime + m_Value.Get(); + + // clamp + if (flVal < m_flMin) + flVal = m_flMin; + else if (flVal > m_flMax) + flVal = m_flMax; + + m_Value.Set( flVal, NULL, this ); SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); } diff --git a/sp/src/game/server/mapbase/ai_grenade.h b/sp/src/game/server/mapbase/ai_grenade.h index 1816ad95..01ef6a12 100644 --- a/sp/src/game/server/mapbase/ai_grenade.h +++ b/sp/src/game/server/mapbase/ai_grenade.h @@ -60,6 +60,17 @@ extern int COMBINE_AE_BEGIN_ALTFIRE; extern int COMBINE_AE_ALTFIRE; +//----------------------------------------------------------------------------- +// Other classes can use this and access some CAI_GrenadeUser functions. +//----------------------------------------------------------------------------- +class CAI_GrenadeUserSink +{ +public: + CAI_GrenadeUserSink() { } + + virtual bool UsingOnThrowGrenade() { return false; } +}; + //----------------------------------------------------------------------------- // // Template class for NPCs using grenades or weapon alt-fire stuff. @@ -70,10 +81,12 @@ extern int COMBINE_AE_ALTFIRE; // //----------------------------------------------------------------------------- template -class CAI_GrenadeUser : public BASE_NPC +class CAI_GrenadeUser : public BASE_NPC, public CAI_GrenadeUserSink { DECLARE_CLASS_NOFRIEND( CAI_GrenadeUser, BASE_NPC ); public: + CAI_GrenadeUser() : CAI_GrenadeUserSink() { } + void AddGrenades( int inc, CBaseEntity *pLastGrenade = NULL ) { m_iNumGrenades += inc; @@ -105,6 +118,9 @@ public: bool CanThrowGrenade( const Vector &vecTarget ); bool CheckCanThrowGrenade( const Vector &vecTarget ); + // For OnThrowGrenade + point_entity_replace, see grenade_frag.cpp + bool UsingOnThrowGrenade() { return m_OnThrowGrenade.NumberOfElements() > 0; } + protected: void StartTask_FaceAltFireTarget( const Task_t *pTask ); @@ -176,13 +192,14 @@ void CAI_GrenadeUser::HandleAnimEvent( animevent_t *pEvent ) GetVectors( &forward, NULL, &up ); vecThrow = forward * 750 + up * 175; - CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, vecThrow, vecSpin, this, COMBINE_GRENADE_TIMER, true ); + // This code is used by player allies now, so it's only "combine spawned" if the thrower isn't allied with the player. + CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, vecThrow, vecSpin, this, COMBINE_GRENADE_TIMER, !IsPlayerAlly() ); m_OnThrowGrenade.Set(pGrenade, pGrenade, this); } else { // Use the Velocity that AI gave us. - CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vecSpin, this, COMBINE_GRENADE_TIMER, true ); + CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vecSpin, this, COMBINE_GRENADE_TIMER, !IsPlayerAlly() ); m_OnThrowGrenade.Set(pGrenade, pGrenade, this); AddGrenades(-1, pGrenade); } diff --git a/sp/src/game/server/mapbase/logic_externaldata.cpp b/sp/src/game/server/mapbase/logic_externaldata.cpp index 56f9fe39..ce4f4d56 100644 --- a/sp/src/game/server/mapbase/logic_externaldata.cpp +++ b/sp/src/game/server/mapbase/logic_externaldata.cpp @@ -45,6 +45,7 @@ public: bool m_bSaveEachChange; bool m_bReloadBeforeEachAction; + string_t m_iszMapname; COutputString m_OutValue; }; @@ -57,6 +58,7 @@ BEGIN_DATADESC( CLogicExternalData ) //DEFINE_KEYFIELD( m_iszBlock, FIELD_STRING, "Block" ), DEFINE_KEYFIELD( m_bSaveEachChange, FIELD_BOOLEAN, "SaveEachChange" ), DEFINE_KEYFIELD( m_bReloadBeforeEachAction, FIELD_BOOLEAN, "ReloadBeforeEachAction" ), + DEFINE_KEYFIELD( m_iszMapname, FIELD_STRING, "Mapname" ), // This should be cached each load //DEFINE_ARRAY( m_iszFile, FIELD_CHARACTER, MAX_PATH ), @@ -147,7 +149,10 @@ void CLogicExternalData::Activate() { BaseClass::Activate(); - Q_snprintf(m_iszFile, sizeof(m_iszFile), "maps/%s_externaldata.txt", gpGlobals->mapname); + if (m_iszMapname == NULL_STRING || STRING(m_iszMapname)[0] == '\0') + m_iszMapname = gpGlobals->mapname; + + Q_snprintf(m_iszFile, sizeof(m_iszFile), "maps/%s_externaldata.txt", STRING(m_iszMapname)); DevMsg("LOGIC_EXTERNALDATA: %s\n", m_iszFile); // This handles !self, etc. even though the end result could just be assigning to itself. diff --git a/sp/src/game/server/mapbase/point_entity_replace.cpp b/sp/src/game/server/mapbase/point_entity_replace.cpp index 3452c11f..e2f6654d 100644 --- a/sp/src/game/server/mapbase/point_entity_replace.cpp +++ b/sp/src/game/server/mapbase/point_entity_replace.cpp @@ -35,6 +35,8 @@ public: REPLACEMENTTYPE_CLASSNAME, // Replace with entity of specified classname REPLACEMENTTYPE_TEMPLATE, // Replace with a point_template's contents REPLACEMENTTYPE_TEMPLATE_RELATIVE, // Replace with a point_template's contents, maintaining relative position + REPLACEMENTTYPE_RANDOM_TEMPLATE, // Replace with one of a point_template's templates, randomly selected + REPLACEMENTTYPE_RANDOM_TEMPLATE_RELATIVE, // Replace with one of a point_template's templates, randomly selected, maintaining relative position }; // Where the replacement entit(ies) should replace at. @@ -176,8 +178,7 @@ void CPointEntityReplace::HandleReplacement(CBaseEntity *pEntity, CBaseEntity *p { pReplacement->m_nRenderMode = pEntity->m_nRenderMode; pReplacement->m_nRenderFX = pEntity->m_nRenderFX; - const color32 rclr = pEntity->GetRenderColor(); - pReplacement->SetRenderColor(rclr.r, rclr.g, rclr.b, rclr.a); + pReplacement->m_clrRender = pEntity->m_clrRender; if (pEntity->GetBaseAnimating() && pReplacement->GetBaseAnimating()) { CBaseAnimating *pEntityAnimating = pEntity->GetBaseAnimating(); @@ -185,15 +186,6 @@ void CPointEntityReplace::HandleReplacement(CBaseEntity *pEntity, CBaseEntity *p pReplacementAnimating->CopyAnimationDataFrom(pEntityAnimating); - //pReplacementAnimating->SetCycle(pEntityAnimating->GetCycle()); - //pReplacementAnimating->IncrementInterpolationFrame(); - //pReplacementAnimating->SetSequence(pEntityAnimating->GetSequence()); - //pReplacementAnimating->m_flAnimTime = pEntityAnimating->m_flAnimTime; - //pReplacementAnimating->m_nBody = pEntityAnimating->m_nBody; - //pReplacementAnimating->m_nSkin = pEntityAnimating->m_nSkin; - if (pEntityAnimating->GetModelScale() != pReplacementAnimating->GetModelScale()) - pReplacementAnimating->SetModelScale(pEntityAnimating->GetModelScale()); - for ( int iPose = 0; iPose < MAXSTUDIOPOSEPARAM; ++iPose ) { pReplacementAnimating->SetPoseParameter( iPose, pEntityAnimating->GetPoseParameter( iPose ) ); @@ -407,8 +399,6 @@ void CPointEntityReplace::ReplaceEntity(CBaseEntity *pEntity, inputdata_t &input if (m_iReplacementType != REPLACEMENTTYPE_TEMPLATE_RELATIVE) { // We have to do this again. - //pTemplateEntity->SetAbsOrigin( vecOrigin ); - //pTemplateEntity->SetAbsAngles( angAngles ); pTemplateEntity->Teleport( &vecOrigin, &angAngles, &vecVelocity ); } @@ -428,12 +418,45 @@ void CPointEntityReplace::ReplaceEntity(CBaseEntity *pEntity, inputdata_t &input m_OnReplace.Set(pTemplateEntity, pTemplateEntity, pCaller); } } - - // Templates with only one entity probably need to stay in the specified position. - if (hNewEntities.Count() == 1) + } break; + case REPLACEMENTTYPE_RANDOM_TEMPLATE: + case REPLACEMENTTYPE_RANDOM_TEMPLATE_RELATIVE: + { + CPointTemplate *pTemplate = dynamic_cast(GetReplacementEntity(&inputdata)); + if (!pTemplate) { - hNewEntities[0]->SetAbsOrigin( vecOrigin ); - hNewEntities[0]->SetAbsAngles( angAngles ); + Warning("%s unable to retrieve entity %s. It either does not exist or is not a point_template.\n", GetDebugName(), STRING(m_iszReplacementEntity)); + return; + } + + CBaseEntity *pTemplateEntity = NULL; + if ( !pTemplate->CreateSpecificInstance( RandomInt(0, pTemplate->GetNumTemplates() - 1), vecOrigin, angAngles, &pTemplateEntity ) ) + return; + + if (pTemplateEntity) + { + HandleReplacement(pEntity, pTemplateEntity); + + if (m_iReplacementType != REPLACEMENTTYPE_RANDOM_TEMPLATE_RELATIVE) + { + // We have to do this again. + pTemplateEntity->Teleport( &vecOrigin, &angAngles, &vecVelocity ); + } + + if (pTemplateEntity->VPhysicsGetObject()) + { + AngularImpulse angImpulse; + QAngleToAngularImpulse(angAngles, angImpulse); + pTemplateEntity->VPhysicsGetObject()->SetVelocityInstantaneous(&vecVelocity, &angImpulse); + } + else + { + pTemplateEntity->SetAbsVelocity(vecVelocity); + pTemplateEntity->SetBaseVelocity( vec3_origin ); + pTemplateEntity->SetLocalAngularVelocity(angVelocity); + } + + m_OnReplace.Set(pTemplateEntity, pTemplateEntity, pCaller); } } break; } diff --git a/sp/src/game/server/point_camera.cpp b/sp/src/game/server/point_camera.cpp index a4b4d1fa..c900be8f 100644 --- a/sp/src/game/server/point_camera.cpp +++ b/sp/src/game/server/point_camera.cpp @@ -284,9 +284,7 @@ BEGIN_DATADESC( CPointCameraOrtho ) // Input DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetOrthoEnabled", InputSetOrthoEnabled ), -#ifdef MAPBASE DEFINE_INPUTFUNC( FIELD_STRING, "ScaleOrtho", InputScaleOrtho ), -#endif DEFINE_INPUTFUNC( FIELD_STRING, "SetOrthoTop", InputSetOrthoTop ), DEFINE_INPUTFUNC( FIELD_STRING, "SetOrthoBottom", InputSetOrthoBottom ), DEFINE_INPUTFUNC( FIELD_STRING, "SetOrthoLeft", InputSetOrthoLeft ), diff --git a/sp/src/game/server/point_template.cpp b/sp/src/game/server/point_template.cpp index 1599de7b..a1af651b 100644 --- a/sp/src/game/server/point_template.cpp +++ b/sp/src/game/server/point_template.cpp @@ -399,6 +399,81 @@ bool CPointTemplate::CreateInstance( const Vector &vecOrigin, const QAngle &vecA return true; } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: Spawn one of the entities I contain +// Input : &vecOrigin - +// &vecAngles - +// pEntities - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CPointTemplate::CreateSpecificInstance( int iTemplate, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity **pOutEntity ) +{ + // Go through all our templated map data and spawn all the entities in it + int iTemplates = m_hTemplates.Count(); + if ( !iTemplates ) + { + Msg("CreateInstance called on a point_template that has no templates: %s\n", STRING(GetEntityName()) ); + return false; + } + + // Tell the template system we're about to start a new template + Templates_StartUniqueInstance(); + + CBaseEntity *pEntity = NULL; + char *pMapData; + int iTemplateIndex = m_hTemplates[iTemplate].iTemplateIndex; + + // Some templates have Entity I/O connecting the entities within the template. + // Unique versions of these templates need to be created whenever they're instanced. + if ( AllowNameFixup() && Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) ) + { + // This template requires instancing. + // Create a new mapdata block and ask the template system to fill it in with + // a unique version (with fixed Entity I/O connections). + pMapData = Templates_GetEntityIOFixedMapData( iTemplateIndex ); + } + else + { + // Use the unmodified mapdata + pMapData = (char*)STRING( Templates_FindByIndex( iTemplateIndex ) ); + } + + // Create the entity from the mapdata + MapEntity_ParseEntity( pEntity, pMapData, NULL ); + if ( pEntity == NULL ) + { + Msg("Failed to initialize templated entity with mapdata: %s\n", pMapData ); + return false; + } + + // Get a matrix that'll convert from world to the new local space + VMatrix matNewTemplateToWorld, matStoredLocalToWorld; + matNewTemplateToWorld.SetupMatrixOrgAngles( vecOrigin, vecAngles ); + MatrixMultiply( matNewTemplateToWorld, m_hTemplates[iTemplate].matEntityToTemplate, matStoredLocalToWorld ); + + // Get the world origin & angles from the stored local coordinates + Vector vecNewOrigin; + QAngle vecNewAngles; + vecNewOrigin = matStoredLocalToWorld.GetTranslation(); + MatrixToAngles( matStoredLocalToWorld, vecNewAngles ); + + // Set its origin & angles + pEntity->SetAbsOrigin( vecNewOrigin ); + pEntity->SetAbsAngles( vecNewAngles ); + + // Spawn it + DispatchSpawn( pEntity ); + + if (pOutEntity) + { + *pOutEntity = pEntity; + } + + return true; +} +#endif + //----------------------------------------------------------------------------- // Purpose: // Input : &inputdata - @@ -429,55 +504,10 @@ void CPointTemplate::InputForceSpawn( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CPointTemplate::InputForceSpawnRandomTemplate( inputdata_t &inputdata ) { + // Spawn our template CBaseEntity *pEntity = NULL; - char *pMapData; - - // Index for our m_hTemplates - int iIndex = RandomInt(0, GetNumTemplates() - 1); - - // Index for the template itself in the global template list - int iTemplateIndex = m_hTemplates[iIndex].iTemplateIndex; - - // Some templates have Entity I/O connecting the entities within the template. - // Unique versions of these templates need to be created whenever they're instanced. - if ( AllowNameFixup() && Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) ) - { - // This template requires instancing. - // Create a new mapdata block and ask the template system to fill it in with - // a unique version (with fixed Entity I/O connections). - pMapData = Templates_GetEntityIOFixedMapData( iTemplateIndex ); - } - else - { - // Use the unmodified mapdata - pMapData = (char*)STRING( Templates_FindByIndex( iTemplateIndex ) ); - } - - // Create the entity from the mapdata - MapEntity_ParseEntity( pEntity, pMapData, NULL ); - if ( pEntity == NULL ) - { - Msg("Failed to initialize templated entity with mapdata: %s\n", pMapData ); + if ( !CreateSpecificInstance( RandomInt(0, GetNumTemplates() - 1), GetAbsOrigin(), GetAbsAngles(), &pEntity ) ) return; - } - - // Get a matrix that'll convert from world to the new local space - VMatrix matNewTemplateToWorld, matStoredLocalToWorld; - matNewTemplateToWorld.SetupMatrixOrgAngles( GetAbsOrigin(), GetAbsAngles() ); - MatrixMultiply( matNewTemplateToWorld, m_hTemplates[iIndex].matEntityToTemplate, matStoredLocalToWorld ); - - // Get the world origin & angles from the stored local coordinates - Vector vecNewOrigin; - QAngle vecNewAngles; - vecNewOrigin = matStoredLocalToWorld.GetTranslation(); - MatrixToAngles( matStoredLocalToWorld, vecNewAngles ); - - // Set its origin & angles - pEntity->SetAbsOrigin( vecNewOrigin ); - pEntity->SetAbsAngles( vecNewAngles ); - - // Spawn it - DispatchSpawn(pEntity); // Fire our output m_pOutputOnSpawned.FireOutput( this, this ); diff --git a/sp/src/game/server/point_template.h b/sp/src/game/server/point_template.h index 73480ee0..dc60d078 100644 --- a/sp/src/game/server/point_template.h +++ b/sp/src/game/server/point_template.h @@ -49,6 +49,9 @@ public: // Template instancing bool CreateInstance( const Vector &vecOrigin, const QAngle &vecAngles, CUtlVector *pEntities ); +#ifdef MAPBASE + bool CreateSpecificInstance( int iTemplate, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity **pOutEntity ); +#endif // Inputs void InputForceSpawn( inputdata_t &inputdata ); diff --git a/sp/src/game/server/soundent.h b/sp/src/game/server/soundent.h index 670af8b2..b566aeae 100644 --- a/sp/src/game/server/soundent.h +++ b/sp/src/game/server/soundent.h @@ -59,18 +59,16 @@ enum #ifdef MAPBASE // You know, I wouldn't mind this approach of leaving types and contexts on the same int - // since there can be so many CSounds at any given time. - // It's just that there's very little room to expand and a lot of the contexts are very specific and/or useless. + // since it was important in the GoldSrc era with how many CSounds there can be at any given time. + // I'm just frustrated that this system was retained in Source with very specific and/or useless contexts with very little room to expand. // If this doesn't work, replace SOUND_CONTEXT_PLAYER_VEHICLE with owner server vehicle checks. // Only heard by NPCs the owner likes. Needed for shared grenade code. SOUND_CONTEXT_OWNER_ALLIES = 0x40000000, - - ALL_CONTEXTS = 0x3FF00000, -#else - ALL_CONTEXTS = 0xFFF00000, #endif + ALL_CONTEXTS = 0xFFF00000, + ALL_SCENTS = SOUND_CARCASS | SOUND_MEAT | SOUND_GARBAGE, ALL_SOUNDS = 0x000FFFFF & ~ALL_SCENTS, diff --git a/sp/src/game/server/triggers.cpp b/sp/src/game/server/triggers.cpp index 8d0bf729..8dc43370 100644 --- a/sp/src/game/server/triggers.cpp +++ b/sp/src/game/server/triggers.cpp @@ -1044,6 +1044,9 @@ public: float m_flTimeoutDuration; // Number of seconds after start touch to fire anyway bool m_bTimeoutFired; // True if the OnTimeout output fired since the last StartTouch. EHANDLE m_hActivator; // The entity that triggered us. +#ifdef MAPBASE + bool m_bUseLOS; // Makes lookers use LOS calculations in addition to viewcone calculations +#endif void Spawn( void ); void Touch( CBaseEntity *pOther ); @@ -1070,6 +1073,9 @@ BEGIN_DATADESC( CTriggerLook ) DEFINE_KEYFIELD( m_flTimeoutDuration, FIELD_FLOAT, "timeout" ), DEFINE_FIELD( m_bTimeoutFired, FIELD_BOOLEAN ), DEFINE_FIELD( m_hActivator, FIELD_EHANDLE ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bUseLOS, FIELD_BOOLEAN, "UseLOS" ), +#endif DEFINE_OUTPUT( m_OnTimeout, "OnTimeout" ), @@ -1192,7 +1198,11 @@ void CTriggerLook::Touch(CBaseEntity *pOther) VectorNormalize(vTargetDir); float fDotPr = DotProduct(vLookDir,vTargetDir); +#ifdef MAPBASE + if (fDotPr > m_flFieldOfView && (!m_bUseLOS || pOther->FVisible(pOther))) +#else if (fDotPr > m_flFieldOfView) +#endif { // Is it the first time I'm looking? if (m_flLookTimeTotal == -1) @@ -4428,6 +4438,10 @@ int CTriggerImpact::DrawDebugTextOverlays(void) const int SF_TRIGGER_MOVE_AUTODISABLE = 0x80; // disable auto movement const int SF_TRIGGER_AUTO_DUCK = 0x800; // Duck automatically +#ifdef MAPBASE +const int SF_TRIGGER_AUTO_WALK = 0x1000; +const int SF_TRIGGER_DISABLE_JUMP = 0x2000; +#endif class CTriggerPlayerMovement : public CBaseTrigger { @@ -4485,6 +4499,18 @@ void CTriggerPlayerMovement::StartTouch( CBaseEntity *pOther ) pPlayer->ForceButtons( IN_DUCK ); } +#ifdef MAPBASE + if ( HasSpawnFlags( SF_TRIGGER_AUTO_WALK ) ) + { + pPlayer->ForceButtons( IN_WALK ); + } + + if ( HasSpawnFlags( SF_TRIGGER_DISABLE_JUMP ) ) + { + pPlayer->DisableButtons( IN_JUMP ); + } +#endif + // UNDONE: Currently this is the only operation this trigger can do if ( HasSpawnFlags(SF_TRIGGER_MOVE_AUTODISABLE) ) { @@ -4507,6 +4533,18 @@ void CTriggerPlayerMovement::EndTouch( CBaseEntity *pOther ) pPlayer->UnforceButtons( IN_DUCK ); } +#ifdef MAPBASE + if ( HasSpawnFlags( SF_TRIGGER_AUTO_WALK ) ) + { + pPlayer->UnforceButtons( IN_WALK ); + } + + if ( HasSpawnFlags( SF_TRIGGER_DISABLE_JUMP ) ) + { + pPlayer->EnableButtons( IN_JUMP ); + } +#endif + if ( HasSpawnFlags(SF_TRIGGER_MOVE_AUTODISABLE) ) { pPlayer->m_Local.m_bAllowAutoMovement = true; diff --git a/sp/src/game/shared/basecombatweapon_shared.cpp b/sp/src/game/shared/basecombatweapon_shared.cpp index 215c95ca..083e744f 100644 --- a/sp/src/game/shared/basecombatweapon_shared.cpp +++ b/sp/src/game/shared/basecombatweapon_shared.cpp @@ -141,9 +141,6 @@ void CBaseCombatWeapon::GiveDefaultAmmo( void ) // If I use clips, set my clips to the default if ( UsesClipsForAmmo1() ) { -#ifdef MAPBASE - if (!HasSpawnFlags(SF_WEAPON_PRESERVE_AMMO)) -#endif m_iClip1 = AutoFiresFullClip() ? 0 : GetDefaultClip1(); } else @@ -153,9 +150,6 @@ void CBaseCombatWeapon::GiveDefaultAmmo( void ) } if ( UsesClipsForAmmo2() ) { -#ifdef MAPBASE - if (!HasSpawnFlags(SF_WEAPON_PRESERVE_AMMO)) -#endif m_iClip2 = GetDefaultClip2(); } else @@ -184,6 +178,10 @@ void CBaseCombatWeapon::Spawn( void ) // Assume m_nViewModelIndex = 0; +#ifdef MAPBASE + // Don't reset to default ammo if we're supposed to use the keyvalue + if (!HasSpawnFlags( SF_WEAPON_PRESERVE_AMMO )) +#endif GiveDefaultAmmo(); if ( GetWorldModel() ) @@ -1735,7 +1733,7 @@ void CBaseCombatWeapon::InputBreakConstraint( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CBaseCombatWeapon::InputForceFire( inputdata_t &inputdata, bool bSecondary ) { - CBaseCombatCharacter *pOperator = ToBaseCombatCharacter(GetOwnerEntity()); + CBaseCombatCharacter *pOperator = GetOwner(); if (!pOperator) { diff --git a/sp/src/game/shared/env_wind_shared.cpp b/sp/src/game/shared/env_wind_shared.cpp index e090e8ec..a9267f90 100644 --- a/sp/src/game/shared/env_wind_shared.cpp +++ b/sp/src/game/shared/env_wind_shared.cpp @@ -320,7 +320,6 @@ void ResetWindspeed() // NEW WITH MAPBASE: Inner-radius! // You can now choose an inner-radius for your wind, which allows for varying intensities at different distances. // This can mix in with a global wind controller or even other wind controllers. -// (note: wind is additive and does not blend into itself, maybe fix that sometime) //----------------------------------------------------------------------------- Vector GetWindspeedAtLocation( const Vector &location ) { diff --git a/sp/src/game/shared/hl2/hl2_gamerules.cpp b/sp/src/game/shared/hl2/hl2_gamerules.cpp index 67cd191d..50445f20 100644 --- a/sp/src/game/shared/hl2/hl2_gamerules.cpp +++ b/sp/src/game/shared/hl2/hl2_gamerules.cpp @@ -44,7 +44,7 @@ extern bool g_bCacheLegacyFlashlightStatus; BEGIN_DATADESC( CHalfLife2Proxy ) - // These get the gamerules values on save and writes to them on restore + // These get the gamerules values on save and write to them on restore DEFINE_FIELD( m_save_DefaultCitizenType, FIELD_INTEGER ), DEFINE_FIELD( m_save_LegacyFlashlight, FIELD_CHARACTER ), DEFINE_FIELD( m_save_PlayerSquadAutosummonDisabled, FIELD_BOOLEAN ), @@ -316,6 +316,10 @@ ConVar sk_plr_dmg_buckshot ( "sk_plr_dmg_buckshot","0", FCVAR_REPLICATED); ConVar sk_npc_dmg_buckshot ( "sk_npc_dmg_buckshot","0", FCVAR_REPLICATED); ConVar sk_max_buckshot ( "sk_max_buckshot","0", FCVAR_REPLICATED); ConVar sk_plr_num_shotgun_pellets( "sk_plr_num_shotgun_pellets","7", FCVAR_REPLICATED); +#ifdef MAPBASE +ConVar sk_plr_num_shotgun_pellets_double( "sk_plr_num_shotgun_pellets_double","12", FCVAR_REPLICATED); +ConVar sk_npc_num_shotgun_pellets( "sk_npc_num_shotgun_pellets","8", FCVAR_REPLICATED); +#endif ConVar sk_plr_dmg_rpg_round ( "sk_plr_dmg_rpg_round","0", FCVAR_REPLICATED); ConVar sk_npc_dmg_rpg_round ( "sk_npc_dmg_rpg_round","0", FCVAR_REPLICATED); diff --git a/sp/src/game/shared/hl2/hl2_gamerules.h b/sp/src/game/shared/hl2/hl2_gamerules.h index 5951eb43..1c9975b9 100644 --- a/sp/src/game/shared/hl2/hl2_gamerules.h +++ b/sp/src/game/shared/hl2/hl2_gamerules.h @@ -47,7 +47,9 @@ public: void InputSetPlayerSquadAutosummon( inputdata_t &inputdata ); void InputSetStunstickPickupBehavior( inputdata_t &inputdata ); - // These are written to from HL2GameRules on save and given to HL2GameRules on restore + // Gamerules classes don't seem to support datadescs, so the hl2_gamerules entity takes the current values + // from the actual gamerules and saves them in the entity itself, where they're saved via the entity's own datadesc. + // When the save is loaded, the entity sets the main gamerules values according to what was saved. int m_save_DefaultCitizenType; char m_save_LegacyFlashlight; bool m_save_PlayerSquadAutosummonDisabled; diff --git a/sp/src/game/shared/mapbase/mapbase_rpc.cpp b/sp/src/game/shared/mapbase/mapbase_rpc.cpp index b693848f..038b67c2 100644 --- a/sp/src/game/shared/mapbase/mapbase_rpc.cpp +++ b/sp/src/game/shared/mapbase/mapbase_rpc.cpp @@ -465,12 +465,13 @@ void MapbaseRPC_GetDiscordParameters( DiscordRichPresence &discordPresence, int } else { + Q_strncpy( state, g_iszGameName, sizeof(state) ); + switch (iType) { case RPCSTATE_INIT: case RPCSTATE_LEVEL_SHUTDOWN: { - Q_strncpy( state, g_iszGameName, sizeof(state) ); Q_strncpy( details, "Main Menu", sizeof(details) ); } break; case RPCSTATE_LEVEL_INIT: diff --git a/sp/src/materialsystem/stdshaders/MonitorScreen_dx9.cpp b/sp/src/materialsystem/stdshaders/MonitorScreen_dx9.cpp new file mode 100644 index 00000000..ae952b9e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/MonitorScreen_dx9.cpp @@ -0,0 +1,182 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "BaseVSShader.h" +#include "sdk_unlittwotexture_vs20.inc" +#include "sdk_monitorscreen_ps20.inc" +#include "sdk_monitorscreen_ps20b.inc" +#include "cpp_shader_constant_register_map.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( SDK_MonitorScreen, SDK_MonitorScreen_DX9 ) + +BEGIN_VS_SHADER( SDK_MonitorScreen_DX9, + "This is a shader that does a contrast/saturation version of base times lightmap." ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( CONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( SATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( TINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "monitor tint" ) + SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/lightmappedtexture", "second texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $texture2" ) + SHADER_PARAM( TEXTURE2TRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$texture2 texcoord transform" ) + END_SHADER_PARAMS + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + if( !params[CONTRAST]->IsDefined() ) + { + params[CONTRAST]->SetFloatValue( 0.0f ); + } + if( !params[SATURATION]->IsDefined() ) + { + params[SATURATION]->SetFloatValue( 1.0f ); + } + if( !params[TINT]->IsDefined() ) + { + params[TINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + if (!IS_FLAG_DEFINED( MATERIAL_VAR_MODEL )) + { + CLEAR_FLAGS( MATERIAL_VAR_MODEL ); + } + } + + SHADER_FALLBACK + { + if( params && !params[BASETEXTURE]->IsDefined() ) + return "SDK_LightmappedGeneric"; + + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } + if (params[TEXTURE2]->IsDefined()) + { + LoadTexture( TEXTURE2 ); + } + } + + SHADER_DRAW + { + bool bHasTexture2 = params[TEXTURE2]->IsTexture(); + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + if ( bHasTexture2 ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a texture alpha on either texture + isTranslucent = isTranslucent || TextureIsTranslucent( BASETEXTURE, true ) || + TextureIsTranslucent( TEXTURE2, true ); + + if ( isTranslucent ) + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + else + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + else + DisableAlphaBlending( ); + } + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_unlittwotexture_vs20 ); + SET_STATIC_VERTEX_SHADER( sdk_unlittwotexture_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sdk_monitorscreen_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE2, (bHasTexture2)?(1):(0) ); + SET_STATIC_PIXEL_SHADER( sdk_monitorscreen_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sdk_monitorscreen_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE2, (bHasTexture2)?(1):(0) ); + SET_STATIC_PIXEL_SHADER( sdk_monitorscreen_ps20 ); + } + + DefaultFog(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + if( bHasTexture2 ) + { + BindTexture( SHADER_SAMPLER1, TEXTURE2, FRAME2 ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, TEXTURE2TRANSFORM ); + } + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetPixelShaderConstant( 1, CONTRAST ); + SetPixelShaderConstant( 2, SATURATION ); + SetPixelShaderConstant( 3, TINT ); + SetModulationVertexShaderDynamicState(); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_unlittwotexture_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_unlittwotexture_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_monitorscreen_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_monitorscreen_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_monitorscreen_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_monitorscreen_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/SDK_eye_refract_ps2x.fxc b/sp/src/materialsystem/stdshaders/SDK_eye_refract_ps2x.fxc index a3507f1e..057e8306 100644 --- a/sp/src/materialsystem/stdshaders/SDK_eye_refract_ps2x.fxc +++ b/sp/src/materialsystem/stdshaders/SDK_eye_refract_ps2x.fxc @@ -107,10 +107,10 @@ float IntersectRaySphere ( float3 cameraPos, float3 ray, float3 sphereCenter, fl } // Calculate both types of Fog and lerp to get result -float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float3 vEyePos, const float3 vWorldPos, const float flProjPosZ ) { - float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); - float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + float fRangeFog = CalcRangeFogFactorNonFixedFunction( vWorldPos, vEyePos, fogParams.z, fogParams.x, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, vEyePos.z, vWorldPos.z, flProjPosZ, fogParams.w ); return lerp( fRangeFog, fHeightFog, fPixelFogType ); } @@ -484,7 +484,7 @@ float4 main( PS_INPUT i ) : COLOR result.a = 1.0; #if !defined( SHADER_MODEL_PS_2_0 ) - float fogFactor = CalcPixelFogFactor( g_fPixelFogType, g_FogParams, g_vCameraPosition.xyz, i.vWorldPosition_ProjPosZ.xyz, i.vWorldPosition_ProjPosZ.w ); + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_vCameraPosition.xyz, i.vWorldPosition_ProjPosZ.xyz, i.vWorldPosition_ProjPosZ.w ); return FinalOutputConst( result, fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR ); #else float fogFactor = CalcPixelFogFactor( PIXEL_FOG_TYPE_NONE, g_FogParams, g_vCameraPosition.xyz, i.vWorldPosition_ProjPosZ.xyz, i.vWorldPosition_ProjPosZ.w ); diff --git a/sp/src/materialsystem/stdshaders/SDK_monitorscreen_ps2x.fxc b/sp/src/materialsystem/stdshaders/SDK_monitorscreen_ps2x.fxc new file mode 100644 index 00000000..204ceac1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/SDK_monitorscreen_ps2x.fxc @@ -0,0 +1,55 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// +//paired with unlittwotexture_vs20 + +// STATIC: "TEXTURE2" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "shader_constant_register_map.h" +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler SecondaryTextureSampler : register( s1 ); + + +const float4 g_Contrast : register( c1 ); +const float4 g_Saturation : register( c2 ); +const float4 g_Tint : register( c3 ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +#define g_Grey float4( 0.33333f, 0.33333f, 0.33333f, 0.33333f ) + +struct PS_INPUT +{ + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 vColor : COLOR0; + + float4 worldPos_projPosZ : TEXCOORD7; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 resultColor = tex2D( BaseTextureSampler, i.vTexCoord0 ) * i.vColor; // base texture modulated with vertex color + +#if (TEXTURE2 == 1) + resultColor = tex2D( SecondaryTextureSampler, i.vTexCoord1 ) * resultColor; // modulate base color by another texture +#endif + + float3 tempColor = resultColor.rgb * resultColor.rgb; //base * base + resultColor.rgb = lerp( resultColor.rgb, tempColor.rgb, g_Contrast.rgb ); // blend between color and color * color + tempColor = dot( resultColor.rgb, g_Grey ); // color greyscaled + resultColor.rgb = lerp( tempColor.rgb, resultColor.rgb, g_Saturation.rgb ); // blend between color and greyscale + resultColor.rgb = resultColor.rgb * g_Tint.rgb; // tint + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/sp/src/materialsystem/stdshaders/SDK_unlittwotexture_ps2x.fxc b/sp/src/materialsystem/stdshaders/SDK_unlittwotexture_ps2x.fxc new file mode 100644 index 00000000..4df0de86 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/SDK_unlittwotexture_ps2x.fxc @@ -0,0 +1,59 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// STATIC: "TRANSLUCENT" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +#if defined( SHADER_MODEL_PS_2_0 ) + #define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +const HALF4 g_DiffuseModulation : register( c1 ); +#if !FLASHLIGHT + // we don't use these with HDR. + const HALF3 g_EnvmapContrast : register( c2 ); + const HALF3 g_EnvmapSaturation : register( c3 ); +#endif + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const HALF3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + +sampler BaseTextureSampler : register( s0 ); +sampler BaseTextureSampler2 : register( s1 ); + +struct PS_INPUT +{ + float4 projPos : POSITION; // Projection-space position + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + HALF2 baseTexCoord2 : TEXCOORD1; // Base texture coordinate + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha + +#if defined( _X360 ) //matching pixel shader inputs to vertex shader outputs to avoid shader patches + float4 vColor : COLOR0; +#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + float4 baseColor2 = tex2D( BaseTextureSampler2, i.baseTexCoord2.xy ); + float4 result = baseColor * baseColor2 * g_DiffuseModulation; + + // This material can only get a non-opaque alpha if the material is marked as translucent +# if ( TRANSLUCENT == 0 ) + result.a = 1.0f; +# endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} + diff --git a/sp/src/materialsystem/stdshaders/SDK_unlittwotexture_vs20.fxc b/sp/src/materialsystem/stdshaders/SDK_unlittwotexture_vs20.fxc new file mode 100644 index 00000000..9c9976ac --- /dev/null +++ b/sp/src/materialsystem/stdshaders/SDK_unlittwotexture_vs20.fxc @@ -0,0 +1,66 @@ +//========== Copyright (c) Valve Corporation, All rights reserved. ==========// + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); // 0 & 1 +const float4 cBaseTexCoordTransform2[2] : register( SHADER_SPECIFIC_CONST_2 ); // 2 & 3 + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 ) + float fog : FOG; +#endif + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + HALF2 baseTexCoord2 : TEXCOORD1; // Base texture coordinate + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha + + float4 vColor : COLOR0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + + // Perform skinning + float3 worldNormal, worldPos; + SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, worldPos ); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + +#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 ) + o.fog = CalcFixedFunctionFog( worldPos, g_FogType ); +#endif + + // Needed for water fog alpha; + o.worldPos_projPosZ = float4( worldPos.xyz, o.projPos.z ); // FIXME: we shouldn't have to compute this all thie time. + + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); // Base texture coordinates + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + o.baseTexCoord2.x = dot( v.vTexCoord0, cBaseTexCoordTransform2[0] ); // Secondary texture coordinates + o.baseTexCoord2.y = dot( v.vTexCoord0, cBaseTexCoordTransform2[1] ); + + o.vColor = cModulationColor; + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps2x.fxc b/sp/src/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps2x.fxc index c0e58fba..c4ba4bdc 100644 --- a/sp/src/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps2x.fxc +++ b/sp/src/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_bump_ps2x.fxc @@ -131,10 +131,10 @@ struct PS_INPUT }; // Calculate both types of Fog and lerp to get result -float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float3 vEyePos, const float3 vWorldPos, const float flProjPosZ ) { - float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); - float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + float fRangeFog = CalcRangeFogFactorNonFixedFunction( vWorldPos, vEyePos, fogParams.z, fogParams.x, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, vEyePos.z, vWorldPos.z, flProjPosZ, fogParams.w ); return lerp( fRangeFog, fHeightFog, fPixelFogType ); } @@ -329,7 +329,7 @@ float4 main( PS_INPUT i ) : COLOR #if defined(SHADER_MODEL_PS_2_0) float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); #else - float fogFactor = CalcPixelFogFactor( g_fPixelFogType, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w ); #endif #if defined( SHADER_MODEL_PS_2_0 ) @@ -343,7 +343,7 @@ float4 main( PS_INPUT i ) : COLOR #if defined( SHADER_MODEL_PS_2_0 ) return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.worldPos_projPosZ.w ); #else - return FinalOutput( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w ); + return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w ); #endif } diff --git a/sp/src/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps2x.fxc b/sp/src/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps2x.fxc index f67bc1ca..9ed758b6 100644 --- a/sp/src/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps2x.fxc +++ b/sp/src/materialsystem/stdshaders/SDK_vertexlit_and_unlit_generic_ps2x.fxc @@ -169,13 +169,17 @@ const float3 g_DetailTint : register( c10 ); // Calculate unified fog -float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float3 vEyePos, const float3 vWorldPos, const float flProjPosZ ) { - float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive + /*float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive float flDepthBelowEye = fPixelFogType*flEyePosZ - flWorldPosZ; // above eye = negative, below eye = positive // if fPixelFogType == 0, then flDepthBelowWater == flDepthBelowEye and frac will be 1 float frac = (flDepthBelowEye == 0) ? 1 : saturate(flDepthBelowWater/flDepthBelowEye); - return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) ); + return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) );*/ + + float fRangeFog = CalcRangeFogFactorNonFixedFunction( vWorldPos, vEyePos, fogParams.z, fogParams.x, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, vEyePos.z, vWorldPos.z, flProjPosZ, fogParams.w ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); } // Blend both types of Fog and lerp to get result @@ -474,7 +478,7 @@ float4 main( PS_INPUT i ) : COLOR #endif return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.projPos.z ); #else // 2b or higher - float fogFactor = CalcPixelFogFactor( g_fPixelFogType, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.projPos.z ); + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.projPos.z ); alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z ); #endif diff --git a/sp/src/materialsystem/stdshaders/decalmodulate_dx9.cpp b/sp/src/materialsystem/stdshaders/decalmodulate_dx9.cpp index 4f5eae9a..9a930194 100644 --- a/sp/src/materialsystem/stdshaders/decalmodulate_dx9.cpp +++ b/sp/src/materialsystem/stdshaders/decalmodulate_dx9.cpp @@ -22,7 +22,7 @@ #include "tier0/memdbgon.h" #ifdef MAPBASE -ConVar mat_decalmodulate_noflashdraw( "mat_decalmodulate_noflashdraw", "0" ); +ConVar mat_decalmodulate_flashdraw( "mat_decalmodulate_flashdraw", "0" ); #endif DEFINE_FALLBACK_SHADER( SDK_DecalModulate, SDK_DecalModulate_DX9 ) @@ -76,6 +76,8 @@ BEGIN_VS_SHADER( SDK_DecalModulate_dx9, // The flashlight part is transparent and overlaid on top of the decal. // When a fix is found, this flashlight code could be removed. bool bHasFlashlight = UsingFlashlight( params ); + if (bHasFlashlight && !mat_decalmodulate_flashdraw.GetBool()) + return; #endif SHADOW_STATE { diff --git a/sp/src/materialsystem/stdshaders/eye_refract_helper.cpp b/sp/src/materialsystem/stdshaders/eye_refract_helper.cpp index 605155e7..6bf7525a 100644 --- a/sp/src/materialsystem/stdshaders/eye_refract_helper.cpp +++ b/sp/src/materialsystem/stdshaders/eye_refract_helper.cpp @@ -437,7 +437,7 @@ void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, { params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); } - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, timeVec, 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, timeVec, 1 ); } } pShader->Draw(); diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20.inc new file mode 100644 index 00000000..12b6a1b6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps20_Static_Index +{ +private: + int m_nTEXTURE2; +#ifdef _DEBUG + bool m_bTEXTURE2; +#endif +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } + void SetTEXTURE2( bool i ) + { + m_nTEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } +public: + sdk_monitorscreen_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + m_nTEXTURE2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEXTURE2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nTEXTURE2 ) + 0; + } +}; +#define shaderStaticTest_sdk_monitorscreen_ps20 psh_forgot_to_set_static_TEXTURE2 + 0 +class sdk_monitorscreen_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_monitorscreen_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_monitorscreen_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20b.inc new file mode 100644 index 00000000..39daea2f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps20b_Static_Index +{ +private: + int m_nTEXTURE2; +#ifdef _DEBUG + bool m_bTEXTURE2; +#endif +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } + void SetTEXTURE2( bool i ) + { + m_nTEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } +public: + sdk_monitorscreen_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + m_nTEXTURE2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEXTURE2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTEXTURE2 ) + 0; + } +}; +#define shaderStaticTest_sdk_monitorscreen_ps20b psh_forgot_to_set_static_TEXTURE2 + 0 +class sdk_monitorscreen_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_monitorscreen_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_monitorscreen_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20.inc new file mode 100644 index 00000000..47ecb668 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps20_Static_Index +{ +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_unlittwotexture_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_ps20 psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_unlittwotexture_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_unlittwotexture_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20b.inc new file mode 100644 index 00000000..52b755c8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps20b_Static_Index +{ +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_unlittwotexture_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_ps20b psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_unlittwotexture_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_unlittwotexture_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_vs20.inc new file mode 100644 index 00000000..a9757e65 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_vs20.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_vs20_Static_Index +{ +public: + sdk_unlittwotexture_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_vs20 0 +class sdk_unlittwotexture_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlittwotexture_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20.inc new file mode 100644 index 00000000..12b6a1b6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps20_Static_Index +{ +private: + int m_nTEXTURE2; +#ifdef _DEBUG + bool m_bTEXTURE2; +#endif +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } + void SetTEXTURE2( bool i ) + { + m_nTEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } +public: + sdk_monitorscreen_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + m_nTEXTURE2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEXTURE2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nTEXTURE2 ) + 0; + } +}; +#define shaderStaticTest_sdk_monitorscreen_ps20 psh_forgot_to_set_static_TEXTURE2 + 0 +class sdk_monitorscreen_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_monitorscreen_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_monitorscreen_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20b.inc new file mode 100644 index 00000000..39daea2f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps20b_Static_Index +{ +private: + int m_nTEXTURE2; +#ifdef _DEBUG + bool m_bTEXTURE2; +#endif +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } + void SetTEXTURE2( bool i ) + { + m_nTEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } +public: + sdk_monitorscreen_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + m_nTEXTURE2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEXTURE2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTEXTURE2 ) + 0; + } +}; +#define shaderStaticTest_sdk_monitorscreen_ps20b psh_forgot_to_set_static_TEXTURE2 + 0 +class sdk_monitorscreen_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_monitorscreen_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_monitorscreen_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20.inc new file mode 100644 index 00000000..47ecb668 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps20_Static_Index +{ +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_unlittwotexture_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_ps20 psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_unlittwotexture_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_unlittwotexture_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20b.inc new file mode 100644 index 00000000..52b755c8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps20b_Static_Index +{ +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_unlittwotexture_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_ps20b psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_unlittwotexture_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_unlittwotexture_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_vs20.inc new file mode 100644 index 00000000..a9757e65 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_vs20.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_vs20_Static_Index +{ +public: + sdk_unlittwotexture_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_vs20 0 +class sdk_unlittwotexture_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlittwotexture_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc b/sp/src/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc index 37ccb254..d0ab9d1c 100644 --- a/sp/src/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc +++ b/sp/src/materialsystem/stdshaders/game_shader_dx9_mapbase.vpc @@ -47,6 +47,9 @@ $Project $File "sprite_dx9.cpp" $File "decalmodulate_dx9.cpp" + + $File "unlittwotexture_dx9.cpp" + $File "MonitorScreen_dx9.cpp" } //$Shaders "mapbase_dx9_20b.txt" diff --git a/sp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt b/sp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt index 6647a4ad..eb02e3a7 100644 --- a/sp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt +++ b/sp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt @@ -86,4 +86,8 @@ SDK_sprite_ps2x.fxc SDK_sprite_vs20.fxc SDK_decalmodulate_ps2x.fxc -SDK_decalmodulate_vs20.fxc \ No newline at end of file +SDK_decalmodulate_vs20.fxc + +SDK_unlittwotexture_ps2x.fxc +SDK_unlittwotexture_vs20.fxc +SDK_monitorscreen_ps2x.fxc \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/unlittwotexture_dx9.cpp b/sp/src/materialsystem/stdshaders/unlittwotexture_dx9.cpp new file mode 100644 index 00000000..86a5ad6f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlittwotexture_dx9.cpp @@ -0,0 +1,265 @@ +//===== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "cloak_blended_pass_helper.h" +#include "cpp_shader_constant_register_map.h" + +#include "sdk_unlittwotexture_vs20.inc" +#include "sdk_unlittwotexture_ps20.inc" +#include "sdk_unlittwotexture_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( SDK_UnlitTwoTexture, SDK_UnlitTwoTexture_DX9 ) +BEGIN_VS_SHADER( SDK_UnlitTwoTexture_DX9, "Help for SDK_UnlitTwoTexture_DX9" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "second texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $texture2" ) + SHADER_PARAM( TEXTURE2TRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$texture2 texcoord transform" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + return 0; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + LoadTexture( BASETEXTURE ); + if (params[TEXTURE2]->IsDefined()) + LoadTexture( TEXTURE2 ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardPass = false; + } + } + + // Skip flashlight pass for unlit stuff + bool bNewFlashlightPath = IsX360(); + if ( bDrawStandardPass && ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && + !bNewFlashlightPath && ( pShaderAPI->InFlashlightMode() ) ) // not snapshotting && flashlight pass) + { + bDrawStandardPass = false; + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + + s_pShaderShadow->EnableSRGBWrite( true ); + + // Either we've got a constant modulation or we've got a texture alpha on either texture + if ( IsAlphaModulating() || IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) || TextureIsTranslucent( BASETEXTURE, true ) || TextureIsTranslucent( TEXTURE2, true ) ) + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + } + else + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + DisableAlphaBlending( ); + } + } + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + if (IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR )) + { + flags |= VERTEX_COLOR; + } + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // If this is set, blend with the alpha channels of the textures and modulation color + bool bTranslucent = IsAlphaModulating() || IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) || TextureIsTranslucent( BASETEXTURE, true ) || TextureIsTranslucent( TEXTURE2, true ); + + DECLARE_STATIC_VERTEX_SHADER( sdk_unlittwotexture_vs20 ); + SET_STATIC_VERTEX_SHADER( sdk_unlittwotexture_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sdk_unlittwotexture_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( TRANSLUCENT, bTranslucent ); + SET_STATIC_PIXEL_SHADER( sdk_unlittwotexture_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sdk_unlittwotexture_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( TRANSLUCENT, bTranslucent ); + SET_STATIC_PIXEL_SHADER( sdk_unlittwotexture_ps20 ); + } + + DefaultFog(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, TEXTURE2, FRAME2 ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, TEXTURE2TRANSFORM ); + SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + int numBones = pShaderAPI->GetCurrentNumBones(); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_unlittwotexture_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( sdk_unlittwotexture_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_unlittwotexture_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_unlittwotexture_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_unlittwotexture_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sdk_unlittwotexture_ps20 ); + } + } + Draw(); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/vortwarp_vs20_helper.h b/sp/src/materialsystem/stdshaders/vortwarp_vs20_helper.h new file mode 100644 index 00000000..20631692 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vortwarp_vs20_helper.h @@ -0,0 +1,41 @@ +#include "common_vs_fxc.h" + +float Sine( float min, float max, float t ) +{ + return ( sin( t ) * 0.5f + 0.5f ) * ( max - min ) + min; +} + +float3 QuadraticBezier( float3 A, float3 B, float3 C, float t ) +{ + return lerp( lerp( A, B, t ), lerp( B, C, t ), t ); +} + +float3 CubicBezier( float3 A, float3 B, float3 C, float3 D, float t ) +{ + return QuadraticBezier( lerp( A, B, t ), lerp( B, C, t ), lerp( C, D, t ), t ); +} + +void WorldSpaceVertexProcess( in float time, in float3 modelOrigin, inout float3 worldPos, inout float3 worldNormal, inout float3 worldTangentS, inout float3 worldTangentT ) +{ + float myTime = time; + myTime = saturate( 1.0f - myTime ); + myTime *= myTime; + myTime *= myTime; + myTime *= myTime; +// worldPos.z += 72.0f * myTime; + + // end + float3 A = float3( 0.0f, 0.0f, 1.0f ); + float3 B = float3( 1.0f, 1.0f, 1.0f ); + float3 C = float3( 0.0f, 0.0f, 1.0f ); + float3 D = float3( 0.0f, 0.0f, 1.0f ); + // start + +// float3 modelOrigin = float3( 70.0f, -14.0f, 0.0f ); + + float t = worldPos.z * ( 1.0f / ( 72.0f ) ); // about 72 inches tall + t = saturate( t ); + float3 worldPosDelta = ( worldPos - modelOrigin ) * CubicBezier( A, B, C, D, t ); + worldPosDelta.z += Sine( 0.0f, 10.0, worldPos.z ); + worldPos = lerp( worldPos, worldPosDelta + modelOrigin, myTime ); +}