1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 20:16:10 +08:00

First version of the SOurce SDK 2013

This commit is contained in:
Joe Ludwig
2013-06-26 15:22:04 -07:00
commit e7d6f4c174
3682 changed files with 1624327 additions and 0 deletions

View File

@ -0,0 +1,472 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Basic BOT handling.
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "player.h"
#include "sdk_player.h"
#include "in_buttons.h"
#include "movehelper_server.h"
#include "gameinterface.h"
class CSDKBot;
void Bot_Think( CSDKBot *pBot );
ConVar bot_forcefireweapon( "bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." );
ConVar bot_forceattack2( "bot_forceattack2", "0", 0, "When firing, use attack2." );
ConVar bot_forceattackon( "bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." );
ConVar bot_flipout( "bot_flipout", "0", 0, "When on, all bots fire their guns." );
ConVar bot_changeclass( "bot_changeclass", "0", 0, "Force all bots to change to the specified class." );
static ConVar bot_mimic( "bot_mimic", "0", 0, "Bot uses usercmd of player by index." );
static ConVar bot_mimic_yaw_offset( "bot_mimic_yaw_offset", "0", 0, "Offsets the bot yaw." );
ConVar bot_sendcmd( "bot_sendcmd", "", 0, "Forces bots to send the specified command." );
ConVar bot_crouch( "bot_crouch", "0", 0, "Bot crouches" );
static int g_CurBotNumber = 1;
// This is our bot class.
class CSDKBot : public CSDKPlayer
{
public:
bool m_bBackwards;
float m_flNextTurnTime;
bool m_bLastTurnToRight;
float m_flNextStrafeTime;
float m_flSideMove;
QAngle m_ForwardAngle;
QAngle m_LastAngles;
};
LINK_ENTITY_TO_CLASS( sdk_bot, CSDKBot );
class CBotManager
{
public:
static CBasePlayer* ClientPutInServerOverride_Bot( edict_t *pEdict, const char *playername )
{
// This tells it which edict to use rather than creating a new one.
CBasePlayer::s_PlayerEdict = pEdict;
CSDKBot *pPlayer = static_cast<CSDKBot *>( CreateEntityByName( "sdk_bot" ) );
if ( pPlayer )
{
pPlayer->SetPlayerName( playername );
}
return pPlayer;
}
};
//-----------------------------------------------------------------------------
// Purpose: Create a new Bot and put it in the game.
// Output : Pointer to the new Bot, or NULL if there's no free clients.
//-----------------------------------------------------------------------------
CBasePlayer *BotPutInServer( bool bFrozen )
{
char botname[ 64 ];
Q_snprintf( botname, sizeof( botname ), "Bot%02i", g_CurBotNumber );
// This trick lets us create a CSDKBot for this client instead of the CSDKPlayer
// that we would normally get when ClientPutInServer is called.
ClientPutInServerOverride( &CBotManager::ClientPutInServerOverride_Bot );
edict_t *pEdict = engine->CreateFakeClient( botname );
ClientPutInServerOverride( NULL );
if (!pEdict)
{
Msg( "Failed to create Bot.\n");
return NULL;
}
// Allocate a player entity for the bot, and call spawn
CSDKBot *pPlayer = ((CSDKBot*)CBaseEntity::Instance( pEdict ));
pPlayer->ClearFlags();
pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT );
if ( bFrozen )
pPlayer->AddEFlags( EFL_BOT_FROZEN );
pPlayer->ChangeTeam( TEAM_UNASSIGNED );
pPlayer->RemoveAllItems( true );
pPlayer->Spawn();
g_CurBotNumber++;
return pPlayer;
}
// Handler for the "bot" command.
CON_COMMAND_F( "bot_add", "Add a bot.", FCVAR_CHEAT )
{
// Look at -count.
int count = args.FindArgInt( "-count", 1 );
count = clamp( count, 1, 16 );
// Look at -frozen.
bool bFrozen = !!args.FindArg( "-frozen" );
// Ok, spawn all the bots.
while ( --count >= 0 )
{
BotPutInServer( bFrozen );
}
}
//-----------------------------------------------------------------------------
// Purpose: Run through all the Bots in the game and let them think.
//-----------------------------------------------------------------------------
void Bot_RunAll( void )
{
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CSDKPlayer *pPlayer = ToSDKPlayer( UTIL_PlayerByIndex( i ) );
if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) )
{
CSDKBot *pBot = dynamic_cast< CSDKBot* >( pPlayer );
if ( pBot )
Bot_Think( pBot );
}
}
}
bool Bot_RunMimicCommand( CUserCmd& cmd )
{
if ( bot_mimic.GetInt() <= 0 )
return false;
if ( bot_mimic.GetInt() > gpGlobals->maxClients )
return false;
CBasePlayer *pPlayer = UTIL_PlayerByIndex( bot_mimic.GetInt() );
if ( !pPlayer )
return false;
if ( !pPlayer->GetLastUserCommand() )
return false;
cmd = *pPlayer->GetLastUserCommand();
cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat();
if( bot_crouch.GetInt() )
cmd.buttons |= IN_DUCK;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Simulates a single frame of movement for a player
// Input : *fakeclient -
// *viewangles -
// forwardmove -
// m_flSideMove -
// upmove -
// buttons -
// impulse -
// msec -
// Output : virtual void
//-----------------------------------------------------------------------------
static void RunPlayerMove( CSDKPlayer *fakeclient, CUserCmd &cmd, float frametime )
{
if ( !fakeclient )
return;
// Store off the globals.. they're gonna get whacked
float flOldFrametime = gpGlobals->frametime;
float flOldCurtime = gpGlobals->curtime;
float flTimeBase = gpGlobals->curtime + gpGlobals->frametime - frametime;
fakeclient->SetTimeBase( flTimeBase );
MoveHelperServer()->SetHost( fakeclient );
fakeclient->PlayerRunCommand( &cmd, MoveHelperServer() );
// save off the last good usercmd
fakeclient->SetLastUserCommand( cmd );
// Clear out any fixangle that has been set
fakeclient->pl.fixangle = FIXANGLE_NONE;
// Restore the globals..
gpGlobals->frametime = flOldFrametime;
gpGlobals->curtime = flOldCurtime;
}
void Bot_UpdateStrafing( CSDKBot *pBot, CUserCmd &cmd )
{
if ( gpGlobals->curtime >= pBot->m_flNextStrafeTime )
{
pBot->m_flNextStrafeTime = gpGlobals->curtime + 1.0f;
if ( random->RandomInt( 0, 5 ) == 0 )
{
pBot->m_flSideMove = -600.0f + 1200.0f * random->RandomFloat( 0, 2 );
}
else
{
pBot->m_flSideMove = 0;
}
cmd.sidemove = pBot->m_flSideMove;
if ( random->RandomInt( 0, 20 ) == 0 )
{
pBot->m_bBackwards = true;
}
else
{
pBot->m_bBackwards = false;
}
}
}
void Bot_UpdateDirection( CSDKBot *pBot )
{
float angledelta = 15.0;
QAngle angle;
int maxtries = (int)360.0/angledelta;
if ( pBot->m_bLastTurnToRight )
{
angledelta = -angledelta;
}
angle = pBot->GetLocalAngles();
trace_t trace;
Vector vecSrc, vecEnd, forward;
while ( --maxtries >= 0 )
{
AngleVectors( angle, &forward );
vecSrc = pBot->GetLocalOrigin() + Vector( 0, 0, 36 );
vecEnd = vecSrc + forward * 10;
UTIL_TraceHull( vecSrc, vecEnd, VEC_HULL_MIN_SCALED( pBot ), VEC_HULL_MAX_SCALED( pBot ),
MASK_PLAYERSOLID, pBot, COLLISION_GROUP_NONE, &trace );
if ( trace.fraction == 1.0 )
{
if ( gpGlobals->curtime < pBot->m_flNextTurnTime )
{
break;
}
}
angle.y += angledelta;
if ( angle.y > 180 )
angle.y -= 360;
else if ( angle.y < -180 )
angle.y += 360;
pBot->m_flNextTurnTime = gpGlobals->curtime + 2.0;
pBot->m_bLastTurnToRight = random->RandomInt( 0, 1 ) == 0 ? true : false;
pBot->m_ForwardAngle = angle;
pBot->m_LastAngles = angle;
}
pBot->SetLocalAngles( angle );
}
void Bot_FlipOut( CSDKBot *pBot, CUserCmd &cmd )
{
if ( bot_flipout.GetInt() > 0 && pBot->IsAlive() )
{
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
{
cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
}
if ( bot_flipout.GetInt() >= 2 )
{
QAngle angOffset = RandomAngle( -1, 1 );
pBot->m_LastAngles += angOffset;
for ( int i = 0 ; i < 2; i++ )
{
if ( fabs( pBot->m_LastAngles[ i ] - pBot->m_ForwardAngle[ i ] ) > 15.0f )
{
if ( pBot->m_LastAngles[ i ] > pBot->m_ForwardAngle[ i ] )
{
pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] + 15;
}
else
{
pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] - 15;
}
}
}
pBot->m_LastAngles[ 2 ] = 0;
pBot->SetLocalAngles( pBot->m_LastAngles );
}
}
}
void Bot_HandleSendCmd( CSDKBot *pBot )
{
if ( strlen( bot_sendcmd.GetString() ) > 0 )
{
//send the cmd from this bot
pBot->ClientCommand( bot_sendcmd.GetString() );
bot_sendcmd.SetValue("");
}
}
// If bots are being forced to fire a weapon, see if I have it
void Bot_ForceFireWeapon( CSDKBot *pBot, CUserCmd &cmd )
{
if ( bot_forcefireweapon.GetString() )
{
CBaseCombatWeapon *pWeapon = pBot->Weapon_OwnsThisType( bot_forcefireweapon.GetString() );
if ( pWeapon )
{
// Switch to it if we don't have it out
CBaseCombatWeapon *pActiveWeapon = pBot->GetActiveWeapon();
// Switch?
if ( pActiveWeapon != pWeapon )
{
pBot->Weapon_Switch( pWeapon );
}
else
{
// Start firing
// Some weapons require releases, so randomise firing
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
{
cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
}
}
}
}
}
void Bot_SetForwardMovement( CSDKBot *pBot, CUserCmd &cmd )
{
if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) )
{
if ( pBot->m_iHealth == 100 )
{
cmd.forwardmove = 600 * ( pBot->m_bBackwards ? -1 : 1 );
if ( pBot->m_flSideMove != 0.0f )
{
cmd.forwardmove *= random->RandomFloat( 0.1, 1.0f );
}
}
else
{
// Stop when shot
cmd.forwardmove = 0;
}
}
}
void Bot_HandleRespawn( CSDKBot *pBot, CUserCmd &cmd )
{
// Wait for Reinforcement wave
if ( !pBot->IsAlive() )
{
// Try hitting my buttons occasionally
if ( random->RandomInt( 0, 100 ) > 80 )
{
// Respawn the bot
if ( random->RandomInt( 0, 1 ) == 0 )
{
cmd.buttons |= IN_JUMP;
}
else
{
cmd.buttons = 0;
}
}
}
}
//-----------------------------------------------------------------------------
// Run this Bot's AI for one frame.
//-----------------------------------------------------------------------------
void Bot_Think( CSDKBot *pBot )
{
// Make sure we stay being a bot
pBot->AddFlag( FL_FAKECLIENT );
CUserCmd cmd;
Q_memset( &cmd, 0, sizeof( cmd ) );
// Finally, override all this stuff if the bot is being forced to mimic a player.
if ( !Bot_RunMimicCommand( cmd ) )
{
cmd.sidemove = pBot->m_flSideMove;
if ( pBot->IsAlive() && (pBot->GetSolid() == SOLID_BBOX) )
{
Bot_SetForwardMovement( pBot, cmd );
// Only turn if I haven't been hurt
if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_iHealth == 100 )
{
Bot_UpdateDirection( pBot );
Bot_UpdateStrafing( pBot, cmd );
}
// Handle console settings.
Bot_ForceFireWeapon( pBot, cmd );
Bot_HandleSendCmd( pBot );
}
else
{
Bot_HandleRespawn( pBot, cmd );
}
Bot_FlipOut( pBot, cmd );
cmd.viewangles = pBot->GetLocalAngles();
cmd.upmove = 0;
cmd.impulse = 0;
}
float frametime = gpGlobals->frametime;
RunPlayerMove( pBot, cmd, frametime );
}

