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:
472
game/server/sdk/sdk_bot_temp.cpp
Normal file
472
game/server/sdk/sdk_bot_temp.cpp
Normal 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 );
|
||||
}
|
||||
|
||||
|
21
game/server/sdk/sdk_bot_temp.h
Normal file
21
game/server/sdk/sdk_bot_temp.h
Normal 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
|
79
game/server/sdk/sdk_brushentity.cpp
Normal file
79
game/server/sdk/sdk_brushentity.cpp
Normal 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 );
|
||||
}
|
164
game/server/sdk/sdk_client.cpp
Normal file
164
game/server/sdk/sdk_client.cpp
Normal 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" );
|
||||
}
|
46
game/server/sdk/sdk_env_message.cpp
Normal file
46
game/server/sdk/sdk_env_message.cpp
Normal 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();
|
||||
}
|
104
game/server/sdk/sdk_env_sparkler.cpp
Normal file
104
game/server/sdk/sdk_env_sparkler.cpp
Normal 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 );
|
||||
}
|
55
game/server/sdk/sdk_eventlog.cpp
Normal file
55
game/server/sdk/sdk_eventlog.cpp
Normal 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;
|
||||
}
|
||||
|
29
game/server/sdk/sdk_gameinterface.cpp
Normal file
29
game/server/sdk/sdk_gameinterface.cpp
Normal 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 )
|
||||
{
|
||||
}
|
66
game/server/sdk/sdk_logicalentity.cpp
Normal file
66
game/server/sdk/sdk_logicalentity.cpp
Normal 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;
|
||||
}
|
||||
}
|
128
game/server/sdk/sdk_modelentity.cpp
Normal file
128
game/server/sdk/sdk_modelentity.cpp
Normal 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;
|
||||
}
|
||||
}
|
366
game/server/sdk/sdk_player.cpp
Normal file
366
game/server/sdk/sdk_player.cpp
Normal 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 );
|
||||
}
|
101
game/server/sdk/sdk_player.h
Normal file
101
game/server/sdk/sdk_player.h
Normal 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
|
89
game/server/sdk/sdk_playermove.cpp
Normal file
89
game/server/sdk/sdk_playermove.cpp
Normal 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 );
|
||||
}
|
||||
}
|
40
game/server/sdk/sdk_team.cpp
Normal file
40
game/server/sdk/sdk_team.cpp
Normal 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 );
|
||||
}
|
||||
|
38
game/server/sdk/sdk_team.h
Normal file
38
game/server/sdk/sdk_team.h
Normal 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
|
1584
game/server/sdk/sdk_vehicle_jeep.cpp
Normal file
1584
game/server/sdk/sdk_vehicle_jeep.cpp
Normal file
File diff suppressed because it is too large
Load Diff
98
game/server/sdk/te_firebullets.cpp
Normal file
98
game/server/sdk/te_firebullets.cpp
Normal 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 );
|
||||
}
|
24
game/server/sdk/te_firebullets.h
Normal file
24
game/server/sdk/te_firebullets.h
Normal 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
|
Reference in New Issue
Block a user