Skip to content

Fix all horizontal movement being broken#1156

Merged
coelckers merged 5 commits intoZDoom:masterfrom
Macil:fixMovement
Jul 17, 2025
Merged

Fix all horizontal movement being broken#1156
coelckers merged 5 commits intoZDoom:masterfrom
Macil:fixMovement

Conversation

@Macil
Copy link
Contributor

@Macil Macil commented Jul 11, 2025

Fixes #1141.

The commit 940e53a seems to have broken all horizontal movement in Raze. The commit copied a change to vectors.h from GZDoom that makes it so TVector3::XY() returns a fresh TVector2 object instead of a reference to the TVector3 type-punned to look like a TVector2, which has the consequence that modifying the returned object (like vec3.XY() = someVec2;) no longer works to modify the TVector3. That wasn't an issue in GZDoom but this pattern is done in a ton of places in Raze.

The commit changed vectors.h to no longer use type-punning which seems like a reasonable goal, so I wanted to find a solution that didn't just revert that. I think it would be possible to make all of Raze's code continue working by making the TVector3::XY() method return a TVector2-like proxy object that contains references to the TVector3's X and Y properties and implements all of the same methods as TVector2 and support for being implicitly converted to a TVector2, but that struck me as a lot of duplication in vectors.h which also wouldn't be useful for GZDoom. Instead I just went through all of the calls to TVector3::XY() that mutated the returned value and made them not do that.

Here are the main kinds of changes I did many times:

-spr.pos.XY() = opos.XY();
+spr.pos.SetXY(opos.XY());

I added a TVector3::SetXY(const Vector2 &v) method instead of overloading operator= for Vector2 values because it seemed like the latter might allow accidents.

-pPlayerActor->vel.XY().Zero();
+pPlayerActor->vel.SetXY(DVector2(0, 0));
-tspr->pos.XY() += tspr->Angles.Yaw.ToVector() * 0.125;
+tspr->pos += tspr->Angles.Yaw.ToVector() * 0.125;

The above works because TVector3 has methods like TVector3 &operator+= (const Vector2 &other) and other compound assignment operators defined for it that only affects the X and Y properties.

-p->vel.XY() *= gs.playerfriction;
+p->vel.SetXY(p->vel.XY() * gs.playerfriction);

This had to be handled differently because gs.playerfriction is a number instead of a Vector2, so if I just removed the .XY() part again then all 3 coordinates would be modified, not just X and Y.

Additionally, while working on this I discovered a bug in source/games/blood/src/aiunicult.cpp dudeLeechOperate() where the Z coordinate of a vector wasn't set to the intended value and was left uninitialized. It's fixed in its own commit, 3ff9ef5.

@sinisterseed sinisterseed mentioned this pull request Jul 12, 2025
1 task
@coelckers coelckers merged commit 50fa148 into ZDoom:master Jul 17, 2025
8 checks passed
@Macil Macil deleted the fixMovement branch July 17, 2025 11:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Nothing can move around

2 participants