Compare commits

...

19 commits

Author SHA1 Message Date
KebsCS 7eaf4d9b72
Merge 3fd0062fb7 into 20cb02048d 2024-09-16 01:34:39 +02:00
Dennis Felsing 20cb02048d
Merge pull request #8957 from Robyt3/Client-Binds-Composite-Chat-Console-Menus-Fix
Fix composite binds that open chat, console or menus
2024-09-15 21:43:19 +00:00
Dennis Felsing a5138c078e
Merge pull request #8949 from MilkeeyCat/pr_fix_color_speed_values
Fix colored speed values after connecting to a server
2024-09-15 21:42:02 +00:00
Robert Müller 0d93b1add7 Fix composite binds that open chat, console or menus
Events with flag `FLAG_RELEASE` must always be forwarded to all components so keys being released can be handled in all components also after some components have been disabled.

Closes #8901.
2024-09-15 14:54:03 +02:00
Dennis Felsing 0f12044fcd
Merge pull request #8956 from Robyt3/UI-Scrollbar-Rail-HotItem
Fix scrollbar rail clicking being active while popups open
2024-09-15 10:21:41 +00:00
Robert Müller 8f2c288698 Fix scrollbar rail clicking being active while popups open
Scrollbars are now also set as the hot item when the rail is hovered and the rail clicking function is now only enabled for the scrollbar that is the hot item.

Closes #8954.
2024-09-15 11:45:22 +02:00
MilkeeyCat 9963a3e3db Pass color to RenderMovementInformationTextContainer function 2024-09-15 12:40:17 +03:00
Dennis Felsing 4b6f2e22a8
Merge pull request #8955 from furo321/url-master-parsing
Don't allow URLs without port from the masterserver
2024-09-15 09:28:43 +00:00
furo 7bbd51cf73 Don't allow URLs without port from the masterserver 2024-09-15 11:04:48 +02:00
Dennis Felsing dcd02b50bb
Merge pull request #8953 from ChillerDragon/pr_bind_null
Add BindNull to SQL api
2024-09-15 06:31:43 +00:00
Dennis Felsing 4fe956dffc
Merge pull request #8951 from furo321/fix-capture-count
Fix captures not being counted for certain names
2024-09-15 06:13:40 +00:00
ChillerDragon 7c2f058c40 Add BindNull to SQL api
Comes in handy in my downstream project
2024-09-15 09:14:00 +08:00
furo 6bf4a016ba Fix captures not being counted for certain names 2024-09-15 00:51:39 +02:00
Dennis Felsing 0feee9aa3e
Merge pull request #8948 from Robyt3/Client-Chat-TeeRenderInfo-Cleanup
Store `CTeeRenderInfo` instead of members for chat lines, extract `CTeeRenderInfo::Apply(const CSkin *)` function
2024-09-14 21:39:46 +00:00
MilkeeyCat d5be8d1633 Fix colored speed values after connecting to a server 2024-09-14 23:18:28 +03:00
Robert Müller 65cf776846 Extract CTeeRenderInfo::Apply(const CSkin *) function
Add function to apply information of `CSkin` to a `CTeeRenderInfo` to reduce duplicate code.
2024-09-14 21:12:43 +02:00
Robert Müller 62075d22e3 Store CTeeRenderInfo instead of members for chat lines
Avoid code to convert from `CTeeRenderInfo` to chat-internal representation and back to `CTeeRenderInfo`.
2024-09-14 21:12:25 +02:00
Robert Müller 0369946156
Merge pull request #8946 from MilkeeyCat/pr_fix_callvote_map_change
Don't add `/` if the directory is empty
2024-09-14 17:11:22 +00:00
MilkeeyCat 232018de23 Don't add / if the directory is empty 2024-09-14 19:49:01 +03:00
19 changed files with 124 additions and 182 deletions

View file