View File

@ -0,0 +1,21 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SDK_BOT_TEMP_H
#define SDK_BOT_TEMP_H
#ifdef _WIN32
#pragma once
#endif
// If iTeam or iClass is -1, then a team or class is randomly chosen.
CBasePlayer *BotPutInServer( bool bFrozen, int iTeam, int iClass );
void Bot_RunAll();
#endif // SDK_BOT_TEMP_H

View File

@ -0,0 +1,79 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Simple brush entity that moves when touched
//
//=============================================================================//
#include "cbase.h"
class CMyBrushEntity : public CBaseToggle
{
public:
DECLARE_CLASS( CMyBrushEntity, CBaseToggle );
DECLARE_DATADESC();
void Spawn( void );
bool CreateVPhysics( void );
void BrushTouch( CBaseEntity *pOther );
};
LINK_ENTITY_TO_CLASS( my_brush_entity, CMyBrushEntity );
// Start of our data description for the class
BEGIN_DATADESC( CMyBrushEntity )
// Declare this function as being a touch function
DEFINE_ENTITYFUNC( BrushTouch ),
END_DATADESC()
//-----------------------------------------------------------------------------
// Purpose: Sets up the entity's initial state
//-----------------------------------------------------------------------------
void CMyBrushEntity::Spawn( void )
{
// We want to capture touches from other entities
SetTouch( &CMyBrushEntity::BrushTouch );
// We should collide with physics
SetSolid( SOLID_VPHYSICS );
// We push things out of our way
SetMoveType( MOVETYPE_PUSH );
// Use our brushmodel
SetModel( STRING( GetModelName() ) );
// Create our physics hull information
CreateVPhysics();
}
//-----------------------------------------------------------------------------
// Purpose: Setup our physics information so we collide properly
//-----------------------------------------------------------------------------
bool CMyBrushEntity::CreateVPhysics( void )
{
// For collisions with physics objects
VPhysicsInitShadow( false, false );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Move away from an entity that touched us
// Input : *pOther - the entity we touched
//-----------------------------------------------------------------------------
void CMyBrushEntity::BrushTouch( CBaseEntity *pOther )
{
// Get the collision information
const trace_t &tr = GetTouchTrace();
// We want to move away from the impact point along our surface
Vector vecPushDir = tr.plane.normal;
vecPushDir.Negate();
vecPushDir.z = 0.0f;
// Move slowly in that direction
LinearMove( GetAbsOrigin() + ( vecPushDir * 64.0f ), 32.0f );
}

View File

@ -0,0 +1,164 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
/*
===== tf_client.cpp ========================================================
HL2 client/server game specific stuff
*/
#include "cbase.h"
#include "player.h"
#include "gamerules.h"
#include "entitylist.h"
#include "physics.h"
#include "game.h"
#include "ai_network.h"
#include "ai_node.h"
#include "ai_hull.h"
#include "shake.h"
#include "player_resource.h"
#include "engine/IEngineSound.h"
#include "sdk_player.h"
#include "sdk_gamerules.h"
#include "tier0/vprof.h"
#include "sdk_bot_temp.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern CBaseEntity *FindPickerEntity( CBasePlayer *pPlayer );
extern bool g_fGameOver;
void FinishClientPutInServer( CSDKPlayer *pPlayer )
{
pPlayer->InitialSpawn();
pPlayer->Spawn();
if (!pPlayer->IsBot())
{
// When the player first joins the server, they
pPlayer->m_takedamage = DAMAGE_YES;
pPlayer->pl.deadflag = false;
pPlayer->m_lifeState = LIFE_ALIVE;
pPlayer->RemoveEffects( EF_NODRAW );
pPlayer->ChangeTeam( TEAM_UNASSIGNED );
pPlayer->SetThink( NULL );
}
char sName[128];
Q_strncpy( sName, pPlayer->GetPlayerName(), sizeof( sName ) );
// First parse the name and remove any %'s
for ( char *pApersand = sName; pApersand != NULL && *pApersand != 0; pApersand++ )
{
// Replace it with a space
if ( *pApersand == '%' )
*pApersand = ' ';
}
// notify other clients of player joining the game
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Game_connected", sName[0] != 0 ? sName : "<unconnected>" );
}
/*
===========
ClientPutInServer
called each time a player is spawned into the game
============
*/
void ClientPutInServer( edict_t *pEdict, const char *playername )
{
// Allocate a CBaseTFPlayer for pev, and call spawn
CSDKPlayer *pPlayer = CSDKPlayer::CreatePlayer( "player", pEdict );
pPlayer->SetPlayerName( playername );
}
void ClientActive( edict_t *pEdict, bool bLoadGame )
{
// Can't load games in CS!
Assert( !bLoadGame );
CSDKPlayer *pPlayer = ToSDKPlayer( CBaseEntity::Instance( pEdict ) );
FinishClientPutInServer( pPlayer );
}
/*
===============
const char *GetGameDescription()
Returns the descriptive name of this .dll. E.g., Half-Life, or Team Fortress 2
===============
*/
const char *GetGameDescription()
{
if ( g_pGameRules ) // this function may be called before the world has spawned, and the game rules initialized
return g_pGameRules->GetGameDescription();
else
return "CounterStrike";
}
//-----------------------------------------------------------------------------
// Purpose: Precache game-specific models & sounds
//-----------------------------------------------------------------------------
void ClientGamePrecache( void )
{
// Materials used by the client effects
CBaseEntity::PrecacheModel( "sprites/white.vmt" );
CBaseEntity::PrecacheModel( "sprites/physbeam.vmt" );
}
// called by ClientKill and DeadThink
void respawn( CBaseEntity *pEdict, bool fCopyCorpse )
{
if (gpGlobals->coop || gpGlobals->deathmatch)
{
if ( fCopyCorpse )
{
// make a copy of the dead body for appearances sake
dynamic_cast< CBasePlayer* >( pEdict )->CreateCorpse();
}
// respawn player
pEdict->Spawn();
}
else
{ // restart the entire server
engine->ServerCommand("reload\n");
}
}
void GameStartFrame( void )
{
VPROF( "GameStartFrame" );
if ( g_pGameRules )
g_pGameRules->Think();
if ( g_fGameOver )
return;
gpGlobals->teamplay = teamplay.GetInt() ? true : false;
}
//=========================================================
// instantiate the proper game rules object
//=========================================================
void InstallGameRules()
{
CreateGameRulesObject( "CSDKGameRules" );
}

View File

@ -0,0 +1,46 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Simple entity to transmit message to the client
//
//=============================================================================//
#include "cbase.h"
class CGameMessageEntity : public CLogicalEntity
{
public:
DECLARE_CLASS( CGameMessageEntity, CLogicalEntity );
DECLARE_DATADESC();
CGameMessageEntity( void ) {};
void InputDisplayMessage( inputdata_t &data );
string_t m_strText;
};
LINK_ENTITY_TO_CLASS( logic_game_message, CGameMessageEntity );
BEGIN_DATADESC( CGameMessageEntity )
DEFINE_KEYFIELD( m_strText, FIELD_STRING, "text" ),
DEFINE_INPUTFUNC( FIELD_VOID, "DisplayMessage", InputDisplayMessage ),
END_DATADESC()
void CGameMessageEntity::InputDisplayMessage( inputdata_t &data )
{
// Only send this message the local player
CSingleUserRecipientFilter user( UTIL_PlayerByIndex(1) );
user.MakeReliable();
// Start the message block
UserMessageBegin( user, "GameMessage" );
// Send our text to the client
WRITE_STRING( STRING( m_strText ) );
// End the message block
MessageEnd();
}

View File

@ -0,0 +1,104 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: A simple test entity for creating special effects
//
//=============================================================================//
#include "cbase.h"
#include "te_effect_dispatch.h"
// Declare the sparkler entity for the server-side
class CSparkler : public CBaseEntity
{
public:
DECLARE_SERVERCLASS();
DECLARE_CLASS( CSparkler, CBaseEntity );
void Spawn( void );
void InputToggle( inputdata_t &input ); // Input function for toggling our effect's state
void InputScale( inputdata_t &input );
private:
CNetworkVar( bool, m_bEmit ); // Marks whether the effect should be active or not
CNetworkVar( float, m_flScale ); // The size and speed of the effect
DECLARE_DATADESC();
};
// Link our class to the "env_sparkler" entity classname
LINK_ENTITY_TO_CLASS( env_sparkler, CSparkler );
// Declare our data description for this entity
BEGIN_DATADESC( CSparkler )
DEFINE_FIELD( m_bEmit, FIELD_BOOLEAN ),
DEFINE_KEYFIELD( m_flScale, FIELD_FLOAT, "scale" ),
DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ), // Declare our toggle input function
DEFINE_INPUTFUNC( FIELD_FLOAT, "Scale", InputScale ),
END_DATADESC()
// Declare the data-table for server/client communication
IMPLEMENT_SERVERCLASS_ST( CSparkler, DT_Sparkler )
SendPropInt( SENDINFO( m_bEmit ), 1, SPROP_UNSIGNED ), // Declare our boolean state variable
SendPropFloat( SENDINFO( m_flScale ), 0, SPROP_NOSCALE ),
END_SEND_TABLE()
//-----------------------------------------------------------------------------
// Purpose: Spawn function for this entity
//-----------------------------------------------------------------------------
void CSparkler::Spawn( void )
{
SetMoveType( MOVETYPE_NONE ); // Will not move on its own
SetSolid( SOLID_NONE ); // Will not collide with anything
// Set a size for culling
UTIL_SetSize( this, -Vector(2,2,2), Vector(2,2,2) );
// We must add this flag to receive network transmitions
AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
}
//-----------------------------------------------------------------------------
// Purpose: Toggles the emission state of the effect
//-----------------------------------------------------------------------------
void CSparkler::InputToggle( inputdata_t &input )
{
// Toggle our state
m_bEmit = !m_bEmit;
}
//-----------------------------------------------------------------------------
// Purpose: Change our scale via a float value
//-----------------------------------------------------------------------------
void CSparkler::InputScale( inputdata_t &input )
{
// Change our scale
m_flScale = input.value.Float();
}
// ============================================================================
//
// Dispatch Effect version
//
// ============================================================================
//-----------------------------------------------------------------------------
// Purpose: Create a sparkle effect at the given location of the given size
// Input : &position - Where to emit from
// flSize - Size of the effect
//-----------------------------------------------------------------------------
void MakeSparkle( const Vector &origin, float flScale )
{
CEffectData data;
// Send our origin
data.m_vOrigin = origin;
// Send our scale
data.m_flScale = flScale;
// Send the effect off to the client
DispatchEffect( "Sparkle", data );
}

