Mapbase v4.2

- Added keyvalue to use random bounds on logic_timer to limit AddToTimer/SubtractFromTimer inputs (suggested by White_Red_Dragons)
- Fixed inconsistent env_projectedtexture state on save/load
- Added code to allow skybox to use a direct entity handle instead of a stored origin and angles in order to take advantage of entity interpolation while moving (less jittering)
- Moved map-specific file manifest parsing to happen after other entities are created (highly experimental)
- Added various misc. code improvements related to debug build and MP branch
- Fixed some VScript ammo type-related code forgotten in the previous update
- Added more VScript functions to CBaseAnimating, including pose parameter functions and the ability to look up bones and get bone position
- Added more origin and angles functions for VScript (suggested by krassell)
This commit is contained in:
Blixibon 2020-07-01 19:32:49 +00:00
parent bc6a35a99c
commit f636089003
24 changed files with 380 additions and 120 deletions

View File

@ -12,7 +12,8 @@ that is always open to contributions.
Whenever you contribute to the Mapbase repository, you must keep in mind that any contributions
made could be deployed to all mods utilizing Mapbase, which can include everything from high-profile
Steam mods to amateur HL2 maps.
Steam mods to amateur HL2 maps. Many contributions can also end up being available in both SP and MP
if the contributions are not obviously exclusive to one of the two.
All contributions must follow the following rules:
@ -24,9 +25,8 @@ All contributions must follow the following rules:
* All content in a contribution must be either already legally open-source or done with the
full permission of the contribution's original creator(s).
* A code contribution should typically follow Mapbase's preprocessor conventions unless it's a massive
feature which makes fundamental changes to several different parts of the code (e.g. reductor's VScript PR).
When following these standards, all changes should be nested within "#ifdef MAPBASE", "#ifndef MAPBASE", etc.
* Code contributions are not obliged to follow Mapbase's preprocessor conventions (e.g. #ifdef MAPBASE),
although it's acceptable.
If your contribution is accepted, you may be listed in Mapbase's credits:
https://github.com/mapbase-source/source-sdk-2013/wiki/Mapbase-Credits#Contributors

View File

@ -282,6 +282,9 @@ BEGIN_DATADESC( C_ClientRagdoll )
END_DATADESC()
BEGIN_ENT_SCRIPTDESC( C_BaseAnimating, C_BaseEntity, "Animating models client-side" )
#ifdef MAPBASE_VSCRIPT
DEFINE_SCRIPTFUNC_NAMED( ScriptGetPoseParameter, "GetPoseParameter", "Get the specified pose parameter's value" )
#endif
DEFINE_SCRIPTFUNC_NAMED( ScriptSetPoseParameter, "SetPoseParameter", "Set the specified pose parameter to the specified value" )
DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" )
END_SCRIPTDESC();
@ -1408,6 +1411,18 @@ float C_BaseAnimating::ClampCycle( float flCycle, bool isLooping )
return flCycle;
}
#ifdef MAPBASE_VSCRIPT
float C_BaseAnimating::ScriptGetPoseParameter( const char* szName )
{
CStudioHdr* pHdr = GetModelPtr();
if (pHdr == NULL)
return 0.0f;
int iPoseParam = LookupPoseParameter( pHdr, szName );
return GetPoseParameter( iPoseParam );
}
#endif
void C_BaseAnimating::ScriptSetPoseParameter(const char* szName, float fValue)
{
CStudioHdr* pHdr = GetModelPtr();

View File

@ -446,6 +446,9 @@ public:
virtual bool IsViewModel() const;
#ifdef MAPBASE_VSCRIPT
float ScriptGetPoseParameter(const char* szName);
#endif
void ScriptSetPoseParameter(const char* szName, float fValue);
protected:
// View models scale their attachment positions to account for FOV. To get the unmodified

View File

@ -192,6 +192,7 @@ BEGIN_RECV_TABLE_NOBASE( CPlayerLocalData, DT_Local )
RecvPropVector(RECVINFO(m_skybox3d.origin)),
#ifdef MAPBASE
RecvPropVector(RECVINFO(m_skybox3d.angles)),
RecvPropEHandle(RECVINFO(m_skybox3d.skycamera)),
RecvPropInt( RECVINFO( m_skybox3d.skycolor ), 0, RecvProxy_IntToColor32 ),
#endif
RecvPropInt(RECVINFO(m_skybox3d.area)),

View File

@ -396,6 +396,10 @@ protected:
void Enable3dSkyboxFog( void );
void DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostRender, ITexture *pRenderTarget, ITexture *pDepthTarget );
#ifdef MAPBASE
void CalculateSkyAngles( const QAngle &angAngles );
#endif
sky3dparams_t * PreRender3dSkyboxWorld( SkyboxVisibility_t nSkyboxVisible );
sky3dparams_t *m_pSky3dParams;
@ -4969,59 +4973,40 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR
// Skybox angle support.
//
// If any of the angles aren't 0, do the rotation code.
if (m_pSky3dParams->angles.GetX() != 0 ||
m_pSky3dParams->angles.GetY() != 0 ||
m_pSky3dParams->angles.GetZ() != 0)
if (m_pSky3dParams->skycamera)
{
// Unfortunately, it's not as simple as "angles += m_pSky3dParams->angles".
// This stuff took a long time to figure out. I'm glad I got it working.
// Re-use the x coordinate to determine if we shuld do this with angles
if (m_pSky3dParams->angles.GetX() != 0)
{
CalculateSkyAngles( m_pSky3dParams->skycamera->GetAbsAngles() );
}
// First, create a matrix for the sky's angles.
matrix3x4_t matSkyAngles;
AngleMatrix( m_pSky3dParams->angles, matSkyAngles );
// The code in between the lines below was mostly lifted from projected texture screenspace code and was a huge lifesaver.
// The comments are my attempt at explaining the little I understand of what's going on here.
// ----------------------------------------------------------------------
// These are the vectors that would eventually become our final angle directions.
Vector vecSkyForward, vecSkyRight, vecSkyUp;
// Get vectors from our original angles.
Vector vPlayerForward, vPlayerRight, vPlayerUp;
AngleVectors( angles, &vPlayerForward, &vPlayerRight, &vPlayerUp );
// Transform them from our sky angles matrix and put the results in those vectors we declared earlier.
VectorTransform( vPlayerForward, matSkyAngles, vecSkyForward );
VectorTransform( vPlayerRight, matSkyAngles, vecSkyRight );
VectorTransform( vPlayerUp, matSkyAngles, vecSkyUp );
// Normalize them.
VectorNormalize( vecSkyForward );
VectorNormalize( vecSkyRight );
VectorNormalize( vecSkyUp );
// Now do a bit of quaternion magic and apply that to our original angles.
// This works perfectly, so I'm not gonna touch it.
Quaternion quat;
BasisToQuaternion( vecSkyForward, vecSkyRight, vecSkyUp, quat );
QuaternionAngles( quat, angles );
// End of code mostly lifted from projected texture screenspace stuff
// ----------------------------------------------------------------------
// Now just rotate our origin with that matrix.
// We create a copy of the origin since VectorRotate doesn't want in1 to be the same variable as the destination.
VectorRotate(Vector(origin), matSkyAngles, origin);
VectorAdd( origin, m_pSky3dParams->skycamera->GetAbsOrigin(), origin );
}
#endif
else
{
if (m_pSky3dParams->angles.GetX() != 0 ||
m_pSky3dParams->angles.GetY() != 0 ||
m_pSky3dParams->angles.GetZ() != 0)
{
CalculateSkyAngles( m_pSky3dParams->angles.Get() );
}
VectorAdd( origin, m_pSky3dParams->origin, origin );
}
#else
VectorAdd( origin, m_pSky3dParams->origin, origin );
#endif
// BUGBUG: Fix this!!! We shouldn't need to call setup vis for the sky if we're connecting
// the areas. We'd have to mark all the clusters in the skybox area in the PVS of any
// cluster with sky. Then we could just connect the areas to do our vis.
//m_bOverrideVisOrigin could hose us here, so call direct
#ifdef MAPBASE
render->ViewSetupVis( false, 1, m_pSky3dParams->skycamera ? &m_pSky3dParams->skycamera->GetAbsOrigin() : &m_pSky3dParams->origin.Get() );
#else
render->ViewSetupVis( false, 1, &m_pSky3dParams->origin.Get() );
#endif
render->Push3DView( (*this), m_ClearFlags, pRenderTarget, GetFrustum(), pDepthTarget );
// Store off view origin and angles
@ -5079,6 +5064,55 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR
#endif
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CSkyboxView::CalculateSkyAngles( const QAngle &angAngles )
{
// Unfortunately, it's not as simple as "angles += m_pSky3dParams->angles".
// This stuff took a long time to figure out. I'm glad I got it working.
// First, create a matrix for the sky's angles.
matrix3x4_t matSkyAngles;
AngleMatrix( angAngles, matSkyAngles );
// The code in between the lines below was mostly lifted from projected texture screenspace code and was a huge lifesaver.
// The comments are my attempt at explaining the little I understand of what's going on here.
// ----------------------------------------------------------------------
// These are the vectors that would eventually become our final angle directions.
Vector vecSkyForward, vecSkyRight, vecSkyUp;
// Get vectors from our original angles.
Vector vPlayerForward, vPlayerRight, vPlayerUp;
AngleVectors( angles, &vPlayerForward, &vPlayerRight, &vPlayerUp );
// Transform them from our sky angles matrix and put the results in those vectors we declared earlier.
VectorTransform( vPlayerForward, matSkyAngles, vecSkyForward );
VectorTransform( vPlayerRight, matSkyAngles, vecSkyRight );
VectorTransform( vPlayerUp, matSkyAngles, vecSkyUp );
// Normalize them.
VectorNormalize( vecSkyForward );
VectorNormalize( vecSkyRight );
VectorNormalize( vecSkyUp );
// Now do a bit of quaternion magic and apply that to our original angles.
// This works perfectly, so I'm not gonna touch it.
Quaternion quat;
BasisToQuaternion( vecSkyForward, vecSkyRight, vecSkyUp, quat );
QuaternionAngles( quat, angles );
// End of code mostly lifted from projected texture screenspace stuff
// ----------------------------------------------------------------------
// Now just rotate our origin with that matrix.
// We create a copy of the origin since VectorRotate doesn't want in1 to be the same variable as the destination.
VectorRotate(Vector(origin), matSkyAngles, origin);
}
#endif
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------

