Merge pull request #354 from mapbase-source/develop

Mapbase v7.3
This commit is contained in:
Blixibon 2025-01-17 13:43:07 -06:00 committed by GitHub
commit ab6dbb860d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
79 changed files with 4136 additions and 461 deletions

View File

@ -54,7 +54,7 @@ jobs:
- uses: actions/checkout@v4
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.1
uses: compnerd/gha-setup-vsdevenv@v6
- name: Enable VS2022
working-directory: '${{inputs.branch}}/src/vpc_scripts'
@ -77,107 +77,40 @@ jobs:
# --------------------------------------------------------------------
# "I'm invoking msbuild for each project individually, which looks a bit odd considering there is a solution file which should be able to invoke the builds in their proper order automatically, but passing the solution to msbuild doesn't seem to work."
# https://github.com/mapbase-source/source-sdk-2013/pull/162
- name: Build mathlib
- name: Build
#if: steps.filter.outputs.game == 'true'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} mathlib\mathlib.vcxproj
- name: Build Base Libraries
if: inputs.project-group == 'all' || inputs.project-group == 'game' || inputs.project-group == 'maptools'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} raytrace\raytrace.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} tier1\tier1.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} vgui2\vgui_controls\vgui_controls.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} vscript\vscript.vcxproj
- name: Build Map Tools
if: inputs.project-group == 'all' || inputs.project-group == 'maptools'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} fgdlib\fgdlib.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vbsp\vbsp.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vvis\vvis_dll.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vvis_launcher\vvis_launcher.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vrad\vrad_dll.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} utils\vrad_launcher\vrad_launcher.vcxproj
- name: Build Shaders
if: inputs.project-group == 'shaders'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} materialsystem\stdshaders\game_shader_dx9_${{inputs.game}}.vcxproj
- name: Build Game
if: inputs.project-group == 'game'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} responserules\runtime\responserules.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\client\client_${{inputs.game}}.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\server\server_${{inputs.game}}.vcxproj
# TODO: Hook to game naming?
- name: Build everything
if: inputs.project-group == 'all'
working-directory: '${{inputs.branch}}/src'
shell: cmd
run: |
msbuild -m -p:Configuration=${{inputs.configuration}} responserules\runtime\responserules.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} materialsystem\stdshaders\game_shader_dx9_episodic.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} materialsystem\stdshaders\game_shader_dx9_hl2.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\client\client_episodic.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\client\client_hl2.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\server\server_episodic.vcxproj
msbuild -m -p:Configuration=${{inputs.configuration}} game\server\server_hl2.vcxproj
devenv ${{inputs.solution-name}}.sln /upgrade
msbuild -m -t:Rebuild -p:Configuration=${{inputs.configuration}};Platform=x86 ${{inputs.solution-name}}.sln
# --------------------------------------------------------------------
- name: Publish Windows game DLLs
if: inputs.project-group == 'game'
uses: actions/upload-artifact@v3
- name: Publish game binaries
if: inputs.project-group == 'game' || inputs.project-group == 'shaders'
uses: actions/upload-artifact@v4
with:
name: 'Windows Game DLLs (server & client.dll) [${{ inputs.configuration }}]'
name: '${{inputs.project-group}}_${{inputs.game}}_win32_${{ inputs.configuration }}'
path: |
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/client.dll
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/server.dll
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/*.dll
if-no-files-found: error
- name: Publish Windows shader DLL
if: inputs.project-group == 'shaders'
uses: actions/upload-artifact@v3
with:
name: 'Windows Shader DLL (game_shader_dx9.dll) [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/game_shader_dx9.dll
if-no-files-found: error
- name: Publish Windows map tools
- name: Publish map tools
if: inputs.project-group == 'maptools'
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: 'Windows Map Tools [${{ inputs.configuration }}]'
name: '${{inputs.project-group}}_win32_${{ inputs.configuration }}'
path: |
${{inputs.branch}}/game/bin/vbsp.exe
${{inputs.branch}}/game/bin/vvis.exe
${{inputs.branch}}/game/bin/vvis_dll.dll
${{inputs.branch}}/game/bin/vrad.exe
${{inputs.branch}}/game/bin/vrad_dll.dll
${{inputs.branch}}/game/bin/*.exe
${{inputs.branch}}/game/bin/*.dll
if-no-files-found: error
- name: Publish everything (Windows)
- name: Publish everything
if: inputs.project-group == 'all'
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: 'Everything (Windows) [${{ inputs.configuration }}]'
name: 'everything_win32_${{ inputs.configuration }}'
path: |
${{inputs.branch}}/game/bin
${{inputs.branch}}/game/mod_*/bin
@ -224,30 +157,21 @@ jobs:
# --------------------------------------------------------------------
- name: Publish Linux game SOs
if: inputs.project-group == 'game'
uses: actions/upload-artifact@v3
- name: Publish game binaries
if: inputs.project-group == 'game' || inputs.project-group == 'shaders'
uses: actions/upload-artifact@v4
with:
name: 'Linux Game SOs (server & client.so) [${{ inputs.configuration }}]'
name: '${{inputs.project-group}}_${{inputs.game}}_linux32_${{ inputs.configuration }}'
path: |
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/client.so
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/server.so
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/*.so
!${{inputs.branch}}/game/mod_${{inputs.game}}/bin/*_srv.so
if-no-files-found: error
- name: Publish Linux shader SO
if: inputs.project-group == 'shaders'
uses: actions/upload-artifact@v3
with:
name: 'Linux Shader SO (game_shader_dx9.so) [${{ inputs.configuration }}]'
path: |
${{inputs.branch}}/game/mod_${{inputs.game}}/bin/game_shader_dx9.so
if-no-files-found: error
#- name: Publish Linux map tools
#- name: Publish map tools
# if: inputs.project-group == 'maptools'
# uses: actions/upload-artifact@v3
# uses: actions/upload-artifact@v4
# with:
# name: 'Linux Map Tools [${{ inputs.configuration }}]'
# name: '${{inputs.project-group}}_linux32_${{ inputs.configuration }}'
# path: |
# ${{inputs.branch}}/game/bin/vbsp
# ${{inputs.branch}}/game/bin/vvis
@ -258,11 +182,11 @@ jobs:
# For now, don't publish the .dbg files even though we publish .pdb files on Windows
# (they're too big)
- name: Publish everything (Linux)
- name: Publish everything
if: inputs.project-group == 'all'
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: 'Everything (Linux) [${{ inputs.configuration }}]'
name: 'everything_linux32_${{ inputs.configuration }}'
path: |
${{inputs.branch}}/game/bin/*.so
!${{inputs.branch}}/game/bin/*_srv.so

17
README
View File

@ -1,6 +1,6 @@
//=========================================================================================================================
Mapbase v7.2 - Source 2013
Mapbase v7.3 - Source 2013
https://github.com/mapbase-source/source-sdk-2013
https://www.moddb.com/mods/mapbase
@ -117,7 +117,18 @@ Direct contributions:
- https://github.com/mapbase-source/source-sdk-2013/pull/237 (Commander goal trace fix by Agrimar)
- https://github.com/mapbase-source/source-sdk-2013/pull/245 (ViewPunch random fix by Mr0maks)
- https://github.com/mapbase-source/source-sdk-2013/pull/248 (soundlevel_t conversation warning fix by Mechami)
- https://github.com/mapbase-source/source-sdk-2013/pull/266 ("OnPhysGunPull" output in CPhysicsProp by rlenhub)
- https://github.com/mapbase-source/source-sdk-2013/pull/292 (env_headcrabcanister random spawn type by arbabf)
- https://github.com/mapbase-source/source-sdk-2013/pull/294 (SDK_LightmappedGeneric editor blend swap fix by azzyr)
- https://github.com/mapbase-source/source-sdk-2013/pull/308 (BlurFilterY fix by Wikot235)
- https://github.com/mapbase-source/source-sdk-2013/pull/312 (Zombie improvements by Wikot235)
- https://github.com/mapbase-source/source-sdk-2013/pull/315 (env_flare crash fix by Wikot235)
- https://github.com/mapbase-source/source-sdk-2013/pull/324 (server-only info/func_null by SirYodaJedi)
- https://github.com/mapbase-source/source-sdk-2013/pull/333 (Cvar to transition levels while in MOVETYPE_NOCLIP by Wikot235)
- https://github.com/mapbase-source/source-sdk-2013/pull/342 (NaN particle cull radius fix by celisej567)
- https://github.com/mapbase-source/mapbase-game-src/pull/1 (Advanced video options duplicate field name fix by arbabf; This is asset-based and not reflected in the code)
- https://github.com/mapbase-source/mapbase-game-src/pull/2 (gameinfo.txt typo fix by CarePackage17; This is asset-based and not reflected in the code)
- https://github.com/mapbase-source/mapbase-game-src/pull/3 (HudMessage cutoff fix by arbabf; This is asset-based and not reflected in the code)
- Demo autorecord code provided by Klems
- cc_emit crash fix provided by 1upD
- Custom HL2 ammo crate models created by Rykah (Textures created by Blixibon; This is asset-based and, aside from the SLAM crate, not reflected in the code)
@ -144,8 +155,10 @@ Direct contributions:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/206 (Fix CScriptNetMsgHelper::WriteEntity())
=-- https://github.com/mapbase-source/source-sdk-2013/pull/213 (VScript HUD visibility control, optimizations for 3D skybox angles/fake worldportals)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/229 (VScript VGUI HUD viewport parenting, game_text and vgui_text_display VScript font fallback)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/260 (CScriptNetPropManager rewrite)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/261 (Misc VScript additions)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/279 (weapon_custom_scripted fixes)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/332 (Fix OOB access)
== Contributions from z33ky:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/21 (Various GCC/Linux compilation fixes)
@ -159,6 +172,7 @@ Direct contributions:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/159 (Additional GCC/Linux compilation fixes)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/162 (VS2019 exception specification fix)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/170 (HL2 non-Episodic build fix)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/322 (Small Mapbase fixes)
== Contributions from Petercov:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/182 (NPCs load dynamic interactions from all animation MDLs)
@ -168,6 +182,7 @@ Direct contributions:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/183 (Enhanced custom weapons support)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/230 (Caption fixes)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/231 (Sentence source bug fix)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/264 (Outputs for vgui_screen)
//-------------------------------------------------------------------------------------------------------------------------

View File

@ -146,6 +146,8 @@ CParticleEffectBinding::CParticleEffectBinding()
m_LastMin = m_Min;
m_LastMax = m_Max;
m_flParticleCullRadius = 0.0f;
SetParticleCullRadius( 0.0f );
m_nActiveParticles = 0;

View File

@ -22,10 +22,10 @@ void CPointEntity::Spawn( void )
}
class CNullEntity : public CBaseEntity
class CNullEntity : public CServerOnlyEntity
{
public:
DECLARE_CLASS( CNullEntity, CBaseEntity );
DECLARE_CLASS( CNullEntity, CServerOnlyEntity );
void Spawn( void );
};

View File

@ -34,6 +34,10 @@ C_BaseCombatCharacter::C_BaseCombatCharacter()
m_pGlowEffect = NULL;
m_bGlowEnabled = false;
m_bOldGlowEnabled = false;
m_GlowColor.Init( 0.76f, 0.76f, 0.76f );
m_OldGlowColor = m_GlowColor;
m_GlowAlpha = 1.0f;
m_OldGlowAlpha = 1.0f;
#endif // GLOWS_ENABLE
}
@ -66,6 +70,8 @@ void C_BaseCombatCharacter::OnPreDataChanged( DataUpdateType_t updateType )
#ifdef GLOWS_ENABLE
m_bOldGlowEnabled = m_bGlowEnabled;
m_OldGlowColor = m_GlowColor;
m_OldGlowAlpha = m_GlowAlpha;
#endif // GLOWS_ENABLE
}
@ -77,7 +83,7 @@ void C_BaseCombatCharacter::OnDataChanged( DataUpdateType_t updateType )
BaseClass::OnDataChanged( updateType );
#ifdef GLOWS_ENABLE
if ( m_bOldGlowEnabled != m_bGlowEnabled )
if ( m_bOldGlowEnabled != m_bGlowEnabled || m_OldGlowColor != m_GlowColor || m_OldGlowAlpha != m_GlowAlpha )
{
UpdateGlowEffect();
}
@ -106,11 +112,13 @@ void C_BaseCombatCharacter::DoMuzzleFlash()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::GetGlowEffectColor( float *r, float *g, float *b )
void C_BaseCombatCharacter::GetGlowEffectColor( float *r, float *g, float *b, float *a )
{
*r = 0.76f;
*g = 0.76f;
*b = 0.76f;
*r = m_GlowColor.x;
*g = m_GlowColor.y;
*b = m_GlowColor.z;
if (a)
*a = m_GlowAlpha;
}
//-----------------------------------------------------------------------------
@ -127,10 +135,10 @@ void C_BaseCombatCharacter::UpdateGlowEffect( void )
// create a new effect
if ( m_bGlowEnabled )
{
float r, g, b;
GetGlowEffectColor( &r, &g, &b );
float r, g, b, a;
GetGlowEffectColor( &r, &g, &b, &a );
m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true );
m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), a, true );
}
}
@ -161,6 +169,8 @@ BEGIN_RECV_TABLE(C_BaseCombatCharacter, DT_BaseCombatCharacter)
RecvPropArray3( RECVINFO_ARRAY(m_hMyWeapons), RecvPropEHandle( RECVINFO( m_hMyWeapons[0] ) ) ),
#ifdef GLOWS_ENABLE
RecvPropBool( RECVINFO( m_bGlowEnabled ) ),
RecvPropVector( RECVINFO( m_GlowColor ) ),
RecvPropFloat( RECVINFO( m_GlowAlpha ) ),
#endif // GLOWS_ENABLE
#ifdef INVASION_CLIENT_DLL

View File

@ -99,7 +99,7 @@ public:
#ifdef GLOWS_ENABLE
CGlowObject *GetGlowObject( void ){ return m_pGlowEffect; }
virtual void GetGlowEffectColor( float *r, float *g, float *b );
virtual void GetGlowEffectColor( float *r, float *g, float *b, float *a = NULL );
#endif // GLOWS_ENABLE
#ifdef MAPBASE_VSCRIPT
@ -133,6 +133,10 @@ private:
bool m_bGlowEnabled;
bool m_bOldGlowEnabled;
CGlowObject *m_pGlowEffect;
Vector m_GlowColor;
Vector m_OldGlowColor;
float m_GlowAlpha;
int m_OldGlowAlpha;
#endif // GLOWS_ENABLE
private:

View File

@ -485,6 +485,8 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities
DEFINE_SCRIPTFUNC_NAMED( ScriptEntityToWorldTransform, "EntityToWorldTransform", "Get the entity's transform" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetPhysicsObject, "GetPhysicsObject", "Get the entity's physics object if it has one" )
DEFINE_SCRIPTFUNC_NAMED( ScriptPhysicsInitNormal, "PhysicsInitNormal", "Initializes the entity's physics object with the specified solid type, solid flags, and whether to start asleep" )
DEFINE_SCRIPTFUNC_NAMED( ScriptPhysicsDestroyObject, "PhysicsDestroyObject", "Destroys the entity's physics object" )
DEFINE_SCRIPTFUNC( GetWaterLevel, "Get current level of water submergence" )

View File

@ -1206,6 +1206,8 @@ public:
HSCRIPT ScriptEntityToWorldTransform( void );
HSCRIPT ScriptGetPhysicsObject( void );
void ScriptPhysicsInitNormal( int nSolidType, int nSolidFlags, bool createAsleep );
void ScriptPhysicsDestroyObject() { VPhysicsDestroyObject(); }
void ScriptSetParent( HSCRIPT hParent, const char *szAttachment );
HSCRIPT ScriptGetMoveParent( void );

View File

@ -1133,6 +1133,9 @@ void C_BasePlayer::DetermineVguiInputMode( CUserCmd *pCmd )
// Kill all attack inputs if we're in vgui screen mode
pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2 | IN_VALIDVGUIINPUT);
#ifdef MAPBASE
pCmd->buttons |= IN_VGUIMODE;
#endif // MAPBASE
return;
}
#else
@ -1142,6 +1145,10 @@ void C_BasePlayer::DetermineVguiInputMode( CUserCmd *pCmd )
// Kill all attack inputs if we're in vgui screen mode
pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2);
#ifdef MAPBASE
pCmd->buttons &= ~(IN_USE | IN_ATTACK3);
pCmd->buttons |= IN_VGUIMODE;
#endif // MAPBASE
return;
}
#endif
@ -1206,6 +1213,10 @@ void C_BasePlayer::DetermineVguiInputMode( CUserCmd *pCmd )
// Kill all attack inputs if we're in vgui screen mode
pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2);
#ifdef MAPBASE
pCmd->buttons &= ~(IN_USE | IN_ATTACK3);
pCmd->buttons |= IN_VGUIMODE;
#endif // MAPBASE
}
}

View File

@ -219,6 +219,11 @@ enum
SCREENEFFECT_EP2_ADVISOR_STUN,
SCREENEFFECT_EP1_INTRO,
SCREENEFFECT_EP2_GROGGY,
#ifdef MAPBASE
SCREENEFFECT_MAPBASE_CHROMATIC_BLUR = 100, // Overlays 3 different frames of red, green, and blue tints respectively with different offsets
SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION, // Similar to above, except it stretches frames in addition to offsetting them
#endif
};
// ============================================================================
@ -303,6 +308,21 @@ void C_EnvScreenEffect::ReceiveMessage( int classID, bf_read &msg )
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "ep2_groggy", pKeys );
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "ep2_groggy" );
}
#ifdef MAPBASE
else if ( m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_BLUR || m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION )
{
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
return;
// Set our keys
pKeys->SetFloat( "duration", m_flDuration );
pKeys->SetInt( "fadeout", 0 );
pKeys->SetInt( "stretch", m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION );
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "mapbase_chromatic_aberration", pKeys );
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "mapbase_chromatic_aberration" );
}
#endif
pKeys->deleteThis();
}
@ -349,6 +369,25 @@ void C_EnvScreenEffect::ReceiveMessage( int classID, bf_read &msg )
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "ep2_groggy", pKeys );
}
#ifdef MAPBASE
else if ( m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_BLUR || m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION )
{
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
return;
// Create a keyvalue block to set these params
KeyValues *pKeys = new KeyValues( "keys" );
if ( pKeys == NULL )
return;
// Set our keys
pKeys->SetFloat( "duration", m_flDuration );
pKeys->SetInt( "fadeout", 1 );
pKeys->SetInt( "stretch", m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION );
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "mapbase_chromatic_aberration", pKeys );
}
#endif
break;
}

View File

@ -95,18 +95,23 @@ extern PMaterialHandle g_Material_Spark;
//-----------------------------------------------------------------------------
void GetColorForSurface( trace_t *trace, Vector *color )
{
Vector baseColor, diffuseColor;
Vector end = trace->startpos + ( ( Vector )trace->endpos - ( Vector )trace->startpos ) * 1.1f;
Vector baseColor = vec3_invalid, diffuseColor;
const char *kind;
if ( trace->DidHitWorld() )
{
if ( trace->hitbox == 0 )
{
kind = "World";
Vector end = trace->startpos + ( trace->endpos - trace->startpos ) * 1.1f;
// If we hit the world, then ask the world for the fleck color
engine->TraceLineMaterialAndLighting( trace->startpos, end, diffuseColor, baseColor );
if ( !engine->TraceLineMaterialAndLighting( trace->startpos, end, diffuseColor, baseColor ) ) {
baseColor = vec3_invalid; // Make sure this wasn't modified
}
}
else
{
kind = "Static Prop";
// In this case we hit a static prop.
staticpropmgr->GetStaticPropMaterialColorAndLighting( trace, trace->hitbox - 1, diffuseColor, baseColor );
}
@ -117,20 +122,24 @@ void GetColorForSurface( trace_t *trace, Vector *color )
C_BaseEntity *pEnt = trace->m_pEnt;
if ( !pEnt )
{
Msg("Couldn't find surface in GetColorForSurface()\n");
color->x = 255;
color->y = 255;
color->z = 255;
return;
kind = "Null-Entity";
} else {
kind = "Entity";
ICollideable *pCollide = pEnt->GetCollideable();
int modelIndex = pCollide->GetCollisionModelIndex();
model_t* pModel = const_cast<model_t*>(modelinfo->GetModel( modelIndex ));
// Ask the model info about what we need to know
modelinfo->GetModelMaterialColorAndLighting( pModel, pCollide->GetCollisionOrigin(),
pCollide->GetCollisionAngles(), trace, diffuseColor, baseColor );
}
}
ICollideable *pCollide = pEnt->GetCollideable();
int modelIndex = pCollide->GetCollisionModelIndex();
model_t* pModel = const_cast<model_t*>(modelinfo->GetModel( modelIndex ));
// Ask the model info about what we need to know
modelinfo->GetModelMaterialColorAndLighting( pModel, pCollide->GetCollisionOrigin(),
pCollide->GetCollisionAngles(), trace, diffuseColor, baseColor );
if ( baseColor == vec3_invalid )
{
Warning( "Couldn't find surface color of %s\n", kind );
baseColor = Vector( .5f, .5f, .5f );
diffuseColor = engine->GetLightForPoint( trace->endpos, true );
}
//Get final light value

View File

@ -38,10 +38,14 @@ extern vgui::IInputInternal *g_InputInternal;
#define VGUI_SCREEN_MODE_RADIUS 80
//Precache the materials
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectVGuiScreen )
CLIENTEFFECT_MATERIAL( "engine/writez" )
CLIENTEFFECT_REGISTER_BEGIN(PrecacheEffectVGuiScreen)
CLIENTEFFECT_MATERIAL("engine/writez")
CLIENTEFFECT_REGISTER_END()
#ifdef MAPBASE
C_EntityClassList<C_VGuiScreen> g_VGUIScreenList;
template <> C_VGuiScreen* C_EntityClassList<C_VGuiScreen>::m_pClassList = NULL;
#endif // MAPBASE
// ----------------------------------------------------------------------------- //
// This is a cache of preloaded keyvalues.
@ -102,11 +106,19 @@ C_VGuiScreen::C_VGuiScreen()
m_WriteZMaterial.Init( "engine/writez", TEXTURE_GROUP_VGUI );
m_OverlayMaterial.Init( m_WriteZMaterial );
#ifdef MAPBASE
g_VGUIScreenList.Insert(this);
#endif // MAPBASE
}
C_VGuiScreen::~C_VGuiScreen()
{
DestroyVguiScreen();
#ifdef MAPBASE
g_VGUIScreenList.Remove(this);
#endif // MAPBASE
}
//-----------------------------------------------------------------------------
@ -416,34 +428,69 @@ void C_VGuiScreen::ClientThink( void )
int px = (int)(u * m_nPixelWidth + 0.5f);
int py = (int)(v * m_nPixelHeight + 0.5f);
#ifndef MAPBASE
// Generate mouse input commands
if ((px != m_nOldPx) || (py != m_nOldPy))
{
g_InputInternal->InternalCursorMoved( px, py );
g_InputInternal->InternalCursorMoved(px, py);
m_nOldPx = px;
m_nOldPy = py;
}
if (m_nButtonPressed & IN_ATTACK)
{
g_InputInternal->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_PRESSED );
g_InputInternal->SetMouseCodeState(MOUSE_LEFT, vgui::BUTTON_PRESSED);
g_InputInternal->InternalMousePressed(MOUSE_LEFT);
}
if (m_nButtonPressed & IN_ATTACK2)
{
g_InputInternal->SetMouseCodeState( MOUSE_RIGHT, vgui::BUTTON_PRESSED );
g_InputInternal->InternalMousePressed( MOUSE_RIGHT );
g_InputInternal->SetMouseCodeState(MOUSE_RIGHT, vgui::BUTTON_PRESSED);
g_InputInternal->InternalMousePressed(MOUSE_RIGHT);
}
if ( (m_nButtonReleased & IN_ATTACK) || m_bLoseThinkNextFrame) // for a button release on loosing focus
if ((m_nButtonReleased & IN_ATTACK) || m_bLoseThinkNextFrame) // for a button release on loosing focus
{
g_InputInternal->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_RELEASED );
g_InputInternal->InternalMouseReleased( MOUSE_LEFT );
g_InputInternal->SetMouseCodeState(MOUSE_LEFT, vgui::BUTTON_RELEASED);
g_InputInternal->InternalMouseReleased(MOUSE_LEFT);
}
if (m_nButtonReleased & IN_ATTACK2)
{
g_InputInternal->SetMouseCodeState( MOUSE_RIGHT, vgui::BUTTON_RELEASED );
g_InputInternal->InternalMouseReleased( MOUSE_RIGHT );
g_InputInternal->SetMouseCodeState(MOUSE_RIGHT, vgui::BUTTON_RELEASED);
g_InputInternal->InternalMouseReleased(MOUSE_RIGHT);
}
#else
vgui::VPANEL focus = g_InputInternal->GetMouseOver();
// Generate mouse input commands
if ((px != m_nOldPx) || (py != m_nOldPy))
{
g_InputInternal->UpdateCursorPosInternal(px, py);
m_nOldPx = px;
m_nOldPy = py;
focus = pPanel->IsWithinTraverse(px, py, true);
g_InputInternal->SetMouseFocus(focus);
vgui::ivgui()->PostMessage(focus, new KeyValues("CursorMoved", "xpos", px, "ypos", py), NULL);
}
for (int i = 0; i < 2; i++)
{
const int nBit = i ? IN_ATTACK2 : (IN_ATTACK | IN_USE);
const vgui::MouseCode nButton = i ? MOUSE_RIGHT : MOUSE_LEFT;
if ((m_nButtonReleased & nBit) || ((m_nButtonState & nBit) && m_bLoseThinkNextFrame)) // for a button release on loosing focus
{
g_InputInternal->SetMouseCodeState(nButton, vgui::BUTTON_RELEASED);
vgui::ivgui()->PostMessage(focus, new KeyValues("MouseReleased", "code", nButton), NULL);
}
else if (m_nButtonPressed & nBit)
{
g_InputInternal->SetMouseCodeState(nButton, vgui::BUTTON_PRESSED);
vgui::ivgui()->PostMessage(focus, new KeyValues("MousePressed", "code", nButton), NULL);
}
}
#endif // !MAPBASE
if ( m_bLoseThinkNextFrame == true )
{
@ -627,6 +674,7 @@ bool C_VGuiScreen::IsInputOnlyToOwner( void )
return (m_fScreenFlags & VGUI_SCREEN_ONLY_USABLE_BY_OWNER) != 0;
}
#ifndef MAPBASE
//-----------------------------------------------------------------------------
//
// Enumator class for finding vgui screens close to the local player
@ -634,29 +682,29 @@ bool C_VGuiScreen::IsInputOnlyToOwner( void )
//-----------------------------------------------------------------------------
class CVGuiScreenEnumerator : public IPartitionEnumerator
{
DECLARE_CLASS_GAMEROOT( CVGuiScreenEnumerator, IPartitionEnumerator );
DECLARE_CLASS_GAMEROOT(CVGuiScreenEnumerator, IPartitionEnumerator);
public:
virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity );
virtual IterationRetval_t EnumElement(IHandleEntity* pHandleEntity);
int GetScreenCount();
C_VGuiScreen *GetVGuiScreen( int index );
C_VGuiScreen* GetVGuiScreen(int index);
private:
CUtlVector< CHandle< C_VGuiScreen > > m_VguiScreens;
};
IterationRetval_t CVGuiScreenEnumerator::EnumElement( IHandleEntity *pHandleEntity )
IterationRetval_t CVGuiScreenEnumerator::EnumElement(IHandleEntity* pHandleEntity)
{
C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( pHandleEntity->GetRefEHandle() );
if ( pEnt == NULL )
C_BaseEntity* pEnt = ClientEntityList().GetBaseEntityFromHandle(pHandleEntity->GetRefEHandle());
if (pEnt == NULL)
return ITERATION_CONTINUE;
// FIXME.. pretty expensive...
C_VGuiScreen *pScreen = dynamic_cast<C_VGuiScreen*>(pEnt);
if ( pScreen )
C_VGuiScreen* pScreen = dynamic_cast<C_VGuiScreen*>(pEnt);
if (pScreen)
{
int i = m_VguiScreens.AddToTail( );
m_VguiScreens[i].Set( pScreen );
int i = m_VguiScreens.AddToTail();
m_VguiScreens[i].Set(pScreen);
}
return ITERATION_CONTINUE;
@ -667,10 +715,12 @@ int CVGuiScreenEnumerator::GetScreenCount()
return m_VguiScreens.Count();
}
C_VGuiScreen *CVGuiScreenEnumerator::GetVGuiScreen( int index )
C_VGuiScreen* CVGuiScreenEnumerator::GetVGuiScreen(int index)
{
return m_VguiScreens[index].Get();
}
#endif // !MAPBASE
//-----------------------------------------------------------------------------
@ -704,18 +754,29 @@ C_BaseEntity *FindNearbyVguiScreen( const Vector &viewPosition, const QAngle &vi
Ray_t lookRay;
lookRay.Init( viewPosition, lookEnd );
#ifndef MAPBASE
// Look for vgui screens that are close to the player
CVGuiScreenEnumerator localScreens;
partition->EnumerateElementsInSphere( PARTITION_CLIENT_NON_STATIC_EDICTS, viewPosition, VGUI_SCREEN_MODE_RADIUS, false, &localScreens );
partition->EnumerateElementsInSphere(PARTITION_CLIENT_NON_STATIC_EDICTS, viewPosition, VGUI_SCREEN_MODE_RADIUS, false, &localScreens);
#endif // !MAPBASE
Vector vecOut, vecViewDelta;
float flBestDist = 2.0f;
C_VGuiScreen *pBestScreen = NULL;
#ifndef MAPBASE
for (int i = localScreens.GetScreenCount(); --i >= 0; )
#else
for (C_VGuiScreen* pScreen = g_VGUIScreenList.m_pClassList; pScreen != NULL; pScreen = pScreen->m_pNext)
#endif // !MAPBASE
{
C_VGuiScreen *pScreen = localScreens.GetVGuiScreen(i);
#ifndef MAPBASE
C_VGuiScreen* pScreen = localScreens.GetVGuiScreen(i);
#else
// Skip if out of PVS
if (pScreen->IsDormant())
continue;
#endif
if ( pScreen->IsAttachedToViewModel() )
continue;
@ -865,11 +926,21 @@ vgui::Panel *CVGuiScreenPanel::CreateControlByName(const char *controlName)
//-----------------------------------------------------------------------------
// Purpose: Called when the user presses a button
//-----------------------------------------------------------------------------
void CVGuiScreenPanel::OnCommand( const char *command)
void CVGuiScreenPanel::OnCommand(const char* command)
{
if ( Q_stricmp( command, "vguicancel" ) )
if (Q_stricmp(command, "vguicancel"))
{
engine->ClientCmd( const_cast<char *>( command ) );
#ifdef MAPBASE
if (m_hEntity && m_hEntity->IsServerEntity())
{
KeyValues* pCommand = new KeyValues("EntityCommand");
pCommand->SetInt("entindex", m_hEntity->index);
pCommand->SetString("command_data", command);
engine->ServerCmdKeyValues(pCommand);
}
else
#endif
engine->ClientCmd(const_cast<char*>(command));
}
BaseClass::OnCommand(command);

View File

@ -66,6 +66,10 @@ class C_VGuiScreen : public C_BaseEntity
public:
DECLARE_CLIENTCLASS();
#ifdef MAPBASE
C_VGuiScreen* m_pNext;
#endif // MAPBASE
C_VGuiScreen();
~C_VGuiScreen();

View File

@ -462,3 +462,225 @@ void CEP2StunEffect::Render( int x, int y, int w, int h )
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PopMatrix();
}
// ================================================================================================================
//
// Chromatic Aberration
//
// ================================================================================================================
#ifdef MAPBASE
ConVar r_chromatic_aberration_offset( "r_chromatic_aberration_offset", "8.0" );
ConVar r_chromatic_aberration_intensity( "r_chromatic_aberration_intensity", "0.2" );
ConVar r_chromatic_aberration_noise( "r_chromatic_aberration_noise", "4.0" );
ConVar r_chromatic_aberration_frame1_clr( "r_chromatic_aberration_frame1_clr", "1.0 0.0 0.0 1.0" );
ConVar r_chromatic_aberration_frame1_offset_x( "r_chromatic_aberration_frame1_offset_x", "1.0" );
ConVar r_chromatic_aberration_frame1_offset_y( "r_chromatic_aberration_frame1_offset_y", "4.0" );
ConVar r_chromatic_aberration_frame2_clr( "r_chromatic_aberration_frame2_clr", "0.0 1.0 0.0 1.0" );
ConVar r_chromatic_aberration_frame2_offset_x( "r_chromatic_aberration_frame2_offset_x", "-5.0" );
ConVar r_chromatic_aberration_frame2_offset_y( "r_chromatic_aberration_frame2_offset_y", "-1.0" );
ConVar r_chromatic_aberration_frame3_clr( "r_chromatic_aberration_frame3_clr", "0.0 0.0 1.0 1.0" );
ConVar r_chromatic_aberration_frame3_offset_x( "r_chromatic_aberration_frame3_offset_x", "3.0" );
ConVar r_chromatic_aberration_frame3_offset_y( "r_chromatic_aberration_frame3_offset_y", "-3.0" );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CChromaticAberrationEffect::Init( void )
{
m_flDuration = 0.0f;
m_flFinishTime = 0.0f;
m_bUpdateView = true;
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
pVMTKeyValues->SetString( "$basetexture", STUN_TEXTURE );
m_EffectMaterial.Init( "__stuneffect", TEXTURE_GROUP_CLIENT_EFFECTS, pVMTKeyValues );
m_StunTexture.Init( STUN_TEXTURE, TEXTURE_GROUP_CLIENT_EFFECTS );
}
void CChromaticAberrationEffect::Shutdown( void )
{
m_EffectMaterial.Shutdown();
m_StunTexture.Shutdown();
}
//------------------------------------------------------------------------------
// Purpose: Pick up changes in our parameters
//------------------------------------------------------------------------------
void CChromaticAberrationEffect::SetParameters( KeyValues *params )
{
if( params->FindKey( "duration" ) )
{
m_flDuration = params->GetFloat( "duration" );
m_flFinishTime = gpGlobals->curtime + m_flDuration;
m_bUpdateView = true;
}
if( params->FindKey( "fadeout" ) )
{
m_bFadeOut = ( params->GetInt( "fadeout" ) == 1 );
}
if( params->FindKey( "stretch" ) )
{
m_bStretch = ( params->GetInt( "stretch" ) == 1 );
}
}
//-----------------------------------------------------------------------------
// Purpose: Render the effect
//-----------------------------------------------------------------------------
void CChromaticAberrationEffect::RenderColorFrame( CMatRenderContextPtr &pRenderContext, float flEffectPerc, int nColorMode, int x, int y, int w, int h )
{
// Change color
float flColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
float viewOffsX = flEffectPerc;
if (m_bStretch)
viewOffsX *= r_chromatic_aberration_offset.GetFloat() * 2;
else
viewOffsX *= r_chromatic_aberration_offset.GetFloat();
float viewOffsY = viewOffsX;
{
char szColor[16] = { 0 };
float flNoise = sin( gpGlobals->curtime * r_chromatic_aberration_noise.GetFloat() ) * flEffectPerc;
switch (nColorMode)
{
// Red
case 0:
Q_strncpy( szColor, r_chromatic_aberration_frame1_clr.GetString(), sizeof( szColor ) );
viewOffsX *= r_chromatic_aberration_frame1_offset_x.GetFloat();
viewOffsY *= r_chromatic_aberration_frame1_offset_y.GetFloat();
viewOffsX += flNoise;
viewOffsY += flNoise;
break;
// Green
case 1:
Q_strncpy( szColor, r_chromatic_aberration_frame2_clr.GetString(), sizeof( szColor ) );
viewOffsX *= r_chromatic_aberration_frame2_offset_x.GetFloat();
viewOffsY *= r_chromatic_aberration_frame2_offset_y.GetFloat();
viewOffsX += flNoise;
viewOffsY += flNoise;
break;
// Blue
case 2:
Q_strncpy( szColor, r_chromatic_aberration_frame3_clr.GetString(), sizeof( szColor ) );
viewOffsX *= r_chromatic_aberration_frame3_offset_x.GetFloat();
viewOffsY *= r_chromatic_aberration_frame3_offset_y.GetFloat();
viewOffsX += flNoise;
viewOffsY += flNoise;
break;
}
char *c = strtok( szColor, " " );
for (int i = 0; i < 4 && c != NULL; i++, c = strtok( NULL, " " ))
{
flColor[i] = atof( c );
}
}
if (flColor[3] == 0.0f || g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80)
return;
m_EffectMaterial->ColorModulate( flColor[0], flColor[1], flColor[2] );
// Set alpha blend value
float flOverlayAlpha = clamp( r_chromatic_aberration_intensity.GetFloat() * flEffectPerc * flColor[3], 0.0f, 1.0f);
m_EffectMaterial->AlphaModulate( flOverlayAlpha );
// Draw full screen alpha-blended quad
if (m_bStretch)
{
float vX = x - (viewOffsX * 0.5f);
float vY = y - (viewOffsY * 0.5f);
pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, vX, vY, w + viewOffsX, h + viewOffsY,
0, 0, (m_StunTexture->GetActualWidth()-1), (m_StunTexture->GetActualHeight()-1),
m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() );
}
else
{
float vX = x + viewOffsX;
float vY = y + viewOffsY;
pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, 0, 0, w, h,
vX, vY, (m_StunTexture->GetActualWidth()-1)+vX, (m_StunTexture->GetActualHeight()-1)+vY,
m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() );
}
}
//-----------------------------------------------------------------------------
// Purpose: Render the effect
//-----------------------------------------------------------------------------
void CChromaticAberrationEffect::Render( int x, int y, int w, int h )
{
// Make sure we're ready to play this effect
if ( !IsEnabled() )
return;
if ( m_bFadeOut && m_flFinishTime < gpGlobals->curtime )
{
g_pScreenSpaceEffects->DisableScreenSpaceEffect( "mapbase_chromatic_aberration" );
return;
}
CMatRenderContextPtr pRenderContext( materials );
// Set ourselves to the proper rendermode
pRenderContext->MatrixMode( MATERIAL_VIEW );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
// Draw the texture if we're using it
if ( m_bUpdateView )
{
// Save off this pass
Rect_t srcRect;
srcRect.x = x;
srcRect.y = y;
srcRect.width = w;
srcRect.height = h;
pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL );
m_bUpdateView = false;
}
float flEffectPerc = SmoothCurve( clamp( ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration, 0.0f, 1.0f ) );
if (!m_bFadeOut)
flEffectPerc = 1.0f - flEffectPerc;
RenderColorFrame( pRenderContext, flEffectPerc, 0, x, y, w, h );
RenderColorFrame( pRenderContext, flEffectPerc, 1, x, y, w, h );
RenderColorFrame( pRenderContext, flEffectPerc, 2, x, y, w, h );
// Save off this pass
Rect_t srcRect;
srcRect.x = x;
srcRect.y = y;
srcRect.width = w;
srcRect.height = h;
pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL );
// Restore our state
pRenderContext->MatrixMode( MATERIAL_VIEW );
pRenderContext->PopMatrix();
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PopMatrix();
}
#endif

View File

@ -116,4 +116,38 @@ private:
ADD_SCREENSPACE_EFFECT( CEP2StunEffect, ep2_groggy );
#ifdef MAPBASE
class CChromaticAberrationEffect : public IScreenSpaceEffect
{
public:
CChromaticAberrationEffect( void ) :
m_flDuration( 0.0f ),
m_flFinishTime( 0.0f ),
m_bUpdateView( true ),
m_bEnabled( false ),
m_bFadeOut( false ) {}
virtual void Init( void );
virtual void Shutdown( void );
virtual void SetParameters( KeyValues *params );
virtual void Enable( bool bEnable ) { m_bEnabled = bEnable; };
virtual bool IsEnabled( ) { return m_bEnabled; }
virtual void RenderColorFrame( CMatRenderContextPtr &pRenderContext, float flEffectPerc, int nColorMode, int x, int y, int w, int h );
virtual void Render( int x, int y, int w, int h );
private:
CTextureReference m_StunTexture;
CMaterialReference m_EffectMaterial;
float m_flDuration;
float m_flFinishTime;
bool m_bUpdateView;
bool m_bStretch;
bool m_bFadeOut;
bool m_bEnabled;
};
ADD_SCREENSPACE_EFFECT( CChromaticAberrationEffect, mapbase_chromatic_aberration );
#endif
#endif // EPISODIC_SCREENSPACEEFFECTS_H

View File

@ -35,8 +35,7 @@ struct creditname_t
#ifdef MAPBASE
// New credits stuff
Color cColorOverride;
CCopyableUtlVector<int> cColorOverride;
// Images
int iImageID = -1;
@ -408,8 +407,8 @@ void CHudCredits::DrawOutroCreditsName( void )
Color cColor = m_TextColor;
#ifdef MAPBASE
if (pCredit->cColorOverride.a() > 0)
cColor = pCredit->cColorOverride;
if (pCredit->cColorOverride.Count() > 0)
cColor.SetRawColor( pCredit->cColorOverride[0] );
// Some lines should stick around and fade out
if ( i >= m_CreditsList.Count()-m_iEndLines )
@ -473,6 +472,12 @@ void CHudCredits::DrawOutroCreditsName( void )
{
FOR_EACH_VEC( outStrings, i )
{
if (i < pCredit->cColorOverride.Count())
{
// Change color to this particular column's color
cColor.SetRawColor( pCredit->cColorOverride[i] );
}
int iImageID = GetOrAllocateImageID( outStrings[i] );
// Center the image if needed
@ -492,6 +497,12 @@ void CHudCredits::DrawOutroCreditsName( void )
{
FOR_EACH_VEC( outStrings, i )
{
if (i < pCredit->cColorOverride.Count())
{
// Change color to this particular column's color
cColor.SetRawColor( pCredit->cColorOverride[i] );
}
DrawOutroCreditFont( outStrings[i], pCredit->flYPos, m_hTFont, cColor, iWidth*(i + 1), iDivisor );
}
}
@ -768,8 +779,8 @@ void CHudCredits::DrawIntroCreditsName( void )
surface()->DrawSetTextFont( m_hTFont );
#ifdef MAPBASE
Color cColor = m_cColor;
if (pCredit->cColorOverride.a() > 0)
cColor = pCredit->cColorOverride;
if (pCredit->cColorOverride.Count() > 0)
cColor.SetRawColor( pCredit->cColorOverride[0] );
surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], FadeBlend( m_flFadeInTime, m_flFadeOutTime, m_flFadeHoldTime + pCredit->flTimeAdd, localTime ) * cColor[3] );
#else
@ -941,9 +952,25 @@ void CHudCredits::PrepareOutroCredits( void )
// Get color
case 2:
int tmp[4];
UTIL_StringToIntArray( tmp, 4, outStrings[i] );
pCredit->cColorOverride = Color( tmp[0], tmp[1], tmp[2], tmp[3] );
char *pToken = strtok( outStrings[i], "," );
if (pToken)
{
// Multiple colors for multiple columns
while (pToken != NULL)
{
int tmp[4];
UTIL_StringToIntArray( tmp, 4, pToken );
pCredit->cColorOverride.AddToTail( Color( tmp[0], tmp[1], tmp[2], tmp[3] ).GetRawColor() );
pToken = strtok( NULL, "," );
}
}
else
{
int tmp[4];
UTIL_StringToIntArray( tmp, 4, outStrings[i] );
pCredit->cColorOverride.AddToTail( Color( tmp[0], tmp[1], tmp[2], tmp[3] ).GetRawColor() );
}
break;
}
}
@ -999,9 +1026,25 @@ void CHudCredits::PrepareOutroCredits( void )
{
// Get color
case 1:
int tmp[4];
UTIL_StringToIntArray( tmp, 4, outStrings[i] );
pCredit->cColorOverride = Color( tmp[0], tmp[1], tmp[2], tmp[3] );
char *pToken = strtok( outStrings[i], "," );
if (pToken)
{
// Multiple colors for multiple columns
while (pToken != NULL)
{
int tmp[4];
UTIL_StringToIntArray( tmp, 4, pToken );
pCredit->cColorOverride.AddToTail( Color( tmp[0], tmp[1], tmp[2], tmp[3] ).GetRawColor() );
pToken = strtok( NULL, "," );
}
}
else
{
int tmp[4];
UTIL_StringToIntArray( tmp, 4, outStrings[i] );
pCredit->cColorOverride.AddToTail( Color( tmp[0], tmp[1], tmp[2], tmp[3] ).GetRawColor() );
}
break;
}
}
@ -1024,8 +1067,12 @@ void CHudCredits::PrepareOutroCredits( void )
#ifdef MAPBASE
// Check if the last line has a color override. If it does, use that as the alpha for the fadeout
if (m_CreditsList.Tail().cColorOverride.a() != 0)
m_Alpha = m_CreditsList.Tail().cColorOverride.a();
if (m_CreditsList.Tail().cColorOverride.Count() > 0)
{
Color clr;
clr.SetRawColor( m_CreditsList.Tail().cColorOverride[0] );
m_Alpha = clr.a();
}
#endif
SetActive( true );
@ -1057,9 +1104,10 @@ void CHudCredits::PrepareIntroCredits( void )
{
// Get color
case 1:
// TODO: Columns?
int tmp[4];
UTIL_StringToIntArray( tmp, 4, outStrings[i] );
pCredit->cColorOverride = Color( tmp[0], tmp[1], tmp[2], tmp[3] );
pCredit->cColorOverride.AddToTail( Color( tmp[0], tmp[1], tmp[2], tmp[3] ).GetRawColor() );
break;
}
}

View File

@ -125,6 +125,12 @@ public:
//Msg("No maps to cubemap with!\n");
//return;
if (C_BasePlayer::GetLocalPlayer() == NULL)
{
Msg( "Must be in a level (or have a loaded map list) to begin autocubemap\n" );
return;
}
// Just do this map
m_AutoCubemapMaps.AddToTail( strdup( g_MapName ) );
}

View File

@ -146,6 +146,8 @@ CParticleEffectBinding::CParticleEffectBinding()
m_LastMin = m_Min;
m_LastMax = m_Max;
m_flParticleCullRadius = 0.0f;
SetParticleCullRadius( 0.0f );
m_nActiveParticles = 0;

View File

@ -272,6 +272,8 @@ void CScriptMaterialProxy::Release( void )
m_hScriptInstance = NULL;
}
g_ScriptPersistableList.FindAndRemove( this );
delete this;
}

View File

@ -38,6 +38,9 @@ public:
DECLARE_CLASS( CBasePropDoor, CDynamicProp );
DECLARE_SERVERCLASS();
#ifdef MAPBASE_VSCRIPT
DECLARE_ENT_SCRIPTDESC();
#endif
CBasePropDoor( void );
@ -79,6 +82,28 @@ public:
virtual bool PassesDoorFilter(CBaseEntity *pEntity) { return true; }
virtual bool KeyValue( const char *szKeyName, const char *szValue );
float GetSpeed() const { return m_flSpeed; }
#endif
#ifdef MAPBASE_VSCRIPT
bool ScriptIsDoorOpen() { return IsDoorOpen(); }
bool ScriptIsDoorAjar() { return IsDoorAjar(); }
bool ScriptIsDoorOpening() { return IsDoorOpening(); }
bool ScriptIsDoorClosed() { return IsDoorClosed(); }
bool ScriptIsDoorClosing() { return IsDoorClosing(); }
bool ScriptIsDoorLocked() { return IsDoorLocked(); }
bool ScriptIsDoorBlocked() const { return IsDoorBlocked(); }
HSCRIPT ScriptGetActivator() { return ToHScript( m_hActivator.Get() ); }
HSCRIPT ScriptGetDoorList( int i ) { return m_hDoorList.IsValidIndex(i) ? ToHScript( m_hDoorList[i] ) : NULL; }
int GetDoorListCount() { return m_hDoorList.Count(); }
const char *ScriptGetFullyOpenSound() { return STRING( m_SoundOpen ); }
const char *ScriptGetFullyClosedSound() { return STRING( m_SoundClose ); }
const char *ScriptGetMovingSound() { return STRING( m_SoundMoving ); }
const char *ScriptGetLockedSound() { return STRING( m_ls.sLockedSound ); }
const char *ScriptGetUnlockedSound() { return STRING( m_ls.sUnlockedSound ); }
#endif
protected:
@ -178,6 +203,12 @@ private:
#ifdef MAPBASE
void InputAllowPlayerUse(inputdata_t &inputdata);
void InputDisallowPlayerUse(inputdata_t &inputdata);
void InputSetFullyOpenSound(inputdata_t &inputdata);
void InputSetFullyClosedSound(inputdata_t &inputdata);
void InputSetMovingSound(inputdata_t &inputdata);
void InputSetLockedSound(inputdata_t &inputdata);
void InputSetUnlockedSound(inputdata_t &inputdata);
#endif
void SetDoorBlocker( CBaseEntity *pBlocker );

View File

@ -211,6 +211,11 @@ void CSkyCamera::Activate( )
}
}
#endif
#ifdef MAPBASE
if (HasSpawnFlags( SF_SKY_MASTER ))
g_hActiveSkybox = this;
#endif
}
#ifdef MAPBASE
@ -368,9 +373,11 @@ void CSkyCamera::InputActivateSkybox( inputdata_t &inputdata )
// Deactivate that skybox
pActiveSky->SetThink( NULL );
pActiveSky->SetNextThink( TICK_NEVER_THINK );
pActiveSky->RemoveSpawnFlags( SF_SKY_MASTER );
}
g_hActiveSkybox = this;
AddSpawnFlags( SF_SKY_MASTER );
if (HasSpawnFlags( SF_SKY_START_UPDATING ))
InputStartUpdating( inputdata );
@ -384,6 +391,7 @@ void CSkyCamera::InputDeactivateSkybox( inputdata_t &inputdata )
if (GetCurrentSkyCamera() == this)
{
g_hActiveSkybox = NULL;
RemoveSpawnFlags( SF_SKY_MASTER );
// ClientData doesn't catch this immediately
CBasePlayer *pPlayer = NULL;

View File

@ -6110,7 +6110,11 @@ bool CAI_BaseNPC::UpdateEnemyMemory( CBaseEntity *pEnemy, const Vector &position
// If the was eluding me and allow the NPC to play a sound
if (GetEnemies()->HasEludedMe(pEnemy))
{
#ifdef MAPBASE
FoundEnemySound( pEnemy );
#else
FoundEnemySound();
#endif
}
float reactionDelay = ( !pInformer || pInformer == this ) ? GetReactionDelay( pEnemy ) : 0.0;
bool result = GetEnemies()->UpdateMemory(GetNavigator()->GetNetwork(), pEnemy, position, reactionDelay, firstHand);
@ -8045,10 +8049,13 @@ int CAI_BaseNPC::UnholsterWeapon( void )
if (i == -1)
{
// Set i to the first weapon you can find
for (i = 0; i < WeaponCount(); i++)
for (i = 0;;)
{
if (GetWeapon(i))
break;
if (++i >= WeaponCount())
return -1;
}
}
#else
@ -11731,7 +11738,11 @@ bool CAI_BaseNPC::ChooseEnemy( void )
if ( fEnemyEluded )
{
SetCondition( COND_LOST_ENEMY );
#ifdef MAPBASE
LostEnemySound( pInitialEnemy );
#else
LostEnemySound();
#endif
}
if ( fEnemyWasPlayer )
@ -14895,22 +14906,39 @@ void CAI_BaseNPC::ParseScriptedNPCInteractions(void)
else if (!Q_strncmp(szName, "their_", 6))
{
const char *szTheirName = szName + 6;
sInteraction.bHasSeparateSequenceNames = true;
if (!Q_strncmp(szTheirName, "entry_sequence", 14))
{
sInteraction.bHasSeparateSequenceNames = true;
sInteraction.sTheirPhases[SNPCINT_ENTRY].iszSequence = AllocPooledString(szValue);
}
else if (!Q_strncmp(szTheirName, "entry_activity", 14))
{
sInteraction.bHasSeparateSequenceNames = true;
sInteraction.sTheirPhases[SNPCINT_ENTRY].iActivity = GetOrRegisterActivity(szValue);
}
else if (!Q_strncmp(szTheirName, "sequence", 8))
{
sInteraction.bHasSeparateSequenceNames = true;
sInteraction.sTheirPhases[SNPCINT_SEQUENCE].iszSequence = AllocPooledString(szValue);
}
else if (!Q_strncmp(szTheirName, "activity", 8))
{
sInteraction.bHasSeparateSequenceNames = true;
sInteraction.sTheirPhases[SNPCINT_SEQUENCE].iActivity = GetOrRegisterActivity(szValue);
}
else if (!Q_strncmp(szTheirName, "exit_sequence", 13))
{
sInteraction.bHasSeparateSequenceNames = true;
sInteraction.sTheirPhases[SNPCINT_EXIT].iszSequence = AllocPooledString(szValue);
}
else if (!Q_strncmp(szTheirName, "exit_activity", 13))
{
sInteraction.bHasSeparateSequenceNames = true;
sInteraction.sTheirPhases[SNPCINT_EXIT].iActivity = GetOrRegisterActivity(szValue);
}
// Add anything else to our miscellaneous criteria
else
@ -15890,12 +15918,11 @@ bool CAI_BaseNPC::InteractionIsAllowed( CAI_BaseNPC *pOtherNPC, ScriptedNPCInter
if (pOtherNPC->Classify() == CLASS_PLAYER_ALLY_VITAL)
return false;
// This convar allows all NPCs to perform Mapbase interactions for both testing and player fun.
if (ai_dynint_always_enabled.GetBool() && m_iDynamicInteractionsAllowed != TRS_FALSE)
return true;
if (m_iDynamicInteractionsAllowed == TRS_FALSE)
return false;
// m_iDynamicInteractionsAllowed == TRS_FALSE case is already handled in CanRunAScriptedNPCInteraction().
if (pInteraction->iFlags & SCNPC_FLAG_MAPBASE_ADDITION && m_iDynamicInteractionsAllowed == TRS_NONE)
// To maintain existing behavior, Mapbase additions require either explicit TRS_YES or ai_dynint_always_enabled.
if (pInteraction->iFlags & SCNPC_FLAG_MAPBASE_ADDITION && m_iDynamicInteractionsAllowed == TRS_NONE && !ai_dynint_always_enabled.GetBool())
return false;
// Test misc. criteria here since some of it may not have been valid on initial calculation, but could be now

View File

@ -1401,6 +1401,11 @@ public:
virtual void FearSound( void ) { return; };
virtual void LostEnemySound( void ) { return; };
virtual void FoundEnemySound( void ) { return; };
#ifdef MAPBASE
// New versions of the above functions which pass the enemy in question as a parameter. Chains to the original by default
virtual void LostEnemySound( CBaseEntity *pEnemy ) { LostEnemySound(); };
virtual void FoundEnemySound( CBaseEntity *pEnemy ) { FoundEnemySound(); };
#endif
virtual void BarnacleDeathSound( void ) { CTakeDamageInfo info; PainSound( info ); }
virtual void SpeakSentence( int sentenceType ) { return; };

View File

@ -3506,6 +3506,12 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask )
// as this should only run with the NPC "receiving" the interaction
ScriptedNPCInteraction_t *pInteraction = m_hForcedInteractionPartner->GetRunningDynamicInteraction();
if ( !(pInteraction->iFlags & SCNPC_FLAG_TEST_OTHER_ANGLES) )
{
TaskComplete();
return;
}
// Get our target's origin
Vector vecTarget = m_hForcedInteractionPartner->GetAbsOrigin();

View File

@ -14,6 +14,7 @@
#include "gameinterface.h"
#ifdef MAPBASE
#include "mapbase/matchers.h"
#include "ai_memory.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
@ -133,6 +134,8 @@ ConceptInfo_t g_ConceptInfos[] =
{ TLK_TAKING_FIRE, SPEECH_IMPORTANT,-1, -1, -1, -1, -1, -1, AICF_DEFAULT, },
{ TLK_NEW_ENEMY, SPEECH_IMPORTANT,-1, -1, -1, -1, -1, -1, AICF_DEFAULT, },
{ TLK_COMBAT_IDLE, SPEECH_IMPORTANT,-1, -1, -1, -1, -1, -1, AICF_DEFAULT, },
{ TLK_LOSTENEMY, SPEECH_IMPORTANT,-1, -1, -1, -1, -1, -1, AICF_DEFAULT, },
{ TLK_REFINDENEMY, SPEECH_IMPORTANT,-1, -1, -1, -1, -1, -1, AICF_DEFAULT, },
#endif
};
@ -1426,6 +1429,28 @@ void CAI_PlayerAlly::PainSound( const CTakeDamageInfo &info )
SpeakIfAllowed( TLK_WOUND );
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
void CAI_PlayerAlly::LostEnemySound( CBaseEntity *pEnemy )
{
AI_CriteriaSet modifiers;
ModifyOrAppendEnemyCriteria( modifiers, pEnemy );
modifiers.AppendCriteria( "lastseenenemy", gpGlobals->curtime - GetEnemies()->LastTimeSeen( pEnemy ) );
SpeakIfAllowed( TLK_LOSTENEMY, modifiers );
}
//-----------------------------------------------------------------------------
void CAI_PlayerAlly::FoundEnemySound( CBaseEntity *pEnemy )
{
AI_CriteriaSet modifiers;
ModifyOrAppendEnemyCriteria( modifiers, pEnemy );
SpeakIfAllowed( TLK_REFINDENEMY, modifiers );
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Implemented to look at talk target
//-----------------------------------------------------------------------------

View File

@ -137,6 +137,8 @@
#define TLK_TAKING_FIRE "TLK_TAKING_FIRE" // Someone fired at me (regardless of whether I was hit)
#define TLK_NEW_ENEMY "TLK_NEW_ENEMY" // A new enemy appeared while combat was already in progress
#define TLK_COMBAT_IDLE "TLK_COMBAT_IDLE" // Similar to TLK_ATTACKING, but specifically for when *not* currently attacking (e.g. when in cover or reloading)
#define TLK_LOSTENEMY "TLK_LOSTENEMY" // Current enemy has eluded squad
#define TLK_REFINDENEMY "TLK_REFINDENEMY" // Found a previously eluded enemy
#endif
//-----------------------------------------------------------------------------
@ -339,6 +341,11 @@ public:
virtual void PainSound( const CTakeDamageInfo &info );
#ifdef MAPBASE
virtual void LostEnemySound( CBaseEntity *pEnemy );
virtual void FoundEnemySound( CBaseEntity *pEnemy );
#endif
//---------------------------------
// Speech & Acting
//---------------------------------

View File

@ -193,6 +193,15 @@ BEGIN_ENT_SCRIPTDESC( CBaseCombatCharacter, CBaseFlex, "The base class shared by
DEFINE_SCRIPTFUNC( EyeDirection2D, "Get the eyes' 2D direction." )
DEFINE_SCRIPTFUNC( EyeDirection3D, "Get the eyes' 3D direction." )
DEFINE_SCRIPTFUNC( LastHitGroup, "Get the last hitgroup." )
#ifdef GLOWS_ENABLE
DEFINE_SCRIPTFUNC( AddGlowEffect, "" )
DEFINE_SCRIPTFUNC( RemoveGlowEffect, "" )
DEFINE_SCRIPTFUNC( IsGlowEffectActive, "" )
DEFINE_SCRIPTFUNC( SetGlowColor, "" )
#endif
//
// Hooks
//
@ -291,6 +300,8 @@ END_SEND_TABLE();
IMPLEMENT_SERVERCLASS_ST(CBaseCombatCharacter, DT_BaseCombatCharacter)
#ifdef GLOWS_ENABLE
SendPropBool( SENDINFO( m_bGlowEnabled ) ),
SendPropVector( SENDINFO( m_GlowColor ), 8, 0, 0, 1 ),
SendPropFloat( SENDINFO( m_GlowAlpha ) ),
#endif // GLOWS_ENABLE
// Data that only gets sent to the local player.
SendPropDataTable( "bcc_localdata", 0, &REFERENCE_SEND_TABLE(DT_BCCLocalPlayerExclusive), SendProxy_SendBaseCombatCharacterLocalDataTable ),
@ -876,6 +887,8 @@ CBaseCombatCharacter::CBaseCombatCharacter( void )
#ifdef GLOWS_ENABLE
m_bGlowEnabled.Set( false );
m_GlowColor.GetForModify().Init( 0.76f, 0.76f, 0.76f );
m_GlowAlpha.Set(1.0f);
#endif // GLOWS_ENABLE
}
@ -1608,6 +1621,15 @@ void CBaseCombatCharacter::FixupBurningServerRagdoll( CBaseEntity *pRagdoll )
}
}
inline bool CBaseCombatCharacter::ShouldFadeServerRagdolls() const
{
#ifdef MAPBASE
return IsNPC() ? HasSpawnFlags( SF_NPC_FADE_CORPSE ) : true;
#else
return true;
#endif
}
bool CBaseCombatCharacter::BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags )
{
Assert( CanBecomeRagdoll() );
@ -1616,7 +1638,7 @@ bool CBaseCombatCharacter::BecomeRagdollBoogie( CBaseEntity *pKiller, const Vect
info.SetDamageForce( forceVector );
CBaseEntity *pRagdoll = CreateServerRagdoll( this, 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, true );
CBaseEntity *pRagdoll = CreateServerRagdoll( this, 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, ShouldFadeServerRagdolls() );
pRagdoll->SetCollisionBounds( CollisionProp()->OBBMins(), CollisionProp()->OBBMaxs() );
@ -1639,7 +1661,7 @@ CBaseEntity *CBaseCombatCharacter::BecomeRagdollBoogie( CBaseEntity *pKiller, co
info.SetDamageForce( forceVector );
CBaseEntity *pRagdoll = CreateServerRagdoll( this, 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, true );
CBaseEntity *pRagdoll = CreateServerRagdoll( this, 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, ShouldFadeServerRagdolls() );
pRagdoll->SetCollisionBounds( CollisionProp()->OBBMins(), CollisionProp()->OBBMaxs() );
@ -1688,7 +1710,7 @@ bool CBaseCombatCharacter::BecomeRagdoll( const CTakeDamageInfo &info, const Vec
#endif
// in single player create ragdolls on the server when the player hits someone
// with their vehicle - for more dramatic death/collisions
CBaseEntity *pRagdoll = CreateServerRagdoll( this, m_nForceBone, info2, COLLISION_GROUP_INTERACTIVE_DEBRIS, true );
CBaseEntity *pRagdoll = CreateServerRagdoll( this, m_nForceBone, info2, COLLISION_GROUP_INTERACTIVE_DEBRIS, ShouldFadeServerRagdolls() );
FixupBurningServerRagdoll( pRagdoll );
RemoveDeferred();
return true;
@ -1702,7 +1724,7 @@ bool CBaseCombatCharacter::BecomeRagdoll( const CTakeDamageInfo &info, const Vec
// Burning corpses are server-side in episodic, if we're in darkness mode
if ( IsOnFire() && HL2GameRules()->IsAlyxInDarknessMode() )
{
CBaseEntity *pRagdoll = CreateServerRagdoll( this, m_nForceBone, newinfo, COLLISION_GROUP_DEBRIS );
CBaseEntity *pRagdoll = CreateServerRagdoll( this, m_nForceBone, newinfo, COLLISION_GROUP_DEBRIS, ShouldFadeServerRagdolls() );
FixupBurningServerRagdoll( pRagdoll );
RemoveDeferred();
return true;
@ -1723,7 +1745,7 @@ bool CBaseCombatCharacter::BecomeRagdoll( const CTakeDamageInfo &info, const Vec
return false;
//FIXME: This is fairly leafy to be here, but time is short!
CBaseEntity *pRagdoll = CreateServerRagdoll( this, m_nForceBone, newinfo, COLLISION_GROUP_INTERACTIVE_DEBRIS, true );
CBaseEntity *pRagdoll = CreateServerRagdoll( this, m_nForceBone, newinfo, COLLISION_GROUP_INTERACTIVE_DEBRIS, ShouldFadeServerRagdolls() );
FixupBurningServerRagdoll( pRagdoll );
PhysSetEntityGameFlags( pRagdoll, FVPHYSICS_NO_SELF_COLLISIONS );
RemoveDeferred();
@ -1733,7 +1755,7 @@ bool CBaseCombatCharacter::BecomeRagdoll( const CTakeDamageInfo &info, const Vec
if( hl2_episodic.GetBool() && Classify() == CLASS_PLAYER_ALLY_VITAL )
{
CreateServerRagdoll( this, m_nForceBone, newinfo, COLLISION_GROUP_INTERACTIVE_DEBRIS, true );
CreateServerRagdoll( this, m_nForceBone, newinfo, COLLISION_GROUP_INTERACTIVE_DEBRIS, ShouldFadeServerRagdolls() );
RemoveDeferred();
return true;
}
@ -4087,6 +4109,12 @@ bool CBaseCombatCharacter::IsGlowEffectActive( void )
{
return m_bGlowEnabled;
}
void CBaseCombatCharacter::SetGlowColor( float red, float green, float blue, float alpha )
{
m_GlowColor.GetForModify().Init( red, green, blue );
m_GlowAlpha.Set( alpha );
}
#endif // GLOWS_ENABLE
//-----------------------------------------------------------------------------

View File

@ -350,6 +350,8 @@ public:
// A version of BecomeRagdollBoogie() that allows the color to change and returns the entity itself instead.
// In order to avoid breaking anything, it doesn't change the original function.
virtual CBaseEntity *BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags, const Vector *vecColor );
bool ShouldFadeServerRagdolls() const;
#endif
CBaseEntity *FindHealthItem( const Vector &vecPosition, const Vector &range );
@ -530,6 +532,7 @@ public:
void AddGlowEffect( void );
void RemoveGlowEffect( void );
bool IsGlowEffectActive( void );
void SetGlowColor( float red, float green, float blue, float alpha );
#endif // GLOWS_ENABLE
#ifdef INVASION_DLL
@ -574,6 +577,8 @@ public:
#ifdef GLOWS_ENABLE
protected:
CNetworkVar( bool, m_bGlowEnabled );
CNetworkVector( m_GlowColor );
CNetworkVar( float, m_GlowAlpha );
#endif // GLOWS_ENABLE
private:

View File

@ -2312,6 +2312,8 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC_NAMED( ScriptEntityToWorldTransform, "EntityToWorldTransform", "Get the entity's transform" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetPhysicsObject, "GetPhysicsObject", "Get the entity's physics object if it has one" )
DEFINE_SCRIPTFUNC_NAMED( ScriptPhysicsInitNormal, "PhysicsInitNormal", "Initializes the entity's physics object with the specified solid type, solid flags, and whether to start asleep" )
DEFINE_SCRIPTFUNC_NAMED( ScriptPhysicsDestroyObject, "PhysicsDestroyObject", "Destroys the entity's physics object" )
DEFINE_SCRIPTFUNC( ApplyAbsVelocityImpulse, "" )
DEFINE_SCRIPTFUNC( ApplyLocalAngularVelocityImpulse, "" )

View File

@ -606,6 +606,9 @@ public:
void ValidateEntityConnections();
void FireNamedOutput( const char *pszOutput, variant_t variant, CBaseEntity *pActivator, CBaseEntity *pCaller, float flDelay = 0.0f );
#ifdef MAPBASE
virtual
#endif
CBaseEntityOutput *FindNamedOutput( const char *pszOutput );
#ifdef MAPBASE_VSCRIPT
void ScriptFireOutput( const char *pszOutput, HSCRIPT hActivator, HSCRIPT hCaller, const char *szValue, float flDelay );
@ -864,6 +867,13 @@ public:
void SetAIWalkable( bool bBlocksLOS );
bool IsAIWalkable( void );
#ifdef MAPBASE
// Handle a potentially complex command from a client.
// Returns true if the command was handled successfully.
virtual bool HandleEntityCommand(CBasePlayer* pClient, KeyValues* pKeyValues) { return false; }
#endif // MAPBASE
private:
int SaveDataDescBlock( ISave &save, datamap_t *dmap );
int RestoreDataDescBlock( IRestore &restore, datamap_t *dmap );
@ -2097,6 +2107,8 @@ public:
HSCRIPT ScriptEntityToWorldTransform( void );
HSCRIPT ScriptGetPhysicsObject( void );
void ScriptPhysicsInitNormal( int nSolidType, int nSolidFlags, bool createAsleep );
void ScriptPhysicsDestroyObject() { VPhysicsDestroyObject(); }
void ScriptSetParent(HSCRIPT hParent, const char *szAttachment);
#endif

View File

@ -996,6 +996,9 @@ public:
bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
{
if (!pEntity)
return false;
if (FStrEq(STRING(m_strFilterSkin), "-1") /*m_strFilterSkin == NULL_STRING|| FStrEq(STRING(m_strFilterSkin), "")*/)
return Matcher_NamesMatch(STRING(m_iFilterModel), STRING(pEntity->GetModelName()));
else if (pEntity->GetBaseAnimating())
@ -1011,6 +1014,17 @@ public:
inputdata.value.Convert(FIELD_STRING);
m_iFilterModel = inputdata.value.StringID();
}
bool KeyValue( const char *szKeyName, const char *szValue )
{
if (FStrEq( szKeyName, "filtername" ))
{
m_iFilterModel = AllocPooledString( szValue );
return true;
}
else
return BaseClass::KeyValue( szKeyName, szValue );
}
};
LINK_ENTITY_TO_CLASS( filter_activator_model, CFilterModel );
@ -1019,7 +1033,6 @@ BEGIN_DATADESC( CFilterModel )
// Keyfields
DEFINE_KEYFIELD( m_iFilterModel, FIELD_STRING, "filtermodel" ),
DEFINE_KEYFIELD( m_iFilterModel, FIELD_STRING, "filtername" ),
DEFINE_KEYFIELD( m_strFilterSkin, FIELD_STRING, "skin" ),
END_DATADESC()

