From b17177c5202918e699d38db9b19f081d6db8b757 Mon Sep 17 00:00:00 2001
From: khang <mkhangle20@gmail.com>
Date: Sat, 2 Mar 2024 00:27:23 -0500
Subject: [PATCH 1/3] Add trigger_teleport landmark

---
 regamedll/dlls/triggers.cpp | 40 ++++++++++++++++++++++++++++++++++++-
 regamedll/dlls/triggers.h   |  9 +++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/regamedll/dlls/triggers.cpp b/regamedll/dlls/triggers.cpp
index c4af258c4..1d868712c 100644
--- a/regamedll/dlls/triggers.cpp
+++ b/regamedll/dlls/triggers.cpp
@@ -1763,8 +1763,26 @@ void CBaseTrigger::TeleportTouch(CBaseEntity *pOther)
 
 	if (pOther->IsPlayer())
 	{
+#ifdef REGAMEDLL_ADD
+		if (m_iszLandmarkName) {
+			edict_t	*pentLandmark = nullptr;
+
+			pentLandmark = FIND_ENTITY_BY_TARGETNAME(pentLandmark, STRING(m_iszLandmarkName));
+			if (!FNullEnt(pentLandmark)) {
+				Vector diff = pevToucher->origin - VARS(pentLandmark)->origin;
+				tmp += diff;
+				tmp.z--; // offset by +1 because -1 will run out of this scope.
+			} else {
+				// fallback, shouldn't happen but anyway.
+				tmp.z -= pOther->pev->mins.z;
+			}
+		}
+		else
+#endif
 		// make origin adjustments in case the teleportee is a player. (origin in center, not at feet)
-		tmp.z -= pOther->pev->mins.z;
+		{
+			tmp.z -= pOther->pev->mins.z;
+		}
 	}
 
 	tmp.z++;
@@ -1817,6 +1835,26 @@ void CTriggerTeleport::Spawn()
 	SetTouch(&CTriggerTeleport::TeleportTouch);
 }
 
+#ifdef REGAMEDLL_ADD
+void CTriggerTeleport::KeyValue(KeyValueData *pkvd)
+{
+	if (FStrEq(pkvd->szKeyName, "landmark"))
+	{
+		if (Q_strlen(pkvd->szValue) > 0)
+		{
+			m_iszLandmarkName = ALLOC_STRING(pkvd->szValue);
+		}
+		// If empty, handle it in the teleport touch instead
+		pkvd->fHandled = TRUE;
+	}
+	else
+	{
+		CBaseTrigger::KeyValue(pkvd);
+	}
+}
+
+#endif
+
 LINK_ENTITY_TO_CLASS(info_teleport_destination, CPointEntity, CCSPointEntity)
 LINK_ENTITY_TO_CLASS(func_buyzone, CBuyZone, CCSBuyZone)
 
diff --git a/regamedll/dlls/triggers.h b/regamedll/dlls/triggers.h
index c16f969c8..58c06c62b 100644
--- a/regamedll/dlls/triggers.h
+++ b/regamedll/dlls/triggers.h
@@ -204,6 +204,11 @@ class CBaseTrigger: public CBaseToggle
 	void EXPORT CounterUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
 	void EXPORT ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
 	void InitTrigger();
+
+#ifdef REGAMEDLL_ADD
+	// For trigger_teleport TriggerTouch
+	int m_iszLandmarkName = 0;
+#endif
 };
 
 #define SF_TRIGGER_HURT_TARGETONCE      BIT(0) // Only fire hurt target once
@@ -393,6 +398,10 @@ class CTriggerTeleport: public CBaseTrigger
 {
 public:
 	virtual void Spawn();
+
+#ifdef REGAMEDLL_ADD
+	virtual void KeyValue(KeyValueData *pkvd);
+#endif
 };
 
 class CBuyZone: public CBaseTrigger

From df46ae616a3fd16f3d7a7a54b9f79f837cfb10f9 Mon Sep 17 00:00:00 2001
From: s1lentq <s1lentsk@yandex.ru>
Date: Wed, 8 May 2024 21:40:09 +0700
Subject: [PATCH 2/3] Minor refactor