View File

@ -94,7 +94,7 @@ BEGIN_DATADESC( CSkyCamera )
DEFINE_INPUTFUNC( FIELD_COLOR32, "SetSkyColor", InputSetSkyColor ),
DEFINE_THINKFUNC( Update ),
DEFINE_THINKFUNC( UpdateThink ),
#endif
END_DATADESC()
@ -150,16 +150,17 @@ void CSkyCamera::Spawn( void )
if (HasSpawnFlags(SF_SKY_MASTER))
g_hActiveSkybox = this;
if (HasSpawnFlags(SF_SKY_START_UPDATING) && GetCurrentSkyCamera() == this)
if (HasSpawnFlags(SF_SKY_START_UPDATING))
{
SetThink( &CSkyCamera::Update );
SetCameraEntityMode();
SetThink( &CSkyCamera::UpdateThink );
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
}
// Must be absolute now that the sky_camera can be parented
m_skyboxData.origin = GetAbsOrigin();
if (m_bUseAnglesForSky)
m_skyboxData.angles = GetAbsAngles();
else
{
SetCameraPositionMode();
}
#else
m_skyboxData.origin = GetLocalOrigin();
#endif
@ -218,63 +219,104 @@ bool CSkyCamera::AcceptInput( const char *szInputName, CBaseEntity *pActivator,
if (g_hActiveSkybox == this)
{
// Most inputs require an update
Update();
DoUpdate( true );
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Update sky position mid-game
// Purpose:
//-----------------------------------------------------------------------------
void CSkyCamera::Update()
void CSkyCamera::SetCameraEntityMode()
{
m_skyboxData.skycamera = this;
// Ensure the viewrender knows whether this should be using angles
if (m_bUseAnglesForSky)
m_skyboxData.angles.SetX( 1 );
else
m_skyboxData.angles.SetX( 0 );
}
void CSkyCamera::SetCameraPositionMode()
{
// Must be absolute now that the sky_camera can be parented
m_skyboxData.skycamera = NULL;
m_skyboxData.origin = GetAbsOrigin();
if (m_bUseAnglesForSky)
m_skyboxData.angles = GetAbsAngles();
}
//-----------------------------------------------------------------------------
// Purpose: Update sky position mid-game
//-----------------------------------------------------------------------------
bool CSkyCamera::DoUpdate( bool bUpdateData )
{
// Now that sky camera updating uses an entity handle directly transmitted to the client,
// this thinking is only used to update area and other parameters
// Getting into another area is unlikely, but if it's not expensive, I guess it's okay.
m_skyboxData.area = engine->GetArea( m_skyboxData.origin );
int area = engine->GetArea( m_skyboxData.origin );
if (m_skyboxData.area != area)
{
m_skyboxData.area = area;
bUpdateData = true;
}
if ( m_bUseAngles )
{
AngleVectors( GetAbsAngles(), &m_skyboxData.fog.dirPrimary.GetForModify() );
m_skyboxData.fog.dirPrimary.GetForModify() *= -1.0f;
Vector fogForward;
AngleVectors( GetAbsAngles(), &fogForward );
fogForward *= -1.0f;
if ( m_skyboxData.fog.dirPrimary.Get() != fogForward )
{
m_skyboxData.fog.dirPrimary = fogForward;
bUpdateData = true;
}
}
#ifdef MAPBASE_MP
// Updates client data, this completely ignores m_pOldSkyCamera
CBasePlayer *pPlayer = NULL;
for (int i = 1; i <= gpGlobals->maxClients; i++)
if (bUpdateData)
{
pPlayer = UTIL_PlayerByIndex(i);
if (pPlayer)
pPlayer->m_Local.m_skybox3d.CopyFrom(m_skyboxData);
// Updates client data, this completely ignores m_pOldSkyCamera
CBasePlayer *pPlayer = NULL;
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
pPlayer = UTIL_PlayerByIndex(i);
if (pPlayer)
pPlayer->m_Local.m_skybox3d.CopyFrom(m_skyboxData);
}
}
#else
// Updates client data, this completely ignores m_pOldSkyCamera
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
if (pPlayer)
{
pPlayer->m_Local.m_skybox3d.CopyFrom(m_skyboxData);
}
#endif
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
// Needed for entity interpolation
SetSimulationTime( gpGlobals->curtime );
return bUpdateData;
}
void CSkyCamera::UpdateThink()
{
if (DoUpdate())
{
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
}
else
{
SetNextThink( gpGlobals->curtime + 0.2f );
}
}
void CSkyCamera::InputForceUpdate( inputdata_t &inputdata )
{
Update();
// Updates client data, this completely ignores m_pOldSkyCamera
CBasePlayer *pPlayer = NULL;
for (int i = 1; i <= gpGlobals->maxClients; i++)
if (m_skyboxData.skycamera == NULL)
{
pPlayer = UTIL_PlayerByIndex( i );
if (pPlayer)
pPlayer->m_Local.m_skybox3d.CopyFrom( m_skyboxData );
m_skyboxData.origin = GetAbsOrigin();
if (m_bUseAnglesForSky)
m_skyboxData.angles = GetAbsAngles();
}
DoUpdate( true );
}
//-----------------------------------------------------------------------------
@ -284,12 +326,18 @@ void CSkyCamera::InputStartUpdating( inputdata_t &inputdata )
{
if (GetCurrentSkyCamera() == this)
{
SetThink( &CSkyCamera::Update );
SetCameraEntityMode();
DoUpdate( true );
SetThink( &CSkyCamera::UpdateThink );
SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
}
// If we become the current sky camera later, remember that we want to update
AddSpawnFlags( SF_SKY_START_UPDATING );
// Must update transmit state so we show up on the client
DispatchUpdateTransmitState();
}
void CSkyCamera::InputStopUpdating( inputdata_t &inputdata )
@ -297,6 +345,10 @@ void CSkyCamera::InputStopUpdating( inputdata_t &inputdata )
SetThink( NULL );
SetNextThink( TICK_NEVER_THINK );
RemoveSpawnFlags( SF_SKY_START_UPDATING );
DispatchUpdateTransmitState();
SetCameraPositionMode();
DoUpdate( true );
}
//-----------------------------------------------------------------------------

