Duke3D: Grins of Divinity's ladder implementation is broken
A regression occured with r7436 (commit 1eb95599) that manifests itself with the ladders in Grins of Divinity and the Starship Troopers TC, but its effects may not necessarily be restricted to these mods. This is another one of those rabbit hole issues that needs to be investigated more thoroughly.
First of all we have the ladders themselves, their function is demonstrated in the following video: https://streamable.com/n1pbq
The mod utilizes floor-aligned sprites that raise once the player presses use if they are close. However, starting with r7436 these ladders continuously move down: https://streamable.com/jceia
Now, in the forum thread I speculated that
ifceilingdistl may be broken, but this is not the case. Much rather, starting with r7436, the actor field
vm.pActor->ceilingz is altered continuously as the sprite moves up and down, where in r7435 and before this value would remain constant. This is strange because the sprite never moves anywhere on the x or y axis.
For example, before the offending commit, the sprite seen in the video has a constant
ceilingz value of
-121856, which matches the ceiling height reported by mapster32 for the sector the sprite is placed in. After said commit however, the value increases as soon as the player presses use and the sprite is moved upwards. Values I've observed were
-75776 which is the ceiling height of the adjacent sector,
-25476. For the latter three values, there are no ceilings on the map with those specific heights. However, they were very close to the z-position of the ladder sprite itself, leading me to believe that it is detecting another sprite, possibly the player, as the ceiling.
Since the commit this difference originated from was about projectile collision, I believe that this may not be intended. It stems from the following change:
diff --git a/source/duke3d/src/actors.cpp b/source/duke3d/src/actors.cpp index 019dc15f9..84a6d3b43 100644 --- a/source/duke3d/src/actors.cpp +++ b/source/duke3d/src/actors.cpp @@ -388,6 +388,8 @@ static int32_t A_CheckNeedZUpdate(int32_t spriteNum, int32_t zChange, int32_t *p *pZcoord = newZ; + A_GetZLimits(spriteNum); + if (newZ > actor[spriteNum].ceilingz && newZ <= actor[spriteNum].floorz) return 1;
By removing this call, the ladder regains its functionality and the reported ceiling height is once again constant.