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 <s1lentsk@yandex.ru>
This commit is contained in:
Sergey Shorokhov 2023-07-16 15:55:58 +03:00 committed by GitHub
parent c526fa5885
commit 942776783b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 61 additions and 35 deletions

View File

@ -58,7 +58,7 @@ EXT_FUNC bool CCSPlayer::JoinTeam(TeamName team)
pPlayer->StartObserver(pentSpawnSpot->v.origin, pentSpawnSpot->v.angles); pPlayer->StartObserver(pentSpawnSpot->v.origin, pentSpawnSpot->v.angles);
// do we have fadetoblack on? (need to fade their screen back in) // 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); UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN);
} }

View File

@ -179,6 +179,11 @@ NOXREF int CBaseAnimating::GetBodygroup(int iGroup)
return ::GetBodygroup(GET_MODEL_PTR(ENT(pev)), pev, 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) int CBaseAnimating::ExtractBbox(int sequence, float *mins, float *maxs)
{ {
return ::ExtractBbox(GET_MODEL_PTR(ENT(pev)), sequence, mins, maxs); return ::ExtractBbox(GET_MODEL_PTR(ENT(pev)), sequence, mins, maxs);

View File

@ -246,6 +246,21 @@ void GetSequenceInfo(void *pmodel, entvars_t *pev, float *pflFrameRate, float *p
*pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1); *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) int GetSequenceFlags(void *pmodel, entvars_t *pev)
{ {
studiohdr_t *pstudiohdr = (studiohdr_t *)pmodel; studiohdr_t *pstudiohdr = (studiohdr_t *)pmodel;

View File

@ -42,6 +42,7 @@ int LookupActivity(void *pmodel, entvars_t *pev, int activity);
int LookupActivityHeaviest(void *pmodel, entvars_t *pev, int activity); int LookupActivityHeaviest(void *pmodel, entvars_t *pev, int activity);
int LookupSequence(void *pmodel, const char *label); int LookupSequence(void *pmodel, const char *label);
void GetSequenceInfo(void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed); 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); int GetSequenceFlags(void *pmodel, entvars_t *pev);
float SetController(void *pmodel, entvars_t *pev, int iController, float flValue); float SetController(void *pmodel, entvars_t *pev, int iController, float flValue);
float SetBlending(void *pmodel, entvars_t *pev, int iBlender, float flValue); float SetBlending(void *pmodel, entvars_t *pev, int iBlender, float flValue);

View File

@ -369,6 +369,7 @@ public:
float SetBoneController(int iController, float flValue = 0.0f); float SetBoneController(int iController, float flValue = 0.0f);
void InitBoneControllers(); void InitBoneControllers();
float GetSequenceDuration() const;
float SetBlending(int iBlender, float flValue); float SetBlending(int iBlender, float flValue);
void GetBonePosition(int iBone, Vector &origin, Vector &angles); void GetBonePosition(int iBone, Vector &origin, Vector &angles);
void GetAutomovement(Vector &origin, Vector &angles, float flInterval = 0.1f); void GetAutomovement(Vector &origin, Vector &angles, float flInterval = 0.1f);

View File

@ -1911,7 +1911,7 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *pPlayer, int slot)
MESSAGE_END(); MESSAGE_END();
#endif #endif
// do we have fadetoblack on? (need to fade their screen back in) // 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); UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN);
} }

View File