View File

@ -50,7 +50,14 @@ public:
#ifdef MAPBASE
bool AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID );
void Update();
int UpdateTransmitState() { return HasSpawnFlags( SF_SKY_START_UPDATING ) ? SetTransmitState( FL_EDICT_ALWAYS ) : BaseClass::UpdateTransmitState(); }
void SetCameraEntityMode();
void SetCameraPositionMode();
bool DoUpdate( bool bUpdateData = false );
void UpdateThink();
void InputForceUpdate( inputdata_t &inputdata );
void InputStartUpdating( inputdata_t &inputdata );
void InputStopUpdating( inputdata_t &inputdata );

View File

@ -289,6 +289,12 @@ BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentAngles, "GetAttachmentAngles", "Get the attachement id's angles as a p,y,r vector" )
#ifdef MAPBASE_VSCRIPT
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentMatrix, "GetAttachmentMatrix", "Get the attachement id's matrix transform" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetPoseParameter, "GetPoseParameter", "Get the specified pose parameter's value" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetPoseParameter, "SetPoseParameter", "Set the specified pose parameter to the specified value" )
DEFINE_SCRIPTFUNC( LookupBone, "Get the named bone id" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoneTransform, "GetBoneTransform", "Get the transform for the specified bone" )
DEFINE_SCRIPTFUNC( Dissolve, "" )
DEFINE_SCRIPTFUNC( Scorch, "Makes the entity darker from scorching" )
#endif
DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" )
DEFINE_SCRIPTFUNC( SetBodygroup, "Sets a bodygroup")
@ -2166,6 +2172,36 @@ HSCRIPT CBaseAnimating::ScriptGetAttachmentMatrix( int iAttachment )
CBaseAnimating::GetAttachment( iAttachment, matrix );
return ScriptCreateMatrixInstance( matrix );
}
float CBaseAnimating::ScriptGetPoseParameter( const char* szName )
{
CStudioHdr* pHdr = GetModelPtr();
if (pHdr == NULL)
return 0.0f;
int iPoseParam = LookupPoseParameter( pHdr, szName );
return GetPoseParameter( iPoseParam );
}
void CBaseAnimating::ScriptSetPoseParameter( const char* szName, float fValue )
{
CStudioHdr* pHdr = GetModelPtr();
if (pHdr == NULL)
return;
int iPoseParam = LookupPoseParameter( pHdr, szName );
SetPoseParameter( pHdr, iPoseParam, fValue );
}
extern matrix3x4_t *ToMatrix3x4( HSCRIPT hMat );
void CBaseAnimating::ScriptGetBoneTransform( int iBone, HSCRIPT hTransform )
{
if (hTransform == NULL)
return;
GetBoneTransform( iBone, *ToMatrix3x4( hTransform ) );
}
#endif
//-----------------------------------------------------------------------------

