diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9ec4171..bef188f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -101,9 +101,9 @@ jobs: - name: Setup .NET - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v4 with: - dotnet-version: 6.0.x # net6 can still build older as well + dotnet-version: 8.0.x - name: Build diff --git a/Bytes/Alchemists.bytes b/Bytes/Alchemists.bytes index 0709484..f115ecc 100644 Binary files a/Bytes/Alchemists.bytes and b/Bytes/Alchemists.bytes differ diff --git a/Bytes/BananaFarms.bytes b/Bytes/BananaFarms.bytes index b254eb5..45d7ca8 100644 Binary files a/Bytes/BananaFarms.bytes and b/Bytes/BananaFarms.bytes differ diff --git a/Bytes/BeastHandlers.bytes b/Bytes/BeastHandlers.bytes index b65820a..c530f7a 100644 Binary files a/Bytes/BeastHandlers.bytes and b/Bytes/BeastHandlers.bytes differ diff --git a/Bytes/BombShooters.bytes b/Bytes/BombShooters.bytes index cef7bc1..540086b 100644 Binary files a/Bytes/BombShooters.bytes and b/Bytes/BombShooters.bytes differ diff --git a/Bytes/BoomerangMonkeys.bytes b/Bytes/BoomerangMonkeys.bytes index c3f5cce..f79d247 100644 Binary files a/Bytes/BoomerangMonkeys.bytes and b/Bytes/BoomerangMonkeys.bytes differ diff --git a/Bytes/DartMonkeys.bytes b/Bytes/DartMonkeys.bytes index 47afeeb..943a1f1 100644 Binary files a/Bytes/DartMonkeys.bytes and b/Bytes/DartMonkeys.bytes differ diff --git a/Bytes/DartlingGunners.bytes b/Bytes/DartlingGunners.bytes index 5737220..982b517 100644 Binary files a/Bytes/DartlingGunners.bytes and b/Bytes/DartlingGunners.bytes differ diff --git a/Bytes/Druids.bytes b/Bytes/Druids.bytes index 9aa1459..ebe4a5a 100644 Binary files a/Bytes/Druids.bytes and b/Bytes/Druids.bytes differ diff --git a/Bytes/EngineerMonkeys.bytes b/Bytes/EngineerMonkeys.bytes index adb560d..e5a4691 100644 Binary files a/Bytes/EngineerMonkeys.bytes and b/Bytes/EngineerMonkeys.bytes differ diff --git a/Bytes/GlueGunners.bytes b/Bytes/GlueGunners.bytes index 1af05db..c1934a9 100644 Binary files a/Bytes/GlueGunners.bytes and b/Bytes/GlueGunners.bytes differ diff --git a/Bytes/HeliPilots.bytes b/Bytes/HeliPilots.bytes index cf7aa38..146f6f4 100644 Binary files a/Bytes/HeliPilots.bytes and b/Bytes/HeliPilots.bytes differ diff --git a/Bytes/IceMonkeys.bytes b/Bytes/IceMonkeys.bytes index 416716c..3ad782f 100644 Binary files a/Bytes/IceMonkeys.bytes and b/Bytes/IceMonkeys.bytes differ diff --git a/Bytes/Mermonkeys.bytes b/Bytes/Mermonkeys.bytes new file mode 100644 index 0000000..b1aa28e Binary files /dev/null and b/Bytes/Mermonkeys.bytes differ diff --git a/Bytes/MonkeyAces.bytes b/Bytes/MonkeyAces.bytes index 3569f5f..a304a40 100644 Binary files a/Bytes/MonkeyAces.bytes and b/Bytes/MonkeyAces.bytes differ diff --git a/Bytes/MonkeyBuccaneers.bytes b/Bytes/MonkeyBuccaneers.bytes index 5b397db..924de9d 100644 Binary files a/Bytes/MonkeyBuccaneers.bytes and b/Bytes/MonkeyBuccaneers.bytes differ diff --git a/Bytes/MonkeySubs.bytes b/Bytes/MonkeySubs.bytes index 13973d4..0baae65 100644 Binary files a/Bytes/MonkeySubs.bytes and b/Bytes/MonkeySubs.bytes differ diff --git a/Bytes/MonkeyVillages.bytes b/Bytes/MonkeyVillages.bytes index 77c1570..042446f 100644 Binary files a/Bytes/MonkeyVillages.bytes and b/Bytes/MonkeyVillages.bytes differ diff --git a/Bytes/MortarMonkeys.bytes b/Bytes/MortarMonkeys.bytes index 01a0ab3..ee78a04 100644 Binary files a/Bytes/MortarMonkeys.bytes and b/Bytes/MortarMonkeys.bytes differ diff --git a/Bytes/NinjaMonkeys.bytes b/Bytes/NinjaMonkeys.bytes index 0e6f8d0..b36a93b 100644 Binary files a/Bytes/NinjaMonkeys.bytes and b/Bytes/NinjaMonkeys.bytes differ diff --git a/Bytes/SniperMonkeys.bytes b/Bytes/SniperMonkeys.bytes index 88798e7..7de8e41 100644 Binary files a/Bytes/SniperMonkeys.bytes and b/Bytes/SniperMonkeys.bytes differ diff --git a/Bytes/SpikeFactorys.bytes b/Bytes/SpikeFactorys.bytes index a57c8d4..32a8573 100644 Binary files a/Bytes/SpikeFactorys.bytes and b/Bytes/SpikeFactorys.bytes differ diff --git a/Bytes/SuperMonkeys.bytes b/Bytes/SuperMonkeys.bytes index b7af3b3..13c67ba 100644 Binary files a/Bytes/SuperMonkeys.bytes and b/Bytes/SuperMonkeys.bytes differ diff --git a/Bytes/TackShooters.bytes b/Bytes/TackShooters.bytes index 15ad26c..c3e4ea6 100644 Binary files a/Bytes/TackShooters.bytes and b/Bytes/TackShooters.bytes differ diff --git a/Bytes/WizardMonkeys.bytes b/Bytes/WizardMonkeys.bytes index f29c564..c22196e 100644 Binary files a/Bytes/WizardMonkeys.bytes and b/Bytes/WizardMonkeys.bytes differ diff --git a/LATEST.md b/LATEST.md index 1485896..51d0509 100644 --- a/LATEST.md +++ b/LATEST.md @@ -1,3 +1,4 @@ ## See the [BTD Mod Helper Install Guide](https://gurrenm3.github.io/BTD-Mod-Helper/wiki/Install-Guide) if this is your first time downloading, and the [Common Issues](https://github.com/doombubbles/ultimate-crosspathing/blob/1.4.5/HELP.md#common-issues) page for help -- Updated for BTD6 v42.1 \ No newline at end of file +- Updated for BTD6 v44.0 + - Includes full crosspathing for the new Mermonkey! \ No newline at end of file diff --git a/LoadInfo.cs b/LoadInfo.cs index 5679cc3..b3a5c63 100644 --- a/LoadInfo.cs +++ b/LoadInfo.cs @@ -273,4 +273,13 @@ public class WizardMonkey : LoadInfo public override ModSettingBool Enabled => TowerSettings.WizardMonkeyEnabled; } + + public class Mermonkey : LoadInfo + { +#if RELEASE + public override ModByteLoader Loader => GetInstance(); +#endif + + public override ModSettingBool Enabled => TowerSettings.MermonkeyEnabled; + } } \ No newline at end of file diff --git a/Loaders/AlchemistLoader.cs b/Loaders/AlchemistLoader.cs index 8cd7dfb..40ceef2 100644 --- a/Loaders/AlchemistLoader.cs +++ b/Loaders/AlchemistLoader.cs @@ -372,6 +372,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } diff --git a/Loaders/BananaFarmLoader.cs b/Loaders/BananaFarmLoader.cs index 7b8e4e0..8756e16 100644 --- a/Loaders/BananaFarmLoader.cs +++ b/Loaders/BananaFarmLoader.cs @@ -339,6 +339,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } diff --git a/Loaders/BeastHandlerLoader.cs b/Loaders/BeastHandlerLoader.cs index 615c434..c57a96d 100644 --- a/Loaders/BeastHandlerLoader.cs +++ b/Loaders/BeastHandlerLoader.cs @@ -448,6 +448,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -831,6 +833,7 @@ private void Set_v_GyrfalconPatternModel_Fields(int start, int count) { v.moabPiercePenalty = br.ReadInt32(); v.bfbPiercePenalty = br.ReadInt32(); v.zomgPiercePenalty = br.ReadInt32(); + v.ddtPiercePenalty = br.ReadInt32(); v.continuePickingUpBloons = br.ReadBoolean(); v.moabSpeedScale = br.ReadSingle(); v.enableAdjacentHover = br.ReadBoolean(); @@ -891,6 +894,10 @@ private void Set_v_AirUnitModel_Fields(int start, int count) { v.behaviors = (Il2CppReferenceArray) m[br.ReadInt32()]; v.display = ModContent.CreatePrefabReference(br.ReadString()); v.displayScale = br.ReadSingle(); + v.isAirUnitSelectable = br.ReadBoolean(); + v.selectableRadius = br.ReadSingle(); + v.blocksPlacement = br.ReadBoolean(); + v.blockingRadius = br.ReadSingle(); } } @@ -1242,6 +1249,8 @@ private void Set_v_CreateProjectileOnIntervalModel_Fields(int start, int count) v.targetType.id = br.ReadString(); v.targetType.actionOnCreate = br.ReadBoolean(); v.isBuffedByRate = br.ReadBoolean(); + v.useRawWeaponRate = br.ReadBoolean(); + v.onlyEmitOnce = br.ReadBoolean(); } } diff --git a/Loaders/BombShooterLoader.cs b/Loaders/BombShooterLoader.cs index 3bf261d..b049190 100644 --- a/Loaders/BombShooterLoader.cs +++ b/Loaders/BombShooterLoader.cs @@ -313,6 +313,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } diff --git a/Loaders/BoomerangMonkeyLoader.cs b/Loaders/BoomerangMonkeyLoader.cs index 543c18a..bad9247 100644 --- a/Loaders/BoomerangMonkeyLoader.cs +++ b/Loaders/BoomerangMonkeyLoader.cs @@ -337,6 +337,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -1014,6 +1016,7 @@ private void Set_v_RetargetOnContactModel_Fields(int start, int count) { for (var i=0; i(); @@ -1013,6 +1008,14 @@ private void Set_v_CashPerBananaFarmInRangeModel_Fields(int start, int count) { } } + private void Set_v_BonusLivesOnAbilityModel_Fields(int start, int count) { + Set_v_AbilityBehaviorModel_Fields(start, count); + for (var i=0; i(); Create_Records(); Create_Records(); - Create_Records(); Create_Records(); Create_Records(); Create_Records(); + Create_Records(); Create_Records(); Create_Records(); Create_Records(); Create_Records(); Create_Records(); - Create_Records(); Create_Records(); Create_Records(); Create_Records(); @@ -1483,16 +1480,15 @@ protected override Il2CppAssets.Scripts.Models.Towers.TowerModel Load(byte[] byt Set_v_BuffIndicatorModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_DruidVengeanceEffectModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_DamageModifierWrathModel_Fields(br.ReadInt32(), br.ReadInt32()); - Set_v_BonusLivesPerRoundModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_AbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CreateSoundOnAbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CashPerBananaFarmInRangeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_BonusLivesOnAbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_ActivateAbilitiesOnAbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_SpiritOfTheForestModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_DamageOverTimeZoneModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_DamageOverTimeCustomModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_PerRoundCashBonusTowerModel_Fields(br.ReadInt32(), br.ReadInt32()); - Set_v_BonusLivesOnAbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CreateLightningEffectModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_LightningModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CreateSoundOnProjectileCreatedModel_Fields(br.ReadInt32(), br.ReadInt32()); diff --git a/Loaders/EngineerMonkeyLoader.cs b/Loaders/EngineerMonkeyLoader.cs index 50af5eb..9d3dfec 100644 --- a/Loaders/EngineerMonkeyLoader.cs +++ b/Loaders/EngineerMonkeyLoader.cs @@ -325,6 +325,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -1288,6 +1290,7 @@ private void Set_v_FreezeModel_Fields(int start, int count) { v.canFreezeMoabs = br.ReadBoolean(); v.cascadeMutators = br.ReadBoolean(); v.growBlockModel = (Il2CppAssets.Scripts.Models.Bloons.Behaviors.GrowBlockModel) m[br.ReadInt32()]; + v.applyAfterDamage = br.ReadBoolean(); lifespanField.SetValue(v,br.ReadSingle().ToIl2Cpp()); } } diff --git a/Loaders/GlueGunnerLoader.cs b/Loaders/GlueGunnerLoader.cs index ad6007c..71c822b 100644 --- a/Loaders/GlueGunnerLoader.cs +++ b/Loaders/GlueGunnerLoader.cs @@ -313,6 +313,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } diff --git a/Loaders/HeliPilotLoader.cs b/Loaders/HeliPilotLoader.cs index b7266f8..07e5f9f 100644 --- a/Loaders/HeliPilotLoader.cs +++ b/Loaders/HeliPilotLoader.cs @@ -332,6 +332,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -749,6 +751,10 @@ private void Set_v_AirUnitModel_Fields(int start, int count) { v.behaviors = (Il2CppReferenceArray) m[br.ReadInt32()]; v.display = ModContent.CreatePrefabReference(br.ReadString()); v.displayScale = br.ReadSingle(); + v.isAirUnitSelectable = br.ReadBoolean(); + v.selectableRadius = br.ReadSingle(); + v.blocksPlacement = br.ReadBoolean(); + v.blockingRadius = br.ReadSingle(); } } diff --git a/Loaders/IceMonkeyLoader.cs b/Loaders/IceMonkeyLoader.cs index b14d7b9..797ccf8 100644 --- a/Loaders/IceMonkeyLoader.cs +++ b/Loaders/IceMonkeyLoader.cs @@ -321,6 +321,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -546,6 +548,7 @@ private void Set_v_FreezeModel_Fields(int start, int count) { v.canFreezeMoabs = br.ReadBoolean(); v.cascadeMutators = br.ReadBoolean(); v.growBlockModel = (Il2CppAssets.Scripts.Models.Bloons.Behaviors.GrowBlockModel) m[br.ReadInt32()]; + v.applyAfterDamage = br.ReadBoolean(); lifespanField.SetValue(v,br.ReadSingle().ToIl2Cpp()); } } diff --git a/Loaders/MermonkeyLoader.cs b/Loaders/MermonkeyLoader.cs new file mode 100644 index 0000000..a82ffd7 --- /dev/null +++ b/Loaders/MermonkeyLoader.cs @@ -0,0 +1,1720 @@ +// Generated by FlatFileCodeGen + ModByteLoader +using Il2CppInterop.Runtime; +using Il2CppInterop.Runtime.InteropTypes; +using Il2CppInterop.Runtime.InteropTypes.Arrays; +using BTD_Mod_Helper.Extensions; +using BTD_Mod_Helper.Api; +using Il2Cpp; + +namespace UltimateCrosspathing.Loaders; +using Il2CppSystem.Collections.Generic; +using Il2CppSystem.Runtime.Serialization; +using Il2CppSystem.Reflection; +using Il2CppSystem; +using Il2CppAssets.Scripts.Simulation.SMath; +using System.IO; + +public class MermonkeyLoader : ModByteLoader { + + BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static; + BinaryReader br = null; + + // NOTE: was a collection per type but it prevented inheriance e.g list of Products would required class type id + protected override string BytesFileName => "Mermonkeys.bytes"; + int mIndex = 1; // first element is null + #region Read array + + private void LinkArray() where T : Il2CppObjectBase { + var setCount = br.ReadInt32(); + for (var i = 0; i < setCount; i++) { + var arrIndex = br.ReadInt32(); + var arr = (Il2CppReferenceArray)m[arrIndex]; + for (var j = 0; j < arr.Length; j++) { + arr[j] = (T) m[br.ReadInt32()]; + } + } + } + private void LinkList() where T : Il2CppObjectBase { + var setCount = br.ReadInt32(); + for (var i = 0; i < setCount; i++) { + var arrIndex = br.ReadInt32(); + var arr = (List)m[arrIndex]; + for (var j = 0; j < arr.Capacity; j++) { + arr.Add( (T) m[br.ReadInt32()] ); + } + } + } + private void LinkDictionary() where T : Il2CppObjectBase { + var setCount = br.ReadInt32(); + for (var i = 0; i < setCount; i++) { + var arrIndex = br.ReadInt32(); + var arr = (Dictionary)m[arrIndex]; + var arrCount = br.ReadInt32(); + for (var j = 0; j < arrCount; j++) { + var key = br.ReadString(); + var valueIndex = br.ReadInt32(); + arr[key] = (T) m[valueIndex]; + } + } + } + private void LinkModelDictionary() where T : Il2CppAssets.Scripts.Models.Model { + var setCount = br.ReadInt32(); + for (var i = 0; i < setCount; i++) { + var arrIndex = br.ReadInt32(); + var arr = (Dictionary)m[arrIndex]; + var arrCount = br.ReadInt32(); + for (var j = 0; j < arrCount; j++) { + var valueIndex = br.ReadInt32(); + var obj = (T)m[valueIndex]; + arr[obj.name] = obj; + } + } + } + private void Read_a_Int32_Array() { + var arrSetCount = br.ReadInt32(); + var count = arrSetCount; + for (var i = 0; i < count; i++) { + var arrCount = br.ReadInt32(); + var arr = new Il2CppStructArray(arrCount); + for (var j = 0; j < arr.Length; j++) { + arr[j] = br.ReadInt32(); + } + m[mIndex++] = arr; + } + } + private void Read_a_String_Array() { + var arrSetCount = br.ReadInt32(); + var count = arrSetCount; + for (var i = 0; i < count; i++) { + var arrCount = br.ReadInt32(); + var arr = new Il2CppStringArray(arrCount); + for (var j = 0; j < arr.Length; j++) { + arr[j] = br.ReadBoolean() ? null : br.ReadString(); + } + m[mIndex++] = arr; + } + } + private void Read_a_TargetType_Array() { + var arrSetCount = br.ReadInt32(); + var count = arrSetCount; + for (var i = 0; i < count; i++) { + var arrCount = br.ReadInt32(); + var arr = new Il2CppReferenceArray(arrCount); + for (var j = 0; j < arr.Length; j++) { + arr[j] = new Il2CppAssets.Scripts.Models.Towers.TargetType {id = br.ReadString(), isActionable = br.ReadBoolean()}; + } + m[mIndex++] = arr; + } + } + private void Read_a_TowerSet_Array() { + var arrSetCount = br.ReadInt32(); + var count = arrSetCount; + for (var i = 0; i < count; i++) { + var arrCount = br.ReadInt32(); + var arr = new Il2CppAssets.Scripts.Models.TowerSets.TowerSet[arrCount]; + for (var j = 0; j < arr.Length; j++) { + arr[j] = (Il2CppAssets.Scripts.Models.TowerSets.TowerSet)br.ReadInt32(); + } + m[mIndex++] = arr; + } + } + private void Read_a_AreaType_Array() { + var arrSetCount = br.ReadInt32(); + var count = arrSetCount; + for (var i = 0; i < count; i++) { + var arrCount = br.ReadInt32(); + var arr = new Il2CppAssets.Scripts.Models.Map.AreaType[arrCount]; + for (var j = 0; j < arr.Length; j++) { + arr[j] = (Il2CppAssets.Scripts.Models.Map.AreaType)br.ReadInt32(); + } + m[mIndex++] = arr; + } + } + #endregion + + #region Read object records + + private void CreateArraySet() where T : Il2CppObjectBase { + var arrCount = br.ReadInt32(); + for(var i = 0; i < arrCount; i++) { + m[mIndex++] = new Il2CppReferenceArray(br.ReadInt32());; + } + } + + private void CreateListSet() where T : Il2CppObjectBase { + var arrCount = br.ReadInt32(); + for (var i = 0; i < arrCount; i++) { + m[mIndex++] = new List(br.ReadInt32()); // set capactity + } + } + + private void CreateDictionarySet() { + var arrCount = br.ReadInt32(); + for (var i = 0; i < arrCount; i++) { + m[mIndex++] = new Dictionary(br.ReadInt32());// set capactity + } + } + + private void Create_Records() where T : Il2CppObjectBase { + var count = br.ReadInt32(); + var t = Il2CppType.Of(); + for (var i = 0; i < count; i++) { + m[mIndex++] = FormatterServices.GetUninitializedObject(t).Cast(); + } + } + #endregion + + #region Link object records + + private void Set_v_Model_Fields(int start, int count) { + var t = Il2CppType.Of(); + var _nameField = t.GetField("_name", bindFlags); + var childDependantsField = t.GetField("childDependants", bindFlags); + for (var i=0; i) m[br.ReadInt32()]); + } + } + + private void Set_v_TowerModel_Fields(int start, int count) { + Set_v_Model_Fields(start, count); + for (var i=0; i) m[br.ReadInt32()]; + v.towerSet = (Il2CppAssets.Scripts.Models.TowerSets.TowerSet) (br.ReadInt32()); + v.icon = ModContent.CreateSpriteReference(br.ReadString()); + v.portrait = ModContent.CreateSpriteReference(br.ReadString()); + v.instaIcon = ModContent.CreateSpriteReference(br.ReadString()); + v.areaTypes = (Il2CppAssets.Scripts.Models.Map.AreaType[]) m[br.ReadInt32()]; + v.mods = (Il2CppReferenceArray) m[br.ReadInt32()]; + v.ignoreTowerForSelection = br.ReadBoolean(); + v.behaviors = (Il2CppReferenceArray) m[br.ReadInt32()]; + v.footprint = (Il2CppAssets.Scripts.Models.Towers.Behaviors.FootprintModel) m[br.ReadInt32()]; + v.dontDisplayUpgrades = br.ReadBoolean(); + v.emoteSpriteSmall = ModContent.CreateSpriteReference(br.ReadString()); + v.emoteSpriteLarge = ModContent.CreateSpriteReference(br.ReadString()); + v.doesntRotate = br.ReadBoolean(); + v.upgrades = (Il2CppReferenceArray) m[br.ReadInt32()]; + v.appliedUpgrades = (Il2CppStringArray) m[br.ReadInt32()]; + v.targetTypes = (Il2CppReferenceArray) m[br.ReadInt32()]; + v.paragonUpgrade = (Il2CppAssets.Scripts.Models.Towers.Upgrades.UpgradePathModel) m[br.ReadInt32()]; + v.isSubTower = br.ReadBoolean(); + v.isBakable = br.ReadBoolean(); + v.powerName = br.ReadBoolean() ? null : br.ReadString(); + v.showPowerTowerBuffs = br.ReadBoolean(); + v.animationSpeed = br.ReadSingle(); + v.towerSelectionMenuThemeId = br.ReadBoolean() ? null : br.ReadString(); + v.secondarySelectionMenu = ModContent.CreatePrefabReference(br.ReadString()); + v.ignoreCoopAreas = br.ReadBoolean(); + v.canAlwaysBeSold = br.ReadBoolean(); + v.blockSelling = br.ReadBoolean(); + v.isParagon = br.ReadBoolean(); + v.ignoreMaxSellPercent = br.ReadBoolean(); + v.isStunned = br.ReadBoolean(); + v.geraldoItemName = br.ReadBoolean() ? null : br.ReadString(); + v.sellbackModifierAdd = br.ReadSingle(); + v.skinName = br.ReadBoolean() ? null : br.ReadString(); + v.dontAddMutatorsFromParent = br.ReadBoolean(); + v.displayScale = br.ReadSingle(); + v.showBuffs = br.ReadBoolean(); + v.destroyTowerOnRedistribution = br.ReadBoolean(); + } + } + + private void Set_v_ApplyModModel_Fields(int start, int count) { + Set_v_Model_Fields(start, count); + for (var i=0; i) m[br.ReadInt32()]; + v.behaviors = (Il2CppReferenceArray) m[br.ReadInt32()]; + v.range = br.ReadSingle(); + v.targetProvider = (Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.TargetSupplierModel) m[br.ReadInt32()]; + v.offsetX = br.ReadSingle(); + v.offsetY = br.ReadSingle(); + v.offsetZ = br.ReadSingle(); + v.attackThroughWalls = br.ReadBoolean(); + v.fireWithoutTarget = br.ReadBoolean(); + v.framesBeforeRetarget = br.ReadInt32(); + v.addsToSharedGrid = br.ReadBoolean(); + v.sharedGridRange = br.ReadSingle(); + } + } + + private void Set_v_WeaponModel_Fields(int start, int count) { + Set_v_Model_Fields(start, count); + var t = Il2CppType.Of(); + var animationOffsetField = t.GetField("animationOffset", bindFlags); + var rateField = t.GetField("rate", bindFlags); + var customStartCooldownField = t.GetField("customStartCooldown", bindFlags); + for (var i=0; i) m[br.ReadInt32()]; + rateField.SetValue(v,br.ReadSingle().ToIl2Cpp()); + v.useAttackPosition = br.ReadBoolean(); + v.startInCooldown = br.ReadBoolean(); + customStartCooldownField.SetValue(v,br.ReadSingle().ToIl2Cpp()); + v.animateOnMainAttack = br.ReadBoolean(); + v.isStunned = br.ReadBoolean(); + } + } + + private void Set_v_EmissionModel_Fields(int start, int count) { + Set_v_Model_Fields(start, count); + for (var i=0; i) m[br.ReadInt32()]; + } + } + + private void Set_v_SingleEmissionModel_Fields(int start, int count) { + Set_v_EmissionModel_Fields(start, count); + for (var i=0; i(); + var checkCollisionIntervalField = t.GetField("checkCollisionInterval", bindFlags); + for (var i=0; i) m[br.ReadInt32()]; + v.behaviors = (Il2CppReferenceArray) m[br.ReadInt32()]; + v.collisionPasses = (Il2CppStructArray) m[br.ReadInt32()]; + v.canCollideWithBloons = br.ReadBoolean(); + v.radius = br.ReadSingle(); + v.vsBlockerRadius = br.ReadSingle(); + v.hasDamageModifiers = br.ReadBoolean(); + v.dontUseCollisionChecker = br.ReadBoolean(); + checkCollisionIntervalField.SetValue(v,br.ReadSingle().ToIl2Cpp()); + v.ignoreNonTargetable = br.ReadBoolean(); + v.ignorePierceExhaustion = br.ReadBoolean(); + v.saveId = br.ReadBoolean() ? null : br.ReadString(); + } + } + + private void Set_v_FilterModel_Fields(int start, int count) { + Set_v_Model_Fields(start, count); + for (var i=0; i(); + var speedField = t.GetField("speed", bindFlags); + var lifespanField = t.GetField("lifespan", bindFlags); + for (var i=0; i) m[br.ReadInt32()]; + } + } + + private void Set_v_DamageModifierModel_Fields(int start, int count) { + Set_v_ProjectileBehaviorModel_Fields(start, count); + for (var i=0; i) m[br.ReadInt32()]; + v.delayedReveal = br.ReadSingle(); + v.category = (Il2CppAssets.Scripts.Models.GenericBehaviors.DisplayCategory) (br.ReadUInt16()); + v.isAnimationPaused = br.ReadBoolean(); + } + } + + private void Set_v_ArcEmissionModel_Fields(int start, int count) { + Set_v_EmissionModel_Fields(start, count); + var t = Il2CppType.Of(); + var CountField = t.GetField("Count", bindFlags); + for (var i=0; i(); + var turnRateField = t.GetField("turnRate", bindFlags); + for (var i=0; i(); + var lifespanField = t.GetField("lifespan", bindFlags); + for (var i=0; i(); + var lifespanField = t.GetField("lifespan", bindFlags); + for (var i=0; i) m[br.ReadInt32()]; + } + } + + private void Set_v_TargetSupplierModel_Fields(int start, int count) { + Set_v_AttackBehaviorModel_Fields(start, count); + for (var i=0; i) m[br.ReadInt32()]; + } + } + + private void Set_v_TowerBehaviorBuffModel_Fields(int start, int count) { + Set_v_TowerBehaviorModel_Fields(start, count); + for (var i=0; i(); + var intervalField = t.GetField("interval", bindFlags); + for (var i=0; i(); + var intervalField = t.GetField("interval", bindFlags); + for (var i=0; i(); + var towerField = t.GetField("tower", bindFlags); + var upgradeField = t.GetField("upgrade", bindFlags); + for (var i=0; i) m[br.ReadInt32()]; + v.isGlobal = br.ReadBoolean(); + v.isCustomRadius = br.ReadBoolean(); + v.customRadius = br.ReadSingle(); + v.appliesToOwningTower = br.ReadBoolean(); + v.showBuffIcon = br.ReadBoolean(); + v.buffLocsName = br.ReadBoolean() ? null : br.ReadString(); + v.buffIconName = br.ReadBoolean() ? null : br.ReadString(); + v.maxStackSize = br.ReadInt32(); + v.onlyShowBuffIfMutated = br.ReadBoolean(); + v.onlyAffectParagon = br.ReadBoolean(); + } + } + + private void Set_v_RangeSupportModel_Fields(int start, int count) { + Set_v_SupportModel_Fields(start, count); + for (var i=0; i(); + var cooldownSpeedScaleField = t.GetField("cooldownSpeedScale", bindFlags); + var animationOffsetField = t.GetField("animationOffset", bindFlags); + var cooldownField = t.GetField("cooldown", bindFlags); + for (var i=0; i) m[br.ReadInt32()]; + v.activateOnPreLeak = br.ReadBoolean(); + v.activateOnLeak = br.ReadBoolean(); + v.addedViaUpgrade = br.ReadBoolean() ? null : br.ReadString(); + v.livesCost = br.ReadInt32(); + v.maxActivationsPerRound = br.ReadInt32(); + v.animation = br.ReadInt32(); + v.enabled = br.ReadBoolean(); + v.canActivateBetweenRounds = br.ReadBoolean(); + v.resetCooldownOnTierUpgrade = br.ReadBoolean(); + v.activateOnLivesLost = br.ReadBoolean(); + v.sharedCooldown = br.ReadBoolean(); + v.dontShowStacked = br.ReadBoolean(); + v.animateOnMainAttackDisplay = br.ReadBoolean(); + v.restrictAbilityAfterMaxRoundTimer = br.ReadBoolean(); + cooldownSpeedScaleField.SetValue(v,br.ReadSingle().ToIl2Cpp()); + animationOffsetField.SetValue(v,br.ReadSingle().ToIl2Cpp()); + cooldownField.SetValue(v,br.ReadSingle().ToIl2Cpp()); + } + } + + private void Set_v_AbilityBehaviorModel_Fields(int start, int count) { + Set_v_Model_Fields(start, count); + for (var i=0; i(); + var lifespanField = t.GetField("lifespan", bindFlags); + for (var i=0; i(); + var lifespanField = t.GetField("lifespan", bindFlags); + for (var i=0; i) m[br.ReadInt32()]; + v.processOnActivate = br.ReadBoolean(); + v.cancelIfNoTargets = br.ReadBoolean(); + v.turnOffExisting = br.ReadBoolean(); + v.endOnRoundEnd = br.ReadBoolean(); + v.endOnDefeatScreen = br.ReadBoolean(); + v.isOneShot = br.ReadBoolean(); + lifespanField.SetValue(v,br.ReadSingle().ToIl2Cpp()); + } + } + + private void Set_v_RandomEmissionModel_Fields(int start, int count) { + Set_v_EmissionModel_Fields(start, count); + for (var i=0; i(); + var lifespanField = t.GetField("lifespan", bindFlags); + var multiplierField = t.GetField("multiplier", bindFlags); + for (var i=0; i(); + var ignoreParentRotationTimeField = t.GetField("ignoreParentRotationTime", bindFlags); + for (var i=0; i(); + Read_a_Int32_Array(); + Read_a_AreaType_Array(); + CreateArraySet(); + CreateArraySet(); + CreateArraySet(); + Read_a_String_Array(); + CreateArraySet(); + CreateArraySet(); + CreateArraySet(); + Read_a_TargetType_Array(); + Read_a_TowerSet_Array(); + CreateArraySet(); + CreateArraySet(); + CreateListSet(); + + //## Step 2: create empty objects + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + Create_Records(); + + Set_v_TowerModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ApplyModModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_PlacementAreaTypeRangeBuffModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateSoundOnSellModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_SoundModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateSoundOnUpgradeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_PlayAnimationIndexModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateEffectOnPlaceModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_EffectModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateEffectOnSellModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateEffectOnUpgradeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateSoundOnTowerPlaceModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_AttackModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_WeaponModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_SingleEmissionModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ProjectileModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterInvisibleModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_DamageModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TravelStraitModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ProjectileFilterModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ScaleDamageWithTimeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ScaleProjectileOverTimeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_DamageModifierForBloonStateModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_DisplayModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ArcEmissionModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TrackTargetModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FreezeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_GrowBlockModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateProjectileOnExhaustPierceModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_AgeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_RotateToTargetModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_AttackFilterModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TargetFirstModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TargetLastModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TargetCloseModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TargetStrongModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_SupportStackingRangeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterInBaseTowerIdModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterInTowerTiersModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_BuffIndicatorModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_LinkProjectileRadiusToTowerRangeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterOfftrackModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterOutTagModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TranceBloonModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateEffectOnExhaustedModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_RefreshPierceModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ClearHitBloonsModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_DestroyProjectileIfTowerDestroyedModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CollideExtraPierceReductionModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_LinkDisplayScaleToTowerRangeModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_WeaponRateMinModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_PauseOtherAttacksModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ZeroRotationModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateSoundOnProjectileCreatedModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_EjectEffectModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterWithTagModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterMutatedTargetModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CircleFootprintModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_UpgradePathModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TranceTotemSpawnerModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TowerExpireOnParentDestroyedModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_SavedSubTowerModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_SelectParentOnSelectedModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterWithTagsModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_RemoveBloonModifiersModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreditPopsToParentTowerModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_Il2CppAssets_Scripts_Models_Towers_Behaviors_CreateEffectOnExpireModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateEffectOnParentOnAttackModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_DrawSubtowerRangeCircleModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_RangeSupportModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterInSetModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_AbilityCooldownScaleSupportModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_PierceSupportModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterTowerParentModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_DamageModifierForTagModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_AbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_MutateRemoveAllAttacksOnAbilityActivateModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ActivateAttackModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_RandomEmissionModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ProjectileBlockerCollisionReboundModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_TargetSelectedPointOrDefaultModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateEffectWhileAttackingModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateSoundOnAbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_MapBorderReboundModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_SlowModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateEffectOnAbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_EmissionRotationOffDisplayModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterAllModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_InstantModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateProjectileOnIntervalModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_WeaponRateAnimationSpeedModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_FilterTargetAngleModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_RotateToTargetAttackOffsetModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_PiercePercentageSupportModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_SlowModifierForTagModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateNearbyWaterModel_Fields(br.ReadInt32(), br.ReadInt32()); + + //## Step 4: link object collections e.g Product[]. Note: requires object data e.g dictionary where string = model.name + LinkArray(); + LinkArray(); + LinkArray(); + LinkArray(); + LinkArray(); + LinkArray(); + LinkArray(); + LinkArray(); + LinkArray(); + LinkList(); + + var resIndex = br.ReadInt32(); + UnityEngine.Debug.Assert(br.BaseStream.Position == br.BaseStream.Length); + return (Il2CppAssets.Scripts.Models.Towers.TowerModel) m[resIndex]; + } + } + } +} diff --git a/Loaders/MonkeyAceLoader.cs b/Loaders/MonkeyAceLoader.cs index 92a7235..4e15345 100644 --- a/Loaders/MonkeyAceLoader.cs +++ b/Loaders/MonkeyAceLoader.cs @@ -332,6 +332,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -751,6 +753,10 @@ private void Set_v_AirUnitModel_Fields(int start, int count) { v.behaviors = (Il2CppReferenceArray) m[br.ReadInt32()]; v.display = ModContent.CreatePrefabReference(br.ReadString()); v.displayScale = br.ReadSingle(); + v.isAirUnitSelectable = br.ReadBoolean(); + v.selectableRadius = br.ReadSingle(); + v.blocksPlacement = br.ReadBoolean(); + v.blockingRadius = br.ReadSingle(); } } diff --git a/Loaders/MonkeyBuccaneerLoader.cs b/Loaders/MonkeyBuccaneerLoader.cs index 05a36cd..bf542a7 100644 --- a/Loaders/MonkeyBuccaneerLoader.cs +++ b/Loaders/MonkeyBuccaneerLoader.cs @@ -304,6 +304,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -824,8 +826,19 @@ private void Set_v_UpgradePathModel_Fields(int start, int count) { } } - private void Set_v_CashbackZoneModel_Fields(int start, int count) { + private void Set_v_TowerBehaviorBuffModel_Fields(int start, int count) { Set_v_TowerBehaviorModel_Fields(start, count); + for (var i=0; i(); @@ -1369,6 +1371,10 @@ private void Set_v_AirUnitModel_Fields(int start, int count) { v.behaviors = (Il2CppReferenceArray) m[br.ReadInt32()]; v.display = ModContent.CreatePrefabReference(br.ReadString()); v.displayScale = br.ReadSingle(); + v.isAirUnitSelectable = br.ReadBoolean(); + v.selectableRadius = br.ReadSingle(); + v.blocksPlacement = br.ReadBoolean(); + v.blockingRadius = br.ReadSingle(); } } @@ -1504,13 +1510,13 @@ protected override Il2CppAssets.Scripts.Models.Towers.TowerModel Load(byte[] byt Create_Records(); Create_Records(); Create_Records(); + Create_Records(); Create_Records(); Create_Records(); Create_Records(); Create_Records(); Create_Records(); Create_Records(); - Create_Records(); Create_Records(); Create_Records(); Create_Records(); @@ -1597,13 +1603,13 @@ protected override Il2CppAssets.Scripts.Models.Towers.TowerModel Load(byte[] byt Set_v_CircleFootprintModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_UpgradePathModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CashbackZoneModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_BuffIndicatorModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_RotateToDefaultPositionTowerModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_EmissionRotationOffDisplayModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_DamageModifierForTagModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_EmissionRotationOffDisplayOnEmitModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_EmissionArcRotationOffDisplayDirectionModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_TradeEmpireBuffModel_Fields(br.ReadInt32(), br.ReadInt32()); - Set_v_BuffIndicatorModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_AbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_ActivateAttackModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_GrappleEmissionModel_Fields(br.ReadInt32(), br.ReadInt32()); diff --git a/Loaders/MonkeySubLoader.cs b/Loaders/MonkeySubLoader.cs index 110056e..feaa4d3 100644 --- a/Loaders/MonkeySubLoader.cs +++ b/Loaders/MonkeySubLoader.cs @@ -313,6 +313,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -717,6 +719,8 @@ private void Set_v_InstantModel_Fields(int start, int count) { for (var i=0; i(); CreateArraySet(); CreateArraySet(); + Read_a_String_Array(); CreateArraySet(); CreateArraySet(); CreateArraySet(); - Read_a_String_Array(); Read_a_Single_Array(); CreateArraySet(); CreateArraySet(); diff --git a/Loaders/MortarMonkeyLoader.cs b/Loaders/MortarMonkeyLoader.cs index fce5a7d..b5dd337 100644 --- a/Loaders/MortarMonkeyLoader.cs +++ b/Loaders/MortarMonkeyLoader.cs @@ -313,6 +313,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -467,6 +469,8 @@ private void Set_v_InstantModel_Fields(int start, int count) { for (var i=0; i(); Create_Records(); Create_Records(); + Create_Records(); Set_v_TowerModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_ApplyModModel_Fields(br.ReadInt32(), br.ReadInt32()); @@ -1192,6 +1210,7 @@ protected override Il2CppAssets.Scripts.Models.Towers.TowerModel Load(byte[] byt Set_v_FilterInBaseTowerIdModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_RateSupportModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_SlowMaimMoabModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_CreateProjectileOnContactModel_Fields(br.ReadInt32(), br.ReadInt32()); //## Step 4: link object collections e.g Product[]. Note: requires object data e.g dictionary where string = model.name LinkArray(); diff --git a/Loaders/SpikeFactoryLoader.cs b/Loaders/SpikeFactoryLoader.cs index fafcba7..1b9445f 100644 --- a/Loaders/SpikeFactoryLoader.cs +++ b/Loaders/SpikeFactoryLoader.cs @@ -348,6 +348,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -1010,6 +1012,7 @@ private void Set_v_CreateProjectileOnExhaustPierceModel_Fields(int start, int co v.assetId = ModContent.CreatePrefabReference(br.ReadString()); v.displayLifetime = br.ReadSingle(); v.displayFullscreen = br.ReadBoolean(); + v.useBloonPosition = br.ReadBoolean(); } } diff --git a/Loaders/SuperMonkeyLoader.cs b/Loaders/SuperMonkeyLoader.cs index fe60674..4b1eff4 100644 --- a/Loaders/SuperMonkeyLoader.cs +++ b/Loaders/SuperMonkeyLoader.cs @@ -349,6 +349,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -825,6 +827,7 @@ private void Set_v_RetargetOnContactModel_Fields(int start, int count) { for (var i=0; i) m[br.ReadInt32()]; v.display = ModContent.CreatePrefabReference(br.ReadString()); v.displayScale = br.ReadSingle(); + v.isAirUnitSelectable = br.ReadBoolean(); + v.selectableRadius = br.ReadSingle(); + v.blocksPlacement = br.ReadBoolean(); + v.blockingRadius = br.ReadSingle(); } } @@ -1432,6 +1446,8 @@ private void Set_v_InstantModel_Fields(int start, int count) { for (var i=0; i(); Create_Records(); Create_Records(); + Create_Records(); Create_Records(); Create_Records(); Create_Records(); @@ -1819,6 +1840,7 @@ protected override Il2CppAssets.Scripts.Models.Towers.TowerModel Load(byte[] byt Set_v_CreateSoundOnAbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_RotateToDefaultPositionTowerModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_RectangleFootprintModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_KeepTowerZAtTerrainHeightModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_WindModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CheckTempleCanFireModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_MonkeyTempleModel_Fields(br.ReadInt32(), br.ReadInt32()); diff --git a/Loaders/TackShooterLoader.cs b/Loaders/TackShooterLoader.cs index 3f52eb3..15edc51 100644 --- a/Loaders/TackShooterLoader.cs +++ b/Loaders/TackShooterLoader.cs @@ -313,6 +313,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } diff --git a/Loaders/WizardMonkeyLoader.cs b/Loaders/WizardMonkeyLoader.cs index 65a37de..e0c9584 100644 --- a/Loaders/WizardMonkeyLoader.cs +++ b/Loaders/WizardMonkeyLoader.cs @@ -313,6 +313,8 @@ private void Set_v_CreateSoundOnTowerPlaceModel_Fields(int start, int count) { var v = (Il2CppAssets.Scripts.Models.Towers.Behaviors.CreateSoundOnTowerPlaceModel)m[i+start]; v.sound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.sound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; + v.waterSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound1 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; v.heroSound2 = (Il2CppAssets.Scripts.Models.Audio.SoundModel) m[br.ReadInt32()]; } @@ -567,6 +569,20 @@ private void Set_v_TargetStrongPrioCamoModel_Fields(int start, int count) { } } + private void Set_v_ArcEmissionModel_Fields(int start, int count) { + Set_v_EmissionModel_Fields(start, count); + var t = Il2CppType.Of(); + var CountField = t.GetField("Count", bindFlags); + for (var i=0; i(); + var speedField = t.GetField("speed", bindFlags); + var lifespanField = t.GetField("lifespan", bindFlags); for (var i=0; i(); - var CountField = t.GetField("Count", bindFlags); - for (var i=0; i(); @@ -1215,6 +1223,7 @@ private void Set_v_MutateRemoveAllAttacksOnAbilityActivateModel_Fields(int start for (var i=0; i(); Create_Records(); Create_Records(); + Create_Records(); Create_Records(); Create_Records(); Create_Records(); @@ -1335,7 +1345,6 @@ protected override Il2CppAssets.Scripts.Models.Towers.TowerModel Load(byte[] byt Create_Records(); Create_Records(); Create_Records(); - Create_Records(); Create_Records(); Create_Records(); Create_Records(); @@ -1380,6 +1389,7 @@ protected override Il2CppAssets.Scripts.Models.Towers.TowerModel Load(byte[] byt Set_v_TargetLastPrioCamoModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_TargetClosePrioCamoModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_TargetStrongPrioCamoModel_Fields(br.ReadInt32(), br.ReadInt32()); + Set_v_ArcEmissionModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CreateProjectileOnContactModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_AgeModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CreateEffectOnContactModel_Fields(br.ReadInt32(), br.ReadInt32()); @@ -1413,7 +1423,6 @@ protected override Il2CppAssets.Scripts.Models.Towers.TowerModel Load(byte[] byt Set_v_PrinceOfDarknessEmissionModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_SyncTargetPriorityWithSubTowersModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_OverrideCamoDetectionModel_Fields(br.ReadInt32(), br.ReadInt32()); - Set_v_ArcEmissionModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_AbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_CreateSoundOnAbilityModel_Fields(br.ReadInt32(), br.ReadInt32()); Set_v_AbilityCreateTowerModel_Fields(br.ReadInt32(), br.ReadInt32()); diff --git a/Merging/Algorithm.cs b/Merging/Algorithm.cs index 947c8a6..cf56353 100644 --- a/Merging/Algorithm.cs +++ b/Merging/Algorithm.cs @@ -25,8 +25,8 @@ namespace UltimateCrosspathing.Merging { public static class DeepMerging { - private static readonly HashSet DontMerge = new() - { + private static readonly HashSet DontMerge = + [ "animation", "offsetX", "offsetY", @@ -38,13 +38,13 @@ public static class DeepMerging "rateFrames", "isPowerTower", "isGeraldoItem" - }; + ]; - private static readonly HashSet Multiplicative = new() - { + private static readonly HashSet Multiplicative = + [ "pierce", "range" - }; + ]; private static readonly Dictionary StringOverrides = new() { diff --git a/ModHelperData.cs b/ModHelperData.cs index a95d658..f229c11 100644 --- a/ModHelperData.cs +++ b/ModHelperData.cs @@ -2,8 +2,8 @@ { public static class ModHelperData { - public const string WorksOnVersion = "42.1"; - public const string Version = "1.4.9"; + public const string WorksOnVersion = "44.0"; + public const string Version = "1.5.0"; public const string Name = "Ultimate Crosspathing"; public const string Description = diff --git a/PostMergeFixes/FixMermonkey.cs b/PostMergeFixes/FixMermonkey.cs new file mode 100644 index 0000000..85ff1b8 --- /dev/null +++ b/PostMergeFixes/FixMermonkey.cs @@ -0,0 +1,25 @@ +using BTD_Mod_Helper.Api.Enums; +using BTD_Mod_Helper.Extensions; +using Il2CppAssets.Scripts.Models.Towers; +using Il2CppAssets.Scripts.Models.Towers.Behaviors.Abilities.Behaviors; +using Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors; + +namespace UltimateCrosspathing.PostMergeFixes; + +public class FixMermonkey : PostMergeFix +{ + public override void Apply(TowerModel model) + { + if (model.appliedUpgrades.Contains("Symphonic Resonance")) // TODO replace with UpgradeType.SymphonicResonance + { + model.towerSelectionMenuThemeId = "MermonkeyTrance"; + if (model.appliedUpgrades.Contains("UpgradeType.SymphonicResonance")) // TODO replace with UpgradeType.ArcticKnight + { + var attack = model.GetDescendant().attacks[0]; + attack.RemoveBehavior(); + attack.RemoveChildDependant(attack.targetProvider); + attack.targetProvider = null; + } + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index c567dc2..9678728 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -

