Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,13 @@ ASALocalRun/

# BeatPulse healthcheck temp database
healthchecksdb

# Fallback portraits for Houbr's Towers/Heros
# Don't know how to make the fallback portraits work lol
Resources/Buttons/FallbackPortrait/ArmyBasePortrait.png
Resources/Buttons/FallbackPortrait/BannerMonkeyPortrait.png
Resources/Buttons/FallbackPortrait/BoxerPortrait.png
Resources/Buttons/FallbackPortrait/FrankensteinPortrait.png
Resources/Buttons/FallbackPortrait/PsychomonkeyPortrait.png
Resources/Buttons/FallbackPortrait/MonkeyMachinePortrait.png
.editorconfig
60 changes: 38 additions & 22 deletions BTD6Rogue.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
using MelonLoader;
using BTD_Mod_Helper;
using BTD6Rogue;
using Il2CppAssets.Scripts.Simulation.Bloons;
using Il2CppInterop.Runtime;
using MelonLoader.NativeUtils;
using System.Runtime.InteropServices;
using HarmonyLib;


[assembly: MelonInfo(typeof(BTD6Rogue.BTD6Rogue), ModHelperData.Name, ModHelperData.Version, ModHelperData.RepoOwner)]
[assembly: MelonGame("Ninja Kiwi", "BloonsTD6")]
Expand All @@ -9,7 +15,7 @@ namespace BTD6Rogue;

// Handles the creation of the RogueGame instance and logging
// Outside of this functionality, BTD6Rogue should not be used to keep code organized
public class BTD6Rogue : BloonsTD6Mod {
public partial class BTD6Rogue : BloonsTD6Mod {

// Static instance of BTD6 Rogue, makes it easy to access lol
public static BTD6Rogue mod = null!;
Expand All @@ -30,27 +36,37 @@ public override void OnApplicationQuit() {
fileManager.SavePlayerStats(playerStats);
}

// Use this static function instead of ModHelper.Msg to keep the logging consistent
// Info Logs are informational logs that are meant to be read by the end user but are't disrupting the gameplay or the mod
// Warning Logs are known issues/causes of issues but won't disrupt gameplay or the mod
// Error Logs are issues that will disrupt gameplay or the mod
// Critical Logs are issues that cause crashes, extreme bugs, errors, etc
// Debug is used in development for testing, they should not be sent in release versions
public static void LogMessage(object message, object caller = null!, ErrorLevels errorLevel = ErrorLevels.Debug) {
caller ??= "null";

if (errorLevel == (ErrorLevels) 0 && RogueModSettings.LogInfoMessages) {
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Info) " + caller + ": " + message);
} else if (errorLevel == (ErrorLevels) 1 && RogueModSettings.LogWarningMessages) {
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Warning) " + caller + ": " + message);
} else if (errorLevel == (ErrorLevels) 2 && RogueModSettings.LogErrorMessages) {
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Error) " + caller + ": " + message);
} else if (errorLevel == (ErrorLevels) 3 && RogueModSettings.LogCriticalMessages) {
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Critical) " + caller + ": " + message);
} else if (errorLevel == (ErrorLevels) 4 && RogueModSettings.LogDebugMessages) {
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Debug) " + caller + ": " + message);
}
}
// Use this static function instead of ModHelper.Msg to keep the logging consistent
// Info Logs are informational logs that are meant to be read by the end user but are't disrupting the gameplay or the mod
// Warning Logs are known issues/causes of issues but won't disrupt gameplay or the mod
// Error Logs are issues that will disrupt gameplay or the mod
// Critical Logs are issues that cause crashes, extreme bugs, errors, etc
// Debug is used in development for testing, they should not be sent in release versions
public static void LogMessage(object message, object caller = null!, ErrorLevels errorLevel = ErrorLevels.Debug)
{
caller ??= "null";

if (errorLevel == (ErrorLevels)0 && RogueModSettings.LogInfoMessages)
{
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Info) " + caller + ": " + message);
}
else if (errorLevel == (ErrorLevels)1 && RogueModSettings.LogWarningMessages)
{
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Warning) " + caller + ": " + message);
}
else if (errorLevel == (ErrorLevels)2 && RogueModSettings.LogErrorMessages)
{
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Error) " + caller + ": " + message);
}
else if (errorLevel == (ErrorLevels)3 && RogueModSettings.LogCriticalMessages)
{
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Critical) " + caller + ": " + message);
}
else if (errorLevel == (ErrorLevels)4 && RogueModSettings.LogDebugMessages)
{
ModHelper.Msg<BTD6Rogue>("[BTD6Rogue-v" + ModHelperData.Version + "] (Debug) " + caller + ": " + message);
}
}
}