View File

@ -191,6 +191,10 @@ public:
const Vector& ScriptGetAttachmentAngles(int iAttachment);
#ifdef MAPBASE_VSCRIPT
HSCRIPT ScriptGetAttachmentMatrix(int iAttachment);
float ScriptGetPoseParameter(const char* szName);
void ScriptSetPoseParameter(const char* szName, float fValue);
void ScriptGetBoneTransform( int iBone, HSCRIPT hTransform );
#endif
// These return the attachment in the space of the entity

View File

@ -4419,19 +4419,18 @@ void CBaseCombatCharacter::ScriptEquipWeapon( HSCRIPT hWeapon )
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int CBaseCombatCharacter::ScriptGetAmmoCount( const char *szName ) const
int CBaseCombatCharacter::ScriptGetAmmoCount( int iType ) const
{
return GetAmmoCount( GetAmmoDef()->Index(szName) );
return GetAmmoCount( iType );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CBaseCombatCharacter::ScriptSetAmmoCount( const char *szName, int iCount )
void CBaseCombatCharacter::ScriptSetAmmoCount( int iType, int iCount )
{
int iType = GetAmmoDef()->Index( szName );
if (iType == -1)
{
Warning("\"%s\" is not a valid ammo type\n", szName);
Warning("%i is not a valid ammo type\n", iType);
return;
}

View File

@ -422,8 +422,8 @@ public:
void ScriptEquipWeapon( HSCRIPT hWeapon );
int ScriptGetAmmoCount( const char *szName ) const;
void ScriptSetAmmoCount( const char *szName, int iCount );
int ScriptGetAmmoCount( int iType ) const;
void ScriptSetAmmoCount( int iType, int iCount );
int ScriptRelationType( HSCRIPT pTarget );
int ScriptRelationPriority( HSCRIPT pTarget );

View File

@ -2154,6 +2154,14 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC_NAMED( GetAbsOrigin, "GetOrigin", "" )
DEFINE_SCRIPTFUNC( SetAbsOrigin, "SetAbsOrigin" )
#ifdef MAPBASE_VSCRIPT
DEFINE_SCRIPTFUNC( SetAbsAngles, "SetAbsAngles" )
DEFINE_SCRIPTFUNC( GetLocalOrigin, "GetLocalOrigin" )
DEFINE_SCRIPTFUNC( SetLocalOrigin, "SetLocalOrigin" )
DEFINE_SCRIPTFUNC( GetLocalAngles, "GetLocalAngles" )
DEFINE_SCRIPTFUNC( SetLocalAngles, "SetLocalAngles" )
#endif
DEFINE_SCRIPTFUNC_NAMED( ScriptSetOrigin, "SetOrigin", "" )
@ -2221,6 +2229,17 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC_NAMED( ScriptAddOutput, "AddOutput", "Add an output" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValue, "GetKeyValue", "Get a keyvalue" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorVector, "GetColorVector", "Get the render color as a vector" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorR, "GetColorR", "Get the render color's R value" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorG, "GetColorG", "Get the render color's G value" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetColorB, "GetColorB", "Get the render color's B value" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAlpha, "GetAlpha", "Get the render color's alpha value" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorVector, "SetColorVector", "Set the render color as a vector" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorR, "SetColorR", "Set the render color's R value" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorG, "SetColorG", "Set the render color's G value" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetColorB, "SetColorB", "Set the render color's B value" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetAlpha, "SetAlpha", "Set the render color's alpha value" )
DEFINE_SCRIPTFUNC( GetSpawnFlags, "Get spawnflags" )
DEFINE_SCRIPTFUNC( AddSpawnFlags, "Add spawnflag(s)" )
DEFINE_SCRIPTFUNC( RemoveSpawnFlags, "Remove spawnflag(s)" )
@ -9616,6 +9635,22 @@ const char *CBaseEntity::ScriptGetKeyValue( const char *pszKeyName )
GetKeyValue( pszKeyName, szValue, sizeof(szValue) );
return szValue;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const Vector& CBaseEntity::ScriptGetColorVector()
{
static Vector vecColor;
vecColor.Init( m_clrRender.GetR(), m_clrRender.GetG(), m_clrRender.GetB() );
return vecColor;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptSetColorVector( const Vector& vecColor )
{
SetRenderColor( vecColor.x, vecColor.y, vecColor.z );
}
#endif

View File

@ -2020,6 +2020,17 @@ public:
bool ScriptAddOutput( const char *pszOutputName, const char *pszTarget, const char *pszAction, const char *pszParameter, float flDelay, int iMaxTimes );
const char *ScriptGetKeyValue( const char *pszKeyName );
const Vector& ScriptGetColorVector();
int ScriptGetColorR() { return m_clrRender.GetR(); }
int ScriptGetColorG() { return m_clrRender.GetG(); }
int ScriptGetColorB() { return m_clrRender.GetB(); }
int ScriptGetAlpha() { return m_clrRender.GetA(); }
void ScriptSetColorVector( const Vector& vecColor );
void ScriptSetColorR( int iVal ) { SetRenderColorR( iVal ); }
void ScriptSetColorG( int iVal ) { SetRenderColorG( iVal ); }
void ScriptSetColorB( int iVal ) { SetRenderColorB( iVal ); }
void ScriptSetAlpha( int iVal ) { SetRenderColorA( iVal ); }
#endif
string_t m_iszVScripts;

View File

@ -607,7 +607,7 @@ CBaseEntity *CGlobalEntityList::FindEntityProcedural( const char *szName, CBaseE
CBaseEntity *pEntity = FindEntityProcedural(UTIL_VarArgs("!%s", name), pSearchingEntity, pActivator, pCaller);
if (pEntity && pEntity->IsNPC())
{
char *target = (Q_strstr(pName, ":") + 1);
const char *target = (Q_strstr(pName, ":") + 1);
if (target[0] != '!')
target = UTIL_VarArgs("!%s", target);

View File

@ -398,14 +398,19 @@ void CEnvProjectedTexture::Spawn( void )
m_flLightHorFOV = m_flLightFOV;
}
m_bState = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_STARTON ) != 0 );
m_bAlwaysUpdate = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_ALWAYSUPDATE ) != 0 );
BaseClass::Spawn();
}
#endif
void CEnvProjectedTexture::Activate( void )
{
#ifndef MAPBASE // Putting this in Activate() breaks projected textures which start off or don't start always updating in savegames. Moved to Spawn() instead
m_bState = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_STARTON ) != 0 );
m_bAlwaysUpdate = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_ALWAYSUPDATE ) != 0 );
#endif
SetThink( &CEnvProjectedTexture::InitialThink );
SetNextThink( gpGlobals->curtime + 0.1f );

