diff --git a/ExampleNewMod/ExampleNewMod.csproj b/ExampleNewMod/ExampleNewMod.csproj
index bf99f10..55dc13e 100644
--- a/ExampleNewMod/ExampleNewMod.csproj
+++ b/ExampleNewMod/ExampleNewMod.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/MiasmaColors/ColorUtils.cs b/MiasmaColors/ColorUtils.cs
new file mode 100644
index 0000000..a534d8b
--- /dev/null
+++ b/MiasmaColors/ColorUtils.cs
@@ -0,0 +1,132 @@
+using System;
+using Microsoft.Xna.Framework;
+
+namespace MiasmaColors;
+
+public struct HSV
+{
+ public float H;
+ public float S;
+ public float V;
+
+ public HSV(float h, float s, float v)
+ {
+ H = h;
+ S = s;
+ V = v;
+ }
+}
+
+public static class ColorUtils
+{
+ public static HSV ColorToHSV(Color color)
+ {
+ // Normalize RGB to [0,1]
+ float r = color.R / 255f;
+ float g = color.G / 255f;
+ float b = color.B / 255f;
+
+ float max = Math.Max(r, Math.Max(g, b));
+ float min = Math.Min(r, Math.Min(g, b));
+ float delta = max - min;
+
+ float h = 0f;
+
+ if (delta > 0f)
+ {
+ if (max == r)
+ {
+ h = 60f * (((g - b) / delta) % 6f);
+ }
+ else if (max == g)
+ {
+ h = 60f * (((b - r) / delta) + 2f);
+ }
+ else // max == b
+ {
+ h = 60f * (((r - g) / delta) + 4f);
+ }
+ }
+
+ if (h < 0f) h += 360f;
+
+ float s = (max == 0f) ? 0f : (delta / max);
+ float v = max;
+
+ return new HSV(h, s, v);
+ }
+
+ public static Color HSVToColor(HSV hsv, byte alpha = 255)
+ {
+ float h = hsv.H;
+ float s = hsv.S;
+ float v = hsv.V;
+
+ float c = v * s; // Chroma
+ float x = c * (1 - Math.Abs((h / 60f) % 2 - 1));
+ float m = v - c;
+
+ float r1 = 0f, g1 = 0f, b1 = 0f;
+
+ if (h < 60)
+ {
+ r1 = c;
+ g1 = x;
+ b1 = 0;
+ }
+ else if (h < 120)
+ {
+ r1 = x;
+ g1 = c;
+ b1 = 0;
+ }
+ else if (h < 180)
+ {
+ r1 = 0;
+ g1 = c;
+ b1 = x;
+ }
+ else if (h < 240)
+ {
+ r1 = 0;
+ g1 = x;
+ b1 = c;
+ }
+ else if (h < 300)
+ {
+ r1 = x;
+ g1 = 0;
+ b1 = c;
+ }
+ else
+ {
+ r1 = c;
+ g1 = 0;
+ b1 = x;
+ }
+
+ byte r = (byte)((r1 + m) * 255f);
+ byte g = (byte)((g1 + m) * 255f);
+ byte b = (byte)((b1 + m) * 255f);
+
+ return new Color(r, g, b, alpha);
+ }
+
+ public static void HueShift(ref HSV hsv, float amount)
+ {
+ hsv.H += amount;
+
+ // Wrap around 0-360
+ if (hsv.H < 0f)
+ hsv.H += 360f;
+ else if (hsv.H >= 360f)
+ hsv.H -= 360f;
+ }
+
+ public static Color HueShift(Color color, float amount)
+ {
+ HSV hsv = ColorToHSV(color);
+ HueShift(ref hsv, amount);
+ return HSVToColor(hsv, color.A);
+ }
+}
\ No newline at end of file
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Ascension.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Ascension.png
deleted file mode 100644
index 1f8b63c..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Ascension.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Ascension.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Ascension.tag
deleted file mode 100644
index 2a85ad5..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Ascension.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Ascension
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Backfire.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Backfire.png
deleted file mode 100644
index fa0dd2a..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Backfire.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Backfire.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Backfire.tag
deleted file mode 100644
index 74af9be..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Backfire.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Backfire
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Flight.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Flight.png
deleted file mode 100644
index c490ffe..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Flight.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Flight.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Flight.tag
deleted file mode 100644
index 18962ec..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Flight.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Flight
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Frostfang Keep.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Frostfang Keep.png
deleted file mode 100644
index ea22c06..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Frostfang Keep.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Frostfang Keep.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Frostfang Keep.tag
deleted file mode 100644
index 9f91fef..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Frostfang Keep.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Frostfang Keep
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet II.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet II.png
deleted file mode 100644
index 1e88664..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet II.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet II.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet II.tag
deleted file mode 100644
index 4c2d9bc..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet II.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Gauntlet Ii
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet.png
deleted file mode 100644
index 59176e2..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet.tag
deleted file mode 100644
index 0df3488..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Gauntlet.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Gauntlet
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--King's Court.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--King's Court.png
deleted file mode 100644
index 8840f75..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--King's Court.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--King's Court.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--King's Court.tag
deleted file mode 100644
index 3fd2f0b..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--King's Court.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=King's Court
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Mirage.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Mirage.png
deleted file mode 100644
index 5eaadf6..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Mirage.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Mirage.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Mirage.tag
deleted file mode 100644
index 37fc63c..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Mirage.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Mirage
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Moonstone.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Moonstone.png
deleted file mode 100644
index e805736..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Moonstone.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Moonstone.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Moonstone.tag
deleted file mode 100644
index 96cc5ee..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Moonstone.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Moonstone
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sacred Ground.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sacred Ground.png
deleted file mode 100644
index 700fcae..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sacred Ground.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sacred Ground.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sacred Ground.tag
deleted file mode 100644
index 9fa4417..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sacred Ground.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Sacred Ground
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sunken City.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sunken City.png
deleted file mode 100644
index 5ce9a67..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sunken City.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sunken City.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sunken City.tag
deleted file mode 100644
index 068fb58..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Sunken City.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Sunken City
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Thornwood.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Thornwood.png
deleted file mode 100644
index 8985cf2..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Thornwood.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Thornwood.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Thornwood.tag
deleted file mode 100644
index c737f87..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Thornwood.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Thornwood
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Towerforge.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Towerforge.png
deleted file mode 100644
index 63f6c73..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Towerforge.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Towerforge.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Towerforge.tag
deleted file mode 100644
index 0035984..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Towerforge.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Towerforge
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Twilight Spire.png b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Twilight Spire.png
deleted file mode 100644
index 405db23..0000000
Binary files a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Twilight Spire.png and /dev/null differ
diff --git a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Twilight Spire.tag b/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Twilight Spire.tag
deleted file mode 100644
index c88f366..0000000
--- a/MiasmaColors/Content/Atlas/atlas/quest/(floorMiasma)--Twilight Spire.tag
+++ /dev/null
@@ -1 +0,0 @@
-level=Twilight Spire
diff --git a/MiasmaColors/MiasmaColorsModule.cs b/MiasmaColors/MiasmaColorsModule.cs
index fe9ed3e..9312a5a 100644
--- a/MiasmaColors/MiasmaColorsModule.cs
+++ b/MiasmaColors/MiasmaColorsModule.cs
@@ -1,66 +1,116 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
using FortRise;
+using HarmonyLib;
+using Microsoft.Extensions.Logging;
using Microsoft.Xna.Framework;
-using Monocle;
+using MonoMod.Utils;
using TowerFall;
namespace MiasmaColors;
-public class MiasmaColorsModule : FortModule
+public class MiasmaColorsModule : Mod
{
- public override void Load()
- {
- On.TowerFall.FloorMiasma.ctor += ApplyLightColorToMiasma;
- }
+ public static MiasmaColorsModule Instance = null!;
- public override void Unload()
- {
- On.TowerFall.FloorMiasma.ctor -= ApplyLightColorToMiasma;
- }
+ private DynamicData miasmaData;
+ private DynamicData bottomMiasmaData;
+ private Color originalColor;
+ private Color originalLightColor;
+
+ private SubTextureModifier surfaceModifier;
+ private SubTextureModifier tentaclesModifier;
+ private SubTextureModifier tentaclesHModifier;
+ private SubTextureModifier floorModfier;
+
+ private bool colorsUpdated = false;
- private void ApplyLightColorToMiasma(On.TowerFall.FloorMiasma.orig_ctor orig, FloorMiasma self, Vector2 position, int width, int group)
+ public MiasmaColorsModule(IModContent content, IModuleContext context, ILogger logger) : base(content, context, logger)
{
- orig(self, position, width, group);
- self.Add(new MiasmaColorComponent());
+ Instance = this;
+
+ miasmaData = new DynamicData(typeof(Miasma));
+ bottomMiasmaData = new DynamicData(typeof(BottomMiasma));
+
+ originalColor = miasmaData.Get("Color");
+ originalLightColor = miasmaData.Get("Light");
+
+ OnInitialize = HandleInitialize;
}
-}
-public class MiasmaColorComponent : Component
-{
- public MiasmaColorComponent() : base(false, false)
+ private void HandleInitialize(IModuleContext context)
{
+ floorModfier = new SubTextureModifier("quest/floorMiasma");
+ surfaceModifier = new SubTextureModifier("miasma/surface");
+ tentaclesModifier = new SubTextureModifier("miasma/tentacles");
+ tentaclesHModifier = new SubTextureModifier("miasma/tentaclesH");
+
+ context.Events.OnLevelLoaded += HandleLevelLoaded;
+ context.Harmony.Patch(AccessTools.Method(typeof(LevelSystem), nameof(LevelSystem.Dispose)), postfix: new HarmonyMethod(LevelSystemDisposePostfix));
}
- public override void EntityAdded()
+ private void HandleLevelLoaded(object sender, RoundLogic logic)
{
- base.EntityAdded();
-
- var levelTag = ReadLevelTag(Scene.SceneTags);
+ if (!logic.CanMiasma || colorsUpdated)
+ return;
+
+ var levelTag = ReadLevelTag(logic.Session.CurrentLevel.SceneTags);
if (string.IsNullOrEmpty(levelTag))
return;
- (Entity as LevelEntity).LightColor = (levelTag switch
- {
- "Sacred Ground" => Calc.HexToColor("ffd29e"),
- "Twilight Spire" => Calc.HexToColor("e39eff"),
- "Backfire" => Calc.HexToColor("9ecdff"),
- "Flight" => Calc.HexToColor("ff9620"),
- "Mirage" => Calc.HexToColor("ffff60"),
- "Thornwood" => Calc.HexToColor("72ff66"),
- "Frostfang Keep" => Calc.HexToColor("26fff5"),
- "King's Court" => Calc.HexToColor("ff0000"),
- "Sunken City" => Calc.HexToColor("50ffb1"),
- "Moonstone" => Calc.HexToColor("7275dd"),
- "Towerforge" => Calc.HexToColor("FF2000"),
- "Ascension" => Calc.HexToColor("f8ffff"),
- "Gauntlet" => Calc.HexToColor("616a9e"),
- "Gauntlet II" => Calc.HexToColor("fbfcfc"),
- _ => Calc.HexToColor("9ED1FF")
- }).Invert();
+ float shiftAmount = GetHueShiftForLevel(levelTag);
+
+ surfaceModifier.ApplyHueShift(shiftAmount);
+ tentaclesModifier.ApplyHueShift(shiftAmount);
+ floorModfier.ApplyHueShift(shiftAmount);
+
+ Color newColor = ColorUtils.HueShift(originalColor, shiftAmount);
+ miasmaData.Set("Color", newColor);
+ bottomMiasmaData.Set("Color", newColor);
+
+ Color newLightColor = ColorUtils.HueShift(originalLightColor, shiftAmount);
+ miasmaData.Set("Light", newLightColor);
+ bottomMiasmaData.Set("Light", newLightColor);
}
+ private static void LevelSystemDisposePostfix(LevelSystem __instance)
+ {
+ if (!Instance.colorsUpdated)
+ return;
+
+ Instance.surfaceModifier.Reset();
+ Instance.floorModfier.Reset();
+ Instance.tentaclesModifier.Reset();
+ Instance.tentaclesHModifier.Reset();
+ }
+ private float GetHueShiftForLevel(string levelTag)
+ {
+ return levelTag switch
+ {
+ "SacredGround" => 132.8f,
+ "TwilightSpire" => 27.4f,
+ "Backfire" => -81.2f,
+ "Flight" => 113f,
+ "Mirage" => 143.8f,
+ "Thornwood" => -128.4f,
+ "FrostfangKeep" => -96.6f,
+ "KingsCourt" => 80f,
+ "SunkenCity" => -125f,
+ "Moonstone" => -62f,
+ "TowerForge" => 69.1f,
+ "Ascension" => -95.5f,
+ "GauntletA" => -63.7f,
+ "GauntletB" => -95.5f,
+ "TheAmaranth" => -152.6f,
+ "Dreadwood" => -180f,
+ "Darkfang" => -92.2f,
+ "Cataclysm" => 40.6f,
+ _ => 0
+ };
+ }
+
private static string ReadLevelTag(List tag)
{
for (int i = 0; i < tag.Count; i++)
diff --git a/MiasmaColors/SubTextureModifier.cs b/MiasmaColors/SubTextureModifier.cs
new file mode 100644
index 0000000..9c4041a
--- /dev/null
+++ b/MiasmaColors/SubTextureModifier.cs
@@ -0,0 +1,44 @@
+using Microsoft.Xna.Framework;
+using Monocle;
+using TowerFall;
+
+namespace MiasmaColors;
+
+public class SubTextureModifier
+{
+ private string subtextureName;
+
+ private Color[] originalColors;
+ private Subtexture texture;
+
+ public SubTextureModifier(string subtextureName)
+ {
+ this.subtextureName = subtextureName;
+ texture = TFGame.Atlas[subtextureName];
+ originalColors = new Color[texture.Width * texture.Height];
+ TFGame.Atlas.Texture2D.GetData(0, texture.Rect, originalColors, 0, originalColors.Length);
+ }
+
+ public void ApplyHueShift(float angle)
+ {
+ Color[] newColors = new Color[originalColors.Length];
+ for (int i = 0; i < newColors.Length; i++)
+ {
+ if (originalColors[i].A == 0)
+ {
+ newColors[i] = originalColors[i];
+ continue;
+ }
+
+ HSV hsvColor = ColorUtils.ColorToHSV(originalColors[i]);
+ ColorUtils.HueShift(ref hsvColor, angle);
+ newColors[i] = ColorUtils.HSVToColor(hsvColor, originalColors[i].A);
+ }
+ TFGame.Atlas.Texture2D.SetData(0, texture.Rect, newColors, 0, newColors.Length);
+ }
+
+ public void Reset()
+ {
+ TFGame.Atlas.Texture2D.SetData(0, texture.Rect, originalColors, 0, originalColors.Length);
+ }
+}
\ No newline at end of file
diff --git a/MiasmaColors/meta.json b/MiasmaColors/meta.json
index 26344d4..69ad46f 100644
--- a/MiasmaColors/meta.json
+++ b/MiasmaColors/meta.json
@@ -1,7 +1,7 @@
{
"name": "Teuria.MiasmaColors",
"version": "2.0.0",
- "author": "Terria",
+ "author": "Terria, Lync",
"description": "A mod that changes miasma colors in different level with different colors.",
"dll": "MiasmaColors.dll",
"dependencies": [