Implement ModList.

Code is mainly ported from the old client. The mod listing works but loading mods depends on several other places in the code that need to be fully implemented yet.
This commit is contained in:
/dev/urandom 2016-04-04 00:11:56 +02:00
parent 2e2b58cff7
commit 883f71b7bb
No known key found for this signature in database
GPG Key ID: 41322B973E0F295E
6 changed files with 156 additions and 0 deletions

View File

@ -50,6 +50,7 @@ namespace Components
Loader::Register(new MusicalTalent());
Loader::Register(new StructuredData());
Loader::Register(new ConnectProtocol());
Loader::Register(new ModList());
}
void Loader::Uninitialize()

View File

@ -66,3 +66,4 @@ namespace Components
#include "Modules\MusicalTalent.hpp"
#include "Modules\StructuredData.hpp"
#include "Modules\ConnectProtocol.hpp"
#include "Modules\ModList.hpp"

View File

@ -0,0 +1,117 @@
#include "STDInclude.hpp"
namespace Components
{
static Dvar::Var cl_modVidRestart;
ModList::modInfo_t ModList::modInfo;
bool ModList::hasMod(const char* modName)
{
int count;
auto fs_homepath = Dvar::Var("fs_basepath").Get<const char*>();
char** mods = Game::Sys_ListFiles((char*)Utils::VA("%s\\%s", fs_homepath, "mods"), NULL, NULL, &count, 1);
for (int i = 0; i < count; i++)
{
if (!_stricmp(modName, mods[i]))
{
Game::Sys_FreeFileList(mods);
return true;
}
}
Game::Sys_FreeFileList(mods);
return false;
}
unsigned int ModList::GetItemCount()
{
return ModList::modInfo.max;
}
const char* ModList::GetItemText(unsigned int index, int column)
{
if (ModList::modInfo.current >= 0 && ModList::modInfo.current < ModList::modInfo.max)
{
return ModList::modInfo.mods[index];
}
return "...";
}
void ModList::Select(unsigned int index)
{
ModList::modInfo.current = index;
}
void ModList::UIScript_LoadMods()
{
if (ModList::modInfo.mods != NULL && *ModList::modInfo.mods != NULL)
{
Game::Sys_FreeFileList(ModList::modInfo.mods);
}
auto fs_homepath = Dvar::Var("fs_basepath").Get<const char*>();
auto searchFolder = (char*)Utils::VA("%s\\%s", fs_homepath, "mods");
Game::Com_Printf(0, "Searching for mods in %s...\n", searchFolder);
ModList::modInfo.mods = Game::Sys_ListFiles(searchFolder, NULL, NULL, &ModList::modInfo.max, 1);
Game::Com_Printf(0, "Found %i mods!\n", ModList::modInfo.max);
}
void ModList::UIScript_RunMod()
{
if (ModList::modInfo.mods != NULL
&& *ModList::modInfo.mods != NULL
&& ModList::modInfo.current >= 0
&& ModList::modInfo.current < ModList::modInfo.max)
{
Dvar::Var("fs_game").Set(Utils::VA("mods/%s", ModList::modInfo.mods[ModList::modInfo.current]));
//Game::Cmd_ExecuteSingleCommand(0, 0, Utils::VA("fs_game \"mods/%s\"", modInfo.mods[modInfo.current]));
if (cl_modVidRestart.Get<bool>())
{
Game::Cmd_ExecuteSingleCommand(0, 0, "vid_restart");
}
else
{
Game::Cmd_ExecuteSingleCommand(0, 0, "closemenu mods_menu");
}
}
}
void ModList::UIScript_ClearMods()
{
Dvar::Var("fs_game").Set("");
//Game::Cmd_ExecuteSingleCommand(0, 0, "fs_game \"\"");
if (cl_modVidRestart.Get<bool>())
{
Game::Cmd_ExecuteSingleCommand(0, 0, "vid_restart");
}
else
{
Game::Cmd_ExecuteSingleCommand(0, 0, "closemenu mods_menu");
}
}
ModList::ModList()
{
Dvar::OnInit([]()
{
cl_modVidRestart = Dvar::Register("cl_modVidRestart", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Perform a vid_restart when loading a mod.");
});
ModList::modInfo.max = ModList::modInfo.current = 0;
UIScript::Add("LoadMods", ModList::UIScript_LoadMods);
UIScript::Add("RunMod", ModList::UIScript_RunMod);
UIScript::Add("ClearMods", ModList::UIScript_ClearMods);
UIFeeder::Add(9.0f, ModList::GetItemCount, ModList::GetItemText, ModList::Select);
}
ModList::~ModList()
{
}
}

View File

@ -0,0 +1,29 @@
namespace Components
{
class ModList : public Component
{
public:
ModList();
~ModList();
const char* GetName() { return "Mods"; };
private:
struct modInfo_t
{
char** mods;
int max;
int current;
};
static bool hasMod(const char* modName);
static modInfo_t modInfo;
static unsigned int GetItemCount();
static const char* GetItemText(unsigned int index, int column);
static void Select(unsigned int index);
static void UIScript_LoadMods();
static void UIScript_RunMod();
static void UIScript_ClearMods();
};
}

View File

@ -134,9 +134,11 @@ namespace Game
SV_GameClientNum_Score_t SV_GameClientNum_Score = (SV_GameClientNum_Score_t)0x469AC0;
SV_GameSendServerCommand_t SV_GameSendServerCommand = (SV_GameSendServerCommand_t)0x4BC3A0;
Sys_FreeFileList_t Sys_FreeFileList = (Sys_FreeFileList_t)0x4D8580;
Sys_IsMainThread_t Sys_IsMainThread = (Sys_IsMainThread_t)0x4C37D0;
Sys_SendPacket_t Sys_SendPacket = (Sys_SendPacket_t)0x60FDC0;
Sys_ShowConsole_t Sys_ShowConsole = (Sys_ShowConsole_t)0x4305E0;
Sys_ListFiles_t Sys_ListFiles = (Sys_ListFiles_t)0x45A660;
UI_AddMenuList_t UI_AddMenuList = (UI_AddMenuList_t)0x4533C0;
UI_LoadMenus_t UI_LoadMenus = (UI_LoadMenus_t)0x641460;

View File

@ -311,9 +311,15 @@ namespace Game
typedef void(__cdecl * SV_GameSendServerCommand_t)(int clientNum, /*svscmd_type*/int type, const char* text);
extern SV_GameSendServerCommand_t SV_GameSendServerCommand;
typedef FS_FreeFileList_t Sys_FreeFileList_t;
extern Sys_FreeFileList_t Sys_FreeFileList;
typedef bool(__cdecl * Sys_IsMainThread_t)();
extern Sys_IsMainThread_t Sys_IsMainThread;
typedef char** (__cdecl * Sys_ListFiles_t)(char* path, char* extension, int noclue, int* amount, bool listFolders);
extern Sys_ListFiles_t Sys_ListFiles;
typedef bool(__cdecl * Sys_SendPacket_t)(netsrc_t sock, size_t len, const char *format, netadr_t adr);
extern Sys_SendPacket_t Sys_SendPacket;