diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua index 8fa3bc88..14c7548e 100644 --- a/data/ui_scripts/stats/__init__.lua +++ b/data/ui_scripts/stats/__init__.lua @@ -53,8 +53,7 @@ DataSources.MPStatsSettings = DataSourceHelpers.ListSetup( "MPStatsSettings", fu value = 1 }, }, nil, updateDvar )) - -- Placeholder for later - --[[table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock all camos", "All camos on weapons are unlocked.", "MPStatsSettings_unlockall_camos", "cg_unlockall_camos", { + table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock all Camos and Reticles", "All camos and reticles on weapons are unlocked.", "MPStatsSettings_unlockall_camos_and_reticles", "cg_unlockall_camos_and_reticles", { { option = "MENU_DISABLED", value = 0, @@ -64,7 +63,18 @@ DataSources.MPStatsSettings = DataSourceHelpers.ListSetup( "MPStatsSettings", fu option = "MENU_ENABLED", value = 1 }, - }, nil, updateDvar ))]] + }, nil, updateDvar )) + table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock all Emblems and Backings", "All emblems and backings are unlocked.", "MPStatsSettings_unlockall_emblems_and_backings", "cg_unlockall_emblems_and_backings", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar )) local rankLevels = {} if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then diff --git a/src/client/component/loot.cpp b/src/client/component/loot.cpp index d2afb1c2..26f86ece 100644 --- a/src/client/component/loot.cpp +++ b/src/client/component/loot.cpp @@ -13,7 +13,8 @@ namespace loot game::dvar_t* dvar_cg_unlockall_loot; game::dvar_t* dvar_cg_unlockall_purchases; game::dvar_t* dvar_cg_unlockall_attachments; - game::dvar_t* dvar_cg_cg_unlockall_camos; + game::dvar_t* dvar_cg_unlockall_camos_and_reticles; + game::dvar_t* dvar_cg_unlockall_emblems_and_backings; utils::hook::detour loot_getitemquantity_hook; utils::hook::detour liveinventory_getitemquantity_hook; @@ -21,9 +22,10 @@ namespace loot utils::hook::detour bg_unlockablesisitempurchased_hook; utils::hook::detour bg_unlockablesisitemattachmentlocked_hook; utils::hook::detour bg_unlockablesisattachmentslotlocked_hook; - - int loot_getitemquantity_stub(const game::ControllerIndex_t controller_index, const game::eModes mode, - const int item_id) + utils::hook::detour bg_unlockablesemblemorbackinglockedbychallenge_hook; + utils::hook::detour bg_unlockablesitemoptionlocked_hook; + + int loot_getitemquantity_stub(const game::ControllerIndex_t controller_index, const game::eModes mode, const int item_id) { if (!dvar_cg_unlockall_loot->current.value.enabled) { @@ -41,7 +43,7 @@ namespace loot int liveinventory_getitemquantity_stub(const game::ControllerIndex_t controller_index, const int item_id) { // Item id's for extra CaC slots, CWL camo's and paid specialist outfits - if (dvar_cg_unlockall_loot->current.value.enabled && (item_id == 99003 || item_id >= 99018 && item_id <= 99021 || item_id == 99025|| + if (dvar_cg_unlockall_loot->current.value.enabled && (item_id == 99003 || item_id >= 99018 && item_id <= 99021 || item_id == 99025 || item_id >= 90047 && item_id <= 90064)) { return 1; @@ -89,6 +91,27 @@ namespace loot return bg_unlockablesisattachmentslotlocked_hook.invoke(mode, controller_index, item_index, attachment_slot_index); } + + bool bg_unlockablesitemoptionlocked_stub(game::eModes mode, const game::ControllerIndex_t controllerIndex, int itemIndex, int optionIndex) + { + // This does not unlock Dark Matter. Probably need to do something with group items + if (dvar_cg_unlockall_camos_and_reticles->current.value.enabled) + { + return false; + } + + return bg_unlockablesitemoptionlocked_hook.invoke(mode, controllerIndex, itemIndex, optionIndex); + } + + bool bg_unlockablesemblemorbackinglockedbychallenge_stub(game::eModes mode, const game::ControllerIndex_t controllerIndex, game::emblemChallengeLookup_t* challengeLookup, bool otherPlayer) + { + if (dvar_cg_unlockall_emblems_and_backings->current.value.enabled) + { + return false; + } + + return bg_unlockablesemblemorbackinglockedbychallenge_hook.invoke(mode, controllerIndex, challengeLookup, otherPlayer); + } }; struct component final : client_component @@ -101,8 +124,10 @@ namespace loot dvar_cg_unlockall_purchases->debugName = "cg_unlockall_purchases"; dvar_cg_unlockall_attachments = game::Dvar_RegisterBool(game::Dvar_GenerateHash("cg_unlockall_attachments"), "cg_unlockall_attachments", false, (game::dvarFlags_e)0x0, "Unlocks all attachments"); dvar_cg_unlockall_attachments->debugName = "cg_unlockall_attachments"; - dvar_cg_cg_unlockall_camos = game::Dvar_RegisterBool(game::Dvar_GenerateHash("cg_unlockall_camos"), "cg_unlockall_camos", false, (game::dvarFlags_e)0x0, "Unlocks all camos"); - dvar_cg_cg_unlockall_camos->debugName = "cg_unlockall_camos"; + dvar_cg_unlockall_camos_and_reticles = game::Dvar_RegisterBool(game::Dvar_GenerateHash("cg_unlockall_camos_and_reticles"), "cg_unlockall_camos_and_reticles", false, (game::dvarFlags_e)0x0, "Unlocks all camos and reticles"); + dvar_cg_unlockall_camos_and_reticles->debugName = "cg_unlockall_camos_and_reticles"; + dvar_cg_unlockall_emblems_and_backings = game::Dvar_RegisterBool(game::Dvar_GenerateHash("cg_unlockall_emblems_and_backings"), "cg_unlockall_emblems_and_backings", false, (game::dvarFlags_e)0x0, "Unlocks all emblems and backings"); + dvar_cg_unlockall_emblems_and_backings->debugName = "cg_unlockall_emblems_and_backings"; loot_getitemquantity_hook.create(0x141E82C00_g, loot_getitemquantity_stub); liveinventory_getitemquantity_hook.create(0x141E09030_g, liveinventory_getitemquantity_stub); @@ -110,6 +135,8 @@ namespace loot bg_unlockablesisitempurchased_hook.create(0x1426A9620_g, bg_unlockablesisitempurchased_stub); bg_unlockablesisitemattachmentlocked_hook.create(0x1426A88D0_g, bg_unlockablesisitemattachmentlocked_stub); bg_unlockablesisattachmentslotlocked_hook.create(0x1426A86D0_g, bg_unlockablesisattachmentslotlocked_stub); + bg_unlockablesitemoptionlocked_hook.create(0x1426AA6C0_g, bg_unlockablesitemoptionlocked_stub); + bg_unlockablesemblemorbackinglockedbychallenge_hook.create(0x1426A3AE0_g, bg_unlockablesemblemorbackinglockedbychallenge_stub); scheduler::once([]() { if (dvar_cg_unlockall_loot->current.value.enabled) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index f420fd68..dcba6812 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1593,6 +1593,93 @@ namespace game static_assert(sizeof(workshop_data) == 0x4C8); + struct DDLMember + { + const char* name; + int index; + void* parent; + int bitSize; + int limitSize; + int offset; + int type; + int externalIndex; + unsigned int rangeLimit; + unsigned int serverDelta; + unsigned int clientDelta; + int arraySize; + int enumIndex; + int permission; + }; + + struct DDLHash + { + int hash; + int index; + }; + + struct DDLHashTable + { + DDLHash* list; + int count; + int max; + }; + + struct DDLStruct + { + const char* name; + int bitSize; + int memberCount; + DDLMember* members; + DDLHashTable hashTableUpper; + DDLHashTable hashTableLower; + }; + + struct DDLEnum + { + const char* name; + int memberCount; + const char** members; + DDLHashTable hashTable; + }; + + struct DDLDef + { + char* name; + uint16_t version; + unsigned int checksum; + byte flags; + int bitSize; + int byteSize; + DDLStruct* structList; + int structCount; + DDLEnum* enumList; + int enumCount; + DDLDef* next; + int headerBitSize; + int headerByteSize; + int reserveSize; + int userFlagsSize; + bool paddingUsed; + }; + + struct DDLContext; + typedef void(__stdcall* DDLWriteCB)(DDLContext*, void*); + + struct DDLContext + { + void* buff; + int len; + const DDLDef* def; + DDLWriteCB writeCB; + void* userData; + }; + + struct emblemChallengeLookup_t + { + __int16 challengeIndex; + unsigned char itemIndex; + }; + union XAssetHeader { /*PhysPreset* physPreset;