FWGS / hlsdk-portable

Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
https://xash.su
Other
272 stars 125 forks source link

CBasePlayer::TakeHealth might leave player in invalid state #346

Open FreeSlave opened 1 year ago

FreeSlave commented 1 year ago

CBasePlayer::TakeHealth doesn't convert the value to integer (unlike CBasePlayer::TakeDamage), so player can get non-integer health. Which results in invalid state when health becomes less than 1 but greater than 0.

In the game such effect can be achieved by placing trigger_hurt with negative odd value. trigger_hurt works every 0.5 seconds and halves the specified heal/damage value, so if the value is odd it gets non-integer on halving.

Some maps may have trigger_hurts (e.g. Xen healing pools) with odd numbers and healing by them can cause a bug.

The test map. Just go forward through some trigger_hurts and the player will get invalid: the camera lies on the side and the crowbar is still usable even though the view model is gone.

The similar effect probably can be achieved if healthkit health supply has a non-integer value.

Note that simply converting the value to int in CBasePlayer::TakeHealth (before passing to CBaseMonster::TakeHealth) would mean that player gets healed slower. E.g. is trigger_hurt features the value -3, that means that player is getting healed by 3 hp per second (two times by 1.5). But if it's converted to integer, player is getting healed by 2 hp per second.