Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Teleports broken in versions newer than 4.11.3 #2868

Open
1 task done
nickbailuc opened this issue Dec 21, 2024 · 3 comments
Open
1 task done

[BUG] Teleports broken in versions newer than 4.11.3 #2868

nickbailuc opened this issue Dec 21, 2024 · 3 comments
Labels

Comments

@nickbailuc
Copy link

GZDoom version

4.14.0

Which game are you running with GZDoom?

Doom 2

What Operating System are you using?

Linux ARM (Raspberry Pi)

Please describe your specific OS version

Debian 13 (trixie)

Relevant hardware info

Apple M2

Have you checked that no other similar issue already exists?

  • I have searched and not found similar issues.

A clear and concise description of what the bug is.

After filing #2830 , I realized this is not just for silent teleports in myhouse.pk3 but for regular teleports in vanilla Doom. I tested the original doom2.wad, the BFG doom2.wad, enhanced doom2.wad, and kex doom2.wad. Walking into a teleport does not trigger them immediately, but instead keeps you in the same location usually. Walking back and fourth through them, or with momentum sometimes randomly does trigger the teleport, but this seems to happen entirely random.

Steps to reproduce the behaviour.

Explain how to reproduce

  1. Launch any vanilla Doom2 wad (original, BFG, enhanced, kex)
  2. Go to MAP04
  3. Walk through the teleporters in the end of the map

Your configuration

completely vanilla config, not even key bindings

Provide a Log

No response

@nickbailuc nickbailuc added the bug label Dec 21, 2024
@JeodC
Copy link

JeodC commented Jan 24, 2025

Hi, came across this error when testing various mods. I can confirm on linux arm64 teleports will only function if you are sprinting as you hit them. Normal player movement does not trigger them.

@nickbailuc
Copy link
Author

Hi, came across this error when testing various mods. I can confirm on linux arm64 teleports will only function if you are sprinting as you hit them. Normal player movement does not trigger them.

I have always run activated, but I guess even then it needs a certain speed (although I remember sometimes it works at a low speed randomly too). In any case this is bad in the vanilla games and ruins any silent teleport WADs.

I just use g4.11.3 because it's the last version that worked properly, so definitely something changed in the newer versions that created this bug.

Any idea why this is happening specifically in linux-arm64, and what other architectures it may be happening on?

@JeodC
Copy link

JeodC commented Jan 24, 2025

Tick rate differences, especially in physics. I am able to make a teleport function with standard player speed by sliding back and forth very short distances while colliding with the teleport. It may be something in this section:

int flags = fog ? (TELF_DESTFOG | TELF_SOURCEFOG | TELF_KEEPORIENTATION) : TELF_KEEPORIENTATION;
bool res =
P_Teleport (victim, DVector3(dest->Pos().XY() + newp, z),
nullAngle, flags);
// P_Teleport only changes angle if fog is true
victim->Angles.Yaw = (dest->Angles.Yaw + victim->Angles.Yaw - source->Angles.Yaw).Normalized360();
return res;
}
//-----------------------------------------------------------------------------
//
// [RH] Teleport a group of actors centered around source_tid so
// that they become centered around dest_tid instead.
//
//-----------------------------------------------------------------------------
bool FLevelLocals::EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_tid, bool moveSource, bool fog)
{
AActor *sourceOrigin, *destOrigin;
{
auto iterator = GetActorIterator(source_tid);
sourceOrigin = iterator.Next ();
}
if (sourceOrigin == NULL)
{ // If there is no source origin, behave like TeleportOther
return EV_TeleportOther (group_tid, dest_tid, fog);
}
{
auto iterator = GetActorIterator(NAME_TeleportDest, dest_tid);
destOrigin = iterator.Next ();
}
if (destOrigin == NULL)
{
return false;
}
bool didSomething = false;
bool floorz = !destOrigin->IsKindOf (PClass::FindClass("TeleportDest2"));
// Use the passed victim if group_tid is 0
if (group_tid == 0 && victim != NULL)
{
didSomething = DoGroupForOne (victim, sourceOrigin, destOrigin, floorz, fog);
}
else
{
auto iterator = GetActorIterator(group_tid);
// For each actor with tid matching arg0, move it to the same
// position relative to destOrigin as it is relative to sourceOrigin
// before the teleport.
while ( (victim = iterator.Next ()) )
{
didSomething |= DoGroupForOne (victim, sourceOrigin, destOrigin, floorz, fog);
}
}
if (moveSource && didSomething)
{
didSomething |=
P_Teleport (sourceOrigin, destOrigin->PosAtZ(floorz ? ONFLOORZ : destOrigin->Z()), nullAngle, TELF_KEEPORIENTATION);
sourceOrigin->Angles.Yaw = destOrigin->Angles.Yaw;
}
return didSomething;
}
//-----------------------------------------------------------------------------
//
// [RH] Teleport a group of actors in a sector. Source_tid is used as a
// reference point so that they end up in the same position relative to
// dest_tid. Group_tid can be used to not teleport all actors in the sector.
//
//-----------------------------------------------------------------------------
bool FLevelLocals::EV_TeleportSector (int tag, int source_tid, int dest_tid, bool fog, int group_tid)
{
AActor *sourceOrigin, *destOrigin;
{
auto iterator = GetActorIterator(source_tid);
sourceOrigin = iterator.Next ();
}
if (sourceOrigin == NULL)
{
return false;
}
{
auto iterator = GetActorIterator(NAME_TeleportDest, dest_tid);
destOrigin = iterator.Next ();
}
if (destOrigin == NULL)
{
return false;
}
bool didSomething = false;
bool floorz = !destOrigin->IsKindOf(NAME_TeleportDest2);
int secnum;

..or I could be off track with my guess. Anyway, here is a diff of the two releases for this specific cpp file: https://www.diffchecker.com/PnPaqBex/

In short the second implementation uses a substitute for the Z coordinate, while the first extracts that coordinate from the player actor alongside X and Y. Is this the cause? I don't know. My approach with source code as a hobbyist has always been trial-and-error when it comes to unfamiliar codebase.

This is easily replicable by using GZ Doom with The Legend of Doom mod. The first cave, right in front of you, is a teleport. On Windows 11, g4.14.0 works fine. On Linux Arm64, g4.14.0 fails to teleport unless I perform the above steps and make subtle movements on top of the teleporter area.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants