forked from nikita/muzika-gromche
Compare commits
6 Commits
7730c19de1
...
f77e41bd17
| Author | SHA1 | Date |
|---|---|---|
|
|
f77e41bd17 | |
|
|
65784e726e | |
|
|
0d44728ef7 | |
|
|
d8651ce7db | |
|
|
f15e3a1e3d | |
|
|
98244dd3f1 |
|
|
@ -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,11 +1645,14 @@ 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.Value == 0);
|
||||
var isOff = tracks.All(t => t.Weight == null || t.Weight.Value == 0);
|
||||
var newWeight = isOff ? 50 : 0;
|
||||
foreach (var t in tracks)
|
||||
{
|
||||
t.Weight.Value = newWeight;
|
||||
if (t.Weight != null)
|
||||
{
|
||||
t.Weight.Value = newWeight;
|
||||
}
|
||||
}
|
||||
});
|
||||
LethalConfigManager.AddConfigItem(button);
|
||||
|
|
@ -2117,7 +2120,10 @@ namespace MuzikaGromche
|
|||
ChooseTrackDeferred();
|
||||
foreach (var track in Plugin.Tracks)
|
||||
{
|
||||
track.Weight.SettingChanged += ChooseTrackDeferredDelegate;
|
||||
if (track.Weight is { } weight)
|
||||
{
|
||||
weight.SettingChanged += ChooseTrackDeferredDelegate;
|
||||
}
|
||||
}
|
||||
Config.SkipExplicitTracks.SettingChanged += ChooseTrackDeferredDelegate;
|
||||
base.OnNetworkSpawn();
|
||||
|
|
@ -2127,7 +2133,10 @@ namespace MuzikaGromche
|
|||
{
|
||||
foreach (var track in Plugin.Tracks)
|
||||
{
|
||||
track.Weight.SettingChanged -= ChooseTrackDeferredDelegate;
|
||||
if (track.Weight is { } weight)
|
||||
{
|
||||
weight.SettingChanged -= ChooseTrackDeferredDelegate;
|
||||
}
|
||||
}
|
||||
Config.SkipExplicitTracks.SettingChanged -= ChooseTrackDeferredDelegate;
|
||||
base.OnNetworkDespawn();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MuzikaGromche.Via;
|
||||
|
|
@ -14,32 +15,43 @@ interface ILightshow
|
|||
|
||||
class Animations
|
||||
{
|
||||
private static CancellationTokenSource? cts;
|
||||
|
||||
public static void Flicker(ILightshow lightshow)
|
||||
{
|
||||
_ = Task.Run(() => FlickerAsync(lightshow));
|
||||
if (cts != null)
|
||||
{
|
||||
cts.Cancel();
|
||||
}
|
||||
cts = new();
|
||||
_ = Task.Run(async () => await FlickerAsync(lightshow, cts.Token), cts.Token);
|
||||
}
|
||||
|
||||
static async ValueTask FlickerAsync(ILightshow lightshow)
|
||||
static async ValueTask FlickerAsync(ILightshow lightshow, CancellationToken cancellationToken)
|
||||
{
|
||||
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 => OFF.
|
||||
// Timestamps (in frames of 60 fps) of state switches, starting with 0 => ON.
|
||||
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 = true;
|
||||
bool lastState = false;
|
||||
int lastFrame = 0;
|
||||
|
||||
const int initialMillisecondsDelay = 100;
|
||||
const int initialMillisecondsDelay = 4 * 1000 / 60;
|
||||
await Task.Delay(initialMillisecondsDelay);
|
||||
|
||||
foreach (int frame in MansionWallLampFlicker)
|
||||
|
|
|
|||
Loading…
Reference in New Issue