Merge branch 'develop' into fix-cbuf

This commit is contained in:
Edo 2022-02-07 13:31:29 +01:00 committed by GitHub
commit 9200eff483
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 211 additions and 189 deletions

2
.gitmodules vendored
View File

@ -25,7 +25,7 @@
[submodule "deps/protobuf"]
path = deps/protobuf
url = https://github.com/google/protobuf.git
branch = 3.11.x
branch = 3.17.x
[submodule "deps/udis86"]
path = deps/udis86
url = https://github.com/vmt/udis86.git

2
deps/pdcurses vendored

@ -1 +1 @@
Subproject commit f1cd4f4569451a5028ddf3d3c202f0ad6b1ae446
Subproject commit 2fa0f10dd844da47ee83c05a40a1ec541ceb95e1

2
deps/protobuf vendored

@ -1 +1 @@
Subproject commit df2bce345d4bc8cdc3eba2a866e11e79e1fff4df
Subproject commit 5500c72c5b616da9f0125bcfab513987a1226e2b

2
deps/zlib vendored

@ -1 +1 @@
Subproject commit c3f3043f7aa80750245f8166a338c4877020b589
Subproject commit 2014a993addbc8f1b9785d97f55fd189792c2f78

View File

@ -3,7 +3,7 @@
namespace Components
{
thread_local int AssetHandler::BypassState = 0;
bool AssetHandler::ShouldSearchTempAssets = false;
bool AssetHandler::ShouldSearchTempAssets = false;
std::map<Game::XAssetType, AssetHandler::IAsset*> AssetHandler::AssetInterfaces;
std::map<Game::XAssetType, Utils::Slot<AssetHandler::Callback>> AssetHandler::TypeCallbacks;
Utils::Signal<AssetHandler::RestrictCallback> AssetHandler::RestrictSignal;
@ -70,20 +70,20 @@ namespace Components
return header;
}
Game::XAssetHeader AssetHandler::FindTemporaryAsset(Game::XAssetType type, const char* filename)
{
Game::XAssetHeader header = { nullptr };
if (type >= Game::XAssetType::ASSET_TYPE_COUNT) return header;
Game::XAssetHeader AssetHandler::FindTemporaryAsset(Game::XAssetType type, const char* filename)
{
Game::XAssetHeader header = { nullptr };
if (type >= Game::XAssetType::ASSET_TYPE_COUNT) return header;
auto tempPool = &AssetHandler::TemporaryAssets[type];
auto entry = tempPool->find(filename);
if (entry != tempPool->end())
{
header = { entry->second };
}
auto tempPool = &AssetHandler::TemporaryAssets[type];
auto entry = tempPool->find(filename);
if (entry != tempPool->end())
{
header = { entry->second };
}
return header;
}
return header;
}
int AssetHandler::HasThreadBypass()
{
@ -119,7 +119,6 @@ namespace Components
push esi
push edi
push eax
pushad
@ -130,14 +129,12 @@ namespace Components
popad
pop eax
test al, al
jnz checkTempAssets
mov ecx, [esp + 18h] // Asset type
mov ebx, [esp + 1Ch] // Filename
push eax
pushad
@ -152,31 +149,30 @@ namespace Components
popad
pop eax
test eax, eax
jnz finishFound
checkTempAssets:
mov al, AssetHandler::ShouldSearchTempAssets // check to see if enabled
test eax, eax
jz finishOriginal
mov ecx, [esp + 18h] // Asset type
mov ebx, [esp + 1Ch] // Filename
push ebx
push ecx
call AssetHandler::FindTemporaryAsset
add esp, 8h
test eax, eax
jnz finishFound
checkTempAssets:
mov al, AssetHandler::ShouldSearchTempAssets // check to see if enabled
test eax, eax
jz finishOriginal
mov ecx, [esp + 18h] // Asset type
mov ebx, [esp + 1Ch] // Filename
push ebx
push ecx
call AssetHandler::FindTemporaryAsset
add esp, 8h
test eax, eax
jnz finishFound
finishOriginal:
finishOriginal:
// Asset not found using custom handlers or in temp assets or bypasses were enabled
// redirect to DB_FindXAssetHeader
// redirect to DB_FindXAssetHeader
mov ebx, ds:6D7190h // InterlockedDecrement
mov eax, 40793Bh
jmp eax
@ -546,10 +542,10 @@ namespace Components
for (int i = 0; i < vertexdecl->streamCount; i++)
{
routingData.push_back(json11::Json::object
{
{ "source", (int)vertexdecl->routing.data[i].source },
{ "dest", (int)vertexdecl->routing.data[i].dest },
});
{
{ "source", (int)vertexdecl->routing.data[i].source },
{ "dest", (int)vertexdecl->routing.data[i].dest },
});
}
std::vector<json11::Json> declData;
@ -770,7 +766,7 @@ namespace Components
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LEADERBOARD, 500);
AssetHandler::RegisterInterface(new Assets::IFont_s());
AssetHandler::RegisterInterface(new Assets::IWeapon());
AssetHandler::RegisterInterface(new Assets::IWeapon());
AssetHandler::RegisterInterface(new Assets::IXModel());
AssetHandler::RegisterInterface(new Assets::IFxWorld());
AssetHandler::RegisterInterface(new Assets::IMapEnts());
@ -781,9 +777,9 @@ namespace Components
AssetHandler::RegisterInterface(new Assets::ISndCurve());
AssetHandler::RegisterInterface(new Assets::IMaterial());
AssetHandler::RegisterInterface(new Assets::IMenuList());
AssetHandler::RegisterInterface(new Assets::IclipMap_t());
AssetHandler::RegisterInterface(new Assets::IclipMap_t());
AssetHandler::RegisterInterface(new Assets::ImenuDef_t());
AssetHandler::RegisterInterface(new Assets::ITracerDef());
AssetHandler::RegisterInterface(new Assets::ITracerDef());
AssetHandler::RegisterInterface(new Assets::IPhysPreset());
AssetHandler::RegisterInterface(new Assets::IXAnimParts());
AssetHandler::RegisterInterface(new Assets::IFxEffectDef());