// Error levels for logging a message with the static LogMessage function
Expand Down
52 changes: 49 additions & 3 deletions BTD6Rogue.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>BTD6Rogue</RootNamespace>
Expand All @@ -8,6 +8,7 @@
<LangVersion>latest</LangVersion>
<Optimize>False</Optimize>
<DebugType>embedded</DebugType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Remove=".github\**" />
Expand All @@ -28,14 +29,29 @@
<None Remove="Interface\Screen\**" />
<None Remove="obj\**" />
<None Remove="Portal\**" />
<Compile Remove="Bloon\Bosses\Vanilla\LychTokens\LychMini.cs" />
<None Include="Bloon\Bosses\Vanilla\LychTokens\LychMini.cs" />
<Compile Remove="Bloon\Bosses\Vanilla\LychTokens\Tombstone.cs" />
<None Include="Bloon\Bosses\Vanilla\LychTokens\Tombstone.cs" />
<Compile Remove="Bloon\Bosses\Vanilla\Diamondback\DiamondbackBoss.cs" />
<None Include="Bloon\Bosses\Vanilla\Diamondback\DiamondbackBoss.cs" />
</ItemGroup>

<Import Project="..\btd6.targets" />
<Import Project="..\btd6.targets" />

<ItemGroup>
<Compile Remove="Bloon\Bosses\Vanilla\DiamondbackBoss.cs" />
<Compile Remove="Bloon\Bosses\Vanilla\LychBoss.cs" />
<Compile Remove="Bloon\Bosses\Vanilla\LychBossOld.cs" />
<Compile Remove="Bloon\Bosses\Vanilla\LychMini.cs" />
<Compile Remove="Bloon\Bosses\Vanilla\MiniLychBloonOld.cs" />
<Compile Remove="Bloon\Bosses\Vanilla\Tombstone.cs" />
<Compile Remove="Gamemode\Gamemodes\BlitzMode.cs" />
<Compile Remove="Interface\Panels\ArtifactChoicePanel.cs" />
<Compile Remove="Interface\Panels\InitialHeroChoicePanel.cs" />
<Compile Remove="Modifier\Modifiers\OForceFortifiedModifier.cs" />
<Compile Remove="Modifier\Modifiers\OForceLeadModifier.cs" />
<Compile Remove="Modifier\Modifiers\OPrismaticShard.cs" />
<Compile Remove="Patch\HeroAddXpPatch.cs" />
<Compile Remove="Patch\InGame\OnMatchStartPatch.cs" />
<Compile Remove="Patch\InGame\OnRestartPatch.cs" />
Expand All @@ -50,7 +66,17 @@
<Compile Remove="Patch\OnUpdatePatch.cs" />
<Compile Remove="Round\RoundConfig.cs" />
<Compile Remove="Round\RoundGenerator.cs" />
<Compile Remove="Tower\TowerConfig.cs" />
<Compile Remove="Towers\Modded\CyberMonkey.cs" />
<Compile Remove="Towers\Modded\Powers\CamoTrap.cs" />
<Compile Remove="Towers\Modded\Powers\CaveMonkey.cs" />
<Compile Remove="Towers\Modded\Powers\GlueTrap.cs" />
<Compile Remove="Towers\Modded\Powers\MonkeyBoost.cs" />
<Compile Remove="Towers\Modded\Powers\RoadSpikes.cs" />
<Compile Remove="Towers\Paragons\ModdedParagons\CaveMonkeyParagon.cs" />
<Compile Remove="Towers\Paragons\ModdedParagons\CyberMonkey.cs" />
<Compile Remove="Towers\Paragons\ModdedParagons\MonkeyOfLight.cs" />
<Compile Remove="Towers\Paragons\ModdedParagons\PlasmaMonkey.cs" />
<Compile Remove="Towers\TowerConfig.cs" />
</ItemGroup>

<ItemGroup>
Expand All @@ -61,6 +87,26 @@
</ItemGroup>