View File

@ -0,0 +1,55 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "../EventLog.h"
#include "KeyValues.h"
class CSDKEventLog : public CEventLog
{
private:
typedef CEventLog BaseClass;
public:
virtual ~CSDKEventLog() {};
public:
bool PrintEvent( IGameEvent * event ) // override virtual function
{
if ( BaseClass::PrintEvent( event ) )
{
return true;
}
if ( Q_strcmp(event->GetName(), "sdk_") == 0 )
{
return PrintSDKEvent( event );
}
return false;
}
protected:
bool PrintSDKEvent( IGameEvent * event ) // print Mod specific logs
{
//const char * name = event->GetName() + Q_strlen("sdk_"); // remove prefix
return false;
}
};
CSDKEventLog g_SDKEventLog;
//-----------------------------------------------------------------------------
// Singleton access
//-----------------------------------------------------------------------------
IGameSystem* GameLogSystem()
{
return &g_SDKEventLog;
}

View File

@ -0,0 +1,29 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "gameinterface.h"
#include "mapentities.h"
// -------------------------------------------------------------------------------------------- //
// Mod-specific CServerGameClients implementation.
// -------------------------------------------------------------------------------------------- //
void CServerGameClients::GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const
{
minplayers = 2; // Force multiplayer.
maxplayers = MAX_PLAYERS;
defaultMaxPlayers = 32;
}
// -------------------------------------------------------------------------------------------- //
// Mod-specific CServerGameDLL implementation.
// -------------------------------------------------------------------------------------------- //
void CServerGameDLL::LevelInit_ParseAllEntities( const char *pMapEntities )
{
}

