Anomaly Generator Tweaks (#13856)
This commit is contained in:
@@ -37,7 +37,9 @@ public sealed partial class AnomalyGeneratorWindow : FancyWindow
|
|||||||
var fuelCompletion = Math.Clamp((float) state.FuelAmount / state.FuelCost, 0f, 1f);
|
var fuelCompletion = Math.Clamp((float) state.FuelAmount / state.FuelCost, 0f, 1f);
|
||||||
|
|
||||||
FuelBar.Value = fuelCompletion;
|
FuelBar.Value = fuelCompletion;
|
||||||
FuelText.Text = $"{fuelCompletion:P}";
|
|
||||||
|
var charges = state.FuelAmount / state.FuelCost;
|
||||||
|
FuelText.Text = Loc.GetString("anomaly-generator-charges", ("charges", charges));
|
||||||
|
|
||||||
UpdateTimer();
|
UpdateTimer();
|
||||||
UpdateReady(); // yes this can trigger twice. no i don't care
|
UpdateReady(); // yes this can trigger twice. no i don't care
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Content.Server.Anomaly.Components;
|
using Content.Server.Anomaly.Components;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Shared.Anomaly;
|
using Content.Shared.Anomaly;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Materials;
|
using Content.Shared.Materials;
|
||||||
|
using Content.Shared.Radio;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
@@ -24,6 +26,9 @@ public sealed partial class AnomalySystem
|
|||||||
SubscribeLocalEvent<AnomalyGeneratorComponent, MaterialAmountChangedEvent>(OnGeneratorMaterialAmountChanged);
|
SubscribeLocalEvent<AnomalyGeneratorComponent, MaterialAmountChangedEvent>(OnGeneratorMaterialAmountChanged);
|
||||||
SubscribeLocalEvent<AnomalyGeneratorComponent, AnomalyGeneratorGenerateButtonPressedEvent>(OnGenerateButtonPressed);
|
SubscribeLocalEvent<AnomalyGeneratorComponent, AnomalyGeneratorGenerateButtonPressedEvent>(OnGenerateButtonPressed);
|
||||||
SubscribeLocalEvent<AnomalyGeneratorComponent, PowerChangedEvent>(OnGeneratorPowerChanged);
|
SubscribeLocalEvent<AnomalyGeneratorComponent, PowerChangedEvent>(OnGeneratorPowerChanged);
|
||||||
|
SubscribeLocalEvent<AnomalyGeneratorComponent, EntityUnpausedEvent>(OnGeneratorUnpaused);
|
||||||
|
SubscribeLocalEvent<GeneratingAnomalyGeneratorComponent, ComponentStartup>(OnGeneratingStartup);
|
||||||
|
SubscribeLocalEvent<GeneratingAnomalyGeneratorComponent, EntityUnpausedEvent>(OnGeneratingUnpaused);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGeneratorPowerChanged(EntityUid uid, AnomalyGeneratorComponent component, ref PowerChangedEvent args)
|
private void OnGeneratorPowerChanged(EntityUid uid, AnomalyGeneratorComponent component, ref PowerChangedEvent args)
|
||||||
@@ -46,6 +51,11 @@ public sealed partial class AnomalySystem
|
|||||||
TryGeneratorCreateAnomaly(uid, component);
|
TryGeneratorCreateAnomaly(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGeneratorUnpaused(EntityUid uid, AnomalyGeneratorComponent component, ref EntityUnpausedEvent args)
|
||||||
|
{
|
||||||
|
component.CooldownEndTime += args.PausedTime;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateGeneratorUi(EntityUid uid, AnomalyGeneratorComponent component)
|
public void UpdateGeneratorUi(EntityUid uid, AnomalyGeneratorComponent component)
|
||||||
{
|
{
|
||||||
var materialAmount = _material.GetMaterialAmount(uid, component.RequiredMaterial);
|
var materialAmount = _material.GetMaterialAmount(uid, component.RequiredMaterial);
|
||||||
@@ -65,14 +75,12 @@ public sealed partial class AnomalySystem
|
|||||||
if (Timing.CurTime < component.CooldownEndTime)
|
if (Timing.CurTime < component.CooldownEndTime)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var grid = Transform(uid).GridUid;
|
|
||||||
if (grid == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!_material.TryChangeMaterialAmount(uid, component.RequiredMaterial, -component.MaterialPerAnomaly))
|
if (!_material.TryChangeMaterialAmount(uid, component.RequiredMaterial, -component.MaterialPerAnomaly))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SpawnOnRandomGridLocation(grid.Value, component.SpawnerPrototype);
|
var generating = EnsureComp<GeneratingAnomalyGeneratorComponent>(uid);
|
||||||
|
generating.EndTime = Timing.CurTime + component.GenerationLength;
|
||||||
|
generating.AudioStream = Audio.PlayPvs(component.GeneratingSound, uid, AudioParams.Default.WithLoop(true));
|
||||||
component.CooldownEndTime = Timing.CurTime + component.CooldownLength;
|
component.CooldownEndTime = Timing.CurTime + component.CooldownLength;
|
||||||
UpdateGeneratorUi(uid, component);
|
UpdateGeneratorUi(uid, component);
|
||||||
}
|
}
|
||||||
@@ -126,4 +134,42 @@ public sealed partial class AnomalySystem
|
|||||||
|
|
||||||
Spawn(toSpawn, targetCoords);
|
Spawn(toSpawn, targetCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGeneratingStartup(EntityUid uid, GeneratingAnomalyGeneratorComponent component, ComponentStartup args)
|
||||||
|
{
|
||||||
|
Appearance.SetData(uid, AnomalyGeneratorVisuals.Generating, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGeneratingUnpaused(EntityUid uid, GeneratingAnomalyGeneratorComponent component, ref EntityUnpausedEvent args)
|
||||||
|
{
|
||||||
|
component.EndTime += args.PausedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGeneratingFinished(EntityUid uid, AnomalyGeneratorComponent component)
|
||||||
|
{
|
||||||
|
var grid = Transform(uid).GridUid;
|
||||||
|
if (grid == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SpawnOnRandomGridLocation(grid.Value, component.SpawnerPrototype);
|
||||||
|
RemComp<GeneratingAnomalyGeneratorComponent>(uid);
|
||||||
|
Appearance.SetData(uid, AnomalyGeneratorVisuals.Generating, false);
|
||||||
|
Audio.PlayPvs(component.GeneratingFinishedSound, uid);
|
||||||
|
|
||||||
|
var message = Loc.GetString("anomaly-generator-announcement");
|
||||||
|
_radio.SendRadioMessage(uid, message, _prototype.Index<RadioChannelPrototype>(component.ScienceChannel));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateGenerator()
|
||||||
|
{
|
||||||
|
foreach (var (active, gen) in EntityQuery<GeneratingAnomalyGeneratorComponent, AnomalyGeneratorComponent>())
|
||||||
|
{
|
||||||
|
var ent = active.Owner;
|
||||||
|
|
||||||
|
if (Timing.CurTime < active.EndTime)
|
||||||
|
continue;
|
||||||
|
active.AudioStream?.Stop();
|
||||||
|
OnGeneratingFinished(ent, gen);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,15 @@ using Content.Server.Audio;
|
|||||||
using Content.Server.DoAfter;
|
using Content.Server.DoAfter;
|
||||||
using Content.Server.Explosion.EntitySystems;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.Materials;
|
using Content.Server.Materials;
|
||||||
|
using Content.Server.Radio.EntitySystems;
|
||||||
using Content.Shared.Anomaly;
|
using Content.Shared.Anomaly;
|
||||||
using Content.Shared.Anomaly.Components;
|
using Content.Shared.Anomaly.Components;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Physics.Events;
|
using Robust.Shared.Physics.Events;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
namespace Content.Server.Anomaly;
|
namespace Content.Server.Anomaly;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -18,11 +21,13 @@ namespace Content.Server.Anomaly;
|
|||||||
public sealed partial class AnomalySystem : SharedAnomalySystem
|
public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IConfigurationManager _configuration = default!;
|
[Dependency] private readonly IConfigurationManager _configuration = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
[Dependency] private readonly AmbientSoundSystem _ambient = default!;
|
[Dependency] private readonly AmbientSoundSystem _ambient = default!;
|
||||||
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
|
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
|
||||||
[Dependency] private readonly DoAfterSystem _doAfter = default!;
|
[Dependency] private readonly DoAfterSystem _doAfter = default!;
|
||||||
[Dependency] private readonly ExplosionSystem _explosion = default!;
|
[Dependency] private readonly ExplosionSystem _explosion = default!;
|
||||||
[Dependency] private readonly MaterialStorageSystem _material = default!;
|
[Dependency] private readonly MaterialStorageSystem _material = default!;
|
||||||
|
[Dependency] private readonly RadioSystem _radio = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||||
|
|
||||||
public const float MinParticleVariation = 0.8f;
|
public const float MinParticleVariation = 0.8f;
|
||||||
@@ -128,6 +133,7 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
|||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
UpdateGenerator();
|
||||||
UpdateVessels();
|
UpdateVessels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Content.Shared.Materials;
|
using Content.Shared.Materials;
|
||||||
|
using Content.Shared.Radio;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
@@ -24,6 +26,12 @@ public sealed class AnomalyGeneratorComponent : Component
|
|||||||
[DataField("cooldownLength"), ViewVariables(VVAccess.ReadWrite)]
|
[DataField("cooldownLength"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public TimeSpan CooldownLength = TimeSpan.FromMinutes(5);
|
public TimeSpan CooldownLength = TimeSpan.FromMinutes(5);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How long it takes to generate an anomaly after pushing the button.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("generationLength"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public TimeSpan GenerationLength = TimeSpan.FromSeconds(8);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The material needed to generate an anomaly
|
/// The material needed to generate an anomaly
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -41,4 +49,22 @@ public sealed class AnomalyGeneratorComponent : Component
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("spawnerPrototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
|
[DataField("spawnerPrototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public string SpawnerPrototype = "RandomAnomalySpawner";
|
public string SpawnerPrototype = "RandomAnomalySpawner";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The radio channel for science
|
||||||
|
/// </summary>
|
||||||
|
[DataField("scienceChannel", customTypeSerializer: typeof(PrototypeIdSerializer<RadioChannelPrototype>))]
|
||||||
|
public string ScienceChannel = "Science";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sound looped while an anomaly generates
|
||||||
|
/// </summary>
|
||||||
|
[DataField("generatingSound")]
|
||||||
|
public SoundSpecifier? GeneratingSound;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sound played on generation completion.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("generatingFinishedSound")]
|
||||||
|
public SoundSpecifier? GeneratingFinishedSound;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||||
|
|
||||||
|
namespace Content.Server.Anomaly.Components;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class GeneratingAnomalyGeneratorComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// When the generating period will end.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("endTime", customTypeSerializer: typeof(TimeOffsetSerializer))]
|
||||||
|
public TimeSpan EndTime = TimeSpan.Zero;
|
||||||
|
|
||||||
|
public IPlayingAudioStream? AudioStream;
|
||||||
|
}
|
||||||
@@ -48,6 +48,18 @@ public enum AnomalyVesselVisualLayers : byte
|
|||||||
Base
|
Base
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum AnomalyGeneratorVisuals : byte
|
||||||
|
{
|
||||||
|
Generating
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum AnomalyGeneratorVisualLayers : byte
|
||||||
|
{
|
||||||
|
Base
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public enum AnomalyScannerUiKey : byte
|
public enum AnomalyScannerUiKey : byte
|
||||||
{
|
{
|
||||||
|
|||||||
BIN
Resources/Audio/Machines/anomaly_generate.ogg
Normal file
BIN
Resources/Audio/Machines/anomaly_generate.ogg
Normal file
Binary file not shown.
@@ -1,3 +1,13 @@
|
|||||||
|
- files: ["anomaly_generate.ogg"]
|
||||||
|
license: "CC0-1.0"
|
||||||
|
copyright: "Created by szegvari, converted to mono and .ogg by EmoGarbage404 (github)."
|
||||||
|
source: "https://freesound.org/people/szegvari/sounds/536794/"
|
||||||
|
|
||||||
|
- files: ["beep.ogg"]
|
||||||
|
license: "CC0-1.0"
|
||||||
|
copyright: "Created by dotY21."
|
||||||
|
source: "https://freesound.org/people/dotY21/sounds/330726/"
|
||||||
|
|
||||||
- files: ["vending_restock_start.ogg"]
|
- files: ["vending_restock_start.ogg"]
|
||||||
license: "CC0-1.0"
|
license: "CC0-1.0"
|
||||||
copyright: "https://freesound.org/people/Defaultv/"
|
copyright: "https://freesound.org/people/Defaultv/"
|
||||||
|
|||||||
BIN
Resources/Audio/Machines/beep.ogg
Normal file
BIN
Resources/Audio/Machines/beep.ogg
Normal file
Binary file not shown.
@@ -31,3 +31,8 @@ anomaly-generator-no-cooldown = Cooldown: [color=gray]Complete[/color]
|
|||||||
anomaly-generator-yes-fire = Status: [color=forestgreen]Ready[/color]
|
anomaly-generator-yes-fire = Status: [color=forestgreen]Ready[/color]
|
||||||
anomaly-generator-no-fire = Status: [color=crimson]Not ready[/color]
|
anomaly-generator-no-fire = Status: [color=crimson]Not ready[/color]
|
||||||
anomaly-generator-generate = Generate Anomaly
|
anomaly-generator-generate = Generate Anomaly
|
||||||
|
anomaly-generator-charges = {$charges ->
|
||||||
|
[one] {$charges} charge
|
||||||
|
*[other] {$charges} charges
|
||||||
|
}
|
||||||
|
anomaly-generator-announcement = An anomaly has been generated!
|
||||||
@@ -196,6 +196,10 @@
|
|||||||
- state: inserting
|
- state: inserting
|
||||||
visible: false
|
visible: false
|
||||||
map: ["enum.MaterialStorageVisualLayers.Inserting"]
|
map: ["enum.MaterialStorageVisualLayers.Inserting"]
|
||||||
|
- state: generating
|
||||||
|
visible: false
|
||||||
|
shader: unshaded
|
||||||
|
map: ["enum.AnomalyGeneratorVisualLayers.Base"]
|
||||||
- type: Transform
|
- type: Transform
|
||||||
anchored: true
|
anchored: true
|
||||||
- type: ApcPowerReceiver
|
- type: ApcPowerReceiver
|
||||||
@@ -203,12 +207,16 @@
|
|||||||
- type: ExtensionCableReceiver
|
- type: ExtensionCableReceiver
|
||||||
- type: AmbientSound
|
- type: AmbientSound
|
||||||
range: 5
|
range: 5
|
||||||
volume: -3
|
volume: -6
|
||||||
sound:
|
sound:
|
||||||
path: /Audio/Ambience/Objects/anomaly_generator.ogg
|
path: /Audio/Ambience/Objects/anomaly_generator.ogg
|
||||||
- type: Physics
|
- type: Physics
|
||||||
bodyType: Static
|
bodyType: Static
|
||||||
- type: AnomalyGenerator
|
- type: AnomalyGenerator
|
||||||
|
generatingSound:
|
||||||
|
path: /Audio/Machines/anomaly_generate.ogg
|
||||||
|
generatingFinishedSound:
|
||||||
|
path: /Audio/Machines/beep.ogg
|
||||||
- type: MaterialStorage
|
- type: MaterialStorage
|
||||||
whitelist:
|
whitelist:
|
||||||
tags:
|
tags:
|
||||||
@@ -247,12 +255,19 @@
|
|||||||
- key: enum.AnomalyGeneratorUiKey.Key
|
- key: enum.AnomalyGeneratorUiKey.Key
|
||||||
type: AnomalyGeneratorBoundUserInterface
|
type: AnomalyGeneratorBoundUserInterface
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
|
- type: ActiveRadio
|
||||||
|
channels:
|
||||||
|
- Science
|
||||||
- type: GenericVisualizer
|
- type: GenericVisualizer
|
||||||
visuals:
|
visuals:
|
||||||
enum.PowerDeviceVisuals.Powered:
|
enum.PowerDeviceVisuals.Powered:
|
||||||
enum.PowerDeviceVisualLayers.Powered:
|
enum.PowerDeviceVisualLayers.Powered:
|
||||||
True: { visible: true }
|
True: { visible: true }
|
||||||
False: { visible: false }
|
False: { visible: false }
|
||||||
|
enum.AnomalyGeneratorVisuals.Generating:
|
||||||
|
enum.AnomalyGeneratorVisualLayers.Base:
|
||||||
|
True: { visible: true }
|
||||||
|
False: { visible: false }
|
||||||
- type: WiresVisuals
|
- type: WiresVisuals
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 5000
|
price: 5000
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@@ -7,6 +7,21 @@
|
|||||||
"license":"CC0-1.0",
|
"license":"CC0-1.0",
|
||||||
"copyright":"Created by EmoGarbage",
|
"copyright":"Created by EmoGarbage",
|
||||||
"states":[
|
"states":[
|
||||||
|
{
|
||||||
|
"name": "generating",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name":"base"
|
"name":"base"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user