using Enigmos.Cables; using Enigmos.Modules; using Enigmos.Modules.ControllingModules; using Enigmos.Modules.ProgrammableModules; using Enigmos.Modules.TerminalModules; using Enigmos.Ports.DataPorts; using Godot; using Nocturnis.DataStructures; using Nocturnis.Enigmos.Boards; using Nocturnis.Enigmos.Cables; using Nocturnis.Enigmos.Modules; using Nocturnis.Enigmos.Ports; using Nocturnis.Inventories.Items; using Nocturnis.Inventories.Items.Items; using Nocturnis.UIElements; using Nocturnis.UIElements.Layers; using TabulaSmaragdina; using TabulaSmaragdina.Controls; namespace Enigmos.Boards; public abstract partial class BaseBoard : Panel, IBaseBoard { public bool CableVisualMode { get; set; } public bool LabelVisualMode { get; set; } public HashSet FocusedCables { get; set; } = new(); public void SetCableVisualMode(bool mode) { CableVisualMode = mode; foreach (BaseCable cable in GetChildren().OfType()) cable.Modulate = Color.Color8(255, 255, 255, (Byte)(mode ? 20 : 255)); } public void SetLabelVisualMode(bool mode) { LabelVisualMode = mode; foreach (BaseModule module in GetChildren().OfType()) if(module.HasLabel()) module.Label!.Visible = !mode; } public void AddCable(IBaseCable cable) { AddChild(cable.AsNode); cable.Modulate = Color.Color8(255, 255, 255, (Byte)(CableVisualMode ? 20 : 255)); } public IModuleManualLayer? ModuleManualLayer { get; set; } public bool ManualOpened { get; set; } protected HashSet Modules { get; set; } = new(); protected IEnumerable ProgrammableModules() => Modules .OfType(); public IEnumerable TerminalModules() => Modules .OfType() .Union(ProgrammableModules().SelectMany(module => module.UnderlyingBoard.TerminalModules())); protected HashSet Ports => Modules.SelectMany(module => module.Ports).ToHashSet(); public IPanelViewer? PanelViewer { get; set; } public Dictionary CablePairing { get; set; } = new(); public IBasePort? ConnectPending { get; set; } public IBoardControlLayer? CircuitBoardControlLayer { get; set; } public IModuleMovingLayer? ModuleMovingLayer { get; set; } public virtual void Init() { CablePairing = new Dictionary(); Modules = new HashSet(); FocusedCables = new HashSet(); ConnectPending = null; } public override void _Ready() { base._Ready(); ModuleManualLayer = GetNode("ModuleManualLayer"); ModuleMovingLayer = GetNode("ModuleMovingLayer"); ModuleMovingLayer.Board = this; PanelViewer = GetNode("PanelViewer"); CircuitBoardControlLayer = GetNode("CircuitBoardControlLayer"); CircuitBoardControlLayer.Board = this; } protected virtual void AddModule(IBaseModule module, Vector2 pos) { module.Board = this; AddChild(module.AsNode); if (module is ICompositeModule compositeModule) foreach (IBaseModule subModule in compositeModule.SubModules()) subModule.Board = this; module.Position = pos; Modules.Add(module); } public virtual void Reset() { foreach (IBaseModule module in Modules) { if (module is RootModule rootModule) rootModule.ActionFinished = false; if (module is ICompositeModule compositeModule) { foreach (IBaseModule subModule in compositeModule.SubModules()) { foreach (DataOutPort port in subModule.Ports.OfType()) { port.DataUpdated = false; } } } if (module is ProgrammableModule programmableModule) { programmableModule.UnderlyingBoard.Reset(); foreach (DataOutPort outPort in programmableModule.ExplicitPorts().OfType()) outPort.DataUpdated = false; foreach (DataOutPort outPort in programmableModule.ImplicitPorts().OfType()) outPort.DataUpdated = false; } if (module is ControllingModule controllingModule) controllingModule.Visited = false; if (module is TerminalModule terminalModule) terminalModule.Finished = false; foreach (DataOutPort port in module.Ports.OfType()) port.DataUpdated = false; } } public override bool _CanDropData(Vector2 atPosition, Variant data) { IVariantWithType vData = data.As(); if (vData.TypeHint != "Module") { if(vData.TypeHint != "Item") return false; IBaseItem item = vData.UnderlyingData.As(); if (item is IBaseModuleItem moduleItem) { foreach (IBaseModule module in Modules) if (GlobalProvider.UIProvider.Overlap(atPosition, moduleItem.ContentModule.Size, module.Position, module.Size)) return false; return true; } return false; } BaseModule? moduleData = vData.UnderlyingData.As(); if (moduleData == null) return false; Vector2 pos = atPosition - moduleData.PivotOffset; foreach (IBaseModule module in Modules) { if(module == moduleData) continue; if (GlobalProvider.UIProvider.Overlap(pos, moduleData.Size, module.Position, module.Size)) return false; } return true; } public override void _DropData(Vector2 atPosition, Variant data) { IVariantWithType vData = data.As(); if(vData.TypeHint == "Module") { BaseModule vModule = vData.UnderlyingData.As(); vModule.Position = atPosition - vModule.PivotOffset; vModule.UpdateCables(); } else { IBaseModuleItem moduleItem = vData.UnderlyingData.As(); AddModule(moduleItem.ContentModule, atPosition); ItemDraggingControl.Instance.DraggingFrom!.Item = null; } } protected T GetModule(NodePath path) where T : BaseModule { T res = GetNode(path); res.Init(); Modules.Add(res); res.Board = this; return res; } }