View File

@ -33,6 +33,9 @@ ConVar sk_env_headcrabcanister_shake_radius( "sk_env_headcrabcanister_shake_radi
ConVar sk_env_headcrabcanister_shake_radius_vehicle( "sk_env_headcrabcanister_shake_radius_vehicle", "2500" );
#define ENV_HEADCRABCANISTER_TRAIL_TIME 3.0f
#ifdef MAPBASE
#define RANDOM_CRAB_TYPE -1
#endif
//-----------------------------------------------------------------------------
// Spawn flags
@ -258,7 +261,22 @@ void CEnvHeadcrabCanister::Precache( void )
PrecacheScriptSound( "HeadcrabCanister.SkyboxExplosion" );
PrecacheScriptSound( "HeadcrabCanister.Open" );
#ifdef MAPBASE
if ( m_nHeadcrabType != RANDOM_CRAB_TYPE )
{
UTIL_PrecacheOther( s_pHeadcrabClass[m_nHeadcrabType] );
}
else
{
// precache all the headcrabs if we're spawning random species
for ( int i = 0; i < ARRAYSIZE( s_pHeadcrabClass ); i++ )
{
UTIL_PrecacheOther( s_pHeadcrabClass[i] );
}
}
#else
UTIL_PrecacheOther( s_pHeadcrabClass[m_nHeadcrabType] );
#endif
}
@ -733,7 +751,17 @@ void CEnvHeadcrabCanister::HeadcrabCanisterSpawnHeadcrabThink()
int nHeadCrabAttachment = LookupAttachment( "headcrab" );
if ( GetAttachment( nHeadCrabAttachment, vecSpawnPosition, vecSpawnAngles ) )
{
#ifdef MAPBASE
int iHeadcrabType = m_nHeadcrabType;
if ( m_nHeadcrabType == RANDOM_CRAB_TYPE )
{
iHeadcrabType = RandomInt( 0, ARRAYSIZE( s_pHeadcrabClass ) - 1 );
}
CBaseEntity *pEnt = CreateEntityByName( s_pHeadcrabClass[iHeadcrabType] );
#else
CBaseEntity *pEnt = CreateEntityByName( s_pHeadcrabClass[m_nHeadcrabType] );
#endif
CBaseHeadcrab *pHeadCrab = assert_cast<CBaseHeadcrab*>(pEnt);
// Necessary to get it to eject properly (don't allow the NPC

View File

@ -3617,6 +3617,20 @@ void CHL2_Player::UpdateWeaponPosture( void )
{
m_LowerWeaponTimer.Set( .3 );
VPROF( "CHL2_Player::UpdateWeaponPosture-CheckLower" );
#ifdef MAPBASE
if (m_nButtons & IN_VGUIMODE)
{
//We're over a friendly, drop our weapon
if (Weapon_Lower() == false)
{
//FIXME: We couldn't lower our weapon!
}
return;
}
#endif // MAPBASE
Vector vecAim = BaseClass::GetAutoaimVector( AUTOAIM_SCALE_DIRECT_ONLY );
const float CHECK_FRIENDLY_RANGE = 50 * 12;

View File

@ -211,6 +211,9 @@ BEGIN_DATADESC( CNPC_BaseZombie )
DEFINE_FIELD( m_fIsTorso, FIELD_BOOLEAN ),
#ifdef MAPBASE
DEFINE_KEYFIELD( m_fIsHeadless, FIELD_BOOLEAN, "Headless" ),
DEFINE_KEYFIELD( m_flMeleeReach, FIELD_FLOAT, "MeleeReach" ),
DEFINE_KEYFIELD( m_flMaxDistToSwat, FIELD_FLOAT, "MaxDistToSwat" ),
DEFINE_KEYFIELD( m_iMaxObjMassToSwat, FIELD_INTEGER, "MaxObjMassToSwat" ),
#else
DEFINE_FIELD( m_fIsHeadless, FIELD_BOOLEAN ),
#endif
@ -256,6 +259,12 @@ CNPC_BaseZombie::CNPC_BaseZombie()
// moan loop.
m_iMoanSound = g_numZombies;
#ifdef MAPBASE
m_flMeleeReach = ZOMBIE_MELEE_REACH;
m_flMaxDistToSwat = ZOMBIE_PLAYER_MAX_SWAT_DIST;
m_iMaxObjMassToSwat = ZOMBIE_MAX_PHYSOBJ_MASS;
#endif
g_numZombies++;
}
@ -295,7 +304,11 @@ bool CNPC_BaseZombie::FindNearestPhysicsObject( int iMaxMass )
float dist = VectorNormalize(vecDirToEnemy);
vecDirToEnemy.z = 0;
if( dist > ZOMBIE_PLAYER_MAX_SWAT_DIST )
#ifndef MAPBASE
if (dist > ZOMBIE_PLAYER_MAX_SWAT_DIST)
#else
if (dist > m_flMaxDistToSwat)
#endif
{
// Player is too far away. Don't bother
// trying to swat anything at them until
@ -786,7 +799,7 @@ bool CNPC_BaseZombie::ShouldBecomeTorso( const CTakeDamageInfo &info, float flDa
HeadcrabRelease_t CNPC_BaseZombie::ShouldReleaseHeadcrab( const CTakeDamageInfo &info, float flDamageThreshold )
{
#ifdef MAPBASE
if ( m_iHealth <= 0 && !m_fIsHeadless )
if ( m_iHealth <= 0 && !m_fIsHeadless && !HasSpawnFlags(SF_ZOMBIE_NO_HEADCRAB_SPAWN))
#else
if ( m_iHealth <= 0 )
#endif
@ -2154,7 +2167,11 @@ void CNPC_BaseZombie::GatherConditions( void )
// between him and the object he's heading for already.
if( gpGlobals->curtime >= m_flNextSwatScan && (m_hPhysicsEnt == NULL) )
{
#ifdef MAPBASE
FindNearestPhysicsObject(m_iMaxObjMassToSwat);
#else
FindNearestPhysicsObject( ZOMBIE_MAX_PHYSOBJ_MASS );
#endif
m_flNextSwatScan = gpGlobals->curtime + 2.0;
}
}

View File

@ -44,7 +44,8 @@ extern int AE_ZOMBIE_POUND;
#define ZOMBIE_BLOOD_BITE 3
#ifdef MAPBASE
#define SF_ZOMBIE_NO_TORSO ( 1 << 15 )
#define SF_ZOMBIE_NO_TORSO ( 1 << 15 )
#define SF_ZOMBIE_NO_HEADCRAB_SPAWN ( 1 << 16 )
#endif
@ -141,7 +142,14 @@ public:
}
int MeleeAttack1Conditions ( float flDot, float flDist );
virtual float GetClawAttackRange() const { return ZOMBIE_MELEE_REACH; }
virtual float GetClawAttackRange() const
{
#ifdef MAPBASE
return m_flMeleeReach;
#else
return ZOMBIE_MELEE_REACH;
#endif
}
// No range attacks
int RangeAttack1Conditions ( float flDot, float flDist ) { return( 0 ); }
@ -257,6 +265,12 @@ protected:
float m_flNextFlinch;
#ifdef MAPBASE
float m_flMeleeReach;
float m_flMaxDistToSwat;
int m_iMaxObjMassToSwat;
#endif
bool m_bHeadShot; // Used to determine the survival of our crab beyond our death.
//

View File

@ -378,13 +378,14 @@ void CNPC_Antlion::Spawn( void )
sInteraction01.vecRelativeOrigin = Vector(224, 0, 0);
sInteraction01.angRelativeAngles = QAngle(0, 180, 0);
//sInteraction01.iFlags |= SCNPC_FLAG_TEST_OTHER_ANGLES;
sInteraction01.iFlags |= SCNPC_FLAG_TEST_OTHER_ANGLES;
sInteraction01.iFlags |= SCNPC_FLAG_TEST_END_POSITION;
sInteraction01.vecRelativeEndPos = Vector(312, -10, 0);
sInteraction01.iTriggerMethod = SNPCINT_AUTOMATIC_IN_COMBAT;
sInteraction01.flDelay = 15.0f;
sInteraction01.iFlags |= SCNPC_FLAG_MAPBASE_ADDITION;
sInteraction01.flDistSqr = (8 * 8);
sInteraction01.flMaxAngleDiff = 180.0f; // Initiate from any angle
ScriptedNPCInteraction_t sInteraction02;
@ -393,11 +394,12 @@ void CNPC_Antlion::Spawn( void )
sInteraction02.vecRelativeOrigin = Vector(64, 0, 0);
sInteraction02.angRelativeAngles = QAngle(0, 180, 0);
//sInteraction01.iFlags |= SCNPC_FLAG_TEST_OTHER_ANGLES;
sInteraction02.iFlags |= SCNPC_FLAG_TEST_OTHER_ANGLES;
sInteraction02.iTriggerMethod = SNPCINT_AUTOMATIC_IN_COMBAT;
sInteraction02.flDelay = 7.5f;
sInteraction02.iFlags |= SCNPC_FLAG_MAPBASE_ADDITION;
sInteraction02.flDistSqr = (8 * 8);
sInteraction02.flMaxAngleDiff = 180.0f; // Initiate from any angle
AddScriptedNPCInteraction(&sInteraction01);

View File

@ -3145,13 +3145,22 @@ void CNPC_Combine::PainSound ( void )
// Input :
// Output :
//-----------------------------------------------------------------------------
#ifdef MAPBASE
void CNPC_Combine::LostEnemySound( CBaseEntity *pEnemy )
#else
void CNPC_Combine::LostEnemySound( void)
#endif
{
if ( gpGlobals->curtime <= m_flNextLostSoundTime )
return;
#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM
if (SpeakIfAllowed( TLK_CMB_LOSTENEMY, UTIL_VarArgs("lastseenenemy:%d", GetEnemyLastTimeSeen()) ))
AI_CriteriaSet modifiers;
ModifyOrAppendEnemyCriteria( modifiers, pEnemy );
modifiers.AppendCriteria( "lastseenenemy", gpGlobals->curtime - GetEnemies()->LastTimeSeen( pEnemy ) );
if (SpeakIfAllowed( TLK_CMB_LOSTENEMY, modifiers ))
{
m_flNextLostSoundTime = gpGlobals->curtime + random->RandomFloat(5.0,15.0);
}
@ -3179,10 +3188,17 @@ void CNPC_Combine::LostEnemySound( void)
// Input :
// Output :
//-----------------------------------------------------------------------------
#ifdef MAPBASE
void CNPC_Combine::FoundEnemySound( CBaseEntity *pEnemy )
#else
void CNPC_Combine::FoundEnemySound( void)
#endif
{
#ifdef COMBINE_SOLDIER_USES_RESPONSE_SYSTEM
SpeakIfAllowed( TLK_CMB_REFINDENEMY, SENTENCE_PRIORITY_HIGH );
AI_CriteriaSet modifiers;
ModifyOrAppendEnemyCriteria( modifiers, pEnemy );
SpeakIfAllowed( TLK_CMB_REFINDENEMY, modifiers, SENTENCE_PRIORITY_HIGH );
#else
m_Sentences.Speak( "COMBINE_REFIND_ENEMY", SENTENCE_PRIORITY_HIGH );
#endif

View File

@ -181,8 +181,13 @@ public:
#endif
void IdleSound( void );
void AlertSound( void );
#ifdef MAPBASE
void LostEnemySound( CBaseEntity *pEnemy );
void FoundEnemySound( CBaseEntity *pEnemy );
#else
void LostEnemySound( void );
void FoundEnemySound( void );
#endif
void AnnounceAssault( void );
void AnnounceEnemyType( CBaseEntity *pEnemy );
void AnnounceEnemyKill( CBaseEntity *pEnemy );

View File

@ -534,10 +534,12 @@ void CNPC_MetroPolice::OnScheduleChange()
{
BaseClass::OnScheduleChange();
#ifndef MAPBASE // Moved to Event_KilledOther()
if ( GetEnemy() && HasCondition( COND_ENEMY_DEAD ) )
{
AnnounceEnemyKill( GetEnemy() );
}
#endif
}
@ -2938,7 +2940,11 @@ void CNPC_MetroPolice::DeathSound( const CTakeDamageInfo &info )
// Input :
// Output :
//-----------------------------------------------------------------------------
#ifdef MAPBASE
void CNPC_MetroPolice::LostEnemySound( CBaseEntity *pEnemy )
#else
void CNPC_MetroPolice::LostEnemySound( void)
#endif
{
// Don't announce enemies when the player isn't a criminal
if ( !PlayerIsCriminal() )
@ -2948,7 +2954,12 @@ void CNPC_MetroPolice::LostEnemySound( void)
return;
#ifdef METROPOLICE_USES_RESPONSE_SYSTEM
if (SpeakIfAllowed(TLK_COP_LOSTENEMY))
AI_CriteriaSet modifiers;
ModifyOrAppendEnemyCriteria( modifiers, pEnemy );
modifiers.AppendCriteria( "lastseenenemy", gpGlobals->curtime - GetEnemies()->LastTimeSeen( pEnemy ) );
if (SpeakIfAllowed(TLK_COP_LOSTENEMY, modifiers ))
{
m_flNextLostSoundTime = gpGlobals->curtime + random->RandomFloat(5.0,15.0);
}
@ -2977,14 +2988,21 @@ void CNPC_MetroPolice::LostEnemySound( void)
// Input :
// Output :
//-----------------------------------------------------------------------------
#ifdef MAPBASE
void CNPC_MetroPolice::FoundEnemySound( CBaseEntity *pEnemy )
#else
void CNPC_MetroPolice::FoundEnemySound( void)
#endif
{
// Don't announce enemies when I'm in arrest behavior
if ( HasSpawnFlags( SF_METROPOLICE_ARREST_ENEMY ) )
return;
#ifdef METROPOLICE_USES_RESPONSE_SYSTEM
SpeakIfAllowed( TLK_COP_REFINDENEMY, SENTENCE_PRIORITY_HIGH );
AI_CriteriaSet modifiers;
ModifyOrAppendEnemyCriteria( modifiers, pEnemy );
SpeakIfAllowed( TLK_COP_REFINDENEMY, modifiers, SENTENCE_PRIORITY_HIGH );
#else
m_Sentences.Speak( "METROPOLICE_REFIND_ENEMY", SENTENCE_PRIORITY_HIGH );
#endif
@ -3706,6 +3724,21 @@ void CNPC_MetroPolice::Event_Killed( const CTakeDamageInfo &info )
BaseClass::Event_Killed( info );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CNPC_MetroPolice::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info )
{
BaseClass::Event_KilledOther( pVictim, info );
#ifdef MAPBASE // Moved from OnScheduleChange()
if ( pVictim && (pVictim->IsPlayer() || pVictim->IsNPC()) )
{
AnnounceEnemyKill( pVictim );
}
#endif
}
//-----------------------------------------------------------------------------
// Try to enter a slot where we shoot a pistol
//-----------------------------------------------------------------------------

View File

@ -79,6 +79,8 @@ public:
virtual void Event_Killed( const CTakeDamageInfo &info );
virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info );
virtual void OnScheduleChange();
float GetIdealAccel( void ) const;
@ -170,8 +172,13 @@ private:
void SpeakAssaultSentence( int nSentenceType );
void SpeakStandoffSentence( int nSentenceType );
#ifdef MAPBASE
virtual void LostEnemySound( CBaseEntity *pEnemy );
virtual void FoundEnemySound( CBaseEntity *pEnemy );
#else
virtual void LostEnemySound( void );
virtual void FoundEnemySound( void );
#endif
virtual void AlertSound( void );
virtual void PainSound( const CTakeDamageInfo &info );
virtual void DeathSound( const CTakeDamageInfo &info );

View File

@ -152,6 +152,9 @@ BEGIN_DATADESC( CNPC_FloorTurret )
DEFINE_OUTPUT( m_OnTipped, "OnTipped" ),
DEFINE_OUTPUT( m_OnPhysGunPickup, "OnPhysGunPickup" ),
DEFINE_OUTPUT( m_OnPhysGunDrop, "OnPhysGunDrop" ),
#ifdef MAPBASE
DEFINE_OUTPUT( m_OnStartTipped, "OnStartTipped" ),
#endif
DEFINE_BASENPCINTERACTABLE_DATADESC(),
@ -1526,6 +1529,10 @@ bool CNPC_FloorTurret::PreThink( turretState_e state )
SetEyeState( TURRET_EYE_DEAD );
}
#ifdef MAPBASE
m_OnStartTipped.FireOutput( this, this );
#endif
//Stop being targetted
SetState( NPC_STATE_DEAD );
m_lifeState = LIFE_DEAD;

View File

@ -265,6 +265,9 @@ protected:
COutputEvent m_OnTipped;
COutputEvent m_OnPhysGunPickup;
COutputEvent m_OnPhysGunDrop;
#ifdef MAPBASE
COutputEvent m_OnStartTipped;
#endif
bool m_bHackedByAlyx;
HSOUNDSCRIPTHANDLE m_ShotSounds;

View File

@ -1080,6 +1080,113 @@ void CPropCombineBall::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t R
StopAnimating();
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPropCombineBall::SpawnerDestroyed( CBaseEntity *pActivator, bool *bSeekEnemy )
{
SetState( STATE_THROWN );
WhizSoundThink();
m_bHeld = false;
m_bLaunched = true;
// Stop with the dissolving
SetContextThink( NULL, gpGlobals->curtime, s_pHoldDissolveContext );
// We're ready to start colliding again.
SetCollisionGroup( HL2COLLISION_GROUP_COMBINE_BALL );
if ( m_pGlowTrail )
{
m_pGlowTrail->TurnOn();
m_pGlowTrail->SetRenderColor( 255, 255, 255, 255 );
}
// Set our desired speed to be launched at
SetSpeed( 1500.0f );
SetOwnerEntity( pActivator );
SetWeaponLaunched( false );
if (!VPhysicsGetObject())
return;
if (pActivator->IsPlayer())
{
PhysClearGameFlags( VPhysicsGetObject(), FVPHYSICS_NO_NPC_IMPACT_DMG );
PhysSetGameFlags( VPhysicsGetObject(), FVPHYSICS_DMG_DISSOLVE | FVPHYSICS_HEAVY_OBJECT );
}
else
{
// Don't do impact damage. Just touch them and do your dissolve damage and move on.
PhysSetGameFlags( VPhysicsGetObject(), FVPHYSICS_NO_NPC_IMPACT_DMG );
}
//if (pActivator->IsPlayer())
//{
// SetPlayerLaunched( ToBasePlayer( pActivator ) );
//}
Vector vecVelocity;
if (bSeekEnemy)
{
CBaseEntity *pBestTarget = NULL;
CBaseEntity *list[256];
float distance;
float flBestDist = MAX_COORD_FLOAT;
int nCount = UTIL_EntitiesInSphere( list, 256, GetAbsOrigin(), sk_combine_ball_search_radius.GetFloat(), FL_NPC | FL_CLIENT );
for ( int i = 0; i < nCount; i++ )
{
if ( !IsAttractiveTarget( list[i] ) )
continue;
distance = (list[i]->WorldSpaceCenter() - GetAbsOrigin()).LengthSqr();
if ( distance < flBestDist )
{
pBestTarget = list[i];
flBestDist = distance;
}
}
if ( pBestTarget )
{
VectorSubtract( pBestTarget->WorldSpaceCenter(), GetAbsOrigin(), vecVelocity );
VectorNormalize( vecVelocity );
}
*bSeekEnemy = (pBestTarget != NULL);
}
if (bSeekEnemy == NULL || *bSeekEnemy == false)
{
// Choose a random direction based on current velocity
VPhysicsGetObject()->GetVelocity( &vecVelocity, NULL );
VectorNormalize( vecVelocity );
QAngle shotAng;
VectorAngles( vecVelocity, shotAng );
// Offset by some small cone
shotAng[PITCH] += random->RandomInt( -75, 75 );
shotAng[YAW] += random->RandomInt( -75, 75 );
AngleVectors( shotAng, &vecVelocity, NULL, NULL );
}
vecVelocity *= GetSpeed();
VPhysicsGetObject()->SetVelocity( &vecVelocity, &vec3_origin );
SetBallAsLaunched();
StopAnimating();
}
#endif
//------------------------------------------------------------------------------
// Stop looping sounds
//------------------------------------------------------------------------------
@ -1849,6 +1956,9 @@ BEGIN_DATADESC( CFuncCombineBallSpawner )
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
#ifdef MAPBASE
DEFINE_INPUTFUNC( FIELD_VOID, "Destroy", InputDestroy ),
#endif
DEFINE_OUTPUT( m_OnBallGrabbed, "OnBallGrabbed" ),
DEFINE_OUTPUT( m_OnBallReinserted, "OnBallReinserted" ),
@ -2001,6 +2111,35 @@ void CFuncCombineBallSpawner::InputDisable( inputdata_t &inputdata )
SetThink( NULL );
}
#ifdef MAPBASE
void CFuncCombineBallSpawner::InputDestroy( inputdata_t &inputdata )
{
if ( !m_bEnabled )
{
UTIL_Remove( this );
return;
}
// One ball always seeks the nearest enemy
bool bSoughtEnemy = false;
CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, "prop_combine_ball" );
while (pEnt)
{
CPropCombineBall *pBall = static_cast<CPropCombineBall*>(pEnt);
if (pBall && pBall->GetSpawner() == this)
{
BallGrabbed( pBall );
pBall->SpawnerDestroyed( inputdata.pActivator, bSoughtEnemy ? NULL : &bSoughtEnemy );
}
pEnt = gEntList.FindEntityByClassname( pEnt, "prop_combine_ball" );
}
UTIL_Remove( this );
}
#endif
//-----------------------------------------------------------------------------
// Choose a random point inside the cylinder

View File

@ -98,6 +98,9 @@ public:
void SetSpawner( CFuncCombineBallSpawner *pSpawner ) { m_hSpawner = pSpawner; }
void NotifySpawnerOfRemoval( void );
#ifdef MAPBASE
void SpawnerDestroyed( CBaseEntity *pActivator, bool *bSeekEnemy );
#endif
float LastCaptureTime() const;
@ -243,6 +246,9 @@ private:
// Input
void InputEnable( inputdata_t &inputdata );
void InputDisable( inputdata_t &inputdata );
#ifdef MAPBASE
void InputDestroy( inputdata_t &inputdata );
#endif
// Fire ball grabbed output
void GrabBallTouch( CBaseEntity *pOther );

View File

@ -568,10 +568,13 @@ void CFlare::Start( float lifeTime )
//-----------------------------------------------------------------------------
void CFlare::Die( float fadeTime )
{
m_flTimeBurnOut = gpGlobals->curtime + fadeTime;
if (m_bInActiveList)
{
m_flTimeBurnOut = gpGlobals->curtime + fadeTime;
SetThink( &CFlare::FlareThink );
SetNextThink( gpGlobals->curtime + 0.1f );
SetThink(&CFlare::FlareThink);
SetNextThink(gpGlobals->curtime + 0.1f);
}
}
//-----------------------------------------------------------------------------

View File

@ -490,6 +490,9 @@ public:
float GetLoadWeight( void ) const { return m_flLoadWeight; }
void SetAngleAlignment( float alignAngleCosine ) { m_angleAlignment = alignAngleCosine; }
void SetIgnorePitch( bool bIgnore ) { m_bIgnoreRelativePitch = bIgnore; }
#ifdef MAPBASE
void SetDontUseListMass( bool bDontUse ) { m_bDontUseListMass = bDontUse; }
#endif
QAngle TransformAnglesToPlayerSpace( const QAngle &anglesIn, CBasePlayer *pPlayer );
QAngle TransformAnglesFromPlayerSpace( const QAngle &anglesIn, CBasePlayer *pPlayer );
@ -531,6 +534,12 @@ private:
// NVNT player controlling this grab controller
CBasePlayer* m_pControllingPlayer;
#ifdef MAPBASE
// Prevents using the added mass of every part of the object
// (not saved due to only being used upon attach)
bool m_bDontUseListMass;
#endif
friend class CWeaponPhysCannon;
};
@ -581,6 +590,9 @@ CGrabController::CGrabController( void )
m_flDistanceOffset = 0;
// NVNT constructing m_pControllingPlayer to NULL
m_pControllingPlayer = NULL;
#ifdef MAPBASE
m_bDontUseListMass = false;
#endif
}
CGrabController::~CGrabController( void )
@ -783,12 +795,18 @@ void CGrabController::AttachEntity( CBasePlayer *pPlayer, CBaseEntity *pEntity,
{
float mass = pList[i]->GetMass();
pList[i]->GetDamping( NULL, &m_savedRotDamping[i] );
m_flLoadWeight += mass;
m_savedMass[i] = mass;
// reduce the mass to prevent the player from adding crazy amounts of energy to the system
pList[i]->SetMass( REDUCED_CARRY_MASS / flFactor );
pList[i]->SetDamping( NULL, &damping );
#ifdef MAPBASE
if (!m_bDontUseListMass || pList[i] == pPhys)
#endif
{
m_flLoadWeight += mass;
// reduce the mass to prevent the player from adding crazy amounts of energy to the system
pList[i]->SetMass( REDUCED_CARRY_MASS / flFactor );
pList[i]->SetDamping( NULL, &damping );
}
}
// NVNT setting m_pControllingPlayer to the player attached
@ -1077,7 +1095,24 @@ void CPlayerPickupController::Init( CBasePlayer *pPlayer, CBaseEntity *pObject )
Pickup_OnPhysGunPickup( pObject, m_pPlayer, PICKED_UP_BY_PLAYER );
#ifdef MAPBASE
bool bUseGrabPos = false;
Vector vecGrabPos;
if ( dynamic_cast<CRagdollProp*>( pObject ) )
{
m_grabController.SetDontUseListMass( true );
// Approximate where we're grabbing from
vecGrabPos = pPlayer->EyePosition() + (pPlayer->EyeDirection3D() * 16.0f);
bUseGrabPos = true;
}
else
m_grabController.SetDontUseListMass( false );
m_grabController.AttachEntity( pPlayer, pObject, pPhysics, false, vecGrabPos, bUseGrabPos );
#else
m_grabController.AttachEntity( pPlayer, pObject, pPhysics, false, vec3_origin, false );
#endif
// NVNT apply a downward force to simulate the mass of the held object.
#if defined( WIN32 ) && !defined( _X360 )
HapticSetConstantForce(m_pPlayer,clamp(m_grabController.GetLoadWeight()*0.1,1,6)*Vector(0,-1,0));
@ -2723,6 +2758,11 @@ CWeaponPhysCannon::FindObjectResult_t CWeaponPhysCannon::FindObject( void )
pullDir *= (mass + 0.5) * (1/50.0f);
}
CPhysicsProp* pProp = dynamic_cast<CPhysicsProp*>(pObj);
if (pProp) {
pProp->OnPhysGunPull( pOwner );
}
// Nudge it towards us
pObj->ApplyForceCenter( pullDir );
return OBJECT_NOT_FOUND;

