Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CBasePlayer::CheckTimeBasedDamage hook #749

Open
RauliTop opened this issue Apr 8, 2022 · 0 comments
Open

Add CBasePlayer::CheckTimeBasedDamage hook #749

RauliTop opened this issue Apr 8, 2022 · 0 comments

Comments

@RauliTop
Copy link
Contributor

RauliTop commented Apr 8, 2022

Useful hook to change TimeBasedDamages like Paralyze, Poison, Radiation, Acid...
We can take away health with set_user_health to apply damage

// If player is taking time based damage, continue doing damage to player -
// this simulates the effect of being poisoned, gassed, dosed with radiation etc -
// anything that continues to do damage even after the initial contact stops.
// Update all time based damage counters, and shut off any that are done.
// The m_bitsDamageType bit MUST be set if any damage is to be taken.
// This routine will detect the initial on value of the m_bitsDamageType
// and init the appropriate counter. Only processes damage every second.
void CBasePlayer::CheckTimeBasedDamage()
{
int i;
byte bDuration = 0;
if (!(m_bitsDamageType & DMG_TIMEBASED))
return;
// only check for time based damage approx. every 2 seconds
#ifdef REGAMEDLL_FIXES
if (Q_abs(gpGlobals->time - m_tbdPrev) < 2.0f)
#else
if (Q_abs(int64(gpGlobals->time - m_tbdPrev)) < 2.0f)
#endif
return;
m_tbdPrev = gpGlobals->time;
for (i = 0; i < ITBD_END; i++)
{
// make sure bit is set for damage type
if (m_bitsDamageType & (DMG_PARALYZE << i))
{
switch (i)
{
case ITBD_PARALLYZE:
// UNDONE - flag movement as half-speed
bDuration = PARALYZE_DURATION;
break;
case ITBD_NERVE_GAS:
bDuration = NERVEGAS_DURATION;
break;
case ITBD_POISON:
{
TakeDamage(pev, pev, POISON_DAMAGE, DMG_GENERIC);
bDuration = POISON_DURATION;
break;
}
case ITBD_DROWN_RECOVER:
{
// NOTE: this hack is actually used to RESTORE health
// after the player has been drowning and finally takes a breath
if (m_idrowndmg > m_idrownrestored)
{
int idif = Q_min(m_idrowndmg - m_idrownrestored, 10);
TakeHealth(idif, DMG_GENERIC);
m_idrownrestored += idif;
}
// get up to 5*10 = 50 points back
bDuration = 4;
break;
}
case ITBD_RADIATION:
bDuration = RADIATION_DURATION;
break;
case ITBD_ACID:
bDuration = ACID_DURATION;
break;
case ITBD_SLOW_BURN:
bDuration = SLOWBURN_DURATION;
break;
case ITBD_SLOW_FREEZE:
bDuration = SLOWFREEZE_DURATION;
break;
default:
bDuration = 0;
break;
}
if (m_rgbTimeBasedDamage[i])
{
// use up an antitoxin on poison or nervegas after a few seconds of damage
if ((i == ITBD_NERVE_GAS && m_rgbTimeBasedDamage[i] < NERVEGAS_DURATION) || (i == ITBD_POISON && m_rgbTimeBasedDamage[i] < POISON_DURATION))
{
if (m_rgItems[ITEM_ID_ANTIDOTE])
{
m_rgbTimeBasedDamage[i] = 0;
m_rgItems[ITEM_ID_ANTIDOTE]--;
SetSuitUpdate("!HEV_HEAL4", SUIT_SENTENCE, SUIT_REPEAT_OK);
}
}
// decrement damage duration, detect when done.
if (!m_rgbTimeBasedDamage[i] || --m_rgbTimeBasedDamage[i] == 0)
{
m_rgbTimeBasedDamage[i] = 0;
// if we're done, clear damage bits
m_bitsDamageType &= ~(DMG_PARALYZE << i);
}
}
else
// first time taking this damage type - init damage duration
m_rgbTimeBasedDamage[i] = bDuration;
}
}
}

Also, commented here: dreamstalker/rehlds#906

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

No branches or pull requests

1 participant