View File

@ -0,0 +1,66 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Simple logical entity that counts up to a threshold value, then
// fires an output when reached.
//
//=============================================================================//
#include "cbase.h"
class CMyLogicalEntity : public CLogicalEntity
{
public:
DECLARE_CLASS( CMyLogicalEntity , CLogicalEntity );
DECLARE_DATADESC();
// Constructor
CMyLogicalEntity ( void ) : m_nCounter( 0 ) {}
// Input function
void InputTick( inputdata_t &inputData );
private:
int m_nThreshold; // Count at which to fire our output
int m_nCounter; // Internal counter
COutputEvent m_OnThreshold; // Output even when the counter reaches the threshold
};
LINK_ENTITY_TO_CLASS( my_logical_entity, CMyLogicalEntity );
// Start of our data description for the class
BEGIN_DATADESC( CMyLogicalEntity )
// For save/load
DEFINE_FIELD( m_nCounter, FIELD_INTEGER ),
// Links our member variable to our keyvalue from Hammer
DEFINE_KEYFIELD( m_nThreshold, FIELD_INTEGER, "threshold" ),
// Links our input name from Hammer to our input member function
DEFINE_INPUTFUNC( FIELD_VOID, "Tick", InputTick ),
// Links our output member to the output name used by Hammer
DEFINE_OUTPUT( m_OnThreshold, "OnThreshold" ),
END_DATADESC()
//-----------------------------------------------------------------------------
// Purpose: Handle a tick input from another entity
//-----------------------------------------------------------------------------
void CMyLogicalEntity ::InputTick( inputdata_t &inputData )
{
// Increment our counter
m_nCounter++;
// See if we've met or crossed our threshold value
if ( m_nCounter >= m_nThreshold )
{
// Fire an output event
m_OnThreshold.FireOutput( inputData.pActivator, this );
// Reset our counter
m_nCounter = 0;
}
}

