From 942776783b1e6ac87bbe706af61987683819707c Mon Sep 17 00:00:00 2001 From: Sergey Shorokhov Date: Sun, 16 Jul 2023 15:55:58 +0300 Subject: [PATCH] `mp_fadetoblack 2` fade timings now depends from `mp_dying_time` CVar and code fixes (#845) Fix forcing 1-person view for players when `mp_fadetoblack = 2`; Fix player blackout on server entry when `mp_fadetoblack = 2`; Fix observer not being blinded when `mp_fadetoblack = 2`; Fix fadetoblack message timings using new CVar `mp_dying_time`. fix #501 fix #506 Co-authored-by: s1lentq --- regamedll/dlls/API/CSPlayer.cpp | 2 +- regamedll/dlls/animating.cpp | 5 +++ regamedll/dlls/animation.cpp | 15 ++++++++ regamedll/dlls/animation.h | 1 + regamedll/dlls/cbase.h | 1 + regamedll/dlls/client.cpp | 2 +- regamedll/dlls/combat.cpp | 2 +- regamedll/dlls/multiplay_gamerules.cpp | 6 +-- regamedll/dlls/observer.cpp | 4 +- regamedll/dlls/observer.h | 6 +++ regamedll/dlls/player.cpp | 51 ++++++++++++-------------- regamedll/dlls/player.h | 1 + 12 files changed, 61 insertions(+), 35 deletions(-) diff --git a/regamedll/dlls/API/CSPlayer.cpp b/regamedll/dlls/API/CSPlayer.cpp index 2a8348cba..c59c314b9 100644 --- a/regamedll/dlls/API/CSPlayer.cpp +++ b/regamedll/dlls/API/CSPlayer.cpp @@ -58,7 +58,7 @@ EXT_FUNC bool CCSPlayer::JoinTeam(TeamName team) pPlayer->StartObserver(pentSpawnSpot->v.origin, pentSpawnSpot->v.angles); // do we have fadetoblack on? (need to fade their screen back in) - if (fadetoblack.value) + if (fadetoblack.value == FADETOBLACK_STAY) { UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN); } diff --git a/regamedll/dlls/animating.cpp b/regamedll/dlls/animating.cpp index 8e7d84334..9e104f22e 100644 --- a/regamedll/dlls/animating.cpp +++ b/regamedll/dlls/animating.cpp @@ -179,6 +179,11 @@ NOXREF int CBaseAnimating::GetBodygroup(int iGroup) return ::GetBodygroup(GET_MODEL_PTR(ENT(pev)), pev, iGroup); } +float CBaseAnimating::GetSequenceDuration() const +{ + return ::GetSequenceDuration(GET_MODEL_PTR(ENT(pev)), pev); +} + int CBaseAnimating::ExtractBbox(int sequence, float *mins, float *maxs) { return ::ExtractBbox(GET_MODEL_PTR(ENT(pev)), sequence, mins, maxs); diff --git a/regamedll/dlls/animation.cpp b/regamedll/dlls/animation.cpp index 83c0bd403..7018396aa 100644 --- a/regamedll/dlls/animation.cpp +++ b/regamedll/dlls/animation.cpp @@ -246,6 +246,21 @@ void GetSequenceInfo(void *pmodel, entvars_t *pev, float *pflFrameRate, float *p *pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1); } +float GetSequenceDuration(void *pmodel, entvars_t *pev) +{ + studiohdr_t *pstudiohdr = (studiohdr_t *)pmodel; + if (!pstudiohdr) + return 0; // model ptr is not valid + + if (pev->sequence < 0 || pev->sequence >= pstudiohdr->numseq) + return 0; // sequence is not valid + + // get current sequence time + mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + int(pev->sequence); + + return pseqdesc->numframes / pseqdesc->fps; +} + int GetSequenceFlags(void *pmodel, entvars_t *pev) { studiohdr_t *pstudiohdr = (studiohdr_t *)pmodel; diff --git a/regamedll/dlls/animation.h b/regamedll/dlls/animation.h index 54af21a8c..7889a140b 100644 --- a/regamedll/dlls/animation.h +++ b/regamedll/dlls/animation.h @@ -42,6 +42,7 @@ int LookupActivity(void *pmodel, entvars_t *pev, int activity); int LookupActivityHeaviest(void *pmodel, entvars_t *pev, int activity); int LookupSequence(void *pmodel, const char *label); void GetSequenceInfo(void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed); +float GetSequenceDuration(void *pmodel, entvars_t *pev); int GetSequenceFlags(void *pmodel, entvars_t *pev); float SetController(void *pmodel, entvars_t *pev, int iController, float flValue); float SetBlending(void *pmodel, entvars_t *pev, int iBlender, float flValue); diff --git a/regamedll/dlls/cbase.h b/regamedll/dlls/cbase.h index 1e11bbeef..146245c76 100644 --- a/regamedll/dlls/cbase.h +++ b/regamedll/dlls/cbase.h @@ -369,6 +369,7 @@ class CBaseAnimating: public CBaseDelay { float SetBoneController(int iController, float flValue = 0.0f); void InitBoneControllers(); + float GetSequenceDuration() const; float SetBlending(int iBlender, float flValue); void GetBonePosition(int iBone, Vector &origin, Vector &angles); void GetAutomovement(Vector &origin, Vector &angles, float flInterval = 0.1f); diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp index cd52b7bc3..22f58938b 100644 --- a/regamedll/dlls/client.cpp +++ b/regamedll/dlls/client.cpp @@ -1911,7 +1911,7 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *pPlayer, int slot) MESSAGE_END(); #endif // do we have fadetoblack on? (need to fade their screen back in) - if (fadetoblack.value) + if (fadetoblack.value == FADETOBLACK_STAY) { UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN); } diff --git a/regamedll/dlls/combat.cpp b/regamedll/dlls/combat.cpp index 620c84cfd..390c8d613 100644 --- a/regamedll/dlls/combat.cpp +++ b/regamedll/dlls/combat.cpp @@ -4,7 +4,7 @@ void PlayerBlind(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAt { UTIL_ScreenFade(pPlayer, color, fadeTime, fadeHold, alpha, 0); - if (!fadetoblack.value) + if (fadetoblack.value != FADETOBLACK_STAY) { for (int i = 1; i <= gpGlobals->maxClients; i++) { diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index baf916589..03948aafa 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -2393,7 +2393,7 @@ void CHalfLifeMultiplay::Think() MESSAGE_BEGIN(MSG_ALL, gmsgForceCam); WRITE_BYTE(forcecamera.value != 0); WRITE_BYTE(forcechasecam.value != 0); - WRITE_BYTE(fadetoblack.value != 0); + WRITE_BYTE(fadetoblack.value == FADETOBLACK_STAY); MESSAGE_END(); m_flForceCameraValue = forcecamera.value; @@ -3456,7 +3456,7 @@ void CHalfLifeMultiplay::InitHUD(CBasePlayer *pl) MESSAGE_BEGIN(MSG_ONE, gmsgForceCam, nullptr, pl->edict()); WRITE_BYTE(forcecamera.value != 0); WRITE_BYTE(forcechasecam.value != 0); - WRITE_BYTE(fadetoblack.value != 0); + WRITE_BYTE(fadetoblack.value == FADETOBLACK_STAY); MESSAGE_END(); if (m_bGameOver) @@ -3874,7 +3874,7 @@ BOOL EXT_FUNC CHalfLifeMultiplay::__API_HOOK(FPlayerCanRespawn)(CBasePlayer *pPl { // If this player just connected and fadetoblack is on, then maybe // the server admin doesn't want him peeking around. - if (fadetoblack.value != 0.0f) + if (fadetoblack.value == FADETOBLACK_STAY) { UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT)); } diff --git a/regamedll/dlls/observer.cpp b/regamedll/dlls/observer.cpp index 336b7b3cc..c35b17f9a 100644 --- a/regamedll/dlls/observer.cpp +++ b/regamedll/dlls/observer.cpp @@ -6,7 +6,7 @@ int __API_HOOK(GetForceCamera)(CBasePlayer *pObserver) { int retVal; - if (!fadetoblack.value) + if (fadetoblack.value != FADETOBLACK_STAY) { retVal = int(CVAR_GET_FLOAT("mp_forcechasecam")); @@ -51,7 +51,7 @@ void UpdateClientEffects(CBasePlayer *pObserver, int oldMode) { bool clearProgress = false; bool clearBlindness = false; - bool blindnessOk = (fadetoblack.value == 0); + bool blindnessOk = (fadetoblack.value != FADETOBLACK_STAY); bool clearNightvision = false; if (pObserver->GetObserverMode() == OBS_IN_EYE) diff --git a/regamedll/dlls/observer.h b/regamedll/dlls/observer.h index 722c977a4..743936ff9 100644 --- a/regamedll/dlls/observer.h +++ b/regamedll/dlls/observer.h @@ -32,6 +32,12 @@ #define CAMERA_MODE_SPEC_ONLY_TEAM 1 #define CAMERA_MODE_SPEC_ONLY_FIRST_PERSON 2 +enum FadeToBlack { + FADETOBLACK_OFF, + FADETOBLACK_STAY, + FADETOBLACK_AT_DYING, +}; + int GetForceCamera(CBasePlayer *pObserver); void UpdateClientEffects(CBasePlayer *pObserver, int oldMode); diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index b8c800795..469eb4d6b 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -2292,6 +2292,8 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib) UTIL_ScreenFade(this, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT)); } #else + + float flDyingDuration = GetSequenceDuration() + CGameRules::GetDyingTime(); switch ((int)fadetoblack.value) { default: @@ -2307,12 +2309,12 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib) break; } - case 1: + case FADETOBLACK_STAY: { - UTIL_ScreenFade(this, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT)); + UTIL_ScreenFade(this, Vector(0, 0, 0), 0.8f, flDyingDuration, 255, (FFADE_OUT | FFADE_STAYOUT)); break; } - case 2: + case FADETOBLACK_AT_DYING: { pev->iuser1 = OBS_CHASE_FREE; pev->iuser2 = ENTINDEX(edict()); @@ -2323,15 +2325,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib) MESSAGE_BEGIN(MSG_ONE, gmsgADStop, nullptr, pev); MESSAGE_END(); - for (int i = 1; i <= gpGlobals->maxClients; i++) - { - CBasePlayer* pObserver = UTIL_PlayerByIndex(i); - - if (pObserver == this || (pObserver && pObserver->IsObservingPlayer(this))) - { - UTIL_ScreenFade(pObserver, Vector(0, 0, 0), 1, 4, 255, (FFADE_OUT)); - } - } + UTIL_ScreenFade(this, Vector(0, 0, 0), 0.8f, flDyingDuration, 255, (FFADE_OUT)); break; } @@ -8811,6 +8805,23 @@ int GetPlayerGaitsequence(const edict_t *pEdict) return pPlayer->m_iGaitsequence; } +float CBasePlayer::GetDyingAnimationDuration() const +{ + float animDuration = -1.0f; + + if (CGameRules::GetDyingTime() < DEATH_ANIMATION_TIME) // a short time, timeDiff estimates to be small + { + float flSequenceDuration = GetSequenceDuration(); + if (flSequenceDuration > 0) + animDuration = flSequenceDuration; + } + + if (animDuration <= 0) + animDuration = CGameRules::GetDyingTime(); // in case of failure + + return animDuration; +} + void CBasePlayer::SpawnClientSideCorpse() { #ifdef REGAMEDLL_FIXES @@ -8833,21 +8844,7 @@ void CBasePlayer::SpawnClientSideCorpse() #ifdef REGAMEDLL_ADD if (CGameRules::GetDyingTime() < DEATH_ANIMATION_TIME) // a short time, timeDiff estimates to be small { - float animDuration = -1.0; - - studiohdr_t *pstudiohdr = (studiohdr_t *)GET_MODEL_PTR(ENT(pev)); - if (pstudiohdr && pev->sequence < pstudiohdr->numseq) // model ptr and sequence validation - { - // get current sequence time - mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + int(pev->sequence); - animDuration = pseqdesc->numframes / pseqdesc->fps; - } - - if (animDuration <= 0.0) - { - // in case of failure - animDuration = DEATH_ANIMATION_TIME; - } + float animDuration = GetDyingAnimationDuration(); // client receives a negative value animDuration *= -1.0; diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h index e2f76c680..f1e7009d5 100644 --- a/regamedll/dlls/player.h +++ b/regamedll/dlls/player.h @@ -453,6 +453,7 @@ class CBasePlayer: public CBaseMonster { static CBasePlayer *Instance(entvars_t *pev) { return Instance(ENT(pev)); } static CBasePlayer *Instance(int offset) { return Instance(ENT(offset)); } + float GetDyingAnimationDuration() const; void SpawnClientSideCorpse(); void Observer_FindNextPlayer(bool bReverse, const char *name = nullptr); CBasePlayer *Observer_IsValidTarget(int iPlayerIndex, bool bSameTeam);