Compare commits

...

12 commits

Author SHA1 Message Date
KebsCS c17c8c6e43
Merge db8b41f413 into bb974c94ca 2024-11-01 22:55:24 +08:00
Dennis Felsing bb974c94ca
Merge pull request #9188 from Robyt3/Client-Hook-Collision-Width-Fix
Fix upper bound of hook collision line width scrollbar
2024-11-01 12:27:04 +00:00
Robert Müller e965ccdcac Fix upper bound of hook collision line width scrollbar
The maximum value of the config variable is only `20`. Regression from #9138.
2024-11-01 11:00:11 +01:00
Robert Müller 3345bc9da0
Merge pull request #9186 from def-/pr-transl-18.7
Update translations for upcoming 18.7
2024-11-01 09:06:00 +00:00
Dennis Felsing d6e31d35fe Update translations for upcoming 18.7 2024-11-01 09:12:18 +01:00
Dennis Felsing 19aa7fbb77 Version 18.8 2024-11-01 09:11:04 +01:00
Dennis Felsing 0f91b1287d
Merge pull request #9185 from Robyt3/Client-Font-Error
Improve error handling on invalid fonts and font index
2024-11-01 07:50:48 +00:00
Dennis Felsing 6bcf8ead49 Fix clang-tidy 2024-11-01 08:32:26 +01:00
Robert Müller 96eb49ad3f Improve error handling on invalid fonts and font index
Log more detailed error messages when fonts could not be loaded and when the font index is malformed. Show warning popup on client launch if any font failed to load, although this warning won't be readable if all fonts failed to be loaded.
2024-11-01 00:16:14 +01:00
Dennis Felsing f827b6e999
Merge pull request #9183 from KebsCS/pr-fix-command-preview
Fix chat command preview overlap
2024-10-31 21:27:15 +00:00
KebsCS 6dc11bbb89
Fix chat command preview overlap 2024-10-31 21:33:52 +01:00
KebsCS db8b41f413
Preserve super on hot reload, fix hot reload crashes 2024-10-21 16:52:27 +02:00
50 changed files with 284 additions and 77 deletions

View file

@ -1125,6 +1125,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -1939,3 +1939,6 @@ Feet
[skins]
Eyes
== Göz
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1876,6 +1876,9 @@ Connect address error
Could not connect dummy
==
Some fonts could not be loaded. Check the local console for details.
==
Save skin
==

View file

@ -987,6 +987,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -1970,3 +1970,6 @@ Feet
[skins]
Eyes
== Olhos
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -591,6 +591,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Loading DDNet Client
==

View file

@ -1227,6 +1227,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -594,6 +594,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Loading DDNet Client
==

View file

@ -1943,3 +1943,6 @@ Feet
[skins]
Eyes
== Oči
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1136,6 +1136,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -1273,6 +1273,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -610,6 +610,9 @@ Preparing demo playback
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -1872,6 +1872,9 @@ Connect address error
Could not connect dummy
==
Some fonts could not be loaded. Check the local console for details.
==
Save skin
==

View file

@ -1832,6 +1832,9 @@ Connect address error
Could not connect dummy
==
Some fonts could not be loaded. Check the local console for details.
==
[Spectating]
Following %s
==

View file

@ -1874,6 +1874,9 @@ Connect address error
Could not connect dummy
==
Some fonts could not be loaded. Check the local console for details.
==
[Spectating]
Following %s
==

View file

@ -1586,6 +1586,9 @@ Error saving settings
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Quitting. Please wait…
==

View file

@ -1956,3 +1956,6 @@ Eyes
https://wiki.ddnet.org/wiki/Mapping
== https://wiki.ddnet.org/wiki/Mapping
Some fonts could not be loaded. Check the local console for details.
== Einige Schriften konnten nicht geladen werden. Prüf die lokale Konsole für Details.

View file

@ -600,6 +600,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Loading DDNet Client
==

View file

@ -1566,6 +1566,9 @@ The width of texture %s is not divisible by %d, or the height is not divisible b
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Quitting. Please wait…
==

View file

@ -1435,6 +1435,9 @@ The format of texture %s is not RGBA which will cause visual bugs.
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Why are you slowmo replaying to read this?
==

View file

@ -1168,6 +1168,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -1578,6 +1578,9 @@ The width of texture %s is not divisible by %d, or the height is not divisible b
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Quitting. Please wait…
==

View file