View File

@ -0,0 +1,128 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Simple model entity that randomly moves and changes direction
// when activated.
//
//=============================================================================//
#include "cbase.h"
class CMyModelEntity : public CBaseAnimating
{
public:
DECLARE_CLASS( CMyModelEntity, CBaseAnimating );
DECLARE_DATADESC();
void Spawn( void );
void Precache( void );
void MoveThink( void );
// Input function
void InputToggle( inputdata_t &inputData );
private:
bool m_bActive;
float m_flNextChangeTime;
};
LINK_ENTITY_TO_CLASS( my_model_entity, CMyModelEntity );
// Start of our data description for the class
BEGIN_DATADESC( CMyModelEntity )
// Save/restore our active state
DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
DEFINE_FIELD( m_flNextChangeTime, FIELD_TIME ),
// Links our input name from Hammer to our input member function
DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),
// Declare our think function
DEFINE_THINKFUNC( MoveThink ),
END_DATADESC()
// Name of our entity's model
#define ENTITY_MODEL "models/gibs/airboat_broken_engine.mdl"
//-----------------------------------------------------------------------------
// Purpose: Precache assets used by the entity
//-----------------------------------------------------------------------------
void CMyModelEntity::Precache( void )
{
PrecacheModel( ENTITY_MODEL );
}
//-----------------------------------------------------------------------------
// Purpose: Sets up the entity's initial state
//-----------------------------------------------------------------------------
void CMyModelEntity::Spawn( void )
{
Precache();
SetModel( ENTITY_MODEL );
SetSolid( SOLID_BBOX );
UTIL_SetSize( this, -Vector(20,20,20), Vector(20,20,20) );
m_bActive = false;
}
//-----------------------------------------------------------------------------
// Purpose: Think function to randomly move the entity
//-----------------------------------------------------------------------------
void CMyModelEntity::MoveThink( void )
{
// See if we should change direction again
if ( m_flNextChangeTime < gpGlobals->curtime )
{
// Randomly take a new direction and speed
Vector vecNewVelocity = RandomVector( -64.0f, 64.0f );
SetAbsVelocity( vecNewVelocity );
// Randomly change it again within one to three seconds
m_flNextChangeTime = gpGlobals->curtime + random->RandomFloat( 1.0f, 3.0f );
}
// Snap our facing to where we're heading
Vector velFacing = GetAbsVelocity();
QAngle angFacing;
VectorAngles( velFacing, angFacing );
SetAbsAngles( angFacing );
// Think every 20Hz
SetNextThink( gpGlobals->curtime + 0.05f );
}
//-----------------------------------------------------------------------------
// Purpose: Toggle the movement of the entity
//-----------------------------------------------------------------------------
void CMyModelEntity::InputToggle( inputdata_t &inputData )
{
// Toggle our active state
if ( !m_bActive )
{
// Start thinking
SetThink( &CMyModelEntity::MoveThink );
SetNextThink( gpGlobals->curtime + 0.05f );
// Start flying
SetMoveType( MOVETYPE_FLY );
// Set our next time for changing our speed and direction
m_flNextChangeTime = gpGlobals->curtime;
m_bActive = true;
}
else
{
// Stop thinking
SetThink( NULL );
// Stop moving
SetAbsVelocity( vec3_origin );
SetMoveType( MOVETYPE_NONE );
m_bActive = false;
}
}

View File