View File

@ -412,6 +412,9 @@ public:
int m_iUseRandomTime;
float m_flLowerRandomBound;
float m_flUpperRandomBound;
#ifdef MAPBASE
bool m_bUseBoundsForTimerInputs;
#endif
// methods
void ResetTimer( void );
@ -430,6 +433,10 @@ BEGIN_DATADESC( CTimerEntity )
DEFINE_FIELD( m_bUpDownState, FIELD_BOOLEAN ),
#ifdef MAPBASE
DEFINE_KEYFIELD( m_bUseBoundsForTimerInputs, FIELD_BOOLEAN, "UseBoundsForTimerInputs" ),
#endif
// Inputs
DEFINE_INPUTFUNC( FIELD_FLOAT, "RefireTime", InputRefireTime ),
DEFINE_INPUTFUNC( FIELD_VOID, "FireTimer", InputFireTimer ),
@ -650,7 +657,24 @@ void CTimerEntity::InputAddToTimer( inputdata_t &inputdata )
// Add time to timer
float flNextThink = GetNextThink();
#ifdef MAPBASE
if (m_bUseBoundsForTimerInputs)
{
// Make sure it's not above our min or max bounds
if (flNextThink - gpGlobals->curtime > m_flUpperRandomBound)
return;
flNextThink += inputdata.value.Float();
flNextThink = clamp( flNextThink - gpGlobals->curtime, m_flLowerRandomBound, m_flUpperRandomBound );
SetNextThink( gpGlobals->curtime + flNextThink );
}
else
{
SetNextThink( flNextThink + inputdata.value.Float() );
}
#else
SetNextThink( flNextThink += inputdata.value.Float() );
#endif
}
//-----------------------------------------------------------------------------
@ -665,6 +689,23 @@ void CTimerEntity::InputSubtractFromTimer( inputdata_t &inputdata )
// Subtract time from the timer but don't let the timer go negative
float flNextThink = GetNextThink();
#ifdef MAPBASE
if (m_bUseBoundsForTimerInputs)
{
// Make sure it's not above our min or max bounds
if (flNextThink - gpGlobals->curtime < m_flLowerRandomBound)
return;
flNextThink -= inputdata.value.Float();
flNextThink = clamp( flNextThink - gpGlobals->curtime, m_flLowerRandomBound, m_flUpperRandomBound );
SetNextThink( gpGlobals->curtime + flNextThink );
}
else
{
flNextThink -= inputdata.value.Float();
SetNextThink( (flNextThink <= gpGlobals->curtime) ? gpGlobals->curtime : flNextThink );
}
#else
if ( ( flNextThink - gpGlobals->curtime ) <= inputdata.value.Float() )
{
SetNextThink( gpGlobals->curtime );
@ -673,6 +714,7 @@ void CTimerEntity::InputSubtractFromTimer( inputdata_t &inputdata )
{
SetNextThink( flNextThink -= inputdata.value.Float() );
}
#endif
}
//-----------------------------------------------------------------------------

