1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Teleports a named entity to a given position and restores
// it's physics state
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "in_buttons.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define SF_TELEPORT_TO_SPAWN_POS 0x00000001
#define SF_TELEPORT_INTO_DUCK 0x00000002 ///< episodic only: player should be ducked after this teleport
class CPointTeleport : public CBaseEntity
{
DECLARE_CLASS( CPointTeleport, CBaseEntity );
public:
void Activate( void );
void InputTeleport( inputdata_t &inputdata );
private:
bool EntityMayTeleport( CBaseEntity *pTarget );
Vector m_vSaveOrigin;
QAngle m_vSaveAngles;
DECLARE_DATADESC();
};
LINK_ENTITY_TO_CLASS( point_teleport, CPointTeleport );
BEGIN_DATADESC( CPointTeleport )
DEFINE_FIELD( m_vSaveOrigin, FIELD_VECTOR ),
DEFINE_FIELD( m_vSaveAngles, FIELD_VECTOR ),
DEFINE_INPUTFUNC( FIELD_VOID, "Teleport", InputTeleport ),
END_DATADESC()
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pTarget -
// Output : Returns true if the entity may be teleported
//-----------------------------------------------------------------------------
bool CPointTeleport::EntityMayTeleport( CBaseEntity *pTarget )
{
if ( pTarget->GetMoveParent() != NULL )
{
// Passengers in a vehicle are allowed to teleport; their behavior handles it
CBaseCombatCharacter *pBCC = pTarget->MyCombatCharacterPointer();
if ( pBCC == NULL || ( pBCC != NULL && pBCC->IsInAVehicle() == false ) )
return false;
}
return true;
}
//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CPointTeleport::Activate( void )
{
// Start with our origin point
m_vSaveOrigin = GetAbsOrigin();
m_vSaveAngles = GetAbsAngles();
// Save off the spawn position of the target if instructed to do so
if ( m_spawnflags & SF_TELEPORT_TO_SPAWN_POS )
{
CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, m_target );
if ( pTarget )
{
// If teleport object is in a movement hierarchy, remove it first
if ( EntityMayTeleport( pTarget ) )
{
// Save the points
m_vSaveOrigin = pTarget->GetAbsOrigin();
m_vSaveAngles = pTarget->GetAbsAngles();
}
else
{
Warning("ERROR: (%s) can't teleport object (%s) as it has a parent (%s)!\n",GetDebugName(),pTarget->GetDebugName(),pTarget->GetMoveParent()->GetDebugName());
BaseClass::Activate();
return;
}
}
else
{
Warning("ERROR: (%s) target '%s' not found. Deleting.\n", GetDebugName(), STRING(m_target));
UTIL_Remove( this );
return;
}
}
BaseClass::Activate();
}
//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CPointTeleport::InputTeleport( inputdata_t &inputdata )
{
// Attempt to find the entity in question
CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, m_target, this, inputdata.pActivator, inputdata.pCaller );
if ( pTarget == NULL )
return;
// If teleport object is in a movement hierarchy, remove it first
if ( EntityMayTeleport( pTarget ) == false )
{
Warning("ERROR: (%s) can't teleport object (%s) as it has a parent (%s)!\n",GetDebugName(),pTarget->GetDebugName(),pTarget->GetMoveParent()->GetDebugName());
return;
}
// in episodic, we have a special spawn flag that forces Gordon into a duck
#ifdef HL2_EPISODIC
if ( (m_spawnflags & SF_TELEPORT_INTO_DUCK) && pTarget->IsPlayer() )
{
CBasePlayer *pPlayer = ToBasePlayer( pTarget );
if ( pPlayer != NULL )
{
pPlayer->m_nButtons |= IN_DUCK;
pPlayer->AddFlag( FL_DUCKING );
pPlayer->m_Local.m_bDucked = true;
pPlayer->m_Local.m_bDucking = true;
pPlayer->m_Local.m_flDucktime = 0.0f;
pPlayer->SetViewOffset( VEC_DUCK_VIEW_SCALED( pPlayer ) );
pPlayer->SetCollisionBounds( VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX );
}
}
#endif
pTarget->Teleport( &m_vSaveOrigin, &m_vSaveAngles, NULL );
}
|