2023-09-17 01:24:53 -07:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2023-09-16 00:40:36 -07:00
|
|
|
using System.Reflection.PortableExecutable;
|
2023-07-30 00:22:03 -07:00
|
|
|
using Godot;
|
2023-09-17 23:51:50 -07:00
|
|
|
using WacK.Configuration;
|
2023-09-15 12:00:12 -07:00
|
|
|
using WacK.Data.Chart;
|
|
|
|
|
using WacK.Data.Mer;
|
2023-09-16 00:40:36 -07:00
|
|
|
using WacK.Things.TunnelObjects;
|
2023-07-30 00:22:03 -07:00
|
|
|
|
|
|
|
|
namespace WacK.Scenes
|
|
|
|
|
{
|
|
|
|
|
public class PlayParameters
|
|
|
|
|
{
|
|
|
|
|
/* TODO: store song ID from internal database
|
|
|
|
|
public string songID;
|
|
|
|
|
public Difficulty diff;
|
|
|
|
|
*/
|
|
|
|
|
public string chartPath;
|
|
|
|
|
public string soundPath;
|
|
|
|
|
|
|
|
|
|
public PlayParameters(string chPath, string snPath)
|
|
|
|
|
{
|
|
|
|
|
chartPath = chPath;
|
|
|
|
|
soundPath = snPath;
|
2023-09-29 16:16:44 -07:00
|
|
|
GD.Print($"Chart: {chartPath}\nSound: {soundPath}");
|
2023-07-30 00:22:03 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public partial class Play : Node
|
|
|
|
|
{
|
|
|
|
|
// initialized by another scene, BEFORE loading this one!
|
|
|
|
|
public static PlayParameters playParams;
|
|
|
|
|
|
2023-09-16 00:40:36 -07:00
|
|
|
// TunnelObjects we can instantiate
|
2023-09-16 18:54:35 -07:00
|
|
|
public static PackedScene noteTouch = GD.Load<PackedScene>("res://Things/TunnelObjects/Notes/NoteTouch.tscn");
|
|
|
|
|
public static PackedScene noteHold = GD.Load<PackedScene>("res://Things/TunnelObjects/Notes/NoteHold.tscn");
|
2023-09-28 01:58:50 -07:00
|
|
|
public static PackedScene noteChain = GD.Load<PackedScene>("res://Things/TunnelObjects/Notes/NoteChain.tscn");
|
2023-09-29 17:48:09 -07:00
|
|
|
public static PackedScene noteCW = GD.Load<PackedScene>("res://Things/TunnelObjects/Notes/NoteSwipeCW.tscn");
|
|
|
|
|
public static PackedScene noteCCW = GD.Load<PackedScene>("res://Things/TunnelObjects/Notes/NoteSwipeCCW.tscn");
|
|
|
|
|
public static PackedScene noteIn = GD.Load<PackedScene>("res://Things/TunnelObjects/Notes/NoteSnapIn.tscn");
|
|
|
|
|
public static PackedScene noteOut = GD.Load<PackedScene>("res://Things/TunnelObjects/Notes/NoteSnapOut.tscn");
|
2023-09-16 00:40:36 -07:00
|
|
|
|
2023-09-29 16:16:44 -07:00
|
|
|
[ExportCategory("Audio")]
|
|
|
|
|
[Export]
|
|
|
|
|
private BGM bgmController;
|
|
|
|
|
[Export]
|
|
|
|
|
private SFX sfxController;
|
|
|
|
|
|
|
|
|
|
[ExportCategory("2D")]
|
|
|
|
|
[ExportSubgroup("2D Things")]
|
2023-09-16 00:40:36 -07:00
|
|
|
[Export]
|
|
|
|
|
public Control noteDisplay;
|
2023-09-16 18:54:35 -07:00
|
|
|
[Export]
|
|
|
|
|
public Control scrollDisplay;
|
2023-09-17 16:26:08 -07:00
|
|
|
[Export]
|
|
|
|
|
public Background background;
|
2023-09-16 00:40:36 -07:00
|
|
|
|
2023-09-29 16:16:44 -07:00
|
|
|
[ExportSubgroup("Out-of-bounds Viewports")]
|
2023-09-17 00:12:09 -07:00
|
|
|
[Export]
|
|
|
|
|
public Viewport mainViewport;
|
|
|
|
|
[Export]
|
|
|
|
|
public Viewport leftViewport;
|
|
|
|
|
[Export]
|
|
|
|
|
public Viewport rightViewport;
|
|
|
|
|
|
2023-09-15 12:00:12 -07:00
|
|
|
private Chart chart;
|
2023-09-29 23:49:56 -07:00
|
|
|
// Indices point to the NEXT thing in chart to look for. We process
|
|
|
|
|
// that thing once the song time is at or later than the thing's time.
|
|
|
|
|
private int playNextIdx = 0;
|
2023-09-29 22:37:40 -07:00
|
|
|
private int eventNextIdx = 0;
|
2023-07-30 00:22:03 -07:00
|
|
|
|
2023-09-17 23:09:19 -07:00
|
|
|
// base scroll speed, which we can apply multipliers on
|
|
|
|
|
public static readonly float BASE_PIXELS_PER_SECOND = 800;
|
2023-09-29 22:37:40 -07:00
|
|
|
public static float ScrollPxPerSec
|
2023-09-17 23:51:50 -07:00
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2023-09-18 00:28:54 -07:00
|
|
|
return BASE_PIXELS_PER_SECOND * PlaySettings.playSpeedMultiplier.Value;
|
2023-09-17 23:51:50 -07:00
|
|
|
}
|
|
|
|
|
}
|
2023-09-16 18:54:35 -07:00
|
|
|
|
2023-09-15 12:00:12 -07:00
|
|
|
public override void _Ready()
|
2023-09-17 00:12:09 -07:00
|
|
|
{
|
|
|
|
|
// so we can see objects outside of the 0-60min. region
|
|
|
|
|
leftViewport.World2D = mainViewport.World2D;
|
|
|
|
|
rightViewport.World2D = mainViewport.World2D;
|
|
|
|
|
|
2023-09-16 00:40:36 -07:00
|
|
|
// parse mer and create chart for current play
|
2023-09-15 12:00:12 -07:00
|
|
|
chart = new(playParams.chartPath);
|
2023-09-29 22:37:40 -07:00
|
|
|
InstantiateChartVisuals();
|
2023-09-29 16:16:44 -07:00
|
|
|
|
2023-09-29 22:37:40 -07:00
|
|
|
// // audio setup
|
2023-09-29 16:16:44 -07:00
|
|
|
bgmController.LoadFromUser(playParams.soundPath);
|
|
|
|
|
bgmController.Play();
|
2023-09-29 22:37:40 -07:00
|
|
|
|
|
|
|
|
// TestBGAnim();
|
2023-09-16 00:40:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2023-09-16 18:54:35 -07:00
|
|
|
/// Instantiates necessary notes onto noteDisplay for the player to see.
|
2023-09-16 00:40:36 -07:00
|
|
|
/// </summary>
|
2023-09-29 22:37:40 -07:00
|
|
|
private void InstantiateChartVisuals()
|
2023-09-16 00:40:36 -07:00
|
|
|
{
|
|
|
|
|
foreach (var msNote in chart.playNotes)
|
|
|
|
|
{
|
|
|
|
|
foreach (var note in msNote.Value)
|
|
|
|
|
{
|
|
|
|
|
THNotePlay nNote;
|
2023-09-16 18:54:35 -07:00
|
|
|
switch (note.type)
|
2023-09-16 00:40:36 -07:00
|
|
|
{
|
2023-09-16 18:54:35 -07:00
|
|
|
case NotePlayType.HoldStart:
|
|
|
|
|
nNote = noteHold.Instantiate<THNoteHold>();
|
2023-09-17 23:09:19 -07:00
|
|
|
((THNoteHold)nNote).InitHold((NoteHold)note, scrollDisplay);
|
2023-09-16 18:54:35 -07:00
|
|
|
break;
|
|
|
|
|
case NotePlayType.Touch:
|
|
|
|
|
nNote = noteTouch.Instantiate<THNotePlay>();
|
2023-09-16 00:40:36 -07:00
|
|
|
break;
|
2023-09-29 17:48:09 -07:00
|
|
|
case NotePlayType.Chain:
|
2023-09-28 01:58:50 -07:00
|
|
|
nNote = noteChain.Instantiate<THNotePlay>();
|
|
|
|
|
break;
|
2023-09-29 17:48:09 -07:00
|
|
|
case NotePlayType.SwipeCW:
|
|
|
|
|
nNote = noteCW.Instantiate<THNotePlay>();
|
|
|
|
|
break;
|
|
|
|
|
case NotePlayType.SwipeCCW:
|
|
|
|
|
nNote = noteCCW.Instantiate<THNotePlay>();
|
|
|
|
|
break;
|
|
|
|
|
case NotePlayType.SnapIn:
|
|
|
|
|
nNote = noteIn.Instantiate<THNotePlay>();
|
|
|
|
|
break;
|
|
|
|
|
case NotePlayType.SnapOut:
|
|
|
|
|
nNote = noteOut.Instantiate<THNotePlay>();
|
|
|
|
|
break;
|
2023-09-16 18:54:35 -07:00
|
|
|
default:
|
|
|
|
|
continue;
|
2023-09-16 00:40:36 -07:00
|
|
|
}
|
|
|
|
|
nNote.Init(note);
|
|
|
|
|
var nPos = nNote.Position;
|
2023-09-29 22:37:40 -07:00
|
|
|
nPos.Y = msNote.Key * -ScrollPxPerSec;
|
2023-09-16 00:40:36 -07:00
|
|
|
nNote.Position = nPos;
|
|
|
|
|
noteDisplay.AddChild(nNote);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-29 22:37:40 -07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Process current game state. Should only run if playing a chart and unpaused.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void PlayLoop()
|
|
|
|
|
{
|
|
|
|
|
float time = bgmController.CurTime;
|
|
|
|
|
|
|
|
|
|
// check next event
|
|
|
|
|
while (eventNextIdx < chart.events.Count && time >= chart.events.Keys[eventNextIdx])
|
|
|
|
|
{
|
|
|
|
|
var t = chart.events.Keys[eventNextIdx];
|
|
|
|
|
var l = chart.events[t];
|
|
|
|
|
|
|
|
|
|
foreach (var e in l)
|
|
|
|
|
{
|
2023-09-29 23:49:56 -07:00
|
|
|
GD.Print($"Passed event {e.type} at {t}");
|
2023-09-29 22:37:40 -07:00
|
|
|
switch (e.type)
|
|
|
|
|
{
|
|
|
|
|
case NoteEventType.BGAdd:
|
|
|
|
|
background.SetSegments((int)e.pos, (int)e.size, true, (DrawDirection)e.value);
|
|
|
|
|
break;
|
|
|
|
|
case NoteEventType.BGRem:
|
|
|
|
|
background.SetSegments((int)e.pos, (int)e.size, false, (DrawDirection)e.value);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eventNextIdx++;
|
|
|
|
|
}
|
2023-09-29 16:16:44 -07:00
|
|
|
|
2023-09-29 22:37:40 -07:00
|
|
|
// set scroll
|
2023-09-16 00:40:36 -07:00
|
|
|
var nPos = noteDisplay.Position;
|
2023-09-29 22:37:40 -07:00
|
|
|
nPos.Y = time * ScrollPxPerSec;
|
2023-09-16 00:40:36 -07:00
|
|
|
noteDisplay.Position = nPos;
|
2023-09-17 00:12:09 -07:00
|
|
|
scrollDisplay.Position = nPos;
|
2023-09-29 22:37:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void _Process(double delta)
|
|
|
|
|
{
|
|
|
|
|
PlayLoop();
|
2023-09-16 00:40:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnDestroy()
|
2023-07-30 00:22:03 -07:00
|
|
|
{
|
|
|
|
|
playParams = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|