2020-09-26 07:37:35 +00:00
|
|
|
#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"
|
|
|
|
|
2022-04-02 11:37:59 +00:00
|
|
|
typedef std::function<void()> TMenuAssetScanLoadedFunc;
|
|
|
|
|
|
|
|
struct SMenuAssetScanUser
|
|
|
|
{
|
|
|
|
void *m_pUser;
|
|
|
|
TMenuAssetScanLoadedFunc m_LoadedFunc;
|
|
|
|
};
|
|
|
|
|
2020-09-26 07:37:35 +00:00
|
|
|
void CMenus::LoadEntities(SCustomEntities *pEntitiesItem, void *pUser)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
auto *pRealUser = (SMenuAssetScanUser *)pUser;
|
|
|
|
auto *pThis = (CMenus *)pRealUser->m_pUser;
|
2020-09-26 07:37:35 +00:00
|
|
|
|
2021-09-13 08:06:34 +00:00
|
|
|
char aBuff[IO_MAX_PATH_LENGTH];
|
2020-09-26 07:37:35 +00:00
|
|
|
|
|
|
|
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);
|
2020-11-25 12:05:53 +00:00
|
|
|
pThis->Graphics()->FreePNG(&ImgInfo);
|
2020-09-26 07:37:35 +00:00
|
|
|
|
2012-08-12 12:02:50 +00:00
|
|
|
if(!pEntitiesItem->m_RenderTexture.IsValid())
|
2020-09-26 07:37:35 +00:00
|
|
|
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);
|
2020-11-25 12:05:53 +00:00
|
|
|
pThis->Graphics()->FreePNG(&ImgInfo);
|
2020-09-26 07:37:35 +00:00
|
|
|
|
2012-08-12 12:02:50 +00:00
|
|
|
if(!pEntitiesItem->m_RenderTexture.IsValid())
|
2020-09-26 07:37:35 +00:00
|
|
|
pEntitiesItem->m_RenderTexture = pEntitiesItem->m_aImages[i].m_Texture;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str_format(aBuff, sizeof(aBuff), "assets/entities/%s.png", pEntitiesItem->m_aName);
|
|
|
|
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);
|
2020-11-25 12:05:53 +00:00
|
|
|
pThis->Graphics()->FreePNG(&ImgInfo);
|
2020-09-26 07:37:35 +00:00
|
|
|
|
2012-08-12 12:02:50 +00:00
|
|
|
if(!pEntitiesItem->m_RenderTexture.IsValid())
|
2020-09-26 07:37:35 +00:00
|
|
|
pEntitiesItem->m_RenderTexture = pEntitiesItem->m_aImages[i].m_Texture;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int CMenus::EntitiesScan(const char *pName, int IsDir, int DirType, void *pUser)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
auto *pRealUser = (SMenuAssetScanUser *)pUser;
|
|
|
|
auto *pThis = (CMenus *)pRealUser->m_pUser;
|
2020-09-26 07:37:35 +00:00
|
|
|
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"))
|
|
|
|
{
|
2021-09-13 08:06:34 +00:00
|
|
|
char aName[IO_MAX_PATH_LENGTH];
|
2020-09-26 07:37:35 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 11:37:59 +00:00
|
|
|
pRealUser->m_LoadedFunc();
|
|
|
|
|
2020-09-26 07:37:35 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename TName>
|
|
|
|
static void LoadAsset(TName *pAssetItem, const char *pAssetName, IGraphics *pGraphics, void *pUser)
|
|
|
|
{
|
2021-09-13 08:06:34 +00:00
|
|
|
char aBuff[IO_MAX_PATH_LENGTH];
|
2020-09-26 07:37:35 +00:00
|
|
|
|
|
|
|
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);
|
2020-11-25 12:05:53 +00:00
|
|
|
pGraphics->FreePNG(&ImgInfo);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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);
|
2020-11-25 12:05:53 +00:00
|
|
|
pGraphics->FreePNG(&ImgInfo);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str_format(aBuff, sizeof(aBuff), "assets/%s/%s/%s.png", pAssetName, pAssetItem->m_aName, pAssetName);
|
|
|
|
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);
|
2020-11-25 12:05:53 +00:00
|
|
|
pGraphics->FreePNG(&ImgInfo);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename TName>
|
|
|
|
static int AssetScan(const char *pName, int IsDir, int DirType, sorted_array<TName> &AssetList, const char *pAssetName, IGraphics *pGraphics, void *pUser)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
auto *pRealUser = (SMenuAssetScanUser *)pUser;
|
2020-09-26 07:37:35 +00:00
|
|
|
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"))
|
|
|
|
{
|
2021-09-13 08:06:34 +00:00
|
|
|
char aName[IO_MAX_PATH_LENGTH];
|
2020-09-26 07:37:35 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 11:37:59 +00:00
|
|
|
pRealUser->m_LoadedFunc();
|
|
|
|
|
2020-09-26 07:37:35 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CMenus::GameScan(const char *pName, int IsDir, int DirType, void *pUser)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
auto *pRealUser = (SMenuAssetScanUser *)pUser;
|
|
|
|
auto *pThis = (CMenus *)pRealUser->m_pUser;
|
|
|
|
IGraphics *pGraphics = pThis->Graphics();
|
|
|
|
return AssetScan(pName, IsDir, DirType, pThis->m_GameList, "game", pGraphics, pUser);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int CMenus::EmoticonsScan(const char *pName, int IsDir, int DirType, void *pUser)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
auto *pRealUser = (SMenuAssetScanUser *)pUser;
|
|
|
|
auto *pThis = (CMenus *)pRealUser->m_pUser;
|
|
|
|
IGraphics *pGraphics = pThis->Graphics();
|
|
|
|
return AssetScan(pName, IsDir, DirType, pThis->m_EmoticonList, "emoticons", pGraphics, pUser);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int CMenus::ParticlesScan(const char *pName, int IsDir, int DirType, void *pUser)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
auto *pRealUser = (SMenuAssetScanUser *)pUser;
|
|
|
|
auto *pThis = (CMenus *)pRealUser->m_pUser;
|
|
|
|
IGraphics *pGraphics = pThis->Graphics();
|
|
|
|
return AssetScan(pName, IsDir, DirType, pThis->m_ParticlesList, "particles", pGraphics, pUser);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2012-08-12 12:02:50 +00:00
|
|
|
if(List[i].m_RenderTexture.IsValid())
|
2016-07-02 08:33:37 +00:00
|
|
|
pGraphics->UnloadTexture(&(List[i].m_RenderTexture));
|
2020-09-26 07:37:35 +00:00
|
|
|
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)
|
|
|
|
{
|
2020-10-26 14:14:07 +00:00
|
|
|
for(auto &Image : m_EntitiesList[i].m_aImages)
|
2020-09-26 07:37:35 +00:00
|
|
|
{
|
2012-08-12 12:02:50 +00:00
|
|
|
if(Image.m_Texture.IsValid())
|
2016-07-02 08:33:37 +00:00
|
|
|
Graphics()->UnloadTexture(&Image.m_Texture);
|
2020-10-26 14:14:07 +00:00
|
|
|
Image.m_Texture = IGraphics::CTextureHandle();
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
m_EntitiesList.clear();
|
2021-04-11 12:34:08 +00:00
|
|
|
|
|
|
|
// reload current entities
|
2021-07-12 09:43:56 +00:00
|
|
|
m_pClient->m_MapImages.ChangeEntitiesPath(g_Config.m_ClAssetsEntites);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
else if(CurTab == 1)
|
|
|
|
{
|
|
|
|
ClearAssetList(m_GameList, Graphics());
|
2021-04-11 12:34:08 +00:00
|
|
|
|
|
|
|
// reload current game skin
|
|
|
|
GameClient()->LoadGameSkin(g_Config.m_ClAssetGame);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
else if(CurTab == 2)
|
|
|
|
{
|
|
|
|
ClearAssetList(m_EmoticonList, Graphics());
|
2021-04-11 12:34:08 +00:00
|
|
|
|
|
|
|
// reload current emoticons skin
|
|
|
|
GameClient()->LoadEmoticonsSkin(g_Config.m_ClAssetEmoticons);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
else if(CurTab == 3)
|
|
|
|
{
|
|
|
|
ClearAssetList(m_ParticlesList, Graphics());
|
2021-04-11 12:34:08 +00:00
|
|
|
|
|
|
|
// reload current particles skin
|
|
|
|
GameClient()->LoadParticlesSkin(g_Config.m_ClAssetParticles);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
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
|
2021-06-28 20:51:14 +00:00
|
|
|
if(s_aFilterString[s_CurCustomTab][0] != '\0' && !str_utf8_find_nocase(s->m_aName, s_aFilterString[s_CurCustomTab]))
|
2020-09-26 07:37:35 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
SearchList.add_unsorted(s);
|
|
|
|
}
|
|
|
|
return AssetList.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMenus::RenderSettingsCustom(CUIRect MainView)
|
|
|
|
{
|
2020-10-06 14:00:18 +00:00
|
|
|
CUIRect Label, CustomList, QuickSearch, QuickSearchClearButton, DirectoryButton, Page1Tab, Page2Tab, Page3Tab, Page4Tab, ReloadButton;
|
2020-09-26 07:37:35 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2021-05-17 07:11:36 +00:00
|
|
|
static int s_aPageTabs[4] = {};
|
|
|
|
|
|
|
|
if(DoButton_MenuTab((void *)&s_aPageTabs[0], Localize("Entities"), s_CurCustomTab == 0, &Page1Tab, 5, NULL, NULL, NULL, NULL, 4))
|
2020-09-26 07:37:35 +00:00
|
|
|
s_CurCustomTab = 0;
|
2021-05-17 07:11:36 +00:00
|
|
|
if(DoButton_MenuTab((void *)&s_aPageTabs[1], Localize("Game"), s_CurCustomTab == 1, &Page2Tab, 0, NULL, NULL, NULL, NULL, 4))
|
2020-09-26 07:37:35 +00:00
|
|
|
s_CurCustomTab = 1;
|
2021-05-17 07:11:36 +00:00
|
|
|
if(DoButton_MenuTab((void *)&s_aPageTabs[2], Localize("Emoticons"), s_CurCustomTab == 2, &Page3Tab, 0, NULL, NULL, NULL, NULL, 4))
|
2020-09-26 07:37:35 +00:00
|
|
|
s_CurCustomTab = 2;
|
2021-05-17 07:11:36 +00:00
|
|
|
if(DoButton_MenuTab((void *)&s_aPageTabs[3], Localize("Particles"), s_CurCustomTab == 3, &Page4Tab, 10, NULL, NULL, NULL, NULL, 4))
|
2020-09-26 07:37:35 +00:00
|
|
|
s_CurCustomTab = 3;
|
|
|
|
|
2022-04-02 11:37:59 +00:00
|
|
|
int64_t LoadStartTime = time_get_microseconds();
|
|
|
|
SMenuAssetScanUser User;
|
|
|
|
User.m_pUser = this;
|
|
|
|
User.m_LoadedFunc = [&]() {
|
|
|
|
if(time_get_microseconds() - LoadStartTime > 500000)
|
|
|
|
RenderLoading(false, false);
|
|
|
|
};
|
2020-09-26 07:37:35 +00:00
|
|
|
if(s_CurCustomTab == 0)
|
|
|
|
{
|
|
|
|
if(m_EntitiesList.size() == 0)
|
|
|
|
{
|
|
|
|
SCustomEntities EntitiesItem;
|
|
|
|
str_copy(EntitiesItem.m_aName, "default", sizeof(EntitiesItem.m_aName));
|
2022-04-02 11:37:59 +00:00
|
|
|
LoadEntities(&EntitiesItem, &User);
|
2020-09-26 07:37:35 +00:00
|
|
|
m_EntitiesList.add(EntitiesItem);
|
|
|
|
|
|
|
|
// load entities
|
2022-04-02 11:37:59 +00:00
|
|
|
Storage()->ListDirectory(IStorage::TYPE_ALL, "assets/entities", EntitiesScan, &User);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
if(m_EntitiesList.size() != s_CustomListSize[s_CurCustomTab])
|
|
|
|
s_InitCustomList[s_CurCustomTab] = true;
|
|
|
|
}
|
|
|
|
else if(s_CurCustomTab == 1)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
InitAssetList(m_GameList, "assets/game", "game", GameScan, Graphics(), Storage(), &User);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
else if(s_CurCustomTab == 2)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
InitAssetList(m_EmoticonList, "assets/emoticons", "emoticons", EmoticonsScan, Graphics(), Storage(), &User);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
else if(s_CurCustomTab == 3)
|
|
|
|
{
|
2022-04-02 11:37:59 +00:00
|
|
|
InitAssetList(m_ParticlesList, "assets/particles", "particles", ParticlesScan, Graphics(), Storage(), &User);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2021-06-28 20:51:14 +00:00
|
|
|
if(s_aFilterString[s_CurCustomTab][0] != '\0' && !str_utf8_find_nocase(s->m_aName, s_aFilterString[s_CurCustomTab]))
|
2020-09-26 07:37:35 +00:00
|
|
|
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);
|
2022-01-21 15:20:15 +00:00
|
|
|
UI()->DoLabelScaled(&ItemRect, s->m_aName, ItemRect.h - 2, TEXTALIGN_CENTER);
|
2012-08-12 12:02:50 +00:00
|
|
|
if(s->m_RenderTexture.IsValid())
|
2020-09-26 07:37:35 +00:00
|
|
|
{
|
|
|
|
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));
|
2021-07-12 09:43:56 +00:00
|
|
|
m_pClient->m_MapImages.ChangeEntitiesPath(GetCustomItem(s_CurCustomTab, NewSelected)->m_aName);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
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);
|
2020-10-06 14:00:18 +00:00
|
|
|
QuickSearch.VSplitLeft(240.0f, &QuickSearch, &DirectoryButton);
|
2020-09-26 07:37:35 +00:00
|
|
|
QuickSearch.HSplitTop(5.0f, 0, &QuickSearch);
|
2022-03-19 17:50:33 +00:00
|
|
|
const char *pSearchLabel = "\xEF\x80\x82";
|
2020-09-26 07:37:35 +00:00
|
|
|
TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_ICON_FONT));
|
2020-10-06 10:25:10 +00:00
|
|
|
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
2022-03-11 16:34:48 +00:00
|
|
|
|
|
|
|
SLabelProperties Props;
|
|
|
|
Props.m_AlignVertically = 0;
|
|
|
|
UI()->DoLabelScaled(&QuickSearch, pSearchLabel, 14.0f, TEXTALIGN_LEFT, Props);
|
2020-09-26 07:37:35 +00:00
|
|
|
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;
|
2021-12-03 19:15:44 +00:00
|
|
|
static float s_Offset = 0.0f;
|
2022-03-13 18:09:33 +00:00
|
|
|
SUIExEditBoxProperties EditProps;
|
2021-12-18 11:23:20 +00:00
|
|
|
if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed())
|
2022-03-13 18:09:33 +00:00
|
|
|
{
|
2020-09-26 07:37:35 +00:00
|
|
|
UI()->SetActiveItem(&s_aFilterString[s_CurCustomTab]);
|
2022-03-13 18:09:33 +00:00
|
|
|
EditProps.m_SelectText = true;
|
|
|
|
}
|
|
|
|
EditProps.m_pEmptyText = Localize("Search");
|
|
|
|
if(UIEx()->DoClearableEditBox(&s_aFilterString[s_CurCustomTab], &s_ClearButton, &QuickSearch, s_aFilterString[s_CurCustomTab], sizeof(s_aFilterString[0]), 14.0f, &s_Offset, false, CUI::CORNER_ALL, EditProps))
|
2020-09-26 07:37:35 +00:00
|
|
|
s_InitCustomList[s_CurCustomTab] = true;
|
|
|
|
}
|
|
|
|
|
2020-10-06 14:00:18 +00:00
|
|
|
DirectoryButton.HSplitTop(5.0f, 0, &DirectoryButton);
|
|
|
|
DirectoryButton.VSplitRight(175.0f, 0, &DirectoryButton);
|
|
|
|
DirectoryButton.VSplitRight(25.0f, &DirectoryButton, &ReloadButton);
|
|
|
|
DirectoryButton.VSplitRight(10.0f, &DirectoryButton, 0);
|
2021-05-17 07:11:36 +00:00
|
|
|
static int s_AssetsDirID = 0;
|
|
|
|
if(DoButton_Menu(&s_AssetsDirID, Localize("Assets directory"), 0, &DirectoryButton))
|
2020-09-26 07:37:35 +00:00
|
|
|
{
|
2021-09-13 08:06:34 +00:00
|
|
|
char aBuf[IO_MAX_PATH_LENGTH];
|
|
|
|
char aBufFull[IO_MAX_PATH_LENGTH + 7];
|
2020-09-26 07:37:35 +00:00
|
|
|
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);
|
2021-12-19 00:13:08 +00:00
|
|
|
if(!open_file(aBuf))
|
2020-09-26 07:37:35 +00:00
|
|
|
{
|
2021-12-19 00:13:08 +00:00
|
|
|
dbg_msg("menus", "couldn't open file");
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
|
|
|
}
|
2020-10-06 14:00:18 +00:00
|
|
|
|
|
|
|
TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_ICON_FONT));
|
2020-10-06 10:25:10 +00:00
|
|
|
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
2021-05-17 07:11:36 +00:00
|
|
|
static int s_AssetsReloadBtnID = 0;
|
2022-03-19 17:50:33 +00:00
|
|
|
if(DoButton_Menu(&s_AssetsReloadBtnID, "\xEF\x80\x9E", 0, &ReloadButton, NULL, 15, 5, 0, vec4(1.0f, 1.0f, 1.0f, 0.75f), vec4(1, 1, 1, 0.5f), 0))
|
2020-10-06 14:00:18 +00:00
|
|
|
{
|
|
|
|
ClearCustomItems(s_CurCustomTab);
|
|
|
|
}
|
|
|
|
TextRender()->SetRenderFlags(0);
|
|
|
|
TextRender()->SetCurFont(NULL);
|
2020-09-26 07:37:35 +00:00
|
|
|
}
|
2021-04-11 12:34:08 +00:00
|
|
|
|
|
|
|
void CMenus::ConchainAssetsEntities(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
|
|
|
{
|
|
|
|
CMenus *pThis = (CMenus *)pUserData;
|
|
|
|
if(pResult->NumArguments() == 1)
|
|
|
|
{
|
|
|
|
const char *pArg = pResult->GetString(0);
|
|
|
|
if(str_comp(pArg, g_Config.m_ClAssetsEntites) != 0)
|
|
|
|
{
|
2021-07-12 09:43:56 +00:00
|
|
|
pThis->m_pClient->m_MapImages.ChangeEntitiesPath(pArg);
|
2021-04-11 12:34:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pfnCallback(pResult, pCallbackUserData);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMenus::ConchainAssetGame(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
|
|
|
{
|
|
|
|
CMenus *pThis = (CMenus *)pUserData;
|
|
|
|
if(pResult->NumArguments() == 1)
|
|
|
|
{
|
|
|
|
const char *pArg = pResult->GetString(0);
|
|
|
|
if(str_comp(pArg, g_Config.m_ClAssetGame) != 0)
|
|
|
|
{
|
|
|
|
pThis->GameClient()->LoadGameSkin(pArg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pfnCallback(pResult, pCallbackUserData);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMenus::ConchainAssetParticles(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
|
|
|
{
|
|
|
|
CMenus *pThis = (CMenus *)pUserData;
|
|
|
|
if(pResult->NumArguments() == 1)
|
|
|
|
{
|
|
|
|
const char *pArg = pResult->GetString(0);
|
|
|
|
if(str_comp(pArg, g_Config.m_ClAssetParticles) != 0)
|
|
|
|
{
|
|
|
|
pThis->GameClient()->LoadParticlesSkin(pArg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pfnCallback(pResult, pCallbackUserData);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMenus::ConchainAssetEmoticons(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
|
|
|
{
|
|
|
|
CMenus *pThis = (CMenus *)pUserData;
|
|
|
|
if(pResult->NumArguments() == 1)
|
|
|
|
{
|
|
|
|
const char *pArg = pResult->GetString(0);
|
|
|
|
if(str_comp(pArg, g_Config.m_ClAssetEmoticons) != 0)
|
|
|
|
{
|
|
|
|
pThis->GameClient()->LoadEmoticonsSkin(pArg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pfnCallback(pResult, pCallbackUserData);
|
|
|
|
}
|