diff --git a/data/ui_scripts/custom_depot/__init__.lua b/data/ui_scripts/custom_depot/__init__.lua new file mode 100644 index 00000000..5548e971 --- /dev/null +++ b/data/ui_scripts/custom_depot/__init__.lua @@ -0,0 +1,139 @@ +if game:issingleplayer() then + return +end + +-- from mpdepotbase.lua, global definition isn't working +InventoryCurrencyType = { + LaunchCredits = 1, + Credits = 2, + Parts = 3, + CoDPoints = 4, + Bonus = 5, + Max = 6 +} + +custom_depot = { + collection_details_menu = nil, + data = { + currencies = { + launchCredits = 0, -- LaunchCredits + credits = 0, -- Credits + parts = 0, -- Parts + codPoints = 0, -- CoDPoints + bonus = 0 -- Bonus + }, + items = {}, + reward_splashes = {}, + has_accepted_mod_eula = false, + has_seen_mod_eula = false + }, + directory_path = "h1-mod", + file_name = "depot_save.json", + file_path = nil, + functions = {} +} + +custom_depot.file_path = string.format("%s/%s", custom_depot.directory_path, custom_depot.file_name) + +custom_depot.get_function = function(function_name) + if not function_name or not custom_depot.functions[function_name] then + return nil + end + + return custom_depot.functions[function_name] +end + +custom_depot.functions["save_depot_data"] = function() + io.writefile(custom_depot.file_path, json.encode(custom_depot.data), false) +end + +custom_depot.functions["load_depot_data"] = function() + if not io.directoryexists(custom_depot.directory_path) then + io.createdirectory(custom_depot.directory_path) + end + + if not io.fileexists(custom_depot.file_path) then + custom_depot.get_function("save_depot_data")() + end + + custom_depot.data = json.decode(io.readfile(custom_depot.file_path)) +end + +local function convert_currency_to_string(type) + if type == InventoryCurrencyType.LaunchCredits then + return "launchCredits" + elseif type == InventoryCurrencyType.Credits then + return "credits" + elseif type == InventoryCurrencyType.Parts then + return "parts" + elseif type == InventoryCurrencyType.CoDPoints then + return "codPoints" + elseif type == InventoryCurrencyType.Bonus then + return "bonus" + end +end + +custom_depot.functions["add_currency"] = function(currency_type, amount) + local type = convert_currency_to_string(currency_type) + custom_depot.data.currencies[type] = custom_depot.data.currencies[type] + amount +end + +custom_depot.functions["remove_currency"] = function(currency_type, amount) + local type = convert_currency_to_string(currency_type) + custom_depot.data.currencies[type] = custom_depot.data.currencies[type] - amount +end + +custom_depot.functions["get_currency"] = function(currency_type) + local type = convert_currency_to_string(currency_type) + + if not currency_type or not custom_depot.data.currencies[type] then + return nil + end + + return custom_depot.data.currencies[type] +end + +custom_depot.functions["add_item"] = function(item, value) + custom_depot.data.items[item] = value +end + +custom_depot.functions["has_item"] = function(item) + return custom_depot.data.items[item] ~= nil +end + +custom_depot.functions["add_reward_splash"] = function(item, value) + custom_depot.data.reward_splashes[item] = value +end + +custom_depot.functions["has_reward_splash"] = function(item) + return custom_depot.data.reward_splashes[item] ~= nil +end + +custom_depot.functions["has_accepted_mod_eula"] = function() + return custom_depot.data.has_accepted_mod_eula +end + +custom_depot.functions["set_has_accepted_mod_eula"] = function(value) + custom_depot.data.has_accepted_mod_eula = value + custom_depot.get_function("save_depot_data")() +end + +custom_depot.functions["has_seen_mod_eula"] = function() + return custom_depot.data.has_seen_mod_eula +end + +custom_depot.functions["set_has_seen_mod_eula"] = function(value) + custom_depot.data.has_seen_mod_eula = value + custom_depot.get_function("save_depot_data")() +end + +custom_depot.get_function("load_depot_data")() + +if Engine.InFrontend() then + require("mod_eula") + require("depot_override") +end + +if not Engine.InFrontend() then + require("scoreboard_override") +end diff --git a/data/ui_scripts/custom_depot/depot_override.lua b/data/ui_scripts/custom_depot/depot_override.lua new file mode 100644 index 00000000..51d223dd --- /dev/null +++ b/data/ui_scripts/custom_depot/depot_override.lua @@ -0,0 +1,309 @@ +GetCurrencyBalance = function(currency_type) + return custom_depot.get_function("get_currency")(currency_type) +end + +Inventory_PurchaseItem_orig = Engine.Inventory_PurchaseItem +Engine.Inventory_PurchaseItem = function(controller, item_guid, unk2) + if not custom_depot.get_function("has_item")(item_guid) then + custom_depot.get_function("add_item")(item_guid, true) + + local item_value = Engine.TableLookup(LootTable.File, LootTable.Cols.GUID, item_guid, LootTable.Cols.Value) + custom_depot.get_function("remove_currency")(InventoryCurrencyType.Parts, item_value) + + custom_depot.get_function("save_depot_data")() + + if custom_depot.collection_details_menu then + custom_depot.collection_details_menu:OnCraftedItem() + end + end + + return Inventory_PurchaseItem_orig(controller, item_guid, unk2) +end + +GetItemLockState_orig = Engine.GetItemLockState +Engine.GetItemLockState = function(controller, item_guid) + if custom_depot.get_function("has_item")(item_guid) then + return "Unlocked", 0, "" + end + + return GetItemLockState_orig(controller, item_guid) +end + +GetItemSet_orig = GetItemSet +GetItemSet = function(item_set_id) + local item_set = GetItemSet_orig(item_set_id) + local items_unlocked = 0 + + for k, v in pairs(item_set.setItems) do + if custom_depot.get_function("has_item")(v.guid) and (not v.isOwned or v.lockState == "Unlocked") then + v.isOwned = true + v.lockState = "Unlocked" + items_unlocked = items_unlocked + 1 + end + end + + if items_unlocked == #item_set.setItems then + if not item_set.completed then + item_set.completed = true + end + + if not custom_depot.get_function("has_item")(item_set.setReward.guid) then + custom_depot.get_function("add_item")(item_set.setReward.guid, true) + custom_depot.get_function("save_depot_data")() + + if custom_depot.collection_details_menu then + custom_depot.collection_details_menu:OnCompletedSet() + end + end + end + + item_set.numOwned = items_unlocked + return item_set +end + +GetItemSets_orig = GetItemSets +GetItemSets = function() + local item_sets = GetItemSets_orig() + local completed_sets = 0 + + for i = 1, #item_sets.seasons do + local seasons_completed_sets = 0 + local sets = item_sets.seasons[i].sets + local rewardData = item_sets.seasons[i].rewardData + + for i = 1, #sets do + if sets[i].completed then + completed_sets = completed_sets + 1 + seasons_completed_sets = seasons_completed_sets + 1 + end + end + + if item_sets.seasons[i].completedSets == #sets then + rewardData.setReward.isOwned = true + rewardData.setReward.lockState = "Unlocked" + rewardData.completed = true + + if not custom_depot.get_function("has_item")(rewardData.setReward.guid) then + custom_depot.get_function("add_item")(rewardData.setReward.guid, true) + custom_depot.get_function("save_depot_data")() + end + end + + item_sets.seasons[i].completedSets = seasons_completed_sets + end + + for k, v in pairs(item_sets.itemToSetMap) do + local items_unlocked = 0 + + for i = 1, #v.setItems do + if custom_depot.get_function("has_item")(v.setItems[i].guid) and + (not v.setItems[i].isOwned or v.setItems[i].lockState == "Unlocked") then + v.setItems[i].isOwned = true + v.setItems[i].lockState = "Unlocked" + items_unlocked = items_unlocked + 1 + end + end + + if items_unlocked == #v.setItems then + if not v.completed then + v.completed = true + completed_sets = completed_sets + 1 + end + + if not custom_depot.get_function("has_item")(v.setReward.guid) then + custom_depot.get_function("add_item")(v.setReward.guid, true) + custom_depot.get_function("save_depot_data")() + end + end + + v.numOwned = items_unlocked + end + + item_sets.completedSets = completed_sets + return item_sets +end + +IsContentPromoUnlocked_orig = IsContentPromoUnlocked +IsContentPromoUnlocked = function() + return true +end + +TryShowCollectionCompleted_orig = TryShowCollectionCompleted +TryShowCollectionCompleted = function(controller, reward_data, unk1) + if reward_data.completed then + if not custom_depot.get_function("has_reward_splash")(reward_data.setReward.guid) then + LUI.FlowManager.RequestAddMenu(nil, "MPDepotCollectionRewardSplash", true, controller, false, { + collectionData = reward_data + }) + + if custom_depot.collection_details_menu then + custom_depot.collection_details_menu:OnCompletedSet() + end + + custom_depot.get_function("add_reward_splash")(reward_data.setReward.guid, true) + custom_depot.get_function("save_depot_data")() + end + + return true + else + return false + end +end + +TryShowSeasonCompleted_orig = TryShowSeasonCompleted +TryShowSeasonCompleted = function(controller, reward_data, unk1) + if reward_data.completed then + if not custom_depot.get_function("has_reward_splash")(reward_data.setReward.guid) then + LUI.FlowManager.RequestAddMenu(nil, "MPDepotCollectionRewardSplash", true, controller, false, { + collectionData = reward_data + }) + + if custom_depot.collection_details_menu then + custom_depot.collection_details_menu:OnCompletedSet() + end + + custom_depot.get_function("add_reward_splash")(reward_data.setReward.guid, true) + custom_depot.get_function("save_depot_data")() + end + + return true + else + return false + end +end + +MPDepotCollectionDetailsMenu_orig = LUI.MenuBuilder.m_types_build["MPDepotCollectionDetailsMenu"] +MPDepotCollectionDetailsMenu = function(unk1, unk2) + custom_depot.collection_details_menu = MPDepotCollectionDetailsMenu_orig(unk1, unk2) + return custom_depot.collection_details_menu +end +LUI.MenuBuilder.m_types_build["MPDepotCollectionDetailsMenu"] = MPDepotCollectionDetailsMenu + +MPDepotOpenLootMenu_orig = LUI.MenuBuilder.m_types_build["MPDepotOpenLootMenu"] +MPDepotOpenLootMenu = function(unk1, unk2) + local open_loot_menu = MPDepotOpenLootMenu_orig(unk1, unk2) + + local supply_drop_orig = open_loot_menu.m_eventHandlers["supply_drop"] + open_loot_menu:registerEventHandler("supply_drop", function(f48_arg0, f48_arg1) + f48_arg1.success = true + f48_arg1.transaction = f48_arg0.supplyDropTransaction + f48_arg1.duplicateRefund = false + f48_arg1.items = {} + f48_arg1.currencies = {} + f48_arg1.replacements = {} + f48_arg1.cards = {} + + local supply_drop_price = LUI.MPDepot.GetSupplyDropPrice(f48_arg0.supplyDropType) + custom_depot.get_function("remove_currency")(supply_drop_price.type, supply_drop_price.amount) + custom_depot.get_function("save_depot_data")() + + for i = 1, math.random(1, 3) do + local items_list = LUI.MPLootDropsBase.GetGenericItemList(x, LUI.MPDepot.LootDropsData[LUI.MPDepot + .SuppyDropLootStream[unk2.crateType]].lootTableColName) + local random_item = items_list[math.random(#items_list)] + + while random_item.inventoryItemType ~= Cac.InventoryItemType.Loot do + random_item = items_list[math.random(#items_list)] + end + + if random_item then + f48_arg1.items[i] = random_item.guid + end + end + + for i = 1, #f48_arg1.items do + if not custom_depot.get_function("has_item")(f48_arg1.items[i]) then + custom_depot.get_function("add_item")(f48_arg1.items[i], true) + else + local dismantled_amount = math.random(1, 1000) + + table.insert(f48_arg1.replacements, { + item_index = i, + currency = { + amount = dismantled_amount + } + }) + + custom_depot.get_function("add_currency")(InventoryCurrencyType.Parts, dismantled_amount) + end + end + + custom_depot.get_function("save_depot_data")() + supply_drop_orig(f48_arg0, f48_arg1) + end) + + local slow_purchase_transfer_orig = open_loot_menu.m_eventHandlers["slow_purchase_transfer"] + open_loot_menu:registerEventHandler("slow_purchase_transfer", function(f33_arg0, f33_arg1) + local f33_local0 = 0 + if f33_arg0.slowPurchaseTimer then + f33_arg0.slowPurchaseTimer:close() + f33_arg0.slowPurchaseTimer = nil + end + local f33_local1 = CoD.CreateState(-500, 0, 500, 20, CoD.AnchorTypes.Top) + f33_local1.font = CoD.TextSettings.BodyFont.Font + f33_local1.verticalAlignment = LUI.VerticalAlignment.Top + f33_local1.horizontalAlignment = LUI.HorizontalAlignment.Center + f33_local1.color = Colors.mw1_green + f33_local1.alpha = 1 + f33_arg0.slowPurchaseText = LUI.UIText.new(f33_local1) + f33_arg0:addElement(f33_arg0.slowPurchaseText) + f33_arg0.slowPurchaseText:setText(Engine.Localize("@DEPOT_TRANSFER_IN_PROGRESS_DOT")) + f33_arg0.slowPurchaseText.textState = 1 + f33_arg0.slowPurchaseText:registerEventHandler("update_slow_purchase_text", f0_local30) + f33_arg0.slowPurchaseText:addElement(LUI.UITimer.new(1000, "update_slow_purchase_text")) + local f33_local2 = LUI.MenuBuilder.BuildRegisteredType("progressBar") + f33_local2:registerAnimationState("default", { + topAnchor = false, + bottomAnchor = true, + leftAnchor = false, + rightAnchor = false, + top = 0, + height = 40 + }) + f33_local2:animateToState("default") + f33_arg0.slowPurchaseText:addElement(f33_local2) + f33_local2:animateFill(f33_local0) + f33_arg0.purchaseTimeoutTimer = LUI.UITimer.new(f33_local0, "abort_purchase_transfer", nil, true) + f33_arg0:addElement(f33_arg0.purchaseTimeoutTimer) + end) + + return open_loot_menu +end +LUI.MenuBuilder.m_types_build["MPDepotOpenLootMenu"] = MPDepotOpenLootMenu + +AddLootDropTabSelector_orig = LUI.MPDepotBase.AddLootDropTabSelector +LUI.MPDepotBase.AddLootDropTabSelector = function(unk1, unk2) + if not custom_depot.get_function("has_accepted_mod_eula")() then + local item_sets = GetItemSets() + + unk1:AddButtonWithInfo("depot_collections", "@DEPOT_COLLECTIONS", "MPDepotCollectionsMenu", nil, nil, + Engine.Localize("@MPUI_X_SLASH_Y", item_sets.completedSets, item_sets.numSets)) + + unk1:AddButtonWithInfo("depot_armory", "@DEPOT_ARMORY", "MPDepotArmoryMenu") + return + end + + AddLootDropTabSelector_orig(unk1, unk2) +end + +MPDepotMenu_orig = LUI.MenuBuilder.m_types_build["MPDepotMenu"] +MPDepotMenu = function(unk1, unk2) + local depot_menu = MPDepotMenu_orig(unk1, unk2) + + if not custom_depot.get_function("has_seen_mod_eula")() then + LUI.FlowManager.RequestAddMenu(nil, "mod_eula", true, 0, false, { + acceptCallback = function() + custom_depot.get_function("set_has_accepted_mod_eula")(true) + custom_depot.get_function("set_has_seen_mod_eula")(true) + LUI.FlowManager.RequestLeaveMenu(depot_menu) + end, + declineCallback = function() + custom_depot.get_function("set_has_accepted_mod_eula")(false) + custom_depot.get_function("set_has_seen_mod_eula")(true) + end + }) + end + + return depot_menu +end +LUI.MenuBuilder.m_types_build["MPDepotMenu"] = MPDepotMenu diff --git a/data/ui_scripts/custom_depot/mod_eula.lua b/data/ui_scripts/custom_depot/mod_eula.lua new file mode 100644 index 00000000..31bae99b --- /dev/null +++ b/data/ui_scripts/custom_depot/mod_eula.lua @@ -0,0 +1,23 @@ +game:addlocalizedstring("CUSTOM_DEPOT_EULA_1", "Dear User,") +game:addlocalizedstring("CUSTOM_DEPOT_EULA_2", + "By using this feature, you acknowledge that you are over 18 years old, and that any sort of chance games / gambling are allowed in your country (even if they do not involve real money).") +game:addlocalizedstring("CUSTOM_DEPOT_EULA_3", + "The H1-Mod team is not responsible if you break the law within your country, and the sole responsibility will be upon you to respect the same.") +game:addlocalizedstring("CUSTOM_DEPOT_EULA_4", + "The H1-Mod team will never include real money transactions within the modified systems. The only way to get currency, should you wish to, is by playing the game.") +game:addlocalizedstring("CUSTOM_DEPOT_EULA_5", "Best Regards,") +game:addlocalizedstring("CUSTOM_DEPOT_EULA_6", "The H1-Mod Team.") + +local mod_eula = function(unk1, unk2) + return LUI.EULABase.new(CoD.CreateState(0, 0, 0, 0, CoD.AnchorTypes.All), { + textStrings = LUI.EULABase.CreateTextStrings("@CUSTOM_DEPOT_EULA_", 6), + declineCallback = function(unk3) + unk2.declineCallback(unk3) + end, + acceptCallback = function(unk4) + unk2.acceptCallback(unk4) + end + }) +end + +LUI.MenuBuilder.registerPopupType("mod_eula", mod_eula) diff --git a/data/ui_scripts/custom_depot/scoreboard_override.lua b/data/ui_scripts/custom_depot/scoreboard_override.lua new file mode 100644 index 00000000..bc7edbc5 --- /dev/null +++ b/data/ui_scripts/custom_depot/scoreboard_override.lua @@ -0,0 +1,66 @@ +-- from roundend.lua, dev comments says that the game["round_end"] array contains indexes for this table +local ending_reasons = { + "MP_DRAW", + "LUA_MENU_REPORT_DRAW", + "MP_ROUND_WIN", + "MP_ROUND_LOSS", + "LUA_MENU_REPORT_VICTORY", + "LUA_MENU_REPORT_DEFEAT", + "MP_HALFTIME", + "MP_OVERTIME", + "MP_ROUNDEND", + "MP_INTERMISSION", + "MP_SWITCHING_SIDES", + "MP_MATCH_BONUS_IS", + "MP_MATCH_TIE", + "MP_GAME_END", + "SPLASHES_BLANK" +} + +local function starts_with(str, start) + return str:sub(1, #start) == start +end + +local player_old_score = 0 + +local scoreboard_orig = LUI.MenuBuilder.m_types_build["scoreboard"] +local scoreboard = function(unk1, unk2) + local scoreboard = scoreboard_orig(unk1, unk2) + + scoreboard:registerOmnvarHandler("ui_round_end", function(f22_arg0, f22_arg1) + if GameX.IsRankedMatch() then + local player_score = 0 + + local gamemode = GameX.GetGameMode() + local player_stats = Game.GetPlayerScoreInfoAtRank(Game.GetPlayerTeam(), Game.GetPlayerScoreRanking()) + + --[[ + this will do the job for when its needed, aka when round loss/win occurs + this check may be true more than once cuz this callback happens 3 times, + but the player_old_score variable will stop us from adding more currency + ]] -- + local unlocalized_string = ending_reasons[Game.GetOmnvar("ui_round_end_title")] + local is_round_based = starts_with(unlocalized_string, "MP_ROUND") or IsGameTypeRoundBased(gamemode) + + if is_round_based or gamemode == "conf" or gamemode == "war" then + player_score = player_stats.score + else + player_score = player_stats.extrascore0 + end + + local currency_gain = math.floor((player_score - player_old_score) * 10 / 100) + + if currency_gain <= 0 then + return + end + + custom_depot.get_function("add_currency")(InventoryCurrencyType.Parts, currency_gain) + + player_old_score = player_score + custom_depot.get_function("save_depot_data")() + end + end) + + return scoreboard +end +LUI.MenuBuilder.m_types_build["scoreboard"] = scoreboard