diff --git a/dlls/gearbox/displacer.cpp b/dlls/gearbox/displacer.cpp index d134de53ee..0f2d03f6fe 100644 --- a/dlls/gearbox/displacer.cpp +++ b/dlls/gearbox/displacer.cpp @@ -572,7 +572,7 @@ void CDisplacer::Teleport( void ) if( pTarget ) tmp = pTarget->pev->origin; - if( pTarget && /*HACK*/( tmp != Vector( 0, 0, 0 )/*HACK*/ ) ) + if( pTarget ) { if( (m_pPlayer->m_afPhysicsFlags & PFLAG_ONROPE) ) m_pPlayer->LetGoRope(); @@ -592,6 +592,7 @@ void CDisplacer::Teleport( void ) tmp.z+=37; m_pPlayer->pev->flags &= ~FL_ONGROUND; + m_pPlayer->m_DisplacerReturn = m_pPlayer->pev->origin; UTIL_SetOrigin(m_pPlayer->pev, tmp); diff --git a/dlls/gearbox/gearbox_triggers.cpp b/dlls/gearbox/gearbox_triggers.cpp index a2a196dbc0..43bd97541b 100644 --- a/dlls/gearbox/gearbox_triggers.cpp +++ b/dlls/gearbox/gearbox_triggers.cpp @@ -39,6 +39,7 @@ class CTriggerXenReturn : public CTriggerTeleport public: void Spawn(void); void EXPORT TeleportTouch(CBaseEntity *pOther); + CBaseEntity* GetEarthTarget(CBaseEntity* pOther); }; @@ -55,7 +56,6 @@ void CTriggerXenReturn::Spawn(void) void CTriggerXenReturn::TeleportTouch(CBaseEntity* pOther) { entvars_t* pevToucher = pOther->pev; - edict_t *pentTarget = NULL; // Only teleport monsters or clients if (!FBitSet(pevToucher->flags, FL_CLIENT | FL_MONSTER)) @@ -80,11 +80,11 @@ void CTriggerXenReturn::TeleportTouch(CBaseEntity* pOther) } } - pentTarget = FIND_ENTITY_BY_CLASSNAME(pentTarget, "info_displacer_earth_target"); - if (FNullEnt(pentTarget)) + CBaseEntity* pTarget = GetEarthTarget(pOther); + if (!pTarget) return; - Vector tmp = VARS(pentTarget)->origin; + Vector tmp = pTarget->pev->origin; if (pOther->IsPlayer()) { @@ -97,11 +97,11 @@ void CTriggerXenReturn::TeleportTouch(CBaseEntity* pOther) UTIL_SetOrigin(pevToucher, tmp); - pevToucher->angles = pentTarget->v.angles; + pevToucher->angles = pTarget->pev->angles; if (pOther->IsPlayer()) { - pevToucher->v_angle = pentTarget->v.angles; + pevToucher->v_angle = pTarget->pev->angles; } pevToucher->fixangle = TRUE; @@ -121,6 +121,36 @@ void CTriggerXenReturn::TeleportTouch(CBaseEntity* pOther) EMIT_SOUND(ENT(pOther->pev), CHAN_STATIC, "debris/beamstart7.wav", 1, ATTN_NORM ); } +CBaseEntity* CTriggerXenReturn::GetEarthTarget(CBaseEntity* pOther) +{ + float flMinDist = 8192; + CBaseEntity* pEarthTarget = NULL; + CBasePlayer* pPlayer = NULL; + if (pOther && pOther->IsPlayer()) + { + pPlayer = (CBasePlayer*)pOther; + } + CBaseEntity* pDestination = NULL; + while ((pDestination = UTIL_FindEntityByClassname(pDestination, "info_displacer_earth_target")) != NULL) + { + if (pPlayer) + { + const float flDist = (pPlayer->m_DisplacerReturn - pDestination->pev->origin).Length(); + if (flDist <= flMinDist) + { + pEarthTarget = pDestination; + flMinDist = flDist; + } + } + else + { + pEarthTarget = pDestination; + break; + } + } + return pEarthTarget; +} + //========================================================= // CTriggerGenewormHit //========================================================= diff --git a/dlls/player.cpp b/dlls/player.cpp index f0bf558d54..384689f960 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -120,6 +120,7 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] = DEFINE_FIELD( CBasePlayer, m_iFOV, FIELD_INTEGER ), DEFINE_FIELD(CBasePlayer, m_fInXen, FIELD_BOOLEAN), + DEFINE_FIELD(CBasePlayer, m_DisplacerReturn, FIELD_VECTOR), DEFINE_FIELD(CBasePlayer, m_pRope, FIELD_CLASSPTR), //DEFINE_FIELD( CBasePlayer, m_fDeadTime, FIELD_FLOAT ), // only used in multiplayer games diff --git a/dlls/player.h b/dlls/player.h index 78a53a14e2..439363fbf4 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -341,6 +341,7 @@ class CBasePlayer : public CBaseMonster // Op4 player attributes. // BOOL m_fInXen; + Vector m_DisplacerReturn; friend class CDisplacer; friend class CTriggerXenReturn;