<ItemGroup>
<None Include="Bloon\Bosses\Vanilla\Diamondback\DiamondbackBoss.cs" />
<None Include="Bloon\Bosses\Vanilla\LychBoss.cs" />
<None Include="Bloon\Bosses\Vanilla\LychBossOld.cs" />
<None Include="Bloon\Bosses\Vanilla\LychTokens\LychMini.cs" />
<None Include="Bloon\Bosses\Vanilla\LychTokens\Tombstone.cs" />
<None Include="Bloon\Bosses\Vanilla\MiniLychBloonOld.cs" />
<None Include="BTD6Rogue.sln" />
<None Include="Modifier\Modifiers\OForceFortifiedModifier.cs" />
<None Include="Modifier\Modifiers\OForceLeadModifier.cs" />
<None Include="Modifier\Modifiers\OPrismaticShard.cs" />
<EmbeddedResource Include="Towers\Modded\CyberMonkey.cs" />
<None Include="Towers\Modded\Powers\CamoTrap.cs" />
<None Include="Towers\Modded\Powers\CaveMonkey.cs" />
<None Include="Towers\Modded\Powers\GlueTrap.cs" />
<None Include="Towers\Modded\Powers\MonkeyBoost.cs" />
<None Include="Towers\Modded\Powers\RoadSpikes.cs" />
<None Include="Towers\Modded\TempleBase.cs" />
<None Include="Towers\Paragons\ModdedParagons\CaveMonkeyParagon.cs" />
<EmbeddedResource Include="Towers\Paragons\ModdedParagons\CyberMonkey.cs" />
<EmbeddedResource Include="Towers\Paragons\ModdedParagons\MonkeyOfLight.cs" />
<EmbeddedResource Include="Towers\Paragons\ModdedParagons\PlasmaMonkey.cs" />
</ItemGroup>
</Project>
50 changes: 48 additions & 2 deletions Bloon/BloonUtil.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,56 @@
using BTD_Mod_Helper.Api;
using BTD_Mod_Helper.Extensions;
using Il2CppAssets.Scripts.Unity;
using Il2CppAssets.Scripts.Unity.Achievements.List;
using System.Linq;

namespace BTD6Rogue;

public static class BloonUtil {

public static RogueBloon[] GetAllBloons() {
return ModContent.GetContent<RogueBloon>().ToArray();
return ModContent.GetContent<RogueBloon>()
.Where(bloon => {
try
{
ValidateRogueBloon(bloon);
return true;
}
catch
{
return false;
}
}).ToArray();
}

public static void ValidateRogueBloon(RogueBloon bloon)
{
string?[] arr = [bloon.BaseBloonId, null, null, null, null, null, null, null]; //
string[] brr = ["", "Camo", "Fortified", "FortifiedCamo", "Regrow", "RegrowCamo", "RegrowFortified", "RegrowFortifiedCamo"]; //Suffixes

if (bloon.Camo) { arr[1] = bloon.BaseBloonId + brr[1]; }
if (bloon.Fortified) { arr[2] = bloon.BaseBloonId + brr[2]; }
if (bloon.Camo && bloon.Fortified) { arr[3] = bloon.BaseBloonId + brr[3]; }
if (bloon.Regrow) { arr[4] = bloon.BaseBloonId + brr[4]; }
if (bloon.Regrow && bloon.Camo) { arr[5] = bloon.BaseBloonId + brr[5]; }
if (bloon.Regrow && bloon.Fortified) { arr[6] = bloon.BaseBloonId + brr[6]; }
if (bloon.Regrow && bloon.Fortified && bloon.Camo) { arr[7] = bloon.BaseBloonId + brr[7]; }

foreach (var j in arr) //Nullable string array
{
if (j is null) { continue; }
bool found = false;
foreach (var i in Game.instance.model.bloons) // Il2CppReferenceArray<BloonModel>
{
if (i.id == j)
{
found = true;
break; // Exit loop when a match is found
}
}
if (!found)
{
BTD6Rogue.LogMessage($"The {j} Bloon was not found. It may cause a crash ingame.", typeof(BloonUtil), ErrorLevels.Debug);
}
}
}
}
10 changes: 8 additions & 2 deletions Bloon/Bosses/BossUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ public static string GetBossHint(string boss) {
"A sudden ripple in the cosmos can be felt"
};

switch (boss) {
List<string> BlastapopoulosHints = new List<string>() {
"It's kinda hot"
};

switch (boss) {
case "RogueBloonarius":
return BloonariusHints[new Random().Next(BloonariusHints.Count)];
case "RogueVortex":
Expand All @@ -55,7 +59,9 @@ public static string GetBossHint(string boss) {
return DreadbloonHints[new Random().Next(DreadbloonHints.Count)];
case "RoguePhayze":
return PhayzeHints[new Random().Next(PhayzeHints.Count)];
}
case "RogueBlastapopoulos":
return BlastapopoulosHints[new Random().Next(PhayzeHints.Count)];
}
return "Error Message Lol";
}

Expand Down
95 changes: 95 additions & 0 deletions Bloon/Bosses/Vanilla/Diamondback/DiamondbackBoss.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using BTD_Mod_Helper.Api.Enums;
using Il2CppAssets.Scripts.Models.Bloons.Behaviors;
using Il2CppAssets.Scripts.Models.Bloons;
using Il2CppAssets.Scripts.Simulation.Bloons;
using System.Collections.Generic;
using BTD_Mod_Helper.Extensions;
using Il2CppAssets.Scripts.Simulation.Bloons.Behaviors;
using UnityEngine;
using System;
using BloonType = BTD_Mod_Helper.Api.Enums.BloonType;

namespace BTD6Rogue;

