diff --git a/Code/DreamSpinner.cs b/Code/DreamSpinner.cs index a32f826..f22ced8 100644 --- a/Code/DreamSpinner.cs +++ b/Code/DreamSpinner.cs @@ -1,18 +1,19 @@ using Celeste.Mod.Entities; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using Mono.Cecil.Cil; using Monocle; using System.Collections.Generic; namespace Celeste.Mod.IsaGrabBag { - [Tracked] - [CustomEntity("isaBag/dreamSpinner", "isaBag/dreamSpinFake")] + [Tracked] [CustomEntity("isaBag/dreamSpinner", "isaBag/dreamSpinFake")] public class DreamSpinner : Entity { private static readonly Color debrisColor = Calc.HexToColor("c18a53"); public bool OneUse; public bool Fake; public bool ShouldRender; + public string imagePath; internal float rotation; internal Color color; @@ -22,28 +23,24 @@ public class DreamSpinner : Entity { private DreamBlock block; private bool hasCollided; - public DreamSpinner(Vector2 position, bool _useOnce, bool _fake) + public DreamSpinner(Vector2 position, bool _useOnce, bool _fake, string _imagePath) : base(position) { - Collider = new ColliderList(new Collider[] { - new Circle(6f, 0f, 0f), - new Hitbox(16f, 4f, -8f, -3f) - }); - + Collider = !_fake ? new ColliderList(new Circle(6f), new Hitbox(16f, 4f, -8f, -3f)) : null; Add(new PlayerCollider(OnPlayer)); Add(new LedgeBlocker()); OneUse = _useOnce; Fake = _fake; + imagePath = _imagePath; Depth = -8499; // Update just before our renderer Collidable = false; Visible = false; - rotation = Calc.Random.Choose(0, 1, 2, 3) * MathHelper.PiOver2; offsets = new List(); } public DreamSpinner(EntityData data, Vector2 offset) - : this(data.Position + offset, data.Bool("useOnce", false), _fake: data.Name == "isaBag/dreamSpinFake") { + : this(data.Position + offset, data.Bool("useOnce", false), _fake: data.Name == "isaBag/dreamSpinFake",data.Attr("texturePath", "isafriend/danger/crystal")) { ID = data.ID; } @@ -80,12 +77,12 @@ public override void Awake(Scene scene) { public override void Update() { if (Fake) { return; - } else if (!InView()) { + } + if (!InView()) { block.Active = false; return; - } else { - block.Active = true; } + block.Active = true; base.Update(); @@ -123,7 +120,7 @@ public override void Update() { } public bool InView() { - Camera camera = (Scene as Level).Camera; + Camera camera = SceneAs().Camera; return X > camera.X - 16f && Y > camera.Y - 16f && X < camera.X + 320f + 16f && Y < camera.Y + 180f + 16f; } @@ -144,10 +141,15 @@ public class DreamSpinnerRenderer : Entity { }; private readonly MTexture[] particleTextures; - private readonly MTexture fgSpinnerTexture; - private readonly MTexture bgSpinnerTexture; - private readonly MTexture fgBorderTexture; - private readonly MTexture bgBorderTexture; + private readonly Dictionary textureSets = new(); + + private class SpinnerTextures { + public MTexture FgSpinner; + public MTexture BgSpinner; + public MTexture FgBorder; + public MTexture BgBorder; + } + private VirtualRenderTarget dreamSpinnerTarget; private List spinnersToRender; @@ -160,17 +162,32 @@ public DreamSpinnerRenderer() { AddTag(Tags.Global | Tags.TransitionUpdate); Add(new BeforeRenderHook(BeforeRender)); - fgSpinnerTexture = GFX.Game["isafriend/danger/crystal/dreamSpinner"].GetSubtexture(0, 0, 24, 24); - bgSpinnerTexture = GFX.Game["isafriend/danger/crystal/dreamSpinner"].GetSubtexture(24, 0, 24, 24); - fgBorderTexture = GFX.Game["isafriend/danger/crystal/dreamBorder"].GetSubtexture(0, 0, 24, 24); - bgBorderTexture = GFX.Game["isafriend/danger/crystal/dreamBorder"].GetSubtexture(24, 0, 24, 24); - particleTextures = new MTexture[] { + particleTextures = [ GFX.Game["objects/dreamblock/particles"].GetSubtexture(14, 0, 7, 7), GFX.Game["objects/dreamblock/particles"].GetSubtexture(7, 0, 7, 7), GFX.Game["objects/dreamblock/particles"].GetSubtexture(0, 0, 7, 7), GFX.Game["objects/dreamblock/particles"].GetSubtexture(7, 0, 7, 7) - }; + ]; + + } + private SpinnerTextures GetTextures(string imagePath) { + if (imagePath == "") { + imagePath = "isafriend/danger/crystal"; + } + // handle backslashes because people can be dumb sometimes + imagePath = imagePath.Replace('\\', '/').TrimEnd('/'); + + // kind of hate this but its okay enough + if (!textureSets.TryGetValue(imagePath, out SpinnerTextures textures)) { + textures = new SpinnerTextures { FgSpinner = GFX.Game[$"{imagePath}/dreamSpinner_fg"], BgSpinner = GFX.Game[$"{imagePath}/dreamSpinner_bg"], + FgBorder = GFX.Game[$"{imagePath}/dreamBorder_fg"], BgBorder = GFX.Game[$"{imagePath}/dreamBorder_bg"] }; + textureSets[imagePath] = textures; + } + + return textures; + } + public override void Awake(Scene scene) { base.Awake(scene); @@ -260,13 +277,31 @@ private void BeforeRender() { private void DrawSpinnerTextures() { foreach (DreamSpinner spinner in spinnersToRender) { - fgSpinnerTexture.Draw(spinner.Position, origin, spinner.color, Vector2.One, spinner.rotation); + SpinnerTextures textures = GetTextures(spinner.imagePath); + + textures.FgSpinner.Draw(spinner.Position, origin, spinner.color, Vector2.One, spinner.rotation); + + foreach (Vector2 bgOffset in spinner.offsets) { + textures.BgSpinner.Draw(bgOffset, origin, spinner.color); + } + } + } + + private void DrawSpinnerBorders() { + foreach (DreamSpinner spinner in spinnersToRender) { + SpinnerTextures textures = GetTextures(spinner.imagePath); + + Color borderColor = !dreamDashEnabled ? Color.Gray : spinner.OneUse ? Color.Orange * 0.9f : Color.White; + + textures.FgBorder.Draw(spinner.Position, origin, borderColor, Vector2.One, spinner.rotation); + foreach (Vector2 bgOffset in spinner.offsets) { - bgSpinnerTexture.Draw(bgOffset, origin, spinner.color); + textures.BgBorder.Draw(bgOffset, origin, borderColor); } } } + private void DrawDreamParticles(Vector2 cameraPos) { for (int i = 0; i < particles.Length; i++) { int layer = particles[i].Layer; @@ -288,16 +323,6 @@ private void DrawDreamParticles(Vector2 cameraPos) { } } - private void DrawSpinnerBorders() { - foreach (DreamSpinner spinner in spinnersToRender) { - Color borderColor = !dreamDashEnabled ? Color.Gray : spinner.OneUse ? Color.Orange * 0.9f : Color.White; - fgBorderTexture.Draw(spinner.Position, origin, borderColor, Vector2.One, spinner.rotation); - foreach (Vector2 bgOffset in spinner.offsets) { - bgBorderTexture.Draw(bgOffset, origin, borderColor); - } - } - } - private List GetSpinnersToRender() { List spinnersToRender = new(); foreach (DreamSpinner spinner in Scene.Tracker.GetEntities()) { @@ -323,4 +348,4 @@ public struct DreamParticle { public float TimeOffset; } } -} +} \ No newline at end of file diff --git a/Code/IsaGrabBag.csproj b/Code/IsaGrabBag.csproj index cd5ab0c..130736d 100644 --- a/Code/IsaGrabBag.csproj +++ b/Code/IsaGrabBag.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 IsaMods Celeste.Mod.IsaGrabBag latest @@ -11,31 +11,33 @@ - - + + - + + compile; build; native; contentfiles; analyzers; buildtransitive + - - - + + + - - + + - + $(MSBuildProjectDirectory)=IsaGrabBag/ - + None - + \ No newline at end of file diff --git a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder.png b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder.png deleted file mode 100644 index dd8a4b3..0000000 Binary files a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder.png and /dev/null differ diff --git a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder_bg.png b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder_bg.png new file mode 100644 index 0000000..9c2208e Binary files /dev/null and b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder_bg.png differ diff --git a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder_fg.png b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder_fg.png new file mode 100644 index 0000000..e34bb48 Binary files /dev/null and b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamBorder_fg.png differ diff --git a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner.png b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner.png deleted file mode 100644 index e67b8b4..0000000 Binary files a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner.png and /dev/null differ diff --git a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner_bg.png b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner_bg.png new file mode 100644 index 0000000..2f0f272 Binary files /dev/null and b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner_bg.png differ diff --git a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner_fg.png b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner_fg.png new file mode 100644 index 0000000..c80da93 Binary files /dev/null and b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/dreamSpinner_fg.png differ diff --git a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/fg_dreamspinner.png b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/fg_dreamspinner.png index deb574f..fc4cf72 100644 Binary files a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/fg_dreamspinner.png and b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/fg_dreamspinner.png differ diff --git a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/fg_dreamspinner_fake.png b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/fg_dreamspinner_fake.png index 57ff9e0..b9a76d0 100644 Binary files a/Graphics/Atlases/Gameplay/isafriend/danger/crystal/fg_dreamspinner_fake.png and b/Graphics/Atlases/Gameplay/isafriend/danger/crystal/fg_dreamspinner_fake.png differ diff --git a/Loenn/entities/dream_spinner.lua b/Loenn/entities/dream_spinner.lua index bacca2b..7a8b320 100644 --- a/Loenn/entities/dream_spinner.lua +++ b/Loenn/entities/dream_spinner.lua @@ -9,12 +9,14 @@ dreamSpinner.placements = { { name = "default", data = { + texturePath = "isafriend/danger/crystal", useOnce = false } }, { name = "oneUse", data = { + texturePath = "isafriend/danger/crystal", useOnce = true } } diff --git a/Loenn/entities/dream_spinner_fake.lua b/Loenn/entities/dream_spinner_fake.lua index 6db7e84..ed3aea1 100644 --- a/Loenn/entities/dream_spinner_fake.lua +++ b/Loenn/entities/dream_spinner_fake.lua @@ -6,6 +6,9 @@ dreamSpinnerFake.name = "isaBag/dreamSpinFake" dreamSpinnerFake.depth = -8500 dreamSpinnerFake.placements = { name = "default", + data = { + texturePath = "isafriend/danger/crystal" + } } dreamSpinnerFake.texture = "isafriend/danger/crystal/fg_dreamspinner_fake"