View File

@ -61,6 +61,7 @@ BEGIN_SEND_TABLE_NOBASE( CPlayerLocalData, DT_Local )
SendPropVector (SENDINFO_STRUCTELEM(m_skybox3d.origin), -1, SPROP_COORD),
#ifdef MAPBASE
SendPropVector (SENDINFO_STRUCTELEM(m_skybox3d.angles), -1, SPROP_COORD),
SendPropEHandle (SENDINFO_STRUCTELEM(m_skybox3d.skycamera)),
SendPropInt (SENDINFO_STRUCTELEM(m_skybox3d.skycolor), 32, (SPROP_COORD|SPROP_UNSIGNED), SendProxy_Color32ToInt),
#endif
SendPropInt (SENDINFO_STRUCTELEM(m_skybox3d.area), 8, SPROP_UNSIGNED ),
@ -128,6 +129,7 @@ BEGIN_SIMPLE_DATADESC( sky3dparams_t )
DEFINE_FIELD( origin, FIELD_VECTOR ),
#ifdef MAPBASE
DEFINE_FIELD( angles, FIELD_VECTOR ),
DEFINE_FIELD( skycamera, FIELD_EHANDLE ),
DEFINE_FIELD( skycolor, FIELD_COLOR32 ),
#endif
DEFINE_FIELD( area, FIELD_INTEGER ),