View File

@ -107,7 +107,7 @@ public:
virtual void ReleaseData(const void* pData) const
{
delete pData;
delete (Data*)pData;
}
};

View File

@ -30,6 +30,8 @@
#ifdef MAPBASE
ConVar ragdoll_autointeractions("ragdoll_autointeractions", "1", FCVAR_NONE, "Controls whether we should rely on hardcoded keyvalues or automatic flesh checks for ragdoll physgun interactions.");
#define IsBody() VPhysicsIsFlesh()
ConVar ragdoll_always_allow_use( "ragdoll_always_allow_use", "0", FCVAR_NONE, "Allows all ragdolls to be used and, if they aren't explicitly set to prevent pickup, picked up." );
#endif
//-----------------------------------------------------------------------------
@ -58,6 +60,8 @@ const float ATTACHED_DAMPING_SCALE = 50.0f;
#define SF_RAGDOLLPROP_STARTASLEEP 0x10000
#ifdef MAPBASE
#define SF_RAGDOLLPROP_FIXED_CONSTRAINTS 0x20000
#define SF_RAGDOLLPROP_ALLOW_USE 0x40000
#define SF_RAGDOLLPROP_PREVENT_PICKUP 0x80000
#endif
//-----------------------------------------------------------------------------
@ -104,6 +108,8 @@ BEGIN_DATADESC(CRagdollProp)
#ifdef MAPBASE
DEFINE_INPUTFUNC( FIELD_VOID, "Wake", InputWake ),
DEFINE_INPUTFUNC( FIELD_VOID, "Sleep", InputSleep ),
DEFINE_INPUTFUNC( FIELD_VOID, "AddToLRU", InputAddToLRU ),
DEFINE_INPUTFUNC( FIELD_VOID, "RemoveFromLRU", InputRemoveFromLRU ),
#endif
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputTurnOn ),
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputTurnOff ),
@ -125,6 +131,10 @@ BEGIN_DATADESC(CRagdollProp)
DEFINE_FIELD( m_strSourceClassName, FIELD_STRING ),
DEFINE_FIELD( m_bHasBeenPhysgunned, FIELD_BOOLEAN ),
#ifdef MAPBASE
DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse" ),
#endif
// think functions
DEFINE_THINKFUNC( SetDebrisThink ),
DEFINE_THINKFUNC( ClearFlagsThink ),
@ -334,9 +344,39 @@ void CRagdollProp::Precache( void )
int CRagdollProp::ObjectCaps()
{
return BaseClass::ObjectCaps() | FCAP_WCEDIT_POSITION;
int caps = FCAP_WCEDIT_POSITION;
#ifdef MAPBASE
if (HasSpawnFlags( SF_RAGDOLLPROP_ALLOW_USE ) || ragdoll_always_allow_use.GetBool())
caps |= FCAP_IMPULSE_USE;
#endif
return BaseClass::ObjectCaps() | caps;
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pActivator -
// *pCaller -
// useType -
// value -
//-----------------------------------------------------------------------------
void CRagdollProp::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
CBasePlayer *pPlayer = ToBasePlayer( pActivator );
if (pPlayer)
{
m_OnPlayerUse.FireOutput( pActivator, this );
if (!HasSpawnFlags( SF_RAGDOLLPROP_PREVENT_PICKUP ))
{
pPlayer->PickupObject( this, false );
}
}
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
@ -405,7 +445,7 @@ void CRagdollProp::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t r
m_bHasBeenPhysgunned = true;
#ifdef MAPBASE
if( (ragdoll_autointeractions.GetBool() == true && IsBody()) || HasPhysgunInteraction( "onpickup", "boogie" ) )
if( ((ragdoll_autointeractions.GetBool() == true && IsBody()) || HasPhysgunInteraction( "onpickup", "boogie" )) && reason != PICKED_UP_BY_PLAYER )
#else
if( HasPhysgunInteraction( "onpickup", "boogie" ) )
#endif
@ -447,7 +487,7 @@ void CRagdollProp::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reaso
m_flLastPhysicsInfluenceTime = gpGlobals->curtime;
#ifdef MAPBASE
if( (ragdoll_autointeractions.GetBool() == true && IsBody()) || HasPhysgunInteraction( "onpickup", "boogie" ) )
if( ((ragdoll_autointeractions.GetBool() == true && IsBody()) || HasPhysgunInteraction( "onpickup", "boogie" )) && (Reason != DROPPED_BY_PLAYER && Reason != THROWN_BY_PLAYER) )
#else
if( HasPhysgunInteraction( "onpickup", "boogie" ) )
#endif
@ -1844,6 +1884,24 @@ void CRagdollProp::InputSleep( inputdata_t &inputdata )
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Adds ragdoll to LRU.
//-----------------------------------------------------------------------------
void CRagdollProp::InputAddToLRU( inputdata_t &inputdata )
{
AddSpawnFlags( SF_RAGDOLLPROP_USE_LRU_RETIREMENT );
s_RagdollLRU.MoveToTopOfLRU( this );
}
//-----------------------------------------------------------------------------
// Purpose: Removes ragdoll from LRU.
//-----------------------------------------------------------------------------
void CRagdollProp::InputRemoveFromLRU( inputdata_t &inputdata )
{
RemoveSpawnFlags( SF_RAGDOLLPROP_USE_LRU_RETIREMENT );
s_RagdollLRU.RemoveFromLRU( this );
}
#endif
void CRagdollProp::InputTurnOn( inputdata_t &inputdata )

View File

@ -42,6 +42,10 @@ public:
int ObjectCaps();
#ifdef MAPBASE
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
#endif
DECLARE_SERVERCLASS();
// Don't treat as a live target
virtual bool IsAlive( void ) { return false; }
@ -113,6 +117,8 @@ public:
#ifdef MAPBASE
void InputWake( inputdata_t &inputdata );
void InputSleep( inputdata_t &inputdata );
void InputAddToLRU( inputdata_t &inputdata );
void InputRemoveFromLRU( inputdata_t &inputdata );
#endif
void InputTurnOn( inputdata_t &inputdata );
void InputTurnOff( inputdata_t &inputdata );
@ -158,6 +164,10 @@ private:
string_t m_strSourceClassName;
bool m_bHasBeenPhysgunned;
#ifdef MAPBASE
COutputEvent m_OnPlayerUse;
#endif
// If not 1, then allow underlying sequence to blend in with simulated bone positions
CNetworkVar( float, m_flBlendWeight );
CNetworkVar( int, m_nOverlaySequence );

View File

@ -498,6 +498,7 @@ END_DATADESC()
#ifdef MAPBASE_VSCRIPT
// TODO: Better placement?
ScriptHook_t g_Hook_PlayerRunCommand;
ScriptHook_t g_Hook_FindUseEntity;
BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." )
@ -553,6 +554,9 @@ BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetViewModel, "GetViewModel", "Returns the viewmodel of the specified index." )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetUseEntity, "GetUseEntity", "Gets the player's current use entity." )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetHeldObject, "GetHeldObject", "Gets the player's currently held object IF it is being held by a gravity gun. To check for the player's held +USE object, use the standalone GetPlayerHeldEntity function." )
//
// Hooks
//
@ -560,6 +564,11 @@ BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." )
DEFINE_SCRIPTHOOK_PARAM( "command", FIELD_HSCRIPT )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( g_Hook_FindUseEntity, "FindUseEntity", FIELD_HSCRIPT, "Called when finding an entity to use. The 'entity' parameter is for the entity found by the default function. If 'is_radius' is true, then this entity was found by searching in a radius around the cursor, rather than being directly used. Return a different entity to use something else." )
DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT )
DEFINE_SCRIPTHOOK_PARAM( "is_radius", FIELD_BOOLEAN )
END_SCRIPTHOOK()
END_SCRIPTDESC();
#else
BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseAnimating, "The player entity." )