@@ -15,7 +14,7 @@ Ultimate Crosspathing

-### An exprimental BTD6 mod enabling more crosspathing combinations through algorithmic generation. +### A BTD6 mod enabling more crosspathing combinations through algorithmic generation. Screenshot diff --git a/TowerSettings.cs b/TowerSettings.cs index 336748e..0cbb23e 100644 --- a/TowerSettings.cs +++ b/TowerSettings.cs @@ -182,6 +182,14 @@ public class TowerSettings : ModSettings icon = VanillaSprites.DruidIcon, requiresRestart = true }; + + public static readonly ModSettingBool MermonkeyEnabled = new(true) + { + button = true, + category = IndividualTowers, + icon = "MonkeyIcons[MermonkeyIcon]", // TODO replace with VanillaSprites.MermonkeyIcon + requiresRestart = true + }; public static readonly ModSettingBool BananaFarmEnabled = new(true) { diff --git a/Towers.cs b/Towers.cs index 9fc2ee0..1814f4c 100644 --- a/Towers.cs +++ b/Towers.cs @@ -33,7 +33,8 @@ public class Towers { TowerType.GlueGunner, (2, 0, 1) }, { TowerType.WizardMonkey, (0, 2, 1) }, { TowerType.BananaFarm, (1, 2, 0) }, - { TowerType.SpikeFactory, (2, 1, 0) } + { TowerType.SpikeFactory, (2, 1, 0) }, + { TowerType.Mermonkey, (1, 2, 0) } }; ///