Merge branch 'develop' into feature/asw-response-system

# Conflicts:
#	sp/src/game/server/server_mapbase.vpc
This commit is contained in:
Blixibon 2021-04-21 16:51:36 -05:00
commit e31c45dee3
94 changed files with 6183 additions and 774 deletions

7
README
View File

@ -40,8 +40,8 @@ or complicated code changes accessible and easy to use for level designers and o
If you believe any content in Mapbase originates from any leak or unauthorized source (from Valve or otherwise), please contact Blixibon immediately.
Mapbase is intended to be usable by everyone, including licensed Source projects and Steam mods. ***
The Alien Swarm SDK was used to backport features and code from newer branches of Source into a Source 2013/Half-Life 2 environment.
Mapbase also implements some of Tony Sergi's code changes from the Source 2007 SDK codebase. Both SDKs are publicly distributed by Valve and are available on Steam.
-- The Alien Swarm SDK was used to backport features and code from newer branches of Source into a Source 2013/Half-Life 2 environment.
-- Mapbase also implements some of Tony Sergi's code changes from the Source 2007 SDK codebase. Both SDKs are publicly distributed by Valve and are available on Steam.
Some of the features backported from the Alien Swarm SDK (e.g. game instructor, particle rain) require assets from later versions of Source in order to work properly.
The required assets have been backported from Alien Swarm and Left 4 Dead for the release build. They are not available in the code repository.
@ -100,11 +100,13 @@ Direct contributions:
- Combine lock hardware on door01_left.mdl created by Kralich (This is asset-based and not reflected in the code)
- npc_vehicledriver fixes provided by CrAzY
- npc_combine cover behavior patches provided by iohnnyboy
- logic_playmovie icon created by URAKOLOUY5 (This is asset-based and not reflected in the code)
== Contributions from samisalreadytaken:
=-- https://github.com/mapbase-source/source-sdk-2013/pull/47 (VScript utility/consistency changes)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/59 (New VScript functions and singletons based on API documentation in later Source/Source 2 games)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/80 (More VScript changes, including support for extremely flexible client/server messaging)
=-- https://github.com/mapbase-source/source-sdk-2013/pull/105 (VScript fixes and optimizations, Vector class extensions, custom convars/commands)
//---------------------------------------------------------------------------------------------------------------------------------------------------
@ -117,6 +119,7 @@ Other sources:
-- https://github.com/ValveSoftware/source-sdk-2013/pull/401 (func_rot_button "Starts locked" flag fix)
-- https://github.com/ValveSoftware/source-sdk-2013/pull/391 (VBSP func_detail smoothing group fix)
-- https://github.com/ValveSoftware/source-sdk-2013/pull/362 (npc_manhack npc_maker fix; Adjusted for formatting and save/restore in Mapbase)
-- https://github.com/Petercov/Source-PlusPlus/commit/ecdf50c48cd31dec4dbdb7fea2d0780e7f0dd8ec (used as a guide for porting the Alien Swarm SDK response system)
- https://github.com/momentum-mod/game/blob/1d066180b3bf74830c51e6914d46c40b0bea1fc2/mp/src/game/server/player.cpp#L6543 (spec_goto fix)
- Poison zombie barnacle crash fix implemented based on a snippet from HL2: Plus posted by Agent Agrimar on Discord (Mapbase makes the barnacle recognize it as poison just like poison headcrabs)
- https://gamebanana.com/skins/172192 (Airboat handling fix; This is asset-based and not reflected in the code)

View File

@ -6,10 +6,11 @@ MAKEFILE_LINK:=$(THISFILE).link
-include $(MAKEFILE_LINK)
$(MAKEFILE_LINK): $(shell which $(CC)) $(THISFILE)
if [ "$(shell printf "$(shell $(CC) -dumpversion)\n8" | sort -Vr | head -1)" = 8 ]; then \
$(COMPILE.cpp) -o gcc9+support.o gcc9+support.c ;\
# depend on CXX so the correct makefile can be selected when the system is updated
$(MAKEFILE_LINK): $(shell which $(CXX)) $(THISFILE) $(SRCROOT)/devtools/gcc9+support.cpp
@ if [ "$(shell printf "$(shell $(CXX) -dumpversion)\n8" | sort -Vr | head -1)" = 8 ]; then \
ln -sf $(MAKEFILE_BASE).default $@ ;\
else \
$(COMPILE.cpp) -o $(SRCROOT)/devtools/gcc9+support.o $(SRCROOT)/devtools/gcc9+support.cpp &&\
ln -sf $(MAKEFILE_BASE).gcc8 $@ ;\
fi

View File

@ -293,6 +293,7 @@ BEGIN_ENT_SCRIPTDESC( C_ClientRagdoll, C_BaseAnimating, "Client-side ragdolls" )
END_SCRIPTDESC();
ScriptHook_t C_BaseAnimating::g_Hook_OnClientRagdoll;
ScriptHook_t C_BaseAnimating::g_Hook_FireEvent;
#endif
BEGIN_ENT_SCRIPTDESC( C_BaseAnimating, C_BaseEntity, "Animating models client-side" )
@ -346,6 +347,13 @@ BEGIN_ENT_SCRIPTDESC( C_BaseAnimating, C_BaseEntity, "Animating models client-si
BEGIN_SCRIPTHOOK( C_BaseAnimating::g_Hook_OnClientRagdoll, "OnClientRagdoll", FIELD_VOID, "Called when this entity turns into a client-side ragdoll." )
DEFINE_SCRIPTHOOK_PARAM( "ragdoll", FIELD_HSCRIPT )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( C_BaseAnimating::g_Hook_FireEvent, "FireEvent", FIELD_BOOLEAN, "Called when handling animation events. Return false to cancel base handling." )
DEFINE_SCRIPTHOOK_PARAM( "origin", FIELD_VECTOR )
DEFINE_SCRIPTHOOK_PARAM( "angles", FIELD_VECTOR )
DEFINE_SCRIPTHOOK_PARAM( "event", FIELD_INTEGER )
DEFINE_SCRIPTHOOK_PARAM( "options", FIELD_CSTRING )
END_SCRIPTHOOK()
#endif
END_SCRIPTDESC();
@ -3651,7 +3659,11 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
flEventCycle,
gpGlobals->curtime );
}
#ifdef MAPBASE_VSCRIPT
if (ScriptHookFireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ) == false)
continue;
#endif
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() );
}
@ -3684,6 +3696,11 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
gpGlobals->curtime );
}
#ifdef MAPBASE_VSCRIPT
if (ScriptHookFireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ) == false)
continue;
#endif
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() );
}
}
@ -3691,6 +3708,26 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
m_flPrevEventCycle = flEventCycle;
}
#ifdef MAPBASE_VSCRIPT
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool C_BaseAnimating::ScriptHookFireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
{
if (m_ScriptScope.IsInitialized() && g_Hook_FireEvent.CanRunInScope(m_ScriptScope))
{
// origin, angles, event, options
ScriptVariant_t args[] = { origin, angles, event, options };
ScriptVariant_t returnValue = true;
g_Hook_FireEvent.Call( m_ScriptScope, &returnValue, args );
return returnValue.m_bool;
}
return true;
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Parses a muzzle effect event and sends it out for drawing
// Input : *options - event parameters in text format

View File

@ -164,6 +164,10 @@ public:
virtual void FireObsoleteEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
virtual const char* ModifyEventParticles( const char* token ) { return token; }
#ifdef MAPBASE_VSCRIPT
bool ScriptHookFireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
#endif
#if defined ( SDK_DLL ) || defined ( HL2MP )
virtual void ResetEventsParity() { m_nPrevResetEventsParity = -1; } // used to force animation events to function on players so the muzzleflashes and other events occur
// so new functions don't have to be made to parse the models like CSS does in ProcessMuzzleFlashEvent
@ -477,6 +481,7 @@ public:
HSCRIPT ScriptBecomeRagdollOnClient();
static ScriptHook_t g_Hook_OnClientRagdoll;
static ScriptHook_t g_Hook_FireEvent;
float ScriptGetPoseParameter(const char* szName);
#endif

View File

@ -451,6 +451,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities
DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelName, "GetModelName", "Returns the name of the model" )
DEFINE_SCRIPTFUNC_NAMED( ScriptStopSound, "StopSound", "Stops a sound from this entity." )
DEFINE_SCRIPTFUNC_NAMED( ScriptEmitSound, "EmitSound", "Plays a sound from this entity." )
DEFINE_SCRIPTFUNC_NAMED( VScriptPrecacheScriptSound, "PrecacheSoundScript", "Precache a sound for later playing." )
DEFINE_SCRIPTFUNC_NAMED( ScriptSoundDuration, "GetSoundDuration", "Returns float duration of the sound. Takes soundname and optional actormodelname." )
@ -472,6 +473,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities
DEFINE_SCRIPTFUNC_NAMED( GetAbsAngles, "GetAngles", "Get entity pitch, yaw, roll as a vector" )
DEFINE_SCRIPTFUNC_NAMED( SetAbsAngles, "SetAngles", "Set entity pitch, yaw, roll" )
DEFINE_SCRIPTFUNC( SetSize, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMins, "GetBoundingMins", "Get a vector containing min bounds, centered on object" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMaxs, "GetBoundingMaxs", "Get a vector containing max bounds, centered on object" )
@ -541,7 +543,13 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities
DEFINE_SCRIPTFUNC_NAMED( IsBaseCombatWeapon, "IsWeapon", "Returns true if this entity is a weapon." )
DEFINE_SCRIPTFUNC( IsWorld, "Returns true if this entity is the world." )
DEFINE_SCRIPTFUNC( SetModel, "Set client-only entity model" )
//DEFINE_SCRIPTFUNC_NAMED( ScriptInitializeAsClientEntity, "InitializeAsClientEntity", "" )
DEFINE_SCRIPTFUNC_NAMED( Remove, "Destroy", "Remove clientside entity" )
DEFINE_SCRIPTFUNC_NAMED( GetEntityIndex, "entindex", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." )
#endif
END_SCRIPTDESC();
@ -1334,6 +1342,15 @@ void C_BaseEntity::Term()
{
g_pScriptVM->RemoveInstance( m_hScriptInstance );
m_hScriptInstance = NULL;
#ifdef MAPBASE_VSCRIPT
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
{
HSCRIPT h = m_ScriptThinkFuncs[i]->m_hfnThink;
if ( h ) g_pScriptVM->ReleaseScript( h );
}
m_ScriptThinkFuncs.PurgeAndDeleteElements();
#endif
}
}

View File

@ -161,6 +161,16 @@ struct thinkfunc_t
int m_nLastThinkTick;
};
#ifdef MAPBASE_VSCRIPT
struct scriptthinkfunc_t
{
int m_nNextThinkTick;
HSCRIPT m_hfnThink;
unsigned short m_iContextHash;
bool m_bNoParam;
};
#endif
#define CREATE_PREDICTED_ENTITY( className ) \
C_BaseEntity::CreatePredictedEntityByName( className, __FILE__, __LINE__ );
@ -390,7 +400,7 @@ public:
#ifdef MAPBASE_VSCRIPT
// "I don't know why but wrapping entindex() works, while calling it directly crashes."
inline int C_BaseEntity::GetEntityIndex() const { return entindex(); }
inline int GetEntityIndex() const { return entindex(); }
#endif
// This works for client-only entities and returns the GetEntryIndex() of the entity's handle,
@ -1173,6 +1183,7 @@ public:
#ifdef MAPBASE_VSCRIPT
const char* ScriptGetModelName( void ) const { return STRING(GetModelName()); }
void ScriptStopSound(const char* soundname);
void ScriptEmitSound(const char* soundname);
float ScriptSoundDuration(const char* soundname, const char* actormodel);
@ -1519,6 +1530,15 @@ protected:
CUtlVector< thinkfunc_t > m_aThinkFunctions;
int m_iCurrentThinkContext;
#ifdef MAPBASE_VSCRIPT
public:
void ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float time );
void ScriptContextThink();
private:
CUtlVector< scriptthinkfunc_t* > m_ScriptThinkFuncs;
public:
#endif
// Object eye position
Vector m_vecViewOffset;

View File

@ -15,7 +15,7 @@
#include "ammodef.h"
#include "vprof.h"
#include "view.h"
#include "vstdlib/ikeyvaluessystem.h"
#include "vstdlib/IKeyValuesSystem.h"
#ifdef MAPBASE
#include "usermessages.h"
#endif
@ -666,7 +666,8 @@ void CIconLesson::UpdateInactive()
CUtlBuffer msg_data;
msg_data.PutChar( 1 );
msg_data.PutString( m_szHudHint.String() );
usermessages->DispatchUserMessage( usermessages->LookupUserMessage( "KeyHintText" ), bf_read( msg_data.Base(), msg_data.TellPut() ) );
bf_read msg( msg_data.Base(), msg_data.TellPut() );
usermessages->DispatchUserMessage( usermessages->LookupUserMessage( "KeyHintText" ), msg );
}
#endif
@ -1039,40 +1040,40 @@ Vector CIconLesson::GetIconTargetPosition( C_BaseEntity *pIconTarget )
#define LESSON_VARIABLE_INIT_SYMBOL( _varEnum, _varName, _varType ) g_n##_varEnum##Symbol = KeyValuesSystem()->GetSymbolForString( #_varEnum );
#define LESSON_SCRIPT_STRING_ADD_TO_MAP( _varEnum, _varName, _varType ) g_NameToTypeMap.Insert( #_varEnum, LESSON_VARIABLE_##_varEnum## );
#define LESSON_SCRIPT_STRING_ADD_TO_MAP( _varEnum, _varName, _varType ) g_NameToTypeMap.Insert( #_varEnum, LESSON_VARIABLE_##_varEnum );
// Create enum value
#define LESSON_VARIABLE_ENUM( _varEnum, _varName, _varType ) LESSON_VARIABLE_##_varEnum##,
#define LESSON_VARIABLE_ENUM( _varEnum, _varName, _varType ) LESSON_VARIABLE_##_varEnum,
// Init info call
#define LESSON_VARIABLE_INIT_INFO_CALL( _varEnum, _varName, _varType ) g_pLessonVariableInfo[ LESSON_VARIABLE_##_varEnum## ].Init_##_varEnum##();
#define LESSON_VARIABLE_INIT_INFO_CALL( _varEnum, _varName, _varType ) g_pLessonVariableInfo[ LESSON_VARIABLE_##_varEnum ].Init_##_varEnum();
// Init info
#define LESSON_VARIABLE_INIT_INFO( _varEnum, _varName, _varType ) \
void Init_##_varEnum##() \
void Init_##_varEnum() \
{ \
iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::##_varName## ); \
iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::_varName ); \
varType = LessonParamTypeFromString( #_varType ); \
}
#define LESSON_VARIABLE_INIT_INFO_BOOL( _varEnum, _varName, _varType ) \
void Init_##_varEnum##() \
void Init_##_varEnum() \
{ \
iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::##_varName## ); \
iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::_varName ); \
varType = FIELD_BOOLEAN; \
}
#define LESSON_VARIABLE_INIT_INFO_EHANDLE( _varEnum, _varName, _varType ) \
void Init_##_varEnum##() \
void Init_##_varEnum() \
{ \
iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::##_varName## ); \
iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::_varName ); \
varType = FIELD_EHANDLE; \
}
#define LESSON_VARIABLE_INIT_INFO_STRING( _varEnum, _varName, _varType ) \
void Init_##_varEnum##() \
void Init_##_varEnum() \
{ \
iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::##_varName## ); \
iOffset = offsetof( CScriptedIconLesson, CScriptedIconLesson::_varName ); \
varType = FIELD_STRING; \
}
@ -1094,15 +1095,15 @@ Vector CIconLesson::GetIconTargetPosition( C_BaseEntity *pIconTarget )
// Process the element action on this variable
#define PROCESS_LESSON_ACTION( _varEnum, _varName, _varType ) \
case LESSON_VARIABLE_##_varEnum##:\
case LESSON_VARIABLE_##_varEnum:\
return ProcessElementAction( pLessonElement->iAction, pLessonElement->bNot, #_varName, _varName, &pLessonElement->szParam, eventParam_float );
#define PROCESS_LESSON_ACTION_EHANDLE( _varEnum, _varName, _varType ) \
case LESSON_VARIABLE_##_varEnum##:\
case LESSON_VARIABLE_##_varEnum:\
return ProcessElementAction( pLessonElement->iAction, pLessonElement->bNot, #_varName, _varName, &pLessonElement->szParam, eventParam_float, eventParam_BaseEntity, eventParam_string );
#define PROCESS_LESSON_ACTION_STRING( _varEnum, _varName, _varType ) \
case LESSON_VARIABLE_##_varEnum##:\
case LESSON_VARIABLE_##_varEnum:\
return ProcessElementAction( pLessonElement->iAction, pLessonElement->bNot, #_varName, &_varName, &pLessonElement->szParam, eventParam_string );
// Init the variable from the script (or a convar)
@ -2957,7 +2958,7 @@ bool CScriptedIconLesson::ProcessElementAction( int iAction, bool bNot, const ch
{
if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() )
{
ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->HealthFraction() ", pchVarName, pchVarName );
ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->HealthFraction() ", pchVarName );
ConColorMsg( CBaseLesson::m_rgbaVerboseName, "... " );
ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() );
ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam );
@ -2969,7 +2970,7 @@ bool CScriptedIconLesson::ProcessElementAction( int iAction, bool bNot, const ch
if ( gameinstructor_verbose.GetInt() > 0 && ShouldShowSpew() )
{
ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->HealthFraction() ", pchVarName, pchVarName );
ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "\t[%s]->HealthFraction() ", pchVarName );
ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f ", pVar->HealthFraction() );
ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, ( bNot ) ? ( ">= [%s] " ) : ( "< [%s] " ), pchParamName->String() );
ConColorMsg( CBaseLesson::m_rgbaVerboseName, "%f\n", fParam );

View File

@ -426,7 +426,7 @@ private:
LessonEvent_t * AddUpdateEvent( void );
private:
static CUtlDict< int, int > CScriptedIconLesson::LessonActionMap;
static CUtlDict< int, int > LessonActionMap;
EHANDLE m_hLocalPlayer;
float m_fOutput;

View File

@ -9,7 +9,7 @@
#include "GameEventListener.h"
#include "vgui_controls/phandle.h"
#include "vgui_controls/PHandle.h"
class CBaseLesson;

View File

@ -0,0 +1,26 @@
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//
//=====================================================================================//
#include "cbase.h"
#include "c_movie_display.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
IMPLEMENT_CLIENTCLASS_DT( C_MovieDisplay, DT_MovieDisplay, CMovieDisplay )
RecvPropBool( RECVINFO( m_bEnabled ) ),
RecvPropBool( RECVINFO( m_bLooping ) ),
RecvPropString( RECVINFO( m_szMovieFilename ) ),
RecvPropString( RECVINFO( m_szGroupName ) ),
END_RECV_TABLE()
C_MovieDisplay::C_MovieDisplay()
{
}
C_MovieDisplay::~C_MovieDisplay()
{
}

View File

@ -0,0 +1,34 @@
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#ifndef C_MOVIE_DISPLAY_H
#define C_MOVIE_DISPLAY_H
#include "cbase.h"
class C_MovieDisplay : public C_BaseEntity
{
public:
DECLARE_CLASS( C_MovieDisplay, C_BaseEntity );
DECLARE_CLIENTCLASS();
C_MovieDisplay();
~C_MovieDisplay();
bool IsEnabled( void ) const { return m_bEnabled; }
bool IsLooping( void ) const { return m_bLooping; }
const char *GetMovieFilename( void ) const { return m_szMovieFilename; }
const char *GetGroupName( void ) const { return m_szGroupName; }
private:
bool m_bEnabled;
bool m_bLooping;
char m_szMovieFilename[128];
char m_szGroupName[128];
};
#endif //C_MOVIE_DISPLAY_H

View File

@ -73,6 +73,27 @@ IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_RopeKeyframe, DT_RopeKeyframe, CRopeKeyframe
RecvPropInt( RECVINFO( m_iParentAttachment ) ),
END_RECV_TABLE()
#ifdef MAPBASE_VSCRIPT
BEGIN_ENT_SCRIPTDESC( C_RopeKeyframe, C_BaseEntity, "The clientside class of move_rope and keyframe_rope" )
DEFINE_SCRIPTFUNC( GetNodePosition, "Gets the position of the specified node index" )
DEFINE_SCRIPTFUNC( GetNumNodes, "Gets the number of nodes available" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetStartEntity, "GetStartEntity", "Gets the rope's start entity" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetEndEntity, "GetEndEntity", "Gets the rope's end entity" )
DEFINE_SCRIPTFUNC( SetupHangDistance, "Sets the rope's hang distance" )
DEFINE_SCRIPTFUNC( SetSlack, "Sets the rope's slack value (extra length)" )
DEFINE_SCRIPTFUNC( GetRopeFlags, "Gets the rope's flags" )
DEFINE_SCRIPTFUNC( SetRopeFlags, "Sets the rope's flags" )
DEFINE_SCRIPTFUNC( SetColorMod, "Sets the rope's color mod value" )
DEFINE_SCRIPTFUNC( ShakeRope, "Shakes the rope with the specified center, radius, and magnitude" )
DEFINE_SCRIPTFUNC( AnyPointsMoved, "Returns true if any points have moved recently" )
END_SCRIPTDESC();
#endif
#define ROPE_IMPULSE_SCALE 20
#define ROPE_IMPULSE_DECAY 0.95
@ -2022,6 +2043,25 @@ bool C_RopeKeyframe::GetAttachment( int number, Vector &origin, QAngle &angles )
return false;
}
#ifdef MAPBASE
const Vector &C_RopeKeyframe::GetNodePosition( int index )
{
int nNodes = m_RopePhysics.NumNodes();
if ( index >= nNodes || nNodes < 2 )
{
Warning( "C_RopeKeyframe::GetNodePosition(): Invalid node index %i (number of nodes is %i)\n", index, nNodes );
return vec3_origin;
}
return m_RopePhysics.GetNode( index )->m_vPredicted;
}
int C_RopeKeyframe::GetNumNodes()
{
return m_RopePhysics.NumNodes();
}
#endif
bool C_RopeKeyframe::AnyPointsMoved()
{
#ifdef MAPBASE

View File

@ -33,6 +33,9 @@ public:
DECLARE_CLASS( C_RopeKeyframe, C_BaseEntity );
DECLARE_CLIENTCLASS();
#ifdef MAPBASE_VSCRIPT
DECLARE_ENT_SCRIPTDESC();
#endif
private:
@ -142,6 +145,11 @@ public:
virtual bool GetAttachment( int number, Vector &origin );
virtual bool GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel );
#ifdef MAPBASE
const Vector &GetNodePosition( int index );
int GetNumNodes();
#endif
private:
void FinishInit( const char *pMaterialName );
@ -166,6 +174,11 @@ private:
void ReceiveMessage( int classID, bf_read &msg );
bool CalculateEndPointAttachment( C_BaseEntity *pEnt, int iAttachment, Vector &vPos, QAngle *pAngles );
#ifdef MAPBASE_VSCRIPT
HSCRIPT ScriptGetStartEntity() { return ToHScript( GetStartEntity() ); }
HSCRIPT ScriptGetEndEntity() { return ToHScript( GetEndEntity() ); }
#endif
private:
// Track which links touched something last frame. Used to prevent wind from gusting on them.

View File

@ -49,6 +49,8 @@ public:
#endif
#ifdef MAPBASE_VSCRIPT
void ClientThink() { ScriptContextThink(); }
// -2 = Use server language
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguageClient != -2 ? m_iScriptLanguageClient : m_iScriptLanguageServer); }
#endif

View File

@ -274,6 +274,8 @@ void ProcessCacheUsedMaterials()
}
}
void VGui_ClearVideoPanels();
// String tables
INetworkStringTable *g_pStringTableParticleEffectNames = NULL;
INetworkStringTable *g_StringTableEffectDispatch = NULL;
@ -1217,6 +1219,8 @@ void CHLClient::Shutdown( void )
g_pSixenseInput = NULL;
#endif
VGui_ClearVideoPanels();
C_BaseAnimating::ShutdownBoneSetupThreadPool();
ClientWorldFactoryShutdown();

View File

@ -32,6 +32,9 @@ $Project
$File "c_postprocesscontroller.cpp"
$File "c_postprocesscontroller.h"
$File "c_env_dof_controller.cpp"
$File "c_movie_display.cpp"
$File "c_movie_display.h"
$File "vgui_movie_display.cpp"
$Folder "Mapbase"
{
@ -58,6 +61,7 @@ $Project
$File "mapbase\c_func_fake_worldportal.cpp"
$File "mapbase\c_func_fake_worldportal.h"
$File "mapbase\c_point_glow.cpp"
$File "mapbase\c_vgui_text_display.cpp"
}
$Folder "HL2 DLL"

View File

@ -5,6 +5,10 @@
//=============================================================================
#include "cbase.h"
#ifdef MAPBASE
#include "proxyentity.h"
#include "materialsystem/imaterialvar.h"
#endif
class C_PropScalable : public C_BaseAnimating
{
@ -194,3 +198,56 @@ void C_PropScalable::GetRenderBounds( Vector &theMins, Vector &theMaxs )
Assert( theMins.IsValid() && theMaxs.IsValid() );
}
#ifdef MAPBASE
ConVar r_coreball_update_sphere_center( "r_coreball_update_sphere_center", "1", FCVAR_NONE, "Allows prop_coreball to update its center to the entity's origin" );
class CCoreBallUpdateMaterialProxy : public CEntityMaterialProxy
{
public:
CCoreBallUpdateMaterialProxy()
{
m_pMaterial = NULL;
m_pSphereCenter = NULL;
}
virtual ~CCoreBallUpdateMaterialProxy()
{
}
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
m_pMaterial = pMaterial;
bool found;
m_pSphereCenter = m_pMaterial->FindVar( "$spherecenter", &found );
if( !found )
{
m_pSphereCenter = NULL;
return false;
}
return true;
}
virtual void OnBind( C_BaseEntity *pC_BaseEntity )
{
if (r_coreball_update_sphere_center.GetBool())
{
const Vector &origin = pC_BaseEntity->GetAbsOrigin();
m_pSphereCenter->SetVecValue( origin.x, origin.y, origin.z );
}
else
{
// Just continuously bind the old hacked value (TODO: Optimize so it's not just assigning the same value constantly?)
m_pSphereCenter->SetVecValue( 2688.0, 12139.0, 5170.0 );
}
}
virtual IMaterial *GetMaterial()
{
return m_pMaterial;
}
protected:
IMaterial *m_pMaterial;
IMaterialVar *m_pSphereCenter;
};
EXPOSE_INTERFACE( CCoreBallUpdateMaterialProxy, IMaterialProxy, "CoreBallUpdate" IMATERIAL_PROXY_INTERFACE_VERSION );
#endif

View File

@ -10,7 +10,7 @@
#include "iclientmode.h"
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include <vgui/IVGUI.h>
#include <vgui/IVGui.h>
#include <vgui_controls/EditablePanel.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/Label.h>

View File

@ -34,7 +34,7 @@
#define LOCATOR_ICON_FX_FADE_OUT 0x00000800 // Set when deactivated so it can smoothly vanish
#define LOCATOR_ICON_FX_FADE_IN 0x00001000 // Set when activated so it can smoothly appear
#include "tier1/UtlSymbol.h"
#include "tier1/utlsymbol.h"
// See comments in UtlSymbol on why this is useful
DECLARE_PRIVATE_SYMBOLTYPE( CGameInstructorSymbol );

View File

@ -0,0 +1,259 @@
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
//
// Purpose: Displays easy, flexible VGui text. Mapbase equivalent of point_worldtext.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "panelmetaclassmgr.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include <vgui/IInput.h>
#include <vgui/IPanel.h>
#include <vgui/IVGui.h>
#include "ienginevgui.h"
#include "c_vguiscreen.h"
#include "vgui_bitmapbutton.h"
#include "vgui_bitmappanel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// vgui_text_display
//-----------------------------------------------------------------------------
class C_VGuiTextDisplay : public C_BaseEntity
{
public:
DECLARE_CLASS( C_VGuiTextDisplay, C_BaseEntity );
DECLARE_CLIENTCLASS();
C_VGuiTextDisplay();
~C_VGuiTextDisplay();
virtual void PostDataUpdate( DataUpdateType_t updateType );
bool IsEnabled( void ) const { return m_bEnabled; }
const char *GetDisplayText( void ) const { return m_szDisplayText; }
const char *GetFontName( void ) const { return m_szFont; }
int GetResolution( void ) const { return m_iResolution; }
vgui::Label::Alignment GetContentAlignment() const { return m_iContentAlignment; }
bool NeedsTextUpdate() { return m_bTextNeedsUpdate; }
void UpdatedText() { m_bTextNeedsUpdate = false; }
private:
bool m_bEnabled;
char m_szDisplayText[256];
vgui::Label::Alignment m_iContentAlignment;
char m_szFont[64];
int m_iResolution;
bool m_bTextNeedsUpdate;
};
IMPLEMENT_CLIENTCLASS_DT( C_VGuiTextDisplay, DT_VGuiTextDisplay, CVGuiTextDisplay )
RecvPropBool( RECVINFO( m_bEnabled ) ),
RecvPropString( RECVINFO( m_szDisplayText ) ),
RecvPropInt( RECVINFO( m_iContentAlignment ) ),
RecvPropString( RECVINFO( m_szFont ) ),
RecvPropInt( RECVINFO( m_iResolution ) ),
END_RECV_TABLE()
C_VGuiTextDisplay::C_VGuiTextDisplay()
{
}
C_VGuiTextDisplay::~C_VGuiTextDisplay()
{
}
void C_VGuiTextDisplay::PostDataUpdate( DataUpdateType_t updateType )
{
BaseClass::PostDataUpdate( updateType );
// For now, always update
m_bTextNeedsUpdate = true;
}
using namespace vgui;
//-----------------------------------------------------------------------------
// Control screen
//-----------------------------------------------------------------------------
class C_TextDisplayPanel : public CVGuiScreenPanel
{
DECLARE_CLASS( C_TextDisplayPanel, CVGuiScreenPanel );
public:
C_TextDisplayPanel( vgui::Panel *parent, const char *panelName );
~C_TextDisplayPanel( void );
virtual void ApplySchemeSettings( IScheme *pScheme );
void UpdateText();
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
virtual void OnTick( void );
virtual void Paint( void );
private:
CHandle<C_VGuiScreen> m_hVGUIScreen;
CHandle<C_VGuiTextDisplay> m_hScreenEntity;
// VGUI specifics
Label *m_pDisplayTextLabel;
};
DECLARE_VGUI_SCREEN_FACTORY( C_TextDisplayPanel, "text_display_panel" );
CUtlVector <C_TextDisplayPanel *> g_TextDisplays;
//-----------------------------------------------------------------------------
// Constructor:
//-----------------------------------------------------------------------------
C_TextDisplayPanel::C_TextDisplayPanel( vgui::Panel *parent, const char *panelName )
: BaseClass( parent, "C_TextDisplayPanel"/*, vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/WorldTextPanel.res", "WorldTextPanel" )*/ )
{
// Add ourselves to the global list of movie displays
g_TextDisplays.AddToTail( this );
}
//-----------------------------------------------------------------------------
// Purpose: Clean up the movie
//-----------------------------------------------------------------------------
C_TextDisplayPanel::~C_TextDisplayPanel( void )
{
// Remove ourselves from the global list of movie displays
g_TextDisplays.FindAndRemove( this );
}
//-----------------------------------------------------------------------------
// Purpose: Setup our scheme
//-----------------------------------------------------------------------------
void C_TextDisplayPanel::ApplySchemeSettings( IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
/*
m_pDisplayTextLabel->SetFgColor( Color( 255, 255, 255, 255 ) );
m_pDisplayTextLabel->SetText( "" );
m_pDisplayTextLabel->SetVisible( false );
*/
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_TextDisplayPanel::UpdateText()
{
color32 clr = m_hScreenEntity->GetRenderColor();
m_pDisplayTextLabel->SetFgColor( Color( clr.r, clr.g, clr.b, clr.a ) );
m_pDisplayTextLabel->SetText( m_hScreenEntity->GetDisplayText() );
//SetSize( m_hScreenEntity->GetTextSize(), m_hScreenEntity->GetTextSize() );
SetSize( m_hScreenEntity->GetResolution(), m_hScreenEntity->GetResolution() );
m_pDisplayTextLabel->SetSize( m_hScreenEntity->GetResolution(), m_hScreenEntity->GetResolution() );
//m_pDisplayTextLabel->SetSize( m_hScreenEntity->GetTextSize(), m_hScreenEntity->GetTextSize() );
Label::Alignment iAlignment = m_hScreenEntity->GetContentAlignment();
m_pDisplayTextLabel->SetContentAlignment( iAlignment );
bool bWrap = true;
bool bCenterWrap = false;
switch (iAlignment)
{
// Center wrap if centered
case Label::Alignment::a_north:
case Label::Alignment::a_center:
case Label::Alignment::a_south:
bCenterWrap = true;
break;
// HACKHACK: Don't wrap if using an east alignment
case Label::Alignment::a_northeast:
case Label::Alignment::a_east:
case Label::Alignment::a_southeast:
bWrap = false;
break;
}
m_pDisplayTextLabel->SetWrap( bWrap );
m_pDisplayTextLabel->SetCenterWrap( bCenterWrap );
//Msg( "Resolution is %i\n", m_hScreenEntity->GetResolution() );
const char *pszFontName = m_hScreenEntity->GetFontName();
if (pszFontName && pszFontName[0] != '\0')
{
HFont font = scheme()->GetIScheme( GetScheme() )->GetFont( pszFontName );
m_pDisplayTextLabel->SetFont( font );
}
m_pDisplayTextLabel->SetVisible( true );
}
//-----------------------------------------------------------------------------
// Initialization
//-----------------------------------------------------------------------------
bool C_TextDisplayPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
{
if ( !BaseClass::Init( pKeyValues, pInitData ) )
return false;
// Make sure we get ticked...
vgui::ivgui()->AddTickSignal( GetVPanel() );
m_pDisplayTextLabel = dynamic_cast<vgui::Label*>(FindChildByName( "TextDisplay" ));
// Save this for simplicity later on
m_hVGUIScreen = dynamic_cast<C_VGuiScreen *>( GetEntity() );
if ( m_hVGUIScreen != NULL )
{
// Also get the associated entity
m_hScreenEntity = dynamic_cast<C_VGuiTextDisplay *>(m_hVGUIScreen->GetOwnerEntity());
UpdateText();
}
return true;
}
//-----------------------------------------------------------------------------
// Update the display string
//-----------------------------------------------------------------------------
void C_TextDisplayPanel::OnTick()
{
if (m_hScreenEntity->NeedsTextUpdate())
{
UpdateText();
m_hScreenEntity->UpdatedText();
}
BaseClass::OnTick();
}
ConVar r_vguitext_bg( "r_vguitext_bg", "0" );
//-----------------------------------------------------------------------------
// Purpose: Update and draw the frame
//-----------------------------------------------------------------------------
void C_TextDisplayPanel::Paint( void )
{
// Black out the background (we could omit drawing under the video surface, but this is straight-forward)
if ( r_vguitext_bg.GetBool() )
{
surface()->DrawSetColor( 0, 0, 0, 255 );
surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() );
//surface()->DrawSetColor( 64, 64, 64, 255 );
//surface()->DrawFilledRect( 0, 0, m_pDisplayTextLabel->GetWide(), m_pDisplayTextLabel->GetTall() );
}
// Parent's turn
BaseClass::Paint();
}

