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
34 changes: 31 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 @@ -30,12 +31,15 @@
<None Remove="Portal\**" />
</ItemGroup>

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

<ItemGroup>
<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 +54,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 @@ -62,5 +76,19 @@

<ItemGroup>
<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
37 changes: 25 additions & 12 deletions Bloon/RogueBloon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,56 @@
using Il2CppAssets.Scripts.Data.Knowledge.RelicKnowledge;
using Il2CppAssets.Scripts.Models.Rounds;
using System;
using System.Linq;

namespace BTD6Rogue;

// Abstract class to handle all the data that is needed for Bloons to be used in the Rogue Gamemode
// To Do: allow for custom modifiers instead of just vanilla stuff
public abstract class RogueBloon : NamedModContent {
public abstract string BaseBloonId { get; } // Base ID of the bloon (only need the Base Bloon, modifiers are handled inside class)
public virtual string? MasteryBloonId { get; } // Base ID of the bloon in mastery mode.
public virtual int MasteryMult => 1; //

public virtual int StartRound => -1; // The lowest round number where this bloon can spawn
public virtual int StartRound => -1; // The lowest round number where this bloon can spawn
public virtual int EndRound => -1; // The highest round number where this bloon can spawn

public virtual int MinAmount => 1; // Minimum amount of these bloons that can spawn while spawning
public virtual int MaxAmount => 1; // Maximum amount of these bloons that can spawn while spawning

public virtual int BloonRbe => 1; // The "Red Bloon Equivalent" of the bloon
public virtual bool MoabClass => false;

// Whether or not the modifier exists on the bloon
// The round it can start spawning it
// The round it stops spawning it

public virtual bool Camo => false;
public virtual int CamoStartRound => 0;
public virtual bool MoabClassMastery => false;

// Whether or not the modifier exists on the bloon
// Ditto but for the Mastery mode (null uses the normal value)
// Whether to always force the modifier on the bloon (ie. DDTs)
// The round it can start spawning it
// The round it stops spawning it

public virtual bool Camo => false;
public virtual bool? CamoIfMastery => null;
public virtual bool ForceCamo => false;
public virtual int CamoStartRound => 0;
public virtual int CamoEndRound => 0;

public virtual bool Regrow => false;
public virtual int RegrowStartRound => 0;
public virtual bool? RegrowIfMastery => null;
public virtual bool ForceRegrow => false;
public virtual int RegrowStartRound => 0;
public virtual int RegrowEndRound => 0;

public virtual bool Fortified => false;
public virtual int FortifiedStartRound => 0;
public virtual bool? FortifiedIfMastery => null;
public virtual bool ForceFortified => false;
public virtual int FortifiedStartRound => 0;
public virtual int FortifiedEndRound => 0;

public virtual BloonGroupModel GenerateBloonGroup(int round, float expectedRbe, float start, float end, bool camo, bool regrow, bool fortified) {
public virtual BloonGroupModel GenerateBloonGroup(int round, float expectedRbe, float start, float end, bool camo, bool regrow, bool fortified) {
int bloonAmount = GetBloonAmount(round, expectedRbe, fortified);

string newBloonId = BaseBloonId;
string newBloonId = BaseBloonId;
if (BTD6Rogue.rogueGame.modifiers.Any(m => m is OAMasteryModeModifier) && MasteryBloonId is not null) { newBloonId = MasteryBloonId; bloonAmount *= MasteryMult; }

if (regrow) { newBloonId += "Regrow"; }
if (fortified) { newBloonId += "Fortified"; }
Expand Down
1 change: 1 addition & 0 deletions Bloon/Vanilla/BadBloon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public class BadBloon : RogueBloon {
public override string BaseBloonId => "Bad";
public override int MasteryMult => 6;
public override int StartRound => 100;
public override int EndRound => -1;

Expand Down
1 change: 1 addition & 0 deletions Bloon/Vanilla/BfbBloon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public class BfbBloon : RogueBloon {
public override string BaseBloonId => "Bfb";
public override string MasteryBloonId => "Zomg";
public override int StartRound => 60;
public override int EndRound => -1;

Expand Down
1 change: 1 addition & 0 deletions Bloon/Vanilla/BlackBloon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public class BlackBloon : RogueBloon {
public override string BaseBloonId => "Black";
public override string MasteryBloonId => "White";
public override int StartRound => 18;
public override int EndRound => 39;

Expand Down
1 change: 1 addition & 0 deletions Bloon/Vanilla/BlueBloon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public class BlueBloon : RogueBloon {
public override string BaseBloonId => "Blue";
public override string MasteryBloonId => "Green";
public override int StartRound => 3;
public override int EndRound => 14;

Expand Down
3 changes: 3 additions & 0 deletions Bloon/Vanilla/CeramicBloon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

public class CeramicBloon : RogueBloon {
public override string BaseBloonId => "Ceramic";
public override string MasteryBloonId => "Moab";
public override int StartRound => 39;
public override int EndRound => -1;

public override int BloonRbe => 104;

public override bool Camo => true;
public override bool? CamoIfMastery => false;
public override int CamoStartRound => 62;
public override int CamoEndRound => -1;
public override bool Regrow => true;
public override bool? RegrowIfMastery => false;
public override int RegrowStartRound => 47;
public override int RegrowEndRound => -1;
public override bool Fortified => true;
Expand Down
11 changes: 9 additions & 2 deletions Bloon/Vanilla/DdtBloon.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
namespace BTD6Rogue;

public class DdtBloon : RogueBloon {
public override string BaseBloonId => "Ddt";
public override string BaseBloonId => "Ddt"; //wait were we using the decamoed DDT?
public override int MasteryMult => 6;
public override int StartRound => 90;
public override int EndRound => -1;

public override int BloonRbe => 816;
public override bool MoabClass => true;

public override bool Fortified => true;

public override bool Camo => true;
public override bool ForceCamo => true;
public override int CamoStartRound => 90;
public override int CamoEndRound => -1;

public override bool Fortified => true;
public override int FortifiedStartRound => 110;
public override int FortifiedEndRound => -1;
}
Loading