@ -424,7 +424,10 @@ void CServerBrowserHttp::Refresh()
}
bool ServerbrowserParseUrl(NETADDR *pOut, const char *pUrl)
{
return net_addr_from_url(pOut, pUrl, nullptr, 0) != 0;
int Failure = net_addr_from_url(pOut, pUrl, nullptr, 0);
if(Failure || pOut->port == 0)
return true;
return false;
}
bool CServerBrowserHttp::Validate(json_value *pJson)
{

View file

@ -61,6 +61,7 @@ public:
virtual void BindInt(int Idx, int Value) = 0;
virtual void BindInt64(int Idx, int64_t Value) = 0;
virtual void BindFloat(int Idx, float Value) = 0;
virtual void BindNull(int Idx) = 0;
// Print expanded sql statement
virtual void Print() = 0;

View file

@ -89,6 +89,7 @@ public:
void BindInt(int Idx, int Value) override;
void BindInt64(int Idx, int64_t Value) override;
void BindFloat(int Idx, float Value) override;
void BindNull(int Idx) override;
void Print() override {}
bool Step(bool *pEnd, char *pError, int ErrorSize) override;
@ -421,6 +422,22 @@ void CMysqlConnection::BindFloat(int Idx, float Value)
pParam->error = nullptr;
}
void CMysqlConnection::BindNull(int Idx)
{
m_NewQuery = true;
Idx -= 1;
dbg_assert(0 <= Idx && Idx < (int)m_vStmtParameters.size(), "index out of bounds");
MYSQL_BIND *pParam = &m_vStmtParameters[Idx];
pParam->buffer_type = MYSQL_TYPE_NULL;
pParam->buffer = nullptr;
pParam->buffer_length = 0;
pParam->length = nullptr;
pParam->is_null = nullptr;
pParam->is_unsigned = false;
pParam->error = nullptr;
}
bool CMysqlConnection::Step(bool *pEnd, char *pError, int ErrorSize)
{
if(m_NewQuery)

View file

@ -37,6 +37,7 @@ public:
void BindInt(int Idx, int Value) override;
void BindInt64(int Idx, int64_t Value) override;
void BindFloat(int Idx, float Value) override;
void BindNull(int Idx) override;
void Print() override;
bool Step(bool *pEnd, char *pError, int ErrorSize) override;
@ -241,6 +242,13 @@ void CSqliteConnection::BindFloat(int Idx, float Value)
m_Done = false;
}
void CSqliteConnection::BindNull(int Idx)
{
int Result = sqlite3_bind_null(m_pStmt, Idx);
AssertNoError(Result);
m_Done = false;
}
// Keep support for SQLite < 3.14 on older Linux distributions. MinGW does not
// support __attribute__((weak)): https://sourceware.org/bugzilla/show_bug.cgi?id=9687
#if defined(__GNUC__) && !defined(__MINGW32__)

View file

