diff --git a/.gitignore b/.gitignore index 4f19896..ebccb51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ bin obj -.vscode \ No newline at end of file +.vscode +SC2ExpansionProject \ No newline at end of file diff --git a/AssetLoadingPatches.cs b/AssetLoadingPatches.cs new file mode 100644 index 0000000..7ffb151 --- /dev/null +++ b/AssetLoadingPatches.cs @@ -0,0 +1,98 @@ +namespace SC2ExpansionLoader{ + public class PrefabSpriteLoading{ + [HarmonyPatch(typeof(Factory.__c__DisplayClass21_0),"_CreateAsync_b__0")] + public class FactoryCreateAsync_Patch{ + [HarmonyPrefix] + public static bool Prefix(ref Factory.__c__DisplayClass21_0 __instance,ref UnityDisplayNode prototype){ + string towerName=__instance.objectId.guidRef.Split('-')[0]; + if(towerName!=null&&TowerTypes.ContainsKey(towerName)){ + try{ + SC2Tower tower=TowerTypes[towerName]; + GameObject gObj=uObject.Instantiate(LoadAsset(__instance.objectId.guidRef,tower.LoadedBundle).Cast(), + __instance.__4__this.DisplayRoot); + gObj.name=__instance.objectId.guidRef; + gObj.transform.position=new(0,0,30000); + gObj.AddComponent(); + SC2Sound sound=gObj.AddComponent(); + sound.MaxSelectQuote=tower.MaxSelectQuote; + sound.MaxUpgradeQuote=tower.MaxUpgradeQuote; + if(tower.Behaviours.ContainsKey(gObj.name)){ + gObj.AddComponent(tower.Behaviours[gObj.name]); + } + prototype=gObj.GetComponent(); + __instance.__4__this.active.Add(prototype); + __instance.onComplete.Invoke(prototype); + }catch(Exception error){ + Log("Failed to set "+__instance.objectId.guidRef+" up"); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + return false; + } + return true; + } + } + [HarmonyPatch(typeof(UnityEngine.U2D.SpriteAtlas),"GetSprite")] + public class SpriteAtlasGetSprite_Patch{ + [HarmonyPostfix] + public static void Postfix(string name,ref Sprite __result){ + string towerName=""; + try{ + towerName=name.Split('-')[0]; + }catch{} + if(TowerTypes.ContainsKey(towerName)){ + try{ + Texture2D texture=LoadAsset(name,TowerTypes[towerName].LoadedBundle).Cast(); + __result=Sprite.Create(texture,new(0,0,texture.width,texture.height),new()); + }catch(Exception error){ + Log("Failed to set "+name+" up"); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + + [HarmonyPatch(typeof(AudioFactory),"Start")] + public class AudioFactoryStart_Patch{ + [HarmonyPostfix] + public static void Postfix(AudioFactory __instance){ + Log("audio"); + foreach(string bundlePath in Directory.GetFiles(BundleDir)){ + if(bundlePath.EndsWith("clips")){ + try{ + Log(1); + AssetBundleCreateRequest bundleCreateReq=AssetBundle.LoadFromFileAsync(bundlePath); + Log(bundleCreateReq.isDone); + Log(2); + AssetBundle bundle=bundleCreateReq.assetBundle; + Log(bundle==null); + Log(3); + foreach(var thing in bundle.AllAssetNames()){ + Log(thing); + } + Log(4); + AssetBundleRequest bundleReq=bundle.LoadAllAssetsAsync(); + Log(4.1f); + Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppReferenceArrayassets=bundleReq.allAssets; + Log(5); + foreach(uObject asset in assets){ + Log(6); + __instance.RegisterAudioClip(asset.name,asset.Cast()); + Log(7); + } + Log(8); + }catch(Exception error){ + Log("Failed to add audio clips from "+bundlePath); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Bundles/ui.protossupgrademenu.bundle b/Bundles/ui.protossupgrademenu.bundle new file mode 100644 index 0000000..ac3da06 Binary files /dev/null and b/Bundles/ui.protossupgrademenu.bundle differ diff --git a/Bundles/ui.terranupgrademenu.bundle b/Bundles/ui.terranupgrademenu.bundle new file mode 100644 index 0000000..5e605ea Binary files /dev/null and b/Bundles/ui.terranupgrademenu.bundle differ diff --git a/GlobalUsings.cs b/GlobalUsings.cs index a6c5df8..ee5f376 100644 --- a/GlobalUsings.cs +++ b/GlobalUsings.cs @@ -17,7 +17,7 @@ global using Il2CppAssets.Scripts.Unity.Audio; global using Il2CppAssets.Scripts.Simulation.Towers.Behaviors.Abilities; global using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu; -global using Il2CppAssets.Main.Scenes; +global using Il2CppAssets.Scripts.Unity.Scenes; global using Il2CppAssets.Scripts.Unity.Player; global using Il2CppAssets.Scripts.Models.Profile; global using MelonLoader.Utils; @@ -31,4 +31,11 @@ global using Il2CppAssets.Scripts.Models.GenericBehaviors; global using Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors; global using Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors; +global using Il2CppAssets.Scripts.Unity.UI_New.InGame; +global using UnityEngine.SceneManagement; +global using UnityEngine.UI; +global using Il2CppNinjaKiwi.Common; +global using Il2CppInterop.Runtime.Attributes; +global using Il2CppAssets.Scripts.Unity.Bridge; +global using Il2Cpp; namespace SC2ExpansionLoader{} \ No newline at end of file diff --git a/MiscPatches.cs b/MiscPatches.cs new file mode 100644 index 0000000..7d0632f --- /dev/null +++ b/MiscPatches.cs @@ -0,0 +1,124 @@ +namespace SC2ExpansionLoader{ + public class HarmonyPatches{ + [HarmonyPatch(typeof(Btd6Player),"CheckForNewParagonPipEvent")] + public class Btd6PlayerCheckForNewParagonPipEvent_Patch{ + [HarmonyPrefix] + public static bool Prefix(){ + Log("pip"); + return false; + } + } + [HarmonyPatch(typeof(ProfileModel),"Validate")] + public class ProfileModelValidate_Patch{ + [HarmonyPostfix] + public static void Postfix(ProfileModel __instance){ + Log("profile"); + foreach(KeyValuePairsc2tower in TowerTypes){ + try{ + SC2Tower tower=sc2tower.Value; + __instance.unlockedTowers.Add(tower.Name); + if(tower.Upgradable){ + tower.UpgradeModels=tower.GenerateUpgradeModels(); + foreach(UpgradeModel upgrade in tower.UpgradeModels){ + __instance.acquiredUpgrades.Add(upgrade.name); + } + } + }catch(Exception error){ + Log("Failed to add "+sc2tower.Key+" to unlocked towers or upgrades"); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + [HarmonyPatch(typeof(TitleScreen),"Start")] + public class TitleScreenStart_Patch{ + [HarmonyPostfix] + public static void Postfix(){ + Log("title"); + try{ + gameModel=Game.instance.model; + LocManager=LocalizationManager.Instance; + //mostly suited for protoss warp things + CreateTowerAttackModel=gameModel.GetTowerFromId("EngineerMonkey-100").behaviors.GetModel().Clone(); + ListcreateTowerBehav=CreateTowerAttackModel.behaviors.ToList(); + createTowerBehav.Remove(createTowerBehav.First(a=>a.GetIl2CppType().Name=="RotateToTargetModel")); + createTowerBehav.GetModel().minDistance=70; + createTowerBehav.GetModel().maxDistance=90; + createTowerBehav.GetModel().idealDistanceWithinTrack=0; + createTowerBehav.GetModel().useInverted=false; + CreateTowerAttackModel.behaviors=createTowerBehav.ToArray(); + CreateTowerAttackModel.weapons[0].projectile.display=new(){guidRef=""}; + CreateTowerAttackModel.weapons[0].projectile.behaviors.GetModel().expireOnArrival=false; + CreateTowerAttackModel.weapons[0].projectile.behaviors.GetModel().altSpeed=400; + CreateTowerAttackModel.weapons[0].projectile.behaviors.GetModel().delayedReveal=1; + CreateTowerAttackModel.weapons[0].projectile.behaviors.GetModel().positionOffset=new(0,0,190); + BlankAbilityModel=gameModel.GetTowerFromId("Quincy 4").Cast().behaviors. + First(a=>a.GetIl2CppType().Name=="AbilityModel").Clone().Cast(); + BlankAbilityModel.description="AbilityDescription"; + BlankAbilityModel.displayName="AbilityDisplayName"; + BlankAbilityModel.name="AbilityName"; + Listbehaviors=BlankAbilityModel.behaviors.ToList(); + behaviors.Remove(behaviors.First(a=>a.GetIl2CppType().Name=="TurboModel")); + behaviors.Remove(behaviors.First(a=>a.GetIl2CppType().Name=="CreateEffectOnAbilityModel")); + behaviors.Remove(behaviors.First(a=>a.GetIl2CppType().Name=="CreateSoundOnAbilityModel")); + BlankAbilityModel.behaviors=behaviors.ToArray(); + }catch(Exception error){ + Log("Failed to create BlankAbilityModel"); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + Listtowers=gameModel.towers.ToList(); + ListtowerSet=gameModel.towerSet.ToList(); + Listupgrades=gameModel.upgrades.ToList(); + ListtowerNames=new(); + try{ + foreach(SC2Tower tower in TowerTypes.Values){ + towerNames.Add(tower.Name); + tower.TowerModels=tower.GenerateTowerModels(); + tower.UpgradeModels=tower.GenerateUpgradeModels(); + foreach(TowerModel towerModel in tower.TowerModels){ + towers.Add(towerModel); + } + if(tower.AddToShop){ + towerSet.Add(tower.ShopDetails()); + } + Log(tower.Name+" "+tower.Upgradable); + if(tower.Upgradable){ + foreach(UpgradeModel upgrade in tower.UpgradeModels){ + Log(upgrade.name); + upgrades.Add(upgrade); + } + } + gameModel.towers=towers.ToArray(); + gameModel.towerSet=towerSet.ToArray(); + gameModel.upgrades=upgrades.ToArray(); + Log("Loaded "+tower.Name); + } + }catch(Exception error){ + Log("Failed to add "+towerNames.Last()); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + /*[HarmonyPatch(typeof(Pet),nameof(Pet.Initialise))] + public class petinit{ + [HarmonyPrefix] + public static void Prefix(Model modelToUse){ + WanderModel wander=modelToUse.Cast().behaviors.First(a=>a.GetIl2CppType().Name=="WanderModel").Cast(); + Log("Name "+wander.name+",idletimemax "+wander.IdleTimeMax+",idletimemin "+wander.IdleTimeMin+",innerradius "+wander.InnerRadius+ + ",outerradius "+wander.OuterRadius+",speed "+wander.Speed+",startattower "+wander.startAtTower+ + ",stayinarea "+wander.StayInArea+",usesyncedrandom "+wander.useSyncedRandom); + foreach(var thing in wander.MotionCurve){ + Log("intangent "+thing.inTangent+",inweight "+thing.inWeight+",outtangent "+thing.outTangent+",outweight "+thing.outWeight+ + ",tangentmode "+thing.tangentMode+",tangentmodeinternal "+thing.tangentModeInternal+",time "+thing.time+ + ",value "+thing.value+",weightedmode "+thing.weightedMode); + } + } + }*/ + } +} \ No newline at end of file diff --git a/ModHelperData.cs b/ModHelperData.cs index 1dcbcda..159c751 100644 --- a/ModHelperData.cs +++ b/ModHelperData.cs @@ -1,7 +1,7 @@ namespace SC2ExpansionLoader{ public static class ModHelperData{ public const string WorksOnVersion="34.3"; - public const string Version="2.4.0"; + public const string Version="2.5.0"; public const string Name="SC2ExpansionLoader"; public const string Description="Loader for any SC2Expansion mods, this mod adds nothing by itself. Will be automatically downloaded if required"; public const string RepoOwner = "Onixiya"; diff --git a/ModMain.cs b/ModMain.cs index adfdf6d..b132b05 100755 --- a/ModMain.cs +++ b/ModMain.cs @@ -7,6 +7,8 @@ public class ModMain:MelonMod{ private static MelonLogger.Instance mllog; public static string BundleDir; public static AttackModel CreateTowerAttackModel; + public static GameModel gameModel; + public static LocalizationManager LocManager; public static void Log(object thingtolog,string type="msg"){ switch(type){ case"msg": @@ -36,7 +38,10 @@ public override void OnInitializeMelon(){ SC2Tower tower=(SC2Tower)Activator.CreateInstance(type); if(tower.Name!=""){ TowerTypes.Add(tower.Name,tower); - TowerTypes[tower.Name].LoadedBundle=UnityEngine.AssetBundle.LoadFromFileAsync(BundleDir+tower.Name.ToLower()).assetBundle; + tower.LoadedBundle=UnityEngine.AssetBundle.LoadFromFileAsync(BundleDir+tower.Name.ToLower()).assetBundle; + if(tower.TowerFaction==SC2Tower.Faction.NotSet){ + Log(tower.Name+"'s faction not set!","warn"); + } } }catch{} } diff --git a/Patches.cs b/Patches.cs deleted file mode 100644 index b38116a..0000000 --- a/Patches.cs +++ /dev/null @@ -1,273 +0,0 @@ -namespace SC2ExpansionLoader{ - public class HarmonyPatches{ - [HarmonyPatch(typeof(Btd6Player),"CheckForNewParagonPipEvent")] - public class Btd6PlayerCheckForNewParagonPipEvent_Patch{ - [HarmonyPrefix] - public static bool Prefix(){ - return false; - } - } - [HarmonyPatch(typeof(ProfileModel),"Validate")] - public class ProfileModelValidate_Patch{ - [HarmonyPostfix] - public static void Postfix(ProfileModel __instance){ - foreach(KeyValuePairtower in TowerTypes){ - try{ - __instance.unlockedTowers.Add(tower.Value.Name); - if(tower.Value.Upgradable){ - foreach(UpgradeModel upgrade in tower.Value.Upgrades()){ - __instance.acquiredUpgrades.Add(upgrade.name); - } - } - }catch(Exception error){ - Log("Failed to add "+tower+" to unlocked towers or upgrades"); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - } - [HarmonyPatch(typeof(TitleScreen),"Start")] - public class TitleScreenStart_Patch{ - [HarmonyPostfix] - public static void Postfix(){ - try{ - //mostly suited for protoss warp things - CreateTowerAttackModel=Game.instance.model.GetTowerFromId("EngineerMonkey-100").behaviors.GetModel().Clone(); - ListcreateTowerBehav=CreateTowerAttackModel.behaviors.ToList(); - createTowerBehav.Remove(createTowerBehav.First(a=>a.GetIl2CppType().Name=="RotateToTargetModel")); - createTowerBehav.GetModel().minDistance=70; - createTowerBehav.GetModel().maxDistance=90; - createTowerBehav.GetModel().idealDistanceWithinTrack=0; - createTowerBehav.GetModel().useInverted=false; - CreateTowerAttackModel.behaviors=createTowerBehav.ToArray(); - CreateTowerAttackModel.weapons[0].projectile.display=new(){guidRef=""}; - CreateTowerAttackModel.weapons[0].projectile.behaviors.GetModel().expireOnArrival=false; - CreateTowerAttackModel.weapons[0].projectile.behaviors.GetModel().altSpeed=400; - CreateTowerAttackModel.weapons[0].projectile.behaviors.GetModel().delayedReveal=1; - CreateTowerAttackModel.weapons[0].projectile.behaviors.GetModel().positionOffset=new(0,0,190); - BlankAbilityModel=Game.instance.model.GetTowerFromId("Quincy 4").Cast().behaviors. - First(a=>a.GetIl2CppType().Name=="AbilityModel").Clone().Cast(); - BlankAbilityModel.description="AbilityDescription"; - BlankAbilityModel.displayName="AbilityDisplayName"; - BlankAbilityModel.name="AbilityName"; - Listbehaviors=BlankAbilityModel.behaviors.ToList(); - behaviors.Remove(behaviors.First(a=>a.GetIl2CppType().Name=="TurboModel")); - behaviors.Remove(behaviors.First(a=>a.GetIl2CppType().Name=="CreateEffectOnAbilityModel")); - behaviors.Remove(behaviors.First(a=>a.GetIl2CppType().Name=="CreateSoundOnAbilityModel")); - BlankAbilityModel.behaviors=behaviors.ToArray(); - }catch(Exception error){ - Log("Failed to create BlankAbilityModel"); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - Listtowers=Game.instance.model.towers.ToList(); - ListtowerSet=Game.instance.model.towerSet.ToList(); - Listupgrades=Game.instance.model.upgrades.ToList(); - ListtowerNames=new(); - try{ - foreach(SC2Tower tower in TowerTypes.Values){ - towerNames.Add(tower.Name); - foreach(TowerModel towerModel in tower.TowerModels()){ - towers.Add(towerModel); - } - if(tower.AddToShop){ - towerSet.Add(tower.ShopDetails()); - } - if(tower.Upgradable){ - foreach(UpgradeModel upgrade in tower.Upgrades()){ - upgrades.Add(upgrade); - } - } - Game.instance.model.towers=towers.ToArray(); - Game.instance.model.towerSet=towerSet.ToArray(); - Game.instance.model.upgrades=upgrades.ToArray(); - Log("Loaded "+tower.Name); - } - }catch(Exception error){ - Log("Failed to add "+towerNames.Last()); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - [HarmonyPatch(typeof(Factory.__c__DisplayClass21_0),"_CreateAsync_b__0")] - public class FactoryCreateAsync_Patch{ - [HarmonyPrefix] - public static bool Prefix(ref Factory.__c__DisplayClass21_0 __instance,ref UnityDisplayNode prototype){ - string towerName=__instance.objectId.guidRef.Split('-')[0]; - if(towerName!=null&&TowerTypes.ContainsKey(towerName)){ - try{ - SC2Tower tower=TowerTypes[towerName]; - GameObject gObj=uObject.Instantiate(LoadAsset(__instance.objectId.guidRef,tower.LoadedBundle).Cast(), - __instance.__4__this.DisplayRoot); - gObj.name=__instance.objectId.guidRef; - gObj.transform.position=new(0,0,30000); - gObj.AddComponent(); - SC2Sound sound=gObj.AddComponent(); - sound.MaxSelectQuote=tower.MaxSelectQuote; - sound.MaxUpgradeQuote=tower.MaxUpgradeQuote; - if(tower.Behaviours.ContainsKey(gObj.name)){ - gObj.AddComponent(tower.Behaviours[gObj.name]); - } - prototype=gObj.GetComponent(); - __instance.__4__this.active.Add(prototype); - __instance.onComplete.Invoke(prototype); - }catch(Exception error){ - Log("Failed to set "+__instance.objectId.guidRef+" up"); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - return false; - } - return true; - } - } - [HarmonyPatch(typeof(UnityEngine.U2D.SpriteAtlas),"GetSprite")] - public class SpriteAtlasGetSprite_Patch{ - [HarmonyPostfix] - public static void Postfix(string name,ref Sprite __result){ - string towerName=""; - try{ - towerName=name.Split('-')[0]; - }catch{} - if(TowerTypes.ContainsKey(towerName)){ - try{ - Texture2D texture=LoadAsset(name,TowerTypes[towerName].LoadedBundle).Cast(); - __result=Sprite.Create(texture,new(0,0,texture.width,texture.height),new()); - }catch(Exception error){ - Log("Failed to set "+name+" up"); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - } - [HarmonyPatch(typeof(Weapon),"SpawnDart")] - public class WeaponSpawnDart_Patch{ - [HarmonyPostfix] - public static void Postfix(Weapon __instance){ - string towerName=__instance.attack.tower.towerModel.baseId; - if(TowerTypes.ContainsKey(towerName)){ - try{ - TowerTypes[towerName].Attack(__instance); - }catch(Exception error){ - Log("Failed to run Attack for "+towerName); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - } - [HarmonyPatch(typeof(Tower),"OnPlace")] - public class TowerOnPlace_Patch{ - [HarmonyPostfix] - public static void Postfix(Tower __instance){ - string towerName=__instance.towerModel.baseId; - if(TowerTypes.ContainsKey(towerName)){ - try{ - TowerTypes[towerName].Create(); - }catch(Exception error){ - Log("Failed to run Create for "+towerName); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - } - [HarmonyPatch(typeof(Ability),"Activate")] - public class AbilityActivate_Patch{ - [HarmonyPostfix] - public static void Postfix(Ability __instance){ - string towerName=__instance.tower.towerModel.baseId; - if(TowerTypes.ContainsKey(towerName)){ - try{ - TowerTypes[towerName].Ability(__instance.abilityModel.name,__instance.tower); - }catch(Exception error){ - Log("Failed to run Ability for "+towerName); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - } - [HarmonyPatch(typeof(AudioFactory),"Start")] - public class AudioFactoryStart_Patch{ - [HarmonyPostfix] - public static void Postfix(AudioFactory __instance){ - foreach(string bundlePath in Directory.GetFiles(BundleDir)){ - if(bundlePath.EndsWith("clips")){ - try{ - Il2CppReferenceArrayassets=AssetBundle.LoadFromFileAsync(bundlePath).assetBundle.LoadAllAssetsAsync().allAssets; - foreach(uObject asset in assets){ - __instance.RegisterAudioClip(asset.name,asset.Cast()); - } - }catch(Exception error){ - Log("Failed to add audio clips from "+bundlePath); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - } - } - [HarmonyPatch(typeof(TowerManager),"UpgradeTower")] - public class TowerManagerUpgradeTower_Patch{ - [HarmonyPostfix] - public static void Postfix(Tower tower,TowerModel def){ - string towerName=tower.towerModel.baseId; - if(TowerTypes.ContainsKey(towerName)){ - try{ - TowerTypes[towerName].Upgrade(def.tier,tower); - }catch(Exception error){ - Log("Failed to run Upgrade for "+towerName); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - } - [HarmonyPatch(typeof(TowerSelectionMenu),"SelectTower")] - public class TowerSelectionMenuSelectTower_Patch{ - [HarmonyPostfix] - public static void Postfix(TowerSelectionMenu __instance){ - string towerName=__instance.selectedTower.tower.towerModel.baseId; - if(TowerTypes.ContainsKey(towerName)){ - try{ - TowerTypes[towerName].Select(__instance.selectedTower.tower); - }catch(Exception error){ - Log("Failed to run Select for "+towerName); - string message=error.Message; - message+="@\n"+error.StackTrace; - Log(message,"error"); - } - } - } - } - /*[HarmonyPatch(typeof(Pet),nameof(Pet.Initialise))] - public class petinit{ - [HarmonyPrefix] - public static void Prefix(Model modelToUse){ - WanderModel wander=modelToUse.Cast().behaviors.First(a=>a.GetIl2CppType().Name=="WanderModel").Cast(); - Log("Name "+wander.name+", idletimemax "+wander.IdleTimeMax+", idletimemin "+wander.IdleTimeMin+", innerradius "+wander.InnerRadius+ - ", outerradius "+wander.OuterRadius+", speed "+wander.Speed+", startattower "+wander.startAtTower+ - ", stayinarea "+wander.StayInArea+", usesyncedrandom "+wander.useSyncedRandom); - foreach(var thing in wander.MotionCurve){ - Log("intangent "+thing.inTangent+", inweight "+thing.inWeight+", outtangent "+thing.outTangent+", outweight "+thing.outWeight+ - ", tangentmode "+thing.tangentMode+", tangentmodeinternal "+thing.tangentModeInternal+", time "+thing.time+ - ", value "+thing.value+", weightedmode "+thing.weightedMode); - } - } - }*/ - } -} \ No newline at end of file diff --git a/SC2ExpansionLoader.csproj b/SC2ExpansionLoader.csproj index 3b3be52..262d521 100755 --- a/SC2ExpansionLoader.csproj +++ b/SC2ExpansionLoader.csproj @@ -3,6 +3,7 @@ net6.0 enable disable + $(DefaultItemExcludes);SC2ExpansionProject;SC2ExpansionProject\**\* @@ -26,9 +27,15 @@ /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/Il2CppNinjaKiwi.Common.dll + + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/Il2CppNinjaKiwi.LiNK.dll + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/UnityEngine.dll + + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/Unity.TextMeshPro.dll + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/UnityEngine.AnimationModule.dll @@ -41,8 +48,25 @@ /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/UnityEngine.CoreModule.dll + + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/UnityEngine.UI.dll + + + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/UnityEngine.UIElementsModule.dll + + + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/UnityEngine.UIModule.dll + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/Il2CppNewtonsoft.Json.dll + + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/Il2CppNinjaKiwi.CT.API.dll + + + /home/silentstorm/.steam/steam/steamapps/common/BloonsTD6/MelonLoader/Il2CppAssemblies/Il2CppDebugLog.dll + + + \ No newline at end of file diff --git a/SC2Tower.cs b/SC2Tower.cs index ae756dd..10b0a9a 100755 --- a/SC2Tower.cs +++ b/SC2Tower.cs @@ -3,21 +3,35 @@ public class SC2Tower{ public virtual string Name=>""; public virtual byte[]TowerBundle=>null; public virtual ShopTowerDetailsModel ShopDetails()=>null; - public virtual TowerModel[]TowerModels()=>null; - public virtual UpgradeModel[]Upgrades()=>null; + public virtual TowerModel[]GenerateTowerModels()=>null; + public TowerModel[]TowerModels; + public virtual int MaxTier=>0; + public virtual string Description=>""; + public virtual UpgradeModel[]GenerateUpgradeModels()=>null; + public UpgradeModel[]UpgradeModels; public AssetBundle LoadedBundle=null; public virtual void Attack(Weapon weapon){} public virtual void Upgrade(int tier,Tower tower){} public virtual void Ability(string ability,Tower tower){} - public virtual void Create(){} + public virtual void Create(Tower tower){} public virtual void Select(Tower tower){} public virtual void Sell(Tower tower){} + public virtual void RoundStart(){} + public virtual void RoundEnd(){} public virtual int MaxSelectQuote=>0; public virtual int MaxUpgradeQuote=>0; public virtual DictionarySoundNames=>null; public virtual DictionaryBehaviours=>new(); public virtual bool AddToShop=>true; public virtual bool Upgradable=>true; + public virtual string UpgradeScreenSound=>null; + public enum Faction{ + Protoss, + Terran, + Zerg, + NotSet + } + public virtual Faction TowerFaction=>Faction.NotSet; } [RegisterTypeInIl2Cpp] public class SC2Sound:MonoBehaviour{ diff --git a/TowerPatches.cs b/TowerPatches.cs new file mode 100644 index 0000000..9d78d00 --- /dev/null +++ b/TowerPatches.cs @@ -0,0 +1,142 @@ +using Il2CppAssets.Scripts.Simulation; + +namespace SC2ExpansionLoader{ + public class TowerPatches{ + [HarmonyPatch(typeof(Weapon),"SpawnDart")] + public class WeaponSpawnDart_Patch{ + [HarmonyPostfix] + public static void Postfix(Weapon __instance){ + string towerName=__instance.attack.tower.towerModel.baseId; + if(TowerTypes.ContainsKey(towerName)){ + try{ + TowerTypes[towerName].Attack(__instance); + }catch(Exception error){ + Log("Failed to run Attack for "+towerName); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + [HarmonyPatch(typeof(Simulation),"RoundStart")] + public class SimulationRoundStart_Patch{ + [HarmonyPostfix] + public static void Postfix(){ + Log(1); + foreach(SC2Tower tower in TowerTypes.Values){ + try{ + tower.RoundStart(); + }catch(Exception error){ + Log("Failed to run RoundStart for "+tower.Name); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + [HarmonyPatch(typeof(Simulation),"RoundEnd")] + public class SimulationRoundEnd_Patch{ + [HarmonyPostfix] + public static void Postfix(){ + Log(1); + foreach(SC2Tower tower in TowerTypes.Values){ + try{ + tower.RoundEnd(); + }catch(Exception error){ + Log("Failed to run RoundEnd for "+tower.Name); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + [HarmonyPatch(typeof(Tower),"OnPlace")] + public class TowerOnPlace_Patch{ + [HarmonyPostfix] + public static void Postfix(Tower __instance){ + string towerName=__instance.towerModel.baseId; + if(TowerTypes.ContainsKey(towerName)){ + try{ + TowerTypes[towerName].Create(__instance); + }catch(Exception error){ + Log("Failed to run Create for "+towerName); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + [HarmonyPatch(typeof(Ability),"Activate")] + public class AbilityActivate_Patch{ + [HarmonyPostfix] + public static void Postfix(Ability __instance){ + string towerName=__instance.tower.towerModel.baseId; + if(TowerTypes.ContainsKey(towerName)){ + try{ + TowerTypes[towerName].Ability(__instance.abilityModel.name,__instance.tower); + }catch(Exception error){ + Log("Failed to run Ability for "+towerName); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + [HarmonyPatch(typeof(TowerManager),"UpgradeTower")] + public class TowerManagerUpgradeTower_Patch{ + [HarmonyPostfix] + public static void Postfix(Tower tower,TowerModel def){ + string towerName=tower.towerModel.baseId; + if(TowerTypes.ContainsKey(towerName)){ + try{ + TowerTypes[towerName].Upgrade(def.tier,tower); + }catch(Exception error){ + Log("Failed to run Upgrade for "+towerName); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + [HarmonyPatch(typeof(UnityToSimulation),"UpgradeTower_Impl")] + public class UnityToSimulationUpgradeTowerImpl_Patch{ + [HarmonyPrefix] + public static bool Prefix(ref UnityToSimulation __instance,Il2CppAssets.Scripts.ObjectId id,int pathIndex,int inputId){ + TowerManager towerManager=__instance.simulation.towerManager; + Tower tower=towerManager.GetTowerById(id); + TowerModel towerModel=tower.towerModel; + if(TowerTypes.ContainsKey(towerModel.baseId)){ + int cost=gameModel.upgrades.First(a=>a.name==towerModel.upgrades[pathIndex].upgrade).cost; + if(__instance.simulation.GetCash(inputId)>cost){ + towerManager.UpgradeTower(inputId,tower,gameModel.GetTowerFromId(towerModel.upgrades[pathIndex].tower),pathIndex,cost); + } + return false; + } + return true; + } + } + [HarmonyPatch(typeof(TowerSelectionMenu),"SelectTower")] + public class TowerSelectionMenuSelectTower_Patch{ + [HarmonyPostfix] + public static void Postfix(TowerSelectionMenu __instance){ + string towerName=__instance.selectedTower.tower.towerModel.baseId; + if(TowerTypes.ContainsKey(towerName)){ + try{ + TowerTypes[towerName].Select(__instance.selectedTower.tower); + }catch(Exception error){ + Log("Failed to run Select for "+towerName); + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + } + } + } + } +} \ No newline at end of file diff --git a/UpgradeMenu.cs b/UpgradeMenu.cs new file mode 100644 index 0000000..4d9c762 --- /dev/null +++ b/UpgradeMenu.cs @@ -0,0 +1,199 @@ +namespace SC2ExpansionLoader{ + public class UpgradeMenu{ + public static AssetBundle LoadedUIBundle=null; + [HarmonyPatch(typeof(InGame),"ShowUpgradeTree")] + [HarmonyPatch(new Type[]{typeof(TowerModel),typeof(bool)})] + public class InGameShowUpgradeTree_Patch{ + [HarmonyPrefix] + public static bool Prefix(TowerModel towerModel){ + try{ + string towerId=towerModel.baseId; + if(TowerTypes.ContainsKey(towerId)){ + SC2Tower tower=TowerTypes[towerId]; + string faction=tower.TowerFaction.ToString(); + LoadedUIBundle=AssetBundle.LoadFromFile(BundleDir+faction.ToLower()+"upgrademenu"); + string scene="Assets/Scenes/"+tower.TowerFaction.ToString()+"UiScene.unity"; + SceneManager.LoadScene(scene,LoadSceneMode.Additive); + //must be done in a coroutine as scenes need a frame to get set up; + MelonCoroutines.Start(Setup(tower,tower.TowerFaction.ToString()+"UiScene")); + return false; + } + }catch(Exception error){ + string message=error.Message; + message+="@\n"+error.StackTrace; + Log(message,"error"); + } + return true; + } + public static System.Collections.IEnumerator Setup(SC2Tower tower,string scene){ + yield return null; + SceneManager.GetSceneByName(scene).GetRootGameObjects().First(a=>a.name==tower.TowerFaction.ToString()+"Menu"). + AddComponent().CurrentTower=tower; + } + } + } + [RegisterTypeInIl2Cpp] + public class UpgradeMenuButton:MonoBehaviour{ + public UpgradeMenuButton(IntPtr ptr):base(ptr){} + public string PortraitAsset; + public string Description; + public int Cost; + public UpgradeMenuCom Menu; + void Start(){ + GetComponent