using System.Collections; using System.Collections.Generic; using System.ComponentModel; using Godot; using Godot.Bridge; using Godot.NativeInterop; [ScriptPath("res://Scripts/Resources/DarkWorldTransition.cs")] public partial class DarkWorldTransition : Control { [Export(PropertyHint.None, "")] public Control[] doors; [Export(PropertyHint.None, "")] public CpuParticles2D[] sideParts; [Export(PropertyHint.None, "")] public CpuParticles2D[] partyParts; [Export(PropertyHint.None, "")] public Control cover; [Export(PropertyHint.None, "")] public Sprite2D[] playerSprites; [Export(PropertyHint.None, "")] public Node2D center; [Export(PropertyHint.None, "")] public AudioStreamPlayer[] audios; public static IEnumerator DarkWorldTransitionRoutine(Vector2[] partyPos, Room.IDs target, Vector2[] targetPoints, Vector2 animPoint, bool fast = false, bool setCamAtEnd = true, int blink = 0) { Audio.ChangeMusic(null); Party.UpdateFollowerEntities(); Coroutine c = Coroutine.Start(CameraController.Pan(animPoint, 30f, fixedRate: false)); Room.current.cameraLimit = new Vector2[2] { Vector2.One * -9999f, Vector2.One * 9999f }; Audio.PlaySound("snd_locker_ch1.wav"); Party.ChangeCollider(state: false); Party.LookAt(Vector2.Up); int pamt = SaveFile.current.activeParty.Count; while (!c.done) { for (int i = 0; i < pamt; i++) { Party.party[SaveFile.current.activeParty[i]].oEntity.GlobalPosition = Party.party[SaveFile.current.activeParty[i]].oEntity.GlobalPosition.Lerp(partyPos[i], Main.deltaTime * 0.2f); } yield return null; } Party.SetPosition(in partyPos); float a; if (!fast) { for (a = 0f; a < 30f; a += Main.deltaTime) { yield return null; } } DarkWorldTransition anim = GD.Load("res://Objects/Particles/DarkWorldTransition.tscn").Instantiate(PackedScene.GenEditState.Disabled); Main.instance.AddChild(anim, forceReadableName: false, InternalMode.Disabled); anim.GlobalPosition = animPoint; Vector2[] ppos = new Vector2[pamt]; Vector2 offset = Vector2.Down * 20f; for (int j = 0; j < pamt; j++) { Party.party[SaveFile.current.activeParty[j]].oEntity.anim.Play("ReadyJump"); Party.party[SaveFile.current.activeParty[j]].oEntity.Reparent(anim); ppos[j] = Party.party[SaveFile.current.activeParty[j]].oEntity.GlobalPosition; } a = 0f; float b; for (b = (fast ? 15 : 30); a <= b; a += Main.deltaTime) { for (int k = 0; k < pamt; k++) { Party.party[SaveFile.current.activeParty[k]].oEntity.GlobalPosition = ppos[k].Lerp(ppos[k] + offset, a / b); } yield return null; } Vector2[] mpos = new Vector2[ppos.Length]; for (int l = 0; l < pamt; l++) { ppos[l] = Party.party[SaveFile.current.activeParty[l]].oEntity.GlobalPosition; Party.party[SaveFile.current.activeParty[l]].oEntity.anim.Play("Jumped"); mpos[l] = new Vector2(ppos[l].X, anim.playerSprites[l].GlobalPosition.Y); } c = Coroutine.Start(DarkWorldDoorAnim(anim, fast)); new Vector2(0f, -55f); b = 0f; for (a = (fast ? 60 : 80); b <= a; b += Main.deltaTime) { float weight = Mathf.SmoothStep(0f, 1f, b / a); for (int m = 0; m < pamt; m++) { Party.party[SaveFile.current.activeParty[m]].oEntity.GlobalPosition = ppos[m].Lerp(mpos[m], weight); } yield return null; } if (!fast) { for (a = 0f; a < 30f; a += Main.deltaTime) { yield return null; } } while (!c.done) { yield return null; } anim.audios[0].Play(); anim.sideParts[0].Emitting = true; anim.sideParts[1].Emitting = true; Coroutine twinkle = Coroutine.Start(DarkWorldTwinkles()); for (int n = 0; n < pamt; n++) { anim.playerSprites[n].Texture = GD.Load("res://Sprites/Particles/DWTrans/" + Party.party[SaveFile.current.activeParty[n]].id.ToString() + ".tres"); anim.playerSprites[n].Visible = true; ppos[n] = Party.party[SaveFile.current.activeParty[n]].oEntity.GlobalPosition; anim.playerSprites[n].Offset = Party.party[SaveFile.current.activeParty[n]].oEntity.sprite.Offset; } bool flip = false; a = 0f; for (b = (fast ? 50 : 80); a < b; a += Main.deltaTime) { if (!flip && a / b >= 0.5f) { for (int num = 0; num < pamt; num++) { Party.party[SaveFile.current.activeParty[num]].oEntity.anim.Play("Jumped2"); } flip = true; } for (int num2 = 0; num2 < pamt; num2++) { Party.party[SaveFile.current.activeParty[num2]].oEntity.GlobalPosition = ppos[num2].Lerp(anim.playerSprites[num2].GlobalPosition, Mathf.SmoothStep(0f, 1f, a / b)); } yield return null; } for (int num3 = 0; num3 < pamt; num3++) { anim.playerSprites[num3].GlobalPosition = Party.party[SaveFile.current.activeParty[num3]].oEntity.GlobalPosition; anim.partyParts[num3].GlobalPosition = anim.playerSprites[num3].GlobalPosition; } if (fast) { anim.sideParts[0].Emitting = false; anim.sideParts[1].Emitting = false; } Sprite2D[] blinks = null; Vector2[] bpos = null; if (blink > 0) { Audio.PlaySound("snd_sparkle_glock.wav"); blinks = new Sprite2D[blink]; bpos = new Vector2[blink]; Texture2D texture = GD.Load("res://Sprites/Menus/SavePoint/Save5.tres"); for (int num4 = 0; num4 < blink; num4++) { blinks[num4] = new Sprite2D { Texture = texture, RotationDegrees = Main.RandomRange(0, 90) }; bpos[num4] = new Vector2(anim.GlobalPosition.X + (float)Main.RandomRange(-100, 100), anim.GlobalPosition.Y - 200f); anim.AddChild(blinks[num4], forceReadableName: false, InternalMode.Disabled); } } b = 0f; for (a = (fast ? 100 : 300); b < a; b += Main.deltaTime) { anim.cover.Size = new Vector2(anim.cover.Size.X, Mathf.Lerp(0f, 50f, b / a)); for (int num5 = 0; num5 < pamt; num5++) { if (!anim.partyParts[num5].Emitting) { anim.partyParts[num5].Emitting = true; } anim.partyParts[num5].GlobalPosition += Vector2.Up * 0.175f * Main.deltaTime * ((!fast) ? 1 : 3); if (blink > 0) { for (int num6 = 0; num6 < blink; num6++) { blinks[num6].GlobalPosition = Common.Beizier(anim.playerSprites[0].GlobalPosition + Vector2.Up * 16f, anim.GlobalPosition, bpos[num6], b / a); blinks[num6].RotationDegrees += Main.deltaTime * 0.5f; } } } yield return null; } for (int num7 = 0; num7 < pamt; num7++) { anim.partyParts[num7].Emitting = false; anim.playerSprites[num7].Visible = false; Party.party[SaveFile.current.activeParty[num7]].oEntity.anim.Play("Jumped4"); ppos[num7] = Party.party[SaveFile.current.activeParty[num7]].oEntity.GlobalPosition; mpos[num7] = ppos[num7] + Vector2.Up * 12f; } a = 0f; for (b = 20f; a < b; a += Main.deltaTime) { for (int num8 = 0; num8 < pamt; num8++) { Party.party[SaveFile.current.activeParty[num8]].oEntity.GlobalPosition = ppos[num8].Lerp(mpos[num8], a / b); } yield return null; } for (int num9 = 0; num9 < pamt; num9++) { ppos[num9] = mpos[num9] + Vector2.Down * 200f; Party.party[SaveFile.current.activeParty[num9]].oEntity.doTrail = true; Party.party[SaveFile.current.activeParty[num9]].oEntity.anim.Play("Spin"); } if (!fast) { anim.sideParts[0].Emitting = false; anim.sideParts[1].Emitting = false; } b = 0f; for (a = (fast ? 15 : 30); b <= a; b += Main.deltaTime) { for (int num10 = 0; num10 < pamt; num10++) { Party.party[SaveFile.current.activeParty[num10]].oEntity.GlobalPosition = mpos[num10].Lerp(ppos[num10], b / a); } yield return null; } if (!fast) { for (a = 0f; a < 40f; a += Main.deltaTime) { yield return null; } } Coroutine.Stop(twinkle); anim.audios[0].Stop(); Room.LoadRoom(target); yield return null; CameraController.instance.Position = ((targetPoints.Length == 0) ? targetPoints[0] : targetPoints[0].Lerp(targetPoints[1], 0.5f)); anim.Position = CameraController.instance.Position; for (int num11 = 0; num11 < pamt; num11++) { ppos[num11] = targetPoints[0] + Vector2.Up * 400f; Party.party[SaveFile.current.activeParty[num11]].oEntity.GlobalPosition = Vector2.One * 9999f; } yield return null; a = 0f; for (b = (fast ? 15 : 30); a <= b; a += Main.deltaTime) { for (int num12 = 0; num12 < pamt; num12++) { Party.party[SaveFile.current.activeParty[num12]].oEntity.GlobalPosition = ppos[num12].Lerp(targetPoints[num12], a / b); } yield return null; } Audio.PlaySound("snd_dtrans_flip.ogg"); SaveFile.AddFlag(SaveFile.Flags.IsInDW); for (int num13 = 0; num13 < pamt; num13++) { Party.party[SaveFile.current.activeParty[num13]].oEntity.Shake(10f, 1f); Party.party[SaveFile.current.activeParty[num13]].oEntity.anim.Play("LandDW"); Party.party[SaveFile.current.activeParty[num13]].oEntity.anim.Stop(); Party.party[SaveFile.current.activeParty[num13]].oEntity.animMod = Entity.AnimMods.DW; Party.party[SaveFile.current.activeParty[num13]].oEntity.doTrail = false; } b = 0f; for (a = 20f; b < a; b += Main.deltaTime) { yield return null; } for (int num14 = 0; num14 < pamt; num14++) { Party.party[SaveFile.current.activeParty[num14]].oEntity.anim.Play(); } a = 0f; for (b = 20f; a < b; a += Main.deltaTime) { yield return null; } for (int num15 = 0; num15 < pamt; num15++) { Party.party[SaveFile.current.activeParty[num15]].oEntity.LookAt(Vector2.Down); Party.party[SaveFile.current.activeParty[num15]].oEntity.TopLevel = true; Party.party[SaveFile.current.activeParty[num15]].oEntity.GlobalPosition = targetPoints[num15]; } Party.SortingOrder(110); anim.ZIndex = 100; Audio.PlaySound("snd_him_quick.ogg"); for (int num16 = 0; num16 < 7; num16++) { anim.doors[num16].Visible = num16 == 0; } b = 0f; for (a = 40f; b <= a; b += Main.deltaTime) { anim.Modulate = Main.colorWhite.Lerp(Main.colorClear, b / a); yield return null; } anim.QueueFree(); Player.instance.ResetFollowStep(); Party.Reparent(Room.current); Party.ChangeCollider(state: true); Party.SortingOrder(0); for (int num17 = 0; num17 < pamt; num17++) { Party.party[SaveFile.current.activeParty[num17]].oEntity.TopLevel = false; Party.party[SaveFile.current.activeParty[num17]].oEntity.GlobalPosition = targetPoints[num17]; } if (setCamAtEnd) { a = 0f; for (b = 10f; a < b; a += Main.deltaTime) { yield return null; } c = Coroutine.Start(CameraController.PanToObj(Player.instance, 0.5f)); while (!c.done) { yield return null; } } ConvertItemsToDW(); } private static void ConvertItemsToDW() { if (SaveFile.current.lwItems.Contains(Items.IDs.HomemadeLunch) && !Items.CheckFull(Items.Type.Normal)) { SaveFile.current.lwItems.Remove(Items.IDs.HomemadeLunch); SaveFile.current.dwItems.Add(Items.IDs.KingFeast); } if (SaveFile.current.lwItems.Contains(Items.IDs.KetsukaneHeirloom) && !Items.CheckFull(Items.Type.Equip)) { SaveFile.current.lwItems.Remove(Items.IDs.KetsukaneHeirloom); SaveFile.current.dwArmor.Add(Items.IDs.FoxNecklace); } } private static void ConvertItemsToLW() { if (SaveFile.current.dwArmor.Contains(Items.IDs.FoxNecklace) && !Items.CheckFull(Items.Type.LightWorld)) { SaveFile.current.dwArmor.Remove(Items.IDs.FoxNecklace); SaveFile.current.lwItems.Add(Items.IDs.KetsukaneHeirloom); } } private static IEnumerator DarkWorldTwinkles() { float a = 0f; while (true) { if (a > 0f) { a -= Main.deltaTime; } else { a = Main.RandomRange(15, 20); Audio.PlaySound("snd_dtrans_twinkle.ogg", 1f, Main.RandomRange(0.975f, 1.025f)); } yield return null; } } private static IEnumerator DarkWorldDoorAnim(DarkWorldTransition dwt, bool fast) { for (int i = 0; i < (fast ? 4 : 6); i++) { Audio.PlaySound("snd_dtrans_square.ogg", 1f, fast ? 1.05f : 1f); Coroutine.Start(DarkWorldIndividualDoor(dwt.doors[i])); for (float a = 0f; a < (fast ? 10f : 12f); a += Main.deltaTime) { yield return null; } } } private static IEnumerator DarkWorldIndividualDoor(Control c) { if (Room.current.id != Room.IDs.SchoolCloset) { c.Size = new Vector2(40f, 60f); c.Position = c.Size / -2f; } Vector2 s = c.Size; c.Visible = true; float a = 0f; for (float b = 50f; a <= b; a += Main.deltaTime) { c.Size = s.Lerp(s * 10f, a / b); c.Position = c.Size / -2f; c.PivotOffset = c.Position * -1f; c.RotationDegrees = Mathf.Lerp(0f, 10f, a / b); yield return null; } } public static IEnumerator ReturnToLW() { int party = SaveFile.current.activeParty.Count; Party.ChangeCollider(state: false); Audio.ChangeMusic((Audio.AudioBlock)null, 3f); Party.UpdateFollowerEntities(); Coroutine.Start(CameraController.Pan(CommonEvents.instance.nodes[3].GlobalPosition + Vector2.Up * 40f, 0.75f)); Vector2[] p = Party.GetPositions(); float a; for (a = 0f; a < 10f; a += Main.deltaTime) { for (int i = 0; i < party; i++) { Party.party[SaveFile.current.activeParty[i]].oEntity.GlobalPosition = p[i].Lerp(CommonEvents.instance.nodes[i].GlobalPosition, a / 10f); } yield return null; } Vector2 offset = Vector2.Up * 200f; p = Party.GetPositions(); Audio.PlaySound("snd_dtrans_lw.ogg"); for (int j = 0; j < party; j++) { Party.party[SaveFile.current.activeParty[j]].oEntity.anim.Play("Jumped3"); } CameraController.Transition(Main.colorWhite, 250f); a = 0f; for (float b = 250f; a <= b; a += Main.deltaTime) { for (int k = 0; k < party; k++) { Party.party[SaveFile.current.activeParty[k]].oEntity.GlobalPosition = p[k].Lerp(p[k] + offset, Mathf.SmoothStep(0f, 1f, a / b)); } yield return null; } while (!CameraController.transitionRoutine.done) { yield return null; } yield return null; Room.LoadRoom(Room.IDs.SchoolSupplyCave, reparent: true); CameraController.instance.follow = Player.instance; SaveFile.current.flags.Remove(SaveFile.Flags.IsInDW); yield return null; for (int l = 0; l < party; l++) { Party.party[SaveFile.current.activeParty[l]].oEntity.animMod = Entity.AnimMods.None; Party.party[SaveFile.current.activeParty[l]].oEntity.LookAt(Vector2.Down); Party.party[SaveFile.current.activeParty[l]].oEntity.Position = Room.current.eventPointers[l].GlobalPosition; } for (float b = 0f; b < 30f; b += Main.deltaTime) { yield return null; } CameraController.Transition(Main.colorClear, 100f); while (!CameraController.transitionRoutine.done) { yield return null; } if (!SaveFile.HasFlag(SaveFile.Flags.Day1End)) { TextSystem.GetText("ReturnToLWDay1"); while (TextSystem.instance.Visible) { yield return null; } SaveFile.current.values[5] = 12; } else if (!SaveFile.HasFlag(SaveFile.Flags.Day2End) && SaveFile.HasFlag(SaveFile.Flags.WardenTalkDay2) && !SaveFile.HasFlag(SaveFile.Flags.PostWardenOutDWTalkDay2)) { TextSystem.GetText("PostWardenDWDay2"); while (TextSystem.instance.Visible) { yield return null; } SaveFile.AddFlag(SaveFile.Flags.PostWardenOutDWTalkDay2); SaveFile.current.values[5] = 13; } Player.instance.ResetFollowStep(); Party.ChangeCollider(state: true); ConvertItemsToLW(); } }