View File

@ -414,6 +414,9 @@ public:
const Vector& ScriptGetEyeUp() { static Vector vecUp; EyeVectors( NULL, NULL, &vecUp ); return vecUp; }
HSCRIPT ScriptGetViewModel( int viewmodelindex );
HSCRIPT ScriptGetUseEntity() { return ToHScript( GetUseEntity() ); }
HSCRIPT ScriptGetHeldObject() { return ToHScript( GetHeldObject() ); }
#endif
// View model prediction setup

View File

@ -62,6 +62,7 @@ private:
private:
bool m_bSpotlightOn;
bool m_bEfficientSpotlight;
bool m_bIgnoreSolid;
Vector m_vSpotlightTargetPos;
Vector m_vSpotlightCurrentPos;
Vector m_vSpotlightDir;
@ -100,6 +101,7 @@ BEGIN_DATADESC( CPointSpotlight )
DEFINE_FIELD( m_vSpotlightDir, FIELD_VECTOR ),
DEFINE_FIELD( m_nHaloSprite, FIELD_INTEGER ),
DEFINE_KEYFIELD( m_bIgnoreSolid, FIELD_BOOLEAN, "IgnoreSolid" ),
DEFINE_KEYFIELD( m_flSpotlightMaxLength,FIELD_FLOAT, "SpotlightLength"),
DEFINE_KEYFIELD( m_flSpotlightGoalWidth,FIELD_FLOAT, "SpotlightWidth"),
DEFINE_KEYFIELD( m_flHDRColorScale, FIELD_FLOAT, "HDRColorScale" ),
@ -138,6 +140,7 @@ CPointSpotlight::CPointSpotlight()
#endif
m_flHDRColorScale = 1.0f;
m_nMinDXLevel = 0;
m_bIgnoreSolid = false;
#ifdef MAPBASE
m_flHaloScale = 60.0f;
#endif
@ -380,12 +383,21 @@ void CPointSpotlight::SpotlightCreate(void)
AngleVectors( GetAbsAngles(), &m_vSpotlightDir );
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
Vector vTargetPos;
if ( m_bIgnoreSolid )
{
vTargetPos = GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength;
}
else
{
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
vTargetPos = tr.endpos;
}
m_hSpotlightTarget = (CSpotlightEnd*)CreateEntityByName( "spotlight_end" );
m_hSpotlightTarget->Spawn();
m_hSpotlightTarget->SetAbsOrigin( tr.endpos );
m_hSpotlightTarget->SetAbsOrigin( vTargetPos );
m_hSpotlightTarget->SetOwnerEntity( this );
m_hSpotlightTarget->m_clrRender = m_clrRender;
m_hSpotlightTarget->m_Radius = m_flSpotlightMaxLength;
@ -437,9 +449,17 @@ Vector CPointSpotlight::SpotlightCurrentPos(void)
AngleVectors( GetAbsAngles(), &m_vSpotlightDir );
// Get beam end point. Only collide with solid objects, not npcs
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + (m_vSpotlightDir * 2 * m_flSpotlightMaxLength), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
return tr.endpos;
Vector vEndPos = GetAbsOrigin() + ( m_vSpotlightDir * 2 * m_flSpotlightMaxLength );
if ( m_bIgnoreSolid )
{
return vEndPos;
}
else
{
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), vEndPos, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
return tr.endpos;
}
}
//------------------------------------------------------------------------------