@ -591,6 +591,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Loading DDNet Client
==

View file

@ -1137,6 +1137,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -1534,9 +1534,6 @@ Saving settings to '%s' failed
Error saving settings
== ﺕﺎﻤﯿﻈﻨﺗ ﻥﺩﺮﻛ ﻩﺮﯿﺧﺫ ﺭﺩ ﺎﻄﺧ
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==
The format of texture %s is not RGBA which will cause visual bugs.
== .ﺩﻮﺷ ﯽﻣ ىﺮﻫﺎﻇ ﻝﺎﻜﺷﺍ ﺩﺎﺠﯾﺍ ﺚﻋﺎﺑ ﻪﻛ ﺖﺴﯿﻧ %s RGBA ﯽﻜﯿﻓﺍﺮﮔ ﺖﻟﺎﺣ ﺖﻣﺮﻓ
@ -1938,3 +1935,9 @@ Moved ingame
https://wiki.ddnet.org/wiki/Mapping
== https://wiki.ddnet.org/wiki/Mapping
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1945,3 +1945,6 @@ Moved ingame
https://wiki.ddnet.org/wiki/Mapping
== https://wiki.ddnet.org/wiki/Mapping
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -932,6 +932,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -606,6 +606,9 @@ Loading map file from storage
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Loading DDNet Client
==

View file

@ -1912,6 +1912,9 @@ Custom
Unable to delete skin
== Невозможно удалить скин
Some fonts could not be loaded. Check the local console for details.
==
Save skin
==

View file

@ -1664,6 +1664,9 @@ Error saving settings
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Searching
==

View file

@ -1440,6 +1440,9 @@ Error saving settings
Loading demo file from storage
==
Some fonts could not be loaded. Check the local console for details.
==
Initializing components
==

View file

@ -1983,3 +1983,6 @@ Feet
[skins]
Eyes
== 眼睛
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1940,3 +1940,6 @@ Feet
[skins]
Eyes
== Oči
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1958,3 +1958,6 @@ Feet
[skins]
Eyes
== Ojos
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1942,3 +1942,6 @@ Feet
[skins]
Eyes
== Ögon
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1972,3 +1972,6 @@ Feet
[skins]
Eyes
== 眼睛
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1952,3 +1952,6 @@ Feet
[skins]
Eyes
== Göz
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -1939,3 +1939,6 @@ Zoom in
Zoom out
== Віддалити
Some fonts could not be loaded. Check the local console for details.
==

View file