View File

@ -39,13 +39,13 @@ namespace Components
static void ResetBypassState();
static void ExposeTemporaryAssets(bool expose);
static void ExposeTemporaryAssets(bool expose);
static void OffsetToAlias(Utils::Stream::Offset* offset);
private:
static thread_local int BypassState;
static bool ShouldSearchTempAssets;
static bool ShouldSearchTempAssets;
static std::map<std::string, Game::XAssetHeader> TemporaryAssets[Game::XAssetType::ASSET_TYPE_COUNT];
@ -60,7 +60,7 @@ namespace Components
static void RegisterInterface(IAsset* iAsset);
static Game::XAssetHeader FindAsset(Game::XAssetType type, const char* filename);
static Game::XAssetHeader FindTemporaryAsset(Game::XAssetType type, const char* filename);
static Game::XAssetHeader FindTemporaryAsset(Game::XAssetType type, const char* filename);
static bool IsAssetEligible(Game::XAssetType type, Game::XAssetHeader* asset);
static void FindAssetStub();
static void AddAssetStub();

View File

@ -136,6 +136,41 @@ namespace Components
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
(ent->flags & Game::FL_NOTARGET) ? "GAME_NOTARGETON" : "GAME_NOTARGETOFF"));
});
ClientCommand::Add("setviewpos", [](Game::gentity_s* ent)
{
assert(ent != nullptr);
if (!ClientCommand::CheatsOk(ent))
return;
Command::ServerParams params = {};
Game::vec3_t origin, angles{0.f, 0.f, 0.f};
if (params.length() < 4u || params.length() > 6u)
{
Game::SV_GameSendServerCommand(ent->s.number, 0,
Utils::String::VA("%c \"GAME_USAGE\x15: setviewpos x y z [yaw] [pitch]\n\"", 0x65));
return;
}
for (auto i = 0; i < 3; i++)
{
origin[i] = std::strtof(params.get(i + 1), nullptr);
}
if (params.length() >= 5u)
{
angles[1] = std::strtof(params.get(4), nullptr); // Yaw
}
if (params.length() == 6u)
{
angles[0] = std::strtof(params.get(5), nullptr); // Pitch
}
Game::TeleportPlayer(ent, origin, angles);
});
}
void ClientCommand::AddScriptFunctions()

