using Enigmos.Cables; using Godot; using Nocturnis.Enigmos.Cables; using Nocturnis.Enigmos.Modules; using Nocturnis.Enigmos.Ports; using Nocturnis.Inventories.Items.Items; using VirtualChemistry.Chemistry.Mixtures.Implements; namespace Enigmos.Ports; public abstract partial class BasePort : TextureButton, IBasePort { public virtual Vector2 PositionToBoard() => Position + PivotOffset + Module?.PositionToBoard ?? Vector2.Zero; /// /// When Condition is Equal to 0, Port is Disabled /// public int Condition { get; set; } /// /// Each time the port is used, there is 1/Quality chance to damage the Condition /// public int Quality { get; set; } /// /// Increase Condition /// Modify Quality base on property of material /// public void FixWith(IBaseChemicalItem c) { if (c.ContentMaterial.Amount == 0) return; HeterogeneousMixture material = c.ContentMaterial; double s = 1; //material.LayerOrder.Last.Value.CayleyValue(); double u = 1;//material.LayerOrder.Last.Value.EuclidValue(); double usedAmount = Math.Min(1d, material.LayerOrder.Last.Value.Amount); double dCond = usedAmount * (Module.MaintenanceAlpha * s - Module.MaintenanceBeta * u); double dQuality = usedAmount * (Math.Pow(Module.MaintenanceBeta, 2) * s - Module.MaintenanceAlpha * u); c.ConsumeFromBottom(usedAmount); Condition = Mathf.FloorToInt(Math.Max(0, Math.Min(100, Condition + dCond))); Quality = Mathf.FloorToInt(Math.Max(0, Math.Min(20000, Quality + dQuality))); } public IBaseModule? Module { get; set; } public abstract bool IsMatch(IBasePort oth); public IBasePort? ConnectedPort { get; set; } public bool Connected => ConnectedPort != null; /// /// Try to Connect two Ports /// if this port is Connected already, it will disconnect first /// public void Connect() { if(Connected) Disconnect(); if (Module.Board.ConnectPending == null) { SetStatusPending(); Module.Board.ConnectPending = this; return; } if (Module.Board.ConnectPending.IsMatch(this)) { ConnectedPort = Module.Board.ConnectPending; Module.Board.ConnectPending.ConnectedPort = this; BaseCable cable = MakeCable(Module.Board.ConnectPending); Module.Board.CablePairing[this] = cable; Module.Board.CablePairing[Module.Board.ConnectPending] = cable; Module.Board.AddCable(cable); cable.LineUpdate(); SetStatusConnected(); Module.Board.ConnectPending.SetStatusConnected(); Module.Board.ConnectPending = null; return; } Module.Board.ConnectPending.SetStatusNormal(); Module.Board.ConnectPending = null; } protected virtual void Disconnect() { if (!Connected) return; IBaseCable cable = Module.Board.CablePairing[this]; Module.Board.CablePairing.Remove(ConnectedPort); Module.Board.FocusedCables.Remove(Module.Board.CablePairing[this]); Module.Board.CablePairing.Remove(this); cable.Free(); ConnectedPort.SetStatusNormal(); ConnectedPort.ConnectedPort = null; SetStatusNormal(); ConnectedPort = null; } public abstract void SetStatusPending(); public abstract void SetStatusConnected(); public abstract void SetStatusNormal(); /// /// Determine whether this port can be connected with given port /// public abstract BaseCable MakeCable(IBasePort other); public virtual void Init() { } }