View File

@ -234,14 +234,6 @@ CPanelMetaClassMgrImp::CPanelMetaClassMgrImp() : m_PanelTypeDict( true, 0, 32 )
CPanelMetaClassMgrImp::~CPanelMetaClassMgrImp()
{
#ifdef MAPBASE // VDC Memory Leak Fixes
while (m_MetaClassKeyValues.Count()>0)
{
if (m_MetaClassKeyValues[0])
m_MetaClassKeyValues[0]->deleteThis();
m_MetaClassKeyValues.RemoveAt(0);
}
#endif
}

View File

@ -0,0 +1,437 @@
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#include "cbase.h"
#include "c_vguiscreen.h"
#include "vgui_controls/Label.h"
#include "vgui_bitmappanel.h"
#include <vgui/IVGui.h>
#include "c_slideshow_display.h"
#include "ienginevgui.h"
#include "fmtstr.h"
#include "vgui_controls/ImagePanel.h"
#include <vgui/ISurface.h>
#include "video/ivideoservices.h"
#include "engine/IEngineSound.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include "c_movie_display.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
using namespace vgui;
struct VideoPlaybackInfo_t
{
VideoPlaybackInfo_t( void ) :
m_pMaterial ( NULL ),
m_nSourceHeight(0), m_nSourceWidth(0),
m_flU(0.0f),m_flV(0.0f) {}
IMaterial *m_pMaterial;
int m_nSourceHeight, m_nSourceWidth; // Source movie's dimensions
float m_flU, m_flV; // U,V ranges for video on its sheet
};
//-----------------------------------------------------------------------------
// Control screen
//-----------------------------------------------------------------------------
class CMovieDisplayScreen : public CVGuiScreenPanel
{
DECLARE_CLASS( CMovieDisplayScreen, CVGuiScreenPanel );
public:
CMovieDisplayScreen( vgui::Panel *parent, const char *panelName );
~CMovieDisplayScreen( void );
virtual void ApplySchemeSettings( IScheme *pScheme );
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
virtual void OnTick( void );
virtual void Paint( void );
private:
bool IsActive( void );
void SetupMovie( void );
void UpdateMovie( void );
bool BeginPlayback( const char *pFilename );
void CalculatePlaybackDimensions( int nSrcWidth, int nSrcHeight );
inline void GetPanelPos( int &xpos, int &ypos )
{
xpos = ( (float) ( GetWide() - m_nPlaybackWidth ) / 2 );
ypos = ( (float) ( GetTall() - m_nPlaybackHeight ) / 2 );
}
private:
// BINK playback info
IVideoMaterial *m_VideoMaterial;
VideoPlaybackInfo_t m_playbackInfo;
CHandle<C_VGuiScreen> m_hVGUIScreen;
CHandle<C_MovieDisplay> m_hScreenEntity;
int m_nTextureId;
int m_nPlaybackHeight; // Playback dimensions (proper ration adjustments)
int m_nPlaybackWidth;
bool m_bBlackBackground;
bool m_bSlaved;
bool m_bInitialized;
bool m_bLastActiveState; // HACK: I'd rather get a real callback...
// VGUI specifics
Label *m_pDisplayTextLabel;
Color m_cDefault;
Color m_cInvisible;
bool bIsAlreadyVisible;
};
DECLARE_VGUI_SCREEN_FACTORY( CMovieDisplayScreen, "movie_display_screen" );
CUtlVector <CMovieDisplayScreen *> g_MovieDisplays;
//-----------------------------------------------------------------------------
// Constructor:
//-----------------------------------------------------------------------------
CMovieDisplayScreen::CMovieDisplayScreen( vgui::Panel *parent, const char *panelName )
: BaseClass( parent, "CMovieDisplayScreen", vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/MovieDisplayScreen.res", "MovieDisplayScreen" ) )
{
m_pDisplayTextLabel = new vgui::Label( this, "NumberDisplay", "testing!");
m_VideoMaterial = NULL;
m_nTextureId = -1;
m_bBlackBackground = true;
m_bSlaved = false;
m_bInitialized = false;
// Add ourselves to the global list of movie displays
g_MovieDisplays.AddToTail( this );
m_bLastActiveState = IsActive();
}
//-----------------------------------------------------------------------------
// Purpose: Clean up the movie
//-----------------------------------------------------------------------------
CMovieDisplayScreen::~CMovieDisplayScreen( void )
{
if ( g_pVideo != NULL && m_VideoMaterial != NULL )
{
g_pVideo->DestroyVideoMaterial( m_VideoMaterial );
m_VideoMaterial = NULL;
}
// Clean up our texture reference
g_pMatSystemSurface->DestroyTextureID( m_nTextureId );
// Remove ourselves from the global list of movie displays
g_MovieDisplays.FindAndRemove( this );
}
//-----------------------------------------------------------------------------
// Purpose: Setup our scheme
//-----------------------------------------------------------------------------
void CMovieDisplayScreen::ApplySchemeSettings( IScheme *pScheme )
{
assert( pScheme );
m_cDefault = Color( 255, 255, 255, 255 );
m_cInvisible = Color( 0, 0, 0, 0 );
m_pDisplayTextLabel->SetFgColor( m_cDefault );
m_pDisplayTextLabel->SetText( "" );
m_pDisplayTextLabel->SetVisible( false );
}
//-----------------------------------------------------------------------------
// Initialization
//-----------------------------------------------------------------------------
bool CMovieDisplayScreen::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
{
// Make sure we get ticked...
vgui::ivgui()->AddTickSignal( GetVPanel() );
if ( !BaseClass::Init( pKeyValues, pInitData ) )
return false;
// Save this for simplicity later on
m_hVGUIScreen = dynamic_cast<C_VGuiScreen *>( GetEntity() );
if ( m_hVGUIScreen != NULL )
{
// Also get the associated entity
m_hScreenEntity = dynamic_cast<C_MovieDisplay *>(m_hVGUIScreen->GetOwnerEntity());
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Helper function to check our active state
//-----------------------------------------------------------------------------
bool CMovieDisplayScreen::IsActive( void )
{
bool bScreenActive = false;
if ( m_hVGUIScreen != NULL )
{
bScreenActive = m_hVGUIScreen->IsActive();
}
return bScreenActive;
}
//-----------------------------------------------------------------------------
// Purpose: Either become the master of a group of screens, or become a slave to another
//-----------------------------------------------------------------------------
void CMovieDisplayScreen::SetupMovie( void )
{
// Only bother if we haven't been setup yet
if ( m_bInitialized )
return;
const char *szGroupName = m_hScreenEntity->GetGroupName();
CMovieDisplayScreen *pMasterScreen = NULL;
for ( int i = 0; i < g_MovieDisplays.Count(); i++ )
{
// Must be valid and not us
if ( g_MovieDisplays[i] == NULL || g_MovieDisplays[i] == this )
continue;
// Must have an associated movie entity
if ( g_MovieDisplays[i]->m_hScreenEntity == NULL )
continue;
// Must have a group name to care
if ( szGroupName[0] == NULL )
continue;
// Group names must match!
// FIXME: Use an ID instead?
const char *szTestGroupName = g_MovieDisplays[i]->m_hScreenEntity->GetGroupName();
if ( Q_strnicmp( szTestGroupName, szGroupName, 128 ) )
continue;
// See if we've found a master display
if ( g_MovieDisplays[i]->m_bInitialized && g_MovieDisplays[i]->m_bSlaved == false )
{
m_bSlaved = true;
// Share the info from the master
m_playbackInfo = g_MovieDisplays[i]->m_playbackInfo;
// We need to calculate our own playback dimensions as we may be a different size than our parent
CalculatePlaybackDimensions( m_playbackInfo.m_nSourceWidth, m_playbackInfo.m_nSourceHeight );
// Bind our texture
m_nTextureId = surface()->CreateNewTextureID( true );
g_pMatSystemSurface->DrawSetTextureMaterial( m_nTextureId, m_playbackInfo.m_pMaterial );
// Hold this as the master screen
pMasterScreen = g_MovieDisplays[i];
break;
}
}
// We need to try again, we have no screen entity!
if ( m_hScreenEntity == NULL )
return;
// No master found, become one
if ( pMasterScreen == NULL )
{
const char *szFilename = m_hScreenEntity->GetMovieFilename();
BeginPlayback( szFilename );
m_bSlaved = false;
}
// Done
m_bInitialized = true;
}
//-----------------------------------------------------------------------------
// Purpose: Deal with the details of the video playback
//-----------------------------------------------------------------------------
void CMovieDisplayScreen::UpdateMovie( void )
{
// Only the master in a group updates the bink file
if ( m_bSlaved )
return;
if ( m_VideoMaterial == NULL )
return;
// Get the current activity state of the screen
bool bScreenActive = IsActive();
// Pause if the game has paused
if ( engine->IsPaused() || engine->Con_IsVisible() )
{
bScreenActive = false;
}
// See if we've changed our activity state
if ( bScreenActive != m_bLastActiveState )
{
m_VideoMaterial->SetPaused( !bScreenActive );
}
// Updated
m_bLastActiveState = bScreenActive;
// Update the frame if we're currently enabled
if ( bScreenActive )
{
// Update our frame
if ( m_VideoMaterial->Update() == false )
{
// Issue a close command
// OnVideoOver();
// StopPlayback();
}
}
}
//-----------------------------------------------------------------------------
// Update the display string
//-----------------------------------------------------------------------------
void CMovieDisplayScreen::OnTick()
{
BaseClass::OnTick();
// Create our playback or slave to another screen already playing
SetupMovie();
// Now update the movie
UpdateMovie();
}
//-----------------------------------------------------------------------------
// Purpose: Adjust the playback dimensions to properly account for our screen dimensions
//-----------------------------------------------------------------------------
void CMovieDisplayScreen::CalculatePlaybackDimensions( int nSrcWidth, int nSrcHeight )
{
float flFrameRatio = ( (float) GetWide() / (float) GetTall() );
float flVideoRatio = ( (float) nSrcWidth / (float) nSrcHeight );
if ( flVideoRatio > flFrameRatio )
{
m_nPlaybackWidth = GetWide();
m_nPlaybackHeight = ( GetWide() / flVideoRatio );
}
else if ( flVideoRatio < flFrameRatio )
{
m_nPlaybackWidth = ( GetTall() * flVideoRatio );
m_nPlaybackHeight = GetTall();
}
else
{
m_nPlaybackWidth = GetWide();
m_nPlaybackHeight = GetTall();
}
}
//-----------------------------------------------------------------------------
// Purpose: Begins playback of a movie
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CMovieDisplayScreen::BeginPlayback( const char *pFilename )
{
// need working video services
if ( g_pVideo == NULL )
return false;
// Create a new video material
if ( m_VideoMaterial != NULL )
{
g_pVideo->DestroyVideoMaterial( m_VideoMaterial );
m_VideoMaterial = NULL;
}
// Create a globally unique name for this material
char szMaterialName[256];
// Append our group name if we have one
const char *szGroupName = m_hScreenEntity->GetGroupName();
if ( szGroupName[0] != NULL )
{
Q_snprintf( szMaterialName, sizeof(szMaterialName), "%s_%s", pFilename, szGroupName );
}
else
{
Q_strncpy( szMaterialName, pFilename, sizeof(szMaterialName) );
}
const char *pszMaterialName = CFmtStrN<128>( "VideoMaterial_%s", m_hScreenEntity->GetEntityName() );
m_VideoMaterial = g_pVideo->CreateVideoMaterial( pszMaterialName, pFilename, "GAME",
VideoPlaybackFlags::DEFAULT_MATERIAL_OPTIONS,
VideoSystem::DETERMINE_FROM_FILE_EXTENSION/*, m_bAllowAlternateMedia*/ );
if ( m_VideoMaterial == NULL )
return false;
m_VideoMaterial->SetMuted( true ); // FIXME: Allow?
if ( m_hScreenEntity->IsLooping() )
{
m_VideoMaterial->SetLooping( true );
}
if ( m_VideoMaterial->HasAudio() )
{
// We want to be the sole audio source
enginesound->NotifyBeginMoviePlayback();
}
// Get our basic info from the movie
m_VideoMaterial->GetVideoImageSize( &m_playbackInfo.m_nSourceWidth, &m_playbackInfo.m_nSourceHeight );
m_VideoMaterial->GetVideoTexCoordRange( &m_playbackInfo.m_flU, &m_playbackInfo.m_flV );
m_playbackInfo.m_pMaterial = m_VideoMaterial->GetMaterial();
// Get our playback dimensions
CalculatePlaybackDimensions( m_playbackInfo.m_nSourceWidth, m_playbackInfo.m_nSourceHeight );
// Bind our texture
m_nTextureId = surface()->CreateNewTextureID( true );
g_pMatSystemSurface->DrawSetTextureMaterial( m_nTextureId, m_playbackInfo.m_pMaterial );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Update and draw the frame
//-----------------------------------------------------------------------------
void CMovieDisplayScreen::Paint( void )
{
// Masters must keep the video updated
if ( m_bSlaved == false && m_VideoMaterial == NULL )
{
BaseClass::Paint();
return;
}
// Sit in the "center"
int xpos, ypos;
GetPanelPos( xpos, ypos );
// Black out the background (we could omit drawing under the video surface, but this is straight-forward)
if ( m_bBlackBackground )
{
surface()->DrawSetColor( 0, 0, 0, 255 );
surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() );
}
// Draw it
surface()->DrawSetTexture( m_nTextureId );
surface()->DrawSetColor( 255, 255, 255, 255 );
surface()->DrawTexturedSubRect( xpos, ypos, xpos+m_nPlaybackWidth, ypos+m_nPlaybackHeight, 0.0f, 0.0f, m_playbackInfo.m_flU, m_playbackInfo.m_flV );
// Parent's turn
BaseClass::Paint();
}

View File

@ -16,20 +16,59 @@
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
static CUtlVector< VideoPanel * > g_vecVideoPanels;
// Thiis is a hack due to the fact that the user can type quit with the video panel up, but it's parented to the GameUI dll root panel, which is already gone so
// we would crash in the destructor
void VGui_ClearVideoPanels()
{
for ( int i = g_vecVideoPanels.Count() - 1; i >= 0; --i )
{
if ( g_vecVideoPanels[ i ] )
{
delete g_vecVideoPanels[ i ];
}
}
g_vecVideoPanels.RemoveAll();
}
struct VideoPanelParms_t
{
VideoPanelParms_t( bool _interrupt = true, bool _loop = false, bool _mute = false )
{
bAllowInterrupt = _interrupt;
bLoop = _loop;
bMute = _mute;
}
bool bAllowInterrupt;
bool bLoop;
bool bMute;
//float flFadeIn;
//float flFadeOut;
};
VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHeight, unsigned int nWidth, bool allowAlternateMedia ) :
BaseClass( NULL, "VideoPanel" ),
m_VideoMaterial( NULL ),
m_nPlaybackWidth( 0 ),
m_nPlaybackHeight( 0 ),
m_bAllowAlternateMedia( allowAlternateMedia )
m_nShutdownCount( 0 ),
m_bLooping( false ),
m_bStopAllSounds( true ),
m_bAllowInterruption( true ),
m_bAllowAlternateMedia( allowAlternateMedia ),
m_bStarted( false )
{
#ifdef MAPBASE
vgui::VPANEL pParent = enginevgui->GetPanel( PANEL_ROOT );
#else
vgui::VPANEL pParent = enginevgui->GetPanel( PANEL_GAMEUIDLL );
#endif
SetParent( pParent );
SetVisible( false );
@ -53,6 +92,11 @@ VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHe
SetScheme(vgui::scheme()->LoadSchemeFromFile( "resource/VideoPanelScheme.res", "VideoPanelScheme"));
LoadControlSettings("resource/UI/VideoPanel.res");
// Let us update
vgui::ivgui()->AddTickSignal( GetVPanel() );
g_vecVideoPanels.AddToTail( this );
}
//-----------------------------------------------------------------------------
@ -60,6 +104,8 @@ VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHe
//-----------------------------------------------------------------------------
VideoPanel::~VideoPanel( void )
{
g_vecVideoPanels.FindAndRemove( this );
SetParent( (vgui::Panel *) NULL );
// Shut down this video, destroy the video material
@ -70,13 +116,39 @@ VideoPanel::~VideoPanel( void )
}
}
//-----------------------------------------------------------------------------
// Purpose: Keeps a tab on when the movie is ending and allows a frame to pass to prevent threading issues
//-----------------------------------------------------------------------------
void VideoPanel::OnTick( void )
{
if ( m_nShutdownCount > 0 )
{
m_nShutdownCount++;
if ( m_nShutdownCount > 10 )
{
OnClose();
m_nShutdownCount = 0;
}
}
BaseClass::OnTick();
}
void VideoPanel::OnVideoOver()
{
StopPlayback();
}
//-----------------------------------------------------------------------------
// Purpose: Begins playback of a movie
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool VideoPanel::BeginPlayback( const char *pFilename )
{
// Who the heck hacked this in?
if ( !pFilename || pFilename[ 0 ] == '\0' )
return false;
#ifdef _X360
XVIDEO_MODE videoMode;
XGetVideoMode( &videoMode );
@ -106,9 +178,25 @@ bool VideoPanel::BeginPlayback( const char *pFilename )
if ( m_VideoMaterial == NULL )
return false;
if ( m_bLooping )
{
m_VideoMaterial->SetLooping( true );
}
#ifdef MAPBASE
if ( m_bMuted )
{
m_VideoMaterial->SetMuted( true );
}
#endif
m_bStarted = true;
// We want to be the sole audio source
// FIXME: This may not always be true!
enginesound->NotifyBeginMoviePlayback();
if ( m_bStopAllSounds )
{
enginesound->NotifyBeginMoviePlayback();
}
int nWidth, nHeight;
m_VideoMaterial->GetVideoImageSize( &nWidth, &nHeight );
@ -168,9 +256,10 @@ void VideoPanel::DoModal( void )
//-----------------------------------------------------------------------------
void VideoPanel::OnKeyCodeTyped( vgui::KeyCode code )
{
if ( code == KEY_ESCAPE )
bool bInterruptKeyPressed = ( code == KEY_ESCAPE );
if ( m_bAllowInterruption && bInterruptKeyPressed )
{
OnClose();
StopPlayback();
}
else
{
@ -181,34 +270,54 @@ void VideoPanel::OnKeyCodeTyped( vgui::KeyCode code )
//-----------------------------------------------------------------------------
// Purpose: Handle keys that should cause us to close
//-----------------------------------------------------------------------------
void VideoPanel::OnKeyCodePressed( vgui::KeyCode code )
void VideoPanel::OnKeyCodePressed( vgui::KeyCode keycode )
{
vgui::KeyCode code = GetBaseButtonCode( keycode );
// All these keys will interrupt playback
bool bInterruptKeyPressed = ( code == KEY_ESCAPE ||
code == KEY_BACKQUOTE ||
code == KEY_SPACE ||
code == KEY_ENTER ||
code == KEY_XBUTTON_A ||
code == KEY_XBUTTON_B ||
code == KEY_XBUTTON_X ||
code == KEY_XBUTTON_Y ||
code == KEY_XBUTTON_START ||
code == KEY_XBUTTON_BACK );
// These keys cause the panel to shutdown
if ( code == KEY_ESCAPE ||
code == KEY_BACKQUOTE ||
code == KEY_SPACE ||
code == KEY_ENTER ||
code == KEY_XBUTTON_A ||
code == KEY_XBUTTON_B ||
code == KEY_XBUTTON_X ||
code == KEY_XBUTTON_Y ||
code == KEY_XBUTTON_START ||
code == KEY_XBUTTON_BACK )
if ( m_bAllowInterruption && bInterruptKeyPressed )
{
OnClose();
StopPlayback();
}
else
{
BaseClass::OnKeyCodePressed( code );
BaseClass::OnKeyCodePressed( keycode );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void VideoPanel::StopPlayback( void )
{
SetVisible( false );
// Start the deferred shutdown process
m_nShutdownCount = 1;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void VideoPanel::OnClose( void )
{
enginesound->NotifyEndMoviePlayback();
if ( m_bStopAllSounds )
{
enginesound->NotifyEndMoviePlayback();
}
BaseClass::OnClose();
if ( vgui::input()->GetAppModalSurface() == GetVPanel() )
@ -224,7 +333,6 @@ void VideoPanel::OnClose( void )
engine->ClientCmd( m_szExitCommand );
}
SetVisible( false );
MarkForDeletion();
}
@ -247,26 +355,52 @@ void VideoPanel::Paint( void )
if ( m_VideoMaterial == NULL )
return;
float alpha = ((float)GetFgColor()[3]/255.0f);
#ifdef MAPBASE
if (m_flFadeIn != 0.0f || m_flFadeOut != 0.0f)
{
// GetCurrentVideoTime() and GetVideoDuration() are borked
float flFrameCount = m_VideoMaterial->GetFrameCount();
float flEnd = flFrameCount / m_VideoMaterial->GetVideoFrameRate().GetFPS();
float flTime = ((float)(m_VideoMaterial->GetCurrentFrame()) / flFrameCount) * flEnd;
float flFadeOutDelta = (flEnd - m_flFadeOut);
if (flTime <= m_flFadeIn)
{
alpha = (flTime / m_flFadeIn);
}
else if (flTime >= flFadeOutDelta)
{
alpha = (1.0f - ((flTime - flFadeOutDelta) / m_flFadeOut));
}
}
#endif
if ( m_VideoMaterial->Update() == false )
{
// Issue a close command
OnVideoOver();
OnClose();
//OnClose();
}
// Sit in the "center"
int xpos, ypos;
GetPanelPos( xpos, ypos );
LocalToScreen( xpos, ypos );
// Black out the background (we could omit drawing under the video surface, but this is straight-forward)
if ( m_bBlackBackground )
{
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
vgui::surface()->DrawSetColor( 0, 0, 0, alpha * 255.0f );
vgui::surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() );
}
// Draw the polys to draw this out
CMatRenderContextPtr pRenderContext( materials );
#ifdef MAPBASE
pRenderContext->ClearColor4ub( 255, 255, 255, alpha * 255.0f );
#endif
pRenderContext->MatrixMode( MATERIAL_VIEW );
pRenderContext->PushMatrix();
@ -306,8 +440,6 @@ void VideoPanel::Paint( void )
flTopY = FLerp( 1, -1, 0, vh ,flTopY );
flBottomY = FLerp( 1, -1, 0, vh, flBottomY );
float alpha = ((float)GetFgColor()[3]/255.0f);
for ( int corner=0; corner<4; corner++ )
{
bool bLeft = (corner==0) || (corner==3);
@ -340,16 +472,37 @@ void VideoPanel::Paint( void )
bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos,
unsigned int nWidth, unsigned int nHeight,
const char *pVideoFilename,
const char *pExitCommand /*= NULL*/)
const char *pExitCommand /*= NULL*/,
const VideoPanelParms_t &parms )
{
// Create the base video panel
VideoPanel *pVideoPanel = new VideoPanel( nXPos, nYPos, nHeight, nWidth, false );
VideoPanel *pVideoPanel = new VideoPanel( nXPos, nYPos, nHeight, nWidth );
if ( pVideoPanel == NULL )
return false;
// Toggle if we want the panel to allow interruption
pVideoPanel->SetAllowInterrupt( parms.bAllowInterrupt );
// Set the command we'll call (if any) when the video is interrupted or completes
pVideoPanel->SetExitCommand( pExitCommand );
#ifdef MAPBASE
// Toggle if we want the panel to loop (inspired by Portal 2)
pVideoPanel->SetLooping( parms.bLoop );
// Toggle if we want the panel to be muted
pVideoPanel->SetMuted( parms.bMute );
// TODO: Unique "Stop All Sounds" parameter
if (parms.bMute)
{
pVideoPanel->SetStopAllSounds( false );
}
// Fade parameters (unfinished)
//pVideoPanel->SetFade( parms.flFadeIn, parms.flFadeOut );
#endif
// Start it going
if ( pVideoPanel->BeginPlayback( pVideoFilename ) == false )
{
@ -364,8 +517,29 @@ bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos,
}
//-----------------------------------------------------------------------------
// Purpose: Used to launch a video playback (Debug) -
// user must include file extension
// Purpose: Create a video panel with the supplied commands
//-----------------------------------------------------------------------------
void CreateVideoPanel( const char *lpszFilename, const char *lpszExitCommand, int nWidth, int nHeight, VideoPanelParms_t &parms )
{
char strFullpath[MAX_PATH];
Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory
char strFilename[MAX_PATH];
Q_StripExtension( lpszFilename, strFilename, MAX_PATH );
Q_strncat( strFullpath, lpszFilename, MAX_PATH );
// Use the full screen size if they haven't specified an override
unsigned int nScreenWidth = ( nWidth != 0 ) ? nWidth : ScreenWidth();
unsigned int nScreenHeight = ( nHeight != 0 ) ? nHeight : ScreenHeight();
// Create the panel and go!
if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath, lpszExitCommand, parms ) == false )
{
Warning( "Unable to play video: %s\n", strFullpath );
}
}
//-----------------------------------------------------------------------------
// Purpose: Used to launch a video playback
//-----------------------------------------------------------------------------
CON_COMMAND( playvideo, "Plays a video: <filename> [width height]" )
@ -375,30 +549,32 @@ CON_COMMAND( playvideo, "Plays a video: <filename> [width height]" )
unsigned int nScreenWidth = Q_atoi( args[2] );
unsigned int nScreenHeight = Q_atoi( args[3] );
char strFullpath[MAX_PATH];
Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory
char strFilename[MAX_PATH];
Q_StripExtension( args[1], strFilename, MAX_PATH );
Q_strncat( strFullpath, args[1], MAX_PATH );
if ( nScreenWidth == 0 )
{
nScreenWidth = ScreenWidth();
}
if ( nScreenHeight == 0 )
{
nScreenHeight = ScreenHeight();
}
// Create the panel and go!
if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath ) == false )
{
Warning( "Unable to play video: %s\n", strFullpath );
}
// New struct; functionally identical
VideoPanelParms_t parms;
CreateVideoPanel( args[1], NULL, nScreenWidth, nScreenHeight, parms );
}
//-----------------------------------------------------------------------------
// Purpose: Used to launch a video playback
//-----------------------------------------------------------------------------
CON_COMMAND( playvideo_nointerrupt, "Plays a video without ability to skip: <filename> [width height]" )
{
if ( args.ArgC() < 2 )
return;
unsigned int nScreenWidth = Q_atoi( args[2] );
unsigned int nScreenHeight = Q_atoi( args[3] );
// New struct; functionally identical
VideoPanelParms_t parms( false );
CreateVideoPanel( args[1], NULL, nScreenWidth, nScreenHeight, parms );
}
//-----------------------------------------------------------------------------
// Purpose: Used to launch a video playback and fire a command on completion
//-----------------------------------------------------------------------------
@ -408,21 +584,78 @@ CON_COMMAND( playvideo_exitcommand, "Plays a video and fires and exit command wh
if ( args.ArgC() < 2 )
return;
unsigned int nScreenWidth = ScreenWidth();
unsigned int nScreenHeight = ScreenHeight();
char strFullpath[MAX_PATH];
Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory
char strFilename[MAX_PATH];
Q_StripExtension( args[1], strFilename, MAX_PATH );
Q_strncat( strFullpath, args[1], MAX_PATH );
// Pull out the exit command we want to use
char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] );
// Create the panel and go!
if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath, pExitCommand ) == false )
// New struct; functionally identical
VideoPanelParms_t parms;
CreateVideoPanel( args[1], pExitCommand, 0, 0, parms );
}
//-----------------------------------------------------------------------------
// Purpose: Used to launch a video playback and fire a command on completion
//-----------------------------------------------------------------------------
CON_COMMAND( playvideo_exitcommand_nointerrupt, "Plays a video (without interruption) and fires and exit command when it is stopped or finishes: <filename> <exit command>" )
{
if ( args.ArgC() < 2 )
return;
// Pull out the exit command we want to use
char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] );
// New struct; functionally identical
VideoPanelParms_t parms( false );
CreateVideoPanel( args[1], pExitCommand, 0, 0, parms );
}
//-----------------------------------------------------------------------------
// Purpose: Cause all playback to stop
//-----------------------------------------------------------------------------
CON_COMMAND( stopvideos, "Stops all videos playing to the screen" )
{
FOR_EACH_VEC( g_vecVideoPanels, itr )
{
Warning( "Unable to play video: %s\n", strFullpath );
engine->ClientCmd( pExitCommand );
g_vecVideoPanels[itr]->StopPlayback();
}
}
//-----------------------------------------------------------------------------
// Purpose: Used to launch a video playback and fire a command on completion
//-----------------------------------------------------------------------------
CON_COMMAND( playvideo_complex, "Plays a video with various parameters to simplify logic_playmovie: <filename> <exit command> <no interrupt> <looping> <fade in> <fade out>" )
{
if ( args.ArgC() < 2 )
return;
// Pull out the exit command we want to use
char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] );
// Parameters
VideoPanelParms_t parms;
if (args.ArgC() >= 3)
parms.bAllowInterrupt = atoi( args[3] ) != 0;
if (args.ArgC() >= 4)
parms.bLoop = atoi( args[4] ) != 0;
if (args.ArgC() >= 5)
parms.bMute = atoi( args[5] ) != 0;
//if (args.ArgC() >= 5)
// parms.flFadeIn = atof( args[5] );
//if (args.ArgC() >= 6)
// parms.flFadeOut = atof( args[6] );
// Stop a softlock
if (parms.bAllowInterrupt == false && parms.bLoop)
{
Warning( "WARNING: Tried to play video set to be uninterruptible and looping. This would cause a softlock because the video loops forever and there's no way to stop it.\n" );
return;
}
CreateVideoPanel( args[1], pExitCommand, 0, 0, parms );
}

