11using Celeste . Mod ;
22using Microsoft . Xna . Framework ;
3+ using Monocle ;
34using MonoMod . Detour ;
45using System ;
56using System . Collections . Generic ;
@@ -19,9 +20,13 @@ public class RainbowModule : EverestModule {
1920 // The methods we want to hook.
2021 private readonly static MethodInfo m_GetHairColor = typeof ( PlayerHair ) . GetMethod ( "GetHairColor" , BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ) ;
2122 private readonly static MethodInfo m_GetTrailColor = typeof ( Player ) . GetMethod ( "GetTrailColor" , BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ) ;
23+ private readonly static MethodInfo m_GetHairTexture = typeof ( PlayerHair ) . GetMethod ( "GetHairTexture" , BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ) ;
2224
2325 private static int trailIndex = 0 ;
2426
27+ private static List < MTexture > FoxBangs ;
28+ private static List < MTexture > FoxHair ;
29+
2530 public RainbowModule ( ) {
2631 Instance = this ;
2732 }
@@ -32,12 +37,21 @@ public override void Load() {
3237 // [trampoline] = [method we want to hook] .Detour< [signature] >( [replacement method] );
3338 orig_GetHairColor = m_GetHairColor . Detour < d_GetHairColor > ( t_RainbowModule . GetMethod ( "GetHairColor" ) ) ;
3439 orig_GetTrailColor = m_GetTrailColor . Detour < d_GetTrailColor > ( t_RainbowModule . GetMethod ( "GetTrailColor" ) ) ;
40+ if ( m_GetHairTexture != null ) {
41+ orig_GetHairTexture = m_GetHairTexture . Detour < d_GetHairTexture > ( t_RainbowModule . GetMethod ( "GetHairTexture" ) ) ;
42+ }
43+ }
44+
45+ public override void LoadContent ( ) {
46+ FoxBangs = GFX . Game . GetAtlasSubtextures ( "characters/player/foxbangs" ) ;
47+ FoxHair = GFX . Game . GetAtlasSubtextures ( "characters/player/foxhair" ) ;
3548 }
3649
3750 public override void Unload ( ) {
3851 // Let's just hope that nothing else detoured this, as this is depth-based...
3952 RuntimeDetour . Undetour ( m_GetHairColor ) ;
4053 RuntimeDetour . Undetour ( m_GetTrailColor ) ;
54+ RuntimeDetour . Undetour ( m_GetHairTexture ) ;
4155 }
4256
4357 // The delegate tells MonoMod.Detour / RuntimeDetour about the method signature.
@@ -48,29 +62,70 @@ public override void Unload() {
4862 public static d_GetHairColor orig_GetHairColor ;
4963 public static Color GetHairColor ( PlayerHair self , int index ) {
5064 Color colorOrig = orig_GetHairColor ( self , index ) ;
51- if ( ! Settings . Enabled || self . GetSprite ( ) . Mode == PlayerSpriteMode . Badeline )
65+ if ( Settings . Mode == RainbowModMode . Off || self . GetSprite ( ) . Mode == PlayerSpriteMode . Badeline )
5266 return colorOrig ;
5367
54- float wave = self . GetWave ( ) * 60f ;
55- wave *= Settings . SpeedFactor ;
56- Color colorRainbow = ColorFromHSV ( ( index / ( float ) self . GetSprite ( ) . HairCount ) * 180f + wave , 0.6f , 0.6f ) ;
57- return new Color (
58- ( colorOrig . R / 255f ) * 0.3f + ( colorRainbow . R / 255f ) * 0.7f ,
59- ( colorOrig . G / 255f ) * 0.3f + ( colorRainbow . G / 255f ) * 0.7f ,
60- ( colorOrig . B / 255f ) * 0.3f + ( colorRainbow . B / 255f ) * 0.7f ,
61- colorOrig . A
62- ) ;
68+ Color color = colorOrig ;
69+
70+ if ( ( Settings . Mode & RainbowModMode . Fox ) == RainbowModMode . Fox ) {
71+ Color colorFox ;
72+ if ( index % 2 == 0 ) {
73+ colorFox = new Color ( 0.8f , 0.5f , 0.05f , 1f ) ;
74+ color = new Color (
75+ ( color . R / 255f ) * 0.1f + ( colorFox . R / 255f ) * 0.9f ,
76+ ( color . G / 255f ) * 0.05f + ( colorFox . G / 255f ) * 0.95f ,
77+ ( color . B / 255f ) * 0.2f + ( colorFox . B / 255f ) * 0.8f ,
78+ color . A
79+ ) ;
80+ } else {
81+ colorFox = new Color ( 0.1f , 0.05f , 0f , 1f ) ;
82+ color = new Color (
83+ ( color . R / 255f ) * 0.1f + ( colorFox . R / 255f ) * 0.7f ,
84+ ( color . G / 255f ) * 0.1f + ( colorFox . G / 255f ) * 0.7f ,
85+ ( color . B / 255f ) * 0.1f + ( colorFox . B / 255f ) * 0.7f ,
86+ color . A
87+ ) ;
88+ }
89+ }
90+
91+ if ( ( Settings . Mode & RainbowModMode . Rainbow ) == RainbowModMode . Rainbow ) {
92+ float wave = self . GetWave ( ) * 60f ;
93+ wave *= Settings . RainbowSpeedFactor ;
94+ Color colorRainbow = ColorFromHSV ( ( index / ( float ) self . GetSprite ( ) . HairCount ) * 180f + wave , 0.6f , 0.6f ) ;
95+ color = new Color (
96+ ( color . R / 255f ) * 0.3f + ( colorRainbow . R / 255f ) * 0.7f ,
97+ ( color . G / 255f ) * 0.3f + ( colorRainbow . G / 255f ) * 0.7f ,
98+ ( color . B / 255f ) * 0.3f + ( colorRainbow . B / 255f ) * 0.7f ,
99+ color . A
100+ ) ;
101+ }
102+
103+ color . A = colorOrig . A ;
104+ return color ;
63105 }
64106
65107 public delegate Color d_GetTrailColor ( Player self , bool wasDashB ) ;
66108 public static d_GetTrailColor orig_GetTrailColor ;
67109 public static Color GetTrailColor ( Player self , bool wasDashB ) {
68- if ( ! Settings . Enabled || self . Sprite . Mode == PlayerSpriteMode . Badeline || self . Hair == null )
110+ if ( ( Settings . Mode & RainbowModMode . Rainbow ) != RainbowModMode . Rainbow || self . Sprite . Mode == PlayerSpriteMode . Badeline || self . Hair == null )
69111 return orig_GetTrailColor ( self , wasDashB ) ;
70112
71113 return self . Hair . GetHairColor ( ( trailIndex ++ ) % self . Hair . GetSprite ( ) . HairCount ) ;
72114 }
73115
116+ public delegate MTexture d_GetHairTexture ( PlayerHair self , int index ) ;
117+ public static d_GetHairTexture orig_GetHairTexture ;
118+ public static MTexture GetHairTexture ( PlayerHair self , int index ) {
119+ MTexture orig = orig_GetHairTexture ( self , index ) ;
120+ if ( ( Settings . Mode & RainbowModMode . Fox ) != RainbowModMode . Fox || self . GetSprite ( ) . Mode == PlayerSpriteMode . Badeline )
121+ return orig ;
122+
123+ if ( index == 0 )
124+ return FoxBangs [ self . GetSprite ( ) . HairFrame ] ;
125+
126+ return FoxHair [ index % FoxHair . Count ] ;
127+ }
128+
74129 // Conversion algorithms found randomly on the net - best source for HSV <-> RGB ever:tm:
75130
76131 private static void ColorToHSV ( Color c , out float h , out float s , out float v ) {
0 commit comments