1
0
Fork 0

Compare commits

..

6 Commits

Author SHA1 Message Date
ivan tkachenko 7730c19de1 Add integration with QMK/VIA keyboard on Framework Laptop 16 2026-03-07 00:31:30 +02:00
ivan tkachenko e1a9957154 Add sources of patches Unity assets 2026-02-19 22:17:08 +02:00
ivan tkachenko 09951704f0 README: Rewrite paragraph about HookahPlace 2026-02-19 22:15:22 +02:00
ivan tkachenko 3df1a555a7 README: Fix typo 2026-02-19 22:14:58 +02:00
ivan tkachenko 544e6c174c Bump version of dependency WaterGun-V70PoweredLights_Fix to 1.1.0
It doesn't quite work on its own: sound and animators are still somehow
missing, so I'm not removing the fixes on my end.
2026-01-24 17:24:31 +02:00
ivan tkachenko 8942b2ee37 Implement a better way to disable tracks while keeping them in JSON 2026-01-23 15:32:33 +02:00
2 changed files with 16 additions and 37 deletions

View File

@ -62,7 +62,7 @@ namespace MuzikaGromche
{
var seed = GetCurrentSeed();
var (tracks, season) = GetTracksAndSeason();
int[] weights = tracks.Select(track => track.Weight!.Value).ToArray();
int[] weights = tracks.Select(track => track.Weight.Value).ToArray();
var rwi = new RandomWeightedIndex(weights);
var trackId = rwi.GetRandomWeightedIndex(seed);
var track = tracks[trackId];
@ -87,8 +87,8 @@ namespace MuzikaGromche
// Similar to RandomWeightedIndex:
// If everything is set to zero, everything is equally possible
var allWeightsAreZero = tracks.All(t => t.Weight!.Value == 0);
bool WeightIsCompatible(ISelectableTrack t) => allWeightsAreZero || t.Weight!.Value > 0;
var allWeightsAreZero = tracks.All(t => t.Weight.Value == 0);
bool WeightIsCompatible(ISelectableTrack t) => allWeightsAreZero || t.Weight.Value > 0;
var compatibleSelectableTracks = tracks
.Where(track => WeightIsCompatible(track) && track.GetTracks().Any(TimerIsCompatible))
@ -101,7 +101,7 @@ namespace MuzikaGromche
}
// Select track group where at least one track member is compatible
int[] weights = compatibleSelectableTracks.Select(track => track.Weight!.Value).ToArray();
int[] weights = compatibleSelectableTracks.Select(track => track.Weight.Value).ToArray();
var rwi = new RandomWeightedIndex(weights);
var trackId = rwi.GetRandomWeightedIndex(seed);
var selectableTrack = compatibleSelectableTracks[trackId];
@ -344,7 +344,7 @@ namespace MuzikaGromche
public bool IsExplicit { get; init; }
// How often this track should be chosen, relative to the sum of weights of all tracks.
internal ConfigEntry<int>? Weight { get; set; }
internal ConfigEntry<int> Weight { get; set; }
internal IAudioTrack[] GetTracks();
@ -587,7 +587,7 @@ namespace MuzikaGromche
public /* required */ Language Language { get; init; }
public bool IsExplicit { get; init; } = false;
public Season? Season { get; init; } = null;
ConfigEntry<int>? ISelectableTrack.Weight { get; set; } = null;
ConfigEntry<int> ISelectableTrack.Weight { get; set; } = null!;
IAudioTrack[] ISelectableTrack.GetTracks() => [this];
@ -609,7 +609,7 @@ namespace MuzikaGromche
public /* required */ Language Language { get; init; }
public bool IsExplicit { get; init; } = false;
public Season? Season { get; init; } = null;
ConfigEntry<int>? ISelectableTrack.Weight { get; set; } = null;
ConfigEntry<int> ISelectableTrack.Weight { get; set; } = null!;
public /* required */ IAudioTrack[] Tracks = [];
@ -1645,14 +1645,11 @@ namespace MuzikaGromche
var button = new GenericButtonConfigItem(section, buttonOptionName, buttonDescription, buttonText, () =>
{
var tracks = Plugin.Tracks.Where(t => t.Language.Equals(language)).ToList();
var isOff = tracks.All(t => t.Weight == null || t.Weight.Value == 0);
var isOff = tracks.All(t => t.Weight.Value == 0);
var newWeight = isOff ? 50 : 0;
foreach (var t in tracks)
{
if (t.Weight != null)
{
t.Weight.Value = newWeight;
}
t.Weight.Value = newWeight;
}
});
LethalConfigManager.AddConfigItem(button);
@ -2120,10 +2117,7 @@ namespace MuzikaGromche
ChooseTrackDeferred();
foreach (var track in Plugin.Tracks)
{
if (track.Weight is { } weight)
{
weight.SettingChanged += ChooseTrackDeferredDelegate;
}
track.Weight.SettingChanged += ChooseTrackDeferredDelegate;
}
Config.SkipExplicitTracks.SettingChanged += ChooseTrackDeferredDelegate;
base.OnNetworkSpawn();
@ -2133,10 +2127,7 @@ namespace MuzikaGromche
{
foreach (var track in Plugin.Tracks)
{
if (track.Weight is { } weight)
{
weight.SettingChanged -= ChooseTrackDeferredDelegate;
}
track.Weight.SettingChanged -= ChooseTrackDeferredDelegate;
}
Config.SkipExplicitTracks.SettingChanged -= ChooseTrackDeferredDelegate;
base.OnNetworkDespawn();

View File

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace MuzikaGromche.Via;
@ -15,43 +14,32 @@ interface ILightshow
class Animations
{
private static CancellationTokenSource? cts;
public static void Flicker(ILightshow lightshow)
{
if (cts != null)
{
cts.Cancel();
}
cts = new();
_ = Task.Run(async () => await FlickerAsync(lightshow, cts.Token), cts.Token);
_ = Task.Run(() => FlickerAsync(lightshow));
}
static async ValueTask FlickerAsync(ILightshow lightshow, CancellationToken cancellationToken)
static async ValueTask FlickerAsync(ILightshow lightshow)
{
await foreach (var on in FlickerAnimationAsync())
{
if (cancellationToken.IsCancellationRequested)
{
break;
}
byte brightness = on ? (byte)0xFF : (byte)0x00;
lightshow.SetBrightnessOverride(brightness);
}
lightshow.SetBrightnessOverride(null);
}
// Timestamps (in frames of 60 fps) of state switches, starting with 0 => ON.
// Timestamps (in frames of 60 fps) of state switches, starting with 0 => OFF.
private static readonly int[] MansionWallLampFlicker = [
0, 4, 8, 26, 28, 32, 37, 41, 42, 58, 60, 71,
];
public static async IAsyncEnumerable<bool> FlickerAnimationAsync()
{
bool lastState = false;
bool lastState = true;
int lastFrame = 0;
const int initialMillisecondsDelay = 4 * 1000 / 60;
const int initialMillisecondsDelay = 100;
await Task.Delay(initialMillisecondsDelay);
foreach (int frame in MansionWallLampFlicker)