public class DiamondbackBoss : RogueBoss {
public override string BossName => "Diamondback";

public static readonly float baseMaxHealth = 3000;
public static readonly float levelHealthModifier = 2.2f; //>2.2

public static readonly float baseSpeed = 1.5f;
public static readonly float levelSpeedIncrease = 0.25f;

// Strong Spawn
public static readonly int baseStrongSpawnCount = 30;
public static readonly float levelStrongSpawnCountAddition = -3;
public static readonly int baseStrongSpawnDistAhead = 30;
public static readonly float levelStrongSpawnDistAheadAddition = 0;
public static readonly List<string> strongSpawnBloons = new List<string>() {
BloonType.Yellow,
BloonType.Zebra,
BloonType.Rainbow,
BloonType.Ceramic,
BloonType.Moab,
BloonType.Bfb
};

// Weak Spawn
public static readonly int baseWeakSpawnCount = 40;
public static readonly float levelWeakSpawnCountAddition = -2.5f;
public static readonly float baseWeakSpawnTrackMax = 0.4f;
public static readonly float levelWeakSpawnTrackMaxAddition = 0;
public static readonly float baseWeakSpawnTrackMin = 0.1f;
public static readonly float levelWeakSpawnTrackMinAddition = 0;
public static readonly List<string> weakSpawnBloons = new List<string>() {
BloonType.Green,
BloonType.Pink,
BloonType.Zebra,
BloonType.Rainbow,
BloonType.Ceramic,
BloonType.Moab
};

// Bloon Bleed
public static readonly int baseBleedSpawnCount = 20;
public static readonly float levelBleedSpawnCountAddition = 5;
public static readonly float baseBleedSpawnTrackMax = 0.4f;
public static readonly float levelBleedSpawnTrackMaxAddition = 0;
public static readonly float baseBLeedSpawnTrackMin = 0.1f;
public static readonly float levelBleedSpawnTrackMinAddition = 0;
public static readonly List<string> bleedSpawnBloons = new List<string>() {
BloonType.Blue,
BloonType.Yellow,
BloonType.Pink,
BloonType.Zebra,
BloonType.Rainbow,
BloonType.Ceramic
};

public override void AdjustBloonModel(BloonModel bloonModel, int tier, bool elite) {
bloonModel.maxHealth = Mathf.FloorToInt(baseMaxHealth * Mathf.Pow(levelHealthModifier, tier));
bloonModel.speed = baseSpeed + levelSpeedIncrease * tier;
bloonModel.leakDamage = 99999f;
}

public override void AdjustBloon(Bloon bloon, int tier, bool elite) {
foreach (SpawnBloonsAction behavior in bloon.GetBloonBehaviors<SpawnBloonsAction>()) {
SpawnBloonsActionModel model = behavior.modl;
if (model.actionId == "StrongSpawn") {
model.bloonType = strongSpawnBloons[Math.Min(tier, 5)];
model.spawnCount = Mathf.FloorToInt(baseStrongSpawnCount + levelStrongSpawnCountAddition * tier);
model.spawnDistAhead = baseStrongSpawnDistAhead + levelStrongSpawnDistAheadAddition * tier;
} else if (model.actionId == "WeakSpawn") {
model.bloonType = weakSpawnBloons[Math.Min(tier, 5)];
model.spawnCount = Mathf.FloorToInt(baseWeakSpawnCount + levelWeakSpawnCountAddition * tier);
model.spawnTrackMax = baseWeakSpawnTrackMax + levelWeakSpawnTrackMaxAddition * tier;
model.spawnTrackMin = baseWeakSpawnTrackMin + levelWeakSpawnTrackMinAddition * tier;
} else if (model.actionId == "WeakerSpawn") {
model.bloonType = bleedSpawnBloons[Math.Min(tier, 5)];
model.spawnCount = Mathf.FloorToInt(baseBleedSpawnCount + levelBleedSpawnCountAddition * tier);
model.spawnTrackMax = baseBleedSpawnTrackMax + levelBleedSpawnTrackMaxAddition * tier;
model.spawnTrackMin = baseBLeedSpawnTrackMin + levelBleedSpawnTrackMinAddition * tier;
}
}
}
}
3 changes: 3 additions & 0 deletions Bloon/Bosses/Vanilla/DreadbloonBoss.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public class DreadbloonBoss : RogueBoss {
public static readonly float levelInitialSpawnSizeAddition = 5;
public static readonly float baseTimeBetweenSpawns = 10;
public static readonly float levelTimeBetweenSpawnsAddition = -1;


public static readonly float baseInitialSkulls = -1;

public override void AdjustBloonModel(BloonModel bloonModel, int tier, bool elite) {
bloonModel.maxHealth = Mathf.FloorToInt(baseMaxHealth * Mathf.Pow(levelHealthModifier, tier));
Expand Down
Loading