[MapRotation]: Rename dvar (#737)

This commit is contained in:
Edo 2023-01-27 23:05:26 +00:00 committed by GitHub
parent b1f022b34f
commit b599a9c700
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 175 additions and 134 deletions

View File

@ -197,10 +197,10 @@ namespace Components
CardTitles::CardTitles()
{
Scheduler::Once([]
Events::OnDvarInit([]
{
CustomTitle = Dvar::Register<const char*>("customTitle", "", Game::DVAR_USERINFO | Game::DVAR_ARCHIVE, "Custom card title");
}, Scheduler::Pipeline::MAIN);
});
std::memset(&CustomTitles, 0, sizeof(char[Game::MAX_CLIENTS][18]));

View File

@ -342,10 +342,8 @@ namespace Components
nullptr,
};
DebugOverlay = Game::Dvar_RegisterEnum("debugOverlay", debugOverlayNames_0, 0,
Game::DVAR_NONE, "Toggles the display of various debug info.");
BugName = Game::Dvar_RegisterString("bug_name", "bug0",
Game::DVAR_CHEAT | Game::DVAR_CODINFO, "Name appended to the copied console log");
DebugOverlay = Game::Dvar_RegisterEnum("debugOverlay", debugOverlayNames_0, 0, Game::DVAR_NONE, "Toggles the display of various debug info.");
BugName = Game::Dvar_RegisterString("bug_name", "bug0", Game::DVAR_NONE, "Name appended to the copied console log");
}
const Game::dvar_t* Debug::Dvar_Register_PlayerDebugHealth(const char* name, bool value, [[maybe_unused]] std::uint16_t flags, const char* description)
@ -356,7 +354,7 @@ namespace Components
Debug::Debug()
{
Scheduler::Once(CL_InitDebugDvars, Scheduler::Pipeline::MAIN);
Events::OnDvarInit(CL_InitDebugDvars);
// Hook end of CG_DrawDebugOverlays (This is to ensure some checks are done before our hook is executed).
Utils::Hook(0x49CB0A, CG_DrawDebugOverlays_Hk, HOOK_JUMP).install()->quick();

View File

@ -3,6 +3,7 @@
#include "CardTitles.hpp"
#include "ClanTags.hpp"
#include "Party.hpp"
#include "ServerCommands.hpp"
namespace Components
@ -114,10 +115,9 @@ namespace Components
{
Scheduler::Once([]
{
const auto partyEnable = Dvar::Var("party_enable").get<bool>();
std::string mapname = (*Game::sv_mapname)->current.string;
if (!partyEnable) // Time wrapping should not occur in party servers, but yeah...
if (!Party::IsEnabled()) // Time wrapping should not occur in party servers, but yeah...
{
if (mapname.empty()) mapname = "mp_rust";
Command::Execute(std::format("map {}", mapname), true);
@ -216,10 +216,10 @@ namespace Components
if (!ZoneBuilder::IsEnabled())
{
Scheduler::Once([]
Events::OnDvarInit([]
{
SVMOTD = Dvar::Register<const char*>("sv_motd", "", Game::DVAR_NONE, "A custom message of the day for servers");
}, Scheduler::Pipeline::MAIN);
});
// Post initialization point
Utils::Hook(0x60BFBF, PostInitializationStub, HOOK_JUMP).install()->quick();

View File

@ -372,7 +372,7 @@ namespace Components
Scheduler::Once([]
{
framePushed = false;
Dvar::Var("ui_dl_progress").set(Utils::String::VA("(%d/%d) %d%%", dlIndex, dlSize, dlProgress));
Dvar::Var("ui_dl_progress").set(std::format("({}/{}) {}%%", dlIndex, dlSize, dlProgress));
}, Scheduler::Pipeline::CLIENT);
}
@ -683,12 +683,12 @@ namespace Components
}
else
{
Scheduler::Once([]
Events::OnDvarInit([]
{
Dvar::Register<const char*>("ui_dl_timeLeft", "", Game::DVAR_NONE, "");
Dvar::Register<const char*>("ui_dl_progress", "", Game::DVAR_NONE, "");
Dvar::Register<const char*>("ui_dl_transRate", "", Game::DVAR_NONE, "");
}, Scheduler::Pipeline::MAIN);
});
UIScript::Add("mod_download_cancel", []([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
{
@ -696,11 +696,11 @@ namespace Components
});
}
Scheduler::Once([]
Events::OnDvarInit([]
{
SV_wwwDownload = Dvar::Register<bool>("sv_wwwDownload", false, Game::DVAR_NONE, "Set to true to enable downloading maps/mods from an external server.");
SV_wwwBaseUrl = Dvar::Register<const char*>("sv_wwwBaseUrl", "", Game::DVAR_NONE, "Set to the base url for the external map download.");
}, Scheduler::Pipeline::MAIN);
});
}
Download::~Download()

View File

@ -8,7 +8,7 @@ namespace Components
: dvar_(Game::Dvar_FindVar(dvarName.data()))
{
// If the dvar can't be found it will be registered as an empty string dvar
if (this->dvar_ == nullptr)
if (!this->dvar_)
{
this->dvar_ = const_cast<Game::dvar_t*>(Game::Dvar_SetFromStringByNameFromSource(dvarName.data(), "", Game::DVAR_SOURCE_INTERNAL));
}
@ -21,13 +21,17 @@ namespace Components
template <> const char* Dvar::Var::get()
{
if (this->dvar_ == nullptr)
if (!this->dvar_)
{
return "";
}
if (this->dvar_->type == Game::DVAR_TYPE_STRING || this->dvar_->type == Game::DVAR_TYPE_ENUM)
{
if (this->dvar_->current.string != nullptr)
if (this->dvar_->current.string)
{
return this->dvar_->current.string;
}
}
return "";
@ -35,8 +39,10 @@ namespace Components
template <> int Dvar::Var::get()
{
if (this->dvar_ == nullptr)
if (!this->dvar_)
{
return 0;
}
if (this->dvar_->type == Game::DVAR_TYPE_INT || this->dvar_->type == Game::DVAR_TYPE_ENUM)
{
@ -48,8 +54,10 @@ namespace Components
template <> unsigned int Dvar::Var::get()
{
if (this->dvar_ == nullptr)
if (!this->dvar_)
{
return 0;
}
if (this->dvar_->type == Game::DVAR_TYPE_INT)
{
@ -61,8 +69,10 @@ namespace Components
template <> float Dvar::Var::get()
{
if (this->dvar_ == nullptr)
if (!this->dvar_)
{
return 0.f;
}
if (this->dvar_->type == Game::DVAR_TYPE_FLOAT)
{
@ -72,26 +82,12 @@ namespace Components
return 0.f;
}
template <> float* Dvar::Var::get()
{
static Game::vec4_t vector{0.f, 0.f, 0.f, 0.f};
if (this->dvar_ == nullptr)
return vector;
if (this->dvar_->type == Game::DVAR_TYPE_FLOAT_2 || this->dvar_->type == Game::DVAR_TYPE_FLOAT_3 ||
this->dvar_->type == Game::DVAR_TYPE_FLOAT_4)
{
return this->dvar_->current.vector;
}
return vector;
}
template <> bool Dvar::Var::get()
{
if (this->dvar_ == nullptr)
if (!this->dvar_)
{
return false;
}
if (this->dvar_->type == Game::DVAR_TYPE_BOOL)
{
@ -108,7 +104,9 @@ namespace Components
void Dvar::Var::set(const char* string)
{
assert(string);
assert(this->dvar_->type == Game::DVAR_TYPE_STRING);
if (this->dvar_)
{
Game::Dvar_SetString(this->dvar_, string);
@ -299,7 +297,7 @@ namespace Components
{
// Save the dvar original value if it has the archive flag
const auto* dvar = Game::Dvar_FindVar(dvarName);
if (dvar != nullptr && dvar->flags & Game::DVAR_ARCHIVE)
if (dvar && dvar->flags & Game::DVAR_ARCHIVE)
{
if (!AreArchiveDvarsUnprotected())
{
@ -310,7 +308,7 @@ namespace Components
Logger::Print(Game::CON_CHANNEL_CONSOLEONLY, "Server is overriding saved dvar '{}'\n", dvarName);
}
if (dvar != nullptr && std::strcmp(dvar->name, "com_errorResolveCommand") == 0)
if (dvar && std::strcmp(dvar->name, "com_errorResolveCommand") == 0)
{
Logger::Print(Game::CON_CHANNEL_CONSOLEONLY, "Not allowing server to set '{}'\n", dvar->name);
return;

View File

@ -14,7 +14,7 @@ namespace Components
auto* ps = pm->ps;
auto i = 0;
const auto elevatorSetting = Elevators::BG_Elevators.get<int>();
const auto elevatorSetting = BG_Elevators.get<int>();
while (true)
{
point[0] = ps->origin[0] + (*Game::CorrectSolidDeltas)[i][0];
@ -24,7 +24,7 @@ namespace Components
Game::PM_playerTrace(pm, trace, point, point, &pm->bounds, ps->clientNum, pm->tracemask);
// If the player wishes to glitch without effort they can do so
if (!trace->startsolid || elevatorSetting == Elevators::EASY)
if (!trace->startsolid || elevatorSetting == EASY)
{
ps->origin[0] = point[0];
ps->origin[1] = point[1];
@ -35,7 +35,7 @@ namespace Components
// If elevators are disabled we need to check that startsolid is false before proceeding
// like later versions of the game do
if (!trace->startsolid || elevatorSetting >= Elevators::ENABLED)
if (!trace->startsolid || elevatorSetting >= ENABLED)
{
break;
}
@ -69,7 +69,7 @@ namespace Components
Game::PM_Trace(pm, results, start, end, bounds, passEntityNum, contentMask);
// Allow the player to stand even when there is no headroom
if (Elevators::BG_Elevators.get<int>() == Elevators::EASY)
if (BG_Elevators.get<int>() == EASY)
{
results->allsolid = false;
}
@ -85,7 +85,7 @@ namespace Components
push [esp + 0x8 + 0x24]
push [esp + 0x8 + 0x24]
push eax
call Elevators::PM_CorrectAllSolid
call PM_CorrectAllSolid
add esp, 0xC
mov [esp + 0x20], eax
@ -98,7 +98,7 @@ namespace Components
Elevators::Elevators()
{
Scheduler::Once([]
Events::OnDvarInit([]
{
static const char* values[] =
{
@ -108,16 +108,15 @@ namespace Components
nullptr
};
Elevators::BG_Elevators = Game::Dvar_RegisterEnum("bg_elevators", values,
Elevators::ENABLED, Game::DVAR_CODINFO, "Elevators glitch settings");
}, Scheduler::Pipeline::MAIN);
BG_Elevators = Game::Dvar_RegisterEnum("bg_elevators", values, ENABLED, Game::DVAR_CODINFO, "Elevators glitch settings");
});
Utils::Hook(0x57369E, Elevators::PM_CorrectAllSolidStub, HOOK_CALL).install()->quick(); // PM_GroundTrace
Utils::Hook(0x57369E, PM_CorrectAllSolidStub, HOOK_CALL).install()->quick(); // PM_GroundTrace
// Place hooks in PM_CheckDuck. If the elevators dvar is set to easy the
// flags for duck/prone will always be removed from the player state
Utils::Hook(0x570EC5, Elevators::PM_Trace_Hk, HOOK_CALL).install()->quick();
Utils::Hook(0x570E0B, Elevators::PM_Trace_Hk, HOOK_CALL).install()->quick();
Utils::Hook(0x570D70, Elevators::PM_Trace_Hk, HOOK_CALL).install()->quick();
Utils::Hook(0x570EC5, PM_Trace_Hk, HOOK_CALL).install()->quick();
Utils::Hook(0x570E0B, PM_Trace_Hk, HOOK_CALL).install()->quick();
Utils::Hook(0x570D70, PM_Trace_Hk, HOOK_CALL).install()->quick();
}
}

View File

@ -8,6 +8,7 @@ namespace Components
Utils::Signal<Events::Callback> Events::ShutdownSystemSignal;
Utils::Signal<Events::Callback> Events::ClientInitSignal;
Utils::Signal<Events::Callback> Events::ServerInitSignal;
Utils::Signal<Events::Callback> Events::DvarInitSignal;
void Events::OnClientDisconnect(const Utils::Slot<ClientCallback>& callback)
{
@ -39,6 +40,11 @@ namespace Components
ServerInitSignal.connect(callback);
}
void Events::OnDvarInit(const Utils::Slot<Callback>& callback)
{
DvarInitSignal.connect(callback);
}
/*
* Should be called when a client drops from the server
* but not "between levels" (Quake-III-Arena)
@ -87,6 +93,14 @@ namespace Components
Utils::Hook::Call<void()>(0x474320)(); // SV_InitGameMode
}
void Events::Com_InitDvars_Hk()
{
DvarInitSignal();
DvarInitSignal.clear();
Utils::Hook::Call<void()>(0x60AD10)(); // Com_InitDvars
}
Events::Events()
{
Utils::Hook(0x625235, ClientDisconnect_Hk, HOOK_CALL).install()->quick(); // SV_FreeClient
@ -100,6 +114,8 @@ namespace Components
Utils::Hook(0x60BE5B, CL_InitOnceForAllClients_HK, HOOK_CALL).install()->quick(); // Com_Init_Try_Block_Function
Utils::Hook(0x60BB3A, Com_InitDvars_Hk, HOOK_CALL).install()->quick(); // Com_Init_Try_Block_Function
Utils::Hook(0x4D3665, SV_Init_Hk, HOOK_CALL).install()->quick(); // SV_Init
}
}

View File

@ -27,6 +27,9 @@ namespace Components
// Client & Server (triggered once)
static void OnSVInit(const Utils::Slot<Callback>& callback);
// Client & Server (triggered once)
static void OnDvarInit(const Utils::Slot<Callback>& callback);
private:
static Utils::Signal<ClientCallback> ClientDisconnectSignal;
static Utils::Signal<ClientConnectCallback> ClientConnectSignal;
@ -34,6 +37,7 @@ namespace Components
static Utils::Signal<Callback> ShutdownSystemSignal;
static Utils::Signal<Callback> ClientInitSignal;
static Utils::Signal<Callback> ServerInitSignal;
static Utils::Signal<Callback> DvarInitSignal;
static void ClientDisconnect_Hk(int clientNum);
static void SV_UserinfoChanged_Hk(Game::client_t* cl);
@ -41,5 +45,6 @@ namespace Components
static void Scr_ShutdownSystem_Hk(unsigned char sys);
static void CL_InitOnceForAllClients_HK();
static void SV_Init_Hk();
static void Com_InitDvars_Hk();
};
}

View File

@ -5,6 +5,7 @@ namespace Components
{
Dvar::Var MapRotation::SVRandomMapRotation;
Dvar::Var MapRotation::SVDontRotate;
Dvar::Var MapRotation::SVNextMap;
MapRotation::RotationData MapRotation::DedicatedRotation;
@ -263,19 +264,23 @@ namespace Components
const auto& entry = rotation.peekNextEntry();
if (entry.first == "map"s)
{
Game::Dvar_SetString(*Game::nextmap, entry.second.data());
SVNextMap.set(entry.second);
}
else
{
ClearNextMap();
}
}
void MapRotation::SetNextMap(const char* value)
{
assert(value);
Game::Dvar_SetString(*Game::nextmap, value);
SVNextMap.set(value);
}
void MapRotation::ClearNextMap()
{
Game::Dvar_SetString(*Game::nextmap, "");
SVNextMap.set("");
}
void MapRotation::RandomizeMapRotation()
@ -325,15 +330,19 @@ namespace Components
SetNextMap(DedicatedRotation);
}
void MapRotation::RegisterMapRotationDvars()
{
SVRandomMapRotation = Dvar::Register<bool>("sv_randomMapRotation", false, Game::DVAR_ARCHIVE, "Randomize map rotation when true");
SVDontRotate = Dvar::Register<bool>("sv_dontRotate", false, Game::DVAR_NONE, "Do not perform map rotation");
SVNextMap = Dvar::Register<const char*>("sv_nextMap", "", Game::DVAR_SERVERINFO, "");
}
MapRotation::MapRotation()
{
AddMapRotationCommands();
Utils::Hook::Set<void(*)()>(0x4152E8, SV_MapRotate_f);
SVRandomMapRotation = Dvar::Register<bool>("sv_randomMapRotation", false,
Game::DVAR_ARCHIVE, "Randomize map rotation when true");
SVDontRotate = Dvar::Register<bool>("sv_dontRotate", false,
Game::DVAR_NONE, "Do not perform map rotation");
Events::OnDvarInit(RegisterMapRotationDvars);
}
bool MapRotation::unitTest()

View File

@ -48,6 +48,7 @@ namespace Components
// Rotation Dvars
static Dvar::Var SVRandomMapRotation;
static Dvar::Var SVDontRotate;
static Dvar::Var SVNextMap;
// Holds the parsed data from sv_mapRotation
static RotationData DedicatedRotation;
@ -57,6 +58,7 @@ namespace Components
// Use these commands before SV_MapRotate_f is called
static void AddMapRotationCommands();
static void RegisterMapRotationDvars();
static bool ShouldRotate();
static void ApplyMap(const std::string& map);

View File

@ -265,7 +265,7 @@ namespace Components
AssertOffset(Game::playerState_s, eFlags, 0xB0);
AssertOffset(Game::playerState_s, pm_flags, 0xC);
Scheduler::Once([]
Events::OnDvarInit([]
{
static const char* bg_bouncesValues[] =
{
@ -275,9 +275,8 @@ namespace Components
nullptr
};
BGBounces = Game::Dvar_RegisterEnum("bg_bounces",
bg_bouncesValues, DISABLED, Game::DVAR_CODINFO, "Bounce glitch settings");
}, Scheduler::Pipeline::MAIN);
BGBounces = Game::Dvar_RegisterEnum("bg_bounces", bg_bouncesValues, DISABLED, Game::DVAR_CODINFO, "Bounce glitch settings");
});
// Hook Dvar_RegisterFloat. Only thing that's changed is that the 0x80 flag is not used.
Utils::Hook(0x448990, Dvar_RegisterSpectateSpeedScale, HOOK_CALL).install()->quick();

View File

@ -161,11 +161,11 @@ namespace Components
RconContainer.timestamp = 0;
Scheduler::Once([]
Events::OnDvarInit([]
{
RconPassword = Dvar::Register<const char*>("rcon_password", "", Game::DVAR_NONE, "The password for rcon");
RconLogRequests = Dvar::Register<bool>("rcon_log_requests", false, Game::DVAR_NONE, "Print remote commands in the output log");
}, Scheduler::Pipeline::MAIN);
});
Network::OnClientPacket("rcon", [](const Network::Address& address, [[maybe_unused]] const std::string& data)
{

View File

@ -550,7 +550,7 @@ namespace Components
// End vid_restart
Utils::Hook(0x4CA3A7, Renderer::PostVidRestartStub, HOOK_CALL).install()->quick();
Scheduler::Once([]
Events::OnDvarInit([]
{
static const char* values[] =
{
@ -566,9 +566,9 @@ namespace Components
Renderer::r_drawTriggers = Game::Dvar_RegisterBool("r_drawTriggers", false, Game::DVAR_CHEAT, "Draw triggers");
Renderer::r_drawModelNames = Game::Dvar_RegisterEnum("r_drawModelNames", values, 0, Game::DVAR_CHEAT, "Draw all model names");
Renderer::r_drawAABBTrees = Game::Dvar_RegisterBool("r_drawAabbTrees", false, Game::DVAR_CHEAT, "Draw aabb trees");
Renderer::r_playerDrawDebugDistance = Game::Dvar_RegisterInt("r_drawDebugDistance", 1000, 0, 50000, Game::DVAR_ARCHIVE, "r_draw debug functions draw distance, relative to the player");
Renderer::r_playerDrawDebugDistance = Game::Dvar_RegisterInt("r_drawDebugDistance", 1000, 0, 50000, Game::DVAR_ARCHIVE, "r_draw debug functions draw distance relative to the player");
Renderer::r_forceTechnique = Game::Dvar_RegisterInt("r_forceTechnique", 0, 0, 14, Game::DVAR_NONE, "Force a base technique on the renderer");
}, Scheduler::Pipeline::MAIN);
});
}
Renderer::~Renderer()

View File

@ -161,7 +161,7 @@ namespace Components
// Ensure mapname is set
if (info.get("mapname").empty())
{
info.set("mapname", Dvar::Var("ui_mapname").get<const char*>());
info.set("mapname", (*Game::ui_mapname)->current.string);
}
// Set matchtype

View File

@ -834,7 +834,7 @@ namespace Components
FavouriteList.clear();
VisibleList.clear();
Scheduler::Once([]
Events::OnDvarInit([]
{
UIServerSelected = Dvar::Register<bool>("ui_serverSelected", false,
Game::DVAR_NONE, "Whether a server has been selected in the serverlist");
@ -845,7 +845,7 @@ namespace Components
1, 10, Dedicated::IsEnabled() ? Game::DVAR_NONE : Game::DVAR_ARCHIVE, "Amount of server queries per frame");
NETServerFrames = Dvar::Register<int>("net_serverFrames", 30,
1, 60, Dedicated::IsEnabled() ? Game::DVAR_NONE : Game::DVAR_ARCHIVE, "Amount of server query frames per second");
}, Scheduler::Pipeline::MAIN);
});
// Fix ui_netsource dvar
Utils::Hook::Nop(0x4CDEEC, 5); // Don't reset the netsource when gametypes aren't loaded

View File

@ -6,37 +6,41 @@ namespace Components
int StartupMessages::TotalMessages = -1;
std::list<std::string> StartupMessages::MessageList;
Dvar::Var StartupMessages::UIStartupMessage;
Dvar::Var StartupMessages::UIStartupMessageTitle;
Dvar::Var StartupMessages::UIStartupNextButtonText;
StartupMessages::StartupMessages()
{
Scheduler::Once([]
Events::OnDvarInit([]
{
Dvar::Register<const char*>("ui_startupMessage", "", Game::DVAR_EXTERNAL | Game::DVAR_INIT, "");
Dvar::Register<const char*>("ui_startupMessageTitle", "", Game::DVAR_EXTERNAL | Game::DVAR_INIT, "");
Dvar::Register<const char*>("ui_startupNextButtonText", "", Game::DVAR_EXTERNAL | Game::DVAR_INIT, "");
}, Scheduler::Pipeline::MAIN);
UIStartupMessage = Dvar::Register<const char*>("ui_startupMessage", "", Game::DVAR_NONE, "");
UIStartupMessageTitle = Dvar::Register<const char*>("ui_startupMessageTitle", "", Game::DVAR_NONE, "");
UIStartupNextButtonText = Dvar::Register<const char*>("ui_startupNextButtonText", "", Game::DVAR_NONE, "");
});
UIScript::Add("nextStartupMessage", []([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
{
if (!StartupMessages::MessageList.size()) return;
if (MessageList.empty()) return;
if (StartupMessages::TotalMessages < 1)
if (TotalMessages < 1)
{
StartupMessages::TotalMessages = StartupMessages::MessageList.size();
TotalMessages = static_cast<int>(MessageList.size());
}
const auto& message = StartupMessages::MessageList.front();
const auto& message = MessageList.front();
Game::Dvar_SetStringByName("ui_startupMessage", message.data());
Game::Dvar_SetStringByName("ui_startupMessageTitle", Utils::String::VA("Messages (%d/%d)", StartupMessages::TotalMessages - StartupMessages::MessageList.size(), StartupMessages::TotalMessages));
Game::Dvar_SetStringByName("ui_startupNextButtonText", StartupMessages::MessageList.size() ? "Next" : "Close");
UIStartupMessage.set(message);
UIStartupMessageTitle.set(std::format("Messages ({}/{})", TotalMessages - MessageList.size(), TotalMessages));
UIStartupNextButtonText.set(MessageList.empty() ? "Close" : "Next");
Game::Cbuf_AddText(0, "openmenu startup_messages\n");
StartupMessages::MessageList.pop_front();
MessageList.pop_front();
});
}
void StartupMessages::AddMessage(const std::string& message)
{
StartupMessages::MessageList.push_back(message);
MessageList.push_back(message);
}
}

View File

@ -12,5 +12,9 @@ namespace Components
private:
static int TotalMessages;
static std::list<std::string> MessageList;
static Dvar::Var UIStartupMessage;
static Dvar::Var UIStartupMessageTitle;
static Dvar::Var UIStartupNextButtonText;
};
}

View File

@ -6,16 +6,20 @@ namespace Components
UIFeeder::Container UIFeeder::Current;
std::unordered_map<float, UIFeeder::Callbacks> UIFeeder::Feeders;
void UIFeeder::Add(float feeder, UIFeeder::GetItemCount_t itemCountCb, UIFeeder::GetItemText_t itemTextCb, UIFeeder::Select_t selectCb)
Dvar::Var UIFeeder::UIMapLong;
Dvar::Var UIFeeder::UIMapName;
Dvar::Var UIFeeder::UIMapDesc;
void UIFeeder::Add(float feeder, GetItemCount_t itemCountCb, GetItemText_t itemTextCb, Select_t selectCb)
{
UIFeeder::Feeders[feeder] = { itemCountCb, itemTextCb, selectCb };
Feeders[feeder] = { itemCountCb, itemTextCb, selectCb };
}
const char* UIFeeder::GetItemText()
{
if (UIFeeder::Feeders.contains(UIFeeder::Current.feeder))
if (Feeders.contains(Current.feeder))
{
return UIFeeder::Feeders[UIFeeder::Current.feeder].getItemText(UIFeeder::Current.index, UIFeeder::Current.column);
return Feeders[Current.feeder].getItemText(Current.index, Current.column);
}
return nullptr;
@ -23,9 +27,9 @@ namespace Components
unsigned int UIFeeder::GetItemCount()
{
if (UIFeeder::Feeders.contains(UIFeeder::Current.feeder))
if (Feeders.contains(Current.feeder))
{
return UIFeeder::Feeders[UIFeeder::Current.feeder].getItemCount();
return Feeders[Current.feeder].getItemCount();
}
return 0;
@ -33,9 +37,9 @@ namespace Components
bool UIFeeder::SetItemSelection()
{
if (UIFeeder::Feeders.find(UIFeeder::Current.feeder) != UIFeeder::Feeders.end())
if (Feeders.contains(Current.feeder))
{
UIFeeder::Feeders[UIFeeder::Current.feeder].select(UIFeeder::Current.index);
Feeders[Current.feeder].select(Current.index);
return true;
}
@ -44,8 +48,8 @@ namespace Components
bool UIFeeder::CheckFeeder()
{
if (UIFeeder::Current.feeder == 15.0f) return false;
return (UIFeeder::Feeders.find(UIFeeder::Current.feeder) != UIFeeder::Feeders.end());
if (Current.feeder == 15.0f) return false;
return Feeders.contains(Current.feeder);
}
__declspec(naked) void UIFeeder::SetItemSelectionStub()
@ -53,12 +57,12 @@ namespace Components
__asm
{
mov eax, [esp + 08h]
mov UIFeeder::Current.feeder, eax
mov Current.feeder, eax
mov eax, [esp + 0Ch]
mov UIFeeder::Current.index, eax
mov Current.index, eax
call UIFeeder::SetItemSelection
call SetItemSelection
test al, al
jz continue
@ -78,15 +82,15 @@ namespace Components
__asm
{
mov eax, [esp + 0Ch]
mov UIFeeder::Current.feeder, eax
mov Current.feeder, eax
mov eax, [esp + 10h]
mov UIFeeder::Current.index, eax
mov Current.index, eax
mov eax, [esp + 14h]
mov UIFeeder::Current.column, eax
mov Current.column, eax
call UIFeeder::GetItemText
call GetItemText
test eax, eax
jz continue
@ -111,9 +115,9 @@ namespace Components
__asm
{
mov eax, [esp + 8h]
mov UIFeeder::Current.feeder, eax
mov Current.feeder, eax
call UIFeeder::GetItemCount
call GetItemCount
test eax, eax
jz continue
@ -131,17 +135,16 @@ namespace Components
__declspec(naked) void UIFeeder::HandleKeyStub()
{
// ReSharper disable once CppEntityNeverUsed
static int nextClickTime = 0;
__asm
{
mov ebx, ebp
mov eax, [ebp + 12Ch]
mov UIFeeder::Current.feeder, eax
mov Current.feeder, eax
push ebx
call UIFeeder::CheckFeeder
call CheckFeeder
pop ebx
test al, al
@ -180,9 +183,9 @@ namespace Components
// Update indices if not
mov [ecx], edx
mov UIFeeder::Current.index, edx
mov Current.index, edx
call UIFeeder::SetItemSelection
call SetItemSelection
returnSafe:
retn
@ -198,9 +201,9 @@ namespace Components
__asm
{
mov eax, [edi + 12Ch]
mov UIFeeder::Current.feeder, eax
mov Current.feeder, eax
call UIFeeder::CheckFeeder
call CheckFeeder
test al, al
jnz continue
@ -218,9 +221,9 @@ namespace Components
__asm
{
mov eax, [esp + 08h]
mov UIFeeder::Current.feeder, eax
mov Current.feeder, eax
call UIFeeder::CheckFeeder
call CheckFeeder
test al, al
jnz continue
@ -238,9 +241,9 @@ namespace Components
__asm
{
mov eax, [edi + 12Ch]
mov UIFeeder::Current.feeder, eax
mov Current.feeder, eax
call UIFeeder::CheckFeeder
call CheckFeeder
test al, al
jnz continue
@ -257,13 +260,13 @@ namespace Components
{
if (Game::uiContext->openMenuCount > 0)
{
Game::menuDef_t* menu = Game::uiContext->menuStack[Game::uiContext->openMenuCount - 1];
auto* menu = Game::uiContext->menuStack[Game::uiContext->openMenuCount - 1];
if (menu && menu->items)
{
for (int i = 0; i < menu->itemCount; ++i)
{
Game::itemDef_s* item = menu->items[i];
auto* item = menu->items[i];
if (item && item->type == 6 && item->special == feeder)
{
item->cursorPos[0] = static_cast<int>(index);
@ -302,13 +305,13 @@ namespace Components
if (index < static_cast<unsigned int>(*Game::arenaCount))
{
index = reinterpret_cast<int*>(0x633E934)[index];
const char* mapname = ArenaLength::NewArenas[index].mapName;
const char* longname = ArenaLength::NewArenas[index].uiName;
const char* map_name = ArenaLength::NewArenas[index].mapName;
const char* long_name = ArenaLength::NewArenas[index].uiName;
const char* description = ArenaLength::NewArenas[index].description;
Dvar::Var("ui_map_name").set(mapname);
Dvar::Var("ui_map_long").set(Game::SEH_StringEd_GetString(longname));
Dvar::Var("ui_map_desc").set(Game::SEH_StringEd_GetString(description));
UIMapName.set(map_name);
UIMapLong.set(Game::SEH_StringEd_GetString(long_name));
UIMapDesc.set(Game::SEH_StringEd_GetString(description));
}
}
@ -322,21 +325,21 @@ namespace Components
void UIFeeder::ApplyInitialMap([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
{
const auto mapname = Dvar::Var("ui_mapname").get<std::string>();
const auto* mapname = (*Game::ui_mapname)->current.string;
Game::UI_UpdateArenas();
Game::UI_SortArenas();
for (unsigned int i = 0; i < static_cast<unsigned int>(*Game::arenaCount); ++i)
{
if (ArenaLength::NewArenas[i].mapName == mapname)
if (!std::strcmp(ArenaLength::NewArenas[i].mapName, mapname))
{
for (unsigned int j = 0; j < static_cast<unsigned int>(*Game::arenaCount); ++j)
{
if (reinterpret_cast<unsigned int*>(0x633E934)[j] == i)
{
UIFeeder::SelectMap(j);
UIFeeder::Select(60.0f, j);
SelectMap(j);
Select(60.0f, j);
break;
}
}
@ -361,7 +364,7 @@ namespace Components
call ecx // __ftol2_sse
push eax
call UIFeeder::CheckSelection
call CheckSelection
test al, al
jz returnSafe
@ -382,12 +385,12 @@ namespace Components
{
if (Dedicated::IsEnabled()) return;
Scheduler::Once([]
Events::OnDvarInit([]
{
Dvar::Register<const char*>("ui_map_long", "Afghan", Game::DVAR_NONE, "");
Dvar::Register<const char*>("ui_map_name", "mp_afghan", Game::DVAR_NONE, "");
Dvar::Register<const char*>("ui_map_desc", "", Game::DVAR_NONE, "");
}, Scheduler::Pipeline::MAIN);
UIMapLong = Dvar::Register<const char*>("ui_map_long", "Afghan", Game::DVAR_NONE, "");
UIMapName = Dvar::Register<const char*>("ui_map_name", "mp_afghan", Game::DVAR_NONE, "");
UIMapDesc = Dvar::Register<const char*>("ui_map_desc", "", Game::DVAR_NONE, "");
});
// Get feeder item count
Utils::Hook(0x41A0D0, UIFeeder::GetItemCountStub, HOOK_JUMP).install()->quick();

View File

@ -31,6 +31,10 @@ namespace Components
static Container Current;
static Dvar::Var UIMapLong;
static Dvar::Var UIMapName;
static Dvar::Var UIMapDesc;
static void GetItemCountStub();
static unsigned int GetItemCount();