From 558bf093385a4c5253d7b6554085c4f0135c83ae Mon Sep 17 00:00:00 2001 From: Edo Date: Sat, 4 Jun 2022 19:59:52 +0200 Subject: [PATCH] [ClientCommand] Add give command Just for weapons for now --- src/Components/Modules/ClientCommand.cpp | 76 ++++++++++++++++++++++++ src/Components/Modules/Gamepad.cpp | 8 +-- src/Game/Functions.cpp | 9 +++ src/Game/Functions.hpp | 23 ++++++- src/Utils/Utils.hpp | 3 + 5 files changed, 114 insertions(+), 5 deletions(-) diff --git a/src/Components/Modules/ClientCommand.cpp b/src/Components/Modules/ClientCommand.cpp index 66998e2b..5b429a3f 100644 --- a/src/Components/Modules/ClientCommand.cpp +++ b/src/Components/Modules/ClientCommand.cpp @@ -245,6 +245,82 @@ namespace Components assert(ent != nullptr); ent->client->ps.stunTime = 1000 + Game::level->time; // 1000 is the default test stun time }); + + ClientCommand::Add("give", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params) + { + if (!ClientCommand::CheatsOk(ent)) + return; + + if (params->size() < 2) + { + Game::SV_GameSendServerCommand(ent->s.number, Game::SV_CMD_CAN_IGNORE, + Utils::String::VA("%c \"GAME_USAGE\x15: give weapon\n\"", 0x65)); + return; + } + + Game::level->initializing = 1; + const auto* weaponName = params->get(1); + const auto weaponIndex = Game::G_GetWeaponIndexForName(weaponName); + + if (weaponIndex == 0) + { + Game::level->initializing = 0; + return; + } + + if (Game::BG_GetWeaponDef(weaponIndex)->inventoryType == Game::weapInventoryType_t::WEAPINVENTORY_ALTMODE) + { + Game::Com_PrintError(Game::CON_CHANNEL_ERROR, + "You can't directly spawn the altfire weapon '%s'. Spawn a weapon that has this altmode instead.\n", weaponName); + Game::level->initializing = 0; + return; + } + + auto* weapEnt = Game::G_Spawn(); + Utils::VectorCopy(weapEnt->r.currentOrigin, ent->r.currentOrigin); + Game::G_GetItemClassname(static_cast(weaponIndex), weapEnt); + Game::G_SpawnItem(weapEnt, static_cast(weaponIndex)); + + weapEnt->active = 1; + const auto offHandClass = Game::BG_GetWeaponDef(weaponIndex)->offhandClass; + if (offHandClass != Game::OFFHAND_CLASS_NONE) + { + auto* client = ent->client; + if ((client->ps.weapCommon.offhandPrimary != offHandClass) && (client->ps.weapCommon.offhandSecondary != offHandClass)) + { + switch (offHandClass) + { + case Game::OFFHAND_CLASS_FRAG_GRENADE: + case Game::OFFHAND_CLASS_THROWINGKNIFE: + case Game::OFFHAND_CLASS_OTHER: + client->ps.weapCommon.offhandPrimary = offHandClass; + break; + default: + client->ps.weapCommon.offhandSecondary = offHandClass; + break; + } + } + } + + Game::Touch_Item(weapEnt, ent, 0); + weapEnt->active = 0; + + if (weapEnt->r.isInUse) + { + Game::G_FreeEntity(weapEnt); + } + + Game::level->initializing = 0; + + for (std::size_t i = 0; i < std::extent_v; ++i) + { + const auto index = ent->client->ps.weaponsEquipped[i]; + if (index != 0) + { + Game::Add_Ammo(ent, index, 0, 998, 1); + } + } + }); } void ClientCommand::AddScriptFunctions() diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 36ebd108..0d725b38 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -373,7 +373,7 @@ namespace Components if (!ps->weapIndex) return false; - const auto* weaponDef = Game::BG_GetWeaponDef(ps->weapIndex); + const auto* weaponDef = Game::BG_GetWeaponDef(static_cast(ps->weapIndex)); return weaponDef->offhandClass != Game::OFFHAND_CLASS_NONE; } @@ -448,7 +448,7 @@ namespace Components if (!AimAssist_IsLockonActive(input->localClientNum)) return; - const auto* weaponDef = Game::BG_GetWeaponDef(aaGlob.ps.weapIndex); + const auto* weaponDef = Game::BG_GetWeaponDef(static_cast(aaGlob.ps.weapIndex)); if (weaponDef->requireLockonToFire) return; @@ -532,7 +532,7 @@ namespace Components if (!ps->weapIndex) return false; - const auto* weaponDef = Game::BG_GetWeaponDef(ps->weapIndex); + const auto* weaponDef = Game::BG_GetWeaponDef(static_cast(ps->weapIndex)); if (weaponDef->requireLockonToFire) return false; @@ -565,7 +565,7 @@ namespace Components if (!AimAssist_IsSlowdownActive(&aaGlob.ps)) return; - const auto* weaponDef = Game::BG_GetWeaponDef(aaGlob.ps.weapIndex); + const auto* weaponDef = Game::BG_GetWeaponDef(static_cast(aaGlob.ps.weapIndex)); const auto aimAssistRange = AimAssist_Lerp(weaponDef->aimAssistRange, weaponDef->aimAssistRangeAds, aaGlob.adsLerp) * aim_aimAssistRangeScale.get(); const auto screenTarget = AimAssist_GetBestTarget(&aaGlob, aimAssistRange, aaGlob.tweakables.slowdownRegionWidth, aaGlob.tweakables.slowdownRegionHeight); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 165ee569..2f9ebe92 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -68,6 +68,7 @@ namespace Game Com_Error_t Com_Error = Com_Error_t(0x4B22D0); Com_Printf_t Com_Printf = Com_Printf_t(0x402500); + Com_PrintError_t Com_PrintError = Com_PrintError_t(0x4F8C70); Com_PrintMessage_t Com_PrintMessage = Com_PrintMessage_t(0x4AA830); Com_EndParseSession_t Com_EndParseSession = Com_EndParseSession_t(0x4B80B0); Com_BeginParseSession_t Com_BeginParseSession = Com_BeginParseSession_t(0x4AAB80); @@ -156,6 +157,10 @@ namespace Game G_LogPrintf_t G_LogPrintf = G_LogPrintf_t(0x4B0150); G_GetWeaponIndexForName_t G_GetWeaponIndexForName = G_GetWeaponIndexForName_t(0x49E540); G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString = G_SpawnEntitiesFromString_t(0x4D8840); + G_Spawn_t G_Spawn = G_Spawn_t(0x4226F0); + G_FreeEntity_t G_FreeEntity = G_FreeEntity_t(0x44C9D0); + G_SpawnItem_t G_SpawnItem = G_SpawnItem_t(0x403770); + G_GetItemClassname_t G_GetItemClassname = G_GetItemClassname_t(0x492630); G_PrintEntities_t G_PrintEntities = G_PrintEntities_t(0x4E6A50); G_GetEntityTypeName_t G_GetEntityTypeName = G_GetEntityTypeName_t(0x4EB810); @@ -431,6 +436,10 @@ namespace Game IN_Init_t IN_Init = IN_Init_t(0x45D620); IN_Shutdown_t IN_Shutdown = IN_Shutdown_t(0x426360); + Touch_Item_t Touch_Item = Touch_Item_t(0x44FA20); + + Add_Ammo_t Add_Ammo = Add_Ammo_t(0x4E1480); + ClientUserinfoChanged_t ClientUserinfoChanged = ClientUserinfoChanged_t(0x445240); XAssetHeader* DB_XAssetPool = reinterpret_cast(0x7998A8); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 426df2eb..6a9644cd 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -40,7 +40,7 @@ namespace Game typedef void*(__cdecl * BG_LoadWeaponDef_LoadObj_t)(const char* filename); extern BG_LoadWeaponDef_LoadObj_t BG_LoadWeaponDef_LoadObj; - typedef WeaponDef* (__cdecl * BG_GetWeaponDef_t)(int weaponIndex); + typedef WeaponDef*(__cdecl * BG_GetWeaponDef_t)(unsigned int weaponIndex); extern BG_GetWeaponDef_t BG_GetWeaponDef; typedef const char*(__cdecl * BG_GetEntityTypeName_t)(const int eType); @@ -139,6 +139,9 @@ namespace Game typedef void(__cdecl * Com_Printf_t)(int channel, const char *fmt, ...); extern Com_Printf_t Com_Printf; + typedef void(__cdecl * Com_PrintError_t)(int channel, const char* fmt, ...); + extern Com_PrintError_t Com_PrintError; + typedef void(__cdecl * Com_PrintMessage_t)(int channel, const char *msg, int error); extern Com_PrintMessage_t Com_PrintMessage; @@ -389,6 +392,18 @@ namespace Game typedef void(__cdecl * G_SpawnEntitiesFromString_t)(); extern G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString; + typedef gentity_s*(__cdecl * G_Spawn_t)(); + extern G_Spawn_t G_Spawn; + + typedef void(__cdecl * G_FreeEntity_t)(gentity_s* ed); + extern G_FreeEntity_t G_FreeEntity; + + typedef void(__cdecl * G_SpawnItem_t)(gentity_s* ent, int item); + extern G_SpawnItem_t G_SpawnItem; + + typedef void(__cdecl * G_GetItemClassname_t)(int item, gentity_s* ent); + extern G_GetItemClassname_t G_GetItemClassname; + typedef void(__cdecl * G_PrintEntities_t)(); extern G_PrintEntities_t G_PrintEntities; @@ -1029,6 +1044,12 @@ namespace Game typedef void(__cdecl * IN_Shutdown_t)(); extern IN_Shutdown_t IN_Shutdown; + typedef void(__cdecl * Touch_Item_t)(gentity_s* ent, gentity_s* other, int touched); + extern Touch_Item_t Touch_Item; + + typedef void(__cdecl * Add_Ammo_t)(gentity_s* ent, unsigned int weaponIndex, unsigned char weaponModel, int count, int fillClip); + extern Add_Ammo_t Add_Ammo; + typedef void(__cdecl * ClientUserinfoChanged_t)(int clientNum); extern ClientUserinfoChanged_t ClientUserinfoChanged; diff --git a/src/Utils/Utils.hpp b/src/Utils/Utils.hpp index c33bbda3..d90c5492 100644 --- a/src/Utils/Utils.hpp +++ b/src/Utils/Utils.hpp @@ -127,4 +127,7 @@ namespace Utils mutable std::recursive_mutex mutex; std::vector> slots; }; + + template + constexpr auto VectorCopy(T a, T b) { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; } }