209 lines
3.9 KiB
C#
209 lines
3.9 KiB
C#
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;
|
|
|
|
private bool _growAreaInside;
|
|
private bool _holdInsideGrowArea;
|
|
private Vector2 _lastPosition;
|
|
private bool _freezeMove;
|
|
|
|
[Export]
|
|
private NoduleType _noduleType;
|
|
|
|
private float _maxRadius;
|
|
|
|
[Export]
|
|
public bool BuildMode { get; set; } = false;
|
|
|
|
[Export]
|
|
public float Age { get; set; } = 0;
|
|
|
|
[Export]
|
|
public PackedScene RootScene { get; set; }
|
|
|
|
public List<Nodule> ConnectedNodules { get; } = [];
|
|
|
|
public Nodule ParentNoduleWhileBuilding;
|
|
|
|
public Nodule ChildNoduleWhileBuilding;
|
|
|
|
[Signal]
|
|
public delegate void NoduleBuiltEventHandler();
|
|
|
|
[Signal]
|
|
public delegate void BuildingCanceledEventHandler();
|
|
|
|
public override void _Ready()
|
|
{
|
|
_maxRadius = _.ConnectionArea.GetRadius();
|
|
_.ConnectionArea.NoduleEntered += HandleNoduleEntered;
|
|
_.ConnectionArea.NoduleExited += HandleNoduleExited;
|
|
|
|
switch (_noduleType)
|
|
{
|
|
case NoduleType.Base:
|
|
Modulate = Colors.Red;
|
|
|
|
_.Gfx.Get().Scale = new Vector2(2, 2);
|
|
|
|
BuildNode();
|
|
break;
|
|
case NoduleType.Connector:
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
|
|
QueueRedraw();
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
// TODO: StateMachine?
|
|
if (BuildMode)
|
|
{
|
|
var distanceToParent =
|
|
GetGlobalMousePosition() - ParentNoduleWhileBuilding.GlobalPosition;
|
|
|
|
if (distanceToParent.Length() > _maxRadius)
|
|
{
|
|
GlobalPosition =
|
|
ParentNoduleWhileBuilding.GlobalPosition
|
|
+ distanceToParent.Normalized() * _maxRadius;
|
|
}
|
|
else
|
|
{
|
|
GlobalPosition = GetGlobalMousePosition();
|
|
}
|
|
|
|
if (Input.IsActionJustReleased(Scripts.Globals.MyInput.MouseLeft))
|
|
{
|
|
BuildNode();
|
|
}
|
|
|
|
if (Input.IsMouseButtonPressed(MouseButton.Right))
|
|
{
|
|
EmitSignalBuildingCanceled();
|
|
BuildMode = false;
|
|
BuildManager.Instance.IsBuilding = false;
|
|
|
|
QueueFree();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Input.IsActionJustPressed(Scripts.Globals.MyInput.MouseLeft) && _growAreaInside)
|
|
{
|
|
_holdInsideGrowArea = true;
|
|
}
|
|
|
|
if (Input.IsActionJustReleased(Scripts.Globals.MyInput.MouseLeft) && _growAreaInside)
|
|
{
|
|
_holdInsideGrowArea = false;
|
|
}
|
|
|
|
Age += GrowthFactor * delta.ToFloat();
|
|
Age = MathF.Min(Age, 1);
|
|
|
|
QueueRedraw();
|
|
}
|
|
|
|
// TODO: replace with line2d?
|
|
QueueRedraw();
|
|
|
|
_lastPosition = GlobalPosition;
|
|
}
|
|
|
|
public override void _Draw()
|
|
{
|
|
if (BuildMode)
|
|
{
|
|
foreach (var nodule in ConnectedNodules)
|
|
{
|
|
DrawDashedLine(
|
|
Vector2.Zero,
|
|
nodule.GlobalPosition - GlobalPosition,
|
|
Colors.White,
|
|
2f,
|
|
dash: 4f,
|
|
antialiased: true
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void HandleNoduleEntered(Nodule nodule)
|
|
{
|
|
ConnectedNodules.Add(nodule);
|
|
}
|
|
|
|
private void HandleNoduleExited(Nodule nodule)
|
|
{
|
|
ConnectedNodules.Remove(nodule);
|
|
}
|
|
|
|
private void BuildNode()
|
|
{
|
|
EmitSignalNoduleBuilt();
|
|
|
|
BuildMode = false;
|
|
ChildNoduleWhileBuilding = null;
|
|
|
|
// Weird architecture...
|
|
BuildManager.Instance.IsBuilding = 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 += () =>
|
|
{
|
|
if (_holdInsideGrowArea)
|
|
{
|
|
StartBuilding();
|
|
_holdInsideGrowArea = false;
|
|
}
|
|
|
|
_growAreaInside = false;
|
|
};
|
|
}
|
|
|
|
private void StartBuilding()
|
|
{
|
|
GD.Print("START BUILDING");
|
|
if (BuildManager.Instance.IsBuilding)
|
|
return;
|
|
|
|
BuildManager.Instance.IsBuilding = true;
|
|
var newNodule = Instantiator.Instantiate<Nodule>();
|
|
|
|
GetParent().AddChild(newNodule);
|
|
|
|
newNodule.BuildMode = true;
|
|
newNodule.GlobalPosition = GlobalPosition;
|
|
newNodule.ParentNoduleWhileBuilding = this;
|
|
ChildNoduleWhileBuilding = newNodule;
|
|
}
|
|
}
|