diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index ddd19420d94..240b62a2fbd 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -5007,18 +5007,19 @@ void CClient::GetSmoothTick(int *pSmoothTick, float *pSmoothIntraTick, float Mix int64_t SmoothTime = clamp(GameTime + (int64_t)(MixAmount * (PredTime - GameTime)), GameTime, PredTime); *pSmoothTick = (int)(SmoothTime * GameTickSpeed() / time_freq()) + 1 + g_Config.m_ClFastInput; - *pSmoothIntraTick = (SmoothTime - (*pSmoothTick - 1) * time_freq() / GameTickSpeed()) / (float)(time_freq() / GameTickSpeed()); + *pSmoothIntraTick = (SmoothTime - (*pSmoothTick - 1 - g_Config.m_ClFastInput) * time_freq() / GameTickSpeed()) / (float)(time_freq() / GameTickSpeed()); } void CClient::GetSmoothFreezeTick(int *pSmoothTick, float *pSmoothIntraTick, float MixAmount) { int64_t GameTime = m_aGameTime[g_Config.m_ClDummy].Get(time_get()); int64_t PredTime = m_PredictedTime.Get(time_get()); + GameTime = std::min(GameTime, PredTime); int64_t UpperPredTime = clamp(PredTime - (time_freq() / 50) * g_Config.m_ClUnfreezeLagTicks, GameTime, PredTime); int64_t LowestPredTime = clamp(PredTime, GameTime, UpperPredTime); int64_t SmoothTime = clamp(LowestPredTime + (int64_t)(MixAmount * (PredTime - LowestPredTime)), LowestPredTime, PredTime); *pSmoothTick = (int)(SmoothTime * 50 / time_freq()) + 1 + g_Config.m_ClFastInput; - *pSmoothIntraTick = (SmoothTime - (*pSmoothTick - 1) * time_freq() / 50) / (float)(time_freq() / 50); + *pSmoothIntraTick = (SmoothTime - (*pSmoothTick - 1 - g_Config.m_ClFastInput) * time_freq() / 50) / (float)(time_freq() / 50); } void CClient::AddWarning(const SWarning &Warning) { diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 7746202bf1e..de66dbbbca3 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -3300,7 +3300,7 @@ void CMenus::RenderSettingsTClient(CUIRect MainView) g_Config.m_ClRunOnJoinDelay = Delay; } } - DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClFreezeUpdateFix, ("Update tee skin faster after being frozen (slightly buggy)"), &g_Config.m_ClFreezeUpdateFix, &MainView, LineMargin); + DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClFreezeUpdateFix, ("Update tee skin faster after being frozen"), &g_Config.m_ClFreezeUpdateFix, &MainView, LineMargin); DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClShowCenterLines, ("Show screen center"), &g_Config.m_ClShowCenterLines, &MainView, LineMargin); DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClPingNameCircle, ("Show ping colored circle before names"), &g_Config.m_ClPingNameCircle, &MainView, LineMargin); DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClWhiteFeet, ("Render all custom colored feet as white feet skin"), &g_Config.m_ClWhiteFeet, &MainView, LineMargin); @@ -3331,7 +3331,7 @@ void CMenus::RenderSettingsTClient(CUIRect MainView) Ui()->DoEditBox(&s_LastInput, &Button, 12.0f); MainView.HSplitTop(20.0f, &Section, &MainView); - DoLine_ColorPicker(&NotifyWhenLastTextID, 22.0f, 150.0f, 14.0f, &Section, ("Notification Color"), &g_Config.m_ClNotifyWhenLastColor, ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f), false); + DoLine_ColorPicker(&NotifyWhenLastTextID, 22.0f, 13.0f, 14.0f, &Section, ("Notification Color"), &g_Config.m_ClNotifyWhenLastColor, ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f), false); } CUIRect ButtonVerify, EnableVerifySection; MainView.HSplitTop(LineMargin, &EnableVerifySection, &MainView); @@ -3351,6 +3351,9 @@ void CMenus::RenderSettingsTClient(CUIRect MainView) DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClRenderCursorSpec, ("Show your cursor when in free spectate"), &g_Config.m_ClRenderCursorSpec, &MainView, LineMargin); DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClShowSkinName, ("Show skin names in nameplate"), &g_Config.m_ClShowSkinName, &MainView, LineMargin); + DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClFreezeStars, ("Freeze Stars"), &g_Config.m_ClFreezeStars, &MainView, LineMargin); + DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClColorFreeze, ("Color Frozen Tee Skins"), &g_Config.m_ClColorFreeze, &MainView, LineMargin); + //{ // CUIRect Button, Label; // MainView.HSplitTop(20.0f, &Button, &MainView); @@ -3425,7 +3428,19 @@ void CMenus::RenderSettingsTClient(CUIRect MainView) MainView.HSplitTop(25.0f, &Section, &MainView); DoLine_ColorPicker(&OutlineColorUnfreezeID, 25.0f, 13.0f, 5.0f, &Section, ("Unfreeze Outline Color"), &g_Config.m_ClOutlineColorUnfreeze, ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f), false); + + MainView.HSplitTop(5.0f, 0x0, &MainView); + MainView.HSplitTop(30.0f, &Section, &MainView); + Ui()->DoLabel(&Section, Localize("Input"), 20.0f, TEXTALIGN_LEFT); + MainView.VSplitLeft(5.0f, 0x0, &MainView); + MainView.HSplitTop(5.0f, 0x0, &MainView); + DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClFastInput, ("Fast Inputs (-20ms visual input delay)"), &g_Config.m_ClFastInput, &MainView, LineMargin); + if(g_Config.m_ClFastInput) + { + MainView.HSplitTop(10.0f, 0x0, &MainView); + DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClFastInputOthers, ("Extra tick other tees (increases other tees visual latency, \n makes dragging slightly easier when using fast input)"), &g_Config.m_ClFastInputOthers, &MainView, LineMargin); + } { CUIRect Button; CUIRect ExtMenu; @@ -3597,7 +3612,8 @@ void CMenus::RenderSettingsTClient(CUIRect MainView) char aBuf[64]; str_format(aBuf, sizeof(aBuf), "%s: %ims", "Delay", g_Config.m_ClUnfreezeLagDelayTicks * 20); Ui()->DoLabel(&Label, aBuf, 14.0f, TEXTALIGN_LEFT); - g_Config.m_ClUnfreezeLagDelayTicks = (int)(Ui()->DoScrollbarH(&g_Config.m_ClUnfreezeLagDelayTicks, &Button, (g_Config.m_ClUnfreezeLagDelayTicks) / 200.0f) * 200.0f); + g_Config.m_ClUnfreezeLagDelayTicks = (int)(Ui()->DoScrollbarH(&g_Config.m_ClUnfreezeLagDelayTicks, &Button, (g_Config.m_ClUnfreezeLagDelayTicks) / 150.0f) * 150.0f); + g_Config.m_ClUnfreezeLagDelayTicks = std::max(g_Config.m_ClUnfreezeLagDelayTicks, g_Config.m_ClUnfreezeLagTicks); } if(g_Config.m_ClRemoveAnti) { @@ -3609,10 +3625,6 @@ void CMenus::RenderSettingsTClient(CUIRect MainView) Ui()->DoLabel(&Label, aBuf, 14.0f, TEXTALIGN_LEFT); g_Config.m_ClUnfreezeLagTicks = (int)(Ui()->DoScrollbarH(&g_Config.m_ClUnfreezeLagTicks, &Button, (g_Config.m_ClUnfreezeLagTicks) / 15.0f) * 15.0f); } - if(g_Config.m_ClRemoveAnti) - { - DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClAdjustRemovedDelay, ("Add amount back if you are not currently in freeze"), &g_Config.m_ClAdjustRemovedDelay, &MainView, LineMargin); - } DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClUnpredOthersInFreeze, ("Dont predict other players if you are frozen"), &g_Config.m_ClUnpredOthersInFreeze, &MainView, LineMargin); DoButton_CheckBoxAutoVMarginAndSet(&g_Config.m_ClPredMarginInFreeze, ("Adjust your prediction margin while frozen"), &g_Config.m_ClPredMarginInFreeze, &MainView, LineMargin); diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 7d40dd074f6..15881eb3c66 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -2129,6 +2129,9 @@ void CGameClient::OnPredict() { m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld); m_PredictedPrevChar = pLocalChar->GetCore(); + } + if(Tick == FinalTick - (1 - g_Config.m_ClFastInputOthers)) + { for(int i = 0; i < MAX_CLIENTS; i++) if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i)) m_aClients[i].m_PrevPredicted = pChar->GetCore(); @@ -2163,6 +2166,9 @@ void CGameClient::OnPredict() if(Tick == FinalTick) { m_PredictedChar = pLocalChar->GetCore(); + } + if (Tick == FinalTick - (1 - g_Config.m_ClFastInputOthers)) + { for(int i = 0; i < MAX_CLIENTS; i++) if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i)) m_aClients[i].m_Predicted = pChar->GetCore(); @@ -2183,26 +2189,6 @@ void CGameClient::OnPredict() vec2 Pos = pLocalChar->Core()->m_Pos; int Events = pLocalChar->Core()->m_TriggeredEvents; - // for(int i = 0; i < MAX_CLIENTS; i++) - //{ - // if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i)) - // { - // if(pChar->m_FreezeTime % Client()->GameTickSpeed() == Client()->GameTickSpeed() - 1) - // { - // int Amount = (pChar->m_FreezeTime + 1) / Client()->GameTickSpeed(); - // float a = 3 * pi / 2; - // float s = a - pi / 3; - // float e = a + pi / 3; - // for(int i = 0; i < Amount; i++) - // { - // float f = mix(s, e, (i + 1) / (float)(Amount + 2)); - // vec2 Dir = vec2(cos(f), sin(f)); - // m_Effects.DamageIndicator(pChar->m_Pos, Dir); - // } - // } - // } - // } - if(g_Config.m_ClPredict && !m_SuppressEvents) if(Events & COREEVENT_AIR_JUMP) m_Effects.AirJump(Pos, 1.0f); @@ -2232,6 +2218,40 @@ void CGameClient::OnPredict() if(g_Config.m_ClFastInput) m_PredictedWorld.CopyWorld(&m_PrevPredictedWorld); + if(g_Config.m_ClRemoveAnti) + { + m_ExtraPredictedWorld.CopyWorld(&m_PredictedWorld); + CCharacter *pExtraChar = m_ExtraPredictedWorld.GetCharacterById(m_Snap.m_LocalClientId); + if(pExtraChar) + { + int AliveAccumulation = pExtraChar->m_AliveAccumulation; + bool Unfrozen = false; + bool Frozen = false; + for(int i = 0; i < g_Config.m_ClUnfreezeLagDelayTicks; i++) + { + if(!pExtraChar) + continue; + + if(Frozen && pExtraChar->m_AliveAccumulation > 0) + Unfrozen = true; + + if(pExtraChar->m_AliveAccumulation < 0) + Frozen = true; + + if(!Unfrozen) + { + m_ExtraPredictedWorld.m_GameTick++; + m_ExtraPredictedWorld.Tick(); + } + else + { + pExtraChar->m_AliveAccumulation = std::max(pExtraChar->m_AliveAccumulation, 1); + pExtraChar->m_AliveAccumulation = std::min(pExtraChar->m_AliveAccumulation + 1, g_Config.m_ClUnfreezeLagDelayTicks); + } + } + } + } + // detect mispredictions of other players and make corrections smoother when possible if(g_Config.m_ClAntiPingSmooth && Predict() && AntiPingPlayers() && m_NewTick && m_PredictedTick >= MIN_TICK && absolute(m_PredictedTick - Client()->PredGameTick(g_Config.m_ClDummy)) <= 1 && absolute(Client()->GameTick(g_Config.m_ClDummy) - Client()->PrevGameTick(g_Config.m_ClDummy)) <= 2) { @@ -3148,6 +3168,10 @@ vec2 CGameClient::GetSmoothPos(int ClientId) int SmoothTick; float SmoothIntra; Client()->GetSmoothTick(&SmoothTick, &SmoothIntra, MixAmount); + + if(ClientId != m_Snap.m_LocalClientId && !g_Config.m_ClFastInputOthers && g_Config.m_ClFastInput) + SmoothTick -= 1; + if(SmoothTick > 0 && m_aClients[ClientId].m_aPredTick[(SmoothTick - 1) % 200] >= Client()->PrevGameTick(g_Config.m_ClDummy) && m_aClients[ClientId].m_aPredTick[SmoothTick % 200] <= Client()->PredGameTick(g_Config.m_ClDummy)) Pos[i] = mix(m_aClients[ClientId].m_aPredPos[(SmoothTick - 1) % 200][i], m_aClients[ClientId].m_aPredPos[SmoothTick % 200][i], SmoothIntra); } @@ -3159,33 +3183,55 @@ vec2 CGameClient::GetFreezePos(int ClientId) { vec2 Pos = mix(m_aClients[ClientId].m_PrevPredicted.m_Pos, m_aClients[ClientId].m_Predicted.m_Pos, Client()->PredIntraGameTick(g_Config.m_ClDummy)); // int64_t Now = time_get(); - CCharacter *pChar = m_PredictedWorld.GetCharacterById(ClientId); + CCharacter *pChar = m_PredictedWorld.GetCharacterById(m_Snap.m_LocalClientId); + CCharacter *pExtraChar = m_ExtraPredictedWorld.GetCharacterById(m_Snap.m_LocalClientId); + + int64_t Now = time_get(); for(int i = 0; i < 2; i++) { - // int64_t Len = clamp(m_aClients[ClientId].m_SmoothLen[i], (int64_t)1, time_freq()); - // int64_t TimePassed = Now - m_aClients[ClientId].m_SmoothStart[i]; + //int64_t Len = clamp(m_aClients[ClientId].m_aSmoothLen[i], (int64_t)1, time_freq()); + //int64_t TimePassed = Now - m_aClients[ClientId].m_aSmoothStart[i]; float MixAmount = 0.0f; int SmoothTick; float SmoothIntra; - int TicksFrozen = 0; - if(pChar && ClientId == m_Snap.m_LocalClientId) + int AdjustTicks = 0; + int DelayTicks = g_Config.m_ClUnfreezeLagDelayTicks; + int FreezeTime = 0; + if(pExtraChar && pChar) { - TicksFrozen = pChar->m_FreezeAccumulation; - } + AdjustTicks = pChar->m_FreezeAccumulation; + if(pExtraChar->m_AliveAccumulation > 0) + AdjustTicks -= pExtraChar->m_AliveAccumulation; - if(g_Config.m_ClRemoveAnti && pChar && pChar->m_FreezeTime > 0) + AdjustTicks = std::max(AdjustTicks, 0); + FreezeTime = pChar->m_FreezeTime; + + AdjustTicks = std::min(FreezeTime, AdjustTicks); + } + if(g_Config.m_ClRemoveAnti && pChar && AdjustTicks > 0 && FreezeTime > 0) { - MixAmount = mix(0.0f, 1.0f, 1.0f - std::min((float)TicksFrozen, (float)g_Config.m_ClUnfreezeLagDelayTicks) / (float)g_Config.m_ClUnfreezeLagDelayTicks); + MixAmount = mix(0.0f, 1.0f, 1.0f - AdjustTicks / (float)DelayTicks); } - else + //else if(AdjustTicks == 0 && ClientId != m_Snap.m_LocalClientId) + //{ + // MixAmount = 1.f - std::pow(1.f - TimePassed / (float)Len, 1.2f); + //} + else // our tee when not frozen { - MixAmount = 1.0f; + MixAmount = 1.f; } + Client()->GetSmoothFreezeTick(&SmoothTick, &SmoothIntra, MixAmount); - if(SmoothTick > 0 && m_aClients[ClientId].m_aPredTick[(SmoothTick - 1) % 200] >= Client()->PrevGameTick(g_Config.m_ClDummy) && m_aClients[ClientId].m_aPredTick[SmoothTick % 200] <= Client()->PredGameTick(g_Config.m_ClDummy)) + + if(ClientId != m_Snap.m_LocalClientId && !g_Config.m_ClFastInputOthers && g_Config.m_ClFastInput) + SmoothTick -= 1; + + if(SmoothTick > 0 && m_aClients[ClientId].m_aPredTick[(SmoothTick - 1) % 200] >= Client()->PrevGameTick(g_Config.m_ClDummy) && m_aClients[ClientId].m_aPredTick[SmoothTick % 200] <= Client()->PredGameTick(g_Config.m_ClDummy) + g_Config.m_ClFastInput) + { Pos[i] = mix(m_aClients[ClientId].m_aPredPos[(SmoothTick - 1) % 200][i], m_aClients[ClientId].m_aPredPos[SmoothTick % 200][i], SmoothIntra); + } } return Pos; } diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 8a12787b886..ae409219972 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -593,6 +593,7 @@ class CGameClient : public IGameClient CGameWorld m_GameWorld; CGameWorld m_PredictedWorld; CGameWorld m_PrevPredictedWorld; + CGameWorld m_ExtraPredictedWorld; std::vector &Switchers() { return m_GameWorld.m_Core.m_vSwitchers; } std::vector &PredSwitchers() { return m_PredictedWorld.m_Core.m_vSwitchers; } diff --git a/src/game/client/prediction/entities/character.cpp b/src/game/client/prediction/entities/character.cpp index b6f0f502fa3..ec9c19278ed 100644 --- a/src/game/client/prediction/entities/character.cpp +++ b/src/game/client/prediction/entities/character.cpp @@ -975,11 +975,16 @@ void CCharacter::DDRaceTick() m_Input.m_Hook = 0; } if(m_FreezeTime == 1) - UnFreeze(); + UnFreeze(); + + m_AliveAccumulation = std::min(m_AliveAccumulation - 1, 0); + m_AliveAccumulation = std::max(m_AliveAccumulation, -g_Config.m_ClUnfreezeLagDelayTicks); } - else + else { - m_FreezeAccumulation = 0; + m_AliveAccumulation = std::max(m_AliveAccumulation, 1); + m_AliveAccumulation = std::min(m_AliveAccumulation + 1, g_Config.m_ClUnfreezeLagDelayTicks); + } HandleTuneLayer(); @@ -999,12 +1004,12 @@ void CCharacter::DDRaceTick() break; } } - if (m_Core.m_IsInFreeze) { - m_FreezeAccumulation = std::min(m_FreezeAccumulation + 1, m_FreezeTime); + if (m_Core.m_IsInFreeze && IsGrounded()) { + m_FreezeAccumulation = std::min(m_FreezeAccumulation + 1, g_Config.m_ClUnfreezeLagDelayTicks); } else { - m_FreezeAccumulation = std::max(m_FreezeAccumulation - 1, 0); + m_FreezeAccumulation = std::min(m_FreezeAccumulation, m_FreezeTime); } } diff --git a/src/game/client/prediction/entities/character.h b/src/game/client/prediction/entities/character.h index 0ef5aea285b..9d51def3ea3 100644 --- a/src/game/client/prediction/entities/character.h +++ b/src/game/client/prediction/entities/character.h @@ -141,6 +141,7 @@ class CCharacter : public CEntity bool IsSuper() { return m_Core.m_Super; } int m_FreezeAccumulation; + int m_AliveAccumulation; private: // weapon info diff --git a/src/game/tater_variables.h b/src/game/tater_variables.h index db99a12095b..6fa470f2ba7 100644 --- a/src/game/tater_variables.h +++ b/src/game/tater_variables.h @@ -30,10 +30,9 @@ MACRO_CONFIG_INT(ClLimitMouseToScreen, tc_limit_mouse_to_screen, 0, 0, 2, CFGFLA MACRO_CONFIG_INT(ClFreezeUpdateFix, tc_freeze_update_fix, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Will change your skin faster when you enter freeze. ") MACRO_CONFIG_INT(ClRemoveAnti, tc_remove_anti, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Removes some amount of antiping & player prediction in freeze") MACRO_CONFIG_INT(ClUnfreezeLagTicks, tc_remove_anti_ticks, 5, 0, 20, CFGFLAG_CLIENT | CFGFLAG_SAVE, "The biggest amount of prediction ticks that are removed") -MACRO_CONFIG_INT(ClUnfreezeLagDelayTicks, tc_remove_anti_delay_ticks, 100, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "How many ticks it takes to remove the maximum prediction after being frozen") -MACRO_CONFIG_INT(ClAdjustRemovedDelay, tc_adjust_removed_delay, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Add delay back if you are not currently in freeze (helps up down saves)") -MACRO_CONFIG_INT(ClUnpredOthersInFreeze, tc_unpred_others_in_freeze, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Dont predict other players if you are frozen") +MACRO_CONFIG_INT(ClUnfreezeLagDelayTicks, tc_remove_anti_delay_ticks, 100, 0, 150, CFGFLAG_CLIENT | CFGFLAG_SAVE, "How many ticks it takes to remove the maximum prediction after being frozen") +MACRO_CONFIG_INT(ClUnpredOthersInFreeze, tc_unpred_others_in_freeze, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Dont predict other players if you are frozen") MACRO_CONFIG_INT(ClPredMarginInFreeze, tc_pred_margin_in_freeze, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "enable changing prediction margin while frozen") MACRO_CONFIG_INT(ClPredMarginInFreezeAmount, tc_pred_margin_in_freeze_amount, 15, 0, 2000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Set what your prediction margin while frozen should be") @@ -56,6 +55,7 @@ MACRO_CONFIG_INT(ClShowSkinName, tc_skin_name, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG //MACRO_CONFIG_INT(ClFreeGhost, tc_freeghost, 0, 0, 1, CFGFLAG_CLIENT , "") MACRO_CONFIG_INT(ClFastInput, tc_fast_input, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Uses input for prediction up to 20ms faster") +MACRO_CONFIG_INT(ClFastInputOthers, tc_fast_input_others, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Do an extra 1 tick (20ms) for other tees with your fast inputs. (increases visual latency, makes dragging easier)") MACRO_CONFIG_INT(ClColorFreeze, tc_color_freeze, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Use skin colors for frozen tees") MACRO_CONFIG_INT(ClColorFreezeDarken, tc_color_freeze_darken, 90, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Makes color of tees darker when in freeze (0-100)")