From fcb597613b3f57aca6680ed07ecc60e1abe42427 Mon Sep 17 00:00:00 2001 From: s1lent Date: Sun, 11 Aug 2019 21:12:36 +0700 Subject: [PATCH] Make restartable for func_healthcharger and func_recharge entities Fix bug related to field "dmdelay" doesn't work properly --- regamedll/dlls/cbase.cpp | 8 +++ regamedll/dlls/cbase.h | 1 + regamedll/dlls/h_battery.cpp | 50 ++++++++++++++++--- regamedll/dlls/h_battery.h | 8 +++ regamedll/dlls/healthkit.cpp | 42 ++++++++++++++-- regamedll/dlls/healthkit.h | 7 +++ regamedll/dlls/multiplay_gamerules.cpp | 2 + .../GameDefinitionFile/regamedll-cs.fgd | 5 +- 8 files changed, 111 insertions(+), 12 deletions(-) diff --git a/regamedll/dlls/cbase.cpp b/regamedll/dlls/cbase.cpp index fcf542d4..fb9243de 100644 --- a/regamedll/dlls/cbase.cpp +++ b/regamedll/dlls/cbase.cpp @@ -645,6 +645,14 @@ BOOL CBaseEntity::TakeHealth(float flHealth, int bitsDamageType) return TRUE; } +bool CBaseEntity::CanTakeHealth(float flHealth) const +{ + if ((pev->health + flHealth) > pev->max_health) + return false; + + return true; +} + BOOL CBaseEntity::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { Vector vecTemp; diff --git a/regamedll/dlls/cbase.h b/regamedll/dlls/cbase.h index 43a89554..6e976d7b 100644 --- a/regamedll/dlls/cbase.h +++ b/regamedll/dlls/cbase.h @@ -151,6 +151,7 @@ public: void SUB_UseTargets(CBaseEntity *pActivator, USE_TYPE useType, float value); bool Intersects(CBaseEntity *pOther); bool Intersects(const Vector &mins, const Vector &maxs); + bool CanTakeHealth(float flHealth = 0.0f) const; void MakeDormant(); // This entity's classname. diff --git a/regamedll/dlls/h_battery.cpp b/regamedll/dlls/h_battery.cpp index cd535865..8d74cae0 100644 --- a/regamedll/dlls/h_battery.cpp +++ b/regamedll/dlls/h_battery.cpp @@ -56,6 +56,27 @@ void CRecharge::Spawn() pev->frame = 0; } +#ifdef REGAMEDLL_FIXES +void CRecharge::Restart() +{ + pev->solid = SOLID_BSP; + pev->movetype = MOVETYPE_PUSH; + + // set size and link into world + UTIL_SetOrigin(pev, pev->origin); + UTIL_SetSize(pev, pev->mins, pev->maxs); + SET_MODEL(ENT(pev), STRING(pev->model)); + + int armorValue = (int)gSkillData.suitchargerCapacity; + if (pev->armorvalue != 0.0f) { + armorValue = (int)pev->armorvalue; + } + + pev->nextthink = pev->ltime + 0.1f; + SetThink(&CRecharge::Recharge); +} + +#endif void CRecharge::Precache() { PRECACHE_SOUND("items/suitcharge1.wav"); @@ -77,7 +98,11 @@ void CRecharge::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT } // if the player doesn't have the suit, or there is no juice left, make the deny noise - if (m_iJuice <= 0 || !(pActivator->pev->weapons & (1 << WEAPON_SUIT))) + if (m_iJuice <= 0 || !(pActivator->pev->weapons & (1 << WEAPON_SUIT)) +#ifdef REGAMEDLL_FIXES + || pActivator->pev->armorvalue >= MAX_CHARGE_ARMOR // don't charge health if we can't more, prevent thinking entity +#endif + ) { if (m_flSoundTime <= gpGlobals->time) { @@ -120,7 +145,7 @@ void CRecharge::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT } // charge the player - if (m_hActivator->pev->armorvalue < 100) + if (m_hActivator->pev->armorvalue < MAX_CHARGE_ARMOR) { #ifdef REGAMEDLL_FIXES CBasePlayer *pPlayer = m_hActivator.Get(); @@ -129,10 +154,10 @@ void CRecharge::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT #endif m_iJuice--; - m_hActivator->pev->armorvalue += 1.0f; + m_hActivator->pev->armorvalue += AMOUNT_CHARGE_ARMOR; - if (m_hActivator->pev->armorvalue > 100) - m_hActivator->pev->armorvalue = 100; + if (m_hActivator->pev->armorvalue > MAX_CHARGE_ARMOR) + m_hActivator->pev->armorvalue = MAX_CHARGE_ARMOR; } // govern the rate of charge @@ -162,8 +187,21 @@ void CRecharge::Off() m_iOn = 0; - if (!m_iJuice && (m_iReactivate = g_pGameRules->FlHEVChargerRechargeTime()) > 0) + if (!m_iJuice) { + int iReactivate = m_iReactivate; + +#ifdef REGAMEDLL_FIXES + if (iReactivate <= 0) +#endif // #ifdef REGAMEDLL_FIXES + { + if ((iReactivate = g_pGameRules->FlHEVChargerRechargeTime()) <= 0) + return; + } + + if (m_iReactivate <= 0) + m_iReactivate = iReactivate; + pev->nextthink = pev->ltime + m_iReactivate; SetThink(&CRecharge::Recharge); } diff --git a/regamedll/dlls/h_battery.h b/regamedll/dlls/h_battery.h index 18e13954..05af8e69 100644 --- a/regamedll/dlls/h_battery.h +++ b/regamedll/dlls/h_battery.h @@ -28,6 +28,9 @@ #pragma once +const float AMOUNT_CHARGE_ARMOR = 1.0f; +const float MAX_CHARGE_ARMOR = 100.0f; + class CRecharge: public CBaseToggle { public: @@ -36,6 +39,11 @@ public: virtual void KeyValue(KeyValueData *pkvd); virtual int Save(CSave &save); virtual int Restore(CRestore &restore); + +#ifdef REGAMEDLL_FIXES + virtual void Restart(); +#endif + virtual int ObjectCaps() { return ((CBaseToggle::ObjectCaps() | FCAP_CONTINUOUS_USE) & ~FCAP_ACROSS_TRANSITION); } virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); diff --git a/regamedll/dlls/healthkit.cpp b/regamedll/dlls/healthkit.cpp index 7d780427..e27986c6 100644 --- a/regamedll/dlls/healthkit.cpp +++ b/regamedll/dlls/healthkit.cpp @@ -103,6 +103,23 @@ void CWallHealth::Spawn() pev->frame = 0.0f; } +#ifdef REGAMEDLL_FIXES +void CWallHealth::Restart() +{ + pev->solid = SOLID_BSP; + pev->movetype = MOVETYPE_PUSH; + + // set size and link into world + UTIL_SetOrigin(pev, pev->origin); + UTIL_SetSize(pev, pev->mins, pev->maxs); + + SET_MODEL(ENT(pev), pev->model); + + pev->nextthink = pev->ltime + 0.1f; + SetThink(&CWallHealth::Recharge); +} +#endif // #ifdef REGAMEDLL_FIXES + void CWallHealth::Precache() { PRECACHE_SOUND("items/medshot4.wav"); @@ -128,13 +145,18 @@ void CWallHealth::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us } // if the player doesn't have the suit, or there is no juice left, make the deny noise - if (m_iJuice <= 0 || !(pActivator->pev->weapons & (1 << WEAPON_SUIT))) + if (m_iJuice <= 0 || !(pActivator->pev->weapons & (1 << WEAPON_SUIT)) +#ifdef REGAMEDLL_FIXES + || !pActivator->CanTakeHealth(AMOUNT_CHARGE_HEALTH) // don't charge health if we can't more, prevent thinking entity +#endif // REGAMEDLL_FIXES + ) { if (gpGlobals->time >= m_flSoundTime) { m_flSoundTime = gpGlobals->time + 0.62f; EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshotno1.wav", VOL_NORM, ATTN_NORM); } + return; } @@ -153,6 +175,7 @@ void CWallHealth::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", VOL_NORM, ATTN_NORM); m_flSoundTime = gpGlobals->time + 0.56f; } + if (m_iOn == 1 && gpGlobals->time >= m_flSoundTime) { m_iOn++; @@ -160,7 +183,7 @@ void CWallHealth::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us } // charge the player - if (pActivator->TakeHealth(1, DMG_GENERIC)) + if (pActivator->TakeHealth(AMOUNT_CHARGE_HEALTH, DMG_GENERIC)) m_iJuice--; // govern the rate of charge @@ -192,8 +215,21 @@ void CWallHealth::Off() m_iOn = 0; - if (!m_iJuice && ((m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime()) > 0)) + if (!m_iJuice) { + int iReactivate = m_iReactivate; + +#ifdef REGAMEDLL_FIXES + if (iReactivate <= 0) +#endif // #ifdef REGAMEDLL_FIXES + { + if ((iReactivate = g_pGameRules->FlHealthChargerRechargeTime()) <= 0) + return; + } + + if (m_iReactivate <= 0) + m_iReactivate = iReactivate; + pev->nextthink = pev->ltime + m_iReactivate; SetThink(&CWallHealth::Recharge); } diff --git a/regamedll/dlls/healthkit.h b/regamedll/dlls/healthkit.h index 8f261f29..142ddd36 100644 --- a/regamedll/dlls/healthkit.h +++ b/regamedll/dlls/healthkit.h @@ -36,6 +36,8 @@ public: virtual BOOL MyTouch(CBasePlayer *pPlayer); }; +const float AMOUNT_CHARGE_HEALTH = 1.0f; + class CWallHealth: public CBaseToggle { public: @@ -44,6 +46,11 @@ public: virtual void KeyValue(KeyValueData *pkvd); virtual int Save(CSave &save); virtual int Restore(CRestore &restore); + +#ifdef REGAMEDLL_FIXES + virtual void Restart(); +#endif + virtual int ObjectCaps() { return (CBaseToggle::ObjectCaps() | FCAP_CONTINUOUS_USE) & ~FCAP_ACROSS_TRANSITION; } virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index c6a965dc..45ffcb2d 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -593,6 +593,8 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(CleanUpMap)() #ifdef REGAMEDLL_FIXES UTIL_RestartOther("trigger_once"); UTIL_RestartOther("func_wall_toggle"); + UTIL_RestartOther("func_healthcharger"); + UTIL_RestartOther("func_recharge"); UTIL_RestartOther("trigger_hurt"); UTIL_RestartOther("multisource"); UTIL_RestartOther("env_beam"); diff --git a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd index e4dfd39c..861a7f6a 100644 --- a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd +++ b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd @@ -2435,9 +2435,8 @@ @SolidClass base(Global, RenderFields, ZHLT, TexLightType) = func_healthcharger: "Wall health recharger" [ - // dmdelay may not work in CS health(integer) : "Healthcharger Capacity" : 50 - dmdelay(integer) : "Deathmatch recharge delay" : 0 + dmdelay(integer) : "Deathmatch recharge delay" : 60 _minlight(string) : "Minimum light level" : "0" ] @@ -2545,7 +2544,7 @@ @SolidClass base(Global, RenderFields, ZHLT, TexLightType) = func_recharge: "Battery recharger" [ armorvalue(integer) : "Suitcharger Capacity" : 30 - dmdelay(integer) : "Deathmatch recharge delay" : 0 + dmdelay(integer) : "Deathmatch recharge delay" : 30 _minlight(string) : "Minimum light level" : "0" ]