@ -5,6 +5,8 @@
#include <engine/config.h>
#include <engine/shared/config.h>
#include <game/client/components/chat.h>
#include <game/client/components/console.h>
#include <game/client/gameclient.h>
static const ColorRGBA gs_BindPrintColor{1.0f, 1.0f, 0.8f, 1.0f};
@ -126,7 +128,7 @@ bool CBinds::OnInput(const IInput::CEvent &Event)
});
if(ActiveBind == m_vActiveBinds.end())
{
const auto &&OnPress = [&](int Mask) {
const auto &&OnKeyPress = [&](int Mask) {
const char *pBind = m_aapKeyBindings[Mask][Event.m_Key];
if(g_Config.m_ClSubTickAiming)
{
@ -141,14 +143,14 @@ bool CBinds::OnInput(const IInput::CEvent &Event)
if(m_aapKeyBindings[ModifierMask][Event.m_Key])
{
OnPress(ModifierMask);
OnKeyPress(ModifierMask);
Handled = true;
}
else if(m_aapKeyBindings[MODIFIER_NONE][Event.m_Key] &&
ModifierMask != ((1 << MODIFIER_CTRL) | (1 << MODIFIER_SHIFT)) &&
ModifierMask != ((1 << MODIFIER_GUI) | (1 << MODIFIER_SHIFT)))
{
OnPress(MODIFIER_NONE);
OnKeyPress(MODIFIER_NONE);
Handled = true;
}
}
@ -166,17 +168,30 @@ bool CBinds::OnInput(const IInput::CEvent &Event)
if(Event.m_Flags & IInput::FLAG_RELEASE)
{
const auto &&OnKeyRelease = [&](const CBindSlot &Bind) {
// Prevent binds from being deactivated while chat, console and menus are open, as these components will
// still allow key release events to be forwarded to this component, so the active binds can be cleared.
if(GameClient()->m_Chat.IsActive() ||
!GameClient()->m_GameConsole.IsClosed() ||
GameClient()->m_Menus.IsActive())
{
return;
}
// Have to check for nullptr again because the previous execute can unbind itself
if(!m_aapKeyBindings[Bind.m_ModifierMask][Bind.m_Key])
{
return;
}
Console()->ExecuteLineStroked(0, m_aapKeyBindings[Bind.m_ModifierMask][Bind.m_Key]);
};
// Release active bind that uses this primary key
auto ActiveBind = std::find_if(m_vActiveBinds.begin(), m_vActiveBinds.end(), [&](const CBindSlot &Bind) {
return Event.m_Key == Bind.m_Key;
});
if(ActiveBind != m_vActiveBinds.end())
{
// Have to check for nullptr again because the previous execute can unbind itself
if(m_aapKeyBindings[ActiveBind->m_ModifierMask][ActiveBind->m_Key])
{
Console()->ExecuteLineStroked(0, m_aapKeyBindings[ActiveBind->m_ModifierMask][ActiveBind->m_Key]);
}
OnKeyRelease(*ActiveBind);
m_vActiveBinds.erase(ActiveBind);
Handled = true;
}
@ -191,11 +206,7 @@ bool CBinds::OnInput(const IInput::CEvent &Event)
});
if(ActiveModifierBind == m_vActiveBinds.end())
break;
// Have to check for nullptr again because the previous execute can unbind itself
if(m_aapKeyBindings[ActiveModifierBind->m_ModifierMask][ActiveModifierBind->m_Key])
{
Console()->ExecuteLineStroked(0, m_aapKeyBindings[ActiveModifierBind->m_ModifierMask][ActiveModifierBind->m_Key]);
}
OnKeyRelease(*ActiveModifierBind);
m_vActiveBinds.erase(ActiveModifierBind);
Handled = true;
}

View file

@ -805,50 +805,9 @@ void CChat::AddLine(int ClientId, int Team, const char *pLine)
{
if(!g_Config.m_ClChatOld)
{
pCurrentLine->m_CustomColoredSkin = LineAuthor.m_RenderInfo.m_CustomColoredSkin;
if(pCurrentLine->m_CustomColoredSkin)
pCurrentLine->m_RenderSkin = LineAuthor.m_RenderInfo.m_ColorableRenderSkin;
else
pCurrentLine->m_RenderSkin = LineAuthor.m_RenderInfo.m_OriginalRenderSkin;
str_copy(pCurrentLine->m_aSkinName, LineAuthor.m_aSkinName);
pCurrentLine->m_ColorBody = LineAuthor.m_RenderInfo.m_ColorBody;
pCurrentLine->m_ColorFeet = LineAuthor.m_RenderInfo.m_ColorFeet;
pCurrentLine->m_RenderSkinMetrics = LineAuthor.m_RenderInfo.m_SkinMetrics;
pCurrentLine->m_TeeRenderInfo = LineAuthor.m_RenderInfo;
pCurrentLine->m_HasRenderTee = true;
// 0.7
if(Client()->IsSixup())
{
for(int Part = 0; Part < protocol7::NUM_SKINPARTS; Part++)
{
const char *pPartName = LineAuthor.m_aSixup[g_Config.m_ClDummy].m_aaSkinPartNames[Part];
int Id = m_pClient->m_Skins7.FindSkinPart(Part, pPartName, false);
const CSkins7::CSkinPart *pSkinPart = m_pClient->m_Skins7.GetSkinPart(Part, Id);
if(LineAuthor.m_aSixup[g_Config.m_ClDummy].m_aUseCustomColors[Part])
{
pCurrentLine->m_Sixup.m_aTextures[Part] = pSkinPart->m_ColorTexture;
pCurrentLine->m_Sixup.m_aColors[Part] = m_pClient->m_Skins7.GetColor(
LineAuthor.m_aSixup[g_Config.m_ClDummy].m_aSkinPartColors[Part],
Part == protocol7::SKINPART_MARKING);
}
else
{
pCurrentLine->m_Sixup.m_aTextures[Part] = pSkinPart->m_OrgTexture;
pCurrentLine->m_Sixup.m_aColors[Part] = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}
if(LineAuthor.m_SkinInfo.m_aSixup[g_Config.m_ClDummy].m_HatTexture.IsValid())
{
if(Part == protocol7::SKINPART_BODY && str_comp(pPartName, "standard"))
pCurrentLine->m_Sixup.m_HatSpriteIndex = CSkins7::HAT_OFFSET_SIDE + (ClientId % CSkins7::HAT_NUM);
if(Part == protocol7::SKINPART_DECORATION && str_comp(pPartName, "twinbopp"))
pCurrentLine->m_Sixup.m_HatSpriteIndex = CSkins7::HAT_OFFSET_SIDE + (ClientId % CSkins7::HAT_NUM);
pCurrentLine->m_Sixup.m_HatTexture = LineAuthor.m_SkinInfo.m_aSixup[g_Config.m_ClDummy].m_HatTexture;
}
}
}
}
}
}
@ -917,17 +876,11 @@ void CChat::OnRefreshSkins()
{
if(Line.m_HasRenderTee)
{
const CSkin *pSkin = m_pClient->m_Skins.Find(Line.m_aSkinName);
if(Line.m_CustomColoredSkin)
Line.m_RenderSkin = pSkin->m_ColorableSkin;
else
Line.m_RenderSkin = pSkin->m_OriginalSkin;
Line.m_RenderSkinMetrics = pSkin->m_Metrics;
Line.m_TeeRenderInfo.Apply(m_pClient->m_Skins.Find(Line.m_aSkinName));
}
else
{
Line.m_RenderSkin.Reset();
Line.m_TeeRenderInfo.Reset();
}
}
}
@ -1291,28 +1244,7 @@ void CChat::OnRender()
if(!g_Config.m_ClChatOld && Line.m_HasRenderTee)
{
const int TeeSize = MessageTeeSize();
CTeeRenderInfo RenderInfo;
RenderInfo.m_CustomColoredSkin = Line.m_CustomColoredSkin;
if(Line.m_CustomColoredSkin)
RenderInfo.m_ColorableRenderSkin = Line.m_RenderSkin;
else
RenderInfo.m_OriginalRenderSkin = Line.m_RenderSkin;
RenderInfo.m_SkinMetrics = Line.m_RenderSkinMetrics;
RenderInfo.m_ColorBody = Line.m_ColorBody;
RenderInfo.m_ColorFeet = Line.m_ColorFeet;
RenderInfo.m_Size = TeeSize;
if(Client()->IsSixup())
{
for(int Part = 0; Part < protocol7::NUM_SKINPARTS; Part++)
{
RenderInfo.m_aSixup[g_Config.m_ClDummy].m_aColors[Part] = Line.m_Sixup.m_aColors[Part];
RenderInfo.m_aSixup[g_Config.m_ClDummy].m_aTextures[Part] = Line.m_Sixup.m_aTextures[Part];
RenderInfo.m_aSixup[g_Config.m_ClDummy].m_HatSpriteIndex = Line.m_Sixup.m_HatSpriteIndex;
RenderInfo.m_aSixup[g_Config.m_ClDummy].m_HatTexture = Line.m_Sixup.m_HatTexture;
}
}
Line.m_TeeRenderInfo.m_Size = TeeSize;
float RowHeight = FontSize() + RealMsgPaddingY;
float OffsetTeeY = TeeSize / 2.0f;
@ -1320,9 +1252,9 @@ void CChat::OnRender()
const CAnimState *pIdleState = CAnimState::GetIdle();
vec2 OffsetToMid;
CRenderTools::GetRenderTeeOffsetToRenderedTee(pIdleState, &RenderInfo, OffsetToMid);
CRenderTools::GetRenderTeeOffsetToRenderedTee(pIdleState, &Line.m_TeeRenderInfo, OffsetToMid);
vec2 TeeRenderPos(x + (RealMsgPaddingX + TeeSize) / 2.0f, y + OffsetTeeY + FullHeightMinusTee / 2.0f + OffsetToMid.y);
RenderTools()->RenderTee(pIdleState, &RenderInfo, EMOTE_NORMAL, vec2(1, 0.1f), TeeRenderPos, Blend);
RenderTools()->RenderTee(pIdleState, &Line.m_TeeRenderInfo, EMOTE_NORMAL, vec2(1, 0.1f), TeeRenderPos, Blend);
}
const ColorRGBA TextColor = TextRender()->DefaultTextColor().WithMultipliedAlpha(Blend);

