source-engine/game/server/stargate/ring_transporter.cpp
Deploy Bot 44cb9a4837 StargateTC port — initial integration into nillerusr/source-engine
P1: Source files
- Copy 9 server stargate files + sg_constants.h + sg_weapons.cpp from
  StargateTCSource/sourcecode/ into game/server/stargate/ and
  game/shared/stargate/.
- Add $Folder "Stargate" block to server_hl2mp.vpc and client_hl2mp.vpc.
- Extend $AdditionalIncludeDirectories with stargate paths.

P2/P3: Gamerules + player patches
- hl2mp_gamerules.h: add TEAM_JAFFA=4, TEAM_UNAS=5 to team enum.
- hl2mp_gamerules.cpp: preserve 5 Stargate spawn classnames in
  s_PreserveEnts[]; rename teams to Tau'ri/Goa'uld/Jaffa/Unas;
  rename game description to "StargateTC"/"StargateTC Teamplay".
- hl2mp_player.cpp: EntSelectSpawnPoint now searches Stargate spawn
  classnames first (torri/goauld/marine/unas) with per-team fallback
  chain to combine/rebel/deathmatch.

Build: 0 errors. Server.dll 13.19MB, client.dll 9.85MB.
Runtime test: window title "StargateTC", live game launches,
HEALTH 100 HUD renders, HL2MP MOTD shown, sky/world geometry renders.
Response system loads 217 rules without crashing (was the original
Mapbase+VS2022 heap-corruption point).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 14:08:44 +01:00

70 lines
2.1 KiB
C++

//============= Copyright © StargateTC Source Team =============================
//
// ring_transporter — Goa'uld ring teleport pad. A player stepping onto the pad
// gets sent to the paired pad after a short delay. Pairs are matched via the
// `target` keyvalue (each ring names the other).
//
//==============================================================================
#include "cbase.h"
#include "stargate/sg_constants.h"
class CRingTransporter : public CBaseEntity
{
public:
DECLARE_CLASS( CRingTransporter, CBaseEntity );
DECLARE_DATADESC();
void Spawn() override;
void TouchTransport( CBaseEntity *pOther );
void DoTransport();
void Cooldown() { m_flNextActive = 0; SetNextThink( TICK_NEVER_THINK ); }
private:
EHANDLE m_hPending;
float m_flNextActive { 0.0f };
};
LINK_ENTITY_TO_CLASS( ring_transporter, CRingTransporter );
BEGIN_DATADESC( CRingTransporter )
DEFINE_FIELD( m_hPending, FIELD_EHANDLE ),
DEFINE_FIELD( m_flNextActive, FIELD_TIME ),
DEFINE_ENTITYFUNC( TouchTransport ),
DEFINE_THINKFUNC( DoTransport ),
END_DATADESC()
void CRingTransporter::Spawn()
{
BaseClass::Spawn();
SetSolid( SOLID_BBOX );
SetCollisionGroup( COLLISION_GROUP_NONE );
UTIL_SetSize( this, Vector(-48,-48,0), Vector(48,48,16) );
SetTouch( &CRingTransporter::TouchTransport );
}
void CRingTransporter::TouchTransport( CBaseEntity *pOther )
{
if ( !pOther || !pOther->IsPlayer() ) return;
if ( gpGlobals->curtime < m_flNextActive ) return;
m_hPending = pOther;
m_flNextActive = gpGlobals->curtime + StargateTC::RING_COOLDOWN;
SetThink( &CRingTransporter::DoTransport );
SetNextThink( gpGlobals->curtime + StargateTC::RING_TRAVEL_TIME );
// TODO: spawn ring VFX + sound here.
}
void CRingTransporter::DoTransport()
{
CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, m_target );
CBaseEntity *pPlayer = m_hPending;
if ( pTarget && pPlayer )
{
pPlayer->Teleport( &pTarget->GetAbsOrigin(), NULL, NULL );
}
m_hPending = NULL;
SetThink( &CRingTransporter::Cooldown );
SetNextThink( gpGlobals->curtime + StargateTC::RING_COOLDOWN );
}