View File

@ -1338,6 +1338,12 @@ int CBreakableProp::OnTakeDamage( const CTakeDamageInfo &inputInfo )
//-----------------------------------------------------------------------------
void CBreakableProp::Event_Killed( const CTakeDamageInfo &info )
{
#ifdef MAPBASE_VSCRIPT
// False = Cheat death
if (ScriptDeathHook( const_cast<CTakeDamageInfo *>(&info) ) == false)
return;
#endif
IPhysicsObject *pPhysics = VPhysicsGetObject();
if ( pPhysics && !pPhysics->IsMoveable() )
{
@ -3021,6 +3027,7 @@ BEGIN_DATADESC( CPhysicsProp )
DEFINE_OUTPUT( m_MotionEnabled, "OnMotionEnabled" ),
DEFINE_OUTPUT( m_OnPhysGunPickup, "OnPhysGunPickup" ),
DEFINE_OUTPUT( m_OnPhysGunOnlyPickup, "OnPhysGunOnlyPickup" ),
DEFINE_OUTPUT( m_OnPhysGunPull, "OnPhysGunPull" ),
DEFINE_OUTPUT( m_OnPhysGunPunt, "OnPhysGunPunt" ),
DEFINE_OUTPUT( m_OnPhysGunDrop, "OnPhysGunDrop" ),
DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse" ),
@ -3391,6 +3398,13 @@ void CPhysicsProp::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t r
CheckRemoveRagdolls();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPhysicsProp::OnPhysGunPull( CBasePlayer* pPhysGunUser ) {
m_OnPhysGunPull.FireOutput(pPhysGunUser, this);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
@ -4198,6 +4212,12 @@ BEGIN_DATADESC(CBasePropDoor)
#ifdef MAPBASE
DEFINE_INPUTFUNC(FIELD_VOID, "AllowPlayerUse", InputAllowPlayerUse),
DEFINE_INPUTFUNC(FIELD_VOID, "DisallowPlayerUse", InputDisallowPlayerUse),
DEFINE_INPUTFUNC( FIELD_STRING, "SetFullyOpenSound", InputSetFullyOpenSound ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetFullyClosedSound", InputSetFullyClosedSound ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetMovingSound", InputSetMovingSound ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetLockedSound", InputSetLockedSound ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetUnlockedSound", InputSetUnlockedSound ),
#endif
DEFINE_OUTPUT(m_OnBlockedOpening, "OnBlockedOpening"),
@ -4220,6 +4240,34 @@ END_DATADESC()
IMPLEMENT_SERVERCLASS_ST(CBasePropDoor, DT_BasePropDoor)
END_SEND_TABLE()
#ifdef MAPBASE_VSCRIPT
BEGIN_ENT_SCRIPTDESC( CBasePropDoor, CBaseAnimating, "The base class used by prop doors, such as prop_door_rotating." )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsDoorOpen, "IsDoorOpen", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsDoorAjar, "IsDoorAjar", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsDoorOpening, "IsDoorOpening", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsDoorClosed, "IsDoorClosed", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsDoorClosing, "IsDoorClosing", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsDoorLocked, "IsDoorLocked", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsDoorBlocked, "IsDoorBlocked", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetActivator, "GetActivator", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetDoorList, "GetDoorList", "Get connected door entity by index." )
DEFINE_SCRIPTFUNC( GetDoorListCount, "Get number of connected doors." )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetFullyOpenSound, "GetFullyOpenSound", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetFullyClosedSound, "GetFullyClosedSound", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetMovingSound, "GetMovingSound", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetLockedSound, "GetLockedSound", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetUnlockedSound, "GetUnlockedSound", "" )
DEFINE_SCRIPTFUNC( DoorCanClose, "Return true if the door has room to close. Boolean is for whether or not this is an automatic close and not manually triggered by someone." )
DEFINE_SCRIPTFUNC( DoorCanOpen, "Return true if there are other doors connected to this one." )
DEFINE_SCRIPTFUNC( HasSlaves, "" )
END_SCRIPTDESC();
#endif
CBasePropDoor::CBasePropDoor( void )
{
m_hMaster = NULL;
@ -4693,6 +4741,54 @@ void CBasePropDoor::InputOpenAwayFrom(inputdata_t &inputdata)
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBasePropDoor::InputSetFullyOpenSound( inputdata_t &inputdata )
{
m_SoundOpen = inputdata.value.StringID();
PrecacheScriptSound( STRING( m_SoundOpen ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBasePropDoor::InputSetFullyClosedSound( inputdata_t &inputdata )
{
m_SoundClose = inputdata.value.StringID();
PrecacheScriptSound( STRING( m_SoundClose ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBasePropDoor::InputSetMovingSound( inputdata_t &inputdata )
{
m_SoundMoving = inputdata.value.StringID();
PrecacheScriptSound( STRING( m_SoundMoving ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBasePropDoor::InputSetLockedSound( inputdata_t &inputdata )
{
m_ls.sLockedSound = inputdata.value.StringID();
PrecacheScriptSound( STRING( m_ls.sLockedSound ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBasePropDoor::InputSetUnlockedSound( inputdata_t &inputdata )
{
m_ls.sUnlockedSound = inputdata.value.StringID();
PrecacheScriptSound( STRING( m_ls.sUnlockedSound ) );
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//

View File

@ -413,6 +413,7 @@ public:
void EnableMotion( void );
bool CanBePickedUpByPhyscannon( void );
void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
void OnPhysGunPull( CBasePlayer *pPhysGunUser );
void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t reason );
bool GetPropDataAngles( const char *pKeyName, QAngle &vecAngles );
@ -446,6 +447,7 @@ private:
COutputEvent m_OnPhysGunPickup;
COutputEvent m_OnPhysGunPunt;
COutputEvent m_OnPhysGunOnlyPickup;
COutputEvent m_OnPhysGunPull;
COutputEvent m_OnPhysGunDrop;
COutputEvent m_OnPlayerUse;
COutputEvent m_OnPlayerPickup;

View File

@ -5298,6 +5298,23 @@ float GetSceneDuration( char const *pszScene )
{
msecs = cachedData.msecs;
}
#ifdef MAPBASE
else
{
// Raw scene file support
void *pBuffer = NULL;
if (filesystem->ReadFileEx( pszScene, "MOD", &pBuffer, true ))
{
g_TokenProcessor.SetBuffer((char*)pBuffer);
CChoreoScene *pScene = ChoreoLoadScene( pszScene, NULL, &g_TokenProcessor, LocalScene_Printf );
g_TokenProcessor.SetBuffer(NULL);
float flDuration = pScene->GetDuration();
delete pScene;
return flDuration;
}
}
#endif
return (float)msecs * 0.001f;
}

View File

@ -113,6 +113,9 @@ BEGIN_DATADESC( CAI_ScriptedSequence )
DEFINE_INPUTFUNC( FIELD_VOID, "MoveToPosition", InputMoveToPosition ),
DEFINE_INPUTFUNC( FIELD_VOID, "BeginSequence", InputBeginSequence ),
DEFINE_INPUTFUNC( FIELD_VOID, "CancelSequence", InputCancelSequence ),
#ifdef MAPBASE
DEFINE_INPUTFUNC( FIELD_VOID, "StopActionLoop", InputStopActionLoop ),
#endif
DEFINE_KEYFIELD( m_iPlayerDeathBehavior, FIELD_INTEGER, "onplayerdeath" ),
DEFINE_INPUTFUNC( FIELD_VOID, "ScriptPlayerDeath", InputScriptPlayerDeath ),
@ -382,6 +385,14 @@ void CAI_ScriptedSequence::InputSetTarget( inputdata_t &inputdata )
m_iszEntity = AllocPooledString(inputdata.value.String());
m_hTargetEnt = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAI_ScriptedSequence::InputStopActionLoop( inputdata_t &inputdata )
{
StopActionLoop( false );
}
#endif

View File

@ -112,6 +112,7 @@ public:
void InputCancelSequence( inputdata_t &inputdata );
void InputMoveToPosition( inputdata_t &inputdata );
#ifdef MAPBASE
void InputStopActionLoop( inputdata_t &inputdata );
void InputSetTarget( inputdata_t &inputdata );
#endif

View File

@ -938,7 +938,7 @@ void CAmbientGeneric::SendSound( SoundFlags_t flags)
{
#ifdef MAPBASE
int iFlags = flags != SND_STOP ? ((int)flags | m_iSoundFlags) : flags;
char *szSoundFile = (char *)STRING( m_iszSound );
const char *szSoundFile = STRING( m_iszSound );
CBaseEntity* pSoundSource = m_hSoundSource;
if ( pSoundSource )
{

View File

@ -22,10 +22,10 @@ void CPointEntity::Spawn( void )
}
class CNullEntity : public CBaseEntity
class CNullEntity : public CServerOnlyEntity
{
public:
DECLARE_CLASS( CNullEntity, CBaseEntity );
DECLARE_CLASS( CNullEntity, CServerOnlyEntity );
void Spawn( void );
};

View File

@ -47,6 +47,7 @@
#define DEBUG_TRANSITIONS_VERBOSE 2
ConVar g_debug_transitions( "g_debug_transitions", "0", FCVAR_NONE, "Set to 1 and restart the map to be warned if the map has no trigger_transition volumes. Set to 2 to see a dump of all entities & associated results during a transition." );
ConVar noclip_changelevel("noclip_changelevel", "0", FCVAR_CHEAT);
// Global list of triggers that care about weapon fire
// Doesn't need saving, the triggers re-add themselves on restore.
@ -1848,7 +1849,8 @@ void CChangeLevel::TouchChangeLevel( CBaseEntity *pOther )
return;
}
if ( !pPlayer->IsInAVehicle() && pPlayer->GetMoveType() == MOVETYPE_NOCLIP )
if ( !pPlayer->IsInAVehicle() && pPlayer->GetMoveType() == MOVETYPE_NOCLIP && !noclip_changelevel.GetBool())
{
DevMsg("In level transition: %s %s\n", st_szNextMap, st_szNextSpot );
return;

View File

@ -35,21 +35,21 @@ PRECACHE_REGISTER( vgui_screen );
//-----------------------------------------------------------------------------
// Save/load
//-----------------------------------------------------------------------------
BEGIN_DATADESC( CVGuiScreen )
BEGIN_DATADESC(CVGuiScreen)
DEFINE_CUSTOM_FIELD( m_nPanelName, &g_VguiScreenStringOps ),
DEFINE_FIELD( m_nAttachmentIndex, FIELD_INTEGER ),
DEFINE_CUSTOM_FIELD(m_nPanelName, &g_VguiScreenStringOps),
DEFINE_FIELD(m_nAttachmentIndex, FIELD_INTEGER),
// DEFINE_FIELD( m_nOverlayMaterial, FIELD_INTEGER ),
DEFINE_FIELD( m_fScreenFlags, FIELD_INTEGER ),
DEFINE_KEYFIELD( m_flWidth, FIELD_FLOAT, "width" ),
DEFINE_KEYFIELD( m_flHeight, FIELD_FLOAT, "height" ),
DEFINE_KEYFIELD( m_strOverlayMaterial, FIELD_STRING, "overlaymaterial" ),
DEFINE_FIELD( m_hPlayerOwner, FIELD_EHANDLE ),
DEFINE_FIELD(m_fScreenFlags, FIELD_INTEGER),
DEFINE_KEYFIELD(m_flWidth, FIELD_FLOAT, "width"),
DEFINE_KEYFIELD(m_flHeight, FIELD_FLOAT, "height"),
DEFINE_KEYFIELD(m_strOverlayMaterial, FIELD_STRING, "overlaymaterial"),
DEFINE_FIELD(m_hPlayerOwner, FIELD_EHANDLE),
DEFINE_INPUTFUNC( FIELD_VOID, "SetActive", InputSetActive ),
DEFINE_INPUTFUNC( FIELD_VOID, "SetInactive", InputSetInactive ),
DEFINE_INPUTFUNC(FIELD_VOID, "SetActive", InputSetActive),
DEFINE_INPUTFUNC(FIELD_VOID, "SetInactive", InputSetInactive),
END_DATADESC()
END_DATADESC();
//-----------------------------------------------------------------------------
@ -75,6 +75,24 @@ bool CVGuiScreen::KeyValue( const char *szKeyName, const char *szValue )
*s = '\0';
}
#ifdef MAPBASE
// Named command outputs
if (szKeyName[0] == '~' && szKeyName[1])
{
const char* pszOutputName = szKeyName + 1;
int i = m_PanelOutputs.Find(pszOutputName);
if (!m_PanelOutputs.IsValidIndex(i))
{
auto pMem = new COutputEvent;
V_memset(pMem, 0, sizeof(COutputEvent));
i = m_PanelOutputs.Insert(pszOutputName, pMem);
}
m_PanelOutputs[i]->ParseEventAction(szValue);
return true;
}
#endif // MAPBASE
if ( FStrEq( szKeyName, "panelname" ))
{
SetPanelName( szValue );
@ -158,6 +176,106 @@ void CVGuiScreen::OnRestore()
BaseClass::OnRestore();
}
#ifdef MAPBASE
CVGuiScreen::~CVGuiScreen()
{
m_PanelOutputs.PurgeAndDeleteElements();
}
int CVGuiScreen::Save(ISave& save)
{
#if MAPBASE_VER_INT < 8000
// HACKHACK: Until v8.0, mark this screen as using the new save system to prevent existing saves with vgui_screen from crashing
AddContext( "uses_new_save", "1" );
#endif
int status = BaseClass::Save(save);
if (!status)
return 0;
const int iCount = m_PanelOutputs.Count();
save.WriteInt(&iCount);
for (int i = 0; i < iCount; i++)
{
CBaseEntityOutput* output = m_PanelOutputs[i];
const int nElems = output->NumberOfElements();
save.WriteString(m_PanelOutputs.GetElementName(i));
save.WriteInt(&nElems);
if (!output->Save(save))
return 0;
}
return status;
}
int CVGuiScreen::Restore(IRestore& restore)
{
int status = BaseClass::Restore(restore);
if (!status)
return 0;
#if MAPBASE_VER_INT < 8000
// HACKHACK: Until v8.0, mark this screen as using the new save system to prevent existing saves with vgui_screen from crashing
if (!HasContext( "uses_new_save", "1" ))
return status;
#endif
const int iCount = restore.ReadInt();
m_PanelOutputs.EnsureCapacity(iCount);
for (int i = 0; i < iCount; i++)
{
char cName[MAX_KEY];
restore.ReadString(cName, MAX_KEY, 0);
const int iIndex = m_PanelOutputs.Insert(cName, new COutputEvent);
const int nElems = restore.ReadInt();
if (!m_PanelOutputs[iIndex]->Restore(restore, nElems))
return 0;
}
return status;
}
// Handle a command from the client-side vgui panel.
bool CVGuiScreen::HandleEntityCommand(CBasePlayer* pClient, KeyValues* pKeyValues)
{
#if defined(HL2MP) // Enable this in multiplayer.
// Restrict to commands from our owning player.
if ((m_fScreenFlags & VGUI_SCREEN_ONLY_USABLE_BY_OWNER) && pClient != m_hPlayerOwner.Get())
return false;
#endif
// Give the owning entity a chance to handle the command.
if (GetOwnerEntity() && GetOwnerEntity()->HandleEntityCommand(pClient, pKeyValues))
return true;
// See if we have an output for this command.
const int i = m_PanelOutputs.Find(pKeyValues->GetString());
if (m_PanelOutputs.IsValidIndex(i))
{
variant_t Val;
Val.Set(FIELD_VOID, NULL);
m_PanelOutputs[i]->FireOutput(Val, pClient, this);
return true;
}
return false;
}
CBaseEntityOutput* CVGuiScreen::FindNamedOutput(const char* pszOutput)
{
if (pszOutput && pszOutput[0] == '~' && pszOutput[1])
{
const int i = m_PanelOutputs.Find(pszOutput + 1);
if (m_PanelOutputs.IsValidIndex(i))
return m_PanelOutputs[i];
return NULL;
}
return BaseClass::FindNamedOutput(pszOutput);
}
#endif // MAPBASE
void CVGuiScreen::SetAttachmentIndex( int nIndex )
{
m_nAttachmentIndex = nIndex;

View File

@ -32,6 +32,15 @@ public:
virtual void Activate();
virtual void OnRestore();
#ifdef MAPBASE
~CVGuiScreen();
virtual int Save(ISave& save);
virtual int Restore(IRestore& restore);
virtual bool HandleEntityCommand(CBasePlayer* pClient, KeyValues* pKeyValues);
virtual CBaseEntityOutput* FindNamedOutput(const char* pszOutput);
#endif // MAPBASE
const char *GetPanelName() const;
// Sets the screen size + resolution
@ -75,6 +84,10 @@ private:
CNetworkVar( int, m_fScreenFlags );
CNetworkVar( EHANDLE, m_hPlayerOwner );
#ifdef MAPBASE
CUtlDict<CBaseEntityOutput*> m_PanelOutputs;
#endif // MAPBASE
friend CVGuiScreen *CreateVGuiScreen( const char *pScreenClassname, const char *pScreenType, CBaseEntity *pAttachedTo, CBaseEntity *pOwner, int nAttachmentIndex );
};

View File

@ -1001,7 +1001,11 @@ public:
if ( duration )
{
*duration = enginesound->GetSoundDuration( pSample );
if ( Q_stristr( pSample, ".mp3" ) ) {
*duration = 0;
} else {
*duration = enginesound->GetSoundDuration( pSample );
}
}
TraceEmitSound( "EmitAmbientSound: Raw wave emitted '%s' (ent %i)\n",

View File

@ -2811,6 +2811,14 @@ HSCRIPT CBaseEntity::ScriptGetPhysicsObject( void )
return NULL;
}
//-----------------------------------------------------------------------------
// Vscript: Gets the entity's physics object if it has one
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptPhysicsInitNormal( int nSolidType, int nSolidFlags, bool createAsleep )
{
VPhysicsInitNormal( (SolidType_t)nSolidType, nSolidFlags, createAsleep );
}
#ifdef GAME_DLL
#define SCRIPT_NEVER_THINK TICK_NEVER_THINK

View File

@ -1069,6 +1069,10 @@ float IntervalDistance( float x, float x0, float x1 )
return 0;
}
#if !defined(CLIENT_DLL) && defined(MAPBASE_VSCRIPT)
extern ScriptHook_t g_Hook_FindUseEntity;
#endif
CBaseEntity *CBasePlayer::FindUseEntity()
{
Vector forward, up;
@ -1160,7 +1164,24 @@ CBaseEntity *CBasePlayer::FindUseEntity()
// if this is directly under the cursor just return it now
if ( i == 0 )
{
#if !defined(CLIENT_DLL) && defined(MAPBASE_VSCRIPT)
if (m_ScriptScope.IsInitialized() && g_Hook_FindUseEntity.CanRunInScope( m_ScriptScope ))
{
// entity, is_radius
ScriptVariant_t functionReturn;
ScriptVariant_t args[] = { ToHScript( pNearest ), false };
if (g_Hook_FindUseEntity.Call( m_ScriptScope, &functionReturn, args ))
{
pObject = ToEnt( functionReturn.m_hScript );
pNearest = pObject;
}
}
if (pObject)
#endif
return pObject;
}
}
}
}
@ -1246,6 +1267,19 @@ CBaseEntity *CBasePlayer::FindUseEntity()
pNearest = DoubleCheckUseNPC( pNearest, searchCenter, forward );
}
#ifdef MAPBASE_VSCRIPT
if (m_ScriptScope.IsInitialized() && g_Hook_FindUseEntity.CanRunInScope(m_ScriptScope))
{
// entity, is_radius
ScriptVariant_t functionReturn;
ScriptVariant_t args[] = { ToHScript( pNearest ), true };
if (g_Hook_FindUseEntity.Call( m_ScriptScope, &functionReturn, args ))
{
pNearest = ToEnt( functionReturn.m_hScript );
}
}
#endif
if ( sv_debug_player_use.GetBool() )
{
if ( !pNearest )

View File

@ -963,3 +963,28 @@ CTacticalMissionManager *CGameRules::TacticalMissionManagerFactory( void )
}
#endif
#ifdef MAPBASE
void CGameRules::ClientCommandKeyValues(edict_t* pEntity, KeyValues* pKeyValues)
{
#ifndef CLIENT_DLL
static int s_nEntityCommandSymbol = KeyValues::CallGetSymbolForString("EntityCommand");
static int s_nEntIndexSymbol = KeyValues::CallGetSymbolForString("entindex");
static int s_nCommandDataSymbol = KeyValues::CallGetSymbolForString("command_data");
CBasePlayer* pPlayer = (CBasePlayer*)GetContainingEntity(pEntity);
if (!pPlayer)
return;
if (pKeyValues->GetNameSymbol() == s_nEntityCommandSymbol)
{
CBaseEntity* pEntity = CBaseEntity::Instance(pKeyValues->GetInt(s_nEntIndexSymbol));
KeyValues* pkvCommand = pKeyValues->FindKey(s_nCommandDataSymbol);
if (pEntity && pkvCommand)
{
pEntity->HandleEntityCommand(pPlayer, pkvCommand);
}
}
#endif // GAME_DLL
}
#endif // MAPBASE

View File

@ -178,7 +178,12 @@ public:
//Allow thirdperson camera.
virtual bool AllowThirdPersonCamera( void ) { return false; }
virtual void ClientCommandKeyValues( edict_t *pEntity, KeyValues *pKeyValues ) {}
#ifdef MAPBASE
virtual void ClientCommandKeyValues(edict_t* pEntity, KeyValues* pKeyValues);
#else
virtual void ClientCommandKeyValues(edict_t* pEntity, KeyValues* pKeyValues) {}
#endif // MAPBASE
// IsConnectedUserInfoChangeAllowed allows the clients to change
// cvars with the FCVAR_NOT_CONNECTED rule if it returns true

View File

@ -43,6 +43,10 @@
#define IN_GRENADE2 (1 << 24) // grenade 2
#define IN_ATTACK3 (1 << 25)
#ifdef MAPBASE
#define IN_VGUIMODE (1 << 26)
#endif // MAPBASE
#ifdef VGUI_SCREEN_FIX
#define IN_VALIDVGUIINPUT (1 << 23) //bitflag for vgui fix
#endif

View File

@ -290,6 +290,17 @@ void RegisterSharedScriptConstants()
ScriptRegisterConstant( g_pScriptVM, EF_ITEM_BLINK, "Effect flag used in GetEffects(), etc." );
ScriptRegisterConstant( g_pScriptVM, EF_PARENT_ANIMATES, "Effect flag used in GetEffects(), etc." );
//
// Solid Types
//
ScriptRegisterConstant( g_pScriptVM, SOLID_NONE, "Solid type used by VPhysics" );
ScriptRegisterConstant( g_pScriptVM, SOLID_BSP, "Solid type used by VPhysics" );
ScriptRegisterConstant( g_pScriptVM, SOLID_BBOX, "Solid type used by VPhysics" );
ScriptRegisterConstant( g_pScriptVM, SOLID_OBB, "Solid type used by VPhysics" );
ScriptRegisterConstant( g_pScriptVM, SOLID_OBB_YAW, "Solid type used by VPhysics" );
ScriptRegisterConstant( g_pScriptVM, SOLID_CUSTOM, "Solid type used by VPhysics" );
ScriptRegisterConstant( g_pScriptVM, SOLID_VPHYSICS, "Solid type used by VPhysics" );
//
// Solid Flags
//

View File

@ -10,6 +10,8 @@
#include "hl2_gamerules.h"
#ifndef CLIENT_DLL
#include "eventqueue.h"
#include "weapon_physcannon.h"
#include "player_pickup.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
@ -47,6 +49,48 @@ bool ScriptMegaPhyscannonActive()
{
return HL2GameRules()->MegaPhyscannonActive();
}
void ScriptPickup_ForcePlayerToDropThisObject( HSCRIPT hTarget )
{
Pickup_ForcePlayerToDropThisObject( ToEnt( hTarget ) );
}
float ScriptPlayerPickupGetHeldObjectMass( HSCRIPT hPickupControllerEntity, HSCRIPT hHeldObject )
{
IPhysicsObject *pPhysObj = HScriptToClass<IPhysicsObject>( hHeldObject );
if (!pPhysObj)
{
CBaseEntity *pEnt = ToEnt( hHeldObject );
if (pEnt)
pPhysObj = pEnt->VPhysicsGetObject();
}
if (!pPhysObj)
{
Warning( "PlayerPickupGetHeldObjectMass: Invalid physics object\n" );
return 0.0f;
}
return PlayerPickupGetHeldObjectMass( ToEnt( hPickupControllerEntity ), pPhysObj );
}
HSCRIPT ScriptGetPlayerHeldEntity( HSCRIPT hPlayer )
{
CBasePlayer *pPlayer = ToBasePlayer( ToEnt( hPlayer ) );
if (!pPlayer)
return NULL;
return ToHScript( GetPlayerHeldEntity( pPlayer ) );
}
HSCRIPT ScriptPhysCannonGetHeldEntity( HSCRIPT hWeapon )
{
CBaseEntity *pEnt = ToEnt( hWeapon );
if (!pEnt)
return NULL;
return ToHScript( PhysCannonGetHeldEntity( pEnt->MyCombatWeaponPointer() ) );
}
#endif
//-----------------------------------------------------------------------------
@ -59,5 +103,10 @@ void CHalfLife2::RegisterScriptFunctions( void )
#ifndef CLIENT_DLL
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGameOver, "GameOver", "Ends the game and reloads the last save." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMegaPhyscannonActive, "MegaPhyscannonActive", "Checks if supercharged gravity gun mode is enabled." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPickup_ForcePlayerToDropThisObject, "Pickup_ForcePlayerToDropThisObject", "If the specified entity is being carried, instantly drops it." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPlayerPickupGetHeldObjectMass, "PlayerPickupGetHeldObjectMass", "Gets the mass of the specified player_pickup controller, with the second parameter the held object's physics object." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGetPlayerHeldEntity, "GetPlayerHeldEntity", "Gets the specified player's currently held entity." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPhysCannonGetHeldEntity, "PhysCannonGetHeldEntity", "Gets the specified gravity gun's currently held entity." );
#endif
}

View File

@ -771,6 +771,26 @@ static void AddPhysVelocity( HSCRIPT hPhys, const Vector& vecVelocity, const Vec
pPhys->AddVelocity( &vecVelocity, &vecAngVelocity );
}
static void ScriptPhysEnableEntityCollisions( HSCRIPT hPhys1, HSCRIPT hPhys2 )
{
IPhysicsObject *pPhys1 = HScriptToClass<IPhysicsObject>( hPhys1 );
IPhysicsObject *pPhys2 = HScriptToClass<IPhysicsObject>( hPhys2 );
if (!pPhys1 || !pPhys2)
return;
PhysEnableEntityCollisions( pPhys1, pPhys2 );
}
static void ScriptPhysDisableEntityCollisions( HSCRIPT hPhys1, HSCRIPT hPhys2 )
{
IPhysicsObject *pPhys1 = HScriptToClass<IPhysicsObject>( hPhys1 );
IPhysicsObject *pPhys2 = HScriptToClass<IPhysicsObject>( hPhys2 );
if (!pPhys1 || !pPhys2)
return;
PhysDisableEntityCollisions( pPhys1, pPhys2 );
}
//=============================================================================
//=============================================================================
@ -1045,6 +1065,8 @@ void RegisterSharedScriptFunctions()
ScriptRegisterFunction( g_pScriptVM, GetPhysAngVelocity, "Gets physics angular velocity for the given VPhysics object" );
ScriptRegisterFunction( g_pScriptVM, SetPhysVelocity, "Sets physics velocity for the given VPhysics object" );
ScriptRegisterFunction( g_pScriptVM, AddPhysVelocity, "Adds physics velocity for the given VPhysics object" );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPhysEnableEntityCollisions, "PhysEnableEntityCollisions", "Enables collisions between two VPhysics objects");
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPhysDisableEntityCollisions, "PhysDisableEntityCollisions", "Disables collisions between two VPhysics objects");
//
// Precaching

File diff suppressed because it is too large Load Diff

View File

@ -1178,6 +1178,32 @@ void CRagdollLRURetirement::MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImpo
#endif
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Remove it from the LRU
//-----------------------------------------------------------------------------
void CRagdollLRURetirement::RemoveFromLRU( CBaseAnimating *pRagdoll )
{
for (int i = 0; i < m_LRU.Count(); i++)
{
if (m_LRU[i].Get() == pRagdoll)
{
m_LRU.Remove( i );
return;
}
}
for (int i = 0; i < m_LRUImportantRagdolls.Count(); i++)
{
if (m_LRUImportantRagdolls[i].Get() == pRagdoll)
{
m_LRUImportantRagdolls.Remove( i );
return;
}
}
}
#endif
//EFFECT/ENTITY TRANSFERS

View File

@ -114,8 +114,9 @@ public:
virtual void FrameUpdatePostEntityThink( void );
// Move it to the top of the LRU
#ifdef MAPBASE // From Alien Swarm SDK
void MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant = false, float flForcedRetireTime = 0.0f );
#ifdef MAPBASE
void MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant = false, float flForcedRetireTime = 0.0f ); // From Alien Swarm SDK
void RemoveFromLRU( CBaseAnimating *pRagdoll );
#else
void MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant = false );
#endif

View File

@ -624,6 +624,9 @@ public:
if ( g_pScriptVM->GetValue( STRING(pEnt->m_iszScriptId), &variant ) && variant.m_type == FIELD_HSCRIPT )
{
pEnt->m_ScriptScope.Init( variant.m_hScript, false );
#ifdef MAPBASE_VSCRIPT
g_pScriptVM->SetValue( pEnt->m_ScriptScope, "self", pEnt->m_hScriptInstance );
#endif
#ifndef CLIENT_DLL
pEnt->RunPrecacheScripts();
#endif

View File

@ -85,7 +85,7 @@ BEGIN_VS_SHADER_FLAGS( BlurFilterY, "Help for BlurFilterY", SHADER_NOT_EDITABLE
// The temp buffer is 1/4 back buffer size
ITexture *src_texture = params[BASETEXTURE]->GetTextureValue();
int height = src_texture->GetActualWidth();
int height = src_texture->GetActualHeight();
float dY = 1.0f / height;
// dY *= 0.4;
float v[4];

View File

@ -1537,7 +1537,7 @@ void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar**
float envMapOrigin[4] = {0,0,0,0};
params[info.m_nEnvmapOrigin]->GetVecValue( envMapOrigin, 3 );
#ifdef MAPBASE
envMapOrigin[4] = bEditorBlend ? 1.0f : 0.0f;
envMapOrigin[3] = bEditorBlend ? 1.0f : 0.0f;
#endif
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 21, envMapOrigin );

View File

@ -1281,8 +1281,8 @@ PLATFORM_INTERFACE bool Is64BitOS();
//-----------------------------------------------------------------------------
// General Mapbase version constants compiled into projects for versioning purposes
//-----------------------------------------------------------------------------
#define MAPBASE_VERSION "7.2"
#define MAPBASE_VER_INT 7200 // For use in #if in a similar fashion to macros like _MSC_VER
#define MAPBASE_VERSION "7.3"
#define MAPBASE_VER_INT 7300 // For use in #if in a similar fashion to macros like _MSC_VER
#endif

View File

@ -2776,7 +2776,7 @@ void* SquirrelVM::GetInstanceValue(HSCRIPT hInstance, ScriptClassDesc_t* pExpect
bool SquirrelVM::GenerateUniqueKey(const char* pszRoot, char* pBuf, int nBufSize)
{
static int keyIdx = 0;
static unsigned keyIdx = 0;
// This gets used for script scope, still confused why it needs to be inside IScriptVM
// is it just to be a compatible name for CreateScope?
V_snprintf(pBuf, nBufSize, "%08X_%s", ++keyIdx, pszRoot);