@ -615,38 +615,66 @@ public:
void AddFace(FT_Face Face)
{
m_vFtFaces.push_back(Face);
if(!m_DefaultFace)
m_DefaultFace = Face;
}
void SetDefaultFaceByName(const char *pFamilyName)
bool SetDefaultFaceByName(const char *pFamilyName)
{
m_DefaultFace = GetFaceByName(pFamilyName);
if(!m_DefaultFace)
{
if(!m_vFtFaces.empty())
{
m_DefaultFace = m_vFtFaces.front();
}
log_error("textrender", "The default font face '%s' could not be found", pFamilyName);
return false;
}
return true;
}
void SetIconFaceByName(const char *pFamilyName)
bool SetIconFaceByName(const char *pFamilyName)
{
m_IconFace = GetFaceByName(pFamilyName);
if(!m_IconFace)
{
log_error("textrender", "The icon font face '%s' could not be found", pFamilyName);
return false;
}
return true;
}
void AddFallbackFaceByName(const char *pFamilyName)
bool AddFallbackFaceByName(const char *pFamilyName)
{
FT_Face Face = GetFaceByName(pFamilyName);
if(Face != nullptr && std::find(m_vFallbackFaces.begin(), m_vFallbackFaces.end(), Face) == m_vFallbackFaces.end())
if(!Face)
{
m_vFallbackFaces.push_back(Face);
log_error("textrender", "The fallback font face '%s' could not be found", pFamilyName);
return false;
}
if(std::find(m_vFallbackFaces.begin(), m_vFallbackFaces.end(), Face) != m_vFallbackFaces.end())
{
log_warn("textrender", "The fallback font face '%s' was specified multiple times", pFamilyName);
return true;
}
m_vFallbackFaces.push_back(Face);
return true;
}
void SetVariantFaceByName(const char *pFamilyName)
bool SetVariantFaceByName(const char *pFamilyName)
{
FT_Face Face = GetFaceByName(pFamilyName);
if(m_VariantFace != Face)
{
m_VariantFace = Face;
Clear(); // rebuild atlas after changing variant font
if(!Face && pFamilyName != nullptr)
{
log_error("textrender", "The variant font face '%s' could not be found", pFamilyName);
return false;
}
}
return true;
}
void SetFontPreset(EFontPreset FontPreset)
{
@ -1002,9 +1030,7 @@ class CTextRender : public IEngineTextRender
FT_Error CollectionLoadError = FT_New_Memory_Face(m_FTLibrary, pFontData, FontDataSize, -1, &FtFace);
if(CollectionLoadError)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "Failed to load font file '%s': %s", pFontName, FT_Error_String(CollectionLoadError));
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "textrender", aBuf);
log_error("textrender", "Failed to load font file '%s': %s", pFontName, FT_Error_String(CollectionLoadError));
return false;
}
@ -1017,26 +1043,20 @@ class CTextRender : public IEngineTextRender
FT_Error FaceLoadError = FT_New_Memory_Face(m_FTLibrary, pFontData, FontDataSize, FaceIndex, &FtFace);
if(FaceLoadError)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "Failed to load font face %ld from font file '%s': %s", FaceIndex, pFontName, FT_Error_String(FaceLoadError));
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "textrender", aBuf);
log_error("textrender", "Failed to load font face %ld from font file '%s': %s", FaceIndex, pFontName, FT_Error_String(FaceLoadError));
FT_Done_Face(FtFace);
continue;
}
m_pGlyphMap->AddFace(FtFace);
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "Loaded font face %ld '%s %s' from font file '%s'", FaceIndex, FtFace->family_name, FtFace->style_name, pFontName);
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "textrender", aBuf);
log_debug("textrender", "Loaded font face %ld '%s %s' from font file '%s'", FaceIndex, FtFace->family_name, FtFace->style_name, pFontName);
LoadedAny = true;
}
if(!LoadedAny)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "Failed to load font file '%s': no font faces could be loaded", pFontName);
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "textrender", aBuf);
log_error("textrender", "Failed to load font file '%s': no font faces could be loaded", pFontName);
return false;
}
@ -1083,9 +1103,7 @@ public:
{
int LMajor, LMinor, LPatch;
FT_Library_Version(m_FTLibrary, &LMajor, &LMinor, &LPatch);
char aFreetypeVersion[128];
str_format(aFreetypeVersion, sizeof(aFreetypeVersion), "Freetype version %d.%d.%d (compiled = %d.%d.%d)", LMajor, LMinor, LPatch, FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "textrender", aFreetypeVersion);
log_info("textrender", "Freetype version %d.%d.%d (compiled = %d.%d.%d)", LMajor, LMinor, LPatch, FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
}
m_FirstFreeTextContainerIndex = -1;
@ -1142,7 +1160,7 @@ public:
m_pStorage = nullptr;
}
void LoadFonts() override
bool LoadFonts() override
{
// read file data into buffer
const char *pFilename = "fonts/index.json";
@ -1150,10 +1168,8 @@ public:
unsigned JsonFileSize;
if(!Storage()->ReadFile(pFilename, IStorage::TYPE_ALL, &pFileData, &JsonFileSize))
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "Failed to open/read font index file '%s'", pFilename);
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "textrender", aBuf);
return;
log_error("textrender", "Failed to open/read font index file '%s'", pFilename);
return false;
}
// parse json data
@ -1163,11 +1179,16 @@ public:
free(pFileData);
if(pJsonData == nullptr)
{
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "Failed to parse font index file '%s': %s", pFilename, aError);
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "textrender", aBuf);
return;
log_error("textrender", "Failed to parse font index file '%s': %s", pFilename, aError);
return false;
}
if(pJsonData->type != json_object)
{
log_error("textrender", "Font index malformed: root must be an object", pFilename, aError);
return false;
}
bool Success = true;
// extract font file definitions
const json_value &FontFiles = (*pJsonData)["font files"];
@ -1176,7 +1197,11 @@ public:
for(unsigned FontFileIndex = 0; FontFileIndex < FontFiles.u.array.length; ++FontFileIndex)
{
if(FontFiles[FontFileIndex].type != json_string)
{
log_error("textrender", "Font index malformed: 'font files' must be an array of strings (error at index %d)", FontFileIndex);
Success = false;
continue;
}
char aFontName[IO_MAX_PATH_LENGTH];
str_format(aFontName, sizeof(aFontName), "fonts/%s", FontFiles[FontFileIndex].u.string.ptr);
@ -1193,31 +1218,59 @@ public:
free(pFontData);
}
}
else
{
log_error("textrender", "Failed to open/read font file '%s'", aFontName);
Success = false;
}
}
}
else
{
log_error("textrender", "Font index malformed: 'font files' must be an array");
Success = false;
}
// extract default family name
const json_value &DefaultFace = (*pJsonData)["default"];
if(DefaultFace.type == json_string)
{
m_pGlyphMap->SetDefaultFaceByName(DefaultFace.u.string.ptr);
if(!m_pGlyphMap->SetDefaultFaceByName(DefaultFace.u.string.ptr))
{
Success = false;
}
}
else
{
log_error("textrender", "Font index malformed: 'default' must be a string");
Success = false;
}
// extract language variant family names
const json_value &Variants = (*pJsonData)["language variants"];
if(Variants.type == json_object)
{
m_vVariants.resize(Variants.u.object.length);
m_vVariants.reserve(Variants.u.object.length);
for(size_t i = 0; i < Variants.u.object.length; ++i)
{
str_format(m_vVariants[i].m_aLanguageFile, sizeof(m_vVariants[i].m_aLanguageFile), "languages/%s.txt", Variants.u.object.values[i].name);
const json_value *pFamilyName = Variants.u.object.values[i].value;
if(pFamilyName->type == json_string)
str_copy(m_vVariants[i].m_aFamilyName, pFamilyName->u.string.ptr);
else
m_vVariants[i].m_aFamilyName[0] = '\0';
if(pFamilyName->type != json_string)
{
log_error("textrender", "Font index malformed: 'language variants' entries must have string values (error on entry '%s')", Variants.u.object.values[i].name);
Success = false;
continue;
}
SFontLanguageVariant Variant;
str_format(Variant.m_aLanguageFile, sizeof(Variant.m_aLanguageFile), "languages/%s.txt", Variants.u.object.values[i].name);
str_copy(Variant.m_aFamilyName, pFamilyName->u.string.ptr);
m_vVariants.emplace_back(Variant);
}
}
else
{
log_error("textrender", "Font index malformed: 'language variants' must be an array");
Success = false;
}
// extract fallback family names
@ -1226,21 +1279,41 @@ public:
{
for(unsigned i = 0; i < FallbackFaces.u.array.length; ++i)
{
if(FallbackFaces[i].type == json_string)
if(FallbackFaces[i].type != json_string)
{
m_pGlyphMap->AddFallbackFaceByName(FallbackFaces[i].u.string.ptr);
log_error("textrender", "Font index malformed: 'fallbacks' must be an array of strings (error at index %d)", i);
Success = false;
continue;
}
if(!m_pGlyphMap->AddFallbackFaceByName(FallbackFaces[i].u.string.ptr))
{
Success = false;
}
}
}
else
{
log_error("textrender", "Font index malformed: 'fallbacks' must be an array");
Success = false;
}
// extract icon font family name
const json_value &IconFace = (*pJsonData)["icon"];
if(IconFace.type == json_string)
{
m_pGlyphMap->SetIconFaceByName(IconFace.u.string.ptr);
if(!m_pGlyphMap->SetIconFaceByName(IconFace.u.string.ptr))
{
Success = false;
}
}
else
{
log_error("textrender", "Font index malformed: 'icon' must be a string");
Success = false;
}
json_value_free(pJsonData);
return Success;
}
void SetFontPreset(EFontPreset FontPreset) override