View File

@ -45,14 +45,22 @@ public:
}
bool BeginPlayback( const char *pFilename );
void StopPlayback( void );
void SetBlackBackground( bool bBlack ){ m_bBlackBackground = bBlack; }
void SetAllowInterrupt( bool bAllowInterrupt ) { m_bAllowInterruption = bAllowInterrupt; }
void SetStopAllSounds( bool bStopAllSounds ) { m_bStopAllSounds = bStopAllSounds; }
#ifdef MAPBASE
void SetLooping( bool bLooping ) { m_bLooping = bLooping; }
void SetMuted( bool bMuted ) { m_bMuted = bMuted; }
void SetFade( float flStartFade, float flEndFade ) { m_flFadeIn = flStartFade; m_flFadeOut = flEndFade; }
#endif
protected:
virtual void OnTick( void ) { BaseClass::OnTick(); }
virtual void OnTick( void );
virtual void OnCommand( const char *pcCommand ) { BaseClass::OnCommand( pcCommand ); }
virtual void OnVideoOver(){}
virtual void OnVideoOver();
protected:
IVideoMaterial *m_VideoMaterial;
@ -65,8 +73,19 @@ protected:
float m_flU; // U,V ranges for video on its sheet
float m_flV;
bool m_bLooping;
#ifdef MAPBASE
float m_flFadeIn;
float m_flFadeOut;
bool m_bMuted;
#endif
bool m_bStopAllSounds;
bool m_bAllowInterruption;
bool m_bBlackBackground;
bool m_bAllowAlternateMedia;
int m_nShutdownCount;
bool m_bStarted;
};

View File

@ -165,6 +165,8 @@ public:
void SetVarFloat( int i, float value );
void SetVarVector( int i, const Vector &value );
const char *GetVarName( int i );
private:
IMaterialVar *m_MaterialVars[SCRIPT_MAT_PROXY_MAX_VARS];
@ -194,12 +196,19 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMaterialProxy, "CScriptMaterialProxy", "Mate
DEFINE_SCRIPTFUNC( SetVarInt, "Sets a material var's int value" )
DEFINE_SCRIPTFUNC( SetVarFloat, "Sets a material var's float value" )
DEFINE_SCRIPTFUNC( SetVarVector, "Sets a material var's vector value" )
DEFINE_SCRIPTFUNC( GetVarName, "Gets a material var's name" )
END_SCRIPTDESC();
CScriptMaterialProxy::CScriptMaterialProxy()
{
m_hScriptInstance = NULL;
m_hFuncOnBind = NULL;
for (int i = 0; i < SCRIPT_MAT_PROXY_MAX_VARS; i++)
{
m_MaterialVars[i] = NULL;
}
}
CScriptMaterialProxy::~CScriptMaterialProxy()
@ -316,18 +325,20 @@ void CScriptMaterialProxy::TermScript()
void CScriptMaterialProxy::OnBind( void *pRenderable )
{
if( !pRenderable )
return;
if (m_hFuncOnBind != NULL)
{
IClientRenderable *pRend = ( IClientRenderable* )pRenderable;
C_BaseEntity *pEnt = pRend->GetIClientUnknown()->GetBaseEntity();
if ( pEnt )
C_BaseEntity *pEnt = NULL;
if (pRenderable)
{
g_pScriptVM->SetValue( m_ScriptScope, "entity", pEnt->GetScriptInstance() );
IClientRenderable *pRend = (IClientRenderable*)pRenderable;
pEnt = pRend->GetIClientUnknown()->GetBaseEntity();
if ( pEnt )
{
g_pScriptVM->SetValue( m_ScriptScope, "entity", pEnt->GetScriptInstance() );
}
}
else
if (!pEnt)
{
// Needs to register as a null value so the script doesn't break if it looks for an entity
g_pScriptVM->SetValue( m_ScriptScope, "entity", SCRIPT_VARIANT_NULL );
@ -414,6 +425,14 @@ void CScriptMaterialProxy::SetVarVector( int i, const Vector &value )
return m_MaterialVars[i]->SetVecValue( value.Base(), 3 );
}
const char *CScriptMaterialProxy::GetVarName( int i )
{
if (!ValidateIndex( i ) || !m_MaterialVars[i])
return NULL;
return m_MaterialVars[i]->GetName();
}
EXPOSE_INTERFACE( CScriptMaterialProxy, IMaterialProxy, "VScriptProxy" IMATERIAL_PROXY_INTERFACE_VERSION );
bool CMaterialProxyScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize )
@ -461,6 +480,11 @@ bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
}
#ifdef MAPBASE_VSCRIPT
static float FrameTime()
{
return gpGlobals->frametime;
}
static bool Con_IsVisible()
{
return engine->Con_IsVisible();
@ -585,6 +609,7 @@ bool VScriptClientInit()
ScriptRegisterFunction( g_pScriptVM, DoUniqueString, SCRIPT_ALIAS( "UniqueString", "Generate a string guaranteed to be unique across the life of the script VM, with an optional root string." ) );
ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" );
#ifdef MAPBASE_VSCRIPT
ScriptRegisterFunction( g_pScriptVM, FrameTime, "Get the time spent on the client in the last frame" );
ScriptRegisterFunction( g_pScriptVM, Con_IsVisible, "Returns true if the console is visible" );
ScriptRegisterFunction( g_pScriptVM, ScreenWidth, "Width of the screen in pixels" );
ScriptRegisterFunction( g_pScriptVM, ScreenHeight, "Height of the screen in pixels" );

View File

@ -5,18 +5,26 @@ static char g_Script_vscript_client[] = R"vscript(
//
//=============================================================================
local DoUniqueString = DoUniqueString
local DoDispatchParticleEffect = DoDispatchParticleEffect
function UniqueString( string = "" )
{
return DoUniqueString( string.tostring() );
return DoUniqueString( "" + string );
}
function IncludeScript( name, scope = null )
{
if ( scope == null )
if ( !scope )
{
scope = this;
}
return ::DoIncludeScript( name, scope );
}
function DispatchParticleEffect( particleName, origin, angles, entity = null )
{
DoDispatchParticleEffect( particleName, origin, angles, entity );
}
)vscript";

View File

@ -427,6 +427,11 @@ void CAnimationLayer::DispatchAnimEvents( CBaseAnimating *eventHandler, CBaseAni
event.eventtime = pOwner->m_flAnimTime + (flCycle - m_flCycle) / flCycleRate + pOwner->GetAnimTimeInterval();
}
#ifdef MAPBASE_VSCRIPT
if (eventHandler->m_ScriptScope.IsInitialized() && eventHandler->ScriptHookHandleAnimEvent( &event ) == false)
continue;
#endif
// Msg( "dispatch %d (%d : %.2f)\n", index - 1, event.event, event.eventtime );
eventHandler->HandleAnimEvent( &event );
}

View File

@ -212,6 +212,10 @@ static ConCommand creditsdone("creditsdone", CreditsDone_f );
extern ConVar sv_unlockedchapters;
#ifdef MAPBASE
extern int Mapbase_GetChapterCount();
#endif
void CCredits::OnRestore()
{
BaseClass::OnRestore();
@ -226,6 +230,10 @@ void CCredits::OnRestore()
void CCredits::RollOutroCredits()
{
#ifdef MAPBASE
// Don't set this if we're using Mapbase chapters or if sv_unlockedchapters is already greater than 15
if (Mapbase_GetChapterCount() <= 0 && sv_unlockedchapters.GetInt() < 15)
#endif
sv_unlockedchapters.SetValue( "15" );
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();

View File

@ -97,6 +97,7 @@
#ifdef MAPBASE
#include "mapbase/matchers.h"
#include "items.h"
#endif
#include "env_debughistory.h"
@ -303,10 +304,11 @@ CSimpleSimTimer CAI_BaseNPC::m_AnyUpdateEnemyPosTimer;
#ifdef MAPBASE_VSCRIPT
// TODO: Better placement?
ScriptHook_t g_Hook_QueryHearSound;
ScriptHook_t g_Hook_QuerySeeEntity;
ScriptHook_t g_Hook_TranslateActivity;
ScriptHook_t g_Hook_TranslateSchedule;
ScriptHook_t CAI_BaseNPC::g_Hook_QueryHearSound;
ScriptHook_t CAI_BaseNPC::g_Hook_QuerySeeEntity;
ScriptHook_t CAI_BaseNPC::g_Hook_TranslateActivity;
ScriptHook_t CAI_BaseNPC::g_Hook_TranslateSchedule;
ScriptHook_t CAI_BaseNPC::g_Hook_GetActualShootPosition;
#endif
//
@ -10687,6 +10689,19 @@ void CAI_BaseNPC::CollectShotStats( const Vector &vecShootOrigin, const Vector &
//-----------------------------------------------------------------------------
Vector CAI_BaseNPC::GetActualShootPosition( const Vector &shootOrigin )
{
#ifdef MAPBASE_VSCRIPT
if (m_ScriptScope.IsInitialized() && g_Hook_GetActualShootPosition.CanRunInScope(m_ScriptScope))
{
ScriptVariant_t functionReturn;
ScriptVariant_t args[] = { shootOrigin, ToHScript( GetEnemy() ) };
if (g_Hook_GetActualShootPosition.Call( m_ScriptScope, &functionReturn, args ))
{
if (functionReturn.m_type == FIELD_VECTOR && functionReturn.m_pVector->LengthSqr() != 0.0f)
return *functionReturn.m_pVector;
}
}
#endif
// Project the target's location into the future.
Vector vecEnemyLKP = GetEnemyLKP();
Vector vecEnemyOffset = GetEnemy()->BodyTarget( shootOrigin ) - GetEnemy()->GetAbsOrigin();
@ -11495,17 +11510,9 @@ void CAI_BaseNPC::PickupItem( CBaseEntity *pItem )
m_OnItemPickup.Set( pItem, pItem, this );
Assert( pItem != NULL );
if( FClassnameIs( pItem, "item_healthkit" ) )
if( FClassnameIs( pItem, "item_health*" ) ) // item_healthkit, item_healthvial, item_healthkit_custom, etc.
{
if ( TakeHealth( sk_healthkit.GetFloat(), DMG_GENERIC ) )
{
RemoveAllDecals();
UTIL_Remove( pItem );
}
}
else if( FClassnameIs( pItem, "item_healthvial" ) )
{
if ( TakeHealth( sk_healthvial.GetFloat(), DMG_GENERIC ) )
if ( TakeHealth( static_cast<CItem*>(pItem)->GetItemAmount(), DMG_GENERIC ) )
{
RemoveAllDecals();
UTIL_Remove( pItem );
@ -12075,20 +12082,24 @@ BEGIN_ENT_SCRIPTDESC( CAI_BaseNPC, CBaseCombatCharacter, "The base class all NPC
//
// Hooks
//
BEGIN_SCRIPTHOOK( g_Hook_QueryHearSound, "QueryHearSound", FIELD_BOOLEAN, "Called when the NPC is deciding whether to hear a CSound or not." )
BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_QueryHearSound, "QueryHearSound", FIELD_BOOLEAN, "Called when the NPC is deciding whether to hear a CSound or not." )
DEFINE_SCRIPTHOOK_PARAM( "sound", FIELD_HSCRIPT )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( g_Hook_QuerySeeEntity, "QuerySeeEntity", FIELD_BOOLEAN, "Called when the NPC is deciding whether to see an entity or not." )
BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_QuerySeeEntity, "QuerySeeEntity", FIELD_BOOLEAN, "Called when the NPC is deciding whether to see an entity or not." )
DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( g_Hook_TranslateActivity, "NPC_TranslateActivity", FIELD_VARIANT, "Called when the NPC is translating their current activity. The activity is provided in both string and ID form. Should return either an activity string or an activity ID. Return -1 to not translate." )
BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_TranslateActivity, "NPC_TranslateActivity", FIELD_VARIANT, "Called when the NPC is translating their current activity. The activity is provided in both string and ID form. Should return either an activity string or an activity ID. Return -1 to not translate." )
DEFINE_SCRIPTHOOK_PARAM( "activity", FIELD_CSTRING )
DEFINE_SCRIPTHOOK_PARAM( "activity_id", FIELD_INTEGER )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( g_Hook_TranslateSchedule, "NPC_TranslateSchedule", FIELD_VARIANT, "Called when the NPC is translating their current schedule. The schedule is provided in both string and ID form. Should return either a schedule string or a schedule ID. Return -1 to not translate." )
BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_TranslateSchedule, "NPC_TranslateSchedule", FIELD_VARIANT, "Called when the NPC is translating their current schedule. The schedule is provided in both string and ID form. Should return either a schedule string or a schedule ID. Return -1 to not translate." )
DEFINE_SCRIPTHOOK_PARAM( "schedule", FIELD_CSTRING )
DEFINE_SCRIPTHOOK_PARAM( "schedule_id", FIELD_INTEGER )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( CAI_BaseNPC::g_Hook_GetActualShootPosition, "GetActualShootPosition", FIELD_VOID, "Called when the NPC is getting their actual shoot position, using the default shoot position as the parameter. (NOTE: NPCs which override this themselves might not always use this hook!)" )
DEFINE_SCRIPTHOOK_PARAM( "shootOrigin", FIELD_VECTOR )
DEFINE_SCRIPTHOOK_PARAM( "target", FIELD_HSCRIPT )
END_SCRIPTHOOK()
END_SCRIPTDESC();
#endif

View File

@ -100,11 +100,6 @@ extern bool AIStrongOpt( void );
#ifdef MAPBASE
// Defines Mapbase's extended NPC response system usage.
#define EXPANDED_RESPONSE_SYSTEM_USAGE
// Use the model keyvalue if it is defined
#define DefaultOrCustomModel(defaultModel) GetModelName() != NULL_STRING ? STRING(GetModelName()) : defaultModel
#else
#define DefaultOrCustomModel() defaultModel
#endif
#ifdef EXPANDED_RESPONSE_SYSTEM_USAGE
@ -1244,6 +1239,8 @@ public:
int ScriptGetActivityID() { return GetActivity(); }
void ScriptSetActivity( const char *szActivity ) { SetActivity( (Activity)GetActivityID( szActivity ) ); }
void ScriptSetActivityID( int iActivity ) { SetActivity((Activity)iActivity); }
int ScriptTranslateActivity( const char *szActivity ) { return TranslateActivity( (Activity)GetActivityID( szActivity ) ); }
int ScriptTranslateActivityID( int iActivity ) { return TranslateActivity( (Activity)iActivity ); }
const char* VScriptGetSchedule();
int VScriptGetScheduleID();
@ -2311,6 +2308,15 @@ public:
CUtlVector<AIScheduleChoice_t> m_ScheduleHistory;
#endif//AI_MONITOR_FOR_OSCILLATION
#ifdef MAPBASE_VSCRIPT
static ScriptHook_t g_Hook_QueryHearSound;
static ScriptHook_t g_Hook_QuerySeeEntity;
static ScriptHook_t g_Hook_TranslateActivity;
static ScriptHook_t g_Hook_TranslateSchedule;
static ScriptHook_t g_Hook_GetActualShootPosition;
static ScriptHook_t g_Hook_OverrideMove;
#endif
private:
// Break into pieces!

View File

@ -1210,7 +1210,7 @@ void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... )
}
else
{
CGMsg( 1, CON_GROUP_CHOREO "%s", string );
CGMsg( 1, CON_GROUP_CHOREO, "%s", string );
}
UTIL_LogPrintf( string );
}

View File