View File

@ -18,14 +18,14 @@ namespace Components
return result;
}
char* Command::Params::operator[](size_t index)
const char* Command::Params::operator[](size_t index)
{
return this->get(index);
}
char* Command::ClientParams::get(size_t index)
const char* Command::ClientParams::get(size_t index)
{
if (index >= this->length()) return const_cast<char*>("");
if (index >= this->length()) return "";
return Game::cmd_argv[this->commandId][index];
}
@ -34,9 +34,9 @@ namespace Components
return Game::cmd_argc[this->commandId];
}
char* Command::ServerParams::get(size_t index)
const char* Command::ServerParams::get(size_t index)
{
if (index >= this->length()) return const_cast<char*>("");
if (index >= this->length()) return "";
return Game::cmd_argv_sv[this->commandId][index];
}
@ -160,52 +160,6 @@ namespace Components
{
AssertSize(Game::cmd_function_t, 24);
static int toastDurationShort = 1000;
static int toastDurationMedium = 2500;
static int toastDurationLong = 5000;
Command::Add("setviewpos", [](Command::Params* params)
{
int clientNum = Game::CG_GetClientNum();
if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client)
{
Logger::Print("You are not hosting a match!\n");
Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium);
return;
}
if (!Dvar::Var("sv_cheats").get<bool>())
{
Logger::Print("Cheats disabled!\n");
Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium);
return;
}
if (params->length() != 4 && params->length() != 6)
{
Logger::Print("Invalid coordinate specified!\n");
Toast::Show("cardicon_stop", "Error", "Invalid coordinate specified!", toastDurationMedium);
return;
}
float pos[3] = { 0.0f, 0.0f, 0.0f };
float orientation[3] = { 0.0f, 0.0f, 0.0f };
pos[0] = strtof(params->get(1), nullptr);
pos[1] = strtof(params->get(2), nullptr);
pos[2] = strtof(params->get(3), nullptr);
if (params->length() == 6)
{
orientation[0] = strtof(params->get(4), nullptr);
orientation[1] = strtof(params->get(5), nullptr);
}
Game::TeleportPlayer(&Game::g_entities[clientNum], pos, orientation);
// Logging will spam the console and screen if people use cinematics
});
Command::Add("openLink", [](Command::Params* params)
{
if (params->length() > 1)

View File

@ -10,11 +10,11 @@ namespace Components
public:
Params() {};
virtual ~Params() {};
virtual char* get(size_t index) = 0;
virtual const char* get(size_t index) = 0;
virtual size_t length() = 0;
virtual std::string join(size_t startIndex);
virtual char* operator[](size_t index);
virtual const char* operator[](size_t index);
};
class ClientParams : public Params
@ -24,7 +24,7 @@ namespace Components
ClientParams(const ClientParams &obj) : commandId(obj.commandId) {};
ClientParams() : ClientParams(*Game::cmd_id) {};
char* get(size_t index) override;
const char* get(size_t index) override;
size_t length() override;
private:
@ -38,7 +38,7 @@ namespace Components
ServerParams(const ServerParams &obj) : commandId(obj.commandId) {};
ServerParams() : ServerParams(*Game::cmd_id_sv) {};
char* get(size_t index) override;
const char* get(size_t index) override;
size_t length() override;
private:

View File

@ -273,6 +273,11 @@ namespace Components
}
}
Game::dvar_t* Dedicated::Dvar_RegisterSVNetworkFps(const char* dvarName, int, int min, int, int, const char* description)
{
return Game::Dvar_RegisterInt(dvarName, 1000, min, 1000, Game::dvar_flag::DVAR_FLAG_NONE, description);
}
Dedicated::Dedicated()
{
// Map rotation
@ -311,7 +316,7 @@ namespace Components
Utils::Hook::Nop(0x4DCEC9, 2); // some check preventing proper game functioning
Utils::Hook::Nop(0x507C79, 6); // another similar bsp check
Utils::Hook::Nop(0x414E4D, 6); // unknown check in SV_ExecuteClientMessage (0x20F0890 == 0, related to client->f_40)
Utils::Hook::Nop(0x414E4D, 6); // cl->messageAcknowledge > cl->gamestateMessageNum check in SV_ExecuteClientMessage
Utils::Hook::Nop(0x4DCEE9, 5); // some deinit renderer function
Utils::Hook::Nop(0x59A896, 5); // warning message on a removed subsystem
Utils::Hook::Nop(0x4B4EEF, 5); // same as above
@ -326,14 +331,8 @@ namespace Components
// isHost script call return 0
Utils::Hook::Set<DWORD>(0x5DEC04, 0);
// sv_network_fps max 1000, and uncheat
Utils::Hook::Set<BYTE>(0x4D3C67, 0); // ?
Utils::Hook::Set<DWORD>(0x4D3C69, 1000);
// Manually register sv_network_fps
Utils::Hook::Nop(0x4D3C7B, 5);
Utils::Hook::Nop(0x4D3C8E, 5);
*reinterpret_cast<Game::dvar_t**>(0x62C7C00) = Dvar::Register<int>("sv_network_fps", 1000, 20, 1000, Game::dvar_flag::DVAR_FLAG_NONE, "Number of times per second the server checks for net messages").get<Game::dvar_t*>();
Utils::Hook(0x4D3C7B, Dedicated::Dvar_RegisterSVNetworkFps, HOOK_CALL).install()->quick();
// r_loadForRenderer default to 0
Utils::Hook::Set<BYTE>(0x519DDF, 0);

View File

@ -29,5 +29,7 @@ namespace Components
static void TransmitGuids();
static void TimeWrapStub(Game::errorParm_t code, const char* message);
static Game::dvar_t* Dvar_RegisterSVNetworkFps(const char* dvarName, int value, int min, int max, int flags, const char* description);
};
}

