forked from nikita/muzika-gromche
Add support for per-track palettes, and debug-only synced palette override
Palettes are contributed by @REALJUSTNOTHING
This commit is contained in:
parent
34d8da1562
commit
ad77530b6d
|
@ -30,6 +30,7 @@ namespace MuzikaGromche
|
||||||
Language = Language.RUSSIAN,
|
Language = Language.RUSSIAN,
|
||||||
WindUpTimer = 46.3f,
|
WindUpTimer = 46.3f,
|
||||||
Bars = 8,
|
Bars = 8,
|
||||||
|
Palette = Palette.Parse(["#B300FF", "#FFF100", "#00FF51", "#474747", "#FF00B3", "#0070FF"]),
|
||||||
},
|
},
|
||||||
new Track
|
new Track
|
||||||
{
|
{
|
||||||
|
@ -37,6 +38,7 @@ namespace MuzikaGromche
|
||||||
Language = Language.RUSSIAN,
|
Language = Language.RUSSIAN,
|
||||||
WindUpTimer = 39f,
|
WindUpTimer = 39f,
|
||||||
Bars = 8,
|
Bars = 8,
|
||||||
|
Palette = Palette.Parse(["#FF7F00", "#FFB600", "#FFED00", "#00D1FF", "#6696FB", "#704DF8"]),
|
||||||
},
|
},
|
||||||
new Track
|
new Track
|
||||||
{
|
{
|
||||||
|
@ -44,6 +46,7 @@ namespace MuzikaGromche
|
||||||
Language = Language.RUSSIAN,
|
Language = Language.RUSSIAN,
|
||||||
WindUpTimer = 40.7f,
|
WindUpTimer = 40.7f,
|
||||||
Bars = 8,
|
Bars = 8,
|
||||||
|
Palette = Palette.Parse(["#217F87", "#BAFF00", "#73BE25", "#78AB4E", "#FFFF00"]),
|
||||||
},
|
},
|
||||||
new Track
|
new Track
|
||||||
{
|
{
|
||||||
|
@ -51,6 +54,7 @@ namespace MuzikaGromche
|
||||||
Language = Language.ENGLISH,
|
Language = Language.ENGLISH,
|
||||||
WindUpTimer = 34.5f,
|
WindUpTimer = 34.5f,
|
||||||
Bars = 8,
|
Bars = 8,
|
||||||
|
Palette = Palette.Parse(["#A3A3A3", "#BE3D39", "#5CBC69", "#BE3D39", "#BABC5C", "#BE3D39", "#5C96BC", "#BE3D39"]),
|
||||||
},
|
},
|
||||||
new Track
|
new Track
|
||||||
{
|
{
|
||||||
|
@ -58,6 +62,7 @@ namespace MuzikaGromche
|
||||||
Language = Language.RUSSIAN,
|
Language = Language.RUSSIAN,
|
||||||
WindUpTimer = 43.2f,
|
WindUpTimer = 43.2f,
|
||||||
Bars = 6,
|
Bars = 6,
|
||||||
|
Palette = Palette.Parse(["#42367E", "#FF9400", "#932A04", "#FF9400", "#932A04", "#42367E", "#FF9400", "#932A04"]),
|
||||||
},
|
},
|
||||||
new Track
|
new Track
|
||||||
{
|
{
|
||||||
|
@ -65,6 +70,7 @@ namespace MuzikaGromche
|
||||||
Language = Language.RUSSIAN,
|
Language = Language.RUSSIAN,
|
||||||
WindUpTimer = 37f,
|
WindUpTimer = 37f,
|
||||||
Bars = 10,
|
Bars = 10,
|
||||||
|
Palette = Palette.Parse(["#5986FE", "#FEFEDC", "#FF4FDF", "#FEFEDC", "#FFAA23", "#FEFEDC", "#F95A5A", "#FEFEDC"]),
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -133,6 +139,24 @@ namespace MuzikaGromche
|
||||||
public static readonly Language RUSSIAN = new("RU", "Russian");
|
public static readonly Language RUSSIAN = new("RU", "Russian");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record Palette(Color[] Colors)
|
||||||
|
{
|
||||||
|
public static Palette DEFAULT = new([Color.magenta, Color.cyan, Color.green, Color.yellow]);
|
||||||
|
|
||||||
|
public static Palette Parse(string[] hexColors)
|
||||||
|
{
|
||||||
|
Color[] colors = new Color[hexColors.Length];
|
||||||
|
for (int i = 0; i < hexColors.Length; i++)
|
||||||
|
{
|
||||||
|
if (!ColorUtility.TryParseHtmlString(hexColors[i], out colors[i]))
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Unable to parse color #{i}: {hexColors}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Palette(colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Track
|
public class Track
|
||||||
{
|
{
|
||||||
public string Name;
|
public string Name;
|
||||||
|
@ -214,13 +238,17 @@ namespace MuzikaGromche
|
||||||
return beat;
|
return beat;
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly List<Color> Colors = [Color.magenta, Color.cyan, Color.green, Color.yellow];
|
public Palette _Palette = Palette.DEFAULT;
|
||||||
|
public Palette Palette
|
||||||
|
{
|
||||||
|
get => Config.PaletteOverride ?? _Palette;
|
||||||
|
set => _Palette = value;
|
||||||
|
}
|
||||||
|
|
||||||
public Color ColorAtBeat(float beat)
|
public Color ColorAtBeat(float beat)
|
||||||
{
|
{
|
||||||
int beatIndex = Mod.Positive(Mathf.FloorToInt(beat), Beats);
|
int beatIndex = Mod.Positive(Mathf.FloorToInt(beat), Beats);
|
||||||
|
return Mod.Index(Palette.Colors, beatIndex);
|
||||||
return Mod.Index(Colors, beatIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,6 +380,8 @@ namespace MuzikaGromche
|
||||||
|
|
||||||
public static bool ShouldSkipWindingPhase { get; private set; } = false;
|
public static bool ShouldSkipWindingPhase { get; private set; } = false;
|
||||||
|
|
||||||
|
public static Palette PaletteOverride { get; private set; } = null;
|
||||||
|
|
||||||
public Config(ConfigFile configFile) : base(PluginInfo.PLUGIN_GUID)
|
public Config(ConfigFile configFile) : base(PluginInfo.PLUGIN_GUID)
|
||||||
{
|
{
|
||||||
AudioOffset = configFile.Bind("General", "Audio Offset", 0f, new ConfigDescription(
|
AudioOffset = configFile.Bind("General", "Audio Offset", 0f, new ConfigDescription(
|
||||||
|
@ -361,6 +391,7 @@ namespace MuzikaGromche
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
SetupEntriesToSkipWinding(configFile);
|
SetupEntriesToSkipWinding(configFile);
|
||||||
|
SetupEntriesForPaletteOverride(configFile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var chanceRange = new AcceptableValueRange<int>(0, 100);
|
var chanceRange = new AcceptableValueRange<int>(0, 100);
|
||||||
|
@ -476,6 +507,78 @@ namespace MuzikaGromche
|
||||||
ShouldSkipWindingPhase = syncedEntry.Value;
|
ShouldSkipWindingPhase = syncedEntry.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetupEntriesForPaletteOverride(ConfigFile configFile)
|
||||||
|
{
|
||||||
|
const string section = "Palette";
|
||||||
|
const int maxCustomPaletteSize = 8;
|
||||||
|
// Declare and initialize early to avoid "Use of unassigned local variable"
|
||||||
|
SyncedEntry<int> customPaletteSizeSyncedEntry = null;
|
||||||
|
var customPaletteSyncedEntries = new SyncedEntry<string>[maxCustomPaletteSize];
|
||||||
|
|
||||||
|
var loadButton = new GenericButtonConfigItem(section, "Load Palette from the Current Track",
|
||||||
|
"Override custom palette with the built-in palette of the current track.", "Load", load);
|
||||||
|
loadButton.ButtonOptions.CanModifyCallback = CanModifyIfHost;
|
||||||
|
LethalConfigManager.AddConfigItem(loadButton);
|
||||||
|
|
||||||
|
customPaletteSizeSyncedEntry = configFile.BindSyncedEntry(section, "Palette Size", 0, new ConfigDescription(
|
||||||
|
"Number of colors in the custom palette.\n\nIf set to non-zero, custom palette overrides track's own built-in palette.",
|
||||||
|
new AcceptableValueRange<int>(0, maxCustomPaletteSize)));
|
||||||
|
LethalConfigManager.AddConfigItem(new IntSliderConfigItem(customPaletteSizeSyncedEntry.Entry, new IntSliderOptions
|
||||||
|
{
|
||||||
|
RequiresRestart = false,
|
||||||
|
CanModifyCallback = CanModifyIfHost,
|
||||||
|
}));
|
||||||
|
CSyncHackAddSyncedEntry(customPaletteSizeSyncedEntry);
|
||||||
|
customPaletteSizeSyncedEntry.Changed += (sender, args) => apply();
|
||||||
|
customPaletteSizeSyncedEntry.SyncHostToLocal();
|
||||||
|
|
||||||
|
for (int i = 0; i < maxCustomPaletteSize; i++)
|
||||||
|
{
|
||||||
|
string entryName = $"Custom Color {i + 1}";
|
||||||
|
var customColorSyncedEntry = configFile.BindSyncedEntry(section, entryName, "#FFFFFF", "Choose color for the custom palette");
|
||||||
|
customPaletteSyncedEntries[i] = customColorSyncedEntry;
|
||||||
|
LethalConfigManager.AddConfigItem(new HexColorInputFieldConfigItem(customColorSyncedEntry.Entry, new HexColorInputFieldOptions
|
||||||
|
{
|
||||||
|
RequiresRestart = false,
|
||||||
|
CanModifyCallback = CanModifyIfHost,
|
||||||
|
}));
|
||||||
|
CSyncHackAddSyncedEntry(customColorSyncedEntry);
|
||||||
|
customColorSyncedEntry.Changed += (sender, args) => apply();
|
||||||
|
customColorSyncedEntry.SyncHostToLocal();
|
||||||
|
}
|
||||||
|
|
||||||
|
apply();
|
||||||
|
|
||||||
|
void load()
|
||||||
|
{
|
||||||
|
var palette = Plugin.CurrentTrack?._Palette ?? Palette.DEFAULT;
|
||||||
|
var colors = palette.Colors;
|
||||||
|
var count = Math.Min(colors.Count(), maxCustomPaletteSize);
|
||||||
|
|
||||||
|
customPaletteSizeSyncedEntry.LocalValue = colors.Count();
|
||||||
|
for (int i = 0; i < maxCustomPaletteSize; i++)
|
||||||
|
{
|
||||||
|
var color = i < count ? colors[i] : Color.white;
|
||||||
|
string colorHex = $"#{ColorUtility.ToHtmlStringRGB(color)}";
|
||||||
|
customPaletteSyncedEntries[i].LocalValue = colorHex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply()
|
||||||
|
{
|
||||||
|
int size = customPaletteSizeSyncedEntry.Value;
|
||||||
|
if (size == 0 || size > maxCustomPaletteSize)
|
||||||
|
{
|
||||||
|
PaletteOverride = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var colors = customPaletteSyncedEntries.Select(entry => entry.Value).Take(size).ToArray();
|
||||||
|
PaletteOverride = Palette.Parse(colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// farAudio is during windup, Start overrides popGoesTheWeaselTheme
|
// farAudio is during windup, Start overrides popGoesTheWeaselTheme
|
||||||
|
|
Loading…
Reference in New Issue