mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-19 09:12:19 +00:00
Compare commits
12 commits
13faf02ae6
...
d1d7c49212
Author | SHA1 | Date | |
---|---|---|---|
d1d7c49212 | |||
8d431f8feb | |||
80e2de13da | |||
66fb5d5d7f | |||
d3f0c2a156 | |||
6c0427d23c | |||
38324489a2 | |||
4dc74376e5 | |||
849fa743ba | |||
01f77c6059 | |||
ac806a37f9 | |||
ba9ba69d1e |
|
@ -1016,11 +1016,11 @@ void CClient::Render()
|
|||
GameClient()->OnRender();
|
||||
DebugRender();
|
||||
|
||||
if(State() == IClient::STATE_ONLINE && g_Config.m_ClAntiPingLimit)
|
||||
{
|
||||
int64_t Now = time_get();
|
||||
g_Config.m_ClAntiPing = (m_PredictedTime.Get(Now) - m_aGameTime[g_Config.m_ClDummy].Get(Now)) * 1000 / (float)time_freq() > g_Config.m_ClAntiPingLimit;
|
||||
}
|
||||
// if(State() == IClient::STATE_ONLINE && g_Config.m_ClAntiPingLimit)
|
||||
// {
|
||||
// int64_t Now = time_get();
|
||||
// g_Config.m_ClAntiPing = (m_PredictedTime.Get(Now) - m_aGameTime[g_Config.m_ClDummy].Get(Now)) * 1000 / (float)time_freq() > g_Config.m_ClAntiPingLimit;
|
||||
// }
|
||||
}
|
||||
|
||||
const char *CClient::LoadMap(const char *pName, const char *pFilename, SHA256_DIGEST *pWantedSha256, unsigned WantedCrc)
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
// client
|
||||
MACRO_CONFIG_INT(ClPredict, cl_predict, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict client movements")
|
||||
MACRO_CONFIG_INT(ClPredictDummy, cl_predict_dummy, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict dummy movements")
|
||||
MACRO_CONFIG_INT(ClAntiPingLimit, cl_antiping_limit, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Antiping limit (0 to disable)")
|
||||
MACRO_CONFIG_INT(ClAntiPingLimit, cl_antiping_limit, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Adds delay to antiping (0 to disable)")
|
||||
MACRO_CONFIG_INT(ClAntiPingpercent, cl_antiping_percent, 100, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "how far ahead Antiping predicts, ignored when antiping limit is used")
|
||||
MACRO_CONFIG_INT(ClAntiPing, cl_antiping, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable antiping, i. e. more aggressive prediction.")
|
||||
MACRO_CONFIG_INT(ClAntiPingPlayers, cl_antiping_players, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict other player's movement more aggressively (only enabled if cl_antiping is set to 1)")
|
||||
MACRO_CONFIG_INT(ClAntiPingGrenade, cl_antiping_grenade, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict grenades (only enabled if cl_antiping is set to 1)")
|
||||
|
@ -73,6 +74,7 @@ MACRO_CONFIG_INT(ClShowfps, cl_showfps, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE,
|
|||
MACRO_CONFIG_INT(ClShowpred, cl_showpred, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show ingame prediction time in milliseconds")
|
||||
MACRO_CONFIG_INT(ClEyeWheel, cl_eye_wheel, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show eye wheel along together with emotes")
|
||||
MACRO_CONFIG_INT(ClEyeDuration, cl_eye_duration, 999999, 1, 999999, CFGFLAG_CLIENT | CFGFLAG_SAVE, "How long the eyes emotes last")
|
||||
MACRO_CONFIG_INT(ClFreezeStars, cl_freeze_stars, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show old star particles for frozen tees")
|
||||
|
||||
MACRO_CONFIG_INT(ClAirjumpindicator, cl_airjumpindicator, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show the air jump indicator")
|
||||
MACRO_CONFIG_INT(ClThreadsoundloading, cl_threadsoundloading, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Load sound files threaded")
|
||||
|
|
|
@ -58,9 +58,11 @@ void CItems::RenderProjectile(const CProjectileData *pCurrent, int ItemId)
|
|||
|
||||
bool IsOtherTeam = (pCurrent->m_ExtraInfo && pCurrent->m_Owner >= 0 && m_pClient->IsOtherTeam(pCurrent->m_Owner));
|
||||
|
||||
int predictTick = GameClient()->GetPredictionTick();
|
||||
|
||||
float Ct;
|
||||
if(m_pClient->Predict() && m_pClient->AntiPingGrenade() && LocalPlayerInGame && !IsOtherTeam)
|
||||
Ct = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
|
||||
Ct = ((float)(predictTick - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
|
||||
else
|
||||
Ct = (Client()->PrevGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) / (float)Client()->GameTickSpeed() + s_LastGameTickTime;
|
||||
if(Ct < 0)
|
||||
|
@ -304,9 +306,11 @@ void CItems::RenderLaser(const CLaserData *pCurrent, bool IsPredicted)
|
|||
{
|
||||
Dir = normalize_pre_length(Pos - From, Len);
|
||||
|
||||
int predictTick = GameClient()->GetPredictionTick();
|
||||
|
||||
float Ticks;
|
||||
if(IsPredicted)
|
||||
Ticks = (float)(Client()->PredGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy);
|
||||
Ticks = (float)(predictTick - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy);
|
||||
else
|
||||
Ticks = (float)(Client()->GameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->IntraGameTick(g_Config.m_ClDummy);
|
||||
float Ms = (Ticks / Client()->GameTickSpeed()) * 1000.0f;
|
||||
|
@ -377,7 +381,7 @@ void CItems::OnRender()
|
|||
auto &aSwitchers = GameClient()->Switchers();
|
||||
if(UsePredicted)
|
||||
{
|
||||
for(auto *pProj = (CProjectile *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity())
|
||||
for(auto *pProj = (CProjectile *)GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity())
|
||||
{
|
||||
if(!IsSuper && pProj->m_Number > 0 && pProj->m_Number < (int)aSwitchers.size() && !aSwitchers[pProj->m_Number].m_aStatus[SwitcherTeam] && (pProj->m_Explosive ? BlinkingProjEx : BlinkingProj))
|
||||
continue;
|
||||
|
@ -385,7 +389,7 @@ void CItems::OnRender()
|
|||
CProjectileData Data = pProj->GetData();
|
||||
RenderProjectile(&Data, pProj->GetId());
|
||||
}
|
||||
for(CEntity *pEnt = GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_LASER); pEnt; pEnt = pEnt->NextEntity())
|
||||
for(CEntity *pEnt = GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_LASER); pEnt; pEnt = pEnt->NextEntity())
|
||||
{
|
||||
auto *const pLaser = dynamic_cast<CLaser *>(pEnt);
|
||||
if(!pLaser || pLaser->GetOwner() < 0 || !GameClient()->m_aClients[pLaser->GetOwner()].m_IsPredictedLocal)
|
||||
|
@ -393,7 +397,7 @@ void CItems::OnRender()
|
|||
CLaserData Data = pLaser->GetData();
|
||||
RenderLaser(&Data, true);
|
||||
}
|
||||
for(auto *pPickup = (CPickup *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
|
||||
for(auto *pPickup = (CPickup *)GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
|
||||
{
|
||||
if(!IsSuper && pPickup->m_Layer == LAYER_SWITCH && pPickup->m_Number > 0 && pPickup->m_Number < (int)aSwitchers.size() && !aSwitchers[pPickup->m_Number].m_aStatus[SwitcherTeam] && BlinkingPickup)
|
||||
continue;
|
||||
|
@ -601,7 +605,10 @@ void CItems::ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyT
|
|||
LocalPlayerInGame = m_pClient->m_aClients[m_pClient->m_Snap.m_pLocalInfo->m_ClientId].m_Team != TEAM_SPECTATORS;
|
||||
if(!m_pClient->AntiPingGunfire() || !LocalPlayerInGame)
|
||||
return;
|
||||
if(Client()->PredGameTick(g_Config.m_ClDummy) == pCurrent->m_StartTick)
|
||||
|
||||
int predictTick = GameClient()->GetPredictionTick();
|
||||
|
||||
if(predictTick == pCurrent->m_StartTick)
|
||||
return;
|
||||
|
||||
// get positions
|
||||
|
@ -625,7 +632,7 @@ void CItems::ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyT
|
|||
Speed = pTuning->m_GunSpeed;
|
||||
}
|
||||
|
||||
float Pt = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
|
||||
float Pt = ((float)(predictTick - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
|
||||
if(Pt < 0)
|
||||
return; // projectile haven't been shot yet
|
||||
|
||||
|
|
|
@ -1397,22 +1397,10 @@ void CMenus::RenderDemoBrowserButtons(CUIRect ButtonsView, bool WasListboxItemAc
|
|||
|
||||
// quick search
|
||||
{
|
||||
SetIconMode(true);
|
||||
CUIRect DemoSearch, SearchIcon;
|
||||
CUIRect DemoSearch;
|
||||
ButtonBarTop.VSplitLeft(ButtonBarBottom.h * 21.0f, &DemoSearch, &ButtonBarTop);
|
||||
ButtonBarTop.VSplitLeft(ButtonBarTop.h / 2.0f, nullptr, &ButtonBarTop);
|
||||
DemoSearch.VSplitLeft(TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS), &SearchIcon, &DemoSearch);
|
||||
DemoSearch.VSplitLeft(5.0f, nullptr, &DemoSearch);
|
||||
Ui()->DoLabel(&SearchIcon, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML);
|
||||
SetIconMode(false);
|
||||
m_DemoSearchInput.SetEmptyText(Localize("Search"));
|
||||
|
||||
if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed())
|
||||
{
|
||||
Ui()->SetActiveItem(&m_DemoSearchInput);
|
||||
m_DemoSearchInput.SelectAll();
|
||||
}
|
||||
if(Ui()->DoClearableEditBox(&m_DemoSearchInput, &DemoSearch, 12.0f))
|
||||
if(Ui()->DoEditBox_Search(&m_DemoSearchInput, &DemoSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed()))
|
||||
{
|
||||
RefreshFilteredDemos();
|
||||
DemolistOnUpdate(false);
|
||||
|
|
|
@ -683,26 +683,15 @@ void CMenus::RenderServerControl(CUIRect MainView)
|
|||
|
||||
// render quick search
|
||||
CUIRect QuickSearch;
|
||||
Bottom.VSplitLeft(5.0f, 0, &Bottom);
|
||||
Bottom.VSplitLeft(5.0f, nullptr, &Bottom);
|
||||
Bottom.VSplitLeft(250.0f, &QuickSearch, &Bottom);
|
||||
TextRender()->SetFontPreset(EFontPreset::ICON_FONT);
|
||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
|
||||
Ui()->DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML);
|
||||
float SearchWidth = TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT);
|
||||
QuickSearch.VSplitLeft(SearchWidth, 0, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch);
|
||||
|
||||
if(m_ControlPageOpening || (Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed()))
|
||||
if(m_ControlPageOpening)
|
||||
{
|
||||
Ui()->SetActiveItem(&m_FilterInput);
|
||||
m_ControlPageOpening = false;
|
||||
Ui()->SetActiveItem(&m_FilterInput);
|
||||
m_FilterInput.SelectAll();
|
||||
}
|
||||
m_FilterInput.SetEmptyText(Localize("Search"));
|
||||
Ui()->DoClearableEditBox(&m_FilterInput, &QuickSearch, 14.0f);
|
||||
Ui()->DoEditBox_Search(&m_FilterInput, &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed());
|
||||
|
||||
// call vote
|
||||
Bottom.VSplitRight(10.0f, &Bottom, 0);
|
||||
|
|
|
@ -257,7 +257,7 @@ void CMenus::SetNeedSendInfo()
|
|||
|
||||
void CMenus::RenderSettingsPlayer(CUIRect MainView)
|
||||
{
|
||||
CUIRect TabBar, PlayerTab, DummyTab, ChangeInfo, QuickSearch, QuickSearchClearButton;
|
||||
CUIRect TabBar, PlayerTab, DummyTab, ChangeInfo, QuickSearch;
|
||||
MainView.HSplitTop(20.0f, &TabBar, &MainView);
|
||||
TabBar.VSplitMid(&TabBar, &ChangeInfo, 20.f);
|
||||
TabBar.VSplitMid(&PlayerTab, &DummyTab);
|
||||
|
@ -340,7 +340,10 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView)
|
|||
}
|
||||
|
||||
MainView.HSplitTop(10.0f, nullptr, &MainView);
|
||||
MainView.HSplitBottom(25.0f, &MainView, &QuickSearch);
|
||||
MainView.HSplitBottom(20.0f, &MainView, &QuickSearch);
|
||||
MainView.HSplitBottom(5.0f, &MainView, nullptr);
|
||||
QuickSearch.VSplitLeft(220.0f, &QuickSearch, nullptr);
|
||||
|
||||
int OldSelected = -1;
|
||||
static CListBox s_ListBox;
|
||||
s_ListBox.DoStart(48.0f, vpFilteredFlags.size(), 10, 3, OldSelected, &MainView);
|
||||
|
@ -378,30 +381,7 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView)
|
|||
SetNeedSendInfo();
|
||||
}
|
||||
|
||||
// render quick search
|
||||
QuickSearch.VSplitLeft(240.0f, &QuickSearch, nullptr);
|
||||
QuickSearch.HSplitTop(5.0f, nullptr, &QuickSearch);
|
||||
|
||||
TextRender()->SetFontPreset(EFontPreset::ICON_FONT);
|
||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
Ui()->DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT);
|
||||
|
||||
float SearchWidth = TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f);
|
||||
QuickSearch.VSplitLeft(SearchWidth - 1.5f, nullptr, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(5.0f, nullptr, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(QuickSearch.w - 10.0f, &QuickSearch, &QuickSearchClearButton);
|
||||
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT);
|
||||
if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed())
|
||||
{
|
||||
Ui()->SetActiveItem(&s_FlagFilterInput);
|
||||
s_FlagFilterInput.SelectAll();
|
||||
}
|
||||
s_FlagFilterInput.SetEmptyText(Localize("Search"));
|
||||
Ui()->DoClearableEditBox(&s_FlagFilterInput, &QuickSearch, 14.0f);
|
||||
Ui()->DoEditBox_Search(&s_FlagFilterInput, &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed());
|
||||
}
|
||||
|
||||
struct CUISkin
|
||||
|
@ -770,8 +750,8 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
|||
CUIRect QuickSearch, DatabaseButton, DirectoryButton, RefreshButton;
|
||||
MainView.HSplitBottom(20.0f, &MainView, &QuickSearch);
|
||||
MainView.HSplitBottom(5.0f, &MainView, nullptr);
|
||||
QuickSearch.VSplitLeft(240.0f, &QuickSearch, &DatabaseButton);
|
||||
QuickSearch.VSplitRight(10.0f, &QuickSearch, nullptr);
|
||||
QuickSearch.VSplitLeft(220.0f, &QuickSearch, &DatabaseButton);
|
||||
DatabaseButton.VSplitLeft(10.0f, nullptr, &DatabaseButton);
|
||||
DatabaseButton.VSplitLeft(150.0f, &DatabaseButton, &DirectoryButton);
|
||||
DirectoryButton.VSplitRight(175.0f, nullptr, &DirectoryButton);
|
||||
DirectoryButton.VSplitRight(25.0f, &DirectoryButton, &RefreshButton);
|
||||
|
@ -904,23 +884,9 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
|||
SetNeedSendInfo();
|
||||
}
|
||||
|
||||
// Quick search
|
||||
{
|
||||
TextRender()->SetFontPreset(EFontPreset::ICON_FONT);
|
||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
Ui()->DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML);
|
||||
float SearchWidth = TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT);
|
||||
QuickSearch.VSplitLeft(SearchWidth + 5.0f, nullptr, &QuickSearch);
|
||||
static CLineInput s_SkinFilterInput(g_Config.m_ClSkinFilterString, sizeof(g_Config.m_ClSkinFilterString));
|
||||
if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed())
|
||||
if(Ui()->DoEditBox_Search(&s_SkinFilterInput, &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed()))
|
||||
{
|
||||
Ui()->SetActiveItem(&s_SkinFilterInput);
|
||||
s_SkinFilterInput.SelectAll();
|
||||
}
|
||||
s_SkinFilterInput.SetEmptyText(Localize("Search"));
|
||||
if(Ui()->DoClearableEditBox(&s_SkinFilterInput, &QuickSearch, 14.0f))
|
||||
m_SkinListNeedsUpdate = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -282,23 +282,9 @@ void CMenus::RenderSettingsTee7(CUIRect MainView)
|
|||
}
|
||||
}
|
||||
|
||||
// Quick search
|
||||
{
|
||||
TextRender()->SetFontPreset(EFontPreset::ICON_FONT);
|
||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
Ui()->DoLabel(&QuickSearch, FontIcons::FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML);
|
||||
float SearchWidth = TextRender()->TextWidth(14.0f, FontIcons::FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT);
|
||||
QuickSearch.VSplitLeft(SearchWidth + 5.0f, nullptr, &QuickSearch);
|
||||
static CLineInput s_SkinFilterInput(g_Config.m_ClSkinFilterString, sizeof(g_Config.m_ClSkinFilterString));
|
||||
if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed())
|
||||
if(Ui()->DoEditBox_Search(&s_SkinFilterInput, &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed()))
|
||||
{
|
||||
Ui()->SetActiveItem(&s_SkinFilterInput);
|
||||
s_SkinFilterInput.SelectAll();
|
||||
}
|
||||
s_SkinFilterInput.SetEmptyText(Localize("Search"));
|
||||
if(Ui()->DoClearableEditBox(&s_SkinFilterInput, &QuickSearch, 14.0f))
|
||||
m_SkinListNeedsUpdate = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -352,7 +352,7 @@ int InitSearchList(std::vector<const TName *> &vpSearchList, std::vector<TName>
|
|||
|
||||
void CMenus::RenderSettingsCustom(CUIRect MainView)
|
||||
{
|
||||
CUIRect TabBar, CustomList, QuickSearch, QuickSearchClearButton, DirectoryButton, ReloadButton;
|
||||
CUIRect TabBar, CustomList, QuickSearch, DirectoryButton, ReloadButton;
|
||||
|
||||
MainView.HSplitTop(20.0f, &TabBar, &MainView);
|
||||
const float TabWidth = TabBar.w / NUMBER_OF_ASSETS_TABS;
|
||||
|
@ -599,28 +599,12 @@ void CMenus::RenderSettingsCustom(CUIRect MainView)
|
|||
}
|
||||
}
|
||||
|
||||
// render quick search
|
||||
{
|
||||
// Quick search
|
||||
MainView.HSplitBottom(ms_ButtonHeight, &MainView, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(240.0f, &QuickSearch, &DirectoryButton);
|
||||
QuickSearch.HSplitTop(5.0f, 0, &QuickSearch);
|
||||
TextRender()->SetFontPreset(EFontPreset::ICON_FONT);
|
||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
|
||||
Ui()->DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML);
|
||||
float SearchWidth = TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT);
|
||||
QuickSearch.VSplitLeft(SearchWidth, 0, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(QuickSearch.w - 10.0f, &QuickSearch, &QuickSearchClearButton);
|
||||
if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed())
|
||||
QuickSearch.VSplitLeft(220.0f, &QuickSearch, &DirectoryButton);
|
||||
QuickSearch.HSplitTop(5.0f, nullptr, &QuickSearch);
|
||||
if(Ui()->DoEditBox_Search(&s_aFilterInputs[s_CurCustomTab], &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed()))
|
||||
{
|
||||
Ui()->SetActiveItem(&s_aFilterInputs[s_CurCustomTab]);
|
||||
s_aFilterInputs[s_CurCustomTab].SelectAll();
|
||||
}
|
||||
s_aFilterInputs[s_CurCustomTab].SetEmptyText(Localize("Search"));
|
||||
if(Ui()->DoClearableEditBox(&s_aFilterInputs[s_CurCustomTab], &QuickSearch, 14.0f))
|
||||
gs_aInitCustomList[s_CurCustomTab] = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2071,6 +2071,32 @@ void CGameClient::OnNewSnapshot()
|
|||
m_Effects.AirJump(Pos, Alpha);
|
||||
}
|
||||
|
||||
if(g_Config.m_ClFreezeStars && !m_SuppressEvents)
|
||||
{
|
||||
for(auto &Character : m_Snap.m_aCharacters)
|
||||
{
|
||||
if(Character.m_Active && Character.m_HasExtendedData && Character.m_PrevExtendedData)
|
||||
{
|
||||
int FreezeTimeNow = Character.m_ExtendedData.m_FreezeEnd - Client()->GameTick(g_Config.m_ClDummy);
|
||||
int FreezeTimePrev = Character.m_PrevExtendedData->m_FreezeEnd - Client()->PrevGameTick(g_Config.m_ClDummy);
|
||||
vec2 Pos = vec2(Character.m_Cur.m_X, Character.m_Cur.m_Y);
|
||||
int StarsNow = (FreezeTimeNow + 1) / Client()->GameTickSpeed();
|
||||
int StarsPrev = (FreezeTimePrev + 1) / Client()->GameTickSpeed();
|
||||
if(StarsNow < StarsPrev || (StarsPrev == 0 && StarsNow > 0))
|
||||
{
|
||||
int Amount = StarsNow + 1;
|
||||
float Mid = 3 * pi / 2;
|
||||
float Min = Mid - pi / 3;
|
||||
float Max = Mid + pi / 3;
|
||||
for(int j = 0; j < Amount; j++)
|
||||
{
|
||||
float Angle = mix(Min, Max, (j + 1) / (float)(Amount + 2));
|
||||
m_Effects.DamageIndicator(Pos, direction(Angle));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_Snap.m_LocalClientId != m_PrevLocalId)
|
||||
m_PredictedDummyId = m_PrevLocalId;
|
||||
m_PrevLocalId = m_Snap.m_LocalClientId;
|
||||
|
@ -2100,6 +2126,25 @@ void CGameClient::UpdateEditorIngameMoved()
|
|||
}
|
||||
}
|
||||
|
||||
int CGameClient::GetPredictionTick()
|
||||
{
|
||||
int predictTick = Client()->GetPredictionTime() * Client()->GameTickSpeed() / 1000.0f;
|
||||
|
||||
float predictPercentage = 1 - g_Config.m_ClAntiPingpercent / 100.0f;
|
||||
int predictMin = std::floor(predictTick * predictPercentage);
|
||||
int predictMin2 = g_Config.m_ClAntiPingLimit * Client()->GameTickSpeed() / 1000.0f;
|
||||
if (g_Config.m_ClAntiPingLimit != 0)
|
||||
predictMin = predictMin2;
|
||||
|
||||
predictTick = Client()->PredGameTick(g_Config.m_ClDummy) - predictMin;
|
||||
|
||||
if(predictTick < Client()->GameTick(g_Config.m_ClDummy) + 1)
|
||||
{
|
||||
predictTick = Client()->GameTick(g_Config.m_ClDummy) + 1;
|
||||
}
|
||||
return predictTick;
|
||||
}
|
||||
|
||||
void CGameClient::OnPredict()
|
||||
{
|
||||
// store the previous values so we can detect prediction errors
|
||||
|
@ -2157,19 +2202,32 @@ void CGameClient::OnPredict()
|
|||
if(PredictDummy())
|
||||
pDummyChar = m_PredictedWorld.GetCharacterById(m_PredictedDummyId);
|
||||
|
||||
int predictTick = GetPredictionTick();
|
||||
// predict
|
||||
for(int Tick = Client()->GameTick(g_Config.m_ClDummy) + 1; Tick <= Client()->PredGameTick(g_Config.m_ClDummy); Tick++)
|
||||
{
|
||||
// fetch the previous characters
|
||||
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
|
||||
if(Tick == predictTick)
|
||||
{
|
||||
m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld);
|
||||
m_PredictedPrevChar = pLocalChar->GetCore();
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
|
||||
m_aClients[i].m_PrevPredicted = pChar->GetCore();
|
||||
}
|
||||
|
||||
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
|
||||
{
|
||||
m_PredictedPrevChar = pLocalChar->GetCore();
|
||||
m_aClients[m_Snap.m_LocalClientId].m_PrevPredicted = pLocalChar->GetCore();
|
||||
|
||||
if(pDummyChar)
|
||||
m_aClients[m_PredictedDummyId].m_PrevPredicted = pDummyChar->GetCore();
|
||||
}
|
||||
|
||||
if(Tick == predictTick)
|
||||
{
|
||||
m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld);
|
||||
}
|
||||
|
||||
// optionally allow some movement in freeze by not predicting freeze the last one to two ticks
|
||||
if(g_Config.m_ClPredictFreeze == 2 && Client()->PredGameTick(g_Config.m_ClDummy) - 1 - Client()->PredGameTick(g_Config.m_ClDummy) % 2 <= Tick)
|
||||
pLocalChar->m_CanMoveInFreeze = true;
|
||||
|
@ -2193,14 +2251,22 @@ void CGameClient::OnPredict()
|
|||
m_PredictedWorld.Tick();
|
||||
|
||||
// fetch the current characters
|
||||
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
|
||||
if(Tick == predictTick)
|
||||
{
|
||||
m_PredictedChar = pLocalChar->GetCore();
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
|
||||
m_aClients[i].m_Predicted = pChar->GetCore();
|
||||
}
|
||||
|
||||
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
|
||||
{
|
||||
m_PredictedChar = pLocalChar->GetCore();
|
||||
m_aClients[m_Snap.m_LocalClientId].m_Predicted = pLocalChar->GetCore();
|
||||
|
||||
if(pDummyChar)
|
||||
m_aClients[m_PredictedDummyId].m_Predicted = pDummyChar->GetCore();
|
||||
}
|
||||
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
|
||||
{
|
||||
|
|
|
@ -499,6 +499,7 @@ public:
|
|||
CRenderTools m_RenderTools;
|
||||
|
||||
void OnReset();
|
||||
int GetPredictionTick();
|
||||
|
||||
size_t ComponentCount() { return m_vpAll.size(); }
|
||||
|
||||
|
|
|
@ -1004,6 +1004,25 @@ bool CUi::DoClearableEditBox(CLineInput *pLineInput, const CUIRect *pRect, float
|
|||
return ReturnValue;
|
||||
}
|
||||
|
||||
bool CUi::DoEditBox_Search(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, bool HotkeyEnabled)
|
||||
{
|
||||
CUIRect QuickSearch = *pRect;
|
||||
TextRender()->SetFontPreset(EFontPreset::ICON_FONT);
|
||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, FontSize, TEXTALIGN_ML);
|
||||
const float SearchWidth = TextRender()->TextWidth(FontSize, FONT_ICON_MAGNIFYING_GLASS);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT);
|
||||
QuickSearch.VSplitLeft(SearchWidth + 5.0f, nullptr, &QuickSearch);
|
||||
if(HotkeyEnabled && Input()->ModifierIsPressed() && Input()->KeyPress(KEY_F))
|
||||
{
|
||||
SetActiveItem(pLineInput);
|
||||
pLineInput->SelectAll();
|
||||
}
|
||||
pLineInput->SetEmptyText(Localize("Search"));
|
||||
return DoClearableEditBox(pLineInput, &QuickSearch, FontSize);
|
||||
}
|
||||
|
||||
int CUi::DoButton_Menu(CUIElement &UIElement, const CButtonContainer *pId, const std::function<const char *()> &GetTextLambda, const CUIRect *pRect, const SMenuButtonProperties &Props)
|
||||
{
|
||||
CUIRect Text = *pRect, DropDownIcon;
|
||||
|
|
|
@ -603,6 +603,24 @@ public:
|
|||
*/
|
||||
bool DoClearableEditBox(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, int Corners = IGraphics::CORNER_ALL, const std::vector<STextColorSplit> &vColorSplits = {});
|
||||
|
||||
/**
|
||||
* Creates an input field with a search icon and a clear [x] button attached to it.
|
||||
* The input will have default text "Search" and the hotkey Ctrl+F can be used to activate the input.
|
||||
*
|
||||
* @see DoEditBox
|
||||
*
|
||||
* @param pLineInput This pointer will be stored and written to on next user input.
|
||||
* So you can not pass in a pointer that goes out of scope such as a local variable.
|
||||
* Pass in either a member variable of the current class or a static variable.
|
||||
* For example ```static CLineInputBuffered<IO_MAX_PATH_LENGTH> s_MyInput;```
|
||||
* @param pRect the UI rect it will attach to
|
||||
* @param FontSize Size of the font (`10.0f`, `12.0f` and `14.0f` are commonly used here)
|
||||
* @param HotkeyEnabled Whether the hotkey to enable this editbox is currently enabled.
|
||||
*
|
||||
* @return true if the value of the input field changed since the last call.
|
||||
*/
|
||||
bool DoEditBox_Search(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, bool HotkeyEnabled);
|
||||
|
||||
int DoButton_Menu(CUIElement &UIElement, const CButtonContainer *pId, const std::function<const char *()> &GetTextLambda, const CUIRect *pRect, const SMenuButtonProperties &Props = {});
|
||||
// only used for popup menus
|
||||
int DoButton_PopupMenu(CButtonContainer *pButtonContainer, const char *pText, const CUIRect *pRect, float Size, int Align, float Padding = 0.0f, bool TransparentInactive = false, bool Enabled = true);
|
||||
|
|
Loading…
Reference in a new issue