using Content.Server.ParticleAccelerator.Components; using Content.Server.Singularity.Components; using Content.Shared.Singularity.Components; using Robust.Shared.Physics.Events; namespace Content.Server.Singularity.EntitySystems; public sealed class SingularityGeneratorSystem : EntitySystem { #region Dependencies [Dependency] private readonly IViewVariablesManager _vvm = default!; #endregion Dependencies public override void Initialize() { base.Initialize(); SubscribeLocalEvent(HandleParticleCollide); var vvHandle = _vvm.GetTypeHandler(); vvHandle.AddPath(nameof(SingularityGeneratorComponent.Power), (_, comp) => comp.Power, SetPower); vvHandle.AddPath(nameof(SingularityGeneratorComponent.Threshold), (_, comp) => comp.Threshold, SetThreshold); } public override void Shutdown() { var vvHandle = _vvm.GetTypeHandler(); vvHandle.RemovePath(nameof(SingularityGeneratorComponent.Power)); vvHandle.RemovePath(nameof(SingularityGeneratorComponent.Threshold)); base.Shutdown(); } /// /// Handles what happens when a singularity generator passes its power threshold. /// Default behavior is to reset the singularities power level and spawn a singularity. /// /// The uid of the singularity generator. /// The state of the singularity generator. private void OnPassThreshold(EntityUid uid, SingularityGeneratorComponent? comp) { if(!Resolve(uid, ref comp)) return; SetPower(comp, 0); EntityManager.SpawnEntity(comp.SpawnPrototype, Transform(comp.Owner).Coordinates); } #region Getters/Setters /// /// Setter for /// If the singularity generator passes its threshold it also spawns a singularity. /// /// The singularity generator component. /// The new power level for the generator component to have. public void SetPower(SingularityGeneratorComponent comp, float value) { var oldValue = comp.Power; if (value == oldValue) return; comp.Power = value; if (comp.Power >= comp.Threshold && oldValue < comp.Threshold) OnPassThreshold(comp.Owner, comp); } /// /// Setter for /// If the singularity generator has passed its new threshold it also spawns a singularity. /// /// The singularity generator component. /// The new threshold power level for the generator component to have. public void SetThreshold(SingularityGeneratorComponent comp, float value) { var oldValue = comp.Threshold; if (value == comp.Threshold) return; comp.Power = value; if (comp.Power >= comp.Threshold && comp.Power < oldValue) OnPassThreshold(comp.Owner, comp); } #region VV /// /// VV setter for /// If the singularity generator passes its threshold it also spawns a singularity. /// /// The entity hosting the singularity generator that is being modified. /// The value of the new power level the singularity generator should have. /// The singularity generator to change the power level of. public void SetPower(EntityUid uid, float value, SingularityGeneratorComponent? comp) { if(!Resolve(uid, ref comp)) return; SetPower(comp, value); } /// /// VV setter for /// If the singularity generator has passed its new threshold it also spawns a singularity. /// /// The entity hosting the singularity generator that is being modified. /// The value of the new threshold power level the singularity generator should have. /// The singularity generator to change the threshold power level of. public void SetThreshold(EntityUid uid, float value, SingularityGeneratorComponent? comp) { if(!Resolve(uid, ref comp)) return; SetThreshold(comp, value); } #endregion VV #endregion Getters/Setters #region Event Handlers /// /// Handles PA Particles colliding with a singularity generator. /// Adds the power from the particles to the generator. /// TODO: Desnowflake this. /// /// The uid of the PA particles have collided with. /// The state of the PA particles. /// The state of the beginning of the collision. private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent component, ref StartCollideEvent args) { if (EntityManager.TryGetComponent(args.OtherFixture.Body.Owner, out var singularityGeneratorComponent)) { SetPower( singularityGeneratorComponent, singularityGeneratorComponent.Power + component.State switch { ParticleAcceleratorPowerState.Standby => 0, ParticleAcceleratorPowerState.Level0 => 1, ParticleAcceleratorPowerState.Level1 => 2, ParticleAcceleratorPowerState.Level2 => 4, ParticleAcceleratorPowerState.Level3 => 8, _ => 0 }); EntityManager.QueueDeleteEntity(uid); } } #endregion Event Handlers }