View File

@ -85,6 +85,11 @@ class CSceneListManager : public CLogicalEntity
DECLARE_CLASS( CSceneListManager, CLogicalEntity );
public:
DECLARE_DATADESC();
#ifdef MAPBASE_VSCRIPT
DECLARE_ENT_SCRIPTDESC();
HSCRIPT ScriptGetScene( int iIndex );
#endif
virtual void Activate( void );
@ -5198,14 +5203,6 @@ HSCRIPT ScriptCreateSceneEntity( const char* pszScene )
return ToHScript( pScene );
}
#ifdef MAPBASE
CON_COMMAND(mapbase_scene_precache, "Just work")
{
DevMsg("Attempting to precache %s...\n", args[1]);
PrecacheInstancedScene(args[1]);
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Used for precaching instanced scenes
// Input : *pszScene -
@ -6069,6 +6066,14 @@ BEGIN_DATADESC( CSceneListManager )
DEFINE_INPUTFUNC( FIELD_VOID, "Shutdown", InputShutdown ),
END_DATADESC()
#ifdef MAPBASE_VSCRIPT
BEGIN_ENT_SCRIPTDESC( CSceneListManager, CBaseEntity, "Stores choreo scenes and cleans them up when a later scene in the list begins playing." )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetScene, "GetScene", "Gets the specified scene index from this manager." )
END_SCRIPTDESC();
#endif
//-----------------------------------------------------------------------------
// Purpose:
@ -6211,6 +6216,19 @@ void CSceneListManager::RemoveScene( int iIndex )
}
}
#ifdef MAPBASE_VSCRIPT
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
HSCRIPT CSceneListManager::ScriptGetScene( int iIndex )
{
if ( iIndex < 0 || iIndex >= SCENE_LIST_MANAGER_MAX_SCENES )
return NULL;
return ToHScript( m_hScenes[iIndex] );
}
#endif
void ReloadSceneFromDisk( CBaseEntity *ent )
{
CSceneEntity *scene = dynamic_cast< CSceneEntity * >( ent );

View File

@ -2288,15 +2288,6 @@ bool CBaseCombatWeapon::DefaultReload( int iClipSize1, int iClipSize2, int iActi
#endif
SendWeaponAnim( iActivity );
#ifdef MAPBASE
// TEMPTEMP
#ifdef CLIENT_DLL
//DevMsg("Client SF from primary attack: %i\n", m_spawnflags);
#else
//DevMsg("Server SF from primary attack: %i\n", m_spawnflags);
#endif
#endif
// Play the player's reload animation
if ( pOwner->IsPlayer() )
{

View File

@ -364,6 +364,7 @@ void MapbaseRPC_Init()
void MapbaseRPC_Shutdown()
{
// Discord RPC
Discord_ClearPresence();
Discord_Shutdown();
// Steam RPC

View File

@ -198,24 +198,25 @@ public:
// Shared Mapbase localization file
g_pVGuiLocalize->AddFile( "resource/mapbase_%language%.txt" );
#endif
}
virtual void LevelInitPostEntity()
{
// Check for a generic "mapname_manifest.txt" file and load it.
if (filesystem->FileExists(AUTOLOADED_MANIFEST_FILE, "GAME") /*&& !FStrEq(name, "closecaption")*/)
if (filesystem->FileExists( AUTOLOADED_MANIFEST_FILE, "GAME" ) /*&& !FStrEq(name, "closecaption")*/)
{
AddManifestFile(AUTOLOADED_MANIFEST_FILE);
AddManifestFile( AUTOLOADED_MANIFEST_FILE );
}
else
{
// Load the generic script instead.
ParseGenericManifest();
}
}
#ifdef GAME_DLL
virtual void LevelInitPostEntity()
{
MapbaseGameLog_Init();
}
#endif
}
virtual void LevelShutdownPreEntity()
{

View File

@ -56,7 +56,7 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMatrix3x4, "matrix3x4_t", "A 3x4 matrix tran
END_SCRIPTDESC();
inline matrix3x4_t *ToMatrix3x4( HSCRIPT hMat ) { return HScriptToClass<CScriptMatrix3x4>( hMat )->GetMatrix(); }
matrix3x4_t *ToMatrix3x4( HSCRIPT hMat ) { return HScriptToClass<CScriptMatrix3x4>( hMat )->GetMatrix(); }
HSCRIPT ScriptCreateMatrixInstance( matrix3x4_t &matrix )
{

View File

@ -102,6 +102,9 @@ struct sky3dparams_t
// Skybox angle support
CNetworkQAngle( angles );
// Skybox entity-based option
CNetworkHandle( CBaseEntity, skycamera );
// Sky clearcolor
CNetworkColor32( skycolor );
#endif

View File

@ -225,7 +225,7 @@ BEGIN_VS_SHADER( SDK_DecalModulate_dx9,
SetFlashLightColorFromState( state, pShaderAPI, 28 );
Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 );
Assert( state.m_pSpotlightTexture >= 0 && state.m_nSpotlightTextureFrame >= 0 );
BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame );
float atten_pos[8];