Raptor007 / aq2-tng

Action Quake 2: The Next Generation. Raptor007's sandbox for testing changes. When verified stable, this code is pushed to the official aq2-tng repo:
https://github.com/aq2-tng/aq2-tng/tree/bots
4 stars 2 forks source link

Walking into someone on moving platforms sometimes kills them #95

Closed Raptor007 closed 2 years ago

Raptor007 commented 4 years ago

I've noticed on maps like cliff, if two players are both standing on a moving platform, it might squish one of them if they get too close to each other.

This could be related to the scoot fix in issue #44.

Raptor007 commented 2 years ago

Looking into this. It can occur with any sv_fps including 10, and can also still happen if I comment-out the platform scoot fix so that likely wasn't actually related.

This consistently crushes the player entity earlier in the array (usually whomever connected first) when they are following too close behind another player on a moving platform. Nobody gets crushed if the later-connected player is following behind. Crushing only seems to occur when the platform is moving a specific direction (upward for the tram on cliff).

Some of the relevant events when this happens: SV_TestEntityPosition: Ent 1 (player) ran into ent 2 (player). SV_TestEntityPosition: Ent 1 (player) ran into ent 46 (func_train). SV_Push: Pusher 46 (func_train) ran into obstacle 1 (player). SV_Physics_Pusher: SV_Push reports ent 46 (func_train) #1 in chain blocked. Raptop was flattened

When the earlier players follows too close while the tram is moving downward, only this event happens and there is no crushing: SV_TestEntityPosition: Ent 1 (player) ran into ent 2 (player).

Raptor007 commented 2 years ago

I think I'm starting to understand. If the earlier player entity can't be pushed because of an obstruction ahead (the other player entity that hasn't been pushed yet) SV_Push will see if it could put the player back in their previous position: https://github.com/Raptor007/aq2-tng/blob/216dd81472b9cbfcd75b5377705737930c3944fe/source/g_phys.c#L537-L547

However, if the platform moved upward, the player's old position is now colliding with the platform's new position. This may also apply to platforms moving horizontally if gravity pulls down the player origin.

A decent workable hack for this might be to make sure if the platform had upward Z movement, that part is still applied to the return position of the entity when its push attempt is bounced back (for colliding with an unmoved player). I can't think of an edge case this would break, except possibly a very low-ceiling elevator moving rapidly downward with two players in close proximity.

Raptor007 commented 2 years ago

I think this is fixed! There is still a problem that later-joined players can push earlier-joined players backwards on platforms, even crushing them against the back wall. But at least they no longer kill them just by touching.

Raptor007 commented 2 years ago

I think the reason some players can still shove others backwards is because of the way pushers operate on one object at a time, without allowing their pushed objects to push another object. If an earlier entity would be pushed into a later one that hasn't had its push applied yet, the first entity's position is reset for that frame. Thus they naturally gain a gap of one frame's worth of movement between them, and future pushes can be applied to both. But if the second player is running towards the first, that gap keeps getting closed, then recreated by not moving the first player again. And if the back wall of the tram has arrived at the first player's old position, that player will now be crushed by it.

If this edge case is worth fixing, it may require allowing objects that are pushed to try applying the push motion to any objects they are pushed into, but also making sure those second objects are not pushed again this frame by the same pusher.