mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Add customization
This commit is contained in:
parent
af958704ca
commit
0e71a47708
|
@ -1707,6 +1707,7 @@ if(CLIENT)
|
|||
components/menus_demo.cpp
|
||||
components/menus_ingame.cpp
|
||||
components/menus_settings.cpp
|
||||
components/menus_settings_assets.cpp
|
||||
components/menus_start.cpp
|
||||
components/motd.cpp
|
||||
components/motd.h
|
||||
|
|
|
@ -38,6 +38,11 @@ MACRO_CONFIG_INT(ClPrintBroadcasts, cl_print_broadcasts, 1, 0, 1, CFGFLAG_CLIENT
|
|||
MACRO_CONFIG_INT(ClPrintMotd, cl_print_motd, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Print motd to console")
|
||||
MACRO_CONFIG_INT(ClFriendsIgnoreClan, cl_friends_ignore_clan, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Ignore clan tag when searching for friends")
|
||||
|
||||
MACRO_CONFIG_STR(ClAssetsEntites, cl_assets_entities, 50, "default", CFGFLAG_SAVE | CFGFLAG_CLIENT, "The asset/assets for entities")
|
||||
MACRO_CONFIG_STR(ClAssetGame, cl_asset_game, 50, "default", CFGFLAG_SAVE | CFGFLAG_CLIENT, "The asset for game")
|
||||
MACRO_CONFIG_STR(ClAssetEmoticons, cl_asset_emoticons, 50, "default", CFGFLAG_SAVE | CFGFLAG_CLIENT, "The asset for emoticons")
|
||||
MACRO_CONFIG_STR(ClAssetParticles, cl_asset_particles, 50, "default", CFGFLAG_SAVE | CFGFLAG_CLIENT, "The asset for particles")
|
||||
|
||||
MACRO_CONFIG_STR(BrFilterString, br_filter_string, 25, "Novice", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Server browser filtering string")
|
||||
MACRO_CONFIG_STR(BrExcludeString, br_exclude_string, 25, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Server browser exclusion string")
|
||||
MACRO_CONFIG_INT(BrFilterFull, br_filter_full, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Filter out full server in browser")
|
||||
|
|
|
@ -23,11 +23,22 @@ CMapImages::CMapImages(int TextureSize)
|
|||
m_SpeedupArrowIsLoaded = false;
|
||||
|
||||
mem_zero(m_aTextureUsedByTileOrQuadLayerFlag, sizeof(m_aTextureUsedByTileOrQuadLayerFlag));
|
||||
|
||||
str_copy(m_aEntitiesPath, "editor/entities_clear", sizeof(m_aEntitiesPath));
|
||||
|
||||
static_assert(sizeof(gs_aModEntitiesNames) / sizeof(gs_aModEntitiesNames[0]) == MAP_IMAGE_MOD_TYPE_COUNT, "Mod name string count is not equal to mod type count");
|
||||
}
|
||||
|
||||
void CMapImages::OnInit()
|
||||
{
|
||||
InitOverlayTextures();
|
||||
|
||||
if(str_comp(g_Config.m_ClAssetsEntites, "default") == 0)
|
||||
str_copy(m_aEntitiesPath, "editor/entities_clear", sizeof(m_aEntitiesPath));
|
||||
else
|
||||
{
|
||||
str_format(m_aEntitiesPath, sizeof(m_aEntitiesPath), "assets/entities/%s", g_Config.m_ClAssetsEntites);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapImages::OnMapLoadImpl(class CLayers *pLayers, IMap *pMap)
|
||||
|
@ -141,40 +152,21 @@ bool CMapImages::HasTuneLayer(EMapImageModType ModType)
|
|||
|
||||
IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType EntityLayerType)
|
||||
{
|
||||
const char *pEntities = "ddnet";
|
||||
EMapImageModType EntitiesModType = MAP_IMAGE_MOD_TYPE_DDNET;
|
||||
bool EntitesAreMasked = !GameClient()->m_GameInfo.m_DontMaskEntities;
|
||||
|
||||
if(GameClient()->m_GameInfo.m_EntitiesDDNet)
|
||||
{
|
||||
pEntities = "ddnet";
|
||||
EntitiesModType = MAP_IMAGE_MOD_TYPE_DDNET;
|
||||
}
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesDDRace)
|
||||
{
|
||||
pEntities = "ddrace";
|
||||
EntitiesModType = MAP_IMAGE_MOD_TYPE_DDRACE;
|
||||
}
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesRace)
|
||||
{
|
||||
pEntities = "race";
|
||||
EntitiesModType = MAP_IMAGE_MOD_TYPE_RACE;
|
||||
}
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesBW)
|
||||
{
|
||||
pEntities = "blockworlds";
|
||||
EntitiesModType = MAP_IMAGE_MOD_TYPE_BLOCKWORLDS;
|
||||
}
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesFNG)
|
||||
{
|
||||
pEntities = "fng";
|
||||
EntitiesModType = MAP_IMAGE_MOD_TYPE_FNG;
|
||||
}
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesVanilla)
|
||||
{
|
||||
pEntities = "vanilla";
|
||||
EntitiesModType = MAP_IMAGE_MOD_TYPE_VANILLA;
|
||||
}
|
||||
|
||||
if(!m_EntitiesIsLoaded[(EntitiesModType * 2) + (int)EntitesAreMasked])
|
||||
{
|
||||
|
@ -184,7 +176,7 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit
|
|||
bool WasUnknwon = !EntitesAreMasked;
|
||||
|
||||
char aPath[64];
|
||||
str_format(aPath, sizeof(aPath), "editor/entities_clear/%s.png", pEntities);
|
||||
str_format(aPath, sizeof(aPath), "%s/%s.png", m_aEntitiesPath, gs_aModEntitiesNames[EntitiesModType]);
|
||||
|
||||
bool GameTypeHasFrontLayer = HasFrontLayer(EntitiesModType) || WasUnknwon;
|
||||
bool GameTypeHasSpeedupLayer = HasSpeedupLayer(EntitiesModType) || WasUnknwon;
|
||||
|
@ -195,7 +187,35 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit
|
|||
int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
|
||||
|
||||
CImageInfo ImgInfo;
|
||||
if(Graphics()->LoadPNG(&ImgInfo, aPath, IStorage::TYPE_ALL) && ImgInfo.m_Width > 0 && ImgInfo.m_Height > 0)
|
||||
bool ImagePNGLoaded = false;
|
||||
if(Graphics()->LoadPNG(&ImgInfo, aPath, IStorage::TYPE_ALL))
|
||||
ImagePNGLoaded = true;
|
||||
else
|
||||
{
|
||||
bool TryDefault = true;
|
||||
// try as single ddnet replacement
|
||||
if(EntitiesModType == MAP_IMAGE_MOD_TYPE_DDNET)
|
||||
{
|
||||
str_format(aPath, sizeof(aPath), "%s.png", m_aEntitiesPath);
|
||||
if(Graphics()->LoadPNG(&ImgInfo, aPath, IStorage::TYPE_ALL))
|
||||
{
|
||||
ImagePNGLoaded = true;
|
||||
TryDefault = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ImagePNGLoaded && TryDefault)
|
||||
{
|
||||
// try default
|
||||
str_format(aPath, sizeof(aPath), "editor/entities_clear/%s.png", gs_aModEntitiesNames[EntitiesModType]);
|
||||
if(Graphics()->LoadPNG(&ImgInfo, aPath, IStorage::TYPE_ALL))
|
||||
{
|
||||
ImagePNGLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ImagePNGLoaded && ImgInfo.m_Width > 0 && ImgInfo.m_Height > 0)
|
||||
{
|
||||
int ColorChannelCount = 0;
|
||||
if(ImgInfo.m_Format == CImageInfo::FORMAT_ALPHA)
|
||||
|
@ -344,6 +364,31 @@ IGraphics::CTextureHandle CMapImages::GetOverlayCenter()
|
|||
return m_OverlayCenterTexture;
|
||||
}
|
||||
|
||||
void CMapImages::ChangeEntitiesPath(const char *pPath)
|
||||
{
|
||||
if(str_comp(pPath, "default") == 0)
|
||||
str_copy(m_aEntitiesPath, "editor/entities_clear", sizeof(m_aEntitiesPath));
|
||||
else
|
||||
{
|
||||
str_format(m_aEntitiesPath, sizeof(m_aEntitiesPath), "assets/entities/%s", pPath);
|
||||
}
|
||||
|
||||
for(int i = 0; i < MAP_IMAGE_MOD_TYPE_COUNT * 2; ++i)
|
||||
{
|
||||
if(m_EntitiesIsLoaded[i])
|
||||
{
|
||||
for(int n = 0; n < MAP_IMAGE_ENTITY_LAYER_TYPE_COUNT; ++n)
|
||||
{
|
||||
if(m_EntitiesTextures[i][n] != -1)
|
||||
Graphics()->UnloadTexture(m_EntitiesTextures[i][n]);
|
||||
m_EntitiesTextures[i][n] = IGraphics::CTextureHandle();
|
||||
}
|
||||
|
||||
m_EntitiesIsLoaded[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMapImages::SetTextureScale(int Scale)
|
||||
{
|
||||
if(m_TextureScale == Scale)
|
||||
|
|
|
@ -28,6 +28,14 @@ enum EMapImageModType
|
|||
MAP_IMAGE_MOD_TYPE_COUNT,
|
||||
};
|
||||
|
||||
static const char *const gs_aModEntitiesNames[] = {
|
||||
"ddnet",
|
||||
"ddrace",
|
||||
"race",
|
||||
"blockworlds",
|
||||
"fng",
|
||||
"vanilla"};
|
||||
|
||||
class CMapImages : public CComponent
|
||||
{
|
||||
friend class CBackground;
|
||||
|
@ -37,6 +45,8 @@ class CMapImages : public CComponent
|
|||
int m_aTextureUsedByTileOrQuadLayerFlag[64]; // 0: nothing, 1(as flag): tile layer, 2(as flag): quad layer
|
||||
int m_Count;
|
||||
|
||||
char m_aEntitiesPath[MAX_PATH_LENGTH];
|
||||
|
||||
bool HasFrontLayer(EMapImageModType ModType);
|
||||
bool HasSpeedupLayer(EMapImageModType ModType);
|
||||
bool HasSwitchLayer(EMapImageModType ModType);
|
||||
|
@ -66,6 +76,8 @@ public:
|
|||
void SetTextureScale(int Size);
|
||||
int GetTextureScale();
|
||||
|
||||
void ChangeEntitiesPath(const char *pPath);
|
||||
|
||||
private:
|
||||
bool m_EntitiesIsLoaded[MAP_IMAGE_MOD_TYPE_COUNT * 2];
|
||||
bool m_SpeedupArrowIsLoaded;
|
||||
|
|
|
@ -51,11 +51,11 @@ void CMenuBackground::OnInit()
|
|||
void CMenuBackground::ResetPositions()
|
||||
{
|
||||
m_Positions[POS_START] = vec2(500.0f, 500.0f);
|
||||
m_Positions[POS_INTERNET] = vec2(1000.0f, 1000.0f);
|
||||
m_Positions[POS_LAN] = vec2(1100.0f, 1000.0f);
|
||||
m_Positions[POS_BROWSER_INTERNET] = vec2(1000.0f, 1000.0f);
|
||||
m_Positions[POS_BROWSER_LAN] = vec2(1100.0f, 1000.0f);
|
||||
m_Positions[POS_DEMOS] = vec2(900.0f, 100.0f);
|
||||
m_Positions[POS_NEWS] = vec2(500.0f, 750.0f);
|
||||
m_Positions[POS_FAVORITES] = vec2(1250.0f, 500.0f);
|
||||
m_Positions[POS_BROWSER_FAVORITES] = vec2(1250.0f, 500.0f);
|
||||
m_Positions[POS_SETTINGS_LANGUAGE] = vec2(500.0f, 1200.0f);
|
||||
m_Positions[POS_SETTINGS_GENERAL] = vec2(500.0f, 1000.0f);
|
||||
m_Positions[POS_SETTINGS_PLAYER] = vec2(600.0f, 1000.0f);
|
||||
|
@ -65,8 +65,13 @@ void CMenuBackground::ResetPositions()
|
|||
m_Positions[POS_SETTINGS_GRAPHICS] = vec2(900.0f, 1000.0f);
|
||||
m_Positions[POS_SETTINGS_SOUND] = vec2(1000.0f, 1000.0f);
|
||||
m_Positions[POS_SETTINGS_DDNET] = vec2(1200.0f, 200.0f);
|
||||
for(int i = 0; i < POS_CUSTOM_NUM; ++i)
|
||||
m_Positions[POS_CUSTOM0 + i] = vec2(500.0f + (75.0f * (float)i), 1250.0f - (75.0f * (float)i));
|
||||
m_Positions[POS_SETTINGS_ASSETS] = vec2(500.0f, 500.0f);
|
||||
for(int i = 0; i < POS_BROWSER_CUSTOM_NUM; ++i)
|
||||
m_Positions[POS_BROWSER_CUSTOM0 + i] = vec2(500.0f + (75.0f * (float)i), 1250.0f - (75.0f * (float)i));
|
||||
for(int i = 0; i < POS_SETTINGS_RESERVED_NUM; ++i)
|
||||
m_Positions[POS_SETTINGS_RESERVED0 + i] = vec2(0, 0);
|
||||
for(int i = 0; i < POS_RESERVED_NUM; ++i)
|
||||
m_Positions[POS_RESERVED0 + i] = vec2(0, 0);
|
||||
}
|
||||
|
||||
int CMenuBackground::ThemeScan(const char *pName, int IsDir, int DirType, void *pUser)
|
||||
|
|
|
@ -32,11 +32,8 @@ public:
|
|||
enum
|
||||
{
|
||||
POS_START = 0,
|
||||
POS_INTERNET,
|
||||
POS_LAN,
|
||||
POS_DEMOS,
|
||||
POS_NEWS,
|
||||
POS_FAVORITES,
|
||||
POS_SETTINGS_LANGUAGE,
|
||||
POS_SETTINGS_GENERAL,
|
||||
POS_SETTINGS_PLAYER,
|
||||
|
@ -46,21 +43,26 @@ public:
|
|||
POS_SETTINGS_GRAPHICS,
|
||||
POS_SETTINGS_SOUND,
|
||||
POS_SETTINGS_DDNET,
|
||||
POS_CUSTOM,
|
||||
POS_CUSTOM0 = POS_CUSTOM, // ddnet tab
|
||||
POS_CUSTOM1, // kog tab
|
||||
POS_CUSTOM2,
|
||||
POS_CUSTOM3,
|
||||
POS_CUSTOM4,
|
||||
POS_CUSTOM5,
|
||||
POS_CUSTOM6,
|
||||
POS_CUSTOM7,
|
||||
POS_CUSTOM8,
|
||||
POS_CUSTOM9,
|
||||
POS_SETTINGS_ASSETS,
|
||||
POS_SETTINGS_RESERVED0,
|
||||
POS_SETTINGS_RESERVED1,
|
||||
POS_BROWSER_INTERNET,
|
||||
POS_BROWSER_LAN,
|
||||
POS_BROWSER_FAVORITES,
|
||||
POS_BROWSER_CUSTOM,
|
||||
POS_BROWSER_CUSTOM0 = POS_BROWSER_CUSTOM, // ddnet tab
|
||||
POS_BROWSER_CUSTOM1, // kog tab
|
||||
POS_BROWSER_CUSTOM2,
|
||||
POS_BROWSER_CUSTOM3,
|
||||
POS_RESERVED0,
|
||||
POS_RESERVED1,
|
||||
POS_RESERVED2,
|
||||
|
||||
NUM_POS,
|
||||
|
||||
POS_CUSTOM_NUM = (POS_CUSTOM9 - POS_CUSTOM0) + 1,
|
||||
POS_BROWSER_CUSTOM_NUM = (POS_BROWSER_CUSTOM3 - POS_BROWSER_CUSTOM0) + 1,
|
||||
POS_SETTINGS_RESERVED_NUM = (POS_SETTINGS_RESERVED1 - POS_SETTINGS_RESERVED0) + 1,
|
||||
POS_RESERVED_NUM = (POS_RESERVED2 - POS_RESERVED0) + 1,
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -1242,12 +1242,12 @@ int CMenus::Render()
|
|||
}
|
||||
else if(m_MenuPage == PAGE_INTERNET)
|
||||
{
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_INTERNET);
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_BROWSER_INTERNET);
|
||||
RenderServerbrowser(MainView);
|
||||
}
|
||||
else if(m_MenuPage == PAGE_LAN)
|
||||
{
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_LAN);
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_BROWSER_LAN);
|
||||
RenderServerbrowser(MainView);
|
||||
}
|
||||
else if(m_MenuPage == PAGE_DEMOS)
|
||||
|
@ -1257,17 +1257,17 @@ int CMenus::Render()
|
|||
}
|
||||
else if(m_MenuPage == PAGE_FAVORITES)
|
||||
{
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_FAVORITES);
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_BROWSER_FAVORITES);
|
||||
RenderServerbrowser(MainView);
|
||||
}
|
||||
else if(m_MenuPage == PAGE_DDNET)
|
||||
{
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_CUSTOM0);
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_BROWSER_CUSTOM0);
|
||||
RenderServerbrowser(MainView);
|
||||
}
|
||||
else if(m_MenuPage == PAGE_KOG)
|
||||
{
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_CUSTOM0 + 1);
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_BROWSER_CUSTOM0 + 1);
|
||||
RenderServerbrowser(MainView);
|
||||
}
|
||||
else if(m_MenuPage == PAGE_SETTINGS)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <engine/friends.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/shared/linereader.h>
|
||||
#include <game/client/components/mapimages.h>
|
||||
|
||||
#include <game/client/component.h>
|
||||
#include <game/client/ui.h>
|
||||
|
@ -96,7 +97,7 @@ class CMenus : public CComponent
|
|||
};
|
||||
|
||||
void UiDoListboxStart(const void *pID, const CUIRect *pRect, float RowHeight, const char *pTitle, const char *pBottomText, int NumItems,
|
||||
int ItemsPerRow, int SelectedIndex, float ScrollValue);
|
||||
int ItemsPerRow, int SelectedIndex, float ScrollValue, bool LogicOnly = false);
|
||||
CListboxItem UiDoListboxNextItem(const void *pID, bool Selected = false, bool KeyEvents = true, bool NoHoverEffects = false);
|
||||
CListboxItem UiDoListboxNextRow();
|
||||
int UiDoListboxEnd(float *pScrollValue, bool *pItemActivated, bool *pListBoxActive = 0);
|
||||
|
@ -104,6 +105,53 @@ class CMenus : public CComponent
|
|||
//static void demolist_listdir_callback(const char *name, int is_dir, void *user);
|
||||
//static void demolist_list_callback(const CUIRect *rect, int index, void *user);
|
||||
|
||||
// menus_settings_assets.cpp
|
||||
public:
|
||||
struct SCustomItem
|
||||
{
|
||||
IGraphics::CTextureHandle m_RenderTexture;
|
||||
|
||||
char m_aName[50];
|
||||
|
||||
bool operator<(const SCustomItem &Other) const { return str_comp(m_aName, Other.m_aName) < 0; }
|
||||
};
|
||||
|
||||
struct SCustomEntities : public SCustomItem
|
||||
{
|
||||
struct SEntitiesImage
|
||||
{
|
||||
IGraphics::CTextureHandle m_Texture;
|
||||
};
|
||||
SEntitiesImage m_aImages[MAP_IMAGE_MOD_TYPE_COUNT];
|
||||
};
|
||||
|
||||
struct SCustomGame : public SCustomItem
|
||||
{
|
||||
};
|
||||
|
||||
struct SCustomEmoticon : public SCustomItem
|
||||
{
|
||||
};
|
||||
|
||||
struct SCustomParticle : public SCustomItem
|
||||
{
|
||||
};
|
||||
|
||||
protected:
|
||||
sorted_array<SCustomEntities> m_EntitiesList;
|
||||
sorted_array<SCustomGame> m_GameList;
|
||||
sorted_array<SCustomEmoticon> m_EmoticonList;
|
||||
sorted_array<SCustomParticle> m_ParticlesList;
|
||||
|
||||
static void LoadEntities(struct SCustomEntities *pEntitiesItem, void *pUser);
|
||||
static int EntitiesScan(const char *pName, int IsDir, int DirType, void *pUser);
|
||||
|
||||
static int GameScan(const char *pName, int IsDir, int DirType, void *pUser);
|
||||
static int EmoticonsScan(const char *pName, int IsDir, int DirType, void *pUser);
|
||||
static int ParticlesScan(const char *pName, int IsDir, int DirType, void *pUser);
|
||||
|
||||
void ClearCustomItems(int CurTab);
|
||||
|
||||
int m_MenuPage;
|
||||
int m_GamePage;
|
||||
int m_Popup;
|
||||
|
@ -338,6 +386,7 @@ class CMenus : public CComponent
|
|||
void RenderSettingsGraphics(CUIRect MainView);
|
||||
void RenderSettingsSound(CUIRect MainView);
|
||||
void RenderSettings(CUIRect MainView);
|
||||
void RenderSettingsCustom(CUIRect MainView);
|
||||
|
||||
void SetActive(bool Active);
|
||||
|
||||
|
@ -399,6 +448,7 @@ public:
|
|||
SETTINGS_GRAPHICS,
|
||||
SETTINGS_SOUND,
|
||||
SETTINGS_DDNET,
|
||||
SETTINGS_ASSETS,
|
||||
};
|
||||
|
||||
// DDRace
|
||||
|
|
|
@ -509,25 +509,28 @@ static bool gs_ListBoxItemActivated;
|
|||
static bool gs_ListBoxClicked;
|
||||
|
||||
void CMenus::UiDoListboxStart(const void *pID, const CUIRect *pRect, float RowHeight, const char *pTitle, const char *pBottomText, int NumItems,
|
||||
int ItemsPerRow, int SelectedIndex, float ScrollValue)
|
||||
int ItemsPerRow, int SelectedIndex, float ScrollValue, bool LogicOnly)
|
||||
{
|
||||
CUIRect Scroll, Row;
|
||||
CUIRect View = *pRect;
|
||||
CUIRect Header, Footer;
|
||||
|
||||
// draw header
|
||||
View.HSplitTop(ms_ListheaderHeight, &Header, &View);
|
||||
RenderTools()->DrawUIRect(&Header, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_T, 5.0f);
|
||||
UI()->DoLabel(&Header, pTitle, Header.h * ms_FontmodHeight, 0);
|
||||
if(!LogicOnly)
|
||||
{
|
||||
// draw header
|
||||
View.HSplitTop(ms_ListheaderHeight, &Header, &View);
|
||||
RenderTools()->DrawUIRect(&Header, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_T, 5.0f);
|
||||
UI()->DoLabel(&Header, pTitle, Header.h * ms_FontmodHeight, 0);
|
||||
|
||||
// draw footers
|
||||
View.HSplitBottom(ms_ListheaderHeight, &View, &Footer);
|
||||
RenderTools()->DrawUIRect(&Footer, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_B, 5.0f);
|
||||
Footer.VSplitLeft(10.0f, 0, &Footer);
|
||||
UI()->DoLabel(&Footer, pBottomText, Header.h * ms_FontmodHeight, 0);
|
||||
// draw footers
|
||||
View.HSplitBottom(ms_ListheaderHeight, &View, &Footer);
|
||||
RenderTools()->DrawUIRect(&Footer, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_B, 5.0f);
|
||||
Footer.VSplitLeft(10.0f, 0, &Footer);
|
||||
UI()->DoLabel(&Footer, pBottomText, Header.h * ms_FontmodHeight, 0);
|
||||
|
||||
// background
|
||||
RenderTools()->DrawUIRect(&View, ColorRGBA(0, 0, 0, 0.15f), 0, 0);
|
||||
// background
|
||||
RenderTools()->DrawUIRect(&View, ColorRGBA(0, 0, 0, 0.15f), 0, 0);
|
||||
}
|
||||
|
||||
// prepare the scroll
|
||||
View.VSplitRight(15, &View, &Scroll);
|
||||
|
|
|
@ -527,7 +527,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
|||
static int s_ClearButton = 0;
|
||||
DoClearableEditBox(Skin, &s_ClearButton, &Label, Skin, sizeof(g_Config.m_ClPlayerSkin), 14.0f, &s_OffsetSkin, false, CUI::CORNER_ALL, "default");
|
||||
|
||||
// custom colour selector
|
||||
// custom color selector
|
||||
MainView.HSplitTop(20.0f, 0, &MainView);
|
||||
MainView.HSplitTop(20.0f, &Button, &MainView);
|
||||
Button.VSplitMid(&Button, &Button2);
|
||||
|
@ -1399,7 +1399,8 @@ void CMenus::RenderSettings(CUIRect MainView)
|
|||
Localize("Controls"),
|
||||
Localize("Graphics"),
|
||||
Localize("Sound"),
|
||||
Localize("DDNet")};
|
||||
Localize("DDNet"),
|
||||
Localize("Assets")};
|
||||
|
||||
int NumTabs = (int)(sizeof(aTabs) / sizeof(*aTabs));
|
||||
|
||||
|
@ -1458,6 +1459,11 @@ void CMenus::RenderSettings(CUIRect MainView)
|
|||
m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_DDNET);
|
||||
RenderSettingsDDNet(MainView);
|
||||
}
|
||||
else if(g_Config.m_UiSettingsPage == SETTINGS_ASSETS)
|
||||
{
|
||||
m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_ASSETS);
|
||||
RenderSettingsCustom(MainView);
|
||||
}
|
||||
|
||||
if(m_NeedRestartUpdate)
|
||||
{
|
||||
|
|
550
src/game/client/components/menus_settings_assets.cpp
Normal file
550
src/game/client/components/menus_settings_assets.cpp
Normal file
|
@ -0,0 +1,550 @@
|
|||
#include "binds.h"
|
||||
#include <engine/engine.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/storage.h>
|
||||
#include <engine/textrender.h>
|
||||
#include <game/client/gameclient.h>
|
||||
|
||||
#include "menus.h"
|
||||
|
||||
void CMenus::LoadEntities(SCustomEntities *pEntitiesItem, void *pUser)
|
||||
{
|
||||
CMenus *pThis = (CMenus *)pUser;
|
||||
|
||||
char aBuff[MAX_PATH_LENGTH];
|
||||
|
||||
if(str_comp(pEntitiesItem->m_aName, "default") == 0)
|
||||
{
|
||||
for(int i = 0; i < MAP_IMAGE_MOD_TYPE_COUNT; ++i)
|
||||
{
|
||||
str_format(aBuff, sizeof(aBuff), "editor/entities_clear/%s.png", gs_aModEntitiesNames[i]);
|
||||
CImageInfo ImgInfo;
|
||||
if(pThis->Graphics()->LoadPNG(&ImgInfo, aBuff, IStorage::TYPE_ALL))
|
||||
{
|
||||
pEntitiesItem->m_aImages[i].m_Texture = pThis->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0);
|
||||
free(ImgInfo.m_pData);
|
||||
|
||||
if(pEntitiesItem->m_RenderTexture == -1)
|
||||
pEntitiesItem->m_RenderTexture = pEntitiesItem->m_aImages[i].m_Texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < MAP_IMAGE_MOD_TYPE_COUNT; ++i)
|
||||
{
|
||||
str_format(aBuff, sizeof(aBuff), "assets/entities/%s/%s.png", pEntitiesItem->m_aName, gs_aModEntitiesNames[i]);
|
||||
CImageInfo ImgInfo;
|
||||
if(pThis->Graphics()->LoadPNG(&ImgInfo, aBuff, IStorage::TYPE_ALL))
|
||||
{
|
||||
pEntitiesItem->m_aImages[i].m_Texture = pThis->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0);
|
||||
free(ImgInfo.m_pData);
|
||||
|
||||
if(pEntitiesItem->m_RenderTexture == -1)
|
||||
pEntitiesItem->m_RenderTexture = pEntitiesItem->m_aImages[i].m_Texture;
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuff, sizeof(aBuff), "assets/entities/%s.png", pEntitiesItem->m_aName);
|
||||
CImageInfo ImgInfo;
|
||||
if(pThis->Graphics()->LoadPNG(&ImgInfo, aBuff, IStorage::TYPE_ALL))
|
||||
{
|
||||
pEntitiesItem->m_aImages[i].m_Texture = pThis->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0);
|
||||
free(ImgInfo.m_pData);
|
||||
|
||||
if(pEntitiesItem->m_RenderTexture == -1)
|
||||
pEntitiesItem->m_RenderTexture = pEntitiesItem->m_aImages[i].m_Texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CMenus::EntitiesScan(const char *pName, int IsDir, int DirType, void *pUser)
|
||||
{
|
||||
CMenus *pThis = (CMenus *)pUser;
|
||||
if(IsDir)
|
||||
{
|
||||
if(pName[0] == '.')
|
||||
return 0;
|
||||
|
||||
// default is reserved
|
||||
if(str_comp(pName, "default") == 0)
|
||||
return 0;
|
||||
|
||||
SCustomEntities EntitiesItem;
|
||||
str_copy(EntitiesItem.m_aName, pName, sizeof(EntitiesItem.m_aName));
|
||||
CMenus::LoadEntities(&EntitiesItem, pUser);
|
||||
pThis->m_EntitiesList.add(EntitiesItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(str_endswith(pName, ".png"))
|
||||
{
|
||||
char aName[MAX_PATH_LENGTH];
|
||||
str_truncate(aName, sizeof(aName), pName, str_length(pName) - 4);
|
||||
// default is reserved
|
||||
if(str_comp(aName, "default") == 0)
|
||||
return 0;
|
||||
|
||||
SCustomEntities EntitiesItem;
|
||||
str_copy(EntitiesItem.m_aName, aName, sizeof(EntitiesItem.m_aName));
|
||||
CMenus::LoadEntities(&EntitiesItem, pUser);
|
||||
pThis->m_EntitiesList.add(EntitiesItem);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename TName>
|
||||
static void LoadAsset(TName *pAssetItem, const char *pAssetName, IGraphics *pGraphics, void *pUser)
|
||||
{
|
||||
char aBuff[MAX_PATH_LENGTH];
|
||||
|
||||
if(str_comp(pAssetItem->m_aName, "default") == 0)
|
||||
{
|
||||
str_format(aBuff, sizeof(aBuff), "%s.png", pAssetName);
|
||||
CImageInfo ImgInfo;
|
||||
if(pGraphics->LoadPNG(&ImgInfo, aBuff, IStorage::TYPE_ALL))
|
||||
{
|
||||
pAssetItem->m_RenderTexture = pGraphics->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0);
|
||||
free(ImgInfo.m_pData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuff, sizeof(aBuff), "assets/%s/%s.png", pAssetName, pAssetItem->m_aName);
|
||||
CImageInfo ImgInfo;
|
||||
if(pGraphics->LoadPNG(&ImgInfo, aBuff, IStorage::TYPE_ALL))
|
||||
{
|
||||
pAssetItem->m_RenderTexture = pGraphics->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0);
|
||||
free(ImgInfo.m_pData);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_format(aBuff, sizeof(aBuff), "assets/%s/%s/%s.png", pAssetName, pAssetItem->m_aName, pAssetName);
|
||||
CImageInfo ImgInfo;
|
||||
if(pGraphics->LoadPNG(&ImgInfo, aBuff, IStorage::TYPE_ALL))
|
||||
{
|
||||
pAssetItem->m_RenderTexture = pGraphics->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0);
|
||||
free(ImgInfo.m_pData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TName>
|
||||
static int AssetScan(const char *pName, int IsDir, int DirType, sorted_array<TName> &AssetList, const char *pAssetName, IGraphics *pGraphics, void *pUser)
|
||||
{
|
||||
if(IsDir)
|
||||
{
|
||||
if(pName[0] == '.')
|
||||
return 0;
|
||||
|
||||
// default is reserved
|
||||
if(str_comp(pName, "default") == 0)
|
||||
return 0;
|
||||
|
||||
TName AssetItem;
|
||||
str_copy(AssetItem.m_aName, pName, sizeof(AssetItem.m_aName));
|
||||
LoadAsset(&AssetItem, pAssetName, pGraphics, pUser);
|
||||
AssetList.add(AssetItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(str_endswith(pName, ".png"))
|
||||
{
|
||||
char aName[MAX_PATH_LENGTH];
|
||||
str_truncate(aName, sizeof(aName), pName, str_length(pName) - 4);
|
||||
// default is reserved
|
||||
if(str_comp(aName, "default") == 0)
|
||||
return 0;
|
||||
|
||||
TName AssetItem;
|
||||
str_copy(AssetItem.m_aName, aName, sizeof(AssetItem.m_aName));
|
||||
LoadAsset(&AssetItem, pAssetName, pGraphics, pUser);
|
||||
AssetList.add(AssetItem);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CMenus::GameScan(const char *pName, int IsDir, int DirType, void *pUser)
|
||||
{
|
||||
CMenus *pMenus = (CMenus *)pUser;
|
||||
IGraphics *pGraphics = pMenus->Graphics();
|
||||
return AssetScan(pName, IsDir, DirType, pMenus->m_GameList, "game", pGraphics, pUser);
|
||||
}
|
||||
|
||||
int CMenus::EmoticonsScan(const char *pName, int IsDir, int DirType, void *pUser)
|
||||
{
|
||||
CMenus *pMenus = (CMenus *)pUser;
|
||||
IGraphics *pGraphics = pMenus->Graphics();
|
||||
return AssetScan(pName, IsDir, DirType, pMenus->m_EmoticonList, "emoticons", pGraphics, pUser);
|
||||
}
|
||||
|
||||
int CMenus::ParticlesScan(const char *pName, int IsDir, int DirType, void *pUser)
|
||||
{
|
||||
CMenus *pMenus = (CMenus *)pUser;
|
||||
IGraphics *pGraphics = pMenus->Graphics();
|
||||
return AssetScan(pName, IsDir, DirType, pMenus->m_ParticlesList, "particles", pGraphics, pUser);
|
||||
}
|
||||
|
||||
static sorted_array<const CMenus::SCustomEntities *> s_SearchEntitiesList;
|
||||
static sorted_array<const CMenus::SCustomGame *> s_SearchGamesList;
|
||||
static sorted_array<const CMenus::SCustomEmoticon *> s_SearchEmoticonsList;
|
||||
static sorted_array<const CMenus::SCustomParticle *> s_SearchParticlesList;
|
||||
|
||||
static bool s_InitCustomList[4] = {
|
||||
true,
|
||||
};
|
||||
|
||||
static int s_CustomListSize[4] = {
|
||||
0,
|
||||
};
|
||||
|
||||
static char s_aFilterString[4][50];
|
||||
|
||||
static int s_CurCustomTab = 0;
|
||||
|
||||
static const CMenus::SCustomItem *GetCustomItem(int CurTab, int Index)
|
||||
{
|
||||
if(CurTab == 0)
|
||||
return s_SearchEntitiesList[Index];
|
||||
else if(CurTab == 1)
|
||||
return s_SearchGamesList[Index];
|
||||
else if(CurTab == 2)
|
||||
return s_SearchEmoticonsList[Index];
|
||||
else if(CurTab == 3)
|
||||
return s_SearchParticlesList[Index];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template<typename TName>
|
||||
void ClearAssetList(sorted_array<TName> &List, IGraphics *pGraphics)
|
||||
{
|
||||
for(int i = 0; i < List.size(); ++i)
|
||||
{
|
||||
if(List[i].m_RenderTexture != -1)
|
||||
pGraphics->UnloadTexture(List[i].m_RenderTexture);
|
||||
List[i].m_RenderTexture = IGraphics::CTextureHandle();
|
||||
}
|
||||
List.clear();
|
||||
}
|
||||
|
||||
void CMenus::ClearCustomItems(int CurTab)
|
||||
{
|
||||
if(CurTab == 0)
|
||||
{
|
||||
for(int i = 0; i < m_EntitiesList.size(); ++i)
|
||||
{
|
||||
for(int n = 0; n < MAP_IMAGE_MOD_TYPE_COUNT; ++n)
|
||||
{
|
||||
if(m_EntitiesList[i].m_aImages[n].m_Texture != -1)
|
||||
Graphics()->UnloadTexture(m_EntitiesList[i].m_aImages[n].m_Texture);
|
||||
m_EntitiesList[i].m_aImages[n].m_Texture = IGraphics::CTextureHandle();
|
||||
}
|
||||
}
|
||||
m_EntitiesList.clear();
|
||||
}
|
||||
else if(CurTab == 1)
|
||||
{
|
||||
ClearAssetList(m_GameList, Graphics());
|
||||
}
|
||||
else if(CurTab == 2)
|
||||
{
|
||||
ClearAssetList(m_EmoticonList, Graphics());
|
||||
}
|
||||
else if(CurTab == 3)
|
||||
{
|
||||
ClearAssetList(m_ParticlesList, Graphics());
|
||||
}
|
||||
s_InitCustomList[CurTab] = true;
|
||||
}
|
||||
|
||||
template<typename TName, typename TCaller>
|
||||
void InitAssetList(sorted_array<TName> &AssetList, const char *pAssetPath, const char *pAssetName, FS_LISTDIR_CALLBACK pfnCallback, IGraphics *pGraphics, IStorage *pStorage, TCaller Caller)
|
||||
{
|
||||
if(AssetList.size() == 0)
|
||||
{
|
||||
TName AssetItem;
|
||||
str_copy(AssetItem.m_aName, "default", sizeof(AssetItem.m_aName));
|
||||
LoadAsset(&AssetItem, pAssetName, pGraphics, Caller);
|
||||
AssetList.add(AssetItem);
|
||||
|
||||
// load assets
|
||||
pStorage->ListDirectory(IStorage::TYPE_ALL, pAssetPath, pfnCallback, Caller);
|
||||
}
|
||||
if(AssetList.size() != s_CustomListSize[s_CurCustomTab])
|
||||
s_InitCustomList[s_CurCustomTab] = true;
|
||||
}
|
||||
|
||||
template<typename TName>
|
||||
int InitSearchList(sorted_array<const TName *> &SearchList, sorted_array<TName> &AssetList)
|
||||
{
|
||||
SearchList.clear();
|
||||
int ListSize = AssetList.size();
|
||||
for(int i = 0; i < ListSize; ++i)
|
||||
{
|
||||
const TName *s = &AssetList[i];
|
||||
|
||||
// filter quick search
|
||||
if(s_aFilterString[s_CurCustomTab][0] != '\0' && !str_find_nocase(s->m_aName, s_aFilterString[s_CurCustomTab]))
|
||||
continue;
|
||||
|
||||
SearchList.add_unsorted(s);
|
||||
}
|
||||
return AssetList.size();
|
||||
}
|
||||
|
||||
void CMenus::RenderSettingsCustom(CUIRect MainView)
|
||||
{
|
||||
CUIRect Label, CustomList, QuickSearch, QuickSearchClearButton, SkinDB, Page1Tab, Page2Tab, Page3Tab, Page4Tab;
|
||||
|
||||
MainView.HSplitTop(20, &Label, &MainView);
|
||||
float TabsW = Label.w;
|
||||
Label.VSplitLeft(TabsW / 4, &Page1Tab, &Page2Tab);
|
||||
Page2Tab.VSplitLeft(TabsW / 4, &Page2Tab, &Page3Tab);
|
||||
Page3Tab.VSplitLeft(TabsW / 4, &Page3Tab, &Page4Tab);
|
||||
|
||||
if(DoButton_MenuTab((void *)&Page1Tab, Localize("Entities"), s_CurCustomTab == 0, &Page1Tab, 5, NULL, NULL, NULL, 4))
|
||||
s_CurCustomTab = 0;
|
||||
if(DoButton_MenuTab((void *)&Page2Tab, Localize("Game"), s_CurCustomTab == 1, &Page2Tab, 0, NULL, NULL, NULL, 4))
|
||||
s_CurCustomTab = 1;
|
||||
if(DoButton_MenuTab((void *)&Page3Tab, Localize("Emoticons"), s_CurCustomTab == 2, &Page3Tab, 0, NULL, NULL, NULL, 4))
|
||||
s_CurCustomTab = 2;
|
||||
if(DoButton_MenuTab((void *)&Page4Tab, Localize("Particles"), s_CurCustomTab == 3, &Page4Tab, 10, NULL, NULL, NULL, 4))
|
||||
s_CurCustomTab = 3;
|
||||
|
||||
if(s_CurCustomTab == 0)
|
||||
{
|
||||
if(m_EntitiesList.size() == 0)
|
||||
{
|
||||
SCustomEntities EntitiesItem;
|
||||
str_copy(EntitiesItem.m_aName, "default", sizeof(EntitiesItem.m_aName));
|
||||
LoadEntities(&EntitiesItem, this);
|
||||
m_EntitiesList.add(EntitiesItem);
|
||||
|
||||
// load entities
|
||||
Storage()->ListDirectory(IStorage::TYPE_ALL, "assets/entities", EntitiesScan, this);
|
||||
}
|
||||
if(m_EntitiesList.size() != s_CustomListSize[s_CurCustomTab])
|
||||
s_InitCustomList[s_CurCustomTab] = true;
|
||||
}
|
||||
else if(s_CurCustomTab == 1)
|
||||
{
|
||||
InitAssetList(m_GameList, "assets/game", "game", GameScan, Graphics(), Storage(), this);
|
||||
}
|
||||
else if(s_CurCustomTab == 2)
|
||||
{
|
||||
InitAssetList(m_EmoticonList, "assets/emoticons", "emoticons", EmoticonsScan, Graphics(), Storage(), this);
|
||||
}
|
||||
else if(s_CurCustomTab == 3)
|
||||
{
|
||||
InitAssetList(m_ParticlesList, "assets/particles", "particles", ParticlesScan, Graphics(), Storage(), this);
|
||||
}
|
||||
|
||||
MainView.HSplitTop(10.0f, 0, &MainView);
|
||||
|
||||
// skin selector
|
||||
MainView.HSplitTop(MainView.h - 10.0f - ms_ButtonHeight, &CustomList, &MainView);
|
||||
static float s_ScrollValue = 0.0f;
|
||||
if(s_InitCustomList[s_CurCustomTab])
|
||||
{
|
||||
int ListSize = 0;
|
||||
if(s_CurCustomTab == 0)
|
||||
{
|
||||
s_SearchEntitiesList.clear();
|
||||
ListSize = m_EntitiesList.size();
|
||||
for(int i = 0; i < ListSize; ++i)
|
||||
{
|
||||
const SCustomEntities *s = &m_EntitiesList[i];
|
||||
|
||||
// filter quick search
|
||||
if(s_aFilterString[s_CurCustomTab][0] != '\0' && !str_find_nocase(s->m_aName, s_aFilterString[s_CurCustomTab]))
|
||||
continue;
|
||||
|
||||
s_SearchEntitiesList.add_unsorted(s);
|
||||
}
|
||||
}
|
||||
else if(s_CurCustomTab == 1)
|
||||
{
|
||||
ListSize = InitSearchList(s_SearchGamesList, m_GameList);
|
||||
}
|
||||
else if(s_CurCustomTab == 2)
|
||||
{
|
||||
ListSize = InitSearchList(s_SearchEmoticonsList, m_EmoticonList);
|
||||
}
|
||||
else if(s_CurCustomTab == 3)
|
||||
{
|
||||
ListSize = InitSearchList(s_SearchParticlesList, m_ParticlesList);
|
||||
}
|
||||
s_InitCustomList[s_CurCustomTab] = false;
|
||||
s_CustomListSize[s_CurCustomTab] = ListSize;
|
||||
}
|
||||
|
||||
int OldSelected = -1;
|
||||
float Margin = 10;
|
||||
float TextureWidth = 150;
|
||||
float TextureHeight = 150;
|
||||
|
||||
int SearchListSize = 0;
|
||||
|
||||
if(s_CurCustomTab == 0)
|
||||
{
|
||||
SearchListSize = s_SearchEntitiesList.size();
|
||||
}
|
||||
else if(s_CurCustomTab == 1)
|
||||
{
|
||||
SearchListSize = s_SearchGamesList.size();
|
||||
TextureHeight = 75;
|
||||
}
|
||||
else if(s_CurCustomTab == 2)
|
||||
{
|
||||
SearchListSize = s_SearchEmoticonsList.size();
|
||||
}
|
||||
else if(s_CurCustomTab == 3)
|
||||
{
|
||||
SearchListSize = s_SearchParticlesList.size();
|
||||
}
|
||||
|
||||
UiDoListboxStart(&s_InitCustomList[s_CurCustomTab], &CustomList, TextureHeight + 15.0f + 10.0f + Margin, "", "", SearchListSize, CustomList.w / (Margin + TextureWidth), OldSelected, s_ScrollValue, true);
|
||||
for(int i = 0; i < SearchListSize; ++i)
|
||||
{
|
||||
const SCustomItem *s = GetCustomItem(s_CurCustomTab, i);
|
||||
if(s == NULL)
|
||||
continue;
|
||||
|
||||
if(s_CurCustomTab == 0)
|
||||
{
|
||||
if(str_comp(s->m_aName, g_Config.m_ClAssetsEntites) == 0)
|
||||
OldSelected = i;
|
||||
}
|
||||
else if(s_CurCustomTab == 1)
|
||||
{
|
||||
if(str_comp(s->m_aName, g_Config.m_ClAssetGame) == 0)
|
||||
OldSelected = i;
|
||||
}
|
||||
else if(s_CurCustomTab == 2)
|
||||
{
|
||||
if(str_comp(s->m_aName, g_Config.m_ClAssetEmoticons) == 0)
|
||||
OldSelected = i;
|
||||
}
|
||||
else if(s_CurCustomTab == 3)
|
||||
{
|
||||
if(str_comp(s->m_aName, g_Config.m_ClAssetParticles) == 0)
|
||||
OldSelected = i;
|
||||
}
|
||||
|
||||
CListboxItem Item = UiDoListboxNextItem(s, OldSelected == i);
|
||||
CUIRect ItemRect = Item.m_Rect;
|
||||
ItemRect.Margin(Margin / 2, &ItemRect);
|
||||
if(Item.m_Visible)
|
||||
{
|
||||
CUIRect TextureRect;
|
||||
ItemRect.HSplitTop(15, &ItemRect, &TextureRect);
|
||||
TextureRect.HSplitTop(10, NULL, &TextureRect);
|
||||
UI()->DoLabelScaled(&ItemRect, s->m_aName, ItemRect.h - 2, 0);
|
||||
if(s->m_RenderTexture != -1)
|
||||
{
|
||||
Graphics()->WrapClamp();
|
||||
Graphics()->TextureSet(s->m_RenderTexture);
|
||||
Graphics()->QuadsBegin();
|
||||
Graphics()->SetColor(1, 1, 1, 1);
|
||||
IGraphics::CQuadItem QuadItem(TextureRect.x + (TextureRect.w - TextureWidth) / 2, TextureRect.y + (TextureRect.h - TextureHeight) / 2, TextureWidth, TextureHeight);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
Graphics()->WrapNormal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0);
|
||||
if(OldSelected != NewSelected)
|
||||
{
|
||||
if(GetCustomItem(s_CurCustomTab, NewSelected)->m_aName[0] != '\0')
|
||||
{
|
||||
if(s_CurCustomTab == 0)
|
||||
{
|
||||
str_copy(g_Config.m_ClAssetsEntites, GetCustomItem(s_CurCustomTab, NewSelected)->m_aName, sizeof(g_Config.m_ClAssetsEntites));
|
||||
m_pClient->m_pMapimages->ChangeEntitiesPath(GetCustomItem(s_CurCustomTab, NewSelected)->m_aName);
|
||||
}
|
||||
else if(s_CurCustomTab == 1)
|
||||
{
|
||||
str_copy(g_Config.m_ClAssetGame, GetCustomItem(s_CurCustomTab, NewSelected)->m_aName, sizeof(g_Config.m_ClAssetGame));
|
||||
GameClient()->LoadGameSkin(g_Config.m_ClAssetGame);
|
||||
}
|
||||
else if(s_CurCustomTab == 2)
|
||||
{
|
||||
str_copy(g_Config.m_ClAssetEmoticons, GetCustomItem(s_CurCustomTab, NewSelected)->m_aName, sizeof(g_Config.m_ClAssetEmoticons));
|
||||
GameClient()->LoadEmoticonsSkin(g_Config.m_ClAssetEmoticons);
|
||||
}
|
||||
else if(s_CurCustomTab == 3)
|
||||
{
|
||||
str_copy(g_Config.m_ClAssetParticles, GetCustomItem(s_CurCustomTab, NewSelected)->m_aName, sizeof(g_Config.m_ClAssetParticles));
|
||||
GameClient()->LoadParticlesSkin(g_Config.m_ClAssetParticles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render quick search
|
||||
{
|
||||
MainView.HSplitBottom(ms_ButtonHeight, &MainView, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(240.0f, &QuickSearch, &SkinDB);
|
||||
QuickSearch.HSplitTop(5.0f, 0, &QuickSearch);
|
||||
const char *pSearchLabel = "\xEE\xA2\xB6";
|
||||
TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_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_OVERSIZE);
|
||||
UI()->DoLabelScaled(&QuickSearch, pSearchLabel, 14.0f, -1);
|
||||
float wSearch = TextRender()->TextWidth(0, 14.0f, pSearchLabel, -1, -1.0f);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetCurFont(NULL);
|
||||
QuickSearch.VSplitLeft(wSearch, 0, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch);
|
||||
QuickSearch.VSplitLeft(QuickSearch.w - 15.0f, &QuickSearch, &QuickSearchClearButton);
|
||||
static int s_ClearButton = 0;
|
||||
static float Offset = 0.0f;
|
||||
if(Input()->KeyPress(KEY_F) && (Input()->KeyIsPressed(KEY_LCTRL) || Input()->KeyIsPressed(KEY_RCTRL)))
|
||||
UI()->SetActiveItem(&s_aFilterString[s_CurCustomTab]);
|
||||
if(DoClearableEditBox(&s_aFilterString[s_CurCustomTab], &s_ClearButton, &QuickSearch, s_aFilterString[s_CurCustomTab], sizeof(s_aFilterString[0]), 14.0f, &Offset, false, CUI::CORNER_ALL, Localize("Search")))
|
||||
s_InitCustomList[s_CurCustomTab] = true;
|
||||
}
|
||||
|
||||
CUIRect ReloadButton;
|
||||
|
||||
SkinDB.VSplitRight(310.0f, 0, &SkinDB);
|
||||
SkinDB.VSplitRight(200.0f, &ReloadButton, &SkinDB);
|
||||
|
||||
ReloadButton.HSplitTop(5.0f, 0, &ReloadButton);
|
||||
ReloadButton.VSplitRight(10.0f, &ReloadButton, NULL);
|
||||
if(DoButton_Menu(&ReloadButton, Localize("Refresh"), 0, &ReloadButton))
|
||||
{
|
||||
ClearCustomItems(s_CurCustomTab);
|
||||
}
|
||||
|
||||
SkinDB.HSplitTop(5.0f, 0, &SkinDB);
|
||||
if(DoButton_Menu(&SkinDB, Localize("Assets directory"), 0, &SkinDB))
|
||||
{
|
||||
char aBuf[MAX_PATH_LENGTH];
|
||||
char aBufFull[MAX_PATH_LENGTH];
|
||||
if(s_CurCustomTab == 0)
|
||||
str_copy(aBufFull, "assets/entities", sizeof(aBufFull));
|
||||
else if(s_CurCustomTab == 1)
|
||||
str_copy(aBufFull, "assets/game", sizeof(aBufFull));
|
||||
else if(s_CurCustomTab == 2)
|
||||
str_copy(aBufFull, "assets/emoticons", sizeof(aBufFull));
|
||||
else if(s_CurCustomTab == 3)
|
||||
str_copy(aBufFull, "assets/particles", sizeof(aBufFull));
|
||||
Storage()->GetCompletePath(IStorage::TYPE_SAVE, aBufFull, aBuf, sizeof(aBuf));
|
||||
Storage()->CreateFolder("assets", IStorage::TYPE_SAVE);
|
||||
Storage()->CreateFolder(aBufFull, IStorage::TYPE_SAVE);
|
||||
str_format(aBufFull, sizeof(aBufFull), "file://%s", aBuf);
|
||||
if(!open_link(aBufFull))
|
||||
{
|
||||
dbg_msg("menus", "couldn't open link");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -325,7 +325,14 @@ void CGameClient::OnInit()
|
|||
// setup load amount// load textures
|
||||
for(int i = 0; i < g_pData->m_NumImages; i++)
|
||||
{
|
||||
g_pData->m_aImages[i].m_Id = Graphics()->LoadTexture(g_pData->m_aImages[i].m_pFilename, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
|
||||
if(i == IMAGE_GAME)
|
||||
LoadGameSkin(g_Config.m_ClAssetGame);
|
||||
else if(i == IMAGE_EMOTICONS)
|
||||
LoadEmoticonsSkin(g_Config.m_ClAssetEmoticons);
|
||||
else if(i == IMAGE_PARTICLES)
|
||||
LoadParticlesSkin(g_Config.m_ClAssetParticles);
|
||||
else
|
||||
g_pData->m_aImages[i].m_Id = Graphics()->LoadTexture(g_pData->m_aImages[i].m_pFilename, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
|
||||
g_GameClient.m_pMenus->RenderLoading();
|
||||
}
|
||||
|
||||
|
@ -2495,6 +2502,120 @@ bool CGameClient::IsOtherTeam(int ClientID)
|
|||
return m_Teams.Team(ClientID) != m_Teams.Team(m_Snap.m_LocalClientID);
|
||||
}
|
||||
|
||||
void CGameClient::LoadGameSkin(const char *pPath, bool AsDir)
|
||||
{
|
||||
if(g_pData->m_aImages[IMAGE_GAME].m_Id != -1)
|
||||
{
|
||||
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_GAME].m_Id);
|
||||
g_pData->m_aImages[IMAGE_GAME].m_Id = IGraphics::CTextureHandle();
|
||||
}
|
||||
|
||||
char aPath[MAX_PATH_LENGTH];
|
||||
bool IsDefault = false;
|
||||
if(str_comp(pPath, "default") == 0)
|
||||
{
|
||||
str_format(aPath, sizeof(aPath), "%s", g_pData->m_aImages[IMAGE_GAME].m_pFilename);
|
||||
IsDefault = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(AsDir)
|
||||
str_format(aPath, sizeof(aPath), "assets/game/%s/%s", pPath, g_pData->m_aImages[IMAGE_GAME].m_pFilename);
|
||||
else
|
||||
str_format(aPath, sizeof(aPath), "assets/game/%s.png", pPath);
|
||||
}
|
||||
|
||||
CImageInfo ImgInfo;
|
||||
bool PngLoaded = Graphics()->LoadPNG(&ImgInfo, aPath, IStorage::TYPE_ALL);
|
||||
if(!PngLoaded && !IsDefault)
|
||||
{
|
||||
if(AsDir)
|
||||
LoadGameSkin("default");
|
||||
else
|
||||
LoadGameSkin(pPath, true);
|
||||
}
|
||||
else if(PngLoaded)
|
||||
{
|
||||
g_pData->m_aImages[IMAGE_GAME].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameClient::LoadEmoticonsSkin(const char *pPath, bool AsDir)
|
||||
{
|
||||
if(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id != -1)
|
||||
{
|
||||
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
|
||||
g_pData->m_aImages[IMAGE_EMOTICONS].m_Id = IGraphics::CTextureHandle();
|
||||
}
|
||||
|
||||
char aPath[MAX_PATH_LENGTH];
|
||||
bool IsDefault = false;
|
||||
if(str_comp(pPath, "default") == 0)
|
||||
{
|
||||
str_format(aPath, sizeof(aPath), "%s", g_pData->m_aImages[IMAGE_EMOTICONS].m_pFilename);
|
||||
IsDefault = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(AsDir)
|
||||
str_format(aPath, sizeof(aPath), "assets/emoticons/%s/%s", pPath, g_pData->m_aImages[IMAGE_EMOTICONS].m_pFilename);
|
||||
else
|
||||
str_format(aPath, sizeof(aPath), "assets/emoticons/%s.png", pPath);
|
||||
}
|
||||
|
||||
CImageInfo ImgInfo;
|
||||
bool PngLoaded = Graphics()->LoadPNG(&ImgInfo, aPath, IStorage::TYPE_ALL);
|
||||
if(!PngLoaded && !IsDefault)
|
||||
{
|
||||
if(AsDir)
|
||||
LoadEmoticonsSkin("default");
|
||||
else
|
||||
LoadEmoticonsSkin(pPath, true);
|
||||
}
|
||||
else if(PngLoaded)
|
||||
{
|
||||
g_pData->m_aImages[IMAGE_EMOTICONS].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameClient::LoadParticlesSkin(const char *pPath, bool AsDir)
|
||||
{
|
||||
if(g_pData->m_aImages[IMAGE_PARTICLES].m_Id != -1)
|
||||
{
|
||||
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
|
||||
g_pData->m_aImages[IMAGE_PARTICLES].m_Id = IGraphics::CTextureHandle();
|
||||
}
|
||||
|
||||
char aPath[MAX_PATH_LENGTH];
|
||||
bool IsDefault = false;
|
||||
if(str_comp(pPath, "default") == 0)
|
||||
{
|
||||
str_format(aPath, sizeof(aPath), "%s", g_pData->m_aImages[IMAGE_PARTICLES].m_pFilename);
|
||||
IsDefault = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(AsDir)
|
||||
str_format(aPath, sizeof(aPath), "assets/particles/%s/%s", pPath, g_pData->m_aImages[IMAGE_PARTICLES].m_pFilename);
|
||||
else
|
||||
str_format(aPath, sizeof(aPath), "assets/particles/%s.png", pPath);
|
||||
}
|
||||
|
||||
CImageInfo ImgInfo;
|
||||
bool PngLoaded = Graphics()->LoadPNG(&ImgInfo, aPath, IStorage::TYPE_ALL);
|
||||
if(!PngLoaded && !IsDefault)
|
||||
{
|
||||
if(AsDir)
|
||||
LoadParticlesSkin("default");
|
||||
else
|
||||
LoadParticlesSkin(pPath, true);
|
||||
}
|
||||
else if(PngLoaded)
|
||||
{
|
||||
g_pData->m_aImages[IMAGE_PARTICLES].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameClient::LoadMapSettings()
|
||||
{
|
||||
// Reset Tunezones
|
||||
|
|
|
@ -450,6 +450,10 @@ public:
|
|||
void Echo(const char *pString);
|
||||
bool IsOtherTeam(int ClientID);
|
||||
|
||||
void LoadGameSkin(const char *pPath, bool AsDir = false);
|
||||
void LoadEmoticonsSkin(const char *pPath, bool AsDir = false);
|
||||
void LoadParticlesSkin(const char *pPath, bool AsDir = false);
|
||||
|
||||
private:
|
||||
bool m_DDRaceMsgSent[2];
|
||||
int m_ShowOthers[2];
|
||||
|
|
Loading…
Reference in a new issue