From 48bdbcd06daf54637ccd38ee950df04ca80d1084 Mon Sep 17 00:00:00 2001 From: GrahamKracker Date: Fri, 9 Jun 2023 00:53:40 -0400 Subject: [PATCH] update again woohoo --- Extensions.cs | 8 +- LATEST.md | 7 +- Main.cs | 481 +----------------------- Merging/Algorithm.cs | 35 +- Merging/MergeFixes/FixAbilities.cs | 2 +- Merging/MergeFixes/FixAdoraSacrifice.cs | 12 + ModHelperData.cs | 2 +- Patches.cs | 77 ++-- PortraitManager.cs | 1 - UI.cs | 478 +++++++++++++++++++++++ 10 files changed, 563 insertions(+), 540 deletions(-) create mode 100644 Merging/MergeFixes/FixAdoraSacrifice.cs create mode 100644 UI.cs diff --git a/Extensions.cs b/Extensions.cs index c5f6a61..35b491f 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -5,7 +5,7 @@ namespace OmegaCrosspathing; public static class ReflectionHelper { - private static PropertyInfo GetPropertyInfo(Type type, string propertyName) + public static PropertyInfo GetPropertyInfo(Type type, string propertyName) { PropertyInfo propInfo = null; do @@ -33,12 +33,12 @@ public static object GetPropertyValue(this object obj, string propertyName) public static void SetPropertyValue(this object obj, string propertyName, object val) { if (obj == null) - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); Type objType = obj.GetType(); PropertyInfo propInfo = GetPropertyInfo(objType, propertyName); if (propInfo == null) - throw new ArgumentOutOfRangeException("propertyName", - string.Format("Couldn't find property {0} in type {1}", propertyName, objType.FullName)); + throw new ArgumentOutOfRangeException("propertyName", + $"Couldn't find property {propertyName} in type {objType.FullName}"); propInfo.SetValue(obj, val, null); } } \ No newline at end of file diff --git a/LATEST.md b/LATEST.md index 294e2af..e4c74a5 100644 --- a/LATEST.md +++ b/LATEST.md @@ -1,2 +1,5 @@ -Fixed an issue with tower saving -Fixed paths-plus-plus as being a dependency \ No newline at end of file +Fixed etienne/wizard lord pheonix spawning infinite sub towers (thanks @doombubbles!) +Removed adora's blood sacrifice from being merged +Stopped Geraldo from appearing since he didnt work +Fixed some issues after leaving match and starting a new one +Fixed UI appearing over vanilla ui, when it shouldnt \ No newline at end of file diff --git a/Main.cs b/Main.cs index 310ff49..42524f8 100644 --- a/Main.cs +++ b/Main.cs @@ -1,24 +1,9 @@ -using System; -using System.Collections.Generic; -using BTD_Mod_Helper; -using BTD_Mod_Helper.Api; -using BTD_Mod_Helper.Api.Components; -using BTD_Mod_Helper.Api.Towers; -using Il2CppAssets.Scripts.Data; +using BTD_Mod_Helper; using Il2CppAssets.Scripts.Models.Profile; -using Il2CppAssets.Scripts.Models.TowerSets; using Il2CppAssets.Scripts.Simulation.Towers; using Il2CppAssets.Scripts.Simulation.Towers.Behaviors; -using Il2CppAssets.Scripts.Unity; -using Il2CppAssets.Scripts.Unity.UI_New.InGame; using OmegaCrosspathing; -using PathsPlusPlus; -using UnityEngine; -using UnityEngine.UI; -using static BTD_Mod_Helper.Api.ModContent; using Main = OmegaCrosspathing.Main; -using Object = UnityEngine.Object; -using TowerSet = Il2CppAssets.Scripts.Models.TowerSets.TowerSet; [assembly: MelonInfo(typeof(Main), ModHelperData.Name, ModHelperData.Version, ModHelperData.RepoOwner)] [assembly: MelonGame("Ninja Kiwi", "BloonsTD6")] @@ -29,478 +14,22 @@ namespace OmegaCrosspathing; [HarmonyPatch] public partial class Main : BloonsTD6Mod { - private static readonly Dictionary BackgroundSprites = new() - { - { TowerSet.Primary, GameData._instance.towerBackgroundSprites.primarySprite.guidRef }, - { TowerSet.Military, GameData._instance.towerBackgroundSprites.militarySprite.guidRef }, - { TowerSet.Magic, GameData._instance.towerBackgroundSprites.magicSprite.guidRef }, - { TowerSet.Support, GameData._instance.towerBackgroundSprites.supportSprite.guidRef }, - { TowerSet.Hero, GameData._instance.towerBackgroundSprites.heroSprite.guidRef }, - }; - - private static ModHelperPanel _mainpanel; - - private static float totalcost; + public static float totalcost; public static bool HasPathsPlusPlus => ModHelper.HasMod("PathsPlusPlus"); - private static ModHelperScrollPanel towersetselect; - private static ModHelperScrollPanel pathselect; - private static ModHelperPanel finalselect; - private static ModHelperImage towerportrait; - private static ModHelperText cost; - private static ModHelperButton mergebutton; - private static ModHelperText mergetext; - private static ModHelperText invalidtext; - private static ModHelperPanel levelselect; - private static ModHelperSlider levelslider; - - private static readonly Dictionary> TowerButtonsBySet = new(); - private static readonly Dictionary SelectedImages = new(); - - private static string selectedBaseID = ""; - private static TowerModel? selectedtower; - - private static readonly ModHelperSlider[] Pathsliders = new ModHelperSlider[3]; - private static readonly Dictionary Pathsplusplussliders = new(); - - public override bool CheatMod => false; - - private static void SetUpLevelInput() - { - Object.Destroy(levelselect.Background); - var level = levelselect.AddPanel(new Info("HeroLevelSelect", 290 * 3, 300), VanillaSprites.BrownInsertPanel); - level.AddText(new Info("HeroLevelSelectText", 290 * 3, 100, new Vector2(.5f, .85f)), "Level", 50f); - levelslider = level.AddSlider(new Info("HeroLevelSelectInput", 180 * 3, 60, new Vector2(.5f, .35f)), 1, 1, 20, - 1, - new Vector2(85 * 3, 85), new Action( - _ => - { - selectedtower = InGame.instance.GetGameModel() - .GetTowerModel(selectedBaseID, (int)levelslider.CurrentValue); - UpdateBottomBar(); - } - )); - Object.Destroy(levelslider.DefaultNotch.gameObject); - - levelslider.Label.transform.localScale = new Vector3(2.45f, 1, 1); - levelslider.Label.transform.parent.localScale = new Vector3(.35f, 1, 1); - - levelselect.SetActive(false); - } - - - private static void SetUpPathInput() - { - for (var i = 1; i <= 3; i++) - { - var currentpath = pathselect.AddPanel(new Info($"Path{i}", 290, 300), VanillaSprites.BrownInsertPanel); - currentpath.AddText(new Info($"Path{i}Text", 290, 100, new Vector2(.5f, .85f)), $"Path {i}", 50f); - - var slider = currentpath.AddSlider(new Info($"Path{i}Input", 180, 60, new Vector2(.5f, .35f)), 0, 0, 5, 1, - new Vector2(85, 85), new Action( - _ => - { - selectedtower = InGame.instance.GetGameModel().GetTowerModel(selectedBaseID, - (int)Pathsliders[0].CurrentValue, (int)Pathsliders[1].CurrentValue, - (int)Pathsliders[2].CurrentValue); - UpdateBottomBar(); - } - )); - - Object.Destroy(slider.DefaultNotch.gameObject); - pathselect.AddScrollContent(currentpath); - Pathsliders[i - 1] = slider; - } - pathselect.ScrollRect.StopMovement(); - pathselect.ScrollRect.enabled = false; - } - - public static void ApplyPathPlusPlus(PathPlusPlus path, int tier, ref TowerModel tower) - { - var list = tower.appliedUpgrades.ToList(); - foreach (var pathPlusPlus in GetContent().SelectMany(p=> p.Upgrades)) - { - list.RemoveAll(p => p == pathPlusPlus.Id); - } - tower.appliedUpgrades = list.ToArray(); - - tower.tier = Math.Max(tower.tier, tier); - for (var i = 0; i < tier; i++) - { - var upgrade = path.Upgrades[i]; - upgrade.ApplyUpgrade(tower); - upgrade.ApplyUpgrade(tower, tier); - if (upgrade.IsHighestUpgrade(tower)) - { - tower.portrait = upgrade.PortraitReference; - } - - if (!tower.appliedUpgrades.Contains(upgrade.Id)) - { - tower.appliedUpgrades = tower.appliedUpgrades.AddTo(upgrade.Id); - } - } - } - - - private static void SetUpTowerButtons() - { - foreach (var towerSet in BackgroundSprites.Keys) - { - var icon = "MainMenuUiAtlas[" + towerSet + "Btn]"; - var name = towerSet.ToString(); - - if (towerSet == TowerSet.Hero) - { - icon = VanillaSprites.HeroIconQuincy; - name = "Heroes"; - } - - CreateTowerSetButton(name, - icon, BackgroundSprites[towerSet], towerSet: towerSet); - } - - foreach (var modtowerset in GetContent()) - CreateTowerSetButton(modtowerset.DisplayName, modtowerset.ButtonReference.guidRef, - modtowerset.ContainerReference.guidRef, modtowerset); - } - - public static void DestroyPathsPlusPlusSliders() - { - if (HasPathsPlusPlus) - { - pathselect.ScrollRect.StopMovement(); - pathselect.ScrollRect.SetNormalizedPosition(.5f, 0); - pathselect.ScrollRect.enabled = false; - foreach (var slider in Pathsplusplussliders.Values) - Object.Destroy(slider.transform.parent.gameObject); - Pathsplusplussliders.Clear(); - } - } - - public static void GeneratePathsPlusPlusSliders(string baseId) - { - if (!HasPathsPlusPlus) return; - - DestroyPathsPlusPlusSliders(); - - foreach (var path in GetContent().Where(p => p.Tower == baseId)) - { - var i = path.Path + 1; - var currentpath = pathselect.AddPanel(new Info($"Path{i}", 290, 300), VanillaSprites.BrownInsertPanel); - currentpath.AddText(new Info($"Path{i}Text", 290, 100, new Vector2(.5f, .85f)), $"Path {i}", 50f); - - var slider = currentpath.AddSlider(new Info($"Path{i}Input", 180, 60, new Vector2(.5f, .35f)), 0, 0, 5, - 1, - new Vector2(85, 85), new Action( - tier => - { - selectedtower = InGame.instance.GetGameModel().GetTowerModel(selectedBaseID, - (int)Pathsliders[0].CurrentValue, (int)Pathsliders[1].CurrentValue, - (int)Pathsliders[2].CurrentValue); - ApplyPathPlusPlus(path,(int)tier, ref selectedtower); - UpdateBottomBar(); - } - )); - - Object.Destroy(slider.DefaultNotch.gameObject); - pathselect.AddScrollContent(currentpath); - Pathsplusplussliders[i] = slider; - - pathselect.ScrollRect.enabled = true; - pathselect.ScrollRect.horizontalNormalizedPosition = 0f; - } - } - - private static void CreateTowerSetButton(string name, string icon, string background, - ModTowerSet? modtowerset = null, TowerSet towerSet = TowerSet.None) - { - const int width = 250; - var towersetpanel = towersetselect.AddPanel(new Info(name, width, 300)); - Object.Destroy(towersetpanel.Background); - - towersetpanel.AddText(new Info("TowerSetName", 0, -17.5f, width, 100, new Vector2(.5f, .95f)), - name, 50); - - towersetselect.AddScrollContent(towersetpanel); - - var towersinset = new List(); - - if (modtowerset != null) - foreach (var tower in InGame.instance.GetGameModel().towerSet.Select(model => model.GetTower()) - .Where(tower => tower.GetModTower()?.GetPropertyValue("ModTowerSet") == modtowerset)) - { - var towerpanel = towersetpanel.AddButton(new Info(tower.name, width, 290), - background, new Action(() => - { - DestroyPathsPlusPlusSliders(); - - levelselect.SetActive(false); - pathselect.SetActive(true); - - if (selectedBaseID == tower.name) - { - HideAllSelected(); - selectedtower = null; - foreach (var slider in Pathsliders) - slider.SetCurrentValue(0); - foreach (var slider in Pathsplusplussliders.Values) - slider.SetCurrentValue(0); - UpdateBottomBar(); - return; - } - - HideAllSelected(); - - towersetpanel.transform.parent.FindChild(tower.name).FindChild("TowerSelected").gameObject - .SetActive(true); - selectedBaseID = tower.baseId; - - selectedtower = InGame.instance.GetGameModel().GetTowerModel(selectedBaseID, - (int)Pathsliders[0].CurrentValue, (int)Pathsliders[1].CurrentValue, - (int)Pathsliders[2].CurrentValue); - - - UpdateBottomBar(); - UnlockInputFields(); - })); - - towerpanel.AddImage(new Info("TowerButton", width, width, new Vector2(.5f, .55f)), - tower.portrait.guidRef); - - SelectedImages[towerpanel] = towerpanel.AddImage(new Info("TowerSelected", width + 80, 370), - VanillaSprites.SmallSquareGlowOutline); - - towersetselect.AddScrollContent(towerpanel); - towersinset.Add(towerpanel); - towerpanel.SetActive(false); - } - else - foreach (var tower in InGame.instance.GetGameModel().GetDescendants().ToList() - .Select(model => model.GetTower()).Where(tower => tower.towerSet == towerSet)) - { - if (tower.baseId == "BeastHandler") - { - continue; - } - - var towerpanel = towersetpanel.AddButton(new Info(tower.name, width, 290), - background, new Action(() => - { - if (HasPathsPlusPlus) - { - GeneratePathsPlusPlusSliders(tower.baseId); - } - if (selectedBaseID == tower.name) - { - HideAllSelected(); - foreach (var slider in Pathsliders) - slider.SetCurrentValue(0); - foreach (var slider in Pathsplusplussliders.Values) - slider.SetCurrentValue(0); - levelslider.SetCurrentValue(1); - selectedtower = null; - UpdateBottomBar(); - return; - } - - HideAllSelected(); - - selectedBaseID = tower.baseId; - - if (towerSet == TowerSet.Hero) - { - selectedtower = InGame.instance.GetGameModel() - .GetTowerModel(tower.baseId, (int)levelslider.CurrentValue); - pathselect.SetActive(false); - levelselect.SetActive(true); - } - else - { - levelselect.SetActive(false); - pathselect.SetActive(true); - selectedtower = InGame.instance.GetGameModel().GetTowerModel(tower.baseId, - (int)Pathsliders[0].CurrentValue, (int)Pathsliders[1].CurrentValue, - (int)Pathsliders[2].CurrentValue); - } - - towersetpanel.transform.parent.FindChild(tower.name).FindChild("TowerSelected").gameObject - .SetActive(true); - - UpdateBottomBar(); - UnlockInputFields(); - })); - - towerpanel.AddImage(new Info("TowerButton", width, width, new Vector2(.5f, .55f)), - tower.portrait.guidRef); - - SelectedImages[towerpanel] = towerpanel.AddImage(new Info("TowerSelected", width + 80, 370), - VanillaSprites.SmallSquareGlowOutline); - - towersetselect.AddScrollContent(towerpanel); - towersinset.Add(towerpanel); - towerpanel.SetActive(false); - } - - - var towersetButton = towersetpanel.AddButton(new Info("TowerSetButton", InfoPreset.FillParent), - background, new Action(() => - { - HideAllSelected(); - SwitchTowerSetVisibility(name); - })); - - - towersetButton.AddImage(new Info("TowerSetImage", 0, -20f, 230), - icon); - - towersetButton.AddText(new Info("TowerSetName", 0, -17.5f, width, 100, new Vector2(.5f, .95f)), - name, 50); - - towersetButton.AddImage(new Info("ExpandArrow", 100, 100, new Vector2(.925f, .5f)), - GetSpriteReference
("RoundSetSwitcherButton").guidRef).transform.rotation = - Quaternion.Euler(0, 0, 90); - - TowerButtonsBySet[name] = towersinset; - } - - private static bool ValidTiers(IReadOnlyCollection tiers) => - ModHelper.HasMod("UltimateCrosspathing") || tiers.Count(i => i > 2) <= 1 && tiers.Count(i => i > 0) <= 2; - - - private static void UpdateBottomBar() - { - - if (selectedtower == null || !ValidTiers(selectedtower.tiers.Concat(Pathsplusplussliders.Values.Select(slider => (int)slider.CurrentValue)).ToList())) - { - invalidtext.gameObject.SetActive(true); - towerportrait.Image.enabled = false; - cost.gameObject.SetActive(false); - cost.SetText(""); - mergebutton.Button.interactable = false; - mergebutton.Image.color = mergebutton.Button.colors.disabledColor; - mergetext.Text.color = mergebutton.Button.colors.disabledColor; - return; - } - - if (Pathsplusplussliders.Values.All(x => x.CurrentValue == 0) && selectedtower.tiers.All(x => x == 0)) - { - selectedtower.portrait = CreateSpriteReference(Game.instance.model.GetTower(selectedtower.baseId).portrait.guidRef); - } - - invalidtext.gameObject.SetActive(false); - cost.gameObject.SetActive(true); - mergebutton.Button.interactable = true; - - totalcost = selectedtower.appliedUpgrades.Aggregate(selectedtower.cost, - (current, up) => current + InGame.instance.GetGameModel().upgradesByName[up].cost); - - if (selectedtower.towerSet == TowerSet.Hero) - { - totalcost += selectedtower.appliedUpgrades.Aggregate(selectedtower.cost, - (current, up) => current + InGame.instance.GetGameModel().upgradesByName[up].xpCost); - } - - cost.SetText("$" + totalcost.ToString("N0")); - - mergebutton.Image.color = mergebutton.Button.colors.normalColor; - mergetext.Text.color = mergebutton.Button.colors.normalColor; - towerportrait.Image.enabled = true; - towerportrait.Image.SetSprite(selectedtower.portrait); - } + public static string selectedBaseID = ""; + public static TowerModel? selectedtower; public override void OnTowerSelected(Tower tower) { PortraitManager.SetUpPortrait(tower.GetTowerToSim()); } - private static void UnlockInputFields() - { - foreach (var inputField in Pathsliders) - { - inputField.Slider.interactable = true; - - inputField.Label.transform.parent.gameObject.GetComponent().color = new Color(1f, 1f, 1f, 1f); - inputField.Slider.transform.FindChild("Background").gameObject.GetComponent().color = - new Color(0.219f, 0.125f, 0.058f); - } - - foreach (var inputField in Pathsplusplussliders.Values) - { - inputField.Slider.interactable = true; - - inputField.Label.transform.parent.gameObject.GetComponent().color = new Color(1f, 1f, 1f, 1f); - inputField.Slider.transform.FindChild("Background").gameObject.GetComponent().color = - new Color(0.219f, 0.125f, 0.058f); - } - - levelslider.Slider.interactable = true; - - levelslider.Label.transform.parent.gameObject.GetComponent().color = new Color(1f, 1f, 1f, 1f); - levelslider.Slider.transform.FindChild("Background").gameObject.GetComponent().color = - new Color(0.219f, 0.125f, 0.058f); - } - - private static void LockInputFields() - { - foreach (var inputField in Pathsliders) - { - inputField.Slider.interactable = false; - - inputField.SetCurrentValue(0); - - inputField.Label.transform.parent.gameObject.GetComponent().color = - new Color(0.784f, 0.784f, 0.784f, 0.502f); - - inputField.Slider.transform.FindChild("Background").gameObject.GetComponent().color = - new Color(0.171696f, 0.098f, 0.045472f, 0.502f); - } - - foreach (var inputField in Pathsplusplussliders.Values) - { - inputField.Slider.interactable = false; - - inputField.SetCurrentValue(0); - - inputField.Label.transform.parent.gameObject.GetComponent().color = - new Color(0.784f, 0.784f, 0.784f, 0.502f); - - inputField.Slider.transform.FindChild("Background").gameObject.GetComponent().color = - new Color(0.171696f, 0.098f, 0.045472f, 0.502f); - } - - - levelslider.Slider.interactable = false; - - levelslider.Label.transform.parent.gameObject.GetComponent().color = - new Color(0.784f, 0.784f, 0.784f, 0.502f); - - levelslider.Slider.transform.FindChild("Background").gameObject.GetComponent().color = - new Color(0.171696f, 0.098f, 0.045472f, 0.502f); - - levelslider.SetCurrentValue(1); - } - - private static void SwitchTowerSetVisibility(string towerSet) - { - DestroyPathsPlusPlusSliders(); - LockInputFields(); - foreach (var towerPanel in TowerButtonsBySet[towerSet]) towerPanel.SetActive(!towerPanel.isActiveAndEnabled); - - TowerButtonsBySet[towerSet][0].transform.parent.FindChild(towerSet).FindChild("TowerSetButton") - .FindChild("ExpandArrow").transform.rotation = - Quaternion.Euler(0, 0, TowerButtonsBySet[towerSet][0].isActiveAndEnabled ? 270 : 90); - - } - - private static void HideAllSelected() + public override void OnMainMenu() { - foreach (var (_, image) in SelectedImages.Where(x => x.Value != null)) image.gameObject.SetActive(false); selectedBaseID = ""; selectedtower = null; - LockInputFields(); - UpdateBottomBar(); } public override void OnTowerSaved(Tower tower, TowerSaveDataModel saveData) diff --git a/Merging/Algorithm.cs b/Merging/Algorithm.cs index bb49f2a..41d8eac 100644 --- a/Merging/Algorithm.cs +++ b/Merging/Algorithm.cs @@ -73,7 +73,7 @@ public static void Merge(TowerModel first, TowerModel? second) } - private static readonly HashSet DontMerge = new() + public static readonly HashSet DontMerge = new() { "animation", "offsetX", @@ -88,26 +88,26 @@ public static void Merge(TowerModel first, TowerModel? second) "isGeraldoItem" }; - private static readonly HashSet Multiplicative = new() + public static readonly HashSet Multiplicative = new() { "pierce", "range" }; - private static readonly Dictionary StringOverrides = new() + public static readonly Dictionary StringOverrides = new() { { "fcddee8a92f5d2e4d8605a8924566620", "69bf8d5932f2bea4f9ce36f861240d2e" }, //DartMonkey-340 { "0ddd8752be0d3554cb0db6abe6686e8e", "69bf8d5932f2bea4f9ce36f861240d2e" } //DartMonkey-043 }; - private static readonly Dictionary<(string, Type), bool> BetterBooleans = new() + public static readonly Dictionary<(string, Type), bool> BetterBooleans = new() { { ("isActive", Il2CppType.Of()), false }, { ("ignoreBlockers", Il2CppType.Of()), true }, { ("isSharedRangeEnabled", Il2CppType.Of()), true }, }; - private static Object DeepMerge(Object left, Object right, Object ancestor, History history, + public static Object DeepMerge(Object left, Object right, Object ancestor, History history, bool shallow = false) { if (right is null) @@ -234,7 +234,7 @@ public static void MergeField(MemberInfo memberInfo, Object left, Object right, } } - private static Object MergeArray(MemberInfo memberInfo, Object left, Object right, Object ancestor, + public static Object MergeArray(MemberInfo memberInfo, Object left, Object right, Object ancestor, History history, bool shallow = false) { if (left == null && right != null) @@ -382,7 +382,7 @@ private static Object MergeArray(MemberInfo memberInfo, Object left, Object righ /// /// /// - private static Object MergeInt(MemberInfo memberInfo, Object leftValue, Object rightValue, Object ancestorValue) + public static Object MergeInt(MemberInfo memberInfo, Object leftValue, Object rightValue, Object ancestorValue) { if (leftValue == null) { @@ -423,7 +423,7 @@ private static Object MergeInt(MemberInfo memberInfo, Object leftValue, Object r /// /// /// - private static Object MergeFloat(MemberInfo memberInfo, Object leftValue, Object rightValue, + public static Object MergeFloat(MemberInfo memberInfo, Object leftValue, Object rightValue, Object ancestorValue) { if (leftValue == null) @@ -465,7 +465,7 @@ private static Object MergeFloat(MemberInfo memberInfo, Object leftValue, Object /// /// /// - private static Object MergeBool(MemberInfo memberInfo, Object leftValue, Object rightValue, History history) + public static Object MergeBool(MemberInfo memberInfo, Object leftValue, Object rightValue, History history) { if (leftValue == null) { @@ -507,7 +507,7 @@ private static Object MergeBool(MemberInfo memberInfo, Object leftValue, Object /// /// /// - private static Object MergeString(MemberInfo memberInfo, Object leftValue, Object rightValue, + public static Object MergeString(MemberInfo memberInfo, Object leftValue, Object rightValue, Object ancestorValue) { try @@ -564,7 +564,7 @@ private static Object MergeString(MemberInfo memberInfo, Object leftValue, Objec /// /// /// - private static Object MergeDifferentModels(Object left, Object right, Object ancestor, History history) + public static Object MergeDifferentModels(Object left, Object right, Object ancestor, History history) { var leftModel = left.Cast(); var rightModel = right.Cast(); @@ -630,7 +630,7 @@ private static Object MergeDifferentModels(Object left, Object right, Object anc return leftModel; } - private static Object ShallowMerge(Object left, Object right, Object ancestor, History history) + public static Object ShallowMerge(Object left, Object right, Object ancestor, History history) { var leftFields = left.GetIl2CppType().GetFields(); foreach (var memberInfo in leftFields) @@ -676,7 +676,7 @@ private static Object ShallowMerge(Object left, Object right, Object ancestor, H return left; } - private static int GetCountForEmissionModel(Object methodInfo, EmissionModel emissionModel) + public static int GetCountForEmissionModel(Object methodInfo, EmissionModel emissionModel) { var count = 1; if (emissionModel.IsType()) @@ -701,7 +701,7 @@ private static int GetCountForEmissionModel(Object methodInfo, EmissionModel emi return count; } - private static void Log(string msg, int depth) + public static void Log(string msg, int depth) { for (var i = 0; i < depth; i++) { @@ -710,7 +710,7 @@ private static void Log(string msg, int depth) //ModHelper.Msg(msg); } - private static bool ModelsAreTheSame(Model leftModel, Model rightModel, bool array, History history) + public static bool ModelsAreTheSame(Model leftModel, Model rightModel, bool array, History history) { if (leftModel.IsType(out var leftAbility) && rightModel.IsType(out var rightAbility)) @@ -771,11 +771,10 @@ private static bool ModelsAreTheSame(Model leftModel, Model rightModel, bool arr } } - return rightModel.name == leftModel.name - && rightModel.GetIl2CppType().Name == leftModel.GetIl2CppType().Name; + return rightModel.name == leftModel.name && rightModel.GetIl2CppType().Name == leftModel.GetIl2CppType().Name; } - /*private static bool IsType(this Object objectBase) + /*public static bool IsType(this Object objectBase) { return objectBase.GetIl2CppType().IsType(); }*/ diff --git a/Merging/MergeFixes/FixAbilities.cs b/Merging/MergeFixes/FixAbilities.cs index a9e306f..1a7427c 100644 --- a/Merging/MergeFixes/FixAbilities.cs +++ b/Merging/MergeFixes/FixAbilities.cs @@ -6,7 +6,7 @@ public class FixAbilities : PostMergeFix { public override void Apply(TowerModel model) { - foreach (var ability in model.GetAbilities().Where(abilityModel => abilityModel.displayName == "Supply Drop" || abilityModel.displayName == "Bomb Blitz")) + foreach (var ability in model.GetAbilities().Where(abilityModel => abilityModel.displayName is "Supply Drop" or "Bomb Blitz")) { var activateAttackModel = ability.GetBehavior(); activateAttackModel.isOneShot = true; diff --git a/Merging/MergeFixes/FixAdoraSacrifice.cs b/Merging/MergeFixes/FixAdoraSacrifice.cs new file mode 100644 index 0000000..6acdd16 --- /dev/null +++ b/Merging/MergeFixes/FixAdoraSacrifice.cs @@ -0,0 +1,12 @@ +namespace OmegaCrosspathing.Merging.MergeFixes; + +public class FixAdoraSacrifice : PostMergeFix +{ + public override void Apply(TowerModel model) + { + foreach(var ability in model.GetAbilities().Where(abilityModel => abilityModel.displayName == "Blood Sacrifice")) + { + model.RemoveBehavior(ability); + } + } +} \ No newline at end of file diff --git a/ModHelperData.cs b/ModHelperData.cs index 05f63f0..bee86b9 100644 --- a/ModHelperData.cs +++ b/ModHelperData.cs @@ -4,7 +4,7 @@ public static class ModHelperData { public const string Name = "OmegaCrosspathing"; public const string Description = "Allows you to merge towers together, should be fully compatible with ultimate crosspathing, custom towers, custom heroes, and custom towersets. Thanks to doombubbles for the ultimate crosspathing algorithm, which was used here."; - public const string Version = "0.0.2"; + public const string Version = "0.0.3"; public const string RepoOwner = "GrahamKracker"; public const string RepoName = "OmegaCrosspathing"; public const string WorksOnVersion = "37"; diff --git a/Patches.cs b/Patches.cs index 8d0bbc8..48fc6a4 100644 --- a/Patches.cs +++ b/Patches.cs @@ -2,37 +2,23 @@ using BTD_Mod_Helper.Api; using BTD_Mod_Helper.Api.Components; using Il2CppAssets.Scripts.Models; +using Il2CppAssets.Scripts.Simulation.Objects; +using Il2CppAssets.Scripts.Simulation.Towers; using Il2CppAssets.Scripts.Simulation.Towers.Behaviors; using Il2CppAssets.Scripts.Unity.UI_New.InGame; using Il2CppAssets.Scripts.Unity.UI_New.InGame.AbilitiesMenu; using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu; using OmegaCrosspathing.Merging; using UnityEngine; +using static OmegaCrosspathing.UI; namespace OmegaCrosspathing; + public partial class Main { - private static void SwitchToNormalUpgrades(bool isOn) - { - _mainpanel.gameObject.SetActive(!isOn); - TowerSelectionMenu.instance.towerDetails.SetActive(isOn); - - foreach (var button in TowerSelectionMenu.instance.upgradeButtons) - { - button.gameObject.SetActive(isOn); - } - - for(var i = 0; i < TowerSelectionMenu.instance.towerDetails.transform.childCount; i++) - { - TowerSelectionMenu.instance.towerDetails.transform.GetChild(i).gameObject.SetActive(isOn); - } - - - } - [HarmonyPatch(typeof(TowerSelectionMenu), nameof(TowerSelectionMenu.Show))] [HarmonyPostfix] - private static void TowerSelectionMenu_Show(TowerSelectionMenu __instance) + public static void TowerSelectionMenu_Show(TowerSelectionMenu __instance) { if (__instance.selectedTower is null) { @@ -41,30 +27,40 @@ private static void TowerSelectionMenu_Show(TowerSelectionMenu __instance) TaskScheduler.ScheduleTask(() => //required for paths++ support { - if (__instance.selectedTower.owner != InGame.instance.UnityToSimulation.MyPlayerNumber || __instance.selectedTower.tower.towerModel.IsHero()) + if (__instance.selectedTower.owner != InGame.instance.UnityToSimulation.MyPlayerNumber) { - SwitchToNormalUpgrades(true); + _mainpanel.gameObject.SetActive(false); return; } - + + if (__instance.selectedTower.tower.towerModel.IsHero()) + { + _mainpanel.gameObject.SetActive(false); + return; + } + if (__instance.selectedTower.tower.towerModel.isParagon) { _mainpanel.gameObject.SetActive(false); - __instance.paragonDetails.SetActive(true); - - return; } - SwitchToNormalUpgrades(false); + _mainpanel.gameObject.SetActive(true); + + for (var i = 0; i < TowerSelectionMenu.instance.towerDetails.transform.childCount; i++) + { + TowerSelectionMenu.instance.towerDetails.transform.GetChild(i).gameObject.SetActive(false); + } + }); } [HarmonyPatch(typeof(TowerSelectionMenu), nameof(TowerSelectionMenu.Initialise))] [HarmonyPostfix] - private static void TowerSelectionMenu_Initialise(TowerSelectionMenu __instance) + public static void TowerSelectionMenu_Initialise(TowerSelectionMenu __instance) { + //MelonLogger.Msg("TowerSelectionMenu_Initialise"); var rect = __instance.towerDetails.GetComponent().rect; _mainpanel = @@ -75,13 +71,13 @@ private static void TowerSelectionMenu_Initialise(TowerSelectionMenu __instance) rect.width, rect.height / 3, new Vector2(.5f, .85f)), RectTransform.Axis.Horizontal, VanillaSprites.BrownInsertPanel, 15, 50); - + towersetselect.ScrollContent.transform.Cast().pivot = new Vector2(0, 0); - + pathselect = _mainpanel.AddScrollPanel(new Info("PathSelect", rect.width, rect.height / 3), RectTransform.Axis.Horizontal, "", 15f, 0); pathselect.Mask.showMaskGraphic = false; - + levelselect = _mainpanel.AddPanel(new Info("LevelSelect", rect.width, rect.height / 3), null, RectTransform.Axis.Horizontal, 15f); @@ -106,8 +102,9 @@ private static void TowerSelectionMenu_Initialise(TowerSelectionMenu __instance) return; } - var OCMutator = TowerSelectionMenu.instance.selectedTower.tower.GetMutator("OC")?.Cast(); - + var OCMutator = TowerSelectionMenu.instance.selectedTower.tower.GetMutator("OC") + ?.Cast(); + if (TowerSelectionMenu.instance.selectedTower.tower.mutators != null) TowerSelectionMenu.instance.selectedTower.tower.RemoveMutatorsById("OC"); @@ -117,11 +114,11 @@ private static void TowerSelectionMenu_Initialise(TowerSelectionMenu __instance) { savedata = "hero:" + selectedtower.GetBaseId() + ":" + selectedtower.tiers[0]; } - - + + TowerSelectionMenu.instance.selectedTower.tower.AddMutator( new SupportRemoveFilterOutTag.MutatorTower("OC", - OCMutator?.removeScriptsWithSupportMutatorId + savedata + ",", + OCMutator?.removeScriptsWithSupportMutatorId + savedata + ",", null)); var owner = TowerSelectionMenu.instance.selectedTower.tower.owner; @@ -200,12 +197,14 @@ static bool SupportRemoveFilterOutTag_MutatorTower_Mutate(SupportRemoveFilterOut if (id.StartsWith("hero:")) { var nonheroid = id.Replace("hero:", ""); - towerToMerge = InGame.instance.GetGameModel().GetTowerModel(nonheroid.Split(':')[0], int.Parse(nonheroid.Split(':')[1])); + towerToMerge = InGame.instance.GetGameModel() + .GetTowerModel(nonheroid.Split(':')[0], int.Parse(nonheroid.Split(':')[1])); } else { var tiers = id.Split(':')[1]; - towerToMerge = InGame.instance.GetGameModel().GetTowerModel(id.Split(':')[0], int.Parse(tiers.Split('-')[0]), int.Parse(tiers.Split('-')[1]), int.Parse(tiers.Split('-')[2])); + towerToMerge = InGame.instance.GetGameModel().GetTowerModel(id.Split(':')[0], + int.Parse(tiers.Split('-')[0]), int.Parse(tiers.Split('-')[1]), int.Parse(tiers.Split('-')[2])); } Algorithm.Merge(tower, towerToMerge); @@ -214,4 +213,8 @@ static bool SupportRemoveFilterOutTag_MutatorTower_Mutate(SupportRemoveFilterOut __result = true; return false; } + + [HarmonyPatch(typeof(Tower), nameof(Tower.AddMutator))] + [HarmonyPrefix] + static bool Tower_AddMutator(Tower __instance, BehaviorMutator mutator)=> !(__instance.towerModel.isSubTower && mutator.id == "OC"); } \ No newline at end of file diff --git a/PortraitManager.cs b/PortraitManager.cs index 78c57b8..cba9c9f 100644 --- a/PortraitManager.cs +++ b/PortraitManager.cs @@ -1,5 +1,4 @@ using Il2CppAssets.Scripts.Unity.Bridge; -using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu; namespace OmegaCrosspathing; diff --git a/UI.cs b/UI.cs new file mode 100644 index 0000000..ae14404 --- /dev/null +++ b/UI.cs @@ -0,0 +1,478 @@ +using System; +using System.Collections.Generic; +using BTD_Mod_Helper; +using BTD_Mod_Helper.Api.Components; +using BTD_Mod_Helper.Api.Towers; +using Il2CppAssets.Scripts.Data; +using Il2CppAssets.Scripts.Models.TowerSets; +using Il2CppAssets.Scripts.Unity; +using Il2CppAssets.Scripts.Unity.UI_New.InGame; +using PathsPlusPlus; +using UnityEngine; +using UnityEngine.UI; +using static BTD_Mod_Helper.Api.ModContent; +using Object = UnityEngine.Object; + +namespace OmegaCrosspathing; + +public class UI +{ + public static readonly Dictionary BackgroundSprites = new() + { + { TowerSet.Primary, GameData._instance.towerBackgroundSprites.primarySprite.guidRef }, + { TowerSet.Military, GameData._instance.towerBackgroundSprites.militarySprite.guidRef }, + { TowerSet.Magic, GameData._instance.towerBackgroundSprites.magicSprite.guidRef }, + { TowerSet.Support, GameData._instance.towerBackgroundSprites.supportSprite.guidRef }, + { TowerSet.Hero, GameData._instance.towerBackgroundSprites.heroSprite.guidRef }, + }; + + public static ModHelperPanel _mainpanel; + public static ModHelperScrollPanel towersetselect; + public static ModHelperScrollPanel pathselect; + public static ModHelperPanel finalselect; + public static ModHelperImage towerportrait; + public static ModHelperText cost; + public static ModHelperButton mergebutton; + public static ModHelperText mergetext; + public static ModHelperText invalidtext; + public static ModHelperPanel levelselect; + public static ModHelperSlider levelslider; + + public static readonly Dictionary> TowerButtonsBySet = new(); + public static readonly Dictionary SelectedImages = new(); + + public static readonly ModHelperSlider[] Pathsliders = new ModHelperSlider[3]; + public static readonly Dictionary Pathsplusplussliders = new(); + + public static bool ValidTiers(IReadOnlyCollection tiers) => + ModHelper.HasMod("UltimateCrosspathing") || tiers.Count(i => i > 2) <= 1 && tiers.Count(i => i > 0) <= 2; + + public static void SetUpLevelInput() + { + Object.Destroy(levelselect.Background); + var level = levelselect.AddPanel(new Info("HeroLevelSelect", 290 * 3, 300), VanillaSprites.BrownInsertPanel); + level.AddText(new Info("HeroLevelSelectText", 290 * 3, 100, new Vector2(.5f, .85f)), "Level", 50f); + levelslider = level.AddSlider(new Info("HeroLevelSelectInput", 180 * 3, 60, new Vector2(.5f, .35f)), 1, 1, 20, + 1, + new Vector2(85 * 3, 85), new Action( + _ => + { + Main.selectedtower = InGame.instance.GetGameModel() + .GetTowerModel(Main.selectedBaseID, (int)levelslider.CurrentValue); + UpdateBottomBar(); + } + )); + Object.Destroy(levelslider.DefaultNotch.gameObject); + + levelslider.Label.transform.localScale = new Vector3(2.45f, 1, 1); + levelslider.Label.transform.parent.localScale = new Vector3(.35f, 1, 1); + + levelselect.SetActive(false); + } + + + public static void SetUpPathInput() + { + for (var i = 1; i <= 3; i++) + { + var currentpath = pathselect.AddPanel(new Info($"Path{i}", 290, 300), VanillaSprites.BrownInsertPanel); + currentpath.AddText(new Info($"Path{i}Text", 290, 100, new Vector2(.5f, .85f)), $"Path {i}", 50f); + + var slider = currentpath.AddSlider(new Info($"Path{i}Input", 180, 60, new Vector2(.5f, .35f)), 0, 0, 5, 1, + new Vector2(85, 85), new Action( + _ => + { + Main.selectedtower = InGame.instance.GetGameModel().GetTowerModel(Main.selectedBaseID, + (int)Pathsliders[0].CurrentValue, (int)Pathsliders[1].CurrentValue, + (int)Pathsliders[2].CurrentValue); + UpdateBottomBar(); + } + )); + + Object.Destroy(slider.DefaultNotch.gameObject); + pathselect.AddScrollContent(currentpath); + Pathsliders[i - 1] = slider; + } + pathselect.ScrollRect.StopMovement(); + pathselect.ScrollRect.enabled = false; + } + + public static void ApplyPathPlusPlus(PathPlusPlus path, int tier, ref TowerModel tower) + { + var list = tower.appliedUpgrades.ToList(); + foreach (var pathPlusPlus in GetContent().SelectMany(p=> p.Upgrades)) + { + list.RemoveAll(p => p == pathPlusPlus.Id); + } + tower.appliedUpgrades = list.ToArray(); + + tower.tier = Math.Max(tower.tier, tier); + for (var i = 0; i < tier; i++) + { + var upgrade = path.Upgrades[i]; + upgrade.ApplyUpgrade(tower); + upgrade.ApplyUpgrade(tower, tier); + if (upgrade.IsHighestUpgrade(tower)) + { + tower.portrait = upgrade.PortraitReference; + } + + if (!tower.appliedUpgrades.Contains(upgrade.Id)) + { + tower.appliedUpgrades = tower.appliedUpgrades.AddTo(upgrade.Id); + } + } + } + + + public static void SetUpTowerButtons() + { + foreach (var towerSet in BackgroundSprites.Keys) + { + var icon = "MainMenuUiAtlas[" + towerSet + "Btn]"; + var name = towerSet.ToString(); + + if (towerSet == TowerSet.Hero) + { + icon = VanillaSprites.HeroIconQuincy; + name = "Heroes"; + } + + CreateTowerSetButton(name, + icon, BackgroundSprites[towerSet], towerSet: towerSet); + } + + foreach (var modtowerset in GetContent()) + CreateTowerSetButton(modtowerset.DisplayName, modtowerset.ButtonReference.guidRef, + modtowerset.ContainerReference.guidRef, modtowerset); + } + + public static void DestroyPathsPlusPlusSliders() + { + if (Main.HasPathsPlusPlus) + { + pathselect.ScrollRect.StopMovement(); + pathselect.ScrollRect.SetNormalizedPosition(.5f, 0); + pathselect.ScrollRect.enabled = false; + foreach (var slider in Pathsplusplussliders.Values) + Object.Destroy(slider.transform.parent.gameObject); + Pathsplusplussliders.Clear(); + } + } + + public static void GeneratePathsPlusPlusSliders(string baseId) + { + if (!Main.HasPathsPlusPlus) return; + + DestroyPathsPlusPlusSliders(); + + foreach (var path in GetContent().Where(p => p.Tower == baseId)) + { + var i = path.Path + 1; + var currentpath = pathselect.AddPanel(new Info($"Path{i}", 290, 300), VanillaSprites.BrownInsertPanel); + currentpath.AddText(new Info($"Path{i}Text", 290, 100, new Vector2(.5f, .85f)), $"Path {i}", 50f); + + var slider = currentpath.AddSlider(new Info($"Path{i}Input", 180, 60, new Vector2(.5f, .35f)), 0, 0, 5, + 1, + new Vector2(85, 85), new Action( + tier => + { + Main.selectedtower = InGame.instance.GetGameModel().GetTowerModel(Main.selectedBaseID, + (int)Pathsliders[0].CurrentValue, (int)Pathsliders[1].CurrentValue, + (int)Pathsliders[2].CurrentValue); + ApplyPathPlusPlus(path,(int)tier, ref Main.selectedtower); + UpdateBottomBar(); + } + )); + + Object.Destroy(slider.DefaultNotch.gameObject); + pathselect.AddScrollContent(currentpath); + Pathsplusplussliders[i] = slider; + + pathselect.ScrollRect.enabled = true; + pathselect.ScrollRect.horizontalNormalizedPosition = 0f; + } + } + + public static void CreateTowerSetButton(string name, string icon, string background, + ModTowerSet? modtowerset = null, TowerSet towerSet = TowerSet.None) + { + const int width = 250; + var towersetpanel = towersetselect.AddPanel(new Info(name, width, 300)); + Object.Destroy(towersetpanel.Background); + + towersetpanel.AddText(new Info("TowerSetName", 0, -17.5f, width, 100, new Vector2(.5f, .95f)), + name, 50); + + towersetselect.AddScrollContent(towersetpanel); + + var towersinset = new List(); + + if (modtowerset != null) + foreach (var tower in InGame.instance.GetGameModel().towerSet.Select(model => model.GetTower()) + .Where(tower => tower.GetModTower()?.GetPropertyValue("ModTowerSet") == modtowerset)) + { + var towerpanel = towersetpanel.AddButton(new Info(tower.name, width, 290), + background, new Action(() => + { + DestroyPathsPlusPlusSliders(); + + levelselect.SetActive(false); + pathselect.SetActive(true); + + if (Main.selectedBaseID == tower.name) + { + HideAllSelected(); + Main.selectedtower = null; + foreach (var slider in Pathsliders) + slider.SetCurrentValue(0); + foreach (var slider in Pathsplusplussliders.Values) + slider.SetCurrentValue(0); + UpdateBottomBar(); + return; + } + + HideAllSelected(); + + towersetpanel.transform.parent.FindChild(tower.name).FindChild("TowerSelected").gameObject + .SetActive(true); + Main.selectedBaseID = tower.baseId; + + Main.selectedtower = InGame.instance.GetGameModel().GetTowerModel(Main.selectedBaseID, + (int)Pathsliders[0].CurrentValue, (int)Pathsliders[1].CurrentValue, + (int)Pathsliders[2].CurrentValue); + + + UpdateBottomBar(); + UnlockInputFields(); + })); + + towerpanel.AddImage(new Info("TowerButton", width, width, new Vector2(.5f, .55f)), + tower.portrait.guidRef); + + SelectedImages[towerpanel] = towerpanel.AddImage(new Info("TowerSelected", width + 80, 370), + VanillaSprites.SmallSquareGlowOutline); + + towersetselect.AddScrollContent(towerpanel); + towersinset.Add(towerpanel); + towerpanel.SetActive(false); + } + else + foreach (var tower in InGame.instance.GetGameModel().GetDescendants().ToList() + .Select(model => model.GetTower()).Where(tower => tower.towerSet == towerSet)) + { + if (tower.baseId is "BeastHandler" or "Geraldo") + { + continue; + } + + var towerpanel = towersetpanel.AddButton(new Info(tower.name, width, 290), + background, new Action(() => + { + if (Main.HasPathsPlusPlus) + { + GeneratePathsPlusPlusSliders(tower.baseId); + } + + if (Main.selectedBaseID == tower.name) + { + HideAllSelected(); + foreach (var slider in Pathsliders) + slider.SetCurrentValue(0); + foreach (var slider in Pathsplusplussliders.Values) + slider.SetCurrentValue(0); + levelslider.SetCurrentValue(1); + Main.selectedtower = null; + UpdateBottomBar(); + return; + } + + HideAllSelected(); + + Main.selectedBaseID = tower.baseId; + + if (towerSet == TowerSet.Hero) + { + Main.selectedtower = InGame.instance.GetGameModel() + .GetTowerModel(tower.baseId, (int)levelslider.CurrentValue); + pathselect.SetActive(false); + levelselect.SetActive(true); + } + else + { + levelselect.SetActive(false); + pathselect.SetActive(true); + Main.selectedtower = InGame.instance.GetGameModel().GetTowerModel(tower.baseId, + (int)Pathsliders[0].CurrentValue, (int)Pathsliders[1].CurrentValue, + (int)Pathsliders[2].CurrentValue); + } + + towersetpanel.transform.parent.FindChild(tower.name).FindChild("TowerSelected").gameObject + .SetActive(true); + + UpdateBottomBar(); + UnlockInputFields(); + })); + + towerpanel.AddImage(new Info("TowerButton", width, width, new Vector2(.5f, .55f)), + tower.portrait.guidRef); + + SelectedImages[towerpanel] = towerpanel.AddImage(new Info("TowerSelected", width + 80, 370), + VanillaSprites.SmallSquareGlowOutline); + + towersetselect.AddScrollContent(towerpanel); + towersinset.Add(towerpanel); + towerpanel.SetActive(false); + } + + + var towersetButton = towersetpanel.AddButton(new Info("TowerSetButton", InfoPreset.FillParent), + background, new Action(() => + { + HideAllSelected(); + SwitchTowerSetVisibility(name); + })); + + + towersetButton.AddImage(new Info("TowerSetImage", 0, -20f, 230), + icon); + + towersetButton.AddText(new Info("TowerSetName", 0, -17.5f, width, 100, new Vector2(.5f, .95f)), + name, 50); + + towersetButton.AddImage(new Info("ExpandArrow", 100, 100, new Vector2(.925f, .5f)), + GetSpriteReference
("RoundSetSwitcherButton").guidRef).transform.rotation = + Quaternion.Euler(0, 0, 90); + + TowerButtonsBySet[name] = towersinset; + } + + public static void UpdateBottomBar() + { + + if (Main.selectedtower == null || !ValidTiers(Main.selectedtower.tiers.Concat(Pathsplusplussliders.Values.Select(slider => (int)slider.CurrentValue)).ToList())) + { + invalidtext.gameObject.SetActive(true); + towerportrait.Image.enabled = false; + cost.gameObject.SetActive(false); + cost.SetText(""); + mergebutton.Button.interactable = false; + mergebutton.Image.color = mergebutton.Button.colors.disabledColor; + mergetext.Text.color = mergebutton.Button.colors.disabledColor; + return; + } + + if (Pathsplusplussliders.Values.All(x => x.CurrentValue == 0) && Main.selectedtower.tiers.All(x => x == 0)) + { + Main.selectedtower.portrait = CreateSpriteReference(Game.instance.model.GetTower(Main.selectedtower.baseId).portrait.guidRef); + } + + invalidtext.gameObject.SetActive(false); + cost.gameObject.SetActive(true); + mergebutton.Button.interactable = true; + + Main.totalcost = Main.selectedtower.appliedUpgrades.Aggregate(Main.selectedtower.cost, + (current, up) => current + InGame.instance.GetGameModel().upgradesByName[up].cost); + + if (Main.selectedtower.towerSet == TowerSet.Hero) + { + Main.totalcost += Main.selectedtower.appliedUpgrades.Aggregate(Main.selectedtower.cost, + (current, up) => current + InGame.instance.GetGameModel().upgradesByName[up].xpCost); + } + + cost.SetText("$" + Main.totalcost.ToString("N0")); + + mergebutton.Image.color = mergebutton.Button.colors.normalColor; + mergetext.Text.color = mergebutton.Button.colors.normalColor; + towerportrait.Image.enabled = true; + towerportrait.Image.SetSprite(Main.selectedtower.portrait); + } + + public static void UnlockInputFields() + { + foreach (var inputField in Pathsliders) + { + inputField.Slider.interactable = true; + + inputField.Label.transform.parent.gameObject.GetComponent().color = new Color(1f, 1f, 1f, 1f); + inputField.Slider.transform.FindChild("Background").gameObject.GetComponent().color = + new Color(0.219f, 0.125f, 0.058f); + } + + foreach (var inputField in Pathsplusplussliders.Values) + { + inputField.Slider.interactable = true; + + inputField.Label.transform.parent.gameObject.GetComponent().color = new Color(1f, 1f, 1f, 1f); + inputField.Slider.transform.FindChild("Background").gameObject.GetComponent().color = + new Color(0.219f, 0.125f, 0.058f); + } + + levelslider.Slider.interactable = true; + + levelslider.Label.transform.parent.gameObject.GetComponent().color = new Color(1f, 1f, 1f, 1f); + levelslider.Slider.transform.FindChild("Background").gameObject.GetComponent().color = + new Color(0.219f, 0.125f, 0.058f); + } + + public static void LockInputFields() + { + foreach (var inputField in Pathsliders) + { + inputField.Slider.interactable = false; + + inputField.SetCurrentValue(0); + + inputField.Label.transform.parent.gameObject.GetComponent().color = + new Color(0.784f, 0.784f, 0.784f, 0.502f); + + inputField.Slider.transform.FindChild("Background").gameObject.GetComponent().color = + new Color(0.171696f, 0.098f, 0.045472f, 0.502f); + } + + foreach (var inputField in Pathsplusplussliders.Values) + { + inputField.Slider.interactable = false; + + inputField.SetCurrentValue(0); + + inputField.Label.transform.parent.gameObject.GetComponent().color = + new Color(0.784f, 0.784f, 0.784f, 0.502f); + + inputField.Slider.transform.FindChild("Background").gameObject.GetComponent().color = + new Color(0.171696f, 0.098f, 0.045472f, 0.502f); + } + + + levelslider.Slider.interactable = false; + + levelslider.Label.transform.parent.gameObject.GetComponent().color = + new Color(0.784f, 0.784f, 0.784f, 0.502f); + + levelslider.Slider.transform.FindChild("Background").gameObject.GetComponent().color = + new Color(0.171696f, 0.098f, 0.045472f, 0.502f); + + levelslider.SetCurrentValue(1); + } + + public static void SwitchTowerSetVisibility(string towerSet) + { + DestroyPathsPlusPlusSliders(); + LockInputFields(); + foreach (var towerPanel in TowerButtonsBySet[towerSet]) towerPanel.SetActive(!towerPanel.isActiveAndEnabled); + + TowerButtonsBySet[towerSet][0].transform.parent.FindChild(towerSet).FindChild("TowerSetButton") + .FindChild("ExpandArrow").transform.rotation = + Quaternion.Euler(0, 0, TowerButtonsBySet[towerSet][0].isActiveAndEnabled ? 270 : 90); + + } + + public static void HideAllSelected() + { + foreach (var (_, image) in SelectedImages.Where(x => x.Value != null)) image.gameObject.SetActive(false); + Main.selectedBaseID = ""; + Main.selectedtower = null; + LockInputFields(); + UpdateBottomBar(); + } +} \ No newline at end of file