Linked_portal_door in HL2

The title is almost self-explanatory: is there a sort of linked_portal_door in Half Life 2?

Different engines, so no.

No.
I’m sure you could implement it in as needed yourself through a mod though.

fainting in 3… 2… 1…

Any ideas about how to do that?

Erm, you could just use a func_door or a prop_dynamic?

On a tangent here, you can use prop_dynamic to put Portal 2’s pushbar door into a GMod map… I’ve tried and succeeded.

func_monitor + trigger_teleport + info_landmark is pretty much the only way to mimic it in other engines.

linked_portal_door is an entity that uses portals to make a flawless transition between areas not connected.

linked_portal_door is a feature that was introduced in Portal series (Not sure if it’s 1 or 2). It is not available for all source engine.

If you want to replicate the same similar result for a different game, you can use trigger_teleport (Single player can’t tell if they were teleported, but in multiplayer, with people in game, they’ll notice).

Correct me if I’m wrong:
if I make a sort of trigger which can be linked to another, I can link the two triggers and when the player touches one of them it will be teleported to the other, without changing the player’s view angle and its relative position from the trigger at the moment of the teleport.
Also, I can make a func_monitor linked to a point_camera with a FOV of 180 degrees, so I can see everything even if I move.

Does this make sense? :smile:

Yes. The problem with this is, not only can you not link a landmark’er to the point_camera, but you can only have one point_camera active at once without editing the code in a Source Mod. So, this really isn’t possible for existing games outside of Portal 2 which has this entity built-in.

If you can figure out another way to spoof the visual part of this ‘fake linked_portal_door’, then yes; with a landmark linked to the teleport brushes, you can have the player teleported back and forth without a view angle change/while keeping their angle. This isn’t great in Multiplayer either way though, as another player would be-able to see the player being teleported ‘disappear’, and re-appear at the snapped position.

Assuming this is for single player he could just turn off the camera on teleport and turn on the opposite one.

Personally for teleporters in multiplayer maps I just used airlocks and such to hide the player disappearing.

The mod I’m making is only single player, so I don’t need to worry about the “teleport effect”.

Fair enough, but the cardboard box was un-called for… have one back.

Then yeah, as Ereunity said; when you go through one side of the portal, turn the relative camera/monitor that you would now be seeing on. This making it so you don’t have to edit your mod, as I believe I remember reading somewhere that having multiple cameras crashes your game; why Valve has the camera limit set to one.

This still leaves the problem that you can’t link camera’s to landmarks in any way though, making this quite hard. You’d probably end up having better luck coding your own version of the linked_portal_door into your mod, honestly.

I just need 2 point_cameras. I don’t think the game will crash with two cameras, is it?

No, I meant that I believe the game will crash if you have two point_cameras on at once when modifying the Source Code in your mod to allow more than one point_camera to be on at once. My bad, miss-worded that.

Okay, since my maths knowledge stops at algebraic fractions, can you correct this code?
My scope is to teleport the player with the same relative distance from the teleporter origin to the player and with the same entry angle (rotated to fit the second teleporter’s angle), so the player will be teleported very fluently, almost without being conscious of this.
My biggest problem is not the relative distance, but the angles.
Can you help me? :downs:

trigger_dynamic_teleport.cpp


#include "cbase.h"

#include "trigger_dynamic_teleport.h"

#include <math.h>

#define _USE_MATH_DEFINES

void CTriggerDynamicTeleport::Spawn( void )
{
	BaseClass::Spawn();

	SetTouch( &CTriggerDynamicTeleport::PlayerTouch );

	CBaseTrigger::InitTrigger();
}

void CTriggerDynamicTeleport::PlayerTouch ( CBaseEntity *pOther )
{
	if (bTeleported)
		return;

	CBaseEntity *target = NULL;

	if (tLink != NULL_STRING)
	{
		target = gEntList.FindEntityByName( target, tLink );
		if (!target)
			return;
	}
	else
	{
		return;
	}

	trace_t relativepos;
	UTIL_TraceLine( this->GetAbsOrigin(), pOther->GetAbsOrigin(), NULL, pOther, COLLISION_GROUP_NONE, &relativepos );

	Vector tracevector = relativepos.endpos - relativepos.startpos;
	QAngle traceangle = QAngle( tracevector.x, tracevector.y, tracevector.z );
	float tracelength = tracevector.Length() * relativepos.fraction;

	float newx = tracelength * cos( traceangle.x * 180 / M_PI );
	float newy = tracelength * sin( traceangle.y * 180 / M_PI );
	float newz = tracelength * sin( traceangle.z * 180 / M_PI );

	Vector endrelativepos = Vector( newx, newy + 10, newz );

	Vector endpos = target->GetAbsOrigin() + endrelativepos;

	QAngle endangle = target->GetAbsAngles();

	pOther->SetAbsOrigin( target->GetAbsOrigin() + endrelativepos );
	pOther->SetAbsAngles( endangle );
	pOther->SetAbsVelocity( pOther->GetAbsVelocity() );
	bTeleported = true;
}

void CTriggerDynamicTeleport::InputChangeLink( string_t newLink )
{
	CBaseEntity *target = NULL;


	if (tLink != NULL_STRING)
	{
		target = gEntList.FindEntityByName( target, tLink );
		if (target)
		{
			tLink = newLink;
		}
		else
		{
			return;
		}
	}
	else
	{
		return;
	}
}

void CTriggerDynamicTeleport::EndTouch( CBaseEntity *pOther )
{
	BaseClass::EndTouch( pOther );
	bTeleported = false;
}

trigger_dynamic_teleport.h


#include "triggers.h"

class CTriggerDynamicTeleport : public CBaseTrigger
{
public:
	DECLARE_CLASS( CTriggerDynamicTeleport, CBaseTrigger );
	DECLARE_DATADESC();
 
	void Spawn();
 
	void PlayerTouch( CBaseEntity *pOther );
	void InputChangeLink( string_t newLink );

	void EndTouch ( CBaseEntity *pOther );

	string_t tLink;
	bool bTeleported;
};
 
LINK_ENTITY_TO_CLASS( trigger_dynamic_teleport, CTriggerDynamicTeleport );
 
BEGIN_DATADESC( CTriggerDynamicTeleport )

	DEFINE_ENTITYFUNC( PlayerTouch ),

	DEFINE_FIELD( tLink, FIELD_STRING ),
	DEFINE_FIELD( bTeleported, FIELD_BOOLEAN ),
	DEFINE_KEYFIELD( tLink, FIELD_STRING, "link" ),

	//DEFINE_INPUTFUNC( FIELD_STRING, "ChangeLink", InputChangeLink ),

END_DATADESC()

What is wrong with using a trigger_teleport with an info_landmark? (Does exactly the same job)

Unless you’re trying to change the angle of player orientation which can’t be done in normal source, the closest you can do is change the view angle and make your map in a way so it looks to be at that angle.

I don’t use them because it’s too obvious it’s a teleport, I must make the player believe it wasn’t never teleported.

You really like making your job harder don’t you. Why do you need the portals, we might be able to suggest a workaround.