using System; using System.Collections.Generic; using Godot; using NodeWar.scripts; namespace NodeWar; public enum NoduleType { Base, Connector, } [SceneTree] public partial class Nodule : Area2D { private const float GrowthFactor = 0.01f; [Export] private NoduleType _noduleType; private bool _growAreaInside; [Export] public float MaxRadius { get; set; } = 360; [Export] public bool BuildMode { get; set; } = false; [Export] public float Age { get; set; } = 0; [Export] public PackedScene RootScene { get; set; } public List ConnectedNodules { get; } = []; [Signal] public delegate void NoduleBuiltEventHandler(); [Signal] public delegate void BuildingCanceledEventHandler(); public override void _Ready() { _.ConnectionArea.NoduleEntered += HandleNoduleEntered; _.ConnectionArea.NoduleExited += HandleNoduleExited; switch (_noduleType) { case NoduleType.Base: Modulate = Colors.Red; _.Gfx.Get().Scale = new Vector2(2, 2); _.BaseCollision.Disabled = false; BuildNode(); break; case NoduleType.Connector: break; default: throw new ArgumentOutOfRangeException(); } QueueRedraw(); } public override void _Process(double delta) { if (BuildMode) { GlobalPosition = GetGlobalMousePosition(); if (Input.IsActionJustPressed(Scripts.Globals.MyInput.MouseLeft)) { BuildNode(); } if (Input.IsMouseButtonPressed(MouseButton.Right)) { EmitSignalBuildingCanceled(); BuildMode = false; QueueFree(); } } else { if ( Input.IsActionJustPressed(Scripts.Globals.MyInput.MouseLeft) && _growAreaInside && !BuildMode ) { var newNodule = Instantiator.Instantiate(); newNodule.BuildMode = true; GetParent().AddChild(newNodule); newNodule.GlobalPosition = GlobalPosition; } Age += GrowthFactor * delta.ToFloat(); Age = MathF.Min(Age, 1); QueueRedraw(); } // TODO: replace with line2d? QueueRedraw(); } public override void _Draw() { foreach (var nodule in ConnectedNodules) { if (BuildMode) { DrawDashedLine( Vector2.Zero, nodule.GlobalPosition - GlobalPosition, Colors.White, 2f, dash: 4f, antialiased: true ); } } var value = 200 * Age; if (!BuildMode) { DrawRect( new Rect2(-value / 2, -value / 2, value, value), new Color(Colors.WhiteSmoke, 0.4f) ); } } private void HandleNoduleEntered(Nodule nodule) { ConnectedNodules.Add(nodule); } private void HandleNoduleExited(Nodule nodule) { ConnectedNodules.Remove(nodule); } private void BuildNode() { EmitSignalNoduleBuilt(); BuildMode = false; // try connecting built nodule to connected ones foreach (var connectedNodule in ConnectedNodules) { BuildManager.Instance.RegisterConnection(this, connectedNodule); } _.GrowArea.Get().MouseEntered += () => { _growAreaInside = true; }; _.GrowArea.Get().MouseExited += () => { _growAreaInside = false; }; } }