View File

@ -22,19 +22,19 @@ namespace Components
return this->dvar;
}
template <> char* Dvar::Var::get()
{
if (this->dvar && this->dvar->type == Game::dvar_type::DVAR_TYPE_STRING && this->dvar->current.string)
{
return const_cast<char*>(this->dvar->current.string);
}
return const_cast<char*>("");
}
template <> const char* Dvar::Var::get()
{
return this->get<char*>();
if (this->dvar == nullptr)
return "";
if (this->dvar->type == Game::dvar_type::DVAR_TYPE_STRING
|| this->dvar->type == Game::dvar_type::DVAR_TYPE_ENUM)
{
if (this->dvar->current.string != nullptr)
return this->dvar->current.string;
}
return "";
}
template <> int Dvar::Var::get()
@ -193,7 +193,7 @@ namespace Components
void Dvar::ResetDvarsValue()
{
if (!Utils::IO::FileExists(Dvar::ArchiveDvarPath))
return
return;
Command::Execute("exec archivedvars.cfg", true);
// Clean up
@ -209,7 +209,7 @@ namespace Components
Scheduler::OnFrame([]()
{
static std::string lastValidName = "Unknown Soldier";
std::string name = Dvar::Var("name").get<char*>();
std::string name = Dvar::Var("name").get<const char*>();
// Don't perform any checks if name didn't change
if (name == lastValidName) return;

View File

@ -2,7 +2,7 @@
namespace Components
{
Dvar::Var Elevators::SV_Elevators;
Dvar::Var Elevators::BG_Elevators;
int Elevators::PM_CorrectAllSolid(Game::pmove_s* pm, Game::pml_t* pml, Game::trace_t* trace)
{
@ -13,8 +13,8 @@ namespace Components
auto* ps = pm->ps;
auto i = 0;
const auto EleSettings = Elevators::SV_Elevators.get<int>();
while (TRUE)
const auto elevatorSetting = Elevators::BG_Elevators.get<int>();
while (true)
{
point[0] = ps->origin[0] + Game::CorrectSolidDeltas[i][0];
point[1] = ps->origin[1] + Game::CorrectSolidDeltas[i][1];
@ -23,7 +23,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 || EleSettings == Elevators::EASY)
if (!trace->startsolid || elevatorSetting == Elevators::EASY)
{
ps->origin[0] = point[0];
ps->origin[1] = point[1];
@ -34,27 +34,8 @@ 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 || EleSettings >= Elevators::ENABLED)
if (!trace->startsolid || elevatorSetting >= Elevators::ENABLED)
{
pml->groundTrace.fraction = trace->fraction;
pml->groundTrace.normal[0] = trace->normal[0];
pml->groundTrace.normal[1] = trace->normal[1];
pml->groundTrace.normal[2] = trace->normal[2];
pml->groundTrace.surfaceFlags = trace->surfaceFlags;
pml->groundTrace.contents = trace->contents;
pml->groundTrace.hitType = trace->hitType;
pml->groundTrace.hitId = trace->hitId;
pml->groundTrace.partName = trace->partName;
pml->groundTrace.partGroup = trace->partGroup;
pml->groundTrace.walkable = trace->walkable;
const auto fraction = trace->fraction;
ps->origin[0] += fraction * (point[0] - ps->origin[0]);
ps->origin[1] += fraction * (point[1] - ps->origin[1]);
ps->origin[2] += fraction * (point[2] - ps->origin[2]);
break;
}
}
@ -71,15 +52,23 @@ namespace Components
}
}
pml->groundTrace = *trace;
const auto fraction = trace->fraction;
ps->origin[0] += fraction * (point[0] - ps->origin[0]);
ps->origin[1] += fraction * (point[1] - ps->origin[1]);
ps->origin[2] += fraction * (point[2] - ps->origin[2]);
return 1;
}
void Elevators::PM_TraceStub(Game::pmove_s* pm, Game::trace_t* trace, const float* f3,
void Elevators::PM_Trace_Hk(Game::pmove_s* pm, Game::trace_t* trace, const float* f3,
const float* f4, const Game::Bounds* bounds, int a6, int a7)
{
Game::PM_Trace(pm, trace, f3, f4, bounds, a6, a7);
if (Elevators::SV_Elevators.get<int>() == Elevators::EASY)
// Allow the player to stand even when there is no headroom
if (Elevators::BG_Elevators.get<int>() == Elevators::EASY)
{
trace->allsolid = false;
}
@ -112,18 +101,24 @@ namespace Components
{
static const char* values[] =
{
"Disable elevators",
"Enable elevators",
"Enable easy elevators",
"off",
"normal",
"easy",
nullptr
};
Elevators::SV_Elevators = Game::Dvar_RegisterEnum("sv_Elevators", values,
Elevators::BG_Elevators = Game::Dvar_RegisterEnum("bg_elevators", values,
Elevators::ENABLED, Game::DVAR_FLAG_REPLICATED, "Elevators glitch settings");
});
//Replace PM_CorrectAllSolid
Utils::Hook(0x57369E, Elevators::PM_CorrectAllSolidStub, HOOK_CALL).install()->quick();
Utils::Hook(0x570EC5, Elevators::PM_TraceStub, HOOK_CALL).install()->quick();
// 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();
}
Elevators::~Elevators()

View File

@ -10,10 +10,10 @@ namespace Components
private:
enum ElevatorSettings { DISABLED, ENABLED, EASY };
static Dvar::Var SV_Elevators;
static Dvar::Var BG_Elevators;
static int PM_CorrectAllSolid(Game::pmove_s* move, Game::pml_t* pml, Game::trace_t* trace);
static void PM_CorrectAllSolidStub();
static void PM_TraceStub(Game::pmove_s*, Game::trace_t*, const float*, const float*, const Game::Bounds*, int, int);
static void PM_Trace_Hk(Game::pmove_s*, Game::trace_t*, const float*, const float*, const Game::Bounds*, int, int);
};
}