@ -0,0 +1,366 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Player for HL1.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "sdk_player.h"
#include "sdk_gamerules.h"
#include "weapon_sdkbase.h"
#include "predicted_viewmodel.h"
#include "iservervehicle.h"
#include "viewport_panel_names.h"
extern int gEvilImpulse101;
ConVar sv_motd_unload_on_dismissal( "sv_motd_unload_on_dismissal", "0", 0, "If enabled, the MOTD contents will be unloaded when the player closes the MOTD." );
#define SDK_PLAYER_MODEL "models/player/terror.mdl"
// -------------------------------------------------------------------------------- //
// Player animation event. Sent to the client when a player fires, jumps, reloads, etc..
// -------------------------------------------------------------------------------- //
class CTEPlayerAnimEvent : public CBaseTempEntity
{
public:
DECLARE_CLASS( CTEPlayerAnimEvent, CBaseTempEntity );
DECLARE_SERVERCLASS();
CTEPlayerAnimEvent( const char *name ) : CBaseTempEntity( name )
{
}
CNetworkHandle( CBasePlayer, m_hPlayer );
CNetworkVar( int, m_iEvent );
CNetworkVar( int, m_nData );
};
#define THROWGRENADE_COUNTER_BITS 3
IMPLEMENT_SERVERCLASS_ST_NOBASE( CTEPlayerAnimEvent, DT_TEPlayerAnimEvent )
SendPropEHandle( SENDINFO( m_hPlayer ) ),
SendPropInt( SENDINFO( m_iEvent ), Q_log2( PLAYERANIMEVENT_COUNT ) + 1, SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_nData ), 32 )
END_SEND_TABLE()
static CTEPlayerAnimEvent g_TEPlayerAnimEvent( "PlayerAnimEvent" );
void TE_PlayerAnimEvent( CBasePlayer *pPlayer, PlayerAnimEvent_t event, int nData )
{
CPVSFilter filter( (const Vector&)pPlayer->EyePosition() );
g_TEPlayerAnimEvent.m_hPlayer = pPlayer;
g_TEPlayerAnimEvent.m_iEvent = event;
g_TEPlayerAnimEvent.m_nData = nData;
g_TEPlayerAnimEvent.Create( filter, 0 );
}
// -------------------------------------------------------------------------------- //
// Tables.
// -------------------------------------------------------------------------------- //
BEGIN_DATADESC( CSDKPlayer )
DEFINE_THINKFUNC( SDKPushawayThink ),
END_DATADESC()
LINK_ENTITY_TO_CLASS( player, CSDKPlayer );
PRECACHE_REGISTER(player);
BEGIN_SEND_TABLE_NOBASE( CSDKPlayer, DT_SDKLocalPlayerExclusive )
SendPropInt( SENDINFO( m_iShotsFired ), 8, SPROP_UNSIGNED ),
END_SEND_TABLE()
IMPLEMENT_SERVERCLASS_ST( CSDKPlayer, DT_SDKPlayer )
SendPropExclude( "DT_BaseAnimating", "m_flPoseParameter" ),
SendPropExclude( "DT_BaseAnimating", "m_flPlaybackRate" ),
SendPropExclude( "DT_BaseAnimating", "m_nSequence" ),
SendPropExclude( "DT_BaseEntity", "m_angRotation" ),
SendPropExclude( "DT_BaseAnimatingOverlay", "overlay_vars" ),
// playeranimstate and clientside animation takes care of these on the client
SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ),
SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ),
// Data that only gets sent to the local player.
SendPropDataTable( "sdklocaldata", 0, &REFERENCE_SEND_TABLE(DT_SDKLocalPlayerExclusive), SendProxy_SendLocalDataTable ),
SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 11 ),
SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 11 ),
SendPropEHandle( SENDINFO( m_hRagdoll ) ),
SendPropInt( SENDINFO( m_iThrowGrenadeCounter ), THROWGRENADE_COUNTER_BITS, SPROP_UNSIGNED ),
END_SEND_TABLE()
class CSDKRagdoll : public CBaseAnimatingOverlay
{
public:
DECLARE_CLASS( CSDKRagdoll, CBaseAnimatingOverlay );
DECLARE_SERVERCLASS();
// Transmit ragdolls to everyone.
virtual int UpdateTransmitState()
{
return SetTransmitState( FL_EDICT_ALWAYS );
}
public:
// In case the client has the player entity, we transmit the player index.
// In case the client doesn't have it, we transmit the player's model index, origin, and angles
// so they can create a ragdoll in the right place.
CNetworkHandle( CBaseEntity, m_hPlayer ); // networked entity handle
CNetworkVector( m_vecRagdollVelocity );
CNetworkVector( m_vecRagdollOrigin );
};
LINK_ENTITY_TO_CLASS( sdk_ragdoll, CSDKRagdoll );
IMPLEMENT_SERVERCLASS_ST_NOBASE( CSDKRagdoll, DT_SDKRagdoll )
SendPropVector( SENDINFO(m_vecRagdollOrigin), -1, SPROP_COORD ),
SendPropEHandle( SENDINFO( m_hPlayer ) ),
SendPropModelIndex( SENDINFO( m_nModelIndex ) ),
SendPropInt ( SENDINFO(m_nForceBone), 8, 0 ),
SendPropVector ( SENDINFO(m_vecForce), -1, SPROP_NOSCALE ),
SendPropVector( SENDINFO( m_vecRagdollVelocity ) )
END_SEND_TABLE()
// -------------------------------------------------------------------------------- //
void cc_CreatePredictionError_f()
{
CBaseEntity *pEnt = CBaseEntity::Instance( 1 );
pEnt->SetAbsOrigin( pEnt->GetAbsOrigin() + Vector( 63, 0, 0 ) );
}
ConCommand cc_CreatePredictionError( "CreatePredictionError", cc_CreatePredictionError_f, "Create a prediction error", FCVAR_CHEAT );
CSDKPlayer::CSDKPlayer()
{
m_PlayerAnimState = CreatePlayerAnimState( this, this, LEGANIM_9WAY, true );
UseClientSideAnimation();
m_angEyeAngles.Init();
SetViewOffset( SDK_PLAYER_VIEW_OFFSET );
m_iThrowGrenadeCounter = 0;
}
CSDKPlayer::~CSDKPlayer()
{
m_PlayerAnimState->Release();
}
CSDKPlayer *CSDKPlayer::CreatePlayer( const char *className, edict_t *ed )
{
CSDKPlayer::s_PlayerEdict = ed;
return (CSDKPlayer*)CreateEntityByName( className );
}
void CSDKPlayer::LeaveVehicle( const Vector &vecExitPoint, const QAngle &vecExitAngles )
{
BaseClass::LeaveVehicle( vecExitPoint, vecExitAngles );
//teleport physics shadow too
// Vector newPos = GetAbsOrigin();
// QAngle newAng = GetAbsAngles();
// Teleport( &newPos, &newAng, &vec3_origin );
}
void CSDKPlayer::PreThink(void)
{
// Riding a vehicle?
if ( IsInAVehicle() )
{
// make sure we update the client, check for timed damage and update suit even if we are in a vehicle
UpdateClientData();
CheckTimeBasedDamage();
// Allow the suit to recharge when in the vehicle.
CheckSuitUpdate();
WaterMove();
return;
}
BaseClass::PreThink();
}
void CSDKPlayer::PostThink()
{
BaseClass::PostThink();
QAngle angles = GetLocalAngles();
angles[PITCH] = 0;
SetLocalAngles( angles );
// Store the eye angles pitch so the client can compute its animation state correctly.
m_angEyeAngles = EyeAngles();
m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );
}
void CSDKPlayer::Precache()
{
PrecacheModel( SDK_PLAYER_MODEL );
BaseClass::Precache();
}
void CSDKPlayer::Spawn()
{
SetModel( SDK_PLAYER_MODEL );
SetMoveType( MOVETYPE_WALK );
RemoveSolidFlags( FSOLID_NOT_SOLID );
m_hRagdoll = NULL;
BaseClass::Spawn();
}
void CSDKPlayer::InitialSpawn( void )
{
BaseClass::InitialSpawn();
const ConVar *hostname = cvar->FindVar( "hostname" );
const char *title = (hostname) ? hostname->GetString() : "MESSAGE OF THE DAY";
// open info panel on client showing MOTD:
KeyValues *data = new KeyValues("data");
data->SetString( "title", title ); // info panel title
data->SetString( "type", "1" ); // show userdata from stringtable entry
data->SetString( "msg", "motd" ); // use this stringtable entry
data->SetInt( "cmd", TEXTWINDOW_CMD_IMPULSE101 );// exec this command if panel closed
data->SetBool( "unload", sv_motd_unload_on_dismissal.GetBool() );
ShowViewPortPanel( PANEL_INFO, true, data );
data->deleteThis();
}
void CSDKPlayer::Event_Killed( const CTakeDamageInfo &info )
{
// Note: since we're dead, it won't draw us on the client, but we don't set EF_NODRAW
// because we still want to transmit to the clients in our PVS.
BaseClass::Event_Killed( info );
CreateRagdollEntity();
}
void CSDKPlayer::CreateRagdollEntity()
{
// If we already have a ragdoll, don't make another one.
CSDKRagdoll *pRagdoll = dynamic_cast< CSDKRagdoll* >( m_hRagdoll.Get() );
if ( !pRagdoll )
{
// create a new one
pRagdoll = dynamic_cast< CSDKRagdoll* >( CreateEntityByName( "sdk_ragdoll" ) );
}
if ( pRagdoll )
{
pRagdoll->m_hPlayer = this;
pRagdoll->m_vecRagdollOrigin = GetAbsOrigin();
pRagdoll->m_vecRagdollVelocity = GetAbsVelocity();
pRagdoll->m_nModelIndex = m_nModelIndex;
pRagdoll->m_nForceBone = m_nForceBone;
pRagdoll->m_vecForce = Vector(0,0,0);
}
// ragdolls will be removed on round restart automatically
m_hRagdoll = pRagdoll;
}
void CSDKPlayer::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
{
if ( event == PLAYERANIMEVENT_THROW_GRENADE )
{
// Grenade throwing has to synchronize exactly with the player's grenade weapon going away,
// and events get delayed a bit, so we let CCSPlayerAnimState pickup the change to this
// variable.
m_iThrowGrenadeCounter = (m_iThrowGrenadeCounter+1) % (1<<THROWGRENADE_COUNTER_BITS);
}
else
{
m_PlayerAnimState->DoAnimationEvent( event, nData );
TE_PlayerAnimEvent( this, event, nData ); // Send to any clients who can see this guy.
}
}
CWeaponSDKBase* CSDKPlayer::GetActiveSDKWeapon() const
{
return dynamic_cast< CWeaponSDKBase* >( GetActiveWeapon() );
}
void CSDKPlayer::CreateViewModel( int index /*=0*/ )
{
Assert( index >= 0 && index < MAX_VIEWMODELS );
if ( GetViewModel( index ) )
return;
CPredictedViewModel *vm = ( CPredictedViewModel * )CreateEntityByName( "predicted_viewmodel" );
if ( vm )
{
vm->SetAbsOrigin( GetAbsOrigin() );
vm->SetOwner( this );
vm->SetIndex( index );
DispatchSpawn( vm );
vm->FollowEntity( this, false );
m_hViewModel.Set( index, vm );
}
}
void CSDKPlayer::CheatImpulseCommands( int iImpulse )
{
if ( iImpulse != 101 )
{
BaseClass::CheatImpulseCommands( iImpulse );
return ;
}
gEvilImpulse101 = true;
EquipSuit();
GiveNamedItem( "weapon_mp5" );
GiveNamedItem( "weapon_grenade" );
GiveNamedItem( "weapon_shotgun" );
// Give the player everything!
GiveAmmo( 90, AMMO_BULLETS );
GiveAmmo( 3, AMMO_GRENADE );
if ( GetHealth() < 100 )
{
TakeHealth( 25, DMG_GENERIC );
}
gEvilImpulse101 = false;
}
void CSDKPlayer::FlashlightTurnOn( void )
{
AddEffects( EF_DIMLIGHT );
}
void CSDKPlayer::FlashlightTurnOff( void )
{
RemoveEffects( EF_DIMLIGHT );
}
int CSDKPlayer::FlashlightIsOn( void )
{
return IsEffectActive( EF_DIMLIGHT );
}