@ -284,6 +284,7 @@ END_SEND_TABLE()
#ifdef MAPBASE_VSCRIPT
ScriptHook_t CBaseAnimating::g_Hook_OnServerRagdoll;
ScriptHook_t CBaseAnimating::g_Hook_HandleAnimEvent;
#endif
BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" )
@ -342,6 +343,10 @@ BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" )
DEFINE_SCRIPTHOOK_PARAM( "ragdoll", FIELD_HSCRIPT )
DEFINE_SCRIPTHOOK_PARAM( "submodel", FIELD_BOOLEAN )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( CBaseAnimating::g_Hook_HandleAnimEvent, "HandleAnimEvent", FIELD_BOOLEAN, "Called when handling animation events. Return false to cancel base handling." )
DEFINE_SCRIPTHOOK_PARAM( "event", FIELD_HSCRIPT )
END_SCRIPTHOOK()
#endif
END_SCRIPTDESC();
@ -1243,6 +1248,11 @@ void CBaseAnimating::DispatchAnimEvents ( CBaseAnimating *eventHandler )
event.eventtime = m_flAnimTime + (flCycle - GetCycle()) / flCycleRate + GetAnimTimeInterval();
}
#ifdef MAPBASE_VSCRIPT
if (eventHandler->ScriptHookHandleAnimEvent( &event ) == false)
continue;
#endif
/*
if (m_debugOverlays & OVERLAY_NPC_SELECTED_BIT)
{
@ -1273,6 +1283,29 @@ void CBaseAnimating::DispatchAnimEvents ( CBaseAnimating *eventHandler )
}
}
#ifdef MAPBASE_VSCRIPT
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseAnimating::ScriptHookHandleAnimEvent( animevent_t *pEvent )
{
if (m_ScriptScope.IsInitialized() && g_Hook_HandleAnimEvent.CanRunInScope(m_ScriptScope))
{
HSCRIPT hEvent = g_pScriptVM->RegisterInstance( pEvent );
// event
ScriptVariant_t args[] = { hEvent };
ScriptVariant_t returnValue = true;
g_Hook_HandleAnimEvent.Call( m_ScriptScope, &returnValue, args );
g_pScriptVM->RemoveInstance( hEvent );
return returnValue.m_bool;
}
return true;
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------

View File

@ -144,6 +144,9 @@ public:
bool HasAnimEvent( int nSequence, int nEvent );
virtual void DispatchAnimEvents ( CBaseAnimating *eventHandler ); // Handle events that have happend since last time called up until X seconds into the future
virtual void HandleAnimEvent( animevent_t *pEvent );
#ifdef MAPBASE_VSCRIPT
bool ScriptHookHandleAnimEvent( animevent_t *pEvent );
#endif
int LookupPoseParameter( CStudioHdr *pStudioHdr, const char *szName );
inline int LookupPoseParameter( const char *szName ) { return LookupPoseParameter(GetModelPtr(), szName); }
@ -211,6 +214,7 @@ public:
void SetSkin( int iSkin ) { m_nSkin = iSkin; }
static ScriptHook_t g_Hook_OnServerRagdoll;
static ScriptHook_t g_Hook_HandleAnimEvent;
#endif
// These return the attachment in the space of the entity

View File

@ -2225,6 +2225,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC( SetModel, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelName, "GetModelName", "Returns the name of the model" )
DEFINE_SCRIPTFUNC_NAMED( ScriptStopSound, "StopSound", "Stops a sound from this entity." )
DEFINE_SCRIPTFUNC_NAMED( ScriptEmitSound, "EmitSound", "Plays a sound from this entity." )
DEFINE_SCRIPTFUNC_NAMED( VScriptPrecacheScriptSound, "PrecacheSoundScript", "Precache a sound for later playing." )
DEFINE_SCRIPTFUNC_NAMED( ScriptSoundDuration, "GetSoundDuration", "Returns float duration of the sound. Takes soundname and optional actormodelname.")
@ -2269,6 +2270,9 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC( ApplyAbsVelocityImpulse, "" )
DEFINE_SCRIPTFUNC( ApplyLocalAngularVelocityImpulse, "" )
DEFINE_SCRIPTFUNC( BodyTarget, "" )
DEFINE_SCRIPTFUNC( HeadTarget, "" )
#endif
DEFINE_SCRIPTFUNC_NAMED( GetAbsVelocity, "GetVelocity", "" )
@ -2285,11 +2289,11 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC_NAMED( ScriptSetAngles, "SetAngles", "Set entity pitch, yaw, roll")
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAngles, "GetAngles", "Get entity pitch, yaw, roll as a vector")
DEFINE_SCRIPTFUNC_NAMED( ScriptSetSize, "SetSize", "" )
DEFINE_SCRIPTFUNC( SetSize, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMins, "GetBoundingMins", "Get a vector containing min bounds, centered on object")
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMaxs, "GetBoundingMaxs", "Get a vector containing max bounds, centered on object")
DEFINE_SCRIPTFUNC_NAMED( ScriptUtilRemove, "Destroy", "" )
DEFINE_SCRIPTFUNC_NAMED( Remove, "Destroy", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetOwner, "SetOwner", "" )
DEFINE_SCRIPTFUNC_NAMED( GetTeamNumber, "GetTeam", "" )
DEFINE_SCRIPTFUNC_NAMED( ChangeTeam, "SetTeam", "" )
@ -2590,10 +2594,10 @@ void CBaseEntity::UpdateOnRemove( void )
#ifdef MAPBASE_VSCRIPT
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
{
HSCRIPT h = m_ScriptThinkFuncs[i].m_hfnThink;
HSCRIPT h = m_ScriptThinkFuncs[i]->m_hfnThink;
if ( h ) g_pScriptVM->ReleaseScript( h );
}
m_ScriptThinkFuncs.Purge();
m_ScriptThinkFuncs.PurgeAndDeleteElements();
#endif // MAPBASE_VSCRIPT
}
}
@ -8675,173 +8679,6 @@ void CBaseEntity::ScriptStopThinkFunction()
m_iszScriptThinkFunction = NULL_STRING;
SetContextThink( NULL, TICK_NEVER_THINK, "ScriptThink" );
}
static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
{
g_pScriptVM->ReleaseScript( context->m_hfnThink );
context->m_hfnThink = NULL;
context->m_nNextThinkTick = TICK_NEVER_THINK;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptContextThink()
{
float flNextThink = FLT_MAX;
int nScheduledTick = 0;
for ( int i = m_ScriptThinkFuncs.Count(); i--; )
{
scriptthinkfunc_t *cur = &m_ScriptThinkFuncs[i];
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
continue;
if ( cur->m_nNextThinkTick > gpGlobals->tickcount )
{
// There is more to execute, don't stop thinking if the rest are done.
// also find the shortest schedule
if ( !nScheduledTick || nScheduledTick > cur->m_nNextThinkTick )
{
nScheduledTick = cur->m_nNextThinkTick;
}
continue;
}
ScriptVariant_t varReturn;
if ( cur->m_bNoParam )
{
if ( g_pScriptVM->Call( cur->m_hfnThink, NULL, true, &varReturn ) == SCRIPT_ERROR )
{
ScriptStopContextThink(cur);
m_ScriptThinkFuncs.Remove(i);
continue;
}
}
else
{
if ( g_pScriptVM->Call( cur->m_hfnThink, NULL, true, &varReturn, m_hScriptInstance ) == SCRIPT_ERROR )
{
ScriptStopContextThink(cur);
m_ScriptThinkFuncs.Remove(i);
continue;
}
}
float flReturn;
if ( !varReturn.AssignTo( &flReturn ) )
{
ScriptStopContextThink(cur);
m_ScriptThinkFuncs.Remove(i);
continue;
}
if ( flReturn < 0.0f )
{
ScriptStopContextThink(cur);
m_ScriptThinkFuncs.Remove(i);
continue;
}
// find the shortest delay
if ( flReturn < flNextThink )
{
flNextThink = flReturn;
}
cur->m_nNextThinkTick = TIME_TO_TICKS( gpGlobals->curtime + flReturn );
}
if ( flNextThink < FLT_MAX )
{
SetNextThink( gpGlobals->curtime + flNextThink, "ScriptContextThink" );
}
else if ( nScheduledTick )
{
SetNextThink( TICKS_TO_TIME( nScheduledTick ), "ScriptContextThink" );
}
else
{
SetNextThink( TICK_NEVER_THINK, "ScriptContextThink" );
}
}
// see ScriptSetThink
static bool s_bScriptContextThinkNoParam = false;
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float flTime )
{
scriptthinkfunc_t th;
V_memset( &th, 0x0, sizeof(scriptthinkfunc_t) );
unsigned short hash = ( szContext && *szContext ) ? HashString( szContext ) : 0;
bool bFound = false;
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
{
scriptthinkfunc_t f = m_ScriptThinkFuncs[i];
if ( hash == f.m_iContextHash )
{
th = f;
m_ScriptThinkFuncs.Remove(i); // reorder
bFound = true;
break;
}
}
if ( hFunc )
{
float nextthink = gpGlobals->curtime + flTime;
th.m_bNoParam = s_bScriptContextThinkNoParam;
th.m_hfnThink = hFunc;
th.m_iContextHash = hash;
th.m_nNextThinkTick = TIME_TO_TICKS( nextthink );
m_ScriptThinkFuncs.AddToHead( th );
int nexttick = GetNextThinkTick( RegisterThinkContext( "ScriptContextThink" ) );
// sooner than next think
if ( nexttick <= 0 || nexttick > th.m_nNextThinkTick )
{
SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" );
}
}
// null func input, think exists
else if ( bFound )
{
ScriptStopContextThink( &th );
}
}
//-----------------------------------------------------------------------------
// m_bNoParam and s_bScriptContextThinkNoParam exist only to keep backwards compatibility
// and are an alternative to this script closure:
//
// function CBaseEntity::SetThink( func, time )
// {
// SetContextThink( "", function(_){ return func() }, time )
// }
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time )
{
s_bScriptContextThinkNoParam = true;
ScriptSetContextThink( NULL, hFunc, time );
s_bScriptContextThinkNoParam = false;
}
void CBaseEntity::ScriptStopThink()
{
ScriptSetContextThink( NULL, NULL, 0.0f );
}
#endif // MAPBASE_VSCRIPT
//-----------------------------------------------------------------------------

View File

@ -352,9 +352,9 @@ struct thinkfunc_t
#ifdef MAPBASE_VSCRIPT
struct scriptthinkfunc_t
{
int m_nNextThinkTick;
HSCRIPT m_hfnThink;
unsigned short m_iContextHash;
int m_nNextThinkTick;
bool m_bNoParam;
};
#endif
@ -2025,7 +2025,7 @@ public:
void ScriptStopThink();
void ScriptContextThink();
private:
CUtlVector< scriptthinkfunc_t > m_ScriptThinkFuncs;
CUtlVector< scriptthinkfunc_t* > m_ScriptThinkFuncs;
public:
#endif
const char* GetScriptId();
@ -2056,8 +2056,10 @@ public:
const Vector& ScriptGetAngles(void) { static Vector vec; QAngle qa = GetAbsAngles(); vec.x = qa.x; vec.y = qa.y; vec.z = qa.z; return vec; }
#endif
#ifndef MAPBASE_VSCRIPT
void ScriptSetSize(const Vector& mins, const Vector& maxs) { UTIL_SetSize(this, mins, maxs); }
void ScriptUtilRemove(void) { UTIL_Remove(this); }
#endif
void ScriptSetOwner(HSCRIPT hEntity) { SetOwnerEntity(ToEnt(hEntity)); }
void ScriptSetOrigin(const Vector& v) { Teleport(&v, NULL, NULL); }
void ScriptSetForward(const Vector& v) { QAngle angles; VectorAngles(v, angles); Teleport(NULL, &angles, NULL); }
@ -2083,6 +2085,7 @@ public:
const char* ScriptGetModelName(void) const;
HSCRIPT ScriptGetModelKeyValues(void);
void ScriptStopSound(const char* soundname);
void ScriptEmitSound(const char* soundname);
float ScriptSoundDuration(const char* soundname, const char* actormodel);

View File

@ -450,6 +450,11 @@ protected:
bool m_bSolidBsp; // Brush is SOLID_BSP
#ifdef MAPBASE
int m_iMinPitch = 30; // FANPITCHMIN
int m_iMaxPitch = 100; // FANPITCHMAX
#endif
public:
Vector m_vecClientOrigin;
QAngle m_vecClientAngles;
@ -472,6 +477,10 @@ BEGIN_DATADESC( CFuncRotating )
DEFINE_FIELD( m_angStart, FIELD_VECTOR ),
DEFINE_FIELD( m_bStopAtStartPos, FIELD_BOOLEAN ),
DEFINE_KEYFIELD( m_bSolidBsp, FIELD_BOOLEAN, "solidbsp" ),
#ifdef MAPBASE
DEFINE_KEYFIELD( m_iMinPitch, FIELD_INTEGER, "minpitch" ),
DEFINE_KEYFIELD( m_iMaxPitch, FIELD_INTEGER, "maxpitch" ),
#endif
// Function Pointers
DEFINE_FUNCTION( SpinUpMove ),
@ -823,8 +832,14 @@ void CFuncRotating::HurtTouch ( CBaseEntity *pOther )
}
#ifdef MAPBASE
// In Mapbase, use the keyvalues instead
#define FANPITCHMIN m_iMinPitch
#define FANPITCHMAX m_iMaxPitch
#else
#define FANPITCHMIN 30
#define FANPITCHMAX 100
#endif
//-----------------------------------------------------------------------------

View File

@ -850,7 +850,7 @@ void CEventQueue::Dump( void )
// Purpose: adds the action into the correct spot in the priority queue, targeting entity via string name
//-----------------------------------------------------------------------------
#ifdef MAPBASE_VSCRIPT
intptr_t
int
#else
void
#endif
@ -874,6 +874,7 @@ CEventQueue::AddEvent( const char *target, const char *targetInput, variant_t Va
AddEvent( newEvent );
#ifdef MAPBASE_VSCRIPT
Assert( sizeof(EventQueuePrioritizedEvent_t*) == sizeof(int) );
return reinterpret_cast<intptr_t>(newEvent); // POINTER_TO_INT
#endif
}
@ -882,7 +883,7 @@ CEventQueue::AddEvent( const char *target, const char *targetInput, variant_t Va
// Purpose: adds the action into the correct spot in the priority queue, targeting entity via pointer
//-----------------------------------------------------------------------------
#ifdef MAPBASE_VSCRIPT
intptr_t
int
#else
void
#endif
@ -906,6 +907,7 @@ CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, variant_t V
AddEvent( newEvent );
#ifdef MAPBASE_VSCRIPT
Assert( sizeof(EventQueuePrioritizedEvent_t*) == sizeof(int) );
return reinterpret_cast<intptr_t>(newEvent); // POINTER_TO_INT
#endif
}
@ -1293,7 +1295,7 @@ void CEventQueue::CancelEventsByInput( CBaseEntity *pTarget, const char *szInput
}
}
bool CEventQueue::RemoveEvent( intptr_t event )
bool CEventQueue::RemoveEvent( int event )
{
EventQueuePrioritizedEvent_t *pe = reinterpret_cast<EventQueuePrioritizedEvent_t*>(event); // INT_TO_POINTER
@ -1310,7 +1312,7 @@ bool CEventQueue::RemoveEvent( intptr_t event )
return false;
}
float CEventQueue::GetTimeLeft( intptr_t event )
float CEventQueue::GetTimeLeft( int event )
{
EventQueuePrioritizedEvent_t *pe = reinterpret_cast<EventQueuePrioritizedEvent_t*>(event); // INT_TO_POINTER

View File

@ -104,6 +104,13 @@ extern void FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseE
#define MAX_OLD_ENEMIES 4 // how many old enemies to remember
#ifdef MAPBASE
// Use the model keyvalue if it is defined
#define DefaultOrCustomModel(defaultModel) GetModelName() != NULL_STRING ? STRING(GetModelName()) : defaultModel
#else
#define DefaultOrCustomModel() defaultModel
#endif
// used by suit voice to indicate damage sustained and repaired type to player
enum

View File

@ -48,6 +48,7 @@ BEGIN_DATADESC( CEnvMicrophone )
DEFINE_KEYFIELD(m_iszLandmarkName, FIELD_STRING, "landmark"),
DEFINE_FIELD(m_hLandmark, FIELD_EHANDLE),
DEFINE_KEYFIELD(m_flPitchScale, FIELD_FLOAT, "PitchScale"),
DEFINE_KEYFIELD(m_flVolumeScale, FIELD_FLOAT, "VolumeScale"),
DEFINE_KEYFIELD(m_nChannel, FIELD_INTEGER, "channel"),
#endif
// DEFINE_FIELD(m_bAvoidFeedback, FIELD_BOOLEAN), // DONT SAVE
@ -61,6 +62,7 @@ BEGIN_DATADESC( CEnvMicrophone )
#ifdef MAPBASE
DEFINE_INPUTFUNC(FIELD_INTEGER, "SetDSPPreset", InputSetDSPPreset),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetPitchScale", InputSetPitchScale ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetVolumeScale", InputSetVolumeScale ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetChannel", InputSetChannel ),
#endif
@ -272,6 +274,15 @@ void CEnvMicrophone::InputSetPitchScale( inputdata_t &inputdata )
m_flPitchScale = inputdata.value.Float();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &inputdata -
//-----------------------------------------------------------------------------
void CEnvMicrophone::InputSetVolumeScale( inputdata_t &inputdata )
{
m_flVolumeScale = inputdata.value.Float();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &inputdata -
@ -545,11 +556,13 @@ MicrophoneResult_t CEnvMicrophone::SoundPlayed( int entindex, const char *soundn
EmitSound_t ep;
#ifdef MAPBASE
ep.m_nChannel = m_nChannel;
if (m_flVolumeScale != 1.0f)
ep.m_flVolume = (flVolume * m_flVolumeScale);
#else
ep.m_nChannel = CHAN_STATIC;
ep.m_flVolume = flVolume;
#endif
ep.m_pSoundName = soundname;
ep.m_flVolume = flVolume;
ep.m_SoundLevel = soundlevel;
ep.m_nFlags = iFlags;
#ifdef MAPBASE

View File

@ -57,6 +57,7 @@ public:
#ifdef MAPBASE
void InputSetDSPPreset( inputdata_t &inputdata );
void InputSetPitchScale( inputdata_t &inputdata );
void InputSetVolumeScale( inputdata_t &inputdata );
void InputSetChannel( inputdata_t &inputdata );
#endif
@ -88,6 +89,7 @@ private:
string_t m_iszLandmarkName;
EHANDLE m_hLandmark;
float m_flPitchScale = 1.0f;
float m_flVolumeScale = 1.0f;
int m_nChannel = CHAN_STATIC;
#endif

View File

@ -41,8 +41,8 @@ class CEventQueue
public:
// pushes an event into the queue, targeting a string name (m_iName), or directly by a pointer
#ifdef MAPBASE_VSCRIPT
intptr_t AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
intptr_t AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
int AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
int AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
#else
void AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
void AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
@ -73,8 +73,8 @@ public:
#ifdef MAPBASE_VSCRIPT
void CancelEventsByInput( CBaseEntity *pTarget, const char *szInput );
bool RemoveEvent( intptr_t event );
float GetTimeLeft( intptr_t event );
bool RemoveEvent( int event );
float GetTimeLeft( int event );
#endif // MAPBASE_VSCRIPT
private:

View File

@ -278,6 +278,7 @@ public:
CUtlDict<string_t, int> m_QueuedKV;
int m_MaxArmor = 100;
int m_SuitZoomFOV = 25;
#endif
bool PassesDamageFilter( const CTakeDamageInfo &info );
@ -1760,7 +1761,11 @@ void CHL2_Player::ToggleZoom(void)
//-----------------------------------------------------------------------------
void CHL2_Player::StartZooming( void )
{
#ifdef MAPBASE
int iFOV = GetPlayerProxy() ? GetPlayerProxy()->m_SuitZoomFOV : 25;
#else
int iFOV = 25;
#endif
if ( SetFOV( this, iFOV, 0.4f ) )
{
m_HL2Local.m_bZooming = true;
@ -4615,6 +4620,7 @@ BEGIN_DATADESC( CLogicPlayerProxy )
DEFINE_INPUTFUNC( FIELD_STRING, "SetPlayerModel", InputSetPlayerModel ),
DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetPlayerDrawExternally", InputSetPlayerDrawExternally ),
DEFINE_INPUT( m_MaxArmor, FIELD_INTEGER, "SetMaxInputArmor" ),
DEFINE_INPUT( m_SuitZoomFOV, FIELD_INTEGER, "SetSuitZoomFOV" ),
#endif
DEFINE_FIELD( m_hPlayer, FIELD_EHANDLE ),
END_DATADESC()

View File

@ -303,7 +303,7 @@ public:
virtual bool IsHoldingEntity( CBaseEntity *pEnt );
virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis );
virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject );
virtual CBaseEntity *CHL2_Player::GetHeldObject( void );
virtual CBaseEntity *GetHeldObject( void );
virtual bool IsFollowingPhysics( void ) { return (m_afPhysicsFlags & PFLAG_ONBARNACLE) > 0; }
void InputForceDropPhysObjects( inputdata_t &data );

View File

@ -23,12 +23,12 @@ public:
void Spawn( void )
{
Precache( );
SetModel( "models/items/battery.mdl" );
SetModel( DefaultOrCustomModel( "models/items/battery.mdl" ) );
BaseClass::Spawn( );
}
void Precache( void )
{
PrecacheModel ("models/items/battery.mdl");
PrecacheModel( DefaultOrCustomModel( "models/items/battery.mdl" ) );
PrecacheScriptSound( "ItemBattery.Touch" );
@ -36,10 +36,30 @@ public:
bool MyTouch( CBasePlayer *pPlayer )
{
CHL2_Player *pHL2Player = dynamic_cast<CHL2_Player *>( pPlayer );
#ifdef MAPBASE
return ( pHL2Player && pHL2Player->ApplyBattery( m_flPowerMultiplier ) );
#else
return ( pHL2Player && pHL2Player->ApplyBattery() );
#endif
}
#ifdef MAPBASE
void InputSetPowerMultiplier( inputdata_t &inputdata ) { m_flPowerMultiplier = inputdata.value.Float(); }
float m_flPowerMultiplier = 1.0f;
DECLARE_DATADESC();
#endif
};
LINK_ENTITY_TO_CLASS(item_battery, CItemBattery);
PRECACHE_REGISTER(item_battery);
#ifdef MAPBASE
BEGIN_DATADESC( CItemBattery )
DEFINE_KEYFIELD( m_flPowerMultiplier, FIELD_FLOAT, "PowerMultiplier" ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetPowerMultiplier", InputSetPowerMultiplier ),
END_DATADESC()
#endif

View File

@ -30,11 +30,29 @@ public:
void Spawn( void );
void Precache( void );
bool MyTouch( CBasePlayer *pPlayer );
#ifdef MAPBASE
float GetItemAmount() { return sk_healthkit.GetFloat() * m_flHealthMultiplier; }
void InputSetHealthMultiplier( inputdata_t &inputdata ) { m_flHealthMultiplier = inputdata.value.Float(); }
float m_flHealthMultiplier = 1.0f;
DECLARE_DATADESC();
#endif
};
LINK_ENTITY_TO_CLASS( item_healthkit, CHealthKit );
PRECACHE_REGISTER(item_healthkit);
#ifdef MAPBASE
BEGIN_DATADESC( CHealthKit )
DEFINE_KEYFIELD( m_flHealthMultiplier, FIELD_FLOAT, "HealthMultiplier" ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetHealthMultiplier", InputSetHealthMultiplier ),
END_DATADESC()
#endif
//-----------------------------------------------------------------------------
// Purpose:
@ -66,7 +84,11 @@ void CHealthKit::Precache( void )
//-----------------------------------------------------------------------------
bool CHealthKit::MyTouch( CBasePlayer *pPlayer )
{
#ifdef MAPBASE
if ( pPlayer->TakeHealth( GetItemAmount(), DMG_GENERIC ) )
#else
if ( pPlayer->TakeHealth( sk_healthkit.GetFloat(), DMG_GENERIC ) )
#endif
{
CSingleUserRecipientFilter user( pPlayer );
user.MakeReliable();
@ -119,7 +141,11 @@ public:
bool MyTouch( CBasePlayer *pPlayer )
{
#ifdef MAPBASE
if ( pPlayer->TakeHealth( GetItemAmount(), DMG_GENERIC ) )
#else
if ( pPlayer->TakeHealth( sk_healthvial.GetFloat(), DMG_GENERIC ) )
#endif
{
CSingleUserRecipientFilter user( pPlayer );
user.MakeReliable();
@ -145,11 +171,132 @@ public:
return false;
}
#ifdef MAPBASE
float GetItemAmount() { return sk_healthvial.GetFloat() * m_flHealthMultiplier; }
void InputSetHealthMultiplier( inputdata_t &inputdata ) { m_flHealthMultiplier = inputdata.value.Float(); }
float m_flHealthMultiplier = 1.0f;
DECLARE_DATADESC();
#endif
};
LINK_ENTITY_TO_CLASS( item_healthvial, CHealthVial );
PRECACHE_REGISTER( item_healthvial );
#ifdef MAPBASE
BEGIN_DATADESC( CHealthVial )
DEFINE_KEYFIELD( m_flHealthMultiplier, FIELD_FLOAT, "HealthMultiplier" ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetHealthMultiplier", InputSetHealthMultiplier ),
END_DATADESC()
//-----------------------------------------------------------------------------
// Small health kit. Heals the player when picked up.
//-----------------------------------------------------------------------------
class CHealthKitCustom : public CItem
{
public:
DECLARE_CLASS( CHealthKitCustom, CItem );
CHealthKitCustom();
void Spawn( void );
void Precache( void );
bool MyTouch( CBasePlayer *pPlayer );
float GetItemAmount() { return m_flHealthAmount; }
void InputSetHealthAmount( inputdata_t &inputdata ) { m_flHealthAmount = inputdata.value.Float(); }
float m_flHealthAmount;
string_t m_iszTouchSound;
DECLARE_DATADESC();
};
LINK_ENTITY_TO_CLASS( item_healthkit_custom, CHealthKitCustom );
//PRECACHE_REGISTER(item_healthkit_custom);
#ifdef MAPBASE
BEGIN_DATADESC( CHealthKitCustom )
DEFINE_KEYFIELD( m_flHealthAmount, FIELD_FLOAT, "HealthAmount" ),
DEFINE_KEYFIELD( m_iszTouchSound, FIELD_STRING, "TouchSound" ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetHealthAmount", InputSetHealthAmount ),
END_DATADESC()
#endif
CHealthKitCustom::CHealthKitCustom()
{
SetModelName( AllocPooledString( "models/items/healthkit.mdl" ) );
m_flHealthAmount = sk_healthkit.GetFloat();
m_iszTouchSound = AllocPooledString( "HealthKit.Touch" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHealthKitCustom::Spawn( void )
{
Precache();
SetModel( STRING( GetModelName() ) );
BaseClass::Spawn();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHealthKitCustom::Precache( void )
{
PrecacheModel( STRING( GetModelName() ) );
PrecacheScriptSound( STRING( m_iszTouchSound ) );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
// Output :
//-----------------------------------------------------------------------------
bool CHealthKitCustom::MyTouch( CBasePlayer *pPlayer )
{
if ( pPlayer->TakeHealth( GetItemAmount(), DMG_GENERIC ) )
{
CSingleUserRecipientFilter user( pPlayer );
user.MakeReliable();
UserMessageBegin( user, "ItemPickup" );
WRITE_STRING( GetClassname() );
MessageEnd();
CPASAttenuationFilter filter( pPlayer, STRING( m_iszTouchSound ) );
EmitSound( filter, pPlayer->entindex(), STRING( m_iszTouchSound ) );
if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES )
{
Respawn();
}
else
{
UTIL_Remove(this);
}
return true;
}
return false;
}
#endif
//-----------------------------------------------------------------------------
// Wall mounted health kit. Heals the player when used.
//-----------------------------------------------------------------------------

View File

@ -334,6 +334,10 @@ private:
bool IsPlayerAllySniper();
#ifdef MAPBASE
const Vector &GetPaintCursor() { return m_vecPaintCursor; }
#endif
private:
/// This is the variable from which m_flPaintTime gets set.
@ -403,6 +407,9 @@ private:
DEFINE_CUSTOM_AI;
DECLARE_DATADESC();
#ifdef MAPBASE_VSCRIPT
DECLARE_ENT_SCRIPTDESC();
#endif
};
@ -500,6 +507,26 @@ BEGIN_DATADESC( CProtoSniper )
END_DATADESC()
#ifdef MAPBASE_VSCRIPT
BEGIN_ENT_SCRIPTDESC( CProtoSniper, CAI_BaseNPC, "Combine sniper NPC." )
DEFINE_SCRIPTFUNC( GetBulletSpeed, "" )
DEFINE_SCRIPTFUNC( GetBulletOrigin, "" )
DEFINE_SCRIPTFUNC( ScopeGlint, "" )
DEFINE_SCRIPTFUNC( GetPositionParameter, "" )
DEFINE_SCRIPTFUNC( IsSweepingRandomly, "" )
DEFINE_SCRIPTFUNC( FindFrustratedShot, "" )
DEFINE_SCRIPTFUNC( IsLaserOn, "" )
DEFINE_SCRIPTFUNC( LaserOn, "" )
DEFINE_SCRIPTFUNC( LaserOff, "" )
DEFINE_SCRIPTFUNC( GetPaintCursor, "Get the point the sniper is currently aiming at." )
END_SCRIPTDESC()
#endif
//=========================================================
@ -2588,6 +2615,19 @@ Vector CProtoSniper::DesiredBodyTarget( CBaseEntity *pTarget )
// By default, aim for the center
Vector vecTarget = pTarget->WorldSpaceCenter();
#ifdef MAPBASE_VSCRIPT
if (m_ScriptScope.IsInitialized() && g_Hook_GetActualShootPosition.CanRunInScope(m_ScriptScope))
{
ScriptVariant_t functionReturn;
ScriptVariant_t args[] = { GetBulletOrigin(), ToHScript( pTarget ) };
if (g_Hook_GetActualShootPosition.Call( m_ScriptScope, &functionReturn, args ))
{
if (functionReturn.m_type == FIELD_VECTOR && functionReturn.m_pVector->LengthSqr() != 0.0f)
return *functionReturn.m_pVector;
}
}
#endif
float flTimeSinceLastMiss = gpGlobals->curtime - m_flTimeLastShotMissed;
if( pTarget->GetFlags() & FL_CLIENT )

View File

@ -90,9 +90,12 @@ public:
#ifdef MAPBASE
// This is in CBaseEntity, but I can't find a use for it anywhere.
// Must not have been fully implemented. Please remove this if it turns out to be something important.
// It may have been originally intended for TF2 or some other game-specific item class. Please remove this if it turns out to be something important.
virtual bool IsCombatItem() { return true; }
// Used to access item_healthkit values, etc. from outside of the class
virtual float GetItemAmount() { return 1.0f; }
void InputEnablePlayerPickup( inputdata_t &inputdata );
void InputDisablePlayerPickup( inputdata_t &inputdata );
void InputEnableNPCPickup( inputdata_t &inputdata );

View File

@ -0,0 +1,136 @@
//===== Copyright © 1996-2009, Valve Corporation, All rights reserved. ======//
//
// Purpose: Plays a movie and reports on finish
//
//===========================================================================//
#include "cbase.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CLogicPlayMovie : public CLogicalEntity
{
public:
DECLARE_CLASS( CLogicPlayMovie, CLogicalEntity );
DECLARE_DATADESC();
CLogicPlayMovie( void ) { }
~CLogicPlayMovie( void ) { }
virtual void Precache( void );
virtual void Spawn( void );
private:
void InputPlayMovie( inputdata_t &data );
#ifdef MAPBASE
void InputStopMovie( inputdata_t &data );
#endif
void InputMovieFinished( inputdata_t &data );
string_t m_strMovieFilename;
bool m_bAllowUserSkip;
#ifdef MAPBASE
bool m_bLooping;
bool m_bMuted;
bool m_bPlayingVideo;
#endif
COutputEvent m_OnPlaybackFinished;
};
LINK_ENTITY_TO_CLASS( logic_playmovie, CLogicPlayMovie );
BEGIN_DATADESC( CLogicPlayMovie )
DEFINE_KEYFIELD( m_strMovieFilename, FIELD_STRING, "MovieFilename" ),
DEFINE_KEYFIELD( m_bAllowUserSkip, FIELD_BOOLEAN, "allowskip" ),
#ifdef MAPBASE
DEFINE_KEYFIELD( m_bLooping, FIELD_BOOLEAN, "loopvideo" ),
DEFINE_KEYFIELD( m_bMuted, FIELD_BOOLEAN, "mute" ),
DEFINE_FIELD( m_bPlayingVideo, FIELD_BOOLEAN ),
#endif
DEFINE_INPUTFUNC( FIELD_VOID, "PlayMovie", InputPlayMovie ),
#ifdef MAPBASE
DEFINE_INPUTFUNC( FIELD_VOID, "StopMovie", InputStopMovie ),
#endif
DEFINE_INPUTFUNC( FIELD_VOID, "__MovieFinished", InputMovieFinished ),
DEFINE_OUTPUT( m_OnPlaybackFinished, "OnPlaybackFinished" ),
END_DATADESC()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CLogicPlayMovie::Precache( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CLogicPlayMovie::Spawn( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CLogicPlayMovie::InputPlayMovie( inputdata_t &data )
{
// Build the hacked string
char szClientCmd[256];
Q_snprintf( szClientCmd, sizeof(szClientCmd),
"playvideo_complex %s \"ent_fire %s __MovieFinished\" %d %d %d\n",
STRING(m_strMovieFilename),
GetEntityNameAsCStr(),
m_bAllowUserSkip,
#ifdef MAPBASE
m_bLooping,
m_bMuted
#else
0,
0
#endif
);
// Send it on
engine->ServerCommand( szClientCmd );
#ifdef MAPBASE
m_bPlayingVideo = true;
#endif
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CLogicPlayMovie::InputStopMovie( inputdata_t &data )
{
if (m_bPlayingVideo)
{
// Send it on
engine->ServerCommand( "stopvideos\n" );
}
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CLogicPlayMovie::InputMovieFinished( inputdata_t &data )
{
// Simply fire our output
m_OnPlaybackFinished.FireOutput( this, this );
#ifdef MAPBASE
m_bPlayingVideo = false;
#endif
}

View File

@ -199,7 +199,7 @@ void CLogicExternalData::InputWriteKeyValue( inputdata_t &inputdata )
// Separate key from value
char *delimiter = Q_strstr(szValue, " ");
if (delimiter && (delimiter + 1) != '\0')
if (delimiter && delimiter[1] != '\0')
{
Q_strncpy(key, szValue, MIN((delimiter - szValue) + 1, sizeof(key)));
Q_strncpy(value, delimiter + 1, sizeof(value));

View File

@ -0,0 +1,437 @@
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
//
// Purpose: Displays easy, flexible VGui text. Mapbase equivalent of point_worldtext.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "vguiscreen.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define SF_TESTDISPLAY_START_DISABLED (1 << 0)
//-----------------------------------------------------------------------------
// vgui_text_display
//-----------------------------------------------------------------------------
class CVGuiTextDisplay : public CBaseEntity
{
public:
DECLARE_CLASS( CVGuiTextDisplay, CBaseEntity );
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
CVGuiTextDisplay();
virtual ~CVGuiTextDisplay();
virtual bool KeyValue( const char *szKeyName, const char *szValue );
virtual int UpdateTransmitState();
virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
virtual void Spawn( void );
virtual void Precache( void );
virtual void OnRestore( void );
void ScreenVisible( bool bVisible );
void Disable( void );
void Enable( void );
void InputDisable( inputdata_t &inputdata );
void InputEnable( inputdata_t &inputdata );
void InputToggle( inputdata_t &inputdata );
void InputSetMessage( inputdata_t &inputdata );
void InputSetTextAlignment( inputdata_t &inputdata );
void InputSetFont( inputdata_t &inputdata );
void InputSetResolution( inputdata_t &inputdata );
void InputSetTextSize( inputdata_t &inputdata );
private:
// Control panel
void GetControlPanelInfo( int nPanelIndex, const char *&pPanelName );
void GetControlPanelClassName( int nPanelIndex, const char *&pPanelName );
void SpawnControlPanels( void );
void RestoreControlPanels( void );
private:
CNetworkVar( bool, m_bEnabled );
CNetworkString( m_szDisplayText, 256 );
CNetworkVar( int, m_iContentAlignment );
CNetworkString( m_szFont, 64 );
CNetworkVar( int, m_iResolution );
float m_flTextSize;
//CNetworkColor32( m_DisplayColor ); // Use render color
bool m_bDoFullTransmit;
CHandle<CVGuiScreen> m_hScreen;
};
LINK_ENTITY_TO_CLASS( vgui_text_display, CVGuiTextDisplay );
//-----------------------------------------------------------------------------
// Save/load
//-----------------------------------------------------------------------------
BEGIN_DATADESC( CVGuiTextDisplay )
DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ),
DEFINE_AUTO_ARRAY_KEYFIELD( m_szDisplayText, FIELD_CHARACTER, "message" ),
DEFINE_KEYFIELD( m_iContentAlignment, FIELD_INTEGER, "alignment" ),
DEFINE_AUTO_ARRAY_KEYFIELD( m_szFont, FIELD_CHARACTER, "font" ),
DEFINE_KEYFIELD( m_iResolution, FIELD_INTEGER, "resolution" ),
DEFINE_KEYFIELD( m_flTextSize, FIELD_FLOAT, "textsize" ),
DEFINE_FIELD( m_bDoFullTransmit, FIELD_BOOLEAN ),
DEFINE_FIELD( m_hScreen, FIELD_EHANDLE ),
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetMessage", InputSetMessage ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTextAlignment", InputSetTextAlignment ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetFont", InputSetFont ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetResolution", InputSetResolution ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetPanelSize", InputSetTextSize ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CVGuiTextDisplay, DT_VGuiTextDisplay )
SendPropBool( SENDINFO( m_bEnabled ) ),
SendPropString( SENDINFO( m_szDisplayText ) ),
SendPropInt( SENDINFO( m_iContentAlignment ) ),
SendPropString( SENDINFO( m_szFont ) ),
SendPropInt( SENDINFO( m_iResolution ) ),
END_SEND_TABLE()
CVGuiTextDisplay::CVGuiTextDisplay()
{
m_flTextSize = 100.0f;
m_iResolution = 200;
m_iContentAlignment = 7; // a_south
}
CVGuiTextDisplay::~CVGuiTextDisplay()
{
DestroyVGuiScreen( m_hScreen.Get() );
}
//-----------------------------------------------------------------------------
// Read in Hammer data
//-----------------------------------------------------------------------------
bool CVGuiTextDisplay::KeyValue( const char *szKeyName, const char *szValue )
{
// NOTE: Have to do these separate because they set two values instead of one
if( FStrEq( szKeyName, "angles" ) )
{
Assert( GetMoveParent() == NULL );
QAngle angles;
UTIL_StringToVector( angles.Base(), szValue );
// Because the vgui screen basis is strange (z is front, y is up, x is right)
// we need to rotate the typical basis before applying it
VMatrix mat, rotation, tmp;
MatrixFromAngles( angles, mat );
MatrixBuildRotationAboutAxis( rotation, Vector( 0, 1, 0 ), 90 );
MatrixMultiply( mat, rotation, tmp );
MatrixBuildRotateZ( rotation, 90 );
MatrixMultiply( tmp, rotation, mat );
MatrixToAngles( mat, angles );
SetAbsAngles( angles );
}
else if( FStrEq( szKeyName, "message" ) )
{
Q_strcpy( m_szDisplayText.GetForModify(), szValue );
}
else if( FStrEq( szKeyName, "font" ) )
{
Q_strcpy( m_szFont.GetForModify(), szValue );
}
else if( FStrEq( szKeyName, "color" ) )
{
// Use render color
return BaseClass::KeyValue( "rendercolor", szValue );
}
else
return BaseClass::KeyValue( szKeyName, szValue );
return true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CVGuiTextDisplay::UpdateTransmitState()
{
if ( m_bDoFullTransmit )
{
m_bDoFullTransmit = false;
return SetTransmitState( FL_EDICT_ALWAYS );
}
return SetTransmitState( FL_EDICT_FULLCHECK );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways )
{
// Are we already marked for transmission?
if ( pInfo->m_pTransmitEdict->Get( entindex() ) )
return;
BaseClass::SetTransmit( pInfo, bAlways );
// Force our screen to be sent too.
m_hScreen->SetTransmit( pInfo, bAlways );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::Spawn( void )
{
Precache();
BaseClass::Spawn();
m_bEnabled = !HasSpawnFlags( SF_TESTDISPLAY_START_DISABLED );
SpawnControlPanels();
ScreenVisible( m_bEnabled );
m_bDoFullTransmit = true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::Precache( void )
{
BaseClass::Precache();
PrecacheVGuiScreen( "text_display_panel" );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::OnRestore( void )
{
BaseClass::OnRestore();
RestoreControlPanels();
ScreenVisible( m_bEnabled );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::ScreenVisible( bool bVisible )
{
// Set its active state
m_hScreen->SetActive( bVisible );
if ( bVisible )
{
m_hScreen->RemoveEffects( EF_NODRAW );
}
else
{
m_hScreen->AddEffects( EF_NODRAW );
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::Disable( void )
{
if ( !m_bEnabled )
return;
m_bEnabled = false;
ScreenVisible( false );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::Enable( void )
{
if ( m_bEnabled )
return;
m_bEnabled = true;
ScreenVisible( true );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::InputDisable( inputdata_t &inputdata )
{
Disable();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::InputEnable( inputdata_t &inputdata )
{
Enable();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::InputToggle( inputdata_t &inputdata )
{
m_bEnabled ? Disable() : Enable();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::InputSetMessage( inputdata_t &inputdata )
{
Q_strcpy( m_szDisplayText.GetForModify(), inputdata.value.String() );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::InputSetTextAlignment( inputdata_t &inputdata )
{
m_iContentAlignment = inputdata.value.Int();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::InputSetFont( inputdata_t &inputdata )
{
Q_strcpy( m_szFont.GetForModify(), inputdata.value.String() );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::InputSetResolution( inputdata_t &inputdata )
{
m_iResolution = inputdata.value.Int();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::InputSetTextSize( inputdata_t &inputdata )
{
m_flTextSize = inputdata.value.Float();
if (m_hScreen)
{
m_hScreen->SetActualSize( m_flTextSize, m_flTextSize );
m_hScreen->SetLocalOrigin( m_hScreen->CollisionProp()->OBBCenter() * -1.0f );
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName )
{
pPanelName = "text_display_panel";
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::GetControlPanelClassName( int nPanelIndex, const char *&pPanelName )
{
pPanelName = "vgui_screen";
}
//-----------------------------------------------------------------------------
// This is called by the base object when it's time to spawn the control panels
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::SpawnControlPanels()
{
int nPanel;
for ( nPanel = 0; true; ++nPanel )
{
const char *pScreenName;
GetControlPanelInfo( nPanel, pScreenName );
if (!pScreenName)
continue;
const char *pScreenClassname;
GetControlPanelClassName( nPanel, pScreenClassname );
if ( !pScreenClassname )
continue;
float flWidth = m_flTextSize;
float flHeight = m_flTextSize;
CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, this, this, 0 );
pScreen->ChangeTeam( GetTeamNumber() );
pScreen->SetActualSize( flWidth, flHeight );
pScreen->SetLocalOrigin( pScreen->CollisionProp()->OBBCenter() * -1.0f );
pScreen->SetActive( true );
pScreen->MakeVisibleOnlyToTeammates( false );
pScreen->SetTransparency( true );
m_hScreen = pScreen;
return;
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVGuiTextDisplay::RestoreControlPanels( void )
{
int nPanel;
for ( nPanel = 0; true; ++nPanel )
{
const char *pScreenName;
GetControlPanelInfo( nPanel, pScreenName );
if (!pScreenName)
continue;
const char *pScreenClassname;
GetControlPanelClassName( nPanel, pScreenClassname );
if ( !pScreenClassname )
continue;
CVGuiScreen *pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( NULL, pScreenClassname );
while ( ( pScreen && pScreen->GetOwnerEntity() != this ) || Q_strcmp( pScreen->GetPanelName(), pScreenName ) != 0 )
{
pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( pScreen, pScreenClassname );
}
if ( pScreen )
{
m_hScreen = pScreen;
m_hScreen->SetActive( true );
}
return;
}
}

View File

@ -0,0 +1,372 @@
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
//
// Purpose: Allows movies to be played as a VGUI screen in the world
//
//=====================================================================================//
#include "cbase.h"
#include "EnvMessage.h"
#include "fmtstr.h"
#include "vguiscreen.h"
#include "filesystem.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
class CMovieDisplay : public CBaseEntity
{
public:
DECLARE_CLASS( CMovieDisplay, CBaseEntity );
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
virtual ~CMovieDisplay();
virtual bool KeyValue( const char *szKeyName, const char *szValue );
virtual int UpdateTransmitState();
virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
virtual void Spawn( void );
virtual void Precache( void );
virtual void OnRestore( void );
void ScreenVisible( bool bVisible );
void Disable( void );
void Enable( void );
void InputDisable( inputdata_t &inputdata );
void InputEnable( inputdata_t &inputdata );
void InputSetDisplayText( inputdata_t &inputdata );
private:
// Control panel
void GetControlPanelInfo( int nPanelIndex, const char *&pPanelName );
void GetControlPanelClassName( int nPanelIndex, const char *&pPanelName );
void SpawnControlPanels( void );
void RestoreControlPanels( void );
private:
CNetworkVar( bool, m_bEnabled );
CNetworkVar( bool, m_bLooping );
CNetworkString( m_szDisplayText, 128 );
// Filename of the movie to play
CNetworkString( m_szMovieFilename, 128 );
string_t m_strMovieFilename;
// "Group" name. Screens of the same group name will play the same movie at the same time
// Effectively this lets multiple screens tune to the same "channel" in the world
CNetworkString( m_szGroupName, 128 );
string_t m_strGroupName;
int m_iScreenWidth;
int m_iScreenHeight;
bool m_bDoFullTransmit;
CHandle<CVGuiScreen> m_hScreen;
};
LINK_ENTITY_TO_CLASS( vgui_movie_display, CMovieDisplay );
//-----------------------------------------------------------------------------
// Save/load
//-----------------------------------------------------------------------------
BEGIN_DATADESC( CMovieDisplay )
DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ),
DEFINE_AUTO_ARRAY_KEYFIELD( m_szDisplayText, FIELD_CHARACTER, "displaytext" ),
DEFINE_AUTO_ARRAY( m_szMovieFilename, FIELD_CHARACTER ),
DEFINE_KEYFIELD( m_strMovieFilename, FIELD_STRING, "moviefilename" ),
DEFINE_AUTO_ARRAY( m_szGroupName, FIELD_CHARACTER ),
DEFINE_KEYFIELD( m_strGroupName, FIELD_STRING, "groupname" ),
DEFINE_KEYFIELD( m_iScreenWidth, FIELD_INTEGER, "width" ),
DEFINE_KEYFIELD( m_iScreenHeight, FIELD_INTEGER, "height" ),
DEFINE_KEYFIELD( m_bLooping, FIELD_BOOLEAN, "looping" ),
DEFINE_FIELD( m_bDoFullTransmit, FIELD_BOOLEAN ),
DEFINE_FIELD( m_hScreen, FIELD_EHANDLE ),
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetDisplayText", InputSetDisplayText ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CMovieDisplay, DT_MovieDisplay )
SendPropBool( SENDINFO( m_bEnabled ) ),
SendPropBool( SENDINFO( m_bLooping ) ),
SendPropString( SENDINFO( m_szMovieFilename ) ),
SendPropString( SENDINFO( m_szGroupName ) ),
END_SEND_TABLE()
CMovieDisplay::~CMovieDisplay()
{
DestroyVGuiScreen( m_hScreen.Get() );
}
//-----------------------------------------------------------------------------
// Read in Hammer data
//-----------------------------------------------------------------------------
bool CMovieDisplay::KeyValue( const char *szKeyName, const char *szValue )
{
// NOTE: Have to do these separate because they set two values instead of one
if( FStrEq( szKeyName, "angles" ) )
{
Assert( GetMoveParent() == NULL );
QAngle angles;
UTIL_StringToVector( angles.Base(), szValue );
// Because the vgui screen basis is strange (z is front, y is up, x is right)
// we need to rotate the typical basis before applying it
VMatrix mat, rotation, tmp;
MatrixFromAngles( angles, mat );
MatrixBuildRotationAboutAxis( rotation, Vector( 0, 1, 0 ), 90 );
MatrixMultiply( mat, rotation, tmp );
MatrixBuildRotateZ( rotation, 90 );
MatrixMultiply( tmp, rotation, mat );
MatrixToAngles( mat, angles );
SetAbsAngles( angles );
return true;
}
return BaseClass::KeyValue( szKeyName, szValue );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CMovieDisplay::UpdateTransmitState()
{
if ( m_bDoFullTransmit )
{
m_bDoFullTransmit = false;
return SetTransmitState( FL_EDICT_ALWAYS );
}
return SetTransmitState( FL_EDICT_FULLCHECK );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways )
{
// Are we already marked for transmission?
if ( pInfo->m_pTransmitEdict->Get( entindex() ) )
return;
BaseClass::SetTransmit( pInfo, bAlways );
// Force our screen to be sent too.
m_hScreen->SetTransmit( pInfo, bAlways );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::Spawn( void )
{
// Move the strings into a networkable form
Q_strcpy( m_szMovieFilename.GetForModify(), m_strMovieFilename.ToCStr() );
Q_strcpy( m_szGroupName.GetForModify(), m_strGroupName.ToCStr() );
Precache();
BaseClass::Spawn();
m_bEnabled = false;
SpawnControlPanels();
ScreenVisible( m_bEnabled );
m_bDoFullTransmit = true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::Precache( void )
{
BaseClass::Precache();
PrecacheVGuiScreen( "video_display_screen" );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::OnRestore( void )
{
BaseClass::OnRestore();
RestoreControlPanels();
ScreenVisible( m_bEnabled );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::ScreenVisible( bool bVisible )
{
// Set its active state
m_hScreen->SetActive( bVisible );
if ( bVisible )
{
m_hScreen->RemoveEffects( EF_NODRAW );
}
else
{
m_hScreen->AddEffects( EF_NODRAW );
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::Disable( void )
{
if ( !m_bEnabled )
return;
m_bEnabled = false;
ScreenVisible( false );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::Enable( void )
{
if ( m_bEnabled )
return;
m_bEnabled = true;
ScreenVisible( true );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::InputDisable( inputdata_t &inputdata )
{
Disable();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::InputEnable( inputdata_t &inputdata )
{
Enable();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::InputSetDisplayText( inputdata_t &inputdata )
{
Q_strcpy( m_szDisplayText.GetForModify(), inputdata.value.String() );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName )
{
pPanelName = "movie_display_screen";
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::GetControlPanelClassName( int nPanelIndex, const char *&pPanelName )
{
pPanelName = "vgui_screen";
}
//-----------------------------------------------------------------------------
// This is called by the base object when it's time to spawn the control panels
//-----------------------------------------------------------------------------
void CMovieDisplay::SpawnControlPanels()
{
int nPanel;
for ( nPanel = 0; true; ++nPanel )
{
const char *pScreenName;
GetControlPanelInfo( nPanel, pScreenName );
if (!pScreenName)
continue;
const char *pScreenClassname;
GetControlPanelClassName( nPanel, pScreenClassname );
if ( !pScreenClassname )
continue;
float flWidth = m_iScreenWidth;
float flHeight = m_iScreenHeight;
CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, this, this, 0 );
pScreen->ChangeTeam( GetTeamNumber() );
pScreen->SetActualSize( flWidth, flHeight );
pScreen->SetActive( true );
pScreen->MakeVisibleOnlyToTeammates( false );
pScreen->SetTransparency( true );
m_hScreen = pScreen;
return;
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMovieDisplay::RestoreControlPanels( void )
{
int nPanel;
for ( nPanel = 0; true; ++nPanel )
{
const char *pScreenName;
GetControlPanelInfo( nPanel, pScreenName );
if (!pScreenName)
continue;
const char *pScreenClassname;
GetControlPanelClassName( nPanel, pScreenClassname );
if ( !pScreenClassname )
continue;
CVGuiScreen *pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( NULL, pScreenClassname );
while ( ( pScreen && pScreen->GetOwnerEntity() != this ) || Q_strcmp( pScreen->GetPanelName(), pScreenName ) != 0 )
{
pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( pScreen, pScreenClassname );
}
if ( pScreen )
{
m_hScreen = pScreen;
m_hScreen->SetActive( true );
}
return;
}
}

View File

@ -526,8 +526,8 @@ BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." )
DEFINE_SCRIPTFUNC( GetButtonForced, "Gets the player's currently forced buttons." )
DEFINE_SCRIPTFUNC( GetFOV, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetFOVOwner, "GetFOVOwner", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetFOV, "SetFOV", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetFOVOwner, "GetFOVOwner", "Gets current view owner." )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetFOV, "SetFOV", "Sets player FOV regardless of view owner." )
DEFINE_SCRIPTFUNC( ViewPunch, "Punches the player's view with the specified vector." )
DEFINE_SCRIPTFUNC( SetMuzzleFlashTime, "Sets the player's muzzle flash time for AI." )
@ -5251,6 +5251,11 @@ void CBasePlayer::Spawn( void )
m_vecSmoothedVelocity = vec3_origin;
InitVCollision( GetAbsOrigin(), GetAbsVelocity() );
if ( !g_pGameRules->IsMultiplayer() && g_pScriptVM )
{
g_pScriptVM->SetValue( "player", GetScriptInstance() );
}
#if !defined( TF_DLL )
IGameEvent *event = gameeventmanager->CreateEvent( "player_spawn" );
@ -5275,11 +5280,6 @@ void CBasePlayer::Spawn( void )
UpdateLastKnownArea();
m_weaponFiredTimer.Invalidate();
if ( !g_pGameRules->IsMultiplayer() && g_pScriptVM )
{
g_pScriptVM->SetValue( "player", GetScriptInstance() );
}
}
void CBasePlayer::Activate( void )

View File

@ -75,6 +75,12 @@ private:
float m_flHDRColorScale;
int m_nMinDXLevel;
#ifdef MAPBASE
float m_flHaloScale;
string_t m_iszHaloMaterial;
string_t m_iszSpotlightMaterial;
#endif
public:
COutputEvent m_OnOn, m_OnOff; ///< output fires when turned on, off
};
@ -98,6 +104,11 @@ BEGIN_DATADESC( CPointSpotlight )
DEFINE_KEYFIELD( m_flSpotlightGoalWidth,FIELD_FLOAT, "SpotlightWidth"),
DEFINE_KEYFIELD( m_flHDRColorScale, FIELD_FLOAT, "HDRColorScale" ),
DEFINE_KEYFIELD( m_nMinDXLevel, FIELD_INTEGER, "mindxlevel" ),
#ifdef MAPBASE
DEFINE_KEYFIELD( m_flHaloScale, FIELD_FLOAT, "HaloScale" ),
DEFINE_KEYFIELD( m_iszHaloMaterial, FIELD_STRING, "HaloMaterial" ),
DEFINE_KEYFIELD( m_iszSpotlightMaterial, FIELD_STRING, "SpotlightMaterial" ),
#endif
// Inputs
DEFINE_INPUTFUNC( FIELD_VOID, "LightOn", InputLightOn ),
@ -127,6 +138,9 @@ CPointSpotlight::CPointSpotlight()
#endif
m_flHDRColorScale = 1.0f;
m_nMinDXLevel = 0;
#ifdef MAPBASE
m_flHaloScale = 60.0f;
#endif
}
#ifdef MAPBASE
@ -148,8 +162,23 @@ void CPointSpotlight::Precache(void)
BaseClass::Precache();
// Sprites.
#ifdef MAPBASE
if (m_iszHaloMaterial == NULL_STRING)
{
m_iszHaloMaterial = AllocPooledString( "sprites/light_glow03.vmt" );
}
if (m_iszSpotlightMaterial == NULL_STRING)
{
m_iszSpotlightMaterial = AllocPooledString( "sprites/glow_test02.vmt" );
}
m_nHaloSprite = PrecacheModel( STRING( m_iszHaloMaterial ) );
PrecacheModel( STRING( m_iszSpotlightMaterial ) );
#else
m_nHaloSprite = PrecacheModel("sprites/light_glow03.vmt");
PrecacheModel( "sprites/glow_test02.vmt" );
#endif
}
@ -367,13 +396,21 @@ void CPointSpotlight::SpotlightCreate(void)
}
//m_hSpotlight = CBeam::BeamCreate( "sprites/spotlight.vmt", m_flSpotlightGoalWidth );
#ifdef MAPBASE
m_hSpotlight = CBeam::BeamCreate( STRING(m_iszSpotlightMaterial), m_flSpotlightGoalWidth );
#else
m_hSpotlight = CBeam::BeamCreate( "sprites/glow_test02.vmt", m_flSpotlightGoalWidth );
#endif
// Set the temporary spawnflag on the beam so it doesn't save (we'll recreate it on restore)
m_hSpotlight->SetHDRColorScale( m_flHDRColorScale );
m_hSpotlight->AddSpawnFlags( SF_BEAM_TEMPORARY );
m_hSpotlight->SetColor( m_clrRender->r, m_clrRender->g, m_clrRender->b );
m_hSpotlight->SetHaloTexture(m_nHaloSprite);
#ifdef MAPBASE
m_hSpotlight->SetHaloScale(m_flHaloScale);
#else
m_hSpotlight->SetHaloScale(60);
#endif
m_hSpotlight->SetEndWidth(m_flSpotlightGoalWidth);
m_hSpotlight->SetBeamFlags( (FBEAM_SHADEOUT|FBEAM_NOTILE) );
m_hSpotlight->SetBrightness( 64 );

View File

@ -3508,7 +3508,10 @@ void CSceneEntity::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEv
if ( IsMultiplayer() )
break;
DispatchStartPermitResponses( scene, pActor, event );
if ( pActor )
{
DispatchStartPermitResponses( scene, pActor, event );
}
}
break;
default:
@ -3666,7 +3669,10 @@ void CSceneEntity::EndEvent( float currenttime, CChoreoScene *scene, CChoreoEven
if ( IsMultiplayer() )
break;
DispatchEndPermitResponses( scene, pActor, event );
if ( pActor )
{
DispatchEndPermitResponses( scene, pActor, event );
}
}
break;
default:

View File

@ -28,6 +28,8 @@ $Project
$File "postprocesscontroller.h"
$File "env_dof_controller.cpp"
$File "env_dof_controller.h"
$File "logic_playmovie.cpp"
$File "movie_display.cpp"
$File "ai_expresserfollowup.cpp" [$NEW_RESPONSE_SYSTEM]
$File "ai_speechqueue.cpp" [$NEW_RESPONSE_SYSTEM]
$File "ai_speechqueue.h" [$NEW_RESPONSE_SYSTEM]
@ -78,6 +80,7 @@ $Project
$File "mapbase\SystemConvarMod.cpp"
$File "mapbase\SystemConvarMod.h"
$File "mapbase\variant_tools.h"
$File "mapbase\vgui_text_display.cpp"
$File "mapbase\logic_eventlistener.cpp"
$File "mapbase\logic_register_activator.cpp"

View File

@ -110,6 +110,11 @@ public:
{
return ToHScript( gEntList.FindEntityByClassnameWithin( ToEnt( hStartEntity ), szName, vecMins, vecMaxs ) );
}
HSCRIPT FindByClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, const char *classname )
{
return ToHScript( gEntList.FindEntityClassNearestFacing( origin, facing, threshold, const_cast<char*>(classname) ) );
}
#endif
private:
} g_ScriptEntityIterator;
@ -132,6 +137,7 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptEntityIterator, "CEntities", SCRIPT_SINGLETO
DEFINE_SCRIPTFUNC( FindByClassnameWithin, "Find entities by class name within a radius. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
#ifdef MAPBASE_VSCRIPT
DEFINE_SCRIPTFUNC( FindByClassnameWithinBox, "Find entities by class name within an AABB. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
DEFINE_SCRIPTFUNC( FindByClassNearestFacing, "Find the nearest entity along the facing direction from the given origin within the angular threshold with the given classname." )
#endif
END_SCRIPTDESC();
@ -265,11 +271,6 @@ static int MaxPlayers()
return gpGlobals->maxClients;
}
static float IntervalPerTick()
{
return gpGlobals->interval_per_tick;
}
static int GetLoadType()
{
return gpGlobals->eLoadType;
@ -328,7 +329,11 @@ static void DoEntFire( const char *pszTarget, const char *pszAction, const char
// ent_fire point_servercommand command "rcon_password mynewpassword"
if ( gpGlobals->maxClients > 1 && V_stricmp( target, "point_servercommand" ) == 0 )
{
#ifdef MAPBASE_VSCRIPT
return 0;
#else
return;
#endif
}
if ( *pszAction )
@ -447,12 +452,6 @@ static float GetEntityIOEventTimeLeft( int event )
{
return g_EventQueue.GetTimeLeft(event);
}
// vscript_server.nut adds this to the base CConvars class
static const char *ScriptGetClientConvarValue( const char *pszConVar, int entindex )
{
return engine->GetClientConVarValue( entindex, pszConVar );
}
#endif // MAPBASE_VSCRIPT
bool VScriptServerInit()
@ -537,7 +536,6 @@ bool VScriptServerInit()
#ifdef MAPBASE_VSCRIPT
ScriptRegisterFunction( g_pScriptVM, SendToConsoleServer, "Send a string to the server console as a command" );
ScriptRegisterFunction( g_pScriptVM, MaxPlayers, "Get the maximum number of players allowed on this server" );
ScriptRegisterFunction( g_pScriptVM, IntervalPerTick, "Get the interval used between each tick" );
ScriptRegisterFunction( g_pScriptVM, GetLoadType, "Get the way the current game was loaded (corresponds to the MapLoad enum)" );
ScriptRegisterFunction( g_pScriptVM, DoEntFire, SCRIPT_ALIAS( "EntFire", "Generate an entity i/o event" ) );
ScriptRegisterFunction( g_pScriptVM, DoEntFireByInstanceHandle, SCRIPT_ALIAS( "EntFireByHandle", "Generate an entity i/o event. First parameter is an entity instance." ) );
@ -545,7 +543,6 @@ bool VScriptServerInit()
ScriptRegisterFunction( g_pScriptVM, CancelEntityIOEvent, "Remove entity I/O event." );
ScriptRegisterFunction( g_pScriptVM, GetEntityIOEventTimeLeft, "Get time left on entity I/O event." );
ScriptRegisterFunction( g_pScriptVM, ScriptGetClientConvarValue, SCRIPT_HIDE );
#else
ScriptRegisterFunction( g_pScriptVM, DoEntFire, SCRIPT_ALIAS( "EntFire", "Generate and entity i/o event" ) );
ScriptRegisterFunctionNamed( g_pScriptVM, DoEntFireByInstanceHandle, "EntFireByHandle", "Generate and entity i/o event. First parameter is an entity instance." );

View File

@ -5,15 +5,14 @@ static char g_Script_vscript_server[] = R"vscript(
//
//=============================================================================
local DoEntFire = ::DoEntFire
local DoEntFireByInstanceHandle = ::DoEntFireByInstanceHandle
local DoDispatchParticleEffect = ::DoDispatchParticleEffect
local DoUniqueString = ::DoUniqueString
local ScriptGetClientConvarValue = ::ScriptGetClientConvarValue
local DoEntFire = DoEntFire
local DoEntFireByInstanceHandle = DoEntFireByInstanceHandle
local DoDispatchParticleEffect = DoDispatchParticleEffect
local DoUniqueString = DoUniqueString
function UniqueString( string = "" )
{
return DoUniqueString( string.tostring() );
return DoUniqueString( "" + string );
}
function EntFire( target, action, value = null, delay = 0.0, activator = null, caller = null )
@ -36,7 +35,7 @@ function EntFire( target, action, value = null, delay = 0.0, activator = null, c
}
}
return DoEntFire( target.tostring(), action.tostring(), value.tostring(), delay, activator, caller );
return DoEntFire( "" + target, "" + action, "" + value, delay, activator, caller );
}
function EntFireByHandle( target, action, value = null, delay = 0.0, activator = null, caller = null )
@ -59,7 +58,7 @@ function EntFireByHandle( target, action, value = null, delay = 0.0, activator =
}
}
return DoEntFireByInstanceHandle( target, action.tostring(), value.tostring(), delay, activator, caller );
return DoEntFireByInstanceHandle( target, "" + action, "" + value, delay, activator, caller );
}
function DispatchParticleEffect( particleName, origin, angles, entity = null )
@ -67,12 +66,6 @@ function DispatchParticleEffect( particleName, origin, angles, entity = null )
DoDispatchParticleEffect( particleName, origin, angles, entity );
}
// CConvars is declared within the library
function CConvars::GetClientConvarValue(cvar,idx)
{
return ScriptGetClientConvarValue(cvar,idx);
}
__Documentation.RegisterHelp( "CConvars::GetClientConvarValue", "CConvars::GetClientConvarValue(string, int)", "Returns the convar value for the entindex as a string. Only works with client convars with the FCVAR_USERINFO flag." );
function __ReplaceClosures( script, scope )

View File

@ -1226,6 +1226,11 @@ void CBaseEntity::ScriptEmitSound( const char *soundname )
EmitSound( soundname );
}
void CBaseEntity::ScriptStopSound( const char *soundname )
{
StopSound( soundname );
}
float CBaseEntity::ScriptSoundDuration( const char *soundname, const char *actormodel )
{
float duration = CBaseEntity::GetSoundDuration( soundname, actormodel );

View File

@ -2712,4 +2712,296 @@ HSCRIPT CBaseEntity::ScriptGetPhysicsObject( void )
else
return NULL;
}
static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
{
Assert( context->m_hfnThink );
g_pScriptVM->ReleaseScript( context->m_hfnThink );
context->m_hfnThink = NULL;
//context->m_nNextThinkTick = TICK_NEVER_THINK;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptContextThink()
{
float flNextThink = FLT_MAX;
int nScheduledTick = 0;
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); ++i )
{
scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i];
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
{
continue;
}
if ( cur->m_nNextThinkTick > gpGlobals->tickcount )
{
// There is more to execute, don't stop thinking if the rest are done.
// Find the shortest schedule
if ( !nScheduledTick || nScheduledTick > cur->m_nNextThinkTick )
{
nScheduledTick = cur->m_nNextThinkTick;
}
continue;
}
#ifdef _DEBUG
// going to run the script func
cur->m_nNextThinkTick = 0;
#endif
ScriptVariant_t varReturn;
if ( !cur->m_bNoParam )
{
ScriptVariant_t arg = m_hScriptInstance;
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, &arg, 1, &varReturn, NULL, true ) == SCRIPT_ERROR )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
continue;
}
}
else
{
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, NULL, 0, &varReturn, NULL, true ) == SCRIPT_ERROR )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
continue;
}
}
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
{
// stopped from script while thinking
continue;
}
float flReturn;
if ( !varReturn.AssignTo( &flReturn ) )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
continue;
}
if ( flReturn < 0.0f )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
continue;
}
if ( flReturn < flNextThink )
{
flNextThink = flReturn;
}
cur->m_nNextThinkTick = TIME_TO_TICKS( gpGlobals->curtime + flReturn );
}
// deferred safe removal
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); )
{
if ( m_ScriptThinkFuncs[i]->m_nNextThinkTick == TICK_NEVER_THINK )
{
ScriptStopContextThink( m_ScriptThinkFuncs[i] );
delete m_ScriptThinkFuncs[i];
m_ScriptThinkFuncs.Remove(i);
}
else ++i;
}
bool bNewNext = flNextThink < FLT_MAX;
#ifdef _DEBUG
#ifdef GAME_DLL
int nNextThinkTick = GetNextThinkTick("ScriptContextThink"); // -1
#else
int nNextThinkTick = GetNextThinkTick(); // 0
#endif
if ( ( nNextThinkTick <= 0 ) || ( nNextThinkTick >= nScheduledTick ) || ( nNextThinkTick == gpGlobals->tickcount ) )
{
#endif
if ( nScheduledTick )
{
float flScheduledTime = TICKS_TO_TIME( nScheduledTick );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, flScheduledTime );
}
else
{
flNextThink = flScheduledTime;
}
}
else
{
if ( bNewNext )
{
flNextThink = gpGlobals->curtime + flNextThink;
}
else
{
#ifdef GAME_DLL
flNextThink = TICK_NEVER_THINK;
#else
flNextThink = CLIENT_THINK_NEVER;
#endif
}
}
#ifdef _DEBUG
}
else
{
// Next think was set (from script) to a sooner tick while thinking?
Assert(0);
if ( nScheduledTick )
{
int nNextSchedule = min( nScheduledTick, nNextThinkTick );
float flNextSchedule = TICKS_TO_TIME( nNextSchedule );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, flNextSchedule );
}
else
{
flNextThink = flNextSchedule;
}
}
else
{
float nextthink = TICKS_TO_TIME( nNextThinkTick );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, nextthink );
}
else
{
flNextThink = nextthink;
}
}
}
#endif
#ifdef GAME_DLL
SetNextThink( flNextThink, "ScriptContextThink" );
#else
SetNextClientThink( flNextThink );
#endif
}
// see ScriptSetThink
static bool s_bScriptContextThinkNoParam = false;
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float flTime )
{
#ifdef CLIENT_DLL
// Context thinking is not yet supported on client, entities can only have 1 think function.
// C_World does not have one by default, so it is safe to set its.
if ( !IsWorld() )
{
g_pScriptVM->RaiseException("SetContextThink is only supported on C_World");
return;
}
#endif
scriptthinkfunc_t *pf = NULL;
unsigned short hash = ( szContext && *szContext ) ? HashString( szContext ) : 0;
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
{
scriptthinkfunc_t *f = m_ScriptThinkFuncs[i];
if ( hash == f->m_iContextHash )
{
pf = f;
break;
}
}
if ( hFunc )
{
// add new
if ( !pf )
{
pf = new scriptthinkfunc_t;
m_ScriptThinkFuncs.SetGrowSize(1);
m_ScriptThinkFuncs.AddToTail( pf );
pf->m_bNoParam = s_bScriptContextThinkNoParam;
pf->m_iContextHash = hash;
}
// update existing
else
{
#ifdef _DEBUG
if ( pf->m_nNextThinkTick == 0 )
{
Warning("Script think ('%s') was changed while it was thinking!\n", szContext);
}
#endif
g_pScriptVM->ReleaseScript( pf->m_hfnThink );
}
float nextthink = gpGlobals->curtime + flTime;
pf->m_hfnThink = hFunc;
pf->m_nNextThinkTick = TIME_TO_TICKS( nextthink );
#ifdef GAME_DLL
int nexttick = GetNextThinkTick( RegisterThinkContext( "ScriptContextThink" ) );
#else
int nexttick = GetNextThinkTick();
#endif
// sooner than next think
if ( nexttick <= 0 || nexttick > pf->m_nNextThinkTick )
{
#ifdef GAME_DLL
SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" );
#else
SetNextClientThink( nextthink );
#endif
}
}
// null func input, think exists
else if ( pf )
{
pf->m_nNextThinkTick = TICK_NEVER_THINK;
}
}
//-----------------------------------------------------------------------------
// m_bNoParam and s_bScriptContextThinkNoParam exist only to keep backwards compatibility
// and are an alternative to this script closure:
//
// function CBaseEntity::SetThink( func, time )
// {
// SetContextThink( "", function(_){ return func() }, time )
// }
//-----------------------------------------------------------------------------
#ifndef CLIENT_DLL
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time )
{
s_bScriptContextThinkNoParam = true;
ScriptSetContextThink( NULL, hFunc, time );
s_bScriptContextThinkNoParam = false;
}
void CBaseEntity::ScriptStopThink()
{
ScriptSetContextThink( NULL, NULL, 0.0f );
}
#endif
#endif

View File

@ -71,7 +71,7 @@ ConVar mapbase_load_actbusy("mapbase_load_actbusy", "1", FCVAR_ARCHIVE, "Should
#ifdef GAME_DLL
// This cvar should change with each Mapbase update
ConVar mapbase_version( "mapbase_version", "6.2", FCVAR_NONE, "The version of Mapbase currently being used in this mod." );
ConVar mapbase_version( "mapbase_version", "6.3", FCVAR_NONE, "The version of Mapbase currently being used in this mod." );
extern void MapbaseGameLog_Init();
@ -178,7 +178,7 @@ public:
#ifdef GAME_DLL
if (g_bMapContainsCustomTalker && mapbase_flush_talker.GetBool())
{
CGMsg( 1, "Mapbase Misc.", "Mapbase: Reloading response system to flush custom talker\n" );
CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Mapbase: Reloading response system to flush custom talker\n" );
ReloadResponseSystem();
g_bMapContainsCustomTalker = false;
}
@ -188,7 +188,7 @@ public:
virtual void LevelInitPreEntity()
{
#ifdef GAME_DLL
CGMsg( 0, "Mapbase Misc.", "Mapbase system loaded\n" );
CGMsg( 0, CON_GROUP_MAPBASE_MISC, "Mapbase system loaded\n" );
#endif
// Checks gameinfo.txt for Mapbase-specific options
@ -212,8 +212,11 @@ public:
RefreshMapName();
// Shared Mapbase localization file
// Shared Mapbase scripts to avoid overwriting mod files
g_pVGuiLocalize->AddFile( "resource/mapbase_%language%.txt" );
#ifdef CLIENT_DLL
PanelMetaClassMgr()->LoadMetaClassDefinitionFile( "scripts/vgui_screens_mapbase.txt" );
#endif
}
virtual void OnRestore()
@ -352,11 +355,11 @@ public:
return;
}
CGMsg( 1, "Mapbase Misc.", "===== Mapbase Manifest: Loading manifest file %s =====\n", file );
CGMsg( 1, CON_GROUP_MAPBASE_MISC, "===== Mapbase Manifest: Loading manifest file %s =====\n", file );
AddManifestFile(pKV, false);
CGMsg( 1, "Mapbase Misc.", "==============================================================================\n" );
CGMsg( 1, CON_GROUP_MAPBASE_MISC, "==============================================================================\n" );
pKV->deleteThis();
}
@ -553,6 +556,11 @@ CUtlVector<MODCHAPTER> *Mapbase_GetChapterList()
return &g_MapbaseChapterList;
}
int Mapbase_GetChapterCount()
{
return g_MapbaseChapterList.Count();
}
ThreeState_t Flashlight_GetLegacyVersionKey()
{
KeyValues *gameinfo = new KeyValues( "GameInfo" );
@ -591,7 +599,7 @@ public:
const char *scriptfile = STRING(m_target);
if ( filesystem->FileExists( scriptfile, "MOD" ) )
{
CGMsg(0, "Mapbase Misc.", "Mapbase: Adding manifest file \"%s\"\n", scriptfile);
CGMsg(0, CON_GROUP_MAPBASE_MISC, "Mapbase: Adding manifest file \"%s\"\n", scriptfile);
g_MapbaseSystem.AddManifestFile(scriptfile);
}
else

View File

@ -8,6 +8,7 @@
#include "cbase.h"
#include "activitylist.h"
#include "in_buttons.h"
#include "rope_shared.h"
#ifdef CLIENT_DLL
#include "c_ai_basenpc.h"
#else
@ -66,7 +67,7 @@ BEGIN_SCRIPTENUM( RenderMode, "Render modes used by Get/SetRenderMode" )
DEFINE_ENUMCONST_NAMED( kRenderTransAdd, "Additive", "" )
DEFINE_ENUMCONST_NAMED( kRenderEnvironmental, "Environmental", "" )
DEFINE_ENUMCONST_NAMED( kRenderTransAddFrameBlend, "AdditiveFractionalFrame", "" )
DEFINE_ENUMCONST_NAMED( kRenderTransAlphaAdd, "Alpha Add", "" )
DEFINE_ENUMCONST_NAMED( kRenderTransAlphaAdd, "AlphaAdd", "" )
DEFINE_ENUMCONST_NAMED( kRenderWorldGlow, "WorldSpaceGlow", "" )
DEFINE_ENUMCONST_NAMED( kRenderNone, "None", "" )
@ -310,6 +311,22 @@ void RegisterSharedScriptConstants()
ScriptRegisterConstant( g_pScriptVM, MOVETYPE_OBSERVER, "Move type used in GetMoveType(), etc." );
ScriptRegisterConstant( g_pScriptVM, MOVETYPE_CUSTOM, "Move type used in GetMoveType(), etc." );
//
// Ropes
//
ScriptRegisterConstant( g_pScriptVM, ROPE_RESIZE, "Try to keep the rope dangling the same amount even as the rope length changes. (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_BARBED, "Hack option to draw like a barbed wire. (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_COLLIDE, "Collide with the world. (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_SIMULATE, "Is the rope valid? (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_BREAKABLE, "Can the endpoints detach? (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_USE_WIND, "Wind simulation on this rope. (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_INITIAL_HANG, "By default, ropes will simulate for a bit internally when they are created so they sag, but dynamically created ropes for things like harpoons don't want this. (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_PLAYER_WPN_ATTACH, "If this flag is set, then the second attachment must be a player. The rope will attach to \"buff_attach\" on the player's active weapon. This is a flag because it requires special code on the client to find the weapon. (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_NO_GRAVITY, "Disable gravity on this rope. (for use in rope flags)" );
ScriptRegisterConstant( g_pScriptVM, ROPE_NUMFLAGS, "The number of rope flags recognized by the game." );
ScriptRegisterConstantNamed( g_pScriptVM, Vector( ROPE_GRAVITY ), "ROPE_GRAVITY", "Default rope gravity vector." );
#ifdef GAME_DLL
//
// Sound Types, Contexts, and Channels
@ -483,7 +500,8 @@ void RegisterSharedScriptConstants()
//ScriptRegisterConstant( g_pScriptVM, AISS_AUTO_PVS_AFTER_PVS, "" );
ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAGS_NONE, "No sleep flags. (NPC sleep flag used in Add/Remove/HasSleepFlags())" );
ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAG_AUTO_PVS, "Indicates a NPC will sleep upon exiting PVS. (NPC sleep flag used in Add/Remove/HasSleepFlags())" );
ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAG_AUTO_PVS_AFTER_PVS, "Indicates a NPC will sleep upon exiting PVS after entering PVS for the first time(?????) (NPC sleep flag used in Add/Remove/HasSleepFlags())" );
// note: the one "?" is escaped to prevent evaluation of a trigraph
ScriptRegisterConstant( g_pScriptVM, AI_SLEEP_FLAG_AUTO_PVS_AFTER_PVS, "Indicates a NPC will sleep upon exiting PVS after entering PVS for the first time(????\?) (NPC sleep flag used in Add/Remove/HasSleepFlags())" );
ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_PLAYING, "SCRIPT_PLAYING", "Playing the action animation." );
ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_WAIT, "SCRIPT_WAIT", "Waiting on everyone in the script to be ready. Plays the pre idle animation if there is one." );

View File

@ -22,10 +22,14 @@
#include "globalstate.h"
#include "vscript_server.h"
#include "soundent.h"
#endif // !CLIENT_DLL
#include "rope.h"
#else
#include "c_rope.h"
#endif // CLIENT_DLL
#include "con_nprint.h"
#include "particle_parse.h"
#include "npcevent.h"
#include "vscript_funcs_shared.h"
#include "vscript_singletons.h"
@ -164,18 +168,18 @@ HSCRIPT SpawnEntityFromTable( const char *pszClassname, HSCRIPT hKV )
HSCRIPT EntIndexToHScript( int index )
{
#ifdef GAME_DLL
edict_t *e = INDEXENT(index);
if ( e && !e->IsFree() )
{
return ToHScript( GetContainingEntity( e ) );
}
edict_t *e = INDEXENT(index);
if ( e && !e->IsFree() )
{
return ToHScript( GetContainingEntity( e ) );
}
#else // CLIENT_DLL
if ( index < NUM_ENT_ENTRIES )
{
return ToHScript( CBaseEntity::Instance( index ) );
}
if ( index < NUM_ENT_ENTRIES )
{
return ToHScript( CBaseEntity::Instance( index ) );
}
#endif
return NULL;
return NULL;
}
//-----------------------------------------------------------------------------
@ -501,6 +505,61 @@ FireBulletsInfo_t *GetFireBulletsInfoFromInfo( HSCRIPT hBulletsInfo )
return HScriptToClass<FireBulletsInfo_t>( hBulletsInfo );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CAnimEventTInstanceHelper g_AnimEventTInstanceHelper;
BEGIN_SCRIPTDESC_ROOT( animevent_t, "Handle for accessing animevent_t info." )
DEFINE_SCRIPT_INSTANCE_HELPER( &g_AnimEventTInstanceHelper )
END_SCRIPTDESC();
bool CAnimEventTInstanceHelper::Get( void *p, const char *pszKey, ScriptVariant_t &variant )
{
animevent_t *ani = ((animevent_t *)p);
if (FStrEq( pszKey, "event" ))
variant = ani->event;
else if (FStrEq( pszKey, "options" ))
variant = ani->options;
else if (FStrEq( pszKey, "cycle" ))
variant = ani->cycle;
else if (FStrEq( pszKey, "eventtime" ))
variant = ani->eventtime;
else if (FStrEq( pszKey, "type" ))
variant = ani->type;
else if (FStrEq( pszKey, "source" ))
variant = ToHScript(ani->pSource);
else
return false;
return true;
}
bool CAnimEventTInstanceHelper::Set( void *p, const char *pszKey, ScriptVariant_t &variant )
{
animevent_t *ani = ((animevent_t *)p);
if (FStrEq( pszKey, "event" ))
ani->event = variant;
else if (FStrEq( pszKey, "options" ))
ani->options = variant;
else if (FStrEq( pszKey, "cycle" ))
ani->cycle = variant;
else if (FStrEq( pszKey, "eventtime" ))
ani->eventtime = variant;
else if (FStrEq( pszKey, "type" ))
ani->type = variant;
else if (FStrEq( pszKey, "source" ))
{
CBaseEntity *pEnt = ToEnt( variant.m_hScript );
if (pEnt)
ani->pSource = pEnt->GetBaseAnimating();
}
else
return false;
return true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
@ -682,6 +741,19 @@ static void ScriptDecalTrace( HSCRIPT hTrace, const char *decalName )
UTIL_DecalTrace( &traceInfo->GetTrace(), decalName );
}
static HSCRIPT ScriptCreateRope( HSCRIPT hStart, HSCRIPT hEnd, int iStartAttachment, int iEndAttachment, float ropeWidth, const char *pMaterialName, int numSegments, int ropeFlags )
{
#ifdef CLIENT_DLL
C_RopeKeyframe *pRope = C_RopeKeyframe::Create( ToEnt( hStart ), ToEnt( hEnd ), iStartAttachment, iEndAttachment, ropeWidth, pMaterialName, numSegments, ropeFlags );
#else
CRopeKeyframe *pRope = CRopeKeyframe::Create( ToEnt( hStart ), ToEnt( hEnd ), iStartAttachment, iEndAttachment, ropeWidth, pMaterialName, numSegments );
if (pRope)
pRope->m_RopeFlags |= ropeFlags; // HACKHACK
#endif
return ToHScript( pRope );
}
//-----------------------------------------------------------------------------
// Simple particle effect dispatch
//-----------------------------------------------------------------------------
@ -740,20 +812,29 @@ void NPrint( int pos, const char* fmt )
void NXPrint( int pos, int r, int g, int b, bool fixed, float ftime, const char* fmt )
{
static con_nprint_t *info = new con_nprint_t;
con_nprint_t info;
info->index = pos;
info->time_to_live = ftime;
info->color[0] = r / 255.f;
info->color[1] = g / 255.f;
info->color[2] = b / 255.f;
info->fixed_width_font = fixed;
info.index = pos;
info.time_to_live = ftime;
info.color[0] = r / 255.f;
info.color[1] = g / 255.f;
info.color[2] = b / 255.f;
info.fixed_width_font = fixed;
engine->Con_NXPrintf(info, fmt);
// delete info;
engine->Con_NXPrintf( &info, fmt );
}
static float IntervalPerTick()
{
return gpGlobals->interval_per_tick;
}
static int GetFrameCount()
{
return gpGlobals->framecount;
}
//=============================================================================
//=============================================================================
@ -837,6 +918,8 @@ void RegisterSharedScriptFunctions()
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDecalTrace, "DecalTrace", "Creates a dynamic decal based on the given trace info. The trace information can be generated by TraceLineComplex() and the decal name must be from decals_subrect.txt." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDispatchParticleEffect, "DoDispatchParticleEffect", SCRIPT_ALIAS( "DispatchParticleEffect", "Dispatches a one-off particle system" ) );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateRope, "CreateRope", "Creates a single rope between two entities. Can optionally follow specific attachments." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatcherMatch, "Matcher_Match", "Compares a string to a query using Mapbase's matcher system, supporting wildcards, RS matchers, etc." );
ScriptRegisterFunction( g_pScriptVM, Matcher_NamesMatch, "Compares a string to a query using Mapbase's matcher system using wildcards only." );
ScriptRegisterFunction( g_pScriptVM, AppearsToBeANumber, "Checks if the given string appears to be a number." );
@ -850,6 +933,9 @@ void RegisterSharedScriptFunctions()
#endif
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsServer, "IsServer", "Returns true if the script is being run on the server." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsClient, "IsClient", "Returns true if the script is being run on the client." );
ScriptRegisterFunction( g_pScriptVM, IntervalPerTick, "Simulation tick interval" );
ScriptRegisterFunction( g_pScriptVM, GetFrameCount, "Absolute frame counter" );
//ScriptRegisterFunction( g_pScriptVM, GetTickCount, "Simulation ticks" );
RegisterScriptSingletons();
}

View File

@ -121,4 +121,13 @@ private:
HSCRIPT m_planeAccessor;
};
//-----------------------------------------------------------------------------
// Exposes animevent_t to VScript
//-----------------------------------------------------------------------------
class CAnimEventTInstanceHelper : public IScriptInstanceHelper
{
bool Get( void *p, const char *pszKey, ScriptVariant_t &variant );
bool Set( void *p, const char *pszKey, ScriptVariant_t &variant );
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@
// $NoKeywords: $
//=============================================================================
#ifndef VSCRIPT_SINGLETONS
#define VSCRIPT_SINGLETONS
#ifndef VSCRIPT_SINGLETONS_H
#define VSCRIPT_SINGLETONS_H
#ifdef _WIN32
#pragma once
#endif
@ -29,21 +29,24 @@ class CNetMsgScriptHelper : public CAutoGameSystem
class CNetMsgScriptHelper
#endif
{
#ifdef CLIENT_DLL
public:
bool m_bWriteReady; // dt ready to send
#endif
private:
#ifdef GAME_DLL
CRecipientFilter m_filter;
bf_read *m_MsgIn;
CRecipientFilter m_filter;
#else
bf_read m_MsgIn;
#endif
HSCRIPT m_Hooks;
bf_write m_MsgOut;
byte m_MsgData[ PAD_NUMBER( SCRIPT_NETMSG_DATA_SIZE, 4 ) ];
HSCRIPT m_Hooks;
public:
#ifdef CLIENT_DLL
bool m_bWriteReady; // dt ready to send
CNetMsgScriptHelper() : m_Hooks(NULL), m_bWriteReady(false) {}
#else
CNetMsgScriptHelper() : m_Hooks(NULL) {}
@ -58,9 +61,9 @@ public:
void InitPostVM();
#ifdef GAME_DLL
void RecieveMessage( bf_read *msg, CBaseEntity *pPlayer );
void ReceiveMessage( bf_read *msg, CBaseEntity *pPlayer );
#else
void RecieveMessage( bf_read &msg );
void ReceiveMessage( bf_read &msg );
#endif
void WriteToBuffer( bf_write *bf );
@ -72,7 +75,7 @@ public:
#else
void Send();
#endif
void Recieve( const char *msg, HSCRIPT func );
void Receive( const char *msg, HSCRIPT func );
#ifdef GAME_DLL
inline void DoSendUserMsg( CRecipientFilter *filter, int type );
@ -100,14 +103,14 @@ public:
void WriteShort( int iValue ); // 16 bit short
void WriteWord( int iValue ); // 16 bit unsigned short
void WriteLong( int iValue ); // 32 bit long
void WriteFloat( float flValue );
void WriteNormal( float flValue ); // 12 bit
void WriteFloat( float flValue ); // 32 bit float
void WriteNormal( float flValue ); // 12 bit (1 + NORMAL_FRACTIONAL_BITS)
void WriteAngle( float flValue ); // 8 bit unsigned char
void WriteCoord( float flValue );
void WriteVec3Coord( const Vector& rgflValue );
void WriteVec3Normal( const Vector& rgflValue ); // 27 bit ( 3 + 2 * (1 + NORMAL_FRACTIONAL_BITS) )
void WriteAngles( const QAngle& rgflValue );
void WriteString( const char *sz ); // max 512 bytes at once
void WriteString( const char *sz );
void WriteBool( bool bValue ); // 1 bit
void WriteEntity( HSCRIPT hEnt ); // 11 bit (entindex)
void WriteEHandle( HSCRIPT hEnt ); // 32 bit long

View File

@ -5,8 +5,8 @@
// $NoKeywords: $
//=============================================================================
#ifndef VSCRIPT_FUNCS_MATH
#define VSCRIPT_FUNCS_MATH
#ifndef WEAPON_CUSTOM_SCRIPTED_H
#define WEAPON_CUSTOM_SCRIPTED_H
#ifdef _WIN32
#pragma once
#endif

View File

@ -335,7 +335,7 @@ void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from )
#if defined( MAPBASE_VSCRIPT ) && defined( GAME_DLL )
if ( buf->ReadOneBit() )
{
g_ScriptNetMsg->RecieveMessage( buf, pPlayer );
g_ScriptNetMsg->ReceiveMessage( buf, pPlayer );
}
#endif

View File

@ -440,13 +440,17 @@ ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler()
bool CBaseEntityScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize )
{
CBaseEntity *pEntity = (CBaseEntity *)p;
#ifdef CLIENT_DLL
if ( pEntity->GetEntityName() && pEntity->GetEntityName()[0] )
#else
if ( pEntity->GetEntityName() != NULL_STRING )
#endif
{
V_snprintf( pBuf, bufSize, "([%d] %s: %s)", pEntity->entindex(), STRING(pEntity->m_iClassname), STRING( pEntity->GetEntityName() ) );
V_snprintf( pBuf, bufSize, "([%d] %s: %s)", pEntity->entindex(), pEntity->GetClassname(), STRING( pEntity->GetEntityName() ) );
}
else
{
V_snprintf( pBuf, bufSize, "([%d] %s)", pEntity->entindex(), STRING(pEntity->m_iClassname) );
V_snprintf( pBuf, bufSize, "([%d] %s)", pEntity->entindex(), pEntity->GetClassname() );
}
return true;
}

View File

@ -0,0 +1,222 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX]
// STATIC: "CUBEMAP" "0..1"
// STATIC: "FLOWMAP" "0..1"
// STATIC: "CORECOLORTEXTURE" "0..1"
// STATIC: "REFRACT" "0..1"
// DYNAMIC: "PIXELFOGTYPE" "0..1"
// SKIP: ( $REFRACT || $CORECOLORTEXTURE ) && $CUBEMAP
#include "common_ps_fxc.h"
sampler RefractSampler : register( s2 );
sampler NormalSampler : register( s3 );
#if CUBEMAP
sampler EnvmapSampler : register( s4 );
#endif
#if FLOWMAP
sampler FlowmapSampler : register( s6 );
#endif
#if CORECOLORTEXTURE
sampler CoreColorSampler : register( s7 );
#endif
const HALF3 g_EnvmapTint : register( c0 );
const HALF3 g_RefractTint : register( c1 );
const HALF3 g_EnvmapContrast : register( c2 );
const HALF3 g_EnvmapSaturation : register( c3 );
const HALF2 g_RefractScale : register( c5 );
#if FLOWMAP
const float g_Time : register( c6 );
const float2 g_FlowScrollRate : register( c7 );
const float g_CoreColorTexCoordOffset : register( c9 );
#endif
const float3 g_EyePos : register( c8 );
const float4 g_FogParams : register( c11 );
const float3 g_SphereCenter : register( c12 );
const float3 g_SphereRadius : register( c15 );
float LengthThroughSphere( float3 vecRayOrigin, float3 vecRayDelta,
float3 vecSphereCenter, float flRadius, out float alpha )
{
// Solve using the ray equation + the sphere equation
// P = o + dt
// (x - xc)^2 + (y - yc)^2 + (z - zc)^2 = r^2
// (ox + dx * t - xc)^2 + (oy + dy * t - yc)^2 + (oz + dz * t - zc)^2 = r^2
// (ox - xc)^2 + 2 * (ox-xc) * dx * t + dx^2 * t^2 +
// (oy - yc)^2 + 2 * (oy-yc) * dy * t + dy^2 * t^2 +
// (oz - zc)^2 + 2 * (oz-zc) * dz * t + dz^2 * t^2 = r^2
// (dx^2 + dy^2 + dz^2) * t^2 + 2 * ((ox-xc)dx + (oy-yc)dy + (oz-zc)dz) t +
// (ox-xc)^2 + (oy-yc)^2 + (oz-zc)^2 - r^2 = 0
// or, t = (-b +/- sqrt( b^2 - 4ac)) / 2a
// a = DotProduct( vecRayDelta, vecRayDelta );
// b = 2 * DotProduct( vecRayOrigin - vecCenter, vecRayDelta )
// c = DotProduct(vecRayOrigin - vecCenter, vecRayOrigin - vecCenter) - flRadius * flRadius;
float3 vecSphereToRay;
vecSphereToRay = vecRayOrigin - vecSphereCenter;
float a = dot( vecRayDelta, vecRayDelta );
// This would occur in the case of a zero-length ray
// if ( a == 0.0f )
// {
// *pT1 = *pT2 = 0.0f;
// return vecSphereToRay.LengthSqr() <= flRadius * flRadius;
// }
float b = 2 * dot( vecSphereToRay, vecRayDelta );
float c = dot( vecSphereToRay, vecSphereToRay ) - flRadius * flRadius;
float flDiscrim = b * b - 4 * a * c;
// if ( flDiscrim < 0.0f )
// return 0.0f;
float hack = flDiscrim;
flDiscrim = sqrt( flDiscrim );
float oo2a = 0.5f / a;
//if( hack < 0.0f )
//{
// alpha = 0.0f;
// return 0.0f;
//}
//else
//{
// alpha = 1.0f;
// return abs( flDiscrim ) * 2 * oo2a;
//}
//replacing the if's above because if's in hlsl are bad.....
float fHackGreaterThanZero = step( 0.0f, hack );
alpha = fHackGreaterThanZero;
return (fHackGreaterThanZero * (abs( flDiscrim ) * 2 * oo2a));
// *pT1 = ( - b - flDiscrim ) * oo2a;
// *pT2 = ( - b + flDiscrim ) * oo2a;
// return true;
}
struct PS_INPUT
{
float2 vBumpTexCoord : TEXCOORD0; // dudvMapAndNormalMapTexCoord
HALF3 vWorldVertToEyeVector : TEXCOORD1;
HALF3x3 tangentSpaceTranspose : TEXCOORD2;
float3 vRefractXYW : TEXCOORD5;
float3 projNormal : TEXCOORD6;
float4 worldPos_projPosZ : TEXCOORD7;
};
float4 main( PS_INPUT i ) : COLOR
{
HALF3 result = 0.0f;
HALF blend = 1.0f;
#if FLOWMAP
// Mapbase tries to un-hack some of this code
//float3 g_SphereCenter = { 2688.0f, 12139.0f, 5170.0f };
//float g_SphereDiameter = 430.0f;
//float g_SphereRadius = g_SphereDiameter * 0.5f;
float g_SphereDiameter = g_SphereRadius * 2.0f;
float3 tmp = i.worldPos_projPosZ.xyz - g_SphereCenter;
float hackRadius = 1.05f * sqrt( dot( tmp, tmp ) );
float sphereAlpha;
float lengthThroughSphere = LengthThroughSphere( g_EyePos, normalize( i.worldPos_projPosZ.xyz - g_EyePos ),
g_SphereCenter, /*g_SphereRadius*/ hackRadius, sphereAlpha );
float normalizedLengthThroughSphere = lengthThroughSphere / g_SphereDiameter;
float3 hackWorldSpaceNormal = normalize( i.worldPos_projPosZ.xyz - g_SphereCenter );
float3 realFuckingNormal = abs( hackWorldSpaceNormal );
hackWorldSpaceNormal = 0.5f * ( hackWorldSpaceNormal + 1.0f );
// hackWorldSpaceNormal = abs( hackWorldSpaceNormal );
// return float4( hackWorldSpaceNormal.x, 0.0f, 0.0f, 1.0f );
i.vBumpTexCoord.xy = 0.0f;
i.vBumpTexCoord.xy = realFuckingNormal.z * tex2D( FlowmapSampler, hackWorldSpaceNormal.xy );
i.vBumpTexCoord.xy += realFuckingNormal.y * tex2D( FlowmapSampler, hackWorldSpaceNormal.xz );
i.vBumpTexCoord.xy += realFuckingNormal.x * tex2D( FlowmapSampler, hackWorldSpaceNormal.yz );
i.vBumpTexCoord.xy += g_Time * g_FlowScrollRate;
// return float4( i.vBumpTexCoord.xy, 0.0f, 0.0f );
#endif
// Load normal and expand range
HALF4 vNormalSample = tex2D( NormalSampler, i.vBumpTexCoord );
// return vNormalSample;
HALF3 tangentSpaceNormal = vNormalSample * 2.0 - 1.0;
HALF3 refractTintColor = g_RefractTint;
// Perform division by W only once
float ooW = 1.0f / i.vRefractXYW.z;
// Compute coordinates for sampling refraction
float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW;
float2 vRefractTexCoord = tangentSpaceNormal.xy;
HALF scale = vNormalSample.a * g_RefractScale.x;
#if FLOWMAP
scale *= normalizedLengthThroughSphere;
#endif
vRefractTexCoord *= scale;
#if FLOWMAP
float2 hackOffset = vRefractTexCoord;
#endif
vRefractTexCoord += vRefractTexCoordNoWarp;
float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy );
float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy );
colorWarp *= refractTintColor;
#if REFRACT
result = lerp( colorNoWarp, colorWarp, blend );
// return float4( 1.0f, 0.0f, 0.0f, 1.0f );
#endif
#if CUBEMAP
HALF specularFactor = vNormalSample.a;
HALF3 worldSpaceNormal = mul( i.tangentSpaceTranspose, tangentSpaceNormal );
HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vWorldVertToEyeVector );
HALF3 specularLighting = texCUBE( EnvmapSampler, reflectVect );
specularLighting *= specularFactor;
specularLighting *= g_EnvmapTint;
HALF3 specularLightingSquared = specularLighting * specularLighting;
specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) );
specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
result += specularLighting;
#endif
#if CORECOLORTEXTURE && FLOWMAP
float4 coreColorTexel = tex2D( CoreColorSampler, hackOffset + float2( normalizedLengthThroughSphere, g_CoreColorTexCoordOffset ) );
HALF4 rgba = HALF4( lerp( result, coreColorTexel, coreColorTexel.a /*normalizedLengthThroughSphere*/ ), sphereAlpha );
#else
HALF4 rgba = HALF4( result, vNormalSample.a );
#endif
float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w );
return FinalOutput( rgba, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,103 @@
// STATIC: "MODEL" "0..1"
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "SKINNING" "0..1"
#include "common_vs_fxc.h"
static const bool g_bSkinning = SKINNING ? true : false;
static const bool g_bModel = MODEL ? true : false;
const float4 cBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 );
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vBoneWeights : BLENDWEIGHT;
float4 vBoneIndices : BLENDINDICES;
float4 vNormal : NORMAL;
float4 vBaseTexCoord : TEXCOORD0;
#if !MODEL
float3 vTangentS : TANGENT;
float3 vTangentT : BINORMAL0;
#else
float4 vUserData : TANGENT;
#endif
};
struct VS_OUTPUT
{
float4 vProjPos_POSITION : POSITION;
float vFog : FOG;
float2 vBumpTexCoord : TEXCOORD0;
float3 vTangentEyeVect : TEXCOORD1;
float3x3 tangentSpaceTranspose : TEXCOORD2;
float3 vRefractXYW : TEXCOORD5;
float4 projNormal_screenCoordW : TEXCOORD6;
float4 worldPos_projPosZ : TEXCOORD7;
float4 fogFactorW : COLOR1;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
float3 worldNormal, worldPos, worldTangentS, worldTangentT;
float3 vObjNormal;
#if MODEL
float4 vObjTangent;
DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vObjNormal, vObjTangent );
SkinPositionNormalAndTangentSpace(
g_bSkinning,
v.vPos, vObjNormal, vObjTangent,
v.vBoneWeights, v.vBoneIndices,
worldPos, worldNormal, worldTangentS, worldTangentT );
#else
DecompressVertex_Normal( v.vNormal, vObjNormal );
worldPos = mul( v.vPos, cModel[0] );
worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] );
worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] );
worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] );
#endif
// Projected position
float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj );
o.vProjPos_POSITION = vProjPos;
o.projNormal_screenCoordW.xyz = mul( worldNormal, cViewProj );
o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z );
// Map projected position to the refraction texture
float2 vRefractPos;
vRefractPos.x = vProjPos.x;
vRefractPos.y = -vProjPos.y; // invert Y
vRefractPos = (vRefractPos + vProjPos.w) * 0.5f;
// Refraction transform
o.vRefractXYW = float3(vRefractPos.x, vRefractPos.y, vProjPos.w);
// Compute fog based on the position
float3 vWorldPos = mul( v.vPos, cModel[0] );
o.fogFactorW = o.vFog = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE );
// Eye vector
float3 vWorldEyeVect = cEyePos - vWorldPos;
// Transform to the tangent space
o.vTangentEyeVect.x = dot( vWorldEyeVect, worldTangentS );
o.vTangentEyeVect.y = dot( vWorldEyeVect, worldTangentT );
o.vTangentEyeVect.z = dot( vWorldEyeVect, worldNormal );
// Tranform bump coordinates
o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] );
o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] );
o.tangentSpaceTranspose[0] = worldTangentS;
o.tangentSpaceTranspose[1] = worldTangentT;
o.tangentSpaceTranspose[2] = worldNormal;
return o;
}

