mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-17 05:27:38 +03:00
<!-- This is a semi-strict format, you can add/remove sections as needed but the order/format should be kept the same Remove these comments before submitting --> # Description It's simple as it sounds, really. Adds part upgrading to these machines. The experimental anomaly vessel becomes a stronger demon core every time you upgrade it because I wanted to keep the "More Good but Dangerous" motif and to keep it somewhat balanced... --- <!-- This is default collapsed, readers click to expand it and see all your media The PR media section can get very large at times, so this is a good way to keep it clean The title is written using HTML tags The title must be within the <summary> tags or you won't see it --> <details><summary><h1>Media</h1></summary> <p> i don't feel like opening up OBS today... </p> </details> --- # Changelog <!-- You can add an author after the `🆑` to change the name that appears in the changelog (ex: `🆑 Death`) Leaving it blank will default to your GitHub display name This includes all available types for the changelog --> 🆑 - add: Added part upgrading to the artifact analysis machine. - tweak: Tweaked default artifact analysis scan time to 40 seconds. - fix: Fixed anomaly vessels not actually upgrading. --------- Signed-off-by: VMSolidus <evilexecutive@gmail.com> Co-authored-by: VMSolidus <evilexecutive@gmail.com> (cherry picked from commit cf6707bd67b9c2ab27bc57d91205b204ac3636de)
223 lines
8.3 KiB
C#
223 lines
8.3 KiB
C#
using Content.Server.Anomaly.Components;
|
|
using Content.Server.Construction;
|
|
using Content.Server.Power.EntitySystems;
|
|
using Content.Shared.Anomaly;
|
|
using Content.Shared.Anomaly.Components;
|
|
using Content.Shared.Examine;
|
|
using Content.Shared.Interaction;
|
|
using Content.Shared.Research.Components;
|
|
using Content.Server.Psionics.Glimmer;
|
|
using Content.Shared.Radiation.Components;
|
|
|
|
|
|
namespace Content.Server.Anomaly;
|
|
|
|
/// <summary>
|
|
/// This handles anomalous vessel as well as
|
|
/// the calculations for how many points they
|
|
/// should produce.
|
|
/// </summary>
|
|
public sealed partial class AnomalySystem
|
|
{
|
|
private void InitializeVessel()
|
|
{
|
|
SubscribeLocalEvent<AnomalyVesselComponent, ComponentShutdown>(OnVesselShutdown);
|
|
SubscribeLocalEvent<AnomalyVesselComponent, MapInitEvent>(OnVesselMapInit);
|
|
SubscribeLocalEvent<AnomalyVesselComponent, RefreshPartsEvent>(OnRefreshParts);
|
|
SubscribeLocalEvent<AnomalyVesselComponent, UpgradeExamineEvent>(OnUpgradeExamine);
|
|
SubscribeLocalEvent<AnomalyVesselComponent, InteractUsingEvent>(OnVesselInteractUsing);
|
|
SubscribeLocalEvent<AnomalyVesselComponent, ExaminedEvent>(OnExamined);
|
|
SubscribeLocalEvent<AnomalyVesselComponent, ResearchServerGetPointsPerSecondEvent>(OnVesselGetPointsPerSecond);
|
|
SubscribeLocalEvent<AnomalyShutdownEvent>(OnShutdown);
|
|
SubscribeLocalEvent<AnomalyStabilityChangedEvent>(OnStabilityChanged);
|
|
}
|
|
|
|
private void OnStabilityChanged(ref AnomalyStabilityChangedEvent args)
|
|
{
|
|
OnVesselAnomalyStabilityChanged(ref args);
|
|
OnScannerAnomalyStabilityChanged(ref args);
|
|
}
|
|
|
|
private void OnShutdown(ref AnomalyShutdownEvent args)
|
|
{
|
|
OnVesselAnomalyShutdown(ref args);
|
|
OnScannerAnomalyShutdown(ref args);
|
|
}
|
|
|
|
private void OnExamined(EntityUid uid, AnomalyVesselComponent component, ExaminedEvent args)
|
|
{
|
|
if (!args.IsInDetailsRange)
|
|
return;
|
|
|
|
args.PushText(component.Anomaly == null
|
|
? Loc.GetString("anomaly-vessel-component-not-assigned")
|
|
: Loc.GetString("anomaly-vessel-component-assigned"));
|
|
}
|
|
|
|
private void OnVesselShutdown(EntityUid uid, AnomalyVesselComponent component, ComponentShutdown args)
|
|
{
|
|
if (component.Anomaly is not { } anomaly)
|
|
return;
|
|
|
|
if (!TryComp<AnomalyComponent>(anomaly, out var anomalyComp))
|
|
return;
|
|
|
|
anomalyComp.ConnectedVessel = null;
|
|
}
|
|
|
|
private void OnVesselMapInit(EntityUid uid, AnomalyVesselComponent component, MapInitEvent args)
|
|
{
|
|
UpdateVesselAppearance(uid, component);
|
|
}
|
|
|
|
private void OnRefreshParts(EntityUid uid, AnomalyVesselComponent component, RefreshPartsEvent args)
|
|
{
|
|
var pointRating = args.PartRatings[component.MachinePartPointMultiplier];
|
|
var radRating = args.PartRatings[component.MachinePartPointMultiplier];
|
|
|
|
component.PointMultiplier = component.BasePointMultiplier * (component.UpgradePointMultiplier * pointRating);
|
|
|
|
if (TryComp<RadiationSourceComponent>(uid, out var radiation))
|
|
radiation.Intensity = component.BaseRadiation * radRating;
|
|
}
|
|
|
|
private void OnUpgradeExamine(EntityUid uid, AnomalyVesselComponent component, UpgradeExamineEvent args)
|
|
{
|
|
args.AddPercentageUpgrade("anomaly-vessel-component-upgrade-output", component.PointMultiplier / component.BasePointMultiplier);
|
|
}
|
|
|
|
private void OnVesselInteractUsing(EntityUid uid, AnomalyVesselComponent component, InteractUsingEvent args)
|
|
{
|
|
if (component.Anomaly != null ||
|
|
!TryComp<AnomalyScannerComponent>(args.Used, out var scanner) ||
|
|
scanner.ScannedAnomaly is not { } anomaly)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!TryComp<AnomalyComponent>(anomaly, out var anomalyComponent) || anomalyComponent.ConnectedVessel != null)
|
|
return;
|
|
|
|
// Nyano - Summary - Begin modified code block: tie anomaly harvesting to glimmer rate.
|
|
if (this.IsPowered(uid, EntityManager) &&
|
|
TryComp<GlimmerSourceComponent>(anomaly, out var glimmerSource))
|
|
{
|
|
glimmerSource.Active = true;
|
|
}
|
|
// Nyano - End modified code block.
|
|
|
|
component.Anomaly = scanner.ScannedAnomaly;
|
|
anomalyComponent.ConnectedVessel = uid;
|
|
_radiation.SetSourceEnabled(uid, true);
|
|
UpdateVesselAppearance(uid, component);
|
|
Popup.PopupEntity(Loc.GetString("anomaly-vessel-component-anomaly-assigned"), uid);
|
|
}
|
|
|
|
private void OnVesselGetPointsPerSecond(EntityUid uid, AnomalyVesselComponent component, ref ResearchServerGetPointsPerSecondEvent args)
|
|
{
|
|
if (!this.IsPowered(uid, EntityManager) || component.Anomaly is not {} anomaly)
|
|
return;
|
|
|
|
args.Points += (int) (GetAnomalyPointValue(anomaly) * component.PointMultiplier);
|
|
}
|
|
|
|
private void OnVesselAnomalyShutdown(ref AnomalyShutdownEvent args)
|
|
{
|
|
var query = EntityQueryEnumerator<AnomalyVesselComponent>();
|
|
while (query.MoveNext(out var ent, out var component))
|
|
{
|
|
if (args.Anomaly != component.Anomaly)
|
|
continue;
|
|
|
|
component.Anomaly = null;
|
|
UpdateVesselAppearance(ent, component);
|
|
_radiation.SetSourceEnabled(ent, false);
|
|
|
|
if (!args.Supercritical)
|
|
continue;
|
|
_explosion.TriggerExplosive(ent);
|
|
}
|
|
}
|
|
|
|
private void OnVesselAnomalyStabilityChanged(ref AnomalyStabilityChangedEvent args)
|
|
{
|
|
var query = EntityQueryEnumerator<AnomalyVesselComponent>();
|
|
while (query.MoveNext(out var ent, out var component))
|
|
{
|
|
if (args.Anomaly != component.Anomaly)
|
|
continue;
|
|
|
|
UpdateVesselAppearance(ent, component);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the appearance of an anomaly vessel
|
|
/// based on whether or not it has an anomaly
|
|
/// </summary>
|
|
/// <param name="uid"></param>
|
|
/// <param name="component"></param>
|
|
public void UpdateVesselAppearance(EntityUid uid, AnomalyVesselComponent? component = null)
|
|
{
|
|
if (!Resolve(uid, ref component))
|
|
return;
|
|
|
|
var on = component.Anomaly != null;
|
|
|
|
if (!TryComp<AppearanceComponent>(uid, out var appearanceComponent))
|
|
return;
|
|
|
|
Appearance.SetData(uid, AnomalyVesselVisuals.HasAnomaly, on, appearanceComponent);
|
|
if (_pointLight.TryGetLight(uid, out var pointLightComponent))
|
|
_pointLight.SetEnabled(uid, on, pointLightComponent);
|
|
|
|
// arbitrary value for the generic visualizer to use.
|
|
// i didn't feel like making an enum for this.
|
|
var value = 1;
|
|
if (TryComp<AnomalyComponent>(component.Anomaly, out var anomalyComp))
|
|
{
|
|
if (anomalyComp.Stability <= anomalyComp.DecayThreshold)
|
|
{
|
|
value = 2;
|
|
}
|
|
else if (anomalyComp.Stability >= anomalyComp.GrowthThreshold)
|
|
{
|
|
value = 3;
|
|
}
|
|
}
|
|
Appearance.SetData(uid, AnomalyVesselVisuals.AnomalyState, value, appearanceComponent);
|
|
|
|
_ambient.SetAmbience(uid, on);
|
|
}
|
|
|
|
private void UpdateVessels()
|
|
{
|
|
var query = EntityQueryEnumerator<AnomalyVesselComponent>();
|
|
while (query.MoveNext(out var vesselEnt, out var vessel))
|
|
{
|
|
if (vessel.Anomaly is not { } anomUid)
|
|
continue;
|
|
|
|
if (!TryComp<AnomalyComponent>(anomUid, out var anomaly))
|
|
continue;
|
|
|
|
if (Timing.CurTime < vessel.NextBeep)
|
|
continue;
|
|
|
|
// a lerp between the max and min values for each threshold.
|
|
// longer beeps that get shorter as the anomaly gets more extreme
|
|
float timerPercentage;
|
|
if (anomaly.Stability <= anomaly.DecayThreshold)
|
|
timerPercentage = (anomaly.DecayThreshold - anomaly.Stability) / anomaly.DecayThreshold;
|
|
else if (anomaly.Stability >= anomaly.GrowthThreshold)
|
|
timerPercentage = (anomaly.Stability - anomaly.GrowthThreshold) / (1 - anomaly.GrowthThreshold);
|
|
else //it's not unstable
|
|
continue;
|
|
|
|
Audio.PlayPvs(vessel.BeepSound, vesselEnt);
|
|
var beepInterval = (vessel.MaxBeepInterval - vessel.MinBeepInterval) * (1 - timerPercentage) + vessel.MinBeepInterval;
|
|
vessel.NextBeep = beepInterval + Timing.CurTime;
|
|
}
|
|
}
|
|
}
|