View File

@ -0,0 +1,101 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Player for SDK Game
//
// $NoKeywords: $
//=============================================================================//
#ifndef SDK_PLAYER_H
#define SDK_PLAYER_H
#pragma once
#include "player.h"
#include "server_class.h"
#include "sdk_playeranimstate.h"
#include "sdk_shareddefs.h"
//=============================================================================
// >> SDK Game player
//=============================================================================
class CSDKPlayer : public CBasePlayer, public ISDKPlayerAnimStateHelpers
{
public:
DECLARE_CLASS( CSDKPlayer, CBasePlayer );
DECLARE_SERVERCLASS();
DECLARE_PREDICTABLE();
DECLARE_DATADESC();
CSDKPlayer();
~CSDKPlayer();
static CSDKPlayer *CreatePlayer( const char *className, edict_t *ed );
static CSDKPlayer* Instance( int iEnt );
// This passes the event to the client's and server's CPlayerAnimState.
void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
virtual void FlashlightTurnOn( void );
virtual void FlashlightTurnOff( void );
virtual int FlashlightIsOn( void );
virtual void PreThink();
virtual void PostThink();
virtual void Spawn();
virtual void InitialSpawn();
virtual void Precache();
virtual void Event_Killed( const CTakeDamageInfo &info );
virtual void LeaveVehicle( const Vector &vecExitPoint, const QAngle &vecExitAngles );
CWeaponSDKBase* GetActiveSDKWeapon() const;
virtual void CreateViewModel( int viewmodelindex = 0 );
virtual void CheatImpulseCommands( int iImpulse );
CNetworkVar( int, m_iThrowGrenadeCounter ); // used to trigger grenade throw animations.
CNetworkQAngle( m_angEyeAngles ); // Copied from EyeAngles() so we can send it to the client.
CNetworkVar( int, m_iShotsFired ); // number of shots fired recently
// Tracks our ragdoll entity.
CNetworkHandle( CBaseEntity, m_hRagdoll ); // networked entity handle
// In shared code.
public:
// ISDKPlayerAnimState overrides.
virtual CWeaponSDKBase* SDKAnim_GetActiveWeapon();
virtual bool SDKAnim_CanMove();
void FireBullet(
Vector vecSrc,
const QAngle &shootAngles,
float vecSpread,
int iDamage,
int iBulletType,
CBaseEntity *pevAttacker,
bool bDoEffects,
float x,
float y );
private:
void CreateRagdollEntity();
ISDKPlayerAnimState *m_PlayerAnimState;
};
inline CSDKPlayer *ToSDKPlayer( CBaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
#ifdef _DEBUG
Assert( dynamic_cast<CSDKPlayer*>( pEntity ) != 0 );
#endif
return static_cast< CSDKPlayer* >( pEntity );
}
#endif // SDK_PLAYER_H

View File

