using Godot; using System.Linq; using VirtualChemistry.Chemistry.Compounds.Implements; using VirtualChemistry.Chemistry.Containers; using VirtualChemistry.Chemistry.Mixtures.Implements; public partial class Bottle : MenuButton, IChemicalContainer { private double ContainerVolume { get; set; } public double Volume() => ContainerVolume; public HeterogeneousMixture Content { get; set; } = HeterogeneousMixture.Null; public double EnvironmentPressure { get; set; } public double EnvironmentTemperature { get; set; } public HomogeneousMixture MainComponent => Content.Layers .DefaultIfEmpty(HomogeneousMixture.Null) .MaxBy(x => x.Amount); public Compound MainCompound => MainComponent.Compounds .DefaultIfEmpty(Compound.Null) .MaxBy(x => x.Amount); private const string Empty = "Empty"; private string PotionName => $"Main: {(MainCompound == Compound.Null ? Empty : MainCompound.Expression)}"; private string PotionAmount => $"Amount: {(MainCompound == Compound.Null ? 0d : Content.Amount)}"; public Sprite2D ContentTexture { get; set; } public void BuildMenu() { if (Content == HeterogeneousMixture.Null) ContentTexture.Modulate = Color.Color8(0, 0, 0, 0); else { ContentTexture.Modulate = Color.Color8( MainComponent.ColorRed, MainComponent.ColorGreen, MainComponent.ColorBlue, MainComponent.ColorTransparent ); } PopupMenu menu = GetPopup(); menu.Clear(); foreach (var w in menu.GetSignalConnectionList(PopupMenu.SignalName.IdPressed)) menu.Disconnect(PopupMenu.SignalName.IdPressed, w["callable"].AsCallable()); menu.AddItem(PotionName, 0); menu.AddItem(PotionAmount, 1); menu.SetItemDisabled(0, true); menu.SetItemDisabled(1, true); menu.AddItem("Construct", 2); menu.AddItem("Fill From Flask", 3); menu.AddItem("Load From String", 4); menu.AddItem("Add to Flask", 5); menu.AddItem("Save to String", 6); menu.AddItem("Discard", 7); menu.Connect(PopupMenu.SignalName.IdPressed, Callable.From((int idx) => MenuHandle(idx))); } private void MenuHandle(int idx) { switch (idx) { case 2: GlobalScene.Demo.SelectedBottle = this; GlobalScene.MainScene.SwitchToConstructor(); break; case 3: if (GlobalScene.Flask.Content.Layers.Count == 0) return; Content = GlobalScene.Flask.Content; Content.Container = this; GlobalScene.Flask.Content = HeterogeneousMixture.Null; GlobalScene.Flask.Update(); break; case 4: GlobalScene.Demo.SelectedBottle = this; GlobalScene.Demo.PopupStringLoader(); break; case 5: foreach (HomogeneousMixture m in Content.Layers.ToArray()) { m.Volume = m.FreeVolume; GlobalScene.Flask.Content.AddLayer(m); } //GlobalScene.Flask.Content = Content; //Content.Container = GlobalScene.Flask; Content = HeterogeneousMixture.Null; GlobalScene.Flask.Update(); break; case 6: GlobalScene.Demo.FullRepr.Text = Content.Dump(); break; case 7: Content = HeterogeneousMixture.Null; break; default: break; } BuildMenu(); } // Called when the node enters the scene tree for the first time. public override void _Ready() { ContentTexture = GetNode("Content"); BuildMenu(); } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { } }