From 0e1121ed51e99e1dc898d0799055c9946a96fd60 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 26 Nov 2022 15:58:55 +0100 Subject: [PATCH] - reinstated original distance math for SE20. This one's a catastrophic combination of a bad algorithm depending on equally bad math to calculate distance. It simply does not do what one would expect - it should have calculated the distance to a wall's center to be robust. --- source/games/duke/src/savegame.cpp | 2 +- source/games/duke/src/spawn.cpp | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 1b56ca12c..7fefe45f4 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -282,7 +282,7 @@ void DDukeActor::Serialize(FSerializer& arc) ("temp_actor", temp_actor) ("seek_actor", seek_actor) .Array("temp_data", temp_data, 6) - .Array("temo_wall", temp_walls, 2) + //.Array("temp_wall", temp_walls, 2) ("temp_angle", temp_angle) ("temp_pos", temp_pos) ("temp_pos2", temp_pos2) diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index e31f09a54..38af13985 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -683,15 +683,32 @@ void spawneffector(DDukeActor* actor, TArray* actors) case SE_20_STRETCH_BRIDGE: { - //find the two most clostest wall x's and y's + auto FindDistance2D = [](int x, int y) + { + x = abs(x); + y = abs(y); + + if (x < y) + std::swap(x, y); + + int t = y + (y >> 1); + + return (x - (x >> 5) - (x >> 7) + (t >> 2) + (t >> 6)); + + }; + //find the two most closest wall x's and y's + for (unsigned i = 0; i < 2; i++) { walltype* closewall = nullptr; - double maxdist = 0x7fffffff; + int maxdist = 0x7fffffff; for (auto& wal : sectp->walls) { - double dist = (actor->spr.pos.XY() - wal.pos).LengthSquared(); + int x = int(actor->spr.pos.X - wal.pos.X) * 16; + int y = int(actor->spr.pos.Y - wal.pos.Y) * 16; + + int dist = FindDistance2D(x, y); if (dist < maxdist && &wal != actor->temp_walls[0]) { maxdist = dist;