@ -0,0 +1,89 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "player_command.h"
#include "igamemovement.h"
#include "in_buttons.h"
#include "ipredictionsystem.h"
#include "sdk_player.h"
#include "iservervehicle.h"
static CMoveData g_MoveData;
CMoveData *g_pMoveData = &g_MoveData;
IPredictionSystem *IPredictionSystem::g_pPredictionSystems = NULL;
//-----------------------------------------------------------------------------
// Sets up the move data for TF2
//-----------------------------------------------------------------------------
class CSDKPlayerMove : public CPlayerMove
{
DECLARE_CLASS( CSDKPlayerMove, CPlayerMove );
public:
virtual void StartCommand( CBasePlayer *player, CUserCmd *cmd );
virtual void SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move );
virtual void FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move );
};
// PlayerMove Interface
static CSDKPlayerMove g_PlayerMove;
//-----------------------------------------------------------------------------
// Singleton accessor
//-----------------------------------------------------------------------------
CPlayerMove *PlayerMove()
{
return &g_PlayerMove;
}
//-----------------------------------------------------------------------------
// Main setup, finish
//-----------------------------------------------------------------------------
void CSDKPlayerMove::StartCommand( CBasePlayer *player, CUserCmd *cmd )
{
BaseClass::StartCommand( player, cmd );
}
//-----------------------------------------------------------------------------
// Purpose: This is called pre player movement and copies all the data necessary
// from the player for movement. (Server-side, the client-side version
// of this code can be found in prediction.cpp.)
//-----------------------------------------------------------------------------
void CSDKPlayerMove::SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move )
{
BaseClass::SetupMove( player, ucmd, pHelper, move );
IServerVehicle *pVehicle = player->GetVehicle();
if (pVehicle && gpGlobals->frametime != 0)
{
pVehicle->SetupMove( player, ucmd, pHelper, move );
}
}
//-----------------------------------------------------------------------------
// Purpose: This is called post player movement to copy back all data that
// movement could have modified and that is necessary for future
// movement. (Server-side, the client-side version of this code can
// be found in prediction.cpp.)
//-----------------------------------------------------------------------------
void CSDKPlayerMove::FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move )
{
// Call the default FinishMove code.
BaseClass::FinishMove( player, ucmd, move );
IServerVehicle *pVehicle = player->GetVehicle();
if (pVehicle && gpGlobals->frametime != 0)
{
pVehicle->FinishMove( player, ucmd, move );
}
}

View File

@ -0,0 +1,40 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Team management class. Contains all the details for a specific team
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "sdk_team.h"
#include "entitylist.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// Datatable
IMPLEMENT_SERVERCLASS_ST(CSDKTeam, DT_SDKTeam)
END_SEND_TABLE()
LINK_ENTITY_TO_CLASS( sdk_team_manager, CSDKTeam );
//-----------------------------------------------------------------------------
// Purpose: Get a pointer to the specified TF team manager
//-----------------------------------------------------------------------------
CSDKTeam *GetGlobalSDKTeam( int iIndex )
{
return (CSDKTeam*)GetGlobalTeam( iIndex );
}
//-----------------------------------------------------------------------------
// Purpose: Needed because this is an entity, but should never be used
//-----------------------------------------------------------------------------
void CSDKTeam::Init( const char *pName, int iNumber )
{
BaseClass::Init( pName, iNumber );
// Only detect changes every half-second.
NetworkProp()->SetUpdateInterval( 0.75f );
}

View File

@ -0,0 +1,38 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Team management class. Contains all the details for a specific team
//
// $NoKeywords: $
//=============================================================================//
#ifndef SDK_TEAM_H
#define SDK_TEAM_H
#ifdef _WIN32
#pragma once
#endif
#include "utlvector.h"
#include "team.h"
//-----------------------------------------------------------------------------
// Purpose: Team Manager
//-----------------------------------------------------------------------------
class CSDKTeam : public CTeam
{
DECLARE_CLASS( CSDKTeam, CTeam );
DECLARE_SERVERCLASS();
public:
// Initialization
virtual void Init( const char *pName, int iNumber );
};
extern CSDKTeam *GetGlobalSDKTeam( int iIndex );
#endif // TF_TEAM_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,98 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "basetempentity.h"
#define NUM_BULLET_SEED_BITS 8
//-----------------------------------------------------------------------------
// Purpose: Display's a blood sprite
//-----------------------------------------------------------------------------
class CTEFireBullets : public CBaseTempEntity
{
public:
DECLARE_CLASS( CTEFireBullets, CBaseTempEntity );
DECLARE_SERVERCLASS();
CTEFireBullets( const char *name );
virtual ~CTEFireBullets( void );
public:
CNetworkVar( int, m_iPlayer ); // player who fired
CNetworkVector( m_vecOrigin ); // firing origin
CNetworkQAngle( m_vecAngles ); // firing angle
CNetworkVar( int, m_iWeaponID ); // weapon ID
CNetworkVar( int, m_iMode ); // primary or secondary fire ?
CNetworkVar( int, m_iSeed ); // shared random seed
CNetworkVar( float, m_flSpread ); // bullets spread
};
//-----------------------------------------------------------------------------
// Purpose:
// Input : *name -
//-----------------------------------------------------------------------------
CTEFireBullets::CTEFireBullets( const char *name ) :
CBaseTempEntity( name )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTEFireBullets::~CTEFireBullets( void )
{
}
IMPLEMENT_SERVERCLASS_ST_NOBASE(CTEFireBullets, DT_TEFireBullets)
SendPropVector( SENDINFO(m_vecOrigin), -1, SPROP_COORD ),
SendPropAngle( SENDINFO_VECTORELEM( m_vecAngles, 0 ), 13, 0 ),
SendPropAngle( SENDINFO_VECTORELEM( m_vecAngles, 1 ), 13, 0 ),
SendPropInt( SENDINFO( m_iWeaponID ), 5, SPROP_UNSIGNED ), // max 31 weapons
SendPropInt( SENDINFO( m_iMode ), 1, SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_iSeed ), NUM_BULLET_SEED_BITS, SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_iPlayer ), 6, SPROP_UNSIGNED ), // max 64 players, see MAX_PLAYERS
SendPropFloat( SENDINFO( m_flSpread ), 10, 0, 0, 1 ),
END_SEND_TABLE()
// Singleton
static CTEFireBullets g_TEFireBullets( "Shotgun Shot" );
void TE_FireBullets(
int iPlayerIndex,
const Vector &vOrigin,
const QAngle &vAngles,
int iWeaponID,
int iMode,
int iSeed,
float flSpread )
{
CPASFilter filter( vOrigin );
filter.UsePredictionRules();
g_TEFireBullets.m_iPlayer = iPlayerIndex-1;
g_TEFireBullets.m_vecOrigin = vOrigin;
g_TEFireBullets.m_vecAngles = vAngles;
g_TEFireBullets.m_iSeed = iSeed;
g_TEFireBullets.m_flSpread = flSpread;
g_TEFireBullets.m_iMode = iMode;
g_TEFireBullets.m_iWeaponID = iWeaponID;
Assert( iSeed < (1 << NUM_BULLET_SEED_BITS) );
g_TEFireBullets.Create( filter, 0 );
}

View File

@ -0,0 +1,24 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef TE_FIREBULLETS_H
#define TE_FIREBULLETS_H
#ifdef _WIN32
#pragma once
#endif
void TE_FireBullets(
int iPlayerIndex,
const Vector &vOrigin,
const QAngle &vAngles,
int iWeaponID,
int iMode,
int iSeed,
float flSpread
);
#endif // TE_FIREBULLETS_H