using Enigmos.Exceptions; using Enigmos.Manual; 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.GlobalManagement.Providers; using Nocturnis.UIElements; namespace Enigmos.Modules; public abstract partial class BaseModule : TextureRect, IBaseModule { [Export] private int PresetPortQuality { get; set; } [Export] private int PresetPortCondition { get; set; } [Export] protected bool UsingPreset { get; set; } [Export] public IPresetModuleConnection[] PresetConnections { get; set; } = Array.Empty(); [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 => GetChildren().OfType(); public IBaseBoard? Board { get; set; } private ModuleManual? Manual { get; set; } public Label? 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 = new Label(); Label.AddThemeFontOverride("font", GlobalProvider.Font); Label.Position = new Vector2(0, -25); Label.Text = LabelString; AddChild(Label); } } /// /// 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(IRootModule 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); } 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 .AssetMapper.Scene .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); } //public Texture2D PreviewTexture => GlobalProvider.TextureProvider.ModuleTextureMapper(this); public abstract Texture2D PreviewTexture { get; } }