View File

@ -0,0 +1,307 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "BaseVSShader.h"
#include "SDK_core_vs20.inc"
#include "SDK_core_ps20.inc"
#include "SDK_core_ps20b.inc"
#define MAXBLUR 1
DEFINE_FALLBACK_SHADER( SDK_Core, SDK_Core_DX90 )
BEGIN_VS_SHADER( SDK_Core_DX90,
"Help for Core" )
BEGIN_SHADER_PARAMS
SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE )
SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE )
SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" )
SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" )
SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" )
SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" )
SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" )
SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0f", "" )
SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" )
SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" )
SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" )
SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" )
SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" )
SHADER_PARAM( FLOWMAP, SHADER_PARAM_TYPE_TEXTURE, "", "flowmap" )
SHADER_PARAM( FLOWMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $flowmap" )
SHADER_PARAM( FLOWMAPSCROLLRATE, SHADER_PARAM_TYPE_VEC2, "[0 0", "2D rate to scroll $flowmap" )
SHADER_PARAM( CORECOLORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" );
SHADER_PARAM( CORECOLORTEXTUREFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" );
SHADER_PARAM( FLOWMAPTEXCOORDOFFSET, SHADER_PARAM_TYPE_FLOAT, "0.0", "" );
#ifdef MAPBASE
SHADER_PARAM( SPHERECENTER, SHADER_PARAM_TYPE_VEC3, "2688.0, 12139.0, 5170.0", "The sphere's worldspace center (was previously hardcoded)" );
SHADER_PARAM( SPHERERADIUS, SHADER_PARAM_TYPE_FLOAT, "215.0", "The sphere's worldspace radius (was previously hardcoded)" );
#endif
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
SET_FLAGS( MATERIAL_VAR_TRANSLUCENT );
if( !params[ENVMAPTINT]->IsDefined() )
{
params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f );
}
if( !params[ENVMAPCONTRAST]->IsDefined() )
{
params[ENVMAPCONTRAST]->SetFloatValue( 0.0f );
}
if( !params[ENVMAPSATURATION]->IsDefined() )
{
params[ENVMAPSATURATION]->SetFloatValue( 1.0f );
}
if( !params[ENVMAPFRAME]->IsDefined() )
{
params[ENVMAPFRAME]->SetIntValue( 0 );
}
if( !params[BASETEXTURE]->IsDefined() )
{
SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE );
}
}
SHADER_FALLBACK
{
if( g_pHardwareConfig->GetDXSupportLevel() < 90 )
return "Core_dx90";
return 0;
}
SHADER_INIT
{
if (params[BASETEXTURE]->IsDefined() )
{
LoadTexture( BASETEXTURE );
}
if (params[NORMALMAP]->IsDefined() )
{
LoadBumpMap( NORMALMAP );
}
if ( params[ENVMAP]->IsDefined() )
{
LoadCubeMap( ENVMAP );
}
if ( params[FLOWMAP]->IsDefined() )
{
LoadTexture( FLOWMAP );
}
if ( params[CORECOLORTEXTURE]->IsDefined() )
{
LoadTexture( CORECOLORTEXTURE );
}
}
inline void DrawPass( IMaterialVar **params, IShaderShadow* pShaderShadow,
IShaderDynamicAPI* pShaderAPI, int nPass, VertexCompressionType_t vertexCompression )
{
bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL );
bool bHasEnvmap = params[ENVMAP]->IsTexture();
bool bHasFlowmap = params[FLOWMAP]->IsTexture();
bool bHasCoreColorTexture = params[CORECOLORTEXTURE]->IsTexture();
SHADOW_STATE
{
SetInitialShadowState( );
if( nPass == 0 )
{
// Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState
pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) );
}
else
{
pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL );
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE );
}
// If envmap is not specified, the alpha channel is the translucency
// (If envmap *is* specified, alpha channel is the reflection amount)
if ( params[NORMALMAP]->IsTexture() && !bHasEnvmap )
{
SetDefaultBlendingShadowState( NORMALMAP, false );
}
// source render target that contains the image that we are warping.
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER )
{
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true );
}
// normal map
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
if( bHasEnvmap )
{
// envmap
pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER )
{
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true );
}
}
if( bHasFlowmap )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER6, true );
}
if( bHasCoreColorTexture )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER7, true );
}
if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE )
{
pShaderShadow->EnableSRGBWrite( true );
}
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
int userDataSize = 0;
int nTexCoordCount = 1;
if( bIsModel )
{
userDataSize = 4;
}
else
{
flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T;
}
// This shader supports compressed vertices, so OR in that flag:
flags |= VERTEX_FORMAT_COMPRESSED;
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
DECLARE_STATIC_VERTEX_SHADER( sdk_core_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel );
SET_STATIC_VERTEX_SHADER( sdk_core_vs20 );
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( sdk_core_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && ( nPass == 1 ) );
SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap );
SET_STATIC_PIXEL_SHADER_COMBO( CORECOLORTEXTURE, bHasCoreColorTexture && ( nPass == 0 ) );
SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, nPass == 0 );
SET_STATIC_PIXEL_SHADER( sdk_core_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( sdk_core_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && ( nPass == 1 ) );
SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap );
SET_STATIC_PIXEL_SHADER_COMBO( CORECOLORTEXTURE, bHasCoreColorTexture && ( nPass == 0 ) );
SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, nPass == 0 );
SET_STATIC_PIXEL_SHADER( sdk_core_ps20 );
}
DefaultFog();
}
DYNAMIC_STATE
{
pShaderAPI->SetDefaultState();
if ( params[BASETEXTURE]->IsTexture() )
{
BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME );
}
else
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 );
}
BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME );
if( bHasEnvmap )
{
BindTexture( SHADER_SAMPLER4, ENVMAP, ENVMAPFRAME );
}
if( bHasFlowmap )
{
BindTexture( SHADER_SAMPLER6, FLOWMAP, FLOWMAPFRAME );
}
if( bHasCoreColorTexture )
{
BindTexture( SHADER_SAMPLER7, CORECOLORTEXTURE, CORECOLORTEXTUREFRAME );
}
DECLARE_DYNAMIC_VERTEX_SHADER( sdk_core_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( sdk_core_vs20 );
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( sdk_core_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
SET_DYNAMIC_PIXEL_SHADER( sdk_core_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( sdk_core_ps20 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
SET_DYNAMIC_PIXEL_SHADER( sdk_core_ps20 );
}
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM );
if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
{
SetPixelShaderConstant( 0, ENVMAPTINT );
SetPixelShaderConstant( 1, REFRACTTINT );
}
else
{
SetPixelShaderConstantGammaToLinear( 0, ENVMAPTINT );
SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT );
}
SetPixelShaderConstant( 2, ENVMAPCONTRAST );
SetPixelShaderConstant( 3, ENVMAPSATURATION );
float c5[4] = { params[REFRACTAMOUNT]->GetFloatValue(),
params[REFRACTAMOUNT]->GetFloatValue(), 0.0f, 0.0f };
pShaderAPI->SetPixelShaderConstant( 5, c5, 1 );
float eyePos[4];
s_pShaderAPI->GetWorldSpaceCameraPosition( eyePos );
s_pShaderAPI->SetPixelShaderConstant( 8, eyePos, 1 );
pShaderAPI->SetPixelShaderFogParams( 11 );
if( bHasFlowmap )
{
float curTime = pShaderAPI->CurrentTime();
float timeVec[4] = { curTime, curTime, curTime, curTime };
pShaderAPI->SetPixelShaderConstant( 6, timeVec, 1 );
SetPixelShaderConstant( 7, FLOWMAPSCROLLRATE );
SetPixelShaderConstant( 9, FLOWMAPTEXCOORDOFFSET );
}
#ifdef MAPBASE
SetPixelShaderConstant( 12, SPHERECENTER );
SetPixelShaderConstant( 15, SPHERERADIUS );
#endif
}
Draw();
}
SHADER_DRAW
{
DrawPass( params, pShaderShadow, pShaderAPI, 0, vertexCompression );
DrawPass( params, pShaderShadow, pShaderAPI, 1, vertexCompression );
}
END_SHADER