@ -4,7 +4,7 @@ void PlayerBlind(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAt
{ {
UTIL_ScreenFade(pPlayer, color, fadeTime, fadeHold, alpha, 0); UTIL_ScreenFade(pPlayer, color, fadeTime, fadeHold, alpha, 0);
if (!fadetoblack.value) if (fadetoblack.value != FADETOBLACK_STAY)
{ {
for (int i = 1; i <= gpGlobals->maxClients; i++) for (int i = 1; i <= gpGlobals->maxClients; i++)
{ {

View File

@ -2393,7 +2393,7 @@ void CHalfLifeMultiplay::Think()
MESSAGE_BEGIN(MSG_ALL, gmsgForceCam); MESSAGE_BEGIN(MSG_ALL, gmsgForceCam);
WRITE_BYTE(forcecamera.value != 0); WRITE_BYTE(forcecamera.value != 0);
WRITE_BYTE(forcechasecam.value != 0); WRITE_BYTE(forcechasecam.value != 0);
WRITE_BYTE(fadetoblack.value != 0); WRITE_BYTE(fadetoblack.value == FADETOBLACK_STAY);
MESSAGE_END(); MESSAGE_END();
m_flForceCameraValue = forcecamera.value; m_flForceCameraValue = forcecamera.value;
@ -3456,7 +3456,7 @@ void CHalfLifeMultiplay::InitHUD(CBasePlayer *pl)
MESSAGE_BEGIN(MSG_ONE, gmsgForceCam, nullptr, pl->edict()); MESSAGE_BEGIN(MSG_ONE, gmsgForceCam, nullptr, pl->edict());
WRITE_BYTE(forcecamera.value != 0); WRITE_BYTE(forcecamera.value != 0);
WRITE_BYTE(forcechasecam.value != 0); WRITE_BYTE(forcechasecam.value != 0);
WRITE_BYTE(fadetoblack.value != 0); WRITE_BYTE(fadetoblack.value == FADETOBLACK_STAY);
MESSAGE_END(); MESSAGE_END();
if (m_bGameOver) 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 // If this player just connected and fadetoblack is on, then maybe
// the server admin doesn't want him peeking around. // 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)); UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT));
} }

View File

@ -6,7 +6,7 @@ int __API_HOOK(GetForceCamera)(CBasePlayer *pObserver)
{ {
int retVal; int retVal;
if (!fadetoblack.value) if (fadetoblack.value != FADETOBLACK_STAY)
{ {
retVal = int(CVAR_GET_FLOAT("mp_forcechasecam")); retVal = int(CVAR_GET_FLOAT("mp_forcechasecam"));
@ -51,7 +51,7 @@ void UpdateClientEffects(CBasePlayer *pObserver, int oldMode)
{ {
bool clearProgress = false; bool clearProgress = false;
bool clearBlindness = false; bool clearBlindness = false;
bool blindnessOk = (fadetoblack.value == 0); bool blindnessOk = (fadetoblack.value != FADETOBLACK_STAY);
bool clearNightvision = false; bool clearNightvision = false;
if (pObserver->GetObserverMode() == OBS_IN_EYE) if (pObserver->GetObserverMode() == OBS_IN_EYE)

View File

@ -32,6 +32,12 @@
#define CAMERA_MODE_SPEC_ONLY_TEAM 1 #define CAMERA_MODE_SPEC_ONLY_TEAM 1
#define CAMERA_MODE_SPEC_ONLY_FIRST_PERSON 2 #define CAMERA_MODE_SPEC_ONLY_FIRST_PERSON 2
enum FadeToBlack {
FADETOBLACK_OFF,
FADETOBLACK_STAY,
FADETOBLACK_AT_DYING,
};
int GetForceCamera(CBasePlayer *pObserver); int GetForceCamera(CBasePlayer *pObserver);
void UpdateClientEffects(CBasePlayer *pObserver, int oldMode); void UpdateClientEffects(CBasePlayer *pObserver, int oldMode);

View File

@ -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)); UTIL_ScreenFade(this, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT));
} }
#else #else
float flDyingDuration = GetSequenceDuration() + CGameRules::GetDyingTime();
switch ((int)fadetoblack.value) switch ((int)fadetoblack.value)
{ {
default: default:
@ -2307,12 +2309,12 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
break; 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; break;
} }
case 2: case FADETOBLACK_AT_DYING:
{ {
pev->iuser1 = OBS_CHASE_FREE; pev->iuser1 = OBS_CHASE_FREE;
pev->iuser2 = ENTINDEX(edict()); 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_BEGIN(MSG_ONE, gmsgADStop, nullptr, pev);
MESSAGE_END(); MESSAGE_END();
for (int i = 1; i <= gpGlobals->maxClients; i++) UTIL_ScreenFade(this, Vector(0, 0, 0), 0.8f, flDyingDuration, 255, (FFADE_OUT));
{
CBasePlayer* pObserver = UTIL_PlayerByIndex(i);
if (pObserver == this || (pObserver && pObserver->IsObservingPlayer(this)))
{
UTIL_ScreenFade(pObserver, Vector(0, 0, 0), 1, 4, 255, (FFADE_OUT));
}
}
break; break;
} }
@ -8811,6 +8805,23 @@ int GetPlayerGaitsequence(const edict_t *pEdict)
return pPlayer->m_iGaitsequence; 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() void CBasePlayer::SpawnClientSideCorpse()
{ {
#ifdef REGAMEDLL_FIXES #ifdef REGAMEDLL_FIXES
@ -8833,21 +8844,7 @@ void CBasePlayer::SpawnClientSideCorpse()
#ifdef REGAMEDLL_ADD #ifdef REGAMEDLL_ADD
if (CGameRules::GetDyingTime() < DEATH_ANIMATION_TIME) // a short time, timeDiff estimates to be small if (CGameRules::GetDyingTime() < DEATH_ANIMATION_TIME) // a short time, timeDiff estimates to be small
{ {
float animDuration = -1.0; float animDuration = GetDyingAnimationDuration();
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;
}
// client receives a negative value // client receives a negative value
animDuration *= -1.0; animDuration *= -1.0;

View File

@ -453,6 +453,7 @@ public:
static CBasePlayer *Instance(entvars_t *pev) { return Instance(ENT(pev)); } static CBasePlayer *Instance(entvars_t *pev) { return Instance(ENT(pev)); }
static CBasePlayer *Instance(int offset) { return Instance(ENT(offset)); } static CBasePlayer *Instance(int offset) { return Instance(ENT(offset)); }
float GetDyingAnimationDuration() const;
void SpawnClientSideCorpse(); void SpawnClientSideCorpse();
void Observer_FindNextPlayer(bool bReverse, const char *name = nullptr); void Observer_FindNextPlayer(bool bReverse, const char *name = nullptr);
CBasePlayer *Observer_IsValidTarget(int iPlayerIndex, bool bSameTeam); CBasePlayer *Observer_IsValidTarget(int iPlayerIndex, bool bSameTeam);