using System.Collections.Generic; using System.Linq; using System.Reflection.Metadata; using Godot; using WacK.Configuration; using WacK.Data.Chart; using WacK.Scenes; namespace WacK.Things.TunnelObjects { public partial class THNoteHold : THNotePlay { public NoteHold holdData; private Node2D longThing; public void InitHold(NoteHold noteData, Control holdScroll) { holdData = noteData; BuildLongThing(holdScroll); } // Create longThing in segments. private void BuildLongThing(Control holdScroll) { longThing = new Node2D(); holdScroll.AddChild(longThing); longThing.Position = new Vector2(0, (float)-holdData.time * Play.ScrollPxPerSec); // don't draw invisible hold-mids var drawableMids = holdData.points.Values.Where(e => e.type != NotePlayType.HoldMidInvis).ToList(); if (drawableMids.Count > 0) { var lastMid = holdData.points.Values[^1]; if (drawableMids[^1] != lastMid) drawableMids.Add(lastMid); } else // would most likely happen if HoldEnd is missing drawableMids = holdData.points.Values.ToList(); if (drawableMids.Count() > 0) { NotePlay lastHold = holdData; float segmentPos = 0; foreach (var curNote in drawableMids) { var curLength = Play.ScrollPxPerSec * (float)(curNote.time - lastHold.time); var segment = CreateSegment(lastHold, curNote); longThing.AddChild(segment); segment.Position = new Vector2(0, segmentPos); segmentPos -= curLength; lastHold = curNote; } } else { GD.PrintErr("Tried to create a Hold note's long with no drawable segments!"); } } private Polygon2D CreateSegment(NotePlay origin, NotePlay destination) { float minuteSize = Constants.BASE_2D_RESOLUTION / 60; var length = Play.ScrollPxPerSec * (float)(destination.time - origin.time); var verts = new Vector2[4]; int correctedDestPos = Util.NearestMinute((int) origin.pos, (int) destination.pos); var (originPosPx, originSizePx) = Util.PixelizeNote((int)origin.pos, (int)origin.size); var (destPosPx, destSizePx) = Util.PixelizeNote(correctedDestPos, (int)destination.size); verts[0] = new Vector2(originPosPx, 0); verts[1] = new Vector2(verts[0].X + originSizePx, 0); verts[2] = new Vector2(destPosPx + destSizePx, -length); verts[3] = new Vector2(destPosPx, -length); var segment = new Polygon2D() { Polygon = verts, Antialiased = true }; // draw overflow var originFinalPos = origin.pos + origin.size; var destinationFinalPos = correctedDestPos + destination.size; if (originFinalPos > 60 || destinationFinalPos > 60) { var subSegment = new Polygon2D() { Polygon = verts, Antialiased = true }; subSegment.Translate(new Vector2(-Constants.BASE_2D_RESOLUTION, 0)); segment.AddChild(subSegment); } if (originFinalPos < 60 || destinationFinalPos < 60) { var subSegment = new Polygon2D() { Polygon = verts, Antialiased = true }; subSegment.Translate(new Vector2(Constants.BASE_2D_RESOLUTION, 0)); segment.AddChild(subSegment); } segment.Modulate = new Color("#FFFFFFD0"); return segment; } } }