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

328 lines
7.7 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using Godot;
using Godot.Bridge;
using Godot.NativeInterop;
[ScriptPath("res://Scripts/Bullets/FoxSpecial.cs")]
public partial class FoxSpecial : Node2D
{
[Export(PropertyHint.None, "")]
private Entity fox;
[Export(PropertyHint.None, "")]
private Node2D[] fireBullets;
[Export(PropertyHint.None, "")]
private Node2D[] points;
[Export(PropertyHint.None, "")]
private Node2D blueRing;
[Export(PropertyHint.None, "")]
private CollisionShape2D[] shapes;
[Export(PropertyHint.None, "")]
private PackedScene warning;
[Export(PropertyHint.None, "")]
private PackedScene bomb;
[Export(PropertyHint.None, "")]
private PackedScene bombAnim;
[Export(PropertyHint.None, "")]
private PackedScene circleSmall;
private float startDelay = 20f;
private float cd;
private float bulletTime;
private int state;
private Vector2 foxPos = new Vector2(0f, -63f);
private Vector2 startP;
private Coroutine routine;
private List<Node2D> bombs = new List<Node2D>();
private List<float> bombTime = new List<float>();
private const float sideBulletSpd = 0.4f;
public override void _EnterTree()
{
fox.Modulate = Main.colorClear;
startP = fox.Position;
DWMenu.instance.bulletBoard.SelfModulate = Main.colorBlack;
}
public override void _Process(double delta)
{
if (startDelay > 0f)
{
startDelay -= Main.deltaTime;
return;
}
if (startDelay > -50f)
{
fox.anim.Play("FrontAtk");
startDelay = -100f;
}
Bombs();
fox.sprite.Position = new Vector2(0f, Common.SinOverTime(0.25f) * 5f);
Coroutine coroutine = routine;
if (coroutine != null && !coroutine.done)
{
return;
}
switch (state)
{
case 0:
if (cd < 100f)
{
fox.Position = startP.Lerp(foxPos, cd / 100f);
fox.Modulate = Main.colorClear.Lerp(Main.colorWhite, cd / 100f);
cd += Main.deltaTime;
}
else
{
cd = 0f;
state = 1;
fox.anim.Play("Scream");
fox.Shake(160f, 2f);
Audio.PlaySound("snd_ceroba_scream.wav");
}
break;
case 1:
if (bulletTime <= 0f)
{
NewBullet(in blueRing, fox.GlobalPosition);
bulletTime = 15f;
}
else
{
bulletTime -= Main.deltaTime;
}
if (fox.shake <= 0f)
{
state = 2;
cd = 100f;
startP = fox.GlobalPosition;
fox.anim.Play("Scream");
bulletTime = 15f;
routine = Coroutine.Start(DashAttack());
}
break;
case 2:
break;
}
}
private IEnumerator DashAttack()
{
float a;
for (a = 0f; a < 30f; a += Main.deltaTime)
{
yield return null;
}
float c;
for (int i = 0; i < points.Length; i += 2)
{
float b;
if (i == 0)
{
a = 0f;
for (b = 100f; a < b; a += Main.deltaTime)
{
fox.GlobalPosition = startP.Lerp(points[0].GlobalPosition, a / b);
yield return null;
}
fox.anim.Play("Dash");
for (b = 0f; b < 30f; b += Main.deltaTime)
{
yield return null;
}
shapes[0].SetDeferred("disabled", true);
shapes[1].SetDeferred("disabled", false);
}
fox.Visible = false;
startP = points[i].GlobalPosition;
fox.GlobalPosition = startP;
((Node2D)fox).LookAt(points[i + 1].GlobalPosition);
fox.RotationDegrees += 180f;
Vector2 d = points[i].GlobalPosition.DirectionTo(points[i + 1].GlobalPosition);
for (int j = 0; j < 3; j++)
{
Control control;
AddChild(control = warning.Instantiate<Control>(PackedScene.GenEditState.Disabled), forceReadableName: false, InternalMode.Disabled);
if (j > 0)
{
control.GetChild<AudioStreamPlayer>(1).VolumeDb = Mathf.LinearToDb(0f);
}
control.GlobalPosition = startP.Lerp(points[i + 1].GlobalPosition, (float)(j + 2) / 6f);
for (b = 0f; b < 5f; b += Main.deltaTime)
{
yield return null;
}
}
for (b = 0f; b < 30f; b += Main.deltaTime)
{
yield return null;
}
Audio.PlaySound("snd_mart_feather_atk1-2.wav");
fox.Visible = true;
b = 0f;
a = 70f;
c = 15f;
while (b < a)
{
if (c <= 0f)
{
for (int k = 0; k < 5; k++)
{
MoveAhead moveAhead = (MoveAhead)NewBullet(in fireBullets[Main.RandomRange(0, fireBullets.Length - 1)], fox.GlobalPosition);
switch (k)
{
case 0:
moveAhead.Scale = Vector2.One * 1.2f;
break;
case 1:
moveAhead.speed = d.Rotated(Mathf.DegToRad(45f)) * 0.4f;
break;
case 2:
moveAhead.speed = d.Rotated(Mathf.DegToRad(-45f)) * 0.4f;
break;
case 3:
moveAhead.speed = d.Rotated(Mathf.DegToRad(-135f)) * 0.4f;
break;
case 4:
moveAhead.speed = d.Rotated(Mathf.DegToRad(135f)) * 0.4f;
break;
}
}
c = 15f;
}
fox.GlobalPosition = startP.Lerp(points[i + 1].GlobalPosition, b / a);
yield return null;
b += Main.deltaTime;
c -= Main.deltaTime;
}
}
fox.anim.Play("FrontAtk");
fox.Visible = false;
for (c = 0f; c < 30f; c += Main.deltaTime)
{
yield return null;
}
for (int i = 0; i < 10; i++)
{
Audio.PlaySound("snd_ceroba_attack_bell_ring.wav");
Node2D node2D = NewBullet(in bomb, BattleDR.current.soul.GlobalPosition + Vector2.Up * 80f);
node2D.Modulate = Main.colorClear;
bombs.Add(node2D);
bombTime.Add(80f);
for (c = 0f; c < 60f; c += Main.deltaTime)
{
yield return null;
}
}
shapes[0].SetDeferred("disabled", false);
shapes[1].SetDeferred("disabled", true);
fox.RotationDegrees = 0f;
startP = base.GlobalPosition + new Vector2(0f, -220f);
fox.Visible = true;
c = 0f;
for (a = 100f; c < a; c += Main.deltaTime)
{
fox.GlobalPosition = startP.Lerp(base.GlobalPosition, Mathf.SmoothStep(0f, 1f, c / a));
yield return null;
}
for (a = 0f; a < 20f; a += Main.deltaTime)
{
yield return null;
}
fox.anim.Play("Scream");
fox.Shake(160f, 2f);
Audio.PlaySound("snd_ceroba_scream.wav");
a = 0f;
c = 50f;
while (a < 180f)
{
if (c <= 0f)
{
c = 50f;
NewBullet(in blueRing, fox.GlobalPosition);
}
yield return null;
a += Main.deltaTime;
c -= Main.deltaTime;
}
CameraController.Transition(Main.colorWhite, 180f, 4000);
yield return null;
while (!CameraController.transitionRoutine.done)
{
yield return null;
}
BattleDR.current.activeBoard.timer = 0f;
}
private void Bombs()
{
for (int num = bombs.Count - 1; num >= 0; num--)
{
bombTime[num] -= Main.deltaTime;
if (bombTime[num] <= 0f)
{
NewBullet(in bombAnim, bombs[num].GlobalPosition);
NewBullet(in circleSmall, bombs[num].GlobalPosition);
Vector2 vector = Vector2.Up.Rotated(Mathf.DegToRad(Main.RandomRange(0, 90)));
for (int i = 0; i < 4; i++)
{
MoveAhead obj = (MoveAhead)NewBullet(in fireBullets[1], bombs[num].GlobalPosition);
obj.speed = vector.Rotated(Mathf.DegToRad(90 * i)) * 0.4f * Main.RandomRange(1.1f, 1.5f);
obj.Scale *= 0.8f;
}
Audio.PlaySound("snd_explosion_mmx3.wav");
bombs[num].QueueFree();
bombs.RemoveAt(num);
bombTime.RemoveAt(num);
}
else
{
bombs[num].GlobalPosition += Vector2.Down * Main.deltaTime * 0.7f;
bombs[num].Modulate = bombs[num].Modulate.Lerp(Main.colorWhite, Main.deltaTime * 0.2f);
}
}
}
private Node2D NewBullet(in PackedScene type, Vector2 pos)
{
Node2D node2D;
AddChild(node2D = type.Instantiate<Node2D>(PackedScene.GenEditState.Disabled), forceReadableName: false, InternalMode.Disabled);
node2D.GlobalPosition = pos;
node2D.ProcessMode = ProcessModeEnum.Inherit;
return node2D;
}
private Node2D NewBullet(in Node2D type, Vector2 pos)
{
Node2D node2D;
AddChild(node2D = (Node2D)type.Duplicate(), forceReadableName: false, InternalMode.Disabled);
node2D.GlobalPosition = pos;
node2D.ProcessMode = ProcessModeEnum.Inherit;
return node2D;
}
public override void _ExitTree()
{
CameraController.Transition(Main.colorClear);
}
}