View File

@ -186,7 +186,7 @@ namespace Components
{
std::lock_guard<std::recursive_mutex> _(Friends::Mutex);
const unsigned int modId = *reinterpret_cast<unsigned int*>(const_cast<char*>("IW4x")) | 0x80000000;
const unsigned int modId = *reinterpret_cast<unsigned int*>("IW4x") | 0x80000000;
// Split up the list
for (auto entry : Friends::FriendsList)

View File

@ -536,14 +536,13 @@ namespace Components
if (weaponDef->requireLockonToFire)
return false;
if (ps->linkFlags & 4)
if (ps->linkFlags & Game::PLF_WEAPONVIEW_ONLY)
return false;
if (ps->weaponState >= Game::WEAPON_STUNNED_START && ps->weaponState <= Game::WEAPON_STUNNED_END)
return false;
// The game checks for these flags. Their meaning is to be researched if necessary.
if (ps->eFlags & 0x100C00)
if (ps->eFlags & (Game::EF_VEHICLE_ACTIVE | Game::EF_TURRET_ACTIVE_DUCK | Game::EF_TURRET_ACTIVE_PRONE))
return false;
if (!ps->hasAmmo)

View File

@ -21,7 +21,7 @@ namespace Components
Dvar::Var("xblive_privateserver").set(false);
std::string playlistFilename = Dvar::Var("playlistFilename").get<char*>();
std::string playlistFilename = Dvar::Var("playlistFilename").get<const char*>();
FileSystem::File playlist(playlistFilename);
if (playlist.exists())

View File

@ -747,7 +747,7 @@ namespace Components
Utils::Hook(0x4A9F56, QuickPatch::MsgReadBitsCompressCheckCL, HOOK_CALL).install()->quick(); // CL_ParseServerMessage
Utils::Hook(0x407376, QuickPatch::SVCanReplaceServerCommand , HOOK_CALL).install()->quick(); // SV_CanReplaceServerCommand
Utils::Hook(0x5B67ED, QuickPatch::AtolAdjustPlayerLimit , HOOK_CALL).install()->quick(); // PartyHost_HandleJoinPartyRequest
Utils::Hook::Nop(0x41698E, 5); // Disable Svcmd_EntityList_f
// Patch selectStringTableEntryInDvar
Utils::Hook::Set(0x405959, QuickPatch::SelectStringTableEntryInDvarStub);

View File

@ -23,16 +23,22 @@ namespace Components
StartupMessages::TotalMessages = StartupMessages::MessageList.size();
}
std::string message = StartupMessages::MessageList.front();
StartupMessages::MessageList.pop_front();
const auto& message = StartupMessages::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");
Game::Cbuf_AddText(0, "openmenu startup_messages\n");
StartupMessages::MessageList.pop_front();
});
}
StartupMessages::~StartupMessages()
{
StartupMessages::MessageList.clear();
}
void StartupMessages::AddMessage(const std::string& message)
{
StartupMessages::MessageList.push_back(message);

View File

@ -6,6 +6,7 @@ namespace Components
{
public:
StartupMessages();
~StartupMessages();
static void AddMessage(const std::string& message);

View File

@ -15,19 +15,14 @@ namespace Components
return 0;
}
template<> char* UIScript::Token::get()
template<> const char* UIScript::Token::get()
{
if (this->isValid())
{
return this->token;
}
return const_cast<char*>("");
}
template<> const char* UIScript::Token::get()
{
return this->get<char*>();
return "";
}
template<> std::string UIScript::Token::get()

View File

@ -1300,7 +1300,7 @@ namespace Components
}, nullptr, false);
// HACK: set language to 'techsets' to load from that dir
char* language = Utils::Hook::Get<char*>(0x649E740);
const char* language = Utils::Hook::Get<const char*>(0x649E740);
Utils::Hook::Set<const char*>(0x649E740, "techsets");
// load generated techset fastfiles
@ -1447,7 +1447,7 @@ namespace Components
Utils::IO::WriteFile("zone_source/techsets/techsets.csv", csvStr.data());
// set language back
Utils::Hook::Set<char*>(0x649E740, language);
Utils::Hook::Set<const char*>(0x649E740, language);
Logger::Print("Building zone 'techsets/techsets'...\n");
Zone("techsets/techsets").build();