View file

@ -11,6 +11,7 @@
#include <game/client/component.h>
#include <game/client/lineinput.h>
#include <game/client/render.h>
#include <game/client/skin.h>
#include <game/generated/protocol7.h>
@ -45,30 +46,12 @@ class CChat : public CComponent
int m_QuadContainerIndex;
char m_aSkinName[std::size(g_Config.m_ClPlayerSkin)];
CSkin::SSkinTextures m_RenderSkin;
CSkin::SSkinMetrics m_RenderSkinMetrics;
bool m_CustomColoredSkin;
ColorRGBA m_ColorBody;
ColorRGBA m_ColorFeet;
bool m_HasRenderTee;
CTeeRenderInfo m_TeeRenderInfo;
float m_TextYOffset;
int m_TimesRepeated;
class CSixup
{
public:
IGraphics::CTextureHandle m_aTextures[protocol7::NUM_SKINPARTS];
IGraphics::CTextureHandle m_HatTexture;
IGraphics::CTextureHandle m_BotTexture;
int m_HatSpriteIndex;
ColorRGBA m_BotColor;
ColorRGBA m_aColors[protocol7::NUM_SKINPARTS];
};
// 0.7 Skin
CSixup m_Sixup;
};
bool m_PrevScoreBoardShowed;

View file

