Files
HL2Overcharged/game/server/allcustom/weapon_teleport.cpp
2025-05-21 21:20:08 +03:00

219 lines
5.8 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Pocket Teleport
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "NPCEvent.h"
#include "basehlcombatweapon.h"
#include "basecombatcharacter.h"
#include "AI_BaseNPC.h"
#include "player.h"
#include "gamerules.h"
#include "in_buttons.h"
#include "soundent.h"
#include "game.h"
#include "vstdlib/random.h"
#include "gamestats.h"
//#include "particle_parse.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar aa_wpn_teleport_target( "aa_wpn_teleport_target", "teleport_special", FCVAR_REPLICATED, "Teleport to the named entity in cvar. Usualy made to work with info_teleport_destination" );
//-----------------------------------------------------------------------------
// CWeaponTeleport
//-----------------------------------------------------------------------------
class CWeaponTeleport : public CBaseHLCombatWeapon
{
DECLARE_DATADESC();
public:
DECLARE_CLASS( CWeaponTeleport, CBaseHLCombatWeapon );
CWeaponTeleport(void);
DECLARE_SERVERCLASS();
void Precache( void );
void ItemPostFrame( void );
void PrimaryAttack( void );
void DelayedAttack( void );
string_t m_iLandmark; // teleport
protected:
float m_flDelayedFire;
bool m_bShotDelayed;
DECLARE_ACTTABLE();
};
IMPLEMENT_SERVERCLASS_ST(CWeaponTeleport, DT_WeaponTeleport)
END_SEND_TABLE()
LINK_ENTITY_TO_CLASS( weapon_Teleport, CWeaponTeleport );
PRECACHE_WEAPON_REGISTER( weapon_Teleport );
BEGIN_DATADESC( CWeaponTeleport )
DEFINE_KEYFIELD( m_iLandmark, FIELD_STRING, "landmark" ), // teleport
END_DATADESC()
acttable_t CWeaponTeleport::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false }, // Light Kill : MP animstate for singleplayer
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SLAM, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_THROW, true },
{ ACT_MELEE_ATTACK1, ACT_MELEE_ATTACK_SWING, true },
{ ACT_IDLE, ACT_IDLE_ANGRY_MELEE, false },
{ ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_MELEE, false },
{ ACT_IDLE_RELAXED, ACT_IDLE, false }, // L1ght 15 : Anims update
{ ACT_RUN_RELAXED, ACT_RUN, false },
{ ACT_WALK_RELAXED, ACT_WALK, false },
};
IMPLEMENT_ACTTABLE(CWeaponTeleport);
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeaponTeleport::CWeaponTeleport( void )
{
}
void CWeaponTeleport::Precache( void )
{
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CWeaponTeleport::PrimaryAttack( void )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
if (IsNearWall() || GetOwnerIsRunning())
{
return;
}
if ( m_bShotDelayed )
return;
// Cannot fire underwater
if ( GetOwner() && GetOwner()->GetWaterLevel() == 3 )
{
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f;
return;
}
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
pOwner->SetAnimation( PLAYER_ATTACK1 );
m_bShotDelayed = true;
m_flDelayedFire = gpGlobals->curtime + 3.0f;
m_flNextPrimaryAttack = gpGlobals->curtime + GetViewModelSequenceDuration();
}
void CWeaponTeleport::ItemPostFrame( void )
{
// See if we need to fire off our secondary round
if ( m_bShotDelayed && gpGlobals->curtime > m_flDelayedFire )
{
DelayedAttack();
}
BaseClass::ItemPostFrame();
}
void CWeaponTeleport::DelayedAttack( void )
{
m_bShotDelayed = false;
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
CBaseEntity *pentTarget = NULL;
// The activator and caller are the same
pentTarget = gEntList.FindEntityByName( pentTarget, /*m_target*/ /*"tp_dark_room"*/ aa_wpn_teleport_target.GetString(), NULL, pOwner, pOwner );
if (!pentTarget)
{
//ClientPrint( pOwner, HUD_PRINTCENTER, "No teleports found" );
return;
}
//ClientPrint( pOwner, HUD_PRINTCENTER, "Teleport Found" );
CBaseEntity *pentLandmark = NULL;
Vector vecLandmarkOffset(0, 0, 0);
if (m_iLandmark != NULL_STRING)
{
// The activator and caller are the same
pentLandmark = gEntList.FindEntityByName(pentLandmark, m_iLandmark, NULL, pOwner, pOwner );
if (pentLandmark)
{
vecLandmarkOffset = pOwner->GetAbsOrigin() - pentLandmark->GetAbsOrigin();
}
}
pOwner->SetGroundEntity( NULL );
Vector tmp = pentTarget->GetAbsOrigin();
if (!pentLandmark && pOwner->IsPlayer())
{
// make origin adjustments in case the teleportee is a player. (origin in center, not at feet)
tmp.z -= pOwner->WorldAlignMins().z;
}
//
// Only modify the toucher's angles and zero their velocity if no landmark was specified.
//
const QAngle *pAngles = NULL;
Vector *pVelocity = NULL;
if (!pentLandmark && !HasSpawnFlags(0x20) ) //SF_TELEPORT_PRESERVE_ANGLES) )
{
pAngles = &pentTarget->GetAbsAngles();
pVelocity = NULL; //BUGBUG - This does not set the player's velocity to zero!!!
}
tmp += vecLandmarkOffset;
pOwner->Teleport( &tmp, pAngles, pVelocity );
//==
WeaponSound( SINGLE );
m_iClip1 = m_iClip1 - 1;
color32 ShockEffect = { 255,255,255,255 };
UTIL_ScreenFade( pOwner, ShockEffect, 0.2f, 1.0f, FFADE_IN );
}