Files
Enigmos/Ports/BasePort.cs
2024-06-29 06:35:23 +08:00

108 lines
3.8 KiB
C#

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;
/// <summary>
/// When Condition is Equal to 0, Port is Disabled
/// </summary>
public int Condition { get; set; }
/// <summary>
/// Each time the port is used, there is 1/Quality chance to damage the Condition
/// </summary>
public int Quality { get; set; }
/// <summary>
/// Increase Condition
/// Modify Quality base on property of material
/// </summary>
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;
/// <summary>
/// Try to Connect two Ports
/// if this port is Connected already, it will disconnect first
/// </summary>
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();
/// <summary>
/// Determine whether this port can be connected with given port
/// </summary>
public abstract BaseCable MakeCable(IBasePort other);
public virtual void Init()
{
}
}