ValveSoftware / halflife

Half-Life 1 engine based games
Other
3.68k stars 623 forks source link

Button spawnflag "Sparks" doesn't work as intended #1681

Open ghost opened 8 years ago

ghost commented 8 years ago

The func_button spawnflag "Sparks" does not work as intended. Because it uses gpGlobals->time, its nextthink will be incorrect. It should be using pev->ltime.

Offending line: https://github.com/ValveSoftware/halflife/blob/master/dlls/buttons.cpp#L574

Change pev->nextthink = gpGlobals->time + ( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) );// spark again at random interval to pev->nextthink = pev->ltime + ( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) );// spark again at random interval

This happens because buttons use a different approach to thinking. Unlike all other move types, they only think if nextthink falls between ltime and ltime + frametime. If gpGlobals->time is used, then nextthink may be smaller than ltime. The engine simulates several frames to get physics going, so it's very likely to cause this issue. gpGlobals->time is 1 during map spawn simulation, whereas pev->ltime changes with every frame.

Dedicated servers seem more affected, likely due to differing frametime.

Note: this issue was made by @SamVanheer while logged into an account used for a college assignment. Refer to him for more information.

SamVanheer commented 3 years ago

Note that this only happens if maxplayers is larger than 1. In singleplayer it works because the engine simulates few enough frames that the initial time still works.

This can be tested easily on c1a1 with maxplayers 32. The elevator button should spark.

Additionally the link above doesn't work properly, so here's a proper one: https://github.com/ValveSoftware/halflife/blob/c7240b965743a53a29491dd49320c88eecf6257b/dlls/buttons.cpp#L574

See Quake for the logic behind the use of pev->ltime: https://github.com/id-Software/Quake/blob/bf4ac424ce754894ac8f1dae6a3981954bc9852d/WinQuake/sv_phys.c#L704-L743

SamVanheer commented 2 years ago

There is an additional change needed to fully fix this: https://github.com/ValveSoftware/halflife/blob/c7240b965743a53a29491dd49320c88eecf6257b/dlls/buttons.cpp#L796

This needs to be changed to:

pev->nextthink = pev->ltime + 0.5;// no hurry.

Otherwise the sparks may not show at all once the button has been activated and returned to its off state.