using Content.Shared.Explosion; using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.ResourceManagement; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; namespace Content.Client.Explosion; /// /// This system is responsible for showing the client-side explosion effects (light source & fire-overlay). The /// fire overlay code is just a bastardized version of the atmos plasma fire overlay and uses the same texture. /// public sealed class ExplosionOverlaySystem : EntitySystem { [Dependency] private readonly IPrototypeManager _protoMan = default!; [Dependency] private readonly IResourceCache _resCache = default!; [Dependency] private readonly IOverlayManager _overlayMan = default!; /// /// For how many seconds should an explosion stay on-screen once it has finished expanding? /// public float ExplosionPersistence = 0.3f; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnExplosionInit); SubscribeLocalEvent(OnCompRemove); SubscribeLocalEvent(OnExplosionHandleState); _overlayMan.AddOverlay(new ExplosionOverlay()); } private void OnExplosionHandleState(EntityUid uid, ExplosionVisualsComponent component, ref ComponentHandleState args) { if (args.Current is not ExplosionVisualsState state) return; component.Epicenter = state.Epicenter; component.SpaceTiles = state.SpaceTiles; component.Tiles = state.Tiles; component.Intensity = state.Intensity; component.ExplosionType = state.ExplosionType; component.SpaceMatrix = state.SpaceMatrix; component.SpaceTileSize = state.SpaceTileSize; } private void OnCompRemove(EntityUid uid, ExplosionVisualsComponent component, ComponentRemove args) { if (TryComp(uid, out ExplosionVisualsTexturesComponent? textures)) QueueDel(textures.LightEntity); } private void OnExplosionInit(EntityUid uid, ExplosionVisualsComponent component, ComponentInit args) { EnsureComp(uid); if (!_protoMan.TryIndex(component.ExplosionType, out ExplosionPrototype? type) || !TryComp(uid, out ExplosionVisualsTexturesComponent? textures)) { return; } // spawn in a client-side light source at the epicenter var lightEntity = Spawn("ExplosionLight", component.Epicenter); var light = EnsureComp(lightEntity); light.Energy = light.Radius = component.Intensity.Count; light.Color = type.LightColor; textures.LightEntity = lightEntity; textures.FireColor = type.FireColor; textures.IntensityPerState = type.IntensityPerState; var fireRsi = _resCache.GetResource(type.TexturePath).RSI; foreach (var state in fireRsi) { textures.FireFrames.Add(state.GetFrames(RSI.State.Direction.South)); if (textures.FireFrames.Count == type.FireStates) break; } } public override void Shutdown() { base.Shutdown(); _overlayMan.RemoveOverlay(); } }