@ -366,10 +366,7 @@ void CGhost::OnRender()
IsTeamplay = (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS) != 0;
GhostNinjaRenderInfo = Ghost.m_RenderInfo;
GhostNinjaRenderInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
GhostNinjaRenderInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
GhostNinjaRenderInfo.m_BloodColor = pSkin->m_BloodColor;
GhostNinjaRenderInfo.m_SkinMetrics = pSkin->m_Metrics;
GhostNinjaRenderInfo.Apply(pSkin);
GhostNinjaRenderInfo.m_CustomColoredSkin = IsTeamplay;
if(!IsTeamplay)
{
@ -392,11 +389,7 @@ void CGhost::InitRenderInfos(CGhostItem *pGhost)
IntsToStr(&pGhost->m_Skin.m_Skin0, 6, aSkinName, std::size(aSkinName));
CTeeRenderInfo *pRenderInfo = &pGhost->m_RenderInfo;
const CSkin *pSkin = m_pClient->m_Skins.Find(aSkinName);
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
pRenderInfo->m_BloodColor = pSkin->m_BloodColor;
pRenderInfo->m_SkinMetrics = pSkin->m_Metrics;
pRenderInfo->Apply(m_pClient->m_Skins.Find(aSkinName));
pRenderInfo->m_CustomColoredSkin = pGhost->m_Skin.m_UseCustomColor;
if(pGhost->m_Skin.m_UseCustomColor)
{
@ -697,11 +690,7 @@ void CGhost::OnRefreshSkins()
CTeeRenderInfo *pRenderInfo = &Ghost.m_RenderInfo;
if(aSkinName[0] != '\0')
{
const CSkin *pSkin = m_pClient->m_Skins.Find(aSkinName);
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
pRenderInfo->m_BloodColor = pSkin->m_BloodColor;
pRenderInfo->m_SkinMetrics = pSkin->m_Metrics;
pRenderInfo->Apply(m_pClient->m_Skins.Find(aSkinName));
}
else
{

View file

@ -76,6 +76,8 @@ void CHud::OnReset()
m_ServerRecord = -1.0f;
m_aPlayerRecord[0] = -1.0f;
m_aPlayerRecord[1] = -1.0f;
m_aLastPlayerSpeedChange[0] = ESpeedChange::NONE;
m_aLastPlayerSpeedChange[1] = ESpeedChange::NONE;
ResetHudContainers();
}
@ -1275,11 +1277,11 @@ void CHud::UpdateMovementInformationTextContainer(STextContainerIndex &TextConta
}
}
void CHud::RenderMovementInformationTextContainer(STextContainerIndex &TextContainer, float X, float Y)
void CHud::RenderMovementInformationTextContainer(STextContainerIndex &TextContainer, const ColorRGBA &Color, float X, float Y)
{
if(TextContainer.Valid())
{
TextRender()->RenderTextContainer(TextContainer, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), X - TextRender()->GetBoundingBoxTextContainer(TextContainer).m_W, Y);
TextRender()->RenderTextContainer(TextContainer, Color, TextRender()->DefaultTextOutlineColor(), X - TextRender()->GetBoundingBoxTextContainer(TextContainer).m_W, Y);
}
}
@ -1352,12 +1354,12 @@ void CHud::RenderMovementInformation(const int ClientId)
TextRender()->Text(xl, y, Fontsize, "X:", -1.0f);
UpdateMovementInformationTextContainer(m_aPlayerPositionContainers[0], Fontsize, Pos.x, m_aaPlayerPositionText[0], sizeof(m_aaPlayerPositionText[0]));
RenderMovementInformationTextContainer(m_aPlayerPositionContainers[0], xr, y);
RenderMovementInformationTextContainer(m_aPlayerPositionContainers[0], TextRender()->DefaultTextColor(), xr, y);
y += MOVEMENT_INFORMATION_LINE_HEIGHT;
TextRender()->Text(xl, y, Fontsize, "Y:", -1.0f);
UpdateMovementInformationTextContainer(m_aPlayerPositionContainers[1], Fontsize, Pos.y, m_aaPlayerPositionText[1], sizeof(m_aaPlayerPositionText[1]));
RenderMovementInformationTextContainer(m_aPlayerPositionContainers[1], xr, y);
RenderMovementInformationTextContainer(m_aPlayerPositionContainers[1], TextRender()->DefaultTextColor(), xr, y);
y += MOVEMENT_INFORMATION_LINE_HEIGHT;
}
@ -1369,14 +1371,14 @@ void CHud::RenderMovementInformation(const int ClientId)
const char aaCoordinates[][4] = {"X:", "Y:"};
for(int i = 0; i < 2; i++)
{
TextRender()->TextColor(ColorRGBA(1, 1, 1, 1));
ColorRGBA Color(1, 1, 1, 1);
if(m_aLastPlayerSpeedChange[i] == ESpeedChange::INCREASE)
TextRender()->TextColor(ColorRGBA(0, 1, 0, 1));
Color = ColorRGBA(0, 1, 0, 1);
if(m_aLastPlayerSpeedChange[i] == ESpeedChange::DECREASE)
TextRender()->TextColor(ColorRGBA(1, 0.5f, 0.5f, 1));
Color = ColorRGBA(1, 0.5f, 0.5f, 1);
TextRender()->Text(xl, y, Fontsize, aaCoordinates[i], -1.0f);
UpdateMovementInformationTextContainer(m_aPlayerSpeedTextContainers[i], Fontsize, i == 0 ? DisplaySpeedX : DisplaySpeedY, m_aaPlayerSpeedText[i], sizeof(m_aaPlayerSpeedText[i]));
RenderMovementInformationTextContainer(m_aPlayerSpeedTextContainers[i], xr, y);
RenderMovementInformationTextContainer(m_aPlayerSpeedTextContainers[i], Color, xr, y);
y += MOVEMENT_INFORMATION_LINE_HEIGHT;
}
@ -1389,7 +1391,7 @@ void CHud::RenderMovementInformation(const int ClientId)
y += MOVEMENT_INFORMATION_LINE_HEIGHT;
UpdateMovementInformationTextContainer(m_PlayerAngleTextContainerIndex, Fontsize, DisplayAngle, m_aPlayerAngleText, sizeof(m_aPlayerAngleText));
RenderMovementInformationTextContainer(m_PlayerAngleTextContainerIndex, xr, y);
RenderMovementInformationTextContainer(m_PlayerAngleTextContainerIndex, TextRender()->DefaultTextColor(), xr, y);
}
}

