mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-27 07:15:31 +03:00
Mapbase v2.0; bulk commit
- Added custom map compile tools (vbsp, vvis, vrad) - Changed blink fix (shouldn't change anything in-game) - Added auto-completion to ent_create, npc_create, and the main set of "npc_" debug commands - Added ent_create_aimed, an ent_create equivalent of npc_create_aimed - Made hunters start using the "vs. player" melee animation against smaller NPCs that look weird with the "stab" attack - Added "explosion_sparks" convar, which fixes broken code for giving explosions sparks (disabled by default because of how different it looks) - Made interaction code capable of being dispatched on any entity, not just combat characters - Added npc_barnacle_ignite convar, which lets barnacles be ignited by flares - Fixed certain NPCs getting out of the way for the player when they hate them - Fixed auto-generated "speak" scene responses not using parameters that work on real VCDs - Made "stop_on_nonidle" capable of being used in any mod, not just HL2 episodic mods - Selectable color for ragdoll boogie/point_ragdollboogie - Fixed PickupWeaponInstant not firing weapon pickup outputs - Introduced inputs and keyvalues for "lerping" to math_counter_advanced - Fixed ClearConsole on logic_console - logic_convar should now detect client convars correctly - New NormalizeAngles input on math_vector - logic_modelinfo LookupActivity input - math_generate fixed and expanded to be more like math_counter - Added a WIP game logging system for playtesting maps - Introduced logic_playerinfo, an entity that can read a player's name or ID - Fixed some new filters not working with filter_multi - Added radius pickup spawnflag to func_physbox - Added "Preserve name" spawnflag to weapons - Added cc_achievement_debug message for when an achievement doesn't exist - Made npc_combine_s not speak while in logic_choreographed_scenes - Fixed zombie torsos/legs/headcrabs not being serverside when zombie is forced to server ragdoll - Expanded and cleaned up npc_zombie_custom - Fixed func_commandredirects not cleaning up correctly and sometimes crashing the game - Allowed player squad commands to go through +USE-held objects - Added a bunch of I/O/KV to trigger_waterydeath for better configuration - Changed save comment system to use the chapter title from world properties, and the ability to suppress the title popup that normally results from it - Adjusted game_convar_mod for MP planning - Removed the func_precipitation custom particle/splash code for now, as it was causing problems - Fixed env_global_light not accepting lightcolor - Added "Additional Buttons" to player_speedmod - Added save comment to RPC - Added env_projectedtexture attenuation - Added scripted_sequence OnPreIdleSequence - Added OnCrab to zombies - Added skill_changed game event (may need further testing) - Added a fix for viewmodels flipping under extreme FOV values - Added code that allows mappers to change the skin on shotgunners without it usually flipping back randomly - Fixed a very, very, very major shader performance issue - New SetAbsOrigin/Angles inputs on all entities, analogous to SetLocalOrigin/Angles - Code improvements for I/O involving angles - logic_entity_position improvements/fixes, including a new OutAngles output that outputs the angles on position calls - Alternate collision/player avoidance spawnflag obsoletion enforcement disabled - Enable/DisableHazardLights inputs on the EP2 jalopy, equivalent to the keyvalue - Miscellaneous shader formatting adjustments and fixes - Fixed AlwaysDrawOff on env_projectedtexture not being a valid input
This commit is contained in:
parent
a1dba884a3
commit
dc7f20acc8
@ -88,6 +88,11 @@ private:
|
||||
int m_nSpotlightTextureFrame;
|
||||
int m_nShadowQuality;
|
||||
#ifdef MAPBASE
|
||||
float m_flConstantAtten;
|
||||
float m_flLinearAtten;
|
||||
float m_flQuadraticAtten;
|
||||
float m_flShadowAtten;
|
||||
|
||||
bool m_bAlwaysDraw;
|
||||
//bool m_bProjectedTextureVersion;
|
||||
#endif
|
||||
|
@ -1149,9 +1149,7 @@ void C_BaseFlex::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightC
|
||||
{
|
||||
// hack in an initialization
|
||||
LinkToGlobalFlexControllers( GetModelPtr() );
|
||||
#ifdef MAPBASE
|
||||
m_iBlink = AddGlobalFlexController( "blink" );
|
||||
#else
|
||||
#ifndef MAPBASE
|
||||
m_iBlink = AddGlobalFlexController( "UH" );
|
||||
#endif
|
||||
|
||||
|
@ -33,14 +33,7 @@ Vector g_vSplashColor( 0.5, 0.5, 0.5 );
|
||||
float g_flSplashScale = 0.15;
|
||||
float g_flSplashLifetime = 0.5f;
|
||||
float g_flSplashAlpha = 0.3f;
|
||||
#ifdef MAPBASE
|
||||
// Rain splash stuff based on Tony Sergei's VDC code
|
||||
// (r_RainParticle can be found in effects.cpp on the server as well)
|
||||
ConVar r_RainParticle("r_RainParticle", "Rain_01_impact", FCVAR_CHEAT | FCVAR_REPLICATED);
|
||||
ConVar r_RainSplashPercentage( "r_RainSplashPercentage", "99", FCVAR_CHEAT ); // N% chance of a rain particle making a splash.
|
||||
#else
|
||||
ConVar r_RainSplashPercentage( "r_RainSplashPercentage", "20", FCVAR_CHEAT ); // N% chance of a rain particle making a splash.
|
||||
#endif
|
||||
|
||||
|
||||
float GUST_INTERVAL_MIN = 1;
|
||||
@ -331,20 +324,6 @@ inline bool CClient_Precipitation::SimulateRain( CPrecipitationParticle* pPartic
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Based on Tony Sergi's code on the VDC. This version re-uses m_Splashes instead of dispatching the effect immediately.
|
||||
trace_t trace;
|
||||
UTIL_TraceLine(vOldPos, pParticle->m_Pos, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace);
|
||||
|
||||
if (trace.fraction < 1 || trace.DidHit())
|
||||
{
|
||||
if (RandomInt(0, 100) <= r_RainSplashPercentage.GetInt())
|
||||
m_Splashes.AddToTail( trace.endpos );
|
||||
|
||||
// Tell the framework it's time to remove the particle from the list
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
// No longer in the air? punt.
|
||||
if ( !IsInAir( pParticle->m_Pos ) )
|
||||
{
|
||||
@ -365,7 +344,6 @@ inline bool CClient_Precipitation::SimulateRain( CPrecipitationParticle* pPartic
|
||||
// Tell the framework it's time to remove the particle from the list
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We still want this particle
|
||||
return true;
|
||||
@ -572,15 +550,7 @@ void CClient_Precipitation::CreateWaterSplashes()
|
||||
|
||||
if ( CurrentViewForward().Dot( vSplash - CurrentViewOrigin() ) > 1 )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
// Use a particle or
|
||||
if ( r_RainParticle.GetString()[0] != NULL )
|
||||
DispatchParticleEffect(r_RainParticle.GetString(), vSplash, QAngle(RandomFloat(0, 360), RandomFloat(0, 360), RandomFloat(0, 360)), NULL);
|
||||
else
|
||||
FX_WaterRipple( vSplash, g_flSplashScale, &g_vSplashColor, g_flSplashLifetime, g_flSplashAlpha );
|
||||
#else
|
||||
FX_WaterRipple( vSplash, g_flSplashScale, &g_vSplashColor, g_flSplashLifetime, g_flSplashAlpha );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
m_Splashes.Purge();
|
||||
@ -698,13 +668,6 @@ void CClient_Precipitation::Precache( )
|
||||
|
||||
case PRECIPITATION_TYPE_RAIN:
|
||||
Assert( m_nPrecipType == PRECIPITATION_TYPE_RAIN );
|
||||
#ifdef MAPBASE
|
||||
if (r_RainParticle.GetString()[0] != NULL)
|
||||
{
|
||||
PrecacheParticleSystem( r_RainParticle.GetString() );
|
||||
DevMsg("Rain particle system \"%s\" precached!\n", r_RainParticle.GetString());
|
||||
}
|
||||
#endif
|
||||
m_Speed = RAIN_SPEED;
|
||||
m_MatHandle = materials->FindMaterial( "particle/rain", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
m_InitialRamp = 1.0f;
|
||||
|
@ -56,6 +56,10 @@ IMPLEMENT_CLIENTCLASS_DT( C_EnvProjectedTexture, DT_EnvProjectedTexture, CEnvPro
|
||||
RecvPropFloat( RECVINFO( m_flFarZ ) ),
|
||||
RecvPropInt( RECVINFO( m_nShadowQuality ) ),
|
||||
#ifdef MAPBASE
|
||||
RecvPropFloat( RECVINFO( m_flConstantAtten ) ),
|
||||
RecvPropFloat( RECVINFO( m_flLinearAtten ) ),
|
||||
RecvPropFloat( RECVINFO( m_flQuadraticAtten ) ),
|
||||
RecvPropFloat( RECVINFO( m_flShadowAtten ) ),
|
||||
RecvPropBool( RECVINFO( m_bAlwaysDraw ) ),
|
||||
|
||||
// Not needed on the client right now, change when it actually is needed
|
||||
@ -89,6 +93,10 @@ C_EnvProjectedTexture *C_EnvProjectedTexture::Create( )
|
||||
pEnt->m_bState = true;
|
||||
#ifdef MAPBASE
|
||||
pEnt->m_bAlwaysDraw = false;
|
||||
pEnt->m_flConstantAtten = 0.0f;
|
||||
pEnt->m_flLinearAtten = 100.0f;
|
||||
pEnt->m_flQuadraticAtten = 0.0f;
|
||||
pEnt->m_flShadowAtten = 0.0f;
|
||||
//pEnt->m_bProjectedTextureVersion = 1;
|
||||
#endif
|
||||
|
||||
@ -381,18 +389,23 @@ void C_EnvProjectedTexture::UpdateLight( void )
|
||||
|
||||
float flAlpha = m_flCurrentLinearFloatLightAlpha * ( 1.0f / 255.0f );
|
||||
|
||||
state.m_fQuadraticAtten = 0.0;
|
||||
state.m_fLinearAtten = 100;
|
||||
state.m_fConstantAtten = 0.0f;
|
||||
state.m_FarZAtten = m_flFarZ;
|
||||
#ifdef MAPBASE
|
||||
state.m_fConstantAtten = m_flConstantAtten;
|
||||
state.m_fLinearAtten = m_flLinearAtten;
|
||||
state.m_fQuadraticAtten = m_flQuadraticAtten;
|
||||
state.m_FarZAtten = m_flFarZ;
|
||||
state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale;
|
||||
state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale;
|
||||
state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * ( 1.0f / 255.0f ) * flAlpha) * m_flCurrentBrightnessScale;
|
||||
state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient;
|
||||
state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat();
|
||||
state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat();
|
||||
state.m_flShadowAtten = m_flShadowAtten;
|
||||
#else
|
||||
state.m_fQuadraticAtten = 0.0;
|
||||
state.m_fLinearAtten = 100;
|
||||
state.m_fConstantAtten = 0.0f;
|
||||
state.m_FarZAtten = m_flFarZ;
|
||||
state.m_fBrightnessScale = m_flBrightnessScale;
|
||||
state.m_Color[0] = m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha;
|
||||
state.m_Color[1] = m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * flAlpha;
|
||||
|
@ -59,6 +59,9 @@ BEGIN_RECV_TABLE( C_World, DT_World )
|
||||
RecvPropFloat(RECVINFO(m_flMinPropScreenSpaceWidth)),
|
||||
RecvPropString(RECVINFO(m_iszDetailSpriteMaterial)),
|
||||
RecvPropInt(RECVINFO(m_bColdWorld)),
|
||||
#ifdef MAPBASE
|
||||
RecvPropString(RECVINFO(m_iszChapterTitle)),
|
||||
#endif
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
@ -56,6 +56,9 @@ public:
|
||||
float m_flMinPropScreenSpaceWidth;
|
||||
float m_flMaxPropScreenSpaceWidth;
|
||||
bool m_bColdWorld;
|
||||
#ifdef MAPBASE
|
||||
char m_iszChapterTitle[64];
|
||||
#endif
|
||||
|
||||
private:
|
||||
void RegisterSharedActivities( void );
|
||||
|
@ -26,6 +26,7 @@ $Project
|
||||
{
|
||||
$File "$SRCDIR\game\shared\mapbase\mapbase_shared.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\mapbase_rpc.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\mapbase_game_log.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\MapEdit.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
|
||||
|
||||
|
@ -1256,6 +1256,13 @@ void FX_BuildTeslaHitbox( const CEffectData &data )
|
||||
{
|
||||
Vector vColor( 1, 1, 1 );
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( data.m_bCustomColors )
|
||||
{
|
||||
vColor = data.m_CustomColors.m_vecColor1;
|
||||
}
|
||||
#endif
|
||||
|
||||
C_BaseEntity *pEntity = ClientEntityList().GetEnt( data.entindex() );
|
||||
C_BaseAnimating *pAnimating = pEntity ? pEntity->GetBaseAnimating() : NULL;
|
||||
if (!pAnimating)
|
||||
|
@ -59,6 +59,7 @@ private:
|
||||
#ifdef MAPBASE
|
||||
bool m_bDrawSky;
|
||||
bool m_bDrawSky2;
|
||||
bool m_bUseEyePosition;
|
||||
#endif
|
||||
|
||||
// Fades
|
||||
@ -81,6 +82,7 @@ IMPLEMENT_CLIENTCLASS_DT( C_ScriptIntro, DT_ScriptIntro, CScriptIntro )
|
||||
#ifdef MAPBASE
|
||||
RecvPropBool( RECVINFO( m_bDrawSky ) ),
|
||||
RecvPropBool( RECVINFO( m_bDrawSky2 ) ),
|
||||
RecvPropBool( RECVINFO( m_bUseEyePosition ) ),
|
||||
#endif
|
||||
|
||||
// Fov & fov blends
|
||||
@ -181,11 +183,14 @@ void C_ScriptIntro::PostDataUpdate( DataUpdateType_t updateType )
|
||||
|
||||
// If it's a point_camera and it's ortho, send it to the intro data
|
||||
// Change this code if the purpose of m_hCameraEntity in intro data ever goes beyond ortho
|
||||
if ( Q_strncmp(m_hCameraEntity->GetClassname(), "point_camera", 12) == 0 )
|
||||
{
|
||||
C_PointCamera *pCamera = dynamic_cast<C_PointCamera*>(m_hCameraEntity.Get());
|
||||
if (pCamera && pCamera->IsOrtho())
|
||||
{
|
||||
m_IntroData.m_hCameraEntity = m_hCameraEntity;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -264,10 +269,23 @@ void C_ScriptIntro::ClientThink( void )
|
||||
Assert( m_IntroData.m_Passes.Count() <= 2 );
|
||||
|
||||
if ( m_hCameraEntity )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
if ( m_bUseEyePosition )
|
||||
{
|
||||
m_IntroData.m_vecCameraView = m_hCameraEntity->EyePosition();
|
||||
m_IntroData.m_vecCameraViewAngles = m_hCameraEntity->EyeAngles();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IntroData.m_vecCameraView = m_hCameraEntity->GetAbsOrigin();
|
||||
m_IntroData.m_vecCameraViewAngles = m_hCameraEntity->GetAbsAngles();
|
||||
}
|
||||
#else
|
||||
m_IntroData.m_vecCameraView = m_hCameraEntity->GetAbsOrigin();
|
||||
m_IntroData.m_vecCameraViewAngles = m_hCameraEntity->GetAbsAngles();
|
||||
#endif
|
||||
}
|
||||
|
||||
CalculateFOV();
|
||||
CalculateAlpha();
|
||||
|
@ -736,7 +736,11 @@ void CViewRender::SetUpViews()
|
||||
float flFOVOffset = fDefaultFov - view.fov;
|
||||
|
||||
//Adjust the viewmodel's FOV to move with any FOV offsets on the viewer's end
|
||||
#ifdef MAPBASE
|
||||
view.fovViewmodel = fabs(g_pClientMode->GetViewModelFOV()) - flFOVOffset;
|
||||
#else
|
||||
view.fovViewmodel = g_pClientMode->GetViewModelFOV() - flFOVOffset;
|
||||
#endif
|
||||
|
||||
if ( UseVR() )
|
||||
{
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "IEffects.h"
|
||||
#ifdef MAPBASE
|
||||
#include "saverestore_utlvector.h"
|
||||
#include "interval.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
@ -40,6 +41,10 @@ BEGIN_DATADESC( CRagdollBoogie )
|
||||
// Think this should be handled by StartTouch/etc.
|
||||
// DEFINE_FIELD( m_nSuppressionCount, FIELD_INTEGER ),
|
||||
|
||||
#ifdef MAPBASE
|
||||
DEFINE_FIELD( m_vecColor, FIELD_VECTOR ),
|
||||
#endif
|
||||
|
||||
DEFINE_FUNCTION( BoogieThink ),
|
||||
DEFINE_FUNCTION( ZapThink ),
|
||||
|
||||
@ -53,7 +58,11 @@ LINK_ENTITY_TO_CLASS( env_ragdoll_boogie, CRagdollBoogie );
|
||||
// Input : pTarget -
|
||||
//-----------------------------------------------------------------------------
|
||||
CRagdollBoogie *CRagdollBoogie::Create( CBaseEntity *pTarget, float flMagnitude,
|
||||
#ifdef MAPBASE
|
||||
float flStartTime, float flLengthTime, int nSpawnFlags, const Vector *vecColor )
|
||||
#else
|
||||
float flStartTime, float flLengthTime, int nSpawnFlags )
|
||||
#endif
|
||||
{
|
||||
CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( pTarget );
|
||||
if ( !pRagdoll )
|
||||
@ -67,6 +76,10 @@ CRagdollBoogie *CRagdollBoogie::Create( CBaseEntity *pTarget, float flMagnitude,
|
||||
pBoogie->AttachToEntity( pTarget );
|
||||
pBoogie->SetBoogieTime( flStartTime, flLengthTime );
|
||||
pBoogie->SetMagnitude( flMagnitude );
|
||||
#ifdef MAPBASE
|
||||
if (vecColor != NULL)
|
||||
pBoogie->SetColor( *vecColor );
|
||||
#endif
|
||||
pBoogie->Spawn();
|
||||
return pBoogie;
|
||||
}
|
||||
@ -118,6 +131,13 @@ void CRagdollBoogie::ZapThink()
|
||||
data.m_nEntIndex = GetMoveParent()->entindex();
|
||||
data.m_flMagnitude = 4;
|
||||
data.m_flScale = HasSpawnFlags(SF_RAGDOLL_BOOGIE_ELECTRICAL_NARROW_BEAM) ? 1.0f : 2.0f;
|
||||
#ifdef MAPBASE
|
||||
if (!m_vecColor.IsZero())
|
||||
{
|
||||
data.m_bCustomColors = true;
|
||||
data.m_CustomColors.m_vecColor1 = m_vecColor;
|
||||
}
|
||||
#endif
|
||||
|
||||
DispatchEffect( "TeslaHitboxes", data );
|
||||
}
|
||||
@ -285,14 +305,19 @@ public:
|
||||
void InputActivate( inputdata_t &inputdata );
|
||||
void InputDeactivate( inputdata_t &inputdata );
|
||||
void InputBoogieTarget( inputdata_t &inputdata );
|
||||
void InputSetZapColor( inputdata_t &inputdata );
|
||||
|
||||
bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
|
||||
private:
|
||||
float m_flStartTime;
|
||||
float m_flBoogieLength;
|
||||
interval_t m_BoogieLength;
|
||||
float m_flMagnitude;
|
||||
|
||||
// This allows us to remove active boogies later.
|
||||
CUtlVector<EHANDLE> m_Boogies;
|
||||
Vector m_vecZapColor;
|
||||
|
||||
// This allows us to change or remove active boogies later.
|
||||
CUtlVector<CHandle<CRagdollBoogie>> m_Boogies;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -301,9 +326,11 @@ private:
|
||||
BEGIN_DATADESC( CPointRagdollBoogie )
|
||||
|
||||
DEFINE_KEYFIELD( m_flStartTime, FIELD_FLOAT, "StartTime" ),
|
||||
DEFINE_KEYFIELD( m_flBoogieLength, FIELD_FLOAT, "BoogieLength" ),
|
||||
DEFINE_KEYFIELD( m_BoogieLength, FIELD_INTERVAL, "BoogieLength" ),
|
||||
DEFINE_KEYFIELD( m_flMagnitude, FIELD_FLOAT, "Magnitude" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_vecZapColor, FIELD_VECTOR, "ZapColor" ),
|
||||
|
||||
// Think this should be handled by StartTouch/etc.
|
||||
// DEFINE_FIELD( m_nSuppressionCount, FIELD_INTEGER ),
|
||||
|
||||
@ -313,6 +340,7 @@ BEGIN_DATADESC( CPointRagdollBoogie )
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Deactivate", InputDeactivate ),
|
||||
DEFINE_INPUTFUNC( FIELD_STRING, "BoogieTarget", InputBoogieTarget ),
|
||||
DEFINE_INPUTFUNC( FIELD_VECTOR, "SetZapColor", InputSetZapColor ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
@ -326,7 +354,7 @@ bool CPointRagdollBoogie::ApplyBoogie( CBaseEntity *pTarget, CBaseEntity *pActiv
|
||||
{
|
||||
if (dynamic_cast<CRagdollProp*>(pTarget))
|
||||
{
|
||||
m_Boogies.AddToTail(CRagdollBoogie::Create(pTarget, m_flMagnitude, gpGlobals->curtime + m_flStartTime, m_flBoogieLength, GetSpawnFlags()));
|
||||
m_Boogies.AddToTail(CRagdollBoogie::Create(pTarget, m_flMagnitude, gpGlobals->curtime + m_flStartTime, RandomInterval(m_BoogieLength), GetSpawnFlags(), &m_vecZapColor));
|
||||
}
|
||||
else if (pTarget->MyCombatCharacterPointer())
|
||||
{
|
||||
@ -337,7 +365,7 @@ bool CPointRagdollBoogie::ApplyBoogie( CBaseEntity *pTarget, CBaseEntity *pActiv
|
||||
|
||||
pRagdoll->SetCollisionBounds(CollisionProp()->OBBMins(), CollisionProp()->OBBMaxs());
|
||||
|
||||
m_Boogies.AddToTail(CRagdollBoogie::Create(pRagdoll, m_flMagnitude, gpGlobals->curtime + m_flStartTime, m_flBoogieLength, GetSpawnFlags()));
|
||||
m_Boogies.AddToTail(CRagdollBoogie::Create(pRagdoll, m_flMagnitude, gpGlobals->curtime + m_flStartTime, RandomInterval(m_BoogieLength), GetSpawnFlags(), &m_vecZapColor));
|
||||
|
||||
CTakeDamageInfo ragdollInfo(this, pActivator, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL);
|
||||
ragdollInfo.SetDamagePosition(WorldSpaceCenter());
|
||||
@ -382,6 +410,8 @@ void CPointRagdollBoogie::InputDeactivate( inputdata_t &inputdata )
|
||||
UTIL_Remove(m_Boogies[i]);
|
||||
}
|
||||
|
||||
m_Boogies.Purge();
|
||||
|
||||
//m_Boogies.RemoveAll();
|
||||
}
|
||||
|
||||
@ -402,4 +432,47 @@ void CPointRagdollBoogie::InputBoogieTarget( inputdata_t &inputdata )
|
||||
pEnt = gEntList.FindEntityByName(pEnt, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &inputdata -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPointRagdollBoogie::InputSetZapColor( inputdata_t &inputdata )
|
||||
{
|
||||
inputdata.value.Vector3D( m_vecZapColor );
|
||||
if (!m_vecZapColor.IsZero())
|
||||
{
|
||||
// Turn into ratios of 255
|
||||
m_vecZapColor /= 255.0f;
|
||||
}
|
||||
|
||||
// Apply to existing boogies
|
||||
for (int i = 0; i < m_Boogies.Count(); i++)
|
||||
{
|
||||
if (m_Boogies[i])
|
||||
{
|
||||
m_Boogies[i]->SetColor( m_vecZapColor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles key values from the BSP before spawn is called.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CPointRagdollBoogie::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
if ( FStrEq( szKeyName, "ZapColor" ) )
|
||||
{
|
||||
UTIL_StringToVector(m_vecZapColor.Base(), szValue);
|
||||
if (!m_vecZapColor.IsZero())
|
||||
{
|
||||
// Turn into ratios of 255
|
||||
m_vecZapColor /= 255.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
return BaseClass::KeyValue( szKeyName, szValue );
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -28,10 +28,18 @@ class CRagdollBoogie : public CBaseEntity
|
||||
DECLARE_CLASS( CRagdollBoogie, CBaseEntity );
|
||||
|
||||
public:
|
||||
#ifdef MAPBASE
|
||||
static CRagdollBoogie *Create( CBaseEntity *pTarget, float flMagnitude, float flStartTime, float flLengthTime = 0.0f, int nSpawnFlags = 0, const Vector *vecColor = NULL );
|
||||
#else
|
||||
static CRagdollBoogie *Create( CBaseEntity *pTarget, float flMagnitude, float flStartTime, float flLengthTime = 0.0f, int nSpawnFlags = 0 );
|
||||
#endif
|
||||
static void IncrementSuppressionCount( CBaseEntity *pTarget );
|
||||
static void DecrementSuppressionCount( CBaseEntity *pTarget );
|
||||
|
||||
#ifdef MAPBASE
|
||||
void SetColor( const Vector &vecColor ) { m_vecColor = vecColor; }
|
||||
#endif
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
@ -45,6 +53,10 @@ private:
|
||||
float m_flBoogieLength;
|
||||
float m_flMagnitude;
|
||||
int m_nSuppressionCount;
|
||||
|
||||
#ifdef MAPBASE
|
||||
Vector m_vecColor = Vector(1, 1, 1);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // RAGDOLLBOOGIE_H
|
||||
|
@ -1934,7 +1934,7 @@ void CAI_BaseActor::OnStateChange( NPC_STATE OldState, NPC_STATE NewState )
|
||||
{
|
||||
PlayExpressionForState( NewState );
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
#if defined(HL2_EPISODIC) || defined(MAPBASE)
|
||||
// If we've just switched states, ensure we stop any scenes that asked to be stopped
|
||||
if ( OldState == NPC_STATE_IDLE )
|
||||
{
|
||||
|
@ -13705,7 +13705,11 @@ void CAI_BaseNPC::TestPlayerPushing( CBaseEntity *pEntity )
|
||||
|
||||
// Heuristic for determining if the player is pushing me away
|
||||
CBasePlayer *pPlayer = ToBasePlayer( pEntity );
|
||||
#ifdef MAPBASE
|
||||
if ( pPlayer && !( pPlayer->GetFlags() & FL_NOTARGET ) && IRelationType( pPlayer ) > D_FR )
|
||||
#else
|
||||
if ( pPlayer && !( pPlayer->GetFlags() & FL_NOTARGET ) )
|
||||
#endif
|
||||
{
|
||||
if ( (pPlayer->m_nButtons & (IN_FORWARD|IN_BACK|IN_MOVELEFT|IN_MOVERIGHT)) ||
|
||||
pPlayer->GetAbsVelocity().AsVector2D().LengthSqr() > 50*50 )
|
||||
|
@ -2900,6 +2900,9 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask )
|
||||
//
|
||||
if ( m_hCine->m_iszPreIdle != NULL_STRING )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
m_hCine->OnPreIdleSequence( this );
|
||||
#endif
|
||||
m_hCine->StartSequence( ( CAI_BaseNPC * )this, m_hCine->m_iszPreIdle, false );
|
||||
if ( FStrEq( STRING( m_hCine->m_iszPreIdle ), STRING( m_hCine->m_iszPlay ) ) )
|
||||
{
|
||||
|
@ -390,6 +390,149 @@ void CC_NPC_Focus( const CCommand &args )
|
||||
static ConCommand npc_focus("npc_focus", CC_NPC_Focus, "Displays red line to NPC's enemy (if has one) and blue line to NPC's target entity (if has one)\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at", FCVAR_CHEAT);
|
||||
|
||||
ConVar npc_create_equipment("npc_create_equipment", "");
|
||||
|
||||
#ifdef MAPBASE
|
||||
extern int EntityFactory_AutoComplete( const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0 );
|
||||
extern bool UtlStringLessFunc( const CUtlString &lhs, const CUtlString &rhs );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: Create an NPC of the given type
|
||||
//------------------------------------------------------------------------------
|
||||
class CNPCCreateAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback
|
||||
{
|
||||
public:
|
||||
virtual bool CreateAimed() { return false; }
|
||||
|
||||
virtual void CommandCallback( const CCommand &args )
|
||||
{
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
bool allowPrecache = CBaseEntity::IsPrecacheAllowed();
|
||||
CBaseEntity::SetAllowPrecache( true );
|
||||
|
||||
// Try to create entity
|
||||
CAI_BaseNPC *baseNPC = dynamic_cast< CAI_BaseNPC * >( CreateEntityByName(args[1]) );
|
||||
if (baseNPC)
|
||||
{
|
||||
baseNPC->KeyValue( "additionalequipment", npc_create_equipment.GetString() );
|
||||
|
||||
if ( args.ArgC() == 3 )
|
||||
{
|
||||
baseNPC->SetName( AllocPooledString( args[2] ) );
|
||||
}
|
||||
else if ( args.ArgC() > 3 )
|
||||
{
|
||||
baseNPC->SetName( AllocPooledString( args[2] ) );
|
||||
|
||||
// Pass in any additional parameters.
|
||||
for ( int i = 3; i + 1 < args.ArgC(); i += 2 )
|
||||
{
|
||||
const char *pKeyName = args[i];
|
||||
const char *pValue = args[i+1];
|
||||
baseNPC->KeyValue( pKeyName, pValue );
|
||||
}
|
||||
}
|
||||
|
||||
DispatchSpawn(baseNPC);
|
||||
|
||||
// Now attempt to drop into the world
|
||||
CBasePlayer* pPlayer = UTIL_GetCommandClient();
|
||||
trace_t tr;
|
||||
Vector forward;
|
||||
QAngle angles;
|
||||
pPlayer->EyeVectors( &forward );
|
||||
|
||||
bool bCreateAimed = CreateAimed();
|
||||
if (bCreateAimed)
|
||||
{
|
||||
VectorAngles( forward, angles );
|
||||
angles.x = 0;
|
||||
angles.z = 0;
|
||||
}
|
||||
|
||||
AI_TraceLine(pPlayer->EyePosition(),
|
||||
pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_NPCSOLID,
|
||||
pPlayer, COLLISION_GROUP_NONE, &tr );
|
||||
if ( tr.fraction != 1.0)
|
||||
{
|
||||
if (baseNPC->CapabilitiesGet() & bits_CAP_MOVE_FLY)
|
||||
{
|
||||
Vector pos = tr.endpos - forward * 36;
|
||||
baseNPC->Teleport( &pos, bCreateAimed ? &angles : NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Raise the end position a little up off the floor, place the npc and drop him down
|
||||
tr.endpos.z += 12;
|
||||
baseNPC->Teleport( &tr.endpos, bCreateAimed ? &angles : NULL, NULL );
|
||||
UTIL_DropToFloor( baseNPC, MASK_NPCSOLID );
|
||||
}
|
||||
|
||||
// Now check that this is a valid location for the new npc to be
|
||||
Vector vUpBit = baseNPC->GetAbsOrigin();
|
||||
vUpBit.z += 1;
|
||||
|
||||
AI_TraceHull( baseNPC->GetAbsOrigin(), vUpBit, baseNPC->GetHullMins(), baseNPC->GetHullMaxs(),
|
||||
MASK_NPCSOLID, baseNPC, COLLISION_GROUP_NONE, &tr );
|
||||
if ( tr.startsolid || (tr.fraction < 1.0) )
|
||||
{
|
||||
baseNPC->SUB_Remove();
|
||||
DevMsg("Can't create %s. Bad Position!\n",args[1]);
|
||||
NDebugOverlay::Box(baseNPC->GetAbsOrigin(), baseNPC->GetHullMins(), baseNPC->GetHullMaxs(), 255, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else if (bCreateAimed)
|
||||
{
|
||||
baseNPC->Teleport( NULL, &angles, NULL );
|
||||
}
|
||||
|
||||
baseNPC->Activate();
|
||||
}
|
||||
CBaseEntity::SetAllowPrecache( allowPrecache );
|
||||
}
|
||||
|
||||
virtual int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands )
|
||||
{
|
||||
if ( !g_pGameRules )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *cmdname = CreateAimed() ? "npc_create_aimed" : "npc_create";
|
||||
|
||||
char *substring = (char *)partial;
|
||||
if ( Q_strstr( partial, cmdname ) )
|
||||
{
|
||||
substring = (char *)partial + strlen( cmdname ) + 1;
|
||||
}
|
||||
|
||||
int checklen = Q_strlen( substring );
|
||||
|
||||
if (checklen <= 0)
|
||||
{
|
||||
// Only show classnames prefixed with "npc" unless the user starts typing other characters
|
||||
substring = "npc";
|
||||
checklen = 3;
|
||||
}
|
||||
|
||||
CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc );
|
||||
return EntityFactory_AutoComplete( cmdname, commands, symbols, substring, checklen );
|
||||
}
|
||||
};
|
||||
|
||||
static CNPCCreateAutoCompletionFunctor g_NPCCreateAutoComplete;
|
||||
static ConCommand npc_create("npc_create", &g_NPCCreateAutoComplete, "Creates an NPC of the given type where the player is looking (if the given NPC can actually stand at that location).\n\tArguments: {npc_class_name}", FCVAR_CHEAT, &g_NPCCreateAutoComplete);
|
||||
|
||||
class CNPCCreateAimedAutoCompletionFunctor : public CNPCCreateAutoCompletionFunctor
|
||||
{
|
||||
public:
|
||||
virtual bool CreateAimed() { return true; }
|
||||
};
|
||||
|
||||
static CNPCCreateAimedAutoCompletionFunctor g_NPCCreateAimedAutoComplete;
|
||||
|
||||
static ConCommand npc_create_aimed("npc_create_aimed", &g_NPCCreateAimedAutoComplete, "Creates an NPC aimed away from the player of the given type where the player is looking (if the given NPC can actually stand at that location).\n\tArguments: {npc_class_name}", FCVAR_CHEAT, &g_NPCCreateAimedAutoComplete);
|
||||
#else
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: Create an NPC of the given type
|
||||
//------------------------------------------------------------------------------
|
||||
@ -540,6 +683,7 @@ void CC_NPC_Create_Aimed( const CCommand &args )
|
||||
CBaseEntity::SetAllowPrecache( allowPrecache );
|
||||
}
|
||||
static ConCommand npc_create_aimed("npc_create_aimed", CC_NPC_Create_Aimed, "Creates an NPC aimed away from the player of the given type where the player is looking (if the given NPC can actually stand at that location). Note that this only works for npc classes that are already in the world. You can not create an entity that doesn't have an instance in the level.\n\tArguments: {npc_class_name}", FCVAR_CHEAT);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: Destroy unselected NPCs
|
||||
@ -711,6 +855,134 @@ void CC_NPC_Reset( void )
|
||||
}
|
||||
static ConCommand npc_reset("npc_reset", CC_NPC_Reset, "Reloads schedules for all NPC's from their script files\n\tArguments: -none-", FCVAR_CHEAT);
|
||||
|
||||
#ifdef MAPBASE
|
||||
extern bool UtlStringLessFunc( const CUtlString &lhs, const CUtlString &rhs );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Auto-completes with entities in the entity list, but only uses NPC-derived entities.
|
||||
// Input : cmdname - The name of the command.
|
||||
// &commands - Where the complete autocompletes should be sent to.
|
||||
// substring - The current search query. (only pool entities that start with this)
|
||||
// checklen - The number of characters to check.
|
||||
// Output : A pointer to a cUtlRBTRee containing all of the entities.
|
||||
//------------------------------------------------------------------------------
|
||||
static int AutoCompleteNPCs(const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0)
|
||||
{
|
||||
CBaseEntity *pos = NULL;
|
||||
while ((pos = gEntList.NextEnt(pos)) != NULL)
|
||||
{
|
||||
if (!pos->IsNPC())
|
||||
continue;
|
||||
|
||||
const char *name = pos->GetClassname();
|
||||
if (pos->GetEntityName() == NULL_STRING || Q_strnicmp(STRING(pos->GetEntityName()), substring, checklen))
|
||||
{
|
||||
if (Q_strnicmp(pos->GetClassname(), substring, checklen))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
name = STRING(pos->GetEntityName());
|
||||
|
||||
CUtlString sym = name;
|
||||
int idx = symbols.Find(sym);
|
||||
if (idx == symbols.InvalidIndex())
|
||||
{
|
||||
symbols.Insert(sym);
|
||||
}
|
||||
|
||||
// Too many
|
||||
if (symbols.Count() >= COMMAND_COMPLETION_MAXITEMS)
|
||||
break;
|
||||
}
|
||||
|
||||
// Now fill in the results
|
||||
for (int i = symbols.FirstInorder(); i != symbols.InvalidIndex(); i = symbols.NextInorder(i))
|
||||
{
|
||||
const char *name = symbols[i].String();
|
||||
|
||||
char buf[512];
|
||||
Q_strncpy(buf, name, sizeof(buf));
|
||||
Q_strlower(buf);
|
||||
|
||||
CUtlString command;
|
||||
command = CFmtStr("%s %s", cmdname, buf);
|
||||
commands.AddToTail(command);
|
||||
}
|
||||
|
||||
return symbols.Count();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// There's a big set of NPC debug commands that do similar operations and
|
||||
// can fall under this base class for auto-completion, etc.
|
||||
//------------------------------------------------------------------------------
|
||||
class CNPCDebugAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback
|
||||
{
|
||||
public:
|
||||
virtual const char *CommandName() { return NULL; }
|
||||
virtual void CommandCallback( const CCommand &args )
|
||||
{
|
||||
SetDebugBits( UTIL_GetCommandClient(), args[1], OVERLAY_NPC_NEAREST_BIT );
|
||||
}
|
||||
|
||||
virtual int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands )
|
||||
{
|
||||
if ( !g_pGameRules )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *cmdname = CommandName();
|
||||
|
||||
char *substring = (char *)partial;
|
||||
if ( Q_strstr( partial, cmdname ) )
|
||||
{
|
||||
substring = (char *)partial + strlen( cmdname ) + 1;
|
||||
}
|
||||
|
||||
int checklen = Q_strlen( substring );
|
||||
|
||||
if (checklen == 0 || atoi(substring) != 0)
|
||||
{
|
||||
// Must be the picker or an entity index
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc );
|
||||
return AutoCompleteNPCs(cmdname, commands, symbols, substring, checklen);
|
||||
}
|
||||
};
|
||||
|
||||
#define NPCDebugCommand(name, functor, bit, help) class CNPC##functor##AutoCompletionFunctor : public CNPCDebugAutoCompletionFunctor \
|
||||
{ \
|
||||
public: \
|
||||
virtual const char *CommandName() { return #name; } \
|
||||
virtual void CommandCallback( const CCommand &args ) \
|
||||
{ \
|
||||
SetDebugBits( UTIL_GetCommandClient(), args[1], bit ); \
|
||||
} \
|
||||
}; \
|
||||
static CNPC##functor##AutoCompletionFunctor g_NPC##functor##AutoCompletionFunctor; \
|
||||
static ConCommand name(#name, &g_NPC##functor##AutoCompletionFunctor, help, FCVAR_CHEAT, &g_NPC##functor##AutoCompletionFunctor);
|
||||
|
||||
NPCDebugCommand( npc_nearest, Nearest, OVERLAY_NPC_NEAREST_BIT, "Draw's a while box around the NPC(s) nearest node\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at " );
|
||||
NPCDebugCommand( npc_route, Route, OVERLAY_NPC_ROUTE_BIT, "Displays the current route of the given NPC as a line on the screen. Waypoints along the route are drawn as small cyan rectangles. Line is color coded in the following manner:\n\tBlue - path to a node\n\tCyan - detour around an object (triangulation)\n\tRed - jump\n\tMaroon - path to final target position\n\tArguments: {npc_name} / {npc_class_name} / no argument picks what player is looking at " );
|
||||
NPCDebugCommand( npc_select, Select, OVERLAY_NPC_SELECTED_BIT, "Select or deselects the given NPC(s) for later manipulation. Selected NPC's are shown surrounded by a red translucent box\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at " );
|
||||
NPCDebugCommand( npc_combat, Combat, OVERLAY_NPC_SQUAD_BIT, "Displays text debugging information about the squad and enemy of the selected NPC (See Overlay Text)\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at" );
|
||||
NPCDebugCommand( npc_tasks, Tasks, OVERLAY_NPC_TASK_BIT, "Displays detailed text debugging information about the all the tasks of the selected NPC current schedule (See Overlay Text)\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at " );
|
||||
NPCDebugCommand( npc_task_text, TaskText, OVERLAY_TASK_TEXT_BIT, "Outputs text debugging information to the console about the all the tasks + break conditions of the selected NPC current schedule\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at " );
|
||||
NPCDebugCommand( npc_conditions, Conditions, OVERLAY_NPC_CONDITIONS_BIT, "Displays all the current AI conditions that an NPC has in the overlay text.\n\tArguments: {npc_name} / {npc class_name} / no argument picks what player is looking at" );
|
||||
NPCDebugCommand( npc_viewcone, Viewcone, OVERLAY_NPC_VIEWCONE_BIT, "Displays the viewcone of the NPC (where they are currently looking and what the extents of there vision is)\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at" );
|
||||
NPCDebugCommand( npc_relationships, Relationships, OVERLAY_NPC_RELATION_BIT, "Displays the relationships between this NPC and all others.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at" );
|
||||
NPCDebugCommand( npc_steering, Steering, OVERLAY_NPC_STEERING_REGULATIONS, "Displays the steering obstructions of the NPC( used to perform local avoidance )\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at" );
|
||||
|
||||
// For backwards compatibility
|
||||
void CC_NPC_Squads( const CCommand &args )
|
||||
{
|
||||
SetDebugBits( UTIL_GetCommandClient(),args[1],OVERLAY_NPC_SQUAD_BIT);
|
||||
}
|
||||
static ConCommand npc_squads("npc_squads", CC_NPC_Squads, "Obsolete. Replaced by npc_combat", FCVAR_CHEAT);
|
||||
#else
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: Show the selected NPC's nearest node
|
||||
//------------------------------------------------------------------------------
|
||||
@ -805,6 +1077,7 @@ void CC_NPC_ViewSteeringRegulations( const CCommand &args )
|
||||
SetDebugBits( UTIL_GetCommandClient(), args[1], OVERLAY_NPC_STEERING_REGULATIONS);
|
||||
}
|
||||
static ConCommand npc_steering("npc_steering", CC_NPC_ViewSteeringRegulations, "Displays the steering obstructions of the NPC (used to perform local avoidance)\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at", FCVAR_CHEAT);
|
||||
#endif
|
||||
|
||||
void CC_NPC_ViewSteeringRegulationsAll( void )
|
||||
{
|
||||
|
@ -608,7 +608,11 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *res
|
||||
if ( !result->ShouldntUseScene() )
|
||||
{
|
||||
// This generates a fake CChoreoScene wrapping the sound.txt name
|
||||
#ifdef MAPBASE
|
||||
spoke = SpeakAutoGeneratedScene( response, delay, result, filter );
|
||||
#else
|
||||
spoke = SpeakAutoGeneratedScene( response, delay );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -863,9 +867,17 @@ bool CAI_Expresser::SpeakRawScene( const char *pszScene, float delay, AI_Respons
|
||||
}
|
||||
|
||||
// This will create a fake .vcd/CChoreoScene to wrap the sound to be played
|
||||
#ifdef MAPBASE
|
||||
bool CAI_Expresser::SpeakAutoGeneratedScene( char const *soundname, float delay, AI_Response *response, IRecipientFilter *filter )
|
||||
#else
|
||||
bool CAI_Expresser::SpeakAutoGeneratedScene( char const *soundname, float delay )
|
||||
#endif
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
float speakTime = GetOuter()->PlayAutoGeneratedSoundScene( soundname, delay, response, filter );
|
||||
#else
|
||||
float speakTime = GetOuter()->PlayAutoGeneratedSoundScene( soundname );
|
||||
#endif
|
||||
if ( speakTime > 0 )
|
||||
{
|
||||
SpeechMsg( GetOuter(), "SpeakAutoGeneratedScene( %s, %f) %f\n", soundname, delay, speakTime );
|
||||
|
@ -208,7 +208,11 @@ protected:
|
||||
|
||||
bool SpeakRawScene( const char *pszScene, float delay, AI_Response *response, IRecipientFilter *filter = NULL );
|
||||
// This will create a fake .vcd/CChoreoScene to wrap the sound to be played
|
||||
#ifdef MAPBASE
|
||||
bool SpeakAutoGeneratedScene( char const *soundname, float delay, AI_Response *response = NULL, IRecipientFilter *filter = NULL );
|
||||
#else
|
||||
bool SpeakAutoGeneratedScene( char const *soundname, float delay );
|
||||
#endif
|
||||
|
||||
void DumpHistories();
|
||||
|
||||
|
@ -1524,6 +1524,30 @@ bool CBaseCombatCharacter::BecomeRagdollBoogie( CBaseEntity *pKiller, const Vect
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
CBaseEntity *CBaseCombatCharacter::BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags, const Vector *vecColor )
|
||||
{
|
||||
Assert( CanBecomeRagdoll() );
|
||||
|
||||
CTakeDamageInfo info( pKiller, pKiller, 1.0f, DMG_GENERIC );
|
||||
|
||||
info.SetDamageForce( forceVector );
|
||||
|
||||
CBaseEntity *pRagdoll = CreateServerRagdoll( this, 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, true );
|
||||
|
||||
pRagdoll->SetCollisionBounds( CollisionProp()->OBBMins(), CollisionProp()->OBBMaxs() );
|
||||
|
||||
CBaseEntity *pBoogie = CRagdollBoogie::Create( pRagdoll, 200, gpGlobals->curtime, duration, flags, vecColor );
|
||||
|
||||
CTakeDamageInfo ragdollInfo( pKiller, pKiller, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL );
|
||||
ragdollInfo.SetDamagePosition( WorldSpaceCenter() );
|
||||
ragdollInfo.SetDamageForce( Vector( 0, 0, 1 ) );
|
||||
TakeDamage( ragdollInfo );
|
||||
|
||||
return pBoogie;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -4020,6 +4044,11 @@ void CBaseCombatCharacter::InputPickupWeaponInstant( inputdata_t &inputdata )
|
||||
if (inputdata.value.Entity() && inputdata.value.Entity()->IsBaseCombatWeapon())
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = inputdata.value.Entity()->MyCombatWeaponPointer();
|
||||
if (pWeapon->GetOwner())
|
||||
{
|
||||
Msg("Ignoring PickupWeaponInstant on %s because %s already has an owner\n", GetDebugName(), pWeapon->GetDebugName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (CBaseCombatWeapon *pExistingWeapon = Weapon_OwnsThisType(pWeapon->GetClassname()))
|
||||
{
|
||||
@ -4036,6 +4065,8 @@ void CBaseCombatCharacter::InputPickupWeaponInstant( inputdata_t &inputdata )
|
||||
{
|
||||
Weapon_Equip(pWeapon);
|
||||
}
|
||||
|
||||
pWeapon->OnPickedUp( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -333,6 +333,12 @@ public:
|
||||
|
||||
virtual bool BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags );
|
||||
|
||||
#ifdef MAPBASE
|
||||
// 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 );
|
||||
#endif
|
||||
|
||||
CBaseEntity *FindHealthItem( const Vector &vecPosition, const Vector &range );
|
||||
|
||||
|
||||
|
@ -2037,6 +2037,8 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity )
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VECTOR, "SetLocalOrigin", InputSetLocalOrigin ),
|
||||
DEFINE_INPUTFUNC( FIELD_VECTOR, "SetLocalAngles", InputSetLocalAngles ),
|
||||
DEFINE_INPUTFUNC( FIELD_VECTOR, "SetAbsOrigin", InputSetAbsOrigin ),
|
||||
DEFINE_INPUTFUNC( FIELD_VECTOR, "SetAbsAngles", InputSetAbsAngles ),
|
||||
DEFINE_INPUTFUNC( FIELD_VECTOR, "SetLocalVelocity", InputSetLocalVelocity ),
|
||||
DEFINE_INPUTFUNC( FIELD_VECTOR, "SetLocalAngularVelocity", InputSetLocalAngularVelocity ),
|
||||
|
||||
@ -7092,7 +7094,7 @@ const char *CBaseEntity::GetContextValue( const char *contextName ) const
|
||||
{
|
||||
int idx = FindContextByName( contextName );
|
||||
if ( idx == -1 )
|
||||
return NULL;
|
||||
return "";
|
||||
|
||||
return m_ResponseContexts[ idx ].m_iszValue.ToCStr();
|
||||
}
|
||||
@ -7554,10 +7556,30 @@ void CBaseEntity::InputSetLocalOrigin( inputdata_t& inputdata )
|
||||
// Purpose: Sets our angles.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::InputSetLocalAngles( inputdata_t& inputdata )
|
||||
{
|
||||
QAngle ang;
|
||||
inputdata.value.Angle3D(ang);
|
||||
SetLocalAngles(ang);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets our origin.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::InputSetAbsOrigin( inputdata_t& inputdata )
|
||||
{
|
||||
Vector vec;
|
||||
inputdata.value.Vector3D(vec);
|
||||
SetLocalAngles(QAngle(vec.x, vec.y, vec.z));
|
||||
SetAbsOrigin(vec);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets our angles.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::InputSetAbsAngles( inputdata_t& inputdata )
|
||||
{
|
||||
QAngle ang;
|
||||
inputdata.value.Angle3D(ang);
|
||||
SetAbsAngles(ang);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -8746,6 +8768,130 @@ void CBaseEntity::SetCollisionBoundsFromModel()
|
||||
}
|
||||
|
||||
|
||||
#ifdef MAPBASE
|
||||
extern int EntityFactory_AutoComplete( const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0 );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: Create an entity of the given type
|
||||
//------------------------------------------------------------------------------
|
||||
class CEntCreateAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback
|
||||
{
|
||||
public:
|
||||
virtual bool CreateAimed() { return false; }
|
||||
|
||||
virtual void CommandCallback( const CCommand &args )
|
||||
{
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_GetCommandClient();
|
||||
if (!pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't allow regular users to create point_servercommand entities for the same reason as blocking ent_fire
|
||||
if ( !Q_stricmp( args[1], "point_servercommand" ) )
|
||||
{
|
||||
if ( engine->IsDedicatedServer() )
|
||||
{
|
||||
// We allow people with disabled autokick to do it, because they already have rcon.
|
||||
if ( pPlayer->IsAutoKickDisabled() == false )
|
||||
return;
|
||||
}
|
||||
else if ( gpGlobals->maxClients > 1 )
|
||||
{
|
||||
// On listen servers with more than 1 player, only allow the host to create point_servercommand.
|
||||
CBasePlayer *pHostPlayer = UTIL_GetListenServerHost();
|
||||
if ( pPlayer != pHostPlayer )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool allowPrecache = CBaseEntity::IsPrecacheAllowed();
|
||||
CBaseEntity::SetAllowPrecache( true );
|
||||
|
||||
// Try to create entity
|
||||
CBaseEntity *entity = dynamic_cast< CBaseEntity * >( CreateEntityByName(args[1]) );
|
||||
if (entity)
|
||||
{
|
||||
// Pass in any additional parameters.
|
||||
for ( int i = 2; i + 1 < args.ArgC(); i += 2 )
|
||||
{
|
||||
const char *pKeyName = args[i];
|
||||
const char *pValue = args[i+1];
|
||||
entity->KeyValue( pKeyName, pValue );
|
||||
}
|
||||
|
||||
DispatchSpawn(entity);
|
||||
|
||||
// Now attempt to drop into the world
|
||||
trace_t tr;
|
||||
Vector forward;
|
||||
pPlayer->EyeVectors( &forward );
|
||||
UTIL_TraceLine(pPlayer->EyePosition(),
|
||||
pPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_SOLID,
|
||||
pPlayer, COLLISION_GROUP_NONE, &tr );
|
||||
if ( tr.fraction != 1.0 )
|
||||
{
|
||||
// Raise the end position a little up off the floor, place the npc and drop him down
|
||||
tr.endpos.z += 12;
|
||||
|
||||
if (CreateAimed())
|
||||
{
|
||||
QAngle angles;
|
||||
VectorAngles( forward, angles );
|
||||
angles.x = 0;
|
||||
angles.z = 0;
|
||||
entity->Teleport( &tr.endpos, &angles, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
entity->Teleport( &tr.endpos, NULL, NULL );
|
||||
}
|
||||
|
||||
UTIL_DropToFloor( entity, MASK_SOLID );
|
||||
}
|
||||
|
||||
entity->Activate();
|
||||
}
|
||||
CBaseEntity::SetAllowPrecache( allowPrecache );
|
||||
}
|
||||
|
||||
virtual int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands )
|
||||
{
|
||||
if ( !g_pGameRules )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *cmdname = CreateAimed() ? "ent_create_aimed" : "ent_create";
|
||||
|
||||
char *substring = (char *)partial;
|
||||
if ( Q_strstr( partial, cmdname ) )
|
||||
{
|
||||
substring = (char *)partial + strlen( cmdname ) + 1;
|
||||
}
|
||||
|
||||
int checklen = Q_strlen( substring );
|
||||
|
||||
CUtlRBTree< CUtlString > symbols( 0, 0, UtlStringLessFunc );
|
||||
return EntityFactory_AutoComplete( cmdname, commands, symbols, substring, checklen );
|
||||
}
|
||||
};
|
||||
|
||||
static CEntCreateAutoCompletionFunctor g_EntCreateAutoComplete;
|
||||
static ConCommand ent_create("ent_create", &g_EntCreateAutoComplete, "Creates an entity of the given type where the player is looking. Additional parameters can be passed in in the form: ent_create <entity name> <param 1 name> <param 1> <param 2 name> <param 2>...<param N name> <param N>", FCVAR_GAMEDLL | FCVAR_CHEAT, &g_EntCreateAutoComplete);
|
||||
|
||||
class CEntCreateAimedAutoCompletionFunctor : public CEntCreateAutoCompletionFunctor
|
||||
{
|
||||
public:
|
||||
virtual bool CreateAimed() { return true; }
|
||||
};
|
||||
|
||||
static CEntCreateAimedAutoCompletionFunctor g_EntCreateAimedAutoComplete;
|
||||
|
||||
static ConCommand ent_create_aimed("ent_create_aimed", &g_EntCreateAimedAutoComplete, "Creates an entity of the given type where the player is looking. Additional parameters can be passed in in the form: ent_create_aimed <entity name> <param 1 name> <param 1> <param 2 name> <param 2>...<param N name> <param N>", FCVAR_CHEAT, &g_EntCreateAimedAutoComplete);
|
||||
#else
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: Create an NPC of the given type
|
||||
//------------------------------------------------------------------------------
|
||||
@ -8816,6 +8962,7 @@ void CC_Ent_Create( const CCommand& args )
|
||||
CBaseEntity::SetAllowPrecache( allowPrecache );
|
||||
}
|
||||
static ConCommand ent_create("ent_create", CC_Ent_Create, "Creates an entity of the given type where the player is looking. Additional parameters can be passed in in the form: ent_create <entity name> <param 1 name> <param 1> <param 2 name> <param 2>...<param N name> <param N>", FCVAR_GAMEDLL | FCVAR_CHEAT);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: Teleport a specified entity to where the player is looking
|
||||
|
@ -700,6 +700,8 @@ public:
|
||||
|
||||
void InputSetLocalOrigin( inputdata_t &inputdata );
|
||||
void InputSetLocalAngles( inputdata_t &inputdata );
|
||||
void InputSetAbsOrigin( inputdata_t &inputdata );
|
||||
void InputSetAbsAngles( inputdata_t &inputdata );
|
||||
void InputSetLocalVelocity( inputdata_t &inputdata );
|
||||
void InputSetLocalAngularVelocity( inputdata_t &inputdata );
|
||||
|
||||
@ -1267,6 +1269,18 @@ public:
|
||||
virtual float GetDamage() { return 0; }
|
||||
virtual void SetDamage(float flDamage) {}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Some entities want to use interactions regardless of whether they're a CBaseCombatCharacter.
|
||||
// Valve ran into this issue with frag grenades when they started deriving from CBaseAnimating instead of CBaseCombatCharacter,
|
||||
// preventing them from using the barnacle interactions for rigged grenade timing so it's guaranteed to blow up in the barnacle's face.
|
||||
// We're used to unaltered behavior now, so we're not restoring that as default, but making this a "base entity" thing is supposed to help in situtions like those.
|
||||
//
|
||||
// Also, keep in mind pretty much all existing DispatchInteraction() calls are only performed on CBaseCombatCharacters.
|
||||
// You'll need to change their code manually if you want other, non-character entities to use the interaction.
|
||||
bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return ( interactionType > 0 ) ? HandleInteraction( interactionType, data, sourceEnt ) : false; }
|
||||
virtual bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return false; }
|
||||
#endif
|
||||
|
||||
virtual Vector EyePosition( void ); // position of eyes
|
||||
virtual const QAngle &EyeAngles( void ); // Direction of eyes in world space
|
||||
virtual const QAngle &LocalEyeAngles( void ); // Direction of eyes
|
||||
|
@ -2004,10 +2004,17 @@ float CBaseFlex::PlayScene( const char *pszScene, float flDelay, AI_Response *re
|
||||
// Input : *soundname -
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef MAPBASE
|
||||
float CBaseFlex::PlayAutoGeneratedSoundScene( const char *soundname, float flDelay, AI_Response *response, IRecipientFilter *filter )
|
||||
{
|
||||
return InstancedAutoGeneratedSoundScene( this, soundname, NULL, flDelay, false, response, false, filter );
|
||||
}
|
||||
#else
|
||||
float CBaseFlex::PlayAutoGeneratedSoundScene( const char *soundname )
|
||||
{
|
||||
return InstancedAutoGeneratedSoundScene( this, soundname );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -116,7 +116,11 @@ public:
|
||||
void SentenceStop( void ) { EmitSound( "AI_BaseNPC.SentenceStop" ); }
|
||||
|
||||
virtual float PlayScene( const char *pszScene, float flDelay = 0.0f, AI_Response *response = NULL, IRecipientFilter *filter = NULL );
|
||||
#ifdef MAPBASE
|
||||
virtual float PlayAutoGeneratedSoundScene( const char *soundname, float flDelay = 0.0f, AI_Response *response = NULL, IRecipientFilter *filter = NULL );
|
||||
#else
|
||||
virtual float PlayAutoGeneratedSoundScene( const char *soundname );
|
||||
#endif
|
||||
|
||||
virtual int GetSpecialDSP( void ) { return 0; }
|
||||
|
||||
|
@ -1504,12 +1504,6 @@ void CItemSoda::CanTouch ( CBaseEntity *pOther )
|
||||
// technology demo
|
||||
//=========================================================
|
||||
|
||||
#ifdef MAPBASE
|
||||
// I would leave this on the client, but it sems as if I could only precache the particle system on the server for some reason.
|
||||
// That desn't sound right...look into this further later.
|
||||
ConVar r_RainParticle( "r_RainParticle", "Rain_01_impact", FCVAR_CHEAT | FCVAR_REPLICATED );
|
||||
#endif
|
||||
|
||||
class CPrecipitation : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
@ -1546,9 +1540,6 @@ void CPrecipitation::Spawn( void )
|
||||
PrecacheMaterial( "effects/fleck_ash2" );
|
||||
PrecacheMaterial( "effects/fleck_ash3" );
|
||||
PrecacheMaterial( "effects/ember_swirling001" );
|
||||
#ifdef MAPBASE
|
||||
PrecacheParticleSystem( r_RainParticle.GetString() );
|
||||
#endif
|
||||
|
||||
Precache();
|
||||
SetSolid( SOLID_NONE ); // Remove model & collisions
|
||||
|
@ -152,6 +152,29 @@ public:
|
||||
{
|
||||
m_Value.Vector3D(vec);
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Shortcut to using QAngles in Vector outputs, makes it look cleaner and allows easy modification
|
||||
void Init( const QAngle &value )
|
||||
{
|
||||
// reinterpret_cast<const Vector&>(value)
|
||||
m_Value.SetAngle3D( value );
|
||||
}
|
||||
|
||||
// Shortcut to using QAngles in Vector outputs, makes it look cleaner and allows easy modification
|
||||
void Set( const QAngle &value, CBaseEntity *pActivator, CBaseEntity *pCaller )
|
||||
{
|
||||
// reinterpret_cast<const Vector&>(value)
|
||||
m_Value.SetAngle3D( value );
|
||||
FireOutput( m_Value, pActivator, pCaller );
|
||||
}
|
||||
|
||||
// Shortcut to using QAngles in Vector outputs, makes it look cleaner and allows easy modification
|
||||
void Get( QAngle &ang )
|
||||
{
|
||||
m_Value.Angle3D(ang);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -40,6 +40,13 @@ public:
|
||||
#ifdef MAPBASE
|
||||
void InputSetBrightness( inputdata_t &inputdata );
|
||||
void InputSetColorTransitionTime( inputdata_t &inputdata );
|
||||
void InputSetXOffset( inputdata_t &inputdata ) { m_flEastOffset = inputdata.value.Float(); }
|
||||
void InputSetYOffset( inputdata_t &inputdata ) { m_flForwardOffset = inputdata.value.Float(); }
|
||||
void InputSetOrthoSize( inputdata_t &inputdata ) { m_flOrthoSize = inputdata.value.Float(); }
|
||||
void InputSetDistance( inputdata_t &inputdata ) { m_flSunDistance = inputdata.value.Float(); }
|
||||
void InputSetFOV( inputdata_t &inputdata ) { m_flFOV = inputdata.value.Float(); }
|
||||
void InputSetNearZDistance( inputdata_t &inputdata ) { m_flNearZ = inputdata.value.Float(); }
|
||||
void InputSetNorthOffset( inputdata_t &inputdata ) { m_flNorthOffset = inputdata.value.Float(); }
|
||||
#endif
|
||||
|
||||
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
||||
@ -101,14 +108,19 @@ BEGIN_DATADESC( CGlobalLight )
|
||||
DEFINE_KEYFIELD( m_flColorTransitionTime, FIELD_FLOAT, "colortransitiontime" ),
|
||||
|
||||
// Inputs
|
||||
#ifdef MAPBASE
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetXOffset", InputSetXOffset ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetYOffset", InputSetYOffset ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetOrthoSize", InputSetOrthoSize ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetDistance", InputSetDistance ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFOV", InputSetFOV ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearZDistance", InputSetNearZDistance ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNorthOffset", InputSetNorthOffset ),
|
||||
#else
|
||||
DEFINE_INPUT( m_flSunDistance, FIELD_FLOAT, "SetDistance" ),
|
||||
DEFINE_INPUT( m_flFOV, FIELD_FLOAT, "SetFOV" ),
|
||||
DEFINE_INPUT( m_flNearZ, FIELD_FLOAT, "SetNearZDistance" ),
|
||||
DEFINE_INPUT( m_flNorthOffset, FIELD_FLOAT, "SetNorthOffset" ),
|
||||
#ifdef MAPBASE
|
||||
DEFINE_INPUT( m_flEastOffset, FIELD_FLOAT, "SetXOffset" ),
|
||||
DEFINE_INPUT( m_flForwardOffset, FIELD_FLOAT, "SetYOffset" ),
|
||||
DEFINE_INPUT( m_flOrthoSize, FIELD_FLOAT, "SetOrthoSize" ),
|
||||
#endif
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_COLOR32, "LightColor", InputSetLightColor ),
|
||||
@ -183,7 +195,11 @@ int CGlobalLight::UpdateTransmitState()
|
||||
|
||||
bool CGlobalLight::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
if ( FStrEq( szKeyName, "lightcolor" ) || FStrEq( szKeyName, "color" ) )
|
||||
#else
|
||||
if ( FStrEq( szKeyName, "color" ) )
|
||||
#endif
|
||||
{
|
||||
float tmp[4];
|
||||
UTIL_StringToFloatArray( tmp, 4, szValue );
|
||||
|
@ -44,6 +44,12 @@ BEGIN_DATADESC( CEnvProjectedTexture )
|
||||
DEFINE_KEYFIELD( m_flBrightnessScale, FIELD_FLOAT, "brightnessscale" ),
|
||||
DEFINE_FIELD( m_LightColor, FIELD_COLOR32 ),
|
||||
DEFINE_KEYFIELD( m_flColorTransitionTime, FIELD_FLOAT, "colortransitiontime" ),
|
||||
#ifdef MAPBASE
|
||||
DEFINE_FIELD( m_flConstantAtten, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( m_flLinearAtten, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( m_flQuadraticAtten, FIELD_FLOAT ),
|
||||
DEFINE_KEYFIELD( m_flShadowAtten, FIELD_FLOAT, "shadowatten" ),
|
||||
#endif
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ),
|
||||
@ -66,9 +72,14 @@ BEGIN_DATADESC( CEnvProjectedTexture )
|
||||
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSpotlightFrame", InputSetSpotlightFrame ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetBrightness", InputSetBrightness ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetColorTransitionTime", InputSetColorTransitionTime ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetQuadratic", InputSetQuadratic ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetLinear", InputSetLinear ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetConstant", InputSetConstant ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetShadowAtten", InputSetShadowAtten ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearZ", InputSetNearZ ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarZ", InputSetFarZ ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysDrawOn", InputAlwaysDrawOn ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysDrawOff", InputAlwaysDrawOff ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "StopFollowingTarget", InputStopFollowingTarget ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "StartFollowingTarget", InputStartFollowingTarget ),
|
||||
#endif
|
||||
@ -100,6 +111,10 @@ IMPLEMENT_SERVERCLASS_ST( CEnvProjectedTexture, DT_EnvProjectedTexture )
|
||||
SendPropFloat( SENDINFO( m_flFarZ ), 18, SPROP_ROUNDDOWN, 0.0f, 1500.0f ),
|
||||
SendPropInt( SENDINFO( m_nShadowQuality ), 1, SPROP_UNSIGNED ), // Just one bit for now
|
||||
#ifdef MAPBASE
|
||||
SendPropFloat( SENDINFO( m_flConstantAtten ) ),
|
||||
SendPropFloat( SENDINFO( m_flLinearAtten ) ),
|
||||
SendPropFloat( SENDINFO( m_flQuadraticAtten ) ),
|
||||
SendPropFloat( SENDINFO( m_flShadowAtten ) ),
|
||||
SendPropBool( SENDINFO( m_bAlwaysDraw ) ),
|
||||
|
||||
// Not needed on the client right now, change when it actually is needed
|
||||
@ -128,11 +143,21 @@ CEnvProjectedTexture::CEnvProjectedTexture( void )
|
||||
m_nSpotlightTextureFrame = 0;
|
||||
m_flBrightnessScale = 1.0f;
|
||||
m_LightColor.Init( 255, 255, 255, 255 );
|
||||
#ifdef MAPBASE
|
||||
m_flColorTransitionTime = 0.0f;
|
||||
#else
|
||||
m_flColorTransitionTime = 0.5f;
|
||||
#endif
|
||||
m_flAmbient = 0.0f;
|
||||
m_flNearZ = 4.0f;
|
||||
m_flFarZ = 750.0f;
|
||||
m_nShadowQuality = 0;
|
||||
#ifdef MAPBASE
|
||||
m_flQuadraticAtten = 0.0f;
|
||||
m_flLinearAtten = 100.0f;
|
||||
m_flConstantAtten = 0.0f;
|
||||
m_flShadowAtten = 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void UTIL_ColorStringToLinearFloatColor( Vector &color, const char *pString )
|
||||
@ -195,6 +220,20 @@ bool CEnvProjectedTexture::KeyValue( const char *szKeyName, const char *szValue
|
||||
Q_strcpy( m_SpotlightTextureName.GetForModify(), szValue );
|
||||
#endif
|
||||
}
|
||||
#ifdef MAPBASE
|
||||
else if ( FStrEq( szKeyName, "constant_attn" ) )
|
||||
{
|
||||
m_flConstantAtten = CorrectConstantAtten( atof( szValue ) );
|
||||
}
|
||||
else if ( FStrEq( szKeyName, "linear_attn" ) )
|
||||
{
|
||||
m_flLinearAtten = CorrectLinearAtten( atof( szValue ) );
|
||||
}
|
||||
else if ( FStrEq( szKeyName, "quadratic_attn" ) )
|
||||
{
|
||||
m_flQuadraticAtten = CorrectQuadraticAtten( atof( szValue ) );
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return BaseClass::KeyValue( szKeyName, szValue );
|
||||
@ -215,6 +254,26 @@ bool CEnvProjectedTexture::GetKeyValue( const char *szKeyName, char *szValue, in
|
||||
Q_snprintf( szValue, iMaxLen, "%s", m_SpotlightTextureName.Get() );
|
||||
return true;
|
||||
}
|
||||
#ifdef MAPBASE
|
||||
else if ( FStrEq( szKeyName, "constant_attn" ) )
|
||||
{
|
||||
// Undo correction
|
||||
Q_snprintf( szValue, iMaxLen, "%f", m_flConstantAtten *= 2.0f );
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( szKeyName, "linear_attn" ) )
|
||||
{
|
||||
// Undo correction
|
||||
Q_snprintf( szValue, iMaxLen, "%f", m_flLinearAtten *= 0.01f );
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( szKeyName, "quadratic_attn" ) )
|
||||
{
|
||||
// Undo correction
|
||||
Q_snprintf( szValue, iMaxLen, "%f", m_flQuadraticAtten *= 0.0001f );
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen );
|
||||
}
|
||||
|
||||
|
@ -54,12 +54,21 @@ public:
|
||||
void InputSetSpotlightFrame( inputdata_t &inputdata );
|
||||
void InputSetBrightness( inputdata_t &inputdata );
|
||||
void InputSetColorTransitionTime( inputdata_t &inputdata );
|
||||
void InputSetConstant( inputdata_t &inputdata ) { m_flConstantAtten = CorrectConstantAtten(inputdata.value.Float()); }
|
||||
void InputSetLinear( inputdata_t &inputdata ) { m_flLinearAtten = CorrectLinearAtten(inputdata.value.Float()); }
|
||||
void InputSetQuadratic( inputdata_t &inputdata ) { m_flQuadraticAtten = CorrectQuadraticAtten(inputdata.value.Float()); }
|
||||
void InputSetShadowAtten( inputdata_t &inputdata ) { m_flShadowAtten = inputdata.value.Float(); }
|
||||
void InputSetNearZ( inputdata_t &inputdata );
|
||||
void InputSetFarZ( inputdata_t &inputdata );
|
||||
void InputAlwaysDrawOn( inputdata_t &inputdata ) { m_bAlwaysDraw = true; }
|
||||
void InputAlwaysDrawOff( inputdata_t &inputdata ) { m_bAlwaysDraw = false; }
|
||||
void InputStopFollowingTarget( inputdata_t &inputdata ) { m_bDontFollowTarget = true; }
|
||||
void InputStartFollowingTarget( inputdata_t &inputdata ) { m_bDontFollowTarget = false; }
|
||||
|
||||
// Corrects keyvalue/input attenuation for internal FlashlightEffect_t attenuation.
|
||||
float CorrectConstantAtten( float fl ) { return fl * 0.5f; }
|
||||
float CorrectLinearAtten( float fl ) { return fl * 100.0f; }
|
||||
float CorrectQuadraticAtten( float fl ) { return fl * 10000.0f; }
|
||||
#endif
|
||||
|
||||
void InitialThink( void );
|
||||
@ -91,11 +100,17 @@ private:
|
||||
CNetworkVar( float, m_flFarZ );
|
||||
CNetworkVar( int, m_nShadowQuality );
|
||||
#ifdef MAPBASE
|
||||
CNetworkVar( float, m_flConstantAtten );
|
||||
CNetworkVar( float, m_flLinearAtten );
|
||||
CNetworkVar( float, m_flQuadraticAtten );
|
||||
CNetworkVar( float, m_flShadowAtten );
|
||||
|
||||
CNetworkVar( bool, m_bAlwaysDraw );
|
||||
|
||||
// 1 = New projected texture
|
||||
// 0 = Non-Mapbase projected texture, e.g. one that uses the VDC parenting fix instead of the spawnflag
|
||||
CNetworkVar( bool, m_bProjectedTextureVersion );
|
||||
// Not needed on the client right now, change to CNetworkVar when it actually is needed
|
||||
bool m_bProjectedTextureVersion;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
@ -3504,7 +3504,13 @@ void CNPC_Hunter::StartTask( const Task_t *pTask )
|
||||
{
|
||||
SetLastAttackTime( gpGlobals->curtime );
|
||||
|
||||
#ifdef MAPBASE
|
||||
// The "VS_PLAYER" animation looks better than the regular animation when used against non-humans
|
||||
if ( GetEnemy() && (GetEnemy()->IsPlayer() ||
|
||||
(GetEnemy()->IsCombatCharacter() && GetEnemy()->MyCombatCharacterPointer()->GetHullType() != HULL_HUMAN)) )
|
||||
#else
|
||||
if ( GetEnemy() && GetEnemy()->IsPlayer() )
|
||||
#endif
|
||||
{
|
||||
ResetIdealActivity( ( Activity )ACT_HUNTER_MELEE_ATTACK1_VS_PLAYER );
|
||||
}
|
||||
|
@ -369,6 +369,11 @@ BEGIN_DATADESC( CPropJeepEpisodic )
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetCargoHopperVisibility", InputSetCargoVisibility ),
|
||||
|
||||
#ifdef MAPBASE
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "EnableHazardLights", InputEnableHazardLights ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "DisableHazardLights", InputDisableHazardLights ),
|
||||
#endif
|
||||
|
||||
END_DATADESC();
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CPropJeepEpisodic, DT_CPropJeepEpisodic)
|
||||
@ -1422,6 +1427,26 @@ void CPropJeepEpisodic::DestroyHazardLights( void )
|
||||
SetContextThink( NULL, gpGlobals->curtime, "HazardBlink" );
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
void CPropJeepEpisodic::InputEnableHazardLights( inputdata_t &data )
|
||||
{
|
||||
if (m_bNoHazardLights)
|
||||
{
|
||||
m_bNoHazardLights = false;
|
||||
CreateHazardLights();
|
||||
}
|
||||
}
|
||||
|
||||
void CPropJeepEpisodic::InputDisableHazardLights( inputdata_t &data )
|
||||
{
|
||||
if (!m_bNoHazardLights)
|
||||
{
|
||||
m_bNoHazardLights = true;
|
||||
DestroyHazardLights();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : nRole -
|
||||
|
@ -104,6 +104,10 @@ private:
|
||||
void InputEnableRadarDetectEnemies( inputdata_t &data );
|
||||
void InputAddBusterToCargo( inputdata_t &data );
|
||||
void InputSetCargoVisibility( inputdata_t &data );
|
||||
#ifdef MAPBASE
|
||||
void InputEnableHazardLights( inputdata_t &data );
|
||||
void InputDisableHazardLights( inputdata_t &data );
|
||||
#endif
|
||||
void InputOutsideTransition( inputdata_t &data );
|
||||
#ifndef MAPBASE
|
||||
void InputDisablePhysGun( inputdata_t &data );
|
||||
|
@ -17,6 +17,10 @@
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#ifdef MAPBASE
|
||||
ConVar explosion_sparks("explosion_sparks", "0", FCVAR_NONE);
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spark shower, created by the explosion entity.
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -358,7 +362,11 @@ void CEnvExplosion::InputExplode( inputdata_t &inputdata )
|
||||
SetNextThink( gpGlobals->curtime + 0.3 );
|
||||
|
||||
// Only do these effects if we're not submerged
|
||||
#ifdef MAPBASE
|
||||
if ( explosion_sparks.GetBool() && !(UTIL_PointContents( GetAbsOrigin() ) & CONTENTS_WATER) )
|
||||
#else
|
||||
if ( UTIL_PointContents( GetAbsOrigin() ) & CONTENTS_WATER )
|
||||
#endif
|
||||
{
|
||||
// draw sparks
|
||||
if ( !( m_spawnflags & SF_ENVEXPLOSION_NOSPARKS ) )
|
||||
|
@ -171,6 +171,12 @@ class CFilterMultiple : public CBaseFilter
|
||||
bool PassesDamageFilterImpl(const CTakeDamageInfo &info);
|
||||
#endif
|
||||
void Activate(void);
|
||||
|
||||
#ifdef MAPBASE
|
||||
bool BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info );
|
||||
bool PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info );
|
||||
bool DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info );
|
||||
#endif
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(filter_multi, CFilterMultiple);
|
||||
@ -304,9 +310,9 @@ bool CFilterMultiple::PassesDamageFilterImpl(const CTakeDamageInfo &info)
|
||||
{
|
||||
CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get());
|
||||
#ifdef MAPBASE
|
||||
if (!pFilter->PassesDamageFilter(pCaller, info))
|
||||
if (pFilter->PassesDamageFilter(pCaller, info))
|
||||
#else
|
||||
if (!pFilter->PassesDamageFilter(info))
|
||||
if (pFilter->PassesDamageFilter(info))
|
||||
#endif
|
||||
{
|
||||
return true;
|
||||
@ -317,6 +323,125 @@ bool CFilterMultiple::PassesDamageFilterImpl(const CTakeDamageInfo &info)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if blood should be allowed, false if not.
|
||||
// Input : pEntity - Entity to test.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFilterMultiple::BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info )
|
||||
{
|
||||
// Test against each filter
|
||||
if (m_nFilterType == FILTER_AND)
|
||||
{
|
||||
for (int i=0;i<MAX_FILTERS;i++)
|
||||
{
|
||||
if (m_hFilter[i] != NULL)
|
||||
{
|
||||
CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get());
|
||||
if (!pFilter->BloodAllowed(pCaller, info))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else // m_nFilterType == FILTER_OR
|
||||
{
|
||||
for (int i=0;i<MAX_FILTERS;i++)
|
||||
{
|
||||
if (m_hFilter[i] != NULL)
|
||||
{
|
||||
CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get());
|
||||
if (pFilter->BloodAllowed(pCaller, info))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if the entity passes our filter, false if not.
|
||||
// Input : pEntity - Entity to test.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFilterMultiple::PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info )
|
||||
{
|
||||
// Test against each filter
|
||||
if (m_nFilterType == FILTER_AND)
|
||||
{
|
||||
for (int i=0;i<MAX_FILTERS;i++)
|
||||
{
|
||||
if (m_hFilter[i] != NULL)
|
||||
{
|
||||
CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get());
|
||||
if (!pFilter->PassesFinalDamageFilter(pCaller, info))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else // m_nFilterType == FILTER_OR
|
||||
{
|
||||
for (int i=0;i<MAX_FILTERS;i++)
|
||||
{
|
||||
if (m_hFilter[i] != NULL)
|
||||
{
|
||||
CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get());
|
||||
if (pFilter->PassesFinalDamageFilter(pCaller, info))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if damage should be modded, false if not.
|
||||
// Input : pEntity - Entity to test.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFilterMultiple::DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info )
|
||||
{
|
||||
// Test against each filter
|
||||
if (m_nFilterType == FILTER_AND)
|
||||
{
|
||||
for (int i=0;i<MAX_FILTERS;i++)
|
||||
{
|
||||
if (m_hFilter[i] != NULL)
|
||||
{
|
||||
CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get());
|
||||
if (!pFilter->DamageMod(pCaller, info))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else // m_nFilterType == FILTER_OR
|
||||
{
|
||||
for (int i=0;i<MAX_FILTERS;i++)
|
||||
{
|
||||
if (m_hFilter[i] != NULL)
|
||||
{
|
||||
CBaseFilter* pFilter = (CBaseFilter *)(m_hFilter[i].Get());
|
||||
if (pFilter->DamageMod(pCaller, info))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// ###################################################################
|
||||
// > FilterName
|
||||
|
@ -1059,11 +1059,6 @@ void CBreakable::Die( void )
|
||||
iCount = func_break_max_pieces.GetInt();
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// TEMP TEMP TEMP TEMP
|
||||
DevMsg("vSize: %f %f %f\n", vSize.x, vSize.y, vSize.z);
|
||||
#endif
|
||||
|
||||
ConVarRef breakable_disable_gib_limit( "breakable_disable_gib_limit" );
|
||||
if ( !breakable_disable_gib_limit.GetBool() && iCount )
|
||||
{
|
||||
|
@ -89,6 +89,9 @@
|
||||
#include "tier3/tier3.h"
|
||||
#include "serverbenchmark_base.h"
|
||||
#include "querycache.h"
|
||||
#ifdef MAPBASE
|
||||
#include "world.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TF_DLL
|
||||
@ -701,6 +704,9 @@ bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory,
|
||||
IGameSystem::Add( SoundEmitterSystem() );
|
||||
|
||||
// load Mod specific game events ( MUST be before InitAllSystems() so it can pickup the mod specific events)
|
||||
#ifdef MAPBASE
|
||||
gameeventmanager->LoadEventsFromFile("resource/MapbaseEvents.res");
|
||||
#endif
|
||||
gameeventmanager->LoadEventsFromFile("resource/ModEvents.res");
|
||||
|
||||
#ifdef CSTRIKE_DLL // BOTPORT: TODO: move these ifdefs out
|
||||
@ -1733,6 +1739,17 @@ void CServerGameDLL::GetTitleName( const char *pMapName, char* pTitleBuff, int t
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Check the world entity for a chapter title.
|
||||
if ( CWorld *pWorld = GetWorldEntity() )
|
||||
{
|
||||
const char *pWorldChapter = pWorld->GetChapterTitle();
|
||||
if ( pWorldChapter && pWorldChapter[0] != '\0' )
|
||||
Q_strncpy( chapterTitle, pWorldChapter, sizeof( chapterTitle ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_strncpy( pTitleBuff, pMapName, titleBuffSize );
|
||||
}
|
||||
#endif
|
||||
@ -1771,6 +1788,16 @@ void CServerGameDLL::GetSaveComment( char *text, int maxlength, float flMinutes,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Check the world entity for a chapter title.
|
||||
if ( CWorld *pWorld = GetWorldEntity() )
|
||||
{
|
||||
const char *pWorldChapter = pWorld->GetChapterTitle();
|
||||
if ( pWorldChapter && pWorldChapter[0] != '\0' )
|
||||
pName = pWorldChapter;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we didn't get one, use the designer's map name, or the BSP name itself
|
||||
if ( !pName )
|
||||
{
|
||||
@ -2065,6 +2092,16 @@ void UpdateChapterRestrictions( const char *mapname )
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Check the world entity for a chapter title.
|
||||
if ( CWorld *pWorld = GetWorldEntity() )
|
||||
{
|
||||
const char *pWorldChapter = pWorld->GetChapterTitle();
|
||||
if ( pWorldChapter && pWorldChapter[0] != '\0' )
|
||||
Q_strncpy( chapterTitle, pWorldChapter, sizeof( chapterTitle ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !chapterTitle[0] )
|
||||
return;
|
||||
|
||||
|
@ -17,6 +17,9 @@
|
||||
#include "tier1/strtools.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#ifdef MAPBASE
|
||||
#include "ai_speech.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
@ -148,10 +151,11 @@ void CGenericActor::Spawn()
|
||||
m_flFieldOfView = 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result )
|
||||
m_NPCState = NPC_STATE_NONE;
|
||||
|
||||
CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS );
|
||||
|
||||
#ifdef MAPBASE
|
||||
CapabilitiesAdd( bits_CAP_SQUAD );
|
||||
CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_DOORS_GROUP );
|
||||
#else
|
||||
CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS );
|
||||
#endif
|
||||
|
||||
// remove head turn if no eyes or forward attachment
|
||||
@ -187,6 +191,163 @@ void CGenericActor::Precache()
|
||||
|
||||
|
||||
|
||||
#ifdef MAPBASE
|
||||
//=========================================================
|
||||
#define TLK_ACTOR_PAIN "TLK_WOUND"
|
||||
#define TLK_ACTOR_DEATH "TLK_DEATH"
|
||||
#define TLK_ACTOR_ALERT "TLK_STARTCOMBAT"
|
||||
#define TLK_ACTOR_IDLE "TLK_IDLE"
|
||||
#define TLK_ACTOR_FEAR "TLK_FEAR"
|
||||
#define TLK_ACTOR_LOSTENEMY "TLK_LOSTENEMY"
|
||||
#define TLK_ACTOR_FOUNDENEMY "TLK_REFINDENEMY"
|
||||
//=========================================================
|
||||
// Enhanced generic actor with built-in response system usage, weapon capabilities, and more.
|
||||
//=========================================================
|
||||
class CGenericActorCustom : public CGenericActor
|
||||
{
|
||||
private:
|
||||
DECLARE_CLASS( CGenericActorCustom, CGenericActor );
|
||||
public:
|
||||
//DECLARE_DATADESC();
|
||||
|
||||
CGenericActorCustom() { }
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
|
||||
bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
|
||||
void SpeakIfAllowed( const char *concept, AI_CriteriaSet *modifiers = NULL );
|
||||
void ModifyOrAppendCriteria( AI_CriteriaSet& set );
|
||||
|
||||
void PainSound( const CTakeDamageInfo &info );
|
||||
void DeathSound( const CTakeDamageInfo &info );
|
||||
void AlertSound( void );
|
||||
void IdleSound( void );
|
||||
void FearSound( void );
|
||||
void LostEnemySound( void );
|
||||
void FoundEnemySound( void );
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( generic_actor_custom, CGenericActorCustom );
|
||||
|
||||
//BEGIN_DATADESC( CGenericActorCustom )
|
||||
//END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::Spawn()
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
CapabilitiesAdd( bits_CAP_USE_WEAPONS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::Precache()
|
||||
{
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Cache user entity field values until spawn is called.
|
||||
// Input : szKeyName - Key to handle.
|
||||
// szValue - Value for key.
|
||||
// Output : Returns true if the key was handled, false if not.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CGenericActorCustom::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
if (FStrEq(szKeyName, "UseShotRegulator"))
|
||||
{
|
||||
if (atoi(szValue) > 0)
|
||||
CapabilitiesAdd( bits_CAP_USE_SHOT_REGULATOR );
|
||||
else
|
||||
CapabilitiesRemove( bits_CAP_USE_SHOT_REGULATOR );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return BaseClass::KeyValue( szKeyName, szValue );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Speak concept
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::SpeakIfAllowed( const char *concept, AI_CriteriaSet *modifiers )
|
||||
{
|
||||
Speak( concept, modifiers ? *modifiers : AI_CriteriaSet() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::ModifyOrAppendCriteria( AI_CriteriaSet& set )
|
||||
{
|
||||
BaseClass::ModifyOrAppendCriteria( set );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::PainSound( const CTakeDamageInfo &info )
|
||||
{
|
||||
AI_CriteriaSet modifiers;
|
||||
ModifyOrAppendDamageCriteria( modifiers, info );
|
||||
SpeakIfAllowed( TLK_ACTOR_PAIN, &modifiers );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::DeathSound( const CTakeDamageInfo &info )
|
||||
{
|
||||
AI_CriteriaSet modifiers;
|
||||
ModifyOrAppendDamageCriteria( modifiers, info );
|
||||
SpeakIfAllowed( TLK_ACTOR_DEATH, &modifiers );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::AlertSound( void )
|
||||
{
|
||||
SpeakIfAllowed( TLK_ACTOR_ALERT );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::IdleSound( void )
|
||||
{
|
||||
SpeakIfAllowed( TLK_ACTOR_IDLE );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::FearSound( void )
|
||||
{
|
||||
SpeakIfAllowed( TLK_ACTOR_FEAR );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::LostEnemySound( void )
|
||||
{
|
||||
SpeakIfAllowed( TLK_ACTOR_LOSTENEMY );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGenericActorCustom::FoundEnemySound( void )
|
||||
{
|
||||
SpeakIfAllowed( TLK_ACTOR_FOUNDENEMY );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -1283,6 +1283,38 @@ void CBounceBomb::CloseHooks()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
extern int g_interactionBarnacleVictimBite;
|
||||
extern int g_interactionBarnacleVictimFinalBite;
|
||||
extern int ACT_BARNACLE_BITE_SMALL_THINGS;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Uses the new CBaseEntity interaction implementation and
|
||||
// replaces the dynamic_casting from npc_barnacle
|
||||
// Input : The type of interaction, extra info pointer, and who started it
|
||||
// Output : true - if sub-class has a response for the interaction
|
||||
// false - if sub-class has no response
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBounceBomb::HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt )
|
||||
{
|
||||
// This was originally done in npc_barnacle itself, but
|
||||
// we've transitioned to interactions so we could extend special behavior to others
|
||||
// without just adding more casting.
|
||||
if ( interactionType == g_interactionBarnacleVictimBite )
|
||||
{
|
||||
Assert( sourceEnt && sourceEnt->IsNPC() );
|
||||
sourceEnt->MyNPCPointer()->SetActivity( (Activity)ACT_BARNACLE_BITE_SMALL_THINGS );
|
||||
return true;
|
||||
}
|
||||
else if ( interactionType == g_interactionBarnacleVictimFinalBite )
|
||||
{
|
||||
ExplodeThink();
|
||||
return true;
|
||||
}
|
||||
|
||||
return BaseClass::HandleInteraction(interactionType, data, sourceEnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void CBounceBomb::InputDisarm( inputdata_t &inputdata )
|
||||
|
@ -83,6 +83,11 @@ public:
|
||||
void OpenHooks( bool bSilent = false );
|
||||
void CloseHooks();
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Uses the new CBaseEntity interaction implementation and replaces the dynamic_casting from npc_barnacle
|
||||
bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt );
|
||||
#endif
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
static string_t gm_iszFloorTurretClassname;
|
||||
|
@ -297,7 +297,7 @@ public:
|
||||
|
||||
~CCommandRedirect()
|
||||
{
|
||||
g_pCommandRedirects.AddToTail(this);
|
||||
g_pCommandRedirects.FindAndRemove(this);
|
||||
/*
|
||||
for (int i = 0; i < g_pCommandRedirects.Count(); i++)
|
||||
{
|
||||
@ -1790,7 +1790,16 @@ bool CHL2_Player::CommanderFindGoal( commandgoal_t *pGoal )
|
||||
|
||||
//---------------------------------
|
||||
// MASK_SHOT on purpose! So that you don't hit the invisible hulls of the NPCs.
|
||||
#ifdef MAPBASE
|
||||
// Get either our +USE entity or the gravity gun entity
|
||||
CBaseEntity *pHeldEntity = GetPlayerHeldEntity(this);
|
||||
if ( !pHeldEntity )
|
||||
PhysCannonGetHeldEntity( GetActiveWeapon() );
|
||||
|
||||
CTraceFilterSkipTwoEntities filter( this, pHeldEntity, COLLISION_GROUP_INTERACTIVE_DEBRIS );
|
||||
#else
|
||||
CTraceFilterSkipTwoEntities filter( this, PhysCannonGetHeldEntity( GetActiveWeapon() ), COLLISION_GROUP_INTERACTIVE_DEBRIS );
|
||||
#endif
|
||||
|
||||
UTIL_TraceLine( EyePosition(), EyePosition() + forward * MAX_COORD_RANGE, MASK_SHOT, &filter, &tr );
|
||||
|
||||
|
@ -589,6 +589,10 @@ class CTriggerWateryDeath : public CBaseTrigger
|
||||
public:
|
||||
DECLARE_DATADESC();
|
||||
|
||||
#ifdef MAPBASE
|
||||
CTriggerWateryDeath();
|
||||
#endif
|
||||
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void Touch( CBaseEntity *pOther );
|
||||
@ -614,6 +618,13 @@ private:
|
||||
CUtlVector< float > m_flEntityKillTimes;
|
||||
float m_flNextPullSound;
|
||||
float m_flPainValue;
|
||||
|
||||
#ifdef MAPBASE
|
||||
float m_flBiteInterval;
|
||||
float m_flPainStep;
|
||||
float m_flMaxPain;
|
||||
COutputInt m_OnDamage;
|
||||
#endif
|
||||
};
|
||||
|
||||
BEGIN_DATADESC( CTriggerWateryDeath )
|
||||
@ -621,6 +632,12 @@ BEGIN_DATADESC( CTriggerWateryDeath )
|
||||
DEFINE_UTLVECTOR( m_hLeeches, FIELD_EHANDLE ),
|
||||
DEFINE_FIELD( m_flNextPullSound, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_flPainValue, FIELD_FLOAT ),
|
||||
#ifdef MAPBASE
|
||||
DEFINE_KEYFIELD( m_flBiteInterval, FIELD_FLOAT, "BiteInterval" ),
|
||||
DEFINE_KEYFIELD( m_flPainStep, FIELD_FLOAT, "PainStep" ),
|
||||
DEFINE_KEYFIELD( m_flMaxPain, FIELD_FLOAT, "MaxPain" ),
|
||||
DEFINE_OUTPUT( m_OnDamage, "OnDamage" ),
|
||||
#endif
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
@ -631,6 +648,15 @@ LINK_ENTITY_TO_CLASS( trigger_waterydeath, CTriggerWateryDeath );
|
||||
#define WD_PAINVALUE_STEP 2.0
|
||||
#define WD_MAX_DAMAGE 15.0f
|
||||
|
||||
#ifdef MAPBASE
|
||||
CTriggerWateryDeath::CTriggerWateryDeath()
|
||||
{
|
||||
m_flBiteInterval = WD_KILLTIME_NEXT_BITE;
|
||||
m_flPainStep = WD_PAINVALUE_STEP;
|
||||
m_flMaxPain = WD_MAX_DAMAGE;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when spawning, after keyvalues have been handled.
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -707,6 +733,23 @@ void CTriggerWateryDeath::Touch( CBaseEntity *pOther )
|
||||
{
|
||||
//EmitSound( filter, entindex(), "WateryDeath.Bite", &pOther->GetAbsOrigin() );
|
||||
// Kill it
|
||||
#ifdef MAPBASE
|
||||
if ( pOther->IsPlayer() )
|
||||
{
|
||||
m_flPainValue = MIN( m_flPainValue + m_flPainStep, m_flMaxPain );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flPainValue = m_flMaxPain;
|
||||
}
|
||||
|
||||
// Do nothing if there is no damage
|
||||
if (m_flPainValue <= 0.0f)
|
||||
{
|
||||
m_flEntityKillTimes[iIndex] = gpGlobals->curtime + m_flBiteInterval;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if ( pOther->IsPlayer() )
|
||||
{
|
||||
m_flPainValue = MIN( m_flPainValue + WD_PAINVALUE_STEP, WD_MAX_DAMAGE );
|
||||
@ -715,6 +758,7 @@ void CTriggerWateryDeath::Touch( CBaseEntity *pOther )
|
||||
{
|
||||
m_flPainValue = WD_MAX_DAMAGE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Use DMG_GENERIC & make the target inflict the damage on himself.
|
||||
// This ensures that if the target is the player, the damage isn't modified by skill
|
||||
@ -723,7 +767,13 @@ void CTriggerWateryDeath::Touch( CBaseEntity *pOther )
|
||||
GuessDamageForce( &info, (pOther->GetAbsOrigin() - GetAbsOrigin()), pOther->GetAbsOrigin() );
|
||||
pOther->TakeDamage( info );
|
||||
|
||||
#ifdef MAPBASE
|
||||
m_OnDamage.Set(m_flPainValue, pOther, this);
|
||||
|
||||
m_flEntityKillTimes[iIndex] = gpGlobals->curtime + m_flBiteInterval;
|
||||
#else
|
||||
m_flEntityKillTimes[iIndex] = gpGlobals->curtime + WD_KILLTIME_NEXT_BITE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,6 +226,7 @@ BEGIN_DATADESC( CNPC_BaseZombie )
|
||||
|
||||
#ifdef MAPBASE
|
||||
DEFINE_OUTPUT( m_OnSwattedProp, "OnSwattedProp" ),
|
||||
DEFINE_OUTPUT( m_OnCrab, "OnCrab" ),
|
||||
#endif
|
||||
|
||||
END_DATADESC()
|
||||
@ -1089,6 +1090,10 @@ bool CNPC_BaseZombie::ShouldIgniteZombieGib( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
extern CBaseAnimating *CreateServerRagdollSubmodel( CBaseAnimating *pOwner, const char *pModelName, const Vector &position, const QAngle &angles, int collisionGroup );
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle the special case of a zombie killed by a physics chopper.
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1138,9 +1143,32 @@ void CNPC_BaseZombie::DieChopped( const CTakeDamageInfo &info )
|
||||
vecLegsForce.z *= -10;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
CBaseEntity *pLegGib = NULL;
|
||||
if ( m_bForceServerRagdoll )
|
||||
{
|
||||
pLegGib = CreateServerRagdollSubmodel( this, GetLegsModel(), GetAbsOrigin(), GetAbsAngles(), COLLISION_GROUP_INTERACTIVE_DEBRIS );
|
||||
pLegGib->VPhysicsGetObject()->AddVelocity(&vecLegsForce, NULL);
|
||||
if (ShouldIgniteZombieGib())
|
||||
static_cast<CBaseAnimating*>(pLegGib)->Ignite( random->RandomFloat( 8.0, 12.0 ), false );
|
||||
|
||||
if ( flFadeTime > 0.0 )
|
||||
{
|
||||
pLegGib->SUB_StartFadeOut( flFadeTime );
|
||||
}
|
||||
}
|
||||
else
|
||||
pLegGib = CreateRagGib( GetLegsModel(), GetAbsOrigin(), GetAbsAngles(), vecLegsForce, flFadeTime, ShouldIgniteZombieGib() );
|
||||
#else
|
||||
CBaseEntity *pLegGib = CreateRagGib( GetLegsModel(), GetAbsOrigin(), GetAbsAngles(), vecLegsForce, flFadeTime, ShouldIgniteZombieGib() );
|
||||
#endif
|
||||
if ( pLegGib )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
// Inherit some misc. properties
|
||||
pLegGib->m_iViewHideFlags = m_iViewHideFlags;
|
||||
#endif
|
||||
|
||||
CopyRenderColorTo( pLegGib );
|
||||
}
|
||||
|
||||
@ -1157,7 +1185,25 @@ void CNPC_BaseZombie::DieChopped( const CTakeDamageInfo &info )
|
||||
QAngle TorsoAngles;
|
||||
TorsoAngles = GetAbsAngles();
|
||||
TorsoAngles.x -= 90.0f;
|
||||
#ifdef MAPBASE
|
||||
CBaseEntity *pTorsoGib = NULL;
|
||||
if ( m_bForceServerRagdoll )
|
||||
{
|
||||
pTorsoGib = CreateServerRagdollSubmodel( this, GetTorsoModel(), GetAbsOrigin() + Vector( 0, 0, 64 ), TorsoAngles, COLLISION_GROUP_INTERACTIVE_DEBRIS );
|
||||
pTorsoGib->VPhysicsGetObject()->AddVelocity(&forceVector, NULL);
|
||||
if (ShouldIgniteZombieGib())
|
||||
static_cast<CBaseAnimating*>(pLegGib)->Ignite( random->RandomFloat( 8.0, 12.0 ), false );
|
||||
|
||||
if ( flFadeTime > 0.0 )
|
||||
{
|
||||
pTorsoGib->SUB_StartFadeOut( flFadeTime );
|
||||
}
|
||||
}
|
||||
else
|
||||
pTorsoGib = CreateRagGib( GetTorsoModel(), GetAbsOrigin() + Vector( 0, 0, 64 ), TorsoAngles, forceVector, flFadeTime, ShouldIgniteZombieGib() );
|
||||
#else
|
||||
CBaseEntity *pTorsoGib = CreateRagGib( GetTorsoModel(), GetAbsOrigin() + Vector( 0, 0, 64 ), TorsoAngles, forceVector, flFadeTime, ShouldIgniteZombieGib() );
|
||||
#endif
|
||||
if ( pTorsoGib )
|
||||
{
|
||||
CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pTorsoGib);
|
||||
@ -1166,6 +1212,11 @@ void CNPC_BaseZombie::DieChopped( const CTakeDamageInfo &info )
|
||||
pAnimating->SetBodygroup( ZOMBIE_BODYGROUP_HEADCRAB, !m_fIsHeadless );
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Inherit some misc. properties
|
||||
pTorsoGib->m_iViewHideFlags = m_iViewHideFlags;
|
||||
#endif
|
||||
|
||||
pTorsoGib->SetOwnerEntity( this );
|
||||
CopyRenderColorTo( pTorsoGib );
|
||||
|
||||
@ -2294,7 +2345,23 @@ void CNPC_BaseZombie::BecomeTorso( const Vector &vecTorsoForce, const Vector &ve
|
||||
if ( m_fIsTorso == true )
|
||||
{
|
||||
// -40 on Z to make up for the +40 on Z that we did above. This stops legs spawning above the head.
|
||||
#ifdef MAPBASE
|
||||
CBaseEntity *pGib = NULL;
|
||||
if ( m_bForceServerRagdoll )
|
||||
{
|
||||
pGib = CreateServerRagdollSubmodel( this, GetLegsModel(), GetAbsOrigin() - Vector(0, 0, 40), GetAbsAngles(), COLLISION_GROUP_INTERACTIVE_DEBRIS );
|
||||
pGib->VPhysicsGetObject()->AddVelocity( &vecLegsForce, NULL );
|
||||
|
||||
if (flFadeTime > 0.0)
|
||||
{
|
||||
pGib->SUB_StartFadeOut( flFadeTime );
|
||||
}
|
||||
}
|
||||
else
|
||||
pGib = CreateRagGib( GetLegsModel(), GetAbsOrigin() - Vector(0, 0, 40), GetAbsAngles(), vecLegsForce, flFadeTime );
|
||||
#else
|
||||
CBaseEntity *pGib = CreateRagGib( GetLegsModel(), GetAbsOrigin() - Vector(0, 0, 40), GetAbsAngles(), vecLegsForce, flFadeTime );
|
||||
#endif
|
||||
|
||||
// don't collide with this thing ever
|
||||
if ( pGib )
|
||||
@ -2430,7 +2497,22 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve
|
||||
if( fRagdollCrab )
|
||||
{
|
||||
//Vector vecForce = Vector( 0, 0, random->RandomFloat( 700, 1100 ) );
|
||||
#ifdef MAPBASE
|
||||
CBaseEntity *pGib = NULL;
|
||||
if ( m_bForceServerRagdoll )
|
||||
{
|
||||
pGib = CreateServerRagdollSubmodel( this, GetHeadcrabModel(), vecOrigin, GetLocalAngles(), COLLISION_GROUP_INTERACTIVE_DEBRIS );
|
||||
pGib->VPhysicsGetObject()->AddVelocity(&vecVelocity, NULL);
|
||||
if (ShouldIgniteZombieGib())
|
||||
static_cast<CBaseAnimating*>(pGib)->Ignite( random->RandomFloat( 8.0, 12.0 ), false );
|
||||
|
||||
pGib->SUB_StartFadeOut( 15 );
|
||||
}
|
||||
else
|
||||
pGib = CreateRagGib( GetHeadcrabModel(), vecOrigin, GetLocalAngles(), vecVelocity, 15, ShouldIgniteZombieGib() );
|
||||
#else
|
||||
CBaseEntity *pGib = CreateRagGib( GetHeadcrabModel(), vecOrigin, GetLocalAngles(), vecVelocity, 15, ShouldIgniteZombieGib() );
|
||||
#endif
|
||||
|
||||
if ( pGib )
|
||||
{
|
||||
@ -2449,6 +2531,11 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Inherit some misc. properties
|
||||
pGib->m_iViewHideFlags = m_iViewHideFlags;
|
||||
#endif
|
||||
|
||||
pGib->SetOwnerEntity( this );
|
||||
CopyRenderColorTo( pGib );
|
||||
|
||||
@ -2489,6 +2576,12 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve
|
||||
// add on the parent flags
|
||||
pCrab->AddSpawnFlags( m_spawnflags & ZOMBIE_CRAB_INHERITED_SPAWNFLAGS );
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Inherit some misc. properties
|
||||
pCrab->m_bForceServerRagdoll = m_bForceServerRagdoll;
|
||||
pCrab->m_iViewHideFlags = m_iViewHideFlags;
|
||||
#endif
|
||||
|
||||
// make me the crab's owner to avoid collision issues
|
||||
pCrab->SetOwnerEntity( this );
|
||||
|
||||
@ -2541,6 +2634,10 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve
|
||||
CopyRenderColorTo( pCrab );
|
||||
|
||||
pCrab->Activate();
|
||||
|
||||
#ifdef MAPBASE
|
||||
m_OnCrab.Set( pCrab, pCrab, this );
|
||||
#endif
|
||||
}
|
||||
|
||||
if( fRemoveHead )
|
||||
|
@ -265,6 +265,7 @@ protected:
|
||||
EHANDLE m_hPhysicsEnt;
|
||||
#ifdef MAPBASE
|
||||
COutputEHANDLE m_OnSwattedProp;
|
||||
COutputEHANDLE m_OnCrab;
|
||||
#endif
|
||||
|
||||
float m_flNextMoanSound;
|
||||
|
@ -40,6 +40,10 @@ ConVar sk_barnacle_health( "sk_barnacle_health","0");
|
||||
|
||||
static ConVar npc_barnacle_swallow( "npc_barnacle_swallow", "0", 0, "Use prototype swallow code." );
|
||||
|
||||
#ifdef MAPBASE
|
||||
ConVar npc_barnacle_ignite( "npc_barnacle_ignite", "0", FCVAR_NONE, "Allows barnacles to be ignited by flares and beyond." );
|
||||
#endif
|
||||
|
||||
const char *CNPC_Barnacle::m_szGibNames[NUM_BARNACLE_GIBS] =
|
||||
{
|
||||
"models/gibs/hgibs.mdl",
|
||||
@ -69,6 +73,9 @@ int g_interactionBarnacleVictimDangle = 0;
|
||||
int g_interactionBarnacleVictimReleased = 0;
|
||||
int g_interactionBarnacleVictimGrab = 0;
|
||||
int g_interactionBarnacleVictimBite = 0;
|
||||
#ifdef MAPBASE
|
||||
int g_interactionBarnacleVictimFinalBite = 0;
|
||||
#endif
|
||||
|
||||
LINK_ENTITY_TO_CLASS( npc_barnacle, CNPC_Barnacle );
|
||||
|
||||
@ -187,7 +194,9 @@ BEGIN_DATADESC( CNPC_Barnacle )
|
||||
DEFINE_THINKFUNC( BarnacleThink ),
|
||||
DEFINE_THINKFUNC( WaitTillDead ),
|
||||
|
||||
#ifndef MAPBASE
|
||||
DEFINE_FIELD( m_bSwallowingBomb, FIELD_BOOLEAN ),
|
||||
#endif
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
@ -275,7 +284,9 @@ void CNPC_Barnacle::Spawn()
|
||||
m_cGibs = 0;
|
||||
m_bLiftingPrey = false;
|
||||
m_bSwallowingPrey = false;
|
||||
#ifndef MAPBASE
|
||||
m_bSwallowingBomb = false;
|
||||
#endif
|
||||
m_flDigestFinish = 0;
|
||||
m_takedamage = DAMAGE_YES;
|
||||
m_pConstraint = NULL;
|
||||
@ -406,6 +417,16 @@ void CNPC_Barnacle::PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot )
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNPC_Barnacle::AllowedToIgnite( void )
|
||||
{
|
||||
return npc_barnacle_ignite.GetBool();
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initialize tongue position when first spawned
|
||||
// Input :
|
||||
@ -509,7 +530,11 @@ void CNPC_Barnacle::BarnacleThink ( void )
|
||||
}
|
||||
else if ( GetEnemy() )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
if ( m_bLiftingPrey )
|
||||
#else
|
||||
if ( m_bLiftingPrey || m_bSwallowingBomb == true )
|
||||
#endif
|
||||
{
|
||||
LiftPrey();
|
||||
}
|
||||
@ -1145,6 +1170,24 @@ void CNPC_Barnacle::LiftPhysicsObject( float flBiteZOffset )
|
||||
// If we got a physics prop, wait until the thing has settled down
|
||||
m_bLiftingPrey = false;
|
||||
|
||||
#ifdef MAPBASE
|
||||
Vector tipPos = m_vecTip.Get();
|
||||
Activity curAct = GetActivity();
|
||||
|
||||
// Other, non-character entities use this now
|
||||
if (pVictim->DispatchInteraction( g_interactionBarnacleVictimBite, &tipPos, this ))
|
||||
{
|
||||
// Make sure the interaction isn't making us use an irregular activity
|
||||
// (e.g. biting)
|
||||
if (GetActivity() == curAct)
|
||||
SetActivity( (Activity)ACT_BARNACLE_TASTE_SPIT );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start the spit animation.
|
||||
SetActivity( (Activity)ACT_BARNACLE_TASTE_SPIT );
|
||||
}
|
||||
#else
|
||||
if ( hl2_episodic.GetBool() )
|
||||
{
|
||||
CBounceBomb *pBounce = dynamic_cast<CBounceBomb *>( pVictim );
|
||||
@ -1181,6 +1224,7 @@ void CNPC_Barnacle::LiftPhysicsObject( float flBiteZOffset )
|
||||
|
||||
pBCC->DispatchInteraction( g_interactionBarnacleVictimBite, &tipPos, this );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -1577,6 +1621,18 @@ void CNPC_Barnacle::BitePrey( void )
|
||||
|
||||
CBaseCombatCharacter *pVictim = GetEnemyCombatCharacterPointer();
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( pVictim == NULL )
|
||||
{
|
||||
if ( GetEnemy() )
|
||||
{
|
||||
Vector tipPos = m_vecTip.Get();
|
||||
GetEnemy()->DispatchInteraction( g_interactionBarnacleVictimFinalBite, &tipPos, this );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#ifdef HL2_EPISODIC
|
||||
if ( pVictim == NULL )
|
||||
{
|
||||
@ -1614,6 +1670,7 @@ void CNPC_Barnacle::BitePrey( void )
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
EmitSound( "NPC_Barnacle.FinalBite" );
|
||||
|
||||
@ -1701,6 +1758,12 @@ void CNPC_Barnacle::BitePrey( void )
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE
|
||||
Vector tipPos = m_vecTip.Get();
|
||||
if (pVictim->DispatchInteraction( g_interactionBarnacleVictimFinalBite, &tipPos, this ))
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Players are never swallowed, nor is anything we don't have a ragdoll for
|
||||
if ( !m_hRagdoll || pVictim->IsPlayer() )
|
||||
{
|
||||
@ -1885,13 +1948,20 @@ void CNPC_Barnacle::LostPrey( bool bRemoveRagdoll )
|
||||
PhysEnableEntityCollisions( this, pEnemy );
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE
|
||||
// These can be CBaseEntity-based now
|
||||
pEnemy->DispatchInteraction( g_interactionBarnacleVictimReleased, NULL, this );
|
||||
#endif
|
||||
|
||||
//No one survives being snatched by a barnacle anymore, so leave
|
||||
// this flag set so that their entity gets removed.
|
||||
//GetEnemy()->RemoveEFlags( EFL_IS_BEING_LIFTED_BY_BARNACLE );
|
||||
CBaseCombatCharacter *pVictim = GetEnemyCombatCharacterPointer();
|
||||
if ( pVictim )
|
||||
{
|
||||
#ifndef MAPBASE
|
||||
pVictim->DispatchInteraction( g_interactionBarnacleVictimReleased, NULL, this );
|
||||
#endif
|
||||
pVictim->RemoveEFlags( EFL_IS_BEING_LIFTED_BY_BARNACLE );
|
||||
|
||||
if ( m_hRagdoll )
|
||||
@ -2721,6 +2791,9 @@ AI_BEGIN_CUSTOM_NPC( npc_barnacle, CNPC_Barnacle )
|
||||
DECLARE_INTERACTION( g_interactionBarnacleVictimReleased )
|
||||
DECLARE_INTERACTION( g_interactionBarnacleVictimGrab )
|
||||
DECLARE_INTERACTION( g_interactionBarnacleVictimBite )
|
||||
#ifdef MAPBASE
|
||||
DECLARE_INTERACTION( g_interactionBarnacleVictimFinalBite )
|
||||
#endif
|
||||
|
||||
// Conditions
|
||||
|
||||
|
@ -84,6 +84,10 @@ public:
|
||||
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
|
||||
void PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot );
|
||||
|
||||
#ifdef MAPBASE
|
||||
bool AllowedToIgnite( void );
|
||||
#endif
|
||||
|
||||
// The tongue's vphysics updated
|
||||
void OnTongueTipUpdated();
|
||||
|
||||
@ -209,7 +213,9 @@ private:
|
||||
Vector m_vLastEnemyPos;
|
||||
float m_flLastPull;
|
||||
CSimpleSimTimer m_StuckTimer;
|
||||
#ifndef MAPBASE // Handled by interactions now
|
||||
bool m_bSwallowingBomb;
|
||||
#endif
|
||||
#ifdef HL2_EPISODIC
|
||||
bool m_bSwallowingPoison;
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@
|
||||
#ifdef MAPBASE
|
||||
#include "mapbase/GlobalStrings.h"
|
||||
#include "globalstate.h"
|
||||
#include "sceneentity.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
@ -448,6 +449,14 @@ void CNPC_Combine::Spawn( void )
|
||||
m_flNextAltFireTime = gpGlobals->curtime;
|
||||
|
||||
NPCInit();
|
||||
|
||||
#ifdef MAPBASE
|
||||
// This was moved from CalcWeaponProficiency() so soldiers don't change skin unnaturally and uncontrollably
|
||||
if ( GetActiveWeapon() && EntIsClass(GetActiveWeapon(), gm_isz_class_Shotgun) && m_nSkin != COMBINE_SKIN_SHOTGUNNER )
|
||||
{
|
||||
m_nSkin = COMBINE_SKIN_SHOTGUNNER;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2950,6 +2959,10 @@ bool CNPC_Combine::SpeakIfAllowed( const char *concept, AI_CriteriaSet& modifier
|
||||
if ( !GetExpresser()->CanSpeakConcept( concept ) )
|
||||
return false;
|
||||
|
||||
// Don't interrupt scripted VCD dialogue
|
||||
if ( IsRunningScriptedSceneWithSpeechAndNotPaused( this, true ) )
|
||||
return false;
|
||||
|
||||
if ( Speak( concept, modifiers ) )
|
||||
{
|
||||
JustMadeSound( sentencepriority, 2.0f /*GetTimeSpeechComplete()*/ );
|
||||
@ -3655,10 +3668,12 @@ WeaponProficiency_t CNPC_Combine::CalcWeaponProficiency( CBaseCombatWeapon *pWea
|
||||
else if( FClassnameIs( pWeapon, "weapon_shotgun" ) )
|
||||
#endif
|
||||
{
|
||||
#ifndef MAPBASE // Moved so soldiers don't change skin unnaturally and uncontrollably
|
||||
if( m_nSkin != COMBINE_SKIN_SHOTGUNNER )
|
||||
{
|
||||
m_nSkin = COMBINE_SKIN_SHOTGUNNER;
|
||||
}
|
||||
#endif
|
||||
|
||||
return WEAPON_PROFICIENCY_PERFECT;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ void CNPC_PlayerCompanion::Spawn()
|
||||
|
||||
m_AnnounceAttackTimer.Set( 10, 30 );
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
#if HL2_EPISODIC && !MAPBASE // Mapbase permits this flag since the warning can be distracting and stripping the flag might break some HL2 maps in Episodic mods
|
||||
// We strip this flag because it's been made obsolete by the StartScripting behavior
|
||||
if ( HasSpawnFlags( SF_NPC_ALTCOLLISION ) )
|
||||
{
|
||||
@ -306,7 +306,7 @@ int CNPC_PlayerCompanion::Restore( IRestore &restore )
|
||||
m_StandoffBehavior.SetActive( false );
|
||||
}
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
#if HL2_EPISODIC && !MAPBASE // Mapbase permits this flag since the warning can be distracting and stripping the flag might break some HL2 maps in Episodic mods
|
||||
// We strip this flag because it's been made obsolete by the StartScripting behavior
|
||||
if ( HasSpawnFlags( SF_NPC_ALTCOLLISION ) )
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "ammodef.h"
|
||||
#ifdef MAPBASE
|
||||
#include "AI_ResponseSystem.h"
|
||||
#include "ai_speech.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
@ -1028,10 +1029,10 @@ AI_END_CUSTOM_NPC()
|
||||
//=============================================================================
|
||||
|
||||
#ifdef MAPBASE
|
||||
class CZombieCustom : public CZombie
|
||||
class CZombieCustom : public CAI_ExpresserHost<CZombie>
|
||||
{
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_CLASS( CZombieCustom, CZombie );
|
||||
DECLARE_CLASS( CZombieCustom, CAI_ExpresserHost<CZombie> );
|
||||
|
||||
public:
|
||||
CZombieCustom();
|
||||
@ -1039,10 +1040,11 @@ public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
|
||||
#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE
|
||||
DeclareResponseSystem()
|
||||
void SpeakIfAllowed(const char *concept);
|
||||
void SpeakIfAllowed( const char *concept, AI_CriteriaSet *modifiers = NULL );
|
||||
void ModifyOrAppendCriteria( AI_CriteriaSet& set );
|
||||
virtual CAI_Expresser *CreateExpresser( void );
|
||||
virtual CAI_Expresser *GetExpresser() { return m_pExpresser; }
|
||||
virtual void PostConstructor( const char *szClassname );
|
||||
|
||||
void PainSound( const CTakeDamageInfo &info );
|
||||
void DeathSound( const CTakeDamageInfo &info );
|
||||
@ -1051,7 +1053,6 @@ public:
|
||||
void AttackSound( void );
|
||||
|
||||
const char *GetMoanSound( int nSound );
|
||||
#endif
|
||||
|
||||
void SetZombieModel( void );
|
||||
|
||||
@ -1064,6 +1065,8 @@ public:
|
||||
string_t m_iszTorsoModel;
|
||||
string_t m_iszHeadcrabClassname;
|
||||
string_t m_iszHeadcrabModel;
|
||||
|
||||
CAI_Expresser *m_pExpresser;
|
||||
};
|
||||
|
||||
BEGIN_DATADESC( CZombieCustom )
|
||||
@ -1166,20 +1169,24 @@ void CZombieCustom::SetZombieModel( void )
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CZombieCustom::PainSound( const CTakeDamageInfo &info )
|
||||
{
|
||||
SpeakIfAllowed( TLK_ZOMBIE_PAIN );
|
||||
AI_CriteriaSet modifiers;
|
||||
ModifyOrAppendDamageCriteria( modifiers, info );
|
||||
SpeakIfAllowed( TLK_ZOMBIE_PAIN, &modifiers );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CZombieCustom::DeathSound( const CTakeDamageInfo &info )
|
||||
{
|
||||
SpeakIfAllowed( TLK_ZOMBIE_DEATH );
|
||||
AI_CriteriaSet modifiers;
|
||||
ModifyOrAppendDamageCriteria( modifiers, info );
|
||||
SpeakIfAllowed( TLK_ZOMBIE_DEATH, &modifiers );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1198,64 +1205,21 @@ void CZombieCustom::AlertSound( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CZombieCustom::GetMoanSound( int nSound )
|
||||
{
|
||||
// This whole thing is really complicated and largely a copy-paste of CBaseEntity::DispatchResponse().
|
||||
AI_CriteriaSet modifiers;
|
||||
|
||||
AddContext( "moansound", UTIL_VarArgs("%i", nSound & 4), 5.0f );
|
||||
// We could probably do this through the response system alone now, but whatever.
|
||||
modifiers.AppendCriteria( "moansound", UTIL_VarArgs("%i", nSound & 4) );
|
||||
|
||||
IResponseSystem *rs = GetResponseSystem();
|
||||
if ( !rs )
|
||||
AI_Response *response = SpeakFindResponse(TLK_ZOMBIE_MOAN, modifiers);
|
||||
|
||||
if ( !response )
|
||||
return "NPC_BaseZombie.Moan1";
|
||||
|
||||
AI_CriteriaSet set;
|
||||
set.AppendCriteria( "concept", TLK_ZOMBIE_MOAN, CONCEPT_WEIGHT );
|
||||
ModifyOrAppendCriteria( set );
|
||||
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
|
||||
if( pPlayer )
|
||||
pPlayer->ModifyOrAppendPlayerCriteria( set );
|
||||
ReAppendContextCriteria( set );
|
||||
// Must be static so it could be returned
|
||||
static char szSound[128];
|
||||
response->GetName(szSound, sizeof(szSound));
|
||||
|
||||
AI_Response result;
|
||||
rs->FindBestResponse(set, result);
|
||||
|
||||
// Get the response and turn it into something we can use
|
||||
char response[256];
|
||||
result.GetResponse(response, sizeof(response));
|
||||
switch (result.GetType())
|
||||
{
|
||||
case RESPONSE_SENTENCE:
|
||||
{
|
||||
if (response[0] != '!')
|
||||
{
|
||||
SENTENCEG_PlayRndSz( edict(), response, 1, result.GetSoundLevel(), 0, PITCH_NORM );
|
||||
break;
|
||||
}
|
||||
int sentenceIndex = SENTENCEG_Lookup( response );
|
||||
if( sentenceIndex == -1 )
|
||||
{
|
||||
// sentence not found
|
||||
break;
|
||||
}
|
||||
|
||||
// Not sure how else to get around this
|
||||
CPASAttenuationFilter filter( this );
|
||||
CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM );
|
||||
return "AI_BaseNPC.SentenceStop";
|
||||
}
|
||||
break;
|
||||
case RESPONSE_SCENE:
|
||||
{
|
||||
extern const char *GetFirstSoundInScene(const char *pszScene);
|
||||
|
||||
// Expand gender string
|
||||
GenderExpandString( response, response, sizeof( response ) );
|
||||
|
||||
// Trust that it's been precached
|
||||
Q_strncpy(response, GetFirstSoundInScene(response), sizeof(response));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
const char *szSound = response;
|
||||
delete response;
|
||||
return szSound;
|
||||
}
|
||||
|
||||
@ -1285,9 +1249,9 @@ void CZombieCustom::AttackSound( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Speak concept
|
||||
//-----------------------------------------------------------------------------
|
||||
void CZombieCustom::SpeakIfAllowed(const char *concept)
|
||||
void CZombieCustom::SpeakIfAllowed(const char *concept, AI_CriteriaSet *modifiers)
|
||||
{
|
||||
DispatchResponse(concept);
|
||||
Speak( concept, modifiers ? *modifiers : AI_CriteriaSet() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1305,5 +1269,26 @@ void CZombieCustom::ModifyOrAppendCriteria( AI_CriteriaSet& set )
|
||||
// This can be overridden with response contexts.
|
||||
set.AppendCriteria( "classname", "npc_zombie" );
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CAI_Expresser *CZombieCustom::CreateExpresser( void )
|
||||
{
|
||||
m_pExpresser = new CAI_Expresser(this);
|
||||
if (!m_pExpresser)
|
||||
return NULL;
|
||||
|
||||
m_pExpresser->Connect(this);
|
||||
return m_pExpresser;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CZombieCustom::PostConstructor(const char *szClassname)
|
||||
{
|
||||
BaseClass::PostConstructor(szClassname);
|
||||
CreateExpresser();
|
||||
}
|
||||
#endif
|
||||
|
@ -49,6 +49,8 @@ BEGIN_DATADESC(CScriptIntro)
|
||||
#ifdef MAPBASE
|
||||
DEFINE_KEYFIELD( m_bDrawSky, FIELD_BOOLEAN, "DrawSky" ),
|
||||
DEFINE_KEYFIELD( m_bDrawSky2, FIELD_BOOLEAN, "DrawSky2" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_bUseEyePosition, FIELD_BOOLEAN, "UseEyePosition" ),
|
||||
#endif
|
||||
|
||||
// Inputs
|
||||
@ -83,6 +85,7 @@ IMPLEMENT_SERVERCLASS_ST( CScriptIntro, DT_ScriptIntro )
|
||||
#ifdef MAPBASE
|
||||
SendPropBool( SENDINFO( m_bDrawSky ) ),
|
||||
SendPropBool( SENDINFO( m_bDrawSky2 ) ),
|
||||
SendPropBool( SENDINFO( m_bUseEyePosition ) ),
|
||||
#endif
|
||||
|
||||
// Fov & fov blends
|
||||
|
@ -69,6 +69,7 @@ private:
|
||||
#ifdef MAPBASE
|
||||
CNetworkVar( bool, m_bDrawSky );
|
||||
CNetworkVar( bool, m_bDrawSky2 );
|
||||
CNetworkVar( bool, m_bUseEyePosition );
|
||||
#endif
|
||||
|
||||
// Fov & fov blends
|
||||
|
@ -276,7 +276,7 @@ void CLogicMeasureMovement::MeasureThink( )
|
||||
if (m_bOutputPosition)
|
||||
{
|
||||
m_OutPosition.Set(vecNewOrigin, m_hTarget.Get(), this);
|
||||
m_OutAngles.Set(*(reinterpret_cast<Vector*>(vecNewAngles.Base())), m_hTarget.Get(), this);
|
||||
m_OutAngles.Set(vecNewAngles, m_hTarget.Get(), this);
|
||||
}
|
||||
|
||||
if (HasSpawnFlags( SF_LOGIC_MEASURE_MOVEMENT_TELEPORT ))
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "mapbase/variant_tools.h"
|
||||
#include "mapbase/matchers.h"
|
||||
#include "mapbase/datadesc_mod.h"
|
||||
#include "activitylist.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
@ -1917,6 +1918,7 @@ private:
|
||||
|
||||
bool m_bPreserveValue;
|
||||
bool m_bAlwaysOutputAsInt;
|
||||
float m_flLerpPercent;
|
||||
|
||||
void UpdateOutValue(CBaseEntity *pActivator, float fNewValue);
|
||||
|
||||
@ -1937,6 +1939,8 @@ private:
|
||||
void InputRandomInt( inputdata_t &inputdata );
|
||||
void InputRandomFloat( inputdata_t &inputdata );
|
||||
|
||||
void InputLerpTo( inputdata_t &inputdata );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
||||
@ -1948,6 +1952,7 @@ BEGIN_DATADESC( CMathCounterAdvanced )
|
||||
// Keys
|
||||
DEFINE_INPUT(m_bPreserveValue, FIELD_BOOLEAN, "PreserveValue"),
|
||||
DEFINE_INPUT(m_bAlwaysOutputAsInt, FIELD_BOOLEAN, "AlwaysOutputAsInt"),
|
||||
DEFINE_INPUT(m_flLerpPercent, FIELD_FLOAT, "SetLerpPercent"),
|
||||
|
||||
// Inputs
|
||||
DEFINE_INPUTFUNC(FIELD_VOID, "SetValueToPi", InputSetValueToPi),
|
||||
@ -1967,6 +1972,8 @@ BEGIN_DATADESC( CMathCounterAdvanced )
|
||||
DEFINE_INPUTFUNC(FIELD_STRING, "RandomInt", InputRandomInt),
|
||||
DEFINE_INPUTFUNC(FIELD_STRING, "RandomFloat", InputRandomFloat),
|
||||
|
||||
DEFINE_INPUTFUNC(FIELD_FLOAT, "LerpTo", InputLerpTo),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2280,6 +2287,21 @@ void CMathCounterAdvanced::InputRandomFloat( inputdata_t &inputdata )
|
||||
UpdateOutValue( inputdata.pActivator, fNewValue );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Input handler for random float generation.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathCounterAdvanced::InputLerpTo( inputdata_t &inputdata )
|
||||
{
|
||||
if( m_bDisabled )
|
||||
{
|
||||
DevMsg("Math Counter %s ignoring LERPTO because it is disabled\n", GetDebugName() );
|
||||
return;
|
||||
}
|
||||
|
||||
float fNewValue = m_OutValue.Get() + (inputdata.value.Float() - m_OutValue.Get()) * m_flLerpPercent;
|
||||
UpdateOutValue( inputdata.pActivator, fNewValue );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the value to the new value, clamping and firing the output value.
|
||||
// Input : fNewValue - Value to set.
|
||||
@ -3058,6 +3080,11 @@ int CLogicBranch::DrawDebugTextOverlays( void )
|
||||
return text_offset;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
extern void MapbaseGameLog_Record( const char *szContext );
|
||||
extern ConVar mapbase_game_log_on_autosave;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Autosaves when triggered
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -3094,6 +3121,13 @@ END_DATADESC()
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicAutosave::InputSave( inputdata_t &inputdata )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
if (mapbase_game_log_on_autosave.GetBool())
|
||||
{
|
||||
MapbaseGameLog_Record( "autosave" );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( m_bForceNewLevelUnit )
|
||||
{
|
||||
engine->ClearSaveDir();
|
||||
@ -3107,6 +3141,13 @@ void CLogicAutosave::InputSave( inputdata_t &inputdata )
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicAutosave::InputSaveDangerous( inputdata_t &inputdata )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
if (mapbase_game_log_on_autosave.GetBool())
|
||||
{
|
||||
MapbaseGameLog_Record( "autosave_dangerous" );
|
||||
}
|
||||
#endif
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
|
||||
|
||||
if ( g_ServerGameDLL.m_fAutoSaveDangerousTime != 0.0f && g_ServerGameDLL.m_fAutoSaveDangerousTime >= gpGlobals->curtime )
|
||||
@ -3609,7 +3650,9 @@ public:
|
||||
void InputNewLine( inputdata_t &inputdata ) { LCMsg("\n"); }
|
||||
void InputDevNewLine( inputdata_t &inputdata ) { LCDevMsg(m_iDevLevel, "\n"); }
|
||||
|
||||
void InputClearConsole( inputdata_t &inputdata ) { engine->ServerCommand("clear"); }
|
||||
// MAPBASE MP TODO: "ClearConsoleOnTarget"
|
||||
// (and make this input broadcast to all players)
|
||||
void InputClearConsole( inputdata_t &inputdata ) { UTIL_GetLocalPlayer() ? engine->ClientCommand(UTIL_GetLocalPlayer()->edict(), "clear") : NULL; }
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
@ -3632,6 +3675,8 @@ BEGIN_DATADESC( CLogicConsole )
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "NewLine", InputNewLine ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "DevNewLine", InputDevNewLine ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "ClearConsole", InputClearConsole ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
ConVar sv_allow_logic_convar("sv_allow_logic_convar", "1");
|
||||
@ -3696,23 +3741,31 @@ const char *CLogicConvar::GetConVarString( inputdata_t &inputdata )
|
||||
ConVarRef pCVar = ConVarRef(STRING(m_iszConVar), true);
|
||||
if (!pCVar.IsValid())
|
||||
{
|
||||
// It's not a convar, so check if it's a common cheat command a player might be using
|
||||
const char *pszCVar = STRING( m_iszConVar );
|
||||
CBasePlayer *pPlayer = ToBasePlayer( inputdata.pActivator );
|
||||
if (!pPlayer && AI_IsSinglePlayer())
|
||||
pPlayer = UTIL_PlayerByIndex( 1 );
|
||||
|
||||
if (pPlayer)
|
||||
{
|
||||
const char *pszCVar = STRING( m_iszConVar );
|
||||
// Check if it's a common cheat command a player might be using
|
||||
if (FStrEq( pszCVar, "god" ))
|
||||
return (pPlayer->GetFlags() & FL_GODMODE) ? "1" : "0";
|
||||
if (FStrEq( pszCVar, "notarget" ))
|
||||
return (pPlayer->GetFlags() & FL_NOTARGET) ? "1" : "0";
|
||||
if (FStrEq( pszCVar, "noclip" ))
|
||||
return (pPlayer->IsEFlagSet(EFL_NOCLIP_ACTIVE)) ? "1" : "0";
|
||||
|
||||
// It might be a client convar
|
||||
// This function returns a blank string if the convar doesn't exist, so we have to put this at the end
|
||||
const char *pszClientValue = engine->GetClientConVarValue( pPlayer->GetClientIndex(), pszCVar );
|
||||
if (pszClientValue)
|
||||
{
|
||||
return pszClientValue;
|
||||
}
|
||||
}
|
||||
|
||||
Warning("Warning: %s has invalid convar \"%s\"\n", GetDebugName(), STRING(m_iszConVar));
|
||||
//Warning("Warning: %s has invalid convar \"%s\"\n", GetDebugName(), STRING(m_iszConVar));
|
||||
}
|
||||
|
||||
return pCVar.GetString();
|
||||
@ -4587,6 +4640,7 @@ private:
|
||||
void InputDisable( inputdata_t &inputdata );
|
||||
|
||||
void InputNormalize( inputdata_t &inputdata );
|
||||
void InputNormalizeAngles( inputdata_t &inputdata );
|
||||
|
||||
void SetCoordinate(float value, char coord, CBaseEntity *pActivator);
|
||||
void GetCoordinate(char coord, CBaseEntity *pActivator);
|
||||
@ -4640,6 +4694,7 @@ BEGIN_DATADESC( CMathVector )
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||
|
||||
DEFINE_INPUTFUNC(FIELD_VOID, "Normalize", InputNormalize),
|
||||
DEFINE_INPUTFUNC(FIELD_VOID, "NormalizeAngles", InputNormalizeAngles),
|
||||
|
||||
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetX", InputSetX),
|
||||
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetY", InputSetY),
|
||||
@ -4879,6 +4934,24 @@ void CMathVector::InputNormalize( inputdata_t &inputdata )
|
||||
UpdateOutValue( inputdata.pActivator, cur );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathVector::InputNormalizeAngles( inputdata_t &inputdata )
|
||||
{
|
||||
if( m_bDisabled )
|
||||
{
|
||||
DevMsg("Math Vector %s ignoring NORMALIZEANGLES because it is disabled\n", GetDebugName() );
|
||||
return;
|
||||
}
|
||||
|
||||
Vector cur;
|
||||
m_OutValue.Get(cur);
|
||||
cur.x = AngleNormalize(cur.x);
|
||||
cur.y = AngleNormalize(cur.y);
|
||||
cur.z = AngleNormalize(cur.z);
|
||||
UpdateOutValue( inputdata.pActivator, cur );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathVector::SetCoordinate(float value, char coord, CBaseEntity *pActivator)
|
||||
@ -5354,6 +5427,7 @@ private:
|
||||
//void InputSetTarget( inputdata_t &inputdata ) { BaseClass::InputSetTarget(inputdata); m_hTarget = NULL; }
|
||||
void InputGetNumSkins( inputdata_t &inputdata );
|
||||
void InputLookupSequence( inputdata_t &inputdata );
|
||||
void InputLookupActivity( inputdata_t &inputdata );
|
||||
|
||||
// Outputs
|
||||
COutputInt m_OutNumSkins;
|
||||
@ -5371,6 +5445,7 @@ BEGIN_DATADESC( CLogicModelInfo )
|
||||
// Inputs
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "GetNumSkins", InputGetNumSkins ),
|
||||
DEFINE_INPUTFUNC( FIELD_STRING, "LookupSequence", InputLookupSequence ),
|
||||
DEFINE_INPUTFUNC( FIELD_STRING, "LookupActivity", InputLookupActivity ),
|
||||
|
||||
// Outputs
|
||||
DEFINE_OUTPUT(m_OutNumSkins, "OutNumSkins"),
|
||||
@ -5416,6 +5491,34 @@ void CLogicModelInfo::InputLookupSequence( inputdata_t &inputdata )
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicModelInfo::InputLookupActivity( inputdata_t &inputdata )
|
||||
{
|
||||
CBaseAnimating *pAnimating = GetTarget(inputdata);
|
||||
if (pAnimating && pAnimating->GetModelPtr())
|
||||
{
|
||||
int iActivity = ActivityList_IndexForName(inputdata.value.String());
|
||||
if (iActivity == -1)
|
||||
{
|
||||
// Check if it's a raw activity ID
|
||||
iActivity = atoi(inputdata.value.String());
|
||||
if (!ActivityList_NameForIndex(iActivity))
|
||||
{
|
||||
Msg("%s received invalid LookupActivity %s\n", inputdata.value.String());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int index = pAnimating->SelectWeightedSequence((Activity)iActivity);
|
||||
|
||||
if (index != ACT_INVALID)
|
||||
m_OnHasSequence.Set(index, pAnimating, this);
|
||||
else
|
||||
m_OnLacksSequence.FireOutput(pAnimating, this);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Checks and calculates an entity's position.
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -5441,7 +5544,8 @@ private:
|
||||
|
||||
CBaseEntity *GetTarget(CBaseEntity *pActivator, CBaseEntity *pCaller);
|
||||
|
||||
Vector GetPosition(CBaseEntity *pEntity);
|
||||
const Vector &GetPosition(CBaseEntity *pEntity);
|
||||
const QAngle &GetAngles(CBaseEntity *pEntity);
|
||||
|
||||
// Inputs
|
||||
void InputGetPosition( inputdata_t &inputdata );
|
||||
@ -5452,6 +5556,7 @@ private:
|
||||
|
||||
// Outputs
|
||||
COutputVector m_OutPosition;
|
||||
COutputVector m_OutAngles;
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
@ -5472,6 +5577,7 @@ BEGIN_DATADESC( CLogicEntityPosition )
|
||||
|
||||
// Outputs
|
||||
DEFINE_OUTPUT(m_OutPosition, "OutPosition"),
|
||||
DEFINE_OUTPUT(m_OutAngles, "OutAngles"),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
@ -5487,16 +5593,15 @@ inline CBaseEntity *CLogicEntityPosition::GetTarget(CBaseEntity *pActivator, CBa
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
Vector CLogicEntityPosition::GetPosition(CBaseEntity *pEntity)
|
||||
const Vector &CLogicEntityPosition::GetPosition(CBaseEntity *pEntity)
|
||||
{
|
||||
Vector vecPosition = vec3_origin;
|
||||
switch (m_iPositionType)
|
||||
{
|
||||
case POSITION_ORIGIN: vecPosition = pEntity->GetAbsOrigin(); break;
|
||||
case POSITION_LOCAL: vecPosition = pEntity->GetLocalOrigin(); break;
|
||||
case POSITION_BBOX: vecPosition = pEntity->WorldSpaceCenter(); break;
|
||||
case POSITION_EYES: vecPosition = pEntity->EyePosition(); break;
|
||||
case POSITION_EARS: vecPosition = pEntity->EarPosition(); break;
|
||||
case POSITION_ORIGIN: return pEntity->GetAbsOrigin();
|
||||
case POSITION_LOCAL: return pEntity->GetLocalOrigin();
|
||||
case POSITION_BBOX: return pEntity->WorldSpaceCenter();
|
||||
case POSITION_EYES: return pEntity->EyePosition();
|
||||
case POSITION_EARS: return pEntity->EarPosition();
|
||||
case POSITION_ATTACHMENT:
|
||||
{
|
||||
CBaseAnimating *pAnimating = pEntity->GetBaseAnimating();
|
||||
@ -5506,10 +5611,47 @@ Vector CLogicEntityPosition::GetPosition(CBaseEntity *pEntity)
|
||||
break;
|
||||
}
|
||||
|
||||
// Attachment position doesn't originate anywhere, so use a static variable
|
||||
static Vector vecPosition;
|
||||
pAnimating->GetAttachment(STRING(m_iszPositionParameter), vecPosition);
|
||||
return vecPosition;
|
||||
}
|
||||
}
|
||||
|
||||
return vec3_origin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const QAngle &CLogicEntityPosition::GetAngles(CBaseEntity *pEntity)
|
||||
{
|
||||
const QAngle *angAngles = &vec3_angle;
|
||||
switch (m_iPositionType)
|
||||
{
|
||||
case POSITION_BBOX:
|
||||
case POSITION_EARS:
|
||||
case POSITION_ORIGIN: angAngles = &pEntity->GetAbsAngles(); break;
|
||||
case POSITION_LOCAL: angAngles = &pEntity->GetLocalAngles(); break;
|
||||
case POSITION_EYES: angAngles = &pEntity->EyeAngles(); break;
|
||||
case POSITION_ATTACHMENT:
|
||||
{
|
||||
CBaseAnimating *pAnimating = pEntity->GetBaseAnimating();
|
||||
if (!pAnimating)
|
||||
{
|
||||
Warning("%s wants to measure one of %s's attachments, but %s doesn't support them!\n", GetDebugName(), pEntity->GetDebugName(), pEntity->GetDebugName());
|
||||
break;
|
||||
}
|
||||
|
||||
// Attachment angles don't originate anywhere, so use a static variable
|
||||
static QAngle AttachmentAngles;
|
||||
matrix3x4_t attachmentToWorld;
|
||||
pAnimating->GetAttachment( pAnimating->LookupAttachment( STRING( m_iszPositionParameter ) ), attachmentToWorld );
|
||||
MatrixAngles( attachmentToWorld, AttachmentAngles );
|
||||
angAngles = &AttachmentAngles;
|
||||
} break;
|
||||
}
|
||||
return vecPosition;
|
||||
|
||||
return *angAngles;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -5518,9 +5660,14 @@ void CLogicEntityPosition::InputGetPosition( inputdata_t &inputdata )
|
||||
{
|
||||
CBaseEntity *pEntity = GetTarget(inputdata.pActivator, inputdata.pCaller);
|
||||
if (!pEntity)
|
||||
m_OutPosition.Set(vec3_origin, NULL, this);
|
||||
{
|
||||
m_OutPosition.Set( vec3_origin, NULL, this );
|
||||
m_OutAngles.Set( vec3_angle, NULL, this );
|
||||
return;
|
||||
}
|
||||
|
||||
m_OutPosition.Set(GetPosition(pEntity), pEntity, this);
|
||||
m_OutPosition.Set( GetPosition(pEntity), pEntity, this );
|
||||
m_OutAngles.Set( GetAngles(pEntity), pEntity, this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -5550,12 +5697,20 @@ void CLogicEntityPosition::InputPredictPosition( inputdata_t &inputdata )
|
||||
{
|
||||
CBaseEntity *pEntity = GetTarget(inputdata.pActivator, inputdata.pCaller);
|
||||
if (!pEntity)
|
||||
m_OutPosition.Set(vec3_origin, NULL, this);
|
||||
{
|
||||
m_OutPosition.Set( vec3_origin, NULL, this );
|
||||
m_OutAngles.Set( vec3_angle, NULL, this );
|
||||
return;
|
||||
}
|
||||
|
||||
Vector vecPosition;
|
||||
UTIL_PredictedPosition(pEntity, GetPosition(pEntity), inputdata.value.Float(), &vecPosition);
|
||||
|
||||
m_OutPosition.Set(vecPosition, pEntity, this);
|
||||
QAngle angAngles;
|
||||
UTIL_PredictedAngles(pEntity, GetAngles(pEntity), inputdata.value.Float(), &angAngles);
|
||||
|
||||
m_OutPosition.Set( vecPosition, pEntity, this );
|
||||
m_OutAngles.Set( angAngles, pEntity, this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -6190,12 +6345,16 @@ public:
|
||||
// Inputs
|
||||
void InputSetValue( inputdata_t &inputdata );
|
||||
void InputSetValueNoFire( inputdata_t &inputdata );
|
||||
void InputGetValue( inputdata_t &inputdata );
|
||||
void InputSetGenerateType( inputdata_t &inputdata );
|
||||
|
||||
void InputEnable( inputdata_t &inputdata );
|
||||
void InputDisable( inputdata_t &inputdata );
|
||||
void InputToggle( inputdata_t &inputdata );
|
||||
|
||||
void UpdateOutValue( float fNewValue, CBaseEntity *pActivator = NULL );
|
||||
void UpdateOutValueSine( float fNewValue, CBaseEntity *pActivator = NULL );
|
||||
|
||||
// Basic functions
|
||||
void Spawn();
|
||||
bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
@ -6213,8 +6372,16 @@ public:
|
||||
// The gaussian stream normally only exists on the client, so we use our own.
|
||||
static CGaussianRandomStream m_GaussianStream;
|
||||
|
||||
bool m_bHitMin; // Set when we reach or go below our minimum value, cleared if we go above it again.
|
||||
bool m_bHitMax; // Set when we reach or exceed our maximum value, cleared if we fall below it again.
|
||||
|
||||
// Outputs
|
||||
COutputFloat m_Value;
|
||||
COutputFloat m_OutValue;
|
||||
COutputFloat m_OnGetValue; // Used for polling the counter value.
|
||||
COutputEvent m_OnHitMin;
|
||||
COutputEvent m_OnHitMax;
|
||||
COutputEvent m_OnChangedFromMin;
|
||||
COutputEvent m_OnChangedFromMax;
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
@ -6232,15 +6399,24 @@ BEGIN_DATADESC( CMathGenerate )
|
||||
|
||||
DEFINE_KEYFIELD( m_iGenerateType, FIELD_INTEGER, "GenerateType" ),
|
||||
|
||||
DEFINE_FIELD( m_bHitMax, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_bHitMin, FIELD_BOOLEAN ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetValue", InputSetValue ),
|
||||
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetValueNoFire", InputSetValueNoFire ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "GetValue", InputGetValue ),
|
||||
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetGenerateType", InputSetGenerateType ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),
|
||||
|
||||
DEFINE_OUTPUT( m_Value, "OutValue" ),
|
||||
DEFINE_OUTPUT( m_OutValue, "OutValue" ),
|
||||
DEFINE_OUTPUT( m_OnHitMin, "OnHitMin" ),
|
||||
DEFINE_OUTPUT( m_OnHitMax, "OnHitMax" ),
|
||||
DEFINE_OUTPUT( m_OnGetValue, "OnGetValue" ),
|
||||
DEFINE_OUTPUT( m_OnChangedFromMin, "OnChangedFromMin" ),
|
||||
DEFINE_OUTPUT( m_OnChangedFromMax, "OnChangedFromMax" ),
|
||||
|
||||
DEFINE_THINKFUNC( GenerateSineWave ),
|
||||
DEFINE_THINKFUNC( GenerateLinearRamp ),
|
||||
@ -6278,7 +6454,7 @@ bool CMathGenerate::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
if (FStrEq( szKeyName, "InitialValue" ))
|
||||
{
|
||||
m_Value.Init( atof(szValue) );
|
||||
m_OutValue.Init( atof(szValue) );
|
||||
}
|
||||
else
|
||||
return BaseClass::KeyValue( szKeyName, szValue );
|
||||
@ -6290,14 +6466,22 @@ bool CMathGenerate::KeyValue( const char *szKeyName, const char *szValue )
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathGenerate::InputSetValue( inputdata_t &inputdata )
|
||||
{
|
||||
m_Value.Set(inputdata.value.Float(), inputdata.pActivator, this);
|
||||
UpdateOutValue(inputdata.value.Float(), inputdata.pActivator);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathGenerate::InputSetValueNoFire( inputdata_t &inputdata )
|
||||
{
|
||||
m_Value.Init(inputdata.value.Float());
|
||||
m_OutValue.Init(inputdata.value.Float());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathGenerate::InputGetValue( inputdata_t &inputdata )
|
||||
{
|
||||
float flOutValue = m_OutValue.Get();
|
||||
m_OnGetValue.Set( flOutValue, inputdata.pActivator, inputdata.pCaller );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -6337,6 +6521,123 @@ void CMathGenerate::InputToggle( inputdata_t &inputdata )
|
||||
m_bDisabled ? InputEnable(inputdata) : InputDisable(inputdata);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the value to the new value, clamping and firing the output value.
|
||||
// Input : fNewValue - Value to set.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathGenerate::UpdateOutValue( float fNewValue, CBaseEntity *pActivator )
|
||||
{
|
||||
if ((m_flMin != 0) || (m_flMax != 0))
|
||||
{
|
||||
//
|
||||
// Fire an output any time we reach or exceed our maximum value.
|
||||
//
|
||||
if ( fNewValue >= m_flMax || (m_iGenerateType == GENERATE_SINE_WAVE && fNewValue >= (m_flMax * 0.995f)) )
|
||||
{
|
||||
if ( !m_bHitMax )
|
||||
{
|
||||
m_bHitMax = true;
|
||||
m_OnHitMax.FireOutput( pActivator, this );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fire an output if we just changed from the maximum value
|
||||
if ( m_OutValue.Get() == m_flMax )
|
||||
{
|
||||
m_OnChangedFromMax.FireOutput( pActivator, this );
|
||||
}
|
||||
|
||||
m_bHitMax = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Fire an output any time we reach or go below our minimum value.
|
||||
//
|
||||
if ( fNewValue <= m_flMin )
|
||||
{
|
||||
if ( !m_bHitMin )
|
||||
{
|
||||
m_bHitMin = true;
|
||||
m_OnHitMin.FireOutput( pActivator, this );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fire an output if we just changed from the maximum value
|
||||
if ( m_OutValue.Get() == m_flMin )
|
||||
{
|
||||
m_OnChangedFromMin.FireOutput( pActivator, this );
|
||||
}
|
||||
|
||||
m_bHitMin = false;
|
||||
}
|
||||
|
||||
fNewValue = clamp(fNewValue, m_flMin, m_flMax);
|
||||
}
|
||||
|
||||
m_OutValue.Set(fNewValue, pActivator, this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the value to the new value, clamping and firing the output value.
|
||||
// Sine generation needs to use a different function to account for skips and imprecision.
|
||||
// Input : fNewValue - Value to set.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathGenerate::UpdateOutValueSine( float fNewValue, CBaseEntity *pActivator )
|
||||
{
|
||||
if ((m_flMin != 0) || (m_flMax != 0))
|
||||
{
|
||||
//
|
||||
// Fire an output any time we reach or exceed our maximum value.
|
||||
//
|
||||
if ( fNewValue >= (m_flMax * 0.995f) )
|
||||
{
|
||||
if ( !m_bHitMax )
|
||||
{
|
||||
m_bHitMax = true;
|
||||
m_OnHitMax.FireOutput( pActivator, this );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fire an output if we just changed from the maximum value
|
||||
if ( m_bHitMax )
|
||||
{
|
||||
m_OnChangedFromMax.FireOutput( pActivator, this );
|
||||
}
|
||||
|
||||
m_bHitMax = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Fire an output any time we reach or go below our minimum value.
|
||||
//
|
||||
if ( fNewValue <= (m_flMin * 1.005f) )
|
||||
{
|
||||
if ( !m_bHitMin )
|
||||
{
|
||||
m_bHitMin = true;
|
||||
m_OnHitMin.FireOutput( pActivator, this );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fire an output if we just changed from the maximum value
|
||||
if ( m_bHitMin )
|
||||
{
|
||||
m_OnChangedFromMin.FireOutput( pActivator, this );
|
||||
}
|
||||
|
||||
m_bHitMin = false;
|
||||
}
|
||||
|
||||
//fNewValue = clamp(fNewValue, m_flMin, m_flMax);
|
||||
}
|
||||
|
||||
m_OutValue.Set(fNewValue, pActivator, this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMathGenerate::StartGenerating()
|
||||
@ -6402,7 +6703,7 @@ void CMathGenerate::GenerateSineWave()
|
||||
// get a value in [min,max]
|
||||
flValue = ( m_flMax - m_flMin ) * flValue + m_flMin;
|
||||
|
||||
m_Value.Set( flValue, NULL, this );
|
||||
UpdateOutValueSine( flValue );
|
||||
|
||||
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
|
||||
}
|
||||
@ -6414,7 +6715,7 @@ void CMathGenerate::GenerateLinearRamp()
|
||||
// CLinearRampProxy in mathproxy.cpp
|
||||
|
||||
// Param1 = rate
|
||||
float flVal = m_flParam1 * gpGlobals->curtime + m_Value.Get();
|
||||
float flVal = m_flParam1 * gpGlobals->curtime + m_OutValue.Get();
|
||||
|
||||
// clamp
|
||||
if (flVal < m_flMin)
|
||||
@ -6422,7 +6723,7 @@ void CMathGenerate::GenerateLinearRamp()
|
||||
else if (flVal > m_flMax)
|
||||
flVal = m_flMax;
|
||||
|
||||
m_Value.Set( flVal, NULL, this );
|
||||
UpdateOutValue( flVal );
|
||||
|
||||
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
|
||||
}
|
||||
@ -6433,7 +6734,7 @@ void CMathGenerate::GenerateUniformNoise()
|
||||
{
|
||||
// CUniformNoiseProxy in mathproxy.cpp
|
||||
|
||||
m_Value.Set( random->RandomFloat( m_flMin, m_flMax ), NULL, this );
|
||||
UpdateOutValue( random->RandomFloat( m_flMin, m_flMax ) );
|
||||
|
||||
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
|
||||
}
|
||||
@ -6454,7 +6755,7 @@ void CMathGenerate::GenerateGaussianNoise()
|
||||
else if (flVal > m_flMax)
|
||||
flVal = m_flMax;
|
||||
|
||||
m_Value.Set( flVal, NULL, this );
|
||||
UpdateOutValue( flVal );
|
||||
|
||||
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
|
||||
}
|
||||
@ -6467,7 +6768,7 @@ void CMathGenerate::GenerateExponential()
|
||||
|
||||
// Param1 = scale
|
||||
// Param2 = offset
|
||||
float flVal = m_flParam1 * exp( m_Value.Get() + m_flParam2 );
|
||||
float flVal = m_flParam1 * exp( m_OutValue.Get() + m_flParam2 );
|
||||
|
||||
// clamp
|
||||
if (flVal < m_flMin)
|
||||
@ -6475,7 +6776,7 @@ void CMathGenerate::GenerateExponential()
|
||||
else if (flVal > m_flMax)
|
||||
flVal = m_flMax;
|
||||
|
||||
m_Value.Set( flVal, NULL, this );
|
||||
UpdateOutValue( flVal );
|
||||
|
||||
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
|
||||
}
|
||||
|
@ -92,19 +92,17 @@ void CVEnt_Precache(CMapbaseCVarModEntity *modent)
|
||||
if (Q_strstr(STRING(modent->m_target), "sv_allow_logic_convar"))
|
||||
return;
|
||||
|
||||
#ifdef MAPBASE_MP
|
||||
if (gpGlobals->maxClients > 1 && !modent->m_bUseServer)
|
||||
{
|
||||
Warning("WARNING: %s is using the local player in a multiplayer game and will not function.\n", modent->GetDebugName());
|
||||
}
|
||||
#endif
|
||||
|
||||
CV_InitMod();
|
||||
}
|
||||
void CVEnt_Activate(CMapbaseCVarModEntity *modent, CBaseEntity *pActivator = UTIL_GetLocalPlayer())
|
||||
void CVEnt_Activate(CMapbaseCVarModEntity *modent)
|
||||
{
|
||||
edict_t *edict = pActivator ? pActivator->edict() : NULL;
|
||||
if (!edict)
|
||||
return;
|
||||
|
||||
SetChangingCVars( modent );
|
||||
|
||||
if (m_ModEntities.Find(modent) == m_ModEntities.InvalidIndex())
|
||||
m_ModEntities.AddToTail(modent);
|
||||
|
||||
const char *pszCommands = STRING( modent->m_target );
|
||||
if ( Q_strnchr(pszCommands, '^', MAX_CONVARMOD_STRING_SIZE) )
|
||||
{
|
||||
@ -123,8 +121,29 @@ void CVEnt_Activate(CMapbaseCVarModEntity *modent, CBaseEntity *pActivator = UTI
|
||||
pszCommands = szTmp;
|
||||
}
|
||||
|
||||
if (modent->m_bUseServer)
|
||||
{
|
||||
SetChangingCVars( modent );
|
||||
|
||||
engine->ServerCommand( pszCommands );
|
||||
engine->ServerCommand( "mapbase_cvarsnotchanging" );
|
||||
}
|
||||
else
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
|
||||
edict_t *edict = pPlayer ? pPlayer->edict() : NULL;
|
||||
if (edict)
|
||||
{
|
||||
SetChangingCVars( modent );
|
||||
|
||||
engine->ClientCommand( edict, pszCommands );
|
||||
engine->ClientCommand( edict, "mapbase_cvarsnotchanging\n" );
|
||||
engine->ClientCommand( edict, "mapbase_cvarsnotchanging" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning("%s unable to find local player edict\n", modent->GetDebugName());
|
||||
}
|
||||
}
|
||||
}
|
||||
void CVEnt_Deactivate(CMapbaseCVarModEntity *modent)
|
||||
{
|
||||
@ -173,6 +192,7 @@ LINK_ENTITY_TO_CLASS( mapbase_convar_mod, CMapbaseCVarModEntity );
|
||||
BEGIN_DATADESC( CMapbaseCVarModEntity )
|
||||
|
||||
DEFINE_UTLVECTOR( m_ModifiedConvars, FIELD_EMBEDDED ),
|
||||
DEFINE_KEYFIELD( m_bUseServer, FIELD_BOOLEAN, "UseServer" ),
|
||||
|
||||
// Inputs
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ),
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
bool NewCVar( ConVarRef *var, const char *pOldString, CBaseEntity *modent );
|
||||
|
||||
CUtlVector< modifiedconvars_t > m_ModifiedConvars;
|
||||
bool m_bUseServer;
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
@ -565,6 +565,13 @@ int CPhysBox::ObjectCaps()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( HasSpawnFlags( SF_PHYSBOX_RADIUS_PICKUP ) )
|
||||
{
|
||||
caps |= FCAP_USE_IN_RADIUS;
|
||||
}
|
||||
#endif
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,9 @@
|
||||
#define SF_PHYSBOX_NEVER_PICK_UP 0x200000 // Physcannon will never be able to pick this up.
|
||||
#define SF_PHYSBOX_NEVER_PUNT 0x400000 // Physcannon will never be able to punt this object.
|
||||
#define SF_PHYSBOX_PREVENT_PLAYER_TOUCH_ENABLE 0x800000 // If set, the player will not cause the object to enable its motion when bumped into
|
||||
#ifdef MAPBASE
|
||||
#define SF_PHYSBOX_RADIUS_PICKUP 0x1000000 // Allows this object to be picked up in a radius, useful for smaller objects. Based on the prop_physics input
|
||||
#endif
|
||||
|
||||
// UNDONE: Hook collisions into the physics system to generate touch functions and take damage on falls
|
||||
// UNDONE: Base class PhysBrush
|
||||
|
@ -82,6 +82,7 @@
|
||||
#include "weapon_physcannon.h"
|
||||
#ifdef MAPBASE
|
||||
#include "mapbase/GlobalStrings.h"
|
||||
#include "mapbase/matchers.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -7982,11 +7983,17 @@ public:
|
||||
#ifdef MAPBASE
|
||||
void InputEnable(inputdata_t &data);
|
||||
void InputDisable(inputdata_t &data);
|
||||
|
||||
void InputSetAdditionalButtons(inputdata_t &data);
|
||||
#endif
|
||||
|
||||
private:
|
||||
int GetDisabledButtonMask( void );
|
||||
|
||||
#ifdef MAPBASE
|
||||
int m_iAdditionalButtons;
|
||||
#endif
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
||||
@ -7997,6 +8004,9 @@ BEGIN_DATADESC( CMovementSpeedMod )
|
||||
#ifdef MAPBASE
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iAdditionalButtons, FIELD_INTEGER, "AdditionalButtons" ),
|
||||
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetAdditionalButtons", InputSetAdditionalButtons ),
|
||||
#endif
|
||||
END_DATADESC()
|
||||
|
||||
@ -8034,6 +8044,13 @@ int CMovementSpeedMod::GetDisabledButtonMask( void )
|
||||
nMask |= IN_ZOOM;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( m_iAdditionalButtons != 0 )
|
||||
{
|
||||
nMask |= m_iAdditionalButtons;
|
||||
}
|
||||
#endif
|
||||
|
||||
return nMask;
|
||||
}
|
||||
|
||||
@ -8102,8 +8119,15 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( !HasSpawnFlags( SF_SPEED_MOD_DONT_SUPPRESS_FLASHLIGHT ) )
|
||||
{
|
||||
#endif
|
||||
// Allow the flashlight again
|
||||
pPlayer->SetFlashlightEnabled( true );
|
||||
#ifdef MAPBASE
|
||||
}
|
||||
#endif
|
||||
pPlayer->EnableButtons( GetDisabledButtonMask() );
|
||||
|
||||
// Restore the HUD
|
||||
@ -8200,6 +8224,120 @@ void CMovementSpeedMod::InputDisable(inputdata_t &data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMovementSpeedMod::InputSetAdditionalButtons(inputdata_t &data)
|
||||
{
|
||||
CBasePlayer *pPlayer = NULL;
|
||||
|
||||
if ( data.pActivator && data.pActivator->IsPlayer() )
|
||||
{
|
||||
pPlayer = (CBasePlayer *)data.pActivator;
|
||||
}
|
||||
else if ( !g_pGameRules->IsDeathmatch() )
|
||||
{
|
||||
pPlayer = UTIL_GetLocalPlayer();
|
||||
}
|
||||
|
||||
bool bAlreadyDisabled = false;
|
||||
if ( pPlayer )
|
||||
{
|
||||
bAlreadyDisabled = (pPlayer->m_afButtonDisabled & GetDisabledButtonMask()) != 0;
|
||||
}
|
||||
|
||||
m_iAdditionalButtons = data.value.Int();
|
||||
|
||||
// If we were already disabling buttons, re-disable them
|
||||
if ( bAlreadyDisabled )
|
||||
{
|
||||
// We should probably do something better than this.
|
||||
pPlayer->m_afButtonForced = GetDisabledButtonMask();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE
|
||||
class CLogicPlayerInfo : public CPointEntity
|
||||
{
|
||||
DECLARE_CLASS( CLogicPlayerInfo, CPointEntity );
|
||||
public:
|
||||
void InputGetPlayerInfo( inputdata_t &inputdata );
|
||||
void InputGetPlayerByID( inputdata_t &inputdata );
|
||||
void InputGetPlayerByName( inputdata_t &inputdata );
|
||||
|
||||
void GetPlayerInfo( CBasePlayer *pPlayer );
|
||||
|
||||
COutputInt m_OutUserID;
|
||||
COutputString m_OutPlayerName;
|
||||
COutputEHANDLE m_OutPlayerEntity;
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( logic_playerinfo, CLogicPlayerInfo );
|
||||
|
||||
BEGIN_DATADESC( CLogicPlayerInfo )
|
||||
DEFINE_INPUTFUNC( FIELD_EHANDLE, "GetPlayerInfo", InputGetPlayerInfo ),
|
||||
DEFINE_INPUTFUNC( FIELD_STRING, "GetPlayerByID", InputGetPlayerByID ),
|
||||
DEFINE_INPUTFUNC( FIELD_STRING, "GetPlayerByName", InputGetPlayerByName ),
|
||||
|
||||
DEFINE_OUTPUT( m_OutUserID, "OutUserID" ),
|
||||
DEFINE_OUTPUT( m_OutPlayerName, "OutPlayerName" ),
|
||||
DEFINE_OUTPUT( m_OutPlayerEntity, "OutPlayerEntity" ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
void CLogicPlayerInfo::InputGetPlayerInfo( inputdata_t &inputdata )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer(inputdata.value.Entity());
|
||||
|
||||
// If there was no entity to begin with, try the local player
|
||||
if (!pPlayer && !inputdata.value.Entity())
|
||||
pPlayer = UTIL_GetLocalPlayer();
|
||||
|
||||
if (pPlayer)
|
||||
GetPlayerInfo( pPlayer );
|
||||
}
|
||||
|
||||
void CLogicPlayerInfo::InputGetPlayerByID( inputdata_t &inputdata )
|
||||
{
|
||||
for (int i = 1; i < gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
|
||||
if (pPlayer)
|
||||
{
|
||||
if (Matcher_NamesMatch( inputdata.value.String(), UTIL_VarArgs("%i", pPlayer->GetUserID()) ))
|
||||
{
|
||||
GetPlayerInfo( pPlayer );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLogicPlayerInfo::InputGetPlayerByName( inputdata_t &inputdata )
|
||||
{
|
||||
for (int i = 1; i < gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
|
||||
if (pPlayer)
|
||||
{
|
||||
if (Matcher_NamesMatch( inputdata.value.String(), pPlayer->GetPlayerName() ))
|
||||
{
|
||||
GetPlayerInfo( pPlayer );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLogicPlayerInfo::GetPlayerInfo( CBasePlayer *pPlayer )
|
||||
{
|
||||
m_OutUserID.Set( pPlayer->GetUserID(), pPlayer, this );
|
||||
|
||||
m_OutPlayerName.Set( AllocPooledString(pPlayer->GetPlayerName()), pPlayer, this );
|
||||
|
||||
m_OutPlayerEntity.Set( pPlayer, pPlayer, this );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -755,6 +755,41 @@ void CBreakableProp::HandleInteractionStick( int index, gamevcollisionevent_t *p
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
extern int g_interactionBarnacleVictimBite;
|
||||
extern ConVar npc_barnacle_ignite;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Uses the new CBaseEntity interaction implementation
|
||||
// Input : The type of interaction, extra info pointer, and who started it
|
||||
// Output : true - if sub-class has a response for the interaction
|
||||
// false - if sub-class has no response
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBreakableProp::HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt )
|
||||
{
|
||||
#ifdef HL2_EPISODIC
|
||||
// Allows flares to ignite barnacles.
|
||||
if ( interactionType == g_interactionBarnacleVictimBite )
|
||||
{
|
||||
if ( npc_barnacle_ignite.GetBool() && sourceEnt->IsOnFire() == false )
|
||||
{
|
||||
sourceEnt->Ignite( 25.0f );
|
||||
KillFlare( this, m_hFlareEnt, PROP_FLARE_IGNITE_SUBSTRACT );
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "flare_ignite_npc" );
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "entindex", sourceEnt->entindex() );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return BaseClass::HandleInteraction(interactionType, data, sourceEnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Turn on prop debugging mode
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -120,6 +120,11 @@ public:
|
||||
void HandleInteractionStick( int index, gamevcollisionevent_t *pEvent );
|
||||
void StickAtPosition( const Vector &stickPosition, const Vector &savePosition, const QAngle &saveAngles );
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Uses the new CBaseEntity interaction implementation
|
||||
bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt );
|
||||
#endif
|
||||
|
||||
// Disable auto fading under dx7 or when level fades are specified
|
||||
void DisableAutoFade();
|
||||
|
||||
|
@ -4840,7 +4840,13 @@ float InstancedScriptedScene( CBaseFlex *pActor, const char *pszScene, EHANDLE *
|
||||
// *phSceneEnt -
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef MAPBASE
|
||||
float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, const char *soundname, EHANDLE *phSceneEnt,
|
||||
float flPostDelay, bool bIsBackground, AI_Response *response,
|
||||
bool bMultiplayer, IRecipientFilter *filter /* = NULL */ )
|
||||
#else
|
||||
float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, char const *soundname, EHANDLE *phSceneEnt /*= NULL*/ )
|
||||
#endif
|
||||
{
|
||||
if ( !pActor )
|
||||
{
|
||||
@ -4858,10 +4864,38 @@ float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, char const *soundname
|
||||
|
||||
pScene->GenerateSoundScene( pActor, soundname );
|
||||
|
||||
#ifdef MAPBASE
|
||||
pScene->m_bMultiplayer = bMultiplayer;
|
||||
pScene->SetPostSpeakDelay( flPostDelay );
|
||||
DispatchSpawn( pScene );
|
||||
pScene->Activate();
|
||||
pScene->m_bIsBackground = bIsBackground;
|
||||
|
||||
pScene->SetBackground( bIsBackground );
|
||||
pScene->SetRecipientFilter( filter );
|
||||
|
||||
if ( response )
|
||||
{
|
||||
float flPreDelay = response->GetPreDelay();
|
||||
if ( flPreDelay )
|
||||
{
|
||||
pScene->SetPreDelay( flPreDelay );
|
||||
}
|
||||
}
|
||||
#else
|
||||
pScene->Spawn();
|
||||
pScene->Activate();
|
||||
#endif
|
||||
pScene->StartPlayback();
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( response )
|
||||
{
|
||||
// If the response wants us to abort on NPC state switch, remember that
|
||||
pScene->SetBreakOnNonIdle( response->ShouldBreakOnNonIdle() );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( phSceneEnt )
|
||||
{
|
||||
*phSceneEnt = pScene;
|
||||
|
@ -24,7 +24,11 @@ struct recentNPCSpeech_t
|
||||
|
||||
int GetRecentNPCSpeech( recentNPCSpeech_t speech[ SPEECH_LIST_MAX_SOUNDS ] );
|
||||
float InstancedScriptedScene( CBaseFlex *pActor, const char *pszScene, EHANDLE *phSceneEnt = NULL, float flPostDelay = 0.0f, bool bIsBackground = false, AI_Response *response = NULL, bool bMultiplayer = false, IRecipientFilter *filter = NULL );
|
||||
#ifdef MAPBASE
|
||||
float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, char const *soundname, EHANDLE *phSceneEnt = NULL, float flPostDelay = 0.0f, bool bIsBackground = false, AI_Response *response = NULL, bool bMultiplayer = false, IRecipientFilter *filter = NULL );
|
||||
#else
|
||||
float InstancedAutoGeneratedSoundScene( CBaseFlex *pActor, char const *soundname, EHANDLE *phSceneEnt = NULL );
|
||||
#endif
|
||||
void StopScriptedScene( CBaseFlex *pActor, EHANDLE hSceneEnt );
|
||||
void RemoveActorFromScriptedScenes( CBaseFlex *pActor, bool instancedscenesonly, bool nonidlescenesonly = false, const char *pszThisSceneOnly = NULL );
|
||||
void RemoveAllScenesInvolvingActor( CBaseFlex *pActor );
|
||||
|
@ -118,6 +118,9 @@ BEGIN_DATADESC( CAI_ScriptedSequence )
|
||||
DEFINE_OUTPUT(m_OnScriptEvent[5], "OnScriptEvent06"),
|
||||
DEFINE_OUTPUT(m_OnScriptEvent[6], "OnScriptEvent07"),
|
||||
DEFINE_OUTPUT(m_OnScriptEvent[7], "OnScriptEvent08"),
|
||||
#ifdef MAPBASE
|
||||
DEFINE_OUTPUT(m_OnPreIdleSequence, "OnPreIdleSequence"),
|
||||
#endif
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
@ -838,6 +841,11 @@ void CAI_ScriptedSequence::OnBeginSequence( CBaseEntity *pActor )
|
||||
{
|
||||
m_OnBeginSequence.FireOutput( pActor, this );
|
||||
}
|
||||
|
||||
void CAI_ScriptedSequence::OnPreIdleSequence( CBaseEntity *pActor )
|
||||
{
|
||||
m_OnPreIdleSequence.FireOutput( pActor, this );
|
||||
}
|
||||
#else
|
||||
void CAI_ScriptedSequence::OnBeginSequence( void )
|
||||
{
|
||||
@ -1125,7 +1133,11 @@ void CAI_ScriptedSequence::PostIdleDone( CAI_BaseNPC *pNPC )
|
||||
}
|
||||
|
||||
//Msg("%s finished post idle at %0.2f\n", pNPC->GetDebugName(), gpGlobals->curtime );
|
||||
#ifdef MAPBASE
|
||||
m_OnPostIdleEndSequence.FireOutput(pNPC, this);
|
||||
#else
|
||||
m_OnPostIdleEndSequence.FireOutput(NULL, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,6 +97,7 @@ public:
|
||||
void FireScriptEvent( int nEvent );
|
||||
#ifdef MAPBASE
|
||||
void OnBeginSequence( CBaseEntity *pActor );
|
||||
void OnPreIdleSequence( CBaseEntity *pActor );
|
||||
#else
|
||||
void OnBeginSequence( void );
|
||||
#endif
|
||||
@ -218,6 +219,9 @@ private:
|
||||
COutputEvent m_OnCancelSequence;
|
||||
COutputEvent m_OnCancelFailedSequence; // Fired when a scene is cancelled before it's ever run
|
||||
COutputEvent m_OnScriptEvent[MAX_SCRIPT_EVENTS];
|
||||
#ifdef MAPBASE
|
||||
COutputEvent m_OnPreIdleSequence;
|
||||
#endif
|
||||
|
||||
static void ScriptEntityCancel( CBaseEntity *pentCine, bool bPretendSuccess = false );
|
||||
|
||||
|
@ -26,6 +26,7 @@ $Project
|
||||
{
|
||||
$File "$SRCDIR\game\shared\mapbase\mapbase_shared.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\mapbase_rpc.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\mapbase_game_log.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\MapEdit.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
|
||||
|
||||
|
@ -36,6 +36,9 @@
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "util.h"
|
||||
#include "cdll_int.h"
|
||||
#ifdef MAPBASE
|
||||
#include "fmtstr.h"
|
||||
#endif
|
||||
|
||||
#ifdef PORTAL
|
||||
#include "PortalSimulation.h"
|
||||
@ -204,6 +207,46 @@ void CEntityFactoryDictionary::ReportEntitySizes()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
int EntityFactory_AutoComplete( const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0 )
|
||||
{
|
||||
CEntityFactoryDictionary *pFactoryDict = (CEntityFactoryDictionary*)EntityFactoryDictionary();
|
||||
for ( int i = pFactoryDict->m_Factories.First(); i != pFactoryDict->m_Factories.InvalidIndex(); i = pFactoryDict->m_Factories.Next( i ) )
|
||||
{
|
||||
const char *name = pFactoryDict->m_Factories.GetElementName( i );
|
||||
if (Q_strnicmp(name, substring, checklen))
|
||||
continue;
|
||||
|
||||
CUtlString sym = name;
|
||||
int idx = symbols.Find(sym);
|
||||
if (idx == symbols.InvalidIndex())
|
||||
{
|
||||
symbols.Insert(sym);
|
||||
}
|
||||
|
||||
// Too many
|
||||
if (symbols.Count() >= COMMAND_COMPLETION_MAXITEMS)
|
||||
break;
|
||||
}
|
||||
|
||||
// Now fill in the results
|
||||
for (int i = symbols.FirstInorder(); i != symbols.InvalidIndex(); i = symbols.NextInorder(i))
|
||||
{
|
||||
const char *name = symbols[i].String();
|
||||
|
||||
char buf[512];
|
||||
Q_strncpy(buf, name, sizeof(buf));
|
||||
Q_strlower(buf);
|
||||
|
||||
CUtlString command;
|
||||
command = CFmtStr("%s %s", cmdname, buf);
|
||||
commands.AddToTail(command);
|
||||
}
|
||||
|
||||
return symbols.Count();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class CFlaggedEntitiesEnum
|
||||
@ -2507,6 +2550,10 @@ void UTIL_PredictedPosition( CBaseEntity *pTarget, float flTimeDelta, Vector *ve
|
||||
if ( pAnimating != NULL )
|
||||
{
|
||||
vecPredictedVel = pAnimating->GetGroundSpeedVelocity();
|
||||
#ifdef MAPBASE
|
||||
if (vecPredictedVel.IsZero())
|
||||
vecPredictedVel = pAnimating->GetSmoothedVelocity();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2524,7 +2571,7 @@ void UTIL_PredictedPosition( CBaseEntity *pTarget, float flTimeDelta, Vector *ve
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Same as above, except you don't have to use the absolute origin and can use your own position to predict from.
|
||||
//-----------------------------------------------------------------------------
|
||||
void UTIL_PredictedPosition( CBaseEntity *pTarget, Vector &vecActualPosition, float flTimeDelta, Vector *vecPredictedPosition )
|
||||
void UTIL_PredictedPosition( CBaseEntity *pTarget, const Vector &vecActualPosition, float flTimeDelta, Vector *vecPredictedPosition )
|
||||
{
|
||||
if ( ( pTarget == NULL ) || ( vecPredictedPosition == NULL ) )
|
||||
return;
|
||||
@ -2547,7 +2594,11 @@ void UTIL_PredictedPosition( CBaseEntity *pTarget, Vector &vecActualPosition, fl
|
||||
{
|
||||
CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating *>(pTarget);
|
||||
if ( pAnimating != NULL )
|
||||
{
|
||||
vecPredictedVel = pAnimating->GetGroundSpeedVelocity();
|
||||
if (vecPredictedVel.IsZero())
|
||||
vecPredictedVel = pAnimating->GetSmoothedVelocity();
|
||||
}
|
||||
else
|
||||
vecPredictedVel = pTarget->GetSmoothedVelocity();
|
||||
}
|
||||
@ -2556,6 +2607,38 @@ void UTIL_PredictedPosition( CBaseEntity *pTarget, Vector &vecActualPosition, fl
|
||||
// Get the result
|
||||
(*vecPredictedPosition) = vecActualPosition + ( vecPredictedVel * flTimeDelta );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Predicts angles through angular velocity instead of predicting origin through regular velocity.
|
||||
//-----------------------------------------------------------------------------
|
||||
void UTIL_PredictedAngles( CBaseEntity *pTarget, const QAngle &angActualAngles, float flTimeDelta, QAngle *angPredictedAngles )
|
||||
{
|
||||
if ( ( pTarget == NULL ) || ( angPredictedAngles == NULL ) )
|
||||
return;
|
||||
|
||||
QAngle angPredictedVel;
|
||||
CBasePlayer *pPlayer = ToBasePlayer( pTarget );
|
||||
if ( pPlayer != NULL )
|
||||
{
|
||||
if ( pPlayer->IsInAVehicle() )
|
||||
angPredictedVel = pPlayer->GetVehicleEntity()->GetLocalAngularVelocity();
|
||||
else
|
||||
angPredictedVel = pPlayer->GetLocalAngularVelocity();
|
||||
}
|
||||
else
|
||||
{
|
||||
CBaseCombatCharacter *pCCTarget = pTarget->MyCombatCharacterPointer();
|
||||
if ( pCCTarget != NULL && pCCTarget->IsInAVehicle() )
|
||||
angPredictedVel = pCCTarget->GetVehicleEntity()->GetLocalAngularVelocity();
|
||||
else
|
||||
{
|
||||
angPredictedVel = pTarget->GetLocalAngularVelocity();
|
||||
}
|
||||
}
|
||||
|
||||
// Get the result
|
||||
(*angPredictedAngles) = angActualAngles + ( angPredictedVel * flTimeDelta );
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -379,7 +379,8 @@ void UTIL_AxisStringToUnitDir( Vector &dir, const char *pString );
|
||||
void UTIL_ClipPunchAngleOffset( QAngle &in, const QAngle &punch, const QAngle &clip );
|
||||
void UTIL_PredictedPosition( CBaseEntity *pTarget, float flTimeDelta, Vector *vecPredictedPosition );
|
||||
#ifdef MAPBASE
|
||||
void UTIL_PredictedPosition( CBaseEntity *pTarget, Vector &vecActualPosition, float flTimeDelta, Vector *vecPredictedPosition );
|
||||
void UTIL_PredictedPosition( CBaseEntity *pTarget, const Vector &vecActualPosition, float flTimeDelta, Vector *vecPredictedPosition );
|
||||
void UTIL_PredictedAngles( CBaseEntity *pTarget, const QAngle &angActualAngles, float flTimeDelta, QAngle *angPredictedAngles );
|
||||
#endif
|
||||
void UTIL_Beam( Vector &Start, Vector &End, int nModelIndex, int nHaloIndex, unsigned char FrameStart, unsigned char FrameRate,
|
||||
float Life, unsigned char Width, unsigned char EndWidth, unsigned char FadeLength, unsigned char Noise, unsigned char Red, unsigned char Green,
|
||||
|
@ -49,6 +49,10 @@ public:
|
||||
inline const CHandle<CBaseEntity> &Entity(void) const;
|
||||
inline color32 Color32(void) const { return rgbaVal; }
|
||||
inline void Vector3D(Vector &vec) const;
|
||||
#ifdef MAPBASE
|
||||
// Gets angles from a vector
|
||||
inline void Angle3D(QAngle &ang) const;
|
||||
#endif
|
||||
|
||||
fieldtype_t FieldType( void ) { return fieldType; }
|
||||
|
||||
@ -59,6 +63,10 @@ public:
|
||||
void SetEntity( CBaseEntity *val );
|
||||
void SetVector3D( const Vector &val ) { vecVal[0] = val[0]; vecVal[1] = val[1]; vecVal[2] = val[2]; fieldType = FIELD_VECTOR; }
|
||||
void SetPositionVector3D( const Vector &val ) { vecVal[0] = val[0]; vecVal[1] = val[1]; vecVal[2] = val[2]; fieldType = FIELD_POSITION_VECTOR; }
|
||||
#ifdef MAPBASE
|
||||
// Passes in angles as a vector
|
||||
void SetAngle3D( const QAngle &val ) { vecVal[0] = val[0]; vecVal[1] = val[1]; vecVal[2] = val[2]; fieldType = FIELD_VECTOR; }
|
||||
#endif
|
||||
void SetColor32( color32 val ) { rgbaVal = val; fieldType = FIELD_COLOR32; }
|
||||
void SetColor32( int r, int g, int b, int a ) { rgbaVal.r = r; rgbaVal.g = g; rgbaVal.b = b; rgbaVal.a = a; fieldType = FIELD_COLOR32; }
|
||||
void Set( fieldtype_t ftype, void *data );
|
||||
@ -112,6 +120,25 @@ inline void variant_t::Vector3D(Vector &vec) const
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns this variant as angles.
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void variant_t::Angle3D(QAngle &ang) const
|
||||
{
|
||||
if (( fieldType == FIELD_VECTOR ) || ( fieldType == FIELD_POSITION_VECTOR ))
|
||||
{
|
||||
ang[0] = vecVal[0];
|
||||
ang[1] = vecVal[1];
|
||||
ang[2] = vecVal[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
ang = vec3_angle;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns this variant as an EHANDLE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -376,6 +376,9 @@ BEGIN_DATADESC( CWorld )
|
||||
|
||||
// keyvalues are parsed from map, but not saved/loaded
|
||||
DEFINE_KEYFIELD( m_iszChapterTitle, FIELD_STRING, "chaptertitle" ),
|
||||
#ifdef MAPBASE
|
||||
DEFINE_KEYFIELD( m_bChapterTitleNoMessage, FIELD_BOOLEAN, "chaptertitlenomessage" ),
|
||||
#endif
|
||||
DEFINE_KEYFIELD( m_bStartDark, FIELD_BOOLEAN, "startdark" ),
|
||||
DEFINE_KEYFIELD( m_bDisplayTitle, FIELD_BOOLEAN, "gametitle" ),
|
||||
DEFINE_FIELD( m_WorldMins, FIELD_VECTOR ),
|
||||
@ -407,6 +410,9 @@ IMPLEMENT_SERVERCLASS_ST(CWorld, DT_WORLD)
|
||||
SendPropFloat (SENDINFO(m_flMinPropScreenSpaceWidth), 0, SPROP_NOSCALE ),
|
||||
SendPropStringT (SENDINFO(m_iszDetailSpriteMaterial) ),
|
||||
SendPropInt (SENDINFO(m_bColdWorld), 1, SPROP_UNSIGNED ),
|
||||
#ifdef MAPBASE
|
||||
SendPropStringT (SENDINFO(m_iszChapterTitle) ),
|
||||
#endif
|
||||
END_SEND_TABLE()
|
||||
|
||||
//
|
||||
@ -678,6 +684,23 @@ void CWorld::Precache( void )
|
||||
// Call all registered precachers.
|
||||
CPrecacheRegister::Precache();
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( m_iszChapterTitle.Get() != NULL_STRING && !m_bChapterTitleNoMessage )
|
||||
{
|
||||
DevMsg( 2, "Chapter title: %s\n", STRING(m_iszChapterTitle.Get()) );
|
||||
CMessage *pMessage = (CMessage *)CBaseEntity::Create( "env_message", vec3_origin, vec3_angle, NULL );
|
||||
if ( pMessage )
|
||||
{
|
||||
pMessage->SetMessage( m_iszChapterTitle.Get() );
|
||||
m_iszChapterTitle.Set( NULL_STRING );
|
||||
|
||||
// send the message entity a play message command, delayed by 1 second
|
||||
pMessage->AddSpawnFlags( SF_MESSAGE_ONCE );
|
||||
pMessage->SetThink( &CMessage::SUB_CallUseToggle );
|
||||
pMessage->SetNextThink( gpGlobals->curtime + 1.0f );
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( m_iszChapterTitle != NULL_STRING )
|
||||
{
|
||||
DevMsg( 2, "Chapter title: %s\n", STRING(m_iszChapterTitle) );
|
||||
@ -693,6 +716,7 @@ void CWorld::Precache( void )
|
||||
pMessage->SetNextThink( gpGlobals->curtime + 1.0f );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_iszFuncBrushClassname = AllocPooledString("func_brush");
|
||||
}
|
||||
|
@ -52,10 +52,26 @@ public:
|
||||
|
||||
bool IsColdWorld( void );
|
||||
|
||||
#ifdef MAPBASE
|
||||
inline const char *GetChapterTitle()
|
||||
{
|
||||
return STRING(m_iszChapterTitle.Get());
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
DECLARE_DATADESC();
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Now needs to show up on the client for RPC
|
||||
CNetworkVar( string_t, m_iszChapterTitle );
|
||||
|
||||
// Suppresses m_iszChapterTitle's env_message creation,
|
||||
// allowing it to only be used for saves and RPC
|
||||
bool m_bChapterTitleNoMessage;
|
||||
#else
|
||||
string_t m_iszChapterTitle;
|
||||
#endif
|
||||
|
||||
CNetworkVar( float, m_flWaveHeight );
|
||||
CNetworkVector( m_WorldMins );
|
||||
|
@ -1651,6 +1651,13 @@ void CAchievementMgr::OnMapEvent( const char *pchEventName )
|
||||
CBaseAchievement *pAchievement = m_vecMapEventListeners[iAchievement];
|
||||
pAchievement->OnMapEvent( pchEventName );
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
if (cc_achievement_debug.GetBool())
|
||||
{
|
||||
Msg( "CAchievementMgr::OnMapEvent: Achievement \"%s\" not found\n", pchEventName );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -814,6 +814,10 @@ void CBaseCombatWeapon::OnPickedUp( CBaseCombatCharacter *pNewOwner )
|
||||
// Robin: We don't want to delete weapons the player has picked up, so
|
||||
// clear the name of the weapon. This prevents wildcards that are meant
|
||||
// to find NPCs finding weapons dropped by the NPCs as well.
|
||||
#ifdef MAPBASE
|
||||
// Level designers might want some weapons to preserve their original names, however.
|
||||
if ( !HasSpawnFlags(SF_WEAPON_PRESERVE_NAME) )
|
||||
#endif
|
||||
SetName( NULL_STRING );
|
||||
}
|
||||
else
|
||||
|
@ -52,20 +52,17 @@ class CUserCmd;
|
||||
// I really, REALLY hope no weapon uses their own spawnflags.
|
||||
// If you want yours to use spawnflags, start at 16 just to be safe.
|
||||
|
||||
// Prevents NPCs from picking up the weapon.
|
||||
#define SF_WEAPON_NO_NPC_PICKUP (1<<3)
|
||||
// Prevents the weapon from filling up to max automatically
|
||||
// when picked up by the player or dropped.
|
||||
#define SF_WEAPON_PRESERVE_AMMO (1<<4)
|
||||
#define SF_WEAPON_NO_NPC_PICKUP (1<<3) // Prevents NPCs from picking up the weapon.
|
||||
#define SF_WEAPON_PRESERVE_AMMO (1<<4) // Prevents the weapon from filling up to max automatically when dropped or picked up by players.
|
||||
#define SF_WEAPON_PRESERVE_NAME (1<<5) // Prevents the weapon's name from being cleared upon being picked up by a player.
|
||||
|
||||
// ----------------------------------------------
|
||||
// Internal Spawnflags
|
||||
//
|
||||
// For all of the weapons that show up in-game, I personally feel like
|
||||
// this beats adding new variables by at least a long shot.
|
||||
// These spawnflags are not supposed to be used by level designers.
|
||||
// They're just my way of trying to avoid adding new variables
|
||||
// that have to stay in memory and save/load.
|
||||
// ----------------------------------------------
|
||||
#define SF_WEAPON_NO_AUTO_SWITCH_WHEN_EMPTY (1<<5) // So weapons with ammo preserved at 0 don't switch.
|
||||
#define SF_WEAPON_USED (1<<6) // Weapon is being +USE'd, not bumped
|
||||
#define SF_WEAPON_NO_AUTO_SWITCH_WHEN_EMPTY (1<<6) // So weapons with ammo preserved at 0 don't switch.
|
||||
#define SF_WEAPON_USED (1<<7) // Weapon is being +USE'd, not bumped
|
||||
#endif
|
||||
|
||||
//Percent
|
||||
|
@ -620,6 +620,14 @@ void CGameRules::OnSkillLevelChanged( int iNewLevel )
|
||||
pEntity->AcceptInput("SkillLevelChanged", UTIL_GetLocalPlayer(), NULL, varNewLevel, 0);
|
||||
pEntity = gEntList.FindEntityByClassname(pEntity, "logic_skill");
|
||||
}
|
||||
|
||||
// Fire game event for difficulty level changed
|
||||
IGameEvent *event = gameeventmanager->CreateEvent("skill_changed");
|
||||
if (event)
|
||||
{
|
||||
event->SetInt("skill_level", iNewLevel);
|
||||
gameeventmanager->FireEvent(event);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
243
sp/src/game/shared/mapbase/mapbase_game_log.cpp
Normal file
243
sp/src/game/shared/mapbase/mapbase_game_log.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: A special system designed to record game information for map testing.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "tier0/icommandline.h"
|
||||
#include "igamesystem.h"
|
||||
#include "filesystem.h"
|
||||
#include "utlbuffer.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#else
|
||||
#include "ammodef.h"
|
||||
#include "ai_basenpc.h"
|
||||
#include "ai_squad.h"
|
||||
#include "fmtstr.h"
|
||||
#include "GameEventListener.h"
|
||||
#include "saverestore_utlvector.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#ifdef GAME_DLL
|
||||
// ------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
class CMapbaseGameLogger : public CLogicalEntity, public CGameEventListener
|
||||
{
|
||||
public:
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_CLASS( CMapbaseGameLogger, CLogicalEntity );
|
||||
|
||||
CMapbaseGameLogger()
|
||||
{
|
||||
pGameLoggerEnt = this;
|
||||
}
|
||||
|
||||
void Activate()
|
||||
{
|
||||
BaseClass::Activate();
|
||||
|
||||
ListenForGameEvent("skill_changed");
|
||||
}
|
||||
|
||||
void FireGameEvent( IGameEvent *event )
|
||||
{
|
||||
if (FStrEq(event->GetName(), "skill_changed"))
|
||||
{
|
||||
m_ListSkillChanged.AddToTail(event->GetInt("skill_level"));
|
||||
m_ListSkillChangedTime.AddToTail(gpGlobals->curtime);
|
||||
}
|
||||
}
|
||||
|
||||
float m_flLastLogTime;
|
||||
int m_iSaveID;
|
||||
|
||||
CUtlVector<int> m_ListSkillChanged;
|
||||
CUtlVector<float> m_ListSkillChangedTime;
|
||||
|
||||
static CMapbaseGameLogger *GetGameLoggerEnt()
|
||||
{
|
||||
if (!pGameLoggerEnt)
|
||||
pGameLoggerEnt = static_cast<CMapbaseGameLogger*>(CBaseEntity::Create("mapbase_game_logger", vec3_origin, vec3_angle));
|
||||
|
||||
return pGameLoggerEnt;
|
||||
}
|
||||
|
||||
private:
|
||||
static CHandle<CMapbaseGameLogger> pGameLoggerEnt;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( mapbase_game_logger, CMapbaseGameLogger );
|
||||
|
||||
BEGIN_DATADESC( CMapbaseGameLogger )
|
||||
|
||||
DEFINE_FIELD( m_flLastLogTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_iSaveID, FIELD_INTEGER ),
|
||||
|
||||
DEFINE_UTLVECTOR( m_ListSkillChanged, FIELD_INTEGER ),
|
||||
DEFINE_UTLVECTOR( m_ListSkillChangedTime, FIELD_TIME ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
CHandle<CMapbaseGameLogger> CMapbaseGameLogger::pGameLoggerEnt;
|
||||
|
||||
void MapbaseGameLog_CVarToggle( IConVar *var, const char *pOldString, float flOldValue );
|
||||
ConVar mapbase_game_log_on_autosave( "mapbase_game_log_on_autosave", "0", FCVAR_NONE, "Logs information to %mapname%_log_%number%.txt on each autosave", MapbaseGameLog_CVarToggle );
|
||||
|
||||
void MapbaseGameLog_Init()
|
||||
{
|
||||
if (mapbase_game_log_on_autosave.GetBool())
|
||||
{
|
||||
// Create the game logger ent
|
||||
CMapbaseGameLogger::GetGameLoggerEnt();
|
||||
}
|
||||
}
|
||||
|
||||
void MapbaseGameLog_Record( const char *szContext )
|
||||
{
|
||||
CMapbaseGameLogger *pGameLoggerEnt = CMapbaseGameLogger::GetGameLoggerEnt();
|
||||
if (!pGameLoggerEnt)
|
||||
{
|
||||
Warning("Failed to get game logger ent\n");
|
||||
return;
|
||||
}
|
||||
|
||||
KeyValues *pKV = new KeyValues( "Log" );
|
||||
|
||||
KeyValues *pKVLogInfo = pKV->FindKey( "logging_info", true );
|
||||
if ( pKVLogInfo )
|
||||
{
|
||||
pKVLogInfo->SetString("context", szContext);
|
||||
pKVLogInfo->SetFloat("last_log", pGameLoggerEnt->m_flLastLogTime > 0.0f ? gpGlobals->curtime - pGameLoggerEnt->m_flLastLogTime : -1.0f);
|
||||
}
|
||||
|
||||
KeyValues *pKVGameInfo = pKV->FindKey( "game_info", true );
|
||||
if ( pKVGameInfo )
|
||||
{
|
||||
pKVGameInfo->SetInt("skill", g_pGameRules->GetSkillLevel());
|
||||
|
||||
if (pGameLoggerEnt->m_ListSkillChanged.Count() > 0)
|
||||
{
|
||||
KeyValues *pKVSkill = pKVGameInfo->FindKey("skill_changes", true);
|
||||
for (int i = 0; i < pGameLoggerEnt->m_ListSkillChanged.Count(); i++)
|
||||
{
|
||||
float flTime = pGameLoggerEnt->m_ListSkillChangedTime[i];
|
||||
switch (pGameLoggerEnt->m_ListSkillChanged[i])
|
||||
{
|
||||
case SKILL_EASY: pKVSkill->SetString(CNumStr(flTime), "easy"); break;
|
||||
case SKILL_MEDIUM: pKVSkill->SetString(CNumStr(flTime), "normal"); break;
|
||||
case SKILL_HARD: pKVSkill->SetString(CNumStr(flTime), "hard"); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeyValues *pKVPlayer = pKV->FindKey( "player", true );
|
||||
if ( pKVPlayer )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
|
||||
|
||||
if ( pPlayer )
|
||||
{
|
||||
pKVPlayer->SetInt("health", pPlayer->GetHealth());
|
||||
pKVPlayer->SetInt("armor", pPlayer->ArmorValue());
|
||||
|
||||
pKVPlayer->SetString("position", CFmtStrN<128>("[%f %f %f]", pPlayer->GetAbsOrigin().x, pPlayer->GetAbsOrigin().y, pPlayer->GetAbsOrigin().z));
|
||||
pKVPlayer->SetString("angles", CFmtStrN<128>("[%f %f %f]", pPlayer->EyeAngles().x, pPlayer->EyeAngles().y, pPlayer->EyeAngles().z));
|
||||
|
||||
KeyValues *pKVWeapons = pKVPlayer->FindKey( "weapons", true );
|
||||
if ( pKVWeapons )
|
||||
{
|
||||
// Cycle through all of the player's weapons
|
||||
for ( int i = 0; i < pPlayer->WeaponCount(); i++ )
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = pPlayer->GetWeapon(i);
|
||||
if ( !pWeapon )
|
||||
continue;
|
||||
|
||||
if ( pPlayer->GetActiveWeapon() == pWeapon )
|
||||
pKVWeapons->SetString(pWeapon->GetClassname(), CFmtStrN<32>("%i; %i (active)", pWeapon->m_iClip1, pWeapon->m_iClip2));
|
||||
else
|
||||
pKVWeapons->SetString(pWeapon->GetClassname(), CFmtStrN<32>("%i; %i", pWeapon->m_iClip1, pWeapon->m_iClip2));
|
||||
}
|
||||
}
|
||||
|
||||
KeyValues *pKVAmmo = pKVPlayer->FindKey( "ammo", true );
|
||||
if ( pKVAmmo )
|
||||
{
|
||||
// Cycle through all of the player's ammo
|
||||
for ( int i = 0; i < GetAmmoDef()->m_nAmmoIndex; i++ )
|
||||
{
|
||||
int iAmmo = pPlayer->GetAmmoCount( i );
|
||||
if ( iAmmo > 0 )
|
||||
pKVAmmo->SetInt( GetAmmoDef()->m_AmmoType[i].pName, iAmmo );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
|
||||
int nAIs = g_AI_Manager.NumAIs();
|
||||
for (int i = 0; i < nAIs; i++)
|
||||
{
|
||||
CAI_BaseNPC *pNPC = ppAIs[i];
|
||||
|
||||
if (!pNPC->IsAlive() || pNPC->GetSleepState() != AISS_AWAKE)
|
||||
continue;
|
||||
|
||||
KeyValues *pKVNPC = pKV->FindKey( CNumStr( pNPC->entindex() ), true );
|
||||
if (pKVNPC)
|
||||
{
|
||||
pKVNPC->SetString("classname", pNPC->GetClassname());
|
||||
pKVNPC->SetString("name", STRING(pNPC->GetEntityName()));
|
||||
|
||||
pKVNPC->SetString("position", CFmtStrN<128>("[%f %f %f]", pNPC->GetAbsOrigin().x, pNPC->GetAbsOrigin().y, pNPC->GetAbsOrigin().z));
|
||||
|
||||
pKVNPC->SetInt("health", pNPC->GetHealth());
|
||||
|
||||
if (pNPC->GetActiveWeapon())
|
||||
pKVNPC->SetString("weapon", pNPC->GetActiveWeapon()->GetClassname());
|
||||
|
||||
if (pNPC->GetSquad())
|
||||
pKVNPC->SetString("squad", pNPC->GetSquad()->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
CFmtStrN<MAX_PATH> pathfmt("map_logs/%s_log_%i.txt", gpGlobals->mapname, pGameLoggerEnt->m_iSaveID);
|
||||
|
||||
pGameLoggerEnt->m_flLastLogTime = gpGlobals->curtime;
|
||||
pGameLoggerEnt->m_iSaveID++;
|
||||
|
||||
// Create the folder first, since "map_logs" is not standard and is unlikely to exist
|
||||
g_pFullFileSystem->CreateDirHierarchy( "map_logs", "MOD" );
|
||||
|
||||
if (pKV->SaveToFile( g_pFullFileSystem, pathfmt, "MOD" ))
|
||||
{
|
||||
Msg("Saved game log file to \"%s\"\n", pathfmt);
|
||||
}
|
||||
|
||||
pKV->deleteThis();
|
||||
}
|
||||
|
||||
static void CC_Mapbase_GameLogRecord( const CCommand& args )
|
||||
{
|
||||
MapbaseGameLog_Record( "command" );
|
||||
}
|
||||
|
||||
static ConCommand mapbase_game_log_record("mapbase_game_log_record", CC_Mapbase_GameLogRecord, "Records game data to %mapname%_log_%number%." );
|
||||
|
||||
void MapbaseGameLog_CVarToggle( IConVar *var, const char *pOldString, float flOldValue )
|
||||
{
|
||||
if (mapbase_game_log_on_autosave.GetBool())
|
||||
{
|
||||
// Create the game logger ent
|
||||
CMapbaseGameLogger::GetGameLoggerEnt();
|
||||
}
|
||||
}
|
||||
#endif
|
@ -17,10 +17,13 @@
|
||||
#ifdef DISCORD_RPC
|
||||
#include "discord_rpc.h"
|
||||
#include <time.h>
|
||||
#include "c_world.h"
|
||||
#endif
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "c_playerresource.h"
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
|
||||
#endif
|
||||
|
||||
@ -448,6 +451,35 @@ void MapbaseRPC_UpdateSteam( int iType, const char *pMapName )
|
||||
#endif
|
||||
|
||||
#ifdef DISCORD_RPC
|
||||
void MapbaseRPC_GetDiscordMapInfo( char *pDetails, size_t iSize, const char *pMapName )
|
||||
{
|
||||
if (!pMapName)
|
||||
pMapName = "N/A";
|
||||
|
||||
// Say we're in the main menu if it's a background map
|
||||
if (engine->IsLevelMainMenuBackground())
|
||||
{
|
||||
Q_snprintf( pDetails, iSize, "Main Menu (%s)", pMapName );
|
||||
}
|
||||
else
|
||||
{
|
||||
C_World *pWorld = GetClientWorldEntity();
|
||||
if ( pWorld && pWorld->m_iszChapterTitle[0] != '\0' )
|
||||
{
|
||||
// Show the chapter title first
|
||||
const char *pChapterTitle = g_pVGuiLocalize->FindAsUTF8( pWorld->m_iszChapterTitle );
|
||||
if (!pChapterTitle || pChapterTitle[0] == '\0')
|
||||
pChapterTitle = pWorld->m_iszChapterTitle;
|
||||
|
||||
Q_snprintf( pDetails, iSize, "%s (%s)", pChapterTitle, pMapName );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( pDetails, iSize, "%s", pMapName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapbaseRPC_GetDiscordParameters( DiscordRichPresence &discordPresence, int iType, const char *pMapName )
|
||||
{
|
||||
static char details[128];
|
||||
@ -469,10 +501,7 @@ void MapbaseRPC_GetDiscordParameters( DiscordRichPresence &discordPresence, int
|
||||
Q_strncpy( details, pMetadata->m_iszRPCDetails, sizeof(details) );
|
||||
else
|
||||
{
|
||||
if (engine->IsLevelMainMenuBackground())
|
||||
Q_snprintf( details, sizeof(details), "Main Menu (%s)", pMapName ? pMapName : "N/A" );
|
||||
else
|
||||
Q_snprintf( details, sizeof(details), "%s", pMapName ? pMapName : "N/A" );
|
||||
MapbaseRPC_GetDiscordMapInfo( details, sizeof(details), pMapName );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -489,15 +518,7 @@ void MapbaseRPC_GetDiscordParameters( DiscordRichPresence &discordPresence, int
|
||||
case RPCSTATE_LEVEL_INIT:
|
||||
default:
|
||||
{
|
||||
// Say we're in the main menu if it's a background map
|
||||
if (engine->IsLevelMainMenuBackground())
|
||||
{
|
||||
Q_snprintf( details, sizeof(details), "Main Menu (%s)", pMapName ? pMapName : "N/A" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( details, sizeof(details), "%s", pMapName ? pMapName : "N/A" );
|
||||
}
|
||||
MapbaseRPC_GetDiscordMapInfo( details, sizeof(details), pMapName );
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,8 @@ ConVar mapbase_load_actbusy("mapbase_load_actbusy", "1", FCVAR_ARCHIVE, "Should
|
||||
#endif
|
||||
|
||||
#ifdef GAME_DLL
|
||||
extern void MapbaseGameLog_Init();
|
||||
|
||||
extern void ParseCustomActbusyFile(const char *file);
|
||||
|
||||
extern bool LoadResponseSystemFile(const char *scriptfile);
|
||||
@ -203,6 +205,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
virtual void LevelInitPostEntity()
|
||||
{
|
||||
MapbaseGameLog_Init();
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void LevelShutdownPreEntity()
|
||||
{
|
||||
// How would we make sure they don't last between maps?
|
||||
|
@ -170,7 +170,7 @@ float4 main( PS_INPUT i ) : COLOR
|
||||
float4 stretchColor = tex2D( StretchSampler, i.baseTexCoordDetailTexCoord.xy );
|
||||
|
||||
// Apply wrinkle blend to only RGB. Alpha comes from the base texture
|
||||
baseColor.rgb = flTextureAmount * baseColor + flWrinkleAmount * wrinkleColor + flStretchAmount * stretchColor;
|
||||
baseColor.rgb = flTextureAmount * baseColor.rgb + flWrinkleAmount * wrinkleColor.rgb + flStretchAmount * stretchColor.rgb;
|
||||
#endif
|
||||
|
||||
#if DETAILTEXTURE
|
||||
@ -235,7 +235,7 @@ float4 main( PS_INPUT i ) : COLOR
|
||||
envMapColor = (ENV_MAP_SCALE *
|
||||
lerp(1, fFresnelRanges, g_EnvMapFresnel.x) *
|
||||
lerp(fEnvMapMask, 1-fEnvMapMask, g_fInvertPhongMask)) *
|
||||
texCUBE( EnvmapSampler, vReflect ) *
|
||||
texCUBE( EnvmapSampler, vReflect ).xyz *
|
||||
g_EnvmapTint_ShadowTweaks.xyz;
|
||||
}
|
||||
}
|
||||
@ -332,7 +332,7 @@ float4 main( PS_INPUT i ) : COLOR
|
||||
float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, vEyeDir.xyz ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y;
|
||||
diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo * g_SelfIllumScaleBiasExpBrightness.w, baseColor.a * saturate( flSelfIllumFresnel ) );
|
||||
#else
|
||||
float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoordDetailTexCoord.xy );
|
||||
float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoordDetailTexCoord.xy ).xyz;
|
||||
vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl );
|
||||
diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo, vSelfIllumMask );
|
||||
#endif
|
||||
|
@ -192,7 +192,7 @@ float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMod
|
||||
HALF3 NormalizeWithCubemap( sampler normalizeSampler, HALF3 input )
|
||||
{
|
||||
// return texCUBE( normalizeSampler, input ) * 2.0f - 1.0f;
|
||||
return texCUBE( normalizeSampler, input );
|
||||
return texCUBE( normalizeSampler, input ).xyz;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -209,6 +209,13 @@ HALF4 EnvReflect( sampler envmapSampler,
|
||||
}
|
||||
*/
|
||||
|
||||
// Vectorized smoothstep for doing three smoothsteps at once. Used by uberlight
|
||||
float3 smoothstep3( float3 edge0, float3 edge1, float3 OneOverWidth, float3 x )
|
||||
{
|
||||
x = saturate((x - edge0) * OneOverWidth); // Scale, bias and saturate x to the range of zero to one
|
||||
return x*x*(3-2*x); // Evaluate polynomial
|
||||
}
|
||||
|
||||
float CalcWaterFogAlpha( const float flWaterZ, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ, const float flFogOORange )
|
||||
{
|
||||
#if 0
|
||||
|
@ -116,7 +116,7 @@ float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const floa
|
||||
float3 fOut = float3( fResult, fResult, fResult );
|
||||
if ( bDoLightingWarp )
|
||||
{
|
||||
fOut = 2.0f * tex1D( lightWarpSampler, fResult );
|
||||
fOut = 2.0f * tex1D( lightWarpSampler, fResult ).xyz;
|
||||
}
|
||||
|
||||
return fOut;
|
||||
@ -146,7 +146,7 @@ float3 PixelShaderGetLightVector( const float3 worldPos, PixelShaderLightInfo cL
|
||||
}
|
||||
else
|
||||
{
|
||||
return normalize( cLightInfo[nLightIndex].pos - worldPos );
|
||||
return normalize( cLightInfo[nLightIndex].pos.xyz - worldPos );
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +181,7 @@ void SpecularAndRimTerms( const float3 vWorldNormal, const float3 vLightDir, con
|
||||
|
||||
// Optionally warp as function of scalar specular and fresnel
|
||||
if ( bDoSpecularWarp )
|
||||
specularLighting *= tex2D( specularWarpSampler, float2(specularLighting.x, fFresnel) ); // Sample at { (L.R)^k, fresnel }
|
||||
specularLighting *= tex2D( specularWarpSampler, float2(specularLighting.x, fFresnel) ).xyz; // Sample at { (L.R)^k, fresnel }
|
||||
|
||||
specularLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L
|
||||
specularLighting *= color; // Modulate with light color
|
||||
@ -286,19 +286,19 @@ float3 PixelShaderDoLightingLinear( const float3 worldPos, const float3 worldNor
|
||||
if ( nNumLights > 0 )
|
||||
{
|
||||
linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.x, worldPos, worldNormal, NormalizeSampler,
|
||||
cLightInfo[0].pos, cLightInfo[0].color, bHalfLambert,
|
||||
cLightInfo[0].pos.xyz, cLightInfo[0].color.xyz, bHalfLambert,
|
||||
bDoAmbientOcclusion, fAmbientOcclusion,
|
||||
bDoLightingWarp, lightWarpSampler );
|
||||
if ( nNumLights > 1 )
|
||||
{
|
||||
linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.y, worldPos, worldNormal, NormalizeSampler,
|
||||
cLightInfo[1].pos, cLightInfo[1].color, bHalfLambert,
|
||||
cLightInfo[1].pos.xyz, cLightInfo[1].color.xyz, bHalfLambert,
|
||||
bDoAmbientOcclusion, fAmbientOcclusion,
|
||||
bDoLightingWarp, lightWarpSampler );
|
||||
if ( nNumLights > 2 )
|
||||
{
|
||||
linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.z, worldPos, worldNormal, NormalizeSampler,
|
||||
cLightInfo[2].pos, cLightInfo[2].color, bHalfLambert,
|
||||
cLightInfo[2].pos.xyz, cLightInfo[2].color.xyz, bHalfLambert,
|
||||
bDoAmbientOcclusion, fAmbientOcclusion,
|
||||
bDoLightingWarp, lightWarpSampler );
|
||||
if ( nNumLights > 3 )
|
||||
|
@ -1715,13 +1715,15 @@ void DrawLightmappedGeneric_DX9(CBaseVSShader *pShader, IMaterialVar** params,
|
||||
{
|
||||
bool hasFlashlight = pShader->UsingFlashlight( params );
|
||||
|
||||
ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" );
|
||||
|
||||
if ( !IsX360() && !r_flashlight_version2.GetInt() )
|
||||
{
|
||||
DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr );
|
||||
return;
|
||||
}
|
||||
|
||||
DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr );
|
||||
//ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" );
|
||||
//
|
||||
//if ( !IsX360() && !r_flashlight_version2.GetInt() )
|
||||
//{
|
||||
// DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr );
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr );
|
||||
}
|
@ -992,18 +992,18 @@ void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamic
|
||||
CBasePerMaterialContextData **pContextDataPtr )
|
||||
|
||||
{
|
||||
ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" );
|
||||
//ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" );
|
||||
|
||||
bool bHasFlashlight = pShader->UsingFlashlight( params );
|
||||
if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetBool() ) )
|
||||
{
|
||||
DrawSkin_DX9_Internal( pShader, params, pShaderAPI,
|
||||
pShaderShadow, false, info, vertexCompression, pContextDataPtr++ );
|
||||
if ( pShaderShadow )
|
||||
{
|
||||
pShader->SetInitialShadowState( );
|
||||
}
|
||||
}
|
||||
//if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetBool() ) )
|
||||
//{
|
||||
// DrawSkin_DX9_Internal( pShader, params, pShaderAPI,
|
||||
// pShaderShadow, false, info, vertexCompression, pContextDataPtr++ );
|
||||
// if ( pShaderShadow )
|
||||
// {
|
||||
// pShader->SetInitialShadowState( );
|
||||
// }
|
||||
//}
|
||||
DrawSkin_DX9_Internal( pShader, params, pShaderAPI,
|
||||
pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr );
|
||||
}
|
||||
|
@ -187,10 +187,10 @@ BEGIN_VS_SHADER( SDK_UnlitGeneric, "Help for SDK_UnlitGeneric" )
|
||||
VertexLitGeneric_DX9_Vars_t vars;
|
||||
SetupVars( vars );
|
||||
|
||||
ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" );
|
||||
//ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" );
|
||||
|
||||
bool bNewFlashlightPath = IsX360() || ( r_flashlight_version2.GetInt() != 0 );
|
||||
if ( ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && !bNewFlashlightPath && pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass
|
||||
//bool bNewFlashlightPath = IsX360() || ( r_flashlight_version2.GetInt() != 0 );
|
||||
if ( ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && /*!bNewFlashlightPath &&*/ pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass
|
||||
{
|
||||
Draw( false );
|
||||
}
|
||||
|
@ -487,10 +487,10 @@ END_SHADER_PARAMS
|
||||
|
||||
SHADER_DRAW
|
||||
{
|
||||
ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" );
|
||||
//ConVarRef r_flashlight_version2 = ConVarRef( "r_flashlight_version2" );
|
||||
|
||||
bool bHasFlashlight = UsingFlashlight( params );
|
||||
if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) )
|
||||
if ( bHasFlashlight /*&& ( IsX360() || r_flashlight_version2.GetInt() )*/ )
|
||||
{
|
||||
DrawPass( params, pShaderAPI, pShaderShadow, false, vertexCompression );
|
||||
SHADOW_STATE
|
||||
|
@ -139,10 +139,6 @@ enum
|
||||
|
||||
STATIC_PROP_NO_SELF_SHADOWING = 0x80, // disable self shadowing in vrad
|
||||
|
||||
#ifdef MAPBASE
|
||||
STATIC_PROP_OVERRIDE_PROPDATA = 0x100,
|
||||
#endif
|
||||
|
||||
STATIC_PROP_WC_MASK = 0xd8, // all flags settable in hammer (?)
|
||||
};
|
||||
|
||||
|
@ -59,6 +59,7 @@ void InitMaterialSystem( const char *materialBaseDirPath, CreateInterfaceFn file
|
||||
LoadMaterialSystemInterface( fileSystemFactory );
|
||||
MaterialSystem_Config_t config;
|
||||
g_pMaterialSystem->OverrideConfig( config, false );
|
||||
g_pMaterialSystem->ModInit();
|
||||
}
|
||||
|
||||
void ShutdownMaterialSystem( )
|
||||
|
@ -84,9 +84,15 @@ inline bool SideHasCubemapAndWasntManuallyReferenced( int iSide )
|
||||
return s_aCubemapSideData[iSide].bHasEnvMapInMaterial && !s_aCubemapSideData[iSide].bManuallyPickedByAnEnvCubemap;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
char* g_pParallaxObbStrs[MAX_MAP_CUBEMAPSAMPLES];
|
||||
void Cubemap_InsertSample( const Vector& origin, int size, char* pParallaxObbStr = "" )
|
||||
{
|
||||
g_pParallaxObbStrs[g_nCubemapSamples] = pParallaxObbStr;
|
||||
#else
|
||||
void Cubemap_InsertSample( const Vector& origin, int size )
|
||||
{
|
||||
#endif
|
||||
dcubemapsample_t *pSample = &g_CubemapSamples[g_nCubemapSamples];
|
||||
pSample->origin[0] = ( int )origin[0];
|
||||
pSample->origin[1] = ( int )origin[1];
|
||||
@ -529,7 +535,11 @@ static void GeneratePatchedName( const char *pMaterialName, const PatchInfo_t &i
|
||||
//-----------------------------------------------------------------------------
|
||||
// Patches the $envmap for a material and all its dependents, returns true if any patching happened
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture, const char *pParallaxObbMatrix = "" )
|
||||
#else
|
||||
static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture )
|
||||
#endif
|
||||
{
|
||||
// Do *NOT* patch the material if there is an $envmap specified and it's not 'env_cubemap'
|
||||
|
||||
@ -547,7 +557,11 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||
const char *pDependentMaterial = FindDependentMaterial( pMaterialName, &pDependentMaterialVar );
|
||||
if ( pDependentMaterial )
|
||||
{
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture, pParallaxObbMatrix );
|
||||
#else
|
||||
bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture );
|
||||
#endif
|
||||
}
|
||||
|
||||
// If we have neither to patch, we're done
|
||||
@ -558,7 +572,11 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||
char pPatchedMaterialName[1024];
|
||||
GeneratePatchedName( pMaterialName, info, true, pPatchedMaterialName, 1024 );
|
||||
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
MaterialPatchInfo_t pPatchInfo[6];
|
||||
#else
|
||||
MaterialPatchInfo_t pPatchInfo[2];
|
||||
#endif
|
||||
int nPatchCount = 0;
|
||||
if ( bShouldPatchEnvCubemap )
|
||||
{
|
||||
@ -568,6 +586,31 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||
++nPatchCount;
|
||||
}
|
||||
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
// Parallax cubemap matrix
|
||||
CUtlVector<char *> matRowList;
|
||||
if (pParallaxObbMatrix[0] != '\0')
|
||||
{
|
||||
V_SplitString( pParallaxObbMatrix, ";", matRowList );
|
||||
|
||||
pPatchInfo[nPatchCount].m_pKey = "$envMapParallax";
|
||||
pPatchInfo[nPatchCount].m_pValue = "1";
|
||||
++nPatchCount;
|
||||
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB1";
|
||||
pPatchInfo[nPatchCount].m_pValue = matRowList[0];
|
||||
++nPatchCount;
|
||||
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB2";
|
||||
pPatchInfo[nPatchCount].m_pValue = matRowList[1];
|
||||
++nPatchCount;
|
||||
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB3";
|
||||
pPatchInfo[nPatchCount].m_pValue = matRowList[2];
|
||||
++nPatchCount;
|
||||
pPatchInfo[nPatchCount].m_pKey = "$envMapOrigin";
|
||||
pPatchInfo[nPatchCount].m_pValue = matRowList[3];
|
||||
++nPatchCount;
|
||||
}
|
||||
#endif
|
||||
|
||||
char pDependentPatchedMaterialName[1024];
|
||||
if ( bDependentMaterialPatched )
|
||||
{
|
||||
@ -579,7 +622,14 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||
++nPatchCount;
|
||||
}
|
||||
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_INSERT );
|
||||
|
||||
// Clean up parallax stuff
|
||||
matRowList.PurgeAndDeleteElements();
|
||||
#else
|
||||
CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_REPLACE );
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -598,7 +648,11 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||
// default (skybox) cubemap into this file so the cubemap doesn't have the pink checkerboard at
|
||||
// runtime before they run buildcubemaps.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3], int cubemapIndex )
|
||||
#else
|
||||
static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3] )
|
||||
#endif
|
||||
{
|
||||
// Don't make cubemap tex infos for nodes
|
||||
if ( originalTexInfo == TEXINFO_NODE )
|
||||
@ -630,6 +684,15 @@ static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3] )
|
||||
char pGeneratedTexDataName[1024];
|
||||
GeneratePatchedName( pMaterialName, info, true, pGeneratedTexDataName, 1024 );
|
||||
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
// Append origin info if this cubemap has a parallax OBB
|
||||
char originAppendedString[1024] = "";
|
||||
if (g_pParallaxObbStrs[cubemapIndex][0] != '\0')
|
||||
{
|
||||
Q_snprintf(originAppendedString, 1024, "%s;[%d %d %d]", g_pParallaxObbStrs[cubemapIndex], origin[0], origin[1], origin[2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make sure the texdata doesn't already exist.
|
||||
int nTexDataID = FindTexData( pGeneratedTexDataName );
|
||||
bool bHasTexData = (nTexDataID != -1);
|
||||
@ -641,7 +704,11 @@ static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3] )
|
||||
|
||||
// Hook the texture into the material and all dependent materials
|
||||
// but if no hooking was necessary, exit out
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName, originAppendedString ) )
|
||||
#else
|
||||
if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName ) )
|
||||
#endif
|
||||
return originalTexInfo;
|
||||
|
||||
// Store off the name of the cubemap that we need to create since we successfully patched
|
||||
@ -731,7 +798,11 @@ void Cubemap_FixupBrushSidesMaterials( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin, cubemapID );
|
||||
#else
|
||||
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin );
|
||||
#endif
|
||||
if ( pSide->pMapDisp )
|
||||
{
|
||||
pSide->pMapDisp->face.texinfo = pSide->texinfo;
|
||||
@ -947,7 +1018,11 @@ void Cubemap_AttachDefaultCubemapToSpecularSides( void )
|
||||
Assert( pSide->texinfo == pSide->pMapDisp->face.texinfo );
|
||||
}
|
||||
#endif
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin, iCubemap );
|
||||
#else
|
||||
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin );
|
||||
#endif
|
||||
if ( pSide->pMapDisp )
|
||||
{
|
||||
pSide->pMapDisp->face.texinfo = pSide->texinfo;
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include "materialsub.h"
|
||||
#include "fgdlib/fgdlib.h"
|
||||
#include "manifest.h"
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
#include "matrixinvert.h"
|
||||
#endif
|
||||
|
||||
#ifdef VSVMFIO
|
||||
#include "VmfImport.h"
|
||||
@ -1618,9 +1621,16 @@ ChunkFileResult_t CMapFile::LoadEntityCallback(CChunkFile *pFile, int nParam)
|
||||
if( ( g_nDXLevel == 0 ) || ( g_nDXLevel >= 70 ) )
|
||||
{
|
||||
const char *pSideListStr = ValueForKey( mapent, "sides" );
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
char *pParallaxObbStr = ValueForKey( mapent, "parallaxobb" );
|
||||
#endif
|
||||
int size;
|
||||
size = IntForKey( mapent, "cubemapsize" );
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
Cubemap_InsertSample( mapent->origin, size, pParallaxObbStr );
|
||||
#else
|
||||
Cubemap_InsertSample( mapent->origin, size );
|
||||
#endif
|
||||
Cubemap_SaveBrushSides( pSideListStr );
|
||||
}
|
||||
// clear out this entity
|
||||
@ -1628,6 +1638,88 @@ ChunkFileResult_t CMapFile::LoadEntityCallback(CChunkFile *pFile, int nParam)
|
||||
return(ChunkFile_Ok);
|
||||
}
|
||||
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
//
|
||||
// parallax_obb brushes are removed after the transformation matrix is found and saved into
|
||||
// the entity's data (ent will be removed after data transferred to patched materials)
|
||||
//
|
||||
if (!strcmp("parallax_obb", pClassName))
|
||||
{
|
||||
matrix3x4_t obbMatrix, invObbMatrix;
|
||||
SetIdentityMatrix(obbMatrix);
|
||||
SetIdentityMatrix(invObbMatrix);
|
||||
|
||||
// Get corner and its 3 edges (scaled, local x, y, and z axes)
|
||||
mapbrush_t *brush = &mapbrushes[mapent->firstbrush];
|
||||
Vector corner, x, y, z;
|
||||
|
||||
// Find first valid winding (with these whiles, if not enough valid windings then identity matrix is passed through to vmts)
|
||||
int i = 0;
|
||||
while (i < brush->numsides)
|
||||
{
|
||||
winding_t* wind = brush->original_sides[i].winding;
|
||||
if (!wind)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
corner = wind->p[0];
|
||||
y = wind->p[1] - corner;
|
||||
z = wind->p[3] - corner;
|
||||
x = CrossProduct(y, z).Normalized();
|
||||
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip second valid winding (opposite face from first, unusable for finding Z's length)
|
||||
while (i < brush->numsides)
|
||||
{
|
||||
winding_t* wind = brush->original_sides[i].winding;
|
||||
if (!wind)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
||||
// Find third valid winding
|
||||
while (i < brush->numsides)
|
||||
{
|
||||
winding_t* wind = brush->original_sides[i].winding;
|
||||
if (!wind)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find length of x
|
||||
// Start with diagonal, then scale x by the projection of diag onto x
|
||||
Vector diag = wind->p[0] - wind->p[2];
|
||||
x *= abs(DotProduct(diag, x));
|
||||
|
||||
// Build transformation matrix (what is needed to turn a [0,0,0] - [1,1,1] cube into this brush)
|
||||
MatrixSetColumn(x, 0, obbMatrix);
|
||||
MatrixSetColumn(y, 1, obbMatrix);
|
||||
MatrixSetColumn(z, 2, obbMatrix);
|
||||
MatrixSetColumn(corner, 3, obbMatrix);
|
||||
|
||||
//find inverse (we need the world to local matrix, "transformationmatrix" is kind of a misnomer)
|
||||
MatrixInversion(obbMatrix, invObbMatrix);
|
||||
break;
|
||||
}
|
||||
|
||||
char szMatrix[1024];
|
||||
Q_snprintf(szMatrix, 1024, "[%f %f %f %f];[%f %f %f %f];[%f %f %f %f]", invObbMatrix[0][0], invObbMatrix[0][1], invObbMatrix[0][2], invObbMatrix[0][3], invObbMatrix[1][0], invObbMatrix[1][1], invObbMatrix[1][2], invObbMatrix[1][3], invObbMatrix[2][0], invObbMatrix[2][1], invObbMatrix[2][2], invObbMatrix[2][3]);
|
||||
SetKeyValue(mapent, "transformationmatrix", szMatrix);
|
||||
|
||||
return (ChunkFile_Ok);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !strcmp( "test_sidelist", pClassName ) )
|
||||
{
|
||||
ConvertSideList(mapent, "sides");
|
||||
@ -2615,6 +2707,30 @@ bool LoadMapFile( const char *pszFileName )
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
// Fill out parallax obb matrix array
|
||||
for (int i = 0; i < g_nCubemapSamples; i++)
|
||||
{
|
||||
if (g_pParallaxObbStrs[i][0] != '\0')
|
||||
{
|
||||
entity_t* obbEnt = EntityByName(g_pParallaxObbStrs[i]);
|
||||
g_pParallaxObbStrs[i] = ValueForKey(obbEnt, "transformationmatrix");
|
||||
}
|
||||
}
|
||||
|
||||
// Remove parallax_obb entities (in a nice slow linear search)
|
||||
for (int i = 0; i < g_MainMap->num_entities; i++)
|
||||
{
|
||||
entity_t* mapent = &g_MainMap->entities[i];
|
||||
const char *pClassName = ValueForKey( mapent, "classname" );
|
||||
if ( !strcmp( "parallax_obb", pClassName ) )
|
||||
{
|
||||
mapent->numbrushes = 0;
|
||||
mapent->epairs = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((eResult == ChunkFile_Ok) || (eResult == ChunkFile_EOF))
|
||||
{
|
||||
// Update the overlay/side list(s).
|
||||
|
@ -102,6 +102,7 @@ isstaticprop_ret IsStaticProp( studiohdr_t* pHdr )
|
||||
if (!(pHdr->flags & STUDIOHDR_FLAGS_STATIC_PROP))
|
||||
return RET_FAIL_NOT_MARKED_STATIC_PROP;
|
||||
|
||||
#ifndef MAPBASE
|
||||
// If it's got a propdata section in the model's keyvalues, it's not allowed to be a prop_static
|
||||
KeyValues *modelKeyValues = new KeyValues(pHdr->pszName());
|
||||
if ( StudioKeyValues( pHdr, modelKeyValues ) )
|
||||
@ -117,6 +118,7 @@ isstaticprop_ret IsStaticProp( studiohdr_t* pHdr )
|
||||
}
|
||||
}
|
||||
modelKeyValues->deleteThis();
|
||||
#endif
|
||||
|
||||
return RET_VALID;
|
||||
}
|
||||
@ -166,11 +168,7 @@ bool LoadStudioModel( char const* pModelName, char const* pEntityType, CUtlBuffe
|
||||
}
|
||||
|
||||
isstaticprop_ret isStaticProp = IsStaticProp(pHdr);
|
||||
#ifdef MAPBASE
|
||||
if ( isStaticProp != RET_VALID && strcmp(pEntityType, "prop_static_override") != 0 )
|
||||
#else
|
||||
if ( isStaticProp != RET_VALID )
|
||||
#endif
|
||||
{
|
||||
if ( isStaticProp == RET_FAIL_NOT_MARKED_STATIC_PROP )
|
||||
{
|
||||
@ -244,11 +242,7 @@ CPhysCollide* ComputeConvexHull( studiohdr_t* pStudioHdr )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Add, find collision model in cache
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef MAPBASE
|
||||
static CPhysCollide* GetCollisionModel( char const* pModelName, bool bOverridePropdata = false )
|
||||
#else
|
||||
static CPhysCollide* GetCollisionModel( char const* pModelName )
|
||||
#endif
|
||||
{
|
||||
// Convert to a common string
|
||||
char* pTemp = (char*)_alloca(strlen(pModelName) + 1);
|
||||
@ -271,11 +265,7 @@ static CPhysCollide* GetCollisionModel( char const* pModelName )
|
||||
|
||||
// Load the studio model file
|
||||
CUtlBuffer buf;
|
||||
#ifdef MAPBASE
|
||||
if (!LoadStudioModel(pModelName, bOverridePropdata ? "prop_static_override" : "prop_static", buf))
|
||||
#else
|
||||
if (!LoadStudioModel(pModelName, "prop_static", buf))
|
||||
#endif
|
||||
{
|
||||
Warning("Error loading studio model \"%s\"!\n", pModelName );
|
||||
|
||||
@ -486,11 +476,7 @@ static bool ComputeLightingOrigin( StaticPropBuild_t const& build, Vector& light
|
||||
static void AddStaticPropToLump( StaticPropBuild_t const& build )
|
||||
{
|
||||
// Get the collision model
|
||||
#ifdef MAPBASE
|
||||
CPhysCollide* pConvexHull = GetCollisionModel( build.m_pModelName, (build.m_Flags & STATIC_PROP_OVERRIDE_PROPDATA) > 0 );
|
||||
#else
|
||||
CPhysCollide* pConvexHull = GetCollisionModel( build.m_pModelName );
|
||||
#endif
|
||||
if (!pConvexHull)
|
||||
return;
|
||||
|
||||
@ -602,11 +588,7 @@ void EmitStaticProps()
|
||||
for ( i = 0; i < num_entities; ++i)
|
||||
{
|
||||
char* pEntity = ValueForKey(&entities[i], "classname");
|
||||
#ifdef MAPBASE
|
||||
if (!strncmp(pEntity, "prop_static", 11) || !strcmp(pEntity, "static_prop"))
|
||||
#else
|
||||
if (!strcmp(pEntity, "static_prop") || !strcmp(pEntity, "prop_static"))
|
||||
#endif
|
||||
{
|
||||
StaticPropBuild_t build;
|
||||
|
||||
@ -639,14 +621,6 @@ void EmitStaticProps()
|
||||
build.m_Flags |= STATIC_PROP_SCREEN_SPACE_FADE;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
//if (IntForKey(&entities[i], "override_propdata") == 1)
|
||||
if (!strcmp(pEntity + 11, "_override"))
|
||||
{
|
||||
build.m_Flags |= STATIC_PROP_OVERRIDE_PROPDATA;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *pKey = ValueForKey( &entities[i], "fadescale" );
|
||||
if ( pKey && pKey[0] )
|
||||
{
|
||||
|
@ -153,6 +153,13 @@ int FindMiptex (const char *name)
|
||||
{
|
||||
textureref[i].flags |= SURF_NOLIGHT;
|
||||
}
|
||||
#ifdef MAPBASE
|
||||
// handle Slammin-inspired %compileNoShadows%
|
||||
else if ( ( propVal = GetMaterialVar( matID, "%compileNoShadows" ) ) && StringIsTrue( propVal ) )
|
||||
{
|
||||
textureref[i].flags |= SURF_NOSHADOWS;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
// HANDLE ALL OF THE STUFF THAT IS RENDERED WITH THE MATERIAL THAT IS ON IT.
|
||||
|
@ -43,7 +43,11 @@ qboolean noshare;
|
||||
qboolean nosubdiv;
|
||||
qboolean notjunc;
|
||||
qboolean noopt;
|
||||
#ifdef MAPBASE
|
||||
qboolean noleaktest;
|
||||
#else
|
||||
qboolean leaktest;
|
||||
#endif
|
||||
qboolean verboseentities;
|
||||
qboolean dumpcollide = false;
|
||||
qboolean g_bLowPriority = false;
|
||||
@ -85,182 +89,6 @@ int entity_num;
|
||||
|
||||
node_t *block_nodes[BLOCKS_SPACE+2][BLOCKS_SPACE+2];
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Manifest stuff
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlVector<const char *> g_szManifestFiles;
|
||||
bool g_bManifestVerbose = true; // Change to false when testing is over
|
||||
|
||||
#define ManifestMsg(msg, ...) g_bManifestVerbose ? Msg(msg, __VA_ARGS__) : NULL
|
||||
#define ManifestWarning(msg, ...) g_bManifestVerbose ? Warning(msg, __VA_ARGS__) : NULL
|
||||
|
||||
void SetManifestFile(char const *file)
|
||||
{
|
||||
if (g_pFileSystem->FileExists( file ))
|
||||
{
|
||||
Msg("Manifest file: %s\n", file);
|
||||
g_szManifestFiles.AddToTail(file);
|
||||
}
|
||||
}
|
||||
|
||||
void ZipDirectory(const char *dir, const char *relative, IZip *package, int *filecount)
|
||||
{
|
||||
ManifestMsg(" MANIFEST: Mounting directory \"%s\"\n", dir);
|
||||
|
||||
FileFindHandle_t handle = NULL;
|
||||
const char *file = g_pFullFileSystem->FindFirst(dir, &handle);
|
||||
|
||||
// Prevents us from packaging the folder itself
|
||||
//if (file)
|
||||
// file = g_pFullFileSystem->FindNext(handle);
|
||||
|
||||
while (file)
|
||||
{
|
||||
// Don't use hidden files/folders
|
||||
if (file[0] != '.')
|
||||
{
|
||||
char subdir[MAX_PATH];
|
||||
Q_strncpy(subdir, dir, strlen(dir) - 1); // Remove wildcard
|
||||
Q_ComposeFileName(subdir, file, subdir, sizeof(subdir));
|
||||
|
||||
char subrelative[MAX_PATH];
|
||||
Q_strncpy(subrelative, relative, sizeof(subrelative));
|
||||
Q_ComposeFileName(subrelative, file, subrelative, sizeof(subrelative));
|
||||
|
||||
if (g_pFullFileSystem->FindIsDirectory(handle))
|
||||
{
|
||||
// Append wildcard
|
||||
Q_ComposeFileName(subdir, "*", subdir, sizeof(subdir));
|
||||
|
||||
// Mount subdirectory
|
||||
ZipDirectory(subdir, subrelative, package, filecount);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mount file
|
||||
ManifestMsg(" MANIFEST: File \"%s\" packed into BSP at \"%s\"\n", subdir, subrelative);
|
||||
*filecount++;
|
||||
AddFileToPak(package, subrelative, subdir);
|
||||
}
|
||||
}
|
||||
|
||||
file = g_pFullFileSystem->FindNext(handle);
|
||||
}
|
||||
g_pFullFileSystem->FindClose(handle);
|
||||
}
|
||||
|
||||
void ParseManifestFile()
|
||||
{
|
||||
if (g_szManifestFiles.Count() == 0)
|
||||
return;
|
||||
|
||||
Msg("Starting pack manifest with %i files\n", g_szManifestFiles.Count());
|
||||
|
||||
int totalfilecount = 0;
|
||||
|
||||
for (int i = 0; i < g_szManifestFiles.Count(); i++)
|
||||
{
|
||||
FileHandle_t manifestfile = g_pFileSystem->Open( g_szManifestFiles[i], "rb" );
|
||||
if (!manifestfile)
|
||||
{
|
||||
Warning("Manifest file \"%s\" cannot be read!\n", g_szManifestFiles[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
//FileHandle_t curfile;
|
||||
bool curfile;
|
||||
char buf[1024];
|
||||
char *scan;
|
||||
int filecount = 0;
|
||||
bool fullpath = false;
|
||||
while ( CmdLib_FGets( buf, sizeof( buf ), manifestfile ) )
|
||||
{
|
||||
scan = buf;
|
||||
|
||||
// Check if it's an actual path or just relative
|
||||
fullpath = (scan[0] == '#');
|
||||
if (fullpath)
|
||||
scan += 1;
|
||||
else
|
||||
{
|
||||
char file[128];
|
||||
Q_strncpy(file, scan, sizeof(file));
|
||||
char path[_MAX_PATH];
|
||||
Q_ExtractFilePath(source, path, sizeof(path));
|
||||
sprintf(scan, "%s%s", path, file);
|
||||
}
|
||||
|
||||
bool inquotes = (scan[0] == '"');
|
||||
int namelength;
|
||||
if (inquotes)
|
||||
{
|
||||
scan += 1;
|
||||
namelength = strcspn( scan, "\"" );
|
||||
}
|
||||
else
|
||||
{
|
||||
namelength = strcspn( scan, " \t" );
|
||||
}
|
||||
|
||||
char filename[FILENAME_MAX];
|
||||
Q_strncpy(filename, scan, namelength + 1);
|
||||
|
||||
scan += (namelength + inquotes);
|
||||
scan += strspn(scan, " \t");
|
||||
|
||||
// Remove any quotes in the internal path.
|
||||
// The fact they're actually optional in the second path is irrelevant.
|
||||
if (scan[0] == '"')
|
||||
{
|
||||
scan[0] = '\0';
|
||||
if (scan[strlen(scan) - 1] == '"')
|
||||
scan[strlen(scan) - 1] = '\0';
|
||||
}
|
||||
|
||||
curfile = g_pFileSystem->FileExists(filename);
|
||||
if (curfile)
|
||||
{
|
||||
// Assume internal file is a directory if no extension
|
||||
if (Q_GetFileExtension(scan) == NULL)
|
||||
Q_ComposeFileName(scan, filename, scan, sizeof(filename));
|
||||
|
||||
ManifestMsg(" MANIFEST: File \"%s\" packed into BSP at \"%s\"\n", filename, scan);
|
||||
filecount++;
|
||||
AddFileToPak(GetPakFile(), scan, filename);
|
||||
}
|
||||
else if (g_pFullFileSystem->IsDirectory(filename))
|
||||
{
|
||||
// Append wildcard
|
||||
if (!Q_strstr(filename, "*"))
|
||||
Q_ComposeFileName(filename, "*", filename, sizeof(filename));
|
||||
|
||||
// Internal path must be a directory
|
||||
if (scan[0] == NULL || Q_GetFileExtension(scan) == NULL)
|
||||
ZipDirectory(filename, scan, GetPakFile(), &filecount);
|
||||
else
|
||||
Warning("\n MANIFEST WARNING: Directory \"%s\" tried to pack to a file!\nIf you are not trying to package a directory to the BSP, add an extension to \"%s\".\nIf you are trying to package a directory, remove the extension from \"%s\".\n\n", filename, filename, scan);
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning(" MANIFEST WARNING: File \"%s\" does not exist!\n", filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (filecount > 0)
|
||||
ManifestMsg("%i file(s) packed from manifest %s\n", filecount, g_szManifestFiles[i]);
|
||||
else
|
||||
ManifestWarning("*** No files zipped from manifest %s!\n ***", g_szManifestFiles[i]);
|
||||
|
||||
totalfilecount += filecount;
|
||||
|
||||
g_pFileSystem->Close( manifestfile );
|
||||
}
|
||||
|
||||
Msg("%i total file(s) packed from manifests\n", totalfilecount);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Assign occluder areas (must happen *after* the world model is processed)
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -473,7 +301,11 @@ void ProcessWorldModel (void)
|
||||
Warning( ("**** leaked ****\n") );
|
||||
leaked = true;
|
||||
LeakFile (tree);
|
||||
#ifdef MAPBASE
|
||||
if (!noleaktest)
|
||||
#else
|
||||
if (leaktest)
|
||||
#endif
|
||||
{
|
||||
Warning( ("--- MAP LEAKED ---\n") );
|
||||
exit (0);
|
||||
@ -1178,11 +1010,19 @@ int RunVBSP( int argc, char **argv )
|
||||
Msg ("microvolume = %f\n", microvolume);
|
||||
i++;
|
||||
}
|
||||
#ifdef MAPBASE
|
||||
else if (!Q_stricmp(argv[i], "-noleaktest"))
|
||||
{
|
||||
Msg ("noleaktest = true\n");
|
||||
noleaktest = true;
|
||||
}
|
||||
#else
|
||||
else if (!Q_stricmp(argv[i], "-leaktest"))
|
||||
{
|
||||
Msg ("leaktest = true\n");
|
||||
leaktest = true;
|
||||
}
|
||||
#endif
|
||||
else if (!Q_stricmp(argv[i], "-verboseentities"))
|
||||
{
|
||||
Msg ("verboseentities = true\n");
|
||||
@ -1316,19 +1156,10 @@ int RunVBSP( int argc, char **argv )
|
||||
EnableFullMinidumps( true );
|
||||
}
|
||||
#ifdef MAPBASE
|
||||
else if ( !Q_stricmp( argv[i], "-deletecubemaps" ) )
|
||||
else if ( !Q_stricmp( argv[i], "-nodefaultcubemap" ) )
|
||||
{
|
||||
g_bNoDefaultCubemaps = true;
|
||||
}
|
||||
else if ( !Q_stricmp( argv[i], "-manifest" ) )
|
||||
{
|
||||
SetManifestFile(argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
else if ( !Q_stricmp( argv[i], "-manifest_verbose" ) )
|
||||
{
|
||||
g_bManifestVerbose = true;
|
||||
}
|
||||
#endif
|
||||
else if (argv[i][0] == '-')
|
||||
{
|
||||
@ -1445,13 +1276,6 @@ int RunVBSP( int argc, char **argv )
|
||||
ThreadSetDefault ();
|
||||
numthreads = 1; // multiple threads aren't helping...
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Any additional files to pack?
|
||||
char ManifestFile[512];
|
||||
_snprintf( ManifestFile, sizeof(ManifestFile), "%s_zipmanifest.txt", source );
|
||||
SetManifestFile(ManifestFile);
|
||||
#endif
|
||||
|
||||
// Setup the logfile.
|
||||
char logFile[512];
|
||||
_snprintf( logFile, sizeof(logFile), "%s.log", source );
|
||||
@ -1568,11 +1392,6 @@ int RunVBSP( int argc, char **argv )
|
||||
AddBufferToPak( GetPakFile(), "stale.txt", "stale", strlen( "stale" ) + 1, false );
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Is this a good place for this?
|
||||
ParseManifestFile();
|
||||
#endif
|
||||
|
||||
LoadMapFile (name);
|
||||
WorldVertexTransitionFixup();
|
||||
if( ( g_nDXLevel == 0 ) || ( g_nDXLevel >= 70 ) )
|
||||
|
@ -34,6 +34,12 @@ class CUtlBuffer;
|
||||
// this will output glview files for the given brushmodel. Brushmodel 1 is the world, 2 is the first brush entity, etc.
|
||||
#define DEBUG_BRUSHMODEL 0
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Activates compiler code for parallax corrected cubemaps
|
||||
// https://developer.valvesoftware.com/wiki/Parallax_Corrected_Cubemaps
|
||||
#define PARALLAX_CORRECTED_CUBEMAPS 1
|
||||
#endif
|
||||
|
||||
struct portal_t;
|
||||
struct node_t;
|
||||
|
||||
@ -607,7 +613,12 @@ void SaveVertexNormals( void );
|
||||
|
||||
//=============================================================================
|
||||
// cubemap.cpp
|
||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||
extern char* g_pParallaxObbStrs[MAX_MAP_CUBEMAPSAMPLES];
|
||||
void Cubemap_InsertSample( const Vector& origin, int size, char* pParallaxObbStr );
|
||||
#else
|
||||
void Cubemap_InsertSample( const Vector& origin, int size );
|
||||
#endif
|
||||
void Cubemap_CreateDefaultCubemaps( void );
|
||||
void Cubemap_SaveBrushSides( const char *pSideListStr );
|
||||
void Cubemap_FixupBrushSidesMaterials( void );
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
$Macro OUTBINNAME "mapbase_vbsp"
|
||||
$Macro OUTBINNAME "vbsp"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
$Macro OUTBINNAME "mapbase_vrad_dll"
|
||||
$Macro OUTBINNAME "vrad_dll"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
$Macro OUTBINNAME "mapbase_vrad"
|
||||
$Macro OUTBINNAME "vrad"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
$Macro OUTBINNAME "mapbase_vvis_dll"
|
||||
$Macro OUTBINNAME "vvis_dll"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
$Macro OUTBINNAME "mapbase_vvis"
|
||||
$Macro OUTBINNAME "vvis"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user