using System.Collections.Generic; using System.ComponentModel; using Godot; using Godot.Bridge; using Godot.NativeInterop; [ScriptPath("res://Scripts/Bullets/BulletGenerator.cs")] public partial class BulletGenerator : Node2D { public enum GenType { None, Direction, DirectionFromThisToPoints } [Export(PropertyHint.None, "")] public GenType genType; [Export(PropertyHint.None, "")] public Vector2 randomizePos; [Export(PropertyHint.None, "")] public Vector2 speed; [Export(PropertyHint.None, "")] private float startDelay = 60f; [Export(PropertyHint.None, "")] private float delayInbetween = 60f; [Export(PropertyHint.None, "")] private float delayRandom = 20f; [Export(PropertyHint.None, "")] private float bulletTimeSec = 5f; [Export(PropertyHint.None, "")] public Node2D[] spawnPoints; [Export(PropertyHint.None, "")] private Node2D[] bulletBase; [Export(PropertyHint.None, "")] private int maxBullets = 10; [Export(PropertyHint.None, "")] public bool start = true; private int last; private float cooldown; public override void _EnterTree() { for (int i = 0; i < bulletBase.Length; i++) { Main.SetActive(bulletBase[i], state: false); } } public override void _Process(double delta) { if (startDelay > 0f) { startDelay -= Main.deltaTime; } else { if (!start || GetChildCount() >= maxBullets) { return; } if (cooldown > 0f) { cooldown -= Main.deltaTime; return; } Node2D node2D; AddChild(node2D = (Node2D)bulletBase[Main.RandomRange(0, bulletBase.Length - 1)].Duplicate(), forceReadableName: false, InternalMode.Disabled); Timer obj = new Timer { WaitTime = bulletTimeSec, Autostart = true }; Timer timer = obj; node2D.AddChild(obj, forceReadableName: false, InternalMode.Disabled); if (node2D is IBullet bullet) { bullet.generatedFrom = this; timer.Timeout += ((IBullet)node2D).ResetBullet; } else { timer.Timeout += node2D.QueueFree; } ResetBullet(node2D); cooldown = delayInbetween + Main.RandomRange(0f, delayRandom); } } public void ResetBullet(Node2D node) { if (genType != GenType.DirectionFromThisToPoints) { Node2D[] array = spawnPoints; if (array != null && array.Length != 0) { int num; do { num = Main.RandomRange(0, spawnPoints.Length - 1); } while (last == num); node.GlobalPosition = spawnPoints[num].GlobalPosition; last = num; } else { node.GlobalPosition = base.GlobalPosition; } node.GlobalPosition += new Vector2(Main.RandomRange(0f - randomizePos.X, randomizePos.X), Main.RandomRange(0f - randomizePos.Y, randomizePos.Y)); if (speed.LengthSquared() > 0f && node is MoveAhead moveAhead) { moveAhead.speed = speed; } } else { node.GlobalPosition = base.GlobalPosition; Vector2 globalPosition = spawnPoints[Main.RandomRange(0, spawnPoints.Length - 1)].GlobalPosition; node.LookAt(globalPosition); if (node is MoveAhead moveAhead2) { if (speed.LengthSquared() > 0f) { moveAhead2.speed = node.GlobalPosition.DirectionTo(globalPosition) * speed; } else { moveAhead2.speed = node.GlobalPosition.DirectionTo(globalPosition); } } } Main.SetActive(node, state: true); } }