mirror of
https://github.com/ppy/osu.git
synced 2026-05-27 21:08:34 +08:00
Update resources
This commit is contained in:
@@ -0,0 +1,473 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ManagedBass.Fx;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Audio.Effects;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterfaceV2;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public partial class AfToggleSection : SettingsSection
|
||||
{
|
||||
public override LocalisableString Header => "Toggles";
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.Regular.Dizzy,
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ToggleSettings(),
|
||||
};
|
||||
}
|
||||
|
||||
public partial class ToggleSettings : SettingsSubsection
|
||||
{
|
||||
[Resolved]
|
||||
private OsuGameBase game { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private GameHost host { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private MusicController musicController { get; set; } = null!;
|
||||
|
||||
protected override LocalisableString Header => "You wanted toggles, we give you toggles";
|
||||
|
||||
private List<string> words = new List<string>();
|
||||
|
||||
private List<Action<ValueChangedEvent<bool>>> heroActions = new List<Action<ValueChangedEvent<bool>>>();
|
||||
|
||||
private readonly List<ScheduledDelegate> tasks = new List<ScheduledDelegate>();
|
||||
|
||||
private GlobalActionContainer target = null!;
|
||||
|
||||
private AutoWahParameters autoWahParameters = null!;
|
||||
private ChorusParameters chorusParameters = null!;
|
||||
private PhaserParameters phaserParameters = null!;
|
||||
private Bindable<double> balanceAdjustment = null!;
|
||||
|
||||
private Sprite? dvdLogo;
|
||||
private Vector2 dvdLogoVelocity = new Vector2(0.005f);
|
||||
|
||||
private ScheduledDelegate? dvdLogoMovement;
|
||||
|
||||
private AudioManager audio = null!;
|
||||
|
||||
private double lastUpdate;
|
||||
|
||||
[Resolved]
|
||||
private TextureStore textures { get; set; } = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
autoWahParameters = new AutoWahParameters { fDryMix = 0.5f, fWetMix = 0.5f };
|
||||
chorusParameters = new ChorusParameters { fDryMix = 0.5f, fWetMix = 0.5f };
|
||||
phaserParameters = new PhaserParameters { fDryMix = 0.5f, fWetMix = 0.5f };
|
||||
balanceAdjustment = new Bindable<double>(1);
|
||||
|
||||
audio = game.Audio;
|
||||
|
||||
target = game.ChildrenOfType<GlobalActionContainer>().First();
|
||||
target.Anchor = Anchor.Centre;
|
||||
target.Origin = Anchor.Centre;
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
lastUpdate = Clock.CurrentTime;
|
||||
|
||||
tasks.RemoveAll(t => t.Cancelled || t.Completed);
|
||||
|
||||
if (tasks.Count > 40)
|
||||
explode();
|
||||
}
|
||||
|
||||
private void explode()
|
||||
{
|
||||
foreach (var t in tasks)
|
||||
t.Cancel();
|
||||
|
||||
target.FadeColour(Color4.Black, 2000);
|
||||
target.ScaleTo(1)
|
||||
.ScaleTo(10, 4000);
|
||||
|
||||
audio.Samples.Get("Gameplay/Argon/failsound-alt")?.Play();
|
||||
musicController.DuckMomentarily(2000, new DuckParameters
|
||||
{
|
||||
DuckDuration = 0,
|
||||
DuckVolumeTo = 0,
|
||||
DuckCutoffTo = AudioFilter.MAX_LOWPASS_CUTOFF,
|
||||
RestoreDuration = 3000,
|
||||
RestoreEasing = Easing.InQuint,
|
||||
});
|
||||
|
||||
host.UpdateThread.Scheduler.AddDelayed(() =>
|
||||
{
|
||||
foreach (var c in getCheckboxes())
|
||||
{
|
||||
c.Current.Disabled = false;
|
||||
c.Current.Value = false;
|
||||
}
|
||||
|
||||
target.FinishTransforms();
|
||||
target.ScaleTo(1)
|
||||
.FadeColour(Color4.White, 2000, Easing.OutQuint);
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
var settingsOverlay = game.ChildrenOfType<SettingsOverlay>().First();
|
||||
|
||||
settingsOverlay.SectionsContainer.ScrollTo(settingsOverlay.ChildrenOfType<AfToggleSection>().Single());
|
||||
});
|
||||
|
||||
Clear();
|
||||
|
||||
AddRange(new Drawable[]
|
||||
{
|
||||
new OsuTextFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
Text = "..on second thought, no more toggles for you."
|
||||
},
|
||||
new SettingsButtonV2
|
||||
{
|
||||
Text = "But please peppy",
|
||||
Action = () =>
|
||||
{
|
||||
if (Children.Count < 5 || RNG.NextSingle() > 0.08f)
|
||||
{
|
||||
audio.Samples.Get("Gameplay/sectionfail")?.Play();
|
||||
Add(new OsuTextFlowContainer(p => p.Font = OsuFont.Default.With(size: RNG.Next(10, 30)))
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
Text = "no"
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
audio.Samples.Get("Gameplay/sectionpass")?.Play();
|
||||
reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
private void reset()
|
||||
{
|
||||
Clear();
|
||||
|
||||
words = new List<string>(
|
||||
[
|
||||
"toggle", "toggleability", "inversion", "momentum", "uncertainty", "viscosity", "gravity", "shyness", "peer pressure", "amnesia", "rebellion", "telepathy", "commitment issues",
|
||||
"democracy", "entropy", "recursion", "quantum superposition", "paperclips", "stubbornness", "existentialism", "nostalgia", "anxiety", "procrastination", "synesthesia",
|
||||
"narcissism",
|
||||
"chaos",
|
||||
"determinism", "nihilism", "optimism", "pessimism", "apathy", "enthusiasm", "seven twenty seven", "lethargy", "hyperactivity", "confusion", "clarity", "ambiguity", "precision",
|
||||
"vagueness",
|
||||
"specificity", "generality", "locality", "annihilation", "nonlocality", "causality", "acausality", "reversibility", "irreversibility", "coherence", "decoherence", "entanglement",
|
||||
"disentanglement", "superposition"
|
||||
]);
|
||||
|
||||
heroActions = new List<Action<ValueChangedEvent<bool>>>
|
||||
{
|
||||
val => target.FadeColour(OsuColour.Gray(val.NewValue ? 0.5f : 1), 2500, Easing.OutPow10),
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
{
|
||||
target.ScaleTo(new Vector2(RNG.NextBool() ? -1 : 1, RNG.NextBool() ? -1 : 1))
|
||||
.Delay(1500)
|
||||
.ScaleTo(Vector2.One);
|
||||
}
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
{
|
||||
target.FadeColour(new Color4(
|
||||
(byte)RNG.Next(200, 255),
|
||||
(byte)RNG.Next(200, 255),
|
||||
(byte)RNG.Next(200, 255),
|
||||
255), 1500, Easing.OutQuint);
|
||||
}
|
||||
else
|
||||
target.FadeColour(Color4.White, 2000);
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
target.RotateTo(RNG.NextSingle(-2f, 2f), 4000, Easing.InOutSine);
|
||||
else
|
||||
target.RotateTo(0, 4000, Easing.InOutSine);
|
||||
},
|
||||
val => target.ScaleTo(val.NewValue ? 1.05f : 1f, 3000, Easing.OutQuint),
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
target.ScaleTo(1.02f, 2000, Easing.InOutSine).Then().ScaleTo(0.98f, 2000, Easing.InOutSine).Loop();
|
||||
else
|
||||
target.ScaleTo(1f, 1000);
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
{
|
||||
var colours = new[] { new Color4(255, 230, 230, 255), new Color4(230, 255, 230, 255), new Color4(230, 230, 255, 255) };
|
||||
target.FadeColour(colours[RNG.Next(0, colours.Length)], 300).Loop();
|
||||
}
|
||||
else
|
||||
target.FadeColour(Color4.White, 3000);
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
target.MoveToX(10, 500, Easing.OutQuad).Then().MoveToY(0, 500, Easing.InQuad);
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
target.MoveToY(-10, 500, Easing.OutQuad).Then().MoveToY(0, 500, Easing.InQuad);
|
||||
},
|
||||
_ => game.ChildrenOfType<Toolbar.Toolbar>().FirstOrDefault()?.ToggleVisibility(),
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
audio.TrackMixer.AddEffect(chorusParameters);
|
||||
else
|
||||
audio.TrackMixer.RemoveEffect(chorusParameters);
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
audio.TrackMixer.AddEffect(autoWahParameters);
|
||||
else
|
||||
audio.TrackMixer.RemoveEffect(autoWahParameters);
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
audio.TrackMixer.AddEffect(phaserParameters);
|
||||
else
|
||||
audio.TrackMixer.RemoveEffect(phaserParameters);
|
||||
},
|
||||
|
||||
// game blinks at you
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
{
|
||||
target.ScaleTo(new Vector2(1, 0), 50, Easing.OutQuint)
|
||||
.Then().ScaleTo(Vector2.One, 50, Easing.OutQuint);
|
||||
}
|
||||
},
|
||||
|
||||
// messing with balance
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
{
|
||||
audio.AddAdjustment(AdjustableProperty.Balance, balanceAdjustment);
|
||||
this.TransformBindableTo(balanceAdjustment, 0.3f, 5_000)
|
||||
.Then().TransformBindableTo(balanceAdjustment, 0.7f, 10_000)
|
||||
.Then().TransformBindableTo(balanceAdjustment, 0.5f, 5_000)
|
||||
.Loop();
|
||||
}
|
||||
else
|
||||
{
|
||||
audio.RemoveAdjustment(AdjustableProperty.Balance, balanceAdjustment);
|
||||
}
|
||||
},
|
||||
|
||||
// do a barrel roll! (press Z or R twice)
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
{
|
||||
target.RotateTo(360, 1000)
|
||||
.Then().RotateTo(0);
|
||||
}
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
{
|
||||
if (dvdLogo == null)
|
||||
{
|
||||
target.Add(dvdLogo = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Depth = float.MinValue,
|
||||
Size = new Vector2(30),
|
||||
Texture = textures.Get(@"Menu/logo"),
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()),
|
||||
Alpha = 0,
|
||||
});
|
||||
}
|
||||
|
||||
dvdLogo.Alpha = 1;
|
||||
dvdLogoMovement = host.UpdateThread.Scheduler.AddDelayed(() =>
|
||||
{
|
||||
var logoPosition = dvdLogo.ScreenSpaceDrawQuad;
|
||||
var bounds = target.ScreenSpaceDrawQuad;
|
||||
|
||||
if (logoPosition.TopLeft.X < bounds.TopLeft.X)
|
||||
dvdLogoVelocity = new Vector2(0.005f, dvdLogoVelocity.Y);
|
||||
else if (logoPosition.BottomRight.X > bounds.BottomRight.X)
|
||||
dvdLogoVelocity = new Vector2(-0.005f, dvdLogoVelocity.Y);
|
||||
|
||||
if (logoPosition.TopLeft.Y < bounds.TopLeft.Y)
|
||||
dvdLogoVelocity = new Vector2(dvdLogoVelocity.X, 0.005f);
|
||||
else if (logoPosition.BottomRight.Y > bounds.BottomRight.Y)
|
||||
dvdLogoVelocity = new Vector2(dvdLogoVelocity.X, -0.005f);
|
||||
|
||||
dvdLogo.Position += dvdLogoVelocity;
|
||||
}, 15, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
dvdLogo?.Hide();
|
||||
dvdLogoMovement?.Cancel();
|
||||
}
|
||||
},
|
||||
val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
{
|
||||
string[] samples =
|
||||
[
|
||||
"Keyboard/key-caps.mp3",
|
||||
"Keyboard/key-confirm.mp3",
|
||||
"Keyboard/key-delete.mp3",
|
||||
"Keyboard/key-movement.mp3",
|
||||
"Keyboard/key-press-1.mp3",
|
||||
"Keyboard/key-press-2.mp3",
|
||||
"Keyboard/key-press-3.mp3",
|
||||
"Keyboard/key-press-4.mp3",
|
||||
"Keyboard/deselect.wav",
|
||||
"Keyboard/key-invalid.wav",
|
||||
"Keyboard/select-all.wav",
|
||||
"Keyboard/select-char.wav",
|
||||
"Keyboard/select-word.wav"
|
||||
];
|
||||
|
||||
var repeat = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
audio.Samples.Get(samples[RNG.Next(0, samples.Length)])?.Play();
|
||||
}, 100, true);
|
||||
|
||||
Scheduler.AddDelayed(repeat.Cancel, 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
addNewToggle();
|
||||
}
|
||||
|
||||
private void doRandomThing()
|
||||
{
|
||||
// avoid runaway if settings panel closes
|
||||
if (Math.Abs(Clock.CurrentTime - lastUpdate) > 100)
|
||||
return;
|
||||
|
||||
tasks.Add(host.UpdateThread.Scheduler.AddDelayed(() =>
|
||||
{
|
||||
var formCheckBoxes = getCheckboxes();
|
||||
|
||||
if (heroActions.Count > 0 && RNG.NextSingle() > 0.5f)
|
||||
{
|
||||
addNewToggle();
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var c in formCheckBoxes.Take(Math.Max(1, formCheckBoxes.Length / 8)))
|
||||
{
|
||||
if (RNG.NextSingle() > 0.5f && formCheckBoxes.Count(b => !b.Current.Disabled) > 5)
|
||||
c.Current.Disabled = !c.Current.Disabled;
|
||||
|
||||
if (c.Current.Disabled && RNG.NextSingle() > 0.4f)
|
||||
c.Current.Disabled = false;
|
||||
|
||||
if (RNG.NextSingle() > 0.3f)
|
||||
c.TriggerClick();
|
||||
}
|
||||
}, RNG.Next(400, 2000)));
|
||||
}
|
||||
|
||||
private FormCheckBox[] getCheckboxes() =>
|
||||
Children.OfType<SettingsItemV2>().Select(s => s.Control)
|
||||
.OfType<FormCheckBox>()
|
||||
.OrderBy(_ => RNG.Next(-1, 1))
|
||||
.ToArray();
|
||||
|
||||
private void addNewToggle()
|
||||
{
|
||||
if (words.Count == 0)
|
||||
return;
|
||||
|
||||
FormCheckBox checkbox;
|
||||
|
||||
string word = words[RNG.Next(0, words.Count)];
|
||||
words.Remove(word);
|
||||
|
||||
Add(new SettingsItemV2(checkbox = new FormCheckBox
|
||||
{
|
||||
Caption = $"Toggle {word}"
|
||||
})
|
||||
{
|
||||
Depth = RNG.NextSingle(),
|
||||
});
|
||||
|
||||
checkbox.Current.BindValueChanged(val =>
|
||||
{
|
||||
if (val.NewValue)
|
||||
doRandomThing();
|
||||
});
|
||||
|
||||
if (RNG.NextSingle() > 0.6f)
|
||||
{
|
||||
int i = RNG.Next(0, heroActions.Count);
|
||||
checkbox.Current.BindValueChanged(heroActions[i]);
|
||||
heroActions.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
@@ -30,7 +31,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
protected override IEnumerable<SettingsSection> CreateSections()
|
||||
{
|
||||
return new List<SettingsSection>
|
||||
var sections = new List<SettingsSection>
|
||||
{
|
||||
// This list should be kept in sync with ScreenBehaviour.
|
||||
new GeneralSection(),
|
||||
@@ -45,6 +46,12 @@ namespace osu.Game.Overlays
|
||||
new MaintenanceSection(),
|
||||
new DebugSection()
|
||||
};
|
||||
|
||||
var today = DateTimeOffset.Now;
|
||||
if (today.Month == 4 && today.Day == 1)
|
||||
sections.Insert(9, new AfToggleSection());
|
||||
|
||||
return sections;
|
||||
}
|
||||
|
||||
private readonly List<SettingsSubPanel> subPanels = new List<SettingsSubPanel>();
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Realm" Version="20.1.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2026.318.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2026.312.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2026.331.0" />
|
||||
<PackageReference Include="Sentry" Version="6.2.0" />
|
||||
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
|
||||
<PackageReference Include="SharpCompress" Version="0.47.0" />
|
||||
|
||||
Reference in New Issue
Block a user