From 4758cae7f32b3741fa1122b0ec1b2f49ce43b4e2 Mon Sep 17 00:00:00 2001 From: Maik Macho Date: Tue, 6 Mar 2018 00:50:31 +0100 Subject: [PATCH] Room PB ghosts are gold --- GhostMod/Ghost.cs | 27 +++++++------- GhostMod/GhostManager.cs | 78 ++++++++++++++++++++++++++++++++++++++++ GhostMod/GhostMod.csproj | 1 + GhostMod/GhostModule.cs | 23 ++++-------- 4 files changed, 100 insertions(+), 29 deletions(-) create mode 100644 GhostMod/GhostManager.cs diff --git a/GhostMod/Ghost.cs b/GhostMod/Ghost.cs index 520ada9..eb5cf4d 100644 --- a/GhostMod/Ghost.cs +++ b/GhostMod/Ghost.cs @@ -12,6 +12,8 @@ namespace Celeste.Mod.Ghost { public class Ghost : Actor { + public GhostManager Manager; + public Player Player; public PlayerSprite Sprite; @@ -27,7 +29,7 @@ public class Ghost : Actor { public GhostName Name; - protected Color color; + public Color Color = Color.White; protected float alpha; protected float alphaHair; @@ -73,7 +75,12 @@ public void UpdateHair() { if (!Frame.HasData) return; - Hair.Color = Frame.HairColor; + Hair.Color = new Color( + (Frame.HairColor.R * Color.R) / 255, + (Frame.HairColor.G * Color.G) / 255, + (Frame.HairColor.B * Color.B) / 255, + (Frame.HairColor.A * Color.A) / 255 + ); Hair.Alpha = alphaHair; Hair.Facing = Frame.Facing; Hair.SimulateMotion = Frame.HairSimulateMotion; @@ -87,7 +94,12 @@ public void UpdateSprite() { Sprite.Rotation = Frame.Rotation; Sprite.Scale = Frame.Scale; Sprite.Scale.X = Sprite.Scale.X * (float) Frame.Facing; - Sprite.Color = Frame.Color * alpha; + Sprite.Color = new Color( + (Frame.Color.R * Color.R) / 255, + (Frame.Color.G * Color.G) / 255, + (Frame.Color.B * Color.B) / 255, + (Frame.Color.A * Color.A) / 255 + ) * alpha; Sprite.Rate = Frame.SpriteRate; Sprite.Justify = Frame.SpriteJustify; @@ -137,15 +149,6 @@ public override void Update() { alphaHair = Calc.LerpClamp(GhostModule.Settings.InnerHairOpacityFactor, GhostModule.Settings.OuterHairOpacityFactor, dist); } - if (Data != null) { - /* Proposed colors: - * blue - full run PB - * silver - chapter PB - * gold - room PB - */ - // TODO: Ghost colors based on time. - } - UpdateSprite(); UpdateHair(); diff --git a/GhostMod/GhostManager.cs b/GhostMod/GhostManager.cs new file mode 100644 index 0000000..4297474 --- /dev/null +++ b/GhostMod/GhostManager.cs @@ -0,0 +1,78 @@ +using FMOD.Studio; +using Microsoft.Xna.Framework; +using Monocle; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using YamlDotNet.Serialization; + +namespace Celeste.Mod.Ghost { + public class GhostManager : Entity { + + public List Ghosts = new List(); + + public Player Player; + + public readonly static Color ColorGold = new Color(1f, 1f, 0f, 1f); + public readonly static Color ColorNeutral = new Color(1f, 1f, 1f, 1f); + + public GhostManager(Player player, Level level) + : base(Vector2.Zero) { + Player = player; + + Tag = Tags.HUD; + + // Read and add all ghosts. + GhostData.ForAllGhosts(level.Session, (i, ghostData) => { + Ghost ghost = new Ghost(player, ghostData); + level.Add(ghost); + Ghosts.Add(ghost); + return true; + }); + } + + public override void Removed(Scene scene) { + base.Removed(scene); + + // Remove any dead ghosts (heh) + for (int i = Ghosts.Count - 1; i > -1; --i) { + Ghost ghost = Ghosts[i]; + if (ghost.Player != Player) + ghost.RemoveSelf(); + } + Ghosts.Clear(); + } + + public override void Render() { + /* Proposed colors: + * blue - full run PB (impossible) + * silver - chapter PB (feasible) + * gold - room PB (done) + */ + + // Gold is the easiest: Find fastest active ghost. + Ghost fastest = null; + foreach (Ghost ghost in Ghosts) { + // While we're at it, reset all colors. + ghost.Color = ColorNeutral; + + if (!ghost.Frame.HasData) + continue; + + if (fastest == null || ghost.Data.Frames.Count < fastest.Data.Frames.Count) { + fastest = ghost; + } + } + + if (fastest != null) { + fastest.Color = ColorGold; + } + + base.Render(); + } + + } +} diff --git a/GhostMod/GhostMod.csproj b/GhostMod/GhostMod.csproj index bef16d6..0873e87 100644 --- a/GhostMod/GhostMod.csproj +++ b/GhostMod/GhostMod.csproj @@ -64,6 +64,7 @@ + diff --git a/GhostMod/GhostModule.cs b/GhostMod/GhostModule.cs index d3822e1..fc591e4 100644 --- a/GhostMod/GhostModule.cs +++ b/GhostMod/GhostModule.cs @@ -21,7 +21,7 @@ public class GhostModule : EverestModule { public static string PathGhosts { get; internal set; } - public List Ghosts = new List(); + public GhostManager GhostManager; public GhostRecorder GhostRecorder; public Guid Run; @@ -49,7 +49,8 @@ public override void Unload() { public void OnLoadLevel(Level level, Player.IntroTypes playerIntro, bool isFromLoader) { if (isFromLoader) { - Ghosts.Clear(); + GhostManager?.RemoveSelf(); + GhostManager = null; GhostRecorder?.RemoveSelf(); GhostRecorder = null; Run = Guid.NewGuid(); @@ -82,21 +83,9 @@ public void Step(Level level) { GhostRecorder.Data.Write(); } - // Remove any dead ghosts (heh) - for (int i = Ghosts.Count - 1; i > -1; --i) { - Ghost ghost = Ghosts[i]; - if (ghost.Player != player) - ghost.RemoveSelf(); - } - Ghosts.Clear(); - - // Read and add all ghosts. - GhostData.ForAllGhosts(level.Session, (i, ghostData) => { - Ghost ghost = new Ghost(player, ghostData); - level.Add(ghost); - Ghosts.Add(ghost); - return true; - }); + GhostManager?.RemoveSelf(); + + level.Add(GhostManager = new GhostManager(player, level)); if (GhostRecorder != null) GhostRecorder.RemoveSelf();