View file

@ -80,7 +80,7 @@ class CHud : public CComponent
void RenderMovementInformation(const int ClientId);
void UpdateMovementInformationTextContainer(STextContainerIndex &TextContainer, float FontSize, float Value, char *pPrevValue, size_t Size);
void RenderMovementInformationTextContainer(STextContainerIndex &TextContainer, float X, float Y);
void RenderMovementInformationTextContainer(STextContainerIndex &TextContainer, const ColorRGBA &Color, float X, float Y);
void RenderGameTimer();
void RenderPauseNotification();

View file

@ -1822,12 +1822,8 @@ bool CMenus::PrintHighlighted(const char *pName, F &&PrintFn)
CTeeRenderInfo CMenus::GetTeeRenderInfo(vec2 Size, const char *pSkinName, bool CustomSkinColors, int CustomSkinColorBody, int CustomSkinColorFeet) const
{
const CSkin *pSkin = m_pClient->m_Skins.Find(pSkinName);
CTeeRenderInfo TeeInfo;
TeeInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
TeeInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
TeeInfo.m_SkinMetrics = pSkin->m_Metrics;
TeeInfo.Apply(m_pClient->m_Skins.Find(pSkinName));
TeeInfo.m_CustomColoredSkin = CustomSkinColors;
if(CustomSkinColors)
{

View file

@ -633,11 +633,8 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
// Note: get the skin info after the settings buttons, because they can trigger a refresh
// which invalidates the skin.
const CSkin *pSkin = m_pClient->m_Skins.Find(pSkinName);
CTeeRenderInfo OwnSkinInfo;
OwnSkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
OwnSkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
OwnSkinInfo.m_SkinMetrics = pSkin->m_Metrics;
OwnSkinInfo.Apply(m_pClient->m_Skins.Find(pSkinName));
OwnSkinInfo.m_CustomColoredSkin = *pUseCustomColor;
if(*pUseCustomColor)
{

View file

@ -844,10 +844,7 @@ void CPlayers::OnRender()
{
aRenderInfo[i].m_aSixup[g_Config.m_ClDummy].Reset();
aRenderInfo[i].m_OriginalRenderSkin = pSkin->m_OriginalSkin;
aRenderInfo[i].m_ColorableRenderSkin = pSkin->m_ColorableSkin;
aRenderInfo[i].m_BloodColor = pSkin->m_BloodColor;
aRenderInfo[i].m_SkinMetrics = pSkin->m_Metrics;
aRenderInfo[i].Apply(pSkin);
aRenderInfo[i].m_CustomColoredSkin = IsTeamplay;
if(!IsTeamplay)
{
@ -857,12 +854,8 @@ void CPlayers::OnRender()
}
}
}
const CSkin *pSkin = m_pClient->m_Skins.Find("x_spec");
CTeeRenderInfo RenderInfoSpec;
RenderInfoSpec.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
RenderInfoSpec.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
RenderInfoSpec.m_BloodColor = pSkin->m_BloodColor;
RenderInfoSpec.m_SkinMetrics = pSkin->m_Metrics;
RenderInfoSpec.Apply(m_pClient->m_Skins.Find("x_spec"));
RenderInfoSpec.m_CustomColoredSkin = false;
RenderInfoSpec.m_Size = 64.0f;
const int LocalClientId = m_pClient->m_Snap.m_LocalClientId;

View file

@ -102,7 +102,7 @@ void CStatboard::OnMessage(int MsgType, void *pRawMsg)
if(t <= p)
return;
str_utf8_truncate(aName, sizeof(aName), p, t - p);
str_truncate(aName, sizeof(aName), p, t - p);
for(int i = 0; i < MAX_CLIENTS; i++)
{

View file

@ -447,7 +447,9 @@ void CGameClient::OnUpdate()
Input()->ConsumeEvents([&](const IInput::CEvent &Event) {
for(auto &pComponent : m_vpInput)
{
if(pComponent->OnInput(Event))
// Events with flag `FLAG_RELEASE` must always be forwarded to all components so keys being
// released can be handled in all components also after some components have been disabled.
if(pComponent->OnInput(Event) && (Event.m_Flags & ~IInput::FLAG_RELEASE) != 0)
break;
}
});
@ -1554,11 +1556,7 @@ void CGameClient::OnNewSnapshot()
pClient->m_SkinInfo.m_Size = 64;
// find new skin
const CSkin *pSkin = m_Skins.Find(pClient->m_aSkinName);
pClient->m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pClient->m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
pClient->m_SkinInfo.m_SkinMetrics = pSkin->m_Metrics;
pClient->m_SkinInfo.m_BloodColor = pSkin->m_BloodColor;
pClient->m_SkinInfo.Apply(m_Skins.Find(pClient->m_aSkinName));
pClient->m_SkinInfo.m_CustomColoredSkin = pClient->m_UseCustomColor;
if(!pClient->m_UseCustomColor)
@ -3750,13 +3748,9 @@ void CGameClient::RefreshSkins()
for(auto &Client : m_aClients)
{
Client.m_SkinInfo.m_OriginalRenderSkin.Reset();
Client.m_SkinInfo.m_ColorableRenderSkin.Reset();
if(Client.m_aSkinName[0] != '\0')
{
const CSkin *pSkin = m_Skins.Find(Client.m_aSkinName);
Client.m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
Client.m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
Client.m_SkinInfo.Apply(m_Skins.Find(Client.m_aSkinName));
}
else
{

View file

@ -56,6 +56,14 @@ public:
Sixup.Reset();
}
void Apply(const CSkin *pSkin)
{
m_OriginalRenderSkin = pSkin->m_OriginalSkin;
m_ColorableRenderSkin = pSkin->m_ColorableSkin;
m_BloodColor = pSkin->m_BloodColor;
m_SkinMetrics = pSkin->m_Metrics;
}
CSkin::SSkinTextures m_OriginalRenderSkin;
CSkin::SSkinTextures m_ColorableRenderSkin;

View file

@ -1301,21 +1301,24 @@ float CUi::DoScrollbarV(const void *pId, const CUIRect *pRect, float Current)
}
else if(HotItem() == pId)
{
if(MouseButton(0))
if(InsideHandle)
{
if(MouseButton(0))
{
SetActiveItem(pId);
m_ActiveScrollbarOffset = MouseY() - Handle.y;
Grabbed = true;
}
}
else if(MouseButtonClicked(0))
{
SetActiveItem(pId);
m_ActiveScrollbarOffset = MouseY() - Handle.y;
m_ActiveScrollbarOffset = Handle.h / 2.0f;
Grabbed = true;
}
}
else if(MouseButtonClicked(0) && !InsideHandle && InsideRail)
{
SetActiveItem(pId);
m_ActiveScrollbarOffset = Handle.h / 2.0f;
Grabbed = true;
}
if(InsideHandle && !MouseButton(0))
if(InsideRail && !MouseButton(0))
{
SetHotItem(pId);
}
@ -1380,19 +1383,22 @@ float CUi::DoScrollbarH(const void *pId, const CUIRect *pRect, float Current, co
}
else if(HotItem() == pId)
{
if(MouseButton(0))
if(InsideHandle)
{
if(MouseButton(0))
{
SetActiveItem(pId);
m_ActiveScrollbarOffset = MouseX() - Handle.x;
Grabbed = true;
}
}
else if(MouseButtonClicked(0))
{
SetActiveItem(pId);
m_ActiveScrollbarOffset = MouseX() - Handle.x;
m_ActiveScrollbarOffset = Handle.w / 2.0f;
Grabbed = true;
}
}
else if(MouseButtonClicked(0) && !InsideHandle && InsideRail)
{
SetActiveItem(pId);
m_ActiveScrollbarOffset = Handle.w / 2.0f;
Grabbed = true;
}
if(!pColorInner && (InsideHandle || Grabbed) && (CheckActiveItem(pId) || HotItem() == pId))
{
@ -1400,7 +1406,7 @@ float CUi::DoScrollbarH(const void *pId, const CUIRect *pRect, float Current, co
Handle.y -= 1.5f;
}
if(InsideHandle && !MouseButton(0))
if(InsideRail && !MouseButton(0))
{
SetHotItem(pId);
}

View file

@ -8667,7 +8667,9 @@ void CEditor::OnUpdate()
Input()->ConsumeEvents([&](const IInput::CEvent &Event) {
for(CEditorComponent &Component : m_vComponents)
{
if(Component.OnInput(Event))
// Events with flag `FLAG_RELEASE` must always be forwarded to all components so keys being
// released can be handled in all components also after some components have been disabled.
if(Component.OnInput(Event) && (Event.m_Flags & ~IInput::FLAG_RELEASE) != 0)
return;
}
Ui()->OnInput(Event);

View file

@ -3526,7 +3526,7 @@ void CGameContext::ConAddMapVotes(IConsole::IResult *pResult, void *pUserData)
str_format(aCommand, sizeof(aCommand), "clear_votes; add_map_votes \"%s\"", aDirectory);
}
else
str_format(aCommand, sizeof(aCommand), "change_map \"%s/%s\"", pDirectory, aOptionEscaped);
str_format(aCommand, sizeof(aCommand), "change_map \"%s%s%s\"", pDirectory, pDirectory[0] == '\0' ? "" : "/", aOptionEscaped);
pSelf->AddVote(aDescription, aCommand);
}