View file

@ -316,7 +316,7 @@ public:
virtual void MoveCursor(CTextCursor *pCursor, float x, float y) const = 0;
virtual void SetCursorPosition(CTextCursor *pCursor, float x, float y) const = 0;
virtual void LoadFonts() = 0;
virtual bool LoadFonts() = 0;
virtual void SetFontPreset(EFontPreset FontPreset) = 0;
virtual void SetFontLanguageVariant(const char *pLanguageFile) = 0;

View file

@ -1205,7 +1205,7 @@ void CChat::OnRender()
{
if(str_startswith_nocase(Command.m_aName, m_Input.GetString() + 1))
{
Cursor.m_X = m_Input.GetCaretPosition().x;
Cursor.m_X = Cursor.m_X + TextRender()->TextWidth(Cursor.m_FontSize, m_Input.GetString(), -1, Cursor.m_LineWidth);
Cursor.m_Y = m_Input.GetCaretPosition().y;
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 0.5f);
TextRender()->TextEx(&Cursor, Command.m_aName + str_length(m_Input.GetString() + 1));

View file

@ -2930,7 +2930,7 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView)
}
LeftView.HSplitTop(2 * LineSize, &Button, &LeftView);
Ui()->DoScrollbarOption(&g_Config.m_ClHookCollSize, &g_Config.m_ClHookCollSize, &Button, Localize("Hook collision line width"), 0, 10000, &CUi::ms_LinearScrollbarScale, CUi::SCROLLBAR_OPTION_MULTILINE);
Ui()->DoScrollbarOption(&g_Config.m_ClHookCollSize, &g_Config.m_ClHookCollSize, &Button, Localize("Hook collision line width"), 0, 20, &CUi::ms_LinearScrollbarScale, CUi::SCROLLBAR_OPTION_MULTILINE);
LeftView.HSplitTop(2 * LineSize, &Button, &LeftView);
Ui()->DoScrollbarOption(&g_Config.m_ClHookCollAlpha, &g_Config.m_ClHookCollAlpha, &Button, Localize("Hook collision line opacity"), 0, 100, &CUi::ms_LinearScrollbarScale, CUi::SCROLLBAR_OPTION_MULTILINE, "%");

