using System; using System.Collections.Generic; using Godot; using GodotUtilities; using NodeWar.scripts; namespace NodeWar; public enum NoduleType { Base, Connector, } [Scene] public partial class Nodule : Area2D { private const float GrowthFactor = 0.01f; [Export] private NoduleType _noduleType; [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; set; } = []; [Signal] public delegate void NoduleBuiltEventHandler(); [Signal] public delegate void BuildingCanceledEventHandler(); [Node] private Node2D _gfx; [Node] private CollisionShape2D _baseCollision; public override void _Ready() { AreaEntered += OnAreaEntered; AreaExited += OnAreaExited; switch (_noduleType) { case NoduleType.Base: _gfx.Scale = new Vector2(2, 2); Modulate = Colors.Red; _baseCollision.Disabled = false; break; case NoduleType.Connector: break; default: throw new ArgumentOutOfRangeException(); } QueueRedraw(); } private void OnAreaEntered(Area2D area) { if (area is Nodule nodule) { if (nodule.BuildMode) { return; } ConnectedNodules.Add(nodule); } } private void OnAreaExited(Area2D area) { if (area is Nodule nodule) { if (nodule.BuildMode) { return; } ConnectedNodules.Remove(nodule); } } public override void _Process(double delta) { if (BuildMode) { GlobalPosition = GetGlobalMousePosition(); if (Input.IsMouseButtonPressed(MouseButton.Left)) { EmitSignalNoduleBuilt(); BuildMode = false; MouseEntered += OnMouseEntered; } if (Input.IsMouseButtonPressed(MouseButton.Right)) { EmitSignalBuildingCanceled(); BuildMode = false; QueueFree(); } } else { Age += GrowthFactor * delta.ToFloat(); Age = MathF.Min(Age, 1); QueueRedraw(); } // TODO: replace with line2d? QueueRedraw(); } private void OnMouseEntered() { GD.Print("Mouse entered"); } 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) ); } } public override void _Notification(int what) { if (what == NotificationSceneInstantiated) { WireNodes(); } } }