2025-05-13 19:22:01 +08:00

185 lines
4.0 KiB
C#

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<IBullet>(necklaceObj);
necklace = GetNode<Node2D>(necklaceObj);
sprite = necklace.GetChild<AnimatedSprite2D>(1);
bcd = delay;
Node node = GetNode(chainHolder);
for (int i = 0; i < chain.Length; i++)
{
chain[i] = node.GetChild<Node2D>(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<Node2D>(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;
}
}
}