Skip to content

Commit

Permalink
Result screen 😲
Browse files Browse the repository at this point in the history
  • Loading branch information
kinsi55 committed Dec 25, 2021
1 parent 1a5d7b3 commit fc70fbb
Show file tree
Hide file tree
Showing 14 changed files with 349 additions and 87 deletions.
11 changes: 9 additions & 2 deletions AppLogic/MapPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public void SetDiffValid(BeatmapDifficulty diff) {
}
}

public IPreviewBeatmapLevel[] allLevels { get; private set; }
public ValidSong[] filteredLevels { get; private set; }
public IReadOnlyDictionary<string, int> requestableLevels { get; private set; }

Expand All @@ -60,6 +61,7 @@ public string GetHashFromBeatsaverId(string mapKey) {
public void Clear() {
filteredLevels = null;
requestableLevels = null;
allLevels = null;
}

public void Dispose() => Clear();
Expand All @@ -70,8 +72,11 @@ public async Task ProcessBeatmapPool() {
var maps = beatmapLevelsModel
.allLoadedBeatmapLevelPackCollection.beatmapLevelPacks
.Where(x => !(x is PreviewBeatmapLevelPackSO))
.SelectMany(x => x.beatmapLevelCollection.beatmapLevels)
.Where(x => x.songDuration - x.songTimeOffset >= minLength);
.SelectMany(x => x.beatmapLevelCollection.beatmapLevels);

allLevels = maps.ToArray();

maps = maps.Where(x => x.songDuration - x.songTimeOffset >= minLength);

ConditionalWeakTable<IPreviewBeatmapLevel, BeatmapDifficulty[]> playlistSongs = null;

Expand Down Expand Up @@ -248,6 +253,8 @@ public static string GetHashOfLevelid(string levelid) {

return levelid.Substring(13, 40);
}

// Removes WIP etc from the end of the levelID that SongCore happens to add for duplicate songs with the same hash
public static string GetLevelIdWithoutUniquenessAddition(string levelid) {
if(levelid.Length <= 53)
return levelid;
Expand Down
2 changes: 1 addition & 1 deletion AppLogic/RequestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private void Twitch_OnTextMessageReceived(IChatService _, IChatMessage message)
if(diff == -1)
diff = (int)theMappe.GetRandomValidDiff();

var queued = songQueueManager.EnqueueSong(new QueuedSong(
var queued = songQueueManager.EnqueueSong(new ShaffuruSong(
$"custom_level_{hash}",
diff,
startTime,
Expand Down
49 changes: 49 additions & 0 deletions AppLogic/ShaffuruSongList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Shaffuru.AppLogic {
public class ShaffuruSong {
public string levelId { get; protected set; }
public int diffIndex { get; protected set; } = -1;
public float startTime { get; protected set; }
public float length { get; protected set; }
public string source { get; protected set; }

public IPreviewBeatmapLevel level { get; protected set; }

public ShaffuruSong(string levelId, int diffIndex, float startTime = -1, float length = -1, string source = null) {
this.levelId = levelId;
this.diffIndex = diffIndex;
this.startTime = startTime;
this.length = length;
this.source = source;
}

public ShaffuruSong(string levelId, BeatmapDifficulty diff, float startTime = -1, float length = -1, string source = null) {
this.levelId = levelId;
this.diffIndex = (int)diff;
this.startTime = startTime;
this.length = length;
this.source = source;
}
}

class ShaffuruSongList {
protected readonly List<ShaffuruSong> _list;

public IReadOnlyList<ShaffuruSong> list => _list;

public ShaffuruSongList(ShaffuruSong[] songs = null) {
_list = songs?.ToList() ?? new List<ShaffuruSong>(69);
}
}

class PlayedSongList : ShaffuruSongList {
public void Clear() => _list.Clear();

public void Add(ShaffuruSong song) => _list.Add(song);
}
}
70 changes: 30 additions & 40 deletions AppLogic/SongQueueManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,28 @@

namespace Shaffuru.AppLogic {
class SongQueueManager {
public class QueuedSong {
public string levelId { get; private set; }
public int diffIndex { get; private set; } = -1;
public float startTime { get; private set; }
public float length { get; private set; }
public string source { get; private set; }

public QueuedSong(string levelId, int diffIndex, float startTime = -1, float length = -1, string source = null) {
this.levelId = levelId;
this.diffIndex = diffIndex;
this.startTime = startTime;
this.length = length;
this.source = source;
}

public QueuedSong(string levelId, BeatmapDifficulty diff, float startTime = -1, float length = -1, string source = null) {
this.levelId = levelId;
this.diffIndex = (int)diff;
this.startTime = startTime;
this.length = length;
this.source = source;
}
}

static Queue<QueuedSong> queue;
public static RollingList<string> history { get; private set; }
static Queue<ShaffuruSong> queue;
public static RollingList<string> requeueBlockList { get; private set; }

readonly MapPool mapPool;

public SongQueueManager(MapPool mapPool) {
this.mapPool = mapPool;

queue ??= new Queue<QueuedSong>();
queue ??= new Queue<ShaffuruSong>();

if(history == null) {
history = new RollingList<string>(Config.Instance.queue_requeueLimit);
if(requeueBlockList == null) {
requeueBlockList = new RollingList<string>(Config.Instance.queue_requeueLimit);
} else {
history.SetSize(Config.Instance.queue_requeueLimit);
requeueBlockList.SetSize(Config.Instance.queue_requeueLimit);
}
}

public bool EnqueueSong(string levelId, BeatmapDifficulty difficulty, float startTime = -1, float length = -1, string source = null) {
return EnqueueSong(new QueuedSong(levelId, difficulty, startTime, length, source));
return EnqueueSong(new ShaffuruSong(levelId, difficulty, startTime, length, source));
}

public bool EnqueueSong(QueuedSong queuedSong) {
public bool EnqueueSong(ShaffuruSong queuedSong) {
if(IsFull())
return false;

Expand All @@ -63,20 +39,34 @@ public bool EnqueueSong(QueuedSong queuedSong) {

public void Clear() => queue?.Clear();

public QueuedSong DequeueSong() {
if(queue.Count == 0)
return null;
public ShaffuruSong GetNextSong() {
ShaffuruSong x;

if(queue.Count == 0) {
var levels = mapPool.filteredLevels.Where(x => !SongQueueManager.requeueBlockList.Contains(x.level.levelID));

var x = queue.Dequeue();
// Shouldnt ever be the case, failsafe
if(levels.Count() == 0)
return null;

// Basegame always Initializes the RNG with seed 0 on scene change.. That would be kinda not very RNG probably maybe. Cant hurt.
UnityEngine.Random.InitState((int)DateTime.Now.Ticks);

var l = levels.ElementAt(UnityEngine.Random.Range(0, levels.Count()));

x = new ShaffuruSong(l.level.levelID, l.GetRandomValidDiff(), -1, -1, null);
} else {
x = queue.Dequeue();
}

history.Add(MapPool.GetLevelIdWithoutUniquenessAddition(x.levelId));
requeueBlockList.Add(MapPool.GetLevelIdWithoutUniquenessAddition(x.levelId));

return x;
}

public int Count(Func<QueuedSong, bool> action) => queue.Count(action);
public bool Contains(Func<QueuedSong, bool> action) => queue.Any(action);
public bool IsInHistory(string levelId) => history?.Contains(MapPool.GetLevelIdWithoutUniquenessAddition(levelId)) == true;
public int Count(Func<ShaffuruSong, bool> action) => queue.Count(action);
public bool Contains(Func<ShaffuruSong, bool> action) => queue.Any(action);
public bool IsInHistory(string levelId) => requeueBlockList.Contains(MapPool.GetLevelIdWithoutUniquenessAddition(levelId)) == true;
public bool IsEmpty() => queue.Count == 0;

public bool IsFull() => queue.Count >= Config.Instance.queue_sizeLimit;
Expand Down
34 changes: 12 additions & 22 deletions GameLogic/QueueProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,25 @@ class QueueProcessor : IInitializable, ITickable {
static readonly FieldInfo FIELD_PauseMenuManager_InitData_beatmapDifficulty = AccessTools.Field(typeof(PauseMenuManager.InitData), "beatmapDifficulty");
readonly PauseMenuManager.InitData pauseMenuManager_InitData;


readonly PlayedSongList playedSongList;

public QueueProcessor(
BeatmapLoader beatmapLoader,
BeatmapSwitcher beatmapSwitcher,
SongQueueManager songQueueManager,
MapPool mapPool,
AudioTimeSyncController audioTimeSyncController,
PauseMenuManager.InitData pauseMenuManager_InitData
PauseMenuManager.InitData pauseMenuManager_InitData,
PlayedSongList playedSongList
) {
this.beatmapLoader = beatmapLoader;
this.beatmapSwitcher = beatmapSwitcher;
this.songQueueManager = songQueueManager;
this.mapPool = mapPool;
this.audioTimeSyncController = audioTimeSyncController;
this.pauseMenuManager_InitData = pauseMenuManager_InitData;
this.playedSongList = playedSongList;
}

public void Initialize() {
Expand All @@ -49,7 +54,7 @@ public void Initialize() {
bool isQueueingNewSong = false;

public async void Tick() {
if(audioTimeSyncController.songTime < switchToNextBeatmapAt || isQueueingNewSong)
if(isQueueingNewSong || audioTimeSyncController.songTime < switchToNextBeatmapAt)
return;

// Dont queue a new song in the last 5 seconds... Kinda pointless
Expand All @@ -58,27 +63,10 @@ public async void Tick() {

isQueueingNewSong = true;

var queuedSong = songQueueManager.DequeueSong();

if(queuedSong == null) {
if(!Config.Instance.queue_pickRandomSongIfEmpty)
return;

var levels = mapPool.filteredLevels.Where(x => !SongQueueManager.history.Contains(x.level.levelID));

// Shouldnt ever be the case, failsafe
if(levels.Count() == 0)
return;
var queuedSong = songQueueManager.GetNextSong();

// Basegame always Initializes the RNG with seed 0 on scene change.. That would be kinda not very RNG probably maybe. Cant hurt.
UnityEngine.Random.InitState((int)DateTime.Now.Ticks);

var x = levels.ElementAt(UnityEngine.Random.Range(0, levels.Count()));

queuedSong = new QueuedSong(x.level.levelID, x.GetRandomValidDiff(), -1, -1, null);

SongQueueManager.history.Add(x.level.levelID);
}
if(queuedSong == null)
return;

IDifficultyBeatmap outDiff = null;
IReadonlyBeatmapData outBeatmap = null;
Expand Down Expand Up @@ -157,6 +145,8 @@ await Task.Run(async () => {

beatmapSwitcher.SwitchToDifferentBeatmap(outDiff, outBeatmap, startTime, length);

playedSongList.Add(new ShaffuruSong(queuedSong.levelId, outDiff.difficulty, startTime, length, queuedSong.source));

FIELD_PauseMenuManager_InitData_previewBeatmapLevel.SetValue(pauseMenuManager_InitData, loadedBeatmap.beatmapLevel);
FIELD_PauseMenuManager_InitData_beatmapDifficulty.SetValue(pauseMenuManager_InitData, outDiff.difficulty);

Expand Down
2 changes: 2 additions & 0 deletions Installers/AppInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
namespace Shaffuru.Installers {
class AppInstaller : MonoInstaller {
public override void InstallBindings() {
Container.Bind<PlayedSongList>().FromInstance(new PlayedSongList()).AsSingle();

Container.BindInterfacesAndSelfTo<MapPool>().AsSingle().NonLazy();
Container.BindInterfacesAndSelfTo<SongQueueManager>().AsSingle().NonLazy();

Expand Down
5 changes: 3 additions & 2 deletions Installers/MenuInstaller.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Shaffuru.MenuLogic;
using Shaffuru.UI;
using Shaffuru.MenuLogic.UI;
using SiraUtil;
using Zenject;

Expand All @@ -8,7 +8,8 @@ class MenuInstaller : MonoInstaller {
public override void InstallBindings() {
Container.Bind<Anlasser>().AsSingle().NonLazy();
Container.Bind<SetupUI>().FromNewComponentAsViewController().AsSingle();
Container.Bind<IInitializable>().To<SetupFlowCoordinator>().FromNewComponentOnNewGameObject().AsSingle();
Container.Bind<ResultUI>().FromNewComponentAsViewController().AsSingle();
Container.Bind<IInitializable>().To<ShaffuruFlowCoordinator>().FromNewComponentOnNewGameObject().AsSingle();
//Container.Bind<FlowCoordinatorCoordinatorIHateBSUI>().AsSingle().NonLazy();
}
}
Expand Down
11 changes: 10 additions & 1 deletion MenuLogic/Anlasser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ BeatmapCharacteristicCollectionSO beatmapCharacteristicCollectionSO
standardCharacteristic = beatmapCharacteristicCollectionSO.GetBeatmapCharacteristicBySerializedName("Standard");
}

public event Action<LevelCompletionResults> finishedOrFailedCallback;

public void Start(int lengthSeconds) {
beatmapLevel.beatmapLevelData.audioClip?.UnloadAudioData();

Expand Down Expand Up @@ -84,8 +86,15 @@ public void Start(int lengthSeconds) {
null,
(a, b) => {
// TODO: Handle other cases in some way maybe? Some end stats screen?
if(b.levelEndAction == LevelCompletionResults.LevelEndAction.Restart)
if(b.levelEndAction == LevelCompletionResults.LevelEndAction.Restart) {
Start(lengthSeconds);
} else if(b.levelEndStateType == LevelCompletionResults.LevelEndStateType.Cleared ||
b.levelEndStateType == LevelCompletionResults.LevelEndStateType.Failed ||
// If user is dum dum and plays with nofail and then backs out to menu we show this too because we are nice :)
b.energy == 0f
) {
finishedOrFailedCallback?.Invoke(b);
}
}
);
}
Expand Down
Loading

0 comments on commit fc70fbb

Please # to comment.