View file

@ -328,7 +328,10 @@ void CGameClient::OnInit()
for(int i = 0; i < OLD_NUM_NETOBJTYPES; i++)
Client()->SnapSetStaticsize7(i, m_NetObjHandler7.GetObjSize(i));
TextRender()->LoadFonts();
if(!TextRender()->LoadFonts())
{
Client()->AddWarning(SWarning(Localize("Some fonts could not be loaded. Check the local console for details.")));
}
TextRender()->SetFontLanguageVariant(g_Config.m_ClLanguagefile);
// update and swap after font loading, they are quite huge

View file

@ -123,13 +123,6 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
delete GameServer()->m_apSavedTees[m_pPlayer->GetCid()];
GameServer()->m_apSavedTees[m_pPlayer->GetCid()] = nullptr;
}
if(GameServer()->m_apSavedTeleTees[m_pPlayer->GetCid()])
{
m_pPlayer->m_LastTeleTee = *GameServer()->m_apSavedTeleTees[m_pPlayer->GetCid()];
delete GameServer()->m_apSavedTeleTees[m_pPlayer->GetCid()];
GameServer()->m_apSavedTeleTees[m_pPlayer->GetCid()] = nullptr;
}
}
return true;

View file

@ -26,7 +26,9 @@ class CCharacter : public CEntity
{
MACRO_ALLOC_POOL_ID()
friend class CSaveTee; // need to use core
// need to use core
friend class CSaveTee;
friend class CSaveHotReloadTee;
public:
CCharacter(CGameWorld *pWorld, CNetObj_PlayerInput LastInput);

View file

@ -108,9 +108,6 @@ void CGameContext::Construct(int Resetting)
for(auto &pSavedTee : m_apSavedTees)
pSavedTee = nullptr;
for(auto &pSavedTeleTee : m_apSavedTeleTees)
pSavedTeleTee = nullptr;
for(auto &pSavedTeam : m_apSavedTeams)
pSavedTeam = nullptr;
@ -134,9 +131,6 @@ void CGameContext::Destruct(int Resetting)
for(auto &pSavedTee : m_apSavedTees)
delete pSavedTee;
for(auto &pSavedTeleTee : m_apSavedTeleTees)
delete pSavedTeleTee;
for(auto &pSavedTeam : m_apSavedTeams)
delete pSavedTeam;
@ -1717,9 +1711,6 @@ void CGameContext::OnClientDrop(int ClientId, const char *pReason)
delete m_apSavedTees[ClientId];
m_apSavedTees[ClientId] = nullptr;
delete m_apSavedTeleTees[ClientId];
m_apSavedTeleTees[ClientId] = nullptr;
m_aTeamMapping[ClientId] = -1;
m_VoteUpdate = true;
@ -3219,12 +3210,9 @@ void CGameContext::ConHotReload(IConsole::IResult *pResult, void *pUserData)
CCharacter *pChar = pSelf->GetPlayerChar(i);
// Save the tee individually
pSelf->m_apSavedTees[i] = new CSaveTee();
pSelf->m_apSavedTees[i] = new CSaveHotReloadTee();
pSelf->m_apSavedTees[i]->Save(pChar, false);
if(pSelf->m_apPlayers[i])
pSelf->m_apSavedTeleTees[i] = new CSaveTee(pSelf->m_apPlayers[i]->m_LastTeleTee);
// Save the team state
pSelf->m_aTeamMapping[i] = pSelf->GetDDRaceTeam(i);
if(pSelf->m_aTeamMapping[i] == TEAM_SUPER)

View file

@ -182,8 +182,7 @@ public:
CNetObj_PlayerInput m_aLastPlayerInput[MAX_CLIENTS];
bool m_aPlayerHasInput[MAX_CLIENTS];
CSaveTeam *m_apSavedTeams[MAX_CLIENTS];
CSaveTee *m_apSavedTees[MAX_CLIENTS];
CSaveTee *m_apSavedTeleTees[MAX_CLIENTS];
CSaveHotReloadTee *m_apSavedTees[MAX_CLIENTS];
int m_aTeamMapping[MAX_CLIENTS];
// returns last input if available otherwise nulled PlayerInput object

View file

@ -482,6 +482,26 @@ bool CSaveTee::IsHooking() const
return m_HookState == HOOK_GRABBED || m_HookState == HOOK_FLYING;
}
void CSaveHotReloadTee::Save(CCharacter *pChr, bool AddPenalty)
{
m_SaveTee.Save(pChr, AddPenalty);
m_Super = pChr->m_Core.m_Super;
m_Invincible = pChr->m_Core.m_Invincible;
if(pChr->m_pPlayer)
m_SavedTeleTee = pChr->m_pPlayer->m_LastTeleTee;
}
bool CSaveHotReloadTee::Load(CCharacter *pChr, int Team, bool IsSwap)
{
bool Result = m_SaveTee.Load(pChr, Team, IsSwap);
pChr->SetSuper(m_Super);
pChr->SetInvincible(m_Invincible);
pChr->GetPlayer()->m_LastTeleTee = m_SavedTeleTee;
return Result;
}
CSaveTeam::CSaveTeam()
{
m_aString[0] = '\0';
@ -507,7 +527,7 @@ ESaveResult CSaveTeam::Save(CGameContext *pGameServer, int Team, bool Dry, bool
}
m_MembersCount = pTeams->Count(Team);
if(m_MembersCount <= 0 && !Force)
if(m_MembersCount <= 0)
{
return ESaveResult::TEAM_NOT_FOUND;
}
@ -529,7 +549,7 @@ ESaveResult CSaveTeam::Save(CGameContext *pGameServer, int Team, bool Dry, bool
CCharacter *p = (CCharacter *)pGameServer->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER);
for(; p; p = (CCharacter *)p->TypeNext())
{
if(pTeams->m_Core.Team(p->GetPlayer()->GetCid()) != Team && !Force)
if(pTeams->m_Core.Team(p->GetPlayer()->GetCid()) != Team)
continue;
if(m_MembersCount == j && !Force)
return ESaveResult::CHAR_NOT_FOUND;

View file

@ -148,6 +148,21 @@ private:
char m_aGameUuid[UUID_MAXSTRSIZE];
};
class CSaveHotReloadTee
{
public:
CSaveHotReloadTee() = default;
~CSaveHotReloadTee() = default;
void Save(CCharacter *pchr, bool AddPenalty = true);
bool Load(CCharacter *pchr, int Team, bool IsSwap = false);
private:
CSaveTee m_SaveTee;
int m_Super;
int m_Invincible;
CSaveTee m_SavedTeleTee;
};
class CSaveTeam
{
public:

View file

@ -3,7 +3,7 @@
#ifndef GAME_VERSION_H
#define GAME_VERSION_H
#ifndef GAME_RELEASE_VERSION
#define GAME_RELEASE_VERSION "18.7"
#define GAME_RELEASE_VERSION "18.8"
#endif
// teeworlds
@ -13,7 +13,7 @@
#define GAME_NETVERSION7 "0.7 802f1be60a05665f"
// ddnet
#define DDNET_VERSION_NUMBER 18070
#define DDNET_VERSION_NUMBER 18080
extern const char *GIT_SHORTREV_HASH;
#define GAME_NAME "DDNet"
#endif