View File

@ -783,9 +783,9 @@ namespace Game
float Vec2Normalize(vec2_t& vec)
{
const float length = std::sqrt((vec[0] * vec[0]) + (vec[1] * vec[1]));
const auto length = std::sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
if(length > 0.0f)
if (length > 0.0f)
{
vec[0] /= length;
vec[1] /= length;
@ -796,9 +796,9 @@ namespace Game
float Vec3Normalize(vec3_t& vec)
{
const float length = std::sqrt(std::pow(vec[0], 2.0f) + std::pow(vec[1], 2.0f) + std::pow(vec[2], 2.0f));
const auto length = std::sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
if(length > 0.0f)
if (length > 0.0f)
{
vec[0] /= length;
vec[1] /= length;

View File

@ -1110,6 +1110,40 @@ namespace Game
PM_DEAD_LINKED = 0x9,
};
enum playerEFlag
{
EF_NONSOLID_BMODEL = 0x1,
EF_TELEPORT_BIT = 0x2,
EF_CROUCHING = 0x4,
EF_PRONE = 0x8,
EF_NODRAW = 0x20,
EF_TIMED_OBJECT = 0x40,
EF_VOTED = 0x80,
EF_TALK = 0x100,
EF_FIRING = 0x200,
EF_TURRET_ACTIVE_PRONE = 0x400,
EF_TURRET_ACTIVE_DUCK = 0x800,
EF_LOCK_LIGHT_VIS = 0x1000,
EF_AIM_ASSIST = 0x2000,
EF_LOOP_RUMBLE = 0x4000,
EF_LASER_SIGHT = 0x8000,
EF_MANTLE = 0x10000,
EF_DEAD = 0x20000,
EF_ADS = 0x40000,
EF_NEW = 0x80000,
EF_VEHICLE_ACTIVE = 0x100000,
EF_JAMMING = 0x200000,
EF_COMPASS_PING = 0x400000,
EF_SOFT = 0x800000
};
enum playerLinkFlag
{
PLF_ANGLES_LOCKED = 0x1,
PLF_USES_OFFSET = 0x2,
PLF_WEAPONVIEW_ONLY = 0x4
};
struct playerState_s
{
int commandTime;
@ -5467,14 +5501,14 @@ namespace Game
void /*Vehicle*/* vehicle;
int physObjId;
unsigned __int16 model;
char physicsObject;
char takedamage;
char active;
char handler;
char team;
unsigned char physicsObject;
unsigned char takedamage;
unsigned char active;
unsigned char handler;
unsigned char team;
bool freeAfterEvent;
__int16 padding_short;
short classname;
unsigned __int16 classname;
unsigned __int16 script_classname;
unsigned __int16 script_linkName;
unsigned __int16 target;
@ -5502,7 +5536,10 @@ namespace Game
char pad[100];
} gentity_t;
static_assert(sizeof(gentity_s) == 0x274);
#pragma pack(push, 1)
typedef struct client_s
{
clientstate_t state; // 0
@ -5541,6 +5578,7 @@ namespace Game
unsigned __int64 steamID; // 278272
char __pad9[403592]; // 278280
} client_t;
#pragma pack(pop)
static_assert(sizeof(client_t) == 0xA6790);
@ -6985,16 +7023,15 @@ namespace Game
TRACE_HITTYPE_GLASS = 4
};
#pragma pack(push, 1)
struct trace_t
{
float fraction;
float normal[3];
int surfaceFlags;
int contents;
const char* material;
TraceHitType hitType;
unsigned __int16 hitId;
float fractionForHitType;
unsigned __int16 modelIndex;
unsigned __int16 partName;
unsigned __int16 partGroup;
@ -7002,7 +7039,8 @@ namespace Game
bool startsolid;
bool walkable;
};
#pragma pack(pop)
static_assert(sizeof(trace_t) == 0x2C);
struct pmove_s
{
@ -7045,6 +7083,8 @@ namespace Game
int holdrand;
};
static_assert(sizeof(pml_t) == 0x84);
enum EffectiveStance
{
PM_EFF_STANCE_DEFAULT = 0,

Binary file not shown.