---
 regamedll/dlls/triggers.cpp | 20 ++++++++++++--------
 regamedll/dlls/triggers.h   |  3 ---
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/regamedll/dlls/triggers.cpp b/regamedll/dlls/triggers.cpp
index 1d868712c..49e4d14c4 100644
--- a/regamedll/dlls/triggers.cpp
+++ b/regamedll/dlls/triggers.cpp
@@ -1764,15 +1764,19 @@ void CBaseTrigger::TeleportTouch(CBaseEntity *pOther)
 	if (pOther->IsPlayer())
 	{
 #ifdef REGAMEDLL_ADD
-		if (m_iszLandmarkName) {
-			edict_t	*pentLandmark = nullptr;
+		// If a landmark was specified, offset the player relative to the landmark
+		if (m_iszLandmarkName)
+		{
+			edict_t *pentLandmark = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(m_iszLandmarkName));
 
-			pentLandmark = FIND_ENTITY_BY_TARGETNAME(pentLandmark, STRING(m_iszLandmarkName));
-			if (!FNullEnt(pentLandmark)) {
+			if (!FNullEnt(pentLandmark))
+			{
 				Vector diff = pevToucher->origin - VARS(pentLandmark)->origin;
 				tmp += diff;
 				tmp.z--; // offset by +1 because -1 will run out of this scope.
-			} else {
+			}
+			else
+			{
 				// fallback, shouldn't happen but anyway.
 				tmp.z -= pOther->pev->mins.z;
 			}
@@ -1835,26 +1839,26 @@ void CTriggerTeleport::Spawn()
 	SetTouch(&CTriggerTeleport::TeleportTouch);
 }
 
-#ifdef REGAMEDLL_ADD
 void CTriggerTeleport::KeyValue(KeyValueData *pkvd)
 {
+#ifdef REGAMEDLL_ADD
 	if (FStrEq(pkvd->szKeyName, "landmark"))
 	{
 		if (Q_strlen(pkvd->szValue) > 0)
 		{
 			m_iszLandmarkName = ALLOC_STRING(pkvd->szValue);
 		}
+
 		// If empty, handle it in the teleport touch instead
 		pkvd->fHandled = TRUE;
 	}
 	else
+#endif
 	{
 		CBaseTrigger::KeyValue(pkvd);
 	}
 }
 
-#endif
-
 LINK_ENTITY_TO_CLASS(info_teleport_destination, CPointEntity, CCSPointEntity)
 LINK_ENTITY_TO_CLASS(func_buyzone, CBuyZone, CCSBuyZone)
 
diff --git a/regamedll/dlls/triggers.h b/regamedll/dlls/triggers.h
index 58c06c62b..b21a6bde5 100644
--- a/regamedll/dlls/triggers.h
+++ b/regamedll/dlls/triggers.h
@@ -398,10 +398,7 @@ class CTriggerTeleport: public CBaseTrigger
 {
 public:
 	virtual void Spawn();
-
-#ifdef REGAMEDLL_ADD
 	virtual void KeyValue(KeyValueData *pkvd);
-#endif
 };
 
 class CBuyZone: public CBaseTrigger

From f0e65122a869eead937df663dc1221c81afea7f8 Mon Sep 17 00:00:00 2001
From: s1lentq <s1lentsk@yandex.ru>
Date: Wed, 8 May 2024 21:46:05 +0700
Subject: [PATCH 3/3] Update regamedll-cs.fgd

---
 regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd
index 0e6838732..79fe8333a 100644
--- a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd
+++ b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd
@@ -1934,6 +1934,7 @@
 	bombradius(integer) : "Bomb Radius" : 500
 ]
 
+@PointClass base(Targetname) iconsprite("sprites/CS/info_target.spr") = info_landmark : "Transition/Relative teleport Landmark" []
 @PointClass base(Targetname) iconsprite("sprites/CS/info_target.spr") = info_null : "info_null (spotlight target)" []
 @PointClass iconsprite("sprites/CS/info_player_deathmatch.spr") base(PlayerClass) = info_player_deathmatch : "Terrorist start" []
 @PointClass iconsprite("sprites/CS/info_player_start.spr") base(PlayerClass) = info_player_start : "Counter-terrorist start" []
@@ -2264,6 +2265,7 @@
 
 @SolidClass base(Trigger) = trigger_teleport : "Trigger teleport" 
 [
+	landmark(string) : "Landmark name"
 	spawnflags(flags) =
 	[
 		256: "Keep angles" : 0