using Enigmos.Exceptions; using Enigmos.Manual; using Enigmos.Modules.ControllingModules; using Enigmos.Ports; using Godot; using Nocturnis.DataStructures; using Nocturnis.Enigmos.Boards; using Nocturnis.Enigmos.Cables; using Nocturnis.Enigmos.Modules; using Nocturnis.Enigmos.Ports; using Nocturnis.UIElements; using TabulaSmaragdina; namespace Enigmos.Modules; public abstract partial class BaseModule : TextureRect, IBaseModule { private static readonly Font GnuUni = ResourceLoader.Load("res://Resources/Fonts/GnuUnifontFull-Pm9P.ttf"); [Export] private int PresetPortQuality { get; set; } [Export] private int PresetPortCondition { get; set; } [Export] protected bool UsingPreset { get; set; } [Export] public IPresetModuleConnection[] PresetConnections { get; set; } [Export] public string LabelString { get; set; } = ""; public virtual Vector2 PositionToBoard => Position; protected virtual bool Draggable() => true; protected virtual bool HasManual() => true; public bool HasLabel() => HasManual(); public virtual IEnumerable Ports => Array.Empty(); public IBaseBoard? Board { get; set; } private ModuleManual? Manual { get; set; } public ISimpleLabel? Label { get; set; } public Node AsNode => this; public virtual void PresetValueInit() { foreach (IBasePort port in Ports) { port.Condition = PresetPortCondition; port.Quality = PresetPortQuality; } } public virtual void Init() { if (HasLabel()) { Label = GlobalProvider.SceneProvider .AssetMapper() .Instantiate(); Label.Position = new Vector2(0, -25); Label.Text = LabelString; AddChild(Label.AsNode); } } /// /// Used to determine result of fixing a port with given material /// public virtual double MaintenanceAlpha => 0d; /// /// Used to determine result of fixing a port with given material /// public virtual double MaintenanceBeta => 0d; public virtual string GetDescription => ""; public virtual void UpdateCables() { foreach (IBasePort port in Ports) { if(!Board!.CablePairing.ContainsKey(port)) continue; Board.CablePairing[port].LineUpdate(); } } protected virtual void PostInit() { foreach (IBasePort port in Ports) port.Module = this; if(UsingPreset) PresetValueInit(); } protected virtual void TimeoutCheck(RootModule root) { if (root.Timer.ElapsedMilliseconds < 25) return; root.Timer.Stop(); throw ModuleExecutionTimeout.Exception; } protected virtual void TimeoutHandler(ModuleExecutionTimeout timeout) => throw timeout; public override Variant _GetDragData(Vector2 atPosition) { if (!Draggable()) return default; Board!.ModuleMovingLayer.DraggingModule = this; Board!.ModuleMovingLayer.MouseOffset = GetLocalMousePosition(); return GlobalProvider.DataStructureProvider.NewVariantWithType("Module", this); } protected T GetPort(string path) where T : BasePort { T res = GetNode(path); res.Init(); return res; } public override void _Input(InputEvent @event) { if (@event is InputEventMouseButton eventMouseButton) { Vector2 mousePosition = GetLocalMousePosition(); if(mousePosition.X > 0 && mousePosition.X < Size.X && mousePosition.Y > 0 && mousePosition.Y < Size.Y) { if (eventMouseButton.ButtonIndex == MouseButton.Right && eventMouseButton.Pressed) { if (!HasManual()) return; if (Board.ManualOpened) return; if (Manual == null) { Manual = GlobalProvider.SceneProvider .AssetMapper() .Instantiate(); Manual.Init(this); } Board.ModuleManualLayer.AddChild(Manual); Manual.Position = Board.ModuleManualLayer.ManualPosition.Position - Manual.Size / 2; Board.ManualOpened = true; return; } if (eventMouseButton.ButtonIndex == MouseButton.Left && eventMouseButton.Pressed) { if (Board!.CableVisualMode) { foreach (IBaseCable cable in Board.FocusedCables) cable.Modulate = Color.Color8(255, 255, 255, 20); Board.FocusedCables = Ports .Where(Board.CablePairing.ContainsKey) .Select(p => Board.CablePairing[p]) .ToHashSet(); if (this is ICompositeModule thisCompositeModule) foreach (IBasePort port in thisCompositeModule.SubModules().SelectMany(module => module.Ports).Where(Board.CablePairing.ContainsKey)) Board.FocusedCables.Add(Board.CablePairing[port]); foreach (IBaseCable cable in Board.FocusedCables) cable.Modulate = Color.Color8(255, 255, 255, 255); } } } } base._Input(@event); } }