View File

@ -0,0 +1,162 @@
#include "shaderlib/cshader.h"
class sdk_core_ps20_Static_Index
{
private:
int m_nCUBEMAP;
#ifdef _DEBUG
bool m_bCUBEMAP;
#endif
public:
void SetCUBEMAP( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCUBEMAP = i;
#ifdef _DEBUG
m_bCUBEMAP = true;
#endif
}
void SetCUBEMAP( bool i )
{
m_nCUBEMAP = i ? 1 : 0;
#ifdef _DEBUG
m_bCUBEMAP = true;
#endif
}
private:
int m_nFLOWMAP;
#ifdef _DEBUG
bool m_bFLOWMAP;
#endif
public:
void SetFLOWMAP( int i )
{
Assert( i >= 0 && i <= 1 );
m_nFLOWMAP = i;
#ifdef _DEBUG
m_bFLOWMAP = true;
#endif
}
void SetFLOWMAP( bool i )
{
m_nFLOWMAP = i ? 1 : 0;
#ifdef _DEBUG
m_bFLOWMAP = true;
#endif
}
private:
int m_nCORECOLORTEXTURE;
#ifdef _DEBUG
bool m_bCORECOLORTEXTURE;
#endif
public:
void SetCORECOLORTEXTURE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCORECOLORTEXTURE = i;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = true;
#endif
}
void SetCORECOLORTEXTURE( bool i )
{
m_nCORECOLORTEXTURE = i ? 1 : 0;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = true;
#endif
}
private:
int m_nREFRACT;
#ifdef _DEBUG
bool m_bREFRACT;
#endif
public:
void SetREFRACT( int i )
{
Assert( i >= 0 && i <= 1 );
m_nREFRACT = i;
#ifdef _DEBUG
m_bREFRACT = true;
#endif
}
void SetREFRACT( bool i )
{
m_nREFRACT = i ? 1 : 0;
#ifdef _DEBUG
m_bREFRACT = true;
#endif
}
public:
sdk_core_ps20_Static_Index( )
{
#ifdef _DEBUG
m_bCUBEMAP = false;
#endif // _DEBUG
m_nCUBEMAP = 0;
#ifdef _DEBUG
m_bFLOWMAP = false;
#endif // _DEBUG
m_nFLOWMAP = 0;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = false;
#endif // _DEBUG
m_nCORECOLORTEXTURE = 0;
#ifdef _DEBUG
m_bREFRACT = false;
#endif // _DEBUG
m_nREFRACT = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllStaticVarsDefined = m_bCUBEMAP && m_bFLOWMAP && m_bCORECOLORTEXTURE && m_bREFRACT;
Assert( bAllStaticVarsDefined );
#endif // _DEBUG
return ( 2 * m_nCUBEMAP ) + ( 4 * m_nFLOWMAP ) + ( 8 * m_nCORECOLORTEXTURE ) + ( 16 * m_nREFRACT ) + 0;
}
};
#define shaderStaticTest_sdk_core_ps20 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_FLOWMAP + psh_forgot_to_set_static_CORECOLORTEXTURE + psh_forgot_to_set_static_REFRACT + 0
class sdk_core_ps20_Dynamic_Index
{
private:
int m_nPIXELFOGTYPE;
#ifdef _DEBUG
bool m_bPIXELFOGTYPE;
#endif
public:
void SetPIXELFOGTYPE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nPIXELFOGTYPE = i;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
void SetPIXELFOGTYPE( bool i )
{
m_nPIXELFOGTYPE = i ? 1 : 0;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
public:
sdk_core_ps20_Dynamic_Index()
{
#ifdef _DEBUG
m_bPIXELFOGTYPE = false;
#endif // _DEBUG
m_nPIXELFOGTYPE = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nPIXELFOGTYPE ) + 0;
}
};
#define shaderDynamicTest_sdk_core_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0

