using System.Collections.Generic; using System.ComponentModel; using Godot; using Godot.Bridge; using Godot.NativeInterop; [ScriptPath("res://Scripts/Bullets/FoxNecklace.cs")] public partial class FoxNecklace : Node2D { [Export(PropertyHint.None, "")] private NodePath necklaceObj; [Export(PropertyHint.None, "")] private NodePath chainHolder; [Export(PropertyHint.None, "")] private NodePath pointHolder; private Node2D[] points; [Export(PropertyHint.None, "")] private Node2D[] bullets; [Export(PropertyHint.None, "")] private float delay = 45f; [Export(PropertyHint.None, "")] private float variance = 10f; [Export(PropertyHint.None, "")] private float time = 120f; [Export(PropertyHint.None, "")] private float bulletSpeed = 0.4f; private Node2D necklace; private AnimatedSprite2D sprite; private IBullet necklaceData; private Node2D[] chain = new Node2D[12]; private float cd; private float bcd; private float sd = 15f; private const int chainLength = 6; private const float angle = -45f; private Vector2 chainPoint1 = new Vector2(25f, -130f); private Vector2 chainPoint2 = new Vector2(-25f, -130f); private int flipCD; private bool back; private bool mid; public override void _EnterTree() { if (BattleDR.current.enemies[0].HPPercent() < 0.6f || BattleDR.current.enemies[0].spare > 50) { delay *= 0.5f; time *= 0.8f; bulletSpeed *= 1.1f; } necklaceData = GetNode(necklaceObj); necklace = GetNode(necklaceObj); sprite = necklace.GetChild(1); bcd = delay; Node node = GetNode(chainHolder); for (int i = 0; i < chain.Length; i++) { chain[i] = node.GetChild(i); } chainPoint1 = ToGlobal(chainPoint1); chainPoint2 = ToGlobal(chainPoint2); node = GetNode(pointHolder); points = new Node2D[node.GetChildCount()]; for (int j = 0; j < points.Length; j++) { points[j] = node.GetChild(j); } UpdatePos(); } public override void _Process(double delta) { if (sd > 0f) { sd -= Main.deltaTime; return; } if (back) { cd -= Main.deltaTime; if (!mid && cd / time <= 0.5f) { Mid(); } if (cd <= 0f) { Swing(); } } else { cd += Main.deltaTime; if (!mid && cd / time >= 0.5f) { Mid(); } if (cd >= time) { Swing(); } } UpdatePos(); if (bcd > 0f) { bcd -= Main.deltaTime; } else if (necklace.GlobalPosition.DistanceTo(BattleDR.current.soul.GlobalPosition) > 15f) { bcd = delay + Main.RandomRange(0f - variance, variance); Node2D node2D; AddChild(node2D = (Node2D)bullets[(necklaceData.type != IBullet.Type.Blue) ? 1u : 0u].Duplicate(), forceReadableName: false, InternalMode.Disabled); node2D.GlobalPosition = necklace.GlobalPosition; if (node2D is MoveAhead moveAhead) { moveAhead.speed = node2D.GlobalPosition.DirectionTo(BattleDR.current.soul.GlobalPosition) * bulletSpeed; } node2D.ProcessMode = ProcessModeEnum.Inherit; } } private void UpdatePos() { float num = Mathf.SmoothStep(0f, 1f, cd / time); necklace.GlobalPosition = Common.Beizier(points[0].GlobalPosition, points[1].GlobalPosition, points[2].GlobalPosition, num); necklace.Rotation = Mathf.LerpAngle(Mathf.DegToRad(-45f), Mathf.DegToRad(45f), num); for (int i = 0; i < 6; i++) { float weight = (float)i / 6f; chain[i].GlobalPosition = chainPoint1.Lerp(necklace.GlobalPosition, weight); chain[i + 6].GlobalPosition = chainPoint2.Lerp(necklace.GlobalPosition, weight); } } private void Mid() { mid = true; Audio.PlaySound("snd_swing.wav"); } private void Swing() { mid = false; necklaceData.grazed = false; back = !back; sprite.FlipH = !sprite.FlipH; flipCD--; if (Main.RandomRange(0, 3) == 0 || flipCD <= 0) { necklaceData.type = ((necklaceData.type == IBullet.Type.Normal) ? IBullet.Type.Blue : IBullet.Type.Normal); if (necklaceData.type == IBullet.Type.Blue) { necklace.Modulate = Main.colorCyan; } else { necklace.Modulate = Main.colorWhite; } Audio.PlaySound("snd_victor.wav"); flipCD = 2; } } }