Makes the singularity engine actually work stably. (#4068)

* Add GNU Octave script for tuning singularity engine. startsingularityengine is now properly tuned & sets up radiation collectors. FTLize RadiationCollectorComponent.

* Fix bugs with radiation collectors producing infinite power.

* Ensure singularities don't instantly annihilate other singularities (causing new singularities to instantly dissolve)

Technically found by a "bug" where a singularity generator would make multiple singularities, but this renders that bug harmless.

* Tune singularity shield emitters to hopefully randomly fail less, and add an Octave script for looking into that

* Fix singularity shader

* Map in an unfinished PA into Saltern

* Correct PA particles being counted twice by singularity calculations, add singulo food component

* Hopefully stop "level 1 singulo stuck in a corner" issues by freezing it when it goes to level 1 from any other level

* Apply suggestions on 'jazz' PR
This commit is contained in:
20kdc
2021-05-28 10:44:13 +01:00
committed by GitHub
parent 3ba0c01e4f
commit a3d9562532
20 changed files with 424 additions and 153 deletions

View File

@@ -11,11 +11,12 @@ using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Physics;
using Robust.Shared.Timing;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
{
[RegisterComponent]
public class RadiationCollectorComponent : PowerSupplierComponent, IInteractHand, IRadiationAct
public class RadiationCollectorComponent : Component, IInteractHand, IRadiationAct
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
@@ -23,14 +24,20 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
private bool _enabled;
private TimeSpan _coolDownEnd;
[ComponentDependency] private readonly PhysicsComponent? _collidableComponent = default!;
public void OnAnchoredChanged()
{
if(_collidableComponent != null && _collidableComponent.BodyType == BodyType.Static)
Owner.SnapToGrid();
[ViewVariables(VVAccess.ReadWrite)]
public bool Collecting {
get => _enabled;
set
{
if (_enabled == value) return;
_enabled = value;
SetAppearance(_enabled ? RadiationCollectorVisualState.Activating : RadiationCollectorVisualState.Deactivating);
}
}
[ComponentDependency] private readonly BatteryComponent? _batteryComponent = default!;
[ComponentDependency] private readonly BatteryDischargerComponent? _batteryDischargerComponent = default!;
bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs)
{
var curTime = _gameTiming.CurTime;
@@ -40,13 +47,13 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
if (!_enabled)
{
Owner.PopupMessage(eventArgs.User, Loc.GetString("The collector turns on."));
EnableCollection();
Owner.PopupMessage(eventArgs.User, Loc.GetString("radiation-collector-component-use-on"));
Collecting = true;
}
else
{
Owner.PopupMessage(eventArgs.User, Loc.GetString("The collector turns off."));
DisableCollection();
Owner.PopupMessage(eventArgs.User, Loc.GetString("radiation-collector-component-use-off"));
Collecting = false;
}
_coolDownEnd = curTime + TimeSpan.FromSeconds(0.81f);
@@ -54,23 +61,25 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
return true;
}
void EnableCollection()
{
_enabled = true;
SetAppearance(RadiationCollectorVisualState.Activating);
}
void DisableCollection()
{
_enabled = false;
SetAppearance(RadiationCollectorVisualState.Deactivating);
}
void IRadiationAct.RadiationAct(float frameTime, SharedRadiationPulseComponent radiation)
{
if (!_enabled) return;
SupplyRate = (int) (frameTime * radiation.RadsPerSecond * 3000f);
// No idea if this is even vaguely accurate to the previous logic.
// The maths is copied from that logic even though it works differently.
// But the previous logic would also make the radiation collectors never ever stop providing energy.
// And since frameTime was used there, I'm assuming that this is what the intent was.
// This still won't stop things being potentially hilarously unbalanced though.
if (_batteryComponent != null)
{
_batteryComponent!.CurrentCharge += frameTime * radiation.RadsPerSecond * 3000f;
if (_batteryDischargerComponent != null)
{
// The battery discharger is controlled like this to ensure it won't drain the entire battery in a single tick.
// If that occurs then the battery discharger ends up shutting down.
_batteryDischargerComponent!.ActiveSupplyRate = (int) Math.Max(1, _batteryComponent!.CurrentCharge);
}
}
}
protected void SetAppearance(RadiationCollectorVisualState state)