View File

@ -0,0 +1,187 @@
#include "shaderlib/cshader.h"
class sdk_core_ps20b_Static_Index
{
private:
int m_nCONVERT_TO_SRGB;
#ifdef _DEBUG
bool m_bCONVERT_TO_SRGB;
#endif
public:
void SetCONVERT_TO_SRGB( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCONVERT_TO_SRGB = i;
#ifdef _DEBUG
m_bCONVERT_TO_SRGB = true;
#endif
}
void SetCONVERT_TO_SRGB( bool i )
{
m_nCONVERT_TO_SRGB = i ? 1 : 0;
#ifdef _DEBUG
m_bCONVERT_TO_SRGB = true;
#endif
}
private:
int m_nCUBEMAP;
#ifdef _DEBUG
bool m_bCUBEMAP;
#endif
public:
void SetCUBEMAP( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCUBEMAP = i;
#ifdef _DEBUG
m_bCUBEMAP = true;
#endif
}
void SetCUBEMAP( bool i )
{
m_nCUBEMAP = i ? 1 : 0;
#ifdef _DEBUG
m_bCUBEMAP = true;
#endif
}
private:
int m_nFLOWMAP;
#ifdef _DEBUG
bool m_bFLOWMAP;
#endif
public:
void SetFLOWMAP( int i )
{
Assert( i >= 0 && i <= 1 );
m_nFLOWMAP = i;
#ifdef _DEBUG
m_bFLOWMAP = true;
#endif
}
void SetFLOWMAP( bool i )
{
m_nFLOWMAP = i ? 1 : 0;
#ifdef _DEBUG
m_bFLOWMAP = true;
#endif
}
private:
int m_nCORECOLORTEXTURE;
#ifdef _DEBUG
bool m_bCORECOLORTEXTURE;
#endif
public:
void SetCORECOLORTEXTURE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCORECOLORTEXTURE = i;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = true;
#endif
}
void SetCORECOLORTEXTURE( bool i )
{
m_nCORECOLORTEXTURE = i ? 1 : 0;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = true;
#endif
}
private:
int m_nREFRACT;
#ifdef _DEBUG
bool m_bREFRACT;
#endif
public:
void SetREFRACT( int i )
{
Assert( i >= 0 && i <= 1 );
m_nREFRACT = i;
#ifdef _DEBUG
m_bREFRACT = true;
#endif
}
void SetREFRACT( bool i )
{
m_nREFRACT = i ? 1 : 0;
#ifdef _DEBUG
m_bREFRACT = true;
#endif
}
public:
sdk_core_ps20b_Static_Index( )
{
#ifdef _DEBUG
m_bCONVERT_TO_SRGB = true;
#endif // _DEBUG
m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion();
#ifdef _DEBUG
m_bCUBEMAP = false;
#endif // _DEBUG
m_nCUBEMAP = 0;
#ifdef _DEBUG
m_bFLOWMAP = false;
#endif // _DEBUG
m_nFLOWMAP = 0;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = false;
#endif // _DEBUG
m_nCORECOLORTEXTURE = 0;
#ifdef _DEBUG
m_bREFRACT = false;
#endif // _DEBUG
m_nREFRACT = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bCUBEMAP && m_bFLOWMAP && m_bCORECOLORTEXTURE && m_bREFRACT;
Assert( bAllStaticVarsDefined );
#endif // _DEBUG
return ( 2 * m_nCONVERT_TO_SRGB ) + ( 4 * m_nCUBEMAP ) + ( 8 * m_nFLOWMAP ) + ( 16 * m_nCORECOLORTEXTURE ) + ( 32 * m_nREFRACT ) + 0;
}
};
#define shaderStaticTest_sdk_core_ps20b psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_FLOWMAP + psh_forgot_to_set_static_CORECOLORTEXTURE + psh_forgot_to_set_static_REFRACT + 0
class sdk_core_ps20b_Dynamic_Index
{
private:
int m_nPIXELFOGTYPE;
#ifdef _DEBUG
bool m_bPIXELFOGTYPE;
#endif
public:
void SetPIXELFOGTYPE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nPIXELFOGTYPE = i;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
void SetPIXELFOGTYPE( bool i )
{
m_nPIXELFOGTYPE = i ? 1 : 0;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
public:
sdk_core_ps20b_Dynamic_Index()
{
#ifdef _DEBUG
m_bPIXELFOGTYPE = false;
#endif // _DEBUG
m_nPIXELFOGTYPE = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nPIXELFOGTYPE ) + 0;
}
};
#define shaderDynamicTest_sdk_core_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0

View File

@ -0,0 +1,112 @@
#include "shaderlib/cshader.h"
class sdk_core_vs20_Static_Index
{
private:
int m_nMODEL;
#ifdef _DEBUG
bool m_bMODEL;
#endif
public:
void SetMODEL( int i )
{
Assert( i >= 0 && i <= 1 );
m_nMODEL = i;
#ifdef _DEBUG
m_bMODEL = true;
#endif
}
void SetMODEL( bool i )
{
m_nMODEL = i ? 1 : 0;
#ifdef _DEBUG
m_bMODEL = true;
#endif
}
public:
sdk_core_vs20_Static_Index( )
{
#ifdef _DEBUG
m_bMODEL = false;
#endif // _DEBUG
m_nMODEL = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllStaticVarsDefined = m_bMODEL;
Assert( bAllStaticVarsDefined );
#endif // _DEBUG
return ( 4 * m_nMODEL ) + 0;
}
};
#define shaderStaticTest_sdk_core_vs20 vsh_forgot_to_set_static_MODEL + 0
class sdk_core_vs20_Dynamic_Index
{
private:
int m_nCOMPRESSED_VERTS;
#ifdef _DEBUG
bool m_bCOMPRESSED_VERTS;
#endif
public:
void SetCOMPRESSED_VERTS( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCOMPRESSED_VERTS = i;
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = true;
#endif
}
void SetCOMPRESSED_VERTS( bool i )
{
m_nCOMPRESSED_VERTS = i ? 1 : 0;
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = true;
#endif
}
private:
int m_nSKINNING;
#ifdef _DEBUG
bool m_bSKINNING;
#endif
public:
void SetSKINNING( int i )
{
Assert( i >= 0 && i <= 1 );
m_nSKINNING = i;
#ifdef _DEBUG
m_bSKINNING = true;
#endif
}
void SetSKINNING( bool i )
{
m_nSKINNING = i ? 1 : 0;
#ifdef _DEBUG
m_bSKINNING = true;
#endif
}
public:
sdk_core_vs20_Dynamic_Index()
{
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = false;
#endif // _DEBUG
m_nCOMPRESSED_VERTS = 0;
#ifdef _DEBUG
m_bSKINNING = false;
#endif // _DEBUG
m_nSKINNING = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0;
}
};
#define shaderDynamicTest_sdk_core_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0

View File

@ -0,0 +1,162 @@
#include "shaderlib/cshader.h"
class sdk_core_ps20_Static_Index
{
private:
int m_nCUBEMAP;
#ifdef _DEBUG
bool m_bCUBEMAP;
#endif
public:
void SetCUBEMAP( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCUBEMAP = i;
#ifdef _DEBUG
m_bCUBEMAP = true;
#endif
}
void SetCUBEMAP( bool i )
{
m_nCUBEMAP = i ? 1 : 0;
#ifdef _DEBUG
m_bCUBEMAP = true;
#endif
}
private:
int m_nFLOWMAP;
#ifdef _DEBUG
bool m_bFLOWMAP;
#endif
public:
void SetFLOWMAP( int i )
{
Assert( i >= 0 && i <= 1 );
m_nFLOWMAP = i;
#ifdef _DEBUG
m_bFLOWMAP = true;
#endif
}
void SetFLOWMAP( bool i )
{
m_nFLOWMAP = i ? 1 : 0;
#ifdef _DEBUG
m_bFLOWMAP = true;
#endif
}
private:
int m_nCORECOLORTEXTURE;
#ifdef _DEBUG
bool m_bCORECOLORTEXTURE;
#endif
public:
void SetCORECOLORTEXTURE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCORECOLORTEXTURE = i;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = true;
#endif
}
void SetCORECOLORTEXTURE( bool i )
{
m_nCORECOLORTEXTURE = i ? 1 : 0;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = true;
#endif
}
private:
int m_nREFRACT;
#ifdef _DEBUG
bool m_bREFRACT;
#endif
public:
void SetREFRACT( int i )
{
Assert( i >= 0 && i <= 1 );
m_nREFRACT = i;
#ifdef _DEBUG
m_bREFRACT = true;
#endif
}
void SetREFRACT( bool i )
{
m_nREFRACT = i ? 1 : 0;
#ifdef _DEBUG
m_bREFRACT = true;
#endif
}
public:
sdk_core_ps20_Static_Index( )
{
#ifdef _DEBUG
m_bCUBEMAP = false;
#endif // _DEBUG
m_nCUBEMAP = 0;
#ifdef _DEBUG
m_bFLOWMAP = false;
#endif // _DEBUG
m_nFLOWMAP = 0;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = false;
#endif // _DEBUG
m_nCORECOLORTEXTURE = 0;
#ifdef _DEBUG
m_bREFRACT = false;
#endif // _DEBUG
m_nREFRACT = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllStaticVarsDefined = m_bCUBEMAP && m_bFLOWMAP && m_bCORECOLORTEXTURE && m_bREFRACT;
Assert( bAllStaticVarsDefined );
#endif // _DEBUG
return ( 2 * m_nCUBEMAP ) + ( 4 * m_nFLOWMAP ) + ( 8 * m_nCORECOLORTEXTURE ) + ( 16 * m_nREFRACT ) + 0;
}
};
#define shaderStaticTest_sdk_core_ps20 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_FLOWMAP + psh_forgot_to_set_static_CORECOLORTEXTURE + psh_forgot_to_set_static_REFRACT + 0
class sdk_core_ps20_Dynamic_Index
{
private:
int m_nPIXELFOGTYPE;
#ifdef _DEBUG
bool m_bPIXELFOGTYPE;
#endif
public:
void SetPIXELFOGTYPE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nPIXELFOGTYPE = i;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
void SetPIXELFOGTYPE( bool i )
{
m_nPIXELFOGTYPE = i ? 1 : 0;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
public:
sdk_core_ps20_Dynamic_Index()
{
#ifdef _DEBUG
m_bPIXELFOGTYPE = false;
#endif // _DEBUG
m_nPIXELFOGTYPE = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nPIXELFOGTYPE ) + 0;
}
};
#define shaderDynamicTest_sdk_core_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0

View File

@ -0,0 +1,187 @@
#include "shaderlib/cshader.h"
class sdk_core_ps20b_Static_Index
{
private:
int m_nCONVERT_TO_SRGB;
#ifdef _DEBUG
bool m_bCONVERT_TO_SRGB;
#endif
public:
void SetCONVERT_TO_SRGB( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCONVERT_TO_SRGB = i;
#ifdef _DEBUG
m_bCONVERT_TO_SRGB = true;
#endif
}
void SetCONVERT_TO_SRGB( bool i )
{
m_nCONVERT_TO_SRGB = i ? 1 : 0;
#ifdef _DEBUG
m_bCONVERT_TO_SRGB = true;
#endif
}
private:
int m_nCUBEMAP;
#ifdef _DEBUG
bool m_bCUBEMAP;
#endif
public:
void SetCUBEMAP( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCUBEMAP = i;
#ifdef _DEBUG
m_bCUBEMAP = true;
#endif
}
void SetCUBEMAP( bool i )
{
m_nCUBEMAP = i ? 1 : 0;
#ifdef _DEBUG
m_bCUBEMAP = true;
#endif
}
private:
int m_nFLOWMAP;
#ifdef _DEBUG
bool m_bFLOWMAP;
#endif
public:
void SetFLOWMAP( int i )
{
Assert( i >= 0 && i <= 1 );
m_nFLOWMAP = i;
#ifdef _DEBUG
m_bFLOWMAP = true;
#endif
}
void SetFLOWMAP( bool i )
{
m_nFLOWMAP = i ? 1 : 0;
#ifdef _DEBUG
m_bFLOWMAP = true;
#endif
}
private:
int m_nCORECOLORTEXTURE;
#ifdef _DEBUG
bool m_bCORECOLORTEXTURE;
#endif
public:
void SetCORECOLORTEXTURE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCORECOLORTEXTURE = i;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = true;
#endif
}
void SetCORECOLORTEXTURE( bool i )
{
m_nCORECOLORTEXTURE = i ? 1 : 0;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = true;
#endif
}
private:
int m_nREFRACT;
#ifdef _DEBUG
bool m_bREFRACT;
#endif
public:
void SetREFRACT( int i )
{
Assert( i >= 0 && i <= 1 );
m_nREFRACT = i;
#ifdef _DEBUG
m_bREFRACT = true;
#endif
}
void SetREFRACT( bool i )
{
m_nREFRACT = i ? 1 : 0;
#ifdef _DEBUG
m_bREFRACT = true;
#endif
}
public:
sdk_core_ps20b_Static_Index( )
{
#ifdef _DEBUG
m_bCONVERT_TO_SRGB = true;
#endif // _DEBUG
m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion();
#ifdef _DEBUG
m_bCUBEMAP = false;
#endif // _DEBUG
m_nCUBEMAP = 0;
#ifdef _DEBUG
m_bFLOWMAP = false;
#endif // _DEBUG
m_nFLOWMAP = 0;
#ifdef _DEBUG
m_bCORECOLORTEXTURE = false;
#endif // _DEBUG
m_nCORECOLORTEXTURE = 0;
#ifdef _DEBUG
m_bREFRACT = false;
#endif // _DEBUG
m_nREFRACT = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bCUBEMAP && m_bFLOWMAP && m_bCORECOLORTEXTURE && m_bREFRACT;
Assert( bAllStaticVarsDefined );
#endif // _DEBUG
return ( 2 * m_nCONVERT_TO_SRGB ) + ( 4 * m_nCUBEMAP ) + ( 8 * m_nFLOWMAP ) + ( 16 * m_nCORECOLORTEXTURE ) + ( 32 * m_nREFRACT ) + 0;
}
};
#define shaderStaticTest_sdk_core_ps20b psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_FLOWMAP + psh_forgot_to_set_static_CORECOLORTEXTURE + psh_forgot_to_set_static_REFRACT + 0
class sdk_core_ps20b_Dynamic_Index
{
private:
int m_nPIXELFOGTYPE;
#ifdef _DEBUG
bool m_bPIXELFOGTYPE;
#endif
public:
void SetPIXELFOGTYPE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nPIXELFOGTYPE = i;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
void SetPIXELFOGTYPE( bool i )
{
m_nPIXELFOGTYPE = i ? 1 : 0;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
public:
sdk_core_ps20b_Dynamic_Index()
{
#ifdef _DEBUG
m_bPIXELFOGTYPE = false;
#endif // _DEBUG
m_nPIXELFOGTYPE = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nPIXELFOGTYPE ) + 0;
}
};
#define shaderDynamicTest_sdk_core_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0

View File

@ -0,0 +1,112 @@
#include "shaderlib/cshader.h"
class sdk_core_vs20_Static_Index
{
private:
int m_nMODEL;
#ifdef _DEBUG
bool m_bMODEL;
#endif
public:
void SetMODEL( int i )
{
Assert( i >= 0 && i <= 1 );
m_nMODEL = i;
#ifdef _DEBUG
m_bMODEL = true;
#endif
}
void SetMODEL( bool i )
{
m_nMODEL = i ? 1 : 0;
#ifdef _DEBUG
m_bMODEL = true;
#endif
}
public:
sdk_core_vs20_Static_Index( )
{
#ifdef _DEBUG
m_bMODEL = false;
#endif // _DEBUG
m_nMODEL = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllStaticVarsDefined = m_bMODEL;
Assert( bAllStaticVarsDefined );
#endif // _DEBUG
return ( 4 * m_nMODEL ) + 0;
}
};
#define shaderStaticTest_sdk_core_vs20 vsh_forgot_to_set_static_MODEL + 0
class sdk_core_vs20_Dynamic_Index
{
private:
int m_nCOMPRESSED_VERTS;
#ifdef _DEBUG
bool m_bCOMPRESSED_VERTS;
#endif
public:
void SetCOMPRESSED_VERTS( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCOMPRESSED_VERTS = i;
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = true;
#endif
}
void SetCOMPRESSED_VERTS( bool i )
{
m_nCOMPRESSED_VERTS = i ? 1 : 0;
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = true;
#endif
}
private:
int m_nSKINNING;
#ifdef _DEBUG
bool m_bSKINNING;
#endif
public:
void SetSKINNING( int i )
{
Assert( i >= 0 && i <= 1 );
m_nSKINNING = i;
#ifdef _DEBUG
m_bSKINNING = true;
#endif
}
void SetSKINNING( bool i )
{
m_nSKINNING = i ? 1 : 0;
#ifdef _DEBUG
m_bSKINNING = true;
#endif
}
public:
sdk_core_vs20_Dynamic_Index()
{
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = false;
#endif // _DEBUG
m_nCOMPRESSED_VERTS = 0;
#ifdef _DEBUG
m_bSKINNING = false;
#endif // _DEBUG
m_nSKINNING = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0;
}
};
#define shaderDynamicTest_sdk_core_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0

View File

@ -64,6 +64,8 @@ $Project
$File "engine_post_dx9.cpp"
$File "depthoffield_dx9.cpp"
$File "core_dx9.cpp"
}
//$Shaders "mapbase_dx9_20b.txt"

View File

@ -1566,9 +1566,10 @@ void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar**
// Doing it here in the shader itself allows us to retain other properties, like FANCY_BLENDING.
else
{
// m_SemiStaticCmdsOut wasn't being sent correctly, so we have to assign this to the API directly
float editorBlend = bEditorBlend ? 1.0f : 0.0f;
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 21, &editorBlend, 1 );
// TODO: This is inefficient use of a constant; Something should be done about this in the future
static const float editorBlend[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
static const float regularBlend[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 21, (bEditorBlend ? editorBlend : regularBlend), 1 );
/*
if (bEditorBlend)
{

View File

@ -7,9 +7,9 @@
#include "BaseVSShader.h"
#include "cpp_shader_constant_register_map.h"
#include "sdk_windowimposter_vs20.inc"
#include "sdk_windowimposter_ps20.inc"
#include "sdk_windowimposter_ps20b.inc"
#include "SDK_windowimposter_vs20.inc"
#include "SDK_windowimposter_ps20.inc"
#include "SDK_windowimposter_ps20b.inc"

View File

@ -21,7 +21,7 @@
#include "tier1/utlvector.h"
#include "tier1/utlstring.h"
#include "icvar.h"
#include "color.h"
#include "Color.h"
#ifdef _WIN32
#define FORCEINLINE_CVAR FORCEINLINE
@ -301,6 +301,10 @@ private:
ICommandCallback *m_pCommandCallback;
};
#ifdef MAPBASE_VSCRIPT
// Allow late modification of the completion callback.
public:
#endif
union
{
FnCommandCompletionCallback m_fnCompletionCallback;
@ -308,6 +312,9 @@ private:
};
bool m_bHasCompletionCallback : 1;
#ifdef MAPBASE_VSCRIPT
private:
#endif
bool m_bUsingNewCommandCallback : 1;
bool m_bUsingCommandCallbackInterface : 1;
};

View File

@ -17,21 +17,23 @@
//static const Color CON_COLOR_DEV_VERBOSE( 192, 128, 192, 255 );
// General
#define CON_GROUP_MAPBASE_MISC "Mapbase Misc."
#define CON_GROUP_PHYSICS "Physics"
#define CON_GROUP_MAPBASE_MISC 0 // "Mapbase Misc."
#define CON_GROUP_PHYSICS 1 // "Physics"
// Server
#define CON_GROUP_IO_SYSTEM "I/O System"
#define CON_GROUP_NPC_AI "NPC AI"
#define CON_GROUP_NPC_SCRIPTS "NPC Scripts"
#define CON_GROUP_CHOREO "Choreo"
#define CON_GROUP_IO_SYSTEM 2 // "Entity I/O"
#define CON_GROUP_NPC_AI 3 // "NPC AI"
#define CON_GROUP_NPC_SCRIPTS 4 // "NPC Scripts"
#define CON_GROUP_CHOREO 5 // "Choreo"
// VScript
#define CON_GROUP_VSCRIPT "VScript"
#define CON_GROUP_VSCRIPT_PRINT "VScript Print"
#define CON_GROUP_VSCRIPT 6 // "VScript"
#define CON_GROUP_VSCRIPT_PRINT 7 // "VScript Print"
#define CON_GROUP_MAX 8 // must always be at the end
// Mapbase console group message.
void CGMsg( int level, const char *pszGroup, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
void CGMsg( int level, int nGroup, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
#define CGWarning CGMsg

View File

@ -18,6 +18,15 @@
namespace vgui
{
typedef ButtonCode_t MouseCode;
static inline int MouseButtonBit(MouseCode code)
{
if (code < MOUSE_FIRST || code > MOUSE_LAST) {
Assert(false);
return 0;
}
return 1 << (code - MOUSE_FIRST);
}
}
#endif // MOUSECODE_H

View File

@ -95,6 +95,9 @@
#ifndef IVSCRIPT_H
#define IVSCRIPT_H
#include <type_traits>
#include <utility>
#include "platform.h"
#include "datamap.h"
#include "appframework/IAppSystem.h"
@ -163,20 +166,6 @@ public:
//
//-----------------------------------------------------------------------------
#ifdef MAPBASE_VSCRIPT
template <typename T> T *HScriptToClass( HSCRIPT hObj )
{
return (hObj) ? (T*)g_pScriptVM->GetInstanceValue( hObj, GetScriptDesc( (T*)NULL ) ) : NULL;
}
#else
DECLARE_POINTER_HANDLE( HSCRIPT );
#define INVALID_HSCRIPT ((HSCRIPT)-1)
#endif
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
enum ExtendedFieldType
{
FIELD_TYPEUNKNOWN = FIELD_TYPECOUNT,
@ -645,8 +634,21 @@ struct ScriptEnumDesc_t
//
//-----------------------------------------------------------------------------
// forwards T (and T&) if T is neither enum or an unsigned integer
// the overload for int below captures enums and unsigned integers and "bends" them to int
template<typename T>
static inline typename std::enable_if<!std::is_enum<typename std::remove_reference<T>::type>::value && !std::is_unsigned<typename std::remove_reference<T>::type>::value, T&&>::type ToConstantVariant(T &&value)
{
return std::forward<T>(value);
}
static inline int ToConstantVariant(int value)
{
return value;
}
#define ScriptRegisterConstant( pVM, constant, description ) ScriptRegisterConstantNamed( pVM, constant, #constant, description )
#define ScriptRegisterConstantNamed( pVM, constant, scriptName, description ) do { static ScriptConstantBinding_t binding; binding.m_pszScriptName = scriptName; binding.m_pszDescription = description; binding.m_data = constant; pVM->RegisterConstant( &binding ); } while (0)
#define ScriptRegisterConstantNamed( pVM, constant, scriptName, description ) do { static ScriptConstantBinding_t binding; binding.m_pszScriptName = scriptName; binding.m_pszDescription = description; binding.m_data = ToConstantVariant(constant); pVM->RegisterConstant( &binding ); } while (0)
// Could probably use a better name.
// This is used for registering variants (particularly vectors) not tied to existing variables.
@ -749,9 +751,6 @@ struct ScriptEnumDesc_t
#define DEFINE_SCRIPTHOOK_PARAM( paramName, type ) pHook->AddParameter( paramName, type );
// Define actual parameters instead of global variables
#define DEFINE_SCRIPTHOOK_REALPARAM( paramName, type )
#define END_SCRIPTHOOK() \
pDesc->m_Hooks.AddToTail(pHook); \
}
@ -944,7 +943,7 @@ public:
#endif
#ifdef MAPBASE_VSCRIPT
// virtual void CreateArray(ScriptVariant_t &arr, int size = 0) = 0;
virtual void CreateArray(ScriptVariant_t &arr, int size = 0) = 0;
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) = 0;
#endif
@ -1093,6 +1092,20 @@ public:
#endif
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
#ifdef MAPBASE_VSCRIPT
template <typename T> T *HScriptToClass( HSCRIPT hObj )
{
extern IScriptVM *g_pScriptVM;
return (hObj) ? (T*)g_pScriptVM->GetInstanceValue( hObj, GetScriptDesc( (T*)NULL ) ) : NULL;
}
#else
DECLARE_POINTER_HANDLE( HSCRIPT );
#define INVALID_HSCRIPT ((HSCRIPT)-1)
#endif
//-----------------------------------------------------------------------------
// Script scope helper class

View File

@ -137,29 +137,25 @@ inline void *ScriptConvertFuncPtrToVoid( FUNCPTR_TYPE pFunc )
#elif defined( GNUC )
else if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) )
{
AssertMsg( 0, "Note: This path has not been verified yet. See comments below in #else case." );
struct GnuMFP
{
union
{
void *funcadr; // If vtable_index_2 is even, then this is the function pointer.
int vtable_index_2; // If vtable_index_2 is odd, then this = vindex*2+1.
int vtable_index_2; // If vtable_index_2 is odd, then (vtable_index_2 - 1) * 2 is the index into the vtable.
};
int delta;
int delta; // Offset from this-ptr to vtable
};
GnuMFP *p = (GnuMFP*)&pFunc;
if ( p->vtable_index_2 & 1 )
{
char **delta = (char**)p->delta;
char *pCur = *delta + (p->vtable_index_2+1)/2;
return (void*)( pCur + 4 );
}
else
if ( p->delta == 0 )
{
// No need to check whether this is a direct function pointer or not,
// this gets converted back to a "proper" member-function pointer in
// ScriptConvertFuncPtrFromVoid() to get invoked
return p->funcadr;
}
AssertMsg( 0, "Function pointer must be from primary vtable" );
}
#else
#error "Need to implement code to crack non-offset member function pointer case"
@ -257,8 +253,30 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
convert.mfp.m_delta = 0;
return convert.pFunc;
}
#elif defined( POSIX )
AssertMsg( 0, "Note: This path has not been implemented yet." );
#elif defined( GNUC )
if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) )
{
struct GnuMFP
{
union
{
void *funcadr; // If vtable_index_2 is even, then this is the function pointer.
int vtable_index_2; // If vtable_index_2 is odd, then (vtable_index_2 - 1) * 2 is the index into the vtable.
};
int delta; // Offset from this-ptr to vtable
};
union FuncPtrConvertGnu
{
GnuMFP mfp;
FUNCPTR_TYPE pFunc;
};
FuncPtrConvertGnu convert;
convert.mfp.funcadr = p;
convert.mfp.delta = 0;
return convert.pFunc;
}
#else
#error "Need to implement code to crack non-offset member function pointer case"
#endif

View File

@ -65,46 +65,35 @@ DEFINE_CON_GROUP_CVAR( vscript_print, "80 186 255", "Messages from VScript's 'pr
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#define DEFINE_CON_GROUP(name, codename) { name, &con_group_##codename##_color }
#define DEFINE_CON_GROUP(id, name, codename) { name, &con_group_##codename##_color }
ConGroup_t g_ConGroups[] = {
ConGroup_t g_ConGroups[CON_GROUP_MAX] = {
// General
DEFINE_CON_GROUP( CON_GROUP_MAPBASE_MISC, mapbase_misc ),
DEFINE_CON_GROUP( CON_GROUP_PHYSICS, physics ),
DEFINE_CON_GROUP( CON_GROUP_MAPBASE_MISC, "Mapbase misc.", mapbase_misc ),
DEFINE_CON_GROUP( CON_GROUP_PHYSICS, "Physics", physics ),
// Server
DEFINE_CON_GROUP( CON_GROUP_IO_SYSTEM, inputoutput ),
DEFINE_CON_GROUP( CON_GROUP_NPC_AI, npc_ai ),
DEFINE_CON_GROUP( CON_GROUP_NPC_SCRIPTS, npc_scripts ),
DEFINE_CON_GROUP( CON_GROUP_CHOREO, choreo ),
DEFINE_CON_GROUP( CON_GROUP_IO_SYSTEM, "Entity IO", inputoutput ),
DEFINE_CON_GROUP( CON_GROUP_NPC_AI, "NPC AI", npc_ai ),
DEFINE_CON_GROUP( CON_GROUP_NPC_SCRIPTS, "NPC scripts", npc_scripts ),
DEFINE_CON_GROUP( CON_GROUP_CHOREO, "Choreo", choreo ),
// VScript
DEFINE_CON_GROUP( CON_GROUP_VSCRIPT, vscript ),
DEFINE_CON_GROUP( CON_GROUP_VSCRIPT_PRINT, vscript_print ),
DEFINE_CON_GROUP( CON_GROUP_VSCRIPT, "VScript", vscript ),
DEFINE_CON_GROUP( CON_GROUP_VSCRIPT_PRINT, "VScript print", vscript_print ),
};
void CV_ColorChanged( IConVar *pConVar, const char *pOldString, float flOldValue )
{
for (int i = 0; i < ARRAYSIZE( g_ConGroups ); i++)
for (int i = 0; i < CON_GROUP_MAX; i++)
{
// Reset the alpha to indicate it needs to be refreshed
g_ConGroups[i]._clr[3] = 0;
}
}
ConGroup_t *FindConGroup( const char *pszGroup )
{
for (int i = 0; i < ARRAYSIZE( g_ConGroups ); i++)
{
if (V_strcmp(pszGroup, g_ConGroups[i].pszName) == 0)
return &g_ConGroups[i];
}
return NULL;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@ -113,7 +102,7 @@ ConVar con_group_include_name( "con_group_include_name", "0", FCVAR_NONE, "Inclu
CON_COMMAND( con_group_list, "Prints a list of all console groups." )
{
Msg( "============================================================\n" );
for (int i = 0; i < ARRAYSIZE( g_ConGroups ); i++)
for (int i = 0; i < CON_GROUP_MAX; i++)
{
Msg( " # " );
ConColorMsg( g_ConGroups[i].GetColor(), "%s", g_ConGroups[i].pszName );
@ -146,7 +135,7 @@ CON_COMMAND( con_group_toggle, "Toggles a console group." )
}
*/
void CGMsg( int level, const char *pszGroup, const tchar* pMsg, ... )
void CGMsg( int level, int nGroup, const tchar* pMsg, ... )
{
// Return early if we're not at this level
if (!IsSpewActive("developer", level))
@ -158,22 +147,21 @@ void CGMsg( int level, const char *pszGroup, const tchar* pMsg, ... )
Q_vsnprintf( string, sizeof(string), pMsg, argptr );
va_end( argptr );
ConGroup_t *pGroup = FindConGroup( pszGroup );
if (pGroup)
Assert( nGroup >= 0 );
Assert( nGroup < CON_GROUP_MAX );
ConGroup_t *pGroup = &g_ConGroups[nGroup];
/*if (pGroup->bDisabled)
{
/*if (pGroup->bDisabled)
{
// Do nothing
}
else*/ if (con_group_include_name.GetBool())
{
ConColorMsg( level, pGroup->GetColor(), "[%s] %s", pGroup->pszName, string );
}
else
{
ConColorMsg( level, pGroup->GetColor(), string );
}
// Do nothing
}
else*/ if (con_group_include_name.GetBool())
{
ConColorMsg(level, pGroup->GetColor(), "[%s] %s", pGroup->pszName, string);
}
else
DevMsg( level, string );
{
ConColorMsg(level, pGroup->GetColor(), "%s", string);
}
}

View File

@ -83,6 +83,7 @@ static HSCRIPT VMFKV_LoadFromFile( const char *szFile )
KeyValues *pKV = new KeyValues( szFile );
if ( !pKV->LoadFromFile( g_pFullFileSystem, pszFullName, NULL ) )
{
pKV->deleteThis();
return NULL;
}

View File

@ -11,6 +11,7 @@
#include "vbsp.h"
#include "map.h"
#include "fgdlib/fgdlib.h"
#include "convar.h"
#include "vscript_vbsp.h"
#include "vscript_vbsp.nut"
@ -183,6 +184,28 @@ BEGIN_SCRIPTDESC_ROOT( CMapFile, "Map file" )
END_SCRIPTDESC();
static float cvar_getf( const char* sz )
{
ConVarRef cvar(sz);
if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) )
return NULL;
return cvar.GetFloat();
}
static bool cvar_setf( const char* sz, float val )
{
ConVarRef cvar(sz);
if ( !cvar.IsValid() )
return false;
if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) )
return false;
cvar.SetValue(val);
return true;
}
static const char *GetSource()
{
return source;
@ -244,6 +267,9 @@ bool VScriptVBSPInit()
{
Log( "VSCRIPT VBSP: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
ScriptRegisterFunction( g_pScriptVM, cvar_getf, "Gets the value of the given cvar, as a float." );
ScriptRegisterFunction( g_pScriptVM, cvar_setf, "Sets the value of the given cvar, as a float." );
ScriptRegisterFunction( g_pScriptVM, GetSource, "Gets the base directory of the first map loaded." );
ScriptRegisterFunction( g_pScriptVM, GetMapBase, "Gets the base name of the first map loaded." );
ScriptRegisterFunction( g_pScriptVM, GetMainMap, "Gets the first map loaded." );

View File

@ -695,12 +695,12 @@ void Button::SetMouseClickEnabled(MouseCode code,bool state)
if(state)
{
//set bit to 1
_mouseClickMask|=1<<((int)(code+1));
_mouseClickMask|=MouseButtonBit(code);
}
else
{
//set bit to 0
_mouseClickMask&=~(1<<((int)(code+1)));
_mouseClickMask&=~MouseButtonBit(code);
}
}
@ -709,7 +709,7 @@ void Button::SetMouseClickEnabled(MouseCode code,bool state)
//-----------------------------------------------------------------------------
bool Button::IsMouseClickEnabled(MouseCode code)
{
if(_mouseClickMask&(1<<((int)(code+1))))
if(_mouseClickMask&MouseButtonBit(code))
{
return true;
}

View File

@ -50,100 +50,6 @@ static void ScriptColorPrintL( int r, int g, int b, const char *pszMsg )
ConColorMsg( clr, "%s\n", pszMsg );
}
//=============================================================================
//
// Convar Lookup
//
//=============================================================================
class CScriptConvarLookup
{
public:
float GetFloat( const char *pszConVar )
{
ConVarRef cvar( pszConVar );
return cvar.GetFloat();
}
int GetInt( const char *pszConVar )
{
ConVarRef cvar( pszConVar );
return cvar.GetInt();
}
bool GetBool( const char *pszConVar )
{
ConVarRef cvar( pszConVar );
return cvar.GetBool();
}
const char *GetStr( const char *pszConVar )
{
ConVarRef cvar( pszConVar );
return cvar.GetString();
}
const char *GetDefaultValue( const char *pszConVar )
{
ConVarRef cvar( pszConVar );
return cvar.GetDefault();
}
bool IsFlagSet( const char *pszConVar, int nFlags )
{
ConVarRef cvar( pszConVar );
return cvar.IsFlagSet( nFlags );
}
void SetFloat( const char *pszConVar, float value )
{
SetValue( pszConVar, value );
}
void SetInt( const char *pszConVar, int value )
{
SetValue( pszConVar, value );
}
void SetBool( const char *pszConVar, bool value )
{
SetValue( pszConVar, value );
}
void SetStr( const char *pszConVar, const char *value )
{
SetValue( pszConVar, value );
}
template <typename T>
void SetValue( const char *pszConVar, T value )
{
ConVarRef cvar( pszConVar );
if (!cvar.IsValid())
return;
// FCVAR_NOT_CONNECTED can be used to protect specific convars from nefarious interference
if (cvar.IsFlagSet(FCVAR_NOT_CONNECTED))
return;
cvar.SetValue( value );
}
private:
} g_ScriptConvarLookup;
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptConvarLookup, "CConvars", SCRIPT_SINGLETON "Provides an interface for getting and setting convars." )
DEFINE_SCRIPTFUNC( GetFloat, "Returns the convar as a float. May return null if no such convar." )
DEFINE_SCRIPTFUNC( GetInt, "Returns the convar as an int. May return null if no such convar." )
DEFINE_SCRIPTFUNC( GetBool, "Returns the convar as a bool. May return null if no such convar." )
DEFINE_SCRIPTFUNC( GetStr, "Returns the convar as a string. May return null if no such convar." )
DEFINE_SCRIPTFUNC( GetDefaultValue, "Returns the convar's default value as a string. May return null if no such convar." )
DEFINE_SCRIPTFUNC( IsFlagSet, "Returns the convar's flags. May return null if no such convar." )
DEFINE_SCRIPTFUNC( SetFloat, "Sets the value of the convar as a float." )
DEFINE_SCRIPTFUNC( SetInt, "Sets the value of the convar as an int." )
DEFINE_SCRIPTFUNC( SetBool, "Sets the value of the convar as a bool." )
DEFINE_SCRIPTFUNC( SetStr, "Sets the value of the convar as a string." )
END_SCRIPTDESC();
//=============================================================================
//
@ -203,6 +109,7 @@ BEGIN_SCRIPTDESC_ROOT( CScriptKeyValues, "Wrapper class over KeyValues instance"
DEFINE_SCRIPTFUNC_NAMED( ScriptReleaseKeyValues, "ReleaseKeyValues", "Given a root KeyValues object, release its contents" );
DEFINE_SCRIPTFUNC( TableToSubKeys, "Converts a script table to KeyValues." );
DEFINE_SCRIPTFUNC( SubKeysToTable, "Converts to script table." );
DEFINE_SCRIPTFUNC_NAMED( ScriptFindOrCreateKey, "FindOrCreateKey", "Given a KeyValues object and a key name, find or create a KeyValues object associated with the key name" );
@ -319,6 +226,19 @@ void CScriptKeyValues::TableToSubKeys( HSCRIPT hTable )
}
}
void CScriptKeyValues::SubKeysToTable( HSCRIPT hTable )
{
FOR_EACH_SUBKEY( m_pKeyValues, key )
{
switch ( key->GetDataType() )
{
case KeyValues::TYPE_STRING: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetString() ); break;
case KeyValues::TYPE_INT: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetInt() ); break;
case KeyValues::TYPE_FLOAT: g_pScriptVM->SetValue( hTable, key->GetName(), key->GetFloat() ); break;
}
}
}
HSCRIPT CScriptKeyValues::ScriptFindOrCreateKey( const char *pszName )
{
KeyValues *pKeyValues = m_pKeyValues->FindKey(pszName, true);
@ -529,7 +449,6 @@ void RegisterBaseBindings( IScriptVM *pVM )
//-----------------------------------------------------------------------------
pVM->RegisterInstance( &g_ScriptConvarLookup, "Convars" );
pVM->RegisterInstance( &g_ScriptGlobalSys, "GlobalSys" );
//-----------------------------------------------------------------------------

View File

@ -35,6 +35,7 @@ public:
// Functions below are new with Mapbase
void TableToSubKeys( HSCRIPT hTable );
void SubKeysToTable( HSCRIPT hTable );
HSCRIPT ScriptFindOrCreateKey( const char *pszName );

View File

@ -181,7 +181,7 @@ END_SCRIPTDESC();
bool CScriptQuaternionInstanceHelper::ToString( void *p, char *pBuf, int bufSize )
{
Quaternion *pQuat = ((Quaternion *)p);
V_snprintf( pBuf, bufSize, "(quaternion: (%f, %f, %f, %f))", pQuat->x, pQuat->y, pQuat->z, pQuat->w );
V_snprintf( pBuf, bufSize, "(Quaternion %p [%f %f %f %f])", (void*)pQuat, pQuat->x, pQuat->y, pQuat->z, pQuat->w );
return true;
}
@ -390,6 +390,11 @@ float ScriptCalcDistanceToLineSegment( const Vector &point, const Vector &vLineA
return CalcDistanceToLineSegment( point, vLineA, vLineB );
}
inline float ScriptExponentialDecay( float decayTo, float decayTime, float dt )
{
return ExponentialDecay( decayTo, decayTime, dt );
}
void RegisterMathBaseBindings( IScriptVM *pVM )
{
ScriptRegisterConstantNamed( pVM, ((float)(180.f / M_PI_F)), "RAD2DEG", "" );
@ -453,4 +458,12 @@ void RegisterMathBaseBindings( IScriptVM *pVM )
ScriptRegisterFunctionNamed( pVM, ScriptCalcClosestPointOnLine, "CalcClosestPointOnLine", "Returns the closest point on a line." );
ScriptRegisterFunctionNamed( pVM, ScriptCalcDistanceToLineSegment, "CalcDistanceToLineSegment", "Returns the distance to a line segment." );
ScriptRegisterFunctionNamed( pVM, ScriptCalcClosestPointOnLineSegment, "CalcClosestPointOnLineSegment", "Returns the closest point on a line segment." );
ScriptRegisterFunction( pVM, SimpleSplineRemapVal, "remaps a value in [startInterval, startInterval+rangeInterval] from linear to spline using SimpleSpline" );
ScriptRegisterFunction( pVM, SimpleSplineRemapValClamped, "remaps a value in [startInterval, startInterval+rangeInterval] from linear to spline using SimpleSpline" );
ScriptRegisterFunction( pVM, Bias, "The curve is biased towards 0 or 1 based on biasAmt, which is between 0 and 1." );
ScriptRegisterFunction( pVM, Gain, "Gain is similar to Bias, but biasAmt biases towards or away from 0.5." );
ScriptRegisterFunction( pVM, SmoothCurve, "SmoothCurve maps a 0-1 value into another 0-1 value based on a cosine wave" );
ScriptRegisterFunction( pVM, SmoothCurve_Tweak, "SmoothCurve peaks at flPeakPos, flPeakSharpness controls the sharpness of the peak" );
ScriptRegisterFunctionNamed( pVM, ScriptExponentialDecay, "ExponentialDecay", "decayTo is factor the value should decay to in decayTime" );
}

View File

@ -214,7 +214,7 @@ public:
virtual bool ClearValue(HSCRIPT hScope, const char* pszKey) override;
virtual bool ClearValue( HSCRIPT hScope, ScriptVariant_t pKey ) override;
// virtual void CreateArray(ScriptVariant_t &arr, int size = 0) override;
virtual void CreateArray(ScriptVariant_t &arr, int size = 0) override;
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) override;
//----------------------------------------------------------------------------
@ -241,7 +241,7 @@ public:
HSQOBJECT regexpClass_;
};
SQUserPointer TYPETAG_VECTOR = "VectorTypeTag";
static char TYPETAG_VECTOR[] = "VectorTypeTag";
namespace SQVector
{
@ -270,7 +270,7 @@ namespace SQVector
return 0;
}
SQInteger Get(HSQUIRRELVM vm)
SQInteger _get(HSQUIRRELVM vm)
{
const char* key = nullptr;
sq_getstring(vm, 2, &key);
@ -296,7 +296,7 @@ namespace SQVector
return 1;
}
SQInteger Set(HSQUIRRELVM vm)
SQInteger _set(HSQUIRRELVM vm)
{
const char* key = nullptr;
sq_getstring(vm, 2, &key);
@ -328,7 +328,7 @@ namespace SQVector
return 0;
}
SQInteger Add(HSQUIRRELVM vm)
SQInteger _add(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
Vector* v2 = nullptr;
@ -350,7 +350,7 @@ namespace SQVector
return 1;
}
SQInteger Sub(HSQUIRRELVM vm)
SQInteger _sub(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
Vector* v2 = nullptr;
@ -372,23 +372,20 @@ namespace SQVector
return 1;
}
SQInteger Multiply(HSQUIRRELVM vm)
SQInteger _multiply(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, float) or (Vector, Vector)");
return sq_throwerror(vm, "Expected (Vector, Vector|float)");
}
SQObjectType paramType = sq_gettype(vm, 2);
float s = 0.0;
Vector* v2 = nullptr;
if ((paramType & SQOBJECT_NUMERIC) &&
SQ_SUCCEEDED(sq_getfloat(vm, 2, &s)))
if ( SQ_SUCCEEDED(sq_getfloat(vm, 2, &s)) )
{
sq_getclass(vm, 1);
sq_createinstance(vm, -1);
@ -399,8 +396,7 @@ namespace SQVector
return 1;
}
else if (paramType == OT_INSTANCE &&
SQ_SUCCEEDED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v2, TYPETAG_VECTOR)))
else if ( SQ_SUCCEEDED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v2, TYPETAG_VECTOR)) )
{
sq_getclass(vm, 1);
sq_createinstance(vm, -1);
@ -413,27 +409,24 @@ namespace SQVector
}
else
{
return sq_throwerror(vm, "Expected (Vector, float) or (Vector, Vector)");
return sq_throwerror(vm, "Expected (Vector, Vector|float)");
}
}
SQInteger Divide(HSQUIRRELVM vm)
SQInteger _divide(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, float) or (Vector, Vector)");
return sq_throwerror(vm, "Expected (Vector, Vector|float)");
}
SQObjectType paramType = sq_gettype(vm, 2);
float s = 0.0;
Vector* v2 = nullptr;
if ((paramType & SQOBJECT_NUMERIC) &&
SQ_SUCCEEDED(sq_getfloat(vm, 2, &s)))
if ( SQ_SUCCEEDED(sq_getfloat(vm, 2, &s)) )
{
sq_getclass(vm, 1);
sq_createinstance(vm, -1);
@ -444,8 +437,7 @@ namespace SQVector
return 1;
}
else if (paramType == OT_INSTANCE &&
SQ_SUCCEEDED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v2, TYPETAG_VECTOR)))
else if ( SQ_SUCCEEDED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v2, TYPETAG_VECTOR)) )
{
sq_getclass(vm, 1);
sq_createinstance(vm, -1);
@ -458,10 +450,226 @@ namespace SQVector
}
else
{
return sq_throwerror(vm, "Expected (Vector, float) or (Vector, Vector)");
return sq_throwerror(vm, "Expected (Vector, Vector|float)");
}
}
SQInteger _unm(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
if (sq_gettop(vm) != 1 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector)");
}
sq_getclass(vm, 1);
sq_createinstance(vm, -1);
SQUserPointer p;
sq_getinstanceup(vm, -1, &p, 0);
new(p) Vector(-v1->x, -v1->y, -v1->z);
sq_remove(vm, -2);
return 1;
}
// multi purpose - copy from input vector, or init with 3 float input
SQInteger Set(HSQUIRRELVM vm)
{
SQInteger top = sq_gettop(vm);
Vector* v1 = nullptr;
if ( top < 2 || SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) )
{
return sq_throwerror(vm, "Expected (Vector, Vector)");
}
Vector* v2 = nullptr;
if ( SQ_SUCCEEDED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR)) )
{
if ( top != 2 )
return sq_throwerror(vm, "Expected (Vector, Vector)");
VectorCopy( *v2, *v1 );
sq_remove( vm, -1 );
return 1;
}
float x, y, z;
if ( top == 4 &&
SQ_SUCCEEDED(sq_getfloat(vm, 2, &x)) &&
SQ_SUCCEEDED(sq_getfloat(vm, 3, &y)) &&
SQ_SUCCEEDED(sq_getfloat(vm, 4, &z)) )
{
v1->Init( x, y, z );
sq_pop( vm, 3 );
return 1;
}
return sq_throwerror(vm, "Expected (Vector, Vector)");
}
SQInteger Add(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
Vector* v2 = nullptr;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ||
SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, Vector)");
}
VectorAdd( *v1, *v2, *v1 );
sq_remove( vm, -1 );
return 1;
}
SQInteger Subtract(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
Vector* v2 = nullptr;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ||
SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, Vector)");
}
VectorSubtract( *v1, *v2, *v1 );
sq_remove( vm, -1 );
return 1;
}
SQInteger Multiply(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, Vector|float)");
}
Vector* v2 = nullptr;
if ( SQ_SUCCEEDED(sq_getinstanceup( vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR )) )
{
VectorMultiply( *v1, *v2, *v1 );
sq_remove( vm, -1 );
return 1;
}
float flInput;
if ( SQ_SUCCEEDED(sq_getfloat( vm, 2, &flInput )) )
{
VectorMultiply( *v1, flInput, *v1 );
sq_remove( vm, -1 );
return 1;
}
return sq_throwerror(vm, "Expected (Vector, Vector|float)");
}
SQInteger Divide(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, Vector|float)");
}
Vector* v2 = nullptr;
if ( SQ_SUCCEEDED(sq_getinstanceup( vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR )) )
{
VectorDivide( *v1, *v2, *v1 );
sq_remove( vm, -1 );
return 1;
}
float flInput;
if ( SQ_SUCCEEDED(sq_getfloat( vm, 2, &flInput )) )
{
VectorDivide( *v1, flInput, *v1 );
sq_remove( vm, -1 );
return 1;
}
return sq_throwerror(vm, "Expected (Vector, Vector|float)");
}
SQInteger DistTo(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
Vector* v2 = nullptr;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ||
SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, Vector)");
}
sq_pushfloat( vm, v1->DistTo(*v2) );
return 1;
}
SQInteger DistToSqr(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
Vector* v2 = nullptr;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ||
SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, Vector)");
}
sq_pushfloat( vm, v1->DistToSqr(*v2) );
return 1;
}
SQInteger IsEqualTo(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
Vector* v2 = nullptr;
if (sq_gettop(vm) < 2 || // bother checking > 3?
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ||
SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&v2, TYPETAG_VECTOR)) )
{
return sq_throwerror(vm, "Expected (Vector, Vector, float)");
}
float tolerance = 0.0f;
sq_getfloat( vm, 3, &tolerance );
sq_pushbool( vm, VectorsAreEqual( *v1, *v2, tolerance ) );
return 1;
}
SQInteger Length(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
@ -557,30 +765,23 @@ namespace SQVector
SQInteger Scale(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
float s = 0.0f;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ||
SQ_SUCCEEDED(sq_getfloat(vm, 2, &s)))
{
return sq_throwerror(vm, "Expected (Vector, float)");
}
float s = 0.0;
sq_getclass(vm, 1);
sq_createinstance(vm, -1);
SQUserPointer p;
sq_getinstanceup(vm, -1, &p, 0);
new(p) Vector((*v1) * s);
sq_remove(vm, -2);
if (SQ_SUCCEEDED(sq_getfloat(vm, 2, &s)))
{
sq_getclass(vm, 1);
sq_createinstance(vm, -1);
SQUserPointer p;
sq_getinstanceup(vm, -1, &p, 0);
new(p) Vector((*v1) * s);
sq_remove(vm, -2);
return 1;
}
else
{
return sq_throwerror(vm, "Expected (Vector, float)");
}
return 1;
}
SQInteger Dot(HSQUIRRELVM vm)
@ -613,6 +814,42 @@ namespace SQVector
return 1;
}
SQInteger FromKVString(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
const char* szInput;
if (sq_gettop(vm) != 2 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ||
SQ_FAILED(sq_getstring(vm, 2, &szInput)) )
{
return sq_throwerror(vm, "Expected (Vector, string)");
}
float x = 0.0f, y = 0.0f, z = 0.0f;
if ( sscanf( szInput, "%f %f %f", &x, &y, &z ) < 3 ) // UTIL_StringToVector
{
// Don't throw, return null while invalidating the input vector.
// This allows the user to easily check for input errors without halting.
//return sq_throwerror(vm, "invalid KV string");
sq_pushnull(vm);
*v1 = vec3_invalid;
return 1;
}
v1->x = x;
v1->y = y;
v1->z = z;
// return input vector
sq_remove( vm, -1 );
return 1;
}
SQInteger Cross(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
@ -635,6 +872,25 @@ namespace SQVector
return 1;
}
SQInteger WithinAABox(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
Vector* mins = nullptr;
Vector* maxs = nullptr;
if (sq_gettop(vm) != 3 ||
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)) ||
SQ_FAILED(sq_getinstanceup(vm, 2, (SQUserPointer*)&mins, TYPETAG_VECTOR)) ||
SQ_FAILED(sq_getinstanceup(vm, 3, (SQUserPointer*)&maxs, TYPETAG_VECTOR)))
{
return sq_throwerror(vm, "Expected (Vector, Vector, Vector)");
}
sq_pushbool( vm, v1->WithinAABox( *mins, *maxs ) );
return 1;
}
SQInteger ToString(HSQUIRRELVM vm)
{
Vector* v1 = nullptr;
@ -645,7 +901,7 @@ namespace SQVector
return sq_throwerror(vm, "Expected (Vector)");
}
sqstd_pushstringf(vm, "(vector: (%f, %f, %f))", v1->x, v1->y, v1->z);
sqstd_pushstringf(vm, "(Vector %p [%f %f %f])", (void*)v1, v1->x, v1->y, v1->z);
return 1;
}
@ -701,22 +957,33 @@ namespace SQVector
static const SQRegFunction funcs[] = {
{_SC("constructor"), Construct,0,nullptr},
{_SC("_get"), Get, 2, _SC(".s")},
{_SC("_set"), Set, 3, _SC(".sn")},
{_SC("_add"), Add, 2, _SC("..")},
{_SC("_sub"), Sub, 2, _SC("..")},
{_SC("_mul"), Multiply, 2, _SC("..")},
{_SC("_div"), Divide, 2, _SC("..")},
{_SC("_get"), _get, 2, _SC(".s")},
{_SC("_set"), _set, 3, _SC(".sn")},
{_SC("_add"), _add, 2, _SC("..")},
{_SC("_sub"), _sub, 2, _SC("..")},
{_SC("_mul"), _multiply, 2, _SC("..")},
{_SC("_div"), _divide, 2, _SC("..")},
{_SC("_unm"), _unm, 1, _SC(".")},
{_SC("Set"), Set, -2, _SC("..nn")},
{_SC("Add"), Add, 2, _SC("..")},
{_SC("Subtract"), Subtract, 2, _SC("..")},
{_SC("Multiply"), Multiply, 2, _SC("..")},
{_SC("Divide"), Divide, 2, _SC("..")},
{_SC("DistTo"), DistTo, 2, _SC("..")},
{_SC("DistToSqr"), DistToSqr, 2, _SC("..")},
{_SC("IsEqualTo"), IsEqualTo, -2, _SC("..n")},
{_SC("Length"), Length, 1, _SC(".")},
{_SC("LengthSqr"), LengthSqr, 1, _SC(".")},
{_SC("Length2D"), Length2D, 1, _SC(".")},
{_SC("Length2DSqr"), Length2DSqr, 1, _SC(".")},
{_SC("Normalized"), Normalized, 1, _SC(".")},
{_SC("Norm"), Norm, 1, _SC(".")},
{_SC("Scale"), Scale, 2, _SC("..")},
{_SC("Scale"), Scale, 2, _SC(".n")}, // identical to _multiply
{_SC("Dot"), Dot, 2, _SC("..")},
{_SC("Cross"), Cross, 2, _SC("..")},
{_SC("WithinAABox"), WithinAABox, 3, _SC("...")},
{_SC("ToKVString"), ToKVString, 1, _SC(".")},
{_SC("FromKVString"), FromKVString, 2, _SC(".s")},
{_SC("_tostring"), ToString, 1, _SC(".")},
{_SC("_typeof"), TypeOf, 1, _SC(".")},
{_SC("_nexti"), Nexti, 2, _SC("..")},
@ -827,7 +1094,7 @@ void PushVariant(HSQUIRRELVM vm, const ScriptVariant_t& value)
sq_createinstance(vm, -1);
SQUserPointer p;
sq_getinstanceup(vm, -1, &p, 0);
new(p) Vector(value);
new(p) Vector(static_cast<const Vector&>(value));
sq_remove(vm, -2);
break;
}
@ -2698,7 +2965,7 @@ bool SquirrelVM::ClearValue(HSCRIPT hScope, ScriptVariant_t pKey)
return true;
}
/*
void SquirrelVM::CreateArray(ScriptVariant_t &arr, int size)
{
SquirrelSafeCheck safeCheck(vm_);
@ -2713,16 +2980,14 @@ void SquirrelVM::CreateArray(ScriptVariant_t &arr, int size)
arr = (HSCRIPT)obj;
}
*/
bool SquirrelVM::ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val)
{
SquirrelSafeCheck safeCheck(vm_);
HSQOBJECT arr = *(HSQOBJECT*)hArray;
if ( !sq_isarray(arr) )
return false;
HSQOBJECT *arr = (HSQOBJECT*)hArray;
sq_pushobject(vm_, arr);
sq_pushobject(vm_, *arr);
PushVariant(vm_, val);
bool ret = sq_arrayappend(vm_, -2) == SQ_OK;
sq_pop(vm_, 1);

View File

@ -65,6 +65,22 @@ function AngleDistance( next, cur )
return delta
}
function FLerp( f1, f2, i1, i2, x )
{
return f1+(f2-f1)*(x-i1)/(i2-i1);
}
function Lerp( f, A, B )
{
return A + ( B - A ) * f
}
function SimpleSpline( f )
{
local ff = f * f;
return 3.0 * ff - 2.0 * ff * f;
}
function printl( text )
{
return ::print(text + "\n");