diff --git a/Content.Server/Lightning/LightningSystem.cs b/Content.Server/Lightning/LightningSystem.cs index 8b0a18afb3..226772faf0 100644 --- a/Content.Server/Lightning/LightningSystem.cs +++ b/Content.Server/Lightning/LightningSystem.cs @@ -50,6 +50,7 @@ public sealed class LightningSystem : SharedLightningSystem public void ShootLightning(EntityUid user, EntityUid target, string lightningPrototype = "Lightning", bool triggerLightningEvents = true) { var spriteState = LightningRandomizer(); + _beam.TryCreateBeam(user, target, lightningPrototype, spriteState); if (triggerLightningEvents) // we don't want certain prototypes to trigger lightning level events @@ -69,7 +70,7 @@ public sealed class LightningSystem : SharedLightningSystem /// The prototype for the lightning to be created /// how many times to recursively fire lightning bolts from the target points of the first shot. /// if the lightnings being fired should trigger lightning events. - public void ShootRandomLightnings(EntityUid user, float range, int boltCount, string lightningPrototype = "Lightning", int arcDepth = 0, bool triggerLightningEvents = true) + public bool ShootRandomLightnings(EntityUid user, float range, int boltCount, string lightningPrototype = "Lightning", int arcDepth = 0, bool triggerLightningEvents = true) { //TODO: add support to different priority target tablem for different lightning types //TODO: Remove Hardcode LightningTargetComponent (this should be a parameter of the SharedLightningComponent) @@ -80,6 +81,7 @@ public sealed class LightningSystem : SharedLightningSystem _random.Shuffle(targets); targets.Sort((x, y) => y.Comp.Priority.CompareTo(x.Comp.Priority)); + bool shooted = false; //starlight int shootedCount = 0; int count = -1; while(shootedCount < boltCount) @@ -93,12 +95,14 @@ public sealed class LightningSystem : SharedLightningSystem continue; ShootLightning(user, targets[count].Owner, lightningPrototype, triggerLightningEvents); + shooted = true;//starlight if (arcDepth - targets[count].Comp.LightningResistance > 0) { ShootRandomLightnings(targets[count].Owner, range, 1, lightningPrototype, arcDepth - targets[count].Comp.LightningResistance, triggerLightningEvents); } shootedCount++; } + return shooted; //starlight } } diff --git a/Content.Server/Singularity/EntitySystems/SingularitySystem.cs b/Content.Server/Singularity/EntitySystems/SingularitySystem.cs index 13f5afa5ba..f28502fc75 100644 --- a/Content.Server/Singularity/EntitySystems/SingularitySystem.cs +++ b/Content.Server/Singularity/EntitySystems/SingularitySystem.cs @@ -4,10 +4,11 @@ using Content.Server.Singularity.Events; using Content.Shared.Singularity.Components; using Content.Shared.Singularity.EntitySystems; using Content.Shared.Singularity.Events; -using Content.Server.Supermatter.Components; using Robust.Server.GameStates; +using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.GameStates; +using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Singularity.EntitySystems; @@ -36,11 +37,6 @@ public sealed class SingularitySystem : SharedSingularitySystem /// public const float BaseEntityEnergy = 1f; - /// - /// Whether or not the singuloo has eaten the supermatter crystal - /// - public bool HasEatenSM = false; - public override void Initialize() { base.Initialize(); @@ -107,7 +103,7 @@ public sealed class SingularitySystem : SharedSingularitySystem { // Normally, a level 6 singularity requires the supermatter + 3000 energy. // The required amount of energy has been bumped up to compensate for the lack of the supermatter. - >= 5000 when HasEatenSM => 6, + >= 5000 => 6, >= 2000 => 5, >= 1000 => 4, >= 500 => 3, @@ -220,8 +216,7 @@ public sealed class SingularitySystem : SharedSingularitySystem // Don't double count singulo food if (HasComp(args.Entity)) return; - if (HasComp(uid)) - HasEatenSM = true; + AdjustEnergy(uid, BaseEntityEnergy, singularity: comp); } diff --git a/Content.Server/Supermatter/Components/SupermatterComponent.cs b/Content.Server/Supermatter/Components/SupermatterComponent.cs deleted file mode 100644 index 5e699e9a49..0000000000 --- a/Content.Server/Supermatter/Components/SupermatterComponent.cs +++ /dev/null @@ -1,276 +0,0 @@ -using Content.Shared.Atmos; -using Robust.Shared.Audio; - -namespace Content.Server.Supermatter.Components; - -[RegisterComponent] -public sealed partial class SupermatterComponent : Component -{ - /// - /// The damage taken from direct hits, e.g. laser weapons - /// - [ViewVariables(VVAccess.ReadOnly)] - public float AVExternalDamage = 0f; - - // - [ViewVariables(VVAccess.ReadOnly)] - public float HeatAccumulatorRate = 0.5f; - - [ViewVariables(VVAccess.ReadOnly)] - public float AVHeatAccumulator = 0f; - - [ViewVariables(VVAccess.ReadOnly)] - public float RadiationAccumulatorRate = 0.3f; - - [ViewVariables(VVAccess.ReadOnly)] - public float AVRadiationAccumulator = 0f; - - [ViewVariables(VVAccess.ReadOnly)] - public float LightingAccumulatorThreshold = 2f; - - [ViewVariables(VVAccess.ReadOnly)] - public float LightingAccumulatorRate = 0.1f; - - [ViewVariables(VVAccess.ReadOnly)] - public float AVLightingAccumulator = 0f; - - [ViewVariables(VVAccess.ReadOnly)] - public float InternalEnergyAccumulatorRate = 0.1f; - /// - /// Lightning prototype IDs that the supermatter should spit out. - /// - public readonly string[] LightningPrototypeIDs = - { - "Lightning", - "ChargedLightning", - "SuperchargedLightning", - "HyperchargedLightning" - }; - public readonly string SliverPrototype = "SupermatterSliver"; - - [DataField("zapSound")] - public SoundSpecifier SupermatterZapSound = new SoundPathSpecifier("/Audio/Weapons/emitter2.ogg"); - - [DataField("calmAmbienceSound")] - public SoundSpecifier CalmAmbienceSound = new SoundPathSpecifier("/Audio/Ambience/Objects/supermatter_calm.ogg"); - - [DataField("delamAmbienceSound")] - public SoundSpecifier DelamAmbienceSound = new SoundPathSpecifier("/Audio/Ambience/Objects/supermatter_delam.ogg"); - - [ViewVariables] - public SoundSpecifier CurrentAmbience = new SoundPathSpecifier("/Audio/Ambience/Objects/supermatter_calm.ogg"); - - [DataField("teslaSpawnPrototype")] - public string TeslaPrototype = "TeslaEnergyBall"; - - [DataField("singularitySpawnPrototype")] - public string SingularityPrototype = "Singularity"; - - [DataField("supermatterKudzuSpawnPrototype")] - public string SupermatterKudzuPrototype = "SupermatterKudzu"; - - /// - /// If a supermatter sliver has been removed. Lowers the delamination countdown time. - /// - [ViewVariables(VVAccess.ReadOnly)] - public bool SliverRemoved = false; - - /// - /// Indicates whether supermatter crystal is active or not. - /// - [DataField("activated")] - public bool Activated = false; - - [ViewVariables] - public GasMixture AbsorbedGasMix = new(); - - /// - /// Delta time between Update() calls storage. - /// - public float DeltaTime = 0f; - - public float UpdateTimerAccumulator = 0f; - - public float AnnouncementTimerAccumulator = 0f; - - /// - /// Amount of seconds to pass before another SM cycle. - /// - [DataField("updateTimer")] - public float UpdateTimer = 1f; - - /// - /// Amount of seconds to pass before makes an announcement. - /// - [DataField("announcementTimer")] - public float AnnouncementTimer = 60f; - - [ViewVariables(VVAccess.ReadWrite)] - public int? PreferredDelamType = 0; - - /// - /// The time in seconds for crystal to delaminate. - /// - [DataField("countdownTimer")] - public float DelamCountdownTimerRaw = 120f; - public float DelamCountdownTimer => SliverRemoved ? DelamCountdownTimerRaw / 2 : DelamCountdownTimerRaw; - public bool DelamAnnouncementHappened = false; - - [ViewVariables(VVAccess.ReadWrite)] - public float DelamCountdownAccumulator = 0f; - - /// - /// The portion of gasmix we should absorb. - /// - [DataField("gasAbsorptionRatio")] - public float AbsorptionRatio = .15f; - - /// - /// This value effects gas output, damage and power generation. - /// - [ViewVariables(VVAccess.ReadOnly)] - public float InternalEnergy = 0f; - - /// - /// The amount of damage the SM currently has. - /// - [DataField("damage")] - public float Damage = 0f; - - /// - /// The amount of damage SM had before the cycle. - /// - public float DamageArchive = 0f; - - /// - /// The temperature at which the supermatter crystal will begin to take damage. - /// - [ViewVariables(VVAccess.ReadOnly)] - public float TempLimit = Atmospherics.T0C + HeatPenaltyThreshold; - - /// - /// Multiplies our gas waste amount and temperature. - /// - [ViewVariables(VVAccess.ReadOnly)] - public float WasteMultiplier = 0f; - - [DataField("damageDangerPoint")] - public float DamageDangerPoint = 50f; - - [DataField("damageEmergencyPoint")] - public float DamageEmergencyPoint = 75f; - - [DataField("damageDelaminationPoint")] - public float DelaminationPoint = 100f; - - [ViewVariables(VVAccess.ReadOnly)] - public bool AreWeDelaming = false; - - /// - /// Affects the heat SM makes. - /// - [ViewVariables(VVAccess.ReadOnly)] - public float GasHeatModifier = 0f; - /// - /// Affters the minimum point at which SM takes damage. - /// - [ViewVariables(VVAccess.ReadOnly)] - public float GasHeatResistance = 0f; - /// - /// How much power decay is negated. Complete power decay negation at 1. - /// - [ViewVariables(VVAccess.ReadOnly)] - public float GasPowerlossInhibition = 0f; - [ViewVariables(VVAccess.ReadOnly)] - public float ThermalСonductivity = 0f; - /// - /// Affects the power gain the SM experiences from heat. - /// - [ViewVariables(VVAccess.ReadOnly)] - public float HeatPowerGeneration = 0f; - - /// - /// Lesser than that and it's not worth processing. - /// - public const float MinimumMoleCount = .01f; - - public const float HeatPenaltyThreshold = 40f; - public const float PowerPenaltyThreshold = 3f; - public const float MolePenaltyThreshold = 900f; - public const float ThermalReleaseModifier = 4f; - public const float PlasmaReleaseModifier = 1.5f; - public const float OxygenReleaseModifier = 2.5f; - public const float GasHeatPowerScaling = 1f / 6f; - - /// - /// Stores gas properties used for the supermatter. - /// Array values should alwayd match gas enum values. - /// - [ViewVariables(VVAccess.ReadOnly)] - public GasFact[] GasFacts = - { - new (thermalConductivity: 2.4f, heatPowerGeneration: 1f), // o2 - new (thermalConductivity: 2.0f, heatModifier: -2.5f, heatPowerGeneration: -1), // n2 - new (thermalConductivity: 1.2f, heatModifier: 1f, heatPowerGeneration: 1f, powerlossInhibition: 1f), // co2 - new (thermalConductivity: 6.0f, heatModifier: 14f, heatPowerGeneration: 1f), // plasma - new (thermalConductivity: 3.0f, heatModifier: 9f, heatPowerGeneration: 1f), // tritium - new (thermalConductivity: 1.4f, heatModifier: 11f, heatPowerGeneration: 1f), // vapor - new (thermalConductivity: 1.6f, heatPowerGeneration: .5f), // ommonium - new (thermalConductivity: 1.3f, heatResistance: 5f), // n2o - new (thermalConductivity: 9.9f, heatModifier: 9f, heatResistance: 1f, heatPowerGeneration: 1f), // frezon - }; -} - -/// -/// Stores gas properties used for the supermatter. -/// -[Serializable] -[DataDefinition] -public sealed partial class GasFact -{ - /// - /// Affects the amount of power the main SM zap makes. - /// - [ViewVariables(VVAccess.ReadWrite)] - public float ThermalСonductivity; - /// - /// Affects the heat SM makes. - /// - [ViewVariables(VVAccess.ReadWrite)] - public float HeatModifier; - /// - /// Affters the minimum point at which SM takes damage. - /// - [ViewVariables(VVAccess.ReadWrite)] - public float HeatResistance; - /// - /// Affects the power gain the SM experiences from heat. - /// - [ViewVariables(VVAccess.ReadWrite)] - public float HeatPowerGeneration; - /// - /// How much power decay is negated. Complete power decay negation at 1. - /// - [ViewVariables(VVAccess.ReadWrite)] - public float PowerlossInhibition; - - public GasFact(float? thermalConductivity = null, float? heatModifier = null, float? heatResistance = null, float? heatPowerGeneration = null, float? powerlossInhibition = null) - { - ThermalСonductivity = thermalConductivity ?? 1; - HeatModifier = heatModifier ?? 1; - HeatResistance = heatResistance ?? 0; - HeatPowerGeneration = heatPowerGeneration ?? 0; - PowerlossInhibition = powerlossInhibition ?? 0; - } -} - -/// -/// Type of delamination that should occur. -/// -public enum DelamType : sbyte -{ - Explosion = 0, - Tesla = 1, - Singularity = 2, - ResonanceCascade = 3, -} diff --git a/Content.Server/Supermatter/EntitySystems/SupermatterSystem.cs b/Content.Server/Supermatter/EntitySystems/SupermatterSystem.cs deleted file mode 100644 index f82677cb5c..0000000000 --- a/Content.Server/Supermatter/EntitySystems/SupermatterSystem.cs +++ /dev/null @@ -1,504 +0,0 @@ -using Content.Server.Atmos.EntitySystems; -using Content.Server.Supermatter.Components; -using Content.Shared.Atmos; -using Content.Server.Lightning; -using Content.Shared.Radiation.Components; -using Content.Shared.Interaction; -using Content.Server.Audio; -using Content.Shared.Audio; -using Content.Server.Station.Systems; -using Content.Server.Station.Components; -using Content.Server.Anomaly; -using Content.Shared.Damage; -using Content.Shared.Tag; -using Content.Shared.DoAfter; -using Content.Server.Popups; -using Content.Shared.Supermatter; -using Content.Server.Administration.Logs; -using Robust.Shared.Physics.Events; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Random; -using Content.Shared.Database; -using Content.Server.Chat.Systems; -using System.Text; -using Content.Server.AlertLevel; -using Content.Shared.Examine; -using Content.Server.DoAfter; -using Content.Server.Explosion.EntitySystems; -using Content.Server.Kitchen.Components; -using Content.Shared.Weapons.Melee.EnergySword; -using Content.Shared.Singularity.Components; -using System; -using Robust.Shared.Audio; - -namespace Content.Server.Supermatter.EntitySystems; - -public sealed class SupermatterSystem : EntitySystem -{ - [Dependency] private readonly AtmosphereSystem _atmos = default!; - [Dependency] private readonly SharedAudioSystem _sound = default!; - [Dependency] private readonly LightningSystem _lightning = default!; - [Dependency] private readonly ChatSystem _chat = default!; - [Dependency] private readonly AlertLevelSystem _alert = default!; - [Dependency] private readonly PopupSystem _popup = default!; - [Dependency] private readonly AmbientSoundSystem _ambience = default!; - [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly TagSystem _tagSystem = default!; - [Dependency] private readonly StationSystem _station = default!; - [Dependency] private readonly AnomalySystem _anomaly = default!; - [Dependency] private readonly SharedTransformSystem _transform = default!; - [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly DoAfterSystem _doAfter = default!; - [Dependency] private readonly ExplosionSystem _explosion = default!; - - public static SoundSpecifier VaporizeSound = - new SoundPathSpecifier("/Audio/Effects/Grenades/Supermatter/supermatter_start.ogg"); - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnCollide); - SubscribeLocalEvent(OnClick); - SubscribeLocalEvent(OnGetSliver); - SubscribeLocalEvent(OnGetHit); - SubscribeLocalEvent(OnExamine); - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - foreach (var sm in EntityQuery()) - { - if (!sm.Activated) - return; - - var uid = sm.Owner; - - sm.DeltaTime = frameTime; - sm.UpdateTimerAccumulator += frameTime; - - if (sm.UpdateTimerAccumulator >= sm.UpdateTimer) - { - sm.UpdateTimerAccumulator = 0f; - Cycle(uid, sm); - } - } - } - - public void Cycle(EntityUid uid, SupermatterComponent sm) - { - sm.AnnouncementTimerAccumulator++; - - ProcessAtmos(uid, sm); - ProcessPower(uid, sm); - ProcessDamage(uid, sm); - - // due to how damage calculation works, it will do the announcement only if sm is consistently taking damage - if (sm.Damage > sm.DamageArchive) - { - if (sm.AnnouncementTimerAccumulator > sm.AnnouncementTimer) - { - sm.AnnouncementTimerAccumulator = 0f; - var loc = "danger"; - if (sm.Damage > sm.DamageEmergencyPoint) - loc = "critical"; - - SupermatterAlert(uid, Loc.GetString($"supermatter-announcement-{loc}", ("integrity", (int)(sm.DelaminationPoint - sm.Damage)))); - } - } - sm.DamageArchive = sm.Damage; - - if (sm.AreWeDelaming) - DelamCountdown(uid, sm); - - ProcessWaste(uid, sm); - - HandleSound(uid, sm); - } - - /// - /// Calculate power based on gases absorbed. - /// - private void ProcessAtmos(EntityUid uid, SupermatterComponent sm) - { - var mix = _atmos.GetContainingMixture((uid, Transform(uid)), true, true) ?? new(); - var absorbedMix = mix?.RemoveRatio(sm.AbsorptionRatio) ?? new(); - - // calculate gases - var gasPercentages = new float[Enum.GetValues(typeof(Gas)).Length]; - - var thermalСonductivity = 0f; - var heatModifier = 0f; - var heatResistance = 0f; - var heatPowerGeneration = 0f; - var powerlossInhibition = 0f; - - var moles = absorbedMix.TotalMoles; - - if (moles <= SupermatterComponent.MinimumMoleCount) - return; - - for (int i = 0; i < gasPercentages.Length; i++) - { - var moleCount = absorbedMix.GetMoles(i); - - if (moleCount <= SupermatterComponent.MinimumMoleCount) - continue; - - gasPercentages[i] = moleCount / moles; - var smGas = sm.GasFacts[i]; - - thermalСonductivity += smGas.ThermalСonductivity * gasPercentages[i]; - heatModifier += smGas.HeatModifier * gasPercentages[i]; - heatResistance += smGas.HeatResistance * gasPercentages[i]; - heatPowerGeneration += smGas.HeatPowerGeneration * gasPercentages[i]; - powerlossInhibition += smGas.PowerlossInhibition * gasPercentages[i]; - } - - heatPowerGeneration = Math.Clamp(heatPowerGeneration, 0, 1); - powerlossInhibition = Math.Clamp(powerlossInhibition, 0, 1); - - sm.AbsorbedGasMix = absorbedMix; - sm.ThermalСonductivity = thermalСonductivity; - sm.GasHeatModifier = heatModifier; - sm.GasHeatResistance = heatResistance; - sm.HeatPowerGeneration = heatPowerGeneration; - sm.GasPowerlossInhibition = powerlossInhibition; - } - /// - /// Shoot lightning and radiate everything based on whatever power there is. - /// - private void ProcessPower(EntityUid uid, SupermatterComponent sm) - { - var powerHeat = sm.HeatPowerGeneration * sm.AbsorbedGasMix.Temperature * SupermatterComponent.GasHeatPowerScaling; - var powerloss = -1 * sm.GasPowerlossInhibition; - var atmosStrength = Math.Clamp((powerHeat + powerloss) * 0.2f, 0, 2); - - var damageStrength = Math.Clamp(sm.Damage / sm.DelaminationPoint, 0, 1); - var strength = Math.Clamp(atmosStrength + damageStrength, 0, 4); - var damageExternal = sm.AVExternalDamage + strength; - sm.AVExternalDamage = 0f; - - sm.AVHeatAccumulator = Math.Clamp(sm.AVHeatAccumulator + (damageExternal * sm.HeatAccumulatorRate), 0, 10); - sm.AVRadiationAccumulator = Math.Clamp(sm.AVRadiationAccumulator + (damageExternal * sm.RadiationAccumulatorRate), 0, 10); - sm.AVLightingAccumulator = Math.Clamp(sm.AVLightingAccumulator + (damageExternal * sm.LightingAccumulatorRate), 0, 10); - sm.InternalEnergy = Math.Clamp(sm.InternalEnergy + (damageExternal * sm.InternalEnergyAccumulatorRate), 0, 10); - - if (sm.AVLightingAccumulator > sm.LightingAccumulatorThreshold) - { - var lightningProto = sm.LightningPrototypeIDs[(int)Math.Clamp(sm.AVLightingAccumulator, 0, 3)]; - _lightning.ShootRandomLightnings(uid, 3, (int)sm.AVLightingAccumulator, lightningProto); - sm.AVLightingAccumulator = 0; - } - - Comp(uid).Intensity = 1 + sm.AVRadiationAccumulator; - sm.AVRadiationAccumulator /= 2; - sm.InternalEnergy /= 2; - - var mix = _atmos.GetContainingMixture((uid, Transform(uid)), true, true) ?? new(); - mix.Temperature += sm.AVHeatAccumulator * 4; - sm.AVHeatAccumulator /= sm.ThermalСonductivity; - } - /// - /// React to damage dealt by all doodads. - /// - private void ProcessDamage(EntityUid uid, SupermatterComponent sm) - { - var additiveTempBase = Atmospherics.T0C + SupermatterComponent.HeatPenaltyThreshold; - var tempLimitBase = additiveTempBase; - var tempLimitGas = sm.GasHeatResistance * additiveTempBase; - var tempLimitMoles = Math.Clamp(2 - sm.AbsorbedGasMix.TotalMoles / 100, 0, 1) * additiveTempBase; - - sm.TempLimit = Math.Max(tempLimitBase + tempLimitGas + tempLimitMoles, Atmospherics.TCMB); - - var damageHeat = Math.Clamp((sm.AbsorbedGasMix.Temperature - sm.TempLimit) / 24000, 0, .15f); - var damagePower = Math.Clamp((sm.InternalEnergy - SupermatterComponent.PowerPenaltyThreshold), 0, .1f); - var damageMoles = Math.Clamp((sm.AbsorbedGasMix.TotalMoles - SupermatterComponent.MolePenaltyThreshold) / 3200, 0, .1f); - - var damageHealHeat = 0f; - - if (sm.AbsorbedGasMix.TotalMoles > 0) - damageHealHeat = Math.Clamp((sm.AbsorbedGasMix.TotalMoles - sm.TempLimit) / 6000, -.1f, 0); - - var totalDamage = damageHeat + damagePower + damageMoles + damageHealHeat; - var oldDamage = sm.Damage; - sm.Damage += Math.Max(totalDamage, 0); - - if (sm.Damage >= sm.DelaminationPoint && !sm.AreWeDelaming) - { - sm.AreWeDelaming = true; - SupermatterAlert(uid, Loc.GetString("supermatter-announcement-delam")); - } - - if (sm.Damage > sm.DamageDangerPoint && _random.Prob(.0001f)) - GenerateAnomaly(uid); - } - /// - /// Process waste, release hot plasma and oxygen. - /// - private void ProcessWaste(EntityUid uid, SupermatterComponent sm) - { - sm.WasteMultiplier = Math.Clamp(1f + sm.GasHeatModifier, .5f, float.PositiveInfinity); - var mix = _atmos.GetContainingMixture((uid, Transform(uid)), true, true) ?? new(); - var mergeMix = sm.AbsorbedGasMix; - - mergeMix.Temperature += .65f * sm.WasteMultiplier * SupermatterComponent.ThermalReleaseModifier; - mergeMix.Temperature = Math.Clamp(mergeMix.Temperature, Atmospherics.TCMB, 2500 * sm.WasteMultiplier); - - mergeMix.AdjustMoles(Gas.Plasma, Math.Max(.65f * sm.InternalEnergy * sm.WasteMultiplier * SupermatterComponent.PlasmaReleaseModifier, 0)); - mergeMix.AdjustMoles(Gas.Oxygen, Math.Max(.65f * sm.InternalEnergy * sm.WasteMultiplier * SupermatterComponent.OxygenReleaseModifier, 0)); - - _atmos.Merge(mix, mergeMix); - } - - /// - /// Swaps out ambience sounds whether the SM is delamming or not. - /// - private void HandleSound(EntityUid uid, SupermatterComponent sm) - { - var ambienceComp = Comp(uid); - - if (sm.AreWeDelaming) - { - if (sm.CurrentAmbience != sm.DelamAmbienceSound) - sm.CurrentAmbience = sm.DelamAmbienceSound; - } - else if (sm.CurrentAmbience != sm.CalmAmbienceSound) - sm.CurrentAmbience = sm.CalmAmbienceSound; - - if (ambienceComp.Sound != sm.CurrentAmbience) - _ambience.SetSound(uid, sm.CurrentAmbience, ambienceComp); - } - - /// - /// Make console alerts, set station codes, etc. etc. - /// - /// If true, the message will be sent from Central Command - public void SupermatterAlert(EntityUid uid, string message, bool customSender = false) - { - _chat.DispatchStationAnnouncement(uid, message, customSender ? "Central Command" : Loc.GetString("supermatter-announcement-sender"), playDefault: false, playTts: true, colorOverride: Color.Yellow); - } - - private void GenerateAnomaly(EntityUid uid, float amount = 1) - { - var stationUid = _station.GetOwningStation(uid); - - if (stationUid == null || !TryComp(stationUid, out var data)) - return; - - var grid = _station.GetLargestGrid(data); - - if (grid == null) - return; - - for (var i = 0; i < amount; i++) - { - _anomaly.SpawnOnRandomGridLocation((EntityUid)grid, "RandomAnomalySpawner"); - _adminLogger.Add(LogType.Anomaly, LogImpact.Medium, $"An anomaly has been spawned by the supermatter crystal."); - } - } - - /// - /// Vaporizes the targeted uid. - /// - private void Vaporize(EntityUid uid, EntityUid smUid) - { - if (EntityManager.IsQueuedForDeletion(uid)) - return; - - if (_tagSystem.HasTag(uid, "EmitterBolt") - || HasComp(uid)) - return; - - if (TryComp(smUid, out var sm)) - sm.AVExternalDamage += 1f; - - _sound.PlayPvs(VaporizeSound, smUid); - EntityManager.QueueDeleteEntity(uid); - - // getting discombobulated by the SM is the same as permanent round removal so why not log that - _adminLogger.Add(LogType.Action, LogImpact.High, $"{EntityManager.ToPrettyString(uid):player} has been vaporized by the supermatter."); - } - - /// - /// Handle supermatter delamination and the end of the station. - /// - private void Delaminate(EntityUid uid, SupermatterComponent sm) - { - sm.PreferredDelamType = sm.PreferredDelamType ?? (int)ChooseDelam(sm); - Delaminate(uid, sm, (DelamType)sm.PreferredDelamType); - } - - /// - /// Handle supermatter delamination based on it's type. - /// - private void Delaminate(EntityUid uid, SupermatterComponent sm, DelamType type) - { - GenerateAnomaly(uid, _random.Next(2, 4)); - - var prototypeId = string.Empty; - switch (type) - { - case DelamType.Explosion: - default: - _explosion.TriggerExplosive(uid); return; - case DelamType.Tesla: - prototypeId = sm.TeslaPrototype; break; - case DelamType.Singularity: - prototypeId = sm.SingularityPrototype; break; - case DelamType.ResonanceCascade: - prototypeId = sm.SupermatterKudzuPrototype; break; - } - if (string.IsNullOrWhiteSpace(prototypeId)) - return; - EntityManager.SpawnEntity(prototypeId, Transform(uid).Coordinates); - } - - /// - /// Choose a prefered delamination type. The supermatter is picky. - /// - private DelamType ChooseDelam(SupermatterComponent sm) - { - if (sm.AbsorbedGasMix.TotalMoles >= SupermatterComponent.MolePenaltyThreshold) - return DelamType.Singularity; - - if (sm.InternalEnergy > SupermatterComponent.PowerPenaltyThreshold) - return DelamType.Tesla; - - // todo: add resonance cascade when hypernob and antinob gases get added - // or a destabilizing crystal. bet it will take years :godo: - - return DelamType.Explosion; - } - /// - /// Handle the delamination countdown, alerts, etc. - /// - private void DelamCountdown(EntityUid uid, SupermatterComponent sm) - { - if (!sm.DelamAnnouncementHappened) - { - var delamType = ChooseDelam(sm); - var stationUid = _station.GetStationInMap(Transform(uid).MapID); - - var alertLevel = string.Empty; - var announcementLoc = string.Empty; - - var sb = new StringBuilder(); - sb.Append(Loc.GetString("supermatter-announcement-delam")); - switch (delamType) - { - case DelamType.Explosion: - default: - announcementLoc = "supermatter-announcement-delam-explosion"; - alertLevel = "yellow"; - break; - case DelamType.Tesla: - announcementLoc = "supermatter-announcement-delam-tesla"; - alertLevel = "delta"; - break; - case DelamType.Singularity: - announcementLoc = "supermatter-announcement-delam-singuloose"; - alertLevel = "delta"; - break; - case DelamType.ResonanceCascade: - announcementLoc = "supermatter-announcement-delam-cascade"; - alertLevel = "delta"; - break; - } - sb.AppendLine(" " + Loc.GetString(announcementLoc)); - sb.Append(Loc.GetString("supermatter-announcement-delam-countdown", ("seconds", sm.DelamCountdownTimer))); - // make it cancellable in case there are crazy engineers that managed to contain the delam - if (stationUid != null) - _alert.SetLevel(stationUid.Value, alertLevel, true, true, true, false); - - SupermatterAlert(uid, sb.ToString()); - - sm.DelamAnnouncementHappened = true; - } - - if (sm.Damage < sm.DelaminationPoint) - { - // yay! - sm.DelamCountdownAccumulator = 0; - sm.DelamAnnouncementHappened = false; - sm.AreWeDelaming = false; - SupermatterAlert(uid, Loc.GetString("supermatter-announcement-safe")); - return; - } - if (sm.DelamCountdownAccumulator >= sm.DelamCountdownTimer) // uh oh - Delaminate(uid, sm); - sm.DelamCountdownAccumulator++; - } - - private void OnCollide(EntityUid uid, SupermatterComponent sm, StartCollideEvent args) - { - if (!sm.Activated) - sm.Activated = true; - - Vaporize(args.OtherEntity, uid); - } - - private void OnClick(EntityUid uid, SupermatterComponent sm, InteractUsingEvent args) - { - if (HasComp(args.Used)) - { - if (sm.Damage >= 100) - { - _popup.PopupEntity(Loc.GetString("supermatter-tamper-fail"), args.User, args.User); - return; - } - - if (HasComp(args.Used)) - { - _adminLogger.Add(LogType.Action, LogImpact.High, $"{EntityManager.ToPrettyString(args.User):player} is trying to extract a sliver from the supermatter crystal."); - _popup.PopupEntity(Loc.GetString("supermatter-tamper-begin"), args.User, args.User); - - var doAfterArgs = new DoAfterArgs(EntityManager, args.User, 30, new SupermatterDoAfterEvent(), uid, target: uid, used: args.Used) - { - BreakOnDamage = true, - BreakOnHandChange = true, - BreakOnMove = true, - BreakOnWeightlessMove = false, - NeedHand = true, - RequireCanInteract = true, - }; - - _doAfter.TryStartDoAfter(doAfterArgs); - } - else - { - Vaporize(args.Used, uid); - } - } - } - - private void OnGetSliver(EntityUid uid, SupermatterComponent sm, SupermatterDoAfterEvent args) - { - if (args.Cancelled) - return; - - sm.Damage += 10; // your criminal actions will not go unnoticed - SupermatterAlert(uid, Loc.GetString("supermatter-announcement-tamper", ("integrity", (int)(100 - sm.Damage)))); - - Spawn(sm.SliverPrototype, _transform.GetMapCoordinates(args.User)); - _popup.PopupEntity(Loc.GetString("supermatter-tamper-end"), args.User, args.User); - } - - private void OnGetHit(EntityUid uid, SupermatterComponent sm, DamageChangedEvent args) - { - if (!sm.Activated) - sm.Activated = true; - - sm.AVExternalDamage += args.DamageDelta?.GetTotal().Value / 100 ?? 0; - } - - private void OnExamine(EntityUid uid, SupermatterComponent sm, ExaminedEvent args) - { - if (args.IsInDetailsRange) // get all close to it - { - args.PushMarkup(Loc.GetString("supermatter-examine-integrity", ("integrity", (int)(100 - sm.Damage)))); - } - } -} diff --git a/Content.Server/_Starlight/Energy/Supermatter/Const.cs b/Content.Server/_Starlight/Energy/Supermatter/Const.cs new file mode 100644 index 0000000000..f8daae6290 --- /dev/null +++ b/Content.Server/_Starlight/Energy/Supermatter/Const.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Content.Shared.Atmos; +using Content.Shared.FixedPoint; +using Robust.Shared.Physics; + +namespace Content.Server.Starlight.Energy.Supermatter; +internal static class Const +{ + public static FixedPoint2 HeatPercent = 0.82f; + public static FixedPoint2 BreakPercent = 0.04f; + public static FixedPoint2 LightingPercent = 0.03f; + public static FixedPoint2 RadiationPercent = 0.11f; + + public static FixedPoint2 DamageMultiplayer = 3.14f; + + public static GasProperties[] GasProperties = + [ + new (0.24f, 1.20f, 1.4f), // oxygen + new (0.20f, 1.46f, 1.5f), // nitrogen + new (0.12f, 2.21f, 3.5f), // carbon dioxide + new (0.60f, 0.61f, 1.3f), // plasma + new (0.30f, 0.45f, 1.2f), // tritium + new (0.14f, 2.31f, 2.5f), // vapor + new (0.16f, 2.11f, 4.4f), // ommonium + new (0.13f, 2.19f, 2.2f), // nitrous oxide + new (1.00f, 0.01f, 1.1f), // frezon + ]; + + public static float MinPressure = 33f; + public static float MaxPressure = 303.9f; + + public static float MaxTemperature = Atmospherics.T0C + 150; + + public static float EvaporationCompensation = 10; + + public static FixedPoint2 MaxDamagePerSecond = (100f / 120f) + RegenerationPerSecond; // Ensures it takes at least 2 minutes to deplete + public static FixedPoint2 RegenerationPerSecond = 0.3f; + + public static string[] AudioCrack = ["/Audio/_Starlight/Effects/supermatter/crystal_crack_1.ogg", "/Audio/_Starlight/Effects/supermatter/crystal_crack_2.ogg"]; + public static string[] AudioBurn = ["/Audio/_Starlight/Effects/supermatter/burning_1.ogg", "/Audio/_Starlight/Effects/supermatter/burning_2.ogg", "/Audio/_Starlight/Effects/supermatter/burning_3.ogg"]; + public static string AudioEvaporate = "/Audio/_Starlight/Effects/supermatter/emitter2.ogg"; +} +public record struct GasProperties(float HeatTransferPerMole, float HeatModifier, float RadiationStability); diff --git a/Content.Server/_Starlight/Energy/Supermatter/SupermatterCascadeSystem.cs b/Content.Server/_Starlight/Energy/Supermatter/SupermatterCascadeSystem.cs new file mode 100644 index 0000000000..09996cc5e6 --- /dev/null +++ b/Content.Server/_Starlight/Energy/Supermatter/SupermatterCascadeSystem.cs @@ -0,0 +1,146 @@ +using System; +using System.Linq; +using Content.Server.Atmos.EntitySystems; +using Content.Server.Chat.Managers; +using Content.Server.Lightning; +using Content.Server.Radio.EntitySystems; +using Content.Server.Starlight.Energy.Supermatter; +using Content.Shared.Abilities.Goliath; +using Content.Shared.Atmos; +using Content.Shared.Coordinates.Helpers; +using Content.Shared.Directions; +using Content.Shared.Maps; +using Content.Shared.Physics; +using Content.Shared.Random.Helpers; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Random; + +namespace Content.Server.Starlight.Energy.Supermatter; + +public sealed class SupermatterCascadeSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SharedMapSystem _map = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + + private readonly LinkedList _branches = []; + private LinkedListNode? node; + private readonly string[] _prototypes = ["Cascad1", "Cascad2", "Cascad3", "Cascad4", "Cascad5", "Cascad6"]; + public override void Initialize() + { + } + + public override void Update(float frameTime) + { + node ??= _branches.First; + if (node == null) return; + var branch = node.Value; + var nextNode = node.Next; + + branch.Lifetime--; + if (branch.Lifetime <= 0) + { + _branches.Remove(node); + node = nextNode; + return; + } + + var rand = _random.Next(0, 100); + + if (rand < 10) + { + branch.Direction = branch.RotateLeft(); + } + else if (rand < 20) + { + branch.Direction = branch.RotateRight(); + } + else if (rand < 25 && _branches.Count < 10) + { + var leftBranch = new Branch + { + Coordinates = branch.Coordinates, + Direction = branch.RotateLeft(), + Lifetime = branch.Lifetime + }; + var rightBranch = new Branch + { + Coordinates = branch.Coordinates, + Direction = branch.RotateRight(), + Lifetime = branch.Lifetime + }; + + _branches.AddLast(leftBranch); + _branches.AddLast(rightBranch); + + _branches.Remove(node); + node = nextNode; + return; + } + + branch.Coordinates = branch.Coordinates.Offset(branch.Direction); + if (_transform.GetGrid(branch.Coordinates) is not { } grid + || !TryComp(grid, out var gridComp) + || !_map.TryGetTileRef(grid, gridComp, branch.Coordinates, out var tileRef) + || tileRef.IsSpace()) + { + _branches.Remove(node); + node = nextNode; + return; + } + branch.Coordinates = branch.Coordinates.SnapToGrid(gridComp); + + foreach (var entity in _lookup.GetEntitiesIntersecting(branch.Coordinates)) + QueueDel(entity); + + SpawnAttachedTo(_random.Pick(_prototypes), branch.Coordinates); + + node = nextNode; + } + + public void StartCascade(EntityCoordinates coordinates) + { + for (int i = 0; i < 8; i += 2) + _branches.AddLast(new Branch + { + Coordinates = coordinates, + Direction = (Direction)i, + Lifetime = 100 + }); + } + + private sealed class Branch + { + public EntityCoordinates Coordinates { get; set; } + public Direction Direction { get; set; } + public int Lifetime { get; set; } + + public Direction RotateLeft() => Direction switch + { + Direction.North => Direction.NorthWest, + Direction.NorthWest => Direction.West, + Direction.West => Direction.SouthWest, + Direction.SouthWest => Direction.South, + Direction.South => Direction.SouthEast, + Direction.SouthEast => Direction.East, + Direction.East => Direction.NorthEast, + Direction.NorthEast => Direction.North, + _ => Direction, + }; + + public Direction RotateRight() => Direction switch + { + Direction.North => Direction.NorthEast, + Direction.NorthEast => Direction.East, + Direction.East => Direction.SouthEast, + Direction.SouthEast => Direction.South, + Direction.South => Direction.SouthWest, + Direction.SouthWest => Direction.West, + Direction.West => Direction.NorthWest, + Direction.NorthWest => Direction.North, + _ => Direction, + }; + } +} \ No newline at end of file diff --git a/Content.Server/_Starlight/Energy/Supermatter/SupermatterSystem.cs b/Content.Server/_Starlight/Energy/Supermatter/SupermatterSystem.cs new file mode 100644 index 0000000000..a3d819c763 --- /dev/null +++ b/Content.Server/_Starlight/Energy/Supermatter/SupermatterSystem.cs @@ -0,0 +1,242 @@ +using System; +using System.Linq; +using Content.Server.Atmos.EntitySystems; +using Content.Server.Chat.Managers; +using Content.Server.Lightning; +using Content.Server.Radio.EntitySystems; +using Content.Server.Starlight.Energy.Supermatter; +using Content.Shared.Abilities.Goliath; +using Content.Shared.Atmos; +using Content.Shared.Damage; +using Content.Shared.Damage.Prototypes; +using Content.Shared.FixedPoint; +using Content.Shared.Ghost; +using Content.Shared.Interaction; +using Content.Shared.Projectiles; +using Content.Shared.Radiation.Components; +using Content.Shared.Radio; +using Content.Shared.Singularity.Components; +using Content.Shared.Starlight.Energy.Supermatter; +using Microsoft.CodeAnalysis; +using Robust.Server.Audio; +using Robust.Shared.Physics; +using Robust.Shared.Physics.Events; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Toolshed.TypeParsers; + +namespace Content.Server.Starlight.Energy.Supermatter; + +public sealed class SupermatterSystem : AccUpdateEntitySystem +{ + [Dependency] private readonly DamageableSystem _damageable = default!; + [Dependency] private readonly AtmosphereSystem _atmosphere = default!; + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly LightningSystem _lightning = default!; + [Dependency] private readonly RadioSystem _radioSystem = default!; + [Dependency] private readonly SupermatterCascadeSystem _cascade = default!; + [Dependency] private readonly IChatManager _chat = default!; + [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + private readonly Dictionary> _supermatters = []; + private DamageGroupPrototype? _brute; + private DamageGroupPrototype? _burn; + private RadioChannelPrototype? _engi; + public override void Initialize() + { + SubscribeLocalEvent(AddSupermatter); + SubscribeLocalEvent(RemoveSupermatter); + + SubscribeLocalEvent(OnCollide); + SubscribeLocalEvent(OnInteract); + } + + private void OnInteract(Entity ent, ref InteractHandEvent args) + { + if (HasComp(args.User)) return; + + _audio.PlayPvs(Const.AudioEvaporate, ent.Owner); + + float damage = 1; + if (TryComp(args.User, out var fixture)) + damage = fixture.Fixtures.Select(x => x.Value.Density).Aggregate((i, p) => p + i) / 3; + + _burn ??= _prototypes.Index("Burn"); + _damageable.TryChangeDamage(ent.Owner, new(_burn, damage), true); + + QueueDel(args.User); + } + + private void OnCollide(Entity ent, ref EndCollideEvent args) + { + ent.Comp.Activated = true; + + if (HasComp(args.OtherEntity) + || HasComp(args.OtherEntity)) return; + + _audio.PlayPvs(Const.AudioEvaporate, ent.Owner); + float damage = 1; + if (TryComp(args.OtherEntity, out var fixture)) + damage = fixture.Fixtures.Select(x => x.Value.Density).Aggregate((i, p) => p + i) / 3; + + _burn ??= _prototypes.Index("Burn"); + _damageable.TryChangeDamage(ent.Owner, new(_burn, damage), true); + + QueueDel(args.OtherEntity); + } + private void AddSupermatter(Entity ent, ref ComponentInit args) => _supermatters.TryAdd(ent.Owner, ent); + private void RemoveSupermatter(Entity ent, ref ComponentShutdown args) => _supermatters.Remove(ent.Owner); + + protected override float Threshold { get; set; } = 1f; + protected override void AccUpdate() + { + foreach (var supermatter in _supermatters) + Handle(supermatter.Value); + } + + private void Handle(Entity supermatter) + { + if (!supermatter.Comp.Activated) return; + + HandleDamage(supermatter); + HandleGas(supermatter); + HandleRadiation(supermatter); + HandleLighting(supermatter); + HandleDestruction(supermatter); + NotifyCascad(supermatter); + Cascad(supermatter); + } + + private void Cascad(Entity supermatter) + { + if (supermatter.Comp.Durability > 0.01) return; + + _cascade.StartCascade(Transform(supermatter.Owner).Coordinates); + QueueDel(supermatter.Owner); + } + + private void NotifyCascad(Entity supermatter) + { + var currentDurability = (int)Math.Floor(supermatter.Comp.Durability.Float()); + var lastDurability = (int)Math.Floor(supermatter.Comp.LastSendedDurability.Float()); + _engi ??= _prototypes.Index("Engineering"); + + if (Math.Abs(currentDurability - lastDurability) < 5) + return; + + supermatter.Comp.LastSendedDurability = supermatter.Comp.Durability; + + if (currentDurability > lastDurability) + _radioSystem.SendRadioMessage(supermatter.Owner, $"The crystal is regenerating. Durability: {currentDurability}%", _engi, supermatter.Owner); + else switch (currentDurability) + { + case > 75: _radioSystem.SendRadioMessage(supermatter.Owner, $"Attention! The crystal is destabilizing. Durability: {currentDurability}%", _engi, supermatter.Owner); break; + case > 50: _chat.DispatchServerAnnouncement($"Attention! The crystal is destabilizing. Durability: {currentDurability}%", Color.Yellow); break; + case > 25: _chat.DispatchServerAnnouncement($"Critical state of the crystal! Durability: {currentDurability}%", Color.OrangeRed); break; + default: _chat.DispatchServerAnnouncement($"Crystal destruction is inevitable. Current durability: {currentDurability}%", Color.Red); break; + } + } + + private void HandleDestruction(Entity supermatter) + { + var damageToApply = MathHelper.Clamp((supermatter.Comp.AccBreak / 10) - Const.RegenerationPerSecond, -Const.RegenerationPerSecond, Const.MaxDamagePerSecond); + supermatter.Comp.AccBreak = 0; + + supermatter.Comp.Durability = MathHelper.Clamp(supermatter.Comp.Durability - damageToApply, 0f, 100f); + } + + private void HandleLighting(Entity supermatter) + { + if (supermatter.Comp.AccLighting != 0 + && _lightning.ShootRandomLightnings(supermatter.Owner, supermatter.Comp.AccLighting.Float(), 1)) + supermatter.Comp.AccLighting = 0; + } + + private void HandleRadiation(Entity supermatter) + { + var radComp = EnsureComp(supermatter.Owner); + radComp.Intensity = supermatter.Comp.AccRadiation.Float(); + + supermatter.Comp.AccRadiation /= supermatter.Comp.RadiationStability; + } + + private void HandleGas(Entity supermatter) + { + var gas = _atmosphere.GetTileMixture(supermatter.Owner, true) ?? new(); + DamageByPressure(supermatter, gas); + DamageByTemperature(supermatter, gas); + + if (gas.TotalMoles < 1) return; + + float heatTransfer = 0; + float heatModifier = 0; + float radiationStability = 0; + + for (var i = 0; i < Const.GasProperties.Length; i++) + { + var prop = Const.GasProperties[i]; + var percent = Math.Clamp(gas.Moles[i] / gas.TotalMoles, 0, 1); + heatTransfer += prop.HeatTransferPerMole * gas.Moles[i]; + heatModifier += prop.HeatModifier * percent; + radiationStability += prop.RadiationStability * percent; + } + + supermatter.Comp.RadiationStability = MathHelper.Clamp(radiationStability, 1, 10); + + ProcessHeat(supermatter, gas, heatTransfer, heatModifier); + TryCompensateDamage(supermatter, gas); + } + + private static void TryCompensateDamage(Entity supermatter, GasMixture gas) + { + var breakDelta = supermatter.Comp.AccBreak > Const.EvaporationCompensation ? Const.EvaporationCompensation : supermatter.Comp.AccBreak; + if (breakDelta == 0) return; + supermatter.Comp.AccBreak -= breakDelta; + + gas.AdjustMoles((int)Gas.Tritium, breakDelta.Float()/2); + + gas.AdjustMoles((int)Gas.Oxygen, breakDelta.Float()*4); + } + + private static void ProcessHeat(Entity supermatter, GasMixture gas, float heatTransfer, float heatModifier) + { + var accHeat = supermatter.Comp.AccHeat.Float(); + var heatDelta = heatTransfer <= accHeat ? heatTransfer : accHeat; + + accHeat = MathHelper.Clamp(accHeat - heatDelta, 0, 9999); ; + supermatter.Comp.AccHeat = 0; + gas.Temperature += heatDelta * heatModifier; + supermatter.Comp.AccBreak += accHeat; + } + + private void DamageByTemperature(Entity supermatter, GasMixture gas) + { + if (gas.Temperature <= Const.MaxTemperature) return; + _audio.PlayPvs(_random.Pick(Const.AudioBurn), supermatter.Owner); + _burn ??= _prototypes.Index("Burn"); + DamageSpecifier damage = new(_burn, Const.MaxTemperature - gas.Temperature); + _damageable.TryChangeDamage(supermatter.Owner, damage, true); + } + + private void DamageByPressure(Entity supermatter, GasMixture gas) + { + if (gas.Pressure >= Const.MinPressure && gas.Pressure <= Const.MaxPressure) return; + _audio.PlayPvs(_random.Pick(Const.AudioCrack), supermatter.Owner); + _brute ??= _prototypes.Index("Brute"); + DamageSpecifier damage = new(_brute, Math.Max(Const.MinPressure - gas.Pressure, gas.Pressure - Const.MaxPressure) / 100); + _damageable.TryChangeDamage(supermatter.Owner, damage, true); + } + + private void HandleDamage(Entity supermatter) + { + EnsureComp(supermatter.Owner, out var damageable); + var trueDamage = damageable.TotalDamage * Const.DamageMultiplayer; + _damageable.TryChangeDamage(supermatter.Owner, damageable.Damage.Invert(), true); + + supermatter.Comp.AccBreak = MathHelper.Clamp(supermatter.Comp.AccBreak + (trueDamage * Const.BreakPercent), 0, 9999); + supermatter.Comp.AccHeat = MathHelper.Clamp(supermatter.Comp.AccHeat + (trueDamage * Const.HeatPercent), 0, 9999); + supermatter.Comp.AccLighting = MathHelper.Clamp(supermatter.Comp.AccLighting + (trueDamage * Const.LightingPercent), 0, 25); + supermatter.Comp.AccRadiation = MathHelper.Clamp(supermatter.Comp.AccRadiation + (trueDamage * Const.RadiationPercent), 0, 100); + } +} diff --git a/Content.Shared/Atmos/GasMixture.cs b/Content.Shared/Atmos/GasMixture.cs index 612626d614..7ecb934b58 100644 --- a/Content.Shared/Atmos/GasMixture.cs +++ b/Content.Shared/Atmos/GasMixture.cs @@ -19,7 +19,7 @@ namespace Content.Shared.Atmos public static GasMixture SpaceGas => new() {Volume = Atmospherics.CellVolume, Temperature = Atmospherics.TCMB, Immutable = true}; // No access, to ensure immutable mixtures are never accidentally mutated. - [Access(typeof(SharedAtmosphereSystem), typeof(SharedAtmosDebugOverlaySystem), typeof(GasEnumerator), Other = AccessPermissions.None)] + [Access(typeof(SharedAtmosphereSystem), typeof(SharedAtmosDebugOverlaySystem), typeof(GasEnumerator), Other = AccessPermissions.Read)] // Sunrise-Edit [DataField] public float[] Moles = new float[Atmospherics.AdjustedNumberOfGases]; diff --git a/Content.Shared/Construction/Components/FlatpackComponent.cs b/Content.Shared/Construction/Components/FlatpackComponent.cs index 5cb178075b..5a877064bd 100644 --- a/Content.Shared/Construction/Components/FlatpackComponent.cs +++ b/Content.Shared/Construction/Components/FlatpackComponent.cs @@ -19,6 +19,12 @@ public sealed partial class FlatpackComponent : Component [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public ProtoId QualityNeeded = "Pulsing"; + /// + /// Is Flatpack allowed to unpuck on tables? (For microwaves, etc.) + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public bool AllowUnpackOnTables = false; // Starlight-edit + /// /// The entity that is spawned when this object is unpacked. /// diff --git a/Content.Shared/Construction/SharedFlatpackSystem.cs b/Content.Shared/Construction/SharedFlatpackSystem.cs index f3358031d2..7372cc0a6c 100644 --- a/Content.Shared/Construction/SharedFlatpackSystem.cs +++ b/Content.Shared/Construction/SharedFlatpackSystem.cs @@ -1,4 +1,5 @@ using Content.Shared._Sunrise.Economy; +using System.Linq; using Content.Shared.Construction.Components; using Content.Shared.Administration.Logs; using Content.Shared.Containers.ItemSlots; @@ -6,6 +7,7 @@ using Content.Shared.Database; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Materials; +using Content.Shared.Tag; using Content.Shared.Popups; using Content.Shared.Tools.Systems; using Robust.Shared.Audio.Systems; @@ -31,6 +33,7 @@ public abstract class SharedFlatpackSystem : EntitySystem [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedToolSystem _tool = default!; + [Dependency] private readonly TagSystem _tag = default!; /// public override void Initialize() @@ -80,10 +83,12 @@ public abstract class SharedFlatpackSystem : EntitySystem var buildPos = _map.TileIndicesFor(grid, gridComp, xform.Coordinates); var coords = _map.ToCenterCoordinates(grid, buildPos); - // TODO FLATPAK - // Make this logic smarter. This should eventually allow for shit like building microwaves on tables and such. - // Also: make it ignore ghosts - if (_entityLookup.AnyEntitiesIntersecting(coords, LookupFlags.Dynamic | LookupFlags.Static)) + // TODO FLATPACK + // make it ignore ghosts + // Starlight-start + if (_entityLookup.GetEntitiesIntersecting(coords, LookupFlags.Dynamic | LookupFlags.Static) + .Any(entity => entity != uid && (!_tag.HasTag(entity, "Table") || !ent.Comp.AllowUnpackOnTables))) + // Starlight-end { // this popup is on the server because the predicts on the intersection is crazy if (_net.IsServer) diff --git a/Content.Shared/Supermatter/SupermatterDoAfterEvent.cs b/Content.Shared/Supermatter/SupermatterDoAfterEvent.cs deleted file mode 100644 index addc07b721..0000000000 --- a/Content.Shared/Supermatter/SupermatterDoAfterEvent.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Content.Shared.DoAfter; -using Robust.Shared.Serialization; - -namespace Content.Shared.Supermatter; - -[Serializable, NetSerializable] -public sealed partial class SupermatterDoAfterEvent : SimpleDoAfterEvent -{ - -} diff --git a/Content.Shared/_Starlight/Abstract/AccUpdateEntitySystem.cs b/Content.Shared/_Starlight/Abstract/AccUpdateEntitySystem.cs new file mode 100644 index 0000000000..3d17d54725 --- /dev/null +++ b/Content.Shared/_Starlight/Abstract/AccUpdateEntitySystem.cs @@ -0,0 +1,19 @@ +namespace Content.Shared.Abilities.Goliath; + +public abstract class AccUpdateEntitySystem : EntitySystem +{ + public override void Update(float frameTime) + { + _accumulator += frameTime; + if (_accumulator > Threshold) + { + AccUpdate(); + _accumulator = 0; + } + } + protected virtual void AccUpdate() + { + } + protected virtual float Threshold { get; set; } = 0.35f; + private float _accumulator = 0f; +} diff --git a/Content.Shared/_Starlight/Energy/Supermatter/SupermatterComponent.cs b/Content.Shared/_Starlight/Energy/Supermatter/SupermatterComponent.cs new file mode 100644 index 0000000000..0f79da5a8f --- /dev/null +++ b/Content.Shared/_Starlight/Energy/Supermatter/SupermatterComponent.cs @@ -0,0 +1,33 @@ +using Content.Shared.FixedPoint; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared.Starlight.Energy.Supermatter; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SupermatterComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite)] + public bool Activated = false; + + [ViewVariables(VVAccess.ReadOnly)] + public FixedPoint2 AccHeat = 0f; + + [ViewVariables(VVAccess.ReadOnly)] + public FixedPoint2 AccRadiation = 0f; + + [ViewVariables(VVAccess.ReadOnly)] + public FixedPoint2 AccLighting = 0f; + + [ViewVariables(VVAccess.ReadOnly)] + public FixedPoint2 AccBreak = 0f; + + [ViewVariables(VVAccess.ReadOnly)] + public FixedPoint2 RadiationStability = 1f; + + [ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 Durability = 100f; + + [ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 LastSendedDurability = 100f; +} diff --git a/Resources/Audio/Ambience/Objects/attributions.yml b/Resources/Audio/Ambience/Objects/attributions.yml index 1e1d03d4f0..e5cd81a372 100644 --- a/Resources/Audio/Ambience/Objects/attributions.yml +++ b/Resources/Audio/Ambience/Objects/attributions.yml @@ -62,8 +62,3 @@ license: "CC-BY-4.0" copyright: "Taken and edited from source" source: "https://freesound.org/people/juskiddink/sounds/215658/" - -- files: ["supermatter_calm.ogg", "supermatter_delam.ogg"] - license: "CC-BY-SA-3.0" - copyright: "Taken from source" - source: "https://github.com/tgstation/tgstation/blob/master/sound/machines/sm/loops" \ No newline at end of file diff --git a/Resources/Audio/Ambience/Objects/supermatter_calm.ogg b/Resources/Audio/Ambience/Objects/supermatter_calm.ogg deleted file mode 100644 index cee14fcd13..0000000000 Binary files a/Resources/Audio/Ambience/Objects/supermatter_calm.ogg and /dev/null differ diff --git a/Resources/Audio/Ambience/Objects/supermatter_delam.ogg b/Resources/Audio/Ambience/Objects/supermatter_delam.ogg deleted file mode 100644 index 7d79f0e3c4..0000000000 Binary files a/Resources/Audio/Ambience/Objects/supermatter_delam.ogg and /dev/null differ diff --git a/Resources/Audio/_Starlight/Effects/supermatter/attributions.yml b/Resources/Audio/_Starlight/Effects/supermatter/attributions.yml new file mode 100644 index 0000000000..77ea07bf56 --- /dev/null +++ b/Resources/Audio/_Starlight/Effects/supermatter/attributions.yml @@ -0,0 +1,9 @@ +- files: ["crystal_crack_1.ogg","crystal_crack_2.ogg", "burning_1.ogg", "burning_2.ogg", "burning_3.ogg"] + license: "CC-BY-4.0" + copyright: 'Darkrell' + source: "https://github.com/ss14Starlight/space-station-14" + +- files: ["emitter2.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from tgstation" + source: "https://github.com/tgstation/tgstation/blob/master/sound/weapons/emitter2.ogg" \ No newline at end of file diff --git a/Resources/Audio/_Starlight/Effects/supermatter/burning_1.ogg b/Resources/Audio/_Starlight/Effects/supermatter/burning_1.ogg new file mode 100644 index 0000000000..7a89578111 Binary files /dev/null and b/Resources/Audio/_Starlight/Effects/supermatter/burning_1.ogg differ diff --git a/Resources/Audio/_Starlight/Effects/supermatter/burning_2.ogg b/Resources/Audio/_Starlight/Effects/supermatter/burning_2.ogg new file mode 100644 index 0000000000..5b1bd5358f Binary files /dev/null and b/Resources/Audio/_Starlight/Effects/supermatter/burning_2.ogg differ diff --git a/Resources/Audio/_Starlight/Effects/supermatter/burning_3.ogg b/Resources/Audio/_Starlight/Effects/supermatter/burning_3.ogg new file mode 100644 index 0000000000..23ac1ea231 Binary files /dev/null and b/Resources/Audio/_Starlight/Effects/supermatter/burning_3.ogg differ diff --git a/Resources/Audio/_Starlight/Effects/supermatter/crystal_crack_1.ogg b/Resources/Audio/_Starlight/Effects/supermatter/crystal_crack_1.ogg new file mode 100644 index 0000000000..d816fa6312 Binary files /dev/null and b/Resources/Audio/_Starlight/Effects/supermatter/crystal_crack_1.ogg differ diff --git a/Resources/Audio/_Starlight/Effects/supermatter/crystal_crack_2.ogg b/Resources/Audio/_Starlight/Effects/supermatter/crystal_crack_2.ogg new file mode 100644 index 0000000000..eaba292527 Binary files /dev/null and b/Resources/Audio/_Starlight/Effects/supermatter/crystal_crack_2.ogg differ diff --git a/Resources/Audio/_Starlight/Effects/supermatter/emitter2.ogg b/Resources/Audio/_Starlight/Effects/supermatter/emitter2.ogg new file mode 100644 index 0000000000..4cba77cd96 Binary files /dev/null and b/Resources/Audio/_Starlight/Effects/supermatter/emitter2.ogg differ diff --git a/Resources/Locale/en-US/_prototypes/_sunrise/objectives/traitorObjectives.ftl b/Resources/Locale/en-US/_prototypes/_sunrise/objectives/traitorObjectives.ftl index ee9f06a0cf..0e14422eb5 100644 --- a/Resources/Locale/en-US/_prototypes/_sunrise/objectives/traitorObjectives.ftl +++ b/Resources/Locale/en-US/_prototypes/_sunrise/objectives/traitorObjectives.ftl @@ -4,7 +4,5 @@ ent-CMOAdvancedDefibrillatorStealObjective = { ent-BaseCMOStealObjective } .desc = { ent-BaseCMOStealObjective.desc } ent-PlutoniumCoreStealObjective = { ent-BaseTraitorStealObjective } .desc = { ent-BaseTraitorStealObjective.desc } -ent-StealSupermatterSliverObjective = { ent-BaseTraitorStealObjective } - .desc = { ent-BaseTraitorStealObjective.desc } ent-HandheldFaxStealObjective = { ent-BaseTraitorStealObjective } .desc = { ent-BaseTraitorStealObjective.desc } diff --git a/Resources/Locale/en-US/_prototypes/entities/objects/misc/supermatter_sliver.ftl b/Resources/Locale/en-US/_prototypes/entities/objects/misc/supermatter_sliver.ftl deleted file mode 100644 index 0892c1911a..0000000000 --- a/Resources/Locale/en-US/_prototypes/entities/objects/misc/supermatter_sliver.ftl +++ /dev/null @@ -1,2 +0,0 @@ -ent-SupermatterSliver = supermatter sliver - .desc = A shard from the station's supermatter engine. Highly radioactive. diff --git a/Resources/Locale/en-US/_strings/_sunrise/objectives/steal.ftl b/Resources/Locale/en-US/_strings/_sunrise/objectives/steal.ftl index 9e070174a3..0a97aa4fa5 100644 --- a/Resources/Locale/en-US/_strings/_sunrise/objectives/steal.ftl +++ b/Resources/Locale/en-US/_strings/_sunrise/objectives/steal.ftl @@ -1,5 +1,4 @@ objective-condition-steal-nuclear-bomb = nuclear bomb -objective-condition-steal-supermatter-sliver = Отрежьте кусочек от кристалла суперматерии. objective-description-steal-supermatter-sliver = Используйте любой подходящий режущий инструмент. Лучше всего подойдёт скальпель. И постарайтесь не умереть от радиационного отравления. objective-description-steal-handheld-fax = You need to steal a portable fax machine from a corporate representative. objective-condition-steal-handheld-fax = Portable fax diff --git a/Resources/Locale/ru-RU/_prototypes/_sunrise/objectives/traitorObjectives.ftl b/Resources/Locale/ru-RU/_prototypes/_sunrise/objectives/traitorObjectives.ftl index ee9f06a0cf..0e14422eb5 100644 --- a/Resources/Locale/ru-RU/_prototypes/_sunrise/objectives/traitorObjectives.ftl +++ b/Resources/Locale/ru-RU/_prototypes/_sunrise/objectives/traitorObjectives.ftl @@ -4,7 +4,5 @@ ent-CMOAdvancedDefibrillatorStealObjective = { ent-BaseCMOStealObjective } .desc = { ent-BaseCMOStealObjective.desc } ent-PlutoniumCoreStealObjective = { ent-BaseTraitorStealObjective } .desc = { ent-BaseTraitorStealObjective.desc } -ent-StealSupermatterSliverObjective = { ent-BaseTraitorStealObjective } - .desc = { ent-BaseTraitorStealObjective.desc } ent-HandheldFaxStealObjective = { ent-BaseTraitorStealObjective } .desc = { ent-BaseTraitorStealObjective.desc } diff --git a/Resources/Locale/ru-RU/_prototypes/entities/objects/misc/supermatter_sliver.ftl b/Resources/Locale/ru-RU/_prototypes/entities/objects/misc/supermatter_sliver.ftl deleted file mode 100644 index 7d87e34d98..0000000000 --- a/Resources/Locale/ru-RU/_prototypes/entities/objects/misc/supermatter_sliver.ftl +++ /dev/null @@ -1,2 +0,0 @@ -ent-SupermatterSliver = осколок суперматерии - .desc = Осколок от кристалла суперматерии станции. Сильно радиоактивен. diff --git a/Resources/Locale/ru-RU/_strings/_sunrise/objectives/steal.ftl b/Resources/Locale/ru-RU/_strings/_sunrise/objectives/steal.ftl index c1f0f452f7..715b9f032b 100644 --- a/Resources/Locale/ru-RU/_strings/_sunrise/objectives/steal.ftl +++ b/Resources/Locale/ru-RU/_strings/_sunrise/objectives/steal.ftl @@ -1,3 +1,2 @@ objective-condition-steal-nuclear-bomb = ядерную бомбу -objective-condition-steal-supermatter-sliver = Отрежьте кусочек от кристалла суперматерии. objective-description-steal-supermatter-sliver = Используйте любой подходящий режущий инструмент. Лучше всего подойдёт скальпель. И постарайтесь не умереть от радиационного отравления. diff --git a/Resources/Locale/ru-RU/_strings/objectives/conditions/steal-target-groups.ftl b/Resources/Locale/ru-RU/_strings/objectives/conditions/steal-target-groups.ftl index ea87f96ef7..e2c7f9dd88 100644 --- a/Resources/Locale/ru-RU/_strings/objectives/conditions/steal-target-groups.ftl +++ b/Resources/Locale/ru-RU/_strings/objectives/conditions/steal-target-groups.ftl @@ -1,5 +1,4 @@ # Traitor single items -steal-target-groups-supermatter-sliver = осколок суперматерии steal-target-groups-hypospray = гипоспрей steal-target-groups-handheld-crew-monitor = портативный монитор экипажа steal-target-groups-clothing-outer-hardsuit-rd = экспериментальный исследовательский скафандр diff --git a/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml b/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml index fe15d88942..3aedd5bf6a 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml @@ -231,6 +231,7 @@ layers: - state: fax-machine - type: Flatpack + allowUnpackOnTables: true entity: FaxMachineBase - type: entity @@ -251,6 +252,32 @@ - type: Flatpack entity: ComputerCrewMonitoring +- type: entity + parent: BaseFlatpack + id: MicrowaveFlatpack + name: microwave flatpack + description: A flatpack used for constructing a microwave. + components: + - type: Sprite + layers: + - state: microwave + - type: Flatpack + allowUnpackOnTables: true + entity: KitchenMicrowave + +- type: entity + parent: BaseFlatpack + id: SyndicateMicrowaveFlatpack + name: microwave flatpack + description: A flatpack used for constructing a microwave. + components: + - type: Sprite + layers: + - state: microwave + - type: Flatpack + allowUnpackOnTables: true + entity: SyndicateMicrowave + - type: entity parent: BaseFlatpack id: HydroponicsTrayFlatpack diff --git a/Resources/Prototypes/Entities/Objects/Misc/supermatter_sliver.yml b/Resources/Prototypes/Entities/Objects/Misc/supermatter_sliver.yml deleted file mode 100644 index ab7e1d6815..0000000000 --- a/Resources/Prototypes/Entities/Objects/Misc/supermatter_sliver.yml +++ /dev/null @@ -1,24 +0,0 @@ -- type: entity - parent: BaseItem - id: SupermatterSliver - name: supermatter sliver - description: A shard from the station's supermatter engine. Highly radioactive. - components: - - type: PointLight - enabled: true - radius: 3 - energy: 2 - color: "#fff633" - - type: RadiationSource - intensity: 2.5 - - type: Icon - sprite: Objects/Misc/supermatter_sliver.rsi - state: icon - - type: Sprite - sprite: Objects/Misc/supermatter_sliver.rsi - state: icon - - type: StealTarget - stealGroup: SupermatterSliver - - type: Tag - tags: - - HighRiskItem diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml index 27cb4d8b68..d8c69f0646 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml @@ -40,6 +40,7 @@ - type: Tag tags: - ForceFixRotations + - Table - type: entity id: CounterBase diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Supermatter/supermatter.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Supermatter/supermatter.yml deleted file mode 100644 index 4e56d30a9f..0000000000 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Supermatter/supermatter.yml +++ /dev/null @@ -1,60 +0,0 @@ -- type: entity - id: SupermatterCrystal - name: supermatter crystal - description: A strangely translucent and iridescent crystal. - placement: - mode: SnapgridCenter - components: - - type: Supermatter - - type: Transform - anchored: true - noRot: true - - type: Damageable - damageContainer: Inorganic - damageModifierSet: Glass - - type: RadiationSource - intensity: 0 # will be set somewhere else - - type: Physics - bodyType: Static - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.45,-0.45,0.45,0.45" - density: 250 - mask: - - FullTileMask - layer: - - WallLayer - - type: CollisionWake - enabled: false - - type: Clickable - - type: InteractionOutline - - type: Sprite - drawdepth: 2 - sprite: Structures/Power/Generation/supermatter.rsi - state: supermatter - - type: Icon - sprite: Structures/Power/Generation/supermatter.rsi - state: supermatter - - type: PointLight - enabled: true - radius: 10 - energy: 5 - color: "#fff633" - - type: AmbientSound - range: 4 - volume: -2 - sound: - path: /Audio/Ambience/Objects/supermatter_calm.ogg - - type: SinguloFood - energy: 7500 - - type: WarpPoint - follow: true - location: supermatter - - type: Explosive - explosionType: HardBomb - totalIntensity: 10000.0 - intensitySlope: 4 - maxIntensity: 1000 diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Supermatter/supermatter_kudzu.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Supermatter/supermatter_kudzu.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml index 090d2f1839..cdb98dc8bd 100644 --- a/Resources/Prototypes/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -26,7 +26,6 @@ PlutoniumCoreStealObjective: 0.5 #MultiphaseEnergygunStealObjective: 1 # Sunrise-Edit: ОСЩ больше не появляется на станции CMOAdvancedDefibrillatorStealObjective: 1 - StealSupermatterSliverObjective: 1 HandheldFaxStealObjective: 1 # Sunrise-End diff --git a/Resources/Prototypes/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Objectives/stealTargetGroups.yml index f87866bdcc..b99696331c 100644 --- a/Resources/Prototypes/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Objectives/stealTargetGroups.yml @@ -1,12 +1,5 @@ # Traitor single items -- type: stealTargetGroup - id: SupermatterSliver - name: steal-target-groups-supermatter-sliver - sprite: - sprite: Objects/Misc/supermatter_sliver.rsi - state: icon - - type: stealTargetGroup id: Hypospray name: steal-target-groups-hypospray diff --git a/Resources/Prototypes/_Starlight/Catalog/Cargo/cargo_engineering.yml b/Resources/Prototypes/_Starlight/Catalog/Cargo/cargo_engineering.yml new file mode 100644 index 0000000000..b283321dfa --- /dev/null +++ b/Resources/Prototypes/_Starlight/Catalog/Cargo/cargo_engineering.yml @@ -0,0 +1,9 @@ +- type: cargoProduct + id: SupermatterFlatpackPurchase + icon: + sprite: _Starlight/Objects/Specific/supermatter.rsi + state: supermatter + product: SupermatterFlatpack + cost: 8000 + category: cargoproduct-category-name-engineering + group: market diff --git a/Resources/Prototypes/_Starlight/Entities/Objects/Devices/flatpack.yml b/Resources/Prototypes/_Starlight/Entities/Objects/Devices/flatpack.yml new file mode 100644 index 0000000000..ed9c01ed93 --- /dev/null +++ b/Resources/Prototypes/_Starlight/Entities/Objects/Devices/flatpack.yml @@ -0,0 +1,67 @@ +- type: entity + parent: BaseStructureDynamic + id: BaseStructureFlatpack + name: base structure flatpack + description: A flatpack used for constructing something. + categories: + - HideSpawnMenu + components: + - type: Animateable + - type: Transform + noRot: true + - type: Icon + sprite: Structures/Storage/Crates/generic.rsi + state: base + - type: Sprite + sprite: Objects/Devices/flatpack.rsi + layers: + - state: base + - state: overlay + color: "#cec8ac" + map: ["enum.FlatpackVisualLayers.Overlay"] + - state: icon-default + - type: InteractionOutline + - type: Physics + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.29" + density: 50 + mask: + - CrateMask #this is so they can go under plastic flaps + layer: + - MachineLayer + - type: Appearance + - type: Flatpack + boardColors: + command: "#334E6D" + medical: "#52B4E9" + service: "#9FED58" + engineering: "#EFB341" + security: "#DE3A3A" + science: "#D381C9" + supply: "#A46106" + cpu_command: "#334E6D" + cpu_medical: "#52B4E9" + cpu_service: "#9FED58" + cpu_engineering: "#EFB341" + cpu_security: "#DE3A3A" + cpu_science: "#D381C9" + cpu_supply: "#A46106" + - type: StaticPrice + price: 250 + +- type: entity + parent: [BaseStructureFlatpack, BaseEngineeringContraband] + id: SupermatterFlatpack + name: supermatter flatpack + description: A flatpack used for constructing a Supermatter Crystal. + components: + - type: Sprite + sprite: Objects/Devices/flatpack.rsi + layers: + - state: large + - type: Flatpack + entity: SupermatterCrystal \ No newline at end of file diff --git a/Resources/Prototypes/_Starlight/Entities/Structures/Specific/supermatter.yml b/Resources/Prototypes/_Starlight/Entities/Structures/Specific/supermatter.yml new file mode 100644 index 0000000000..637d530c63 --- /dev/null +++ b/Resources/Prototypes/_Starlight/Entities/Structures/Specific/supermatter.yml @@ -0,0 +1,141 @@ +- type: entity + id: SupermatterCrystal + name: supermatter + description: A glowing supermatter crystal, with half an ID card lying next to it, and it says "Clown pira..." on it. + placement: + mode: SnapgridCenter + components: + - type: Supermatter + - type: Transform + noRot: true + anchored: true + - type: InteractionOutline + - type: Clickable + - type: Anchorable + delay: 2 + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.40,-0.40,0.40,0.40" + density: 190 + friction: 0.8 + mask: + - FullTileMask + layer: + - FullTileLayer + - type: Pullable + - type: Sprite + sprite: _Starlight/Objects/Specific/supermatter.rsi + state: supermatter + shader: unshaded + - type: Icon + sprite: _Starlight/Objects/Specific/supermatter.rsi + state: supermatter + - type: PointLight + enabled: true + color: "#FFFB97" + - type: Damageable + damageModifierSet: RGlass + damageContainer: StructuralInorganic + # - type: LightningTarget Tesla needs to interact too. + # priority: 1 + + +- type: entity + id: Cascad1 + name: cascad + description: Consequences of the supermatter crystal's cascade failure. + placement: + mode: SnapgridCenter + components: + - type: Damageable + damageContainer: StructuralInorganic + damageModifierSet: Glass + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 80 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + - type: Sprite + drawdepth: Walls + sprite: _Starlight/Objects/Specific/supermatter_cascade.rsi + layers: + - state: cascade_1 + - type: Icon + sprite: _Starlight/Objects/Specific/supermatter_cascade.rsi + state: cascade_1 + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + layer: + - GlassLayer + +- type: entity + id: Cascad2 + parent: Cascad1 + components: + - type: Sprite + layers: + - state: cascade_2 + - type: Icon + sprite: _Starlight/Objects/Specific/supermatter_cascade.rsi + state: cascade_2 + +- type: entity + id: Cascad3 + parent: Cascad1 + components: + - type: Sprite + layers: + - state: cascade_3 + - type: Icon + sprite: _Starlight/Objects/Specific/supermatter_cascade.rsi + state: cascade_3 + +- type: entity + id: Cascad4 + parent: Cascad1 + components: + - type: Sprite + layers: + - state: cascade_4 + - type: Icon + sprite: _Starlight/Objects/Specific/supermatter_cascade.rsi + state: cascade_4 + +- type: entity + id: Cascad5 + parent: Cascad1 + components: + - type: Sprite + layers: + - state: cascade_5 + - type: Icon + sprite: _Starlight/Objects/Specific/supermatter_cascade.rsi + state: cascade_5 + +- type: entity + id: Cascad6 + parent: Cascad1 + components: + - type: Sprite + layers: + - state: cascade_6 + - type: Icon + sprite: _Starlight/Objects/Specific/supermatter_cascade.rsi + state: cascade_6 \ No newline at end of file diff --git a/Resources/Prototypes/_Sunrise/Objectives/traitorObjectives.yml b/Resources/Prototypes/_Sunrise/Objectives/traitorObjectives.yml index d57a7f2390..3dc702f6fc 100644 --- a/Resources/Prototypes/_Sunrise/Objectives/traitorObjectives.yml +++ b/Resources/Prototypes/_Sunrise/Objectives/traitorObjectives.yml @@ -33,18 +33,6 @@ listings: - UplinkCoreExtractionToolbox -- type: entity - categories: [ HideSpawnMenu ] - parent: BaseTraitorStealObjective - id: StealSupermatterSliverObjective - components: - - type: Objective - difficulty: 2.5 - - type: StealCondition - stealGroup: SupermatterSliver - objectiveNoOwnerText: objective-condition-steal-supermatter-sliver - descriptionText: objective-description-steal-supermatter-sliver - - type: entity parent: BaseTraitorStealObjective id: HandheldFaxStealObjective diff --git a/Resources/Prototypes/_Sunrise/tags.yml b/Resources/Prototypes/_Sunrise/tags.yml index acb8721b06..95add452b8 100644 --- a/Resources/Prototypes/_Sunrise/tags.yml +++ b/Resources/Prototypes/_Sunrise/tags.yml @@ -456,3 +456,6 @@ - type: Tag id: SnapPop + +- type: Tag + id: Table diff --git a/Resources/Textures/Objects/Devices/flatpack.rsi/large.png b/Resources/Textures/Objects/Devices/flatpack.rsi/large.png new file mode 100644 index 0000000000..587c6b271f Binary files /dev/null and b/Resources/Textures/Objects/Devices/flatpack.rsi/large.png differ diff --git a/Resources/Textures/Objects/Devices/flatpack.rsi/meta.json b/Resources/Textures/Objects/Devices/flatpack.rsi/meta.json index ac1e6be151..5efc8b68e4 100644 --- a/Resources/Textures/Objects/Devices/flatpack.rsi/meta.json +++ b/Resources/Textures/Objects/Devices/flatpack.rsi/meta.json @@ -48,6 +48,12 @@ }, { "name": "hydroponics-tray" + }, + { + "name": "large" + }, + { + "name": "microwave" } ] } diff --git a/Resources/Textures/Objects/Devices/flatpack.rsi/microwave.png b/Resources/Textures/Objects/Devices/flatpack.rsi/microwave.png new file mode 100644 index 0000000000..9eb23c25d3 Binary files /dev/null and b/Resources/Textures/Objects/Devices/flatpack.rsi/microwave.png differ diff --git a/Resources/Textures/Objects/Misc/supermatter_sliver.rsi/icon.png b/Resources/Textures/Objects/Misc/supermatter_sliver.rsi/icon.png deleted file mode 100644 index 2187706b10..0000000000 Binary files a/Resources/Textures/Objects/Misc/supermatter_sliver.rsi/icon.png and /dev/null differ diff --git a/Resources/Textures/Objects/Misc/supermatter_sliver.rsi/meta.json b/Resources/Textures/Objects/Misc/supermatter_sliver.rsi/meta.json deleted file mode 100644 index 744651bea0..0000000000 --- a/Resources/Textures/Objects/Misc/supermatter_sliver.rsi/meta.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": 1, - "copyright": "Taken and edited from https://github.com/tgstation/tgstation/blob/master/icons/obj/antags/syndicate_tools.dmi", - "license": "CC-BY-SA-3.0", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "icon" - } - ] -} diff --git a/Resources/Textures/Structures/Power/Generation/supermatter.rsi/meta.json b/Resources/Textures/Structures/Power/Generation/supermatter.rsi/meta.json deleted file mode 100644 index d0a000ae2b..0000000000 --- a/Resources/Textures/Structures/Power/Generation/supermatter.rsi/meta.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "version": 1, - "copyright": "Taken and edited from https://tgstation13.org/wiki/images/a/a4/Supermatter-bg.gif", - "license": "CC-BY-SA-3.0", - "size": { - "x": 32, - "y": 48 - }, - "states": [ - { - "name": "supermatter", - "delays": [ - [ - 0.08, - 0.08, - 0.08 - ] - ] - } - ] -} diff --git a/Resources/Textures/Structures/Power/Generation/supermatter.rsi/supermatter.png b/Resources/Textures/Structures/Power/Generation/supermatter.rsi/supermatter.png deleted file mode 100644 index 0c5747a315..0000000000 Binary files a/Resources/Textures/Structures/Power/Generation/supermatter.rsi/supermatter.png and /dev/null differ diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter.rsi/meta.json b/Resources/Textures/_Starlight/Objects/Specific/supermatter.rsi/meta.json new file mode 100644 index 0000000000..f1364c9a97 --- /dev/null +++ b/Resources/Textures/_Starlight/Objects/Specific/supermatter.rsi/meta.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://tgstation13.org/wiki/images/a/a4/Supermatter-bg.gif", + "size": { + "x": 32, + "y": 48 + }, + "states": [ + { + "name": "supermatter", + "delays": [ + [ + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter.rsi/supermatter.png b/Resources/Textures/_Starlight/Objects/Specific/supermatter.rsi/supermatter.png new file mode 100644 index 0000000000..04db70cde1 Binary files /dev/null and b/Resources/Textures/_Starlight/Objects/Specific/supermatter.rsi/supermatter.png differ diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_1.png b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_1.png new file mode 100644 index 0000000000..a16072b8e1 Binary files /dev/null and b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_1.png differ diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_2.png b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_2.png new file mode 100644 index 0000000000..a3c7e2786d Binary files /dev/null and b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_2.png differ diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_3.png b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_3.png new file mode 100644 index 0000000000..59338c0961 Binary files /dev/null and b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_3.png differ diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_4.png b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_4.png new file mode 100644 index 0000000000..559063f9b3 Binary files /dev/null and b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_4.png differ diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_5.png b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_5.png new file mode 100644 index 0000000000..b2050dfd89 Binary files /dev/null and b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_5.png differ diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_6.png b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_6.png new file mode 100644 index 0000000000..be9635ea33 Binary files /dev/null and b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/cascade_6.png differ diff --git a/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/meta.json b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/meta.json new file mode 100644 index 0000000000..462a0b4d0d --- /dev/null +++ b/Resources/Textures/_Starlight/Objects/Specific/supermatter_cascade.rsi/meta.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://tgstation13.org/wiki/images/a/a4/Supermatter-bg.gif", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "cascade_1" + }, + { + "name": "cascade_2" + }, + { + "name": "cascade_3" + }, + { + "name": "cascade_4" + }, + { + "name": "cascade_5" + }, + { + "name": "cascade_6" + } + ] +}