Upgrade structure of code base
This commit is contained in:
41
Modules/TerminalModules/EngineModule.cs
Normal file
41
Modules/TerminalModules/EngineModule.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Enigmos.Ports.DataPorts;
|
||||
using Nocturnis.Enigmos.Ports;
|
||||
using Nocturnis.GlobalManagement.Constants;
|
||||
using Nocturnis.GlobalManagement.Controls;
|
||||
using Nocturnis.Inventories.ItemSlots.ItemSlots;
|
||||
using Skeleton.Utils.Helpers;
|
||||
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
|
||||
namespace Enigmos.Modules.TerminalModules;
|
||||
public partial class EngineModule : TerminalModule
|
||||
{
|
||||
protected override bool Draggable => false;
|
||||
public DataInPort? Throttle { get; set; }
|
||||
public IChemicalItemSlot? FuelTank { get; set; }
|
||||
private double MaxPumpSpeed => 2d;
|
||||
private double EnergyConversionEfficiency => 0.5d;
|
||||
public override IEnumerable<IBasePort> Ports => new[] { Throttle! };
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
Throttle!.SetDataType(EnigmosConstant.DataPortTypes.Real);
|
||||
FuelTank = GetNode<IChemicalItemSlot>("FuelTank");
|
||||
PostInit();
|
||||
}
|
||||
|
||||
public override void Drain()
|
||||
{
|
||||
base.Drain();
|
||||
if (FuelTank!.Item!.ContentMaterial.Layers.Count == 0)
|
||||
{
|
||||
EnigmosControl.Instance.Energy = 0;
|
||||
return;
|
||||
}
|
||||
HomogeneousMixture bottom = FuelTank.Item.ContentMaterial.LayerOrder.Last.Value;
|
||||
double consumption = Math.Min(bottom.Amount, Throttle!.GetData.Get!.Double.DoubleCut() * bottom.CombustRate);
|
||||
EnigmosControl.Instance.Energy = consumption * bottom.Energy;
|
||||
bottom.Amount -= consumption;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +1,42 @@
|
||||
using Enigmos.Modules.ControllingModules;
|
||||
using Enigmos.Modules.Other;
|
||||
using Enigmos.Ports;
|
||||
using Enigmos.Ports.DataPorts;
|
||||
using Nocturnis.DataStructures;
|
||||
using Nocturnis.DataStructures.DataPortGroups;
|
||||
using Nocturnis.Enigmos.Modules;
|
||||
using Nocturnis.Enigmos.Modules.ComputationalModules;
|
||||
using Nocturnis.Enigmos.Ports;
|
||||
using TabulaSmaragdina;
|
||||
using TabulaSmaragdina.Constants;
|
||||
using Nocturnis.Enigmos.Ports.DataPorts;
|
||||
using Nocturnis.Enigmos.Ports.DataPorts.Directions;
|
||||
using Nocturnis.GlobalManagement.Constants;
|
||||
using Nocturnis.GlobalManagement.Providers;
|
||||
|
||||
namespace Enigmos.Modules.TerminalModules;
|
||||
|
||||
public partial class MemoryModule : TerminalModule, IPolymorphismModule, IComputationalCompositeModule
|
||||
public partial class MemoryModule : BaseModule, ITerminalModule, ISourceModule, IDuplicateOutputModule
|
||||
{
|
||||
private DataInPort? Input1 { get; set; }
|
||||
private DataInPort? Input2 { get; set; }
|
||||
private DataInPort? Input3 { get; set; }
|
||||
private IDataPackage? Memory { get; set; }
|
||||
private IData? Memory { get; set; }
|
||||
private IDataPortGroup? MemoryPortGroup { get; set; }
|
||||
public HashSet<IDataPortGroup> ConfigurablePortGroups { get; set; } = new();
|
||||
private OutputSubModule? Output1 { get; set; }
|
||||
private OutputSubModule? Output2 { get; set; }
|
||||
private OutputSubModule? Output3 { get; set; }
|
||||
private OutputSubModule? Output4 { get; set; }
|
||||
public override IEnumerable<BasePort> Ports => new BasePort[] { Input1!, Input2!, Input3! };
|
||||
public IBaseModule[] SubModules() => new IBaseModule[] { Output1!, Output2!, Output3!, Output4! };
|
||||
|
||||
public IDataInPort[] DataInPorts { get; set; } = Array.Empty<IDataInPort>();
|
||||
public IDataOutPort[] DataOutPorts { get; set; } = Array.Empty<IDataOutPort>();
|
||||
public override IEnumerable<IBasePort> Ports => DataInPorts.Union<IBasePort>(DataOutPorts);
|
||||
|
||||
|
||||
protected OutputSubModule GetOutputModule(string path)
|
||||
{
|
||||
OutputSubModule res = GetNode<OutputSubModule>(path);
|
||||
res.Init();
|
||||
res.ParentModule = this;
|
||||
res.Board = Board;
|
||||
return res;
|
||||
}
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
Memory = GlobalProvider.DataStructureProvider!.NewDataPackage();
|
||||
Input1 = GetPort<DataInPort>("Input1");
|
||||
Input2 = GetPort<DataInPort>("Input2");
|
||||
Input2.SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
Input3 = GetPort<DataInPort>("Input3");
|
||||
Input3.SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
Output1 = GetOutputModule("Output1");
|
||||
Output2 = GetOutputModule("Output2");
|
||||
Output3 = GetOutputModule("Output3");
|
||||
Output4 = GetOutputModule("Output4");
|
||||
Memory = GlobalProvider.DataStructureProvider!.NewData(0, EnigmosConstant.DataPortTypes.Null);
|
||||
this.DataInInit("Input", 3);
|
||||
this.DataOutInit("Output", 4);
|
||||
DataInPorts[1].SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
DataInPorts[2].SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
|
||||
MemoryPortGroup =GlobalProvider.DataStructureProvider!.NewDataPortGroup(
|
||||
this,
|
||||
new IDataPort[] { Input1, Output1.DataOut, Output2.DataOut, Output3.DataOut, Output4.DataOut },
|
||||
new IDataPort[] { DataInPorts[0] }.Union(DataOutPorts).ToArray(),
|
||||
"Memory Data Type:",
|
||||
EnigmosConstant.DataPortTypes.Real,
|
||||
EnigmosConstant.DataPortTypes.AnyType
|
||||
);
|
||||
ConfigurablePortGroups = new HashSet<IDataPortGroup>() { MemoryPortGroup };
|
||||
ConfigurablePortGroups = new HashSet<IDataPortGroup> { MemoryPortGroup };
|
||||
PostInit();
|
||||
}
|
||||
|
||||
@@ -62,30 +44,27 @@ public partial class MemoryModule : TerminalModule, IPolymorphismModule, IComput
|
||||
{
|
||||
}
|
||||
|
||||
public void Compute(IRootModule root)
|
||||
|
||||
public void Define()
|
||||
{
|
||||
Output1!.DataOut.ResultData.Assign(Memory!, MemoryPortGroup!.SelectedType);
|
||||
Output2!.DataOut.ResultData.Assign(Memory!, MemoryPortGroup.SelectedType);
|
||||
Output3!.DataOut.ResultData.Assign(Memory!, MemoryPortGroup.SelectedType);
|
||||
Output4!.DataOut.ResultData.Assign(Memory!, MemoryPortGroup.SelectedType);
|
||||
this.Define(cache => (Memory!.Data, Memory.Type)!);
|
||||
}
|
||||
|
||||
protected override void Consume(RootModule root)
|
||||
public void Drain()
|
||||
{
|
||||
bool setValue = Input2!.GetData(root).Bit;
|
||||
bool resetValue = Input3!.GetData(root).Bit;
|
||||
if (setValue)
|
||||
Memory!.Assign(Input1!.GetData(root), MemoryPortGroup!.SelectedType);
|
||||
else if(resetValue)
|
||||
Memory!.Assign(GlobalProvider.DataStructureProvider!.DefaultDataPackage, MemoryPortGroup!.SelectedType);
|
||||
Finished = true;
|
||||
}
|
||||
|
||||
public override void UpdateCables()
|
||||
{
|
||||
base.UpdateCables();
|
||||
foreach (BaseModule subModule in SubModules())
|
||||
subModule.UpdateCables();
|
||||
bool setValue = DataInPorts[1].GetData.Get!.Bit;
|
||||
bool resetValue = DataInPorts[2].GetData.Get!.Bit;
|
||||
if(resetValue)
|
||||
{
|
||||
Memory!.Assign(0, MemoryPortGroup!.SelectedType);
|
||||
Define();
|
||||
}
|
||||
else if (setValue)
|
||||
{
|
||||
Memory!.Assign(DataInPorts[1].GetData.Get!, MemoryPortGroup!.SelectedType);
|
||||
Define();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +1,27 @@
|
||||
using Enigmos.Modules.ControllingModules;
|
||||
using Enigmos.Modules.Other;
|
||||
using Enigmos.Ports;
|
||||
using Enigmos.Ports.DataPorts;
|
||||
using Nocturnis.Enigmos.Modules;
|
||||
using TabulaSmaragdina.Constants;
|
||||
using Nocturnis.Enigmos.Modules.ComputationalModules;
|
||||
using Nocturnis.Enigmos.Ports;
|
||||
using Nocturnis.Enigmos.Ports.DataPorts.Directions;
|
||||
using Nocturnis.GlobalManagement.Constants;
|
||||
|
||||
namespace Enigmos.Modules.TerminalModules;
|
||||
|
||||
public partial class SRLatchModule : TerminalModule, IComputationalCompositeModule
|
||||
public partial class SRLatchModule : BaseModule,
|
||||
ITerminalModule,
|
||||
ISourceModule,
|
||||
IDuplicateOutputModule,
|
||||
IOperationModule
|
||||
{
|
||||
private DataInPort? Input1 { get; set; }
|
||||
private DataInPort? Input2 { get; set; }
|
||||
public OutputSubModule? Output1 { get; set; }
|
||||
public OutputSubModule? Output2 { get; set; }
|
||||
public override IEnumerable<BasePort> Ports => new[] { Input1, Input2 }!;
|
||||
public IDataOutPort[] DataOutPorts { get; set; } = Array.Empty<IDataOutPort>();
|
||||
public IDataInPort[] DataInPorts { get; set; } = Array.Empty<IDataInPort>();
|
||||
public override IEnumerable<IBasePort> Ports => DataInPorts.Union<IBasePort>(DataOutPorts);
|
||||
|
||||
private bool State { get; set; }
|
||||
public IBaseModule[] SubModules() => new IBaseModule[] { Output1, Output2 };
|
||||
public void Compute(IRootModule root)
|
||||
{
|
||||
Output1!.DataOut.ResultData.Bit = State;
|
||||
Output2!.DataOut.ResultData.Bit = State;
|
||||
}
|
||||
|
||||
protected override void Consume(RootModule root)
|
||||
public void Drain()
|
||||
{
|
||||
bool set = Input1!.GetData(root).Bit;
|
||||
bool reset = Input2!.GetData(root).Bit;
|
||||
bool set = DataInPorts[0].GetData.Get!.Bit;
|
||||
bool reset = DataInPorts[1].GetData.Get!.Bit;
|
||||
if (set && reset)
|
||||
State = false;
|
||||
else if (set)
|
||||
@@ -34,33 +29,18 @@ public partial class SRLatchModule : TerminalModule, IComputationalCompositeModu
|
||||
else if (reset)
|
||||
State = false;
|
||||
}
|
||||
protected OutputSubModule GetOutputModule(string path)
|
||||
{
|
||||
OutputSubModule res = GetNode<OutputSubModule>(path);
|
||||
res.Init();
|
||||
res.ParentModule = this;
|
||||
res.Board = Board;
|
||||
return res;
|
||||
}
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
Input1 = GetPort<DataInPort>("Input1");
|
||||
Input1.SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
Input2 = GetPort<DataInPort>("Input2");
|
||||
Input2.SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
Output1 = GetOutputModule("Output1");
|
||||
Output1.DataOut.SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
Output2 = GetOutputModule("Output2");
|
||||
Output2.DataOut.SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
this.DataInInit("Input",2);
|
||||
this.DataOutInit("Output", 2);
|
||||
this.SetOutputType(EnigmosConstant.DataPortTypes.Bit);
|
||||
this.SetInputType(EnigmosConstant.DataPortTypes.Bit);
|
||||
PostInit();
|
||||
}
|
||||
|
||||
public override void UpdateCables()
|
||||
|
||||
public void Define()
|
||||
{
|
||||
base.UpdateCables();
|
||||
foreach (IBaseModule subModule in SubModules())
|
||||
subModule.UpdateCables();
|
||||
|
||||
this.Define(cache => (State, EnigmosConstant.DataPortTypes.Bit));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,13 @@
|
||||
using Enigmos.Exceptions;
|
||||
using Enigmos.Modules.ControllingModules;
|
||||
using Enigmos.Ports.DataPorts;
|
||||
using Nocturnis.Enigmos.Modules;
|
||||
using Nocturnis.Enigmos.Ports.DataPorts.Directions;
|
||||
|
||||
namespace Enigmos.Modules.TerminalModules;
|
||||
|
||||
public abstract partial class TerminalModule : BaseModule
|
||||
public abstract partial class TerminalModule : BaseModule, ITerminalModule
|
||||
{
|
||||
public bool Finished { get; set; }
|
||||
public IDataInPort[] DataInPorts { get; set; } = Array.Empty<IDataInPort>();
|
||||
|
||||
protected virtual void Consume(RootModule root)
|
||||
{
|
||||
foreach (DataInPort port in Ports.OfType<DataInPort>())
|
||||
port.GetData(root);
|
||||
Finished = true;
|
||||
}
|
||||
public virtual void Drain() => Finished = true;
|
||||
}
|
||||
|
||||
public void ConsumeWithTimeoutHandle(RootModule root)
|
||||
{
|
||||
try
|
||||
{
|
||||
Finished = true;
|
||||
Consume(root);
|
||||
}
|
||||
catch (ModuleExecutionTimeout timeout)
|
||||
{
|
||||
TimeoutHandler(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void TimeoutHandler(ModuleExecutionTimeout timeout)
|
||||
{
|
||||
Finished = false;
|
||||
base.TimeoutHandler(timeout);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,18 @@
|
||||
using Enigmos.Modules.ControllingModules;
|
||||
using Enigmos.Ports;
|
||||
using Enigmos.Ports.DataPorts;
|
||||
using Godot;
|
||||
using Nocturnis.Enigmos.Modules;
|
||||
using Nocturnis.Enigmos.Ports;
|
||||
using TabulaSmaragdina.Constants;
|
||||
using Nocturnis.Enigmos.Ports.DataPorts.Directions;
|
||||
using Nocturnis.GlobalManagement.Constants;
|
||||
|
||||
namespace Enigmos.Modules.TerminalModules.TestingModules;
|
||||
|
||||
public partial class LightEmittingDiodeModule : TerminalModule
|
||||
{
|
||||
private Sprite2D LightEmittingDiode { get; set; }
|
||||
private DataInPort Input { get; set; }
|
||||
public override IEnumerable<IBasePort> Ports => new[] { Input };
|
||||
private Sprite2D? LightEmittingDiode { get; set; }
|
||||
private IDataInPort? Input { get; set; }
|
||||
public override IEnumerable<IBasePort> Ports => new[] { Input! };
|
||||
|
||||
private static readonly Texture2D TrueTexture =
|
||||
ResourceLoader.Load<Texture2D>("res://Resources/Circuits/Modules/Terminal/Testing/LEDBubble-T.png");
|
||||
@@ -22,17 +23,17 @@ public partial class LightEmittingDiodeModule : TerminalModule
|
||||
base.Init();
|
||||
Finished = true;
|
||||
LightEmittingDiode = GetNode<Sprite2D>("LightEmittingDiode");
|
||||
Input = GetPort<DataInPort>("Input");
|
||||
Input = this.GetPort<DataInPort>("Input");
|
||||
Input.SetDataType(EnigmosConstant.DataPortTypes.Bit);
|
||||
PostInit();
|
||||
}
|
||||
|
||||
protected override void Consume(RootModule root)
|
||||
public override void Drain()
|
||||
{
|
||||
if (Input.GetData(root).Bit)
|
||||
LightEmittingDiode.Texture = TrueTexture;
|
||||
if (Input!.GetData.Get!.Bit)
|
||||
LightEmittingDiode!.Texture = TrueTexture;
|
||||
else
|
||||
LightEmittingDiode.Texture = FalseTexture;
|
||||
LightEmittingDiode!.Texture = FalseTexture;
|
||||
Finished = true;
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,11 @@ namespace Enigmos.Modules.TerminalModules.TestingModules;
|
||||
|
||||
public partial class R2Reader : Control
|
||||
{
|
||||
private AnimatedSprite2D Direction { get; set; }
|
||||
private AnimatedSprite2D Magnitude { get; set; }
|
||||
public R2 UnderlyingVector { get; set; }
|
||||
private double TargetPhase() => Math.Atan2(UnderlyingVector[2], UnderlyingVector[1]);
|
||||
private double TargetLength() => UnderlyingVector.Magnitude;
|
||||
private AnimatedSprite2D? Direction { get; set; }
|
||||
private AnimatedSprite2D? Magnitude { get; set; }
|
||||
public R2? UnderlyingVector { get; set; }
|
||||
private double TargetPhase() => Math.Atan2(UnderlyingVector![2], UnderlyingVector![1]);
|
||||
private double TargetLength() => UnderlyingVector!.Magnitude;
|
||||
|
||||
private int TargetPhaseFrame =>
|
||||
Mathf.FloorToInt((TargetPhase() % (2d * Math.PI) + 2d * Math.PI) % (2d * Math.PI) * 44d / (2d * Math.PI));
|
||||
@@ -19,8 +19,8 @@ public partial class R2Reader : Control
|
||||
Mathf.FloorToInt(TargetLength().DoubleCut() * 9d);
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
Magnitude.SpeedScale = (TargetLengthFrame - Magnitude.Frame) / 7f;
|
||||
var debug = new[] { TargetPhaseFrame - Direction.Frame, TargetPhaseFrame + 44 - Direction.Frame };
|
||||
Magnitude!.SpeedScale = (TargetLengthFrame - Magnitude.Frame) / 7f;
|
||||
var debug = new[] { TargetPhaseFrame - Direction!.Frame, TargetPhaseFrame + 44 - Direction.Frame };
|
||||
Direction.SpeedScale = debug.MinBy(Math.Abs) / 25f;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
using Enigmos.Modules.ControllingModules;
|
||||
using Enigmos.Ports;
|
||||
using Enigmos.Ports.DataPorts;
|
||||
using TabulaSmaragdina.Constants;
|
||||
using Nocturnis.Enigmos.Modules;
|
||||
using Nocturnis.GlobalManagement.Constants;
|
||||
|
||||
namespace Enigmos.Modules.TerminalModules.TestingModules;
|
||||
|
||||
public partial class R2ReaderModule : TerminalModule
|
||||
{
|
||||
private DataInPort DataIn { get; set; }
|
||||
private R2Reader R2Reader { get; set; }
|
||||
private DataInPort? DataIn { get; set; }
|
||||
private R2Reader? R2Reader { get; set; }
|
||||
|
||||
public override IEnumerable<BasePort> Ports => new[] { DataIn };
|
||||
public override IEnumerable<BasePort> Ports => new[] { DataIn! };
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
DataIn = GetPort<DataInPort>("DataIn");
|
||||
DataIn = this.GetPort<DataInPort>("DataIn");
|
||||
DataIn.SetDataType(EnigmosConstant.DataPortTypes.R2);
|
||||
R2Reader = GetNode<R2Reader>("R2Reader");
|
||||
R2Reader.Init();
|
||||
PostInit();
|
||||
}
|
||||
|
||||
protected override void Consume(RootModule root)
|
||||
public override void Drain()
|
||||
{
|
||||
R2Reader.UnderlyingVector = DataIn.GetData(root).R2;
|
||||
R2Reader!.UnderlyingVector = DataIn!.GetData.Get!.R2;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,38 @@
|
||||
using Enigmos.Modules.ControllingModules;
|
||||
using Enigmos.Ports;
|
||||
using Enigmos.Ports.DataPorts;
|
||||
using Godot;
|
||||
using Nocturnis.Enigmos.Modules;
|
||||
using Nocturnis.Enigmos.Modules.ComputationalModules;
|
||||
using Nocturnis.Enigmos.Ports;
|
||||
using Nocturnis.Enigmos.Ports.DataPorts.Directions;
|
||||
using Nocturnis.GlobalManagement.Constants;
|
||||
using Skeleton.Utils.Helpers;
|
||||
using TabulaSmaragdina.Constants;
|
||||
|
||||
namespace Enigmos.Modules.TerminalModules.TestingModules;
|
||||
|
||||
public partial class RealReaderModule : TerminalModule
|
||||
public partial class RealReaderModule : BaseModule, ITerminalModule, IOperationModule
|
||||
{
|
||||
private DataInPort Input1 { get; set; }
|
||||
private DataInPort Input2 { get; set; }
|
||||
private DataInPort Input3 { get; set; }
|
||||
private AnimatedSprite2D RealReader { get; set; }
|
||||
public override IEnumerable<BasePort> Ports => new[] { Input1, Input2, Input3 };
|
||||
private AnimatedSprite2D? RealReader { get; set; }
|
||||
public IDataInPort[] DataInPorts { get; set; } = Array.Empty<IDataInPort>();
|
||||
public override IEnumerable<IBasePort> Ports => DataInPorts;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
Input1 = GetPort<DataInPort>("Input1");
|
||||
Input2 = GetPort<DataInPort>("Input2");
|
||||
Input3 = GetPort<DataInPort>("Input3");
|
||||
Input1.SetDataType(EnigmosConstant.DataPortTypes.Real);
|
||||
Input2.SetDataType(EnigmosConstant.DataPortTypes.Real);
|
||||
Input3.SetDataType(EnigmosConstant.DataPortTypes.Real);
|
||||
this.DataInInit("Input", 3);
|
||||
this.SetInputType(EnigmosConstant.DataPortTypes.Real);
|
||||
RealReader = GetNode<AnimatedSprite2D>("RealReader");
|
||||
RealReader.SpeedScale = 0;
|
||||
RealReader.Play();
|
||||
PostInit();
|
||||
}
|
||||
|
||||
protected override void Consume(RootModule root)
|
||||
public void Drain()
|
||||
{
|
||||
double max = Input1.GetData(root).Real;
|
||||
double min = Input3.GetData(root).Real;
|
||||
double value = Input2.GetData(root).Real;
|
||||
//DebugToolWindow.FreeInfo = $"{value}";
|
||||
double max = DataInPorts[0].GetData.Get!.Double;
|
||||
double min = DataInPorts[2].GetData.Get!.Double;
|
||||
double value = DataInPorts[1].GetData.Get!.Double;
|
||||
double range = max - min;
|
||||
double percentage = (range == 0 ? 0d : value / range).DoubleCut();
|
||||
int frame = Mathf.FloorToInt(percentage * 122);
|
||||
RealReader.SpeedScale = (frame - RealReader.Frame) / 60f;
|
||||
Finished = true;
|
||||
RealReader!.SpeedScale = (frame - RealReader.Frame) / 60f;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user