mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2024-12-23 01:59:43 +08:00
Added original SDK code for Alien Swarm.
This commit is contained in:
commit
c0a96ff1e8
116
common/ConfigManager.h
Normal file
116
common/ConfigManager.h
Normal file
@ -0,0 +1,116 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CONFIGMANAGER_H
|
||||
#define CONFIGMANAGER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "KeyValues.h"
|
||||
#include "utlvector.h"
|
||||
#include "filesystem_init.h"
|
||||
|
||||
|
||||
// See filesystem_init for the vconfig registry values.
|
||||
|
||||
|
||||
#define TOKEN_GAMES "Games"
|
||||
#define TOKEN_GAME_DIRECTORY "GameDir"
|
||||
#define TOKEN_TOOLS "Tools"
|
||||
|
||||
// STEAM CLOUD FLAGS
|
||||
#define STEAMREMOTESTORAGE_CLOUD_CONFIG (1<<0)
|
||||
#define STEAMREMOTESTORAGE_CLOUD_SPRAY (1<<1)
|
||||
|
||||
#define STEAMREMOTESTORAGE_CLOUD_ALL 0x7fff // all bits set, so any new items added will be on by default
|
||||
|
||||
struct defaultConfigInfo_t
|
||||
{
|
||||
char gameName[MAX_PATH];
|
||||
char gameDir[MAX_PATH];
|
||||
char FGD[MAX_PATH];
|
||||
char steamPath[MAX_PATH];
|
||||
char defaultPointEntity[MAX_PATH];
|
||||
char exeName[MAX_PATH];
|
||||
int steamAppID;
|
||||
};
|
||||
|
||||
enum eSDKEpochs
|
||||
{
|
||||
HL2 = 1,
|
||||
EP1 = 2,
|
||||
EP2 = 3,
|
||||
SWARM = 4,
|
||||
};
|
||||
|
||||
extern defaultConfigInfo_t *gDefaultConfigs[];
|
||||
|
||||
class CGameConfigManager
|
||||
{
|
||||
public:
|
||||
|
||||
enum loadStatus_t
|
||||
{
|
||||
LOADSTATUS_NONE = 0, // Configs were loaded with no error
|
||||
LOADSTATUS_CONVERTED, // GameConfig.txt did not exist and was created by converting GameCfg.INI
|
||||
LOADSTATUS_CREATED, // GameCfg.INI was not found, the system created the default configuration based on found GameInfo.txt resources
|
||||
LOADSTATUS_ERROR, // File was not loaded and was unable to perform the above fail-safe procedures
|
||||
};
|
||||
|
||||
CGameConfigManager( void );
|
||||
CGameConfigManager( const char *fileName );
|
||||
|
||||
~CGameConfigManager( void );
|
||||
|
||||
bool LoadConfigs( const char *baseDir = NULL );
|
||||
bool SaveConfigs( const char *baseDir = NULL );
|
||||
bool ResetConfigs( const char *baseDir = NULL );
|
||||
|
||||
int GetNumConfigs( void );
|
||||
|
||||
KeyValues *GetGameBlock( void );
|
||||
KeyValues *GetGameSubBlock( const char *keyName );
|
||||
bool GetDefaultGameBlock( KeyValues *pIn );
|
||||
|
||||
bool IsLoaded( void ) const { return m_pData != NULL; }
|
||||
|
||||
bool WasConvertedOnLoad( void ) const { return m_LoadStatus == LOADSTATUS_CONVERTED; }
|
||||
bool WasCreatedOnLoad( void ) const { return m_LoadStatus == LOADSTATUS_CREATED; }
|
||||
|
||||
bool AddDefaultConfig( const defaultConfigInfo_t &info, KeyValues *out, const char *rootDirectory, const char *gameExeDir );
|
||||
|
||||
void SetBaseDirectory( const char *pDirectory );
|
||||
|
||||
void GetRootGameDirectory( char *out, size_t outLen, const char *rootDir, const char *steamDir );
|
||||
|
||||
const char *GetRootDirectory( void );
|
||||
void SetSDKEpoch( eSDKEpochs epoch ) { m_eSDKEpoch = epoch; };
|
||||
|
||||
private:
|
||||
|
||||
void GetRootContentDirectory( char *out, size_t outLen, const char *rootDir );
|
||||
|
||||
const char *GetBaseDirectory( void );
|
||||
const char *GetIniFilePath( void );
|
||||
|
||||
bool LoadConfigsInternal( const char *baseDir, bool bRecursiveCall );
|
||||
void UpdateConfigsInternal( void );
|
||||
void VersionConfig( void );
|
||||
bool IsConfigCurrent( void );
|
||||
|
||||
bool ConvertGameConfigsINI( void );
|
||||
bool CreateAllDefaultConfigs( void );
|
||||
bool IsAppSubscribed( int nAppID );
|
||||
|
||||
loadStatus_t m_LoadStatus; // Holds various state about what occured while loading
|
||||
KeyValues *m_pData; // Data as read from configuration file
|
||||
char m_szBaseDirectory[MAX_PATH]; // Default directory
|
||||
eSDKEpochs m_eSDKEpoch; // Holds the "working version" of the SDK for times when we need to create an older set of game configurations.
|
||||
// This is required now that the SDK is deploying the tools for both the latest and previous versions of the engine.
|
||||
};
|
||||
|
||||
#endif // CONFIGMANAGER_H
|
41
common/GameUI/IGameConsole.h
Normal file
41
common/GameUI/IGameConsole.h
Normal file
@ -0,0 +1,41 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef IGAMECONSOLE_H
|
||||
#define IGAMECONSOLE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/interface.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: interface to game/dev console
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IGameConsole : public IBaseInterface
|
||||
{
|
||||
public:
|
||||
// activates the console, makes it visible and brings it to the foreground
|
||||
virtual void Activate() = 0;
|
||||
|
||||
virtual void Initialize() = 0;
|
||||
|
||||
// hides the console
|
||||
virtual void Hide() = 0;
|
||||
|
||||
// clears the console
|
||||
virtual void Clear() = 0;
|
||||
|
||||
// return true if the console has focus
|
||||
virtual bool IsConsoleVisible() = 0;
|
||||
|
||||
virtual void SetParent( int parent ) = 0;
|
||||
};
|
||||
|
||||
#define GAMECONSOLE_INTERFACE_VERSION "GameConsole004"
|
||||
|
||||
#endif // IGAMECONSOLE_H
|
103
common/GameUI/IGameUI.h
Normal file
103
common/GameUI/IGameUI.h
Normal file
@ -0,0 +1,103 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IGAMEUI_H
|
||||
#define IGAMEUI_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "interface.h"
|
||||
#include "vgui/ipanel.h"
|
||||
|
||||
#if !defined( _X360 )
|
||||
#include "xbox/xboxstubs.h"
|
||||
#endif
|
||||
|
||||
class CCommand;
|
||||
|
||||
// reasons why the user can't connect to a game server
|
||||
enum ESteamLoginFailure
|
||||
{
|
||||
STEAMLOGINFAILURE_NONE,
|
||||
STEAMLOGINFAILURE_BADTICKET,
|
||||
STEAMLOGINFAILURE_NOSTEAMLOGIN,
|
||||
STEAMLOGINFAILURE_VACBANNED,
|
||||
STEAMLOGINFAILURE_LOGGED_IN_ELSEWHERE
|
||||
};
|
||||
|
||||
enum ESystemNotify
|
||||
{
|
||||
SYSTEMNOTIFY_STORAGEDEVICES_CHANGED,
|
||||
SYSTEMNOTIFY_USER_SIGNEDIN,
|
||||
SYSTEMNOTIFY_USER_SIGNEDOUT,
|
||||
SYSTEMNOTIFY_XLIVE_LOGON_ESTABLISHED, // we are logged into live service
|
||||
SYSTEMNOTIFY_XLIVE_LOGON_CLOSED, // no longer logged into live - either from natural (signed out) or unnatural (e.g. severed net connection) causes
|
||||
SYSTEMNOTIFY_XUIOPENING,
|
||||
SYSTEMNOTIFY_XUICLOSED,
|
||||
SYSTEMNOTIFY_INVITE_SHUTDOWN, // Cross-game invite is causing us to shutdown
|
||||
SYSTEMNOTIFY_MUTECHANGED, // Player changed mute settings
|
||||
SYSTEMNOTIFY_INPUTDEVICESCHANGED, // Input device has changed (used for controller disconnection)
|
||||
SYSTEMNOTIFY_PROFILE_UNAVAILABLE, // Profile failed to read or write
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: contains all the functions that the GameUI dll exports
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IGameUI
|
||||
{
|
||||
public:
|
||||
// initialization/shutdown
|
||||
virtual void Initialize( CreateInterfaceFn appFactory ) = 0;
|
||||
virtual void PostInit() = 0;
|
||||
|
||||
// connect to other interfaces at the same level (gameui.dll/server.dll/client.dll)
|
||||
virtual void Connect( CreateInterfaceFn gameFactory ) = 0;
|
||||
|
||||
virtual void Start() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual void RunFrame() = 0;
|
||||
|
||||
// notifications
|
||||
virtual void OnGameUIActivated() = 0;
|
||||
virtual void OnGameUIHidden() = 0;
|
||||
|
||||
// OLD: Use OnConnectToServer2
|
||||
virtual void OLD_OnConnectToServer(const char *game, int IP, int port) = 0;
|
||||
|
||||
virtual void OnDisconnectFromServer_OLD( uint8 eSteamLoginFailure, const char *username ) = 0;
|
||||
virtual void OnLevelLoadingStarted( const char *levelName, bool bShowProgressDialog ) = 0;
|
||||
virtual void OnLevelLoadingFinished(bool bError, const char *failureReason, const char *extendedReason) = 0;
|
||||
|
||||
// level loading progress, returns true if the screen needs updating
|
||||
virtual bool UpdateProgressBar(float progress, const char *statusText) = 0;
|
||||
// Shows progress desc, returns previous setting... (used with custom progress bars )
|
||||
virtual bool SetShowProgressText( bool show ) = 0;
|
||||
|
||||
// !!!!!!!!!members added after "GameUI011" initial release!!!!!!!!!!!!!!!!!!!
|
||||
// Allows the level loading progress to show map-specific info
|
||||
virtual void SetProgressLevelName( const char *levelName ) = 0;
|
||||
|
||||
// inserts specified panel as background for level load dialog
|
||||
virtual void SetLoadingBackgroundDialog( vgui::VPANEL panel ) = 0;
|
||||
|
||||
virtual void OnConnectToServer2(const char *game, int IP, int connectionPort, int queryPort) = 0;
|
||||
|
||||
virtual void SetProgressOnStart() = 0;
|
||||
virtual void OnDisconnectFromServer( uint8 eSteamLoginFailure ) = 0;
|
||||
|
||||
virtual void NeedConnectionProblemWaitScreen() = 0;
|
||||
virtual void ShowPasswordUI( char const *pchCurrentPW ) = 0;
|
||||
|
||||
#if defined( _X360 ) && defined( _DEMO )
|
||||
virtual void OnDemoTimeout( void ) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define GAMEUI_INTERFACE_VERSION "GameUI011"
|
||||
|
||||
#endif // IGAMEUI_H
|
81
common/IRunGameEngine.h
Normal file
81
common/IRunGameEngine.h
Normal file
@ -0,0 +1,81 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef IRUNGAMEENGINE_H
|
||||
#define IRUNGAMEENGINE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
#ifdef GetUserName
|
||||
#undef GetUserName
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to running the game engine
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IRunGameEngine : public IBaseInterface
|
||||
{
|
||||
public:
|
||||
// Returns true if the engine is running, false otherwise.
|
||||
virtual bool IsRunning() = 0;
|
||||
|
||||
// Adds text to the engine command buffer. Only works if IsRunning()
|
||||
// returns true on success, false on failure
|
||||
virtual bool AddTextCommand(const char *text) = 0;
|
||||
|
||||
// runs the engine with the specified command line parameters. Only works if !IsRunning()
|
||||
// returns true on success, false on failure
|
||||
virtual bool RunEngine(const char *gameDir, const char *commandLineParams) = 0;
|
||||
|
||||
// returns true if the player is currently connected to a game server
|
||||
virtual bool IsInGame() = 0;
|
||||
|
||||
// gets information about the server the engine is currently connected to
|
||||
// returns true on success, false on failure
|
||||
virtual bool GetGameInfo(char *infoBuffer, int bufferSize) = 0;
|
||||
|
||||
// tells the engine our userID
|
||||
virtual void SetTrackerUserID(int trackerID, const char *trackerName) = 0;
|
||||
|
||||
// this next section could probably moved to another interface
|
||||
// iterates users
|
||||
// returns the number of user
|
||||
virtual int GetPlayerCount() = 0;
|
||||
|
||||
// returns a playerID for a player
|
||||
// playerIndex is in the range [0, GetPlayerCount)
|
||||
virtual unsigned int GetPlayerFriendsID(int playerIndex) = 0;
|
||||
|
||||
// gets the in-game name of another user, returns NULL if that user doesn't exists
|
||||
virtual const char *GetPlayerName(int friendsID) = 0;
|
||||
|
||||
// gets the friends name of a player
|
||||
virtual const char *GetPlayerFriendsName(int friendsID) = 0;
|
||||
|
||||
// returns the engine build number and mod version string for server versioning
|
||||
virtual unsigned int GetEngineBuildNumber() = 0;
|
||||
virtual const char *GetProductVersionString() = 0;
|
||||
|
||||
// new interface to RunEngine (done so we don't have to roll the interface version)
|
||||
virtual bool RunEngine2(const char *gameDir, const char *commandLineParams, bool isSourceGame) = 0;
|
||||
|
||||
enum ERunResult
|
||||
{
|
||||
k_ERunResultOkay = 0,
|
||||
k_ERunResultModNotInstalled = 1,
|
||||
k_ERunResultAppNotFound = 2,
|
||||
k_ERunResultNotInitialized = 3,
|
||||
};
|
||||
virtual ERunResult RunEngine( int iAppID, const char *gameDir, const char *commandLineParams ) = 0;
|
||||
|
||||
};
|
||||
|
||||
#define RUNGAMEENGINE_INTERFACE_VERSION "RunGameEngine005"
|
||||
|
||||
#endif // IRUNGAMEENGINE_H
|
64
common/IVGuiModule.h
Normal file
64
common/IVGuiModule.h
Normal file
@ -0,0 +1,64 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IVGUIMODULE_H
|
||||
#define IVGUIMODULE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "interface.h"
|
||||
#include <vgui/VGUI.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Standard interface to loading vgui modules
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IVGuiModule : public IBaseInterface
|
||||
{
|
||||
public:
|
||||
// called first to setup the module with the vgui
|
||||
// returns true on success, false on failure
|
||||
virtual bool Initialize(CreateInterfaceFn *vguiFactories, int factoryCount) = 0;
|
||||
|
||||
// called after all the modules have been initialized
|
||||
// modules should use this time to link to all the other module interfaces
|
||||
virtual bool PostInitialize(CreateInterfaceFn *modules, int factoryCount) = 0;
|
||||
|
||||
// called when the module is selected from the menu or otherwise activated
|
||||
virtual bool Activate() = 0;
|
||||
|
||||
// returns true if the module is successfully initialized and available
|
||||
virtual bool IsValid() = 0;
|
||||
|
||||
// requests that the UI is temporarily disabled and all data files saved
|
||||
virtual void Deactivate() = 0;
|
||||
|
||||
// restart from a Deactivate()
|
||||
virtual void Reactivate() = 0;
|
||||
|
||||
// called when the module is about to be shutdown
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
// returns a handle to the main module panel
|
||||
virtual vgui::VPANEL GetPanel() = 0;
|
||||
|
||||
// sets the parent of the main module panel
|
||||
virtual void SetParent(vgui::VPANEL parent) = 0;
|
||||
|
||||
// messages sent through through the panel returned by GetPanel():
|
||||
//
|
||||
// "ConnectedToGame" "ip" "port" "gamedir"
|
||||
// "DisconnectedFromGame"
|
||||
// "ActiveGameName" "name"
|
||||
// "LoadingStarted" "type" "name"
|
||||
// "LoadingFinished" "type" "name"
|
||||
};
|
||||
|
||||
#define VGUIMODULE_INTERFACE_VERSION "VGuiModule002"
|
||||
|
||||
|
||||
#endif // IVGUIMODULE_H
|
33
common/IVGuiModuleLoader.h
Normal file
33
common/IVGuiModuleLoader.h
Normal file
@ -0,0 +1,33 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IVGUIMODULELOADER_H
|
||||
#define IVGUIMODULELOADER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: interface to accessing all loaded modules
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IVGuiModuleLoader : public IBaseInterface
|
||||
{
|
||||
public:
|
||||
virtual int GetModuleCount() = 0;
|
||||
virtual const char *GetModuleLabel(int moduleIndex) = 0;
|
||||
virtual CreateInterfaceFn GetModuleFactory(int moduleIndex) = 0;
|
||||
virtual bool ActivateModule(int moduleIndex) = 0;
|
||||
virtual bool ActivateModule(const char *moduleName) = 0;
|
||||
virtual void SetPlatformToRestart() = 0;
|
||||
};
|
||||
|
||||
#define VGUIMODULELOADER_INTERFACE_VERSION "VGuiModuleLoader003"
|
||||
|
||||
|
||||
#endif // IVGUIMODULELOADER_H
|
45
common/ServerBrowser/IServerBrowser.h
Normal file
45
common/ServerBrowser/IServerBrowser.h
Normal file
@ -0,0 +1,45 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef ISERVERBROWSER_H
|
||||
#define ISERVERBROWSER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to server browser module
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IServerBrowser
|
||||
{
|
||||
public:
|
||||
// activates the server browser window, brings it to the foreground
|
||||
virtual bool Activate() = 0;
|
||||
|
||||
// joins a game directly
|
||||
virtual bool JoinGame( uint32 unGameIP, uint16 usGamePort ) = 0;
|
||||
|
||||
// joins a specified game - game info dialog will only be opened if the server is fully or passworded
|
||||
virtual bool JoinGame( uint64 ulSteamIDFriend ) = 0;
|
||||
|
||||
// opens a game info dialog to watch the specified server; associated with the friend 'userName'
|
||||
virtual bool OpenGameInfoDialog( uint64 ulSteamIDFriend ) = 0;
|
||||
|
||||
// forces the game info dialog closed
|
||||
virtual void CloseGameInfoDialog( uint64 ulSteamIDFriend ) = 0;
|
||||
|
||||
// closes all the game info dialogs
|
||||
virtual void CloseAllGameInfoDialogs() = 0;
|
||||
};
|
||||
|
||||
#define SERVERBROWSER_INTERFACE_VERSION "ServerBrowser003"
|
||||
|
||||
|
||||
|
||||
#endif // ISERVERBROWSER_H
|
48
common/blackbox_helper.cpp
Normal file
48
common/blackbox_helper.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "../../engine/iblackbox.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern IBlackBox *blackboxrecorder;
|
||||
|
||||
void BlackBox_Record( const char *type, const char *pFormat, ... )
|
||||
{
|
||||
static ConVarRef blackbox( "blackbox" );
|
||||
|
||||
if ( IsX360() )
|
||||
return;
|
||||
|
||||
if ( !blackbox.IsValid() || !blackbox.GetBool() )
|
||||
return;
|
||||
|
||||
int type_num;
|
||||
for ( type_num = 0; type_num < blackboxrecorder->GetTypeCount(); type_num++ )
|
||||
{
|
||||
if ( !V_strcasecmp( blackboxrecorder->GetTypeName( type_num ), type ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( type_num >= blackboxrecorder->GetTypeCount() )
|
||||
{
|
||||
Msg( "Invalid blackbox type: %s\n", type );
|
||||
return;
|
||||
}
|
||||
|
||||
char szMessage[1024];
|
||||
va_list marker;
|
||||
|
||||
va_start( marker, pFormat);
|
||||
Q_vsnprintf( szMessage, sizeof( szMessage ), pFormat, marker);
|
||||
va_end( marker );
|
||||
|
||||
//Msg( "Record: %s: %s\n", type, szMessage );
|
||||
blackboxrecorder->Record( type_num, szMessage );
|
||||
}
|
||||
|
11
common/blackbox_helper.h
Normal file
11
common/blackbox_helper.h
Normal file
@ -0,0 +1,11 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#ifndef BLACKBOX_HELPER_H
|
||||
#define BLACKBOX_HELPER_H 1
|
||||
|
||||
void BlackBox_Record(const char * type, const char *fmt, ...);
|
||||
|
||||
#endif
|
103
common/compiledcaptionswap.cpp
Normal file
103
common/compiledcaptionswap.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Swap a compiled caption file.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "utlbuffer.h"
|
||||
#include "byteswap.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier2/fileutils.h"
|
||||
#include "captioncompiler.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
BEGIN_BYTESWAP_DATADESC( CompiledCaptionHeader_t )
|
||||
DEFINE_FIELD( magic, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( version, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( numblocks, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( blocksize, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( directorysize, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( dataoffset, FIELD_INTEGER ),
|
||||
END_BYTESWAP_DATADESC()
|
||||
|
||||
BEGIN_BYTESWAP_DATADESC( CaptionLookup_t )
|
||||
DEFINE_FIELD( hash, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( blockNum, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( offset, FIELD_SHORT ),
|
||||
DEFINE_FIELD( length, FIELD_SHORT ),
|
||||
END_BYTESWAP_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Swap a compiled closecaption file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SwapClosecaptionFile( void *pData )
|
||||
{
|
||||
CByteswap swap;
|
||||
swap.ActivateByteSwapping( true );
|
||||
|
||||
CompiledCaptionHeader_t *pHdr = (CompiledCaptionHeader_t*)pData;
|
||||
|
||||
if ( IsX360() )
|
||||
{
|
||||
// pre-swap file header
|
||||
swap.SwapFieldsToTargetEndian( pHdr );
|
||||
}
|
||||
|
||||
if ( pHdr->magic != COMPILED_CAPTION_FILEID || pHdr->version != COMPILED_CAPTION_VERSION )
|
||||
{
|
||||
// bad data
|
||||
return false;
|
||||
}
|
||||
|
||||
// lookup headers
|
||||
pData = (byte*)pData + sizeof(CompiledCaptionHeader_t);
|
||||
swap.SwapFieldsToTargetEndian( (CaptionLookup_t*)pData, pHdr->directorysize );
|
||||
|
||||
// unicode data
|
||||
pData = (byte*)pHdr + pHdr->dataoffset;
|
||||
swap.SwapBufferToTargetEndian( (wchar_t*)pData, (wchar_t*)pData, pHdr->numblocks * pHdr->blocksize / sizeof(wchar_t) );
|
||||
|
||||
if ( IsPC() )
|
||||
{
|
||||
// post-swap file header
|
||||
swap.SwapFieldsToTargetEndian( pHdr );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined( CLIENT_DLL ) || defined( GAME_DLL )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback for UpdateOrCreate - generates .360 file
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool CaptionCreateCallback( const char *pSourceName, const char *pTargetName, const char *pPathID, void *pExtraData )
|
||||
{
|
||||
// Generate the file
|
||||
CUtlBuffer buf;
|
||||
bool bOk = g_pFullFileSystem->ReadFile( pSourceName, pPathID, buf );
|
||||
if ( bOk )
|
||||
{
|
||||
bOk = SwapClosecaptionFile( buf.Base() );
|
||||
if ( bOk )
|
||||
{
|
||||
bOk = g_pFullFileSystem->WriteFile( pTargetName, pPathID, buf );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Failed to create %s\n", pTargetName );
|
||||
}
|
||||
}
|
||||
return bOk;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calls utility function UpdateOrCreate
|
||||
//-----------------------------------------------------------------------------
|
||||
int UpdateOrCreateCaptionFile( const char *pSourceName, char *pTargetName, int maxLen, bool bForce )
|
||||
{
|
||||
return ::UpdateOrCreate( pSourceName, pTargetName, maxLen, "GAME", CaptionCreateCallback, bForce );
|
||||
}
|
||||
#endif
|
16
common/debug_dll_check.cpp
Normal file
16
common/debug_dll_check.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
//======= Copyright © 1996-2008, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Add a specially formatted string to each debug DLL of the form
|
||||
// "%DLLNAME%.dll is built debug!". We can search for this string via
|
||||
// a Perforce trigger to ensure that debug LIBs are not checked in.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#include "tier0/platform.h"
|
||||
|
||||
#define _DEBUGONLYSTRING(x) #x
|
||||
#define DEBUGONLYSTRING(x) _DEBUGONLYSTRING(x)
|
||||
DLL_GLOBAL_EXPORT char const *pDebugString = DEBUGONLYSTRING(DLLNAME) ".dll is built debug!";
|
||||
|
||||
#endif
|
51
common/ifilesystemopendialog.h
Normal file
51
common/ifilesystemopendialog.h
Normal file
@ -0,0 +1,51 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IFILESYSTEMOPENDIALOG_H
|
||||
#define IFILESYSTEMOPENDIALOG_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define FILESYSTEMOPENDIALOG_VERSION "FileSystemOpenDlg003"
|
||||
|
||||
|
||||
class IFileSystem;
|
||||
|
||||
|
||||
abstract_class IFileSystemOpenDialog
|
||||
{
|
||||
public:
|
||||
// You must call this first to set the hwnd.
|
||||
virtual void Init( CreateInterfaceFn factory, void *parentHwnd ) = 0;
|
||||
|
||||
// Call this to free the dialog.
|
||||
virtual void Release() = 0;
|
||||
|
||||
// Use these to configure the dialog.
|
||||
virtual void AddFileMask( const char *pMask ) = 0;
|
||||
virtual void SetInitialDir( const char *pDir, const char *pPathID = NULL ) = 0;
|
||||
virtual void SetFilterMdlAndJpgFiles( bool bFilter ) = 0;
|
||||
virtual void GetFilename( char *pOut, int outLen ) const = 0; // Get the filename they chose.
|
||||
|
||||
// Call this to make the dialog itself. Returns true if they clicked OK and false
|
||||
// if they canceled it.
|
||||
virtual bool DoModal() = 0;
|
||||
|
||||
// This uses the standard windows file open dialog.
|
||||
virtual bool DoModal_WindowsDialog() = 0;
|
||||
|
||||
// Mark the dialog as allowing us to multi-select
|
||||
virtual void AllowMultiSelect( bool bAllow ) = 0;
|
||||
|
||||
// Request the length of the buffer sufficient enough to hold the entire filename result
|
||||
virtual int GetFilenameBufferSize() const = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // IFILESYSTEMOPENDIALOG_H
|
116
common/language.cpp
Normal file
116
common/language.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: languages definition
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "language.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
struct Language_t
|
||||
{
|
||||
char *m_pchName;
|
||||
char *m_pchShortName;
|
||||
char *m_pchVGUILocalizationName;
|
||||
ELanguage m_ELanguage;
|
||||
};
|
||||
|
||||
|
||||
static Language_t s_LanguageNames[] =
|
||||
{
|
||||
{ "None", "none", "None", k_Lang_None },
|
||||
{ "English", "english", "#GameUI_Language_English", k_Lang_English },
|
||||
{ "German", "german", "#GameUI_Language_German", k_Lang_German } ,
|
||||
{ "French", "french", "#GameUI_Language_French", k_Lang_French } ,
|
||||
{ "Italian", "italian", "#GameUI_Language_Italian", k_Lang_Italian } ,
|
||||
{ "Korean", "koreana", "#GameUI_Language_Korean", k_Lang_Korean } ,
|
||||
{ "Spanish", "spanish", "#GameUI_Language_Spanish", k_Lang_Spanish },
|
||||
{ "Simplified_Chinese", "schinese", "#GameUI_Language_Simplified_Chinese", k_Lang_Simplified_Chinese } ,
|
||||
{ "Traditional_Chinese", "tchinese", "#GameUI_Language_Traditional_Chinese", k_Lang_Traditional_Chinese } ,
|
||||
{ "Russian", "russian", "#GameUI_Language_Russian", k_Lang_Russian } ,
|
||||
{ "Thai", "thai", "#GameUI_Language_Thai", k_Lang_Thai } ,
|
||||
{ "Japanese", "japanese", "#GameUI_Language_Japanese", k_Lang_Japanese } ,
|
||||
{ "Portuguese", "portuguese", "#GameUI_Language_Portuguese", k_Lang_Portuguese } ,
|
||||
{ "Polish", "polish", "#GameUI_Language_Polish", k_Lang_Polish } ,
|
||||
{ "Danish", "danish", "#GameUI_Language_Danish", k_Lang_Danish } ,
|
||||
{ "Dutch", "dutch", "#GameUI_Language_Dutch", k_Lang_Dutch } ,
|
||||
{ "Finnish", "finnish", "#GameUI_Language_Finnish", k_Lang_Finnish } ,
|
||||
{ "Norwegian", "norwegian", "#GameUI_Language_Norwegian", k_Lang_Norwegian } ,
|
||||
{ "Swedish", "swedish", "#GameUI_Language_Swedish", k_Lang_Swedish } ,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// STATIC
|
||||
// Purpose: find the language by name
|
||||
//-----------------------------------------------------------------------------
|
||||
ELanguage PchLanguageToELanguage( const char *pchShortName )
|
||||
{
|
||||
Assert( ARRAYSIZE(s_LanguageNames) == k_Lang_MAX + 1 );
|
||||
if ( !pchShortName )
|
||||
return k_Lang_English;
|
||||
|
||||
for ( int iLang = 0; iLang < Q_ARRAYSIZE(s_LanguageNames); ++iLang )
|
||||
{
|
||||
if ( !Q_stricmp( pchShortName, s_LanguageNames[iLang].m_pchShortName ) )
|
||||
{
|
||||
return s_LanguageNames[iLang].m_ELanguage;
|
||||
}
|
||||
}
|
||||
|
||||
// default to English
|
||||
return k_Lang_English;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: return the short string name used for this language by SteamUI
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *GetLanguageShortName( ELanguage eLang )
|
||||
{
|
||||
Assert( Q_ARRAYSIZE(s_LanguageNames) == k_Lang_MAX + 1 );
|
||||
if ( s_LanguageNames[ eLang + 1 ].m_ELanguage == eLang )
|
||||
{
|
||||
return s_LanguageNames[ eLang + 1 ].m_pchShortName;
|
||||
}
|
||||
|
||||
Assert( !"enum ELanguage order mismatched from Language_t s_LanguageNames, fix it!" );
|
||||
return s_LanguageNames[0].m_pchShortName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: return the short string name used for this language by SteamUI
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *GetLanguageName( ELanguage eLang )
|
||||
{
|
||||
Assert( Q_ARRAYSIZE(s_LanguageNames) == k_Lang_MAX + 1 );
|
||||
if ( s_LanguageNames[ eLang + 1 ].m_ELanguage == eLang )
|
||||
{
|
||||
return s_LanguageNames[ eLang + 1 ].m_pchName;
|
||||
}
|
||||
|
||||
Assert( !"enum ELanguage order mismatched from Language_t s_LanguageNames, fix it!" );
|
||||
return s_LanguageNames[0].m_pchShortName;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: return the short string name used for this language by SteamUI
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *GetLanguageVGUILocalization( ELanguage eLang )
|
||||
{
|
||||
Assert( Q_ARRAYSIZE(s_LanguageNames) == k_Lang_MAX + 1 );
|
||||
if ( s_LanguageNames[ eLang + 1 ].m_ELanguage == eLang )
|
||||
{
|
||||
return s_LanguageNames[ eLang + 1 ].m_pchVGUILocalizationName;
|
||||
}
|
||||
|
||||
Assert( !"enum ELanguage order mismatched from Language_t s_LanguageNames, fix it!" );
|
||||
return s_LanguageNames[0].m_pchVGUILocalizationName;
|
||||
}
|
||||
|
43
common/language.h
Normal file
43
common/language.h
Normal file
@ -0,0 +1,43 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: represent a canonical list of the languages we support,
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef LANG_H
|
||||
#define LANG_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// if you change this enum also change language.cpp:s_LanguageNames
|
||||
enum ELanguage
|
||||
{
|
||||
k_Lang_None = -1,
|
||||
k_Lang_English = 0,
|
||||
k_Lang_German,
|
||||
k_Lang_French,
|
||||
k_Lang_Italian,
|
||||
k_Lang_Korean,
|
||||
k_Lang_Spanish,
|
||||
k_Lang_Simplified_Chinese,
|
||||
k_Lang_Traditional_Chinese,
|
||||
k_Lang_Russian,
|
||||
k_Lang_Thai,
|
||||
k_Lang_Japanese,
|
||||
k_Lang_Portuguese,
|
||||
k_Lang_Polish,
|
||||
k_Lang_Danish,
|
||||
k_Lang_Dutch,
|
||||
k_Lang_Finnish,
|
||||
k_Lang_Norwegian,
|
||||
k_Lang_Swedish,
|
||||
k_Lang_MAX
|
||||
};
|
||||
|
||||
ELanguage PchLanguageToELanguage(const char *pchShortName);
|
||||
const char *GetLanguageShortName( ELanguage eLang );
|
||||
const char *GetLanguageVGUILocalization( ELanguage eLang );
|
||||
const char *GetLanguageName( ELanguage eLang );
|
||||
|
||||
#endif /* LANG_H */
|
92
common/matchmaking/mm_helpers.h
Normal file
92
common/matchmaking/mm_helpers.h
Normal file
@ -0,0 +1,92 @@
|
||||
//===== Copyright © 1996-2009, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: common routines to operate on matchmaking sessions and members
|
||||
// Assumptions: caller should include all required headers before including mm_helpers.h
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef __COMMON__MM_HELPERS_H_
|
||||
#define __COMMON__MM_HELPERS_H_
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "tier1/fmtstr.h"
|
||||
|
||||
|
||||
//
|
||||
// Contains inline functions to deal with common tasks involving matchmaking and sessions
|
||||
//
|
||||
|
||||
inline KeyValues * SessionMembersFindPlayer( KeyValues *pSessionSettings, XUID xuidPlayer, KeyValues **ppMachine = NULL )
|
||||
{
|
||||
if ( ppMachine )
|
||||
*ppMachine = NULL;
|
||||
|
||||
if ( !pSessionSettings )
|
||||
return NULL;
|
||||
|
||||
KeyValues *pMembers = pSessionSettings->FindKey( "Members" );
|
||||
if ( !pMembers )
|
||||
return NULL;
|
||||
|
||||
int numMachines = pMembers->GetInt( "numMachines" );
|
||||
for ( int k = 0; k < numMachines; ++ k )
|
||||
{
|
||||
KeyValues *pMachine = pMembers->FindKey( CFmtStr( "machine%d", k ) );
|
||||
if ( !pMachine )
|
||||
continue;
|
||||
|
||||
int numPlayers = pMachine->GetInt( "numPlayers" );
|
||||
for ( int j = 0; j < numPlayers; ++ j )
|
||||
{
|
||||
KeyValues *pPlayer = pMachine->FindKey( CFmtStr( "player%d", j ) );
|
||||
if ( !pPlayer )
|
||||
continue;
|
||||
|
||||
if ( pPlayer->GetUint64( "xuid" ) == xuidPlayer )
|
||||
{
|
||||
if ( ppMachine )
|
||||
*ppMachine = pMachine;
|
||||
|
||||
return pPlayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline XUID SessionMembersFindNonGuestXuid( XUID xuid )
|
||||
{
|
||||
#ifdef _X360
|
||||
if ( !g_pMatchFramework )
|
||||
return xuid;
|
||||
|
||||
if ( !g_pMatchFramework->GetMatchSession() )
|
||||
return xuid;
|
||||
|
||||
KeyValues *pMachine = NULL;
|
||||
KeyValues *pPlayer = SessionMembersFindPlayer( g_pMatchFramework->GetMatchSession()->GetSessionSettings(), xuid, &pMachine );
|
||||
if ( !pPlayer || !pMachine )
|
||||
return xuid;
|
||||
|
||||
if ( !strchr( pPlayer->GetString( "name" ), '(' ) )
|
||||
return xuid;
|
||||
|
||||
int numPlayers = pMachine->GetInt( "numPlayers" );
|
||||
for ( int k = 0; k < numPlayers; ++ k )
|
||||
{
|
||||
XUID xuidOtherPlayer = pMachine->GetUint64( CFmtStr( "player%d/xuid", k ) );
|
||||
if ( xuidOtherPlayer && !strchr( pMachine->GetString( CFmtStr( "player%d/xuid", k ) ), '(' ) )
|
||||
return xuidOtherPlayer; // found a replacement that is not guest
|
||||
}
|
||||
#endif
|
||||
|
||||
return xuid;
|
||||
}
|
||||
|
||||
|
||||
#endif // __COMMON__MM_HELPERS_H_
|
||||
|
176
common/protocol.h
Normal file
176
common/protocol.h
Normal file
@ -0,0 +1,176 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
// protocol.h -- communications protocols
|
||||
#ifndef PROTOCOL_H
|
||||
#define PROTOCOL_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Used to classify entity update types in DeltaPacketEntities.
|
||||
enum UpdateType
|
||||
{
|
||||
EnterPVS = 0, // Entity came back into pvs, create new entity if one doesn't exist
|
||||
|
||||
LeavePVS, // Entity left pvs
|
||||
|
||||
DeltaEnt, // There is a delta for this entity.
|
||||
PreserveEnt, // Entity stays alive but no delta ( could be LOD, or just unchanged )
|
||||
|
||||
Finished, // finished parsing entities successfully
|
||||
Failed, // parsing error occured while reading entities
|
||||
};
|
||||
|
||||
// Flags for delta encoding header
|
||||
enum
|
||||
{
|
||||
FHDR_ZERO = 0x0000,
|
||||
FHDR_LEAVEPVS = 0x0001,
|
||||
FHDR_DELETE = 0x0002,
|
||||
FHDR_ENTERPVS = 0x0004,
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define INSTANCE_BASELINE_TABLENAME "instancebaseline"
|
||||
#define LIGHT_STYLES_TABLENAME "lightstyles"
|
||||
#define USER_INFO_TABLENAME "userinfo"
|
||||
#define SERVER_STARTUP_DATA_TABLENAME "server_query_info" // the name is a remnant...
|
||||
|
||||
|
||||
//#define CURRENT_PROTOCOL 1
|
||||
|
||||
|
||||
#define DELTA_OFFSET_BITS 5
|
||||
#define DELTA_OFFSET_MAX ( ( 1 << DELTA_OFFSET_BITS ) - 1 )
|
||||
|
||||
#define DELTASIZE_BITS 20 // must be: 2^DELTASIZE_BITS > (NET_MAX_PAYLOAD * 8)
|
||||
|
||||
// Largest # of commands to send in a packet
|
||||
#define NUM_NEW_COMMAND_BITS 4
|
||||
#define MAX_NEW_COMMANDS ((1 << NUM_NEW_COMMAND_BITS)-1)
|
||||
|
||||
// Max number of history commands to send ( 2 by default ) in case of dropped packets
|
||||
#define NUM_BACKUP_COMMAND_BITS 3
|
||||
#define MAX_BACKUP_COMMANDS ((1 << NUM_BACKUP_COMMAND_BITS)-1)
|
||||
|
||||
|
||||
#define PROTOCOL_AUTHCERTIFICATE 0x01 // Connection from client is using a WON authenticated certificate
|
||||
#define PROTOCOL_HASHEDCDKEY 0x02 // Connection from client is using hashed CD key because WON comm. channel was unreachable
|
||||
#define PROTOCOL_STEAM 0x03 // Steam certificates
|
||||
#define PROTOCOL_LASTVALID 0x03 // Last valid protocol
|
||||
|
||||
#define CONNECTIONLESS_HEADER 0xFFFFFFFF // all OOB packet start with this sequence
|
||||
#define STEAM_KEYSIZE 2048 // max size needed to contain a steam authentication key (both server and client)
|
||||
|
||||
// each channel packet has 1 byte of FLAG bits
|
||||
#define PACKET_FLAG_RELIABLE (1<<0) // packet contains subchannel stream data
|
||||
#define PACKET_FLAG_COMPRESSED (1<<1) // packet is compressed
|
||||
#define PACKET_FLAG_ENCRYPTED (1<<2) // packet is encrypted
|
||||
#define PACKET_FLAG_SPLIT (1<<3) // packet is split
|
||||
#define PACKET_FLAG_CHOKED (1<<4) // packet was choked by sender
|
||||
|
||||
// NOTE: Bits 5, 6, and 7 are used to specify the # of padding bits at the end of the packet!!!
|
||||
#define ENCODE_PAD_BITS( x ) ( ( x << 5 ) & 0xff )
|
||||
#define DECODE_PAD_BITS( x ) ( ( x >> 5 ) & 0xff )
|
||||
|
||||
// shared commands used by all streams, handled by stream layer, TODO
|
||||
|
||||
#define net_NOP 0 // nop command used for padding
|
||||
#define net_Disconnect 1 // disconnect, last message in connection
|
||||
#define net_File 2 // file transmission message request/deny
|
||||
|
||||
#define net_LastControlMessage 2
|
||||
|
||||
#define net_SplitScreenUser 3 // Changes split screen user
|
||||
#define net_Tick 4 // send last world tick
|
||||
#define net_StringCmd 5 // a string command
|
||||
#define net_SetConVar 6 // sends one/multiple convar settings
|
||||
#define net_SignonState 7 // signals current signon state
|
||||
|
||||
//
|
||||
// server to client
|
||||
//
|
||||
|
||||
#define svc_ServerInfo 8 // first message from server about game, map etc
|
||||
#define svc_SendTable 9 // sends a sendtable description for a game class
|
||||
#define svc_ClassInfo 10 // Info about classes (first byte is a CLASSINFO_ define).
|
||||
#define svc_SetPause 11 // tells client if server paused or unpaused
|
||||
|
||||
|
||||
#define svc_CreateStringTable 12 // inits shared string tables
|
||||
#define svc_UpdateStringTable 13 // updates a string table
|
||||
|
||||
#define svc_VoiceInit 14 // inits used voice codecs & quality
|
||||
#define svc_VoiceData 15 // Voicestream data from the server
|
||||
|
||||
#define svc_Print 16 // print text to console
|
||||
|
||||
#define svc_Sounds 17 // starts playing sound
|
||||
|
||||
#define svc_SetView 18 // sets entity as point of view
|
||||
#define svc_FixAngle 19 // sets/corrects players viewangle
|
||||
#define svc_CrosshairAngle 20 // adjusts crosshair in auto aim mode to lock on traget
|
||||
|
||||
#define svc_BSPDecal 21 // add a static decal to the world BSP
|
||||
|
||||
#define svc_SplitScreen 22 // split screen style message
|
||||
|
||||
// Message from server side to client side entity
|
||||
#define svc_UserMessage 23 // a game specific message
|
||||
#define svc_EntityMessage 24 // a message for an entity
|
||||
#define svc_GameEvent 25 // global game event fired
|
||||
|
||||
#define svc_PacketEntities 26 // non-delta compressed entities
|
||||
|
||||
#define svc_TempEntities 27 // non-reliable event object
|
||||
|
||||
#define svc_Prefetch 28 // only sound indices for now
|
||||
|
||||
#define svc_Menu 29 // display a menu from a plugin
|
||||
|
||||
#define svc_GameEventList 30 // list of known games events and fields
|
||||
|
||||
#define svc_GetCvarValue 31 // Server wants to know the value of a cvar on the client
|
||||
|
||||
#define svc_CmdKeyValues 32 // Server submits KeyValues command for the client
|
||||
|
||||
#define SVC_LASTMSG 32 // last known server messages
|
||||
|
||||
//
|
||||
// client to server
|
||||
//
|
||||
|
||||
#define clc_ClientInfo 8 // client info (table CRC etc)
|
||||
#define clc_Move 9 // [CUserCmd]
|
||||
#define clc_VoiceData 10 // Voicestream data from a client
|
||||
#define clc_BaselineAck 11 // client acknowledges a new baseline seqnr
|
||||
#define clc_ListenEvents 12 // client acknowledges a new baseline seqnr
|
||||
#define clc_RespondCvarValue 13 // client is responding to a svc_GetCvarValue message.
|
||||
#define clc_FileCRCCheck 14 // client is sending a file's CRC to the server to be verified.
|
||||
#define clc_LoadingProgress 15 // client loading progress
|
||||
#define clc_SplitPlayerConnect 16
|
||||
#define clc_CmdKeyValues 17
|
||||
#define CLC_LASTMSG 17 // last known client message
|
||||
|
||||
#define RES_FATALIFMISSING (1<<0) // Disconnect if we can't get this file.
|
||||
#define RES_PRELOAD (1<<1) // Load on client rather than just reserving name
|
||||
|
||||
#define SIGNONSTATE_NONE 0 // no state yet, about to connect
|
||||
#define SIGNONSTATE_CHALLENGE 1 // client challenging server, all OOB packets
|
||||
#define SIGNONSTATE_CONNECTED 2 // client is connected to server, netchans ready
|
||||
#define SIGNONSTATE_NEW 3 // just got serverinfo and string tables
|
||||
#define SIGNONSTATE_PRESPAWN 4 // received signon buffers
|
||||
#define SIGNONSTATE_SPAWN 5 // ready to receive entity packets
|
||||
#define SIGNONSTATE_FULL 6 // we are fully connected, first non-delta packet received
|
||||
#define SIGNONSTATE_CHANGELEVEL 7 // server is changing level, please wait
|
||||
|
||||
#endif // PROTOCOL_H
|
||||
|
||||
|
35
common/qlimits.h
Normal file
35
common/qlimits.h
Normal file
@ -0,0 +1,35 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef QLIMITS_H
|
||||
#define QLIMITS_H
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// DATA STRUCTURE INFO
|
||||
|
||||
#define MAX_NUM_ARGVS 50
|
||||
|
||||
// SYSTEM INFO
|
||||
#define MAX_QPATH 96 // max length of a game pathname
|
||||
#define MAX_OSPATH 260 // max length of a filesystem pathname
|
||||
|
||||
#define ON_EPSILON 0.1 // point on plane side epsilon
|
||||
|
||||
|
||||
// Resource counts;
|
||||
#define MAX_MODEL_INDEX_BITS 10 // sent as a short
|
||||
#define MAX_MODELS (1<<MAX_MODEL_INDEX_BITS)
|
||||
|
||||
#define MAX_GENERIC_INDEX_BITS 9
|
||||
#define MAX_GENERIC (1<<MAX_GENERIC_INDEX_BITS)
|
||||
#define MAX_DECAL_INDEX_BITS 9
|
||||
#define MAX_BASE_DECALS (1<<MAX_DECAL_INDEX_BITS)
|
||||
|
||||
#endif // QLIMITS_H
|
27
common/randoverride.cpp
Normal file
27
common/randoverride.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB)
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "vstdlib/random.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#ifdef GNUC
|
||||
#define __cdecl
|
||||
#endif
|
||||
|
||||
void __cdecl srand(unsigned int)
|
||||
{
|
||||
}
|
||||
|
||||
int __cdecl rand()
|
||||
{
|
||||
return RandomInt( 0, 0x7fff );
|
||||
}
|
||||
|
||||
#endif // !_STATIC_LINKED || _SHARED_LIB
|
2636
common/studiobyteswap.cpp
Normal file
2636
common/studiobyteswap.cpp
Normal file
File diff suppressed because it is too large
Load Diff
40
common/studiobyteswap.h
Normal file
40
common/studiobyteswap.h
Normal file
@ -0,0 +1,40 @@
|
||||
//========= Copyright © 1996-2006, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: StudioMDL byteswapping functions.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#ifndef STUDIOBYTESWAP_H
|
||||
#define STUDIOBYTESWAP_H
|
||||
|
||||
#if defined(_WIN32)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "byteswap.h"
|
||||
struct studiohdr_t;
|
||||
class IPhysicsCollision;
|
||||
|
||||
namespace StudioByteSwap
|
||||
{
|
||||
typedef bool (*CompressFunc_t)( const void *pInput, int inputSize, void **pOutput, int *pOutputSize );
|
||||
|
||||
//void SetTargetBigEndian( bool bigEndian );
|
||||
void ActivateByteSwapping( bool bActivate );
|
||||
void SourceIsNative( bool bActivate );
|
||||
void SetVerbose( bool bVerbose );
|
||||
void SetCollisionInterface( IPhysicsCollision *pPhysicsCollision );
|
||||
|
||||
int ByteswapStudioFile( const char *pFilename, void *pOutBase, int outBaseSize, const void *pFileBase, int fileSize, studiohdr_t *pHdr, CompressFunc_t pCompressFunc = NULL );
|
||||
int ByteswapPHY( void *pOutBase, int outBaseSize, const void *pFileBase, int fileSize );
|
||||
int ByteswapANI( studiohdr_t* pHdr, void *pOutBase, int outBaseSize, const void *pFileBase, int filesize );
|
||||
int ByteswapVVD( void *pOutBase, int outBaseSize, const void *pFileBase, int fileSize );
|
||||
int ByteswapVTX( void *pOutBase, int outBaseSize, const void *pFileBase, int fileSize );
|
||||
int ByteswapMDL( void *pOutBase, int OutBaseSize, const void *pFileBase, int fileSize );
|
||||
|
||||
#define BYTESWAP_ALIGNMENT_PADDING 4096
|
||||
#define ERROR_MISALIGNED_DATA -1
|
||||
#define ERROR_VERSION -2
|
||||
}
|
||||
|
||||
#endif // STUDIOBYTESWAP_H
|
107
common/vgui_surfacelib/ifontsurface.h
Normal file
107
common/vgui_surfacelib/ifontsurface.h
Normal file
@ -0,0 +1,107 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef IFONTSURFACE_H
|
||||
#define IFONTSURFACE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "mathlib/vector2d.h" // must be before the namespace line
|
||||
|
||||
#ifdef CreateFont
|
||||
#undef CreateFont
|
||||
#endif
|
||||
|
||||
|
||||
// returns true if the surface supports minimize & maximize capabilities
|
||||
// Numbered this way to prevent interface change in surface.
|
||||
enum FontFeature_t
|
||||
{
|
||||
FONT_FEATURE_ANTIALIASED_FONTS = 1,
|
||||
FONT_FEATURE_DROPSHADOW_FONTS = 2,
|
||||
FONT_FEATURE_OUTLINE_FONTS = 6,
|
||||
};
|
||||
|
||||
// adds to the font
|
||||
enum FontFlags_t
|
||||
{
|
||||
FONTFLAG_NONE,
|
||||
FONTFLAG_ITALIC = 0x001,
|
||||
FONTFLAG_UNDERLINE = 0x002,
|
||||
FONTFLAG_STRIKEOUT = 0x004,
|
||||
FONTFLAG_SYMBOL = 0x008,
|
||||
FONTFLAG_ANTIALIAS = 0x010,
|
||||
FONTFLAG_GAUSSIANBLUR = 0x020,
|
||||
FONTFLAG_ROTARY = 0x040,
|
||||
FONTFLAG_DROPSHADOW = 0x080,
|
||||
FONTFLAG_ADDITIVE = 0x100,
|
||||
FONTFLAG_OUTLINE = 0x200,
|
||||
FONTFLAG_CUSTOM = 0x400, // custom generated font - never fall back to asian compatibility mode
|
||||
FONTFLAG_BITMAP = 0x800, // compiled bitmap font - no fallbacks
|
||||
};
|
||||
|
||||
enum FontDrawType_t
|
||||
{
|
||||
// Use the "additive" value from the scheme file
|
||||
FONT_DRAW_DEFAULT = 0,
|
||||
|
||||
// Overrides
|
||||
FONT_DRAW_NONADDITIVE,
|
||||
FONT_DRAW_ADDITIVE,
|
||||
|
||||
FONT_DRAW_TYPE_COUNT = 2,
|
||||
};
|
||||
|
||||
|
||||
struct FontVertex_t
|
||||
{
|
||||
FontVertex_t() {}
|
||||
FontVertex_t( const Vector2D &pos, const Vector2D &coord = Vector2D( 0, 0 ) )
|
||||
{
|
||||
m_Position = pos;
|
||||
m_TexCoord = coord;
|
||||
}
|
||||
void Init( const Vector2D &pos, const Vector2D &coord = Vector2D( 0, 0 ) )
|
||||
{
|
||||
m_Position = pos;
|
||||
m_TexCoord = coord;
|
||||
}
|
||||
|
||||
Vector2D m_Position;
|
||||
Vector2D m_TexCoord;
|
||||
};
|
||||
|
||||
typedef unsigned long FontHandle_t;
|
||||
|
||||
struct FontCharRenderInfo
|
||||
{
|
||||
// Text pos
|
||||
int x, y;
|
||||
// Top left and bottom right
|
||||
// This is now a pointer to an array maintained by the surface, to avoid copying the data on the 360
|
||||
FontVertex_t *verts;
|
||||
int textureId;
|
||||
int abcA;
|
||||
int abcB;
|
||||
int abcC;
|
||||
int fontTall;
|
||||
FontHandle_t currentFont;
|
||||
// In:
|
||||
FontDrawType_t drawType;
|
||||
wchar_t ch;
|
||||
|
||||
// Out
|
||||
bool valid;
|
||||
// In/Out (true by default)
|
||||
bool shouldclip;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // IFONTSURFACE_H
|
409
common/xbox/xboxstubs.h
Normal file
409
common/xbox/xboxstubs.h
Normal file
@ -0,0 +1,409 @@
|
||||
//========= Copyright 1996-2004, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Win32 replacements for XBox.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#if !defined( XBOXSTUBS_H ) && !defined( _X360 )
|
||||
#define XBOXSTUBS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/platform.h"
|
||||
|
||||
// Content creation/open flags
|
||||
#define XCONTENTFLAG_NONE 0x00
|
||||
#define XCONTENTFLAG_CREATENEW 0x00
|
||||
#define XCONTENTFLAG_CREATEALWAYS 0x00
|
||||
#define XCONTENTFLAG_OPENEXISTING 0x00
|
||||
#define XCONTENTFLAG_OPENALWAYS 0x00
|
||||
#define XCONTENTFLAG_TRUNCATEEXISTING 0x00
|
||||
|
||||
// Content attributes
|
||||
#define XCONTENTFLAG_NOPROFILE_TRANSFER 0x00
|
||||
#define XCONTENTFLAG_NODEVICE_TRANSFER 0x00
|
||||
#define XCONTENTFLAG_STRONG_SIGNED 0x00
|
||||
#define XCONTENTFLAG_ALLOWPROFILE_TRANSFER 0x00
|
||||
#define XCONTENTFLAG_MOVEONLY_TRANSFER 0x00
|
||||
|
||||
// XNet flags
|
||||
#define XNET_GET_XNADDR_PENDING 0x00000000 // Address acquisition is not yet complete
|
||||
#define XNET_GET_XNADDR_NONE 0x00000001 // XNet is uninitialized or no debugger found
|
||||
#define XNET_GET_XNADDR_ETHERNET 0x00000002 // Host has ethernet address (no IP address)
|
||||
#define XNET_GET_XNADDR_STATIC 0x00000004 // Host has statically assigned IP address
|
||||
#define XNET_GET_XNADDR_DHCP 0x00000008 // Host has DHCP assigned IP address
|
||||
#define XNET_GET_XNADDR_PPPOE 0x00000010 // Host has PPPoE assigned IP address
|
||||
#define XNET_GET_XNADDR_GATEWAY 0x00000020 // Host has one or more gateways configured
|
||||
#define XNET_GET_XNADDR_DNS 0x00000040 // Host has one or more DNS servers configured
|
||||
#define XNET_GET_XNADDR_ONLINE 0x00000080 // Host is currently connected to online service
|
||||
#define XNET_GET_XNADDR_TROUBLESHOOT 0x00008000 // Network configuration requires troubleshooting
|
||||
|
||||
// Console device ports
|
||||
#define XDEVICE_PORT0 0
|
||||
#define XDEVICE_PORT1 1
|
||||
#define XDEVICE_PORT2 2
|
||||
#define XDEVICE_PORT3 3
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#define XUSER_INDEX_NONE 0x000000FE
|
||||
|
||||
#define XBX_CLR_DEFAULT 0xFF000000
|
||||
#define XBX_CLR_WARNING 0x0000FFFF
|
||||
#define XBX_CLR_ERROR 0x000000FF
|
||||
|
||||
#define XBOX_MINBORDERSAFE 0
|
||||
#define XBOX_MAXBORDERSAFE 0
|
||||
|
||||
typedef enum
|
||||
{
|
||||
XK_NULL,
|
||||
XK_BUTTON_UP,
|
||||
XK_BUTTON_DOWN,
|
||||
XK_BUTTON_LEFT,
|
||||
XK_BUTTON_RIGHT,
|
||||
XK_BUTTON_START,
|
||||
XK_BUTTON_BACK,
|
||||
XK_BUTTON_STICK1,
|
||||
XK_BUTTON_STICK2,
|
||||
XK_BUTTON_A,
|
||||
XK_BUTTON_B,
|
||||
XK_BUTTON_X,
|
||||
XK_BUTTON_Y,
|
||||
XK_BUTTON_LEFT_SHOULDER,
|
||||
XK_BUTTON_RIGHT_SHOULDER,
|
||||
XK_BUTTON_LTRIGGER,
|
||||
XK_BUTTON_RTRIGGER,
|
||||
XK_STICK1_UP,
|
||||
XK_STICK1_DOWN,
|
||||
XK_STICK1_LEFT,
|
||||
XK_STICK1_RIGHT,
|
||||
XK_STICK2_UP,
|
||||
XK_STICK2_DOWN,
|
||||
XK_STICK2_LEFT,
|
||||
XK_STICK2_RIGHT,
|
||||
XK_BUTTON_INACTIVE_START,
|
||||
XK_MAX_KEYS,
|
||||
} xKey_t;
|
||||
|
||||
//typedef enum
|
||||
//{
|
||||
// XVRB_NONE, // off
|
||||
// XVRB_ERROR, // fatal error
|
||||
// XVRB_ALWAYS, // no matter what
|
||||
// XVRB_WARNING, // non-fatal warnings
|
||||
// XVRB_STATUS, // status reports
|
||||
// XVRB_ALL,
|
||||
//} xverbose_e;
|
||||
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#ifndef POSIX
|
||||
typedef void* HANDLE;
|
||||
typedef unsigned __int64 ULONGLONG;
|
||||
#endif
|
||||
|
||||
#ifdef POSIX
|
||||
typedef int32 COLORREF;
|
||||
#endif
|
||||
|
||||
#ifndef INVALID_HANDLE_VALUE
|
||||
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internet address (old style... should be updated)
|
||||
*/
|
||||
#ifdef _POSIX
|
||||
struct ip4_addr {
|
||||
union {
|
||||
struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
|
||||
struct { unsigned short s_w1,s_w2; } S_un_w;
|
||||
unsigned long S_addr;
|
||||
} S_un;
|
||||
};
|
||||
typedef struct ip4_addr IN_ADDR;
|
||||
#else
|
||||
#ifndef s_addr
|
||||
/*
|
||||
* Internet address (old style... should be updated)
|
||||
*/
|
||||
struct in_addr {
|
||||
union {
|
||||
struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
|
||||
struct { unsigned short s_w1,s_w2; } S_un_w;
|
||||
unsigned long S_addr;
|
||||
} S_un;
|
||||
#define s_addr S_un.S_addr
|
||||
/* can be used for most tcp & ip code */
|
||||
#define s_host S_un.S_un_b.s_b2
|
||||
/* host on imp */
|
||||
#define s_net S_un.S_un_b.s_b1
|
||||
/* network */
|
||||
#define s_imp S_un.S_un_w.s_w2
|
||||
/* imp */
|
||||
#define s_impno S_un.S_un_b.s_b4
|
||||
/* imp # */
|
||||
#define s_lh S_un.S_un_b.s_b3
|
||||
/* logical host */
|
||||
};
|
||||
typedef struct in_addr IN_ADDR;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef unsigned int XIN_ADDR;
|
||||
|
||||
typedef struct {
|
||||
IN_ADDR ina; // IP address (zero if not static/DHCP)
|
||||
IN_ADDR inaOnline; // Online IP address (zero if not online)
|
||||
WORD wPortOnline; // Online port
|
||||
BYTE abEnet[6]; // Ethernet MAC address
|
||||
BYTE abOnline[20]; // Online identification
|
||||
} XNADDR;
|
||||
|
||||
typedef uint64 XUID;
|
||||
|
||||
typedef struct {
|
||||
BYTE ab[8]; // xbox to xbox key identifier
|
||||
} XNKID;
|
||||
|
||||
typedef struct {
|
||||
BYTE ab[16]; // xbox to xbox key exchange key
|
||||
} XNKEY;
|
||||
|
||||
typedef struct _XSESSION_INFO
|
||||
{
|
||||
XNKID sessionID; // 8 bytes
|
||||
XNADDR hostAddress; // 36 bytes
|
||||
XNKEY keyExchangeKey; // 16 bytes
|
||||
} XSESSION_INFO, *PXSESSION_INFO;
|
||||
|
||||
typedef struct _XUSER_DATA
|
||||
{
|
||||
BYTE type;
|
||||
|
||||
union
|
||||
{
|
||||
int nData; // XUSER_DATA_TYPE_INT32
|
||||
int64 i64Data; // XUSER_DATA_TYPE_INT64
|
||||
double dblData; // XUSER_DATA_TYPE_DOUBLE
|
||||
struct // XUSER_DATA_TYPE_UNICODE
|
||||
{
|
||||
uint cbData; // Includes null-terminator
|
||||
char * pwszData;
|
||||
} string;
|
||||
float fData; // XUSER_DATA_TYPE_FLOAT
|
||||
struct // XUSER_DATA_TYPE_BINARY
|
||||
{
|
||||
uint cbData;
|
||||
char * pbData;
|
||||
} binary;
|
||||
};
|
||||
} XUSER_DATA, *PXUSER_DATA;
|
||||
|
||||
typedef struct _XUSER_PROPERTY
|
||||
{
|
||||
DWORD dwPropertyId;
|
||||
XUSER_DATA value;
|
||||
} XUSER_PROPERTY, *PXUSER_PROPERTY;
|
||||
|
||||
typedef struct _XUSER_CONTEXT
|
||||
{
|
||||
DWORD dwContextId;
|
||||
DWORD dwValue;
|
||||
} XUSER_CONTEXT, *PXUSER_CONTEXT;
|
||||
|
||||
typedef struct _XSESSION_SEARCHRESULT
|
||||
{
|
||||
XSESSION_INFO info;
|
||||
DWORD dwOpenPublicSlots;
|
||||
DWORD dwOpenPrivateSlots;
|
||||
DWORD dwFilledPublicSlots;
|
||||
DWORD dwFilledPrivateSlots;
|
||||
DWORD cProperties;
|
||||
DWORD cContexts;
|
||||
PXUSER_PROPERTY pProperties;
|
||||
PXUSER_CONTEXT pContexts;
|
||||
} XSESSION_SEARCHRESULT, *PXSESSION_SEARCHRESULT;
|
||||
|
||||
typedef struct _XSESSION_SEARCHRESULT_HEADER
|
||||
{
|
||||
DWORD dwSearchResults;
|
||||
XSESSION_SEARCHRESULT *pResults;
|
||||
} XSESSION_SEARCHRESULT_HEADER, *PXSESSION_SEARCHRESULT_HEADER;
|
||||
|
||||
typedef struct _XSESSION_REGISTRANT
|
||||
{
|
||||
uint64 qwMachineID;
|
||||
DWORD bTrustworthiness;
|
||||
DWORD bNumUsers;
|
||||
XUID *rgUsers;
|
||||
|
||||
} XSESSION_REGISTRANT;
|
||||
|
||||
typedef struct _XSESSION_REGISTRATION_RESULTS
|
||||
{
|
||||
DWORD wNumRegistrants;
|
||||
XSESSION_REGISTRANT *rgRegistrants;
|
||||
} XSESSION_REGISTRATION_RESULTS, *PXSESSION_REGISTRATION_RESULTS;
|
||||
|
||||
typedef struct {
|
||||
BYTE bFlags;
|
||||
BYTE bReserved;
|
||||
WORD cProbesXmit;
|
||||
WORD cProbesRecv;
|
||||
WORD cbData;
|
||||
BYTE * pbData;
|
||||
WORD wRttMinInMsecs;
|
||||
WORD wRttMedInMsecs;
|
||||
DWORD dwUpBitsPerSec;
|
||||
DWORD dwDnBitsPerSec;
|
||||
} XNQOSINFO;
|
||||
|
||||
typedef struct {
|
||||
uint cxnqos;
|
||||
uint cxnqosPending;
|
||||
XNQOSINFO axnqosinfo[1];
|
||||
} XNQOS;
|
||||
|
||||
#define XSESSION_CREATE_HOST 0
|
||||
#define XSESSION_CREATE_USES_ARBITRATION 0
|
||||
#define XNET_QOS_LISTEN_ENABLE 0
|
||||
#define XNET_QOS_LISTEN_DISABLE 0
|
||||
#define XNET_QOS_LISTEN_SET_DATA 0
|
||||
|
||||
#define XUSER_DATA_TYPE_CONTEXT ((BYTE)0)
|
||||
#define XUSER_DATA_TYPE_INT32 ((BYTE)1)
|
||||
#define XUSER_DATA_TYPE_INT64 ((BYTE)2)
|
||||
#define XUSER_DATA_TYPE_DOUBLE ((BYTE)3)
|
||||
#define XUSER_DATA_TYPE_UNICODE ((BYTE)4)
|
||||
#define XUSER_DATA_TYPE_FLOAT ((BYTE)5)
|
||||
#define XUSER_DATA_TYPE_BINARY ((BYTE)6)
|
||||
#define XUSER_DATA_TYPE_DATETIME ((BYTE)7)
|
||||
#define XUSER_DATA_TYPE_NULL ((BYTE)0xFF)
|
||||
|
||||
#define XPROFILE_TITLE_SPECIFIC1 0x3FFF
|
||||
#define XPROFILE_TITLE_SPECIFIC2 0x3FFE
|
||||
#define XPROFILE_TITLE_SPECIFIC3 0x3FFD
|
||||
#define XPROFILE_SETTING_MAX_SIZE 1000
|
||||
|
||||
FORCEINLINE DWORD XBX_GetNumGameUsers() { return 1; }
|
||||
FORCEINLINE void XBX_ProcessEvents() {}
|
||||
FORCEINLINE void XBX_DispatchEventsQueue() {}
|
||||
FORCEINLINE unsigned int XBX_GetSystemTime() { return 0; }
|
||||
FORCEINLINE DWORD XBX_GetPrimaryUserId() { return 0; }
|
||||
FORCEINLINE void XBX_SetPrimaryUserId( DWORD idx ) {}
|
||||
FORCEINLINE void XBX_ResetStorageDeviceInfo() {}
|
||||
FORCEINLINE DWORD XBX_DescribeStorageDevice( DWORD nStorageID ) { return 1; }
|
||||
FORCEINLINE DWORD XBX_GetStorageDeviceId(int) { return 0; }
|
||||
FORCEINLINE void XBX_SetStorageDeviceId( int, DWORD ) {}
|
||||
FORCEINLINE const char *XBX_GetLanguageString() { return ""; }
|
||||
FORCEINLINE bool XBX_IsLocalized() { return false; }
|
||||
FORCEINLINE bool XBX_IsAudioLocalized() { return false; }
|
||||
FORCEINLINE const char *XBX_GetNextSupportedLanguage( const char *pLanguage, bool *pbHasAudio ) { return NULL; }
|
||||
FORCEINLINE bool XBX_IsRestrictiveLanguage() { return false; }
|
||||
|
||||
FORCEINLINE int XBX_GetUserId( int nSlot ) { return nSlot; }
|
||||
FORCEINLINE void XBX_SetUserId( int nSlot, int idx ) {}
|
||||
|
||||
|
||||
#define XCONTENT_MAX_DISPLAYNAME_LENGTH 128
|
||||
#define XCONTENT_MAX_FILENAME_LENGTH 42
|
||||
|
||||
#define XBX_INVALID_STORAGE_ID ((DWORD) -1)
|
||||
#define XBX_STORAGE_DECLINED ((DWORD) -2)
|
||||
|
||||
enum XUSER_SIGNIN_STATE
|
||||
{
|
||||
eXUserSigninState_NotSignedIn,
|
||||
eXUserSigninState_SignedInLocally,
|
||||
eXUserSigninState_SignedInToLive,
|
||||
};
|
||||
|
||||
#if (defined(_POSIX))
|
||||
typedef size_t ULONG_PTR;
|
||||
#else
|
||||
typedef _W64 unsigned long ULONG_PTR;
|
||||
#endif
|
||||
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
|
||||
|
||||
|
||||
typedef void * PXOVERLAPPED_COMPLETION_ROUTINE;
|
||||
|
||||
|
||||
#ifndef _POSIX
|
||||
typedef struct _XOVERLAPPED {
|
||||
ULONG_PTR InternalLow;
|
||||
ULONG_PTR InternalHigh;
|
||||
ULONG_PTR InternalContext;
|
||||
HANDLE hEvent;
|
||||
PXOVERLAPPED_COMPLETION_ROUTINE pCompletionRoutine;
|
||||
DWORD_PTR dwCompletionContext;
|
||||
DWORD dwExtendedError;
|
||||
} XOVERLAPPED, *PXOVERLAPPED;
|
||||
#endif
|
||||
|
||||
#ifndef MAX_RICHPRESENCE_SIZE
|
||||
#define MAX_RICHPRESENCE_SIZE 64
|
||||
#endif
|
||||
|
||||
#ifndef XUSER_NAME_SIZE
|
||||
#define XUSER_NAME_SIZE 16
|
||||
#endif
|
||||
|
||||
#ifndef GPU_RESOLVE_ALIGNMENT
|
||||
#define GPU_RESOLVE_ALIGNMENT 8
|
||||
#endif
|
||||
|
||||
#define XCONTENT_MAX_DISPLAYNAME_LENGTH 128
|
||||
#define XCONTENT_MAX_FILENAME_LENGTH 42
|
||||
#define XCONTENTDEVICE_MAX_NAME_LENGTH 27
|
||||
typedef DWORD XCONTENTDEVICEID, *PXCONTENTDEVICEID;
|
||||
typedef struct _XCONTENT_DATA
|
||||
{
|
||||
XCONTENTDEVICEID DeviceID;
|
||||
DWORD dwContentType;
|
||||
wchar_t szDisplayName[XCONTENT_MAX_DISPLAYNAME_LENGTH];
|
||||
char szFileName[XCONTENT_MAX_FILENAME_LENGTH];
|
||||
} XCONTENT_DATA, *PXCONTENT_DATA;
|
||||
|
||||
#define X_CONTEXT_PRESENCE 0x00010001
|
||||
#define X_CONTEXT_GAME_TYPE 0x0001000A
|
||||
#define X_CONTEXT_GAME_MODE 0x0001000B
|
||||
|
||||
#define X_PROPERTY_RANK 0x00011001
|
||||
#define X_PROPERTY_GAMERNAME 0x00011002
|
||||
#define X_PROPERTY_SESSION_ID 0x00011003
|
||||
|
||||
// System attributes used in matchmaking queries
|
||||
#define X_PROPERTY_GAMER_ZONE 0x00011101
|
||||
#define X_PROPERTY_GAMER_COUNTRY 0x00011102
|
||||
#define X_PROPERTY_GAMER_LANGUAGE 0x00011103
|
||||
#define X_PROPERTY_GAMER_RATING 0x00011104
|
||||
#define X_PROPERTY_GAMER_MU 0x00011105
|
||||
#define X_PROPERTY_GAMER_SIGMA 0x00011106
|
||||
#define X_PROPERTY_GAMER_PUID 0x00011107
|
||||
#define X_PROPERTY_AFFILIATE_SCORE 0x00011108
|
||||
#define X_PROPERTY_GAMER_HOSTNAME 0x00011109
|
||||
|
||||
// Properties used to write to skill leaderboards
|
||||
#define X_PROPERTY_RELATIVE_SCORE 0x0001100A
|
||||
#define X_PROPERTY_SESSION_TEAM 0x0001100B
|
||||
|
||||
// Properties written at the session level to override TrueSkill parameters
|
||||
#define X_PROPERTY_PLAYER_PARTIAL_PLAY_PERCENTAGE 0x0001100C
|
||||
#define X_PROPERTY_PLAYER_SKILL_UPDATE_WEIGHTING_FACTOR 0x0001100D
|
||||
#define X_PROPERTY_SESSION_SKILL_BETA 0x0001100E
|
||||
#define X_PROPERTY_SESSION_SKILL_TAU 0x0001100F
|
||||
#define X_PROPERTY_SESSION_SKILL_DRAW_PROBABILITY 0x00011010
|
||||
|
||||
// Attachment size is written to a leaderboard when the entry qualifies for
|
||||
// a gamerclip. The rating can be retrieved via XUserEstimateRankForRating.
|
||||
#define X_PROPERTY_ATTACHMENT_SIZE 0x00011011
|
||||
|
||||
// Values for X_CONTEXT_GAME_TYPE
|
||||
#define X_CONTEXT_GAME_TYPE_RANKED 0
|
||||
#define X_CONTEXT_GAME_TYPE_STANDARD 1
|
||||
|
||||
#endif // XBOXSTUBS_H
|
19
engine/iblackbox.h
Normal file
19
engine/iblackbox.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef IBLACKBOX_H
|
||||
#define IBLACKBOX_H
|
||||
|
||||
#define BLACKBOX_INTERFACE_VERSION "BlackBoxVersion001"
|
||||
|
||||
class IBlackBox
|
||||
{
|
||||
public:
|
||||
virtual void Record(int type, const char *fmt) = 0;
|
||||
virtual void SetLimit(int type, unsigned int count) = 0;
|
||||
virtual const char *Get(int type, unsigned int index) = 0;
|
||||
virtual int Count(int type) = 0;
|
||||
virtual void Flush(int type) = 0;
|
||||
|
||||
virtual const char *GetTypeName(int type) = 0;
|
||||
virtual int GetTypeCount() = 0;
|
||||
};
|
||||
|
||||
#endif
|
54
game/client/AnimateSpecificTextureProxy.cpp
Normal file
54
game/client/AnimateSpecificTextureProxy.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Acts exactly like "AnimatedTexture", but ONLY if the texture
|
||||
// it's working on matches the desired texture to work on.
|
||||
//
|
||||
// This assumes that some other proxy will be switching out the textures.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/IMaterialProxy.h"
|
||||
#include "materialsystem/IMaterialVar.h"
|
||||
#include "materialsystem/IMaterial.h"
|
||||
#include "materialsystem/ITexture.h"
|
||||
#include "BaseAnimatedTextureProxy.h"
|
||||
#include "utlstring.h"
|
||||
#include <KeyValues.h>
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CAnimateSpecificTexture : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
private:
|
||||
CUtlString m_OnlyAnimateOnTexture;
|
||||
public:
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity ) { return 0; }
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
};
|
||||
|
||||
bool CAnimateSpecificTexture::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
char const* pszAnimateOnTexture = pKeyValues->GetString( "onlyAnimateOnTexture" );
|
||||
if( !pszAnimateOnTexture )
|
||||
return false;
|
||||
|
||||
m_OnlyAnimateOnTexture.Set( pszAnimateOnTexture );
|
||||
|
||||
return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||
}
|
||||
|
||||
void CAnimateSpecificTexture::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if( FStrEq( m_AnimatedTextureVar->GetTextureValue()->GetName(), m_OnlyAnimateOnTexture ) )
|
||||
{
|
||||
CBaseAnimatedTextureProxy::OnBind( pC_BaseEntity );
|
||||
}
|
||||
//else do nothing
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CAnimateSpecificTexture, AnimateSpecificTexture );
|
785
game/client/C_MaterialModifyControl.cpp
Normal file
785
game/client/C_MaterialModifyControl.cpp
Normal file
@ -0,0 +1,785 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Material Modify control entity.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "ProxyEntity.h"
|
||||
#include "materialsystem/IMaterial.h"
|
||||
#include "materialsystem/IMaterialVar.h"
|
||||
#include "materialsystem/ITexture.h"
|
||||
#include "iviewrender.h"
|
||||
#include "texture_group_names.h"
|
||||
#include "BaseAnimatedTextureProxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define MATERIAL_MODIFY_STRING_SIZE 255
|
||||
#define MATERIAL_MODIFY_ANIMATION_UNSET -1
|
||||
|
||||
// Must match MaterialModifyControl.cpp
|
||||
enum MaterialModifyMode_t
|
||||
{
|
||||
MATERIAL_MODIFY_MODE_NONE = 0,
|
||||
MATERIAL_MODIFY_MODE_SETVAR = 1,
|
||||
MATERIAL_MODIFY_MODE_ANIM_SEQUENCE = 2,
|
||||
MATERIAL_MODIFY_MODE_FLOAT_LERP = 3,
|
||||
};
|
||||
|
||||
ConVar debug_materialmodifycontrol_client( "debug_materialmodifycontrol_client", "0" );
|
||||
|
||||
struct materialanimcommands_t
|
||||
{
|
||||
int iFrameStart;
|
||||
int iFrameEnd;
|
||||
bool bWrap;
|
||||
float flFrameRate;
|
||||
};
|
||||
|
||||
struct materialfloatlerpcommands_t
|
||||
{
|
||||
int flStartValue;
|
||||
int flEndValue;
|
||||
float flTransitionTime;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FIXME: This really should inherit from something more lightweight
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class C_MaterialModifyControl : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_MaterialModifyControl, C_BaseEntity );
|
||||
|
||||
C_MaterialModifyControl();
|
||||
|
||||
void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
bool ShouldDraw();
|
||||
|
||||
IMaterial *GetMaterial( void ) { return m_pMaterial; }
|
||||
const char *GetMaterialVariableName( void ) { return m_szMaterialVar; }
|
||||
const char *GetMaterialVariableValue( void ) { return m_szMaterialVarValue; }
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
// Animated texture and Float Lerp usage
|
||||
bool HasNewAnimationCommands( void ) { return m_bHasNewAnimationCommands; }
|
||||
void ClearAnimationCommands( void ) { m_bHasNewAnimationCommands = false; }
|
||||
|
||||
// Animated texture usage
|
||||
void GetAnimationCommands( materialanimcommands_t *pCommands );
|
||||
|
||||
// FloatLerp usage
|
||||
void GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands );
|
||||
|
||||
void SetAnimationStartTime( float flTime )
|
||||
{
|
||||
m_flAnimationStartTime = flTime;
|
||||
}
|
||||
float GetAnimationStartTime( void ) const
|
||||
{
|
||||
return m_flAnimationStartTime;
|
||||
}
|
||||
|
||||
MaterialModifyMode_t GetModifyMode( void ) const
|
||||
{
|
||||
return ( MaterialModifyMode_t)m_nModifyMode;
|
||||
}
|
||||
private:
|
||||
|
||||
char m_szMaterialName[MATERIAL_MODIFY_STRING_SIZE];
|
||||
char m_szMaterialVar[MATERIAL_MODIFY_STRING_SIZE];
|
||||
char m_szMaterialVarValue[MATERIAL_MODIFY_STRING_SIZE];
|
||||
IMaterial *m_pMaterial;
|
||||
|
||||
bool m_bHasNewAnimationCommands;
|
||||
|
||||
// Animation commands from the server
|
||||
int m_iFrameStart;
|
||||
int m_iFrameEnd;
|
||||
bool m_bWrap;
|
||||
float m_flFramerate;
|
||||
bool m_bNewAnimCommandsSemaphore;
|
||||
bool m_bOldAnimCommandsSemaphore;
|
||||
|
||||
// Float lerp commands from the server
|
||||
float m_flFloatLerpStartValue;
|
||||
float m_flFloatLerpEndValue;
|
||||
float m_flFloatLerpTransitionTime;
|
||||
bool m_bFloatLerpWrap;
|
||||
float m_flAnimationStartTime;
|
||||
|
||||
int m_nModifyMode;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_MaterialModifyControl, DT_MaterialModifyControl, CMaterialModifyControl)
|
||||
RecvPropString( RECVINFO( m_szMaterialName ) ),
|
||||
RecvPropString( RECVINFO( m_szMaterialVar ) ),
|
||||
RecvPropString( RECVINFO( m_szMaterialVarValue ) ),
|
||||
RecvPropInt( RECVINFO(m_iFrameStart) ),
|
||||
RecvPropInt( RECVINFO(m_iFrameEnd) ),
|
||||
RecvPropInt( RECVINFO(m_bWrap) ),
|
||||
RecvPropFloat( RECVINFO(m_flFramerate) ),
|
||||
RecvPropInt( RECVINFO(m_bNewAnimCommandsSemaphore) ),
|
||||
RecvPropFloat( RECVINFO(m_flFloatLerpStartValue) ),
|
||||
RecvPropFloat( RECVINFO(m_flFloatLerpEndValue) ),
|
||||
RecvPropFloat( RECVINFO(m_flFloatLerpTransitionTime) ),
|
||||
RecvPropInt( RECVINFO(m_bFloatLerpWrap) ),
|
||||
RecvPropInt( RECVINFO(m_nModifyMode) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//------------------------------------------------------------------------------
|
||||
C_MaterialModifyControl::C_MaterialModifyControl()
|
||||
{
|
||||
m_pMaterial = NULL;
|
||||
m_bOldAnimCommandsSemaphore = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MaterialModifyControl::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
m_bOldAnimCommandsSemaphore = m_bNewAnimCommandsSemaphore;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//------------------------------------------------------------------------------
|
||||
void C_MaterialModifyControl::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_pMaterial = materials->FindMaterial( m_szMaterialName, TEXTURE_GROUP_OTHER );
|
||||
|
||||
// Clear out our variables
|
||||
m_bHasNewAnimationCommands = true;
|
||||
}
|
||||
|
||||
// Detect changes in the anim commands
|
||||
if ( m_bNewAnimCommandsSemaphore != m_bOldAnimCommandsSemaphore )
|
||||
{
|
||||
m_bHasNewAnimationCommands = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MaterialModifyControl::GetAnimationCommands( materialanimcommands_t *pCommands )
|
||||
{
|
||||
pCommands->iFrameStart = m_iFrameStart;
|
||||
pCommands->iFrameEnd = m_iFrameEnd;
|
||||
pCommands->bWrap = m_bWrap;
|
||||
pCommands->flFrameRate = m_flFramerate;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MaterialModifyControl::GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands )
|
||||
{
|
||||
pCommands->flStartValue = m_flFloatLerpStartValue;
|
||||
pCommands->flEndValue = m_flFloatLerpEndValue;
|
||||
pCommands->flTransitionTime = m_flFloatLerpTransitionTime;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: We don't draw.
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_MaterialModifyControl::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// THE MATERIALMODIFYPROXY ITSELF
|
||||
//
|
||||
class CMaterialModifyProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CMaterialModifyProxy();
|
||||
virtual ~CMaterialModifyProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pEntity );
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
void OnBindSetVar( C_MaterialModifyControl *pControl );
|
||||
void OnBindAnimatedTexture( C_MaterialModifyControl *pControl );
|
||||
void OnBindFloatLerp( C_MaterialModifyControl *pControl );
|
||||
float GetAnimationStartTime( void* pArg );
|
||||
void AnimationWrapped( void* pArg );
|
||||
|
||||
IMaterial *m_pMaterial;
|
||||
|
||||
// texture animation stuff
|
||||
int m_iFrameStart;
|
||||
int m_iFrameEnd;
|
||||
bool m_bReachedEnd;
|
||||
bool m_bCustomWrap;
|
||||
float m_flCustomFramerate;
|
||||
|
||||
// float lerp stuff
|
||||
IMaterialVar *m_pMaterialVar;
|
||||
int m_flStartValue;
|
||||
int m_flEndValue;
|
||||
float m_flStartTime;
|
||||
float m_flTransitionTime;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMaterialModifyProxy::CMaterialModifyProxy()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMaterialModifyProxy::~CMaterialModifyProxy()
|
||||
{
|
||||
}
|
||||
|
||||
bool CMaterialModifyProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
// set var stuff
|
||||
m_pMaterial = pMaterial;
|
||||
|
||||
// float lerp stuff
|
||||
m_flStartValue = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
m_flEndValue = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
|
||||
// animated stuff
|
||||
// m_pMaterial = pMaterial;
|
||||
// m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
// m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
// m_bReachedEnd = false;
|
||||
// return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMaterialModifyProxy::OnBind( void *pEntity )
|
||||
{
|
||||
// Get the modified material vars from the entity input
|
||||
IClientRenderable *pRend = (IClientRenderable *)pEntity;
|
||||
if ( pRend )
|
||||
{
|
||||
C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
|
||||
if ( pBaseEntity )
|
||||
{
|
||||
if( debug_materialmodifycontrol_client.GetBool() )
|
||||
{
|
||||
// DevMsg( 1, "%s\n", pBaseEntity->GetDebugName() );
|
||||
}
|
||||
int numChildren = 0;
|
||||
bool gotOne = false;
|
||||
for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
|
||||
{
|
||||
numChildren++;
|
||||
C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
|
||||
if ( !pControl )
|
||||
continue;
|
||||
|
||||
if( debug_materialmodifycontrol_client.GetBool() )
|
||||
{
|
||||
// DevMsg( 1, "pControl: 0x%p\n", pControl );
|
||||
}
|
||||
|
||||
switch( pControl->GetModifyMode() )
|
||||
{
|
||||
case MATERIAL_MODIFY_MODE_NONE:
|
||||
break;
|
||||
case MATERIAL_MODIFY_MODE_SETVAR:
|
||||
gotOne = true;
|
||||
OnBindSetVar( pControl );
|
||||
break;
|
||||
case MATERIAL_MODIFY_MODE_ANIM_SEQUENCE:
|
||||
OnBindAnimatedTexture( pControl );
|
||||
break;
|
||||
case MATERIAL_MODIFY_MODE_FLOAT_LERP:
|
||||
OnBindFloatLerp( pControl );
|
||||
break;
|
||||
default:
|
||||
Assert( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( gotOne )
|
||||
{
|
||||
// DevMsg( 1, "numChildren: %d\n", numChildren );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IMaterial *CMaterialModifyProxy::GetMaterial()
|
||||
{
|
||||
return m_pMaterial;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyProxy::OnBindSetVar( C_MaterialModifyControl *pControl )
|
||||
{
|
||||
IMaterial *pMaterial = pControl->GetMaterial();
|
||||
if( !pMaterial )
|
||||
{
|
||||
Assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pMaterial != m_pMaterial )
|
||||
{
|
||||
// Warning( "\t%s!=%s\n", pMaterial->GetName(), m_pMaterial->GetName() );
|
||||
return;
|
||||
}
|
||||
|
||||
bool bFound;
|
||||
IMaterialVar *pMaterialVar = pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
|
||||
if ( !bFound )
|
||||
return;
|
||||
|
||||
if( Q_strcmp( pControl->GetMaterialVariableValue(), "" ) )
|
||||
{
|
||||
// const char *pMaterialName = m_pMaterial->GetName();
|
||||
// const char *pMaterialVarName = pMaterialVar->GetName();
|
||||
// const char *pMaterialVarValue = pControl->GetMaterialVariableValue();
|
||||
// if( debug_materialmodifycontrol_client.GetBool()
|
||||
// && Q_stristr( m_pMaterial->GetName(), "faceandhair" )
|
||||
// && Q_stristr( pMaterialVar->GetName(), "self" )
|
||||
// )
|
||||
// {
|
||||
// static int count = 0;
|
||||
// DevMsg( 1, "CMaterialModifyProxy::OnBindSetVar \"%s\" %s=%s %d pControl=0x%p\n",
|
||||
// m_pMaterial->GetName(), pMaterialVar->GetName(), pControl->GetMaterialVariableValue(), count++, pControl );
|
||||
// }
|
||||
pMaterialVar->SetValueAutodetectType( pControl->GetMaterialVariableValue() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the dirty deed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyProxy::OnBindAnimatedTexture( C_MaterialModifyControl *pControl )
|
||||
{
|
||||
assert ( m_AnimatedTextureVar );
|
||||
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||
return;
|
||||
|
||||
ITexture *pTexture;
|
||||
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||
|
||||
if ( !pControl )
|
||||
return;
|
||||
|
||||
if ( pControl->HasNewAnimationCommands() )
|
||||
{
|
||||
// Read the data from the modify entity
|
||||
materialanimcommands_t sCommands;
|
||||
pControl->GetAnimationCommands( &sCommands );
|
||||
|
||||
m_iFrameStart = sCommands.iFrameStart;
|
||||
m_iFrameEnd = sCommands.iFrameEnd;
|
||||
m_bCustomWrap = sCommands.bWrap;
|
||||
m_flCustomFramerate = sCommands.flFrameRate;
|
||||
m_bReachedEnd = false;
|
||||
|
||||
m_flStartTime = gpGlobals->curtime;
|
||||
|
||||
pControl->ClearAnimationCommands();
|
||||
}
|
||||
|
||||
// Init all the vars based on whether we're using the base material settings,
|
||||
// or the custom ones from the entity input.
|
||||
int numFrames;
|
||||
bool bWrapAnimation;
|
||||
float flFrameRate;
|
||||
int iLastFrame;
|
||||
|
||||
// Do we have a custom frame section from the server?
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
m_iFrameEnd = pTexture->GetNumAnimationFrames();
|
||||
}
|
||||
|
||||
numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
|
||||
bWrapAnimation = m_bCustomWrap;
|
||||
flFrameRate = m_flCustomFramerate;
|
||||
iLastFrame = (m_iFrameEnd - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
numFrames = pTexture->GetNumAnimationFrames();
|
||||
bWrapAnimation = m_WrapAnimation;
|
||||
flFrameRate = m_FrameRate;
|
||||
iLastFrame = (numFrames - 1);
|
||||
}
|
||||
|
||||
// Have we already reached the end? If so, stay there.
|
||||
if ( m_bReachedEnd && !bWrapAnimation )
|
||||
{
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Must not use relative time based methods here
|
||||
// because the bind proxy can be called many times per frame.
|
||||
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||
float startTime;
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
startTime = m_flStartTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
startTime = GetAnimationStartTime(pControl);
|
||||
}
|
||||
float deltaTime = gpGlobals->curtime - startTime;
|
||||
float prevTime = deltaTime - gpGlobals->frametime;
|
||||
|
||||
// Clamp..
|
||||
if (deltaTime < 0.0f)
|
||||
deltaTime = 0.0f;
|
||||
if (prevTime < 0.0f)
|
||||
prevTime = 0.0f;
|
||||
|
||||
float frame = flFrameRate * deltaTime;
|
||||
float prevFrame = flFrameRate * prevTime;
|
||||
|
||||
int intFrame = ((int)frame) % numFrames;
|
||||
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
intFrame += m_iFrameStart;
|
||||
intPrevFrame += m_iFrameStart;
|
||||
}
|
||||
|
||||
// Report wrap situation...
|
||||
if (intPrevFrame > intFrame)
|
||||
{
|
||||
m_bReachedEnd = true;
|
||||
|
||||
if (bWrapAnimation)
|
||||
{
|
||||
AnimationWrapped( pControl );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only sent the wrapped message once.
|
||||
// when we're in non-wrapping mode
|
||||
if (prevFrame < numFrames)
|
||||
AnimationWrapped( pControl );
|
||||
intFrame = numFrames - 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
float CMaterialModifyProxy::GetAnimationStartTime( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return 0.0f;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
return pEntity->GetTextureAnimationStartTime();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyProxy::AnimationWrapped( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
pEntity->TextureAnimationWrapped();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the dirty deed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyProxy::OnBindFloatLerp( C_MaterialModifyControl *pControl )
|
||||
{
|
||||
if ( !pControl )
|
||||
return;
|
||||
|
||||
if ( pControl->HasNewAnimationCommands() )
|
||||
{
|
||||
pControl->SetAnimationStartTime( gpGlobals->curtime );
|
||||
pControl->ClearAnimationCommands();
|
||||
}
|
||||
|
||||
// Read the data from the modify entity
|
||||
materialfloatlerpcommands_t sCommands;
|
||||
pControl->GetFloatLerpCommands( &sCommands );
|
||||
|
||||
m_flStartValue = sCommands.flStartValue;
|
||||
m_flEndValue = sCommands.flEndValue;
|
||||
m_flTransitionTime = sCommands.flTransitionTime;
|
||||
m_flStartTime = pControl->GetAnimationStartTime();
|
||||
bool bFound;
|
||||
m_pMaterialVar = m_pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
|
||||
|
||||
if( bFound )
|
||||
{
|
||||
float currentValue;
|
||||
if( m_flTransitionTime > 0.0f )
|
||||
{
|
||||
currentValue = m_flStartValue + ( m_flEndValue - m_flStartValue ) * clamp( ( ( gpGlobals->curtime - m_flStartTime ) / m_flTransitionTime ), 0.0f, 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentValue = m_flEndValue;
|
||||
}
|
||||
|
||||
if( debug_materialmodifycontrol_client.GetBool() && Q_stristr( m_pMaterial->GetName(), "faceandhair" ) && Q_stristr( m_pMaterialVar->GetName(), "warp" ) )
|
||||
{
|
||||
static int count = 0;
|
||||
DevMsg( 1, "CMaterialFloatLerpProxy::OnBind \"%s\" %s=%f %d\n", m_pMaterial->GetName(), m_pMaterialVar->GetName(), currentValue, count++ );
|
||||
}
|
||||
m_pMaterialVar->SetFloatValue( currentValue );
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// MATERIALMODIFYANIMATED PROXY
|
||||
//
|
||||
class CMaterialModifyAnimatedProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CMaterialModifyAnimatedProxy() {};
|
||||
virtual ~CMaterialModifyAnimatedProxy() {};
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pEntity );
|
||||
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||
virtual void AnimationWrapped( void* pC_BaseEntity );
|
||||
|
||||
private:
|
||||
IMaterial *m_pMaterial;
|
||||
int m_iFrameStart;
|
||||
int m_iFrameEnd;
|
||||
bool m_bReachedEnd;
|
||||
float m_flStartTime;
|
||||
bool m_bCustomWrap;
|
||||
float m_flCustomFramerate;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMaterialModifyAnimatedProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
m_pMaterial = pMaterial;
|
||||
m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
m_bReachedEnd = false;
|
||||
return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the dirty deed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyAnimatedProxy::OnBind( void *pEntity )
|
||||
{
|
||||
assert ( m_AnimatedTextureVar );
|
||||
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||
return;
|
||||
|
||||
ITexture *pTexture;
|
||||
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||
|
||||
// Get the modified material vars from the entity input
|
||||
IClientRenderable *pRend = (IClientRenderable *)pEntity;
|
||||
if ( pRend )
|
||||
{
|
||||
C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if ( pBaseEntity )
|
||||
{
|
||||
for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
|
||||
{
|
||||
C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
|
||||
if ( !pControl )
|
||||
continue;
|
||||
|
||||
if ( !pControl->HasNewAnimationCommands() )
|
||||
continue;
|
||||
|
||||
// Read the data from the modify entity
|
||||
materialanimcommands_t sCommands;
|
||||
pControl->GetAnimationCommands( &sCommands );
|
||||
|
||||
m_iFrameStart = sCommands.iFrameStart;
|
||||
m_iFrameEnd = sCommands.iFrameEnd;
|
||||
m_bCustomWrap = sCommands.bWrap;
|
||||
m_flCustomFramerate = sCommands.flFrameRate;
|
||||
m_bReachedEnd = false;
|
||||
|
||||
m_flStartTime = gpGlobals->curtime;
|
||||
|
||||
pControl->ClearAnimationCommands();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Init all the vars based on whether we're using the base material settings,
|
||||
// or the custom ones from the entity input.
|
||||
int numFrames;
|
||||
bool bWrapAnimation;
|
||||
float flFrameRate;
|
||||
int iLastFrame;
|
||||
|
||||
// Do we have a custom frame section from the server?
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
m_iFrameEnd = pTexture->GetNumAnimationFrames();
|
||||
}
|
||||
|
||||
numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
|
||||
bWrapAnimation = m_bCustomWrap;
|
||||
flFrameRate = m_flCustomFramerate;
|
||||
iLastFrame = (m_iFrameEnd - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
numFrames = pTexture->GetNumAnimationFrames();
|
||||
bWrapAnimation = m_WrapAnimation;
|
||||
flFrameRate = m_FrameRate;
|
||||
iLastFrame = (numFrames - 1);
|
||||
}
|
||||
|
||||
// Have we already reached the end? If so, stay there.
|
||||
if ( m_bReachedEnd && !bWrapAnimation )
|
||||
{
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Must not use relative time based methods here
|
||||
// because the bind proxy can be called many times per frame.
|
||||
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||
float startTime;
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
startTime = m_flStartTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
startTime = GetAnimationStartTime(pEntity);
|
||||
}
|
||||
float deltaTime = gpGlobals->curtime - startTime;
|
||||
float prevTime = deltaTime - gpGlobals->frametime;
|
||||
|
||||
// Clamp..
|
||||
if (deltaTime < 0.0f)
|
||||
deltaTime = 0.0f;
|
||||
if (prevTime < 0.0f)
|
||||
prevTime = 0.0f;
|
||||
|
||||
float frame = flFrameRate * deltaTime;
|
||||
float prevFrame = flFrameRate * prevTime;
|
||||
|
||||
int intFrame = ((int)frame) % numFrames;
|
||||
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
intFrame += m_iFrameStart;
|
||||
intPrevFrame += m_iFrameStart;
|
||||
}
|
||||
|
||||
// Report wrap situation...
|
||||
if (intPrevFrame > intFrame)
|
||||
{
|
||||
m_bReachedEnd = true;
|
||||
|
||||
if (bWrapAnimation)
|
||||
{
|
||||
AnimationWrapped( pEntity );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only sent the wrapped message once.
|
||||
// when we're in non-wrapping mode
|
||||
if (prevFrame < numFrames)
|
||||
AnimationWrapped( pEntity );
|
||||
intFrame = numFrames - 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
float CMaterialModifyAnimatedProxy::GetAnimationStartTime( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return 0.0f;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
return pEntity->GetTextureAnimationStartTime();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyAnimatedProxy::AnimationWrapped( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
pEntity->TextureAnimationWrapped();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CMaterialModifyProxy, MaterialModify );
|
||||
EXPOSE_MATERIAL_PROXY( CMaterialModifyAnimatedProxy, MaterialModifyAnimated );
|
60
game/client/C_WaterLODControl.cpp
Normal file
60
game/client/C_WaterLODControl.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Water LOD control entity.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "iviewrender.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FIXME: This really should inherit from something more lightweight
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Water LOD control entity
|
||||
//------------------------------------------------------------------------------
|
||||
class C_WaterLODControl : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_WaterLODControl, C_BaseEntity );
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
|
||||
private:
|
||||
float m_flCheapWaterStartDistance;
|
||||
float m_flCheapWaterEndDistance;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_WaterLODControl, DT_WaterLODControl, CWaterLODControl)
|
||||
RecvPropFloat(RECVINFO(m_flCheapWaterStartDistance)),
|
||||
RecvPropFloat(RECVINFO(m_flCheapWaterEndDistance)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_WaterLODControl::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
view->SetCheapWaterStartDistance( m_flCheapWaterStartDistance );
|
||||
view->SetCheapWaterEndDistance( m_flCheapWaterEndDistance );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// We don't draw...
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_WaterLODControl::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
231
game/client/EffectsClient.cpp
Normal file
231
game/client/EffectsClient.cpp
Normal file
@ -0,0 +1,231 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Utility code.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "IEffects.h"
|
||||
#include "fx.h"
|
||||
#include "c_te_legacytempents.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Client-server neutral effects interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class CEffectsClient : public IEffects
|
||||
{
|
||||
public:
|
||||
CEffectsClient();
|
||||
virtual ~CEffectsClient();
|
||||
|
||||
// Members of the IEffect interface
|
||||
virtual void Beam( const Vector &Start, const Vector &End, int nModelIndex,
|
||||
int nHaloIndex, unsigned char frameStart, unsigned char frameRate,
|
||||
float flLife, unsigned char width, unsigned char endWidth, unsigned char fadeLength,
|
||||
unsigned char noise, unsigned char red, unsigned char green,
|
||||
unsigned char blue, unsigned char brightness, unsigned char speed);
|
||||
virtual void Smoke( const Vector &origin, int modelIndex, float scale, float framerate );
|
||||
virtual void Sparks( const Vector &position, int nMagnitude = 1, int nTrailLength = 1, const Vector *pvecDir = NULL );
|
||||
virtual void Dust( const Vector &pos, const Vector &dir, float size, float speed );
|
||||
virtual void MuzzleFlash( const Vector &origin, const QAngle &angles, float fScale, int type );
|
||||
virtual void MetalSparks( const Vector &position, const Vector &direction );
|
||||
virtual void EnergySplash( const Vector &position, const Vector &direction, bool bExplosive = false );
|
||||
virtual void Ricochet( const Vector &position, const Vector &direction );
|
||||
|
||||
// FIXME: Should these methods remain in this interface? Or go in some
|
||||
// other client-server neutral interface?
|
||||
virtual float Time();
|
||||
virtual bool IsServer();
|
||||
virtual void SuppressEffectsSounds( bool bSuppress );
|
||||
|
||||
private:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returning true means don't even call TE func
|
||||
// Input : filter -
|
||||
// *suppress_host -
|
||||
// Output : static bool
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SuppressTE( C_RecipientFilter& filter )
|
||||
{
|
||||
if ( !CanPredict() )
|
||||
return true;
|
||||
|
||||
if ( !filter.GetRecipientCount() )
|
||||
{
|
||||
// Suppress it
|
||||
return true;
|
||||
}
|
||||
|
||||
// There's at least one recipient
|
||||
return false;
|
||||
}
|
||||
|
||||
bool m_bSuppressSound;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Client-server neutral effects interface accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
static CEffectsClient s_EffectClient;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CEffectsClient, IEffects, IEFFECTS_INTERFACE_VERSION, s_EffectClient);
|
||||
IEffects *g_pEffects = &s_EffectClient;
|
||||
|
||||
ConVar r_decals( "r_decals", "2048" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CEffectsClient::CEffectsClient()
|
||||
{
|
||||
m_bSuppressSound = false;
|
||||
}
|
||||
|
||||
CEffectsClient::~CEffectsClient()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Suppress sound on effects
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEffectsClient::SuppressEffectsSounds( bool bSuppress )
|
||||
{
|
||||
m_bSuppressSound = bSuppress;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Generates a beam
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEffectsClient::Beam( const Vector &vecStartPoint, const Vector &vecEndPoint,
|
||||
int nModelIndex, int nHaloIndex, unsigned char frameStart, unsigned char nFrameRate,
|
||||
float flLife, unsigned char nWidth, unsigned char nEndWidth, unsigned char nFadeLength,
|
||||
unsigned char noise, unsigned char r, unsigned char g,
|
||||
unsigned char b, unsigned char brightness, unsigned char nSpeed)
|
||||
{
|
||||
Assert(0);
|
||||
// CBroadcastRecipientFilter filter;
|
||||
// if ( !SuppressTE( filter ) )
|
||||
// {
|
||||
// beams->CreateBeamPoints( vecStartPoint, vecEndPoint, nModelIndex, nHaloIndex,
|
||||
// m_fHaloScale,
|
||||
// flLife, 0.1 * nWidth, 0.1 * nEndWidth, nFadeLength, 0.01 * nAmplitude, a, 0.1 * nSpeed,
|
||||
// m_nStartFrame, 0.1 * nFrameRate, r, g, b );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Generates various tempent effects
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEffectsClient::Smoke( const Vector &vecOrigin, int modelIndex, float scale, float framerate )
|
||||
{
|
||||
CPVSFilter filter( vecOrigin );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
int iColor = random->RandomInt(20,35);
|
||||
color32 color;
|
||||
color.r = iColor;
|
||||
color.g = iColor;
|
||||
color.b = iColor;
|
||||
color.a = iColor;
|
||||
QAngle angles;
|
||||
VectorAngles( Vector(0,0,1), angles );
|
||||
FX_Smoke( vecOrigin, angles, scale * 0.1f, 4, (unsigned char *)&color, 255 );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::Sparks( const Vector &position, int nMagnitude, int nTrailLength, const Vector *pVecDir )
|
||||
{
|
||||
CPVSFilter filter( position );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_ElectricSpark( position, nMagnitude, nTrailLength, pVecDir );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::Dust( const Vector &pos, const Vector &dir, float size, float speed )
|
||||
{
|
||||
CPVSFilter filter( pos );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_Dust( pos, dir, size, speed );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::MuzzleFlash( const Vector &vecOrigin, const QAngle &vecAngles, float flScale, int iType )
|
||||
{
|
||||
CPVSFilter filter( vecOrigin );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
switch( iType )
|
||||
{
|
||||
case MUZZLEFLASH_TYPE_DEFAULT:
|
||||
FX_MuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
|
||||
break;
|
||||
|
||||
case MUZZLEFLASH_TYPE_GUNSHIP:
|
||||
FX_GunshipMuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
|
||||
break;
|
||||
|
||||
case MUZZLEFLASH_TYPE_STRIDER:
|
||||
FX_StriderMuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
|
||||
break;
|
||||
|
||||
default:
|
||||
Msg("No case for Muzzleflash type: %d\n", iType );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::MetalSparks( const Vector &position, const Vector &direction )
|
||||
{
|
||||
CPVSFilter filter( position );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_MetalSpark( position, direction, direction );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::EnergySplash( const Vector &position, const Vector &direction, bool bExplosive )
|
||||
{
|
||||
CPVSFilter filter( position );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_EnergySplash( position, direction, bExplosive );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::Ricochet( const Vector &position, const Vector &direction )
|
||||
{
|
||||
CPVSFilter filter( position );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_MetalSpark( position, direction, direction );
|
||||
|
||||
if ( !m_bSuppressSound )
|
||||
{
|
||||
FX_RicochetSound( position );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Should these methods remain in this interface? Or go in some
|
||||
// other client-server neutral interface?
|
||||
float CEffectsClient::Time()
|
||||
{
|
||||
return gpGlobals->curtime;
|
||||
}
|
||||
|
||||
|
||||
bool CEffectsClient::IsServer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
56
game/client/IsNPCProxy.cpp
Normal file
56
game/client/IsNPCProxy.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "FunctionProxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the player health (from 0 to 1)
|
||||
//-----------------------------------------------------------------------------
|
||||
class CProxyIsNPC : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pC_BaseEntity );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CProxyIsNPC::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProxyIsNPC::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if ( !pC_BaseEntity )
|
||||
return;
|
||||
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
|
||||
if ( pEntity && pEntity->IsNPC() )
|
||||
{
|
||||
SetFloatResult( m_Factor.GetFloat() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFloatResult( 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CProxyIsNPC, IsNPC );
|
||||
|
||||
|
65
game/client/MonitorMaterialProxy.cpp
Normal file
65
game/client/MonitorMaterialProxy.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/IMaterialProxy.h"
|
||||
#include "materialsystem/IMaterial.h"
|
||||
#include "materialsystem/IMaterialVar.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
// $monitorTextureVar
|
||||
class CMonitorMaterialProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CMonitorMaterialProxy();
|
||||
virtual ~CMonitorMaterialProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
private:
|
||||
IMaterialVar *m_pMonitorTextureVar;
|
||||
};
|
||||
|
||||
CMonitorMaterialProxy::CMonitorMaterialProxy()
|
||||
{
|
||||
m_pMonitorTextureVar = NULL;
|
||||
}
|
||||
|
||||
CMonitorMaterialProxy::~CMonitorMaterialProxy()
|
||||
{
|
||||
m_pMonitorTextureVar = NULL;
|
||||
}
|
||||
|
||||
|
||||
bool CMonitorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
char const* pMonitorTextureVarName = pKeyValues->getString( "$monitorTextureVar" );
|
||||
if( !pMonitorTextureVarName )
|
||||
return false;
|
||||
|
||||
bool foundVar;
|
||||
m_pMonitorTextureVar = pMaterial->FindVar( pMonitorTextureVarName, &foundVar, false );
|
||||
if( !foundVar )
|
||||
{
|
||||
m_pMonitorTextureVar = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMonitorMaterialProxy::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if( !m_pMonitorTextureVar )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CMonitorMaterialProxy, Monitor );
|
101
game/client/NPSClient.h
Normal file
101
game/client/NPSClient.h
Normal file
@ -0,0 +1,101 @@
|
||||
// *******************************************************************************
|
||||
// *
|
||||
// * Module Name:
|
||||
// * NPSClient.h
|
||||
// *
|
||||
// * Abstract:
|
||||
// * Header for NaturalPoint Simple Game Client API.
|
||||
// *
|
||||
// * Environment:
|
||||
// * Microsoft Windows -- User mode
|
||||
// *
|
||||
// *******************************************************************************
|
||||
|
||||
#ifndef _NPSCLIENT_H_DEFINED_
|
||||
#define _NPSCLIENT_H_DEFINED_
|
||||
|
||||
#pragma pack( push, npsclient_h ) // Save current pack value
|
||||
#pragma pack(1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
//////////////////
|
||||
/// Typedefs /////////////////////////////////////////////////////////////////////
|
||||
/////////////////
|
||||
|
||||
#ifndef _NPCLIENT_H_DEFINED_
|
||||
|
||||
// NPESULT values are returned from the Game Client API functions.
|
||||
//
|
||||
typedef enum tagNPResult
|
||||
{
|
||||
NP_OK = 0,
|
||||
NP_ERR_DEVICE_NOT_PRESENT,
|
||||
NP_ERR_UNSUPPORTED_OS,
|
||||
NP_ERR_INVALID_ARG,
|
||||
NP_ERR_DLL_NOT_FOUND,
|
||||
NP_ERR_NO_DATA,
|
||||
NP_ERR_INTERNAL_DATA,
|
||||
NP_ERR_ALREADY_REGISTERED, // a window handle or game ID is already registered
|
||||
NP_ERR_UNKNOWN_ID, // unknown game ID registered
|
||||
NP_ERR_READ_ONLY, // parameter is read only
|
||||
|
||||
} NPRESULT;
|
||||
|
||||
typedef struct tagTrackIRData
|
||||
{
|
||||
unsigned short wNPStatus;
|
||||
unsigned short wPFrameSignature;
|
||||
unsigned long dwNPIOData;
|
||||
|
||||
float fNPRoll;
|
||||
float fNPPitch;
|
||||
float fNPYaw;
|
||||
float fNPX;
|
||||
float fNPY;
|
||||
float fNPZ;
|
||||
float fNPRawX;
|
||||
float fNPRawY;
|
||||
float fNPRawZ;
|
||||
float fNPDeltaX;
|
||||
float fNPDeltaY;
|
||||
float fNPDeltaZ;
|
||||
float fNPSmoothX;
|
||||
float fNPSmoothY;
|
||||
float fNPSmoothZ;
|
||||
|
||||
} TRACKIRDATA, *LPTRACKIRDATA;
|
||||
|
||||
#endif
|
||||
|
||||
typedef NPRESULT (__stdcall *PF_NPS_INIT)( HWND );
|
||||
typedef NPRESULT (__stdcall *PF_NPS_SHUTDOWN)( void );
|
||||
typedef NPRESULT (__stdcall *PF_NPS_GETDATA)( LPTRACKIRDATA );
|
||||
|
||||
//// Function Prototypes ///////////////////////////////////////////////
|
||||
//
|
||||
// Functions exported from game client API DLL ( note __stdcall calling convention
|
||||
// is used for ease of interface to clients of differing implementations including
|
||||
// C, C++, Pascal (Delphi) and VB. )
|
||||
//
|
||||
NPRESULT __stdcall NPS_Init( HWND hWnd );
|
||||
NPRESULT __stdcall NPS_Shutdown( void );
|
||||
NPRESULT __stdcall NPS_GetData( LPTRACKIRDATA pTID );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma pack( pop, npsclient_h ) // Ensure previous pack value is restored
|
||||
|
||||
#endif // #ifdef NPCLIENT_H_DEFINED_
|
||||
|
||||
//
|
||||
// *** End of file: NPSClient.h ***
|
||||
//
|
||||
|
||||
|
51
game/client/ProxyHealth.cpp
Normal file
51
game/client/ProxyHealth.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "FunctionProxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the player health (from 0 to 1)
|
||||
//-----------------------------------------------------------------------------
|
||||
class CProxyHealth : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pC_BaseEntity );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CProxyHealth::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProxyHealth::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if (!pC_BaseEntity)
|
||||
return;
|
||||
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
|
||||
|
||||
Assert( m_pResult );
|
||||
SetFloatResult( pEntity->HealthFraction() * m_Factor.GetFloat() );
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CProxyHealth, Health );
|
||||
|
||||
|
316
game/client/ScreenSpaceEffects.cpp
Normal file
316
game/client/ScreenSpaceEffects.cpp
Normal file
@ -0,0 +1,316 @@
|
||||
#include "cbase.h"
|
||||
|
||||
#include "keyvalues.h"
|
||||
#include "cdll_client_int.h"
|
||||
#include "view_scene.h"
|
||||
#include "viewrender.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "materialsystem/IMesh.h"
|
||||
#include "materialsystem/IMaterial.h"
|
||||
#include "materialsystem/IMaterialSystemHardwareConfig.h"
|
||||
#include "materialsystem/IMaterialVar.h"
|
||||
|
||||
#include "ScreenSpaceEffects.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectRegistration code
|
||||
// Used to register and effect with the IScreenSpaceEffectManager
|
||||
//------------------------------------------------------------------------------
|
||||
CScreenSpaceEffectRegistration *CScreenSpaceEffectRegistration::s_pHead = NULL;
|
||||
|
||||
CScreenSpaceEffectRegistration::CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect )
|
||||
{
|
||||
m_pEffectName = pName;
|
||||
m_pEffect = pEffect;
|
||||
m_pNext = s_pHead;
|
||||
s_pHead = this;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager - Implementation of IScreenSpaceEffectManager
|
||||
//------------------------------------------------------------------------------
|
||||
class CScreenSpaceEffectManager : public IScreenSpaceEffectManager
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void InitScreenSpaceEffects( );
|
||||
virtual void ShutdownScreenSpaceEffects( );
|
||||
|
||||
virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName );
|
||||
|
||||
virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params );
|
||||
virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params );
|
||||
|
||||
virtual void EnableScreenSpaceEffect( const char *pEffectName );
|
||||
virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
|
||||
|
||||
virtual void DisableScreenSpaceEffect( const char *pEffectName );
|
||||
virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
|
||||
|
||||
virtual void DisableAllScreenSpaceEffects( );
|
||||
|
||||
virtual void RenderEffects( int x, int y, int w, int h );
|
||||
};
|
||||
|
||||
CScreenSpaceEffectManager g_ScreenSpaceEffectManager;
|
||||
IScreenSpaceEffectManager *g_pScreenSpaceEffects = &g_ScreenSpaceEffectManager;
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::InitScreenSpaceEffects - Initialise all registered effects
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::InitScreenSpaceEffects( )
|
||||
{
|
||||
if ( CommandLine()->FindParm( "-filmgrain" ) )
|
||||
{
|
||||
GetScreenSpaceEffect( "filmgrain" )->Enable( true );
|
||||
}
|
||||
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
if( pEffect )
|
||||
{
|
||||
bool bIsEnabled = pEffect->IsEnabled( );
|
||||
pEffect->Init( );
|
||||
pEffect->Enable( bIsEnabled );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::ShutdownScreenSpaceEffects - Shutdown all registered effects
|
||||
//----------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::ShutdownScreenSpaceEffects( )
|
||||
{
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
if( pEffect )
|
||||
{
|
||||
pEffect->Shutdown( );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::GetScreenSpaceEffect - Returns a point to the named effect
|
||||
//---------------------------------------------------------------------------------------
|
||||
IScreenSpaceEffect *CScreenSpaceEffectManager::GetScreenSpaceEffect( const char *pEffectName )
|
||||
{
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
if( !Q_stricmp( pReg->m_pEffectName, pEffectName ) )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
return pEffect;
|
||||
}
|
||||
}
|
||||
|
||||
Warning( "Could not find screen space effect %s\n", pEffectName );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::SetScreenSpaceEffectParams
|
||||
// - Assign parameters to the specified effect
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||
if( pEffect )
|
||||
SetScreenSpaceEffectParams( pEffect, params );
|
||||
}
|
||||
|
||||
void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params )
|
||||
{
|
||||
if( pEffect )
|
||||
pEffect->SetParameters( params );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::EnableScreenSpaceEffect
|
||||
// - Enables the specified effect
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::EnableScreenSpaceEffect( const char *pEffectName )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||
if( pEffect )
|
||||
EnableScreenSpaceEffect( pEffect );
|
||||
}
|
||||
|
||||
void CScreenSpaceEffectManager::EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
|
||||
{
|
||||
if( pEffect )
|
||||
pEffect->Enable( true );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::DisableScreenSpaceEffect
|
||||
// - Disables the specified effect
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::DisableScreenSpaceEffect( const char *pEffectName )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||
if( pEffect )
|
||||
DisableScreenSpaceEffect( pEffect );
|
||||
}
|
||||
|
||||
void CScreenSpaceEffectManager::DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
|
||||
{
|
||||
if( pEffect )
|
||||
pEffect->Enable( false );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::DisableAllScreenSpaceEffects
|
||||
// - Disables all registered screen space effects
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::DisableAllScreenSpaceEffects( )
|
||||
{
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
if( pEffect )
|
||||
{
|
||||
pEffect->Enable( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::RenderEffects
|
||||
// - Renders all registered screen space effects
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::RenderEffects( int x, int y, int w, int h )
|
||||
{
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
if( pEffect )
|
||||
{
|
||||
pEffect->Render( x, y, w, h );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Example post-processing effect
|
||||
//------------------------------------------------------------------------------
|
||||
class CExampleEffect : public IScreenSpaceEffect
|
||||
{
|
||||
public:
|
||||
CExampleEffect( );
|
||||
~CExampleEffect( );
|
||||
|
||||
void Init( );
|
||||
void Shutdown( );
|
||||
|
||||
void SetParameters( KeyValues *params );
|
||||
|
||||
void Render( int x, int y, int w, int h );
|
||||
|
||||
void Enable( bool bEnable );
|
||||
bool IsEnabled( );
|
||||
|
||||
private:
|
||||
|
||||
bool m_bEnable;
|
||||
|
||||
CMaterialReference m_Material;
|
||||
};
|
||||
|
||||
ADD_SCREENSPACE_EFFECT( CExampleEffect, exampleeffect );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect constructor
|
||||
//------------------------------------------------------------------------------
|
||||
CExampleEffect::CExampleEffect( )
|
||||
{
|
||||
m_bEnable = false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect destructor
|
||||
//------------------------------------------------------------------------------
|
||||
CExampleEffect::~CExampleEffect( )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect init
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::Init( )
|
||||
{
|
||||
// This is just example code, init your effect material here
|
||||
//m_Material.Init( "engine/exampleeffect", TEXTURE_GROUP_OTHER );
|
||||
|
||||
m_bEnable = false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect shutdown
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::Shutdown( )
|
||||
{
|
||||
m_Material.Shutdown();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect enable
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::Enable( bool bEnable )
|
||||
{
|
||||
// This is just example code, don't enable it
|
||||
// m_bEnable = bEnable;
|
||||
}
|
||||
|
||||
bool CExampleEffect::IsEnabled( )
|
||||
{
|
||||
return m_bEnable;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect SetParameters
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::SetParameters( KeyValues *params )
|
||||
{
|
||||
if( params->GetDataType( "example_param" ) == KeyValues::TYPE_STRING )
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect render
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::Render( int x, int y, int w, int h )
|
||||
{
|
||||
if ( !IsEnabled() )
|
||||
return;
|
||||
|
||||
// Render Effect
|
||||
Rect_t actualRect;
|
||||
UpdateScreenEffectTexture( 0, x, y, w, h, false, &actualRect );
|
||||
ITexture *pTexture = GetFullFrameFrameBufferTexture( 0 );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
|
||||
pRenderContext->DrawScreenSpaceRectangle( m_Material, x, y, w, h,
|
||||
actualRect.x, actualRect.y, actualRect.x+actualRect.width-1, actualRect.y+actualRect.height-1,
|
||||
pTexture->GetActualWidth(), pTexture->GetActualHeight() );
|
||||
}
|
88
game/client/ScreenSpaceEffects.h
Normal file
88
game/client/ScreenSpaceEffects.h
Normal file
@ -0,0 +1,88 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#ifndef SCREENSPACEEFFECTS_H
|
||||
#define SCREENSPACEEFFECTS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class KeyValues;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Simple base class for screen space post-processing effects
|
||||
//------------------------------------------------------------------------------
|
||||
abstract_class IScreenSpaceEffect
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void Init( ) = 0;
|
||||
virtual void Shutdown( ) = 0;
|
||||
|
||||
virtual void SetParameters( KeyValues *params ) = 0;
|
||||
|
||||
virtual void Render( int x, int y, int w, int h ) = 0;
|
||||
|
||||
virtual void Enable( bool bEnable ) = 0;
|
||||
virtual bool IsEnabled( ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Interface class for managing screen space post-processing effects
|
||||
//------------------------------------------------------------------------------
|
||||
abstract_class IScreenSpaceEffectManager
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void InitScreenSpaceEffects( ) = 0;
|
||||
virtual void ShutdownScreenSpaceEffects( ) = 0;
|
||||
|
||||
virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||
|
||||
virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params ) = 0;
|
||||
virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params ) = 0;
|
||||
|
||||
virtual void EnableScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||
virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect ) = 0;
|
||||
|
||||
virtual void DisableScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||
virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect ) = 0;
|
||||
|
||||
virtual void DisableAllScreenSpaceEffects( ) = 0;
|
||||
|
||||
virtual void RenderEffects( int x, int y, int w, int h ) = 0;
|
||||
};
|
||||
|
||||
extern IScreenSpaceEffectManager *g_pScreenSpaceEffects;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Registration class for adding screen space effects to the IScreenSpaceEffectManager
|
||||
//-------------------------------------------------------------------------------------
|
||||
class CScreenSpaceEffectRegistration
|
||||
{
|
||||
public:
|
||||
CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect );
|
||||
|
||||
const char *m_pEffectName;
|
||||
IScreenSpaceEffect *m_pEffect;
|
||||
|
||||
CScreenSpaceEffectRegistration *m_pNext;
|
||||
|
||||
static CScreenSpaceEffectRegistration *s_pHead;
|
||||
};
|
||||
|
||||
#define ADD_SCREENSPACE_EFFECT( CEffect, pEffectName ) CEffect pEffectName##_effect; \
|
||||
CScreenSpaceEffectRegistration pEffectName##_reg( #pEffectName, &pEffectName##_effect );
|
||||
|
||||
|
||||
|
||||
#endif
|
172
game/client/TeamBitmapImage.cpp
Normal file
172
game/client/TeamBitmapImage.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is a panel which is rendered image on top of an entity
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "teambitmapimage.h"
|
||||
#include <KeyValues.h>
|
||||
#include "vgui_BitmapImage.h"
|
||||
#include "PanelMetaClassMgr.h"
|
||||
#include "vguimatsurface/IMatSystemSurface.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A multiplexer bitmap that chooses a bitmap based on team
|
||||
//-----------------------------------------------------------------------------
|
||||
CTeamBitmapImage::CTeamBitmapImage() : m_Alpha(1.0f)
|
||||
{
|
||||
memset( m_ppImage, 0, BITMAP_COUNT * sizeof(BitmapImage*) );
|
||||
m_pEntity = NULL;
|
||||
m_bRelativeTeams = 0;
|
||||
}
|
||||
|
||||
CTeamBitmapImage::~CTeamBitmapImage()
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < BITMAP_COUNT; ++i )
|
||||
{
|
||||
if (m_ppImage[i])
|
||||
delete m_ppImage[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamBitmapImage::Init( vgui::Panel *pParent, KeyValues* pInitData, C_BaseEntity* pEntity )
|
||||
{
|
||||
static char *pRelativeTeamNames[BITMAP_COUNT] =
|
||||
{
|
||||
"NoTeam",
|
||||
"MyTeam",
|
||||
"EnemyTeam",
|
||||
};
|
||||
|
||||
static char *pAbsoluteTeamNames[BITMAP_COUNT] =
|
||||
{
|
||||
"Team0",
|
||||
"Team1",
|
||||
"Team2",
|
||||
};
|
||||
|
||||
m_pEntity = pEntity;
|
||||
m_bRelativeTeams = (pInitData->GetInt( "relativeteam" ) != 0);
|
||||
|
||||
char **ppTeamNames = m_bRelativeTeams ? pRelativeTeamNames : pAbsoluteTeamNames;
|
||||
|
||||
int i;
|
||||
for ( i = 0 ; i < BITMAP_COUNT; ++i )
|
||||
{
|
||||
// Default to null
|
||||
m_ppImage[i] = NULL;
|
||||
|
||||
// Look for team section
|
||||
KeyValues *pTeamKV = pInitData->FindKey( ppTeamNames[i] );
|
||||
if ( !pTeamKV )
|
||||
continue;
|
||||
|
||||
char const* pClassImage = pTeamKV->GetString( "material" );
|
||||
if ( !pClassImage || !pClassImage[ 0 ] )
|
||||
return false;
|
||||
|
||||
// modulation color
|
||||
Color color;
|
||||
if (!ParseRGBA( pTeamKV, "color", color ))
|
||||
color.SetColor( 255, 255, 255, 255 );
|
||||
|
||||
// hook in the bitmap
|
||||
m_ppImage[i] = new BitmapImage( pParent->GetVPanel(), pClassImage );
|
||||
m_ppImage[i]->SetColor( color );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Alpha modulate...
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamBitmapImage::SetAlpha( float alpha )
|
||||
{
|
||||
m_Alpha = clamp( alpha, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamBitmapImage::Paint( float yaw /*= 0.0f*/ )
|
||||
{
|
||||
if (m_Alpha == 0.0f)
|
||||
return;
|
||||
|
||||
int team = 0;
|
||||
if (m_bRelativeTeams)
|
||||
{
|
||||
if (GetEntity())
|
||||
{
|
||||
if (GetEntity()->GetTeamNumber() != 0)
|
||||
{
|
||||
team = GetEntity()->InLocalTeam() ? 1 : 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetEntity())
|
||||
team = GetEntity()->GetTeamNumber();
|
||||
}
|
||||
|
||||
// Paint the image for the current team
|
||||
if (m_ppImage[team])
|
||||
{
|
||||
// Modulate the color based on the alpha....
|
||||
Color color = m_ppImage[team]->GetColor();
|
||||
int alpha = color[3];
|
||||
color[3] = (alpha * m_Alpha);
|
||||
m_ppImage[team]->SetColor( color );
|
||||
|
||||
if ( yaw != 0.0f )
|
||||
{
|
||||
g_pMatSystemSurface->DisableClipping( true );
|
||||
|
||||
m_ppImage[team]->DoPaint( m_ppImage[team]->GetRenderSizePanel(), yaw );
|
||||
|
||||
g_pMatSystemSurface->DisableClipping( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Paint
|
||||
m_ppImage[team]->Paint();
|
||||
}
|
||||
|
||||
// restore previous color
|
||||
color[3] = alpha;
|
||||
m_ppImage[team]->SetColor( color );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method to initialize a team image from KeyValues data..
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InitializeTeamImage( KeyValues *pInitData, const char* pSectionName, vgui::Panel *pParent, C_BaseEntity *pEntity, CTeamBitmapImage* pTeamImage )
|
||||
{
|
||||
KeyValues *pTeamImageSection = pInitData;
|
||||
if (pSectionName)
|
||||
{
|
||||
pTeamImageSection = pInitData->FindKey( pSectionName );
|
||||
if ( !pTeamImageSection )
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTeamImage->Init( pParent, pTeamImageSection, pEntity );
|
||||
}
|
||||
|
80
game/client/TeamBitmapImage.h
Normal file
80
game/client/TeamBitmapImage.h
Normal file
@ -0,0 +1,80 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is a panel which is rendered image on top of an entity
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TEAMBITMAPIMAGE_H
|
||||
#define TEAMBITMAPIMAGE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//#include "tf_shareddefs.h"
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Panel;
|
||||
}
|
||||
|
||||
class BitmapImage;
|
||||
class C_BaseEntity;
|
||||
class KeyValues;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A multiplexer bitmap that chooses a bitmap based on team
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTeamBitmapImage
|
||||
{
|
||||
public:
|
||||
// construction, destruction
|
||||
CTeamBitmapImage();
|
||||
~CTeamBitmapImage();
|
||||
|
||||
// initialization
|
||||
bool Init( vgui::Panel *pParent, KeyValues* pInitData, C_BaseEntity* pEntity );
|
||||
|
||||
// Alpha override...
|
||||
void SetAlpha( float alpha );
|
||||
|
||||
// Paint the sucka. Paint it the size of the parent panel
|
||||
void Paint( float yaw = 0.0f );
|
||||
|
||||
protected:
|
||||
// Wrapper so we can implement this with EHANDLES some day
|
||||
C_BaseEntity *GetEntity() { return m_pEntity; }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
// NOTE: Was MAX_TF_TEAMS not 4, but I don't like the dependency here.
|
||||
BITMAP_COUNT = 4 + 1
|
||||
};
|
||||
|
||||
BitmapImage *m_ppImage[ BITMAP_COUNT ];
|
||||
C_BaseEntity *m_pEntity;
|
||||
float m_Alpha;
|
||||
bool m_bRelativeTeams;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method to initialize a team image from KeyValues data..
|
||||
// KeyValues contains the bitmap data. pSectionName, if it exists,
|
||||
// indicates which subsection of pInitData should be looked at to get at the
|
||||
// image data. The final argument is the bitmap image to initialize.
|
||||
// The function returns true if it succeeded.
|
||||
//
|
||||
// NOTE: This function looks for the key values 'material' and 'color'
|
||||
// and uses them to set up the material + modulation color of the image
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InitializeTeamImage( KeyValues *pInitData, const char* pSectionName,
|
||||
vgui::Panel *pParent, C_BaseEntity *pEntity, CTeamBitmapImage* pBitmapImage );
|
||||
|
||||
|
||||
#endif // TEAMBITMAPIMAGE_H
|
83
game/client/ViewConeImage.cpp
Normal file
83
game/client/ViewConeImage.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is a panel which is rendered image on top of an entity
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "ViewConeImage.h"
|
||||
#include <KeyValues.h>
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include "vguimatsurface/IMatSystemSurface.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CViewConeImage::Init( vgui::Panel *pParent, KeyValues* pInitData )
|
||||
{
|
||||
Assert( pParent );
|
||||
|
||||
// Load viewcone material
|
||||
if (!m_Image.Init( pParent->GetVPanel(), pInitData ))
|
||||
return false;
|
||||
|
||||
// Position the view cone...
|
||||
int viewconesize = pInitData->GetInt( "size", 32 );
|
||||
m_Image.SetRenderSize( viewconesize, viewconesize );
|
||||
|
||||
int cx, cy;
|
||||
pParent->GetSize( cx, cy );
|
||||
m_Image.SetPos( (cx - viewconesize) / 2, (cy - viewconesize) / 2 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paint the sucka
|
||||
//-----------------------------------------------------------------------------
|
||||
void CViewConeImage::Paint( float yaw )
|
||||
{
|
||||
g_pMatSystemSurface->DisableClipping( true );
|
||||
|
||||
m_Image.DoPaint( NULL, yaw );
|
||||
|
||||
g_pMatSystemSurface->DisableClipping( false );
|
||||
}
|
||||
|
||||
void CViewConeImage::SetColor( int r, int g, int b )
|
||||
{
|
||||
m_Image.SetColor( Color( r, g, b, 255 ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method to initialize a view cone image from KeyValues data..
|
||||
// KeyValues contains the bitmap data, pSectionName, if it exists,
|
||||
// indicates which subsection of pInitData should be looked at to get at the
|
||||
// image data. The final argument is the bitmap image to initialize.
|
||||
// The function returns true if it succeeded.
|
||||
//
|
||||
// NOTE: This function looks for the key values 'material' and 'color'
|
||||
// and uses them to set up the material + modulation color of the image
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InitializeViewConeImage( KeyValues *pInitData, const char* pSectionName,
|
||||
vgui::Panel *pParent, CViewConeImage* pViewConeImage )
|
||||
{
|
||||
KeyValues *pViewConeImageSection;
|
||||
if (pSectionName)
|
||||
{
|
||||
pViewConeImageSection = pInitData->FindKey( pSectionName );
|
||||
if ( !pViewConeImageSection )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pViewConeImageSection = pInitData;
|
||||
}
|
||||
|
||||
return pViewConeImage->Init( pParent, pViewConeImageSection );
|
||||
}
|
||||
|
56
game/client/ViewConeImage.h
Normal file
56
game/client/ViewConeImage.h
Normal file
@ -0,0 +1,56 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is a panel which draws a viewcone
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VIEWCONEIMAGE_H
|
||||
#define VIEWCONEIMAGE_H
|
||||
|
||||
#include "shareddefs.h"
|
||||
#include "VGUI_BitmapImage.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Panel;
|
||||
}
|
||||
|
||||
class C_BaseEntity;
|
||||
class KeyValues;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A bitmap that renders a view cone based on angles
|
||||
//-----------------------------------------------------------------------------
|
||||
class CViewConeImage
|
||||
{
|
||||
public:
|
||||
// initialization
|
||||
bool Init( vgui::Panel *pParent, KeyValues* pInitData );
|
||||
|
||||
// Paint the sucka
|
||||
void Paint( float yaw );
|
||||
|
||||
void SetColor( int r, int g, int b );
|
||||
|
||||
private:
|
||||
BitmapImage m_Image;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method to initialize a view cone image from KeyValues data..
|
||||
// KeyValues contains the bitmap data, pSectionName, if it exists,
|
||||
// indicates which subsection of pInitData should be looked at to get at the
|
||||
// image data. The final argument is the bitmap image to initialize.
|
||||
// The function returns true if it succeeded.
|
||||
//
|
||||
// NOTE: This function looks for the key values 'material' and 'color'
|
||||
// and uses them to set up the material + modulation color of the image
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InitializeViewConeImage( KeyValues *pInitData, const char* pSectionName,
|
||||
vgui::Panel *pParent, CViewConeImage* pViewConeImage );
|
||||
|
||||
|
||||
#endif // VIEWCONEIMAGE_H
|
75
game/client/WaterLODMaterialProxy.cpp
Normal file
75
game/client/WaterLODMaterialProxy.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/IMaterialProxy.h"
|
||||
#include "materialsystem/IMaterial.h"
|
||||
#include "materialsystem/IMaterialVar.h"
|
||||
#include "iviewrender.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// no inputs, assumes that the results go into $CHEAPWATERSTARTDISTANCE and $CHEAPWATERENDDISTANCE
|
||||
class CWaterLODMaterialProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CWaterLODMaterialProxy();
|
||||
virtual ~CWaterLODMaterialProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
IMaterialVar *m_pCheapWaterStartDistanceVar;
|
||||
IMaterialVar *m_pCheapWaterEndDistanceVar;
|
||||
};
|
||||
|
||||
CWaterLODMaterialProxy::CWaterLODMaterialProxy()
|
||||
{
|
||||
m_pCheapWaterStartDistanceVar = NULL;
|
||||
m_pCheapWaterEndDistanceVar = NULL;
|
||||
}
|
||||
|
||||
CWaterLODMaterialProxy::~CWaterLODMaterialProxy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool CWaterLODMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
bool foundVar;
|
||||
m_pCheapWaterStartDistanceVar = pMaterial->FindVar( "$CHEAPWATERSTARTDISTANCE", &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
m_pCheapWaterEndDistanceVar = pMaterial->FindVar( "$CHEAPWATERENDDISTANCE", &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWaterLODMaterialProxy::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if( !m_pCheapWaterStartDistanceVar || !m_pCheapWaterEndDistanceVar )
|
||||
{
|
||||
return;
|
||||
}
|
||||
float start, end;
|
||||
view->GetWaterLODParams( start, end );
|
||||
m_pCheapWaterStartDistanceVar->SetFloatValue( start );
|
||||
m_pCheapWaterEndDistanceVar->SetFloatValue( end );
|
||||
}
|
||||
|
||||
IMaterial *CWaterLODMaterialProxy::GetMaterial()
|
||||
{
|
||||
return m_pCheapWaterStartDistanceVar->GetOwningMaterial();
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CWaterLODMaterialProxy, WaterLOD );
|
70
game/client/WorldDimsProxy.cpp
Normal file
70
game/client/WorldDimsProxy.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/IMaterialProxy.h"
|
||||
#include "materialsystem/IMaterial.h"
|
||||
#include "materialsystem/IMaterialVar.h"
|
||||
#include "c_world.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CWorldDimsProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CWorldDimsProxy();
|
||||
virtual ~CWorldDimsProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
|
||||
public:
|
||||
IMaterialVar *m_pMinsVar;
|
||||
IMaterialVar *m_pMaxsVar;
|
||||
};
|
||||
|
||||
|
||||
CWorldDimsProxy::CWorldDimsProxy()
|
||||
{
|
||||
m_pMinsVar = m_pMaxsVar = NULL;
|
||||
}
|
||||
|
||||
CWorldDimsProxy::~CWorldDimsProxy()
|
||||
{
|
||||
}
|
||||
|
||||
bool CWorldDimsProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
m_pMinsVar = pMaterial->FindVar( "$world_mins", NULL, false );
|
||||
m_pMaxsVar = pMaterial->FindVar( "$world_maxs", NULL, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWorldDimsProxy::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if ( m_pMinsVar && m_pMaxsVar )
|
||||
{
|
||||
C_World *pWorld = GetClientWorldEntity();
|
||||
if ( pWorld )
|
||||
{
|
||||
m_pMinsVar->SetVecValue( (const float*)&pWorld->m_WorldMins, 3 );
|
||||
m_pMaxsVar->SetVecValue( (const float*)&pWorld->m_WorldMaxs, 3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IMaterial *CWorldDimsProxy::GetMaterial()
|
||||
{
|
||||
return m_pMinsVar->GetOwningMaterial();
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CWorldDimsProxy, WorldDims );
|
||||
|
||||
|
272
game/client/achievement_notification_panel.cpp
Normal file
272
game/client/achievement_notification_panel.cpp
Normal file
@ -0,0 +1,272 @@
|
||||
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hud_macros.h"
|
||||
#include "hudelement.h"
|
||||
#include "iclientmode.h"
|
||||
#include "ienginevgui.h"
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/IVGUI.h>
|
||||
#include <vgui_controls/EditablePanel.h>
|
||||
#include <vgui_controls/Label.h>
|
||||
#include <vgui_controls/ImagePanel.h>
|
||||
#include "achievement_notification_panel.h"
|
||||
#include "steam/steam_api.h"
|
||||
#include "iachievementmgr.h"
|
||||
#include "fmtstr.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#define ACHIEVEMENT_NOTIFICATION_DURATION 10.0f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// DECLARE_HUDELEMENT_DEPTH( CAchievementNotificationPanel, 100 );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CAchievementNotificationPanel::CAchievementNotificationPanel( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "AchievementNotificationPanel" )
|
||||
{
|
||||
Panel *pParent = GetClientMode()->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
m_flHideTime = 0;
|
||||
m_pPanelBackground = new EditablePanel( this, "Notification_Background" );
|
||||
m_pIcon = new ImagePanel( this, "Notification_Icon" );
|
||||
m_pLabelHeading = new Label( this, "HeadingLabel", "" );
|
||||
m_pLabelTitle = new Label( this, "TitleLabel", "" );
|
||||
|
||||
m_pIcon->SetShouldScaleImage( true );
|
||||
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::Init()
|
||||
{
|
||||
ListenForGameEvent( "achievement_event" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
// load control settings...
|
||||
LoadControlSettings( "resource/UI/AchievementNotification.res" );
|
||||
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::PerformLayout( void )
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
// Set background color of various elements. Need to do this in code, if we do it in res file it gets slammed by the
|
||||
// scheme. (Incl. label background: some products don't have label background colors set in their scheme and helpfully slam it to white.)
|
||||
SetBgColor( Color( 0, 0, 0, 0 ) );
|
||||
m_pLabelHeading->SetBgColor( Color( 0, 0, 0, 0 ) );
|
||||
m_pLabelTitle->SetBgColor( Color( 0, 0, 0, 0 ) );
|
||||
m_pPanelBackground->SetBgColor( Color( 62,70,55, 200 ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::FireGameEvent( IGameEvent * event )
|
||||
{
|
||||
const char *name = event->GetName();
|
||||
if ( 0 == Q_strcmp( name, "achievement_event" ) )
|
||||
{
|
||||
const char *pchName = event->GetString( "achievement_name" );
|
||||
int iCur = event->GetInt( "cur_val" );
|
||||
int iMax = event->GetInt( "max_val" );
|
||||
wchar_t szLocalizedName[256]=L"";
|
||||
|
||||
if ( IsPC() )
|
||||
{
|
||||
// shouldn't ever get achievement progress if steam not running and user logged in, but check just in case
|
||||
if ( !steamapicontext->SteamUserStats() )
|
||||
{
|
||||
Msg( "Steam not running, achievement progress notification not displayed\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// use Steam to show achievement progress UI
|
||||
steamapicontext->SteamUserStats()->IndicateAchievementProgress( pchName, iCur, iMax );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// on X360 we need to show our own achievement progress UI
|
||||
|
||||
const wchar_t *pchLocalizedName = ACHIEVEMENT_LOCALIZED_NAME_FROM_STR( pchName );
|
||||
Assert( pchLocalizedName );
|
||||
if ( !pchLocalizedName || !pchLocalizedName[0] )
|
||||
return;
|
||||
Q_wcsncpy( szLocalizedName, pchLocalizedName, sizeof( szLocalizedName ) );
|
||||
|
||||
// this is achievement progress, compose the message of form: "<name> (<#>/<max>)"
|
||||
wchar_t szFmt[128]=L"";
|
||||
wchar_t szText[512]=L"";
|
||||
wchar_t szNumFound[16]=L"";
|
||||
wchar_t szNumTotal[16]=L"";
|
||||
_snwprintf( szNumFound, ARRAYSIZE( szNumFound ), L"%i", iCur );
|
||||
_snwprintf( szNumTotal, ARRAYSIZE( szNumTotal ), L"%i", iMax );
|
||||
|
||||
const wchar_t *pchFmt = g_pVGuiLocalize->Find( "#GameUI_Achievement_Progress_Fmt" );
|
||||
if ( !pchFmt || !pchFmt[0] )
|
||||
return;
|
||||
Q_wcsncpy( szFmt, pchFmt, sizeof( szFmt ) );
|
||||
|
||||
g_pVGuiLocalize->ConstructString( szText, sizeof( szText ), szFmt, 3, szLocalizedName, szNumFound, szNumTotal );
|
||||
AddNotification( pchName, g_pVGuiLocalize->FindSafe( "#GameUI_Achievement_Progress" ), szText );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called on each tick
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::OnTick( void )
|
||||
{
|
||||
if ( ( m_flHideTime > 0 ) && ( m_flHideTime < gpGlobals->curtime ) )
|
||||
{
|
||||
m_flHideTime = 0;
|
||||
ShowNextNotification();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAchievementNotificationPanel::ShouldDraw( void )
|
||||
{
|
||||
return ( ( m_flHideTime > 0 ) && ( m_flHideTime > gpGlobals->curtime ) && CHudElement::ShouldDraw() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::AddNotification( const char *szIconBaseName, const wchar_t *pHeading, const wchar_t *pTitle )
|
||||
{
|
||||
// put this notification in our queue
|
||||
int iQueueItem = m_queueNotification.AddToTail();
|
||||
Notification_t ¬ification = m_queueNotification[iQueueItem];
|
||||
Q_strncpy( notification.szIconBaseName, szIconBaseName, ARRAYSIZE( notification.szIconBaseName ) );
|
||||
Q_wcsncpy( notification.szHeading, pHeading, sizeof( notification.szHeading ) );
|
||||
Q_wcsncpy( notification.szTitle, pTitle, sizeof( notification.szTitle ) );
|
||||
|
||||
// if we are not currently displaying a notification, go ahead and show this one
|
||||
if ( 0 == m_flHideTime )
|
||||
{
|
||||
ShowNextNotification();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shows next notification in queue if there is one
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::ShowNextNotification()
|
||||
{
|
||||
// see if we have anything to do
|
||||
if ( 0 == m_queueNotification.Count() )
|
||||
{
|
||||
m_flHideTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
Notification_t ¬ification = m_queueNotification[ m_queueNotification.Head() ];
|
||||
|
||||
m_flHideTime = gpGlobals->curtime + ACHIEVEMENT_NOTIFICATION_DURATION;
|
||||
|
||||
// set the text and icon in the dialog
|
||||
SetDialogVariable( "heading", notification.szHeading );
|
||||
SetDialogVariable( "title", notification.szTitle );
|
||||
const char *pchIconBaseName = notification.szIconBaseName;
|
||||
if ( pchIconBaseName && pchIconBaseName[0] )
|
||||
{
|
||||
m_pIcon->SetImage( CFmtStr( "achievements/%s.vmt", pchIconBaseName ) );
|
||||
}
|
||||
|
||||
// resize the panel so it always looks good
|
||||
|
||||
// get fonts
|
||||
HFont hFontHeading = m_pLabelHeading->GetFont();
|
||||
HFont hFontTitle = m_pLabelTitle->GetFont();
|
||||
// determine how wide the text strings are
|
||||
int iHeadingWidth = UTIL_ComputeStringWidth( hFontHeading, notification.szHeading );
|
||||
int iTitleWidth = UTIL_ComputeStringWidth( hFontTitle, notification.szTitle );
|
||||
// use the widest string
|
||||
int iTextWidth = MAX( iHeadingWidth, iTitleWidth );
|
||||
// don't let it be insanely wide
|
||||
iTextWidth = MIN( iTextWidth, XRES( 300 ) );
|
||||
int iIconWidth = m_pIcon->GetWide();
|
||||
int iSpacing = XRES( 10 );
|
||||
int iPanelWidth = iSpacing + iIconWidth + iSpacing + iTextWidth + iSpacing;
|
||||
int iPanelX = GetWide() - iPanelWidth;
|
||||
int iIconX = iPanelX + iSpacing;
|
||||
int iTextX = iIconX + iIconWidth + iSpacing;
|
||||
// resize all the elements
|
||||
SetXAndWide( m_pPanelBackground, iPanelX, iPanelWidth );
|
||||
SetXAndWide( m_pIcon, iIconX, iIconWidth );
|
||||
SetXAndWide( m_pLabelHeading, iTextX, iTextWidth );
|
||||
SetXAndWide( m_pLabelTitle, iTextX, iTextWidth );
|
||||
|
||||
m_queueNotification.Remove( m_queueNotification.Head() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::SetXAndWide( Panel *pPanel, int x, int wide )
|
||||
{
|
||||
int xCur, yCur;
|
||||
pPanel->GetPos( xCur, yCur );
|
||||
pPanel->SetPos( x, yCur );
|
||||
pPanel->SetWide( wide );
|
||||
}
|
||||
|
||||
CON_COMMAND_F( achievement_notification_test, "Test the hud notification UI", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY )
|
||||
{
|
||||
static int iCount=0;
|
||||
|
||||
CAchievementNotificationPanel *pPanel = GET_HUDELEMENT( CAchievementNotificationPanel );
|
||||
if ( pPanel )
|
||||
{
|
||||
pPanel->AddNotification( "HL2_KILL_ODESSAGUNSHIP", L"Achievement Progress", ( 0 == ( iCount % 2 ) ? L"Test Notification Message A (1/10)" :
|
||||
L"Test Message B" ) );
|
||||
}
|
||||
|
||||
#if 0
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "achievement_event" );
|
||||
if ( event )
|
||||
{
|
||||
const char *szTestStr[] = { "TF_GET_HEADSHOTS", "TF_PLAY_GAME_EVERYMAP", "TF_PLAY_GAME_EVERYCLASS", "TF_GET_HEALPOINTS" };
|
||||
event->SetString( "achievement_name", szTestStr[iCount%ARRAYSIZE(szTestStr)] );
|
||||
event->SetInt( "cur_val", ( iCount%9 ) + 1 );
|
||||
event->SetInt( "max_val", 10 );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
#endif
|
||||
|
||||
iCount++;
|
||||
}
|
57
game/client/achievement_notification_panel.h
Normal file
57
game/client/achievement_notification_panel.h
Normal file
@ -0,0 +1,57 @@
|
||||
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef ACHIEVEMENT_NOTIFICATION_PANEL_H
|
||||
#define ACHIEVEMENT_NOTIFICATION_PANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/EditablePanel.h>
|
||||
#include "hudelement.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
class CAchievementNotificationPanel : public CHudElement, public EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CAchievementNotificationPanel, EditablePanel );
|
||||
|
||||
public:
|
||||
CAchievementNotificationPanel( const char *pElementName );
|
||||
|
||||
virtual void Init();
|
||||
virtual void ApplySchemeSettings( IScheme *scheme );
|
||||
virtual bool ShouldDraw( void );
|
||||
virtual void PerformLayout( void );
|
||||
virtual void LevelInit( void ) { m_flHideTime = 0; }
|
||||
virtual void FireGameEvent( IGameEvent * event );
|
||||
virtual void OnTick( void );
|
||||
|
||||
void AddNotification( const char *szIconBaseName, const wchar_t *pHeading, const wchar_t *pTitle );
|
||||
|
||||
private:
|
||||
void ShowNextNotification();
|
||||
void SetXAndWide( Panel *pPanel, int x, int wide );
|
||||
|
||||
float m_flHideTime;
|
||||
|
||||
Label *m_pLabelHeading;
|
||||
Label *m_pLabelTitle;
|
||||
EditablePanel *m_pPanelBackground;
|
||||
ImagePanel *m_pIcon;
|
||||
|
||||
struct Notification_t
|
||||
{
|
||||
char szIconBaseName[255];
|
||||
wchar_t szHeading[255];
|
||||
wchar_t szTitle[255];
|
||||
};
|
||||
|
||||
CUtlLinkedList<Notification_t> m_queueNotification;
|
||||
};
|
||||
|
||||
#endif // ACHIEVEMENT_NOTIFICATION_PANEL_H
|
52
game/client/animatedentitytextureproxy.cpp
Normal file
52
game/client/animatedentitytextureproxy.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "BaseAnimatedTextureProxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CAnimatedEntityTextureProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CAnimatedEntityTextureProxy() {}
|
||||
virtual ~CAnimatedEntityTextureProxy() {}
|
||||
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||
virtual void AnimationWrapped( void* pC_BaseEntity );
|
||||
|
||||
};
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CAnimatedEntityTextureProxy, AnimatedEntityTexture );
|
||||
|
||||
float CAnimatedEntityTextureProxy::GetAnimationStartTime( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return 0.0f;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
return pEntity->GetTextureAnimationStartTime();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void CAnimatedEntityTextureProxy::AnimationWrapped( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
pEntity->TextureAnimationWrapped();
|
||||
}
|
||||
}
|
57
game/client/animatedoffsettextureproxy.cpp
Normal file
57
game/client/animatedoffsettextureproxy.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "BaseAnimatedTextureProxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CAnimatedOffsetTextureProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CAnimatedOffsetTextureProxy() : m_flFrameOffset( 0.0f ) {}
|
||||
|
||||
virtual ~CAnimatedOffsetTextureProxy() {}
|
||||
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||
virtual void OnBind( void *pBaseEntity );
|
||||
|
||||
protected:
|
||||
|
||||
float m_flFrameOffset;
|
||||
};
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CAnimatedOffsetTextureProxy, AnimatedOffsetTexture );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pArg -
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float CAnimatedOffsetTextureProxy::GetAnimationStartTime( void* pArg )
|
||||
{
|
||||
return m_flFrameOffset;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pBaseEntity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAnimatedOffsetTextureProxy::OnBind( void *pBaseEntity )
|
||||
{
|
||||
C_BaseEntity* pEntity = (C_BaseEntity*)pBaseEntity;
|
||||
|
||||
if ( pEntity )
|
||||
{
|
||||
m_flFrameOffset = pEntity->GetTextureAnimationStartTime();
|
||||
}
|
||||
|
||||
// Call into the base class
|
||||
CBaseAnimatedTextureProxy::OnBind( pBaseEntity );
|
||||
}
|
||||
|
30
game/client/animatedtextureproxy.cpp
Normal file
30
game/client/animatedtextureproxy.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "BaseAnimatedTextureProxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CAnimatedTextureProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CAnimatedTextureProxy() {}
|
||||
virtual ~CAnimatedTextureProxy() {}
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||
};
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CAnimatedTextureProxy, AnimatedTexture );
|
||||
|
||||
#pragma warning (disable : 4100)
|
||||
|
||||
float CAnimatedTextureProxy::GetAnimationStartTime( void* pBaseEntity )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
326
game/client/animationlayer.h
Normal file
326
game/client/animationlayer.h
Normal file
@ -0,0 +1,326 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef ANIMATIONLAYER_H
|
||||
#define ANIMATIONLAYER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "rangecheckedvar.h"
|
||||
#include "tier1/lerp_functions.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
class C_BaseAnimatingOverlay;
|
||||
#endif
|
||||
|
||||
class C_AnimationLayer
|
||||
{
|
||||
public:
|
||||
|
||||
// This allows the datatables to access private members.
|
||||
ALLOW_DATATABLES_PRIVATE_ACCESS();
|
||||
|
||||
C_AnimationLayer();
|
||||
void Reset();
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
void SetOwner( C_BaseAnimatingOverlay *pOverlay );
|
||||
C_BaseAnimatingOverlay *GetOwner() const;
|
||||
#endif
|
||||
|
||||
void SetOrder( int order );
|
||||
bool IsActive( void );
|
||||
float GetFadeout( float flCurTime );
|
||||
|
||||
void SetSequence( int nSequence );
|
||||
void SetCycle( float flCycle );
|
||||
void SetPrevCycle( float flCycle );
|
||||
void SetPlaybackRate( float flPlaybackRate );
|
||||
void SetWeight( float flWeight );
|
||||
|
||||
int GetOrder() const;
|
||||
int GetSequence( ) const;
|
||||
float GetCycle( ) const;
|
||||
float GetPrevCycle( ) const;
|
||||
float GetPlaybackRate( ) const;
|
||||
float GetWeight( ) const;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
// If the weights, cycle or sequence #s changed due to interpolation then
|
||||
// we'll need to recompute the bbox
|
||||
int GetInvalidatePhysicsBits() const;
|
||||
void SetInvalidatePhysicsBits( int iBit ) { m_nInvalidatePhysicsBits = iBit; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
float m_flLayerAnimtime;
|
||||
float m_flLayerFadeOuttime;
|
||||
|
||||
private:
|
||||
int m_nOrder;
|
||||
CRangeCheckedVar<int, -1, 65535, 0> m_nSequence;
|
||||
CRangeCheckedVar<float, -2, 2, 0> m_flPrevCycle;
|
||||
CRangeCheckedVar<float, -5, 5, 0> m_flWeight;
|
||||
|
||||
// used for automatic crossfades between sequence changes
|
||||
CRangeCheckedVar<float, -50, 50, 1> m_flPlaybackRate;
|
||||
CRangeCheckedVar<float, -2, 2, 0> m_flCycle;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
C_BaseAnimatingOverlay *m_pOwner;
|
||||
int m_nInvalidatePhysicsBits;
|
||||
#endif
|
||||
|
||||
friend class C_BaseAnimatingOverlay;
|
||||
friend C_AnimationLayer LoopingLerp( float flPercent, C_AnimationLayer& from, C_AnimationLayer& to );
|
||||
friend C_AnimationLayer Lerp( float flPercent, const C_AnimationLayer& from, const C_AnimationLayer& to );
|
||||
friend C_AnimationLayer LoopingLerp_Hermite( const C_AnimationLayer& current, float flPercent, C_AnimationLayer& prev, C_AnimationLayer& from, C_AnimationLayer& to );
|
||||
friend C_AnimationLayer Lerp_Hermite( const C_AnimationLayer& current, float flPercent, const C_AnimationLayer& prev, const C_AnimationLayer& from, const C_AnimationLayer& to );
|
||||
friend void Lerp_Clamp( C_AnimationLayer &val );
|
||||
friend int CheckForSequenceBoxChanges( const C_AnimationLayer& newLayer, const C_AnimationLayer& oldLayer );
|
||||
};
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CAnimationLayer C_AnimationLayer
|
||||
#endif
|
||||
|
||||
|
||||
inline C_AnimationLayer::C_AnimationLayer()
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
m_pOwner = NULL;
|
||||
m_nInvalidatePhysicsBits = 0;
|
||||
#endif
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
|
||||
inline void C_AnimationLayer::SetSequence( int nSequence )
|
||||
{
|
||||
m_nSequence = nSequence;
|
||||
}
|
||||
|
||||
inline void C_AnimationLayer::SetCycle( float flCycle )
|
||||
{
|
||||
m_flCycle = flCycle;
|
||||
}
|
||||
|
||||
inline void C_AnimationLayer::SetWeight( float flWeight )
|
||||
{
|
||||
m_flWeight = flWeight;
|
||||
}
|
||||
|
||||
#endif // GAME_DLL
|
||||
|
||||
FORCEINLINE void C_AnimationLayer::SetPrevCycle( float flPrevCycle )
|
||||
{
|
||||
m_flPrevCycle = flPrevCycle;
|
||||
}
|
||||
|
||||
FORCEINLINE void C_AnimationLayer::SetPlaybackRate( float flPlaybackRate )
|
||||
{
|
||||
m_flPlaybackRate = flPlaybackRate;
|
||||
}
|
||||
|
||||
FORCEINLINE int C_AnimationLayer::GetSequence( ) const
|
||||
{
|
||||
return m_nSequence;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetCycle( ) const
|
||||
{
|
||||
return m_flCycle;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetPrevCycle( ) const
|
||||
{
|
||||
return m_flPrevCycle;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetPlaybackRate( ) const
|
||||
{
|
||||
return m_flPlaybackRate;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetWeight( ) const
|
||||
{
|
||||
return m_flWeight;
|
||||
}
|
||||
|
||||
FORCEINLINE int C_AnimationLayer::GetOrder() const
|
||||
{
|
||||
return m_nOrder;
|
||||
}
|
||||
|
||||
inline float C_AnimationLayer::GetFadeout( float flCurTime )
|
||||
{
|
||||
float s;
|
||||
|
||||
if (m_flLayerFadeOuttime <= 0.0f)
|
||||
{
|
||||
s = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// blend in over 0.2 seconds
|
||||
s = 1.0 - (flCurTime - m_flLayerAnimtime) / m_flLayerFadeOuttime;
|
||||
if (s > 0 && s <= 1.0)
|
||||
{
|
||||
// do a nice spline curve
|
||||
s = 3 * s * s - 2 * s * s * s;
|
||||
}
|
||||
else if ( s > 1.0f )
|
||||
{
|
||||
// Shouldn't happen, but maybe curtime is behind animtime?
|
||||
s = 1.0f;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
FORCEINLINE int C_AnimationLayer::GetInvalidatePhysicsBits() const
|
||||
{
|
||||
return m_nInvalidatePhysicsBits;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline C_AnimationLayer LoopingLerp( float flPercent, C_AnimationLayer& from, C_AnimationLayer& to )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
Assert( from.GetOwner() == to.GetOwner() );
|
||||
#endif
|
||||
|
||||
C_AnimationLayer output;
|
||||
|
||||
output.m_nSequence = to.m_nSequence;
|
||||
output.m_flCycle = LoopingLerp( flPercent, (float)from.m_flCycle, (float)to.m_flCycle );
|
||||
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||
output.m_nOrder = to.m_nOrder;
|
||||
|
||||
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||
#ifdef CLIENT_DLL
|
||||
output.SetOwner( to.GetOwner() );
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
inline C_AnimationLayer Lerp( float flPercent, const C_AnimationLayer& from, const C_AnimationLayer& to )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
Assert( from.GetOwner() == to.GetOwner() );
|
||||
#endif
|
||||
|
||||
C_AnimationLayer output;
|
||||
|
||||
output.m_nSequence = to.m_nSequence;
|
||||
output.m_flCycle = Lerp( flPercent, from.m_flCycle, to.m_flCycle );
|
||||
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||
output.m_nOrder = to.m_nOrder;
|
||||
|
||||
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||
#ifdef CLIENT_DLL
|
||||
output.SetOwner( to.GetOwner() );
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
inline int CheckForSequenceBoxChanges( const C_AnimationLayer& newLayer, const C_AnimationLayer& oldLayer )
|
||||
{
|
||||
int nChangeFlags = 0;
|
||||
|
||||
bool bOldIsZero = ( oldLayer.GetWeight() == 0.0f );
|
||||
bool bNewIsZero = ( newLayer.GetWeight() == 0.0f );
|
||||
|
||||
if ( ( newLayer.GetSequence() != oldLayer.GetSequence() ) ||
|
||||
( bNewIsZero != bOldIsZero ) )
|
||||
{
|
||||
nChangeFlags |= SEQUENCE_CHANGED | BOUNDS_CHANGED;
|
||||
}
|
||||
|
||||
if ( newLayer.GetCycle() != oldLayer.GetCycle() )
|
||||
{
|
||||
nChangeFlags |= ANIMATION_CHANGED;
|
||||
}
|
||||
|
||||
if ( newLayer.GetOrder() != oldLayer.GetOrder() )
|
||||
{
|
||||
nChangeFlags |= BOUNDS_CHANGED;
|
||||
}
|
||||
|
||||
return nChangeFlags;
|
||||
}
|
||||
|
||||
inline C_AnimationLayer LoopingLerp_Hermite( const C_AnimationLayer& current, float flPercent, C_AnimationLayer& prev, C_AnimationLayer& from, C_AnimationLayer& to )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
Assert( prev.GetOwner() == from.GetOwner() );
|
||||
Assert( from.GetOwner() == to.GetOwner() );
|
||||
#endif
|
||||
|
||||
C_AnimationLayer output;
|
||||
|
||||
output.m_nSequence = to.m_nSequence;
|
||||
output.m_flCycle = LoopingLerp_Hermite( (float)current.m_flCycle, flPercent, (float)prev.m_flCycle, (float)from.m_flCycle, (float)to.m_flCycle );
|
||||
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||
output.m_nOrder = to.m_nOrder;
|
||||
|
||||
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
output.SetOwner( to.GetOwner() );
|
||||
output.m_nInvalidatePhysicsBits = CheckForSequenceBoxChanges( output, current );
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
// YWB: Specialization for interpolating euler angles via quaternions...
|
||||
inline C_AnimationLayer Lerp_Hermite( const C_AnimationLayer& current, float flPercent, const C_AnimationLayer& prev, const C_AnimationLayer& from, const C_AnimationLayer& to )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
Assert( prev.GetOwner() == from.GetOwner() );
|
||||
Assert( from.GetOwner() == to.GetOwner() );
|
||||
#endif
|
||||
|
||||
C_AnimationLayer output;
|
||||
|
||||
output.m_nSequence = to.m_nSequence;
|
||||
output.m_flCycle = Lerp_Hermite( (float)current.m_flCycle, flPercent, (float)prev.m_flCycle, (float)from.m_flCycle, (float)to.m_flCycle );
|
||||
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||
output.m_nOrder = to.m_nOrder;
|
||||
|
||||
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||
#ifdef CLIENT_DLL
|
||||
output.SetOwner( to.GetOwner() );
|
||||
output.m_nInvalidatePhysicsBits = CheckForSequenceBoxChanges( output, current );
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
inline void Lerp_Clamp( C_AnimationLayer &val )
|
||||
{
|
||||
Lerp_Clamp( val.m_nSequence );
|
||||
Lerp_Clamp( val.m_flCycle );
|
||||
Lerp_Clamp( val.m_flPrevCycle );
|
||||
Lerp_Clamp( val.m_flWeight );
|
||||
Lerp_Clamp( val.m_nOrder );
|
||||
Lerp_Clamp( val.m_flLayerAnimtime );
|
||||
Lerp_Clamp( val.m_flLayerFadeOuttime );
|
||||
}
|
||||
|
||||
#endif // ANIMATIONLAYER_H
|
129
game/client/baseanimatedtextureproxy.cpp
Normal file
129
game/client/baseanimatedtextureproxy.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "BaseAnimatedTextureProxy.h"
|
||||
#include "materialsystem/IMaterial.h"
|
||||
#include "materialsystem/IMaterialVar.h"
|
||||
#include "materialsystem/ITexture.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CBaseAnimatedTextureProxy::CBaseAnimatedTextureProxy()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
CBaseAnimatedTextureProxy::~CBaseAnimatedTextureProxy()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseAnimatedTextureProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
char const* pAnimatedTextureVarName = pKeyValues->GetString( "animatedTextureVar" );
|
||||
if( !pAnimatedTextureVarName )
|
||||
return false;
|
||||
|
||||
bool foundVar;
|
||||
m_AnimatedTextureVar = pMaterial->FindVar( pAnimatedTextureVarName, &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
char const* pAnimatedTextureFrameNumVarName = pKeyValues->GetString( "animatedTextureFrameNumVar" );
|
||||
if( !pAnimatedTextureFrameNumVarName )
|
||||
return false;
|
||||
|
||||
m_AnimatedTextureFrameNumVar = pMaterial->FindVar( pAnimatedTextureFrameNumVarName, &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
m_FrameRate = pKeyValues->GetFloat( "animatedTextureFrameRate", 15 );
|
||||
m_WrapAnimation = !pKeyValues->GetInt( "animationNoWrap", 0 );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBaseAnimatedTextureProxy::Cleanup()
|
||||
{
|
||||
m_AnimatedTextureVar = NULL;
|
||||
m_AnimatedTextureFrameNumVar = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the dirty deed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAnimatedTextureProxy::OnBind( void *pEntity )
|
||||
{
|
||||
Assert ( m_AnimatedTextureVar );
|
||||
|
||||
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
ITexture *pTexture;
|
||||
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||
int numFrames = pTexture->GetNumAnimationFrames();
|
||||
|
||||
if ( numFrames <= 0 )
|
||||
{
|
||||
Assert( !"0 frames in material calling animated texture proxy" );
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Must not use relative time based methods here
|
||||
// because the bind proxy can be called many times per frame.
|
||||
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||
float startTime = GetAnimationStartTime(pEntity);
|
||||
float deltaTime = gpGlobals->curtime - startTime;
|
||||
float prevTime = deltaTime - gpGlobals->frametime;
|
||||
|
||||
// Clamp..
|
||||
if (deltaTime < 0.0f)
|
||||
deltaTime = 0.0f;
|
||||
if (prevTime < 0.0f)
|
||||
prevTime = 0.0f;
|
||||
|
||||
float frame = m_FrameRate * deltaTime;
|
||||
float prevFrame = m_FrameRate * prevTime;
|
||||
|
||||
int intFrame = ((int)frame) % numFrames;
|
||||
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||
|
||||
// Report wrap situation...
|
||||
if (intPrevFrame > intFrame)
|
||||
{
|
||||
if (m_WrapAnimation)
|
||||
{
|
||||
AnimationWrapped( pEntity );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only sent the wrapped message once.
|
||||
// when we're in non-wrapping mode
|
||||
if (prevFrame < numFrames)
|
||||
AnimationWrapped( pEntity );
|
||||
intFrame = numFrames - 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||
}
|
||||
|
||||
IMaterial *CBaseAnimatedTextureProxy::GetMaterial()
|
||||
{
|
||||
return m_AnimatedTextureVar->GetOwningMaterial();
|
||||
}
|
47
game/client/baseanimatedtextureproxy.h
Normal file
47
game/client/baseanimatedtextureproxy.h
Normal file
@ -0,0 +1,47 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BASEANIMATEDTEXTUREPROXY
|
||||
#define BASEANIMATEDTEXTUREPROXY
|
||||
|
||||
#include "materialsystem/IMaterialProxy.h"
|
||||
|
||||
class IMaterial;
|
||||
class IMaterialVar;
|
||||
|
||||
#pragma warning (disable : 4100)
|
||||
|
||||
class CBaseAnimatedTextureProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CBaseAnimatedTextureProxy();
|
||||
virtual ~CBaseAnimatedTextureProxy();
|
||||
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
protected:
|
||||
// derived classes must implement this; it returns the time
|
||||
// that the animation began
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity ) = 0;
|
||||
|
||||
// Derived classes may implement this if they choose;
|
||||
// this method is called whenever the animation wraps...
|
||||
virtual void AnimationWrapped( void* pBaseEntity ) {}
|
||||
|
||||
protected:
|
||||
void Cleanup();
|
||||
|
||||
IMaterialVar *m_AnimatedTextureVar;
|
||||
IMaterialVar *m_AnimatedTextureFrameNumVar;
|
||||
float m_FrameRate;
|
||||
bool m_WrapAnimation;
|
||||
};
|
||||
|
||||
#endif // BASEANIMATEDTEXTUREPROXY
|
125
game/client/baseclientrendertargets.cpp
Normal file
125
game/client/baseclientrendertargets.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation for CBaseClientRenderTargets class.
|
||||
// Provides Init functions for common render textures used by the engine.
|
||||
// Mod makers can inherit from this class, and call the Create functions for
|
||||
// only the render textures the want for their mod.
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "baseclientrendertargets.h" // header
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h" // Hardware config checks
|
||||
#include "materialsystem/itexture.h" // Hardware config checks
|
||||
#include "tier0/icommandline.h"
|
||||
#ifdef GAMEUI_UISYSTEM2_ENABLED
|
||||
#include "gameui.h"
|
||||
#endif
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar cl_disable_water_render_targets( "cl_disable_water_render_targets", "0" );
|
||||
|
||||
ITexture* CBaseClientRenderTargets::CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem, int iSize )
|
||||
{
|
||||
iSize = CommandLine()->ParmValue( "-reflectionTextureSize", iSize );
|
||||
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||
"_rt_WaterReflection",
|
||||
iSize, iSize, RT_SIZE_PICMIP,
|
||||
pMaterialSystem->GetBackBufferFormat(),
|
||||
MATERIAL_RT_DEPTH_SHARED,
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
|
||||
CREATERENDERTARGETFLAGS_HDR );
|
||||
}
|
||||
|
||||
ITexture* CBaseClientRenderTargets::CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem, int iSize )
|
||||
{
|
||||
iSize = CommandLine()->ParmValue( "-reflectionTextureSize", iSize );
|
||||
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||
"_rt_WaterRefraction",
|
||||
iSize, iSize, RT_SIZE_PICMIP,
|
||||
// This is different than reflection because it has to have alpha for fog factor.
|
||||
IMAGE_FORMAT_RGBA8888,
|
||||
MATERIAL_RT_DEPTH_SHARED,
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
|
||||
CREATERENDERTARGETFLAGS_HDR );
|
||||
}
|
||||
|
||||
ITexture* CBaseClientRenderTargets::CreateCameraTexture( IMaterialSystem* pMaterialSystem, int iSize )
|
||||
{
|
||||
iSize = CommandLine()->ParmValue( "-monitorTextureSize", iSize );
|
||||
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||
"_rt_Camera",
|
||||
iSize, iSize, RT_SIZE_DEFAULT,
|
||||
pMaterialSystem->GetBackBufferFormat(),
|
||||
MATERIAL_RT_DEPTH_SHARED,
|
||||
0,
|
||||
CREATERENDERTARGETFLAGS_HDR );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called by the engine in material system init and shutdown.
|
||||
// Clients should override this in their inherited version, but the base
|
||||
// is to init all standard render targets for use.
|
||||
// Input : pMaterialSystem - the engine's material system (our singleton is not yet inited at the time this is called)
|
||||
// pHardwareConfig - the user hardware config, useful for conditional render target setup
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseClientRenderTargets::SetupClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig, int iWaterTextureSize, int iCameraTextureSize )
|
||||
{
|
||||
IMaterialSystem *pSave = materials;
|
||||
|
||||
// Make sure our config is loaded before we try to init rendertargets
|
||||
ConfigureCurrentSystemLevel();
|
||||
|
||||
// Water effects
|
||||
materials = pMaterialSystem; // in case not initted yet for mat system util
|
||||
g_pMaterialSystem = pMaterialSystem;
|
||||
g_pMaterialSystemHardwareConfig = pHardwareConfig;
|
||||
if ( iWaterTextureSize && !cl_disable_water_render_targets.GetBool() )
|
||||
{
|
||||
m_WaterReflectionTexture.Init( CreateWaterReflectionTexture( pMaterialSystem, iWaterTextureSize ) );
|
||||
m_WaterRefractionTexture.Init( CreateWaterRefractionTexture( pMaterialSystem, iWaterTextureSize ) );
|
||||
}
|
||||
|
||||
// Monitors
|
||||
if ( iCameraTextureSize )
|
||||
m_CameraTexture.Init( CreateCameraTexture( pMaterialSystem, iCameraTextureSize ) );
|
||||
|
||||
ITexture *pGlintTexture = pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||
"_rt_eyeglint", 32, 32, RT_SIZE_NO_CHANGE, IMAGE_FORMAT_BGRA8888, MATERIAL_RT_DEPTH_NONE );
|
||||
pGlintTexture->IncrementReferenceCount();
|
||||
g_pClientShadowMgr->InitRenderTargets();
|
||||
#ifdef GAMEUI_UISYSTEM2_ENABLED
|
||||
g_pGameUIGameSystem->InitRenderTargets();
|
||||
#endif
|
||||
|
||||
materials = pSave;
|
||||
}
|
||||
|
||||
void CBaseClientRenderTargets::InitClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig )
|
||||
{
|
||||
SetupClientRenderTargets( pMaterialSystem, pHardwareConfig );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shut down each CTextureReference we created in InitClientRenderTargets.
|
||||
// Called by the engine in material system shutdown.
|
||||
// Input : -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseClientRenderTargets::ShutdownClientRenderTargets()
|
||||
{
|
||||
// Water effects
|
||||
m_WaterReflectionTexture.Shutdown();
|
||||
m_WaterRefractionTexture.Shutdown();
|
||||
|
||||
// Monitors
|
||||
m_CameraTexture.Shutdown();
|
||||
|
||||
g_pClientShadowMgr->ShutdownRenderTargets();
|
||||
|
||||
}
|
||||
|
||||
static CBaseClientRenderTargets g_BaseClientRenderTargets;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CBaseClientRenderTargets, IClientRenderTargets,
|
||||
CLIENTRENDERTARGETS_INTERFACE_VERSION, g_BaseClientRenderTargets );
|
62
game/client/baseclientrendertargets.h
Normal file
62
game/client/baseclientrendertargets.h
Normal file
@ -0,0 +1,62 @@
|
||||
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Has init functions for all the standard render targets used by most games.
|
||||
// Mods who wish to make their own render targets can inherit from this class
|
||||
// and in the 'InitClientRenderTargets' interface called by the engine, set up
|
||||
// their own render targets as well as calling the init functions for various
|
||||
// common render targets provided by this class.
|
||||
//
|
||||
// Note: Unless the client defines a singleton interface by inheriting from
|
||||
// this class and exposing the singleton instance, these init and shutdown
|
||||
// functions WILL NOT be called by the engine.
|
||||
//
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#ifndef CLIENTRENDERTARTETS_H_
|
||||
#define CLIENTRENDERTARTETS_H_
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "game/client/iclientrendertargets.h" // base class with interfaces called by the engine
|
||||
#include "materialsystem/imaterialsystem.h" // for material system classes and interfaces
|
||||
|
||||
|
||||
// Externs
|
||||
class IMaterialSystem;
|
||||
class IMaterialSystemHardwareConfig;
|
||||
|
||||
class CBaseClientRenderTargets : public IClientRenderTargets
|
||||
{
|
||||
// no networked vars
|
||||
DECLARE_CLASS_GAMEROOT( CBaseClientRenderTargets, IClientRenderTargets );
|
||||
public:
|
||||
// Interface called by engine during material system startup.
|
||||
virtual void InitClientRenderTargets ( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig );
|
||||
// Shutdown all custom render targets here.
|
||||
virtual void ShutdownClientRenderTargets ( void );
|
||||
|
||||
protected:
|
||||
void SetupClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig, int iWaterTextureSize = 1024, int iCameraTextureSize = 256 );
|
||||
|
||||
// Standard render textures used by most mods-- Classes inheriting from
|
||||
// this can choose to init these or not depending on their needs.
|
||||
|
||||
// For reflective and refracting water
|
||||
CTextureReference m_WaterReflectionTexture;
|
||||
CTextureReference m_WaterRefractionTexture;
|
||||
|
||||
// Used for monitors
|
||||
CTextureReference m_CameraTexture;
|
||||
|
||||
// Init functions for the common render targets
|
||||
ITexture* CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem, int iSize = 1024 );
|
||||
ITexture* CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem, int iSize = 1024 );
|
||||
ITexture* CreateCameraTexture( IMaterialSystem* pMaterialSystem, int iSize = 256 );
|
||||
|
||||
};
|
||||
|
||||
#endif // CLIENTRENDERTARTETS_H_
|
1527
game/client/beamdraw.cpp
Normal file
1527
game/client/beamdraw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
167
game/client/beamdraw.h
Normal file
167
game/client/beamdraw.h
Normal file
@ -0,0 +1,167 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#if !defined( BEAMDRAW_H )
|
||||
#define BEAMDRAW_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "tier2/beamsegdraw.h"
|
||||
#include "c_pixel_visibility.h"
|
||||
|
||||
#define NOISE_DIVISIONS 128
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct model_t;
|
||||
struct BeamTrail_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Beams fill out this data structure
|
||||
// This is also used for rendering
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class Beam_t : public CDefaultClientRenderable
|
||||
{
|
||||
public:
|
||||
Beam_t();
|
||||
|
||||
// Methods of IClientRenderable
|
||||
virtual const Vector& GetRenderOrigin( void );
|
||||
virtual const QAngle& GetRenderAngles( void );
|
||||
virtual const matrix3x4_t &RenderableToWorldTransform();
|
||||
virtual void GetRenderBounds( Vector& mins, Vector& maxs );
|
||||
virtual bool ShouldDraw( void );
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
|
||||
// Resets the beam state
|
||||
void Reset();
|
||||
|
||||
// Method to computing the bounding box
|
||||
void ComputeBounds();
|
||||
|
||||
// Bounding box...
|
||||
Vector m_Mins;
|
||||
Vector m_Maxs;
|
||||
pixelvis_handle_t *m_queryHandleHalo;
|
||||
float m_haloProxySize;
|
||||
|
||||
// Data is below..
|
||||
|
||||
// Next beam in list
|
||||
Beam_t* next;
|
||||
|
||||
// Type of beam
|
||||
int type;
|
||||
int flags;
|
||||
|
||||
// Control points for the beam
|
||||
int numAttachments;
|
||||
Vector attachment[MAX_BEAM_ENTS];
|
||||
Vector delta;
|
||||
|
||||
// 0 .. 1 over lifetime of beam
|
||||
float t;
|
||||
float freq;
|
||||
|
||||
// Time when beam should die
|
||||
float die;
|
||||
float width;
|
||||
float endWidth;
|
||||
float fadeLength;
|
||||
float amplitude;
|
||||
float life;
|
||||
|
||||
// Color
|
||||
float r, g, b;
|
||||
float brightness;
|
||||
|
||||
// Speed
|
||||
float speed;
|
||||
|
||||
// Animation
|
||||
float frameRate;
|
||||
float frame;
|
||||
int segments;
|
||||
|
||||
// Attachment entities for the beam
|
||||
EHANDLE entity[MAX_BEAM_ENTS];
|
||||
int attachmentIndex[MAX_BEAM_ENTS];
|
||||
|
||||
// Model info
|
||||
int modelIndex;
|
||||
int haloIndex;
|
||||
|
||||
float haloScale;
|
||||
int frameCount;
|
||||
|
||||
float rgNoise[NOISE_DIVISIONS+1];
|
||||
|
||||
// Popcorn trail for beam follows to use
|
||||
BeamTrail_t* trail;
|
||||
|
||||
// for TE_BEAMRINGPOINT
|
||||
float start_radius;
|
||||
float end_radius;
|
||||
|
||||
// for FBEAM_ONLYNOISEONCE
|
||||
bool m_bCalculatedNoise;
|
||||
|
||||
float m_flHDRColorScale;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
int ScreenTransform( const Vector& point, Vector& screen );
|
||||
|
||||
void DrawSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||
void DrawTeslaSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||
void DrawSplineSegs( int noise_divisions, float *prgNoise,
|
||||
const model_t* beammodel, const model_t* halomodel, float flHaloScale,
|
||||
float frame, int rendermode, int numAttachments, Vector* attachment,
|
||||
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||
void DrawHalo(IMaterial* pMaterial, const Vector& source, float scale, float const* color, float flHDRColorScale = 1.0f );
|
||||
void BeamDrawHalo( const model_t* spritemodel, float frame, int rendermode, const Vector& source,
|
||||
float scale, float* color, float flHDRColorScale = 1.0f );
|
||||
void DrawDisk( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||
float width, float scale, float freq, float speed,
|
||||
int segments, float* color, float flHDRColorScale = 1.0f );
|
||||
void DrawCylinder( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||
float frame, int rendermode, const Vector& source,
|
||||
const Vector& delta, float width, float scale, float freq,
|
||||
float speed, int segments, float* color, float flHDRColorScale = 1.0f );
|
||||
void DrawRing( int noise_divisions, float *prgNoise, void (*pfnNoise)( float *noise, int divs, float scale ),
|
||||
const model_t* spritemodel, float frame, int rendermode,
|
||||
const Vector& source, const Vector& delta, float width, float amplitude,
|
||||
float freq, float speed, int segments, float* color, float flHDRColorScale = 1.0f );
|
||||
void DrawBeamFollow( const model_t* spritemodel, BeamTrail_t* pHead, int frame, int rendermode, Vector& delta,
|
||||
Vector& screen, Vector& screenLast, float die, const Vector& source,
|
||||
int flags, float width, float amplitude, float freq, float* color, float flHDRColorScale = 1.0f );
|
||||
|
||||
void DrawBeamQuadratic( const Vector &start, const Vector &control, const Vector &end, float width, const Vector &color, float scrollOffset, float flHDRColorScale = 1.0f );
|
||||
class CEngineSprite *Draw_SetSpriteTexture( const model_t *pSpriteModel, int frame, int rendermode );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Assumes the material has already been bound
|
||||
//-----------------------------------------------------------------------------
|
||||
void DrawSprite( const Vector &vecOrigin, float flWidth, float flHeight, color32 color );
|
||||
|
||||
#endif // BEAMDRAW_H
|
193
game/client/bone_merge_cache.cpp
Normal file
193
game/client/bone_merge_cache.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "bone_merge_cache.h"
|
||||
#include "bone_setup.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CBoneMergeCache
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CBoneMergeCache::CBoneMergeCache()
|
||||
{
|
||||
m_pOwner = NULL;
|
||||
m_pFollow = NULL;
|
||||
m_pFollowHdr = NULL;
|
||||
m_pOwnerHdr = NULL;
|
||||
m_nFollowBoneSetupMask = 0;
|
||||
}
|
||||
|
||||
void CBoneMergeCache::Init( C_BaseAnimating *pOwner )
|
||||
{
|
||||
m_pOwner = pOwner;
|
||||
m_pFollow = NULL;
|
||||
m_pFollowHdr = NULL;
|
||||
m_pOwnerHdr = NULL;
|
||||
m_nFollowBoneSetupMask = 0;
|
||||
}
|
||||
|
||||
void CBoneMergeCache::UpdateCache()
|
||||
{
|
||||
if ( !m_pOwner )
|
||||
return;
|
||||
|
||||
CStudioHdr *pOwnerHdr = m_pOwner->GetModelPtr();
|
||||
if ( !pOwnerHdr )
|
||||
return;
|
||||
|
||||
C_BaseAnimating *pTestFollow = m_pOwner->FindFollowedEntity();
|
||||
CStudioHdr *pTestHdr = (pTestFollow ? pTestFollow->GetModelPtr() : NULL);
|
||||
// if the follow parent has changed, or any of the underlying models has changed, reset the MergedBones list
|
||||
if ( pTestFollow != m_pFollow || pTestHdr != m_pFollowHdr || pOwnerHdr != m_pOwnerHdr )
|
||||
{
|
||||
m_MergedBones.Purge();
|
||||
|
||||
// Update the cache.
|
||||
if ( pTestFollow && pTestHdr && pOwnerHdr )
|
||||
{
|
||||
m_pFollow = pTestFollow;
|
||||
m_pFollowHdr = pTestHdr;
|
||||
m_pOwnerHdr = pOwnerHdr;
|
||||
|
||||
m_BoneMergeBits.Resize( pOwnerHdr->numbones() );
|
||||
m_BoneMergeBits.ClearAll();
|
||||
|
||||
mstudiobone_t *pOwnerBones = m_pOwnerHdr->pBone( 0 );
|
||||
|
||||
m_nFollowBoneSetupMask = BONE_USED_BY_BONE_MERGE;
|
||||
const bool bDeveloperDebugPrints = developer.GetBool();
|
||||
for ( int i = 0; i < m_pOwnerHdr->numbones(); i++ )
|
||||
{
|
||||
int parentBoneIndex = Studio_BoneIndexByName( m_pFollowHdr, pOwnerBones[i].pszName() );
|
||||
if ( parentBoneIndex < 0 )
|
||||
continue;
|
||||
|
||||
// Add a merged bone here.
|
||||
CMergedBone mergedBone;
|
||||
mergedBone.m_iMyBone = i;
|
||||
mergedBone.m_iParentBone = parentBoneIndex;
|
||||
m_MergedBones.AddToTail( mergedBone );
|
||||
m_BoneMergeBits.Set( i );
|
||||
|
||||
// Warn for performance-negative ad hoc bone merges. They're bad. Don't do them.
|
||||
if ( ( m_pFollowHdr->boneFlags( parentBoneIndex ) & BONE_USED_BY_BONE_MERGE ) == 0 )
|
||||
{
|
||||
// go ahead and mark the bone and its parents
|
||||
int n = parentBoneIndex;
|
||||
while (n != -1)
|
||||
{
|
||||
m_pFollowHdr->setBoneFlags( n, BONE_USED_BY_BONE_MERGE );
|
||||
n = m_pFollowHdr->boneParent( n );
|
||||
}
|
||||
// dump out a warning
|
||||
if ( bDeveloperDebugPrints )
|
||||
{
|
||||
char sz[ 256 ];
|
||||
Q_snprintf( sz, sizeof( sz ), "Performance warning: Add $bonemerge \"%s\" to QC that builds \"%s\"\n",
|
||||
m_pFollowHdr->pBone( parentBoneIndex )->pszName(), m_pFollowHdr->pszName() );
|
||||
|
||||
static CUtlSymbolTableMT s_FollowerWarnings;
|
||||
if ( UTL_INVAL_SYMBOL == s_FollowerWarnings.Find( sz ) )
|
||||
{
|
||||
s_FollowerWarnings.AddString( sz );
|
||||
Warning( "%s", sz );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No merged bones found? Slam the mask to 0
|
||||
if ( !m_MergedBones.Count() )
|
||||
{
|
||||
m_nFollowBoneSetupMask = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFollow = NULL;
|
||||
m_pFollowHdr = NULL;
|
||||
m_pOwnerHdr = NULL;
|
||||
m_nFollowBoneSetupMask = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBoneMergeCache::MergeMatchingBones( int boneMask, CBoneBitList &boneComputed )
|
||||
{
|
||||
UpdateCache();
|
||||
|
||||
// If this is set, then all the other cache data is set.
|
||||
if ( !m_pOwnerHdr || m_MergedBones.Count() == 0 )
|
||||
return;
|
||||
|
||||
// Have the entity we're following setup its bones.
|
||||
m_pFollow->SetupBones( NULL, -1, m_nFollowBoneSetupMask, gpGlobals->curtime );
|
||||
|
||||
// Now copy the bone matrices.
|
||||
for ( int i=0; i < m_MergedBones.Count(); i++ )
|
||||
{
|
||||
int iOwnerBone = m_MergedBones[i].m_iMyBone;
|
||||
int iParentBone = m_MergedBones[i].m_iParentBone;
|
||||
|
||||
// Only update bones reference by the bone mask.
|
||||
if ( !( m_pOwnerHdr->boneFlags( iOwnerBone ) & boneMask ) )
|
||||
continue;
|
||||
|
||||
// INFESTED_DLL temp comment
|
||||
//MatrixCopy( m_pFollow->GetBone( iParentBone ), m_pOwner->GetBoneForWrite( iOwnerBone ) );
|
||||
|
||||
// INFESTED_DLL hack
|
||||
matrix3x4_t matPitchUp;
|
||||
AngleMatrix( QAngle( 15, 0, 0 ), matPitchUp );
|
||||
ConcatTransforms( m_pFollow->GetBone( iParentBone ), matPitchUp, m_pOwner->GetBoneForWrite( iOwnerBone ) );
|
||||
|
||||
|
||||
boneComputed.Set( i );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CBoneMergeCache::GetAimEntOrigin( Vector *pAbsOrigin, QAngle *pAbsAngles )
|
||||
{
|
||||
UpdateCache();
|
||||
|
||||
// If this is set, then all the other cache data is set.
|
||||
if ( !m_pOwnerHdr || m_MergedBones.Count() == 0 )
|
||||
return false;
|
||||
|
||||
// We want the abs origin such that if we put the entity there, the first merged bone
|
||||
// will be aligned. This way the entity will be culled in the correct position.
|
||||
//
|
||||
// ie: mEntity * mBoneLocal = mFollowBone
|
||||
// so: mEntity = mFollowBone * Inverse( mBoneLocal )
|
||||
//
|
||||
// Note: the code below doesn't take animation into account. If the attached entity animates
|
||||
// all over the place, then this won't get the right results.
|
||||
|
||||
// Get mFollowBone.
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 );
|
||||
m_pFollow->SetupBones( NULL, -1, m_nFollowBoneSetupMask, gpGlobals->curtime );
|
||||
const matrix3x4_t &mFollowBone = m_pFollow->GetBone( m_MergedBones[0].m_iParentBone );
|
||||
|
||||
// Get Inverse( mBoneLocal )
|
||||
matrix3x4_t mBoneLocal, mBoneLocalInv;
|
||||
SetupSingleBoneMatrix( m_pOwnerHdr, m_pOwner->GetSequence(), 0, m_MergedBones[0].m_iMyBone, mBoneLocal );
|
||||
MatrixInvert( mBoneLocal, mBoneLocalInv );
|
||||
|
||||
// Now calculate mEntity = mFollowBone * Inverse( mBoneLocal )
|
||||
matrix3x4_t mEntity;
|
||||
ConcatTransforms( mFollowBone, mBoneLocalInv, mEntity );
|
||||
MatrixAngles( mEntity, *pAbsAngles, *pAbsOrigin );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
79
game/client/bone_merge_cache.h
Normal file
79
game/client/bone_merge_cache.h
Normal file
@ -0,0 +1,79 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BONE_MERGE_CACHE_H
|
||||
#define BONE_MERGE_CACHE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class C_BaseAnimating;
|
||||
class CStudioHdr;
|
||||
class CBoneBitList;
|
||||
|
||||
#include "mathlib/vector.h"
|
||||
|
||||
|
||||
class CBoneMergeCache
|
||||
{
|
||||
public:
|
||||
|
||||
CBoneMergeCache();
|
||||
|
||||
void Init( C_BaseAnimating *pOwner );
|
||||
|
||||
// Updates the lookups that let it merge bones quickly.
|
||||
void UpdateCache();
|
||||
|
||||
// This copies the transform from all bones in the followed entity that have
|
||||
// names that match our bones.
|
||||
virtual void MergeMatchingBones( int boneMask, CBoneBitList &boneComputed );
|
||||
|
||||
// Returns true if the specified bone is one that gets merged in MergeMatchingBones.
|
||||
int IsBoneMerged( int iBone ) const;
|
||||
|
||||
// Gets the origin for the first merge bone on the parent.
|
||||
bool GetAimEntOrigin( Vector *pAbsOrigin, QAngle *pAbsAngles );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// This is the entity that we're keeping the cache updated for.
|
||||
C_BaseAnimating *m_pOwner;
|
||||
|
||||
// All the cache data is based off these. When they change, the cache data is regenerated.
|
||||
// These are either all valid pointers or all NULL.
|
||||
C_BaseAnimating *m_pFollow;
|
||||
CStudioHdr *m_pFollowHdr;
|
||||
CStudioHdr *m_pOwnerHdr;
|
||||
|
||||
// This is the mask we need to use to set up bones on the followed entity to do the bone merge
|
||||
int m_nFollowBoneSetupMask;
|
||||
|
||||
// Cache data.
|
||||
class CMergedBone
|
||||
{
|
||||
public:
|
||||
unsigned short m_iMyBone;
|
||||
unsigned short m_iParentBone;
|
||||
};
|
||||
|
||||
CUtlVector<CMergedBone> m_MergedBones;
|
||||
CVarBitVec m_BoneMergeBits; // One bit for each bone. The bit is set if the bone gets merged.
|
||||
};
|
||||
|
||||
|
||||
inline int CBoneMergeCache::IsBoneMerged( int iBone ) const
|
||||
{
|
||||
if ( m_pOwnerHdr )
|
||||
return m_BoneMergeBits.Get( iBone );
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // BONE_MERGE_CACHE_H
|
71
game/client/bonetoworldarray.h
Normal file
71
game/client/bonetoworldarray.h
Normal file
@ -0,0 +1,71 @@
|
||||
//========== Copyright © 2006, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef BONETOWORLDARRAY_H
|
||||
#define BONETOWORLDARRAY_H
|
||||
|
||||
#include "tier0/tslist.h"
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/memdbgon.h" // for _aligned_malloc usage below
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
template <int NUM_ARRAYS>
|
||||
class CBoneToWorldArrays
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ALIGNMENT = 128,
|
||||
};
|
||||
|
||||
CBoneToWorldArrays()
|
||||
{
|
||||
const int SIZE_ARRAY = AlignValue( sizeof(matrix3x4_t) * MAXSTUDIOBONES, ALIGNMENT );
|
||||
m_pBase = (matrix3x4_t *)_aligned_malloc( SIZE_ARRAY * NUM_ARRAYS, ALIGNMENT );
|
||||
for ( int i = 0; i < NUM_ARRAYS; i++ )
|
||||
{
|
||||
matrix3x4_t *pArray = (matrix3x4_t *)((byte *)m_pBase + SIZE_ARRAY * i);
|
||||
Assert( (size_t)pArray % ALIGNMENT == 0 );
|
||||
Free( pArray );
|
||||
}
|
||||
}
|
||||
|
||||
~CBoneToWorldArrays()
|
||||
{
|
||||
_aligned_free( m_pBase );
|
||||
}
|
||||
|
||||
int NumArrays()
|
||||
{
|
||||
return NUM_ARRAYS;
|
||||
}
|
||||
|
||||
matrix3x4_t *Alloc( bool bBlock = true )
|
||||
{
|
||||
TSLNodeBase_t *p;
|
||||
while ( ( p = m_Free.Pop() ) == NULL && bBlock )
|
||||
{
|
||||
ThreadPause();
|
||||
}
|
||||
return (matrix3x4_t *)p;
|
||||
}
|
||||
|
||||
void Free( matrix3x4_t *p )
|
||||
{
|
||||
m_Free.Push( (TSLNodeBase_t *) p );
|
||||
}
|
||||
|
||||
private:
|
||||
CTSListBase m_Free;
|
||||
matrix3x4_t *m_pBase;
|
||||
};
|
||||
|
||||
#endif // BONETOWORLDARRAY_H
|
169
game/client/c_ai_basehumanoid.cpp
Normal file
169
game/client/c_ai_basehumanoid.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#if 0
|
||||
|
||||
class C_AI_BaseHumanoid : public C_AI_BaseNPC
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_AI_BaseHumanoid, C_AI_BaseNPC );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_AI_BaseHumanoid();
|
||||
|
||||
// model specific
|
||||
virtual bool Interpolate( float currentTime );
|
||||
virtual void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
|
||||
|
||||
float m_recanimtime[3];
|
||||
AnimationLayer_t m_Layer[4][3];
|
||||
};
|
||||
|
||||
|
||||
|
||||
C_AI_BaseHumanoid::C_AI_BaseHumanoid()
|
||||
{
|
||||
memset(m_recanimtime, 0, sizeof(m_recanimtime));
|
||||
memset(m_Layer, 0, sizeof(m_Layer));
|
||||
}
|
||||
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE(AnimationLayer_t, DT_Animationlayer)
|
||||
RecvPropInt(RECVINFO_NAME(nSequence,sequence)),
|
||||
RecvPropFloat(RECVINFO_NAME(flCycle,cycle)),
|
||||
RecvPropFloat(RECVINFO_NAME(flPlaybackrate,playbackrate)),
|
||||
RecvPropFloat(RECVINFO_NAME(flWeight,weight))
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_AI_BaseHumanoid, DT_BaseHumanoid, CAI_BaseHumanoid)
|
||||
/*
|
||||
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[0][2],m_Layer0),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[1][2],m_Layer1),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[2][2],m_Layer2),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[3][2],m_Layer3),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||
*/
|
||||
RecvPropInt(RECVINFO_NAME(m_Layer[0][2].nSequence,sequence0)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flCycle,cycle0)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flPlaybackrate,playbackrate0)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flWeight,weight0)),
|
||||
RecvPropInt(RECVINFO_NAME(m_Layer[1][2].nSequence,sequence1)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flCycle,cycle1)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flPlaybackrate,playbackrate1)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flWeight,weight1)),
|
||||
RecvPropInt(RECVINFO_NAME(m_Layer[2][2].nSequence,sequence2)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flCycle,cycle2)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flPlaybackrate,playbackrate2)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flWeight,weight2)),
|
||||
RecvPropInt(RECVINFO_NAME(m_Layer[3][2].nSequence,sequence3)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flCycle,cycle3)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flPlaybackrate,playbackrate3)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flWeight,weight3))
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_AI_BaseHumanoid::StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask )
|
||||
{
|
||||
VPROF( "C_AI_BaseHumanoid::StandardBlendingRules" );
|
||||
|
||||
BaseClass::StandardBlendingRules( pStudioHdr, pos, q, currentTime, boneMask );
|
||||
|
||||
if ( !hdr )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
float poseparam[MAXSTUDIOPOSEPARAM];
|
||||
|
||||
if ( GetSequence() >= hdr->numseq )
|
||||
{
|
||||
SetSequence( 0 );
|
||||
}
|
||||
|
||||
// interpolate pose parameters
|
||||
for (int i = 0; i < hdr->numposeparameters; i++)
|
||||
{
|
||||
poseparam[ i ] = m_flPoseParameter[i];
|
||||
}
|
||||
|
||||
// build root animation
|
||||
float fCycle = GetCycle();
|
||||
CalcPose( hdr, NULL, pos, q, GetSequence(), fCycle, poseparam );
|
||||
|
||||
// debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 0, "%30s %6.2f : %6.2f", hdr->pSeqdesc( GetSequence() )->pszLabel( ), fCycle, 1.0 );
|
||||
|
||||
MaintainSequenceTransitions( hdr, fCycle, poseparam, pos, q, boneMask );
|
||||
|
||||
#if 1
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (m_Layer[i][2].nSequence != m_Layer[i][1].nSequence)
|
||||
{
|
||||
if (m_Layer[i][2].flWeight > 0.5) m_Layer[i][1].flWeight = 1.0; else m_Layer[i][1].flWeight = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
Vector pos2[MAXSTUDIOBONES];
|
||||
Quaternion q2[MAXSTUDIOBONES];
|
||||
float fWeight = m_Layer[i][1].flWeight * (1 - dadt) + m_Layer[i][2].flWeight * dadt;
|
||||
|
||||
/*
|
||||
debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -i - 1, 0,
|
||||
"%2d %6.2f %6.2f : %2d %6.2f %6.2f : %2d %6.2f %6.2f",
|
||||
m_Layer[i][0].nSequence, m_Layer[i][0].flCycle, m_Layer[i][0].flWeight,
|
||||
m_Layer[i][1].nSequence, m_Layer[i][1].flCycle, m_Layer[i][1].flWeight,
|
||||
m_Layer[i][2].nSequence, m_Layer[i][2].flCycle, m_Layer[i][2].flWeight );
|
||||
*/
|
||||
|
||||
if (fWeight > 0)
|
||||
{
|
||||
mstudioseqdesc_t *pseqdesc = hdr->pSeqdesc( m_Layer[i][2].nSequence );
|
||||
|
||||
float fCycle = m_Layer[i][2].flCycle;
|
||||
|
||||
// UNDONE: Do IK here.
|
||||
CalcPose( hdr, NULL, pos2, q2, m_Layer[i][2].nSequence, fCycle, poseparam );
|
||||
|
||||
if (fWeight > 1)
|
||||
fWeight = 1;
|
||||
SlerpBones( hdr, q, pos, pseqdesc, q2, pos2, fWeight );
|
||||
|
||||
engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", pseqdesc->pszLabel(), fCycle, fWeight );
|
||||
}
|
||||
else
|
||||
{
|
||||
engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", " ", 0, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
CIKContext auto_ik;
|
||||
auto_ik.Init( hdr, GetRenderAngles(), GetRenderOrigin(), gpGlobals->curtime );
|
||||
CalcAutoplaySequences( hdr, &auto_ik, pos, q, poseparam, boneMask, currentTime );
|
||||
|
||||
float controllers[MAXSTUDIOBONECTRLS];
|
||||
GetBoneControllers(controllers);
|
||||
CalcBoneAdj( hdr, pos, q, controllers );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif
|
173
game/client/c_ai_basenpc.cpp
Normal file
173
game/client/c_ai_basenpc.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_AI_BaseNPC.h"
|
||||
#include "engine/IVDebugOverlay.h"
|
||||
|
||||
#if defined( HL2_DLL ) || defined( HL2_EPISODIC )
|
||||
#include "c_basehlplayer.h"
|
||||
#endif
|
||||
|
||||
#include "death_pose.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define PING_MAX_TIME 2.0
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_AI_BaseNPC, DT_AI_BaseNPC, CAI_BaseNPC )
|
||||
RecvPropInt( RECVINFO( m_lifeState ) ),
|
||||
RecvPropBool( RECVINFO( m_bPerformAvoidance ) ),
|
||||
RecvPropBool( RECVINFO( m_bIsMoving ) ),
|
||||
RecvPropBool( RECVINFO( m_bFadeCorpse ) ),
|
||||
RecvPropInt( RECVINFO ( m_iDeathPose) ),
|
||||
RecvPropInt( RECVINFO( m_iDeathFrame) ),
|
||||
RecvPropInt( RECVINFO( m_iSpeedModRadius ) ),
|
||||
RecvPropInt( RECVINFO( m_iSpeedModSpeed ) ),
|
||||
RecvPropInt( RECVINFO( m_bSpeedModActive ) ),
|
||||
RecvPropBool( RECVINFO( m_bImportanRagdoll ) ),
|
||||
RecvPropFloat( RECVINFO( m_flTimePingEffect ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
extern ConVar cl_npc_speedmod_intime;
|
||||
|
||||
bool NPC_IsImportantNPC( C_BaseAnimating *pAnimating )
|
||||
{
|
||||
C_AI_BaseNPC *pBaseNPC = pAnimating->MyNPCPointer();
|
||||
if ( pBaseNPC == NULL )
|
||||
return false;
|
||||
|
||||
return pBaseNPC->ImportantRagdoll();
|
||||
}
|
||||
|
||||
C_AI_BaseNPC::C_AI_BaseNPC()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes ragdolls ignore npcclip brushes
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int C_AI_BaseNPC::PhysicsSolidMaskForEntity( void ) const
|
||||
{
|
||||
// This allows ragdolls to move through npcclip brushes
|
||||
if ( !IsRagdoll() )
|
||||
{
|
||||
return MASK_NPCSOLID;
|
||||
}
|
||||
return MASK_SOLID;
|
||||
}
|
||||
|
||||
|
||||
void C_AI_BaseNPC::ClientThink( void )
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
#ifdef HL2_DLL
|
||||
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
|
||||
|
||||
if ( ShouldModifyPlayerSpeed() == true )
|
||||
{
|
||||
if ( pPlayer )
|
||||
{
|
||||
float flDist = (GetAbsOrigin() - pPlayer->GetAbsOrigin()).LengthSqr();
|
||||
|
||||
if ( flDist <= GetSpeedModifyRadius() )
|
||||
{
|
||||
if ( pPlayer->m_hClosestNPC )
|
||||
{
|
||||
if ( pPlayer->m_hClosestNPC != this )
|
||||
{
|
||||
float flDistOther = (pPlayer->m_hClosestNPC->GetAbsOrigin() - pPlayer->GetAbsOrigin()).Length();
|
||||
|
||||
//If I'm closer than the other NPC then replace it with myself.
|
||||
if ( flDist < flDistOther )
|
||||
{
|
||||
pPlayer->m_hClosestNPC = this;
|
||||
pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pPlayer->m_hClosestNPC = this;
|
||||
pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // HL2_DLL
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
|
||||
|
||||
if ( pPlayer && m_flTimePingEffect > gpGlobals->curtime )
|
||||
{
|
||||
float fPingEffectTime = m_flTimePingEffect - gpGlobals->curtime;
|
||||
|
||||
if ( fPingEffectTime > 0.0f )
|
||||
{
|
||||
Vector vRight, vUp;
|
||||
Vector vMins, vMaxs;
|
||||
|
||||
float fFade;
|
||||
|
||||
if( fPingEffectTime <= 1.0f )
|
||||
{
|
||||
fFade = 1.0f - (1.0f - fPingEffectTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
fFade = 1.0f;
|
||||
}
|
||||
|
||||
GetRenderBounds( vMins, vMaxs );
|
||||
AngleVectors (pPlayer->GetAbsAngles(), NULL, &vRight, &vUp );
|
||||
Vector p1 = GetAbsOrigin() + vRight * vMins.x + vUp * vMins.z;
|
||||
Vector p2 = GetAbsOrigin() + vRight * vMaxs.x + vUp * vMins.z;
|
||||
Vector p3 = GetAbsOrigin() + vUp * vMaxs.z;
|
||||
|
||||
int r = 0 * fFade;
|
||||
int g = 255 * fFade;
|
||||
int b = 0 * fFade;
|
||||
|
||||
debugoverlay->AddLineOverlay( p1, p2, r, g, b, true, 0.05f );
|
||||
debugoverlay->AddLineOverlay( p2, p3, r, g, b, true, 0.05f );
|
||||
debugoverlay->AddLineOverlay( p3, p1, r, g, b, true, 0.05f );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void C_AI_BaseNPC::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if ( ( ShouldModifyPlayerSpeed() == true ) || ( m_flTimePingEffect > gpGlobals->curtime ) )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
void C_AI_BaseNPC::GetRagdollInitBoneArrays( matrix3x4a_t *pDeltaBones0, matrix3x4a_t *pDeltaBones1, matrix3x4a_t *pCurrentBones, float boneDt )
|
||||
{
|
||||
ForceSetupBonesAtTime( pDeltaBones0, gpGlobals->curtime - boneDt );
|
||||
GetRagdollCurSequenceWithDeathPose( this, pDeltaBones1, gpGlobals->curtime, m_iDeathPose, m_iDeathFrame );
|
||||
float ragdollCreateTime = PhysGetSyncCreateTime();
|
||||
if ( ragdollCreateTime != gpGlobals->curtime )
|
||||
{
|
||||
// The next simulation frame begins before the end of this frame
|
||||
// so initialize the ragdoll at that time so that it will reach the current
|
||||
// position at curtime. Otherwise the ragdoll will simulate forward from curtime
|
||||
// and pop into the future a bit at this point of transition
|
||||
ForceSetupBonesAtTime( pCurrentBones, ragdollCreateTime );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupBones( pCurrentBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime );
|
||||
}
|
||||
}
|
||||
|
61
game/client/c_ai_basenpc.h
Normal file
61
game/client/c_ai_basenpc.h
Normal file
@ -0,0 +1,61 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_AI_BASENPC_H
|
||||
#define C_AI_BASENPC_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_basecombatcharacter.h"
|
||||
|
||||
// NOTE: MOved all controller code into c_basestudiomodel
|
||||
class C_AI_BaseNPC : public C_BaseCombatCharacter
|
||||
{
|
||||
DECLARE_CLASS( C_AI_BaseNPC, C_BaseCombatCharacter );
|
||||
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_AI_BaseNPC();
|
||||
virtual unsigned int PhysicsSolidMaskForEntity( void ) const;
|
||||
virtual bool IsNPC( void ) { return true; }
|
||||
bool IsMoving( void ){ return m_bIsMoving; }
|
||||
bool ShouldAvoidObstacle( void ){ return m_bPerformAvoidance; }
|
||||
virtual bool AddRagdollToFadeQueue( void ) { return m_bFadeCorpse; }
|
||||
|
||||
virtual void GetRagdollInitBoneArrays( matrix3x4a_t *pDeltaBones0, matrix3x4a_t *pDeltaBones1, matrix3x4a_t *pCurrentBones, float boneDt );
|
||||
|
||||
int GetDeathPose( void ) { return m_iDeathPose; }
|
||||
|
||||
bool ShouldModifyPlayerSpeed( void ) { return m_bSpeedModActive; }
|
||||
int GetSpeedModifyRadius( void ) { return m_iSpeedModRadius; }
|
||||
int GetSpeedModifySpeed( void ) { return m_iSpeedModSpeed; }
|
||||
|
||||
void ClientThink( void );
|
||||
void OnDataChanged( DataUpdateType_t type );
|
||||
bool ImportantRagdoll( void ) { return m_bImportanRagdoll; }
|
||||
|
||||
private:
|
||||
C_AI_BaseNPC( const C_AI_BaseNPC & ); // not defined, not accessible
|
||||
float m_flTimePingEffect;
|
||||
int m_iDeathPose;
|
||||
int m_iDeathFrame;
|
||||
|
||||
int m_iSpeedModRadius;
|
||||
int m_iSpeedModSpeed;
|
||||
|
||||
bool m_bPerformAvoidance;
|
||||
bool m_bIsMoving;
|
||||
bool m_bFadeCorpse;
|
||||
bool m_bSpeedModActive;
|
||||
bool m_bImportanRagdoll;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_AI_BASENPC_H
|
6816
game/client/c_baseanimating.cpp
Normal file
6816
game/client/c_baseanimating.cpp
Normal file
File diff suppressed because it is too large
Load Diff
850
game/client/c_baseanimating.h
Normal file
850
game/client/c_baseanimating.h
Normal file
@ -0,0 +1,850 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#ifndef C_BASEANIMATING_H
|
||||
#define C_BASEANIMATING_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseentity.h"
|
||||
#include "studio.h"
|
||||
#include "UtlVector.h"
|
||||
#include "ragdoll.h"
|
||||
#include "mouthinfo.h"
|
||||
// Shared activities
|
||||
#include "ai_activity.h"
|
||||
#include "animationlayer.h"
|
||||
#include "sequence_transitioner.h"
|
||||
#include "bone_accessor.h"
|
||||
#include "bone_merge_cache.h"
|
||||
#include "ragdoll_shared.h"
|
||||
#include "tier0/threadtools.h"
|
||||
#include "datacache/idatacache.h"
|
||||
#include "toolframework/itoolframework.h"
|
||||
|
||||
#define LIPSYNC_POSEPARAM_NAME "mouth"
|
||||
#define NUM_HITBOX_FIRES 10
|
||||
|
||||
/*
|
||||
class C_BaseClientShader
|
||||
{
|
||||
virtual void RenderMaterial( C_BaseEntity *pEntity, int count, const vec4_t *verts, const vec4_t *normals, const vec2_t *texcoords, vec4_t *lightvalues );
|
||||
};
|
||||
*/
|
||||
|
||||
class IRagdoll;
|
||||
class C_ClientRagdoll;
|
||||
class CIKContext;
|
||||
class CIKState;
|
||||
class ConVar;
|
||||
class C_RopeKeyframe;
|
||||
class CBoneBitList;
|
||||
class CBoneList;
|
||||
class KeyValues;
|
||||
class CJiggleBones;
|
||||
class IBoneSetup;
|
||||
FORWARD_DECLARE_HANDLE( memhandle_t );
|
||||
typedef unsigned short MDLHandle_t;
|
||||
|
||||
extern ConVar vcollide_wireframe;
|
||||
extern IDataCache *datacache;
|
||||
|
||||
struct ClientModelRenderInfo_t : public ModelRenderInfo_t
|
||||
{
|
||||
// Added space for lighting origin override. Just allocated space, need to set base pointer
|
||||
matrix3x4_t lightingOffset;
|
||||
|
||||
// Added space for model to world matrix. Just allocated space, need to set base pointer
|
||||
matrix3x4_t modelToWorld;
|
||||
};
|
||||
|
||||
struct RagdollInfo_t
|
||||
{
|
||||
bool m_bActive;
|
||||
float m_flSaveTime;
|
||||
int m_nNumBones;
|
||||
Vector m_rgBonePos[MAXSTUDIOBONES];
|
||||
Quaternion m_rgBoneQuaternion[MAXSTUDIOBONES];
|
||||
};
|
||||
|
||||
|
||||
class CAttachmentData
|
||||
{
|
||||
public:
|
||||
matrix3x4_t m_AttachmentToWorld;
|
||||
QAngle m_angRotation;
|
||||
Vector m_vOriginVelocity;
|
||||
int m_nLastFramecount : 31;
|
||||
int m_bAnglesComputed : 1;
|
||||
};
|
||||
|
||||
|
||||
typedef unsigned int ClientSideAnimationListHandle_t;
|
||||
|
||||
#define INVALID_CLIENTSIDEANIMATION_LIST_HANDLE (ClientSideAnimationListHandle_t)~0
|
||||
|
||||
|
||||
class C_BaseAnimating : public C_BaseEntity, public IClientModelRenderable
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseAnimating, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_INTERPOLATION();
|
||||
DECLARE_FRIEND_DATADESC_ACCESS();
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_POSEPAREMETERS = 24,
|
||||
NUM_BONECTRLS = 4
|
||||
};
|
||||
|
||||
// Inherited from IClientUnknown
|
||||
public:
|
||||
virtual IClientModelRenderable* GetClientModelRenderable();
|
||||
|
||||
// Inherited from IClientModelRenderable
|
||||
public:
|
||||
virtual bool GetRenderData( void *pData, ModelDataCategory_t nCategory );
|
||||
|
||||
public:
|
||||
C_BaseAnimating();
|
||||
~C_BaseAnimating();
|
||||
|
||||
virtual C_BaseAnimating* GetBaseAnimating() { return this; }
|
||||
|
||||
int GetRenderFlags( void );
|
||||
|
||||
virtual bool Interpolate( float currentTime );
|
||||
virtual bool Simulate();
|
||||
virtual void Release();
|
||||
|
||||
float GetAnimTimeInterval( void ) const;
|
||||
|
||||
// Get bone controller values.
|
||||
virtual void GetBoneControllers(float controllers[MAXSTUDIOBONECTRLS]);
|
||||
virtual float SetBoneController ( int iController, float flValue );
|
||||
|
||||
LocalFlexController_t GetNumFlexControllers( void );
|
||||
const char *GetFlexDescFacs( int iFlexDesc );
|
||||
const char *GetFlexControllerName( LocalFlexController_t iFlexController );
|
||||
const char *GetFlexControllerType( LocalFlexController_t iFlexController );
|
||||
|
||||
virtual void GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pAbsOrigin, QAngle *pAbsAngles );
|
||||
|
||||
// Computes a box that surrounds all hitboxes
|
||||
bool ComputeHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
|
||||
bool ComputeEntitySpaceHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
|
||||
|
||||
// Gets the hitbox-to-world transforms, returns false if there was a problem
|
||||
bool HitboxToWorldTransforms( matrix3x4_t *pHitboxToWorld[MAXSTUDIOBONES] );
|
||||
|
||||
// base model functionality
|
||||
float ClampCycle( float cycle, bool isLooping );
|
||||
virtual void GetPoseParameters( CStudioHdr *pStudioHdr, float poseParameter[MAXSTUDIOPOSEPARAM] );
|
||||
virtual void CalcBoneMerge( CStudioHdr *hdr, int boneMask, CBoneBitList &boneComputed );
|
||||
virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
|
||||
void BuildJiggleTransformations( int boneIndex, const mstudiojigglebone_t *jiggleParams, const matrix3x4_t &goalMX );
|
||||
virtual void ApplyBoneMatrixTransform( matrix3x4_t& transform );
|
||||
virtual int VPhysicsGetObjectList( IPhysicsObject **pList, int listMax );
|
||||
|
||||
// model specific
|
||||
virtual bool SetupBones( matrix3x4a_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime );
|
||||
virtual void UpdateIKLocks( float currentTime );
|
||||
virtual void CalculateIKLocks( float currentTime );
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
virtual int InternalDrawModel( int flags, const RenderableInstance_t &instance );
|
||||
virtual bool OnInternalDrawModel( ClientModelRenderInfo_t *pInfo );
|
||||
virtual bool OnPostInternalDrawModel( ClientModelRenderInfo_t *pInfo );
|
||||
void DoInternalDrawModel( ClientModelRenderInfo_t *pInfo, DrawModelState_t *pState, matrix3x4_t *pBoneToWorldArray = NULL );
|
||||
|
||||
//
|
||||
virtual CMouthInfo *GetMouth();
|
||||
virtual void ControlMouth( CStudioHdr *pStudioHdr );
|
||||
|
||||
// override in sub-classes
|
||||
virtual void DoAnimationEvents( CStudioHdr *pStudio );
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
virtual void FireObsoleteEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
|
||||
// Parses and distributes muzzle flash events
|
||||
virtual bool DispatchMuzzleEffect( const char *options, bool isFirstPerson );
|
||||
virtual void EjectParticleBrass( const char *pEffectName, const int iAttachment );
|
||||
|
||||
// virtual void AllocateMaterials( void );
|
||||
// virtual void FreeMaterials( void );
|
||||
|
||||
virtual CStudioHdr *OnNewModel( void );
|
||||
CStudioHdr *GetModelPtr() const;
|
||||
void InvalidateMdlCache();
|
||||
|
||||
virtual void SetPredictable( bool state );
|
||||
void UseClientSideAnimation();
|
||||
bool IsUsingClientSideAnimation() { return m_bClientSideAnimation; }
|
||||
|
||||
// C_BaseClientShader **p_ClientShaders;
|
||||
|
||||
virtual void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], QuaternionAligned q[], float currentTime, int boneMask );
|
||||
void UnragdollBlend( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime );
|
||||
|
||||
void MaintainSequenceTransitions( IBoneSetup &boneSetup, float flCycle, Vector pos[], Quaternion q[] );
|
||||
virtual void AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime );
|
||||
|
||||
// Attachments
|
||||
virtual int LookupAttachment( const char *pAttachmentName );
|
||||
int LookupRandomAttachment( const char *pAttachmentNameSubstring );
|
||||
|
||||
int LookupPoseParameter( CStudioHdr *pStudioHdr, const char *szName );
|
||||
inline int LookupPoseParameter( const char *szName ) { return LookupPoseParameter(GetModelPtr(), szName); }
|
||||
|
||||
float SetPoseParameter( CStudioHdr *pStudioHdr, const char *szName, float flValue );
|
||||
inline float SetPoseParameter( const char *szName, float flValue ) { return SetPoseParameter( GetModelPtr(), szName, flValue ); }
|
||||
float SetPoseParameter( CStudioHdr *pStudioHdr, int iParameter, float flValue );
|
||||
inline float SetPoseParameter( int iParameter, float flValue ) { return SetPoseParameter( GetModelPtr(), iParameter, flValue ); }
|
||||
float GetPoseParameter( int iParameter );
|
||||
|
||||
float GetPoseParameterRaw( int iPoseParameter ); // returns raw 0..1 value
|
||||
bool GetPoseParameterRange( int iPoseParameter, float &minValue, float &maxValue );
|
||||
|
||||
int LookupBone( const char *szName );
|
||||
void GetBonePosition( int iBone, Vector &origin, QAngle &angles );
|
||||
void GetBoneTransform( int iBone, matrix3x4_t &pBoneToWorld );
|
||||
|
||||
void CopySequenceTransitions( C_BaseAnimating *pCopyFrom );
|
||||
//bool solveIK(float a, float b, const Vector &Foot, const Vector &Knee1, Vector &Knee2);
|
||||
//void DebugIK( mstudioikchain_t *pikchain );
|
||||
|
||||
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
// This can be used to force client side animation to be on. Only use if you know what you're doing!
|
||||
// Normally, the server entity should set this.
|
||||
void ForceClientSideAnimationOn();
|
||||
|
||||
void AddToClientSideAnimationList();
|
||||
void RemoveFromClientSideAnimationList();
|
||||
|
||||
virtual bool IsSelfAnimating();
|
||||
virtual void ResetLatched();
|
||||
|
||||
// implements these so ragdolls can handle frustum culling & leaf visibility
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
virtual const Vector& GetRenderOrigin( void );
|
||||
virtual const QAngle& GetRenderAngles( void );
|
||||
|
||||
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
|
||||
|
||||
// Attachments.
|
||||
bool GetAttachment( const char *szName, Vector &absOrigin );
|
||||
bool GetAttachment( const char *szName, Vector &absOrigin, QAngle &absAngles );
|
||||
|
||||
// Inherited from C_BaseEntity
|
||||
virtual bool GetAttachment( int number, Vector &origin );
|
||||
virtual bool GetAttachment( int number, Vector &origin, QAngle &angles );
|
||||
virtual bool GetAttachment( int number, matrix3x4_t &matrix );
|
||||
virtual bool GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel );
|
||||
virtual void InvalidateAttachments();
|
||||
|
||||
// Returns the attachment in local space
|
||||
bool GetAttachmentLocal( int iAttachment, matrix3x4_t &attachmentToLocal );
|
||||
bool GetAttachmentLocal( int iAttachment, Vector &origin, QAngle &angles );
|
||||
bool GetAttachmentLocal( int iAttachment, Vector &origin );
|
||||
|
||||
// Should this object cast render-to-texture shadows?
|
||||
virtual ShadowType_t ShadowCastType();
|
||||
|
||||
// Should we collide?
|
||||
virtual CollideType_t GetCollideType( void );
|
||||
|
||||
virtual bool TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
|
||||
virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
|
||||
|
||||
// returns true if we are of type C_ClientRagdoll
|
||||
virtual bool IsClientRagdoll() const { return false; }
|
||||
|
||||
// returns true if we're currently being ragdolled
|
||||
bool IsRagdoll() const;
|
||||
virtual C_BaseAnimating *BecomeRagdollOnClient();
|
||||
virtual C_ClientRagdoll *CreateClientRagdoll( bool bRestoring = false );
|
||||
C_BaseAnimating *CreateRagdollCopy();
|
||||
bool InitAsClientRagdoll( const matrix3x4_t *pDeltaBones0, const matrix3x4_t *pDeltaBones1, const matrix3x4_t *pCurrentBonePosition, float boneDt );
|
||||
void IgniteRagdoll( C_BaseAnimating *pSource );
|
||||
void TransferDissolveFrom( C_BaseAnimating *pSource );
|
||||
virtual void SaveRagdollInfo( int numbones, const matrix3x4_t &cameraTransform, CBoneAccessor &pBoneToWorld );
|
||||
virtual bool RetrieveRagdollInfo( Vector *pos, Quaternion *q );
|
||||
virtual void Clear( void );
|
||||
void ClearRagdoll();
|
||||
void CreateUnragdollInfo( C_BaseAnimating *pRagdoll );
|
||||
void ForceSetupBonesAtTime( matrix3x4a_t *pBonesOut, float flTime );
|
||||
virtual void GetRagdollInitBoneArrays( matrix3x4a_t *pDeltaBones0, matrix3x4a_t *pDeltaBones1, matrix3x4a_t *pCurrentBones, float boneDt );
|
||||
|
||||
// For shadows rendering the correct body + sequence...
|
||||
virtual int GetBody() { return m_nBody; }
|
||||
virtual int GetSkin() { return m_nSkin; }
|
||||
|
||||
bool IsOnFire() { return ( (GetFlags() & FL_ONFIRE) != 0 ); }
|
||||
float GetFrozenAmount() { return m_flFrozen; }
|
||||
|
||||
inline float GetPlaybackRate() const;
|
||||
inline void SetPlaybackRate( float rate );
|
||||
|
||||
void SetModelScale( float scale );
|
||||
inline float GetModelScale() const { return m_flModelScale; }
|
||||
inline bool IsModelScaleFractional() const; /// very fast way to ask if the model scale is < 1.0f (faster than if (GetModelScale() < 1.0f) )
|
||||
|
||||
int GetSequence();
|
||||
void SetSequence(int nSequence);
|
||||
inline void ResetSequence(int nSequence);
|
||||
void OnNewSequence( );
|
||||
float GetSequenceGroundSpeed( CStudioHdr *pStudioHdr, int iSequence );
|
||||
inline float GetSequenceGroundSpeed( int iSequence ) { return GetSequenceGroundSpeed(GetModelPtr(), iSequence); }
|
||||
bool IsSequenceLooping( CStudioHdr *pStudioHdr, int iSequence );
|
||||
inline bool IsSequenceLooping( int iSequence ) { return IsSequenceLooping(GetModelPtr(),iSequence); }
|
||||
float GetSequenceMoveDist( CStudioHdr *pStudioHdr, int iSequence );
|
||||
void GetSequenceLinearMotion( int iSequence, Vector *pVec );
|
||||
float GetSequenceLinearMotionAndDuration( int iSequence, Vector *pVec );
|
||||
bool GetSequenceMovement( int nSequence, float fromCycle, float toCycle, Vector &deltaPosition, QAngle &deltaAngles );
|
||||
void GetBlendedLinearVelocity( Vector *pVec );
|
||||
void SetMovementPoseParams( const Vector &vecLocalVelocity, int iMoveX, int iMoveY, int iXSign = 1, int iYSign = 1 );
|
||||
int LookupSequence ( const char *label );
|
||||
int LookupActivity( const char *label );
|
||||
char const *GetSequenceName( int iSequence );
|
||||
char const *GetSequenceActivityName( int iSequence );
|
||||
Activity GetSequenceActivity( int iSequence );
|
||||
virtual void StudioFrameAdvance(); // advance animation frame to some time in the future
|
||||
void ExtractBbox( int nSequence, Vector &mins, Vector &maxs );
|
||||
|
||||
// Clientside animation
|
||||
virtual float FrameAdvance( float flInterval = 0.0f );
|
||||
virtual float GetSequenceCycleRate( CStudioHdr *pStudioHdr, int iSequence );
|
||||
virtual void UpdateClientSideAnimation();
|
||||
void ClientSideAnimationChanged();
|
||||
virtual unsigned int ComputeClientSideAnimationFlags();
|
||||
float GetGroundSpeed( void ) { return m_flGroundSpeed; }
|
||||
virtual void ReachedEndOfSequence() { return; }
|
||||
|
||||
void SetCycle( float flCycle );
|
||||
float GetCycle() const;
|
||||
|
||||
void SetBodygroup( int iGroup, int iValue );
|
||||
int GetBodygroup( int iGroup );
|
||||
|
||||
void SetSkin( int iSkin );
|
||||
void SetBody( int iBody );
|
||||
|
||||
const char *GetBodygroupName( int iGroup );
|
||||
int FindBodygroupByName( const char *name );
|
||||
int GetBodygroupCount( int iGroup );
|
||||
int GetNumBodyGroups( void );
|
||||
|
||||
void SetHitboxSet( int setnum );
|
||||
void SetHitboxSetByName( const char *setname );
|
||||
int GetHitboxSet( void );
|
||||
char const *GetHitboxSetName( void );
|
||||
int GetHitboxSetCount( void );
|
||||
void DrawClientHitboxes( float duration = 0.0f, bool monocolor = false );
|
||||
void DrawSkeleton( CStudioHdr const* pHdr, int iBoneMask ) const;
|
||||
|
||||
C_BaseAnimating* FindFollowedEntity();
|
||||
|
||||
virtual bool IsActivityFinished( void ) { return m_bSequenceFinished; }
|
||||
inline bool IsSequenceFinished( void );
|
||||
inline bool SequenceLoops( void ) { return m_bSequenceLoops; }
|
||||
|
||||
// All view model attachments origins are stretched so you can place entities at them and
|
||||
// they will match up with where the attachment winds up being drawn on the view model, since
|
||||
// the view models are drawn with a different FOV.
|
||||
//
|
||||
// If you're drawing something inside of a view model's DrawModel() function, then you want the
|
||||
// original attachment origin instead of the adjusted one. To get that, call this on the
|
||||
// adjusted attachment origin.
|
||||
virtual void UncorrectViewModelAttachment( Vector &vOrigin ) {}
|
||||
|
||||
// Call this if SetupBones() has already been called this frame but you need to move the
|
||||
// entity and rerender.
|
||||
void InvalidateBoneCache();
|
||||
bool IsBoneCacheValid() const; // Returns true if the bone cache is considered good for this frame.
|
||||
void GetCachedBoneMatrix( int boneIndex, matrix3x4_t &out );
|
||||
|
||||
// Wrappers for CBoneAccessor.
|
||||
const matrix3x4a_t& GetBone( int iBone ) const;
|
||||
matrix3x4a_t& GetBoneForWrite( int iBone );
|
||||
matrix3x4a_t* GetBoneArrayForWrite();
|
||||
|
||||
// Used for debugging. Will produce asserts if someone tries to setup bones or
|
||||
// attachments before it's allowed.
|
||||
// Use the "AutoAllowBoneAccess" class to auto push/pop bone access.
|
||||
// Use a distinct "tag" when pushing/popping - asserts when push/pop tags do not match.
|
||||
struct AutoAllowBoneAccess
|
||||
{
|
||||
AutoAllowBoneAccess( bool bAllowForNormalModels, bool bAllowForViewModels );
|
||||
~AutoAllowBoneAccess( void );
|
||||
};
|
||||
static void PushAllowBoneAccess( bool bAllowForNormalModels, bool bAllowForViewModels, char const *tagPush );
|
||||
static void PopBoneAccess( char const *tagPop );
|
||||
static void ThreadedBoneSetup();
|
||||
static bool InThreadedBoneSetup();
|
||||
static void InitBoneSetupThreadPool();
|
||||
static void ShutdownBoneSetupThreadPool();
|
||||
void MarkForThreadedBoneSetup();
|
||||
static void SetupBonesOnBaseAnimating( C_BaseAnimating *&pBaseAnimating );
|
||||
|
||||
// Invalidate bone caches so all SetupBones() calls force bone transforms to be regenerated.
|
||||
static void InvalidateBoneCaches();
|
||||
|
||||
// Purpose: My physics object has been updated, react or extract data
|
||||
virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
|
||||
|
||||
void DisableMuzzleFlash(); // Turn off the muzzle flash (ie: signal that we handled the server's event).
|
||||
virtual void DoMuzzleFlash(); // Force a muzzle flash event. Note: this only QUEUES an event, so
|
||||
// ProcessMuzzleFlashEvent will get called later.
|
||||
bool ShouldMuzzleFlash() const; // Is the muzzle flash event on?
|
||||
|
||||
// This is called to do the actual muzzle flash effect.
|
||||
virtual void ProcessMuzzleFlashEvent();
|
||||
|
||||
// Update client side animations
|
||||
static void UpdateClientSideAnimations();
|
||||
|
||||
// Load the model's keyvalues section and create effects listed inside it
|
||||
void InitModelEffects( void );
|
||||
|
||||
// Sometimes the server wants to update the client's cycle to get the two to run in sync (for proper hit detection)
|
||||
virtual void SetServerIntendedCycle( float intended ) { intended; }
|
||||
virtual float GetServerIntendedCycle( void ) { return -1.0f; }
|
||||
|
||||
// For prediction
|
||||
int SelectWeightedSequence ( int activity );
|
||||
int SelectWeightedSequenceFromModifiers( Activity activity, CUtlSymbol *pActivityModifiers, int iModifierCount );
|
||||
void ResetSequenceInfo( void );
|
||||
float SequenceDuration( void );
|
||||
float SequenceDuration( CStudioHdr *pStudioHdr, int iSequence );
|
||||
inline float SequenceDuration( int iSequence ) { return SequenceDuration(GetModelPtr(), iSequence); }
|
||||
int FindTransitionSequence( int iCurrentSequence, int iGoalSequence, int *piDir );
|
||||
|
||||
void RagdollMoved( void );
|
||||
|
||||
virtual void GetToolRecordingState( KeyValues *msg );
|
||||
virtual void CleanupToolRecordingState( KeyValues *msg );
|
||||
|
||||
void SetReceivedSequence( void );
|
||||
virtual bool ShouldResetSequenceOnNewModel( void );
|
||||
|
||||
// View models say yes to this.
|
||||
virtual bool IsViewModel() const;
|
||||
|
||||
// viewmodel or viewmodelattachmentmodel or lowerbody
|
||||
virtual bool IsViewModelOrAttachment() const;
|
||||
|
||||
void EnableJiggleBones( void );
|
||||
void DisableJiggleBones( void );
|
||||
|
||||
void ScriptSetPoseParameter( const char *szName, float fValue );
|
||||
|
||||
protected:
|
||||
// View models scale their attachment positions to account for FOV. To get the unmodified
|
||||
// attachment position (like if you're rendering something else during the view model's DrawModel call),
|
||||
// use TransformViewModelAttachmentToWorld.
|
||||
virtual void FormatViewModelAttachment( int nAttachment, matrix3x4_t &attachmentToWorld ) {}
|
||||
|
||||
bool IsBoneAccessAllowed() const;
|
||||
CMouthInfo& MouthInfo();
|
||||
|
||||
// Models used in a ModelPanel say yes to this
|
||||
virtual bool IsMenuModel() const;
|
||||
|
||||
// Allow studio models to tell C_BaseEntity what their m_nBody value is
|
||||
virtual int GetStudioBody( void ) { return m_nBody; }
|
||||
|
||||
virtual bool CalcAttachments();
|
||||
|
||||
virtual bool ComputeStencilState( ShaderStencilState_t *pStencilState );
|
||||
|
||||
virtual bool WantsInterpolatedVars() { return true; }
|
||||
|
||||
virtual void ResetSequenceLooping() { m_bSequenceFinished = false; }
|
||||
|
||||
private:
|
||||
// This method should return true if the bones have changed + SetupBones needs to be called
|
||||
virtual float LastBoneChangedTime() { return FLT_MAX; }
|
||||
|
||||
CBoneList* RecordBones( CStudioHdr *hdr, matrix3x4_t *pBoneState );
|
||||
|
||||
bool PutAttachment( int number, const matrix3x4_t &attachmentToWorld );
|
||||
void TermRopes();
|
||||
|
||||
void DelayedInitModelEffects( void );
|
||||
void ParseModelEffects( KeyValues *modelKeyValues );
|
||||
|
||||
void UpdateRelevantInterpolatedVars();
|
||||
void AddBaseAnimatingInterpolatedVars();
|
||||
void RemoveBaseAnimatingInterpolatedVars();
|
||||
|
||||
|
||||
void LockStudioHdr();
|
||||
void UnlockStudioHdr();
|
||||
|
||||
public:
|
||||
CRagdoll *m_pRagdoll;
|
||||
CBaseAnimating *m_pClientsideRagdoll;
|
||||
|
||||
// Hitbox set to use (default 0)
|
||||
int m_nHitboxSet;
|
||||
|
||||
CSequenceTransitioner m_SequenceTransitioner;
|
||||
|
||||
private:
|
||||
|
||||
// BEGIN PREDICTION DATA COMPACTION (these fields are together to allow for faster copying in prediction system)
|
||||
// FTYPEDESC_INSENDTABLE STUFF
|
||||
int m_nPrevSequence;
|
||||
protected:
|
||||
|
||||
//float m_flCycle;
|
||||
// This needs to be ranged checked because some interpolation edge cases
|
||||
// can assign it to values far out of range. Interpolation vars will only
|
||||
// clamp range checked vars.
|
||||
CRangeCheckedVar<float, -2, 2, 0> m_flCycle;
|
||||
float m_flPlaybackRate;// Animation playback framerate
|
||||
|
||||
// FTYPEDESC_INSENDTABLE STUFF (end)
|
||||
int m_nSkin;// Texture group to use
|
||||
int m_nBody;// Object bodygroup
|
||||
int m_nNewSequenceParity;
|
||||
int m_nResetEventsParity;
|
||||
int m_nPrevNewSequenceParity;
|
||||
int m_nPrevResetEventsParity;
|
||||
|
||||
float m_flEncodedController[MAXSTUDIOBONECTRLS];
|
||||
private:
|
||||
// This is compared against m_nOldMuzzleFlashParity to determine if the entity should muzzle flash.
|
||||
unsigned char m_nMuzzleFlashParity;
|
||||
// END PREDICTION DATA COMPACTION
|
||||
|
||||
protected:
|
||||
CIKContext *m_pIk;
|
||||
|
||||
int m_iEyeAttachment;
|
||||
|
||||
|
||||
// Decomposed ragdoll info
|
||||
bool m_bStoreRagdollInfo;
|
||||
RagdollInfo_t *m_pRagdollInfo;
|
||||
Vector m_vecForce;
|
||||
int m_nForceBone;
|
||||
|
||||
// Is bone cache valid
|
||||
// bone transformation matrix
|
||||
unsigned long m_iMostRecentModelBoneCounter;
|
||||
unsigned long m_iMostRecentBoneSetupRequest;
|
||||
C_BaseAnimating * m_pNextForThreadedBoneSetup;
|
||||
int m_iPrevBoneMask;
|
||||
int m_iAccumulatedBoneMask;
|
||||
|
||||
CBoneAccessor m_BoneAccessor;
|
||||
CThreadFastMutex m_BoneSetupLock;
|
||||
|
||||
ClientSideAnimationListHandle_t m_ClientSideAnimationListHandle;
|
||||
|
||||
// Client-side animation
|
||||
bool m_bClientSideFrameReset;
|
||||
|
||||
protected:
|
||||
|
||||
float m_flFrozen;
|
||||
|
||||
// Can we use the fast rendering path?
|
||||
bool m_bCanUseFastPath;
|
||||
|
||||
private:
|
||||
float m_flGroundSpeed; // computed linear movement rate for current sequence
|
||||
float m_flLastEventCheck; // cycle index of when events were last checked
|
||||
bool m_bSequenceFinished;// flag set when StudioAdvanceFrame moves across a frame boundry
|
||||
bool m_bSequenceLoops; // true if the sequence loops
|
||||
|
||||
bool m_bIsUsingRelativeLighting;
|
||||
|
||||
// Mouth lipsync/envelope following values
|
||||
CMouthInfo m_mouth;
|
||||
|
||||
CNetworkVar( float, m_flModelScale );
|
||||
|
||||
int m_nRestoreSequence;
|
||||
|
||||
// Ropes that got spawned when the model was created.
|
||||
CUtlLinkedList<C_RopeKeyframe*,unsigned short> m_Ropes;
|
||||
|
||||
// event processing info
|
||||
float m_flPrevEventCycle;
|
||||
int m_nEventSequence;
|
||||
|
||||
// Animation blending factors
|
||||
float m_flPoseParameter[MAXSTUDIOPOSEPARAM];
|
||||
CInterpolatedVarArray< float, MAXSTUDIOPOSEPARAM > m_iv_flPoseParameter;
|
||||
float m_flOldPoseParameters[MAXSTUDIOPOSEPARAM];
|
||||
|
||||
CInterpolatedVarArray< float, MAXSTUDIOBONECTRLS > m_iv_flEncodedController;
|
||||
float m_flOldEncodedController[MAXSTUDIOBONECTRLS];
|
||||
|
||||
// Clientside animation
|
||||
bool m_bClientSideAnimation;
|
||||
bool m_bLastClientSideFrameReset;
|
||||
|
||||
Vector m_vecPreRagdollMins;
|
||||
Vector m_vecPreRagdollMaxs;
|
||||
bool m_builtRagdoll;
|
||||
bool m_bReceivedSequence;
|
||||
bool m_bIsStaticProp;
|
||||
|
||||
// Current animation sequence
|
||||
int m_nSequence;
|
||||
|
||||
// Current cycle location from server
|
||||
protected:
|
||||
CInterpolatedVar< CRangeCheckedVar<float, -2, 2, 0> > m_iv_flCycle;
|
||||
//CInterpolatedVar< float > m_iv_flCycle;
|
||||
float m_flOldCycle;
|
||||
float m_prevClientCycle;
|
||||
float m_prevClientAnimTime;
|
||||
|
||||
// True if bone setup should latch bones for demo polish subsystem
|
||||
bool m_bBonePolishSetup;
|
||||
|
||||
CBoneMergeCache *m_pBoneMergeCache; // This caches the strcmp lookups that it has to do
|
||||
// when merg
|
||||
|
||||
private:
|
||||
int m_nPrevBody;
|
||||
int m_nPrevSkin;
|
||||
|
||||
float m_flOldModelScale;
|
||||
int m_nOldSequence;
|
||||
|
||||
CUtlVector< matrix3x4a_t, CUtlMemoryAligned<matrix3x4a_t,16> > m_CachedBoneData; // never access this directly. Use m_BoneAccessor.
|
||||
float m_flLastBoneSetupTime;
|
||||
CJiggleBones *m_pJiggleBones;
|
||||
bool m_isJiggleBonesEnabled;
|
||||
|
||||
// Calculated attachment points
|
||||
CUtlVector<CAttachmentData> m_Attachments;
|
||||
|
||||
void SetupBones_AttachmentHelper( CStudioHdr *pStudioHdr );
|
||||
|
||||
EHANDLE m_hLightingOrigin;
|
||||
|
||||
unsigned char m_nOldMuzzleFlashParity;
|
||||
|
||||
bool m_bInitModelEffects;
|
||||
|
||||
static bool m_bBoneListInUse;
|
||||
static CBoneList m_recordingBoneList;
|
||||
|
||||
private:
|
||||
mutable CStudioHdr *m_pStudioHdr;
|
||||
mutable MDLHandle_t m_hStudioHdr;
|
||||
CThreadFastMutex m_StudioHdrInitLock;
|
||||
|
||||
CUtlReference<CNewParticleEffect> m_ejectBrassEffect;
|
||||
int m_iEjectBrassAttachment;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RAGDOLL_FRICTION_OFF = -2,
|
||||
RAGDOLL_FRICTION_NONE,
|
||||
RAGDOLL_FRICTION_IN,
|
||||
RAGDOLL_FRICTION_HOLD,
|
||||
RAGDOLL_FRICTION_OUT,
|
||||
};
|
||||
|
||||
class C_ClientRagdoll : public C_BaseAnimating, public IPVSNotify
|
||||
{
|
||||
public:
|
||||
C_ClientRagdoll( bool bRestoring = true , bool fullInit = true);
|
||||
public:
|
||||
DECLARE_CLASS( C_ClientRagdoll, C_BaseAnimating );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
// inherited from IClientUnknown
|
||||
virtual IClientModelRenderable* GetClientModelRenderable();
|
||||
|
||||
// inherited from IPVSNotify
|
||||
virtual void OnPVSStatusChanged( bool bInPVS );
|
||||
|
||||
virtual void Release( void );
|
||||
virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
|
||||
virtual void ImpactTrace( trace_t *pTrace, int iDamageType, char *pCustomImpactName );
|
||||
void ClientThink( void );
|
||||
void ReleaseRagdoll( void ) { m_bReleaseRagdoll = true; }
|
||||
bool ShouldSavePhysics( void ) { return true; }
|
||||
virtual void OnSave();
|
||||
virtual void OnRestore();
|
||||
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | FCAP_SAVE_NON_NETWORKABLE; }
|
||||
virtual IPVSNotify* GetPVSNotifyInterface() { return this; }
|
||||
|
||||
void HandleAnimatedFriction( void );
|
||||
virtual void SUB_Remove( void );
|
||||
|
||||
void FadeOut( void );
|
||||
virtual float LastBoneChangedTime();
|
||||
|
||||
inline bool IsFadingOut() { return m_bFadingOut; }
|
||||
|
||||
bool m_bFadeOut;
|
||||
bool m_bImportant;
|
||||
float m_flEffectTime;
|
||||
|
||||
// returns true if we are of type C_ClientRagdoll
|
||||
virtual bool IsClientRagdoll() const { return true; }
|
||||
|
||||
protected:
|
||||
bool m_bReleaseRagdoll;
|
||||
|
||||
private:
|
||||
int m_iCurrentFriction;
|
||||
int m_iMinFriction;
|
||||
int m_iMaxFriction;
|
||||
float m_flFrictionModTime;
|
||||
float m_flFrictionTime;
|
||||
|
||||
int m_iFrictionAnimState;
|
||||
|
||||
bool m_bFadingOut;
|
||||
|
||||
float m_flScaleEnd[NUM_HITBOX_FIRES];
|
||||
float m_flScaleTimeStart[NUM_HITBOX_FIRES];
|
||||
float m_flScaleTimeEnd[NUM_HITBOX_FIRES];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Serves the 90% case of calling SetSequence / ResetSequenceInfo.
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void C_BaseAnimating::ResetSequence(int nSequence)
|
||||
{
|
||||
SetSequence( nSequence );
|
||||
ResetSequenceInfo();
|
||||
}
|
||||
|
||||
inline float C_BaseAnimating::GetPlaybackRate() const
|
||||
{
|
||||
return m_flPlaybackRate * clamp( 1.0f - m_flFrozen, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
inline void C_BaseAnimating::SetPlaybackRate( float rate )
|
||||
{
|
||||
m_flPlaybackRate = rate;
|
||||
}
|
||||
|
||||
inline const matrix3x4a_t& C_BaseAnimating::GetBone( int iBone ) const
|
||||
{
|
||||
return m_BoneAccessor.GetBone( iBone );
|
||||
}
|
||||
|
||||
inline matrix3x4a_t& C_BaseAnimating::GetBoneForWrite( int iBone )
|
||||
{
|
||||
return m_BoneAccessor.GetBoneForWrite( iBone );
|
||||
}
|
||||
|
||||
inline matrix3x4a_t* C_BaseAnimating::GetBoneArrayForWrite()
|
||||
{
|
||||
return m_BoneAccessor.GetBoneArrayForWrite();
|
||||
}
|
||||
|
||||
inline bool C_BaseAnimating::ShouldMuzzleFlash() const
|
||||
{
|
||||
return m_nOldMuzzleFlashParity != m_nMuzzleFlashParity;
|
||||
}
|
||||
|
||||
inline float C_BaseAnimating::GetCycle() const
|
||||
{
|
||||
return m_flCycle;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: return a pointer to an updated studiomdl cache cache
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline CStudioHdr *C_BaseAnimating::GetModelPtr() const
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
#ifndef _X360
|
||||
// 360's don't need to lock the modeldata cache since it never flushes
|
||||
static IDataCacheSection *pModelCache = g_pDataCache->FindSection( "ModelData" );
|
||||
AssertOnce( pModelCache->IsFrameLocking() );
|
||||
#endif
|
||||
#endif
|
||||
// GetModelPtr() is often called before OnNewModel() so go ahead and set it up first chance.
|
||||
if ( !m_pStudioHdr && GetModel() )
|
||||
{
|
||||
const_cast<C_BaseAnimating *>(this)->LockStudioHdr();
|
||||
}
|
||||
return ( m_pStudioHdr && m_pStudioHdr->IsValid() ) ? m_pStudioHdr : NULL;
|
||||
}
|
||||
|
||||
|
||||
inline void C_BaseAnimating::InvalidateMdlCache()
|
||||
{
|
||||
UnlockStudioHdr();
|
||||
if ( m_pStudioHdr != NULL )
|
||||
{
|
||||
delete m_pStudioHdr;
|
||||
m_pStudioHdr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline bool C_BaseAnimating::IsModelScaleFractional() const /// very fast way to ask if the model scale is < 1.0f
|
||||
{
|
||||
COMPILE_TIME_ASSERT( sizeof( m_flModelScale ) == sizeof( int ) );
|
||||
return *((const int *) &m_flModelScale) < 0x3f800000;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sequence access
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int C_BaseAnimating::GetSequence()
|
||||
{
|
||||
return m_nSequence;
|
||||
}
|
||||
|
||||
inline bool C_BaseAnimating::IsSequenceFinished( void )
|
||||
{
|
||||
return m_bSequenceFinished;
|
||||
}
|
||||
|
||||
inline float C_BaseAnimating::SequenceDuration( void )
|
||||
{
|
||||
return SequenceDuration( GetSequence() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Mouth
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CMouthInfo& C_BaseAnimating::MouthInfo()
|
||||
{
|
||||
return m_mouth;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: move these to somewhere that makes sense
|
||||
void GetColumn( matrix3x4_t& src, int column, Vector &dest );
|
||||
void SetColumn( Vector &src, int column, matrix3x4_t& dest );
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BaseAnimating);
|
||||
|
||||
|
||||
extern void DevMsgRT( char const* pMsg, ... );
|
||||
|
||||
#endif // C_BASEANIMATING_H
|
753
game/client/c_baseanimatingoverlay.cpp
Normal file
753
game/client/c_baseanimatingoverlay.cpp
Normal file
@ -0,0 +1,753 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_baseanimatingoverlay.h"
|
||||
#include "animation.h"
|
||||
#include "bone_setup.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "engine/IVDebugOverlay.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "eventlist.h"
|
||||
#include "toolframework_client.h"
|
||||
|
||||
#include "dt_utlvector_recv.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern ConVar r_sequence_debug;
|
||||
|
||||
template class CInterpolatedVar<CAnimationLayer>;
|
||||
|
||||
|
||||
mstudioevent_for_client_server_t *GetEventIndexForSequence( mstudioseqdesc_t &seqdesc );
|
||||
|
||||
|
||||
void C_AnimationLayer::SetOwner( C_BaseAnimatingOverlay *pOverlay )
|
||||
{
|
||||
m_pOwner = pOverlay;
|
||||
}
|
||||
|
||||
C_BaseAnimatingOverlay *C_AnimationLayer::GetOwner() const
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
|
||||
void C_AnimationLayer::Reset()
|
||||
{
|
||||
if ( m_pOwner )
|
||||
{
|
||||
int nFlags = 0;
|
||||
if ( m_nSequence != 0 || m_flWeight != 0.0f )
|
||||
{
|
||||
nFlags |= BOUNDS_CHANGED;
|
||||
}
|
||||
if ( m_flCycle != 0.0f )
|
||||
{
|
||||
nFlags |= ANIMATION_CHANGED;
|
||||
}
|
||||
if ( nFlags )
|
||||
{
|
||||
m_pOwner->InvalidatePhysicsRecursive( nFlags );
|
||||
}
|
||||
}
|
||||
|
||||
m_nSequence = 0;
|
||||
m_flPrevCycle = 0;
|
||||
m_flWeight = 0;
|
||||
m_flPlaybackRate = 0;
|
||||
m_flCycle = 0;
|
||||
m_flLayerAnimtime = 0;
|
||||
m_flLayerFadeOuttime = 0;
|
||||
}
|
||||
|
||||
void C_AnimationLayer::SetSequence( int nSequence )
|
||||
{
|
||||
if ( m_pOwner && m_nSequence != nSequence )
|
||||
{
|
||||
m_pOwner->InvalidatePhysicsRecursive( BOUNDS_CHANGED );
|
||||
}
|
||||
m_nSequence = nSequence;
|
||||
}
|
||||
|
||||
void C_AnimationLayer::SetCycle( float flCycle )
|
||||
{
|
||||
if ( m_pOwner && m_flCycle != flCycle )
|
||||
{
|
||||
m_pOwner->InvalidatePhysicsRecursive( ANIMATION_CHANGED );
|
||||
}
|
||||
m_flCycle = flCycle;
|
||||
}
|
||||
|
||||
void C_AnimationLayer::SetOrder( int order )
|
||||
{
|
||||
if ( m_pOwner && ( m_nOrder != order ) )
|
||||
{
|
||||
if ( m_nOrder == C_BaseAnimatingOverlay::MAX_OVERLAYS || order == C_BaseAnimatingOverlay::MAX_OVERLAYS )
|
||||
{
|
||||
m_pOwner->InvalidatePhysicsRecursive( BOUNDS_CHANGED );
|
||||
}
|
||||
}
|
||||
m_nOrder = order;
|
||||
}
|
||||
|
||||
|
||||
void C_AnimationLayer::SetWeight( float flWeight )
|
||||
{
|
||||
if ( m_pOwner && m_flWeight != flWeight )
|
||||
{
|
||||
if ( m_flWeight == 0.0f || flWeight == 0.0f )
|
||||
{
|
||||
m_pOwner->InvalidatePhysicsRecursive( BOUNDS_CHANGED );
|
||||
}
|
||||
}
|
||||
m_flWeight = flWeight;
|
||||
}
|
||||
|
||||
C_BaseAnimatingOverlay::C_BaseAnimatingOverlay()
|
||||
{
|
||||
// NOTE: We zero the memory in the max capacity m_Layer vector in dt_ultvector_common.h
|
||||
|
||||
// FIXME: where does this initialization go now?
|
||||
// AddVar( m_Layer, &m_iv_AnimOverlay, LATCH_ANIMATION_VAR );
|
||||
}
|
||||
|
||||
#undef CBaseAnimatingOverlay
|
||||
|
||||
|
||||
void RecvProxy_SequenceChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
|
||||
pLayer->SetSequence( pData->m_Value.m_Int );
|
||||
}
|
||||
|
||||
void RecvProxy_WeightChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
|
||||
pLayer->SetWeight( pData->m_Value.m_Float );
|
||||
}
|
||||
|
||||
void RecvProxy_CycleChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
|
||||
pLayer->SetCycle( pData->m_Value.m_Float );
|
||||
}
|
||||
|
||||
void RecvProxy_OrderChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
|
||||
pLayer->SetOrder( pData->m_Value.m_Int );
|
||||
}
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE(CAnimationLayer, DT_Animationlayer)
|
||||
RecvPropInt( RECVINFO_NAME(m_nSequence, m_nSequence), 0, RecvProxy_SequenceChanged ),
|
||||
RecvPropFloat( RECVINFO_NAME(m_flCycle, m_flCycle), 0, RecvProxy_CycleChanged ),
|
||||
RecvPropFloat( RECVINFO_NAME(m_flPrevCycle, m_flPrevCycle)),
|
||||
RecvPropFloat( RECVINFO_NAME(m_flWeight, m_flWeight), 0, RecvProxy_WeightChanged ),
|
||||
RecvPropInt( RECVINFO_NAME(m_nOrder, m_nOrder), 0, RecvProxy_OrderChanged )
|
||||
END_RECV_TABLE()
|
||||
|
||||
const char *s_m_iv_AnimOverlayNames[C_BaseAnimatingOverlay::MAX_OVERLAYS] =
|
||||
{
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay00",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay01",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay02",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay03",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay04",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay05",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay06",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay07",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay08",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay09",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay10",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay11",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay12",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay13",
|
||||
"C_BaseAnimatingOverlay::m_iv_AnimOverlay14"
|
||||
};
|
||||
|
||||
void ResizeAnimationLayerCallback( void *pStruct, int offsetToUtlVector, int len )
|
||||
{
|
||||
C_BaseAnimatingOverlay *pEnt = (C_BaseAnimatingOverlay*)pStruct;
|
||||
CUtlVector < CAnimationLayer > *pVec = &pEnt->m_AnimOverlay;
|
||||
CUtlVector< CInterpolatedVar< CAnimationLayer > > *pVecIV = &pEnt->m_iv_AnimOverlay;
|
||||
|
||||
Assert( (char*)pVec - (char*)pEnt == offsetToUtlVector );
|
||||
Assert( pVec->Count() == pVecIV->Count() );
|
||||
Assert( pVec->Count() <= C_BaseAnimatingOverlay::MAX_OVERLAYS );
|
||||
|
||||
int diff = len - pVec->Count();
|
||||
if ( diff != 0 )
|
||||
{
|
||||
// remove all entries
|
||||
for ( int i=0; i < pVec->Count(); i++ )
|
||||
{
|
||||
pEnt->RemoveVar( &pVec->Element( i ) );
|
||||
}
|
||||
|
||||
pEnt->InvalidatePhysicsRecursive( BOUNDS_CHANGED );
|
||||
|
||||
// adjust vector sizes
|
||||
if ( diff > 0 )
|
||||
{
|
||||
for ( int i = 0; i < diff; ++i )
|
||||
{
|
||||
int j = pVec->AddToTail( );
|
||||
(*pVec)[j].SetOwner( pEnt );
|
||||
}
|
||||
pVecIV->AddMultipleToTail( diff );
|
||||
}
|
||||
else
|
||||
{
|
||||
pVec->RemoveMultiple( len, -diff );
|
||||
pVecIV->RemoveMultiple( len, -diff );
|
||||
}
|
||||
|
||||
// Rebind all the variables in the ent's list.
|
||||
for ( int i=0; i < len; i++ )
|
||||
{
|
||||
IInterpolatedVar *pWatcher = &pVecIV->Element( i );
|
||||
pWatcher->SetDebugName( s_m_iv_AnimOverlayNames[i] );
|
||||
pEnt->AddVar( &pVec->Element( i ), pWatcher, LATCH_ANIMATION_VAR, true );
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: need to set historical values of nOrder in pVecIV to MAX_OVERLAY
|
||||
|
||||
// Ensure capacity
|
||||
pVec->EnsureCapacity( len );
|
||||
|
||||
int nNumAllocated = pVec->NumAllocated();
|
||||
|
||||
// This is important to do because EnsureCapacity doesn't actually call the constructors
|
||||
// on the elements, but we need them to be initialized, otherwise it'll have out-of-range
|
||||
// values which will piss off the datatable encoder.
|
||||
UtlVector_InitializeAllocatedElements( pVec->Base() + pVec->Count(), nNumAllocated - pVec->Count() );
|
||||
}
|
||||
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE( C_BaseAnimatingOverlay, DT_OverlayVars )
|
||||
RecvPropUtlVector(
|
||||
RECVINFO_UTLVECTOR_SIZEFN( m_AnimOverlay, ResizeAnimationLayerCallback ),
|
||||
C_BaseAnimatingOverlay::MAX_OVERLAYS,
|
||||
RecvPropDataTable(NULL, 0, 0, &REFERENCE_RECV_TABLE( DT_Animationlayer ) ) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BaseAnimatingOverlay, DT_BaseAnimatingOverlay, CBaseAnimatingOverlay )
|
||||
RecvPropDataTable( "overlay_vars", 0, 0, &REFERENCE_RECV_TABLE( DT_OverlayVars ) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( C_BaseAnimatingOverlay )
|
||||
|
||||
/*
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_nSequence, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flCycle, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flPlaybackRate, FIELD_FLOAT),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flWeight, FIELD_FLOAT),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_nSequence, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flCycle, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flPlaybackRate, FIELD_FLOAT),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flWeight, FIELD_FLOAT),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_nSequence, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flCycle, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flPlaybackRate, FIELD_FLOAT),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flWeight, FIELD_FLOAT),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_nSequence, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flCycle, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flPlaybackRate, FIELD_FLOAT),
|
||||
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flWeight, FIELD_FLOAT),
|
||||
*/
|
||||
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
CAnimationLayer* C_BaseAnimatingOverlay::GetAnimOverlay( int i )
|
||||
{
|
||||
Assert( i >= 0 && i < MAX_OVERLAYS );
|
||||
return &m_AnimOverlay[i];
|
||||
}
|
||||
|
||||
|
||||
void C_BaseAnimatingOverlay::SetNumAnimOverlays( int num )
|
||||
{
|
||||
if ( m_AnimOverlay.Count() < num )
|
||||
{
|
||||
int nCountToAdd = num - m_AnimOverlay.Count();
|
||||
for ( int i = 0; i < nCountToAdd; ++i )
|
||||
{
|
||||
int j = m_AnimOverlay.AddToTail( );
|
||||
m_AnimOverlay[j].SetOwner( this );
|
||||
}
|
||||
}
|
||||
else if ( m_AnimOverlay.Count() > num )
|
||||
{
|
||||
m_AnimOverlay.RemoveMultiple( num, m_AnimOverlay.Count() - num );
|
||||
InvalidatePhysicsRecursive( BOUNDS_CHANGED );
|
||||
}
|
||||
|
||||
// Ensure capacity
|
||||
m_AnimOverlay.EnsureCapacity( C_BaseAnimatingOverlay::MAX_OVERLAYS );
|
||||
|
||||
int nNumAllocated = m_AnimOverlay.NumAllocated();
|
||||
|
||||
// This is important to do because EnsureCapacity doesn't actually call the constructors
|
||||
// on the elements, but we need them to be initialized, otherwise it'll have out-of-range
|
||||
// values which will piss off the datatable encoder.
|
||||
UtlVector_InitializeAllocatedElements( m_AnimOverlay.Base() + m_AnimOverlay.Count(), nNumAllocated - m_AnimOverlay.Count() );
|
||||
}
|
||||
|
||||
|
||||
int C_BaseAnimatingOverlay::GetNumAnimOverlays() const
|
||||
{
|
||||
return m_AnimOverlay.Count();
|
||||
}
|
||||
|
||||
void C_BaseAnimatingOverlay::GetRenderBounds( Vector& theMins, Vector& theMaxs )
|
||||
{
|
||||
BaseClass::GetRenderBounds( theMins, theMaxs );
|
||||
|
||||
if ( IsRagdoll() )
|
||||
return;
|
||||
|
||||
CStudioHdr *pStudioHdr = GetModelPtr();
|
||||
if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() )
|
||||
return;
|
||||
|
||||
int nSequences = pStudioHdr->GetNumSeq();
|
||||
|
||||
int i;
|
||||
for (i = 0; i < m_AnimOverlay.Count(); i++)
|
||||
{
|
||||
if ( m_AnimOverlay[i].m_flWeight > 0.0 && m_AnimOverlay[i].m_nOrder != MAX_OVERLAYS )
|
||||
{
|
||||
if ( m_AnimOverlay[i].m_nSequence >= nSequences )
|
||||
continue;
|
||||
|
||||
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[i].m_nSequence );
|
||||
VectorMin( seqdesc.bbmin, theMins, theMins );
|
||||
VectorMax( seqdesc.bbmax, theMaxs, theMaxs );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool C_BaseAnimatingOverlay::Interpolate( float flCurrentTime )
|
||||
{
|
||||
bool bOk = BaseClass::Interpolate( flCurrentTime );
|
||||
|
||||
CheckForLayerPhysicsInvalidate();
|
||||
|
||||
return bOk;
|
||||
}
|
||||
|
||||
void C_BaseAnimatingOverlay::CheckForLayerChanges( CStudioHdr *hdr, float currentTime )
|
||||
{
|
||||
CDisableRangeChecks disableRangeChecks;
|
||||
|
||||
// FIXME: damn, there has to be a better way than this.
|
||||
int i;
|
||||
for (i = 0; i < m_iv_AnimOverlay.Count(); i++)
|
||||
{
|
||||
CDisableRangeChecks disableRangeChecks;
|
||||
|
||||
int iHead, iPrev1, iPrev2;
|
||||
m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
|
||||
|
||||
// fake up previous cycle values.
|
||||
float t0;
|
||||
CAnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
|
||||
// reset previous
|
||||
float t1;
|
||||
CAnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
|
||||
// reset previous previous
|
||||
float t2;
|
||||
CAnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
|
||||
|
||||
if ( !pHead || !pPrev1 || pHead->m_nSequence == pPrev1->m_nSequence )
|
||||
continue;
|
||||
|
||||
#if 1 // _DEBUG
|
||||
if (r_sequence_debug.GetInt() == entindex())
|
||||
{
|
||||
DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t0, hdr->pSeqdesc( pHead->m_nSequence ).pszLabel(), (float)pHead->m_flCycle, (float)pHead->m_flWeight, i );
|
||||
DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t1, hdr->pSeqdesc( pPrev1->m_nSequence ).pszLabel(), (float)pPrev1->m_flCycle, (float)pPrev1->m_flWeight, i );
|
||||
if (pPrev2)
|
||||
DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t2, hdr->pSeqdesc( pPrev2->m_nSequence ).pszLabel(), (float)pPrev2->m_flCycle, (float)pPrev2->m_flWeight, i );
|
||||
}
|
||||
#endif
|
||||
|
||||
pPrev1->m_nSequence = pHead->m_nSequence;
|
||||
pPrev1->m_flCycle = pHead->m_flPrevCycle;
|
||||
pPrev1->m_flWeight = pHead->m_flWeight;
|
||||
|
||||
if (pPrev2)
|
||||
{
|
||||
float num = 0;
|
||||
if ( fabs( t0 - t1 ) > 0.001f )
|
||||
num = (t2 - t1) / (t0 - t1);
|
||||
|
||||
pPrev2->m_nSequence = pHead->m_nSequence;
|
||||
float flTemp;
|
||||
if (IsSequenceLooping( hdr, pHead->m_nSequence ))
|
||||
{
|
||||
flTemp = LoopingLerp( num, (float)pHead->m_flPrevCycle, (float)pHead->m_flCycle );
|
||||
}
|
||||
else
|
||||
{
|
||||
flTemp = Lerp( num, (float)pHead->m_flPrevCycle, (float)pHead->m_flCycle );
|
||||
}
|
||||
pPrev2->m_flCycle = flTemp;
|
||||
pPrev2->m_flWeight = pHead->m_flWeight;
|
||||
}
|
||||
|
||||
/*
|
||||
if (stricmp( r_seq_overlay_debug.GetString(), hdr->name ) == 0)
|
||||
{
|
||||
DevMsgRT( "(%30s %6.2f : %6.2f : %6.2f)\n", hdr->pSeqdesc( pHead->nSequence ).pszLabel(), (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle );
|
||||
}
|
||||
*/
|
||||
|
||||
m_iv_AnimOverlay[i].SetLooping( IsSequenceLooping( hdr, pHead->m_nSequence ) );
|
||||
m_iv_AnimOverlay[i].Interpolate( currentTime );
|
||||
|
||||
// reset event indexes
|
||||
m_flOverlayPrevEventCycle[i] = pHead->m_flPrevCycle - 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//#define DEBUG_TF2_OVERLAYS
|
||||
void C_BaseAnimatingOverlay::AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime )
|
||||
{
|
||||
BaseClass::AccumulateLayers( boneSetup, pos, q, currentTime );
|
||||
int i;
|
||||
|
||||
// resort the layers
|
||||
int layer[MAX_OVERLAYS];
|
||||
for (i = 0; i < MAX_OVERLAYS; i++)
|
||||
{
|
||||
layer[i] = MAX_OVERLAYS;
|
||||
}
|
||||
|
||||
for (i = 0; i < m_AnimOverlay.Count(); i++)
|
||||
{
|
||||
if (m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS)
|
||||
{
|
||||
/*
|
||||
Assert( layer[m_AnimOverlay[i].m_nOrder] == MAX_OVERLAYS );
|
||||
layer[m_AnimOverlay[i].m_nOrder] = i;
|
||||
*/
|
||||
// hacky code until initialization of new layers is finished
|
||||
if ( layer[m_AnimOverlay[i].m_nOrder] != MAX_OVERLAYS )
|
||||
{
|
||||
m_AnimOverlay[i].SetOrder( MAX_OVERLAYS );
|
||||
}
|
||||
else
|
||||
{
|
||||
layer[m_AnimOverlay[i].m_nOrder] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckForLayerChanges( boneSetup.GetStudioHdr(), currentTime );
|
||||
|
||||
int nSequences = boneSetup.GetStudioHdr()->GetNumSeq();
|
||||
|
||||
// add in the overlay layers
|
||||
int j;
|
||||
for (j = 0; j < MAX_OVERLAYS; j++)
|
||||
{
|
||||
i = layer[ j ];
|
||||
if ( i >= m_AnimOverlay.Count() )
|
||||
{
|
||||
#if defined( DEBUG_TF2_OVERLAYS )
|
||||
engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i );
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( m_AnimOverlay[i].m_nSequence >= nSequences )
|
||||
continue;
|
||||
|
||||
/*
|
||||
DevMsgRT( 1 , "%.3f %.3f %.3f\n", currentTime, fWeight, dadt );
|
||||
debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -j - 1, 0,
|
||||
"%2d(%s) : %6.2f : %6.2f",
|
||||
m_AnimOverlay[i].m_nSequence,
|
||||
boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence )->pszLabel(),
|
||||
m_AnimOverlay[i].m_flCycle,
|
||||
m_AnimOverlay[i].m_flWeight
|
||||
);
|
||||
*/
|
||||
|
||||
float fWeight = m_AnimOverlay[i].m_flWeight;
|
||||
if ( fWeight <= 0.0f )
|
||||
{
|
||||
#if defined( DEBUG_TF2_OVERLAYS )
|
||||
engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i );
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
// check to see if the sequence changed
|
||||
// FIXME: move this to somewhere more reasonable
|
||||
// do a nice spline interpolation of the values
|
||||
// if ( m_AnimOverlay[i].m_nSequence != m_iv_AnimOverlay.GetPrev( i )->nSequence )
|
||||
float fCycle = m_AnimOverlay[ i ].m_flCycle;
|
||||
fCycle = ClampCycle( fCycle, IsSequenceLooping( m_AnimOverlay[i].m_nSequence ) );
|
||||
|
||||
if (fWeight > 1.0f)
|
||||
{
|
||||
fWeight = 1.0f;
|
||||
}
|
||||
|
||||
boneSetup.AccumulatePose( pos, q, m_AnimOverlay[i].m_nSequence, fCycle, fWeight, currentTime, m_pIk );
|
||||
|
||||
#if defined( DEBUG_TF2_OVERLAYS )
|
||||
engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
|
||||
#endif
|
||||
|
||||
#if 1 // _DEBUG
|
||||
if (r_sequence_debug.GetInt() == entindex())
|
||||
{
|
||||
if (1)
|
||||
{
|
||||
DevMsgRT( "%8.4f : %30s : %5.3f : %4.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
|
||||
}
|
||||
else
|
||||
{
|
||||
int iHead, iPrev1, iPrev2;
|
||||
m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
|
||||
|
||||
// fake up previous cycle values.
|
||||
float t0;
|
||||
CAnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
|
||||
// reset previous
|
||||
float t1;
|
||||
CAnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
|
||||
// reset previous previous
|
||||
float t2;
|
||||
CAnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
|
||||
|
||||
if ( pHead && pPrev1 && pPrev2 )
|
||||
{
|
||||
DevMsgRT( "%6.2f : %30s %6.2f (%6.2f:%6.2f:%6.2f) : %6.2f (%6.2f:%6.2f:%6.2f) : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(),
|
||||
fCycle, (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle,
|
||||
fWeight, (float)pPrev2->m_flWeight, (float)pPrev1->m_flWeight, (float)pHead->m_flWeight,
|
||||
i );
|
||||
}
|
||||
else
|
||||
{
|
||||
DevMsgRT( "%6.2f : %30s %6.2f : %6.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void C_BaseAnimatingOverlay::DoAnimationEvents( CStudioHdr *pStudioHdr )
|
||||
{
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() )
|
||||
return;
|
||||
|
||||
|
||||
int nSequences = pStudioHdr->GetNumSeq();
|
||||
|
||||
BaseClass::DoAnimationEvents( pStudioHdr );
|
||||
|
||||
bool watch = false; // Q_strstr( hdr->name, "rifle" ) ? true : false;
|
||||
|
||||
CheckForLayerChanges( pStudioHdr, gpGlobals->curtime ); // !!!
|
||||
|
||||
int j;
|
||||
for (j = 0; j < m_AnimOverlay.Count(); j++)
|
||||
{
|
||||
if ( m_AnimOverlay[j].m_nSequence >= nSequences )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't bother with 0-weight layers
|
||||
if ( m_AnimOverlay[j].m_flWeight == 0.0f || m_AnimOverlay[j].m_nOrder == MAX_OVERLAYS )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[j].m_nSequence );
|
||||
if ( seqdesc.numevents == 0 )
|
||||
continue;
|
||||
|
||||
// stalled?
|
||||
if (m_AnimOverlay[j].m_flCycle == m_flOverlayPrevEventCycle[j])
|
||||
continue;
|
||||
|
||||
bool bLoopingSequence = IsSequenceLooping( m_AnimOverlay[j].m_nSequence );
|
||||
|
||||
bool bLooped = false;
|
||||
|
||||
//in client code, m_flOverlayPrevEventCycle is set to -1 when we first start an overlay, looping or not
|
||||
if ( bLoopingSequence &&
|
||||
m_flOverlayPrevEventCycle[j] > 0.0f &&
|
||||
m_AnimOverlay[j].m_flCycle <= m_flOverlayPrevEventCycle[j] )
|
||||
{
|
||||
if (m_flOverlayPrevEventCycle[j] - m_AnimOverlay[j].m_flCycle > 0.5)
|
||||
{
|
||||
bLooped = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// things have backed up, which is bad since it'll probably result in a hitch in the animation playback
|
||||
// but, don't play events again for the same time slice
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mstudioevent_t *pevent = GetEventIndexForSequence( seqdesc );
|
||||
|
||||
// This makes sure events that occur at the end of a sequence occur are
|
||||
// sent before events that occur at the beginning of a sequence.
|
||||
if (bLooped)
|
||||
{
|
||||
for (int i = 0; i < (int)seqdesc.numevents; i++)
|
||||
{
|
||||
// ignore all non-client-side events
|
||||
if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
|
||||
{
|
||||
if ( !(pevent[i].type & AE_TYPE_CLIENT) )
|
||||
continue;
|
||||
}
|
||||
else if ( pevent[i].Event_OldSystem() < EVENT_CLIENT ) //Adrian - Support the old event system
|
||||
continue;
|
||||
|
||||
if ( pevent[i].cycle <= m_flOverlayPrevEventCycle[j] )
|
||||
continue;
|
||||
|
||||
if ( watch )
|
||||
{
|
||||
Msg( "%i FE %i Looped cycle %f, prev %f ev %f (time %.3f)\n",
|
||||
gpGlobals->tickcount,
|
||||
pevent[i].Event(),
|
||||
pevent[i].cycle,
|
||||
(float)m_flOverlayPrevEventCycle[j],
|
||||
(float)m_AnimOverlay[j].m_flCycle,
|
||||
gpGlobals->curtime );
|
||||
}
|
||||
|
||||
|
||||
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].Event(), pevent[ i ].pszOptions() );
|
||||
}
|
||||
|
||||
// Necessary to get the next loop working
|
||||
m_flOverlayPrevEventCycle[j] = -0.01;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)seqdesc.numevents; i++)
|
||||
{
|
||||
if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
|
||||
{
|
||||
if ( !(pevent[i].type & AE_TYPE_CLIENT) )
|
||||
continue;
|
||||
}
|
||||
else if ( pevent[i].Event_OldSystem() < EVENT_CLIENT ) //Adrian - Support the old event system
|
||||
continue;
|
||||
|
||||
bool bStartedSequence = ( m_flOverlayPrevEventCycle[j] > m_AnimOverlay[j].m_flCycle || m_flOverlayPrevEventCycle[j] == 0 );
|
||||
|
||||
if ( ( ( pevent[i].cycle > m_flOverlayPrevEventCycle[j] || bStartedSequence && pevent[i].cycle == 0 ) && pevent[i].cycle <= m_AnimOverlay[j].m_flCycle) )
|
||||
{
|
||||
if ( watch )
|
||||
{
|
||||
Msg( "%i (seq: %d) FE %i Normal cycle %f, prev %f ev %f (time %.3f)\n",
|
||||
gpGlobals->tickcount,
|
||||
(int)m_AnimOverlay[j].m_nSequence,
|
||||
(int)pevent[i].Event(),
|
||||
(float)pevent[i].cycle,
|
||||
(float)m_flOverlayPrevEventCycle[j],
|
||||
(float)m_AnimOverlay[j].m_flCycle,
|
||||
gpGlobals->curtime );
|
||||
}
|
||||
|
||||
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].Event(), pevent[ i ].pszOptions() );
|
||||
}
|
||||
}
|
||||
|
||||
m_flOverlayPrevEventCycle[j] = m_AnimOverlay[j].m_flCycle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CStudioHdr *C_BaseAnimatingOverlay::OnNewModel()
|
||||
{
|
||||
CStudioHdr *hdr = BaseClass::OnNewModel();
|
||||
|
||||
// Clear out animation layers
|
||||
for ( int i=0; i < m_AnimOverlay.Count(); i++ )
|
||||
{
|
||||
m_AnimOverlay[i].Reset();
|
||||
m_AnimOverlay[i].m_nOrder = MAX_OVERLAYS;
|
||||
}
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseAnimatingOverlay::CheckInterpChanges( void )
|
||||
{
|
||||
CDisableRangeChecks disableRangeChecks;
|
||||
|
||||
for (int i = 0; i < m_AnimOverlay.Count(); i++)
|
||||
{
|
||||
int iHead, iPrev1, iPrev2;
|
||||
m_iv_AnimOverlay[i].GetInterpolationInfo( gpGlobals->curtime, &iHead, &iPrev1, &iPrev2 );
|
||||
|
||||
float t0;
|
||||
CAnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
|
||||
|
||||
float t1;
|
||||
CAnimationLayer *pPrev = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
|
||||
|
||||
if ( !pHead || !pPrev )
|
||||
continue;
|
||||
|
||||
m_AnimOverlay[ i ].m_nInvalidatePhysicsBits = CheckForSequenceBoxChanges( *pHead, *pPrev );
|
||||
}
|
||||
|
||||
CheckForLayerPhysicsInvalidate();
|
||||
}
|
||||
|
||||
void C_BaseAnimatingOverlay::CheckForLayerPhysicsInvalidate( void )
|
||||
{
|
||||
// When the layers interpolate they may change the animation or bbox so we
|
||||
// have them accumulate the changes and call InvalidatePhysicsRecursive if any
|
||||
// changes are needed.
|
||||
int nInvalidatePhysicsChangeBits = 0;
|
||||
|
||||
int nLayerCount = m_AnimOverlay.Count();
|
||||
for ( int i = 0; i < nLayerCount; ++i )
|
||||
{
|
||||
int nChangeBits = m_AnimOverlay[ i ].m_nInvalidatePhysicsBits;
|
||||
if ( nChangeBits )
|
||||
{
|
||||
nInvalidatePhysicsChangeBits |= nChangeBits;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nInvalidatePhysicsChangeBits )
|
||||
{
|
||||
InvalidatePhysicsRecursive( nInvalidatePhysicsChangeBits );
|
||||
}
|
||||
}
|
77
game/client/c_baseanimatingoverlay.h
Normal file
77
game/client/c_baseanimatingoverlay.h
Normal file
@ -0,0 +1,77 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_BASEANIMATINGOVERLAY_H
|
||||
#define C_BASEANIMATINGOVERLAY_H
|
||||
#pragma once
|
||||
|
||||
#include "c_baseanimating.h"
|
||||
#include "toolframework/itoolframework.h"
|
||||
|
||||
// For shared code.
|
||||
#define CBaseAnimatingOverlay C_BaseAnimatingOverlay
|
||||
|
||||
|
||||
class C_BaseAnimatingOverlay : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_BaseAnimatingOverlay, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_INTERPOLATION();
|
||||
|
||||
// Inherited from C_BaseAnimating
|
||||
public:
|
||||
virtual void AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime );
|
||||
virtual void DoAnimationEvents( CStudioHdr *pStudioHdr );
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
virtual CStudioHdr *OnNewModel();
|
||||
|
||||
virtual bool Interpolate( float flCurrentTime );
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_OVERLAYS = 15,
|
||||
};
|
||||
|
||||
C_BaseAnimatingOverlay();
|
||||
CAnimationLayer* GetAnimOverlay( int i );
|
||||
void SetNumAnimOverlays( int num ); // This makes sure there is space for this # of layers.
|
||||
int GetNumAnimOverlays() const;
|
||||
void SetOverlayPrevEventCycle( int nSlot, float flValue );
|
||||
|
||||
void CheckInterpChanges( void );
|
||||
void CheckForLayerPhysicsInvalidate( void );
|
||||
|
||||
private:
|
||||
void CheckForLayerChanges( CStudioHdr *hdr, float currentTime );
|
||||
|
||||
CUtlVector < CAnimationLayer > m_AnimOverlay;
|
||||
CUtlVector < CInterpolatedVar< CAnimationLayer > > m_iv_AnimOverlay;
|
||||
|
||||
float m_flOverlayPrevEventCycle[ MAX_OVERLAYS ];
|
||||
|
||||
C_BaseAnimatingOverlay( const C_BaseAnimatingOverlay & ); // not defined, not accessible
|
||||
|
||||
friend void ResizeAnimationLayerCallback( void *pStruct, int offsetToUtlVector, int len );
|
||||
};
|
||||
|
||||
|
||||
inline void C_BaseAnimatingOverlay::SetOverlayPrevEventCycle( int nSlot, float flValue )
|
||||
{
|
||||
m_flOverlayPrevEventCycle[nSlot] = flValue;
|
||||
}
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BaseAnimatingOverlay);
|
||||
|
||||
|
||||
#endif // C_BASEANIMATINGOVERLAY_H
|
||||
|
||||
|
||||
|
||||
|
96
game/client/c_basecombatcharacter.cpp
Normal file
96
game/client/c_basecombatcharacter.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's C_BaseCombatCharacter entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basecombatcharacter.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#if defined( CBaseCombatCharacter )
|
||||
#undef CBaseCombatCharacter
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseCombatCharacter::C_BaseCombatCharacter()
|
||||
{
|
||||
for ( int i=0; i < m_iAmmo.Count(); i++ )
|
||||
m_iAmmo.Set( i, 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseCombatCharacter::~C_BaseCombatCharacter()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns the amount of ammunition of the specified type the character's carrying
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseCombatCharacter::GetAmmoCount( char *szName ) const
|
||||
{
|
||||
return GetAmmoCount( g_pGameRules->GetAmmoDef()->Index(szName) );
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Overload our muzzle flash and send it to any actively held weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::DoMuzzleFlash()
|
||||
{
|
||||
// Our weapon takes our muzzle flash command
|
||||
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
{
|
||||
pWeapon->DoMuzzleFlash();
|
||||
//NOTENOTE: We do not chain to the base here
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::DoMuzzleFlash();
|
||||
}
|
||||
}
|
||||
IMPLEMENT_CLIENTCLASS(C_BaseCombatCharacter, DT_BaseCombatCharacter, CBaseCombatCharacter);
|
||||
|
||||
// Only send active weapon index to local player
|
||||
BEGIN_RECV_TABLE_NOBASE( C_BaseCombatCharacter, DT_BCCLocalPlayerExclusive )
|
||||
RecvPropTime( RECVINFO( m_flNextAttack ) ),
|
||||
|
||||
|
||||
RecvPropArray3( RECVINFO_ARRAY(m_hMyWeapons), RecvPropEHandle( RECVINFO( m_hMyWeapons[0] ) ) ),
|
||||
|
||||
|
||||
END_RECV_TABLE();
|
||||
|
||||
|
||||
BEGIN_RECV_TABLE(C_BaseCombatCharacter, DT_BaseCombatCharacter)
|
||||
RecvPropDataTable( "bcc_localdata", 0, 0, &REFERENCE_RECV_TABLE(DT_BCCLocalPlayerExclusive) ),
|
||||
RecvPropEHandle( RECVINFO( m_hActiveWeapon ) ),
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
BEGIN_PREDICTION_DATA( C_BaseCombatCharacter )
|
||||
|
||||
DEFINE_PRED_ARRAY( m_iAmmo, FIELD_INTEGER, MAX_AMMO_TYPES, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_flNextAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_hActiveWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_ARRAY( m_hMyWeapons, FIELD_EHANDLE, MAX_WEAPONS, FTYPEDESC_INSENDTABLE ),
|
||||
|
||||
END_PREDICTION_DATA()
|
140
game/client/c_basecombatcharacter.h
Normal file
140
game/client/c_basecombatcharacter.h
Normal file
@ -0,0 +1,140 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Defines the client-side representation of CBaseCombatCharacter.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_BASECOMBATCHARACTER_H
|
||||
#define C_BASECOMBATCHARACTER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "shareddefs.h"
|
||||
#include "c_baseflex.h"
|
||||
|
||||
#define BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE 0.9f
|
||||
|
||||
class C_BaseCombatWeapon;
|
||||
class C_WeaponCombatShield;
|
||||
|
||||
class C_BaseCombatCharacter : public C_BaseFlex
|
||||
{
|
||||
DECLARE_CLASS( C_BaseCombatCharacter, C_BaseFlex );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
C_BaseCombatCharacter( void );
|
||||
virtual ~C_BaseCombatCharacter( void );
|
||||
|
||||
virtual bool IsBaseCombatCharacter( void ) { return true; };
|
||||
virtual C_BaseCombatCharacter *MyCombatCharacterPointer( void ) { return this; }
|
||||
|
||||
// -----------------------
|
||||
// Vision
|
||||
// -----------------------
|
||||
enum FieldOfViewCheckType { USE_FOV, DISREGARD_FOV };
|
||||
bool IsAbleToSee( const CBaseEntity *entity, FieldOfViewCheckType checkFOV ); // Visible starts with line of sight, and adds all the extra game checks like fog, smoke, camo...
|
||||
bool IsAbleToSee( C_BaseCombatCharacter *pBCC, FieldOfViewCheckType checkFOV ); // Visible starts with line of sight, and adds all the extra game checks like fog, smoke, camo...
|
||||
|
||||
virtual bool IsLookingTowards( const CBaseEntity *target, float cosTolerance = BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE ) const; // return true if our view direction is pointing at the given target, within the cosine of the angular tolerance. LINE OF SIGHT IS NOT CHECKED.
|
||||
virtual bool IsLookingTowards( const Vector &target, float cosTolerance = BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE ) const; // return true if our view direction is pointing at the given target, within the cosine of the angular tolerance. LINE OF SIGHT IS NOT CHECKED.
|
||||
|
||||
virtual bool IsInFieldOfView( CBaseEntity *entity ) const; // Calls IsLookingAt with the current field of view.
|
||||
virtual bool IsInFieldOfView( const Vector &pos ) const;
|
||||
|
||||
enum LineOfSightCheckType
|
||||
{
|
||||
IGNORE_NOTHING,
|
||||
IGNORE_ACTORS
|
||||
};
|
||||
virtual bool IsLineOfSightClear( CBaseEntity *entity, LineOfSightCheckType checkType = IGNORE_NOTHING ) const;// strictly LOS check with no other considerations
|
||||
virtual bool IsLineOfSightClear( const Vector &pos, LineOfSightCheckType checkType = IGNORE_NOTHING, CBaseEntity *entityToIgnore = NULL ) const;
|
||||
|
||||
// -----------------------
|
||||
// Ammo
|
||||
// -----------------------
|
||||
void RemoveAmmo( int iCount, int iAmmoIndex );
|
||||
void RemoveAmmo( int iCount, const char *szName );
|
||||
void RemoveAllAmmo( );
|
||||
int GetAmmoCount( int iAmmoIndex ) const;
|
||||
int GetAmmoCount( char *szName ) const;
|
||||
|
||||
virtual C_BaseCombatWeapon* Weapon_OwnsThisType( const char *pszWeapon, int iSubType = 0 ) const; // True if already owns a weapon of this class
|
||||
virtual int Weapon_GetSlot( const char *pszWeapon, int iSubType = 0 ) const; // Returns -1 if they don't have one
|
||||
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 );
|
||||
virtual bool Weapon_CanSwitchTo(C_BaseCombatWeapon *pWeapon);
|
||||
|
||||
// I can't use my current weapon anymore. Switch me to the next best weapon.
|
||||
bool SwitchToNextBestWeapon(C_BaseCombatWeapon *pCurrent);
|
||||
|
||||
virtual C_BaseCombatWeapon *GetActiveWeapon( void ) const;
|
||||
int WeaponCount() const;
|
||||
virtual C_BaseCombatWeapon *GetWeapon( int i ) const;
|
||||
|
||||
// This is a sort of hack back-door only used by physgun!
|
||||
void SetAmmoCount( int iCount, int iAmmoIndex );
|
||||
|
||||
float GetNextAttack() const { return m_flNextAttack; }
|
||||
void SetNextAttack( float flWait ) { m_flNextAttack = flWait; }
|
||||
|
||||
virtual int BloodColor();
|
||||
|
||||
// Blood color (see BLOOD_COLOR_* macros in baseentity.h)
|
||||
void SetBloodColor( int nBloodColor );
|
||||
|
||||
virtual void DoMuzzleFlash();
|
||||
|
||||
public:
|
||||
|
||||
// BEGIN PREDICTION DATA COMPACTION (these fields are together to allow for faster copying in prediction system)
|
||||
float m_flNextAttack;
|
||||
|
||||
private:
|
||||
bool ComputeLOS( const Vector &vecEyePosition, const Vector &vecTarget ) const;
|
||||
|
||||
private:
|
||||
CNetworkArray( int, m_iAmmo, MAX_AMMO_TYPES );
|
||||
CHandle<C_BaseCombatWeapon> m_hMyWeapons[MAX_WEAPONS];
|
||||
CHandle< C_BaseCombatWeapon > m_hActiveWeapon;
|
||||
|
||||
// END PREDICTION DATA COMPACTION
|
||||
|
||||
protected:
|
||||
|
||||
int m_bloodColor; // color of blood particless
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
private:
|
||||
C_BaseCombatCharacter( const C_BaseCombatCharacter & ); // not defined, not accessible
|
||||
|
||||
|
||||
//-----------------------
|
||||
|
||||
|
||||
};
|
||||
|
||||
inline C_BaseCombatCharacter *ToBaseCombatCharacter( C_BaseEntity *pEntity )
|
||||
{
|
||||
return pEntity ? pEntity->MyCombatCharacterPointer() : NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int C_BaseCombatCharacter::WeaponCount() const
|
||||
{
|
||||
return MAX_WEAPONS;
|
||||
}
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BaseCombatCharacter);
|
||||
|
||||
#endif // C_BASECOMBATCHARACTER_H
|
545
game/client/c_basecombatweapon.cpp
Normal file
545
game/client/c_basecombatweapon.cpp
Normal file
@ -0,0 +1,545 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side implementation of CBaseCombatWeapon.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "history_resource.h"
|
||||
#include "iclientmode.h"
|
||||
#include "iinput.h"
|
||||
#include "weapon_selection.h"
|
||||
#include "hud_crosshair.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "hltvcamera.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "toolframework/itoolframework.h"
|
||||
#include "toolframework_client.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::SetDormant( bool bDormant )
|
||||
{
|
||||
// If I'm going from active to dormant and I'm carried by another player, holster me.
|
||||
if ( !IsDormant() && bDormant && !IsCarriedByLocalPlayer() )
|
||||
{
|
||||
Holster( NULL );
|
||||
}
|
||||
|
||||
BaseClass::SetDormant( bDormant );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||
{
|
||||
BaseClass::NotifyShouldTransmit(state);
|
||||
|
||||
if (state == SHOULDTRANSMIT_END)
|
||||
{
|
||||
if (m_iState == WEAPON_IS_ACTIVE)
|
||||
{
|
||||
m_iState = WEAPON_IS_CARRIED_BY_PLAYER;
|
||||
}
|
||||
}
|
||||
else if( state == SHOULDTRANSMIT_START )
|
||||
{
|
||||
if( m_iState == WEAPON_IS_CARRIED_BY_PLAYER )
|
||||
{
|
||||
if( GetOwner() && GetOwner()->GetActiveWeapon() == this )
|
||||
{
|
||||
// Restore the Activeness of the weapon if we client-twiddled it off in the first case above.
|
||||
m_iState = WEAPON_IS_ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline bool ShouldDrawLocalPlayer( C_BasePlayer *pl )
|
||||
{
|
||||
|
||||
Assert( pl );
|
||||
return pl->ShouldDrawLocalPlayer();
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::OnRestore()
|
||||
{
|
||||
BaseClass::OnRestore();
|
||||
|
||||
// if the player is holding this weapon,
|
||||
// mark it as just restored so it won't show as a new pickup
|
||||
if ( C_BasePlayer::IsLocalPlayer( GetOwner() ) )
|
||||
{
|
||||
m_bJustRestored = true;
|
||||
}
|
||||
}
|
||||
|
||||
int C_BaseCombatWeapon::GetWorldModelIndex( void )
|
||||
{
|
||||
return m_iWorldModelIndex;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bnewentity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// If it's being carried by the *local* player, on the first update,
|
||||
// find the registered weapon for this ID
|
||||
|
||||
C_BaseCombatCharacter *pOwner = GetOwner();
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( pOwner );
|
||||
|
||||
// check if weapon is carried by local player
|
||||
bool bIsLocalPlayer = C_BasePlayer::IsLocalPlayer( pPlayer );
|
||||
if ( bIsLocalPlayer )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD( C_BasePlayer::GetSplitScreenSlotForPlayer( pPlayer ) );
|
||||
|
||||
// If I was just picked up, or created & immediately carried, add myself to this client's list of weapons
|
||||
if ( ( m_iState != WEAPON_NOT_CARRIED ) &&
|
||||
( m_iOldState == WEAPON_NOT_CARRIED ) )
|
||||
{
|
||||
// Tell the HUD this weapon's been picked up
|
||||
if ( ShouldDrawPickup() )
|
||||
{
|
||||
CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
|
||||
if ( pHudSelection )
|
||||
{
|
||||
pHudSelection->OnWeaponPickup( this );
|
||||
}
|
||||
|
||||
pPlayer->EmitSound( "Player.PickupWeapon" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateVisibility();
|
||||
|
||||
m_iOldState = m_iState;
|
||||
|
||||
m_bJustRestored = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is anyone carrying it?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsBeingCarried() const
|
||||
{
|
||||
return ( m_hOwner.Get() != NULL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is the carrier alive?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsCarrierAlive() const
|
||||
{
|
||||
if ( !m_hOwner.Get() )
|
||||
return false;
|
||||
|
||||
return m_hOwner.Get()->GetHealth() > 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Should this object cast shadows?
|
||||
//-----------------------------------------------------------------------------
|
||||
ShadowType_t C_BaseCombatWeapon::ShadowCastType()
|
||||
{
|
||||
if ( IsEffectActive( /*EF_NODRAW |*/ EF_NOSHADOW ) )
|
||||
return SHADOWS_NONE;
|
||||
|
||||
if (!IsBeingCarried())
|
||||
return SHADOWS_RENDER_TO_TEXTURE;
|
||||
|
||||
if (IsCarriedByLocalPlayer())
|
||||
return SHADOWS_NONE;
|
||||
|
||||
return (m_iState != WEAPON_IS_CARRIED_BY_PLAYER) ? SHADOWS_RENDER_TO_TEXTURE : SHADOWS_NONE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This weapon is the active weapon, and it should now draw anything
|
||||
// it wants to. This gets called every frame.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::Redraw()
|
||||
{
|
||||
if ( GetClientMode()->ShouldDrawCrosshair() )
|
||||
{
|
||||
DrawCrosshair();
|
||||
}
|
||||
|
||||
// ammo drawing has been moved into hud_ammo.cpp
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draw the weapon's crosshair
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::DrawCrosshair()
|
||||
{
|
||||
#ifndef INFESTED_DLL
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
Color clr = GetHud().m_clrNormal;
|
||||
/*
|
||||
|
||||
// TEST: if the thing under your crosshair is on a different team, light the crosshair with a different color.
|
||||
Vector vShootPos, vShootAngles;
|
||||
GetShootPosition( vShootPos, vShootAngles );
|
||||
|
||||
Vector vForward;
|
||||
AngleVectors( vShootAngles, &vForward );
|
||||
|
||||
|
||||
// Change the color depending on if we're looking at a friend or an enemy.
|
||||
CPartitionFilterListMask filter( PARTITION_ALL_CLIENT_EDICTS );
|
||||
trace_t tr;
|
||||
traceline->TraceLine( vShootPos, vShootPos + vForward * 10000, COLLISION_GROUP_NONE, MASK_SHOT, &tr, true, ~0, &filter );
|
||||
|
||||
if ( tr.index != 0 && tr.index != INVALID_CLIENTENTITY_HANDLE )
|
||||
{
|
||||
C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( tr.index );
|
||||
if ( pEnt )
|
||||
{
|
||||
if ( pEnt->GetTeamNumber() != player->GetTeamNumber() )
|
||||
{
|
||||
g = b = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
CHudCrosshair *crosshair = GET_HUDELEMENT( CHudCrosshair );
|
||||
if ( !crosshair )
|
||||
return;
|
||||
|
||||
// Find out if this weapon's auto-aimed onto a target
|
||||
bool bOnTarget = ( m_iState == WEAPON_IS_ACTIVE ) && player->m_fOnTarget;
|
||||
|
||||
if ( player->GetFOV() >= 90 )
|
||||
{
|
||||
// normal crosshairs
|
||||
if ( bOnTarget && GetWpnData().iconAutoaim )
|
||||
{
|
||||
clr[3] = 255;
|
||||
|
||||
crosshair->SetCrosshair( GetWpnData().iconAutoaim, clr );
|
||||
}
|
||||
else if ( GetWpnData().iconCrosshair )
|
||||
{
|
||||
clr[3] = 255;
|
||||
crosshair->SetCrosshair( GetWpnData().iconCrosshair, clr );
|
||||
}
|
||||
else
|
||||
{
|
||||
crosshair->ResetCrosshair();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Color white( 255, 255, 255, 255 );
|
||||
|
||||
// zoomed crosshairs
|
||||
if (bOnTarget && GetWpnData().iconZoomedAutoaim)
|
||||
crosshair->SetCrosshair(GetWpnData().iconZoomedAutoaim, white);
|
||||
else if ( GetWpnData().iconZoomedCrosshair )
|
||||
crosshair->SetCrosshair( GetWpnData().iconZoomedCrosshair, white );
|
||||
else
|
||||
crosshair->ResetCrosshair();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This weapon is the active weapon, and the viewmodel for it was just drawn.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::ViewModelDrawn( C_BaseViewModel *pViewModel )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if this client's carrying this weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsCarriedByLocalPlayer( void )
|
||||
{
|
||||
if ( !GetOwner() )
|
||||
return false;
|
||||
|
||||
return ( C_BasePlayer::IsLocalPlayer( GetOwner() ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if this weapon is the local client's currently wielded weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsActiveByLocalPlayer( void )
|
||||
{
|
||||
if ( IsCarriedByLocalPlayer() )
|
||||
{
|
||||
return (m_iState == WEAPON_IS_ACTIVE);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool C_BaseCombatWeapon::GetShootPosition( Vector &vOrigin, QAngle &vAngles )
|
||||
{
|
||||
// Get the entity because the weapon doesn't have the right angles.
|
||||
C_BaseCombatCharacter *pEnt = ToBaseCombatCharacter( GetOwner() );
|
||||
if ( pEnt )
|
||||
{
|
||||
if ( pEnt == C_BasePlayer::GetLocalPlayer() )
|
||||
{
|
||||
vAngles = pEnt->EyeAngles();
|
||||
}
|
||||
else
|
||||
{
|
||||
vAngles = pEnt->GetRenderAngles();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vAngles.Init();
|
||||
}
|
||||
|
||||
C_BasePlayer *player = ToBasePlayer( pEnt );
|
||||
bool bUseViewModel = false;
|
||||
if ( C_BasePlayer::IsLocalPlayer( pEnt ) )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( pEnt );
|
||||
bUseViewModel = !player->ShouldDrawLocalPlayer();
|
||||
}
|
||||
|
||||
QAngle vDummy;
|
||||
if ( IsActiveByLocalPlayer() && bUseViewModel )
|
||||
{
|
||||
C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
|
||||
if ( vm )
|
||||
{
|
||||
int iAttachment = vm->LookupAttachment( "muzzle" );
|
||||
if ( vm->GetAttachment( iAttachment, vOrigin, vDummy ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Thirdperson
|
||||
int iAttachment = LookupAttachment( "muzzle" );
|
||||
if ( GetAttachment( iAttachment, vOrigin, vDummy ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
vOrigin = GetRenderOrigin();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::ShouldDraw( void )
|
||||
{
|
||||
if ( m_iWorldModelIndex == 0 )
|
||||
return false;
|
||||
|
||||
// FIXME: All weapons with owners are set to transmit in CBaseCombatWeapon::UpdateTransmitState,
|
||||
// even if they have EF_NODRAW set, so we have to check this here. Ideally they would never
|
||||
// transmit except for the weapons owned by the local player.
|
||||
if ( IsEffectActive( EF_NODRAW ) )
|
||||
return false;
|
||||
|
||||
C_BaseCombatCharacter *pOwner = GetOwner();
|
||||
|
||||
// weapon has no owner, always draw it
|
||||
if ( !pOwner )
|
||||
return true;
|
||||
|
||||
bool bIsActive = ( m_iState == WEAPON_IS_ACTIVE );
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
|
||||
// carried by local player?
|
||||
if ( pOwner == pLocalPlayer )
|
||||
{
|
||||
// Only ever show the active weapon
|
||||
if ( !bIsActive )
|
||||
return false;
|
||||
|
||||
// 3rd person mode
|
||||
if ( pLocalPlayer->ShouldDrawLocalPlayer() )
|
||||
return true;
|
||||
|
||||
// don't draw active weapon if not in some kind of 3rd person mode, the viewmodel will do that
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's a player, then only show active weapons
|
||||
if ( pOwner->IsPlayer() )
|
||||
{
|
||||
// Show it if it's active...
|
||||
return bIsActive;
|
||||
}
|
||||
|
||||
// FIXME: We may want to only show active weapons on NPCs
|
||||
// These are carried by AIs; always show them
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true if a weapon-pickup icon should be displayed when this weapon is received
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::ShouldDrawPickup( void )
|
||||
{
|
||||
if ( GetWeaponFlags() & ITEM_FLAG_NOITEMPICKUP )
|
||||
return false;
|
||||
|
||||
if ( m_bJustRestored )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Hooks into the fast path render system
|
||||
//----------------------------------------------------------------------------
|
||||
IClientModelRenderable* C_BaseCombatWeapon::GetClientModelRenderable()
|
||||
{
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
// check if local player chases owner of this weapon in first person
|
||||
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( localplayer && localplayer->IsObserver() && GetOwner() )
|
||||
{
|
||||
// don't draw weapon if chasing this guy as spectator
|
||||
// we don't check that in ShouldDraw() since this may change
|
||||
// without notification
|
||||
if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
|
||||
localplayer->GetObserverTarget() == GetOwner() )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !BaseClass::GetClientModelRenderable() )
|
||||
return NULL;
|
||||
|
||||
EnsureCorrectRenderingModel();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
|
||||
// by this player, otherwise draw the worldmodel.
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseCombatWeapon::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
VPROF_BUDGET( "C_BaseCombatWeapon::DrawModel", VPROF_BUDGETGROUP_MODEL_RENDERING );
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
if ( !IsVisible() )
|
||||
return 0;
|
||||
|
||||
// check if local player chases owner of this weapon in first person
|
||||
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
|
||||
|
||||
if ( localplayer && localplayer->IsObserver() && GetOwner() )
|
||||
{
|
||||
// don't draw weapon if chasing this guy as spectator
|
||||
// we don't check that in ShouldDraw() since this may change
|
||||
// without notification
|
||||
|
||||
if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
|
||||
localplayer->GetObserverTarget() == GetOwner() )
|
||||
return false;
|
||||
}
|
||||
|
||||
// See comment below
|
||||
EnsureCorrectRenderingModel();
|
||||
|
||||
return BaseClass::DrawModel( flags, instance );
|
||||
}
|
||||
|
||||
// If the local player is visible (thirdperson mode, tf2 taunts, etc., then make sure that we are using the
|
||||
// w_ (world) model not the v_ (view) model or else the model can flicker, etc.
|
||||
// Otherwise, if we're not the local player, always use the world model
|
||||
void C_BaseCombatWeapon::EnsureCorrectRenderingModel()
|
||||
{
|
||||
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( localplayer &&
|
||||
localplayer == GetOwner() &&
|
||||
!localplayer->ShouldDrawLocalPlayer() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// BRJ 10/14/02
|
||||
// FIXME: Remove when Yahn's client-side prediction is done
|
||||
// It's a hacky workaround for the model indices fighting
|
||||
// (GetRenderBounds uses the model index, which is for the view model)
|
||||
SetModelIndex( GetWorldModelIndex() );
|
||||
|
||||
// Validate our current sequence just in case ( in theory the view and weapon models should have the same sequences for sequences that overlap at least )
|
||||
CStudioHdr *pStudioHdr = GetModelPtr();
|
||||
if ( pStudioHdr &&
|
||||
GetSequence() >= pStudioHdr->GetNumSeq() )
|
||||
{
|
||||
SetSequence( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// tool recording
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::GetToolRecordingState( KeyValues *msg )
|
||||
{
|
||||
if ( !ToolsEnabled() )
|
||||
return;
|
||||
|
||||
int nModelIndex = GetModelIndex();
|
||||
int nWorldModelIndex = GetWorldModelIndex();
|
||||
if ( nModelIndex != nWorldModelIndex )
|
||||
{
|
||||
SetModelIndex( nWorldModelIndex );
|
||||
}
|
||||
|
||||
BaseClass::GetToolRecordingState( msg );
|
||||
|
||||
if ( m_iState == WEAPON_NOT_CARRIED )
|
||||
{
|
||||
BaseEntityRecordingState_t *pBaseEntity = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" );
|
||||
pBaseEntity->m_nOwner = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->SetInt( "worldmodel", 1 );
|
||||
if ( m_iState == WEAPON_IS_ACTIVE )
|
||||
{
|
||||
BaseEntityRecordingState_t *pBaseEntity = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" );
|
||||
pBaseEntity->m_bVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nModelIndex != nWorldModelIndex )
|
||||
{
|
||||
SetModelIndex( nModelIndex );
|
||||
}
|
||||
}
|
22
game/client/c_basecombatweapon.h
Normal file
22
game/client/c_basecombatweapon.h
Normal file
@ -0,0 +1,22 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CBaseCombatWeapon entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef C_BASECOMBATWEAPON_H
|
||||
#define C_BASECOMBATWEAPON_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basecombatweapon_shared.h"
|
||||
#include "weapons_resource.h"
|
||||
|
||||
class CViewSetup;
|
||||
class C_BaseViewModel;
|
||||
|
||||
#endif // C_BASECOMBATWEAPON
|
28
game/client/c_basedoor.cpp
Normal file
28
game/client/c_basedoor.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basedoor.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#ifdef CBaseDoor
|
||||
#undef CBaseDoor
|
||||
#endif
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_BaseDoor, DT_BaseDoor, CBaseDoor)
|
||||
RecvPropFloat(RECVINFO(m_flWaveHeight)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_BaseDoor::C_BaseDoor( void )
|
||||
{
|
||||
m_flWaveHeight = 0.0f;
|
||||
}
|
||||
|
||||
C_BaseDoor::~C_BaseDoor( void )
|
||||
{
|
||||
}
|
33
game/client/c_basedoor.h
Normal file
33
game/client/c_basedoor.h
Normal file
@ -0,0 +1,33 @@
|
||||
//========= Copyright Š 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#if !defined( C_BASEDOOR_H )
|
||||
#define C_BASEDOOR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseentity.h"
|
||||
#include "c_basetoggle.h"
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
#define CBaseDoor C_BaseDoor
|
||||
#endif
|
||||
|
||||
class C_BaseDoor : public C_BaseToggle
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseDoor, C_BaseToggle );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BaseDoor( void );
|
||||
~C_BaseDoor( void );
|
||||
|
||||
public:
|
||||
float m_flWaveHeight;
|
||||
};
|
||||
|
||||
#endif // C_BASEDOOR_H
|
6436
game/client/c_baseentity.cpp
Normal file
6436
game/client/c_baseentity.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2508
game/client/c_baseentity.h
Normal file
2508
game/client/c_baseentity.h
Normal file
File diff suppressed because it is too large
Load Diff
2144
game/client/c_baseflex.cpp
Normal file
2144
game/client/c_baseflex.cpp
Normal file
File diff suppressed because it is too large
Load Diff
309
game/client/c_baseflex.h
Normal file
309
game/client/c_baseflex.h
Normal file
@ -0,0 +1,309 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
// Client-side CBasePlayer
|
||||
|
||||
#ifndef C_STUDIOFLEX_H
|
||||
#define C_STUDIOFLEX_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "c_baseanimating.h"
|
||||
#include "c_baseanimatingoverlay.h"
|
||||
#include "sceneentity_shared.h"
|
||||
|
||||
#include "UtlVector.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Item in list of loaded scene files
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFlexSceneFile
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_FLEX_FILENAME = 128,
|
||||
};
|
||||
|
||||
char filename[ MAX_FLEX_FILENAME ];
|
||||
void *buffer;
|
||||
};
|
||||
|
||||
// For phoneme emphasis track
|
||||
struct Emphasized_Phoneme;
|
||||
class CSentence;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BaseFlex : public C_BaseAnimatingOverlay
|
||||
{
|
||||
DECLARE_CLASS( C_BaseFlex, C_BaseAnimatingOverlay );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_INTERPOLATION();
|
||||
|
||||
C_BaseFlex();
|
||||
virtual ~C_BaseFlex();
|
||||
|
||||
virtual void Spawn();
|
||||
|
||||
virtual IClientModelRenderable* GetClientModelRenderable();
|
||||
|
||||
virtual void InitPhonemeMappings();
|
||||
|
||||
void SetupMappings( char const *pchFileRoot );
|
||||
|
||||
virtual CStudioHdr *OnNewModel( void );
|
||||
|
||||
virtual void StandardBlendingRules( CStudioHdr *hdr, Vector pos[], QuaternionAligned q[], float currentTime, int boneMask );
|
||||
|
||||
virtual void OnThreadedDrawSetup();
|
||||
|
||||
// model specific
|
||||
virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
|
||||
virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
|
||||
virtual bool UsesFlexDelayedWeights();
|
||||
|
||||
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
|
||||
|
||||
virtual void GetToolRecordingState( KeyValues *msg );
|
||||
|
||||
// Called at the lowest level to actually apply a flex animation
|
||||
void AddFlexAnimation( CSceneEventInfo *info );
|
||||
|
||||
void SetFlexWeight( LocalFlexController_t index, float value );
|
||||
float GetFlexWeight( LocalFlexController_t index );
|
||||
|
||||
// Look up flex controller index by global name
|
||||
LocalFlexController_t FindFlexController( const char *szName );
|
||||
|
||||
public:
|
||||
Vector m_viewtarget;
|
||||
CInterpolatedVar< Vector > m_iv_viewtarget;
|
||||
// indexed by model local flexcontroller
|
||||
float m_flexWeight[MAXSTUDIOFLEXCTRL];
|
||||
CInterpolatedVarArray< float, MAXSTUDIOFLEXCTRL > m_iv_flexWeight;
|
||||
|
||||
int m_blinktoggle;
|
||||
|
||||
static int AddGlobalFlexController( char *szName );
|
||||
static char const *GetGlobalFlexControllerName( int idx );
|
||||
|
||||
// bah, this should be unified with all prev/current stuff.
|
||||
|
||||
public:
|
||||
|
||||
// Keep track of what scenes are being played
|
||||
void StartChoreoScene( CChoreoScene *scene );
|
||||
void RemoveChoreoScene( CChoreoScene *scene );
|
||||
|
||||
// Start the specifics of an scene event
|
||||
virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, C_BaseEntity *pTarget );
|
||||
|
||||
virtual bool ProcessSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||
|
||||
// Remove all playing events
|
||||
void ClearSceneEvents( CChoreoScene *scene, bool canceled );
|
||||
|
||||
// Stop specifics of event
|
||||
virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled );
|
||||
|
||||
// Add the event to the queue for this actor
|
||||
void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, C_BaseEntity *pTarget = NULL, bool bClientSide = false, C_SceneEntity *pSceneEntity = NULL );
|
||||
|
||||
// Remove the event from the queue for this actor
|
||||
void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill );
|
||||
|
||||
// Checks to see if the event should be considered "completed"
|
||||
bool CheckSceneEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event );
|
||||
|
||||
// Checks to see if a event should be considered "completed"
|
||||
virtual bool CheckSceneEventCompletion( CSceneEventInfo *info, float currenttime, CChoreoScene *scene, CChoreoEvent *event );
|
||||
|
||||
int FlexControllerLocalToGlobal( const flexsettinghdr_t *pSettinghdr, int key );
|
||||
void EnsureTranslations( const flexsettinghdr_t *pSettinghdr );
|
||||
|
||||
// For handling scene files
|
||||
const void *FindSceneFile( const char *filename );
|
||||
|
||||
static void InvalidateFlexCaches();
|
||||
bool IsFlexCacheValid() const;
|
||||
|
||||
private:
|
||||
Vector SetViewTarget( CStudioHdr *pStudioHdr, const float *pGlobalFlexWeight );
|
||||
void RunFlexRules( CStudioHdr *pStudioHdr, const float *pGlobalFlexWeight, float *dest );
|
||||
|
||||
// Manipulation of events for the object
|
||||
// Should be called by think function to process all scene events
|
||||
// The default implementation resets m_flexWeight array and calls
|
||||
// AddSceneEvents
|
||||
void ProcessSceneEvents( bool bFlexEvents, float *pGlobalFlexWeight );
|
||||
|
||||
// Assumes m_flexWeight array has been set up, this adds the actual currently playing
|
||||
// expressions to the flex weights and adds other scene events as needed
|
||||
bool ProcessSceneEvent( float *pGlobalFlexWeight, bool bFlexEvents, CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||
|
||||
bool RequestStartSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget );
|
||||
|
||||
bool ProcessFlexAnimationSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||
bool ProcessFlexSettingSceneEvent( float *pGlobalFlexWeight, CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||
void AddFlexSetting( float *pGlobalFlexWeight, const char *expr, float scale,
|
||||
const flexsettinghdr_t *pSettinghdr, bool newexpression );
|
||||
|
||||
// Array of active SceneEvents, in order oldest to newest
|
||||
CUtlVector < CSceneEventInfo > m_SceneEvents;
|
||||
CUtlVector < CChoreoScene * > m_ActiveChoreoScenes;
|
||||
|
||||
bool HasSceneEvents() const;
|
||||
|
||||
private:
|
||||
// Mapping for each loaded scene file used by this actor
|
||||
struct FS_LocalToGlobal_t
|
||||
{
|
||||
explicit FS_LocalToGlobal_t() :
|
||||
m_Key( 0 ),
|
||||
m_nCount( 0 ),
|
||||
m_Mapping( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
explicit FS_LocalToGlobal_t( const flexsettinghdr_t *key ) :
|
||||
m_Key( key ),
|
||||
m_nCount( 0 ),
|
||||
m_Mapping( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void SetCount( int count )
|
||||
{
|
||||
Assert( !m_Mapping );
|
||||
Assert( count > 0 );
|
||||
m_nCount = count;
|
||||
m_Mapping = new int[ m_nCount ];
|
||||
Q_memset( m_Mapping, 0, m_nCount * sizeof( int ) );
|
||||
}
|
||||
|
||||
FS_LocalToGlobal_t( const FS_LocalToGlobal_t& src )
|
||||
{
|
||||
m_Key = src.m_Key;
|
||||
delete m_Mapping;
|
||||
m_Mapping = new int[ src.m_nCount ];
|
||||
Q_memcpy( m_Mapping, src.m_Mapping, src.m_nCount * sizeof( int ) );
|
||||
|
||||
m_nCount = src.m_nCount;
|
||||
}
|
||||
|
||||
~FS_LocalToGlobal_t()
|
||||
{
|
||||
delete m_Mapping;
|
||||
m_nCount = 0;
|
||||
m_Mapping = 0;
|
||||
}
|
||||
|
||||
const flexsettinghdr_t *m_Key;
|
||||
int m_nCount;
|
||||
int *m_Mapping;
|
||||
};
|
||||
|
||||
static bool FlexSettingLessFunc( const FS_LocalToGlobal_t& lhs, const FS_LocalToGlobal_t& rhs );
|
||||
|
||||
CUtlRBTree< FS_LocalToGlobal_t, unsigned short > m_LocalToGlobal;
|
||||
|
||||
float m_blinktime;
|
||||
int m_prevblinktoggle;
|
||||
|
||||
int m_iBlink;
|
||||
LocalFlexController_t m_iEyeUpdown;
|
||||
LocalFlexController_t m_iEyeRightleft;
|
||||
int m_iMouthAttachment;
|
||||
|
||||
float *m_flFlexDelayedWeight;
|
||||
|
||||
int m_iMostRecentFlexCounter;
|
||||
Vector m_CachedViewTarget;
|
||||
CUtlVector< float > m_CachedFlexWeights;
|
||||
CUtlVector< float > m_CachedDelayedFlexWeights;
|
||||
|
||||
// shared flex controllers
|
||||
static int g_numflexcontrollers;
|
||||
static char *g_flexcontroller[MAXSTUDIOFLEXCTRL*4]; // room for global set of flexcontrollers
|
||||
static float s_pGlobalFlexWeight[MAXSTUDIOFLEXCTRL*4];
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
PHONEME_CLASS_WEAK = 0,
|
||||
PHONEME_CLASS_NORMAL,
|
||||
PHONEME_CLASS_STRONG,
|
||||
|
||||
NUM_PHONEME_CLASSES
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
struct Emphasized_Phoneme
|
||||
{
|
||||
// Global fields, setup at start
|
||||
char classname[ 64 ];
|
||||
bool required;
|
||||
// Global fields setup first time tracks played
|
||||
bool basechecked;
|
||||
const flexsettinghdr_t *base;
|
||||
const flexsetting_t *exp;
|
||||
|
||||
// Local fields, processed for each sentence
|
||||
bool valid;
|
||||
float amount;
|
||||
};
|
||||
|
||||
Emphasized_Phoneme m_PhonemeClasses[ NUM_PHONEME_CLASSES ];
|
||||
|
||||
private:
|
||||
|
||||
C_BaseFlex( const C_BaseFlex & ); // not defined, not accessible
|
||||
|
||||
const flexsetting_t *FindNamedSetting( const flexsettinghdr_t *pSettinghdr, const char *expr );
|
||||
|
||||
void ProcessVisemes( Emphasized_Phoneme *classes, float *pGlobalFlexWeight );
|
||||
void AddVisemesForSentence( float *pGlobalFlexWeight, Emphasized_Phoneme *classes, float emphasis_intensity, CSentence *sentence, float t, float dt, bool juststarted );
|
||||
void AddViseme( float *pGlobalFlexWeight, Emphasized_Phoneme *classes, float emphasis_intensity, int phoneme, float scale, bool newexpression );
|
||||
bool SetupEmphasisBlend( Emphasized_Phoneme *classes, int phoneme );
|
||||
void ComputeBlendedSetting( Emphasized_Phoneme *classes, float emphasis_intensity );
|
||||
|
||||
#ifdef HL2_CLIENT_DLL
|
||||
public:
|
||||
|
||||
Vector m_vecLean;
|
||||
CInterpolatedVar< Vector > m_iv_vecLean;
|
||||
Vector m_vecShift;
|
||||
CInterpolatedVar< Vector > m_iv_vecShift;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Do we have active expressions?
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool C_BaseFlex::HasSceneEvents() const
|
||||
{
|
||||
return m_SceneEvents.Count() != 0;
|
||||
}
|
||||
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BaseFlex);
|
||||
|
||||
float *GetVisemeWeights( int phoneme );
|
||||
|
||||
#endif // C_STUDIOFLEX_H
|
||||
|
||||
|
||||
|
||||
|
3820
game/client/c_baselesson.cpp
Normal file
3820
game/client/c_baselesson.cpp
Normal file
File diff suppressed because it is too large
Load Diff
446
game/client/c_baselesson.h
Normal file
446
game/client/c_baselesson.h
Normal file
@ -0,0 +1,446 @@
|
||||
//========= Copyright © 1996-2008, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client handler for instruction players how to play
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef _C_BASELESSON_H_
|
||||
#define _C_BASELESSON_H_
|
||||
|
||||
|
||||
#include "GameEventListener.h"
|
||||
#include "hud_locator_target.h"
|
||||
|
||||
|
||||
#define DECLARE_LESSON( _lessonClassName, _baseLessonClassName ) \
|
||||
typedef _baseLessonClassName BaseClass;\
|
||||
typedef _lessonClassName ThisClass;\
|
||||
_lessonClassName( const char *pchName, bool bIsDefaultHolder, bool bIsOpenOpportunity, int nSplitScreenSlot )\
|
||||
: _baseLessonClassName( pchName, bIsDefaultHolder, bIsOpenOpportunity, nSplitScreenSlot )\
|
||||
{\
|
||||
Init();\
|
||||
}
|
||||
|
||||
|
||||
enum LessonInstanceType
|
||||
{
|
||||
LESSON_INSTANCE_MULTIPLE,
|
||||
LESSON_INSTANCE_SINGLE_OPEN,
|
||||
LESSON_INSTANCE_FIXED_REPLACE,
|
||||
LESSON_INSTANCE_SINGLE_ACTIVE,
|
||||
|
||||
LESSON_INSTANCE_TYPE_TOTAL
|
||||
};
|
||||
|
||||
|
||||
// This is used to solve a problem where bots can take the place of a player, where on or the other don't have valid entities on the client at the same time
|
||||
#define MAX_DELAYED_PLAYER_SWAPS 8
|
||||
|
||||
struct delayed_player_swap_t
|
||||
{
|
||||
CHandle<C_BaseEntity> *phHandleToChange;
|
||||
int iNewUserID;
|
||||
|
||||
delayed_player_swap_t( void )
|
||||
{
|
||||
phHandleToChange = NULL;
|
||||
iNewUserID = -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
abstract_class CBaseLesson : public CGameEventListener
|
||||
{
|
||||
public:
|
||||
CBaseLesson( const char *pchName, bool bIsDefaultHolder, bool bIsOpenOpportunity, int nSplitScreenSlot );
|
||||
virtual ~CBaseLesson( void );
|
||||
|
||||
void AddPrerequisite( const char *pchLessonName );
|
||||
|
||||
const CGameInstructorSymbol& GetNameSymbol( void ) const { return m_stringName; }
|
||||
const char * GetName( void ) const { return m_stringName.String(); }
|
||||
int GetPriority( void ) const { return m_iPriority; }
|
||||
const char * GetCloseReason( void ) const { return m_stringCloseReason.String(); }
|
||||
void SetCloseReason( const char *pchReason ) { m_stringCloseReason = pchReason; }
|
||||
|
||||
CBaseLesson* GetRoot( void ) const { return m_pRoot; }
|
||||
void SetRoot( CBaseLesson *pRoot );
|
||||
const CUtlVector < CBaseLesson * >* GetChildren( void ) const { return &m_OpenOpportunities; }
|
||||
|
||||
float GetInitTime( void ) { return m_fInitTime; }
|
||||
void SetStartTime( void ) { m_fStartTime = gpGlobals->curtime; }
|
||||
void ResetStartTime( void ) { m_fStartTime = 0.0f; m_bHasPlayedSound = false; }
|
||||
|
||||
bool ShouldShowSpew( void );
|
||||
bool NoPriority( void ) const;
|
||||
bool IsDefaultHolder( void ) const { return m_bIsDefaultHolder; }
|
||||
bool IsOpenOpportunity( void ) const { return m_bIsOpenOpportunity; }
|
||||
bool IsLocked( void ) const;
|
||||
bool CanOpenWhenDead( void ) const { return m_bCanOpenWhenDead; }
|
||||
bool IsInstructing( void ) const { return ( m_fStartTime > 0.0f ); }
|
||||
bool IsLearned( void ) const;
|
||||
bool PrerequisitesHaveBeenMet( void ) const;
|
||||
bool IsTimedOut( void );
|
||||
|
||||
int InstanceType( void ) const { return m_iInstanceType; }
|
||||
const CGameInstructorSymbol& GetReplaceKeySymbol( void ) const { return m_stringReplaceKey; }
|
||||
const char* GetReplaceKey( void ) const { return m_stringReplaceKey.String(); }
|
||||
int GetFixedInstancesMax( void ) const { return m_iFixedInstancesMax; }
|
||||
bool ShouldReplaceOnlyWhenStopped( void ) const { return m_bReplaceOnlyWhenStopped; }
|
||||
void SetInstanceActive( bool bInstanceActive ) { m_bInstanceActive = bInstanceActive; }
|
||||
bool IsInstanceActive( void ) const { return m_bInstanceActive; }
|
||||
|
||||
void ResetDisplaysAndSuccesses( void );
|
||||
bool IncDisplayCount( void );
|
||||
bool IncSuccessCount( void );
|
||||
void SetDisplayCount( int iDisplayCount ) { m_iDisplayCount = iDisplayCount; }
|
||||
void SetSuccessCount( int iSuccessCount ) { m_iSuccessCount = iSuccessCount; }
|
||||
int GetDisplayCount( void ) const { return m_iDisplayCount; }
|
||||
int GetSuccessCount( void ) const { return m_iSuccessCount; }
|
||||
int GetDisplayLimit( void ) const { return m_iDisplayLimit; }
|
||||
int GetSuccessLimit( void ) const { return m_iSuccessLimit; }
|
||||
|
||||
void Init( void ); // NOT virtual, each constructor calls their own
|
||||
virtual void InitPrerequisites( void ) {};
|
||||
virtual void Start( void ) = 0;
|
||||
virtual void Stop( void ) = 0;
|
||||
virtual void OnOpen( void ) {};
|
||||
virtual void Update( void ) {};
|
||||
virtual void UpdateInactive( void ) {};
|
||||
|
||||
virtual bool ShouldDisplay( void ) const { return true; }
|
||||
virtual bool IsVisible( void ) const { return true; }
|
||||
virtual bool WasDisplayed( void ) const { return m_bWasDisplayed ? true : false; }
|
||||
virtual void SwapOutPlayers( int iOldUserID, int iNewUserID ) {}
|
||||
virtual void TakePlaceOf( CBaseLesson *pLesson );
|
||||
|
||||
int GetSplitScreenSlot() const { return m_nSplitScreenSlot; }
|
||||
|
||||
const char *GetGroup() { return m_szLessonGroup.String(); }
|
||||
void SetEnabled( bool bEnabled ) { m_bDisabled = !bEnabled; }
|
||||
|
||||
protected:
|
||||
void MarkSucceeded( void );
|
||||
void CloseOpportunity( const char *pchReason );
|
||||
bool DoDelayedPlayerSwaps( void ) const;
|
||||
|
||||
private:
|
||||
|
||||
CBaseLesson *m_pRoot;
|
||||
CUtlVector < CBaseLesson * > m_OpenOpportunities;
|
||||
CUtlVector < const CBaseLesson * > m_Prerequisites;
|
||||
|
||||
CGameInstructorSymbol m_stringCloseReason;
|
||||
CGameInstructorSymbol m_stringName;
|
||||
|
||||
bool m_bInstanceActive : 1;
|
||||
bool m_bSuccessCounted : 1;
|
||||
bool m_bIsDefaultHolder : 1;
|
||||
bool m_bIsOpenOpportunity : 1;
|
||||
|
||||
protected:
|
||||
LessonInstanceType m_iInstanceType;
|
||||
|
||||
int m_iPriority;
|
||||
CGameInstructorSymbol m_stringReplaceKey;
|
||||
int m_iFixedInstancesMax;
|
||||
bool m_bReplaceOnlyWhenStopped;
|
||||
int m_iTeam;
|
||||
bool m_bOnlyKeyboard;
|
||||
bool m_bOnlyGamepad;
|
||||
|
||||
int m_iDisplayLimit;
|
||||
int m_iDisplayCount;
|
||||
bool m_bWasDisplayed;
|
||||
int m_iSuccessLimit;
|
||||
int m_iSuccessCount;
|
||||
int m_nSplitScreenSlot;
|
||||
|
||||
float m_fLockDuration;
|
||||
float m_fTimeout;
|
||||
float m_fInitTime;
|
||||
float m_fStartTime;
|
||||
float m_fLockTime;
|
||||
float m_fUpdateInterval;
|
||||
bool m_bHasPlayedSound;
|
||||
|
||||
CGameInstructorSymbol m_szStartSound;
|
||||
CGameInstructorSymbol m_szLessonGroup;
|
||||
|
||||
bool m_bCanOpenWhenDead;
|
||||
bool m_bBumpWithTimeoutWhenLearned;
|
||||
bool m_bCanTimeoutWhileInactive;
|
||||
bool m_bDisabled;
|
||||
|
||||
// Right now we can only queue up 4 swaps...
|
||||
// this number can be increased if more entity handle scripted variables are added
|
||||
mutable delayed_player_swap_t m_pDelayedPlayerSwap[ MAX_DELAYED_PLAYER_SWAPS ];
|
||||
mutable int m_iNumDelayedPlayerSwaps;
|
||||
|
||||
public:
|
||||
|
||||
// Colors for console spew in verbose mode
|
||||
static Color m_rgbaVerboseHeader;
|
||||
static Color m_rgbaVerbosePlain;
|
||||
static Color m_rgbaVerboseName;
|
||||
static Color m_rgbaVerboseOpen;
|
||||
static Color m_rgbaVerboseClose;
|
||||
static Color m_rgbaVerboseSuccess;
|
||||
static Color m_rgbaVerboseUpdate;
|
||||
};
|
||||
|
||||
|
||||
class CTextLesson : public CBaseLesson
|
||||
{
|
||||
public:
|
||||
DECLARE_LESSON( CTextLesson, CBaseLesson );
|
||||
|
||||
void Init( void ); // NOT virtual, each constructor calls their own
|
||||
virtual void Start( void );
|
||||
virtual void Stop( void );
|
||||
|
||||
protected:
|
||||
|
||||
CGameInstructorSymbol m_szDisplayText;
|
||||
CGameInstructorSymbol m_szDisplayParamText;
|
||||
CGameInstructorSymbol m_szBinding;
|
||||
CGameInstructorSymbol m_szGamepadBinding;
|
||||
};
|
||||
|
||||
|
||||
class CIconLesson : public CTextLesson
|
||||
{
|
||||
public:
|
||||
DECLARE_LESSON( CIconLesson, CTextLesson );
|
||||
|
||||
void Init( void ); // NOT virtual, each constructor calls their own
|
||||
virtual void Start( void );
|
||||
virtual void Stop( void );
|
||||
virtual void Update( void );
|
||||
virtual void UpdateInactive( void );
|
||||
|
||||
virtual bool ShouldDisplay( void ) const;
|
||||
virtual bool IsVisible( void ) const;
|
||||
virtual void SwapOutPlayers( int iOldUserID, int iNewUserID );
|
||||
virtual void TakePlaceOf( CBaseLesson *pLesson );
|
||||
|
||||
void SetLocatorBinding( CLocatorTarget * pLocatorTarget );
|
||||
|
||||
const char *GetCaptionColorString() { return m_szCaptionColor.String(); }
|
||||
|
||||
bool IsPresentComplete( void );
|
||||
void PresentStart( void );
|
||||
void PresentEnd( void );
|
||||
|
||||
private:
|
||||
virtual void UpdateLocatorTarget( CLocatorTarget *pLocatorTarget, C_BaseEntity *pIconTarget );
|
||||
|
||||
protected:
|
||||
CHandle<C_BaseEntity> m_hIconTarget;
|
||||
CGameInstructorSymbol m_szVguiTargetName;
|
||||
CGameInstructorSymbol m_szVguiTargetLookup;
|
||||
int m_nVguiTargetEdge;
|
||||
float m_flUpOffset;
|
||||
float m_flRelativeUpOffset;
|
||||
float m_fFixedPositionX;
|
||||
float m_fFixedPositionY;
|
||||
|
||||
int m_hLocatorTarget;
|
||||
int m_iFlags;
|
||||
|
||||
float m_fRange;
|
||||
float m_fCurrentDistance;
|
||||
float m_fOnScreenStartTime;
|
||||
float m_fUpdateDistanceTime;
|
||||
|
||||
CGameInstructorSymbol m_szOnscreenIcon;
|
||||
CGameInstructorSymbol m_szOffscreenIcon;
|
||||
CGameInstructorSymbol m_szCaptionColor;
|
||||
|
||||
bool m_bFixedPosition;
|
||||
bool m_bNoIconTarget;
|
||||
bool m_bAllowNodrawTarget;
|
||||
bool m_bVisible;
|
||||
bool m_bShowWhenOccluded;
|
||||
bool m_bNoOffscreen;
|
||||
bool m_bForceCaption;
|
||||
};
|
||||
|
||||
enum LessonAction
|
||||
{
|
||||
LESSON_ACTION_NONE,
|
||||
|
||||
LESSON_ACTION_SCOPE_IN,
|
||||
LESSON_ACTION_SCOPE_OUT,
|
||||
LESSON_ACTION_CLOSE,
|
||||
LESSON_ACTION_SUCCESS,
|
||||
LESSON_ACTION_LOCK,
|
||||
LESSON_ACTION_PRESENT_COMPLETE,
|
||||
LESSON_ACTION_PRESENT_START,
|
||||
LESSON_ACTION_PRESENT_END,
|
||||
|
||||
LESSON_ACTION_REFERENCE_OPEN,
|
||||
|
||||
LESSON_ACTION_SET,
|
||||
LESSON_ACTION_ADD,
|
||||
LESSON_ACTION_SUBTRACT,
|
||||
LESSON_ACTION_MULTIPLY,
|
||||
LESSON_ACTION_IS,
|
||||
LESSON_ACTION_LESS_THAN,
|
||||
LESSON_ACTION_HAS_PREFIX,
|
||||
LESSON_ACTION_HAS_BIT,
|
||||
LESSON_ACTION_BIT_COUNT_IS,
|
||||
LESSON_ACTION_BIT_COUNT_LESS_THAN,
|
||||
|
||||
LESSON_ACTION_GET_DISTANCE,
|
||||
LESSON_ACTION_GET_ANGULAR_DISTANCE,
|
||||
LESSON_ACTION_GET_PLAYER_DISPLAY_NAME,
|
||||
LESSON_ACTION_CLASSNAME_IS,
|
||||
LESSON_ACTION_MODELNAME_IS,
|
||||
LESSON_ACTION_TEAM_IS,
|
||||
LESSON_ACTION_HEALTH_LESS_THAN,
|
||||
LESSON_ACTION_HEALTH_PERCENTAGE_LESS_THAN,
|
||||
LESSON_ACTION_GET_ACTIVE_WEAPON,
|
||||
LESSON_ACTION_WEAPON_IS,
|
||||
LESSON_ACTION_WEAPON_HAS,
|
||||
LESSON_ACTION_GET_ACTIVE_WEAPON_SLOT,
|
||||
LESSON_ACTION_GET_WEAPON_SLOT,
|
||||
LESSON_ACTION_GET_WEAPON_IN_SLOT,
|
||||
LESSON_ACTION_CLIP_PERCENTAGE_LESS_THAN,
|
||||
LESSON_ACTION_WEAPON_AMMO_LOW,
|
||||
LESSON_ACTION_WEAPON_AMMO_FULL,
|
||||
LESSON_ACTION_WEAPON_AMMO_EMPTY,
|
||||
LESSON_ACTION_WEAPON_CAN_USE,
|
||||
LESSON_ACTION_USE_TARGET_IS,
|
||||
LESSON_ACTION_GET_USE_TARGET,
|
||||
LESSON_ACTION_GET_POTENTIAL_USE_TARGET,
|
||||
|
||||
// Enum continued in Mod_LessonAction
|
||||
LESSON_ACTION_MOD_START,
|
||||
};
|
||||
|
||||
struct LessonElement_t
|
||||
{
|
||||
int iVariable;
|
||||
int iParamVarIndex;
|
||||
int iAction;
|
||||
_fieldtypes paramType;
|
||||
CGameInstructorSymbol szParam;
|
||||
bool bNot : 1;
|
||||
bool bOptionalParam : 1;
|
||||
|
||||
LessonElement_t( int p_iVariable, int p_iAction, bool p_bNot, bool p_bOptionalParam, const char *pchParam, int p_iParamVarIndex, _fieldtypes p_paramType )
|
||||
{
|
||||
iVariable = p_iVariable;
|
||||
iAction = p_iAction;
|
||||
bNot = p_bNot;
|
||||
bOptionalParam = p_bOptionalParam;
|
||||
szParam = pchParam;
|
||||
iParamVarIndex = p_iParamVarIndex;
|
||||
paramType = p_paramType;
|
||||
}
|
||||
|
||||
LessonElement_t( const LessonElement_t &p_LessonElement )
|
||||
{
|
||||
iVariable = p_LessonElement.iVariable;
|
||||
iAction = p_LessonElement.iAction;
|
||||
bNot = p_LessonElement.bNot;
|
||||
bOptionalParam = p_LessonElement.bOptionalParam;
|
||||
szParam = p_LessonElement.szParam;
|
||||
iParamVarIndex = p_LessonElement.iParamVarIndex;
|
||||
paramType = p_LessonElement.paramType;
|
||||
}
|
||||
};
|
||||
|
||||
struct LessonEvent_t
|
||||
{
|
||||
CUtlVector< LessonElement_t > elements;
|
||||
CGameInstructorSymbol szEventName;
|
||||
};
|
||||
|
||||
class CScriptedIconLesson : public CIconLesson
|
||||
{
|
||||
public:
|
||||
DECLARE_LESSON( CScriptedIconLesson, CIconLesson )
|
||||
|
||||
virtual ~CScriptedIconLesson( void );
|
||||
|
||||
static void PreReadLessonsFromFile( void );
|
||||
static void Mod_PreReadLessonsFromFile( void );
|
||||
|
||||
void Init( void ); // NOT virtual, each constructor calls their own
|
||||
virtual void InitPrerequisites( void );
|
||||
virtual void OnOpen( void );
|
||||
virtual void Update( void );
|
||||
|
||||
virtual void SwapOutPlayers( int iOldUserID, int iNewUserID );
|
||||
|
||||
virtual void FireGameEvent( IGameEvent *event );
|
||||
virtual void ProcessOpenGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event );
|
||||
virtual void ProcessCloseGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event );
|
||||
virtual void ProcessSuccessGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event );
|
||||
|
||||
CUtlVector< LessonEvent_t >& GetOpenEvents( void ) { return m_OpenEvents; }
|
||||
CUtlVector< LessonEvent_t >& GetCloseEvents( void ) { return m_CloseEvents; }
|
||||
CUtlVector< LessonEvent_t >& GetSuccessEvents( void ) { return m_SuccessEvents; }
|
||||
CUtlVector< LessonEvent_t >& GetOnOpenEvents( void ) { return m_OnOpenEvents; }
|
||||
CUtlVector< LessonEvent_t >& GetUpdateEvents( void ) { return m_UpdateEvents; }
|
||||
|
||||
bool ProcessElements( IGameEvent *event, const CUtlVector< LessonElement_t > *pElements );
|
||||
|
||||
private:
|
||||
void InitElementsFromKeys( CUtlVector< LessonElement_t > *pLessonElements, KeyValues *pKey );
|
||||
void InitElementsFromElements( CUtlVector< LessonElement_t > *pLessonElements, const CUtlVector< LessonElement_t > *pLessonElements2 );
|
||||
|
||||
void InitFromKeys( KeyValues *pKey );
|
||||
|
||||
bool ProcessElement( IGameEvent *event, const LessonElement_t *pLessonElement, bool bInFailedScope );
|
||||
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, float &bVar, const CGameInstructorSymbol *pchParamName, float fParam );
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, int &bVar, const CGameInstructorSymbol *pchParamName, float fParam );
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, bool &bVar, const CGameInstructorSymbol *pchParamName, float fParam );
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, EHANDLE &hVar, const CGameInstructorSymbol *pchParamName, float fParam, C_BaseEntity *pParam, const char *pchParam );
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, CGameInstructorSymbol *pchVar, const CGameInstructorSymbol *pchParamName, const char *pchParam );
|
||||
|
||||
// Implemented per mod so they can have custom actions
|
||||
bool Mod_ProcessElementAction( int iAction, bool bNot, const char *pchVarName, EHANDLE &hVar, const CGameInstructorSymbol *pchParamName, float fParam, C_BaseEntity *pParam, const char *pchParam, bool &bModHandled );
|
||||
|
||||
LessonEvent_t * AddOpenEvent( void );
|
||||
LessonEvent_t * AddCloseEvent( void );
|
||||
LessonEvent_t * AddSuccessEvent( void );
|
||||
LessonEvent_t * AddOnOpenEvent( void );
|
||||
LessonEvent_t * AddUpdateEvent( void );
|
||||
|
||||
private:
|
||||
static CUtlDict< int, int > CScriptedIconLesson::LessonActionMap;
|
||||
|
||||
EHANDLE m_hLocalPlayer;
|
||||
float m_fOutput;
|
||||
CHandle<C_BaseEntity> m_hEntity1;
|
||||
CHandle<C_BaseEntity> m_hEntity2;
|
||||
CGameInstructorSymbol m_szString1;
|
||||
CGameInstructorSymbol m_szString2;
|
||||
int m_iInteger1;
|
||||
int m_iInteger2;
|
||||
float m_fFloat1;
|
||||
float m_fFloat2;
|
||||
|
||||
CUtlVector< CGameInstructorSymbol > m_PrerequisiteNames;
|
||||
CUtlVector< LessonEvent_t > m_OpenEvents;
|
||||
CUtlVector< LessonEvent_t > m_CloseEvents;
|
||||
CUtlVector< LessonEvent_t > m_SuccessEvents;
|
||||
CUtlVector< LessonEvent_t > m_OnOpenEvents;
|
||||
CUtlVector< LessonEvent_t > m_UpdateEvents;
|
||||
|
||||
float m_fUpdateEventTime;
|
||||
CScriptedIconLesson *m_pDefaultHolder;
|
||||
|
||||
int m_iScopeDepth;
|
||||
|
||||
// Need this to get offsets to scripted variables
|
||||
friend class LessonVariableInfo;
|
||||
friend int LessonActionFromString( const char *pchName );
|
||||
};
|
||||
|
||||
|
||||
#endif // _C_BASELESSON_H_
|
2899
game/client/c_baseplayer.cpp
Normal file
2899
game/client/c_baseplayer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
793
game/client/c_baseplayer.h
Normal file
793
game/client/c_baseplayer.h
Normal file
@ -0,0 +1,793 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Client-side CBasePlayer.
|
||||
//
|
||||
// - Manages the player's flashlight effect.
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_BASEPLAYER_H
|
||||
#define C_BASEPLAYER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_playerlocaldata.h"
|
||||
#include "c_basecombatcharacter.h"
|
||||
#include "playerstate.h"
|
||||
#include "usercmd.h"
|
||||
#include "shareddefs.h"
|
||||
#include "timedevent.h"
|
||||
#include "smartptr.h"
|
||||
#include "fx_water.h"
|
||||
#include "hintsystem.h"
|
||||
#include "soundemittersystem/isoundemittersystembase.h"
|
||||
#include "c_env_fog_controller.h"
|
||||
#include "C_PostProcessController.h"
|
||||
#include "C_ColorCorrection.h"
|
||||
|
||||
class C_BaseCombatWeapon;
|
||||
class C_BaseViewModel;
|
||||
class C_FuncLadder;
|
||||
|
||||
extern int g_nKillCamMode;
|
||||
extern int g_nKillCamTarget1;
|
||||
extern int g_nKillCamTarget2;
|
||||
|
||||
class C_CommandContext
|
||||
{
|
||||
public:
|
||||
bool needsprocessing;
|
||||
|
||||
CUserCmd cmd;
|
||||
int command_number;
|
||||
};
|
||||
|
||||
class C_PredictionError
|
||||
{
|
||||
public:
|
||||
float time;
|
||||
Vector error;
|
||||
};
|
||||
|
||||
#define CHASE_CAM_DISTANCE 96.0f
|
||||
#define WALL_OFFSET 6.0f
|
||||
|
||||
|
||||
enum PlayerRenderMode_t
|
||||
{
|
||||
PLAYER_RENDER_NONE = 0,
|
||||
PLAYER_RENDER_FIRSTPERSON,
|
||||
PLAYER_RENDER_THIRDPERSON,
|
||||
};
|
||||
|
||||
|
||||
bool IsInFreezeCam( void );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Base Player class
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BasePlayer : public C_BaseCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BasePlayer, C_BaseCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_INTERPOLATION();
|
||||
|
||||
C_BasePlayer();
|
||||
virtual ~C_BasePlayer();
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual void SharedSpawn(); // Shared between client and server.
|
||||
Class_T Classify( void ) { return CLASS_PLAYER; }
|
||||
|
||||
// IClientEntity overrides.
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||
|
||||
virtual void OnRestore();
|
||||
|
||||
virtual void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
|
||||
|
||||
virtual void GetToolRecordingState( KeyValues *msg );
|
||||
|
||||
void SetAnimationExtension( const char *pExtension );
|
||||
|
||||
C_BaseViewModel *GetViewModel( int viewmodelindex = 0 );
|
||||
C_BaseCombatWeapon *GetActiveWeapon( void ) const;
|
||||
const char *GetTracerType( void );
|
||||
|
||||
// View model prediction setup
|
||||
virtual void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
|
||||
virtual void CalcViewModelView( const Vector& eyeOrigin, const QAngle& eyeAngles);
|
||||
|
||||
|
||||
// Handle view smoothing when going up stairs
|
||||
void SmoothViewOnStairs( Vector& eyeOrigin );
|
||||
virtual float CalcRoll (const QAngle& angles, const Vector& velocity, float rollangle, float rollspeed);
|
||||
void CalcViewRoll( QAngle& eyeAngles );
|
||||
virtual void CalcViewBob( Vector& eyeOrigin );
|
||||
void CreateWaterEffects( void );
|
||||
|
||||
virtual void SetPlayerUnderwater( bool state );
|
||||
void UpdateUnderwaterState( void );
|
||||
bool IsPlayerUnderwater( void ) { return m_bPlayerUnderwater; }
|
||||
|
||||
virtual C_BaseCombatCharacter *ActivePlayerCombatCharacter( void ) { return this; }
|
||||
|
||||
virtual Vector Weapon_ShootPosition();
|
||||
virtual bool Weapon_CanUse( C_BaseCombatWeapon *pWeapon );
|
||||
virtual void Weapon_DropPrimary( void ) {}
|
||||
|
||||
virtual Vector GetAutoaimVector( float flScale );
|
||||
void SetSuitUpdate(char *name, int fgroup, int iNoRepeat);
|
||||
|
||||
// Input handling
|
||||
virtual bool CreateMove( float flInputSampleTime, CUserCmd *pCmd );
|
||||
virtual void AvoidPhysicsProps( CUserCmd *pCmd );
|
||||
|
||||
virtual void PlayerUse( void );
|
||||
CBaseEntity *FindUseEntity( void );
|
||||
virtual bool IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps );
|
||||
|
||||
// Data handlers
|
||||
virtual bool IsPlayer( void ) const { return true; }
|
||||
virtual int GetHealth() const { return m_iHealth; }
|
||||
|
||||
int GetBonusProgress() const { return m_iBonusProgress; }
|
||||
int GetBonusChallenge() const { return m_iBonusChallenge; }
|
||||
|
||||
// observer mode
|
||||
virtual int GetObserverMode() const;
|
||||
virtual CBaseEntity *GetObserverTarget() const;
|
||||
void SetObserverTarget( EHANDLE hObserverTarget );
|
||||
|
||||
bool AudioStateIsUnderwater( Vector vecMainViewOrigin );
|
||||
|
||||
bool IsObserver() const;
|
||||
bool IsHLTV() const;
|
||||
bool IsReplay() const;
|
||||
void ResetObserverMode();
|
||||
bool IsBot( void ) const { return false; }
|
||||
|
||||
// Eye position..
|
||||
virtual Vector EyePosition();
|
||||
virtual const QAngle &EyeAngles(); // Direction of eyes
|
||||
void EyePositionAndVectors( Vector *pPosition, Vector *pForward, Vector *pRight, Vector *pUp );
|
||||
virtual const QAngle &LocalEyeAngles(); // Direction of eyes
|
||||
|
||||
// This can be overridden to return something other than m_pRagdoll if the mod uses separate
|
||||
// entities for ragdolls.
|
||||
virtual IRagdoll* GetRepresentativeRagdoll() const;
|
||||
|
||||
// override the initial bone position for ragdolls
|
||||
virtual void GetRagdollInitBoneArrays( matrix3x4a_t *pDeltaBones0, matrix3x4a_t *pDeltaBones1, matrix3x4a_t *pCurrentBones, float boneDt );
|
||||
|
||||
// Returns eye vectors
|
||||
void EyeVectors( Vector *pForward, Vector *pRight = NULL, Vector *pUp = NULL );
|
||||
void CacheVehicleView( void ); // Calculate and cache the position of the player in the vehicle
|
||||
|
||||
|
||||
bool IsSuitEquipped( void ) { return m_Local.m_bWearingSuit; };
|
||||
|
||||
// Team handlers
|
||||
virtual void TeamChange( int iNewTeam );
|
||||
|
||||
// Flashlight
|
||||
void Flashlight( void );
|
||||
void UpdateFlashlight( void );
|
||||
void TurnOffFlashlight( void ); // TERROR
|
||||
virtual const char *GetFlashlightTextureName( void ) const { return NULL; } // TERROR
|
||||
virtual float GetFlashlightFOV( void ) const { return 0.0f; } // TERROR
|
||||
virtual float GetFlashlightFarZ( void ) const { return 0.0f; } // TERROR
|
||||
virtual float GetFlashlightLinearAtten( void ) const { return 0.0f; } // TERROR
|
||||
virtual bool CastsFlashlightShadows( void ) const { return true; } // TERROR
|
||||
virtual void GetFlashlightOffset( const Vector &vecForward, const Vector &vecRight, const Vector &vecUp, Vector *pVecOffset ) const;
|
||||
Vector m_vecFlashlightOrigin;
|
||||
Vector m_vecFlashlightForward;
|
||||
Vector m_vecFlashlightUp;
|
||||
Vector m_vecFlashlightRight;
|
||||
|
||||
// Weapon selection code
|
||||
virtual bool IsAllowedToSwitchWeapons( void ) { return !IsObserver(); }
|
||||
virtual C_BaseCombatWeapon *GetActiveWeaponForSelection( void );
|
||||
|
||||
// Returns the view model if this is the local player. If you're in third person or
|
||||
// this is a remote player, it returns the active weapon
|
||||
// (and its appropriate left/right weapon if this is TF2).
|
||||
virtual C_BaseAnimating* GetRenderedWeaponModel();
|
||||
|
||||
virtual bool IsOverridingViewmodel( void ) { return false; };
|
||||
virtual int DrawOverriddenViewmodel( C_BaseViewModel *pViewmodel, int flags, const RenderableInstance_t &instance ) { return 0; };
|
||||
|
||||
virtual float GetDefaultAnimSpeed( void ) { return 1.0; }
|
||||
|
||||
void SetMaxSpeed( float flMaxSpeed ) { m_flMaxspeed = flMaxSpeed; }
|
||||
float MaxSpeed() const { return m_flMaxspeed; }
|
||||
|
||||
// Should this object cast shadows?
|
||||
virtual ShadowType_t ShadowCastType() { return SHADOWS_NONE; }
|
||||
|
||||
virtual bool ShouldReceiveProjectedTextures( int flags )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Makes sure s_pLocalPlayer is properly initialized
|
||||
void CheckForLocalPlayer( int nSplitScreenSlot );
|
||||
|
||||
/// Is the passed in player one of the split screen users
|
||||
static bool IsLocalPlayer( const C_BaseEntity *pl );
|
||||
/// is this player a local player ( call when you have already verified that your pointer really is a C_BasePlayer )
|
||||
inline bool IsLocalPlayer( void ) const;
|
||||
|
||||
// Global/static methods
|
||||
virtual void ThirdPersonSwitch( bool bThirdperson );
|
||||
bool ShouldDrawLocalPlayer();
|
||||
static C_BasePlayer *GetLocalPlayer( int nSlot = -1 );
|
||||
static void SetRemoteSplitScreenPlayerViewsAreLocalPlayer( bool bSet ); //if true, calls to GetLocalPlayer() will return a remote splitscreen player when applicable.
|
||||
static bool HasAnyLocalPlayer();
|
||||
static int GetSplitScreenSlotForPlayer( C_BaseEntity *pl );
|
||||
|
||||
void AddSplitScreenPlayer( C_BasePlayer *pOther );
|
||||
void RemoveSplitScreenPlayer( C_BasePlayer *pOther );
|
||||
CUtlVector< CHandle< C_BasePlayer > > &GetSplitScreenPlayers();
|
||||
|
||||
bool IsSplitScreenPartner( C_BasePlayer *pPlayer );
|
||||
|
||||
bool IsSplitScreenPlayer() const;
|
||||
int GetSplitScreenPlayerSlot();
|
||||
|
||||
virtual IClientModelRenderable* GetClientModelRenderable();
|
||||
virtual bool PreRender( int nSplitScreenPlayerSlot );
|
||||
|
||||
int GetUserID( void ) const;
|
||||
virtual bool CanSetSoundMixer( void );
|
||||
|
||||
// return the entity used for soundscape radius checks
|
||||
virtual C_BaseEntity *GetSoundscapeListener();
|
||||
|
||||
|
||||
#if !defined( NO_ENTITY_PREDICTION )
|
||||
void AddToPlayerSimulationList( C_BaseEntity *other );
|
||||
void SimulatePlayerSimulatedEntities( void );
|
||||
void RemoveFromPlayerSimulationList( C_BaseEntity *ent );
|
||||
void ClearPlayerSimulationList( void );
|
||||
#endif
|
||||
|
||||
virtual void PhysicsSimulate( void );
|
||||
virtual unsigned int PhysicsSolidMaskForEntity( void ) const { return MASK_PLAYERSOLID; }
|
||||
|
||||
// Prediction stuff
|
||||
virtual bool ShouldPredict( void );
|
||||
virtual C_BasePlayer *GetPredictionOwner( void );
|
||||
|
||||
virtual void PreThink( void );
|
||||
virtual void PostThink( void );
|
||||
|
||||
virtual void ItemPreFrame( void );
|
||||
virtual void ItemPostFrame( void );
|
||||
virtual void AbortReload( void );
|
||||
|
||||
virtual void SelectLastItem(void);
|
||||
virtual void Weapon_SetLast( C_BaseCombatWeapon *pWeapon );
|
||||
virtual bool Weapon_ShouldSetLast( C_BaseCombatWeapon *pOldWeapon, C_BaseCombatWeapon *pNewWeapon ) { return true; }
|
||||
virtual bool Weapon_ShouldSelectItem( C_BaseCombatWeapon *pWeapon );
|
||||
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 ); // Switch to given weapon if has ammo (false if failed)
|
||||
virtual C_BaseCombatWeapon *GetLastWeapon( void ) { return m_hLastWeapon.Get(); }
|
||||
void ResetAutoaim( void );
|
||||
virtual void SelectItem( const char *pstr, int iSubType = 0 );
|
||||
|
||||
virtual void UpdateClientData( void );
|
||||
|
||||
virtual float GetFOV( void ) const;
|
||||
virtual int GetDefaultFOV( void ) const;
|
||||
virtual bool IsZoomed( void ) { return false; }
|
||||
bool SetFOV( CBaseEntity *pRequester, int FOV, float zoomRate, int iZoomStart = 0 );
|
||||
void ClearZoomOwner( void );
|
||||
|
||||
float GetFOVDistanceAdjustFactor();
|
||||
|
||||
virtual void ViewPunch( const QAngle &angleOffset );
|
||||
void ViewPunchReset( float tolerance = 0 );
|
||||
|
||||
void UpdateButtonState( int nUserCmdButtonMask );
|
||||
int GetImpulse( void ) const;
|
||||
|
||||
virtual bool Simulate();
|
||||
|
||||
virtual bool ShouldInterpolate();
|
||||
|
||||
virtual bool ShouldDraw();
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
|
||||
// Called when not in tactical mode. Allows view to be overriden for things like driving a tank.
|
||||
virtual void OverrideView( CViewSetup *pSetup );
|
||||
|
||||
C_BaseEntity *GetViewEntity( void ) const { return m_hViewEntity; }
|
||||
|
||||
// returns the player name
|
||||
const char * GetPlayerName();
|
||||
virtual const Vector GetPlayerMins( void ) const; // uses local player
|
||||
virtual const Vector GetPlayerMaxs( void ) const; // uses local player
|
||||
|
||||
virtual void UpdateCollisionBounds( void );
|
||||
|
||||
// Is the player dead?
|
||||
bool IsPlayerDead();
|
||||
bool IsPoisoned( void ) { return m_Local.m_bPoisoned; }
|
||||
|
||||
virtual C_BaseEntity* GetUseEntity( void ) const;
|
||||
virtual C_BaseEntity* GetPotentialUseEntity( void ) const;
|
||||
|
||||
// Vehicles...
|
||||
IClientVehicle *GetVehicle();
|
||||
const IClientVehicle *GetVehicle() const;
|
||||
|
||||
bool IsInAVehicle() const { return ( NULL != m_hVehicle.Get() ) ? true : false; }
|
||||
virtual void SetVehicleRole( int nRole );
|
||||
void LeaveVehicle( void );
|
||||
|
||||
bool UsingStandardWeaponsInVehicle( void );
|
||||
|
||||
virtual void SetAnimation( PLAYER_ANIM playerAnim );
|
||||
|
||||
float GetTimeBase( void ) const;
|
||||
float GetFinalPredictedTime() const;
|
||||
|
||||
bool IsInVGuiInputMode() const;
|
||||
bool IsInViewModelVGuiInputMode() const;
|
||||
|
||||
C_CommandContext *GetCommandContext();
|
||||
|
||||
// Get the command number associated with the current usercmd we're running (if in predicted code).
|
||||
int CurrentCommandNumber() const;
|
||||
const CUserCmd *GetCurrentUserCommand() const;
|
||||
|
||||
virtual const QAngle& GetPunchAngle();
|
||||
void SetPunchAngle( const QAngle &angle );
|
||||
|
||||
float GetWaterJumpTime() const;
|
||||
void SetWaterJumpTime( float flWaterJumpTime );
|
||||
float GetSwimSoundTime( void ) const;
|
||||
void SetSwimSoundTime( float flSwimSoundTime );
|
||||
|
||||
float GetDeathTime( void ) { return m_flDeathTime; }
|
||||
|
||||
void SetPreviouslyPredictedOrigin( const Vector &vecAbsOrigin );
|
||||
const Vector &GetPreviouslyPredictedOrigin() const;
|
||||
|
||||
// CS wants to allow small FOVs for zoomed-in AWPs.
|
||||
virtual float GetMinFOV() const;
|
||||
|
||||
virtual void DoMuzzleFlash();
|
||||
virtual void PlayPlayerJingle();
|
||||
|
||||
virtual void UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity );
|
||||
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
|
||||
virtual surfacedata_t * GetFootstepSurface( const Vector &origin, const char *surfaceName );
|
||||
virtual void GetStepSoundVelocities( float *velwalk, float *velrun );
|
||||
virtual void SetStepSoundTime( stepsoundtimes_t iStepSoundTime, bool bWalking );
|
||||
|
||||
// Called by prediction when it detects a prediction correction.
|
||||
// vDelta is the line from where the client had predicted the player to at the usercmd in question,
|
||||
// to where the server says the client should be at said usercmd.
|
||||
void NotePredictionError( const Vector &vDelta );
|
||||
|
||||
// Called by the renderer to apply the prediction error smoothing.
|
||||
void GetPredictionErrorSmoothingVector( Vector &vOffset );
|
||||
|
||||
virtual void ExitLadder() {}
|
||||
surfacedata_t *GetLadderSurface( const Vector &origin );
|
||||
|
||||
void ForceButtons( int nButtons );
|
||||
void UnforceButtons( int nButtons );
|
||||
|
||||
|
||||
void SetLadderNormal( Vector vecLadderNormal ) { m_vecLadderNormal = vecLadderNormal; }
|
||||
const Vector &GetLadderNormal( void ) const { return m_vecLadderNormal; }
|
||||
int GetLadderSurfaceProps( void ) const { return m_ladderSurfaceProps; }
|
||||
|
||||
// Hints
|
||||
virtual CHintSystem *Hints( void ) { return NULL; }
|
||||
bool ShouldShowHints( void ) { return Hints() ? Hints()->ShouldShowHints() : false; }
|
||||
bool HintMessage( int hint, bool bForce = false, bool bOnlyIfClear = false ) { return Hints() ? Hints()->HintMessage( hint, bForce, bOnlyIfClear ) : false; }
|
||||
void HintMessage( const char *pMessage ) { if (Hints()) Hints()->HintMessage( pMessage ); }
|
||||
|
||||
virtual IMaterial *GetHeadLabelMaterial( void );
|
||||
|
||||
// Fog
|
||||
virtual fogparams_t *GetFogParams( void ) { return &m_CurrentFog; }
|
||||
void FogControllerChanged( bool bSnap );
|
||||
void UpdateFogController( void );
|
||||
void UpdateFogBlend( void );
|
||||
|
||||
C_PostProcessController* GetActivePostProcessController() const;
|
||||
C_ColorCorrection* GetActiveColorCorrection() const;
|
||||
|
||||
void IncrementEFNoInterpParity();
|
||||
int GetEFNoInterpParity() const;
|
||||
|
||||
float GetFOVTime( void ){ return m_flFOVTime; }
|
||||
|
||||
PlayerRenderMode_t GetPlayerRenderMode( int nSlot );
|
||||
|
||||
virtual void OnAchievementAchieved( int iAchievement ) {}
|
||||
|
||||
protected:
|
||||
fogparams_t m_CurrentFog;
|
||||
EHANDLE m_hOldFogController;
|
||||
|
||||
public:
|
||||
// RecvProxies
|
||||
static void RecvProxy_LocalVelocityX( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
static void RecvProxy_LocalVelocityY( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
static void RecvProxy_LocalVelocityZ( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
|
||||
static void RecvProxy_ObserverTarget( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
static void RecvProxy_ObserverMode( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
|
||||
static void RecvProxy_LocalOriginXY( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
static void RecvProxy_LocalOriginZ( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
static void RecvProxy_NonLocalOriginXY( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
static void RecvProxy_NonLocalOriginZ( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
static void RecvProxy_NonLocalCellOriginXY( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
static void RecvProxy_NonLocalCellOriginZ( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
|
||||
virtual bool ShouldRegenerateOriginFromCellBits() const;
|
||||
|
||||
public:
|
||||
int m_StuckLast;
|
||||
|
||||
// Data for only the local player
|
||||
CNetworkVarEmbedded( CPlayerLocalData, m_Local );
|
||||
|
||||
EHANDLE m_hTonemapController;
|
||||
|
||||
// Data common to all other players, too
|
||||
CPlayerState pl;
|
||||
|
||||
public:
|
||||
// BEGIN PREDICTION DATA COMPACTION (these fields are together to allow for faster copying in prediction system)
|
||||
|
||||
// FTYPEDESC_INSENDTABLE STUFF
|
||||
// Player FOV values
|
||||
int m_iFOV; // field of view
|
||||
int m_iFOVStart; // starting value of the FOV changing over time (client only)
|
||||
int m_afButtonLast;
|
||||
int m_afButtonPressed;
|
||||
int m_afButtonReleased;
|
||||
int m_nButtons;
|
||||
protected:
|
||||
int m_nImpulse;
|
||||
CNetworkVar( int, m_ladderSurfaceProps );
|
||||
int m_flPhysics;
|
||||
public:
|
||||
float m_flFOVTime; // starting time of the FOV zoom
|
||||
private:
|
||||
float m_flWaterJumpTime; // used to be called teleport_time
|
||||
float m_flSwimSoundTime;
|
||||
protected:
|
||||
float m_flStepSoundTime;
|
||||
float m_surfaceFriction;
|
||||
private:
|
||||
CNetworkVector( m_vecLadderNormal );
|
||||
|
||||
// FTYPEDESC_INSENDTABLE STUFF (end)
|
||||
public:
|
||||
char m_szAnimExtension[32];
|
||||
private:
|
||||
int m_nOldTickBase;
|
||||
private:
|
||||
int m_iBonusProgress;
|
||||
int m_iBonusChallenge;
|
||||
|
||||
private:
|
||||
float m_flMaxspeed;
|
||||
|
||||
|
||||
public:
|
||||
EHANDLE m_hZoomOwner; // This is a pointer to the entity currently controlling the player's zoom
|
||||
private:
|
||||
EHANDLE m_hVehicle;
|
||||
typedef CHandle<C_BaseCombatWeapon> CBaseCombatWeaponHandle;
|
||||
CBaseCombatWeaponHandle m_hLastWeapon;
|
||||
// players own view models, left & right hand
|
||||
CHandle< C_BaseViewModel > m_hViewModel[ MAX_VIEWMODELS ];
|
||||
|
||||
public:
|
||||
// For weapon prediction
|
||||
bool m_fOnTarget; //Is the crosshair on a target?
|
||||
|
||||
|
||||
|
||||
// END PREDICTION DATA COMPACTION
|
||||
public:
|
||||
|
||||
|
||||
int m_iDefaultFOV; // default FOV if no other zooms are occurring
|
||||
// Only this entity can change the zoom state once it has ownership
|
||||
int m_afButtonForced; // These are forced onto the player's inputs
|
||||
|
||||
|
||||
CUserCmd *m_pCurrentCommand;
|
||||
|
||||
EHANDLE m_hViewEntity;
|
||||
|
||||
// Movement constraints
|
||||
EHANDLE m_hConstraintEntity;
|
||||
Vector m_vecConstraintCenter;
|
||||
float m_flConstraintRadius;
|
||||
float m_flConstraintWidth;
|
||||
float m_flConstraintSpeedFactor;
|
||||
bool m_bConstraintPastRadius;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void CalcPlayerView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||
void CalcVehicleView(IClientVehicle *pVehicle, Vector& eyeOrigin, QAngle& eyeAngles,
|
||||
float& zNear, float& zFar, float& fov );
|
||||
virtual void CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||
virtual Vector GetChaseCamViewOffset( CBaseEntity *target );
|
||||
void CalcChaseCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||
void CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||
virtual void CalcDeathCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||
virtual void CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov);
|
||||
virtual void CalcFreezeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||
|
||||
// Check to see if we're in vgui input mode...
|
||||
void DetermineVguiInputMode( CUserCmd *pCmd );
|
||||
|
||||
// Used by prediction, sets the view angles for the player
|
||||
virtual void SetLocalViewAngles( const QAngle &viewAngles );
|
||||
virtual void SetViewAngles( const QAngle& ang );
|
||||
|
||||
// used by client side player footsteps
|
||||
surfacedata_t* GetGroundSurface();
|
||||
|
||||
protected:
|
||||
// Did we just enter a vehicle this frame?
|
||||
bool JustEnteredVehicle();
|
||||
|
||||
// DATA
|
||||
int m_iObserverMode; // if in spectator mode != 0
|
||||
EHANDLE m_hObserverTarget; // current observer target
|
||||
float m_flObserverChaseDistance; // last distance to observer traget
|
||||
Vector m_vecFreezeFrameStart;
|
||||
float m_flFreezeFrameStartTime; // Time at which we entered freeze frame observer mode
|
||||
float m_flFreezeFrameDistance;
|
||||
bool m_bWasFreezeFraming;
|
||||
float m_flDeathTime; // last time player died
|
||||
|
||||
|
||||
private:
|
||||
// Make sure no one calls this...
|
||||
C_BasePlayer& operator=( const C_BasePlayer& src );
|
||||
C_BasePlayer( const C_BasePlayer & ); // not defined, not accessible
|
||||
|
||||
// Vehicle stuff.
|
||||
EHANDLE m_hOldVehicle;
|
||||
EHANDLE m_hUseEntity;
|
||||
|
||||
CInterpolatedVar< Vector > m_iv_vecViewOffset;
|
||||
|
||||
// Not replicated
|
||||
Vector m_vecWaterJumpVel;
|
||||
|
||||
|
||||
protected:
|
||||
QAngle m_vecOldViewAngles;
|
||||
|
||||
private:
|
||||
bool m_bWasFrozen;
|
||||
|
||||
int m_nTickBase;
|
||||
int m_nFinalPredictedTick;
|
||||
|
||||
EHANDLE m_pCurrentVguiScreen;
|
||||
|
||||
|
||||
// Player flashlight dynamic light pointers
|
||||
bool m_bFlashlightEnabled[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
|
||||
#if !defined( NO_ENTITY_PREDICTION )
|
||||
CUtlVector< CHandle< C_BaseEntity > > m_SimulatedByThisPlayer;
|
||||
#endif
|
||||
|
||||
float m_flOldPlayerZ;
|
||||
float m_flOldPlayerViewOffsetZ;
|
||||
|
||||
Vector m_vecVehicleViewOrigin; // Used to store the calculated view of the player while riding in a vehicle
|
||||
QAngle m_vecVehicleViewAngles; // Vehicle angles
|
||||
float m_flVehicleViewFOV;
|
||||
int m_nVehicleViewSavedFrame; // Used to mark which frame was the last one the view was calculated for
|
||||
|
||||
// For UI purposes...
|
||||
int m_iOldAmmo[ MAX_AMMO_TYPES ];
|
||||
|
||||
C_CommandContext m_CommandContext;
|
||||
|
||||
// For underwater effects
|
||||
float m_flWaterSurfaceZ;
|
||||
bool m_bResampleWaterSurface;
|
||||
TimedEvent m_tWaterParticleTimer;
|
||||
CSmartPtr<WaterDebrisEffect> m_pWaterEmitter;
|
||||
|
||||
bool m_bPlayerUnderwater;
|
||||
|
||||
friend class CPrediction;
|
||||
friend class CASW_Prediction;
|
||||
|
||||
// HACK FOR TF2 Prediction
|
||||
friend class CTFGameMovementRecon;
|
||||
friend class CGameMovement;
|
||||
friend class CTFGameMovement;
|
||||
friend class CCSGameMovement;
|
||||
friend class CHL2GameMovement;
|
||||
friend class CPortalGameMovement;
|
||||
friend class CASW_MarineGameMovement;
|
||||
friend class CPaintGameMovement;
|
||||
|
||||
// Accessors for gamemovement
|
||||
float GetStepSize( void ) const { return m_Local.m_flStepSize; }
|
||||
|
||||
float m_flNextAvoidanceTime;
|
||||
float m_flAvoidanceRight;
|
||||
float m_flAvoidanceForward;
|
||||
float m_flAvoidanceDotForward;
|
||||
float m_flAvoidanceDotRight;
|
||||
|
||||
protected:
|
||||
virtual bool IsDucked( void ) const { return m_Local.m_bDucked; }
|
||||
virtual bool IsDucking( void ) const { return m_Local.m_bDucking; }
|
||||
virtual float GetFallVelocity( void ) { return m_Local.m_flFallVelocity; }
|
||||
void ForceSetupBonesAtTimeFakeInterpolation( matrix3x4a_t *pBonesOut, float curtimeOffset );
|
||||
|
||||
float m_flLaggedMovementValue;
|
||||
|
||||
// These are used to smooth out prediction corrections. They're most useful when colliding with
|
||||
// vphysics objects. The server will be sending constant prediction corrections, and these can help
|
||||
// the errors not be so jerky.
|
||||
Vector m_vecPredictionError;
|
||||
float m_flPredictionErrorTime;
|
||||
|
||||
Vector m_vecPreviouslyPredictedOrigin; // Used to determine if non-gamemovement game code has teleported, or tweaked the player's origin
|
||||
|
||||
char m_szLastPlaceName[MAX_PLACE_NAME_LENGTH]; // received from the server
|
||||
|
||||
// Texture names and surface data, used by CGameMovement
|
||||
int m_surfaceProps;
|
||||
surfacedata_t* m_pSurfaceData;
|
||||
char m_chTextureType;
|
||||
|
||||
bool m_bSentFreezeFrame;
|
||||
float m_flFreezeZOffset;
|
||||
byte m_ubEFNoInterpParity;
|
||||
byte m_ubOldEFNoInterpParity;
|
||||
|
||||
// If we have any attached split users, this is the list of them
|
||||
CUtlVector< CHandle< CBasePlayer > > m_hSplitScreenPlayers;
|
||||
int m_nSplitScreenSlot; //-1 == not a split player
|
||||
CHandle< CBasePlayer > m_hSplitOwner;
|
||||
bool m_bIsLocalPlayer;
|
||||
|
||||
private:
|
||||
|
||||
struct StepSoundCache_t
|
||||
{
|
||||
StepSoundCache_t() : m_usSoundNameIndex( 0 ) {}
|
||||
CSoundParameters m_SoundParameters;
|
||||
unsigned short m_usSoundNameIndex;
|
||||
};
|
||||
// One for left and one for right side of step
|
||||
StepSoundCache_t m_StepSoundCache[ 2 ];
|
||||
|
||||
public:
|
||||
|
||||
const char *GetLastKnownPlaceName( void ) const { return m_szLastPlaceName; } // return the last nav place name the player occupied
|
||||
|
||||
float GetLaggedMovementValue( void ){ return m_flLaggedMovementValue; }
|
||||
bool ShouldGoSouth( Vector vNPCForward, Vector vNPCRight ); //Such a bad name.
|
||||
|
||||
void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld; }
|
||||
|
||||
const fogplayerparams_t& GetPlayerFog() const { return m_PlayerFog; }
|
||||
|
||||
private:
|
||||
friend class CMoveHelperClient;
|
||||
|
||||
CNetworkHandle( CPostProcessController, m_hPostProcessCtrl ); // active postprocessing controller
|
||||
CNetworkHandle( CColorCorrection, m_hColorCorrectionCtrl ); // active FXVolume color correction
|
||||
|
||||
// fog params
|
||||
fogplayerparams_t m_PlayerFog;
|
||||
};
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BasePlayer);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
inline C_BasePlayer *ToBasePlayer( C_BaseEntity *pEntity )
|
||||
{
|
||||
if ( !pEntity || !pEntity->IsPlayer() )
|
||||
return NULL;
|
||||
|
||||
#if _DEBUG
|
||||
Assert( dynamic_cast<C_BasePlayer *>( pEntity ) != NULL );
|
||||
#endif
|
||||
|
||||
return static_cast<C_BasePlayer *>( pEntity );
|
||||
}
|
||||
|
||||
inline const C_BasePlayer *ToBasePlayer( const C_BaseEntity *pEntity )
|
||||
{
|
||||
if ( !pEntity || !pEntity->IsPlayer() )
|
||||
return NULL;
|
||||
|
||||
#if _DEBUG
|
||||
Assert( dynamic_cast<const C_BasePlayer *>( pEntity ) != NULL );
|
||||
#endif
|
||||
|
||||
return static_cast<const C_BasePlayer *>( pEntity );
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline IClientVehicle *C_BasePlayer::GetVehicle()
|
||||
{
|
||||
C_BaseEntity *pVehicleEnt = m_hVehicle.Get();
|
||||
return pVehicleEnt ? pVehicleEnt->GetClientVehicle() : NULL;
|
||||
}
|
||||
|
||||
inline bool C_BasePlayer::IsObserver() const
|
||||
{
|
||||
return (GetObserverMode() != OBS_MODE_NONE);
|
||||
}
|
||||
|
||||
inline int C_BasePlayer::GetImpulse( void ) const
|
||||
{
|
||||
return m_nImpulse;
|
||||
}
|
||||
|
||||
|
||||
inline C_CommandContext* C_BasePlayer::GetCommandContext()
|
||||
{
|
||||
return &m_CommandContext;
|
||||
}
|
||||
|
||||
inline int CBasePlayer::CurrentCommandNumber() const
|
||||
{
|
||||
Assert( m_pCurrentCommand );
|
||||
if ( !m_pCurrentCommand )
|
||||
return 0;
|
||||
return m_pCurrentCommand->command_number;
|
||||
}
|
||||
|
||||
inline const CUserCmd *CBasePlayer::GetCurrentUserCommand() const
|
||||
{
|
||||
Assert( m_pCurrentCommand );
|
||||
return m_pCurrentCommand;
|
||||
}
|
||||
|
||||
extern bool g_bEngineIsHLTV;
|
||||
|
||||
inline bool C_BasePlayer::IsHLTV() const
|
||||
{
|
||||
return m_bIsLocalPlayer && g_bEngineIsHLTV;
|
||||
}
|
||||
|
||||
inline bool C_BasePlayer::IsLocalPlayer( void ) const
|
||||
{
|
||||
return m_bIsLocalPlayer;
|
||||
}
|
||||
|
||||
|
||||
#endif // C_BASEPLAYER_H
|
201
game/client/c_basetempentity.cpp
Normal file
201
game/client/c_basetempentity.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Core Temp Entity client implementation.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basetempentity.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS(C_BaseTempEntity, DT_BaseTempEntity, CBaseTempEntity);
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE(C_BaseTempEntity, DT_BaseTempEntity)
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
// Global list of temp entity classes
|
||||
C_BaseTempEntity *C_BaseTempEntity::s_pTempEntities = NULL;
|
||||
|
||||
// Global list of dynamic temp entities
|
||||
C_BaseTempEntity *C_BaseTempEntity::s_pDynamicEntities = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns head of list
|
||||
// Output : CBaseTempEntity * -- head of list
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity *C_BaseTempEntity::GetDynamicList( void )
|
||||
{
|
||||
return s_pDynamicEntities;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns head of list
|
||||
// Output : CBaseTempEntity * -- head of list
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity *C_BaseTempEntity::GetList( void )
|
||||
{
|
||||
return s_pTempEntities;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity::C_BaseTempEntity( void )
|
||||
{
|
||||
// Add to list
|
||||
m_pNext = s_pTempEntities;
|
||||
s_pTempEntities = this;
|
||||
|
||||
m_pNextDynamic = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity::~C_BaseTempEntity( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get next temp ent in chain
|
||||
// Output : CBaseTempEntity *
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity *C_BaseTempEntity::GetNext( void )
|
||||
{
|
||||
return m_pNext;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get next temp ent in chain
|
||||
// Output : CBaseTempEntity *
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity *C_BaseTempEntity::GetNextDynamic( void )
|
||||
{
|
||||
return m_pNextDynamic;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::Precache( void )
|
||||
{
|
||||
// Nothing...
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called at startup to allow temp entities to precache any models/sounds that they need
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::PrecacheTempEnts( void )
|
||||
{
|
||||
C_BaseTempEntity *te = GetList();
|
||||
while ( te )
|
||||
{
|
||||
te->Precache();
|
||||
te = te->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called at startup and level load to clear out leftover temp entities
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::ClearDynamicTempEnts( void )
|
||||
{
|
||||
C_BaseTempEntity *next;
|
||||
C_BaseTempEntity *te = s_pDynamicEntities;
|
||||
while ( te )
|
||||
{
|
||||
next = te->GetNextDynamic();
|
||||
delete te;
|
||||
te = next;
|
||||
}
|
||||
|
||||
s_pDynamicEntities = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called at startup and level load to clear out leftover temp entities
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::CheckDynamicTempEnts( void )
|
||||
{
|
||||
C_BaseTempEntity *next, *newlist = NULL;
|
||||
C_BaseTempEntity *te = s_pDynamicEntities;
|
||||
while ( te )
|
||||
{
|
||||
next = te->GetNextDynamic();
|
||||
if ( te->ShouldDestroy() )
|
||||
{
|
||||
delete te;
|
||||
}
|
||||
else
|
||||
{
|
||||
te->m_pNextDynamic = newlist;
|
||||
newlist = te;
|
||||
}
|
||||
te = next;
|
||||
}
|
||||
|
||||
s_pDynamicEntities = newlist;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Dynamic/non-singleton temp entities are initialized by
|
||||
// calling into here. They should be added to a list of C_BaseTempEntities so
|
||||
// that their memory can be deallocated appropriately.
|
||||
// Input : *pEnt -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseTempEntity::Init( int entnum, int iSerialNum )
|
||||
{
|
||||
if ( entnum != -1 )
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
|
||||
// Link into dynamic entity list
|
||||
m_pNextDynamic = s_pDynamicEntities;
|
||||
s_pDynamicEntities = this;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void C_BaseTempEntity::Release()
|
||||
{
|
||||
Assert( !"C_BaseTempEntity::Release should never be called" );
|
||||
}
|
||||
|
||||
|
||||
void C_BaseTempEntity::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bool -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::PreDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
// TE's may or may not implement this
|
||||
}
|
||||
|
||||
|
||||
int C_BaseTempEntity::entindex( void ) const { Assert( 0 ); return 0; }
|
||||
void C_BaseTempEntity::PostDataUpdate( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||
void C_BaseTempEntity::OnPreDataChanged( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||
void C_BaseTempEntity::OnDataChanged( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||
void C_BaseTempEntity::SetDormant( bool bDormant ) { Assert( 0 ); }
|
||||
bool C_BaseTempEntity::IsDormant( void ) { Assert( 0 ); return false; };
|
||||
void C_BaseTempEntity::ReceiveMessage( int classID, bf_read &msg ) { Assert( 0 ); }
|
||||
void C_BaseTempEntity::SetDestroyedOnRecreateEntities( void ) { Assert(0); }
|
||||
|
||||
void* C_BaseTempEntity::GetDataTableBasePtr()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
122
game/client/c_basetempentity.h
Normal file
122
game/client/c_basetempentity.h
Normal file
@ -0,0 +1,122 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_BASETEMPENTITY_H
|
||||
#define C_BASETEMPENTITY_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "client_class.h"
|
||||
#include "iclientnetworkable.h"
|
||||
#include "c_recipientfilter.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Base class for TEs. All TEs should derive from this and at
|
||||
// least implement OnDataChanged to be notified when the TE has been received
|
||||
// from the server
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BaseTempEntity : public IClientUnknown, public IClientNetworkable
|
||||
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_NOBASE( C_BaseTempEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BaseTempEntity( void );
|
||||
virtual ~C_BaseTempEntity( void );
|
||||
|
||||
|
||||
// IClientUnknown implementation.
|
||||
public:
|
||||
|
||||
virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); }
|
||||
virtual const CBaseHandle& GetRefEHandle() const { return *((CBaseHandle*)0); }
|
||||
|
||||
virtual IClientUnknown* GetIClientUnknown() { return this; }
|
||||
virtual ICollideable* GetCollideable() { return 0; }
|
||||
virtual IClientNetworkable* GetClientNetworkable() { return this; }
|
||||
virtual IClientRenderable* GetClientRenderable() { return 0; }
|
||||
virtual IClientEntity* GetIClientEntity() { return 0; }
|
||||
virtual C_BaseEntity* GetBaseEntity() { return 0; }
|
||||
virtual IClientThinkable* GetClientThinkable() { return 0; }
|
||||
virtual IClientModelRenderable* GetClientModelRenderable() { return 0; }
|
||||
virtual IClientAlphaProperty* GetClientAlphaProperty() { return 0; }
|
||||
|
||||
// IClientNetworkable overrides.
|
||||
public:
|
||||
|
||||
virtual void Release();
|
||||
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void SetDormant( bool bDormant );
|
||||
virtual bool IsDormant( void );
|
||||
virtual int entindex( void ) const;
|
||||
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||
virtual void* GetDataTableBasePtr();
|
||||
virtual void SetDestroyedOnRecreateEntities( void );
|
||||
|
||||
public:
|
||||
|
||||
// Dummy for CNetworkVars.
|
||||
void NetworkStateChanged() {}
|
||||
void NetworkStateChanged( void *pVar ) {}
|
||||
|
||||
virtual bool Init(int entnum, int iSerialNum);
|
||||
|
||||
virtual void Precache( void );
|
||||
|
||||
// For dynamic entities, return true to allow destruction
|
||||
virtual bool ShouldDestroy( void ) { return false; };
|
||||
|
||||
C_BaseTempEntity *GetNext( void );
|
||||
|
||||
// Get list of tempentities
|
||||
static C_BaseTempEntity *GetList( void );
|
||||
|
||||
C_BaseTempEntity *GetNextDynamic( void );
|
||||
|
||||
// Determine the color modulation amount
|
||||
void GetColorModulation( float* color )
|
||||
{
|
||||
assert(color);
|
||||
color[0] = color[1] = color[2] = 1.0f;
|
||||
}
|
||||
|
||||
// Should this object be able to have shadows cast onto it?
|
||||
virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
|
||||
|
||||
// Static members
|
||||
public:
|
||||
// List of dynamically allocated temp entis
|
||||
static C_BaseTempEntity *GetDynamicList();
|
||||
|
||||
// Called at startup to allow temp entities to precache any models/sounds that they need
|
||||
static void PrecacheTempEnts( void );
|
||||
|
||||
static void ClearDynamicTempEnts( void );
|
||||
|
||||
static void CheckDynamicTempEnts( void );
|
||||
|
||||
private:
|
||||
|
||||
// Next in chain
|
||||
C_BaseTempEntity *m_pNext;
|
||||
C_BaseTempEntity *m_pNextDynamic;
|
||||
|
||||
// TEs add themselves to this list for the executable.
|
||||
static C_BaseTempEntity *s_pTempEntities;
|
||||
static C_BaseTempEntity *s_pDynamicEntities;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_BASETEMPENTITY_H
|
33
game/client/c_basetoggle.cpp
Normal file
33
game/client/c_basetoggle.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Copyright (c) 2007 Turtle Rock Studios, Inc.
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_basetoggle.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BaseToggle, DT_BaseToggle, CBaseToggle )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Returns the velocity imparted to players standing on us.
|
||||
void C_BaseToggle::GetGroundVelocityToApply( Vector &vecGroundVel )
|
||||
{
|
||||
vecGroundVel = GetLocalVelocity();
|
||||
vecGroundVel.z = 0.0f; // don't give upward velocity, or it could predict players into the air.
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BaseButton, DT_BaseButton, CBaseButton )
|
||||
RecvPropBool( RECVINFO( m_usable ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
bool C_BaseButton::IsPotentiallyUsable( void )
|
||||
{
|
||||
return true;
|
||||
}
|
42
game/client/c_basetoggle.h
Normal file
42
game/client/c_basetoggle.h
Normal file
@ -0,0 +1,42 @@
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Copyright (c) 2007 Turtle Rock Studios, Inc.
|
||||
|
||||
#if !defined( C_BASETOGGLE_H )
|
||||
#define C_BASETOGGLE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseentity.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class C_BaseToggle: public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseToggle, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void GetGroundVelocityToApply( Vector &vecGroundVel );
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class C_BaseButton: public C_BaseToggle
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseButton, C_BaseToggle );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BaseButton()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool IsPotentiallyUsable( void );
|
||||
|
||||
private:
|
||||
bool m_usable;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_BASETOGGLE_H
|
509
game/client/c_baseviewmodel.cpp
Normal file
509
game/client/c_baseviewmodel.cpp
Normal file
@ -0,0 +1,509 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side view model implementation. Responsible for drawing
|
||||
// the view model.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseviewmodel.h"
|
||||
#include "model_types.h"
|
||||
#include "hud.h"
|
||||
#include "view_shared.h"
|
||||
#include "iviewrender.h"
|
||||
#include "view.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "cl_animevent.h"
|
||||
#include "eventlist.h"
|
||||
#include "tools/bonelist.h"
|
||||
#include <KeyValues.h>
|
||||
#include "hltvcamera.h"
|
||||
#include "r_efx.h"
|
||||
#include "dlight.h"
|
||||
#include "clientalphaproperty.h"
|
||||
#include "iinput.h"
|
||||
#if defined( REPLAY_ENABLED )
|
||||
#include "replaycamera.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar vm_debug( "vm_debug", "0", FCVAR_CHEAT );
|
||||
ConVar vm_draw_always( "vm_draw_always", "0" );
|
||||
|
||||
void PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg );
|
||||
extern float g_flMuzzleFlashScale;
|
||||
|
||||
void FormatViewModelAttachment( C_BasePlayer *pPlayer, Vector &vOrigin, bool bInverse )
|
||||
{
|
||||
int nSlot = 0;
|
||||
if ( pPlayer )
|
||||
{
|
||||
int nPlayerSlot = C_BasePlayer::GetSplitScreenSlotForPlayer( pPlayer );
|
||||
if ( nPlayerSlot == -1 )
|
||||
{
|
||||
nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
|
||||
}
|
||||
else
|
||||
{
|
||||
nSlot = nPlayerSlot;
|
||||
}
|
||||
}
|
||||
|
||||
Assert( nSlot != -1 );
|
||||
|
||||
// Presumably, SetUpView has been called so we know our FOV and render origin.
|
||||
const CViewSetup *pViewSetup = view->GetPlayerViewSetup( nSlot );
|
||||
|
||||
float worldx = tan( pViewSetup->fov * M_PI/360.0 );
|
||||
float viewx = tan( pViewSetup->fovViewmodel * M_PI/360.0 );
|
||||
|
||||
// aspect ratio cancels out, so only need one factor
|
||||
// the difference between the screen coordinates of the 2 systems is the ratio
|
||||
// of the coefficients of the projection matrices (tan (fov/2) is that coefficient)
|
||||
float factorX = worldx / viewx;
|
||||
|
||||
float factorY = factorX;
|
||||
|
||||
// Get the coordinates in the viewer's space.
|
||||
Vector tmp = vOrigin - pViewSetup->origin;
|
||||
Vector vTransformed( MainViewRight(nSlot).Dot( tmp ), MainViewUp(nSlot).Dot( tmp ), MainViewForward(nSlot).Dot( tmp ) );
|
||||
|
||||
// Now squash X and Y.
|
||||
if ( bInverse )
|
||||
{
|
||||
if ( factorX != 0 && factorY != 0 )
|
||||
{
|
||||
vTransformed.x /= factorX;
|
||||
vTransformed.y /= factorY;
|
||||
}
|
||||
else
|
||||
{
|
||||
vTransformed.x = 0.0f;
|
||||
vTransformed.y = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vTransformed.x *= factorX;
|
||||
vTransformed.y *= factorY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Transform back to world space.
|
||||
Vector vOut = (MainViewRight(nSlot) * vTransformed.x) + (MainViewUp(nSlot) * vTransformed.y) + (MainViewForward(nSlot) * vTransformed.z);
|
||||
vOrigin = pViewSetup->origin + vOut;
|
||||
}
|
||||
|
||||
|
||||
void C_BaseViewModel::FormatViewModelAttachment( int nAttachment, matrix3x4_t &attachmentToWorld )
|
||||
{
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
Vector vecOrigin;
|
||||
MatrixPosition( attachmentToWorld, vecOrigin );
|
||||
::FormatViewModelAttachment( pPlayer, vecOrigin, false );
|
||||
PositionMatrix( vecOrigin, attachmentToWorld );
|
||||
}
|
||||
|
||||
void C_BaseViewModel::UncorrectViewModelAttachment( Vector &vOrigin )
|
||||
{
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
// Unformat the attachment.
|
||||
::FormatViewModelAttachment( pPlayer, vOrigin, true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseViewModel::FireEvent( const Vector& origin, const QAngle& angles, int eventNum, const char *options )
|
||||
{
|
||||
// We override sound requests so that we can play them locally on the owning player
|
||||
if ( ( eventNum == AE_CL_PLAYSOUND ) || ( eventNum == CL_EVENT_SOUND ) )
|
||||
{
|
||||
// Only do this if we're owned by someone
|
||||
if ( GetOwner() != NULL )
|
||||
{
|
||||
CLocalPlayerFilter filter;
|
||||
EmitSound( filter, GetOwner()->GetSoundSourceIndex(), options, &GetAbsOrigin() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
C_BasePlayer *pOwner = ToBasePlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return;
|
||||
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( pOwner );
|
||||
|
||||
// Otherwise pass the event to our associated weapon
|
||||
C_BaseCombatWeapon *pWeapon = pOwner->GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
{
|
||||
bool bResult = pWeapon->OnFireEvent( this, origin, angles, eventNum, options );
|
||||
if ( !bResult )
|
||||
{
|
||||
if ( eventNum == AE_CLIENT_EFFECT_ATTACH && ::input->CAM_IsThirdPerson() )
|
||||
return;
|
||||
|
||||
BaseClass::FireEvent( origin, angles, eventNum, options );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool C_BaseViewModel::Interpolate( float currentTime )
|
||||
{
|
||||
CStudioHdr *pStudioHdr = GetModelPtr();
|
||||
// Make sure we reset our animation information if we've switch sequences
|
||||
UpdateAnimationParity();
|
||||
|
||||
bool bret = BaseClass::Interpolate( currentTime );
|
||||
|
||||
// Hack to extrapolate cycle counter for view model
|
||||
float elapsed_time = currentTime - m_flAnimTime;
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
// Predicted viewmodels have fixed up interval
|
||||
if ( GetPredictable() || IsClientCreated() )
|
||||
{
|
||||
Assert( pPlayer );
|
||||
float curtime = pPlayer ? pPlayer->GetFinalPredictedTime() : gpGlobals->curtime;
|
||||
elapsed_time = curtime - m_flAnimTime;
|
||||
// Adjust for interpolated partial frame
|
||||
elapsed_time += ( gpGlobals->interpolation_amount * TICK_INTERVAL );
|
||||
}
|
||||
|
||||
// Prediction errors?
|
||||
if ( elapsed_time < 0 )
|
||||
{
|
||||
elapsed_time = 0;
|
||||
}
|
||||
|
||||
float dt = elapsed_time * GetSequenceCycleRate( pStudioHdr, GetSequence() );
|
||||
if ( dt >= 1.0f )
|
||||
{
|
||||
if ( !IsSequenceLooping( GetSequence() ) )
|
||||
{
|
||||
dt = 0.999f;
|
||||
}
|
||||
else
|
||||
{
|
||||
dt = fmod( dt, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
SetCycle( dt );
|
||||
return bret;
|
||||
}
|
||||
|
||||
|
||||
inline bool C_BaseViewModel::ShouldFlipViewModel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void C_BaseViewModel::ApplyBoneMatrixTransform( matrix3x4_t& transform )
|
||||
{
|
||||
if ( ShouldFlipViewModel() )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( GetOwner() );
|
||||
|
||||
matrix3x4_t viewMatrix, viewMatrixInverse;
|
||||
|
||||
// We could get MATERIAL_VIEW here, but this is called sometimes before the renderer
|
||||
// has set that matrix. Luckily, this is called AFTER the CViewSetup has been initialized.
|
||||
const CViewSetup *pSetup = view->GetPlayerViewSetup();
|
||||
AngleMatrix( pSetup->angles, pSetup->origin, viewMatrixInverse );
|
||||
MatrixInvert( viewMatrixInverse, viewMatrix );
|
||||
|
||||
// Transform into view space.
|
||||
matrix3x4_t temp, temp2;
|
||||
ConcatTransforms( viewMatrix, transform, temp );
|
||||
|
||||
// Flip it along X.
|
||||
|
||||
// (This is the slower way to do it, and it equates to negating the top row).
|
||||
//matrix3x4_t mScale;
|
||||
//SetIdentityMatrix( mScale );
|
||||
//mScale[0][0] = 1;
|
||||
//mScale[1][1] = -1;
|
||||
//mScale[2][2] = 1;
|
||||
//ConcatTransforms( mScale, temp, temp2 );
|
||||
temp[1][0] = -temp[1][0];
|
||||
temp[1][1] = -temp[1][1];
|
||||
temp[1][2] = -temp[1][2];
|
||||
temp[1][3] = -temp[1][3];
|
||||
|
||||
// Transform back out of view space.
|
||||
ConcatTransforms( viewMatrixInverse, temp, transform );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: check if weapon viewmodel should be drawn
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseViewModel::ShouldDraw()
|
||||
{
|
||||
if ( g_bEngineIsHLTV )
|
||||
{
|
||||
return ( HLTVCamera()->GetMode() == OBS_MODE_IN_EYE &&
|
||||
HLTVCamera()->GetPrimaryTarget() == GetOwner() );
|
||||
}
|
||||
#if defined( REPLAY_ENABLED )
|
||||
else if ( engine->IsReplay() )
|
||||
{
|
||||
return ( ReplayCamera()->GetMode() == OBS_MODE_IN_EYE &&
|
||||
ReplayCamera()->GetPrimaryTarget() == GetOwner() );
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
Assert( !IsEffectActive( EF_NODRAW ) );
|
||||
Assert( GetRenderMode() != kRenderNone );
|
||||
|
||||
if ( vm_draw_always.GetBool() )
|
||||
return true;
|
||||
if ( GetOwner() != C_BasePlayer::GetLocalPlayer() )
|
||||
return false;
|
||||
|
||||
return BaseClass::ShouldDraw();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
|
||||
// by this player, otherwise draw the worldmodel.
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseViewModel::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
if ( flags & STUDIO_RENDER )
|
||||
{
|
||||
// Determine blending amount and tell engine
|
||||
float blend = (float)( instance.m_nAlpha / 255.0f );
|
||||
|
||||
// Totally gone
|
||||
if ( blend <= 0.0f )
|
||||
return 0;
|
||||
|
||||
// Tell engine
|
||||
render->SetBlend( blend );
|
||||
|
||||
float color[3];
|
||||
GetColorModulation( color );
|
||||
render->SetColorModulation( color );
|
||||
}
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
|
||||
if ( ShouldFlipViewModel() )
|
||||
pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
|
||||
|
||||
int ret = 0;
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
C_BaseCombatWeapon *pWeapon = GetOwningWeapon();
|
||||
|
||||
// If the local player's overriding the viewmodel rendering, let him do it
|
||||
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
|
||||
{
|
||||
ret = pPlayer->DrawOverriddenViewmodel( this, flags, instance );
|
||||
}
|
||||
else if ( pWeapon && pWeapon->IsOverridingViewmodel() )
|
||||
{
|
||||
ret = pWeapon->DrawOverriddenViewmodel( this, flags, instance );
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = BaseClass::DrawModel( flags, instance );
|
||||
}
|
||||
|
||||
pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
|
||||
|
||||
// Now that we've rendered, reset the animation restart flag
|
||||
if ( flags & STUDIO_RENDER )
|
||||
{
|
||||
if ( m_nOldAnimationParity != m_nAnimationParity )
|
||||
{
|
||||
m_nOldAnimationParity = m_nAnimationParity;
|
||||
}
|
||||
|
||||
// Tell the weapon itself that we've rendered, in case it wants to do something
|
||||
if ( pWeapon )
|
||||
{
|
||||
pWeapon->ViewModelDrawn( this );
|
||||
}
|
||||
|
||||
if ( vm_debug.GetBool() )
|
||||
{
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
int line = 16;
|
||||
CStudioHdr *hdr = GetModelPtr();
|
||||
engine->Con_NPrintf( line++, "%s: %s(%d), cycle: %.2f cyclerate: %.2f playbackrate: %.2f\n",
|
||||
(hdr)?hdr->pszName():"(null)",
|
||||
GetSequenceName( GetSequence() ),
|
||||
GetSequence(),
|
||||
GetCycle(),
|
||||
GetSequenceCycleRate( hdr, GetSequence() ),
|
||||
GetPlaybackRate()
|
||||
);
|
||||
if ( hdr )
|
||||
{
|
||||
for( int i=0; i < hdr->GetNumPoseParameters(); ++i )
|
||||
{
|
||||
const mstudioposeparamdesc_t &Pose = hdr->pPoseParameter( i );
|
||||
engine->Con_NPrintf( line++, "pose_param %s: %f",
|
||||
Pose.pszName(), GetPoseParameter( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Determine blending amount and tell engine
|
||||
float blend = (float)( instance.m_nAlpha / 255.0f );
|
||||
float color[3];
|
||||
GetColorModulation( color );
|
||||
engine->Con_NPrintf( line++, "blend=%f, color=%f,%f,%f", blend, color[0], color[1], color[2] );
|
||||
engine->Con_NPrintf( line++, "GetRenderMode()=%d", GetRenderMode() );
|
||||
engine->Con_NPrintf( line++, "m_nRenderFX=0x%8.8X", GetRenderFX() );
|
||||
|
||||
color24 c = GetRenderColor();
|
||||
unsigned char a = GetRenderAlpha();
|
||||
engine->Con_NPrintf( line++, "rendercolor=%d,%d,%d,%d", c.r, c.g, c.b, a );
|
||||
|
||||
engine->Con_NPrintf( line++, "origin=%f, %f, %f", GetRenderOrigin().x, GetRenderOrigin().y, GetRenderOrigin().z );
|
||||
engine->Con_NPrintf( line++, "angles=%f, %f, %f", GetRenderAngles()[0], GetRenderAngles()[1], GetRenderAngles()[2] );
|
||||
|
||||
if ( IsEffectActive( EF_NODRAW ) )
|
||||
{
|
||||
engine->Con_NPrintf( line++, "EF_NODRAW" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called by the player when the player's overriding the viewmodel drawing. Avoids infinite recursion.
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseViewModel::DrawOverriddenViewmodel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
return BaseClass::DrawModel( flags, instance );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
uint8 C_BaseViewModel::OverrideAlphaModulation( uint8 nAlpha )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( GetOwner() );
|
||||
|
||||
// See if the local player wants to override the viewmodel's rendering
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
|
||||
return pPlayer->AlphaProp()->ComputeRenderAlpha();
|
||||
|
||||
C_BaseCombatWeapon *pWeapon = GetOwningWeapon();
|
||||
if ( pWeapon && pWeapon->IsOverridingViewmodel() )
|
||||
return pWeapon->AlphaProp()->ComputeRenderAlpha();
|
||||
|
||||
return nAlpha;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderableTranslucencyType_t C_BaseViewModel::ComputeTranslucencyType( void )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( GetOwner() );
|
||||
|
||||
// See if the local player wants to override the viewmodel's rendering
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
|
||||
return pPlayer->ComputeTranslucencyType();
|
||||
|
||||
C_BaseCombatWeapon *pWeapon = GetOwningWeapon();
|
||||
if ( pWeapon && pWeapon->IsOverridingViewmodel() )
|
||||
return pWeapon->ComputeTranslucencyType();
|
||||
|
||||
return BaseClass::ComputeTranslucencyType();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: If the animation parity of the weapon has changed, we reset cycle to avoid popping
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseViewModel::UpdateAnimationParity( void )
|
||||
{
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
|
||||
// If we're predicting, then we don't use animation parity because we change the animations on the clientside
|
||||
// while predicting. When not predicting, only the server changes the animations, so a parity mismatch
|
||||
// tells us if we need to reset the animation.
|
||||
if ( m_nOldAnimationParity != m_nAnimationParity && !GetPredictable() )
|
||||
{
|
||||
float curtime = (pPlayer && IsIntermediateDataAllocated()) ? pPlayer->GetFinalPredictedTime() : gpGlobals->curtime;
|
||||
// FIXME: this is bad
|
||||
// Simulate a networked m_flAnimTime and m_flCycle
|
||||
// FIXME: Do we need the magic 0.1?
|
||||
SetCycle( 0.0f ); // GetSequenceCycleRate( GetSequence() ) * 0.1;
|
||||
m_flAnimTime = curtime;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update global map state based on data received
|
||||
// Input : bnewentity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseViewModel::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
AlphaProp()->EnableAlphaModulationOverride( true );
|
||||
}
|
||||
|
||||
SetPredictionEligible( true );
|
||||
BaseClass::OnDataChanged(updateType);
|
||||
}
|
||||
void C_BaseViewModel::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate(updateType);
|
||||
OnLatchInterpolatedVariables( LATCH_ANIMATION_VAR );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return the player who will predict this entity
|
||||
//-----------------------------------------------------------------------------
|
||||
CBasePlayer *C_BaseViewModel::GetPredictionOwner()
|
||||
{
|
||||
return ToBasePlayer( GetOwner() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseViewModel::GetBoneControllers(float controllers[MAXSTUDIOBONECTRLS])
|
||||
{
|
||||
BaseClass::GetBoneControllers( controllers );
|
||||
|
||||
// Tell the weapon itself that we've rendered, in case it wants to do something
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( GetOwner() );
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
{
|
||||
pWeapon->GetViewmodelBoneControllers( this, controllers );
|
||||
}
|
||||
}
|
||||
|
20
game/client/c_baseviewmodel.h
Normal file
20
game/client/c_baseviewmodel.h
Normal file
@ -0,0 +1,20 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side view model implementation. Responsible for drawing
|
||||
// the view model.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_BASEVIEWMODEL_H
|
||||
#define C_BASEVIEWMODEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseanimating.h"
|
||||
#include "UtlVector.h"
|
||||
#include "baseviewmodel_shared.h"
|
||||
|
||||
|
||||
#endif // C_BASEVIEWMODEL_H
|
354
game/client/c_beamspotlight.cpp
Normal file
354
game/client/c_beamspotlight.cpp
Normal file
@ -0,0 +1,354 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dlight.h"
|
||||
#include "iefx.h"
|
||||
|
||||
#include "beam_shared.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSpotlightTraceCacheEntry
|
||||
{
|
||||
public:
|
||||
CSpotlightTraceCacheEntry()
|
||||
{
|
||||
m_origin.Init();
|
||||
m_radius = -1.0f;
|
||||
}
|
||||
bool IsValidFor( const Vector &origin )
|
||||
{
|
||||
if ( m_radius > 0 && m_origin.DistToSqr(origin) < 1.0f )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
void Cache( const Vector &origin, const trace_t &tr )
|
||||
{
|
||||
m_radius = (tr.endpos - origin).Length();
|
||||
m_origin = origin;
|
||||
}
|
||||
|
||||
Vector m_origin;
|
||||
float m_radius;
|
||||
};
|
||||
|
||||
static const int NUM_CACHE_ENTRIES = 64;
|
||||
|
||||
class C_BeamSpotLight : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BeamSpotLight, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BeamSpotLight();
|
||||
~C_BeamSpotLight();
|
||||
|
||||
bool ShouldDraw();
|
||||
void ClientThink( void );
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
void Release( void );
|
||||
|
||||
private:
|
||||
|
||||
Vector SpotlightCurrentPos(void);
|
||||
void SpotlightCreate(void);
|
||||
void SpotlightDestroy(void);
|
||||
|
||||
// Computes render info for a spotlight
|
||||
void ComputeRenderInfo();
|
||||
|
||||
private:
|
||||
|
||||
int m_nHaloIndex;
|
||||
int m_nRotationAxis;
|
||||
float m_flRotationSpeed;
|
||||
|
||||
|
||||
bool m_bSpotlightOn;
|
||||
bool m_bHasDynamicLight;
|
||||
|
||||
float m_flSpotlightMaxLength;
|
||||
float m_flSpotlightGoalWidth;
|
||||
float m_flHDRColorScale;
|
||||
|
||||
Vector m_vSpotlightTargetPos;
|
||||
Vector m_vSpotlightCurrentPos;
|
||||
Vector m_vSpotlightDir;
|
||||
|
||||
CHandle<C_Beam> m_hSpotlight;
|
||||
|
||||
float m_flSpotlightCurLength;
|
||||
|
||||
float m_flLightScale;
|
||||
|
||||
dlight_t* m_pDynamicLight;
|
||||
|
||||
float m_lastTime;
|
||||
CSpotlightTraceCacheEntry *m_pCache;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( beam_spotlight, C_BeamSpotLight );
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BeamSpotLight, DT_BeamSpotlight, CBeamSpotlight )
|
||||
RecvPropInt( RECVINFO(m_nHaloIndex) ),
|
||||
RecvPropBool( RECVINFO(m_bSpotlightOn) ),
|
||||
RecvPropBool( RECVINFO(m_bHasDynamicLight) ),
|
||||
RecvPropFloat( RECVINFO(m_flSpotlightMaxLength) ),
|
||||
RecvPropFloat( RECVINFO(m_flSpotlightGoalWidth) ),
|
||||
RecvPropFloat( RECVINFO(m_flHDRColorScale) ),
|
||||
RecvPropInt( RECVINFO(m_nRotationAxis) ),
|
||||
RecvPropFloat( RECVINFO(m_flRotationSpeed) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BeamSpotLight::C_BeamSpotLight()
|
||||
: m_vSpotlightTargetPos( vec3_origin )
|
||||
, m_vSpotlightCurrentPos( vec3_origin )
|
||||
, m_vSpotlightDir( vec3_origin )
|
||||
, m_flSpotlightCurLength( 0.0f )
|
||||
, m_flLightScale( 100.0f )
|
||||
, m_pDynamicLight( NULL )
|
||||
, m_lastTime( 0.0f )
|
||||
, m_pCache(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
C_BeamSpotLight::~C_BeamSpotLight()
|
||||
{
|
||||
delete[] m_pCache;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BeamSpotLight::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::ClientThink( void )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_lastTime;
|
||||
if ( !m_lastTime )
|
||||
{
|
||||
dt = 0.0f;
|
||||
}
|
||||
m_lastTime = gpGlobals->curtime;
|
||||
|
||||
// ---------------------------------------------------
|
||||
// If I don't have a spotlight attempt to create one
|
||||
// ---------------------------------------------------
|
||||
if ( !m_hSpotlight )
|
||||
{
|
||||
if ( m_bSpotlightOn )
|
||||
{
|
||||
// Make the spotlight
|
||||
SpotlightCreate();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ( !m_bSpotlightOn )
|
||||
{
|
||||
SpotlightDestroy();
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
return;
|
||||
}
|
||||
|
||||
// update rotation
|
||||
if ( m_flRotationSpeed != 0.0f )
|
||||
{
|
||||
QAngle angles = GetAbsAngles();
|
||||
angles[m_nRotationAxis] += m_flRotationSpeed * dt;
|
||||
angles[m_nRotationAxis] = anglemod(angles[m_nRotationAxis]);
|
||||
if ( !m_pCache )
|
||||
{
|
||||
m_pCache = new CSpotlightTraceCacheEntry[NUM_CACHE_ENTRIES];
|
||||
}
|
||||
|
||||
SetAbsAngles( angles );
|
||||
}
|
||||
m_vSpotlightCurrentPos = SpotlightCurrentPos();
|
||||
|
||||
Assert( m_hSpotlight );
|
||||
|
||||
m_hSpotlight->SetStartPos( GetAbsOrigin() );
|
||||
m_hSpotlight->SetEndPos( m_vSpotlightCurrentPos );
|
||||
|
||||
// Avoid sudden change in where beam fades out when cross disconinuities
|
||||
Vector dir = m_vSpotlightCurrentPos - GetAbsOrigin();
|
||||
float flBeamLength = VectorNormalize( dir );
|
||||
m_flSpotlightCurLength = (0.60*m_flSpotlightCurLength) + (0.4*flBeamLength);
|
||||
|
||||
ComputeRenderInfo();
|
||||
|
||||
m_hSpotlight->RelinkBeam();
|
||||
|
||||
//NDebugOverlay::Cross3D(GetAbsOrigin(),Vector(-5,-5,-5),Vector(5,5,5),0,255,0,true,0.1);
|
||||
//NDebugOverlay::Cross3D(m_vSpotlightCurrentPos,Vector(-5,-5,-5),Vector(5,5,5),0,255,0,true,0.1);
|
||||
//NDebugOverlay::Cross3D(m_vSpotlightTargetPos,Vector(-5,-5,-5),Vector(5,5,5),255,0,0,true,0.1);
|
||||
|
||||
// Do we need to keep updating?
|
||||
if ( !GetMoveParent() && m_flRotationSpeed == 0 )
|
||||
{
|
||||
// No reason to think again, we're not going to move unless there's a data change
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_flSpotlightCurLength = m_flSpotlightMaxLength;
|
||||
}
|
||||
|
||||
// On a data change always think again
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::Release()
|
||||
{
|
||||
SpotlightDestroy();
|
||||
BaseClass::Release();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::SpotlightCreate(void)
|
||||
{
|
||||
m_vSpotlightTargetPos = SpotlightCurrentPos();
|
||||
|
||||
{
|
||||
//C_Beam *beam = CBeam::BeamCreate( "sprites/spotlight.vmt", m_flSpotlightGoalWidth );
|
||||
C_Beam *beam = C_Beam::BeamCreate( "sprites/glow_test02.vmt", m_flSpotlightGoalWidth );
|
||||
// Beam only exists client side
|
||||
ClientEntityList().AddNonNetworkableEntity( beam );
|
||||
m_hSpotlight = beam;
|
||||
}
|
||||
|
||||
// Set the temporary spawnflag on the beam so it doesn't save (we'll recreate it on restore)
|
||||
m_hSpotlight->SetHDRColorScale( m_flHDRColorScale );
|
||||
const color24 c = GetRenderColor();
|
||||
m_hSpotlight->SetColor( c.r, c.g, c.b );
|
||||
m_hSpotlight->SetHaloTexture(m_nHaloIndex);
|
||||
m_hSpotlight->SetHaloScale(60);
|
||||
m_hSpotlight->SetEndWidth(m_flSpotlightGoalWidth);
|
||||
m_hSpotlight->SetBeamFlags( (FBEAM_SHADEOUT|FBEAM_NOTILE) );
|
||||
m_hSpotlight->SetBrightness( 64 );
|
||||
m_hSpotlight->SetNoise( 0 );
|
||||
|
||||
m_hSpotlight->PointsInit( GetAbsOrigin(), m_vSpotlightTargetPos );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::SpotlightDestroy(void)
|
||||
{
|
||||
if ( m_hSpotlight )
|
||||
{
|
||||
UTIL_Remove( m_hSpotlight );
|
||||
m_hSpotlight.Term();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Vector C_BeamSpotLight::SpotlightCurrentPos(void)
|
||||
{
|
||||
QAngle angles = GetAbsAngles();
|
||||
GetVectors( &m_vSpotlightDir, NULL, NULL );
|
||||
Vector position = GetAbsOrigin();
|
||||
int cacheIndex = -1;
|
||||
if ( m_pCache )
|
||||
{
|
||||
cacheIndex = int( angles[m_nRotationAxis] * float(NUM_CACHE_ENTRIES) * (1.0f / 360.0f)) & (NUM_CACHE_ENTRIES - 1);
|
||||
if ( m_pCache[cacheIndex].IsValidFor(GetAbsOrigin()) )
|
||||
{
|
||||
return position + m_vSpotlightDir * m_pCache[cacheIndex].m_radius;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get beam end point. Only collide with solid objects, not npcs
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( position, position + (m_vSpotlightDir * 2 * m_flSpotlightMaxLength), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
|
||||
if ( cacheIndex >= 0 )
|
||||
{
|
||||
m_pCache[cacheIndex].Cache(position, tr);
|
||||
}
|
||||
|
||||
return tr.endpos;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Computes render info for a spotlight
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::ComputeRenderInfo()
|
||||
{
|
||||
// Fade out spotlight end if past max length.
|
||||
if ( m_flSpotlightCurLength > 2*m_flSpotlightMaxLength )
|
||||
{
|
||||
SetRenderAlpha( 0 );
|
||||
m_hSpotlight->SetFadeLength( m_flSpotlightMaxLength );
|
||||
}
|
||||
else if ( m_flSpotlightCurLength > m_flSpotlightMaxLength )
|
||||
{
|
||||
SetRenderAlpha( (1-((m_flSpotlightCurLength-m_flSpotlightMaxLength)/m_flSpotlightMaxLength)) );
|
||||
m_hSpotlight->SetFadeLength( m_flSpotlightMaxLength );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRenderAlpha( 1.0 );
|
||||
m_hSpotlight->SetFadeLength( m_flSpotlightCurLength );
|
||||
}
|
||||
|
||||
// Adjust end width to keep beam width constant
|
||||
float flNewWidth = m_flSpotlightGoalWidth * (m_flSpotlightCurLength / m_flSpotlightMaxLength);
|
||||
flNewWidth = clamp(flNewWidth, 0, MAX_BEAM_WIDTH );
|
||||
m_hSpotlight->SetEndWidth(flNewWidth);
|
||||
|
||||
if ( m_bHasDynamicLight )
|
||||
{
|
||||
// <<TODO>> - magic number 1.8 depends on sprite size
|
||||
m_flLightScale = 1.8*flNewWidth;
|
||||
|
||||
if ( m_flLightScale > 0 )
|
||||
{
|
||||
const color24 c = GetRenderColor();
|
||||
float a = GetRenderAlpha() / 255.0f;
|
||||
ColorRGBExp32 color;
|
||||
color.r = c.r * a;
|
||||
color.g = c.g * a;
|
||||
color.b = c.b * a;
|
||||
color.exponent = 0;
|
||||
if ( color.r == 0 && color.g == 0 && color.b == 0 )
|
||||
return;
|
||||
|
||||
// Deal with the environment light
|
||||
if ( !m_pDynamicLight || (m_pDynamicLight->key != index) )
|
||||
{
|
||||
m_pDynamicLight = effects->CL_AllocDlight( index );
|
||||
assert (m_pDynamicLight);
|
||||
}
|
||||
|
||||
//m_pDynamicLight->flags = DLIGHT_NO_MODEL_ILLUMINATION;
|
||||
m_pDynamicLight->radius = m_flLightScale*3.0f;
|
||||
m_pDynamicLight->origin = GetAbsOrigin() + Vector(0,0,5);
|
||||
m_pDynamicLight->die = gpGlobals->curtime + 0.05f;
|
||||
m_pDynamicLight->color = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
game/client/c_breakableprop.cpp
Normal file
51
game/client/c_breakableprop.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "model_types.h"
|
||||
#include "vcollide.h"
|
||||
#include "vcollide_parse.h"
|
||||
#include "solidsetdefaults.h"
|
||||
#include "bone_setup.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "physics.h"
|
||||
#include "c_breakableprop.h"
|
||||
#include "view.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_BreakableProp, DT_BreakableProp, CBreakableProp)
|
||||
RecvPropBool( RECVINFO( m_bClientPhysics ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BreakableProp::C_BreakableProp( void )
|
||||
{
|
||||
m_takedamage = DAMAGE_YES;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copy fade from another breakable prop
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BreakableProp::CopyFadeFrom( C_BreakableProp *pSource )
|
||||
{
|
||||
SetGlobalFadeScale( pSource->GetGlobalFadeScale() );
|
||||
SetDistanceFade( pSource->GetMinFadeDist(), pSource->GetMaxFadeDist() );
|
||||
}
|
||||
|
||||
void C_BreakableProp::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
if ( m_bClientPhysics )
|
||||
{
|
||||
bool bCreate = (type == DATA_UPDATE_CREATED) ? true : false;
|
||||
VPhysicsShadowDataChanged(bCreate, this);
|
||||
}
|
||||
}
|
||||
|
37
game/client/c_breakableprop.h
Normal file
37
game/client/c_breakableprop.h
Normal file
@ -0,0 +1,37 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_BREAKABLEPROP_H
|
||||
#define C_BREAKABLEPROP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BreakableProp : public C_BaseAnimating
|
||||
{
|
||||
typedef C_BaseAnimating BaseClass;
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BreakableProp();
|
||||
|
||||
virtual bool IsProp( void ) const
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
// Copy fade from another breakable prop
|
||||
void CopyFadeFrom( C_BreakableProp *pSource );
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
|
||||
private:
|
||||
bool m_bClientPhysics;
|
||||
};
|
||||
|
||||
#endif // C_BREAKABLEPROP_H
|
247
game/client/c_colorcorrection.cpp
Normal file
247
game/client/c_colorcorrection.cpp
Normal file
@ -0,0 +1,247 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Color correction entity with simple radial falloff
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_colorcorrection.h"
|
||||
#include "filesystem.h"
|
||||
#include "cdll_client_int.h"
|
||||
#include "colorcorrectionmgr.h"
|
||||
#include "materialsystem/materialsystemutil.h"
|
||||
#include "iclientmode.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
static ConVar mat_colcorrection_disableentities( "mat_colcorrection_disableentities", "0", FCVAR_NONE, "Disable map color-correction entities" );
|
||||
|
||||
static ConVar mat_colcorrection_forceentitiesclientside( "mat_colcorrection_forceentitiesclientside", "0", FCVAR_CHEAT, "Forces color correction entities to be updated on the client" );
|
||||
|
||||
#ifdef CColorCorrection
|
||||
#undef CColorCorrection
|
||||
#endif
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrection, DT_ColorCorrection, CColorCorrection)
|
||||
RecvPropVector( RECVINFO(m_vecOrigin) ),
|
||||
RecvPropFloat( RECVINFO(m_minFalloff) ),
|
||||
RecvPropFloat( RECVINFO(m_maxFalloff) ),
|
||||
RecvPropFloat( RECVINFO(m_flCurWeight) ),
|
||||
RecvPropFloat( RECVINFO(m_flMaxWeight) ),
|
||||
RecvPropFloat( RECVINFO(m_flFadeInDuration) ),
|
||||
RecvPropFloat( RECVINFO(m_flFadeOutDuration) ),
|
||||
RecvPropString( RECVINFO(m_netLookupFilename) ),
|
||||
RecvPropBool( RECVINFO(m_bEnabled) ),
|
||||
RecvPropBool( RECVINFO(m_bMaster) ),
|
||||
RecvPropBool( RECVINFO(m_bClientSide) ),
|
||||
RecvPropBool( RECVINFO(m_bExclusive) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//------------------------------------------------------------------------------
|
||||
C_ColorCorrection::C_ColorCorrection()
|
||||
{
|
||||
m_minFalloff = -1.0f;
|
||||
m_maxFalloff = -1.0f;
|
||||
m_flFadeInDuration = 0.0f;
|
||||
m_flFadeOutDuration = 0.0f;
|
||||
m_flCurWeight = 0.0f;
|
||||
m_flMaxWeight = 1.0f;
|
||||
m_netLookupFilename[0] = '\0';
|
||||
m_bEnabled = false;
|
||||
m_bMaster = false;
|
||||
m_bExclusive = false;
|
||||
m_CCHandle = INVALID_CLIENT_CCHANDLE;
|
||||
|
||||
for ( int i = 0; i < MAX_SPLITSCREEN_PLAYERS; i++ )
|
||||
{
|
||||
m_bEnabledOnClient[i] = false;
|
||||
m_flCurWeightOnClient[i] = 0.0f;
|
||||
m_bFadingIn[i] = false;
|
||||
m_flFadeStartWeight[i] = 0.0f;
|
||||
m_flFadeStartTime[i] = 0.0f;
|
||||
m_flFadeDuration[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
C_ColorCorrection::~C_ColorCorrection()
|
||||
{
|
||||
g_pColorCorrectionMgr->RemoveColorCorrectionEntity( this, m_CCHandle );
|
||||
}
|
||||
|
||||
bool C_ColorCorrection::IsClientSide() const
|
||||
{
|
||||
return m_bClientSide || mat_colcorrection_forceentitiesclientside.GetBool();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_ColorCorrection::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
if ( m_CCHandle == INVALID_CLIENT_CCHANDLE )
|
||||
{
|
||||
// forming a unique name without extension
|
||||
char cleanName[MAX_PATH];
|
||||
V_StripExtension( m_netLookupFilename, cleanName, sizeof( cleanName ) );
|
||||
char name[MAX_PATH];
|
||||
Q_snprintf( name, MAX_PATH, "%s_%d", cleanName, entindex() );
|
||||
|
||||
m_CCHandle = g_pColorCorrectionMgr->AddColorCorrectionEntity( this, name, m_netLookupFilename );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// We don't draw...
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_ColorCorrection::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void C_ColorCorrection::Update( C_BasePlayer *pPlayer, float ccScale )
|
||||
{
|
||||
Assert( m_CCHandle != INVALID_CLIENT_CCHANDLE );
|
||||
|
||||
if ( mat_colcorrection_disableentities.GetInt() )
|
||||
{
|
||||
// Allow the colorcorrectionui panel (or user) to turn off color-correction entities
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive );
|
||||
return;
|
||||
}
|
||||
|
||||
int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
|
||||
bool bEnabled = IsClientSide() ? m_bEnabledOnClient[nSlot] : m_bEnabled;
|
||||
|
||||
// fade weight on client
|
||||
if ( IsClientSide() )
|
||||
{
|
||||
m_flCurWeightOnClient[nSlot] = Lerp( GetFadeRatio( nSlot ), m_flFadeStartWeight[nSlot], m_bFadingIn[nSlot] ? m_flMaxWeight : 0.0f );
|
||||
}
|
||||
|
||||
float flCurWeight = IsClientSide() ? m_flCurWeightOnClient[nSlot] : m_flCurWeight;
|
||||
|
||||
if( !bEnabled && flCurWeight == 0.0f )
|
||||
{
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive );
|
||||
return;
|
||||
}
|
||||
|
||||
Vector playerOrigin = pPlayer->GetAbsOrigin();
|
||||
|
||||
float weight = 0;
|
||||
if ( ( m_minFalloff != -1 ) && ( m_maxFalloff != -1 ) && m_minFalloff != m_maxFalloff )
|
||||
{
|
||||
float dist = (playerOrigin - m_vecOrigin).Length();
|
||||
weight = (dist-m_minFalloff) / (m_maxFalloff-m_minFalloff);
|
||||
if ( weight<0.0f ) weight = 0.0f;
|
||||
if ( weight>1.0f ) weight = 1.0f;
|
||||
}
|
||||
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, flCurWeight * ( 1.0 - weight ) * ccScale, m_bExclusive );
|
||||
}
|
||||
|
||||
void C_ColorCorrection::EnableOnClient( bool bEnable, bool bSkipFade )
|
||||
{
|
||||
if ( !IsClientSide() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
|
||||
|
||||
if( m_bEnabledOnClient[nSlot] == bEnable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_bFadingIn[nSlot] = bEnable;
|
||||
m_bEnabledOnClient[nSlot] = bEnable;
|
||||
|
||||
// initialize countdown timer
|
||||
m_flFadeStartWeight[nSlot] = m_flCurWeightOnClient[nSlot];
|
||||
float flFadeTimeScale = 1.0f;
|
||||
if ( m_flMaxWeight != 0.0f )
|
||||
{
|
||||
flFadeTimeScale = m_flCurWeightOnClient[nSlot] / m_flMaxWeight;
|
||||
}
|
||||
|
||||
if ( m_bFadingIn[nSlot] )
|
||||
{
|
||||
flFadeTimeScale = 1.0f - flFadeTimeScale;
|
||||
}
|
||||
|
||||
if ( bSkipFade )
|
||||
{
|
||||
flFadeTimeScale = 0.0f;
|
||||
}
|
||||
|
||||
StartFade( nSlot, flFadeTimeScale * ( m_bFadingIn[nSlot] ? m_flFadeInDuration : m_flFadeOutDuration ) );
|
||||
|
||||
// update the clientside weight once here, in case the fade duration is 0
|
||||
m_flCurWeightOnClient[nSlot] = Lerp( GetFadeRatio( nSlot ), m_flFadeStartWeight[nSlot], m_bFadingIn[nSlot] ? m_flMaxWeight : 0.0f );
|
||||
}
|
||||
|
||||
Vector C_ColorCorrection::GetOrigin()
|
||||
{
|
||||
return m_vecOrigin;
|
||||
}
|
||||
|
||||
float C_ColorCorrection::GetMinFalloff()
|
||||
{
|
||||
return m_minFalloff;
|
||||
}
|
||||
|
||||
float C_ColorCorrection::GetMaxFalloff()
|
||||
{
|
||||
return m_maxFalloff;
|
||||
}
|
||||
|
||||
void C_ColorCorrection::SetWeight( float fWeight )
|
||||
{
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, fWeight, false );
|
||||
}
|
||||
|
||||
void C_ColorCorrection::StartFade( int nSplitScreenSlot, float flDuration )
|
||||
{
|
||||
m_flFadeStartTime[nSplitScreenSlot] = gpGlobals->curtime;
|
||||
m_flFadeDuration[nSplitScreenSlot] = MAX( flDuration, 0.0f );
|
||||
}
|
||||
|
||||
float C_ColorCorrection::GetFadeRatio( int nSplitScreenSlot ) const
|
||||
{
|
||||
float flRatio = 1.0f;
|
||||
|
||||
if ( m_flFadeDuration[nSplitScreenSlot] != 0.0f )
|
||||
{
|
||||
flRatio = ( gpGlobals->curtime - m_flFadeStartTime[nSplitScreenSlot] ) / m_flFadeDuration[nSplitScreenSlot];
|
||||
flRatio = clamp( flRatio, 0.0f, 1.0f );
|
||||
}
|
||||
return flRatio;
|
||||
}
|
||||
|
||||
bool C_ColorCorrection::IsFadeTimeElapsed( int nSplitScreenSlot ) const
|
||||
{
|
||||
return ( ( gpGlobals->curtime - m_flFadeStartTime[nSplitScreenSlot] ) > m_flFadeDuration[nSplitScreenSlot] ) ||
|
||||
( ( gpGlobals->curtime - m_flFadeStartTime[nSplitScreenSlot] ) < 0.0f );
|
||||
}
|
||||
|
||||
void UpdateColorCorrectionEntities( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrection **pList, int listCount )
|
||||
{
|
||||
for ( int i = 0; i < listCount; i++ )
|
||||
{
|
||||
pList[i]->Update(pPlayer, ccScale);
|
||||
}
|
||||
}
|
76
game/client/c_colorcorrection.h
Normal file
76
game/client/c_colorcorrection.h
Normal file
@ -0,0 +1,76 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Color correction entity with simple radial falloff
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_COLORCORRECTION_H
|
||||
#define C_COLORCORRECTION_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "colorcorrectionmgr.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Color correction entity with radial falloff
|
||||
//------------------------------------------------------------------------------
|
||||
class C_ColorCorrection : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_ColorCorrection, C_BaseEntity );
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ColorCorrection();
|
||||
virtual ~C_ColorCorrection();
|
||||
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
|
||||
virtual void Update(C_BasePlayer *pPlayer, float ccScale);
|
||||
|
||||
bool IsMaster() const { return m_bMaster; }
|
||||
bool IsClientSide() const;
|
||||
bool IsExclusive() const { return m_bExclusive; }
|
||||
|
||||
void EnableOnClient( bool bEnable, bool bSkipFade = false );
|
||||
|
||||
Vector GetOrigin();
|
||||
float GetMinFalloff();
|
||||
float GetMaxFalloff();
|
||||
|
||||
void SetWeight( float fWeight );
|
||||
|
||||
protected:
|
||||
void StartFade( int nSplitScreenSlot, float flDuration );
|
||||
float GetFadeRatio( int nSplitScreenSlot ) const;
|
||||
bool IsFadeTimeElapsed( int nSplitScreenSlot ) const;
|
||||
|
||||
Vector m_vecOrigin;
|
||||
|
||||
float m_minFalloff;
|
||||
float m_maxFalloff;
|
||||
float m_flFadeInDuration;
|
||||
float m_flFadeOutDuration;
|
||||
float m_flMaxWeight;
|
||||
float m_flCurWeight; // networked from server
|
||||
char m_netLookupFilename[MAX_PATH];
|
||||
|
||||
bool m_bEnabled; // networked from server
|
||||
bool m_bMaster;
|
||||
bool m_bClientSide;
|
||||
bool m_bExclusive;
|
||||
|
||||
bool m_bEnabledOnClient[MAX_SPLITSCREEN_PLAYERS];
|
||||
float m_flCurWeightOnClient[MAX_SPLITSCREEN_PLAYERS];
|
||||
bool m_bFadingIn[MAX_SPLITSCREEN_PLAYERS];
|
||||
float m_flFadeStartWeight[MAX_SPLITSCREEN_PLAYERS];
|
||||
float m_flFadeStartTime[MAX_SPLITSCREEN_PLAYERS];
|
||||
float m_flFadeDuration[MAX_SPLITSCREEN_PLAYERS];
|
||||
|
||||
ClientCCHandle_t m_CCHandle;
|
||||
};
|
||||
|
||||
#endif
|
204
game/client/c_colorcorrectionvolume.cpp
Normal file
204
game/client/c_colorcorrectionvolume.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Color correction entity.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "cdll_client_int.h"
|
||||
#include "materialsystem/materialsystemutil.h"
|
||||
#include "colorcorrectionmgr.h"
|
||||
#include "c_triggers.h"
|
||||
|
||||
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FIXME: This really should inherit from something more lightweight
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Shadow control entity
|
||||
//------------------------------------------------------------------------------
|
||||
class C_ColorCorrectionVolume : public C_BaseTrigger
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_ColorCorrectionVolume, C_BaseTrigger );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
C_ColorCorrectionVolume();
|
||||
virtual ~C_ColorCorrectionVolume();
|
||||
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
|
||||
void Update( C_BasePlayer *pPlayer, float ccScale );
|
||||
|
||||
void StartTouch( C_BaseEntity *pOther );
|
||||
void EndTouch( C_BaseEntity *pOther );
|
||||
|
||||
private:
|
||||
float m_LastEnterWeight;
|
||||
float m_LastEnterTime;
|
||||
|
||||
float m_LastExitWeight;
|
||||
float m_LastExitTime;
|
||||
bool m_bEnabled;
|
||||
float m_MaxWeight;
|
||||
float m_FadeDuration;
|
||||
float m_Weight;
|
||||
char m_lookupFilename[MAX_PATH];
|
||||
|
||||
ClientCCHandle_t m_CCHandle;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrectionVolume, DT_ColorCorrectionVolume, CColorCorrectionVolume)
|
||||
RecvPropBool( RECVINFO(m_bEnabled) ),
|
||||
RecvPropFloat( RECVINFO(m_MaxWeight) ),
|
||||
RecvPropFloat( RECVINFO(m_FadeDuration) ),
|
||||
RecvPropFloat( RECVINFO(m_Weight) ),
|
||||
RecvPropString( RECVINFO(m_lookupFilename) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( C_ColorCorrectionVolume )
|
||||
DEFINE_PRED_FIELD( m_Weight, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//------------------------------------------------------------------------------
|
||||
C_ColorCorrectionVolume::C_ColorCorrectionVolume()
|
||||
{
|
||||
m_CCHandle = INVALID_CLIENT_CCHANDLE;
|
||||
}
|
||||
|
||||
C_ColorCorrectionVolume::~C_ColorCorrectionVolume()
|
||||
{
|
||||
g_pColorCorrectionMgr->RemoveColorCorrectionVolume( this, m_CCHandle );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_ColorCorrectionVolume::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
if ( m_CCHandle == INVALID_CLIENT_CCHANDLE )
|
||||
{
|
||||
// forming a unique name without extension
|
||||
char cleanName[MAX_PATH];
|
||||
V_StripExtension( m_lookupFilename, cleanName, sizeof( cleanName ) );
|
||||
char name[MAX_PATH];
|
||||
Q_snprintf( name, MAX_PATH, "%s_%d", cleanName, entindex() );
|
||||
|
||||
m_CCHandle = g_pColorCorrectionMgr->AddColorCorrectionVolume( this, name, m_lookupFilename );
|
||||
|
||||
SetSolid( SOLID_BSP );
|
||||
SetSolidFlags( FSOLID_TRIGGER | FSOLID_NOT_SOLID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// We don't draw...
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_ColorCorrectionVolume::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void C_ColorCorrectionVolume::StartTouch( CBaseEntity *pEntity )
|
||||
{
|
||||
m_LastEnterTime = gpGlobals->curtime;
|
||||
m_LastEnterWeight = m_Weight;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void C_ColorCorrectionVolume::EndTouch( CBaseEntity *pEntity )
|
||||
{
|
||||
m_LastExitTime = gpGlobals->curtime;
|
||||
m_LastExitWeight = m_Weight;
|
||||
}
|
||||
|
||||
|
||||
void C_ColorCorrectionVolume::Update( C_BasePlayer *pPlayer, float ccScale )
|
||||
{
|
||||
if ( pPlayer )
|
||||
{
|
||||
bool isTouching = CollisionProp()->IsPointInBounds( pPlayer->EyePosition() );
|
||||
bool wasTouching = m_LastEnterTime > m_LastExitTime;
|
||||
|
||||
if ( isTouching && !wasTouching )
|
||||
{
|
||||
StartTouch( pPlayer );
|
||||
}
|
||||
else if ( !isTouching && wasTouching )
|
||||
{
|
||||
EndTouch( pPlayer );
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_bEnabled )
|
||||
{
|
||||
m_Weight = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_LastEnterTime > m_LastExitTime )
|
||||
{
|
||||
// we most recently entered the volume
|
||||
|
||||
if( m_Weight < 1.0f )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_LastEnterTime;
|
||||
float weight = m_LastEnterWeight + dt / ((1.0f-m_LastEnterWeight)*m_FadeDuration);
|
||||
if( weight>1.0f )
|
||||
weight = 1.0f;
|
||||
|
||||
m_Weight = weight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we most recently exitted the volume
|
||||
|
||||
if( m_Weight > 0.0f )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_LastExitTime;
|
||||
float weight = (1.0f-m_LastExitWeight) + dt / (m_LastExitWeight*m_FadeDuration);
|
||||
if( weight>1.0f )
|
||||
weight = 1.0f;
|
||||
|
||||
m_Weight = 1.0f - weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vector entityPosition = GetAbsOrigin();
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_Weight * ccScale );
|
||||
}
|
||||
|
||||
|
||||
void UpdateColorCorrectionVolumes( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrectionVolume **pList, int listCount )
|
||||
{
|
||||
for ( int i = 0; i < listCount; i++ )
|
||||
{
|
||||
pList[i]->Update(pPlayer, ccScale);
|
||||
}
|
||||
}
|
239
game/client/c_dynamiclight.cpp
Normal file
239
game/client/c_dynamiclight.cpp
Normal file
@ -0,0 +1,239 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Dynamic light
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "dlight.h"
|
||||
#include "iefx.h"
|
||||
#include "IViewRender.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
#if HL2_EPISODIC
|
||||
// In Episodic we unify the NO_WORLD_ILLUMINATION lights to use
|
||||
// the more efficient elight structure instead. This should theoretically
|
||||
// be extended to other projects but may have unintended consequences
|
||||
// and bears more thorough testing.
|
||||
//
|
||||
// For an earlier iteration on this technique see changelist 214433,
|
||||
// which had a specific flag for use of elights.
|
||||
#define DLIGHT_NO_WORLD_USES_ELIGHT 1
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A dynamic light, with the goofy hack needed for spotlights
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_DynamicLight : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_DynamicLight, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_DynamicLight();
|
||||
|
||||
public:
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
void ClientThink( void );
|
||||
void Release( void );
|
||||
|
||||
unsigned char m_Flags;
|
||||
unsigned char m_LightStyle;
|
||||
|
||||
float m_Radius;
|
||||
int m_Exponent;
|
||||
float m_InnerAngle;
|
||||
float m_OuterAngle;
|
||||
float m_SpotRadius;
|
||||
|
||||
private:
|
||||
dlight_t* m_pDynamicLight;
|
||||
dlight_t* m_pSpotlightEnd;
|
||||
|
||||
|
||||
inline bool ShouldBeElight() { return (m_Flags & DLIGHT_NO_WORLD_ILLUMINATION); }
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_DynamicLight, DT_DynamicLight, CDynamicLight)
|
||||
RecvPropInt (RECVINFO(m_Flags)),
|
||||
RecvPropInt (RECVINFO(m_LightStyle)),
|
||||
RecvPropFloat (RECVINFO(m_Radius)),
|
||||
RecvPropInt (RECVINFO(m_Exponent)),
|
||||
RecvPropFloat (RECVINFO(m_InnerAngle)),
|
||||
RecvPropFloat (RECVINFO(m_OuterAngle)),
|
||||
RecvPropFloat (RECVINFO(m_SpotRadius)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
C_DynamicLight::C_DynamicLight(void) : m_pSpotlightEnd(0), m_pDynamicLight(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_DynamicLight::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink(gpGlobals->curtime + 0.05);
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_DynamicLight::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Disable drawing of this light when entity perishes
|
||||
//------------------------------------------------------------------------------
|
||||
void C_DynamicLight::Release()
|
||||
{
|
||||
if (m_pDynamicLight)
|
||||
{
|
||||
m_pDynamicLight->die = gpGlobals->curtime;
|
||||
m_pDynamicLight = 0;
|
||||
}
|
||||
|
||||
if (m_pSpotlightEnd)
|
||||
{
|
||||
m_pSpotlightEnd->die = gpGlobals->curtime;
|
||||
m_pSpotlightEnd = 0;
|
||||
}
|
||||
|
||||
BaseClass::Release();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_DynamicLight::ClientThink(void)
|
||||
{
|
||||
Vector forward;
|
||||
AngleVectors( GetAbsAngles(), &forward );
|
||||
|
||||
if ( (m_Flags & DLIGHT_NO_MODEL_ILLUMINATION) == 0 )
|
||||
{
|
||||
// Deal with the model light
|
||||
if ( !m_pDynamicLight || (m_pDynamicLight->key != index) )
|
||||
{
|
||||
#if DLIGHT_NO_WORLD_USES_ELIGHT
|
||||
m_pDynamicLight = ShouldBeElight() != 0
|
||||
? effects->CL_AllocElight( index )
|
||||
: effects->CL_AllocDlight( index );
|
||||
#else
|
||||
m_pDynamicLight = effects->CL_AllocDlight( index );
|
||||
#endif
|
||||
Assert (m_pDynamicLight);
|
||||
m_pDynamicLight->minlight = 0;
|
||||
}
|
||||
|
||||
m_pDynamicLight->style = m_LightStyle;
|
||||
m_pDynamicLight->radius = m_Radius;
|
||||
m_pDynamicLight->flags = m_Flags;
|
||||
if ( m_OuterAngle > 0 )
|
||||
m_pDynamicLight->flags |= DLIGHT_NO_WORLD_ILLUMINATION;
|
||||
color24 c = GetRenderColor();
|
||||
m_pDynamicLight->color.r = c.r;
|
||||
m_pDynamicLight->color.g = c.g;
|
||||
m_pDynamicLight->color.b = c.b;
|
||||
m_pDynamicLight->color.exponent = m_Exponent; // this makes it match the world
|
||||
m_pDynamicLight->origin = GetAbsOrigin();
|
||||
m_pDynamicLight->m_InnerAngle = m_InnerAngle;
|
||||
m_pDynamicLight->m_OuterAngle = m_OuterAngle;
|
||||
m_pDynamicLight->die = gpGlobals->curtime + 1e6;
|
||||
m_pDynamicLight->m_Direction = forward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In this case, the m_Flags could have changed; which is how we turn the light off
|
||||
if (m_pDynamicLight)
|
||||
{
|
||||
m_pDynamicLight->die = gpGlobals->curtime;
|
||||
m_pDynamicLight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if DLIGHT_NO_WORLD_USES_ELIGHT
|
||||
if (( m_OuterAngle > 0 ) && !ShouldBeElight())
|
||||
#else
|
||||
if (( m_OuterAngle > 0 ) && ((m_Flags & DLIGHT_NO_WORLD_ILLUMINATION) == 0))
|
||||
#endif
|
||||
{
|
||||
// Raycast to where the endpoint goes
|
||||
// Deal with the environment light
|
||||
if ( !m_pSpotlightEnd || (m_pSpotlightEnd->key != -index) )
|
||||
{
|
||||
m_pSpotlightEnd = effects->CL_AllocDlight( -index );
|
||||
Assert (m_pSpotlightEnd);
|
||||
}
|
||||
|
||||
// Trace a line outward, don't use hitboxes (too slow)
|
||||
Vector end;
|
||||
VectorMA( GetAbsOrigin(), m_Radius, forward, end );
|
||||
|
||||
trace_t pm;
|
||||
C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace
|
||||
UTIL_TraceLine( GetAbsOrigin(), end, MASK_NPCWORLDSTATIC, NULL, COLLISION_GROUP_NONE, &pm );
|
||||
C_BaseEntity::PopEnableAbsRecomputations();
|
||||
VectorCopy( pm.endpos, m_pSpotlightEnd->origin );
|
||||
|
||||
if (pm.fraction == 1.0f)
|
||||
{
|
||||
m_pSpotlightEnd->die = gpGlobals->curtime;
|
||||
m_pSpotlightEnd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float falloff = 1.0 - pm.fraction;
|
||||
falloff *= falloff;
|
||||
|
||||
m_pSpotlightEnd->style = m_LightStyle;
|
||||
m_pSpotlightEnd->flags = DLIGHT_NO_MODEL_ILLUMINATION | (m_Flags & DLIGHT_DISPLACEMENT_MASK);
|
||||
m_pSpotlightEnd->radius = m_SpotRadius; // * falloff;
|
||||
m_pSpotlightEnd->die = gpGlobals->curtime + 1e6;
|
||||
color24 c = GetRenderColor();
|
||||
m_pSpotlightEnd->color.r = c.r * falloff;
|
||||
m_pSpotlightEnd->color.g = c.g * falloff;
|
||||
m_pSpotlightEnd->color.b = c.b * falloff;
|
||||
m_pSpotlightEnd->color.exponent = m_Exponent;
|
||||
|
||||
// For bumped lighting
|
||||
m_pSpotlightEnd->m_Direction = forward;
|
||||
|
||||
// Update list of surfaces we influence
|
||||
render->TouchLight( m_pSpotlightEnd );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In this case, the m_Flags could have changed; which is how we turn the light off
|
||||
if (m_pSpotlightEnd)
|
||||
{
|
||||
m_pSpotlightEnd->die = gpGlobals->curtime;
|
||||
m_pSpotlightEnd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SetNextClientThink(gpGlobals->curtime + 0.001);
|
||||
}
|
||||
|
2657
game/client/c_effects.cpp
Normal file
2657
game/client/c_effects.cpp
Normal file
File diff suppressed because it is too large
Load Diff
210
game/client/c_effects.h
Normal file
210
game/client/c_effects.h
Normal file
@ -0,0 +1,210 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_EFFECTS_H
|
||||
#define C_EFFECTS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "cbase.h"
|
||||
#include "precipitation_shared.h"
|
||||
|
||||
// Draw rain effects.
|
||||
void DrawPrecipitation();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Precipitation particle type
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CPrecipitationParticle
|
||||
{
|
||||
public:
|
||||
Vector m_Pos;
|
||||
Vector m_Velocity;
|
||||
float m_SpawnTime; // Note: Tweak with this to change lifetime
|
||||
float m_Mass;
|
||||
float m_Ramp;
|
||||
|
||||
float m_flMaxLifetime;
|
||||
int m_nSplitScreenPlayerSlot;
|
||||
};
|
||||
|
||||
class CClient_Precipitation;
|
||||
static CUtlVector<CClient_Precipitation*> g_Precipitations;
|
||||
|
||||
//===========
|
||||
// Snow fall
|
||||
//===========
|
||||
class CSnowFallManager;
|
||||
static CSnowFallManager *s_pSnowFallMgr[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
bool SnowFallManagerCreate( CClient_Precipitation *pSnowEntity );
|
||||
void SnowFallManagerDestroy( void );
|
||||
|
||||
class AshDebrisEffect : public CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
AshDebrisEffect( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
|
||||
|
||||
static AshDebrisEffect* Create( const char *pDebugName );
|
||||
|
||||
virtual float UpdateAlpha( const SimpleParticle *pParticle );
|
||||
virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta );
|
||||
|
||||
private:
|
||||
AshDebrisEffect( const AshDebrisEffect & );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Precipitation blocker entity
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_PrecipitationBlocker : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_PrecipitationBlocker, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_PrecipitationBlocker();
|
||||
virtual ~C_PrecipitationBlocker();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Precipitation base entity
|
||||
//-----------------------------------------------------------------------------
|
||||
class CClient_Precipitation : public C_BaseEntity
|
||||
{
|
||||
class CPrecipitationEffect;
|
||||
friend class CClient_Precipitation::CPrecipitationEffect;
|
||||
|
||||
public:
|
||||
DECLARE_CLASS( CClient_Precipitation, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
CClient_Precipitation();
|
||||
virtual ~CClient_Precipitation();
|
||||
|
||||
// Inherited from C_BaseEntity
|
||||
virtual void Precache( );
|
||||
virtual RenderableTranslucencyType_t ComputeTranslucencyType() { return RENDERABLE_IS_TRANSLUCENT; }
|
||||
|
||||
void Render();
|
||||
|
||||
// Computes where we're gonna emit
|
||||
bool ComputeEmissionArea( Vector& origin, Vector2D& size, C_BaseCombatCharacter *pCharacter );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Creates a single particle
|
||||
CPrecipitationParticle* CreateParticle();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink();
|
||||
|
||||
void Simulate( float dt );
|
||||
|
||||
// Renders the particle
|
||||
void RenderParticle( CPrecipitationParticle* pParticle, CMeshBuilder &mb );
|
||||
|
||||
void CreateWaterSplashes();
|
||||
|
||||
// Emits the actual particles
|
||||
void EmitParticles( float fTimeDelta );
|
||||
|
||||
// Gets the tracer width and speed
|
||||
float GetWidth() const;
|
||||
float GetLength() const;
|
||||
float GetSpeed() const;
|
||||
|
||||
// Gets the remaining lifetime of the particle
|
||||
float GetRemainingLifetime( CPrecipitationParticle* pParticle ) const;
|
||||
|
||||
// Computes the wind vector
|
||||
static void ComputeWindVector( );
|
||||
|
||||
// simulation methods
|
||||
bool SimulateRain( CPrecipitationParticle* pParticle, float dt );
|
||||
bool SimulateSnow( CPrecipitationParticle* pParticle, float dt );
|
||||
|
||||
void CreateParticlePrecip( void );
|
||||
void InitializeParticlePrecip( void );
|
||||
void DispatchOuterParticlePrecip( int nSlot, C_BasePlayer *pPlayer, Vector vForward );
|
||||
void DispatchInnerParticlePrecip( int nSlot, C_BasePlayer *pPlayer, Vector vForward );
|
||||
void DestroyOuterParticlePrecip( int nSlot );
|
||||
void DestroyInnerParticlePrecip( int nSlot );
|
||||
|
||||
void UpdateParticlePrecip( C_BasePlayer *pPlayer, int nSlot );
|
||||
float GetDensity() { return m_flDensity; }
|
||||
|
||||
private:
|
||||
void CreateAshParticle( void );
|
||||
void CreateRainOrSnowParticle( const Vector &vSpawnPosition, const Vector &vEndPosition, const Vector &vVelocity ); // TERROR: adding end pos for lifetime calcs
|
||||
|
||||
// Information helpful in creating and rendering particles
|
||||
IMaterial *m_MatHandle; // material used
|
||||
|
||||
float m_Color[4]; // precip color
|
||||
float m_Lifetime; // Precip lifetime
|
||||
float m_InitialRamp; // Initial ramp value
|
||||
float m_Speed; // Precip speed
|
||||
float m_Width; // Tracer width
|
||||
float m_Remainder; // particles we should render next time
|
||||
PrecipitationType_t m_nPrecipType; // Precip type
|
||||
float m_flHalfScreenWidth; // Precalculated each frame.
|
||||
|
||||
float m_flDensity;
|
||||
|
||||
#ifdef INFESTED_DLL
|
||||
int m_nSnowDustAmount;
|
||||
#endif
|
||||
|
||||
// Some state used in rendering and simulation
|
||||
// Used to modify the rain density and wind from the console
|
||||
static ConVar s_raindensity;
|
||||
static ConVar s_rainwidth;
|
||||
static ConVar s_rainlength;
|
||||
static ConVar s_rainspeed;
|
||||
|
||||
static Vector s_WindVector; // Stores the wind speed vector
|
||||
|
||||
CUtlLinkedList<CPrecipitationParticle> m_Particles;
|
||||
CUtlVector<Vector> m_Splashes;
|
||||
|
||||
struct AshSplit_t
|
||||
{
|
||||
AshSplit_t() : m_bActiveAshEmitter( false ), m_vAshSpawnOrigin( 0, 0, 0 ), m_iAshCount( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
CSmartPtr<AshDebrisEffect> m_pAshEmitter;
|
||||
TimedEvent m_tAshParticleTimer;
|
||||
TimedEvent m_tAshParticleTraceTimer;
|
||||
bool m_bActiveAshEmitter;
|
||||
Vector m_vAshSpawnOrigin;
|
||||
|
||||
int m_iAshCount;
|
||||
};
|
||||
|
||||
protected:
|
||||
AshSplit_t m_Ash[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
|
||||
float m_flParticleInnerDist; //The distance at which to start drawing the inner system
|
||||
char *m_pParticleInnerNearDef; //Name of the first inner system
|
||||
char *m_pParticleInnerFarDef; //Name of the second inner system
|
||||
char *m_pParticleOuterDef; //Name of the outer system
|
||||
HPARTICLEFFECT m_pParticlePrecipInnerNear[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
HPARTICLEFFECT m_pParticlePrecipInnerFar[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
HPARTICLEFFECT m_pParticlePrecipOuter[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
TimedEvent m_tParticlePrecipTraceTimer[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
bool m_bActiveParticlePrecipEmitter[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
bool m_bParticlePrecipInitialized;
|
||||
|
||||
private:
|
||||
CClient_Precipitation( const CClient_Precipitation & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
#endif // C_EFFECTS_H
|
776
game/client/c_entitydissolve.cpp
Normal file
776
game/client/c_entitydissolve.cpp
Normal file
@ -0,0 +1,776 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "IViewRender.h"
|
||||
#include "view.h"
|
||||
#include "studio.h"
|
||||
#include "bone_setup.h"
|
||||
#include "model_types.h"
|
||||
#include "beamdraw.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "iviewrender_beams.h"
|
||||
#include "fx.h"
|
||||
#include "IEffects.h"
|
||||
#include "c_entitydissolve.h"
|
||||
#include "movevars_shared.h"
|
||||
#include "precache_register.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
PRECACHE_REGISTER_BEGIN( GLOBAL, PrecacheEffectBuild )
|
||||
PRECACHE( MATERIAL,"effects/tesla_glow_noz" )
|
||||
PRECACHE( MATERIAL,"effects/spark" )
|
||||
PRECACHE( MATERIAL,"effects/combinemuzzle2" )
|
||||
PRECACHE_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityDissolve, DT_EntityDissolve, CEntityDissolve )
|
||||
RecvPropTime(RECVINFO(m_flStartTime)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeOutStart)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeOutLength)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeOutModelStart)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeOutModelLength)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeInStart)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeInLength)),
|
||||
RecvPropInt(RECVINFO(m_nDissolveType)),
|
||||
RecvPropVector( RECVINFO( m_vDissolverOrigin) ),
|
||||
RecvPropInt( RECVINFO( m_nMagnitude ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
extern PMaterialHandle g_Material_Spark;
|
||||
PMaterialHandle g_Material_AR2Glow = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EntityDissolve::C_EntityDissolve( void )
|
||||
{
|
||||
m_bLinkedToServerEnt = true;
|
||||
m_pController = false;
|
||||
m_bCoreExplode = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::GetRenderBounds( Vector& theMins, Vector& theMaxs )
|
||||
{
|
||||
if ( GetMoveParent() )
|
||||
{
|
||||
GetMoveParent()->GetRenderBounds( theMins, theMaxs );
|
||||
}
|
||||
else
|
||||
{
|
||||
theMins = GetAbsOrigin();
|
||||
theMaxs = theMaxs;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On data changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_flNextSparkTime = m_flStartTime;
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cleanup
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::UpdateOnRemove( void )
|
||||
{
|
||||
if ( m_pController )
|
||||
{
|
||||
physenv->DestroyMotionController( m_pController );
|
||||
m_pController = NULL;
|
||||
}
|
||||
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Apply the forces to the entity
|
||||
//------------------------------------------------------------------------------
|
||||
IMotionEvent::simresult_e C_EntityDissolve::Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular )
|
||||
{
|
||||
linear.Init();
|
||||
angular.Init();
|
||||
|
||||
// Make it zero g
|
||||
linear.z -= -1.02 * sv_gravity.GetFloat();
|
||||
|
||||
Vector vel;
|
||||
AngularImpulse angVel;
|
||||
pObject->GetVelocity( &vel, &angVel );
|
||||
vel += linear * deltaTime; // account for gravity scale
|
||||
|
||||
Vector unitVel = vel;
|
||||
Vector unitAngVel = angVel;
|
||||
|
||||
float speed = VectorNormalize( unitVel );
|
||||
// float angSpeed = VectorNormalize( unitAngVel );
|
||||
|
||||
// float speedScale = 0.0;
|
||||
// float angSpeedScale = 0.0;
|
||||
|
||||
float flLinearLimit = 50;
|
||||
float flLinearLimitDelta = 40;
|
||||
if ( speed > flLinearLimit )
|
||||
{
|
||||
float flDeltaVel = (flLinearLimit - speed) / deltaTime;
|
||||
if ( flLinearLimitDelta != 0.0f )
|
||||
{
|
||||
float flMaxDeltaVel = -flLinearLimitDelta / deltaTime;
|
||||
if ( flDeltaVel < flMaxDeltaVel )
|
||||
{
|
||||
flDeltaVel = flMaxDeltaVel;
|
||||
}
|
||||
}
|
||||
VectorMA( linear, flDeltaVel, unitVel, linear );
|
||||
}
|
||||
|
||||
return SIM_GLOBAL_ACCELERATION;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tesla effect
|
||||
//-----------------------------------------------------------------------------
|
||||
static void FX_BuildTesla( C_BaseEntity *pEntity, Vector &vecOrigin, Vector &vecEnd )
|
||||
{
|
||||
BeamInfo_t beamInfo;
|
||||
beamInfo.m_pStartEnt = pEntity;
|
||||
beamInfo.m_nStartAttachment = 0;
|
||||
beamInfo.m_pEndEnt = NULL;
|
||||
beamInfo.m_nEndAttachment = 0;
|
||||
beamInfo.m_nType = TE_BEAMTESLA;
|
||||
beamInfo.m_vecStart = vecOrigin;
|
||||
beamInfo.m_vecEnd = vecEnd;
|
||||
beamInfo.m_pszModelName = "sprites/lgtning.vmt";
|
||||
beamInfo.m_flHaloScale = 0.0;
|
||||
beamInfo.m_flLife = random->RandomFloat( 0.25f, 1.0f );
|
||||
beamInfo.m_flWidth = random->RandomFloat( 8.0f, 14.0f );
|
||||
beamInfo.m_flEndWidth = 1.0f;
|
||||
beamInfo.m_flFadeLength = 0.5f;
|
||||
beamInfo.m_flAmplitude = 24;
|
||||
beamInfo.m_flBrightness = 255.0;
|
||||
beamInfo.m_flSpeed = 150.0f;
|
||||
beamInfo.m_nStartFrame = 0.0;
|
||||
beamInfo.m_flFrameRate = 30.0;
|
||||
beamInfo.m_flRed = 255.0;
|
||||
beamInfo.m_flGreen = 255.0;
|
||||
beamInfo.m_flBlue = 255.0;
|
||||
beamInfo.m_nSegments = 18;
|
||||
beamInfo.m_bRenderable = true;
|
||||
beamInfo.m_nFlags = 0; //FBEAM_ONLYNOISEONCE;
|
||||
|
||||
beams->CreateBeamEntPoint( beamInfo );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Tesla effect
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset )
|
||||
{
|
||||
Vector vecOrigin;
|
||||
QAngle vecAngles;
|
||||
MatrixGetColumn( hitboxToWorld, 3, vecOrigin );
|
||||
MatrixAngles( hitboxToWorld, vecAngles.Base() );
|
||||
C_BaseEntity *pEntity = GetMoveParent();
|
||||
|
||||
// Make a couple of tries at it
|
||||
int iTries = -1;
|
||||
Vector vecForward;
|
||||
trace_t tr;
|
||||
do
|
||||
{
|
||||
iTries++;
|
||||
|
||||
// Some beams are deliberatly aimed around the point, the rest are random.
|
||||
if ( !bRandom )
|
||||
{
|
||||
QAngle vecTemp = vecAngles;
|
||||
vecTemp[YAW] += flYawOffset;
|
||||
AngleVectors( vecTemp, &vecForward );
|
||||
|
||||
// Randomly angle it up or down
|
||||
vecForward.z = RandomFloat( -1, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
vecForward = RandomVector( -1, 1 );
|
||||
}
|
||||
|
||||
UTIL_TraceLine( vecOrigin, vecOrigin + (vecForward * 192), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr );
|
||||
} while ( tr.fraction >= 1.0 && iTries < 3 );
|
||||
|
||||
Vector vecEnd = tr.endpos - (vecForward * 8);
|
||||
|
||||
// Only spark & glow if we hit something
|
||||
if ( tr.fraction < 1.0 )
|
||||
{
|
||||
if ( !EffectOccluded( tr.endpos ) )
|
||||
{
|
||||
int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
|
||||
|
||||
// Move it towards the camera
|
||||
Vector vecFlash = tr.endpos;
|
||||
Vector vecForward;
|
||||
AngleVectors( MainViewAngles(nSlot), &vecForward );
|
||||
vecFlash -= (vecForward * 8);
|
||||
|
||||
g_pEffects->EnergySplash( vecFlash, -vecForward, false );
|
||||
|
||||
// End glow
|
||||
CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
|
||||
pSimple->SetSortOrigin( vecFlash );
|
||||
SimpleParticle *pParticle;
|
||||
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash );
|
||||
if ( pParticle != NULL )
|
||||
{
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = RandomFloat( 0.5, 1 );
|
||||
pParticle->m_vecVelocity = vec3_origin;
|
||||
Vector color( 1,1,1 );
|
||||
float colorRamp = RandomFloat( 0.75f, 1.25f );
|
||||
pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
|
||||
pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
|
||||
pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
|
||||
pParticle->m_uchStartSize = RandomFloat( 6,13 );
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize - 2;
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 10;
|
||||
pParticle->m_flRoll = RandomFloat( 0,360 );
|
||||
pParticle->m_flRollDelta = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build the tesla
|
||||
FX_BuildTesla( pEntity, vecOrigin, tr.endpos );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sorts the components of a vector
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline void SortAbsVectorComponents( const Vector& src, int* pVecIdx )
|
||||
{
|
||||
Vector absVec( fabs(src[0]), fabs(src[1]), fabs(src[2]) );
|
||||
|
||||
int maxIdx = (absVec[0] > absVec[1]) ? 0 : 1;
|
||||
if (absVec[2] > absVec[maxIdx])
|
||||
{
|
||||
maxIdx = 2;
|
||||
}
|
||||
|
||||
// always choose something right-handed....
|
||||
switch( maxIdx )
|
||||
{
|
||||
case 0:
|
||||
pVecIdx[0] = 1;
|
||||
pVecIdx[1] = 2;
|
||||
pVecIdx[2] = 0;
|
||||
break;
|
||||
case 1:
|
||||
pVecIdx[0] = 2;
|
||||
pVecIdx[1] = 0;
|
||||
pVecIdx[2] = 1;
|
||||
break;
|
||||
case 2:
|
||||
pVecIdx[0] = 0;
|
||||
pVecIdx[1] = 1;
|
||||
pVecIdx[2] = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute the bounding box's center, size, and basis
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
|
||||
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec )
|
||||
{
|
||||
// Compute the center of the hitbox in worldspace
|
||||
Vector vecHitboxCenter;
|
||||
VectorAdd( pHitBox->bbmin, pHitBox->bbmax, vecHitboxCenter );
|
||||
vecHitboxCenter *= 0.5f;
|
||||
VectorTransform( vecHitboxCenter, hitboxToWorld, *pVecAbsOrigin );
|
||||
|
||||
// Get the object's basis
|
||||
Vector vec[3];
|
||||
MatrixGetColumn( hitboxToWorld, 0, vec[0] );
|
||||
MatrixGetColumn( hitboxToWorld, 1, vec[1] );
|
||||
MatrixGetColumn( hitboxToWorld, 2, vec[2] );
|
||||
// vec[1] *= -1.0f;
|
||||
|
||||
Vector vecViewDir;
|
||||
VectorSubtract( CurrentViewOrigin(), *pVecAbsOrigin, vecViewDir );
|
||||
VectorNormalize( vecViewDir );
|
||||
|
||||
// Project the shadow casting direction into the space of the hitbox
|
||||
Vector localViewDir;
|
||||
localViewDir[0] = DotProduct( vec[0], vecViewDir );
|
||||
localViewDir[1] = DotProduct( vec[1], vecViewDir );
|
||||
localViewDir[2] = DotProduct( vec[2], vecViewDir );
|
||||
|
||||
// Figure out which vector has the largest component perpendicular
|
||||
// to the view direction...
|
||||
// Sort by how perpendicular it is
|
||||
int vecIdx[3];
|
||||
SortAbsVectorComponents( localViewDir, vecIdx );
|
||||
|
||||
// Here's our hitbox basis vectors; namely the ones that are
|
||||
// most perpendicular to the view direction
|
||||
*pXVec = vec[vecIdx[0]];
|
||||
*pYVec = vec[vecIdx[1]];
|
||||
|
||||
// Project them into a plane perpendicular to the view direction
|
||||
*pXVec -= vecViewDir * DotProduct( vecViewDir, *pXVec );
|
||||
*pYVec -= vecViewDir * DotProduct( vecViewDir, *pYVec );
|
||||
VectorNormalize( *pXVec );
|
||||
VectorNormalize( *pYVec );
|
||||
|
||||
// Compute the hitbox size
|
||||
Vector boxSize;
|
||||
VectorSubtract( pHitBox->bbmax, pHitBox->bbmin, boxSize );
|
||||
|
||||
// We project the two longest sides into the vectors perpendicular
|
||||
// to the projection direction, then add in the projection of the perp direction
|
||||
Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] );
|
||||
size.x *= fabs( DotProduct( vec[vecIdx[0]], *pXVec ) );
|
||||
size.y *= fabs( DotProduct( vec[vecIdx[1]], *pYVec ) );
|
||||
|
||||
// Add the third component into x and y
|
||||
size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pXVec ) );
|
||||
size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pYVec ) );
|
||||
|
||||
// Bloat a bit, since the shadow wants to extend outside the model a bit
|
||||
size *= 2.0f;
|
||||
|
||||
// Clamp the minimum size
|
||||
Vector2DMax( size, Vector2D(10.0f, 10.0f), size );
|
||||
|
||||
// Factor the size into the xvec + yvec
|
||||
(*pXVec) *= size.x * 0.5f;
|
||||
(*pYVec) *= size.y * 0.5f;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sparks!
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] )
|
||||
{
|
||||
if ( m_flNextSparkTime > gpGlobals->curtime )
|
||||
return;
|
||||
|
||||
float dt = m_flStartTime + m_flFadeOutStart - gpGlobals->curtime;
|
||||
dt = clamp( dt, 0.0f, m_flFadeOutStart );
|
||||
|
||||
float flNextTime;
|
||||
if (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL)
|
||||
{
|
||||
flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 2.0f * TICK_INTERVAL, 0.4f );
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT);
|
||||
flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 0.3f, 1.0f );
|
||||
}
|
||||
|
||||
m_flNextSparkTime = gpGlobals->curtime + flNextTime;
|
||||
|
||||
// Send out beams around us
|
||||
int iNumBeamsAround = 2;
|
||||
int iNumRandomBeams = 1;
|
||||
int iTotalBeams = iNumBeamsAround + iNumRandomBeams;
|
||||
float flYawOffset = RandomFloat(0,360);
|
||||
for ( int i = 0; i < iTotalBeams; i++ )
|
||||
{
|
||||
int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
|
||||
mstudiobbox_t *pBox = set->pHitbox(nHitbox);
|
||||
|
||||
float flActualYawOffset = 0;
|
||||
bool bRandom = ( i >= iNumBeamsAround );
|
||||
if ( !bRandom )
|
||||
{
|
||||
flActualYawOffset = anglemod( flYawOffset + ((360 / iTotalBeams) * i) );
|
||||
}
|
||||
|
||||
BuildTeslaEffect( pBox, *hitboxbones[pBox->bone], bRandom, flActualYawOffset );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::SetupEmitter( void )
|
||||
{
|
||||
if ( !m_pEmitter )
|
||||
{
|
||||
m_pEmitter = CSimpleEmitter::Create( "C_EntityDissolve" );
|
||||
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_EntityDissolve::GetFadeInPercentage( void )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_flStartTime;
|
||||
|
||||
if ( dt > m_flFadeOutStart )
|
||||
return 1.0f;
|
||||
|
||||
if ( dt < m_flFadeInStart )
|
||||
return 0.0f;
|
||||
|
||||
if ( (dt > m_flFadeInStart) && (dt < m_flFadeInStart + m_flFadeInLength) )
|
||||
{
|
||||
dt -= m_flFadeInStart;
|
||||
|
||||
return ( dt / m_flFadeInLength );
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_EntityDissolve::GetFadeOutPercentage( void )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_flStartTime;
|
||||
|
||||
if ( dt < m_flFadeInStart )
|
||||
return 1.0f;
|
||||
|
||||
if ( dt > m_flFadeOutStart )
|
||||
{
|
||||
dt -= m_flFadeOutStart;
|
||||
|
||||
if ( dt > m_flFadeOutLength )
|
||||
return 0.0f;
|
||||
|
||||
return 1.0f - ( dt / m_flFadeOutLength );
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_EntityDissolve::GetModelFadeOutPercentage( void )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_flStartTime;
|
||||
|
||||
if ( dt < m_flFadeOutModelStart )
|
||||
return 1.0f;
|
||||
|
||||
if ( dt > m_flFadeOutModelStart )
|
||||
{
|
||||
dt -= m_flFadeOutModelStart;
|
||||
|
||||
if ( dt > m_flFadeOutModelLength )
|
||||
return 0.0f;
|
||||
|
||||
return 1.0f - ( dt / m_flFadeOutModelLength );
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::ClientThink( void )
|
||||
{
|
||||
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||
if (!pAnimating)
|
||||
return;
|
||||
|
||||
// NOTE: IsRagdoll means *client-side* ragdoll. We shouldn't be trying to fight
|
||||
// the server ragdoll (or any server physics) on the client
|
||||
if (( !m_pController ) && ( m_nDissolveType == ENTITY_DISSOLVE_NORMAL ) && pAnimating->IsRagdoll())
|
||||
{
|
||||
IPhysicsObject *ppList[VPHYSICS_MAX_OBJECT_LIST_COUNT];
|
||||
int nCount = pAnimating->VPhysicsGetObjectList( ppList, ARRAYSIZE(ppList) );
|
||||
if ( nCount > 0 )
|
||||
{
|
||||
m_pController = physenv->CreateMotionController( this );
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
m_pController->AttachObject( ppList[i], true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
color32 color;
|
||||
|
||||
color.r = color.g = color.b = ( 1.0f - GetFadeInPercentage() ) * 255.0f;
|
||||
color.a = GetModelFadeOutPercentage() * 255.0f;
|
||||
|
||||
// Setup the entity fade
|
||||
pAnimating->SetRenderMode( kRenderTransColor );
|
||||
pAnimating->SetRenderColor( color.r, color.g, color.b );
|
||||
pAnimating->SetRenderAlpha( color.a );
|
||||
|
||||
if ( GetModelFadeOutPercentage() <= 0.2f )
|
||||
{
|
||||
m_bCoreExplode = true;
|
||||
}
|
||||
|
||||
// If we're dead, fade out
|
||||
if ( GetFadeOutPercentage() <= 0.0f )
|
||||
{
|
||||
// Do NOT remove from the client entity list. It'll confuse the local network backdoor, and the entity will never get destroyed
|
||||
// because when the server says to destroy it, the client won't be able to find it.
|
||||
// ClientEntityList().RemoveEntity( GetClientHandle() );
|
||||
|
||||
partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() );
|
||||
|
||||
RemoveFromLeafSystem();
|
||||
|
||||
//FIXME: Ick!
|
||||
//Adrian: I'll assume we don't need the ragdoll either so I'll remove that too.
|
||||
if ( m_bLinkedToServerEnt == false )
|
||||
{
|
||||
Release();
|
||||
|
||||
C_ClientRagdoll *pRagdoll = dynamic_cast <C_ClientRagdoll *> ( pAnimating );
|
||||
|
||||
if ( pRagdoll )
|
||||
{
|
||||
pRagdoll->ReleaseRagdoll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_EntityDissolve::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
// See if we should draw
|
||||
if ( gpGlobals->frametime == 0 || m_bReadyToDraw == false )
|
||||
return 0;
|
||||
|
||||
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||
if ( pAnimating == NULL )
|
||||
return 0;
|
||||
|
||||
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
|
||||
if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) == false )
|
||||
return 0;
|
||||
|
||||
studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
|
||||
if ( pStudioHdr == NULL )
|
||||
return false;
|
||||
|
||||
mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
|
||||
if ( set == NULL )
|
||||
return false;
|
||||
|
||||
// Make sure the emitter is setup properly
|
||||
SetupEmitter();
|
||||
|
||||
// Get fade percentages for the effect
|
||||
float fadeInPerc = GetFadeInPercentage();
|
||||
float fadeOutPerc = GetFadeOutPercentage();
|
||||
|
||||
float fadePerc = ( fadeInPerc >= 1.0f ) ? fadeOutPerc : fadeInPerc;
|
||||
|
||||
Vector vecSkew = vec3_origin;
|
||||
|
||||
// Do extra effects under certain circumstances
|
||||
if ( ( fadePerc < 0.99f ) && ( (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) )
|
||||
{
|
||||
DoSparks( set, hitboxbones );
|
||||
}
|
||||
|
||||
// Skew the particles in front or in back of their targets
|
||||
vecSkew = CurrentViewForward() * ( 8.0f - ( ( 1.0f - fadePerc ) * 32.0f ) );
|
||||
|
||||
float spriteScale = ( ( gpGlobals->curtime - m_flStartTime ) / m_flFadeOutLength );
|
||||
spriteScale = clamp( spriteScale, 0.75f, 1.0f );
|
||||
|
||||
// Cache off this material reference
|
||||
if ( g_Material_Spark == NULL )
|
||||
{
|
||||
g_Material_Spark = ParticleMgr()->GetPMaterial( "effects/spark" );
|
||||
}
|
||||
|
||||
if ( g_Material_AR2Glow == NULL )
|
||||
{
|
||||
g_Material_AR2Glow = ParticleMgr()->GetPMaterial( "effects/combinemuzzle2" );
|
||||
}
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
for ( int i = 0; i < set->numhitboxes; ++i )
|
||||
{
|
||||
Vector vecAbsOrigin, xvec, yvec;
|
||||
mstudiobbox_t *pBox = set->pHitbox(i);
|
||||
ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );
|
||||
|
||||
Vector offset;
|
||||
Vector xDir, yDir;
|
||||
|
||||
xDir = xvec;
|
||||
float xScale = VectorNormalize( xDir ) * 0.75f;
|
||||
|
||||
yDir = yvec;
|
||||
float yScale = VectorNormalize( yDir ) * 0.75f;
|
||||
|
||||
int numParticles = clamp( 3.0f * fadePerc, 0, 3 );
|
||||
|
||||
int iTempParts = 2;
|
||||
|
||||
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||
{
|
||||
if ( m_bCoreExplode == true )
|
||||
{
|
||||
numParticles = 15;
|
||||
iTempParts = 20;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int j = 0; j < iTempParts; j++ )
|
||||
{
|
||||
// Skew the origin
|
||||
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
|
||||
offset += vecSkew;
|
||||
|
||||
if ( random->RandomInt( 0, 2 ) != 0 )
|
||||
continue;
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_Spark, vecAbsOrigin + offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return 1;
|
||||
|
||||
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 16.0f, 64.0f ) );
|
||||
|
||||
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||
{
|
||||
if ( m_bCoreExplode == true )
|
||||
{
|
||||
Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
|
||||
VectorNormalize( vDirection );
|
||||
sParticle->m_vecVelocity = vDirection * m_nMagnitude;
|
||||
}
|
||||
}
|
||||
|
||||
if ( sParticle->m_vecVelocity.z > 0 )
|
||||
{
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 4, 6 ) * spriteScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
sParticle->m_uchStartSize = 2 * spriteScale;
|
||||
}
|
||||
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.4f, 0.5f );
|
||||
|
||||
// If we're the last particles, last longer
|
||||
if ( numParticles == 0 )
|
||||
{
|
||||
sParticle->m_flDieTime *= 2.0f;
|
||||
sParticle->m_uchStartSize = 2 * spriteScale;
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -4.0f, 4.0f );
|
||||
|
||||
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||
{
|
||||
if ( m_bCoreExplode == true )
|
||||
{
|
||||
sParticle->m_flDieTime *= 2.0f;
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f, 8.0f );
|
||||
}
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
|
||||
for ( int j = 0; j < numParticles; j++ )
|
||||
{
|
||||
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
|
||||
offset += vecSkew;
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_AR2Glow, vecAbsOrigin + offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return 1;
|
||||
|
||||
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -64.0f, 128.0f ) );
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 8, 12 ) * spriteScale;
|
||||
sParticle->m_flDieTime = 0.1f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchEndSize = 0;
|
||||
|
||||
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||
{
|
||||
if ( m_bCoreExplode == true )
|
||||
{
|
||||
Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
|
||||
|
||||
VectorNormalize( vDirection );
|
||||
|
||||
sParticle->m_vecVelocity = vDirection * m_nMagnitude;
|
||||
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
77
game/client/c_entitydissolve.h
Normal file
77
game/client/c_entitydissolve.h
Normal file
@ -0,0 +1,77 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_ENTITY_DISSOLVE_H
|
||||
#define C_ENTITY_DISSOLVE_H
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entity Dissolve, client-side implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EntityDissolve : public C_BaseEntity, public IMotionEvent
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_EntityDissolve, C_BaseEntity );
|
||||
|
||||
C_EntityDissolve( void );
|
||||
|
||||
// Inherited from C_BaseEntity
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
virtual bool ShouldDraw() { return true; }
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void UpdateOnRemove( void );
|
||||
|
||||
// Inherited from IMotionEvent
|
||||
virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular );
|
||||
|
||||
void SetupEmitter( void );
|
||||
|
||||
void ClientThink( void );
|
||||
|
||||
void SetServerLinkState( bool state ) { m_bLinkedToServerEnt = state; }
|
||||
|
||||
float m_flStartTime;
|
||||
float m_flFadeOutStart;
|
||||
float m_flFadeOutLength;
|
||||
float m_flFadeOutModelStart;
|
||||
float m_flFadeOutModelLength;
|
||||
float m_flFadeInStart;
|
||||
float m_flFadeInLength;
|
||||
int m_nDissolveType;
|
||||
float m_flNextSparkTime;
|
||||
|
||||
Vector m_vDissolverOrigin;
|
||||
int m_nMagnitude;
|
||||
|
||||
bool m_bCoreExplode;
|
||||
|
||||
protected:
|
||||
|
||||
float GetFadeInPercentage( void ); // Fade in amount (entity fading to black)
|
||||
float GetFadeOutPercentage( void ); // Fade out amount (particles fading away)
|
||||
float GetModelFadeOutPercentage( void );// Mode fade out amount
|
||||
|
||||
// Compute the bounding box's center, size, and basis
|
||||
void ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
|
||||
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec );
|
||||
void BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset );
|
||||
|
||||
void DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] );
|
||||
|
||||
private:
|
||||
|
||||
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||
|
||||
bool m_bLinkedToServerEnt;
|
||||
IPhysicsMotionController *m_pController;
|
||||
};
|
||||
|
||||
#endif // C_ENTITY_DISSOLVE_H
|
||||
|
156
game/client/c_entityflame.cpp
Normal file
156
game/client/c_entityflame.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_entityflame.h"
|
||||
#include "particle_property.h"
|
||||
#include "iefx.h"
|
||||
#include "dlight.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Datadesc
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityFlame, DT_EntityFlame, CEntityFlame )
|
||||
RecvPropEHandle(RECVINFO(m_hEntAttached)),
|
||||
RecvPropBool(RECVINFO(m_bCheapEffect)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EntityFlame::C_EntityFlame( void ) : m_hEffect( NULL )
|
||||
{
|
||||
m_hOldAttached = NULL;
|
||||
AddToEntityList( ENTITY_LIST_SIMULATE );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EntityFlame::~C_EntityFlame( void )
|
||||
{
|
||||
StopEffect();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlame::StopEffect( void )
|
||||
{
|
||||
if ( m_hEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hEffect, true );
|
||||
m_hEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_hEntAttached )
|
||||
{
|
||||
m_hEntAttached->RemoveFlag( FL_ONFIRE );
|
||||
m_hEntAttached->SetEffectEntity( NULL );
|
||||
m_hEntAttached->StopSound( "General.BurningFlesh" );
|
||||
m_hEntAttached->StopSound( "General.BurningObject" );
|
||||
m_hEntAttached = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlame::UpdateOnRemove( void )
|
||||
{
|
||||
StopEffect();
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
void C_EntityFlame::CreateEffect( void )
|
||||
{
|
||||
if ( m_hEffect )
|
||||
{
|
||||
m_hOldAttached = m_hEntAttached;
|
||||
ParticleProp()->StopEmission( m_hEffect, true );
|
||||
m_hEffect = NULL;
|
||||
}
|
||||
|
||||
C_BaseEntity *pEntity = m_hEntAttached;
|
||||
if ( pEntity && !pEntity->IsAbleToHaveFireEffect() )
|
||||
return;
|
||||
|
||||
m_hEffect = ParticleProp()->Create( m_bCheapEffect ? "burning_gib_01" : "burning_character", PATTACH_ABSORIGIN_FOLLOW );
|
||||
if ( m_hEffect )
|
||||
{
|
||||
m_hOldAttached = m_hEntAttached;
|
||||
|
||||
ParticleProp()->AddControlPoint( m_hEffect, 1, pEntity, PATTACH_ABSORIGIN_FOLLOW );
|
||||
m_hEffect->SetControlPoint( 0, GetAbsOrigin() );
|
||||
m_hEffect->SetControlPoint( 1, GetAbsOrigin() );
|
||||
m_hEffect->SetControlPointEntity( 0, pEntity );
|
||||
m_hEffect->SetControlPointEntity( 1, pEntity );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlame::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
CreateEffect();
|
||||
}
|
||||
|
||||
// FIXME: This is a bit of a shady path
|
||||
if ( updateType == DATA_UPDATE_DATATABLE_CHANGED )
|
||||
{
|
||||
// If our owner changed, then recreate the effect
|
||||
if ( m_hEntAttached != m_hOldAttached )
|
||||
{
|
||||
CreateEffect();
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_EntityFlame::Simulate( void )
|
||||
{
|
||||
if ( gpGlobals->frametime <= 0.0f )
|
||||
return true;
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
if ( IsEffectActive(EF_BRIGHTLIGHT) || IsEffectActive(EF_DIMLIGHT) )
|
||||
{
|
||||
dlight_t *dl = effects->CL_AllocDlight( index );
|
||||
dl->origin = GetAbsOrigin();
|
||||
dl->origin[2] += 16;
|
||||
dl->color.r = 254;
|
||||
dl->color.g = 174;
|
||||
dl->color.b = 10;
|
||||
dl->radius = random->RandomFloat(400,431);
|
||||
dl->die = gpGlobals->curtime + 0.001;
|
||||
}
|
||||
|
||||
#endif // HL2_EPISODIC
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlame::ClientThink( void )
|
||||
{
|
||||
StopEffect();
|
||||
Release();
|
||||
}
|
43
game/client/c_entityflame.h
Normal file
43
game/client/c_entityflame.h
Normal file
@ -0,0 +1,43 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifndef C_ENTITY_FLAME_H
|
||||
#define C_ENTITY_FLAME_H
|
||||
|
||||
#include "c_baseentity.h"
|
||||
|
||||
//
|
||||
// Entity flame, client-side implementation
|
||||
//
|
||||
|
||||
class C_EntityFlame : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_EntityFlame, C_BaseEntity );
|
||||
|
||||
C_EntityFlame( void );
|
||||
virtual ~C_EntityFlame( void );
|
||||
|
||||
virtual bool Simulate( void );
|
||||
virtual void UpdateOnRemove( void );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
EHANDLE m_hEntAttached; // The entity that we are burning (attached to).
|
||||
|
||||
private:
|
||||
void CreateEffect( void );
|
||||
void StopEffect( void );
|
||||
|
||||
CUtlReference<CNewParticleEffect> m_hEffect;
|
||||
EHANDLE m_hOldAttached;
|
||||
bool m_bCheapEffect;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ENTITY_FLAME_H
|
116
game/client/c_entityfreezing.cpp
Normal file
116
game/client/c_entityfreezing.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_entityfreezing.h"
|
||||
#include "studio.h"
|
||||
#include "bone_setup.h"
|
||||
#include "c_surfacerender.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "dt_utlvector_recv.h"
|
||||
#include "debugoverlay_shared.h"
|
||||
#include "animation.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
ConVar cl_blobulator_freezing_max_metaball_radius( "cl_blobulator_freezing_max_metaball_radius",
|
||||
#ifdef INFESTED_DLL
|
||||
"25.0", // Don't need as much precision in Alien swarm because everything is zoomed out
|
||||
#else
|
||||
"12.0",
|
||||
#endif
|
||||
FCVAR_NONE, "Setting this can create more complex surfaces on large hitboxes at the cost of performance.", true, 12.0f, true, 100.0f );
|
||||
|
||||
|
||||
//PRECACHE_REGISTER_BEGIN( GLOBAL, PrecacheEffectFreezing )
|
||||
// PRECACHE( MATERIAL,"effects/tesla_glow_noz" )
|
||||
// PRECACHE( MATERIAL,"effects/spark" )
|
||||
// PRECACHE( MATERIAL,"effects/combinemuzzle2" )
|
||||
//PRECACHE_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityFreezing, DT_EntityFreezing, CEntityFreezing )
|
||||
RecvPropVector( RECVINFO(m_vFreezingOrigin) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY(m_flFrozenPerHitbox), RecvPropFloat( RECVINFO( m_flFrozenPerHitbox[0] ) ) ),
|
||||
RecvPropFloat( RECVINFO(m_flFrozen) ),
|
||||
RecvPropBool( RECVINFO(m_bFinishFreezing) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFreezing::GetRenderBounds( Vector& theMins, Vector& theMaxs )
|
||||
{
|
||||
if ( GetMoveParent() )
|
||||
{
|
||||
GetMoveParent()->GetRenderBounds( theMins, theMaxs );
|
||||
}
|
||||
else
|
||||
{
|
||||
theMins = GetAbsOrigin();
|
||||
theMaxs = theMaxs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Yes we bloody are
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderableTranslucencyType_t C_EntityFreezing::ComputeTranslucencyType( )
|
||||
{
|
||||
return RENDERABLE_IS_TRANSLUCENT;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On data changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFreezing::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFreezing::ClientThink( void )
|
||||
{
|
||||
__asm nop;
|
||||
//C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||
//if (!pAnimating)
|
||||
// return;
|
||||
|
||||
//color32 color = pAnimating->GetRenderColor();
|
||||
|
||||
//color.r = color.g = ( 1.0f - m_flFrozen ) * 255.0f;
|
||||
|
||||
//// Setup the entity fade
|
||||
//pAnimating->SetRenderMode( kRenderTransColor );
|
||||
//pAnimating->SetRenderColor( color.r, color.g, color.b, color.a );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_EntityFreezing::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
47
game/client/c_entityfreezing.h
Normal file
47
game/client/c_entityfreezing.h
Normal file
@ -0,0 +1,47 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ENTITY_FREEZING_H
|
||||
#define C_ENTITY_FREEZING_H
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
|
||||
struct EntityFreezingHitboxBlobData_t
|
||||
{
|
||||
CUtlVector<Vector> m_vPoints;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entity Dissolve, client-side implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EntityFreezing : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_EntityFreezing, C_BaseEntity );
|
||||
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
virtual RenderableTranslucencyType_t ComputeTranslucencyType( );
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
virtual bool ShouldDraw() { return true; }
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
void ClientThink( void );
|
||||
|
||||
private:
|
||||
Vector m_vFreezingOrigin;
|
||||
float m_flFrozenPerHitbox[ 50 ];
|
||||
float m_flFrozen;
|
||||
bool m_bFinishFreezing;
|
||||
|
||||
CUtlVector<EntityFreezingHitboxBlobData_t> m_HitboxBlobData;
|
||||
};
|
||||
|
||||
#endif // C_ENTITY_FREEZING_H
|
||||
|
250
game/client/c_entityparticletrail.cpp
Normal file
250
game/client/c_entityparticletrail.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "baseparticleentity.h"
|
||||
#include "entityparticletrail_shared.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_util.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entity particle trail, client-side implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EntityParticleTrail : public C_BaseParticleEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_EntityParticleTrail, C_BaseParticleEntity );
|
||||
|
||||
C_EntityParticleTrail( );
|
||||
~C_EntityParticleTrail( );
|
||||
|
||||
// C_BaseEntity
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
// IParticleEffect
|
||||
void Update( float fTimeDelta );
|
||||
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||
|
||||
private:
|
||||
|
||||
C_EntityParticleTrail( const C_EntityParticleTrail & ); // not defined, not accessible
|
||||
|
||||
void Start( );
|
||||
void AddParticle( float flInitialDeltaTime, const Vector &vecMins, const Vector &vecMaxs, const matrix3x4_t &boxToWorld );
|
||||
|
||||
int m_iMaterialName;
|
||||
EntityParticleTrailInfo_t m_Info;
|
||||
EHANDLE m_hConstraintEntity;
|
||||
|
||||
PMaterialHandle m_hMaterial;
|
||||
TimedEvent m_teParticleSpawn;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityParticleTrail, DT_EntityParticleTrail, CEntityParticleTrail )
|
||||
RecvPropInt(RECVINFO(m_iMaterialName)),
|
||||
RecvPropDataTable( RECVINFO_DT( m_Info ), 0, &REFERENCE_RECV_TABLE(DT_EntityParticleTrailInfo) ),
|
||||
RecvPropEHandle(RECVINFO(m_hConstraintEntity)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EntityParticleTrail::C_EntityParticleTrail( void )
|
||||
{
|
||||
}
|
||||
|
||||
C_EntityParticleTrail::~C_EntityParticleTrail()
|
||||
{
|
||||
ParticleMgr()->RemoveEffect( &m_ParticleEffect );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On data changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityParticleTrail::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
Start( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pParticleMgr -
|
||||
// *pArgs -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityParticleTrail::Start( )
|
||||
{
|
||||
if( ParticleMgr()->AddEffect( &m_ParticleEffect, this ) == false )
|
||||
return;
|
||||
|
||||
const char *pMaterialName = GetMaterialNameFromIndex( m_iMaterialName );
|
||||
if ( !pMaterialName )
|
||||
return;
|
||||
|
||||
m_hMaterial = ParticleMgr()->GetPMaterial( pMaterialName );
|
||||
m_teParticleSpawn.Init( 150 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityParticleTrail::AddParticle( float flInitialDeltaTime, const Vector &vecMins, const Vector &vecMaxs, const matrix3x4_t &boxToWorld )
|
||||
{
|
||||
// Select a random point somewhere in the hitboxes of the entity.
|
||||
Vector vecLocalPosition, vecWorldPosition;
|
||||
vecLocalPosition.x = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.x, vecMaxs.x );
|
||||
vecLocalPosition.y = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.y, vecMaxs.y );
|
||||
vecLocalPosition.z = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.z, vecMaxs.z );
|
||||
VectorTransform( vecLocalPosition, boxToWorld, vecWorldPosition );
|
||||
|
||||
// Don't emit the particle unless it's inside the model
|
||||
if ( m_hConstraintEntity.Get() )
|
||||
{
|
||||
Ray_t ray;
|
||||
trace_t tr;
|
||||
ray.Init( vecWorldPosition, vecWorldPosition );
|
||||
enginetrace->ClipRayToEntity( ray, MASK_ALL, m_hConstraintEntity, &tr );
|
||||
|
||||
if ( !tr.startsolid )
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a new particle
|
||||
SimpleParticle *pParticle = (SimpleParticle *)m_ParticleEffect.AddParticle( sizeof(SimpleParticle), m_hMaterial );
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_Pos = vecWorldPosition;
|
||||
pParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
|
||||
|
||||
pParticle->m_flLifetime = flInitialDeltaTime;
|
||||
pParticle->m_flDieTime = m_Info.m_flLifetime;
|
||||
|
||||
pParticle->m_uchColor[0] = 64;
|
||||
pParticle->m_uchColor[1] = 140;
|
||||
pParticle->m_uchColor[2] = 225;
|
||||
pParticle->m_uchStartAlpha = Helper_RandomInt( 64, 64 );
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
pParticle->m_uchStartSize = m_Info.m_flStartSize;
|
||||
pParticle->m_uchEndSize = m_Info.m_flEndSize;
|
||||
|
||||
pParticle->m_vecVelocity = vec3_origin;
|
||||
VectorMA( pParticle->m_Pos, flInitialDeltaTime, pParticle->m_vecVelocity, pParticle->m_Pos );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : fTimeDelta -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityParticleTrail::Update( float fTimeDelta )
|
||||
{
|
||||
float tempDelta = fTimeDelta;
|
||||
studiohdr_t *pStudioHdr;
|
||||
mstudiohitboxset_t *set;
|
||||
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
|
||||
|
||||
C_BaseEntity *pMoveParent = GetMoveParent();
|
||||
if ( !pMoveParent )
|
||||
return;
|
||||
|
||||
C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating();
|
||||
if (!pAnimating)
|
||||
goto trailNoHitboxes;
|
||||
|
||||
if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) )
|
||||
goto trailNoHitboxes;
|
||||
|
||||
pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
|
||||
if (!pStudioHdr)
|
||||
goto trailNoHitboxes;
|
||||
|
||||
set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
|
||||
if ( !set )
|
||||
goto trailNoHitboxes;
|
||||
|
||||
//Add new particles
|
||||
while ( m_teParticleSpawn.NextEvent( tempDelta ) )
|
||||
{
|
||||
int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
|
||||
mstudiobbox_t *pBox = set->pHitbox(nHitbox);
|
||||
|
||||
AddParticle( tempDelta, pBox->bbmin, pBox->bbmax, *hitboxbones[pBox->bone] );
|
||||
}
|
||||
return;
|
||||
|
||||
trailNoHitboxes:
|
||||
while ( m_teParticleSpawn.NextEvent( tempDelta ) )
|
||||
{
|
||||
AddParticle( tempDelta, pMoveParent->CollisionProp()->OBBMins(), pMoveParent->CollisionProp()->OBBMaxs(), pMoveParent->EntityToWorldTransform() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void C_EntityParticleTrail::RenderParticles( CParticleRenderIterator *pIterator )
|
||||
{
|
||||
const SimpleParticle *pParticle = (const SimpleParticle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
float t = pParticle->m_flLifetime / pParticle->m_flDieTime;
|
||||
|
||||
// Render
|
||||
Vector tPos;
|
||||
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, tPos );
|
||||
float sortKey = tPos.z;
|
||||
|
||||
Vector color = Vector( pParticle->m_uchColor[0] / 255.0f, pParticle->m_uchColor[1] / 255.0f, pParticle->m_uchColor[2] / 255.0f );
|
||||
float alpha = Lerp( t, pParticle->m_uchStartAlpha / 255.0f, pParticle->m_uchEndAlpha / 255.0f );
|
||||
float flSize = Lerp( t, pParticle->m_uchStartSize, pParticle->m_uchEndSize );
|
||||
|
||||
// Render it
|
||||
RenderParticle_ColorSize( pIterator->GetParticleDraw(), tPos, color, alpha, flSize );
|
||||
|
||||
pParticle = (const SimpleParticle*)pIterator->GetNext( sortKey );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void C_EntityParticleTrail::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||
{
|
||||
SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
// Update position
|
||||
float flTimeDelta = pIterator->GetTimeDelta();
|
||||
pParticle->m_Pos += pParticle->m_vecVelocity * flTimeDelta;
|
||||
|
||||
// NOTE: I'm overloading "die time" to be the actual start time.
|
||||
pParticle->m_flLifetime += flTimeDelta;
|
||||
|
||||
if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
|
||||
pIterator->RemoveParticle( pParticle );
|
||||
|
||||
pParticle = (SimpleParticle*)pIterator->GetNext();
|
||||
}
|
||||
}
|
||||
|
95
game/client/c_env_ambient_light.cpp
Normal file
95
game/client/c_env_ambient_light.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Ambient light controller entity with simple radial falloff
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_spatialentity.h"
|
||||
#include "spatialentitymgr.h"
|
||||
#include "c_env_ambient_light.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
static ConVar cl_ambient_light_disableentities( "cl_ambient_light_disableentities", "0", FCVAR_NONE, "Disable map ambient light entities." );
|
||||
|
||||
|
||||
static CSpatialEntityMgr s_EnvAmbientLightMgr;
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvAmbientLight, DT_EnvAmbientLight, CEnvAmbientLight )
|
||||
RecvPropVector( RECVINFO_NAME( m_Value, m_vecColor ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_EnvAmbientLight::ApplyAccumulation( void )
|
||||
{
|
||||
Vector rgbVal = BlendedValue();
|
||||
|
||||
static ConVarRef mat_ambient_light_r( "mat_ambient_light_r" );
|
||||
static ConVarRef mat_ambient_light_g( "mat_ambient_light_g" );
|
||||
static ConVarRef mat_ambient_light_b( "mat_ambient_light_b" );
|
||||
|
||||
if ( mat_ambient_light_r.IsValid() )
|
||||
{
|
||||
mat_ambient_light_r.SetValue( rgbVal.x );
|
||||
}
|
||||
|
||||
if ( mat_ambient_light_g.IsValid() )
|
||||
{
|
||||
mat_ambient_light_g.SetValue( rgbVal.y );
|
||||
}
|
||||
|
||||
if ( mat_ambient_light_b.IsValid() )
|
||||
{
|
||||
mat_ambient_light_b.SetValue( rgbVal.z );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_EnvAmbientLight::AddToPersonalSpatialEntityMgr( void )
|
||||
{
|
||||
s_EnvAmbientLightMgr.AddSpatialEntity( this );
|
||||
}
|
||||
|
||||
void C_EnvAmbientLight::RemoveFromPersonalSpatialEntityMgr( void )
|
||||
{
|
||||
s_EnvAmbientLightMgr.RemoveSpatialEntity( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void C_EnvAmbientLight::SetColor( const Vector &vecColor, float flLerpTime )
|
||||
{
|
||||
if ( flLerpTime <= 0 )
|
||||
{
|
||||
m_Value = vecColor / 255.0f;
|
||||
m_colorTimer.Invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
m_vecStartColor = m_Value;
|
||||
m_vecTargetColor = vecColor / 255.0f;
|
||||
m_colorTimer.Start( flLerpTime );
|
||||
}
|
||||
|
||||
void C_EnvAmbientLight::ClientThink( void )
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
if ( m_colorTimer.HasStarted() )
|
||||
{
|
||||
if ( m_colorTimer.IsElapsed() )
|
||||
{
|
||||
m_Value = m_vecTargetColor;
|
||||
m_colorTimer.Invalidate();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Value = m_vecTargetColor - ( m_vecTargetColor - m_vecStartColor ) * m_colorTimer.GetRemainingRatio();
|
||||
}
|
||||
}
|
||||
}
|
30
game/client/c_env_ambient_light.h
Normal file
30
game/client/c_env_ambient_light.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef _INCLUDED_C_ENV_AMBIENT_LIGHT_H
|
||||
#define _INCLUDED_C_ENV_AMBIENT_LIGHT_H
|
||||
|
||||
#include "c_spatialentity.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Ambient light controller entity with radial falloff
|
||||
//------------------------------------------------------------------------------
|
||||
class C_EnvAmbientLight : public C_SpatialEntityTemplate<Vector>
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_EnvAmbientLight, C_SpatialEntityTemplate<Vector> );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void ApplyAccumulation( void );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
void SetColor( const Vector &vecColor, float flLerpTime = 0 );
|
||||
Vector GetTargetColor() { return m_vecTargetColor * 255.0f; }
|
||||
|
||||
protected:
|
||||
virtual void AddToPersonalSpatialEntityMgr( void );
|
||||
virtual void RemoveFromPersonalSpatialEntityMgr( void );
|
||||
|
||||
Vector m_vecStartColor;
|
||||
Vector m_vecTargetColor;
|
||||
CountdownTimer m_colorTimer;
|
||||
};
|
||||
|
||||
#endif // _INCLUDED_C_ENV_AMBIENT_LIGHT_H
|
100
game/client/c_env_dof_controller.cpp
Normal file
100
game/client/c_env_dof_controller.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
extern bool g_bDOFEnabled;
|
||||
extern float g_flDOFNearBlurDepth;
|
||||
extern float g_flDOFNearFocusDepth;
|
||||
extern float g_flDOFFarFocusDepth;
|
||||
extern float g_flDOFFarBlurDepth;
|
||||
extern float g_flDOFNearBlurRadius;
|
||||
extern float g_flDOFFarBlurRadius;
|
||||
|
||||
EHANDLE g_hDOFControllerInUse = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EnvDOFController : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_EnvDOFController, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EnvDOFController();
|
||||
~C_EnvDOFController();
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
private:
|
||||
bool m_bDOFEnabled;
|
||||
float m_flNearBlurDepth;
|
||||
float m_flNearFocusDepth;
|
||||
float m_flFarFocusDepth;
|
||||
float m_flFarBlurDepth;
|
||||
float m_flNearBlurRadius;
|
||||
float m_flFarBlurRadius;
|
||||
|
||||
private:
|
||||
C_EnvDOFController( const C_EnvDOFController & );
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvDOFController, DT_EnvDOFController, CEnvDOFController )
|
||||
RecvPropInt( RECVINFO(m_bDOFEnabled) ),
|
||||
RecvPropFloat( RECVINFO(m_flNearBlurDepth) ),
|
||||
RecvPropFloat( RECVINFO(m_flNearFocusDepth) ),
|
||||
RecvPropFloat( RECVINFO(m_flFarFocusDepth) ),
|
||||
RecvPropFloat( RECVINFO(m_flFarBlurDepth) ),
|
||||
RecvPropFloat( RECVINFO(m_flNearBlurRadius) ),
|
||||
RecvPropFloat( RECVINFO(m_flFarBlurRadius) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvDOFController::C_EnvDOFController( void )
|
||||
: m_bDOFEnabled( true ),
|
||||
m_flNearBlurDepth( 50.0f ),
|
||||
m_flNearFocusDepth( 100.0f ),
|
||||
m_flFarFocusDepth( 250.0f ),
|
||||
m_flFarBlurDepth( 1000.0f ),
|
||||
m_flNearBlurRadius( 0.0f ), // no near blur by default
|
||||
m_flFarBlurRadius( 5.0f )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvDOFController::~C_EnvDOFController( void )
|
||||
{
|
||||
if ( g_hDOFControllerInUse == this )
|
||||
{
|
||||
g_bDOFEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvDOFController::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
g_bDOFEnabled = m_bDOFEnabled && ( ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ) );
|
||||
g_flDOFNearBlurDepth = m_flNearBlurDepth;
|
||||
g_flDOFNearFocusDepth = m_flNearFocusDepth;
|
||||
g_flDOFFarFocusDepth = m_flFarFocusDepth;
|
||||
g_flDOFFarBlurDepth = m_flFarBlurDepth;
|
||||
g_flDOFNearBlurRadius = m_flNearBlurRadius;
|
||||
g_flDOFFarBlurRadius = m_flFarBlurRadius;
|
||||
|
||||
g_hDOFControllerInUse = this;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user